aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/ath6kl
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/staging/ath6kl
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/staging/ath6kl')
-rw-r--r--drivers/staging/ath6kl/Kconfig158
-rw-r--r--drivers/staging/ath6kl/Makefile122
-rw-r--r--drivers/staging/ath6kl/TODO25
-rw-r--r--drivers/staging/ath6kl/bmi/include/bmi_internal.h54
-rw-r--r--drivers/staging/ath6kl/bmi/src/bmi.c1010
-rw-r--r--drivers/staging/ath6kl/hif/common/hif_sdio_common.h87
-rw-r--r--drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h131
-rw-r--r--drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c1273
-rw-r--r--drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c393
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k.c1479
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k.h401
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c783
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c755
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c1284
-rw-r--r--drivers/staging/ath6kl/htc2/htc.c575
-rw-r--r--drivers/staging/ath6kl/htc2/htc_debug.h38
-rw-r--r--drivers/staging/ath6kl/htc2/htc_internal.h211
-rw-r--r--drivers/staging/ath6kl/htc2/htc_recv.c1572
-rw-r--r--drivers/staging/ath6kl/htc2/htc_send.c1018
-rw-r--r--drivers/staging/ath6kl/htc2/htc_services.c450
-rw-r--r--drivers/staging/ath6kl/include/a_config.h31
-rw-r--r--drivers/staging/ath6kl/include/a_debug.h195
-rw-r--r--drivers/staging/ath6kl/include/a_drv.h32
-rw-r--r--drivers/staging/ath6kl/include/a_drv_api.h204
-rw-r--r--drivers/staging/ath6kl/include/a_osapi.h32
-rw-r--r--drivers/staging/ath6kl/include/aggr_recv_api.h140
-rw-r--r--drivers/staging/ath6kl/include/ar3kconfig.h65
-rw-r--r--drivers/staging/ath6kl/include/ar6000_api.h32
-rw-r--r--drivers/staging/ath6kl/include/ar6000_diag.h48
-rw-r--r--drivers/staging/ath6kl/include/ar6kap_common.h44
-rw-r--r--drivers/staging/ath6kl/include/athbtfilter.h135
-rw-r--r--drivers/staging/ath6kl/include/bmi.h134
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h52
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/addrs.h90
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h40
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h40
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h24
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h552
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h471
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h589
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h187
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h162
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h40
-rw-r--r--drivers/staging/ath6kl/include/common/athdefs.h75
-rw-r--r--drivers/staging/ath6kl/include/common/bmi_msg.h233
-rw-r--r--drivers/staging/ath6kl/include/common/cnxmgmt.h36
-rw-r--r--drivers/staging/ath6kl/include/common/dbglog.h126
-rw-r--r--drivers/staging/ath6kl/include/common/dbglog_id.h558
-rw-r--r--drivers/staging/ath6kl/include/common/discovery.h75
-rw-r--r--drivers/staging/ath6kl/include/common/epping_test.h111
-rw-r--r--drivers/staging/ath6kl/include/common/gmboxif.h70
-rw-r--r--drivers/staging/ath6kl/include/common/gpio_reg.h9
-rw-r--r--drivers/staging/ath6kl/include/common/htc.h227
-rw-r--r--drivers/staging/ath6kl/include/common/htc_services.h52
-rw-r--r--drivers/staging/ath6kl/include/common/pkt_log.h45
-rw-r--r--drivers/staging/ath6kl/include/common/roaming.h41
-rw-r--r--drivers/staging/ath6kl/include/common/targaddrs.h395
-rw-r--r--drivers/staging/ath6kl/include/common/testcmd.h185
-rw-r--r--drivers/staging/ath6kl/include/common/tlpm.h38
-rw-r--r--drivers/staging/ath6kl/include/common/wlan_defs.h79
-rw-r--r--drivers/staging/ath6kl/include/common/wmi.h3220
-rw-r--r--drivers/staging/ath6kl/include/common/wmix.h271
-rw-r--r--drivers/staging/ath6kl/include/common_drv.h104
-rw-r--r--drivers/staging/ath6kl/include/dbglog_api.h52
-rw-r--r--drivers/staging/ath6kl/include/dl_list.h153
-rw-r--r--drivers/staging/ath6kl/include/dset_api.h65
-rw-r--r--drivers/staging/ath6kl/include/hci_transport_api.h259
-rw-r--r--drivers/staging/ath6kl/include/hif.h456
-rw-r--r--drivers/staging/ath6kl/include/host_version.h52
-rw-r--r--drivers/staging/ath6kl/include/htc_api.h575
-rw-r--r--drivers/staging/ath6kl/include/htc_packet.h227
-rw-r--r--drivers/staging/ath6kl/include/wlan_api.h128
-rw-r--r--drivers/staging/ath6kl/include/wmi_api.h441
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kconfig.c565
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c572
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h75
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c969
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h113
-rw-r--r--drivers/staging/ath6kl/miscdrv/common_drv.c910
-rw-r--r--drivers/staging/ath6kl/miscdrv/credit_dist.c417
-rw-r--r--drivers/staging/ath6kl/miscdrv/miscdrv.h42
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_drv.c6267
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_pm.c626
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_raw_if.c455
-rw-r--r--drivers/staging/ath6kl/os/linux/cfg80211.c1892
-rw-r--r--drivers/staging/ath6kl/os/linux/export_hci_transport.c124
-rw-r--r--drivers/staging/ath6kl/os/linux/hci_bridge.c1141
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6000_drv.h776
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6k_pal.h36
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h190
-rw-r--r--drivers/staging/ath6kl/os/linux/include/athdrv_linux.h1217
-rw-r--r--drivers/staging/ath6kl/os/linux/include/cfg80211.h61
-rw-r--r--drivers/staging/ath6kl/os/linux/include/config_linux.h51
-rw-r--r--drivers/staging/ath6kl/os/linux/include/debug_linux.h50
-rw-r--r--drivers/staging/ath6kl/os/linux/include/export_hci_transport.h76
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h177
-rw-r--r--drivers/staging/ath6kl/os/linux/include/osapi_linux.h339
-rw-r--r--drivers/staging/ath6kl/os/linux/include/wlan_config.h108
-rw-r--r--drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h300
-rw-r--r--drivers/staging/ath6kl/os/linux/netbuf.c231
-rw-r--r--drivers/staging/ath6kl/reorder/aggr_rx_internal.h117
-rw-r--r--drivers/staging/ath6kl/reorder/rcv_aggr.c661
-rw-r--r--drivers/staging/ath6kl/wlan/include/ieee80211.h397
-rw-r--r--drivers/staging/ath6kl/wlan/include/ieee80211_node.h93
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_node.c636
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c199
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_utils.c58
-rw-r--r--drivers/staging/ath6kl/wmi/wmi.c6444
-rw-r--r--drivers/staging/ath6kl/wmi/wmi_host.h102
109 files changed, 50003 insertions, 0 deletions
diff --git a/drivers/staging/ath6kl/Kconfig b/drivers/staging/ath6kl/Kconfig
new file mode 100644
index 00000000000..afd6cc16a2b
--- /dev/null
+++ b/drivers/staging/ath6kl/Kconfig
@@ -0,0 +1,158 @@
1config ATH6K_LEGACY
2 tristate "Atheros AR6003 support (non mac80211)"
3 depends on MMC && WLAN
4 depends on CFG80211
5 select WIRELESS_EXT
6 select WEXT_PRIV
7 help
8 This module adds support for wireless adapters based on Atheros AR6003 chipset running over SDIO. If you choose to build it as a module, it will be called ath6kl. Pls note that AR6002 and AR6001 are not supported by this driver.
9
10choice
11 prompt "AR6003 Board Data Configuration"
12 depends on ATH6K_LEGACY
13 default AR600x_SD31_XXX
14 help
15 Select the appropriate board data template from the list below that matches your AR6003 based reference design.
16
17config AR600x_SD31_XXX
18 bool "SD31-xxx"
19 help
20 Board Data file for a standard SD31 reference design (File: bdata.SD31.bin)
21
22config AR600x_WB31_XXX
23 bool "WB31-xxx"
24 help
25 Board Data file for a standard WB31 (BT/WiFi) reference design (File: bdata.WB31.bin)
26
27config AR600x_SD32_XXX
28 bool "SD32-xxx"
29 help
30 Board Data file for a standard SD32 (5GHz) reference design (File: bdata.SD32.bin)
31
32config AR600x_CUSTOM_XXX
33 bool "CUSTOM-xxx"
34 help
35 Board Data file for a custom reference design (File: should be named as bdata.CUSTOM.bin)
36endchoice
37
38config ATH6KL_ENABLE_COEXISTENCE
39 bool "BT Coexistence support"
40 depends on ATH6K_LEGACY
41 help
42 Enables WLAN/BT coexistence support. Select the apprpriate configuration from below.
43
44choice
45 prompt "Front-End Antenna Configuration"
46 depends on ATH6KL_ENABLE_COEXISTENCE
47 default AR600x_DUAL_ANTENNA
48 help
49 Indicates the number of antennas being used by BT and WLAN. Select the appropriate configuration from the list below that matches your AR6003 based reference design.
50
51config AR600x_DUAL_ANTENNA
52 bool "Dual Antenna"
53 help
54 Dual Antenna Design
55
56config AR600x_SINGLE_ANTENNA
57 bool "Single Antenna"
58 help
59 Single Antenna Design
60endchoice
61
62choice
63 prompt "Collocated Bluetooth Type"
64 depends on ATH6KL_ENABLE_COEXISTENCE
65 default AR600x_BT_AR3001
66 help
67 Select the appropriate configuration from the list below that matches your AR6003 based reference design.
68
69config AR600x_BT_QCOM
70 bool "Qualcomm BTS4020X"
71 help
72 Qualcomm BT (3 Wire PTA)
73
74config AR600x_BT_CSR
75 bool "CSR BC06"
76 help
77 CSR BT (3 Wire PTA)
78
79config AR600x_BT_AR3001
80 bool "Atheros AR3001"
81 help
82 Atheros BT (3 Wire PTA)
83endchoice
84
85config ATH6KL_HCI_BRIDGE
86 bool "HCI over SDIO support"
87 depends on ATH6K_LEGACY
88 help
89 Enables BT over SDIO. Applicable only for combo designs (eg: WB31)
90
91config ATH6KL_CONFIG_GPIO_BT_RESET
92 bool "Configure BT Reset GPIO"
93 depends on ATH6KL_HCI_BRIDGE
94 help
95 Configure a WLAN GPIO for use with BT.
96
97config AR600x_BT_RESET_PIN
98 int "GPIO"
99 depends on ATH6KL_CONFIG_GPIO_BT_RESET
100 default 22
101 help
102 WLAN GPIO to be used for resetting BT
103
104config ATH6KL_HTC_RAW_INTERFACE
105 bool "RAW HTC support"
106 depends on ATH6K_LEGACY
107 help
108 Enables raw HTC interface. Allows application to directly talk to the HTC interface via the ioctl interface
109
110config ATH6KL_VIRTUAL_SCATTER_GATHER
111 bool "Virtual Scatter-Gather support"
112 depends on ATH6K_LEGACY
113 help
114 Enables virtual scatter gather support for the hardware that does not support it natively.
115
116config ATH6KL_SKIP_ABI_VERSION_CHECK
117 bool "Skip ABI version check support"
118 depends on ATH6K_LEGACY
119 help
120 Forces the driver to disable ABI version check. Caution: Incompatilbity between the host driver and target firmware may lead to unknown side effects.
121
122config ATH6KL_BT_UART_FC_POLARITY
123 int "UART Flow Control Polarity"
124 depends on ATH6KL_LEGACY
125 default 0
126 help
127 Configures the polarity of UART Flow Control. A value of 0 implies active low and is the default setting. Set it to 1 for active high.
128
129config ATH6KL_DEBUG
130 bool "Debug support"
131 depends on ATH6K_LEGACY
132 help
133 Enables debug support
134
135config ATH6KL_ENABLE_HOST_DEBUG
136 bool "Host Debug support"
137 depends on ATH6KL_DEBUG
138 help
139 Enables debug support in the driver
140
141config ATH6KL_ENABLE_TARGET_DEBUG_PRINTS
142 bool "Target Debug support - Enable UART prints"
143 depends on ATH6KL_DEBUG
144 help
145 Enables uart prints
146
147config AR600x_DEBUG_UART_TX_PIN
148 int "GPIO"
149 depends on ATH6KL_ENABLE_TARGET_DEBUG_PRINTS
150 default 8
151 help
152 WLAN GPIO to be used for Debug UART (Tx)
153
154config ATH6KL_DISABLE_TARGET_DBGLOGS
155 bool "Target Debug support - Disable Debug logs"
156 depends on ATH6KL_DEBUG
157 help
158 Enables debug logs
diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile
new file mode 100644
index 00000000000..1d3f2390a17
--- /dev/null
+++ b/drivers/staging/ath6kl/Makefile
@@ -0,0 +1,122 @@
1#------------------------------------------------------------------------------
2# Copyright (c) 2004-2010 Atheros Communications Inc.
3# All rights reserved.
4#
5#
6#
7# Permission to use, copy, modify, and/or distribute this software for any
8# purpose with or without fee is hereby granted, provided that the above
9# copyright notice and this permission notice appear in all copies.
10#
11# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18#
19#
20#
21# Author(s): ="Atheros"
22#------------------------------------------------------------------------------
23
24ccflags-y += -I$(obj)/include
25ccflags-y += -I$(obj)/include/common
26ccflags-y += -I$(obj)/wlan/include
27ccflags-y += -I$(obj)/os/linux/include
28ccflags-y += -I$(obj)/os
29ccflags-y += -I$(obj)/bmi/include
30ccflags-y += -I$(obj)/include/common/AR6002/hw4.0
31
32ifeq ($(CONFIG_AR600x_DUAL_ANTENNA),y)
33ccflags-y += -DAR600x_DUAL_ANTENNA
34endif
35
36ifeq ($(CONFIG_AR600x_SINGLE_ANTENNA),y)
37ccflags-y += -DAR600x_SINGLE_ANTENNA
38endif
39
40ifeq ($(CONFIG_AR600x_BT_QCOM),y)
41ccflags-y += -DAR600x_BT_QCOM
42endif
43
44ifeq ($(CONFIG_AR600x_BT_CSR),y)
45ccflags-y += -DAR600x_BT_CSR
46endif
47
48ifeq ($(CONFIG_AR600x_BT_AR3001),y)
49ccflags-y += -DAR600x_BT_AR3001
50endif
51
52ifeq ($(CONFIG_ATH6KL_HCI_BRIDGE),y)
53ccflags-y += -DATH_AR6K_ENABLE_GMBOX
54ccflags-y += -DHCI_TRANSPORT_SDIO
55ccflags-y += -DSETUPHCI_ENABLED
56ccflags-y += -DSETUPBTDEV_ENABLED
57ath6kl-y += htc2/AR6000/ar6k_gmbox.o
58ath6kl-y += htc2/AR6000/ar6k_gmbox_hciuart.o
59ath6kl-y += miscdrv/ar3kconfig.o
60ath6kl-y += miscdrv/ar3kps/ar3kpsconfig.o
61ath6kl-y += miscdrv/ar3kps/ar3kpsparser.o
62endif
63
64ifeq ($(CONFIG_ATH6KL_CONFIG_GPIO_BT_RESET),y)
65ccflags-y += -DATH6KL_CONFIG_GPIO_BT_RESET
66endif
67
68ifeq ($(CONFIG_ATH6KL_HTC_RAW_INTERFACE),y)
69ccflags-y += -DHTC_RAW_INTERFACE
70endif
71
72ifeq ($(CONFIG_ATH6KL_ENABLE_HOST_DEBUG),y)
73ccflags-y += -DDEBUG
74ccflags-y += -DATH_DEBUG_MODULE
75endif
76
77ifeq ($(CONFIG_ATH6KL_ENABLE_TARGET_DEBUG_PRINTS),y)
78ccflags-y += -DENABLEUARTPRINT_SET
79endif
80
81ifeq ($(CONFIG_ATH6KL_DISABLE_TARGET_DBGLOGS),y)
82ccflags-y += -DATH6KL_DISABLE_TARGET_DBGLOGS
83endif
84
85ifeq ($(CONFIG_ATH6KL_VIRTUAL_SCATTER_GATHER),y)
86ccflags-y += -DATH6KL_CONFIG_HIF_VIRTUAL_SCATTER
87endif
88
89ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y)
90ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK
91endif
92
93ccflags-y += -DWAPI_ENABLE
94ccflags-y += -DCHECKSUM_OFFLOAD
95
96obj-$(CONFIG_ATH6K_LEGACY) := ath6kl.o
97ath6kl-y += htc2/AR6000/ar6k.o
98ath6kl-y += htc2/AR6000/ar6k_events.o
99ath6kl-y += htc2/htc_send.o
100ath6kl-y += htc2/htc_recv.o
101ath6kl-y += htc2/htc_services.o
102ath6kl-y += htc2/htc.o
103ath6kl-y += bmi/src/bmi.o
104ath6kl-y += os/linux/cfg80211.o
105ath6kl-y += os/linux/ar6000_drv.o
106ath6kl-y += os/linux/ar6000_raw_if.o
107ath6kl-y += os/linux/ar6000_pm.o
108ath6kl-y += os/linux/netbuf.o
109ath6kl-y += os/linux/hci_bridge.o
110ath6kl-y += miscdrv/common_drv.o
111ath6kl-y += miscdrv/credit_dist.o
112ath6kl-y += wmi/wmi.o
113ath6kl-y += reorder/rcv_aggr.o
114ath6kl-y += wlan/src/wlan_node.o
115ath6kl-y += wlan/src/wlan_recv_beacon.o
116ath6kl-y += wlan/src/wlan_utils.o
117
118# ATH_HIF_TYPE := sdio
119ccflags-y += -I$(obj)/hif/sdio/linux_sdio/include
120ccflags-y += -DSDIO
121ath6kl-y += hif/sdio/linux_sdio/src/hif.o
122ath6kl-y += hif/sdio/linux_sdio/src/hif_scatter.o
diff --git a/drivers/staging/ath6kl/TODO b/drivers/staging/ath6kl/TODO
new file mode 100644
index 00000000000..7be4b46ebb5
--- /dev/null
+++ b/drivers/staging/ath6kl/TODO
@@ -0,0 +1,25 @@
1TODO:
2
3We are working hard on cleaning up the driver. There's sooooooooo much todo
4so instead of editing this file please use the wiki:
5
6http://wireless.kernel.org/en/users/Drivers/ath6kl
7
8There's a respective TODO page there. Please also subscribe to the wiki page
9to get e-mail updates on changes.
10
11IRC:
12
13We *really* need to coordinate development for ath6kl as the cleanup
14patches will break pretty much any other patches. Please use IRC to
15help coordinate better:
16
17irc.freenode.net
18#ath6kl
19
20Send patches to:
21
22 - Greg Kroah-Hartman <greg@kroah.com>
23 - Luis R. Rodriguez <mcgrof@gmail.com>
24 - Joe Perches <joe@perches.com>
25 - Naveen Singh <nsingh@atheros.com>
diff --git a/drivers/staging/ath6kl/bmi/include/bmi_internal.h b/drivers/staging/ath6kl/bmi/include/bmi_internal.h
new file mode 100644
index 00000000000..8e2577074d6
--- /dev/null
+++ b/drivers/staging/ath6kl/bmi/include/bmi_internal.h
@@ -0,0 +1,54 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21//
22// Author(s): ="Atheros"
23//==============================================================================
24#ifndef BMI_INTERNAL_H
25#define BMI_INTERNAL_H
26
27#include "a_config.h"
28#include "athdefs.h"
29#include "a_osapi.h"
30#define ATH_MODULE_NAME bmi
31#include "a_debug.h"
32#include "hw/mbox_host_reg.h"
33#include "bmi_msg.h"
34
35#define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0)
36
37
38#define BMI_COMMUNICATION_TIMEOUT 100000
39
40/* ------ Global Variable Declarations ------- */
41static bool bmiDone;
42
43int
44bmiBufferSend(struct hif_device *device,
45 u8 *buffer,
46 u32 length);
47
48int
49bmiBufferReceive(struct hif_device *device,
50 u8 *buffer,
51 u32 length,
52 bool want_timeout);
53
54#endif
diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c
new file mode 100644
index 00000000000..f1f085eba9c
--- /dev/null
+++ b/drivers/staging/ath6kl/bmi/src/bmi.c
@@ -0,0 +1,1010 @@
1//------------------------------------------------------------------------------
2// <copyright file="bmi.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25
26#ifdef THREAD_X
27#include <string.h>
28#endif
29
30#include "hif.h"
31#include "bmi.h"
32#include "htc_api.h"
33#include "bmi_internal.h"
34
35#ifdef ATH_DEBUG_MODULE
36static struct ath_debug_mask_description bmi_debug_desc[] = {
37 { ATH_DEBUG_BMI , "BMI Tracing"},
38};
39
40ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
41 "bmi",
42 "Boot Manager Interface",
43 ATH_DEBUG_MASK_DEFAULTS,
44 ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
45 bmi_debug_desc);
46
47#endif
48
49/*
50Although we had envisioned BMI to run on top of HTC, this is not how the
51final implementation ended up. On the Target side, BMI is a part of the BSP
52and does not use the HTC protocol nor even DMA -- it is intentionally kept
53very simple.
54*/
55
56static bool pendingEventsFuncCheck = false;
57static u32 *pBMICmdCredits;
58static u8 *pBMICmdBuf;
59#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
60 sizeof(u32) /* cmd */ + \
61 sizeof(u32) /* addr */ + \
62 sizeof(u32))/* length */
63#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ)
64
65/* APIs visible to the driver */
66void
67BMIInit(void)
68{
69 bmiDone = false;
70 pendingEventsFuncCheck = false;
71
72 /*
73 * On some platforms, it's not possible to DMA to a static variable
74 * in a device driver (e.g. Linux loadable driver module).
75 * So we need to A_MALLOC space for "command credits" and for commands.
76 *
77 * Note: implicitly relies on A_MALLOC to provide a buffer that is
78 * suitable for DMA (or PIO). This buffer will be passed down the
79 * bus stack.
80 */
81 if (!pBMICmdCredits) {
82 pBMICmdCredits = (u32 *)A_MALLOC_NOWAIT(4);
83 A_ASSERT(pBMICmdCredits);
84 }
85
86 if (!pBMICmdBuf) {
87 pBMICmdBuf = (u8 *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ);
88 A_ASSERT(pBMICmdBuf);
89 }
90
91 A_REGISTER_MODULE_DEBUG_INFO(bmi);
92}
93
94void
95BMICleanup(void)
96{
97 if (pBMICmdCredits) {
98 kfree(pBMICmdCredits);
99 pBMICmdCredits = NULL;
100 }
101
102 if (pBMICmdBuf) {
103 kfree(pBMICmdBuf);
104 pBMICmdBuf = NULL;
105 }
106}
107
108int
109BMIDone(struct hif_device *device)
110{
111 int status;
112 u32 cid;
113
114 if (bmiDone) {
115 AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n"));
116 return 0;
117 }
118
119 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device));
120 bmiDone = true;
121 cid = BMI_DONE;
122
123 status = bmiBufferSend(device, (u8 *)&cid, sizeof(cid));
124 if (status) {
125 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
126 return A_ERROR;
127 }
128
129 if (pBMICmdCredits) {
130 kfree(pBMICmdCredits);
131 pBMICmdCredits = NULL;
132 }
133
134 if (pBMICmdBuf) {
135 kfree(pBMICmdBuf);
136 pBMICmdBuf = NULL;
137 }
138
139 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n"));
140
141 return 0;
142}
143
144int
145BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info)
146{
147 int status;
148 u32 cid;
149
150 if (bmiDone) {
151 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
152 return A_ERROR;
153 }
154
155 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device));
156 cid = BMI_GET_TARGET_INFO;
157
158 status = bmiBufferSend(device, (u8 *)&cid, sizeof(cid));
159 if (status) {
160 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
161 return A_ERROR;
162 }
163
164 status = bmiBufferReceive(device, (u8 *)&targ_info->target_ver,
165 sizeof(targ_info->target_ver), true);
166 if (status) {
167 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n"));
168 return A_ERROR;
169 }
170
171 if (targ_info->target_ver == TARGET_VERSION_SENTINAL) {
172 /* Determine how many bytes are in the Target's targ_info */
173 status = bmiBufferReceive(device, (u8 *)&targ_info->target_info_byte_count,
174 sizeof(targ_info->target_info_byte_count), true);
175 if (status) {
176 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n"));
177 return A_ERROR;
178 }
179
180 /*
181 * The Target's targ_info doesn't match the Host's targ_info.
182 * We need to do some backwards compatibility work to make this OK.
183 */
184 A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info));
185
186 /* Read the remainder of the targ_info */
187 status = bmiBufferReceive(device,
188 ((u8 *)targ_info)+sizeof(targ_info->target_info_byte_count),
189 sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), true);
190 if (status) {
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n",
192 targ_info->target_info_byte_count));
193 return A_ERROR;
194 }
195 }
196
197 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n",
198 targ_info->target_ver, targ_info->target_type));
199
200 return 0;
201}
202
203int
204BMIReadMemory(struct hif_device *device,
205 u32 address,
206 u8 *buffer,
207 u32 length)
208{
209 u32 cid;
210 int status;
211 u32 offset;
212 u32 remaining, rxlen;
213
214 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)));
215 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length));
216
217 if (bmiDone) {
218 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
219 return A_ERROR;
220 }
221
222 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
223 ("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
224 device, address, length));
225
226 cid = BMI_READ_MEMORY;
227
228 remaining = length;
229
230 while (remaining)
231 {
232 rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX;
233 offset = 0;
234 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
235 offset += sizeof(cid);
236 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
237 offset += sizeof(address);
238 memcpy(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen));
239 offset += sizeof(length);
240
241 status = bmiBufferSend(device, pBMICmdBuf, offset);
242 if (status) {
243 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
244 return A_ERROR;
245 }
246 status = bmiBufferReceive(device, pBMICmdBuf, rxlen, true);
247 if (status) {
248 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
249 return A_ERROR;
250 }
251 memcpy(&buffer[length - remaining], pBMICmdBuf, rxlen);
252 remaining -= rxlen; address += rxlen;
253 }
254
255 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n"));
256 return 0;
257}
258
259int
260BMIWriteMemory(struct hif_device *device,
261 u32 address,
262 u8 *buffer,
263 u32 length)
264{
265 u32 cid;
266 int status;
267 u32 offset;
268 u32 remaining, txlen;
269 const u32 header = sizeof(cid) + sizeof(address) + sizeof(length);
270 u8 alignedBuffer[BMI_DATASZ_MAX];
271 u8 *src;
272
273 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
274 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header);
275
276 if (bmiDone) {
277 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
278 return A_ERROR;
279 }
280
281 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
282 ("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
283 device, address, length));
284
285 cid = BMI_WRITE_MEMORY;
286
287 remaining = length;
288 while (remaining)
289 {
290 src = &buffer[length - remaining];
291 if (remaining < (BMI_DATASZ_MAX - header)) {
292 if (remaining & 3) {
293 /* align it with 4 bytes */
294 remaining = remaining + (4 - (remaining & 3));
295 memcpy(alignedBuffer, src, remaining);
296 src = alignedBuffer;
297 }
298 txlen = remaining;
299 } else {
300 txlen = (BMI_DATASZ_MAX - header);
301 }
302 offset = 0;
303 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
304 offset += sizeof(cid);
305 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
306 offset += sizeof(address);
307 memcpy(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
308 offset += sizeof(txlen);
309 memcpy(&(pBMICmdBuf[offset]), src, txlen);
310 offset += txlen;
311 status = bmiBufferSend(device, pBMICmdBuf, offset);
312 if (status) {
313 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
314 return A_ERROR;
315 }
316 remaining -= txlen; address += txlen;
317 }
318
319 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n"));
320
321 return 0;
322}
323
324int
325BMIExecute(struct hif_device *device,
326 u32 address,
327 u32 *param)
328{
329 u32 cid;
330 int status;
331 u32 offset;
332
333 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
334 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
335
336 if (bmiDone) {
337 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
338 return A_ERROR;
339 }
340
341 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
342 ("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
343 device, address, *param));
344
345 cid = BMI_EXECUTE;
346
347 offset = 0;
348 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
349 offset += sizeof(cid);
350 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
351 offset += sizeof(address);
352 memcpy(&(pBMICmdBuf[offset]), param, sizeof(*param));
353 offset += sizeof(*param);
354 status = bmiBufferSend(device, pBMICmdBuf, offset);
355 if (status) {
356 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
357 return A_ERROR;
358 }
359
360 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), false);
361 if (status) {
362 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
363 return A_ERROR;
364 }
365
366 memcpy(param, pBMICmdBuf, sizeof(*param));
367
368 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param));
369 return 0;
370}
371
372int
373BMISetAppStart(struct hif_device *device,
374 u32 address)
375{
376 u32 cid;
377 int status;
378 u32 offset;
379
380 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
381 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
382
383 if (bmiDone) {
384 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
385 return A_ERROR;
386 }
387
388 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
389 ("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n",
390 device, address));
391
392 cid = BMI_SET_APP_START;
393
394 offset = 0;
395 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
396 offset += sizeof(cid);
397 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
398 offset += sizeof(address);
399 status = bmiBufferSend(device, pBMICmdBuf, offset);
400 if (status) {
401 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
402 return A_ERROR;
403 }
404
405 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n"));
406 return 0;
407}
408
409int
410BMIReadSOCRegister(struct hif_device *device,
411 u32 address,
412 u32 *param)
413{
414 u32 cid;
415 int status;
416 u32 offset;
417
418 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
419 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
420
421 if (bmiDone) {
422 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
423 return A_ERROR;
424 }
425
426 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
427 ("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n",
428 device, address));
429
430 cid = BMI_READ_SOC_REGISTER;
431
432 offset = 0;
433 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
434 offset += sizeof(cid);
435 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
436 offset += sizeof(address);
437
438 status = bmiBufferSend(device, pBMICmdBuf, offset);
439 if (status) {
440 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
441 return A_ERROR;
442 }
443
444 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), true);
445 if (status) {
446 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
447 return A_ERROR;
448 }
449 memcpy(param, pBMICmdBuf, sizeof(*param));
450
451 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param));
452 return 0;
453}
454
455int
456BMIWriteSOCRegister(struct hif_device *device,
457 u32 address,
458 u32 param)
459{
460 u32 cid;
461 int status;
462 u32 offset;
463
464 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
465 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
466
467 if (bmiDone) {
468 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
469 return A_ERROR;
470 }
471
472 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
473 ("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
474 device, address, param));
475
476 cid = BMI_WRITE_SOC_REGISTER;
477
478 offset = 0;
479 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
480 offset += sizeof(cid);
481 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
482 offset += sizeof(address);
483 memcpy(&(pBMICmdBuf[offset]), &param, sizeof(param));
484 offset += sizeof(param);
485 status = bmiBufferSend(device, pBMICmdBuf, offset);
486 if (status) {
487 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
488 return A_ERROR;
489 }
490
491 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n"));
492 return 0;
493}
494
495int
496BMIrompatchInstall(struct hif_device *device,
497 u32 ROM_addr,
498 u32 RAM_addr,
499 u32 nbytes,
500 u32 do_activate,
501 u32 *rompatch_id)
502{
503 u32 cid;
504 int status;
505 u32 offset;
506
507 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
508 sizeof(nbytes) + sizeof(do_activate)));
509 memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
510 sizeof(nbytes) + sizeof(do_activate));
511
512 if (bmiDone) {
513 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
514 return A_ERROR;
515 }
516
517 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
518 ("BMI rompatch Install: Enter (device: 0x%p, ROMaddr: 0x%x, RAMaddr: 0x%x length: %d activate: %d)\n",
519 device, ROM_addr, RAM_addr, nbytes, do_activate));
520
521 cid = BMI_ROMPATCH_INSTALL;
522
523 offset = 0;
524 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
525 offset += sizeof(cid);
526 memcpy(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr));
527 offset += sizeof(ROM_addr);
528 memcpy(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr));
529 offset += sizeof(RAM_addr);
530 memcpy(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes));
531 offset += sizeof(nbytes);
532 memcpy(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate));
533 offset += sizeof(do_activate);
534 status = bmiBufferSend(device, pBMICmdBuf, offset);
535 if (status) {
536 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
537 return A_ERROR;
538 }
539
540 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), true);
541 if (status) {
542 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
543 return A_ERROR;
544 }
545 memcpy(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id));
546
547 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id));
548 return 0;
549}
550
551int
552BMIrompatchUninstall(struct hif_device *device,
553 u32 rompatch_id)
554{
555 u32 cid;
556 int status;
557 u32 offset;
558
559 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(rompatch_id)));
560 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(rompatch_id));
561
562 if (bmiDone) {
563 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
564 return A_ERROR;
565 }
566
567 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
568 ("BMI rompatch Uninstall: Enter (device: 0x%p, rompatch_id: %d)\n",
569 device, rompatch_id));
570
571 cid = BMI_ROMPATCH_UNINSTALL;
572
573 offset = 0;
574 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
575 offset += sizeof(cid);
576 memcpy(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id));
577 offset += sizeof(rompatch_id);
578 status = bmiBufferSend(device, pBMICmdBuf, offset);
579 if (status) {
580 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
581 return A_ERROR;
582 }
583
584 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\n", rompatch_id));
585 return 0;
586}
587
588static int
589_BMIrompatchChangeActivation(struct hif_device *device,
590 u32 rompatch_count,
591 u32 *rompatch_list,
592 u32 do_activate)
593{
594 u32 cid;
595 int status;
596 u32 offset;
597 u32 length;
598
599 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)));
600 memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count));
601
602 if (bmiDone) {
603 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
604 return A_ERROR;
605 }
606
607 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
608 ("BMI Change rompatch Activation: Enter (device: 0x%p, count: %d)\n",
609 device, rompatch_count));
610
611 cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE;
612
613 offset = 0;
614 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
615 offset += sizeof(cid);
616 memcpy(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count));
617 offset += sizeof(rompatch_count);
618 length = rompatch_count * sizeof(*rompatch_list);
619 memcpy(&(pBMICmdBuf[offset]), rompatch_list, length);
620 offset += length;
621 status = bmiBufferSend(device, pBMICmdBuf, offset);
622 if (status) {
623 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
624 return A_ERROR;
625 }
626
627 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n"));
628
629 return 0;
630}
631
632int
633BMIrompatchActivate(struct hif_device *device,
634 u32 rompatch_count,
635 u32 *rompatch_list)
636{
637 return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1);
638}
639
640int
641BMIrompatchDeactivate(struct hif_device *device,
642 u32 rompatch_count,
643 u32 *rompatch_list)
644{
645 return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0);
646}
647
648int
649BMILZData(struct hif_device *device,
650 u8 *buffer,
651 u32 length)
652{
653 u32 cid;
654 int status;
655 u32 offset;
656 u32 remaining, txlen;
657 const u32 header = sizeof(cid) + sizeof(length);
658
659 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header));
660 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header);
661
662 if (bmiDone) {
663 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
664 return A_ERROR;
665 }
666
667 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
668 ("BMI Send LZ Data: Enter (device: 0x%p, length: %d)\n",
669 device, length));
670
671 cid = BMI_LZ_DATA;
672
673 remaining = length;
674 while (remaining)
675 {
676 txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
677 remaining : (BMI_DATASZ_MAX - header);
678 offset = 0;
679 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
680 offset += sizeof(cid);
681 memcpy(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
682 offset += sizeof(txlen);
683 memcpy(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen);
684 offset += txlen;
685 status = bmiBufferSend(device, pBMICmdBuf, offset);
686 if (status) {
687 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
688 return A_ERROR;
689 }
690 remaining -= txlen;
691 }
692
693 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n"));
694
695 return 0;
696}
697
698int
699BMILZStreamStart(struct hif_device *device,
700 u32 address)
701{
702 u32 cid;
703 int status;
704 u32 offset;
705
706 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
707 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
708
709 if (bmiDone) {
710 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
711 return A_ERROR;
712 }
713
714 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
715 ("BMI LZ Stream Start: Enter (device: 0x%p, address: 0x%x)\n",
716 device, address));
717
718 cid = BMI_LZ_STREAM_START;
719 offset = 0;
720 memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
721 offset += sizeof(cid);
722 memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
723 offset += sizeof(address);
724 status = bmiBufferSend(device, pBMICmdBuf, offset);
725 if (status) {
726 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device\n"));
727 return A_ERROR;
728 }
729
730 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n"));
731
732 return 0;
733}
734
735/* BMI Access routines */
736int
737bmiBufferSend(struct hif_device *device,
738 u8 *buffer,
739 u32 length)
740{
741 int status;
742 u32 timeout;
743 u32 address;
744 u32 mboxAddress[HTC_MAILBOX_NUM_MAX];
745
746 HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
747 &mboxAddress[0], sizeof(mboxAddress));
748
749 *pBMICmdCredits = 0;
750 timeout = BMI_COMMUNICATION_TIMEOUT;
751
752 while(timeout-- && !(*pBMICmdCredits)) {
753 /* Read the counter register to get the command credits */
754 address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
755 /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause
756 * a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to
757 * make all HIF accesses 4-byte aligned */
758 status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, 4,
759 HIF_RD_SYNC_BYTE_INC, NULL);
760 if (status) {
761 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n"));
762 return A_ERROR;
763 }
764 /* the counter is only 8=bits, ignore anything in the upper 3 bytes */
765 (*pBMICmdCredits) &= 0xFF;
766 }
767
768 if (*pBMICmdCredits) {
769 address = mboxAddress[ENDPOINT1];
770 status = HIFReadWrite(device, address, buffer, length,
771 HIF_WR_SYNC_BYTE_INC, NULL);
772 if (status) {
773 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n"));
774 return A_ERROR;
775 }
776 } else {
777 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferSend\n"));
778 return A_ERROR;
779 }
780
781 return status;
782}
783
784int
785bmiBufferReceive(struct hif_device *device,
786 u8 *buffer,
787 u32 length,
788 bool want_timeout)
789{
790 int status;
791 u32 address;
792 u32 mboxAddress[HTC_MAILBOX_NUM_MAX];
793 struct hif_pending_events_info hifPendingEvents;
794 static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL;
795
796 if (!pendingEventsFuncCheck) {
797 /* see if the HIF layer implements an alternative function to get pending events
798 * do this only once! */
799 HIFConfigureDevice(device,
800 HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
801 &getPendingEventsFunc,
802 sizeof(getPendingEventsFunc));
803 pendingEventsFuncCheck = true;
804 }
805
806 HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
807 &mboxAddress[0], sizeof(mboxAddress));
808
809 /*
810 * During normal bootup, small reads may be required.
811 * Rather than issue an HIF Read and then wait as the Target
812 * adds successive bytes to the FIFO, we wait here until
813 * we know that response data is available.
814 *
815 * This allows us to cleanly timeout on an unexpected
816 * Target failure rather than risk problems at the HIF level. In
817 * particular, this avoids SDIO timeouts and possibly garbage
818 * data on some host controllers. And on an interconnect
819 * such as Compact Flash (as well as some SDIO masters) which
820 * does not provide any indication on data timeout, it avoids
821 * a potential hang or garbage response.
822 *
823 * Synchronization is more difficult for reads larger than the
824 * size of the MBOX FIFO (128B), because the Target is unable
825 * to push the 129th byte of data until AFTER the Host posts an
826 * HIF Read and removes some FIFO data. So for large reads the
827 * Host proceeds to post an HIF Read BEFORE all the data is
828 * actually available to read. Fortunately, large BMI reads do
829 * not occur in practice -- they're supported for debug/development.
830 *
831 * So Host/Target BMI synchronization is divided into these cases:
832 * CASE 1: length < 4
833 * Should not happen
834 *
835 * CASE 2: 4 <= length <= 128
836 * Wait for first 4 bytes to be in FIFO
837 * If CONSERVATIVE_BMI_READ is enabled, also wait for
838 * a BMI command credit, which indicates that the ENTIRE
839 * response is available in the the FIFO
840 *
841 * CASE 3: length > 128
842 * Wait for the first 4 bytes to be in FIFO
843 *
844 * For most uses, a small timeout should be sufficient and we will
845 * usually see a response quickly; but there may be some unusual
846 * (debug) cases of BMI_EXECUTE where we want an larger timeout.
847 * For now, we use an unbounded busy loop while waiting for
848 * BMI_EXECUTE.
849 *
850 * If BMI_EXECUTE ever needs to support longer-latency execution,
851 * especially in production, this code needs to be enhanced to sleep
852 * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
853 * a function of Host processor speed.
854 */
855 if (length >= 4) { /* NB: Currently, always true */
856 /*
857 * NB: word_available is declared static for esoteric reasons
858 * having to do with protection on some OSes.
859 */
860 static u32 word_available;
861 u32 timeout;
862
863 word_available = 0;
864 timeout = BMI_COMMUNICATION_TIMEOUT;
865 while((!want_timeout || timeout--) && !word_available) {
866
867 if (getPendingEventsFunc != NULL) {
868 status = getPendingEventsFunc(device,
869 &hifPendingEvents,
870 NULL);
871 if (status) {
872 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending events \n"));
873 break;
874 }
875
876 if (hifPendingEvents.AvailableRecvBytes >= sizeof(u32)) {
877 word_available = 1;
878 }
879 continue;
880 }
881
882 status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (u8 *)&word_available,
883 sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL);
884 if (status) {
885 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VALID register\n"));
886 return A_ERROR;
887 }
888 /* We did a 4-byte read to the same register; all we really want is one bit */
889 word_available &= (1 << ENDPOINT1);
890 }
891
892 if (!word_available) {
893 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferReceive FIFO empty\n"));
894 return A_ERROR;
895 }
896 }
897
898#define CONSERVATIVE_BMI_READ 0
899#if CONSERVATIVE_BMI_READ
900 /*
901 * This is an extra-conservative CREDIT check. It guarantees
902 * that ALL data is available in the FIFO before we start to
903 * read from the interconnect.
904 *
905 * This credit check is useless when firmware chooses to
906 * allow multiple outstanding BMI Command Credits, since the next
907 * credit will already be present. To restrict the Target to one
908 * BMI Command Credit, see HI_OPTION_BMI_CRED_LIMIT.
909 *
910 * And for large reads (when HI_OPTION_BMI_CRED_LIMIT is set)
911 * we cannot wait for the next credit because the Target's FIFO
912 * will not hold the entire response. So we need the Host to
913 * start to empty the FIFO sooner. (And again, large reads are
914 * not used in practice; they are for debug/development only.)
915 *
916 * For a more conservative Host implementation (which would be
917 * safer for a Compact Flash interconnect):
918 * Set CONSERVATIVE_BMI_READ (above) to 1
919 * Set HI_OPTION_BMI_CRED_LIMIT and
920 * reduce BMI_DATASZ_MAX to 32 or 64
921 */
922 if ((length > 4) && (length < 128)) { /* check against MBOX FIFO size */
923 u32 timeout;
924
925 *pBMICmdCredits = 0;
926 timeout = BMI_COMMUNICATION_TIMEOUT;
927 while((!want_timeout || timeout--) && !(*pBMICmdCredits) {
928 /* Read the counter register to get the command credits */
929 address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;
930 /* read the counter using a 4-byte read. Since the counter is NOT auto-decrementing,
931 * we can read this counter multiple times using a non-incrementing address mode.
932 * The rationale here is to make all HIF accesses a multiple of 4 bytes */
933 status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, sizeof(*pBMICmdCredits),
934 HIF_RD_SYNC_BYTE_FIX, NULL);
935 if (status) {
936 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n"));
937 return A_ERROR;
938 }
939 /* we did a 4-byte read to the same count register so mask off upper bytes */
940 (*pBMICmdCredits) &= 0xFF;
941 }
942
943 if (!(*pBMICmdCredits)) {
944 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout- bmiBufferReceive no credit\n"));
945 return A_ERROR;
946 }
947 }
948#endif
949
950 address = mboxAddress[ENDPOINT1];
951 status = HIFReadWrite(device, address, buffer, length, HIF_RD_SYNC_BYTE_INC, NULL);
952 if (status) {
953 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n"));
954 return A_ERROR;
955 }
956
957 return 0;
958}
959
960int
961BMIFastDownload(struct hif_device *device, u32 address, u8 *buffer, u32 length)
962{
963 int status = A_ERROR;
964 u32 lastWord = 0;
965 u32 lastWordOffset = length & ~0x3;
966 u32 unalignedBytes = length & 0x3;
967
968 status = BMILZStreamStart (device, address);
969 if (status) {
970 return A_ERROR;
971 }
972
973 if (unalignedBytes) {
974 /* copy the last word into a zero padded buffer */
975 memcpy(&lastWord, &buffer[lastWordOffset], unalignedBytes);
976 }
977
978 status = BMILZData(device, buffer, lastWordOffset);
979
980 if (status) {
981 return A_ERROR;
982 }
983
984 if (unalignedBytes) {
985 status = BMILZData(device, (u8 *)&lastWord, 4);
986 }
987
988 if (!status) {
989 //
990 // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches.
991 //
992 status = BMILZStreamStart (device, 0x00);
993 if (status) {
994 return A_ERROR;
995 }
996 }
997 return status;
998}
999
1000int
1001BMIRawWrite(struct hif_device *device, u8 *buffer, u32 length)
1002{
1003 return bmiBufferSend(device, buffer, length);
1004}
1005
1006int
1007BMIRawRead(struct hif_device *device, u8 *buffer, u32 length, bool want_timeout)
1008{
1009 return bmiBufferReceive(device, buffer, length, want_timeout);
1010}
diff --git a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h
new file mode 100644
index 00000000000..93a2adceca3
--- /dev/null
+++ b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h
@@ -0,0 +1,87 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// common header file for HIF modules designed for SDIO
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#ifndef HIF_SDIO_COMMON_H_
26#define HIF_SDIO_COMMON_H_
27
28 /* SDIO manufacturer ID and Codes */
29#define MANUFACTURER_ID_AR6002_BASE 0x200
30#define MANUFACTURER_ID_AR6003_BASE 0x300
31#define MANUFACTURER_ID_AR6K_BASE_MASK 0xFF00
32#define FUNCTION_CLASS 0x0
33#define MANUFACTURER_CODE 0x271 /* Atheros */
34
35 /* Mailbox address in SDIO address space */
36#define HIF_MBOX_BASE_ADDR 0x800
37#define HIF_MBOX_WIDTH 0x800
38#define HIF_MBOX_START_ADDR(mbox) \
39 ( HIF_MBOX_BASE_ADDR + mbox * HIF_MBOX_WIDTH)
40
41#define HIF_MBOX_END_ADDR(mbox) \
42 (HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1)
43
44 /* extended MBOX address for larger MBOX writes to MBOX 0*/
45#define HIF_MBOX0_EXTENDED_BASE_ADDR 0x2800
46#define HIF_MBOX0_EXTENDED_WIDTH_AR6002 (6*1024)
47#define HIF_MBOX0_EXTENDED_WIDTH_AR6003 (18*1024)
48
49 /* version 1 of the chip has only a 12K extended mbox range */
50#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1 0x4000
51#define HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1 (12*1024)
52
53 /* GMBOX addresses */
54#define HIF_GMBOX_BASE_ADDR 0x7000
55#define HIF_GMBOX_WIDTH 0x4000
56
57 /* for SDIO we recommend a 128-byte block size */
58#define HIF_DEFAULT_IO_BLOCK_SIZE 128
59
60 /* set extended MBOX window information for SDIO interconnects */
61static INLINE void SetExtendedMboxWindowInfo(u16 Manfid, struct hif_device_mbox_info *pInfo)
62{
63 switch (Manfid & MANUFACTURER_ID_AR6K_BASE_MASK) {
64 case MANUFACTURER_ID_AR6002_BASE :
65 /* MBOX 0 has an extended range */
66 pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR;
67 pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6002;
68 break;
69 case MANUFACTURER_ID_AR6003_BASE :
70 /* MBOX 0 has an extended range */
71 pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1;
72 pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1;
73 pInfo->GMboxAddress = HIF_GMBOX_BASE_ADDR;
74 pInfo->GMboxSize = HIF_GMBOX_WIDTH;
75 break;
76 default:
77 A_ASSERT(false);
78 break;
79 }
80}
81
82/* special CCCR (func 0) registers */
83
84#define CCCR_SDIO_IRQ_MODE_REG 0xF0 /* interrupt mode register */
85#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ (1 << 0) /* mode to enable special 4-bit interrupt assertion without clock*/
86
87#endif /*HIF_SDIO_COMMON_H_*/
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h
new file mode 100644
index 00000000000..ed7ad4786f5
--- /dev/null
+++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h
@@ -0,0 +1,131 @@
1//------------------------------------------------------------------------------
2// <copyright file="hif_internal.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// internal header file for hif layer
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _HIF_INTERNAL_H_
26#define _HIF_INTERNAL_H_
27
28#include "a_config.h"
29#include "athdefs.h"
30#include "a_osapi.h"
31#include "hif.h"
32#include "../../../common/hif_sdio_common.h"
33#include <linux/scatterlist.h>
34#define HIF_LINUX_MMC_SCATTER_SUPPORT
35
36#define BUS_REQUEST_MAX_NUM 64
37
38#define SDIO_CLOCK_FREQUENCY_DEFAULT 25000000
39#define SDWLAN_ENABLE_DISABLE_TIMEOUT 20
40#define FLAGS_CARD_ENAB 0x02
41#define FLAGS_CARD_IRQ_UNMSK 0x04
42
43#define HIF_MBOX_BLOCK_SIZE HIF_DEFAULT_IO_BLOCK_SIZE
44#define HIF_MBOX0_BLOCK_SIZE 1
45#define HIF_MBOX1_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
46#define HIF_MBOX2_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
47#define HIF_MBOX3_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
48
49typedef struct bus_request {
50 struct bus_request *next; /* link list of available requests */
51 struct bus_request *inusenext; /* link list of in use requests */
52 struct semaphore sem_req;
53 u32 address; /* request data */
54 u8 *buffer;
55 u32 length;
56 u32 request;
57 void *context;
58 int status;
59 struct hif_scatter_req_priv *pScatterReq; /* this request is a scatter request */
60} BUS_REQUEST;
61
62struct hif_device {
63 struct sdio_func *func;
64 spinlock_t asynclock;
65 struct task_struct* async_task; /* task to handle async commands */
66 struct semaphore sem_async; /* wake up for async task */
67 int async_shutdown; /* stop the async task */
68 struct completion async_completion; /* thread completion */
69 BUS_REQUEST *asyncreq; /* request for async tasklet */
70 BUS_REQUEST *taskreq; /* async tasklet data */
71 spinlock_t lock;
72 BUS_REQUEST *s_busRequestFreeQueue; /* free list */
73 BUS_REQUEST busRequest[BUS_REQUEST_MAX_NUM]; /* available bus requests */
74 void *claimedContext;
75 HTC_CALLBACKS htcCallbacks;
76 u8 *dma_buffer;
77 struct dl_list ScatterReqHead; /* scatter request list head */
78 bool scatter_enabled; /* scatter enabled flag */
79 bool is_suspend;
80 bool is_disabled;
81 atomic_t irqHandling;
82 HIF_DEVICE_POWER_CHANGE_TYPE powerConfig;
83 const struct sdio_device_id *id;
84};
85
86#define HIF_DMA_BUFFER_SIZE (32 * 1024)
87#define CMD53_FIXED_ADDRESS 1
88#define CMD53_INCR_ADDRESS 2
89
90BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device);
91void hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest);
92void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest);
93
94#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT
95
96#define MAX_SCATTER_REQUESTS 4
97#define MAX_SCATTER_ENTRIES_PER_REQ 16
98#define MAX_SCATTER_REQ_TRANSFER_SIZE 32*1024
99
100struct hif_scatter_req_priv {
101 struct hif_scatter_req *pHifScatterReq; /* HIF scatter request with allocated entries */
102 struct hif_device *device; /* this device */
103 BUS_REQUEST *busrequest; /* request associated with request */
104 /* scatter list for linux */
105 struct scatterlist sgentries[MAX_SCATTER_ENTRIES_PER_REQ];
106};
107
108#define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0)
109
110int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo);
111void CleanupHIFScatterResources(struct hif_device *device);
112int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest);
113
114#else // HIF_LINUX_MMC_SCATTER_SUPPORT
115
116static inline int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo)
117{
118 return A_ENOTSUP;
119}
120
121static inline int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest)
122{
123 return A_ENOTSUP;
124}
125
126#define CleanupHIFScatterResources(d) { }
127
128#endif // HIF_LINUX_MMC_SCATTER_SUPPORT
129
130#endif // _HIF_INTERNAL_H_
131
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
new file mode 100644
index 00000000000..5f5d67720fa
--- /dev/null
+++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
@@ -0,0 +1,1273 @@
1//------------------------------------------------------------------------------
2// <copyright file="hif.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// HIF layer reference implementation for Linux Native MMC stack
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include <linux/mmc/card.h>
26#include <linux/mmc/mmc.h>
27#include <linux/mmc/host.h>
28#include <linux/mmc/sdio_func.h>
29#include <linux/mmc/sdio_ids.h>
30#include <linux/mmc/sdio.h>
31#include <linux/mmc/sd.h>
32#include <linux/kthread.h>
33
34/* by default setup a bounce buffer for the data packets, if the underlying host controller driver
35 does not use DMA you may be able to skip this step and save the memory allocation and transfer time */
36#define HIF_USE_DMA_BOUNCE_BUFFER 1
37#include "hif_internal.h"
38#define ATH_MODULE_NAME hif
39#include "a_debug.h"
40#include "hw/mbox_host_reg.h"
41
42#if HIF_USE_DMA_BOUNCE_BUFFER
43/* macro to check if DMA buffer is WORD-aligned and DMA-able. Most host controllers assume the
44 * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack).
45 * virt_addr_valid check fails on stack memory.
46 */
47#define BUFFER_NEEDS_BOUNCE(buffer) (((unsigned long)(buffer) & 0x3) || !virt_addr_valid((buffer)))
48#else
49#define BUFFER_NEEDS_BOUNCE(buffer) (false)
50#endif
51
52/* ATHENV */
53#if defined(CONFIG_PM)
54#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev)
55#define to_sdio_driver(d) container_of(d, struct sdio_driver, drv)
56#endif /* CONFIG_PM */
57static void delHifDevice(struct hif_device * device);
58static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte);
59static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte);
60
61static int hifEnableFunc(struct hif_device *device, struct sdio_func *func);
62static int hifDisableFunc(struct hif_device *device, struct sdio_func *func);
63OSDRV_CALLBACKS osdrvCallbacks;
64
65int reset_sdio_on_unload = 0;
66module_param(reset_sdio_on_unload, int, 0644);
67
68extern u32 nohifscattersupport;
69
70static struct hif_device *ath6kl_alloc_hifdev(struct sdio_func *func)
71{
72 struct hif_device *hifdevice;
73
74 hifdevice = kzalloc(sizeof(struct hif_device), GFP_KERNEL);
75
76#if HIF_USE_DMA_BOUNCE_BUFFER
77 hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
78#endif
79 hifdevice->func = func;
80 hifdevice->powerConfig = HIF_DEVICE_POWER_UP;
81 sdio_set_drvdata(func, hifdevice);
82
83 return hifdevice;
84}
85
86static struct hif_device *ath6kl_get_hifdev(struct sdio_func *func)
87{
88 return (struct hif_device *) sdio_get_drvdata(func);
89}
90
91static const struct sdio_device_id ath6kl_hifdev_ids[] = {
92 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) },
93 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) },
94 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) },
95 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) },
96 { /* null */ },
97};
98
99MODULE_DEVICE_TABLE(sdio, ath6kl_hifdev_ids);
100
101static int ath6kl_hifdev_probe(struct sdio_func *func,
102 const struct sdio_device_id *id)
103{
104 int ret;
105 struct hif_device *device;
106 int count;
107
108 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
109 ("ath6kl: Function: 0x%X, Vendor ID: 0x%X, "
110 "Device ID: 0x%X, block size: 0x%X/0x%X\n",
111 func->num, func->vendor, func->device,
112 func->max_blksize, func->cur_blksize));
113
114 ath6kl_alloc_hifdev(func);
115 device = ath6kl_get_hifdev(func);
116
117 device->id = id;
118 device->is_disabled = true;
119
120 spin_lock_init(&device->lock);
121 spin_lock_init(&device->asynclock);
122
123 DL_LIST_INIT(&device->ScatterReqHead);
124
125 /* Try to allow scatter unless globally overridden */
126 if (!nohifscattersupport)
127 device->scatter_enabled = true;
128
129 A_MEMZERO(device->busRequest, sizeof(device->busRequest));
130
131 for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) {
132 sema_init(&device->busRequest[count].sem_req, 0);
133 hifFreeBusRequest(device, &device->busRequest[count]);
134 }
135
136 sema_init(&device->sem_async, 0);
137
138 ret = hifEnableFunc(device, func);
139
140 return ret;
141}
142
143static void ath6kl_hifdev_remove(struct sdio_func *func)
144{
145 int status = 0;
146 struct hif_device *device;
147
148 device = ath6kl_get_hifdev(func);
149 if (device->claimedContext != NULL)
150 status = osdrvCallbacks.
151 deviceRemovedHandler(device->claimedContext, device);
152
153 if (device->is_disabled)
154 device->is_disabled = false;
155 else
156 status = hifDisableFunc(device, func);
157
158 CleanupHIFScatterResources(device);
159
160 delHifDevice(device);
161}
162
163#if defined(CONFIG_PM)
164static int ath6kl_hifdev_suspend(struct device *dev)
165{
166 struct sdio_func *func = dev_to_sdio_func(dev);
167 int status = 0;
168 struct hif_device *device;
169
170 device = ath6kl_get_hifdev(func);
171
172 if (device && device->claimedContext &&
173 osdrvCallbacks.deviceSuspendHandler) {
174 /* set true first for PowerStateChangeNotify(..) */
175 device->is_suspend = true;
176 status = osdrvCallbacks.
177 deviceSuspendHandler(device->claimedContext);
178 if (status)
179 device->is_suspend = false;
180 }
181
182 CleanupHIFScatterResources(device);
183
184 switch (status) {
185 case 0:
186 return 0;
187 case A_EBUSY:
188 /* Hack for kernel in order to support deep sleep and wow */
189 return -EBUSY;
190 default:
191 return -1;
192 }
193}
194
195static int ath6kl_hifdev_resume(struct device *dev)
196{
197 struct sdio_func *func = dev_to_sdio_func(dev);
198 int status = 0;
199 struct hif_device *device;
200
201 device = ath6kl_get_hifdev(func);
202 if (device && device->claimedContext &&
203 osdrvCallbacks.deviceSuspendHandler) {
204 status = osdrvCallbacks.
205 deviceResumeHandler(device->claimedContext);
206 if (status == 0)
207 device->is_suspend = false;
208 }
209
210 return status;
211}
212
213static const struct dev_pm_ops ath6kl_hifdev_pmops = {
214 .suspend = ath6kl_hifdev_suspend,
215 .resume = ath6kl_hifdev_resume,
216};
217#endif /* CONFIG_PM */
218
219static struct sdio_driver ath6kl_hifdev_driver = {
220 .name = "ath6kl_hifdev",
221 .id_table = ath6kl_hifdev_ids,
222 .probe = ath6kl_hifdev_probe,
223 .remove = ath6kl_hifdev_remove,
224#if defined(CONFIG_PM)
225 .drv = {
226 .pm = &ath6kl_hifdev_pmops,
227 },
228#endif
229};
230
231/* make sure we only unregister when registered. */
232static int registered = 0;
233
234extern u32 onebitmode;
235extern u32 busspeedlow;
236extern u32 debughif;
237
238static void ResetAllCards(void);
239
240#ifdef DEBUG
241
242ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif,
243 "hif",
244 "(Linux MMC) Host Interconnect Framework",
245 ATH_DEBUG_MASK_DEFAULTS,
246 0,
247 NULL);
248
249#endif
250
251
252/* ------ Functions ------ */
253int HIFInit(OSDRV_CALLBACKS *callbacks)
254{
255 int r;
256 AR_DEBUG_ASSERT(callbacks != NULL);
257
258 A_REGISTER_MODULE_DEBUG_INFO(hif);
259
260 /* store the callback handlers */
261 osdrvCallbacks = *callbacks;
262
263 /* Register with bus driver core */
264 registered = 1;
265
266 r = sdio_register_driver(&ath6kl_hifdev_driver);
267 if (r < 0)
268 return r;
269
270 return 0;
271}
272
273static int
274__HIFReadWrite(struct hif_device *device,
275 u32 address,
276 u8 *buffer,
277 u32 length,
278 u32 request,
279 void *context)
280{
281 u8 opcode;
282 int status = 0;
283 int ret;
284 u8 *tbuffer;
285 bool bounced = false;
286
287 AR_DEBUG_ASSERT(device != NULL);
288 AR_DEBUG_ASSERT(device->func != NULL);
289
290 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: 0x%p, buffer:0x%p (addr:0x%X)\n",
291 device, buffer, address));
292
293 do {
294 if (request & HIF_EXTENDED_IO) {
295 //AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Command type: CMD53\n"));
296 } else {
297 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
298 ("AR6000: Invalid command type: 0x%08x\n", request));
299 status = A_EINVAL;
300 break;
301 }
302
303 if (request & HIF_BLOCK_BASIS) {
304 /* round to whole block length size */
305 length = (length / HIF_MBOX_BLOCK_SIZE) * HIF_MBOX_BLOCK_SIZE;
306 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
307 ("AR6000: Block mode (BlockLen: %d)\n",
308 length));
309 } else if (request & HIF_BYTE_BASIS) {
310 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
311 ("AR6000: Byte mode (BlockLen: %d)\n",
312 length));
313 } else {
314 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
315 ("AR6000: Invalid data mode: 0x%08x\n", request));
316 status = A_EINVAL;
317 break;
318 }
319
320#if 0
321 /* useful for checking register accesses */
322 if (length & 0x3) {
323 A_PRINTF(KERN_ALERT"AR6000: HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n",
324 request & HIF_WRITE ? "write":"read", address, length);
325 }
326#endif
327
328 if (request & HIF_WRITE) {
329 if ((address >= HIF_MBOX_START_ADDR(0)) &&
330 (address <= HIF_MBOX_END_ADDR(3)))
331 {
332
333 AR_DEBUG_ASSERT(length <= HIF_MBOX_WIDTH);
334
335 /*
336 * Mailbox write. Adjust the address so that the last byte
337 * falls on the EOM address.
338 */
339 address += (HIF_MBOX_WIDTH - length);
340 }
341 }
342
343 if (request & HIF_FIXED_ADDRESS) {
344 opcode = CMD53_FIXED_ADDRESS;
345 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Fixed 0x%X\n", address));
346 } else if (request & HIF_INCREMENTAL_ADDRESS) {
347 opcode = CMD53_INCR_ADDRESS;
348 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Incremental 0x%X\n", address));
349 } else {
350 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
351 ("AR6000: Invalid address mode: 0x%08x\n", request));
352 status = A_EINVAL;
353 break;
354 }
355
356 if (request & HIF_WRITE) {
357#if HIF_USE_DMA_BOUNCE_BUFFER
358 if (BUFFER_NEEDS_BOUNCE(buffer)) {
359 AR_DEBUG_ASSERT(device->dma_buffer != NULL);
360 tbuffer = device->dma_buffer;
361 /* copy the write data to the dma buffer */
362 AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
363 memcpy(tbuffer, buffer, length);
364 bounced = true;
365 } else {
366 tbuffer = buffer;
367 }
368#else
369 tbuffer = buffer;
370#endif
371 if (opcode == CMD53_FIXED_ADDRESS) {
372 ret = sdio_writesb(device->func, address, tbuffer, length);
373 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writesb ret=%d address: 0x%X, len: %d, 0x%X\n",
374 ret, address, length, *(int *)tbuffer));
375 } else {
376 ret = sdio_memcpy_toio(device->func, address, tbuffer, length);
377 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writeio ret=%d address: 0x%X, len: %d, 0x%X\n",
378 ret, address, length, *(int *)tbuffer));
379 }
380 } else if (request & HIF_READ) {
381#if HIF_USE_DMA_BOUNCE_BUFFER
382 if (BUFFER_NEEDS_BOUNCE(buffer)) {
383 AR_DEBUG_ASSERT(device->dma_buffer != NULL);
384 AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
385 tbuffer = device->dma_buffer;
386 bounced = true;
387 } else {
388 tbuffer = buffer;
389 }
390#else
391 tbuffer = buffer;
392#endif
393 if (opcode == CMD53_FIXED_ADDRESS) {
394 ret = sdio_readsb(device->func, tbuffer, address, length);
395 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readsb ret=%d address: 0x%X, len: %d, 0x%X\n",
396 ret, address, length, *(int *)tbuffer));
397 } else {
398 ret = sdio_memcpy_fromio(device->func, tbuffer, address, length);
399 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readio ret=%d address: 0x%X, len: %d, 0x%X\n",
400 ret, address, length, *(int *)tbuffer));
401 }
402#if HIF_USE_DMA_BOUNCE_BUFFER
403 if (bounced) {
404 /* copy the read data from the dma buffer */
405 memcpy(buffer, tbuffer, length);
406 }
407#endif
408 } else {
409 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
410 ("AR6000: Invalid direction: 0x%08x\n", request));
411 status = A_EINVAL;
412 break;
413 }
414
415 if (ret) {
416 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
417 ("AR6000: SDIO bus operation failed! MMC stack returned : %d \n", ret));
418 status = A_ERROR;
419 }
420 } while (false);
421
422 return status;
423}
424
425void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest)
426{
427 unsigned long flags;
428 BUS_REQUEST *async;
429 BUS_REQUEST *active;
430
431 spin_lock_irqsave(&device->asynclock, flags);
432 active = device->asyncreq;
433 if (active == NULL) {
434 device->asyncreq = busrequest;
435 device->asyncreq->inusenext = NULL;
436 } else {
437 for (async = device->asyncreq;
438 async != NULL;
439 async = async->inusenext) {
440 active = async;
441 }
442 active->inusenext = busrequest;
443 busrequest->inusenext = NULL;
444 }
445 spin_unlock_irqrestore(&device->asynclock, flags);
446}
447
448
449/* queue a read/write request */
450int
451HIFReadWrite(struct hif_device *device,
452 u32 address,
453 u8 *buffer,
454 u32 length,
455 u32 request,
456 void *context)
457{
458 int status = 0;
459 BUS_REQUEST *busrequest;
460
461
462 AR_DEBUG_ASSERT(device != NULL);
463 AR_DEBUG_ASSERT(device->func != NULL);
464
465 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: %p addr:0x%X\n", device,address));
466
467 do {
468 if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)){
469 /* serialize all requests through the async thread */
470 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Execution mode: %s\n",
471 (request & HIF_ASYNCHRONOUS)?"Async":"Synch"));
472 busrequest = hifAllocateBusRequest(device);
473 if (busrequest == NULL) {
474 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
475 ("AR6000: no async bus requests available (%s, addr:0x%X, len:%d) \n",
476 request & HIF_READ ? "READ":"WRITE", address, length));
477 return A_ERROR;
478 }
479 busrequest->address = address;
480 busrequest->buffer = buffer;
481 busrequest->length = length;
482 busrequest->request = request;
483 busrequest->context = context;
484
485 AddToAsyncList(device, busrequest);
486
487 if (request & HIF_SYNCHRONOUS) {
488 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%lX\n", (unsigned long)busrequest));
489
490 /* wait for completion */
491 up(&device->sem_async);
492 if (down_interruptible(&busrequest->sem_req) != 0) {
493 /* interrupted, exit */
494 return A_ERROR;
495 } else {
496 int status = busrequest->status;
497 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%lX: 0x%X\n",
498 (unsigned long)busrequest, busrequest->status));
499 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request));
500 hifFreeBusRequest(device, busrequest);
501 return status;
502 }
503 } else {
504 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%lX\n", (unsigned long)busrequest));
505 up(&device->sem_async);
506 return A_PENDING;
507 }
508 } else {
509 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
510 ("AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request));
511 status = A_EINVAL;
512 break;
513 }
514 } while(0);
515
516 return status;
517}
518/* thread to serialize all requests, both sync and async */
519static int async_task(void *param)
520 {
521 struct hif_device *device;
522 BUS_REQUEST *request;
523 int status;
524 unsigned long flags;
525
526 device = (struct hif_device *)param;
527 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n"));
528 set_current_state(TASK_INTERRUPTIBLE);
529 while(!device->async_shutdown) {
530 /* wait for work */
531 if (down_interruptible(&device->sem_async) != 0) {
532 /* interrupted, exit */
533 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n"));
534 break;
535 }
536 if (device->async_shutdown) {
537 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n"));
538 break;
539 }
540 /* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */
541 sdio_claim_host(device->func);
542 spin_lock_irqsave(&device->asynclock, flags);
543 /* pull the request to work on */
544 while (device->asyncreq != NULL) {
545 request = device->asyncreq;
546 if (request->inusenext != NULL) {
547 device->asyncreq = request->inusenext;
548 } else {
549 device->asyncreq = NULL;
550 }
551 spin_unlock_irqrestore(&device->asynclock, flags);
552 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%lX\n", (unsigned long)request));
553
554 if (request->pScatterReq != NULL) {
555 A_ASSERT(device->scatter_enabled);
556 /* this is a queued scatter request, pass the request to scatter routine which
557 * executes it synchronously, note, no need to free the request since scatter requests
558 * are maintained on a separate list */
559 status = DoHifReadWriteScatter(device,request);
560 } else {
561 /* call HIFReadWrite in sync mode to do the work */
562 status = __HIFReadWrite(device, request->address, request->buffer,
563 request->length, request->request & ~HIF_SYNCHRONOUS, NULL);
564 if (request->request & HIF_ASYNCHRONOUS) {
565 void *context = request->context;
566 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%lX\n", (unsigned long)request));
567 hifFreeBusRequest(device, request);
568 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%lX\n", (unsigned long)request));
569 device->htcCallbacks.rwCompletionHandler(context, status);
570 } else {
571 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%lX\n", (unsigned long)request));
572 request->status = status;
573 up(&request->sem_req);
574 }
575 }
576 spin_lock_irqsave(&device->asynclock, flags);
577 }
578 spin_unlock_irqrestore(&device->asynclock, flags);
579 sdio_release_host(device->func);
580 }
581
582 complete_and_exit(&device->async_completion, 0);
583 return 0;
584}
585
586static s32 IssueSDCommand(struct hif_device *device, u32 opcode, u32 arg, u32 flags, u32 *resp)
587{
588 struct mmc_command cmd;
589 s32 err;
590 struct mmc_host *host;
591 struct sdio_func *func;
592
593 func = device->func;
594 host = func->card->host;
595
596 memset(&cmd, 0, sizeof(struct mmc_command));
597 cmd.opcode = opcode;
598 cmd.arg = arg;
599 cmd.flags = flags;
600 err = mmc_wait_for_cmd(host, &cmd, 3);
601
602 if ((!err) && (resp)) {
603 *resp = cmd.resp[0];
604 }
605
606 return err;
607}
608
609int ReinitSDIO(struct hif_device *device)
610{
611 s32 err;
612 struct mmc_host *host;
613 struct mmc_card *card;
614 struct sdio_func *func;
615 u8 cmd52_resp;
616 u32 clock;
617
618 func = device->func;
619 card = func->card;
620 host = card->host;
621
622 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n"));
623 sdio_claim_host(func);
624
625 do {
626 if (!device->is_suspend) {
627 u32 resp;
628 u16 rca;
629 u32 i;
630 int bit = fls(host->ocr_avail) - 1;
631 /* emulate the mmc_power_up(...) */
632 host->ios.vdd = bit;
633 host->ios.chip_select = MMC_CS_DONTCARE;
634 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
635 host->ios.power_mode = MMC_POWER_UP;
636 host->ios.bus_width = MMC_BUS_WIDTH_1;
637 host->ios.timing = MMC_TIMING_LEGACY;
638 host->ops->set_ios(host, &host->ios);
639 /*
640 * This delay should be sufficient to allow the power supply
641 * to reach the minimum voltage.
642 */
643 msleep(2);
644
645 host->ios.clock = host->f_min;
646 host->ios.power_mode = MMC_POWER_ON;
647 host->ops->set_ios(host, &host->ios);
648
649 /*
650 * This delay must be at least 74 clock sizes, or 1 ms, or the
651 * time required to reach a stable voltage.
652 */
653 msleep(2);
654
655 /* Issue CMD0. Goto idle state */
656 host->ios.chip_select = MMC_CS_HIGH;
657 host->ops->set_ios(host, &host->ios);
658 msleep(1);
659 err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL);
660 host->ios.chip_select = MMC_CS_DONTCARE;
661 host->ops->set_ios(host, &host->ios);
662 msleep(1);
663 host->use_spi_crc = 0;
664
665 if (err) {
666 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n",err));
667 break;
668 }
669
670 if (!host->ocr) {
671 /* Issue CMD5, arg = 0 */
672 err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
673 if (err) {
674 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));
675 break;
676 }
677 host->ocr = resp;
678 }
679
680 /* Issue CMD5, arg = ocr. Wait till card is ready */
681 for (i=0;i<100;i++) {
682 err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
683 if (err) {
684 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));
685 break;
686 }
687 if (resp & MMC_CARD_BUSY) {
688 break;
689 }
690 msleep(10);
691 }
692
693 if ((i == 100) || (err)) {
694 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready : %d %d \n",i,err));
695 break;
696 }
697
698 /* Issue CMD3, get RCA */
699 err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp);
700 if (err) {
701 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n",err));
702 break;
703 }
704 rca = resp >> 16;
705 host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
706 host->ops->set_ios(host, &host->ios);
707
708 /* Issue CMD7, select card */
709 err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL);
710 if (err) {
711 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n",err));
712 break;
713 }
714 }
715
716 /* Enable high speed */
717 if (card->host->caps & MMC_CAP_SD_HIGHSPEED) {
718 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n"));
719 err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp);
720 if (err) {
721 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR speed register failed : %d \n",err));
722 card->state &= ~MMC_STATE_HIGHSPEED;
723 /* no need to break */
724 } else {
725 err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS));
726 if (err) {
727 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to CCCR speed register failed : %d \n",err));
728 break;
729 }
730 mmc_card_set_highspeed(card);
731 host->ios.timing = MMC_TIMING_SD_HS;
732 host->ops->set_ios(host, &host->ios);
733 }
734 }
735
736 /* Set clock */
737 if (mmc_card_highspeed(card)) {
738 clock = 50000000;
739 } else {
740 clock = card->cis.max_dtr;
741 }
742
743 if (clock > host->f_max) {
744 clock = host->f_max;
745 }
746 host->ios.clock = clock;
747 host->ops->set_ios(host, &host->ios);
748
749
750 if (card->host->caps & MMC_CAP_4_BIT_DATA) {
751 /* CMD52: Set bus width & disable card detect resistor */
752 err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT);
753 if (err) {
754 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mode failed : %d \n",err));
755 break;
756 }
757 host->ios.bus_width = MMC_BUS_WIDTH_4;
758 host->ops->set_ios(host, &host->ios);
759 }
760 } while (0);
761
762 sdio_release_host(func);
763 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ReinitSDIO \n"));
764
765 return (err) ? A_ERROR : 0;
766}
767
768int
769PowerStateChangeNotify(struct hif_device *device, HIF_DEVICE_POWER_CHANGE_TYPE config)
770{
771 int status = 0;
772#if defined(CONFIG_PM)
773 struct sdio_func *func = device->func;
774 int old_reset_val;
775 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +PowerStateChangeNotify %d\n", config));
776 switch (config) {
777 case HIF_DEVICE_POWER_DOWN:
778 case HIF_DEVICE_POWER_CUT:
779 old_reset_val = reset_sdio_on_unload;
780 reset_sdio_on_unload = 1;
781 status = hifDisableFunc(device, func);
782 reset_sdio_on_unload = old_reset_val;
783 if (!device->is_suspend) {
784 struct mmc_host *host = func->card->host;
785 host->ios.clock = 0;
786 host->ios.vdd = 0;
787 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
788 host->ios.chip_select = MMC_CS_DONTCARE;
789 host->ios.power_mode = MMC_POWER_OFF;
790 host->ios.bus_width = MMC_BUS_WIDTH_1;
791 host->ios.timing = MMC_TIMING_LEGACY;
792 host->ops->set_ios(host, &host->ios);
793 }
794 break;
795 case HIF_DEVICE_POWER_UP:
796 if (device->powerConfig == HIF_DEVICE_POWER_CUT) {
797 status = ReinitSDIO(device);
798 }
799 if (status == 0) {
800 status = hifEnableFunc(device, func);
801 }
802 break;
803 }
804 device->powerConfig = config;
805
806 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -PowerStateChangeNotify\n"));
807#endif
808 return status;
809}
810
811int
812HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode,
813 void *config, u32 configLen)
814{
815 u32 count;
816 int status = 0;
817
818 switch(opcode) {
819 case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
820 ((u32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
821 ((u32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
822 ((u32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
823 ((u32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
824 break;
825
826 case HIF_DEVICE_GET_MBOX_ADDR:
827 for (count = 0; count < 4; count ++) {
828 ((u32 *)config)[count] = HIF_MBOX_START_ADDR(count);
829 }
830
831 if (configLen >= sizeof(struct hif_device_mbox_info)) {
832 SetExtendedMboxWindowInfo((u16)device->func->device,
833 (struct hif_device_mbox_info *)config);
834 }
835
836 break;
837 case HIF_DEVICE_GET_IRQ_PROC_MODE:
838 *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY;
839 break;
840 case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT:
841 if (!device->scatter_enabled) {
842 return A_ENOTSUP;
843 }
844 status = SetupHIFScatterSupport(device, (struct hif_device_scatter_support_info *)config);
845 if (status) {
846 device->scatter_enabled = false;
847 }
848 break;
849 case HIF_DEVICE_GET_OS_DEVICE:
850 /* pass back a pointer to the SDIO function's "dev" struct */
851 ((struct hif_device_os_device_info *)config)->pOSDevice = &device->func->dev;
852 break;
853 case HIF_DEVICE_POWER_STATE_CHANGE:
854 status = PowerStateChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TYPE *)config);
855 break;
856 default:
857 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
858 ("AR6000: Unsupported configuration opcode: %d\n", opcode));
859 status = A_ERROR;
860 }
861
862 return status;
863}
864
865void
866HIFShutDownDevice(struct hif_device *device)
867{
868 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n"));
869 if (device != NULL) {
870 AR_DEBUG_ASSERT(device->func != NULL);
871 } else {
872 /* since we are unloading the driver anyways, reset all cards in case the SDIO card
873 * is externally powered and we are unloading the SDIO stack. This avoids the problem when
874 * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already
875 * enumerated */
876 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFShutDownDevice, resetting\n"));
877 ResetAllCards();
878
879 /* Unregister with bus driver core */
880 if (registered) {
881 registered = 0;
882 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
883 ("AR6000: Unregistering with the bus driver\n"));
884 sdio_unregister_driver(&ath6kl_hifdev_driver);
885 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
886 ("AR6000: Unregistered\n"));
887 }
888 }
889 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -HIFShutDownDevice\n"));
890}
891
892static void
893hifIRQHandler(struct sdio_func *func)
894{
895 int status;
896 struct hif_device *device;
897 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n"));
898
899 device = ath6kl_get_hifdev(func);
900 atomic_set(&device->irqHandling, 1);
901 /* release the host during ints so we can pick it back up when we process cmds */
902 sdio_release_host(device->func);
903 status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context);
904 sdio_claim_host(device->func);
905 atomic_set(&device->irqHandling, 0);
906 AR_DEBUG_ASSERT(status == 0 || status == A_ECANCELED);
907 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifIRQHandler\n"));
908}
909
910/* handle HTC startup via thread*/
911static int startup_task(void *param)
912{
913 struct hif_device *device;
914
915 device = (struct hif_device *)param;
916 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n"));
917 /* start up inform DRV layer */
918 if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != 0) {
919 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
920 }
921 return 0;
922}
923
924#if defined(CONFIG_PM)
925static int enable_task(void *param)
926{
927 struct hif_device *device;
928 device = (struct hif_device *)param;
929 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call from resume_task\n"));
930
931 /* start up inform DRV layer */
932 if (device &&
933 device->claimedContext &&
934 osdrvCallbacks.devicePowerChangeHandler &&
935 osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != 0)
936 {
937 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
938 }
939
940 return 0;
941}
942#endif
943
944void
945HIFAckInterrupt(struct hif_device *device)
946{
947 AR_DEBUG_ASSERT(device != NULL);
948
949 /* Acknowledge our function IRQ */
950}
951
952void
953HIFUnMaskInterrupt(struct hif_device *device)
954{
955 int ret;
956
957 AR_DEBUG_ASSERT(device != NULL);
958 AR_DEBUG_ASSERT(device->func != NULL);
959
960 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFUnMaskInterrupt\n"));
961
962 /* Register the IRQ Handler */
963 sdio_claim_host(device->func);
964 ret = sdio_claim_irq(device->func, hifIRQHandler);
965 sdio_release_host(device->func);
966 AR_DEBUG_ASSERT(ret == 0);
967}
968
969void HIFMaskInterrupt(struct hif_device *device)
970{
971 int ret;
972 AR_DEBUG_ASSERT(device != NULL);
973 AR_DEBUG_ASSERT(device->func != NULL);
974
975 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFMaskInterrupt\n"));
976
977 /* Mask our function IRQ */
978 sdio_claim_host(device->func);
979 while (atomic_read(&device->irqHandling)) {
980 sdio_release_host(device->func);
981 schedule_timeout(HZ/10);
982 sdio_claim_host(device->func);
983 }
984 ret = sdio_release_irq(device->func);
985 sdio_release_host(device->func);
986 AR_DEBUG_ASSERT(ret == 0);
987}
988
989BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device)
990{
991 BUS_REQUEST *busrequest;
992 unsigned long flag;
993
994 /* Acquire lock */
995 spin_lock_irqsave(&device->lock, flag);
996
997 /* Remove first in list */
998 if((busrequest = device->s_busRequestFreeQueue) != NULL)
999 {
1000 device->s_busRequestFreeQueue = busrequest->next;
1001 }
1002 /* Release lock */
1003 spin_unlock_irqrestore(&device->lock, flag);
1004 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifAllocateBusRequest: 0x%p\n", busrequest));
1005 return busrequest;
1006}
1007
1008void
1009hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest)
1010{
1011 unsigned long flag;
1012
1013 AR_DEBUG_ASSERT(busrequest != NULL);
1014 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifFreeBusRequest: 0x%p\n", busrequest));
1015 /* Acquire lock */
1016 spin_lock_irqsave(&device->lock, flag);
1017
1018
1019 /* Insert first in list */
1020 busrequest->next = device->s_busRequestFreeQueue;
1021 busrequest->inusenext = NULL;
1022 device->s_busRequestFreeQueue = busrequest;
1023
1024 /* Release lock */
1025 spin_unlock_irqrestore(&device->lock, flag);
1026}
1027
1028static int hifDisableFunc(struct hif_device *device, struct sdio_func *func)
1029{
1030 int ret;
1031 int status = 0;
1032
1033 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n"));
1034 device = ath6kl_get_hifdev(func);
1035 if (!IS_ERR(device->async_task)) {
1036 init_completion(&device->async_completion);
1037 device->async_shutdown = 1;
1038 up(&device->sem_async);
1039 wait_for_completion(&device->async_completion);
1040 device->async_task = NULL;
1041 }
1042 /* Disable the card */
1043 sdio_claim_host(device->func);
1044 ret = sdio_disable_func(device->func);
1045 if (ret) {
1046 status = A_ERROR;
1047 }
1048
1049 if (reset_sdio_on_unload) {
1050 /* reset the SDIO interface. This is useful in automated testing where the card
1051 * does not need to be removed at the end of the test. It is expected that the user will
1052 * also unload/reload the host controller driver to force the bus driver to re-enumerate the slot */
1053 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uninitialized state \n"));
1054
1055 /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows access
1056 * to undefined registers in the range of: 0xF0-0xFF */
1057
1058 ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3));
1059 if (ret) {
1060 status = A_ERROR;
1061 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret));
1062 }
1063 }
1064
1065 sdio_release_host(device->func);
1066
1067 if (status == 0) {
1068 device->is_disabled = true;
1069 }
1070 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDisableFunc\n"));
1071
1072 return status;
1073}
1074
1075static int hifEnableFunc(struct hif_device *device, struct sdio_func *func)
1076{
1077 struct task_struct* pTask;
1078 const char *taskName = NULL;
1079 int (*taskFunc)(void *) = NULL;
1080 int ret = 0;
1081
1082 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n"));
1083 device = ath6kl_get_hifdev(func);
1084
1085 if (device->is_disabled) {
1086 /* enable the SDIO function */
1087 sdio_claim_host(func);
1088
1089 if ((device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_BASE) {
1090 /* enable 4-bit ASYNC interrupt on AR6003 or later devices */
1091 ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
1092 if (ret) {
1093 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret));
1094 sdio_release_host(func);
1095 return ret;
1096 }
1097 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n"));
1098 }
1099 /* give us some time to enable, in ms */
1100 func->enable_timeout = 100;
1101 ret = sdio_enable_func(func);
1102 if (ret) {
1103 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n",
1104 __FUNCTION__, ret));
1105 sdio_release_host(func);
1106 return ret;
1107 }
1108 ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
1109 sdio_release_host(func);
1110 if (ret) {
1111 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n",
1112 __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret));
1113 return ret;
1114 }
1115 device->is_disabled = false;
1116 /* create async I/O thread */
1117 if (!device->async_task) {
1118 device->async_shutdown = 0;
1119 device->async_task = kthread_create(async_task,
1120 (void *)device,
1121 "AR6K Async");
1122 if (IS_ERR(device->async_task)) {
1123 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__));
1124 return -ENOMEM;
1125 }
1126 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n"));
1127 wake_up_process(device->async_task );
1128 }
1129 }
1130
1131 if (!device->claimedContext) {
1132 taskFunc = startup_task;
1133 taskName = "AR6K startup";
1134 ret = 0;
1135#if defined(CONFIG_PM)
1136 } else {
1137 taskFunc = enable_task;
1138 taskName = "AR6K enable";
1139 ret = -ENOMEM;
1140#endif /* CONFIG_PM */
1141 }
1142 /* create resume thread */
1143 pTask = kthread_create(taskFunc, (void *)device, taskName);
1144 if (IS_ERR(pTask)) {
1145 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__));
1146 return -ENOMEM;
1147 }
1148 wake_up_process(pTask);
1149 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n"));
1150
1151 /* task will call the enable func, indicate pending */
1152 return ret;
1153}
1154
1155/*
1156 * This should be moved to AR6K HTC layer.
1157 */
1158int hifWaitForPendingRecv(struct hif_device *device)
1159{
1160 s32 cnt = 10;
1161 u8 host_int_status;
1162 int status = 0;
1163
1164 do {
1165 while (atomic_read(&device->irqHandling)) {
1166 /* wait until irq handler finished all the jobs */
1167 schedule_timeout(HZ/10);
1168 }
1169 /* check if there is any pending irq due to force done */
1170 host_int_status = 0;
1171 status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS,
1172 (u8 *)&host_int_status, sizeof(host_int_status),
1173 HIF_RD_SYNC_BYTE_INC, NULL);
1174 host_int_status = !status ? (host_int_status & (1 << 0)) : 0;
1175 if (host_int_status) {
1176 schedule(); /* schedule for next dsrHandler */
1177 }
1178 } while (host_int_status && --cnt > 0);
1179
1180 if (host_int_status && cnt == 0) {
1181 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
1182 ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__));
1183 }
1184
1185 return 0;
1186}
1187
1188static void
1189delHifDevice(struct hif_device * device)
1190{
1191 AR_DEBUG_ASSERT(device!= NULL);
1192 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: delHifDevice; 0x%p\n", device));
1193 kfree(device->dma_buffer);
1194 kfree(device);
1195}
1196
1197static void ResetAllCards(void)
1198{
1199}
1200
1201void HIFClaimDevice(struct hif_device *device, void *context)
1202{
1203 device->claimedContext = context;
1204}
1205
1206void HIFReleaseDevice(struct hif_device *device)
1207{
1208 device->claimedContext = NULL;
1209}
1210
1211int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks)
1212{
1213 if (device->htcCallbacks.context != NULL) {
1214 /* already in use! */
1215 return A_ERROR;
1216 }
1217 device->htcCallbacks = *callbacks;
1218 return 0;
1219}
1220
1221void HIFDetachHTC(struct hif_device *device)
1222{
1223 A_MEMZERO(&device->htcCallbacks,sizeof(device->htcCallbacks));
1224}
1225
1226#define SDIO_SET_CMD52_ARG(arg,rw,func,raw,address,writedata) \
1227 (arg) = (((rw) & 1) << 31) | \
1228 (((func) & 0x7) << 28) | \
1229 (((raw) & 1) << 27) | \
1230 (1 << 26) | \
1231 (((address) & 0x1FFFF) << 9) | \
1232 (1 << 8) | \
1233 ((writedata) & 0xFF)
1234
1235#define SDIO_SET_CMD52_READ_ARG(arg,func,address) \
1236 SDIO_SET_CMD52_ARG(arg,0,(func),0,address,0x00)
1237#define SDIO_SET_CMD52_WRITE_ARG(arg,func,address,value) \
1238 SDIO_SET_CMD52_ARG(arg,1,(func),0,address,value)
1239
1240static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte)
1241{
1242 struct mmc_command ioCmd;
1243 unsigned long arg;
1244
1245 memset(&ioCmd,0,sizeof(ioCmd));
1246 SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte);
1247 ioCmd.opcode = SD_IO_RW_DIRECT;
1248 ioCmd.arg = arg;
1249 ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
1250
1251 return mmc_wait_for_cmd(card->host, &ioCmd, 0);
1252}
1253
1254static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte)
1255{
1256 struct mmc_command ioCmd;
1257 unsigned long arg;
1258 s32 err;
1259
1260 memset(&ioCmd,0,sizeof(ioCmd));
1261 SDIO_SET_CMD52_READ_ARG(arg,0,address);
1262 ioCmd.opcode = SD_IO_RW_DIRECT;
1263 ioCmd.arg = arg;
1264 ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
1265
1266 err = mmc_wait_for_cmd(card->host, &ioCmd, 0);
1267
1268 if ((!err) && (byte)) {
1269 *byte = ioCmd.resp[0] & 0xFF;
1270 }
1271
1272 return err;
1273}
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c
new file mode 100644
index 00000000000..7516d913dab
--- /dev/null
+++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c
@@ -0,0 +1,393 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HIF scatter implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#include <linux/mmc/card.h>
26#include <linux/mmc/host.h>
27#include <linux/mmc/sdio_func.h>
28#include <linux/mmc/sdio_ids.h>
29#include <linux/mmc/sdio.h>
30#include <linux/kthread.h>
31#include "hif_internal.h"
32#define ATH_MODULE_NAME hif
33#include "a_debug.h"
34
35#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT
36
37#define _CMD53_ARG_READ 0
38#define _CMD53_ARG_WRITE 1
39#define _CMD53_ARG_BLOCK_BASIS 1
40#define _CMD53_ARG_FIXED_ADDRESS 0
41#define _CMD53_ARG_INCR_ADDRESS 1
42
43#define SDIO_SET_CMD53_ARG(arg,rw,func,mode,opcode,address,bytes_blocks) \
44 (arg) = (((rw) & 1) << 31) | \
45 (((func) & 0x7) << 28) | \
46 (((mode) & 1) << 27) | \
47 (((opcode) & 1) << 26) | \
48 (((address) & 0x1FFFF) << 9) | \
49 ((bytes_blocks) & 0x1FF)
50
51static void FreeScatterReq(struct hif_device *device, struct hif_scatter_req *pReq)
52{
53 unsigned long flag;
54
55 spin_lock_irqsave(&device->lock, flag);
56
57 DL_ListInsertTail(&device->ScatterReqHead, &pReq->ListLink);
58
59 spin_unlock_irqrestore(&device->lock, flag);
60
61}
62
63static struct hif_scatter_req *AllocScatterReq(struct hif_device *device)
64{
65 struct dl_list *pItem;
66 unsigned long flag;
67
68 spin_lock_irqsave(&device->lock, flag);
69
70 pItem = DL_ListRemoveItemFromHead(&device->ScatterReqHead);
71
72 spin_unlock_irqrestore(&device->lock, flag);
73
74 if (pItem != NULL) {
75 return A_CONTAINING_STRUCT(pItem, struct hif_scatter_req, ListLink);
76 }
77
78 return NULL;
79}
80
81 /* called by async task to perform the operation synchronously using direct MMC APIs */
82int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest)
83{
84 int i;
85 u8 rw;
86 u8 opcode;
87 struct mmc_request mmcreq;
88 struct mmc_command cmd;
89 struct mmc_data data;
90 struct hif_scatter_req_priv *pReqPriv;
91 struct hif_scatter_req *pReq;
92 int status = 0;
93 struct scatterlist *pSg;
94
95 pReqPriv = busrequest->pScatterReq;
96
97 A_ASSERT(pReqPriv != NULL);
98
99 pReq = pReqPriv->pHifScatterReq;
100
101 memset(&mmcreq, 0, sizeof(struct mmc_request));
102 memset(&cmd, 0, sizeof(struct mmc_command));
103 memset(&data, 0, sizeof(struct mmc_data));
104
105 data.blksz = HIF_MBOX_BLOCK_SIZE;
106 data.blocks = pReq->TotalLength / HIF_MBOX_BLOCK_SIZE;
107
108 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: (%s) Address: 0x%X, (BlockLen: %d, BlockCount: %d) , (tot:%d,sg:%d)\n",
109 (pReq->Request & HIF_WRITE) ? "WRITE":"READ", pReq->Address, data.blksz, data.blocks,
110 pReq->TotalLength,pReq->ValidScatterEntries));
111
112 if (pReq->Request & HIF_WRITE) {
113 rw = _CMD53_ARG_WRITE;
114 data.flags = MMC_DATA_WRITE;
115 } else {
116 rw = _CMD53_ARG_READ;
117 data.flags = MMC_DATA_READ;
118 }
119
120 if (pReq->Request & HIF_FIXED_ADDRESS) {
121 opcode = _CMD53_ARG_FIXED_ADDRESS;
122 } else {
123 opcode = _CMD53_ARG_INCR_ADDRESS;
124 }
125
126 /* fill SG entries */
127 pSg = pReqPriv->sgentries;
128 sg_init_table(pSg, pReq->ValidScatterEntries);
129
130 /* assemble SG list */
131 for (i = 0 ; i < pReq->ValidScatterEntries ; i++, pSg++) {
132 /* setup each sg entry */
133 if ((unsigned long)pReq->ScatterList[i].pBuffer & 0x3) {
134 /* note some scatter engines can handle unaligned buffers, print this
135 * as informational only */
136 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER,
137 ("HIF: (%s) Scatter Buffer is unaligned 0x%lx\n",
138 pReq->Request & HIF_WRITE ? "WRITE":"READ",
139 (unsigned long)pReq->ScatterList[i].pBuffer));
140 }
141
142 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, (" %d: Addr:0x%lX, Len:%d \n",
143 i,(unsigned long)pReq->ScatterList[i].pBuffer,pReq->ScatterList[i].Length));
144
145 sg_set_buf(pSg, pReq->ScatterList[i].pBuffer, pReq->ScatterList[i].Length);
146 }
147 /* set scatter-gather table for request */
148 data.sg = pReqPriv->sgentries;
149 data.sg_len = pReq->ValidScatterEntries;
150 /* set command argument */
151 SDIO_SET_CMD53_ARG(cmd.arg,
152 rw,
153 device->func->num,
154 _CMD53_ARG_BLOCK_BASIS,
155 opcode,
156 pReq->Address,
157 data.blocks);
158
159 cmd.opcode = SD_IO_RW_EXTENDED;
160 cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
161
162 mmcreq.cmd = &cmd;
163 mmcreq.data = &data;
164
165 mmc_set_data_timeout(&data, device->func->card);
166 /* synchronous call to process request */
167 mmc_wait_for_req(device->func->card->host, &mmcreq);
168
169 if (cmd.error) {
170 status = A_ERROR;
171 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: cmd error: %d \n",cmd.error));
172 }
173
174 if (data.error) {
175 status = A_ERROR;
176 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: data error: %d \n",data.error));
177 }
178
179 if (status) {
180 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: FAILED!!! (%s) Address: 0x%X, Block mode (BlockLen: %d, BlockCount: %d)\n",
181 (pReq->Request & HIF_WRITE) ? "WRITE":"READ",pReq->Address, data.blksz, data.blocks));
182 }
183
184 /* set completion status, fail or success */
185 pReq->CompletionStatus = status;
186
187 if (pReq->Request & HIF_ASYNCHRONOUS) {
188 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: async_task completion routine req: 0x%lX (%d)\n",(unsigned long)busrequest, status));
189 /* complete the request */
190 A_ASSERT(pReq->CompletionRoutine != NULL);
191 pReq->CompletionRoutine(pReq);
192 } else {
193 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER async_task upping busrequest : 0x%lX (%d)\n", (unsigned long)busrequest,status));
194 /* signal wait */
195 up(&busrequest->sem_req);
196 }
197
198 return status;
199}
200
201 /* callback to issue a read-write scatter request */
202static int HifReadWriteScatter(struct hif_device *device, struct hif_scatter_req *pReq)
203{
204 int status = A_EINVAL;
205 u32 request = pReq->Request;
206 struct hif_scatter_req_priv *pReqPriv = (struct hif_scatter_req_priv *)pReq->HIFPrivate[0];
207
208 do {
209
210 A_ASSERT(pReqPriv != NULL);
211
212 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: total len: %d Scatter Entries: %d\n",
213 pReq->TotalLength, pReq->ValidScatterEntries));
214
215 if (!(request & HIF_EXTENDED_IO)) {
216 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
217 ("HIF-SCATTER: Invalid command type: 0x%08x\n", request));
218 break;
219 }
220
221 if (!(request & (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS))) {
222 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
223 ("HIF-SCATTER: Invalid execution mode: 0x%08x\n", request));
224 break;
225 }
226
227 if (!(request & HIF_BLOCK_BASIS)) {
228 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
229 ("HIF-SCATTER: Invalid data mode: 0x%08x\n", request));
230 break;
231 }
232
233 if (pReq->TotalLength > MAX_SCATTER_REQ_TRANSFER_SIZE) {
234 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
235 ("HIF-SCATTER: Invalid length: %d \n", pReq->TotalLength));
236 break;
237 }
238
239 if (pReq->TotalLength == 0) {
240 A_ASSERT(false);
241 break;
242 }
243
244 /* add bus request to the async list for the async I/O thread to process */
245 AddToAsyncList(device, pReqPriv->busrequest);
246
247 if (request & HIF_SYNCHRONOUS) {
248 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued sync req: 0x%lX\n", (unsigned long)pReqPriv->busrequest));
249 /* signal thread and wait */
250 up(&device->sem_async);
251 if (down_interruptible(&pReqPriv->busrequest->sem_req) != 0) {
252 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,("HIF-SCATTER: interrupted! \n"));
253 /* interrupted, exit */
254 status = A_ERROR;
255 break;
256 } else {
257 status = pReq->CompletionStatus;
258 }
259 } else {
260 AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued async req: 0x%lX\n", (unsigned long)pReqPriv->busrequest));
261 /* wake thread, it will process and then take care of the async callback */
262 up(&device->sem_async);
263 status = 0;
264 }
265
266 } while (false);
267
268 if (status && (request & HIF_ASYNCHRONOUS)) {
269 pReq->CompletionStatus = status;
270 pReq->CompletionRoutine(pReq);
271 status = 0;
272 }
273
274 return status;
275}
276
277 /* setup of HIF scatter resources */
278int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo)
279{
280 int status = A_ERROR;
281 int i;
282 struct hif_scatter_req_priv *pReqPriv;
283 BUS_REQUEST *busrequest;
284
285 do {
286
287 /* check if host supports scatter requests and it meets our requirements */
288 if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
289 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n",
290 device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ));
291 status = A_ENOTSUP;
292 break;
293 }
294
295 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HIF-SCATTER Enabled: max scatter req : %d entries: %d \n",
296 MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ));
297
298 for (i = 0; i < MAX_SCATTER_REQUESTS; i++) {
299 /* allocate the private request blob */
300 pReqPriv = (struct hif_scatter_req_priv *)A_MALLOC(sizeof(struct hif_scatter_req_priv));
301 if (NULL == pReqPriv) {
302 break;
303 }
304 A_MEMZERO(pReqPriv, sizeof(struct hif_scatter_req_priv));
305 /* save the device instance*/
306 pReqPriv->device = device;
307 /* allocate the scatter request */
308 pReqPriv->pHifScatterReq = (struct hif_scatter_req *)A_MALLOC(sizeof(struct hif_scatter_req) +
309 (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item)));
310
311 if (NULL == pReqPriv->pHifScatterReq) {
312 kfree(pReqPriv);
313 break;
314 }
315 /* just zero the main part of the scatter request */
316 A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(struct hif_scatter_req));
317 /* back pointer to the private struct */
318 pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv;
319 /* allocate a bus request for this scatter request */
320 busrequest = hifAllocateBusRequest(device);
321 if (NULL == busrequest) {
322 kfree(pReqPriv->pHifScatterReq);
323 kfree(pReqPriv);
324 break;
325 }
326 /* assign the scatter request to this bus request */
327 busrequest->pScatterReq = pReqPriv;
328 /* point back to the request */
329 pReqPriv->busrequest = busrequest;
330 /* add it to the scatter pool */
331 FreeScatterReq(device,pReqPriv->pHifScatterReq);
332 }
333
334 if (i != MAX_SCATTER_REQUESTS) {
335 status = A_NO_MEMORY;
336 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : failed to alloc scatter resources !\n"));
337 break;
338 }
339
340 /* set scatter function pointers */
341 pInfo->pAllocateReqFunc = AllocScatterReq;
342 pInfo->pFreeReqFunc = FreeScatterReq;
343 pInfo->pReadWriteScatterFunc = HifReadWriteScatter;
344 pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ;
345 pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE;
346
347 status = 0;
348
349 } while (false);
350
351 if (status) {
352 CleanupHIFScatterResources(device);
353 }
354
355 return status;
356}
357
358 /* clean up scatter support */
359void CleanupHIFScatterResources(struct hif_device *device)
360{
361 struct hif_scatter_req_priv *pReqPriv;
362 struct hif_scatter_req *pReq;
363
364 /* empty the free list */
365
366 while (1) {
367
368 pReq = AllocScatterReq(device);
369
370 if (NULL == pReq) {
371 break;
372 }
373
374 pReqPriv = (struct hif_scatter_req_priv *)pReq->HIFPrivate[0];
375 A_ASSERT(pReqPriv != NULL);
376
377 if (pReqPriv->busrequest != NULL) {
378 pReqPriv->busrequest->pScatterReq = NULL;
379 /* free bus request */
380 hifFreeBusRequest(device, pReqPriv->busrequest);
381 pReqPriv->busrequest = NULL;
382 }
383
384 if (pReqPriv->pHifScatterReq != NULL) {
385 kfree(pReqPriv->pHifScatterReq);
386 pReqPriv->pHifScatterReq = NULL;
387 }
388
389 kfree(pReqPriv);
390 }
391}
392
393#endif // HIF_LINUX_MMC_SCATTER_SUPPORT
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c
new file mode 100644
index 00000000000..f8607bc0892
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c
@@ -0,0 +1,1479 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6k.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// AR6K device layer that handles register level I/O
22//
23// Author(s): ="Atheros"
24//==============================================================================
25
26#include "a_config.h"
27#include "athdefs.h"
28#include "hw/mbox_host_reg.h"
29#include "a_osapi.h"
30#include "../htc_debug.h"
31#include "hif.h"
32#include "htc_packet.h"
33#include "ar6k.h"
34
35#define MAILBOX_FOR_BLOCK_SIZE 1
36
37int DevEnableInterrupts(struct ar6k_device *pDev);
38int DevDisableInterrupts(struct ar6k_device *pDev);
39
40static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev);
41
42void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket)
43{
44 LOCK_AR6K(pDev);
45 HTC_PACKET_ENQUEUE(&pDev->RegisterIOList,pPacket);
46 UNLOCK_AR6K(pDev);
47}
48
49struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev)
50{
51 struct htc_packet *pPacket;
52
53 LOCK_AR6K(pDev);
54 pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList);
55 UNLOCK_AR6K(pDev);
56
57 return pPacket;
58}
59
60void DevCleanup(struct ar6k_device *pDev)
61{
62 DevCleanupGMbox(pDev);
63
64 if (pDev->HifAttached) {
65 HIFDetachHTC(pDev->HIFDevice);
66 pDev->HifAttached = false;
67 }
68
69 DevCleanupVirtualScatterSupport(pDev);
70
71 if (A_IS_MUTEX_VALID(&pDev->Lock)) {
72 A_MUTEX_DELETE(&pDev->Lock);
73 }
74}
75
76int DevSetup(struct ar6k_device *pDev)
77{
78 u32 blocksizes[AR6K_MAILBOXES];
79 int status = 0;
80 int i;
81 HTC_CALLBACKS htcCallbacks;
82
83 do {
84
85 DL_LIST_INIT(&pDev->ScatterReqHead);
86 /* initialize our free list of IO packets */
87 INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList);
88 A_MUTEX_INIT(&pDev->Lock);
89
90 A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));
91 /* the device layer handles these */
92 htcCallbacks.rwCompletionHandler = DevRWCompletionHandler;
93 htcCallbacks.dsrHandler = DevDsrHandler;
94 htcCallbacks.context = pDev;
95
96 status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks);
97
98 if (status) {
99 break;
100 }
101
102 pDev->HifAttached = true;
103
104 /* get the addresses for all 4 mailboxes */
105 status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
106 &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo));
107
108 if (status) {
109 A_ASSERT(false);
110 break;
111 }
112
113 /* carve up register I/O packets (these are for ASYNC register I/O ) */
114 for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) {
115 struct htc_packet *pIOPacket;
116 pIOPacket = &pDev->RegIOBuffers[i].HtcPacket;
117 SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket,
118 pDev,
119 pDev->RegIOBuffers[i].Buffer,
120 AR6K_REG_IO_BUFFER_SIZE,
121 0); /* don't care */
122 AR6KFreeIOPacket(pDev,pIOPacket);
123 }
124
125 /* get the block sizes */
126 status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
127 blocksizes, sizeof(blocksizes));
128
129 if (status) {
130 A_ASSERT(false);
131 break;
132 }
133
134 /* note: we actually get the block size of a mailbox other than 0, for SDIO the block
135 * size on mailbox 0 is artificially set to 1. So we use the block size that is set
136 * for the other 3 mailboxes */
137 pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE];
138 /* must be a power of 2 */
139 A_ASSERT((pDev->BlockSize & (pDev->BlockSize - 1)) == 0);
140
141 /* assemble mask, used for padding to a block */
142 pDev->BlockMask = pDev->BlockSize - 1;
143
144 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("BlockSize: %d, MailboxAddress:0x%X \n",
145 pDev->BlockSize, pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]));
146
147 pDev->GetPendingEventsFunc = NULL;
148 /* see if the HIF layer implements the get pending events function */
149 HIFConfigureDevice(pDev->HIFDevice,
150 HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
151 &pDev->GetPendingEventsFunc,
152 sizeof(pDev->GetPendingEventsFunc));
153
154 /* assume we can process HIF interrupt events asynchronously */
155 pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC;
156
157 /* see if the HIF layer overrides this assumption */
158 HIFConfigureDevice(pDev->HIFDevice,
159 HIF_DEVICE_GET_IRQ_PROC_MODE,
160 &pDev->HifIRQProcessingMode,
161 sizeof(pDev->HifIRQProcessingMode));
162
163 switch (pDev->HifIRQProcessingMode) {
164 case HIF_DEVICE_IRQ_SYNC_ONLY:
165 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYNC ONLY\n"));
166 /* see if HIF layer wants HTC to yield */
167 HIFConfigureDevice(pDev->HIFDevice,
168 HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
169 &pDev->HifIRQYieldParams,
170 sizeof(pDev->HifIRQYieldParams));
171
172 if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) {
173 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
174 ("HIF requests that DSR yield per %d RECV packets \n",
175 pDev->HifIRQYieldParams.RecvPacketYieldCount));
176 pDev->DSRCanYield = true;
177 }
178 break;
179 case HIF_DEVICE_IRQ_ASYNC_SYNC:
180 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n"));
181 break;
182 default:
183 A_ASSERT(false);
184 }
185
186 pDev->HifMaskUmaskRecvEvent = NULL;
187
188 /* see if the HIF layer implements the mask/unmask recv events function */
189 HIFConfigureDevice(pDev->HIFDevice,
190 HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
191 &pDev->HifMaskUmaskRecvEvent,
192 sizeof(pDev->HifMaskUmaskRecvEvent));
193
194 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%lX , 0x%lX\n",
195 (unsigned long)pDev->GetPendingEventsFunc, (unsigned long)pDev->HifMaskUmaskRecvEvent));
196
197 status = DevDisableInterrupts(pDev);
198
199 if (status) {
200 break;
201 }
202
203 status = DevSetupGMbox(pDev);
204
205 } while (false);
206
207 if (status) {
208 if (pDev->HifAttached) {
209 HIFDetachHTC(pDev->HIFDevice);
210 pDev->HifAttached = false;
211 }
212 }
213
214 return status;
215
216}
217
218int DevEnableInterrupts(struct ar6k_device *pDev)
219{
220 int status;
221 struct ar6k_irq_enable_registers regs;
222
223 LOCK_AR6K(pDev);
224
225 /* Enable all the interrupts except for the internal AR6000 CPU interrupt */
226 pDev->IrqEnableRegisters.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |
227 INT_STATUS_ENABLE_CPU_SET(0x01) |
228 INT_STATUS_ENABLE_COUNTER_SET(0x01);
229
230 if (NULL == pDev->GetPendingEventsFunc) {
231 pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
232 } else {
233 /* The HIF layer provided us with a pending events function which means that
234 * the detection of pending mbox messages is handled in the HIF layer.
235 * This is the case for the SPI2 interface.
236 * In the normal case we enable MBOX interrupts, for the case
237 * with HIFs that offer this mechanism, we keep these interrupts
238 * masked */
239 pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
240 }
241
242
243 /* Set up the CPU Interrupt Status Register */
244 pDev->IrqEnableRegisters.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00);
245
246 /* Set up the Error Interrupt Status Register */
247 pDev->IrqEnableRegisters.error_status_enable =
248 ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) |
249 ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01);
250
251 /* Set up the Counter Interrupt Status Register (only for debug interrupt to catch fatal errors) */
252 pDev->IrqEnableRegisters.counter_int_status_enable =
253 COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK);
254
255 /* copy into our temp area */
256 memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
257
258 UNLOCK_AR6K(pDev);
259
260 /* always synchronous */
261 status = HIFReadWrite(pDev->HIFDevice,
262 INT_STATUS_ENABLE_ADDRESS,
263 &regs.int_status_enable,
264 AR6K_IRQ_ENABLE_REGS_SIZE,
265 HIF_WR_SYNC_BYTE_INC,
266 NULL);
267
268 if (status) {
269 /* Can't write it for some reason */
270 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
271 ("Failed to update interrupt control registers err: %d\n", status));
272
273 }
274
275 return status;
276}
277
278int DevDisableInterrupts(struct ar6k_device *pDev)
279{
280 struct ar6k_irq_enable_registers regs;
281
282 LOCK_AR6K(pDev);
283 /* Disable all interrupts */
284 pDev->IrqEnableRegisters.int_status_enable = 0;
285 pDev->IrqEnableRegisters.cpu_int_status_enable = 0;
286 pDev->IrqEnableRegisters.error_status_enable = 0;
287 pDev->IrqEnableRegisters.counter_int_status_enable = 0;
288 /* copy into our temp area */
289 memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
290
291 UNLOCK_AR6K(pDev);
292
293 /* always synchronous */
294 return HIFReadWrite(pDev->HIFDevice,
295 INT_STATUS_ENABLE_ADDRESS,
296 &regs.int_status_enable,
297 AR6K_IRQ_ENABLE_REGS_SIZE,
298 HIF_WR_SYNC_BYTE_INC,
299 NULL);
300}
301
302/* enable device interrupts */
303int DevUnmaskInterrupts(struct ar6k_device *pDev)
304{
305 /* for good measure, make sure interrupt are disabled before unmasking at the HIF
306 * layer.
307 * The rationale here is that between device insertion (where we clear the interrupts the first time)
308 * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets.
309 * The AR6K interrupt enables reset back to an "enabled" state when this happens.
310 * */
311 int IntStatus = 0;
312 DevDisableInterrupts(pDev);
313
314#ifdef THREAD_X
315 // Tobe verified...
316 IntStatus = DevEnableInterrupts(pDev);
317 /* Unmask the host controller interrupts */
318 HIFUnMaskInterrupt(pDev->HIFDevice);
319#else
320 /* Unmask the host controller interrupts */
321 HIFUnMaskInterrupt(pDev->HIFDevice);
322 IntStatus = DevEnableInterrupts(pDev);
323#endif
324
325 return IntStatus;
326}
327
328/* disable all device interrupts */
329int DevMaskInterrupts(struct ar6k_device *pDev)
330{
331 /* mask the interrupt at the HIF layer, we don't want a stray interrupt taken while
332 * we zero out our shadow registers in DevDisableInterrupts()*/
333 HIFMaskInterrupt(pDev->HIFDevice);
334
335 return DevDisableInterrupts(pDev);
336}
337
338/* callback when our fetch to enable/disable completes */
339static void DevDoEnableDisableRecvAsyncHandler(void *Context, struct htc_packet *pPacket)
340{
341 struct ar6k_device *pDev = (struct ar6k_device *)Context;
342
343 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
344
345 if (pPacket->Status) {
346 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
347 (" Failed to disable receiver, status:%d \n", pPacket->Status));
348 }
349 /* free this IO packet */
350 AR6KFreeIOPacket(pDev,pPacket);
351 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDoEnableDisableRecvAsyncHandler \n"));
352}
353
354/* disable packet reception (used in case the host runs out of buffers)
355 * this is the "override" method when the HIF reports another methods to
356 * disable recv events */
357static int DevDoEnableDisableRecvOverride(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode)
358{
359 int status = 0;
360 struct htc_packet *pIOPacket = NULL;
361
362 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n",
363 EnableRecv,AsyncMode));
364
365 do {
366
367 if (AsyncMode) {
368
369 pIOPacket = AR6KAllocIOPacket(pDev);
370
371 if (NULL == pIOPacket) {
372 status = A_NO_MEMORY;
373 A_ASSERT(false);
374 break;
375 }
376
377 /* stick in our completion routine when the I/O operation completes */
378 pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
379 pIOPacket->pContext = pDev;
380
381 /* call the HIF layer override and do this asynchronously */
382 status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
383 EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
384 pIOPacket);
385 break;
386 }
387
388 /* if we get here we are doing it synchronously */
389 status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
390 EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
391 NULL);
392
393 } while (false);
394
395 if (status && (pIOPacket != NULL)) {
396 AR6KFreeIOPacket(pDev,pIOPacket);
397 }
398
399 return status;
400}
401
402/* disable packet reception (used in case the host runs out of buffers)
403 * this is the "normal" method using the interrupt enable registers through
404 * the host I/F */
405static int DevDoEnableDisableRecvNormal(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode)
406{
407 int status = 0;
408 struct htc_packet *pIOPacket = NULL;
409 struct ar6k_irq_enable_registers regs;
410
411 /* take the lock to protect interrupt enable shadows */
412 LOCK_AR6K(pDev);
413
414 if (EnableRecv) {
415 pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
416 } else {
417 pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
418 }
419
420 /* copy into our temp area */
421 memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
422 UNLOCK_AR6K(pDev);
423
424 do {
425
426 if (AsyncMode) {
427
428 pIOPacket = AR6KAllocIOPacket(pDev);
429
430 if (NULL == pIOPacket) {
431 status = A_NO_MEMORY;
432 A_ASSERT(false);
433 break;
434 }
435
436 /* copy values to write to our async I/O buffer */
437 memcpy(pIOPacket->pBuffer,&regs,AR6K_IRQ_ENABLE_REGS_SIZE);
438
439 /* stick in our completion routine when the I/O operation completes */
440 pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
441 pIOPacket->pContext = pDev;
442
443 /* write it out asynchronously */
444 HIFReadWrite(pDev->HIFDevice,
445 INT_STATUS_ENABLE_ADDRESS,
446 pIOPacket->pBuffer,
447 AR6K_IRQ_ENABLE_REGS_SIZE,
448 HIF_WR_ASYNC_BYTE_INC,
449 pIOPacket);
450 break;
451 }
452
453 /* if we get here we are doing it synchronously */
454
455 status = HIFReadWrite(pDev->HIFDevice,
456 INT_STATUS_ENABLE_ADDRESS,
457 &regs.int_status_enable,
458 AR6K_IRQ_ENABLE_REGS_SIZE,
459 HIF_WR_SYNC_BYTE_INC,
460 NULL);
461
462 } while (false);
463
464 if (status && (pIOPacket != NULL)) {
465 AR6KFreeIOPacket(pDev,pIOPacket);
466 }
467
468 return status;
469}
470
471
472int DevStopRecv(struct ar6k_device *pDev, bool AsyncMode)
473{
474 if (NULL == pDev->HifMaskUmaskRecvEvent) {
475 return DevDoEnableDisableRecvNormal(pDev,false,AsyncMode);
476 } else {
477 return DevDoEnableDisableRecvOverride(pDev,false,AsyncMode);
478 }
479}
480
481int DevEnableRecv(struct ar6k_device *pDev, bool AsyncMode)
482{
483 if (NULL == pDev->HifMaskUmaskRecvEvent) {
484 return DevDoEnableDisableRecvNormal(pDev,true,AsyncMode);
485 } else {
486 return DevDoEnableDisableRecvOverride(pDev,true,AsyncMode);
487 }
488}
489
490int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending)
491{
492 int status = 0;
493 u8 host_int_status = 0x0;
494 u32 counter = 0x0;
495
496 if(TimeoutInMs < 100)
497 {
498 TimeoutInMs = 100;
499 }
500
501 counter = TimeoutInMs / 100;
502
503 do
504 {
505 //Read the Host Interrupt Status Register
506 status = HIFReadWrite(pDev->HIFDevice,
507 HOST_INT_STATUS_ADDRESS,
508 &host_int_status,
509 sizeof(u8),
510 HIF_RD_SYNC_BYTE_INC,
511 NULL);
512 if (status)
513 {
514 AR_DEBUG_PRINTF(ATH_LOG_ERR,("DevWaitForPendingRecv:Read HOST_INT_STATUS_ADDRESS Failed 0x%X\n",status));
515 break;
516 }
517
518 host_int_status = !status ? (host_int_status & (1 << 0)):0;
519 if(!host_int_status)
520 {
521 status = 0;
522 *pbIsRecvPending = false;
523 break;
524 }
525 else
526 {
527 *pbIsRecvPending = true;
528 }
529
530 A_MDELAY(100);
531
532 counter--;
533
534 }while(counter);
535 return status;
536}
537
538void DevDumpRegisters(struct ar6k_device *pDev,
539 struct ar6k_irq_proc_registers *pIrqProcRegs,
540 struct ar6k_irq_enable_registers *pIrqEnableRegs)
541{
542
543 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\n<------- Register Table -------->\n"));
544
545 if (pIrqProcRegs != NULL) {
546 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
547 ("Host Int Status: 0x%x\n",pIrqProcRegs->host_int_status));
548 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
549 ("CPU Int Status: 0x%x\n",pIrqProcRegs->cpu_int_status));
550 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
551 ("Error Int Status: 0x%x\n",pIrqProcRegs->error_int_status));
552 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
553 ("Counter Int Status: 0x%x\n",pIrqProcRegs->counter_int_status));
554 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
555 ("Mbox Frame: 0x%x\n",pIrqProcRegs->mbox_frame));
556 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
557 ("Rx Lookahead Valid: 0x%x\n",pIrqProcRegs->rx_lookahead_valid));
558 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
559 ("Rx Lookahead 0: 0x%x\n",pIrqProcRegs->rx_lookahead[0]));
560 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
561 ("Rx Lookahead 1: 0x%x\n",pIrqProcRegs->rx_lookahead[1]));
562
563 if (pDev->MailBoxInfo.GMboxAddress != 0) {
564 /* if the target supports GMBOX hardware, dump some additional state */
565 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
566 ("GMBOX Host Int Status 2: 0x%x\n",pIrqProcRegs->host_int_status2));
567 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
568 ("GMBOX RX Avail: 0x%x\n",pIrqProcRegs->gmbox_rx_avail));
569 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
570 ("GMBOX lookahead alias 0: 0x%x\n",pIrqProcRegs->rx_gmbox_lookahead_alias[0]));
571 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
572 ("GMBOX lookahead alias 1: 0x%x\n",pIrqProcRegs->rx_gmbox_lookahead_alias[1]));
573 }
574
575 }
576
577 if (pIrqEnableRegs != NULL) {
578 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
579 ("Int Status Enable: 0x%x\n",pIrqEnableRegs->int_status_enable));
580 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
581 ("Counter Int Status Enable: 0x%x\n",pIrqEnableRegs->counter_int_status_enable));
582 }
583 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<------------------------------->\n"));
584}
585
586
587#define DEV_GET_VIRT_DMA_INFO(p) ((struct dev_scatter_dma_virtual_info *)((p)->HIFPrivate[0]))
588
589static struct hif_scatter_req *DevAllocScatterReq(struct hif_device *Context)
590{
591 struct dl_list *pItem;
592 struct ar6k_device *pDev = (struct ar6k_device *)Context;
593 LOCK_AR6K(pDev);
594 pItem = DL_ListRemoveItemFromHead(&pDev->ScatterReqHead);
595 UNLOCK_AR6K(pDev);
596 if (pItem != NULL) {
597 return A_CONTAINING_STRUCT(pItem, struct hif_scatter_req, ListLink);
598 }
599 return NULL;
600}
601
602static void DevFreeScatterReq(struct hif_device *Context, struct hif_scatter_req *pReq)
603{
604 struct ar6k_device *pDev = (struct ar6k_device *)Context;
605 LOCK_AR6K(pDev);
606 DL_ListInsertTail(&pDev->ScatterReqHead, &pReq->ListLink);
607 UNLOCK_AR6K(pDev);
608}
609
610int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA)
611{
612 u8 *pDMABuffer = NULL;
613 int i, remaining;
614 u32 length;
615
616 pDMABuffer = pReq->pScatterBounceBuffer;
617
618 if (pDMABuffer == NULL) {
619 A_ASSERT(false);
620 return A_EINVAL;
621 }
622
623 remaining = (int)pReq->TotalLength;
624
625 for (i = 0; i < pReq->ValidScatterEntries; i++) {
626
627 length = min((int)pReq->ScatterList[i].Length, remaining);
628
629 if (length != (int)pReq->ScatterList[i].Length) {
630 A_ASSERT(false);
631 /* there is a problem with the scatter list */
632 return A_EINVAL;
633 }
634
635 if (FromDMA) {
636 /* from DMA buffer */
637 memcpy(pReq->ScatterList[i].pBuffer, pDMABuffer , length);
638 } else {
639 /* to DMA buffer */
640 memcpy(pDMABuffer, pReq->ScatterList[i].pBuffer, length);
641 }
642
643 pDMABuffer += length;
644 remaining -= length;
645 }
646
647 return 0;
648}
649
650static void DevReadWriteScatterAsyncHandler(void *Context, struct htc_packet *pPacket)
651{
652 struct ar6k_device *pDev = (struct ar6k_device *)Context;
653 struct hif_scatter_req *pReq = (struct hif_scatter_req *)pPacket->pPktContext;
654
655 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
656
657 pReq->CompletionStatus = pPacket->Status;
658
659 AR6KFreeIOPacket(pDev,pPacket);
660
661 pReq->CompletionRoutine(pReq);
662
663 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n"));
664}
665
666static int DevReadWriteScatter(struct hif_device *Context, struct hif_scatter_req *pReq)
667{
668 struct ar6k_device *pDev = (struct ar6k_device *)Context;
669 int status = 0;
670 struct htc_packet *pIOPacket = NULL;
671 u32 request = pReq->Request;
672
673 do {
674
675 if (pReq->TotalLength > AR6K_MAX_TRANSFER_SIZE_PER_SCATTER) {
676 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
677 ("Invalid length: %d \n", pReq->TotalLength));
678 break;
679 }
680
681 if (pReq->TotalLength == 0) {
682 A_ASSERT(false);
683 break;
684 }
685
686 if (request & HIF_ASYNCHRONOUS) {
687 /* use an I/O packet to carry this request */
688 pIOPacket = AR6KAllocIOPacket(pDev);
689 if (NULL == pIOPacket) {
690 status = A_NO_MEMORY;
691 break;
692 }
693
694 /* save the request */
695 pIOPacket->pPktContext = pReq;
696 /* stick in our completion routine when the I/O operation completes */
697 pIOPacket->Completion = DevReadWriteScatterAsyncHandler;
698 pIOPacket->pContext = pDev;
699 }
700
701 if (request & HIF_WRITE) {
702 /* in virtual DMA, we are issuing the requests through the legacy HIFReadWrite API
703 * this API will adjust the address automatically for the last byte to fall on the mailbox
704 * EOM. */
705
706 /* if the address is an extended address, we can adjust the address here since the extended
707 * address will bypass the normal checks in legacy HIF layers */
708 if (pReq->Address == pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress) {
709 pReq->Address += pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize - pReq->TotalLength;
710 }
711 }
712
713 /* use legacy readwrite */
714 status = HIFReadWrite(pDev->HIFDevice,
715 pReq->Address,
716 DEV_GET_VIRT_DMA_INFO(pReq)->pVirtDmaBuffer,
717 pReq->TotalLength,
718 request,
719 (request & HIF_ASYNCHRONOUS) ? pIOPacket : NULL);
720
721 } while (false);
722
723 if ((status != A_PENDING) && status && (request & HIF_ASYNCHRONOUS)) {
724 if (pIOPacket != NULL) {
725 AR6KFreeIOPacket(pDev,pIOPacket);
726 }
727 pReq->CompletionStatus = status;
728 pReq->CompletionRoutine(pReq);
729 status = 0;
730 }
731
732 return status;
733}
734
735
736static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev)
737{
738 struct hif_scatter_req *pReq;
739
740 while (1) {
741 pReq = DevAllocScatterReq((struct hif_device *)pDev);
742 if (NULL == pReq) {
743 break;
744 }
745 kfree(pReq);
746 }
747
748}
749
750 /* function to set up virtual scatter support if HIF layer has not implemented the interface */
751static int DevSetupVirtualScatterSupport(struct ar6k_device *pDev)
752{
753 int status = 0;
754 int bufferSize, sgreqSize;
755 int i;
756 struct dev_scatter_dma_virtual_info *pVirtualInfo;
757 struct hif_scatter_req *pReq;
758
759 bufferSize = sizeof(struct dev_scatter_dma_virtual_info) +
760 2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCATTER;
761
762 sgreqSize = sizeof(struct hif_scatter_req) +
763 (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item));
764
765 for (i = 0; i < AR6K_SCATTER_REQS; i++) {
766 /* allocate the scatter request, buffer info and the actual virtual buffer itself */
767 pReq = (struct hif_scatter_req *)A_MALLOC(sgreqSize + bufferSize);
768
769 if (NULL == pReq) {
770 status = A_NO_MEMORY;
771 break;
772 }
773
774 A_MEMZERO(pReq, sgreqSize);
775
776 /* the virtual DMA starts after the scatter request struct */
777 pVirtualInfo = (struct dev_scatter_dma_virtual_info *)((u8 *)pReq + sgreqSize);
778 A_MEMZERO(pVirtualInfo, sizeof(struct dev_scatter_dma_virtual_info));
779
780 pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0];
781 /* align buffer to cache line in case host controller can actually DMA this */
782 pVirtualInfo->pVirtDmaBuffer = A_ALIGN_TO_CACHE_LINE(pVirtualInfo->pVirtDmaBuffer);
783 /* store the structure in the private area */
784 pReq->HIFPrivate[0] = pVirtualInfo;
785 /* we emulate a DMA bounce interface */
786 pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE;
787 pReq->pScatterBounceBuffer = pVirtualInfo->pVirtDmaBuffer;
788 /* free request to the list */
789 DevFreeScatterReq((struct hif_device *)pDev,pReq);
790 }
791
792 if (status) {
793 DevCleanupVirtualScatterSupport(pDev);
794 } else {
795 pDev->HifScatterInfo.pAllocateReqFunc = DevAllocScatterReq;
796 pDev->HifScatterInfo.pFreeReqFunc = DevFreeScatterReq;
797 pDev->HifScatterInfo.pReadWriteScatterFunc = DevReadWriteScatter;
798 if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) {
799 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K: SPI bus requires RX scatter limits\n"));
800 pDev->HifScatterInfo.MaxScatterEntries = AR6K_MIN_SCATTER_ENTRIES_PER_REQ;
801 pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MIN_TRANSFER_SIZE_PER_SCATTER;
802 } else {
803 pDev->HifScatterInfo.MaxScatterEntries = AR6K_SCATTER_ENTRIES_PER_REQ;
804 pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MAX_TRANSFER_SIZE_PER_SCATTER;
805 }
806 pDev->ScatterIsVirtual = true;
807 }
808
809 return status;
810}
811
812int DevCleanupMsgBundling(struct ar6k_device *pDev)
813{
814 if(NULL != pDev)
815 {
816 DevCleanupVirtualScatterSupport(pDev);
817 }
818
819 return 0;
820}
821
822int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer)
823{
824 int status;
825
826 if (pDev->MailBoxInfo.Flags & HIF_MBOX_FLAG_NO_BUNDLING) {
827 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HIF requires bundling disabled\n"));
828 return A_ENOTSUP;
829 }
830
831 status = HIFConfigureDevice(pDev->HIFDevice,
832 HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT,
833 &pDev->HifScatterInfo,
834 sizeof(pDev->HifScatterInfo));
835
836 if (status) {
837 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
838 ("AR6K: ** HIF layer does not support scatter requests (%d) \n",status));
839
840 /* we can try to use a virtual DMA scatter mechanism using legacy HIFReadWrite() */
841 status = DevSetupVirtualScatterSupport(pDev);
842
843 if (!status) {
844 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
845 ("AR6K: virtual scatter transfers enabled (max scatter items:%d: maxlen:%d) \n",
846 DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev)));
847 }
848
849 } else {
850 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
851 ("AR6K: HIF layer supports scatter requests (max scatter items:%d: maxlen:%d) \n",
852 DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev)));
853 }
854
855 if (!status) {
856 /* for the recv path, the maximum number of bytes per recv bundle is just limited
857 * by the maximum transfer size at the HIF layer */
858 pDev->MaxRecvBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq;
859
860 if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) {
861 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K : SPI bus requires TX bundling disabled\n"));
862 pDev->MaxSendBundleSize = 0;
863 } else {
864 /* for the send path, the max transfer size is limited by the existence and size of
865 * the extended mailbox address range */
866 if (pDev->MailBoxInfo.MboxProp[0].ExtendedAddress != 0) {
867 pDev->MaxSendBundleSize = pDev->MailBoxInfo.MboxProp[0].ExtendedSize;
868 } else {
869 /* legacy */
870 pDev->MaxSendBundleSize = AR6K_LEGACY_MAX_WRITE_LENGTH;
871 }
872
873 if (pDev->MaxSendBundleSize > pDev->HifScatterInfo.MaxTransferSizePerScatterReq) {
874 /* limit send bundle size to what the HIF can support for scatter requests */
875 pDev->MaxSendBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq;
876 }
877 }
878
879 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
880 ("AR6K: max recv: %d max send: %d \n",
881 DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev), DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev)));
882
883 }
884 return status;
885}
886
887int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async)
888{
889 int status;
890
891 if (Read) {
892 /* read operation */
893 pScatterReq->Request = (Async) ? HIF_RD_ASYNC_BLOCK_FIX : HIF_RD_SYNC_BLOCK_FIX;
894 pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX];
895 A_ASSERT(pScatterReq->TotalLength <= (u32)DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev));
896 } else {
897 u32 mailboxWidth;
898
899 /* write operation */
900 pScatterReq->Request = (Async) ? HIF_WR_ASYNC_BLOCK_INC : HIF_WR_SYNC_BLOCK_INC;
901 A_ASSERT(pScatterReq->TotalLength <= (u32)DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev));
902 if (pScatterReq->TotalLength > AR6K_LEGACY_MAX_WRITE_LENGTH) {
903 /* for large writes use the extended address */
904 pScatterReq->Address = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress;
905 mailboxWidth = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize;
906 } else {
907 pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX];
908 mailboxWidth = AR6K_LEGACY_MAX_WRITE_LENGTH;
909 }
910
911 if (!pDev->ScatterIsVirtual) {
912 /* we are passing this scatter list down to the HIF layer' scatter request handler, fixup the address
913 * so that the last byte falls on the EOM, we do this for those HIFs that support the
914 * scatter API */
915 pScatterReq->Address += (mailboxWidth - pScatterReq->TotalLength);
916 }
917
918 }
919
920 AR_DEBUG_PRINTF(ATH_DEBUG_RECV | ATH_DEBUG_SEND,
921 ("DevSubmitScatterRequest, Entries: %d, Total Length: %d Mbox:0x%X (mode: %s : %s)\n",
922 pScatterReq->ValidScatterEntries,
923 pScatterReq->TotalLength,
924 pScatterReq->Address,
925 Async ? "ASYNC" : "SYNC",
926 (Read) ? "RD" : "WR"));
927
928 status = DEV_PREPARE_SCATTER_OPERATION(pScatterReq);
929
930 if (status) {
931 if (Async) {
932 pScatterReq->CompletionStatus = status;
933 pScatterReq->CompletionRoutine(pScatterReq);
934 return 0;
935 }
936 return status;
937 }
938
939 status = pDev->HifScatterInfo.pReadWriteScatterFunc(pDev->ScatterIsVirtual ? pDev : pDev->HIFDevice,
940 pScatterReq);
941 if (!Async) {
942 /* in sync mode, we can touch the scatter request */
943 pScatterReq->CompletionStatus = status;
944 DEV_FINISH_SCATTER_OPERATION(pScatterReq);
945 } else {
946 if (status == A_PENDING) {
947 status = 0;
948 }
949 }
950
951 return status;
952}
953
954
955#ifdef MBOXHW_UNIT_TEST
956
957
958/* This is a mailbox hardware unit test that must be called in a schedulable context
959 * This test is very simple, it will send a list of buffers with a counting pattern
960 * and the target will invert the data and send the message back
961 *
962 * the unit test has the following constraints:
963 *
964 * The target has at least 8 buffers of 256 bytes each. The host will send
965 * the following pattern of buffers in rapid succession :
966 *
967 * 1 buffer - 128 bytes
968 * 1 buffer - 256 bytes
969 * 1 buffer - 512 bytes
970 * 1 buffer - 1024 bytes
971 *
972 * The host will send the buffers to one mailbox and wait for buffers to be reflected
973 * back from the same mailbox. The target sends the buffers FIFO order.
974 * Once the final buffer has been received for a mailbox, the next mailbox is tested.
975 *
976 *
977 * Note: To simplifythe test , we assume that the chosen buffer sizes
978 * will fall on a nice block pad
979 *
980 * It is expected that higher-order tests will be written to stress the mailboxes using
981 * a message-based protocol (with some performance timming) that can create more
982 * randomness in the packets sent over mailboxes.
983 *
984 * */
985
986#define A_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1))
987
988#define BUFFER_BLOCK_PAD 128
989
990#if 0
991#define BUFFER1 128
992#define BUFFER2 256
993#define BUFFER3 512
994#define BUFFER4 1024
995#endif
996
997#if 1
998#define BUFFER1 80
999#define BUFFER2 200
1000#define BUFFER3 444
1001#define BUFFER4 800
1002#endif
1003
1004#define TOTAL_BYTES (A_ROUND_UP_PWR2(BUFFER1,BUFFER_BLOCK_PAD) + \
1005 A_ROUND_UP_PWR2(BUFFER2,BUFFER_BLOCK_PAD) + \
1006 A_ROUND_UP_PWR2(BUFFER3,BUFFER_BLOCK_PAD) + \
1007 A_ROUND_UP_PWR2(BUFFER4,BUFFER_BLOCK_PAD) )
1008
1009#define TEST_BYTES (BUFFER1 + BUFFER2 + BUFFER3 + BUFFER4)
1010
1011#define TEST_CREDITS_RECV_TIMEOUT 100
1012
1013static u8 g_Buffer[TOTAL_BYTES];
1014static u32 g_MailboxAddrs[AR6K_MAILBOXES];
1015static u32 g_BlockSizes[AR6K_MAILBOXES];
1016
1017#define BUFFER_PROC_LIST_DEPTH 4
1018
1019struct buffer_proc_list {
1020 u8 *pBuffer;
1021 u32 length;
1022};
1023
1024
1025#define PUSH_BUFF_PROC_ENTRY(pList,len,pCurrpos) \
1026{ \
1027 (pList)->pBuffer = (pCurrpos); \
1028 (pList)->length = (len); \
1029 (pCurrpos) += (len); \
1030 (pList)++; \
1031}
1032
1033/* a simple and crude way to send different "message" sizes */
1034static void AssembleBufferList(struct buffer_proc_list *pList)
1035{
1036 u8 *pBuffer = g_Buffer;
1037
1038#if BUFFER_PROC_LIST_DEPTH < 4
1039#error "Buffer processing list depth is not deep enough!!"
1040#endif
1041
1042 PUSH_BUFF_PROC_ENTRY(pList,BUFFER1,pBuffer);
1043 PUSH_BUFF_PROC_ENTRY(pList,BUFFER2,pBuffer);
1044 PUSH_BUFF_PROC_ENTRY(pList,BUFFER3,pBuffer);
1045 PUSH_BUFF_PROC_ENTRY(pList,BUFFER4,pBuffer);
1046
1047}
1048
1049#define FILL_ZERO true
1050#define FILL_COUNTING false
1051static void InitBuffers(bool Zero)
1052{
1053 u16 *pBuffer16 = (u16 *)g_Buffer;
1054 int i;
1055
1056 /* fill buffer with 16 bit counting pattern or zeros */
1057 for (i = 0; i < (TOTAL_BYTES / 2) ; i++) {
1058 if (!Zero) {
1059 pBuffer16[i] = (u16)i;
1060 } else {
1061 pBuffer16[i] = 0;
1062 }
1063 }
1064}
1065
1066
1067static bool CheckOneBuffer(u16 *pBuffer16, int Length)
1068{
1069 int i;
1070 u16 startCount;
1071 bool success = true;
1072
1073 /* get the starting count */
1074 startCount = pBuffer16[0];
1075 /* invert it, this is the expected value */
1076 startCount = ~startCount;
1077 /* scan the buffer and verify */
1078 for (i = 0; i < (Length / 2) ; i++,startCount++) {
1079 /* target will invert all the data */
1080 if ((u16)pBuffer16[i] != (u16)~startCount) {
1081 success = false;
1082 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Data Got:0x%X, Expecting:0x%X (offset:%d, total:%d) \n",
1083 pBuffer16[i], ((u16)~startCount), i, Length));
1084 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("0x%X 0x%X 0x%X 0x%X \n",
1085 pBuffer16[i], pBuffer16[i + 1], pBuffer16[i + 2],pBuffer16[i+3]));
1086 break;
1087 }
1088 }
1089
1090 return success;
1091}
1092
1093static bool CheckBuffers(void)
1094{
1095 int i;
1096 bool success = true;
1097 struct buffer_proc_list checkList[BUFFER_PROC_LIST_DEPTH];
1098
1099 /* assemble the list */
1100 AssembleBufferList(checkList);
1101
1102 /* scan the buffers and verify */
1103 for (i = 0; i < BUFFER_PROC_LIST_DEPTH ; i++) {
1104 success = CheckOneBuffer((u16 *)checkList[i].pBuffer, checkList[i].length);
1105 if (!success) {
1106 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer : 0x%X, Length:%d failed verify \n",
1107 (u32)checkList[i].pBuffer, checkList[i].length));
1108 break;
1109 }
1110 }
1111
1112 return success;
1113}
1114
1115 /* find the end marker for the last buffer we will be sending */
1116static u16 GetEndMarker(void)
1117{
1118 u8 *pBuffer;
1119 struct buffer_proc_list checkList[BUFFER_PROC_LIST_DEPTH];
1120
1121 /* fill up buffers with the normal counting pattern */
1122 InitBuffers(FILL_COUNTING);
1123
1124 /* assemble the list we will be sending down */
1125 AssembleBufferList(checkList);
1126 /* point to the last 2 bytes of the last buffer */
1127 pBuffer = &(checkList[BUFFER_PROC_LIST_DEPTH - 1].pBuffer[(checkList[BUFFER_PROC_LIST_DEPTH - 1].length) - 2]);
1128
1129 /* the last count in the last buffer is the marker */
1130 return (u16)pBuffer[0] | ((u16)pBuffer[1] << 8);
1131}
1132
1133#define ATH_PRINT_OUT_ZONE ATH_DEBUG_ERR
1134
1135/* send the ordered buffers to the target */
1136static int SendBuffers(struct ar6k_device *pDev, int mbox)
1137{
1138 int status = 0;
1139 u32 request = HIF_WR_SYNC_BLOCK_INC;
1140 struct buffer_proc_list sendList[BUFFER_PROC_LIST_DEPTH];
1141 int i;
1142 int totalBytes = 0;
1143 int paddedLength;
1144 int totalwPadding = 0;
1145
1146 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sending buffers on mailbox : %d \n",mbox));
1147
1148 /* fill buffer with counting pattern */
1149 InitBuffers(FILL_COUNTING);
1150
1151 /* assemble the order in which we send */
1152 AssembleBufferList(sendList);
1153
1154 for (i = 0; i < BUFFER_PROC_LIST_DEPTH; i++) {
1155
1156 /* we are doing block transfers, so we need to pad everything to a block size */
1157 paddedLength = (sendList[i].length + (g_BlockSizes[mbox] - 1)) &
1158 (~(g_BlockSizes[mbox] - 1));
1159
1160 /* send each buffer synchronously */
1161 status = HIFReadWrite(pDev->HIFDevice,
1162 g_MailboxAddrs[mbox],
1163 sendList[i].pBuffer,
1164 paddedLength,
1165 request,
1166 NULL);
1167 if (status) {
1168 break;
1169 }
1170 totalBytes += sendList[i].length;
1171 totalwPadding += paddedLength;
1172 }
1173
1174 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sent %d bytes (%d padded bytes) to mailbox : %d \n",totalBytes,totalwPadding,mbox));
1175
1176 return status;
1177}
1178
1179/* poll the mailbox credit counter until we get a credit or timeout */
1180static int GetCredits(struct ar6k_device *pDev, int mbox, int *pCredits)
1181{
1182 int status = 0;
1183 int timeout = TEST_CREDITS_RECV_TIMEOUT;
1184 u8 credits = 0;
1185 u32 address;
1186
1187 while (true) {
1188
1189 /* Read the counter register to get credits, this auto-decrements */
1190 address = COUNT_DEC_ADDRESS + (AR6K_MAILBOXES + mbox) * 4;
1191 status = HIFReadWrite(pDev->HIFDevice, address, &credits, sizeof(credits),
1192 HIF_RD_SYNC_BYTE_FIX, NULL);
1193 if (status) {
1194 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1195 ("Unable to decrement the command credit count register (mbox=%d)\n",mbox));
1196 status = A_ERROR;
1197 break;
1198 }
1199
1200 if (credits) {
1201 break;
1202 }
1203
1204 timeout--;
1205
1206 if (timeout <= 0) {
1207 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1208 (" Timeout reading credit registers (mbox=%d, address:0x%X) \n",mbox,address));
1209 status = A_ERROR;
1210 break;
1211 }
1212
1213 /* delay a little, target may not be ready */
1214 A_MDELAY(1000);
1215
1216 }
1217
1218 if (status == 0) {
1219 *pCredits = credits;
1220 }
1221
1222 return status;
1223}
1224
1225
1226/* wait for the buffers to come back */
1227static int RecvBuffers(struct ar6k_device *pDev, int mbox)
1228{
1229 int status = 0;
1230 u32 request = HIF_RD_SYNC_BLOCK_INC;
1231 struct buffer_proc_list recvList[BUFFER_PROC_LIST_DEPTH];
1232 int curBuffer;
1233 int credits;
1234 int i;
1235 int totalBytes = 0;
1236 int paddedLength;
1237 int totalwPadding = 0;
1238
1239 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for buffers on mailbox : %d \n",mbox));
1240
1241 /* zero the buffers */
1242 InitBuffers(FILL_ZERO);
1243
1244 /* assemble the order in which we should receive */
1245 AssembleBufferList(recvList);
1246
1247 curBuffer = 0;
1248
1249 while (curBuffer < BUFFER_PROC_LIST_DEPTH) {
1250
1251 /* get number of buffers that have been completed, this blocks
1252 * until we get at least 1 credit or it times out */
1253 status = GetCredits(pDev, mbox, &credits);
1254
1255 if (status) {
1256 break;
1257 }
1258
1259 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got %d messages on mailbox : %d \n",credits, mbox));
1260
1261 /* get all the buffers that are sitting on the queue */
1262 for (i = 0; i < credits; i++) {
1263 A_ASSERT(curBuffer < BUFFER_PROC_LIST_DEPTH);
1264 /* recv the current buffer synchronously, the buffers should come back in
1265 * order... with padding applied by the target */
1266 paddedLength = (recvList[curBuffer].length + (g_BlockSizes[mbox] - 1)) &
1267 (~(g_BlockSizes[mbox] - 1));
1268
1269 status = HIFReadWrite(pDev->HIFDevice,
1270 g_MailboxAddrs[mbox],
1271 recvList[curBuffer].pBuffer,
1272 paddedLength,
1273 request,
1274 NULL);
1275 if (status) {
1276 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to read %d bytes on mailbox:%d : address:0x%X \n",
1277 recvList[curBuffer].length, mbox, g_MailboxAddrs[mbox]));
1278 break;
1279 }
1280
1281 totalwPadding += paddedLength;
1282 totalBytes += recvList[curBuffer].length;
1283 curBuffer++;
1284 }
1285
1286 if (status) {
1287 break;
1288 }
1289 /* go back and get some more */
1290 credits = 0;
1291 }
1292
1293 if (totalBytes != TEST_BYTES) {
1294 A_ASSERT(false);
1295 } else {
1296 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got all buffers on mbox:%d total recv :%d (w/Padding : %d) \n",
1297 mbox, totalBytes, totalwPadding));
1298 }
1299
1300 return status;
1301
1302
1303}
1304
1305static int DoOneMboxHWTest(struct ar6k_device *pDev, int mbox)
1306{
1307 int status;
1308
1309 do {
1310 /* send out buffers */
1311 status = SendBuffers(pDev,mbox);
1312
1313 if (status) {
1314 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Sending buffers Failed : %d mbox:%d\n",status,mbox));
1315 break;
1316 }
1317
1318 /* go get them, this will block */
1319 status = RecvBuffers(pDev, mbox);
1320
1321 if (status) {
1322 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Recv buffers Failed : %d mbox:%d\n",status,mbox));
1323 break;
1324 }
1325
1326 /* check the returned data patterns */
1327 if (!CheckBuffers()) {
1328 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer Verify Failed : mbox:%d\n",mbox));
1329 status = A_ERROR;
1330 break;
1331 }
1332
1333 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" Send/Recv success! mailbox : %d \n",mbox));
1334
1335 } while (false);
1336
1337 return status;
1338}
1339
1340/* here is where the test starts */
1341int DoMboxHWTest(struct ar6k_device *pDev)
1342{
1343 int i;
1344 int status;
1345 int credits = 0;
1346 u8 params[4];
1347 int numBufs;
1348 int bufferSize;
1349 u16 temp;
1350
1351
1352 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest START - \n"));
1353
1354 do {
1355 /* get the addresses for all 4 mailboxes */
1356 status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
1357 g_MailboxAddrs, sizeof(g_MailboxAddrs));
1358
1359 if (status) {
1360 A_ASSERT(false);
1361 break;
1362 }
1363
1364 /* get the block sizes */
1365 status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
1366 g_BlockSizes, sizeof(g_BlockSizes));
1367
1368 if (status) {
1369 A_ASSERT(false);
1370 break;
1371 }
1372
1373 /* note, the HIF layer usually reports mbox 0 to have a block size of
1374 * 1, but our test wants to run in block-mode for all mailboxes, so we treat all mailboxes
1375 * the same. */
1376 g_BlockSizes[0] = g_BlockSizes[1];
1377 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Block Size to use: %d \n",g_BlockSizes[0]));
1378
1379 if (g_BlockSizes[1] > BUFFER_BLOCK_PAD) {
1380 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("%d Block size is too large for buffer pad %d\n",
1381 g_BlockSizes[1], BUFFER_BLOCK_PAD));
1382 break;
1383 }
1384
1385 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for target.... \n"));
1386
1387 /* the target lets us know it is ready by giving us 1 credit on
1388 * mailbox 0 */
1389 status = GetCredits(pDev, 0, &credits);
1390
1391 if (status) {
1392 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait for target ready \n"));
1393 break;
1394 }
1395
1396 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Target is ready ...\n"));
1397
1398 /* read the first 4 scratch registers */
1399 status = HIFReadWrite(pDev->HIFDevice,
1400 SCRATCH_ADDRESS,
1401 params,
1402 4,
1403 HIF_RD_SYNC_BYTE_INC,
1404 NULL);
1405
1406 if (status) {
1407 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait get parameters \n"));
1408 break;
1409 }
1410
1411 numBufs = params[0];
1412 bufferSize = (int)(((u16)params[2] << 8) | (u16)params[1]);
1413
1414 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE,
1415 ("Target parameters: bufs per mailbox:%d, buffer size:%d bytes (total space: %d, minimum required space (w/padding): %d) \n",
1416 numBufs, bufferSize, (numBufs * bufferSize), TOTAL_BYTES));
1417
1418 if ((numBufs * bufferSize) < TOTAL_BYTES) {
1419 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Not Enough buffer space to run test! need:%d, got:%d \n",
1420 TOTAL_BYTES, (numBufs*bufferSize)));
1421 status = A_ERROR;
1422 break;
1423 }
1424
1425 temp = GetEndMarker();
1426
1427 status = HIFReadWrite(pDev->HIFDevice,
1428 SCRATCH_ADDRESS + 4,
1429 (u8 *)&temp,
1430 2,
1431 HIF_WR_SYNC_BYTE_INC,
1432 NULL);
1433
1434 if (status) {
1435 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write end marker \n"));
1436 break;
1437 }
1438
1439 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("End Marker: 0x%X \n",temp));
1440
1441 temp = (u16)g_BlockSizes[1];
1442 /* convert to a mask */
1443 temp = temp - 1;
1444 status = HIFReadWrite(pDev->HIFDevice,
1445 SCRATCH_ADDRESS + 6,
1446 (u8 *)&temp,
1447 2,
1448 HIF_WR_SYNC_BYTE_INC,
1449 NULL);
1450
1451 if (status) {
1452 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write block mask \n"));
1453 break;
1454 }
1455
1456 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Set Block Mask: 0x%X \n",temp));
1457
1458 /* execute the test on each mailbox */
1459 for (i = 0; i < AR6K_MAILBOXES; i++) {
1460 status = DoOneMboxHWTest(pDev, i);
1461 if (status) {
1462 break;
1463 }
1464 }
1465
1466 } while (false);
1467
1468 if (status == 0) {
1469 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - SUCCESS! - \n"));
1470 } else {
1471 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - FAILED! - \n"));
1472 }
1473 /* don't let HTC_Start continue, the target is actually not running any HTC code */
1474 return A_ERROR;
1475}
1476#endif
1477
1478
1479
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h
new file mode 100644
index 00000000000..e551dbe674d
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h
@@ -0,0 +1,401 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6k.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// AR6K device layer that handles register level I/O
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef AR6K_H_
26#define AR6K_H_
27
28#include "hci_transport_api.h"
29#include "../htc_debug.h"
30
31#define AR6K_MAILBOXES 4
32
33/* HTC runs over mailbox 0 */
34#define HTC_MAILBOX 0
35
36#define AR6K_TARGET_DEBUG_INTR_MASK 0x01
37
38#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \
39 INT_STATUS_ENABLE_CPU_MASK | \
40 INT_STATUS_ENABLE_COUNTER_MASK)
41
42
43//#define MBOXHW_UNIT_TEST 1
44
45PREPACK struct ar6k_irq_proc_registers {
46 u8 host_int_status;
47 u8 cpu_int_status;
48 u8 error_int_status;
49 u8 counter_int_status;
50 u8 mbox_frame;
51 u8 rx_lookahead_valid;
52 u8 host_int_status2;
53 u8 gmbox_rx_avail;
54 u32 rx_lookahead[2];
55 u32 rx_gmbox_lookahead_alias[2];
56} POSTPACK;
57
58#define AR6K_IRQ_PROC_REGS_SIZE sizeof(struct ar6k_irq_proc_registers)
59
60PREPACK struct ar6k_irq_enable_registers {
61 u8 int_status_enable;
62 u8 cpu_int_status_enable;
63 u8 error_status_enable;
64 u8 counter_int_status_enable;
65} POSTPACK;
66
67PREPACK struct ar6k_gmbox_ctrl_registers {
68 u8 int_status_enable;
69} POSTPACK;
70
71#define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(struct ar6k_irq_enable_registers)
72
73#define AR6K_REG_IO_BUFFER_SIZE 32
74#define AR6K_MAX_REG_IO_BUFFERS 8
75#define FROM_DMA_BUFFER true
76#define TO_DMA_BUFFER false
77#define AR6K_SCATTER_ENTRIES_PER_REQ 16
78#define AR6K_MAX_TRANSFER_SIZE_PER_SCATTER 16*1024
79#define AR6K_SCATTER_REQS 4
80#define AR6K_LEGACY_MAX_WRITE_LENGTH 2048
81
82#ifndef A_CACHE_LINE_PAD
83#define A_CACHE_LINE_PAD 128
84#endif
85#define AR6K_MIN_SCATTER_ENTRIES_PER_REQ 2
86#define AR6K_MIN_TRANSFER_SIZE_PER_SCATTER 4*1024
87
88/* buffers for ASYNC I/O */
89struct ar6k_async_reg_io_buffer {
90 struct htc_packet HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */
91 u8 _Pad1[A_CACHE_LINE_PAD];
92 u8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; /* cache-line safe with pads around */
93 u8 _Pad2[A_CACHE_LINE_PAD];
94};
95
96struct ar6k_gmbox_info {
97 void *pProtocolContext;
98 int (*pMessagePendingCallBack)(void *pContext, u8 LookAheadBytes[], int ValidBytes);
99 int (*pCreditsPendingCallback)(void *pContext, int NumCredits, bool CreditIRQEnabled);
100 void (*pTargetFailureCallback)(void *pContext, int Status);
101 void (*pStateDumpCallback)(void *pContext);
102 bool CreditCountIRQEnabled;
103};
104
105struct ar6k_device {
106 A_MUTEX_T Lock;
107 u8 _Pad1[A_CACHE_LINE_PAD];
108 struct ar6k_irq_proc_registers IrqProcRegisters; /* cache-line safe with pads around */
109 u8 _Pad2[A_CACHE_LINE_PAD];
110 struct ar6k_irq_enable_registers IrqEnableRegisters; /* cache-line safe with pads around */
111 u8 _Pad3[A_CACHE_LINE_PAD];
112 void *HIFDevice;
113 u32 BlockSize;
114 u32 BlockMask;
115 struct hif_device_mbox_info MailBoxInfo;
116 HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc;
117 void *HTCContext;
118 struct htc_packet_queue RegisterIOList;
119 struct ar6k_async_reg_io_buffer RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS];
120 void (*TargetFailureCallback)(void *Context);
121 int (*MessagePendingCallback)(void *Context,
122 u32 LookAheads[],
123 int NumLookAheads,
124 bool *pAsyncProc,
125 int *pNumPktsFetched);
126 HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode;
127 HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent;
128 bool HifAttached;
129 struct hif_device_irq_yield_params HifIRQYieldParams;
130 bool DSRCanYield;
131 int CurrentDSRRecvCount;
132 struct hif_device_scatter_support_info HifScatterInfo;
133 struct dl_list ScatterReqHead;
134 bool ScatterIsVirtual;
135 int MaxRecvBundleSize;
136 int MaxSendBundleSize;
137 struct ar6k_gmbox_info GMboxInfo;
138 bool GMboxEnabled;
139 struct ar6k_gmbox_ctrl_registers GMboxControlRegisters;
140 int RecheckIRQStatusCnt;
141};
142
143#define LOCK_AR6K(p) A_MUTEX_LOCK(&(p)->Lock);
144#define UNLOCK_AR6K(p) A_MUTEX_UNLOCK(&(p)->Lock);
145#define REF_IRQ_STATUS_RECHECK(p) (p)->RecheckIRQStatusCnt = 1 /* note: no need to lock this, it only gets set */
146
147int DevSetup(struct ar6k_device *pDev);
148void DevCleanup(struct ar6k_device *pDev);
149int DevUnmaskInterrupts(struct ar6k_device *pDev);
150int DevMaskInterrupts(struct ar6k_device *pDev);
151int DevPollMboxMsgRecv(struct ar6k_device *pDev,
152 u32 *pLookAhead,
153 int TimeoutMS);
154int DevRWCompletionHandler(void *context, int status);
155int DevDsrHandler(void *context);
156int DevCheckPendingRecvMsgsAsync(void *context);
157void DevAsyncIrqProcessComplete(struct ar6k_device *pDev);
158void DevDumpRegisters(struct ar6k_device *pDev,
159 struct ar6k_irq_proc_registers *pIrqProcRegs,
160 struct ar6k_irq_enable_registers *pIrqEnableRegs);
161
162#define DEV_STOP_RECV_ASYNC true
163#define DEV_STOP_RECV_SYNC false
164#define DEV_ENABLE_RECV_ASYNC true
165#define DEV_ENABLE_RECV_SYNC false
166int DevStopRecv(struct ar6k_device *pDev, bool ASyncMode);
167int DevEnableRecv(struct ar6k_device *pDev, bool ASyncMode);
168int DevEnableInterrupts(struct ar6k_device *pDev);
169int DevDisableInterrupts(struct ar6k_device *pDev);
170int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending);
171
172#define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask)))
173#define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length)
174#define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0)
175
176static INLINE int DevSendPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 SendLength) {
177 u32 paddedLength;
178 bool sync = (pPacket->Completion == NULL) ? true : false;
179 int status;
180
181 /* adjust the length to be a multiple of block size if appropriate */
182 paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, SendLength);
183
184#if 0
185 if (paddedLength > pPacket->BufferLength) {
186 A_ASSERT(false);
187 if (pPacket->Completion != NULL) {
188 COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
189 return 0;
190 }
191 return A_EINVAL;
192 }
193#endif
194
195 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
196 ("DevSendPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n",
197 paddedLength,
198 pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
199 sync ? "SYNC" : "ASYNC"));
200
201 status = HIFReadWrite(pDev->HIFDevice,
202 pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
203 pPacket->pBuffer,
204 paddedLength, /* the padded length */
205 sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
206 sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
207
208 if (sync) {
209 pPacket->Status = status;
210 } else {
211 if (status == A_PENDING) {
212 status = 0;
213 }
214 }
215
216 return status;
217}
218
219static INLINE int DevRecvPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 RecvLength) {
220 u32 paddedLength;
221 int status;
222 bool sync = (pPacket->Completion == NULL) ? true : false;
223
224 /* adjust the length to be a multiple of block size if appropriate */
225 paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength);
226
227 if (paddedLength > pPacket->BufferLength) {
228 A_ASSERT(false);
229 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
230 ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
231 paddedLength,RecvLength,pPacket->BufferLength));
232 if (pPacket->Completion != NULL) {
233 COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
234 return 0;
235 }
236 return A_EINVAL;
237 }
238
239 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
240 ("DevRecvPacket (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
241 (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
242 paddedLength,
243 pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
244 sync ? "SYNC" : "ASYNC"));
245
246 status = HIFReadWrite(pDev->HIFDevice,
247 pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
248 pPacket->pBuffer,
249 paddedLength,
250 sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
251 sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
252
253 if (sync) {
254 pPacket->Status = status;
255 }
256
257 return status;
258}
259
260#define DEV_CHECK_RECV_YIELD(pDev) \
261 ((pDev)->CurrentDSRRecvCount >= (pDev)->HifIRQYieldParams.RecvPacketYieldCount)
262
263#define IS_DEV_IRQ_PROC_SYNC_MODE(pDev) (HIF_DEVICE_IRQ_SYNC_ONLY == (pDev)->HifIRQProcessingMode)
264#define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY)
265
266/**************************************************/
267/****** Scatter Function and Definitions
268 *
269 *
270 */
271
272int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA);
273
274 /* copy any READ data back into scatter list */
275#define DEV_FINISH_SCATTER_OPERATION(pR) \
276do { \
277 if (!((pR)->CompletionStatus) && \
278 !((pR)->Request & HIF_WRITE) && \
279 ((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { \
280 (pR)->CompletionStatus = \
281 DevCopyScatterListToFromDMABuffer((pR), \
282 FROM_DMA_BUFFER); \
283 } \
284} while (0)
285
286 /* copy any WRITE data to bounce buffer */
287static INLINE int DEV_PREPARE_SCATTER_OPERATION(struct hif_scatter_req *pReq) {
288 if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) {
289 return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER);
290 } else {
291 return 0;
292 }
293}
294
295
296int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer);
297
298int DevCleanupMsgBundling(struct ar6k_device *pDev);
299
300#define DEV_GET_MAX_MSG_PER_BUNDLE(pDev) (pDev)->HifScatterInfo.MaxScatterEntries
301#define DEV_GET_MAX_BUNDLE_LENGTH(pDev) (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq
302#define DEV_ALLOC_SCATTER_REQ(pDev) \
303 (pDev)->HifScatterInfo.pAllocateReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice)
304
305#define DEV_FREE_SCATTER_REQ(pDev,pR) \
306 (pDev)->HifScatterInfo.pFreeReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice,(pR))
307
308#define DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev) (pDev)->MaxRecvBundleSize
309#define DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev) (pDev)->MaxSendBundleSize
310
311#define DEV_SCATTER_READ true
312#define DEV_SCATTER_WRITE false
313#define DEV_SCATTER_ASYNC true
314#define DEV_SCATTER_SYNC false
315int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async);
316
317#ifdef MBOXHW_UNIT_TEST
318int DoMboxHWTest(struct ar6k_device *pDev);
319#endif
320
321 /* completely virtual */
322struct dev_scatter_dma_virtual_info {
323 u8 *pVirtDmaBuffer; /* dma-able buffer - CPU accessible address */
324 u8 DataArea[1]; /* start of data area */
325};
326
327
328
329void DumpAR6KDevState(struct ar6k_device *pDev);
330
331/**************************************************/
332/****** GMBOX functions and definitions
333 *
334 *
335 */
336
337#ifdef ATH_AR6K_ENABLE_GMBOX
338
339void DevCleanupGMbox(struct ar6k_device *pDev);
340int DevSetupGMbox(struct ar6k_device *pDev);
341int DevCheckGMboxInterrupts(struct ar6k_device *pDev);
342void DevNotifyGMboxTargetFailure(struct ar6k_device *pDev);
343
344#else
345
346 /* compiled out */
347#define DevCleanupGMbox(p)
348#define DevCheckGMboxInterrupts(p) 0
349#define DevNotifyGMboxTargetFailure(p)
350
351static INLINE int DevSetupGMbox(struct ar6k_device *pDev) {
352 pDev->GMboxEnabled = false;
353 return 0;
354}
355
356#endif
357
358#ifdef ATH_AR6K_ENABLE_GMBOX
359
360 /* GMBOX protocol modules must expose each of these internal APIs */
361HCI_TRANSPORT_HANDLE GMboxAttachProtocol(struct ar6k_device *pDev, struct hci_transport_config_info *pInfo);
362int GMboxProtocolInstall(struct ar6k_device *pDev);
363void GMboxProtocolUninstall(struct ar6k_device *pDev);
364
365 /* API used by GMBOX protocol modules */
366struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle);
367#define DEV_GMBOX_SET_PROTOCOL(pDev,recv_callback,credits_pending,failure,statedump,context) \
368{ \
369 (pDev)->GMboxInfo.pProtocolContext = (context); \
370 (pDev)->GMboxInfo.pMessagePendingCallBack = (recv_callback); \
371 (pDev)->GMboxInfo.pCreditsPendingCallback = (credits_pending); \
372 (pDev)->GMboxInfo.pTargetFailureCallback = (failure); \
373 (pDev)->GMboxInfo.pStateDumpCallback = (statedump); \
374}
375
376#define DEV_GMBOX_GET_PROTOCOL(pDev) (pDev)->GMboxInfo.pProtocolContext
377
378int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength);
379int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength);
380
381#define PROC_IO_ASYNC true
382#define PROC_IO_SYNC false
383typedef enum GMBOX_IRQ_ACTION_TYPE {
384 GMBOX_ACTION_NONE = 0,
385 GMBOX_DISABLE_ALL,
386 GMBOX_ERRORS_IRQ_ENABLE,
387 GMBOX_RECV_IRQ_ENABLE,
388 GMBOX_RECV_IRQ_DISABLE,
389 GMBOX_CREDIT_IRQ_ENABLE,
390 GMBOX_CREDIT_IRQ_DISABLE,
391} GMBOX_IRQ_ACTION_TYPE;
392
393int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode);
394int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits);
395int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize);
396int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes);
397int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int SignalNumber, int AckTimeoutMS);
398
399#endif
400
401#endif /*AR6K_H_*/
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c
new file mode 100644
index 00000000000..d7af68f7056
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c
@@ -0,0 +1,783 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6k_events.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// AR6K Driver layer event handling (i.e. interrupts, message polling)
22//
23// Author(s): ="Atheros"
24//==============================================================================
25
26#include "a_config.h"
27#include "athdefs.h"
28#include "hw/mbox_host_reg.h"
29#include "a_osapi.h"
30#include "../htc_debug.h"
31#include "hif.h"
32#include "htc_packet.h"
33#include "ar6k.h"
34
35extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket);
36extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev);
37
38static int DevServiceDebugInterrupt(struct ar6k_device *pDev);
39
40#define DELAY_PER_INTERVAL_MS 10 /* 10 MS delay per polling interval */
41
42/* completion routine for ALL HIF layer async I/O */
43int DevRWCompletionHandler(void *context, int status)
44{
45 struct htc_packet *pPacket = (struct htc_packet *)context;
46
47 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
48 ("+DevRWCompletionHandler (Pkt:0x%lX) , Status: %d \n",
49 (unsigned long)pPacket,
50 status));
51
52 COMPLETE_HTC_PACKET(pPacket,status);
53
54 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
55 ("-DevRWCompletionHandler\n"));
56
57 return 0;
58}
59
60/* mailbox recv message polling */
61int DevPollMboxMsgRecv(struct ar6k_device *pDev,
62 u32 *pLookAhead,
63 int TimeoutMS)
64{
65 int status = 0;
66 int timeout = TimeoutMS/DELAY_PER_INTERVAL_MS;
67
68 A_ASSERT(timeout > 0);
69
70 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevPollMboxMsgRecv \n"));
71
72 while (true) {
73
74 if (pDev->GetPendingEventsFunc != NULL) {
75
76 struct hif_pending_events_info events;
77
78#ifdef THREAD_X
79 events.Polling =1;
80#endif
81
82 /* the HIF layer uses a special mechanism to get events, do this
83 * synchronously */
84 status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
85 &events,
86 NULL);
87 if (status)
88 {
89 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get pending events \n"));
90 break;
91 }
92
93 if (events.Events & HIF_RECV_MSG_AVAIL)
94 {
95 /* there is a message available, the lookahead should be valid now */
96 *pLookAhead = events.LookAhead;
97
98 break;
99 }
100 } else {
101
102 /* this is the standard HIF way.... */
103 /* load the register table */
104 status = HIFReadWrite(pDev->HIFDevice,
105 HOST_INT_STATUS_ADDRESS,
106 (u8 *)&pDev->IrqProcRegisters,
107 AR6K_IRQ_PROC_REGS_SIZE,
108 HIF_RD_SYNC_BYTE_INC,
109 NULL);
110
111 if (status){
112 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to read register table \n"));
113 break;
114 }
115
116 /* check for MBOX data and valid lookahead */
117 if (pDev->IrqProcRegisters.host_int_status & (1 << HTC_MAILBOX)) {
118 if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX))
119 {
120 /* mailbox has a message and the look ahead is valid */
121 *pLookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX];
122 break;
123 }
124 }
125
126 }
127
128 timeout--;
129
130 if (timeout <= 0) {
131 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Timeout waiting for recv message \n"));
132 status = A_ERROR;
133
134 /* check if the target asserted */
135 if ( pDev->IrqProcRegisters.counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) {
136 /* target signaled an assert, process this pending interrupt
137 * this will call the target failure handler */
138 DevServiceDebugInterrupt(pDev);
139 }
140
141 break;
142 }
143
144 /* delay a little */
145 A_MDELAY(DELAY_PER_INTERVAL_MS);
146 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Retry Mbox Poll : %d \n",timeout));
147 }
148
149 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevPollMboxMsgRecv \n"));
150
151 return status;
152}
153
154static int DevServiceCPUInterrupt(struct ar6k_device *pDev)
155{
156 int status;
157 u8 cpu_int_status;
158 u8 regBuffer[4];
159
160 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("CPU Interrupt\n"));
161 cpu_int_status = pDev->IrqProcRegisters.cpu_int_status &
162 pDev->IrqEnableRegisters.cpu_int_status_enable;
163 A_ASSERT(cpu_int_status);
164 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
165 ("Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
166 cpu_int_status));
167
168 /* Clear the interrupt */
169 pDev->IrqProcRegisters.cpu_int_status &= ~cpu_int_status; /* W1C */
170
171 /* set up the register transfer buffer to hit the register 4 times , this is done
172 * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
173 * restrict bus transfer lengths to be a multiple of 4-bytes */
174
175 /* set W1C value to clear the interrupt, this hits the register first */
176 regBuffer[0] = cpu_int_status;
177 /* the remaining 4 values are set to zero which have no-effect */
178 regBuffer[1] = 0;
179 regBuffer[2] = 0;
180 regBuffer[3] = 0;
181
182 status = HIFReadWrite(pDev->HIFDevice,
183 CPU_INT_STATUS_ADDRESS,
184 regBuffer,
185 4,
186 HIF_WR_SYNC_BYTE_FIX,
187 NULL);
188
189 A_ASSERT(status == 0);
190 return status;
191}
192
193
194static int DevServiceErrorInterrupt(struct ar6k_device *pDev)
195{
196 int status;
197 u8 error_int_status;
198 u8 regBuffer[4];
199
200 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error Interrupt\n"));
201 error_int_status = pDev->IrqProcRegisters.error_int_status & 0x0F;
202 A_ASSERT(error_int_status);
203 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
204 ("Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
205 error_int_status));
206
207 if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) {
208 /* Wakeup */
209 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error : Wakeup\n"));
210 }
211
212 if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {
213 /* Rx Underflow */
214 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Rx Underflow\n"));
215 }
216
217 if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {
218 /* Tx Overflow */
219 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Tx Overflow\n"));
220 }
221
222 /* Clear the interrupt */
223 pDev->IrqProcRegisters.error_int_status &= ~error_int_status; /* W1C */
224
225 /* set up the register transfer buffer to hit the register 4 times , this is done
226 * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
227 * restrict bus transfer lengths to be a multiple of 4-bytes */
228
229 /* set W1C value to clear the interrupt, this hits the register first */
230 regBuffer[0] = error_int_status;
231 /* the remaining 4 values are set to zero which have no-effect */
232 regBuffer[1] = 0;
233 regBuffer[2] = 0;
234 regBuffer[3] = 0;
235
236 status = HIFReadWrite(pDev->HIFDevice,
237 ERROR_INT_STATUS_ADDRESS,
238 regBuffer,
239 4,
240 HIF_WR_SYNC_BYTE_FIX,
241 NULL);
242
243 A_ASSERT(status == 0);
244 return status;
245}
246
247static int DevServiceDebugInterrupt(struct ar6k_device *pDev)
248{
249 u32 dummy;
250 int status;
251
252 /* Send a target failure event to the application */
253 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n"));
254
255 if (pDev->TargetFailureCallback != NULL) {
256 pDev->TargetFailureCallback(pDev->HTCContext);
257 }
258
259 if (pDev->GMboxEnabled) {
260 DevNotifyGMboxTargetFailure(pDev);
261 }
262
263 /* clear the interrupt , the debug error interrupt is
264 * counter 0 */
265 /* read counter to clear interrupt */
266 status = HIFReadWrite(pDev->HIFDevice,
267 COUNT_DEC_ADDRESS,
268 (u8 *)&dummy,
269 4,
270 HIF_RD_SYNC_BYTE_INC,
271 NULL);
272
273 A_ASSERT(status == 0);
274 return status;
275}
276
277static int DevServiceCounterInterrupt(struct ar6k_device *pDev)
278{
279 u8 counter_int_status;
280
281 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Counter Interrupt\n"));
282
283 counter_int_status = pDev->IrqProcRegisters.counter_int_status &
284 pDev->IrqEnableRegisters.counter_int_status_enable;
285
286 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
287 ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
288 counter_int_status));
289
290 /* Check if the debug interrupt is pending
291 * NOTE: other modules like GMBOX may use the counter interrupt for
292 * credit flow control on other counters, we only need to check for the debug assertion
293 * counter interrupt */
294 if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) {
295 return DevServiceDebugInterrupt(pDev);
296 }
297
298 return 0;
299}
300
301/* callback when our fetch to get interrupt status registers completes */
302static void DevGetEventAsyncHandler(void *Context, struct htc_packet *pPacket)
303{
304 struct ar6k_device *pDev = (struct ar6k_device *)Context;
305 u32 lookAhead = 0;
306 bool otherInts = false;
307
308 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
309
310 do {
311
312 if (pPacket->Status) {
313 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
314 (" GetEvents I/O request failed, status:%d \n", pPacket->Status));
315 /* bail out, don't unmask HIF interrupt */
316 break;
317 }
318
319 if (pDev->GetPendingEventsFunc != NULL) {
320 /* the HIF layer collected the information for us */
321 struct hif_pending_events_info *pEvents = (struct hif_pending_events_info *)pPacket->pBuffer;
322 if (pEvents->Events & HIF_RECV_MSG_AVAIL) {
323 lookAhead = pEvents->LookAhead;
324 if (0 == lookAhead) {
325 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler1, lookAhead is zero! \n"));
326 }
327 }
328 if (pEvents->Events & HIF_OTHER_EVENTS) {
329 otherInts = true;
330 }
331 } else {
332 /* standard interrupt table handling.... */
333 struct ar6k_irq_proc_registers *pReg = (struct ar6k_irq_proc_registers *)pPacket->pBuffer;
334 u8 host_int_status;
335
336 host_int_status = pReg->host_int_status & pDev->IrqEnableRegisters.int_status_enable;
337
338 if (host_int_status & (1 << HTC_MAILBOX)) {
339 host_int_status &= ~(1 << HTC_MAILBOX);
340 if (pReg->rx_lookahead_valid & (1 << HTC_MAILBOX)) {
341 /* mailbox has a message and the look ahead is valid */
342 lookAhead = pReg->rx_lookahead[HTC_MAILBOX];
343 if (0 == lookAhead) {
344 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler2, lookAhead is zero! \n"));
345 }
346 }
347 }
348
349 if (host_int_status) {
350 /* there are other interrupts to handle */
351 otherInts = true;
352 }
353 }
354
355 if (otherInts || (lookAhead == 0)) {
356 /* if there are other interrupts to process, we cannot do this in the async handler so
357 * ack the interrupt which will cause our sync handler to run again
358 * if however there are no more messages, we can now ack the interrupt */
359 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
360 (" Acking interrupt from DevGetEventAsyncHandler (otherints:%d, lookahead:0x%X)\n",
361 otherInts, lookAhead));
362 HIFAckInterrupt(pDev->HIFDevice);
363 } else {
364 int fetched = 0;
365 int status;
366
367 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
368 (" DevGetEventAsyncHandler : detected another message, lookahead :0x%X \n",
369 lookAhead));
370 /* lookahead is non-zero and there are no other interrupts to service,
371 * go get the next message */
372 status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, NULL, &fetched);
373
374 if (!status && !fetched) {
375 /* HTC layer could not pull out messages due to lack of resources, stop IRQ processing */
376 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("MessagePendingCallback did not pull any messages, force-ack \n"));
377 DevAsyncIrqProcessComplete(pDev);
378 }
379 }
380
381 } while (false);
382
383 /* free this IO packet */
384 AR6KFreeIOPacket(pDev,pPacket);
385 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGetEventAsyncHandler \n"));
386}
387
388/* called by the HTC layer when it wants us to check if the device has any more pending
389 * recv messages, this starts off a series of async requests to read interrupt registers */
390int DevCheckPendingRecvMsgsAsync(void *context)
391{
392 struct ar6k_device *pDev = (struct ar6k_device *)context;
393 int status = 0;
394 struct htc_packet *pIOPacket;
395
396 /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can
397 * cause us to switch contexts */
398
399 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%lX)\n", (unsigned long)pDev));
400
401 do {
402
403 if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
404 /* break the async processing chain right here, no need to continue.
405 * The DevDsrHandler() will handle things in a loop when things are driven
406 * synchronously */
407 break;
408 }
409
410 /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake
411 * the target, if upper layers determine that we are in a low-throughput mode, we can
412 * rely on taking another interrupt rather than re-checking the status registers which can
413 * re-wake the target */
414 if (pDev->RecheckIRQStatusCnt == 0) {
415 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, re-acking HIF interrupts\n"));
416 /* ack interrupt */
417 HIFAckInterrupt(pDev->HIFDevice);
418 break;
419 }
420
421 /* first allocate one of our HTC packets we created for async I/O
422 * we reuse HTC packet definitions so that we can use the completion mechanism
423 * in DevRWCompletionHandler() */
424 pIOPacket = AR6KAllocIOPacket(pDev);
425
426 if (NULL == pIOPacket) {
427 /* there should be only 1 asynchronous request out at a time to read these registers
428 * so this should actually never happen */
429 status = A_NO_MEMORY;
430 A_ASSERT(false);
431 break;
432 }
433
434 /* stick in our completion routine when the I/O operation completes */
435 pIOPacket->Completion = DevGetEventAsyncHandler;
436 pIOPacket->pContext = pDev;
437
438 if (pDev->GetPendingEventsFunc) {
439 /* HIF layer has it's own mechanism, pass the IO to it.. */
440 status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
441 (struct hif_pending_events_info *)pIOPacket->pBuffer,
442 pIOPacket);
443
444 } else {
445 /* standard way, read the interrupt register table asynchronously again */
446 status = HIFReadWrite(pDev->HIFDevice,
447 HOST_INT_STATUS_ADDRESS,
448 pIOPacket->pBuffer,
449 AR6K_IRQ_PROC_REGS_SIZE,
450 HIF_RD_ASYNC_BYTE_INC,
451 pIOPacket);
452 }
453
454 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status...\n"));
455 } while (false);
456
457 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n"));
458
459 return status;
460}
461
462void DevAsyncIrqProcessComplete(struct ar6k_device *pDev)
463{
464 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("DevAsyncIrqProcessComplete - forcing HIF IRQ ACK \n"));
465 HIFAckInterrupt(pDev->HIFDevice);
466}
467
468/* process pending interrupts synchronously */
469static int ProcessPendingIRQs(struct ar6k_device *pDev, bool *pDone, bool *pASyncProcessing)
470{
471 int status = 0;
472 u8 host_int_status = 0;
473 u32 lookAhead = 0;
474
475 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsigned long)pDev));
476
477 /*** NOTE: the HIF implementation guarantees that the context of this call allows
478 * us to perform SYNCHRONOUS I/O, that is we can block, sleep or call any API that
479 * can block or switch thread/task ontexts.
480 * This is a fully schedulable context.
481 * */
482 do {
483
484 if (pDev->IrqEnableRegisters.int_status_enable == 0) {
485 /* interrupt enables have been cleared, do not try to process any pending interrupts that
486 * may result in more bus transactions. The target may be unresponsive at this
487 * point. */
488 break;
489 }
490
491 if (pDev->GetPendingEventsFunc != NULL) {
492 struct hif_pending_events_info events;
493
494#ifdef THREAD_X
495 events.Polling= 0;
496#endif
497 /* the HIF layer uses a special mechanism to get events
498 * get this synchronously */
499 status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
500 &events,
501 NULL);
502
503 if (status) {
504 break;
505 }
506
507 if (events.Events & HIF_RECV_MSG_AVAIL) {
508 lookAhead = events.LookAhead;
509 if (0 == lookAhead) {
510 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs1 lookAhead is zero! \n"));
511 }
512 }
513
514 if (!(events.Events & HIF_OTHER_EVENTS) ||
515 !(pDev->IrqEnableRegisters.int_status_enable & OTHER_INTS_ENABLED)) {
516 /* no need to read the register table, no other interesting interrupts.
517 * Some interfaces (like SPI) can shadow interrupt sources without
518 * requiring the host to do a full table read */
519 break;
520 }
521
522 /* otherwise fall through and read the register table */
523 }
524
525 /*
526 * Read the first 28 bytes of the HTC register table. This will yield us
527 * the value of different int status registers and the lookahead
528 * registers.
529 * length = sizeof(int_status) + sizeof(cpu_int_status) +
530 * sizeof(error_int_status) + sizeof(counter_int_status) +
531 * sizeof(mbox_frame) + sizeof(rx_lookahead_valid) +
532 * sizeof(hole) + sizeof(rx_lookahead) +
533 * sizeof(int_status_enable) + sizeof(cpu_int_status_enable) +
534 * sizeof(error_status_enable) +
535 * sizeof(counter_int_status_enable);
536 *
537 */
538#ifdef CONFIG_MMC_SDHCI_S3C
539 pDev->IrqProcRegisters.host_int_status = 0;
540 pDev->IrqProcRegisters.rx_lookahead_valid = 0;
541 pDev->IrqProcRegisters.host_int_status2 = 0;
542 pDev->IrqProcRegisters.rx_lookahead[0] = 0;
543 pDev->IrqProcRegisters.rx_lookahead[1] = 0xaaa5555;
544#endif /* CONFIG_MMC_SDHCI_S3C */
545 status = HIFReadWrite(pDev->HIFDevice,
546 HOST_INT_STATUS_ADDRESS,
547 (u8 *)&pDev->IrqProcRegisters,
548 AR6K_IRQ_PROC_REGS_SIZE,
549 HIF_RD_SYNC_BYTE_INC,
550 NULL);
551
552 if (status) {
553 break;
554 }
555
556#ifdef ATH_DEBUG_MODULE
557 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) {
558 DevDumpRegisters(pDev,
559 &pDev->IrqProcRegisters,
560 &pDev->IrqEnableRegisters);
561 }
562#endif
563
564 /* Update only those registers that are enabled */
565 host_int_status = pDev->IrqProcRegisters.host_int_status &
566 pDev->IrqEnableRegisters.int_status_enable;
567
568 if (NULL == pDev->GetPendingEventsFunc) {
569 /* only look at mailbox status if the HIF layer did not provide this function,
570 * on some HIF interfaces reading the RX lookahead is not valid to do */
571 if (host_int_status & (1 << HTC_MAILBOX)) {
572 /* mask out pending mailbox value, we use "lookAhead" as the real flag for
573 * mailbox processing below */
574 host_int_status &= ~(1 << HTC_MAILBOX);
575 if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX)) {
576 /* mailbox has a message and the look ahead is valid */
577 lookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX];
578 if (0 == lookAhead) {
579 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs2, lookAhead is zero! \n"));
580 }
581 }
582 }
583 } else {
584 /* not valid to check if the HIF has another mechanism for reading mailbox pending status*/
585 host_int_status &= ~(1 << HTC_MAILBOX);
586 }
587
588 if (pDev->GMboxEnabled) {
589 /*call GMBOX layer to process any interrupts of interest */
590 status = DevCheckGMboxInterrupts(pDev);
591 }
592
593 } while (false);
594
595
596 do {
597
598 /* did the interrupt status fetches succeed? */
599 if (status) {
600 break;
601 }
602
603 if ((0 == host_int_status) && (0 == lookAhead)) {
604 /* nothing to process, the caller can use this to break out of a loop */
605 *pDone = true;
606 break;
607 }
608
609 if (lookAhead != 0) {
610 int fetched = 0;
611
612 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Pending mailbox message, LookAhead: 0x%X\n",lookAhead));
613 /* Mailbox Interrupt, the HTC layer may issue async requests to empty the
614 * mailbox...
615 * When emptying the recv mailbox we use the async handler above called from the
616 * completion routine of the callers read request. This can improve performance
617 * by reducing context switching when we rapidly pull packets */
618 status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, pASyncProcessing, &fetched);
619 if (status) {
620 break;
621 }
622
623 if (!fetched) {
624 /* HTC could not pull any messages out due to lack of resources */
625 /* force DSR handler to ack the interrupt */
626 *pASyncProcessing = false;
627 pDev->RecheckIRQStatusCnt = 0;
628 }
629 }
630
631 /* now handle the rest of them */
632 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
633 (" Valid interrupt source(s) for OTHER interrupts: 0x%x\n",
634 host_int_status));
635
636 if (HOST_INT_STATUS_CPU_GET(host_int_status)) {
637 /* CPU Interrupt */
638 status = DevServiceCPUInterrupt(pDev);
639 if (status){
640 break;
641 }
642 }
643
644 if (HOST_INT_STATUS_ERROR_GET(host_int_status)) {
645 /* Error Interrupt */
646 status = DevServiceErrorInterrupt(pDev);
647 if (status){
648 break;
649 }
650 }
651
652 if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) {
653 /* Counter Interrupt */
654 status = DevServiceCounterInterrupt(pDev);
655 if (status){
656 break;
657 }
658 }
659
660 } while (false);
661
662 /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake
663 * the target, if upper layers determine that we are in a low-throughput mode, we can
664 * rely on taking another interrupt rather than re-checking the status registers which can
665 * re-wake the target.
666 *
667 * NOTE : for host interfaces that use the special GetPendingEventsFunc, this optimization cannot
668 * be used due to possible side-effects. For example, SPI requires the host to drain all
669 * messages from the mailbox before exiting the ISR routine. */
670 if (!(*pASyncProcessing) && (pDev->RecheckIRQStatusCnt == 0) && (pDev->GetPendingEventsFunc == NULL)) {
671 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, forcing done \n"));
672 *pDone = true;
673 }
674
675 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-ProcessPendingIRQs: (done:%d, async:%d) status=%d \n",
676 *pDone, *pASyncProcessing, status));
677
678 return status;
679}
680
681
682/* Synchronousinterrupt handler, this handler kicks off all interrupt processing.*/
683int DevDsrHandler(void *context)
684{
685 struct ar6k_device *pDev = (struct ar6k_device *)context;
686 int status = 0;
687 bool done = false;
688 bool asyncProc = false;
689
690 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
691
692 /* reset the recv counter that tracks when we need to yield from the DSR */
693 pDev->CurrentDSRRecvCount = 0;
694 /* reset counter used to flag a re-scan of IRQ status registers on the target */
695 pDev->RecheckIRQStatusCnt = 0;
696
697 while (!done) {
698 status = ProcessPendingIRQs(pDev, &done, &asyncProc);
699 if (status) {
700 break;
701 }
702
703 if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
704 /* the HIF layer does not allow async IRQ processing, override the asyncProc flag */
705 asyncProc = false;
706 /* this will cause us to re-enter ProcessPendingIRQ() and re-read interrupt status registers.
707 * this has a nice side effect of blocking us until all async read requests are completed.
708 * This behavior is required on some HIF implementations that do not allow ASYNC
709 * processing in interrupt handlers (like Windows CE) */
710
711 if (pDev->DSRCanYield && DEV_CHECK_RECV_YIELD(pDev)) {
712 /* ProcessPendingIRQs() pulled enough recv messages to satisfy the yield count, stop
713 * checking for more messages and return */
714 break;
715 }
716 }
717
718 if (asyncProc) {
719 /* the function performed some async I/O for performance, we
720 need to exit the ISR immediately, the check below will prevent the interrupt from being
721 Ack'd while we handle it asynchronously */
722 break;
723 }
724
725 }
726
727 if (!status && !asyncProc) {
728 /* Ack the interrupt only if :
729 * 1. we did not get any errors in processing interrupts
730 * 2. there are no outstanding async processing requests */
731 if (pDev->DSRCanYield) {
732 /* if the DSR can yield do not ACK the interrupt, there could be more pending messages.
733 * The HIF layer must ACK the interrupt on behalf of HTC */
734 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Yield in effect (cur RX count: %d) \n", pDev->CurrentDSRRecvCount));
735 } else {
736 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Acking interrupt from DevDsrHandler \n"));
737 HIFAckInterrupt(pDev->HIFDevice);
738 }
739 }
740
741 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDsrHandler \n"));
742 return status;
743}
744
745#ifdef ATH_DEBUG_MODULE
746void DumpAR6KDevState(struct ar6k_device *pDev)
747{
748 int status;
749 struct ar6k_irq_enable_registers regs;
750 struct ar6k_irq_proc_registers procRegs;
751
752 LOCK_AR6K(pDev);
753 /* copy into our temp area */
754 memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
755 UNLOCK_AR6K(pDev);
756
757 /* load the register table from the device */
758 status = HIFReadWrite(pDev->HIFDevice,
759 HOST_INT_STATUS_ADDRESS,
760 (u8 *)&procRegs,
761 AR6K_IRQ_PROC_REGS_SIZE,
762 HIF_RD_SYNC_BYTE_INC,
763 NULL);
764
765 if (status) {
766 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
767 ("DumpAR6KDevState : Failed to read register table (%d) \n",status));
768 return;
769 }
770
771 DevDumpRegisters(pDev,&procRegs,&regs);
772
773 if (pDev->GMboxInfo.pStateDumpCallback != NULL) {
774 pDev->GMboxInfo.pStateDumpCallback(pDev->GMboxInfo.pProtocolContext);
775 }
776
777 /* dump any bus state at the HIF layer */
778 HIFConfigureDevice(pDev->HIFDevice,HIF_DEVICE_DEBUG_BUS_STATE,NULL,0);
779
780}
781#endif
782
783
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c
new file mode 100644
index 00000000000..725540f9add
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c
@@ -0,0 +1,755 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6k_gmbox.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Generic MBOX API implementation
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include "a_config.h"
26#include "athdefs.h"
27#include "a_osapi.h"
28#include "../htc_debug.h"
29#include "hif.h"
30#include "htc_packet.h"
31#include "ar6k.h"
32#include "hw/mbox_host_reg.h"
33#include "gmboxif.h"
34
35/*
36 * This file provides management functions and a toolbox for GMBOX protocol modules.
37 * Only one protocol module can be installed at a time. The determination of which protocol
38 * module is installed is determined at compile time.
39 *
40 */
41#ifdef ATH_AR6K_ENABLE_GMBOX
42 /* GMBOX definitions */
43#define GMBOX_INT_STATUS_ENABLE_REG 0x488
44#define GMBOX_INT_STATUS_RX_DATA (1 << 0)
45#define GMBOX_INT_STATUS_TX_OVERFLOW (1 << 1)
46#define GMBOX_INT_STATUS_RX_OVERFLOW (1 << 2)
47
48#define GMBOX_LOOKAHEAD_MUX_REG 0x498
49#define GMBOX_LA_MUX_OVERRIDE_2_3 (1 << 0)
50
51#define AR6K_GMBOX_CREDIT_DEC_ADDRESS (COUNT_DEC_ADDRESS + 4 * AR6K_GMBOX_CREDIT_COUNTER)
52#define AR6K_GMBOX_CREDIT_SIZE_ADDRESS (COUNT_ADDRESS + AR6K_GMBOX_CREDIT_SIZE_COUNTER)
53
54
55 /* external APIs for allocating and freeing internal I/O packets to handle ASYNC I/O */
56extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket);
57extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev);
58
59
60/* callback when our fetch to enable/disable completes */
61static void DevGMboxIRQActionAsyncHandler(void *Context, struct htc_packet *pPacket)
62{
63 struct ar6k_device *pDev = (struct ar6k_device *)Context;
64
65 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
66
67 if (pPacket->Status) {
68 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
69 ("IRQAction Operation (%d) failed! status:%d \n", pPacket->PktInfo.AsRx.HTCRxFlags,pPacket->Status));
70 }
71 /* free this IO packet */
72 AR6KFreeIOPacket(pDev,pPacket);
73 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n"));
74}
75
76static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode)
77{
78 int status = 0;
79 struct ar6k_irq_enable_registers regs;
80 struct htc_packet *pIOPacket = NULL;
81
82 LOCK_AR6K(pDev);
83
84 if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
85 pDev->GMboxInfo.CreditCountIRQEnabled = true;
86 pDev->IrqEnableRegisters.counter_int_status_enable |=
87 COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER);
88 pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_COUNTER_SET(0x01);
89 } else {
90 pDev->GMboxInfo.CreditCountIRQEnabled = false;
91 pDev->IrqEnableRegisters.counter_int_status_enable &=
92 ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER));
93 }
94 /* copy into our temp area */
95 memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
96
97 UNLOCK_AR6K(pDev);
98
99 do {
100
101 if (AsyncMode) {
102
103 pIOPacket = AR6KAllocIOPacket(pDev);
104
105 if (NULL == pIOPacket) {
106 status = A_NO_MEMORY;
107 A_ASSERT(false);
108 break;
109 }
110
111 /* copy values to write to our async I/O buffer */
112 memcpy(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
113
114 /* stick in our completion routine when the I/O operation completes */
115 pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
116 pIOPacket->pContext = pDev;
117 pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
118 /* write it out asynchronously */
119 HIFReadWrite(pDev->HIFDevice,
120 INT_STATUS_ENABLE_ADDRESS,
121 pIOPacket->pBuffer,
122 AR6K_IRQ_ENABLE_REGS_SIZE,
123 HIF_WR_ASYNC_BYTE_INC,
124 pIOPacket);
125
126 pIOPacket = NULL;
127 break;
128 }
129
130 /* if we get here we are doing it synchronously */
131 status = HIFReadWrite(pDev->HIFDevice,
132 INT_STATUS_ENABLE_ADDRESS,
133 &regs.int_status_enable,
134 AR6K_IRQ_ENABLE_REGS_SIZE,
135 HIF_WR_SYNC_BYTE_INC,
136 NULL);
137 } while (false);
138
139 if (status) {
140 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
141 (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));
142 } else {
143 if (!AsyncMode) {
144 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
145 (" IRQAction Operation (%d) success \n", IrqAction));
146 }
147 }
148
149 if (pIOPacket != NULL) {
150 AR6KFreeIOPacket(pDev,pIOPacket);
151 }
152
153 return status;
154}
155
156
157int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode)
158{
159 int status = 0;
160 struct htc_packet *pIOPacket = NULL;
161 u8 GMboxIntControl[4];
162
163 if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
164 return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_ENABLE, AsyncMode);
165 } else if(GMBOX_CREDIT_IRQ_DISABLE == IrqAction) {
166 return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);
167 }
168
169 if (GMBOX_DISABLE_ALL == IrqAction) {
170 /* disable credit IRQ, those are on a different set of registers */
171 DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);
172 }
173
174 /* take the lock to protect interrupt enable shadows */
175 LOCK_AR6K(pDev);
176
177 switch (IrqAction) {
178
179 case GMBOX_DISABLE_ALL:
180 pDev->GMboxControlRegisters.int_status_enable = 0;
181 break;
182 case GMBOX_ERRORS_IRQ_ENABLE:
183 pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_TX_OVERFLOW |
184 GMBOX_INT_STATUS_RX_OVERFLOW;
185 break;
186 case GMBOX_RECV_IRQ_ENABLE:
187 pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_RX_DATA;
188 break;
189 case GMBOX_RECV_IRQ_DISABLE:
190 pDev->GMboxControlRegisters.int_status_enable &= ~GMBOX_INT_STATUS_RX_DATA;
191 break;
192 case GMBOX_ACTION_NONE:
193 default:
194 A_ASSERT(false);
195 break;
196 }
197
198 GMboxIntControl[0] = pDev->GMboxControlRegisters.int_status_enable;
199 GMboxIntControl[1] = GMboxIntControl[0];
200 GMboxIntControl[2] = GMboxIntControl[0];
201 GMboxIntControl[3] = GMboxIntControl[0];
202
203 UNLOCK_AR6K(pDev);
204
205 do {
206
207 if (AsyncMode) {
208
209 pIOPacket = AR6KAllocIOPacket(pDev);
210
211 if (NULL == pIOPacket) {
212 status = A_NO_MEMORY;
213 A_ASSERT(false);
214 break;
215 }
216
217 /* copy values to write to our async I/O buffer */
218 memcpy(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl));
219
220 /* stick in our completion routine when the I/O operation completes */
221 pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
222 pIOPacket->pContext = pDev;
223 pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
224 /* write it out asynchronously */
225 HIFReadWrite(pDev->HIFDevice,
226 GMBOX_INT_STATUS_ENABLE_REG,
227 pIOPacket->pBuffer,
228 sizeof(GMboxIntControl),
229 HIF_WR_ASYNC_BYTE_FIX,
230 pIOPacket);
231 pIOPacket = NULL;
232 break;
233 }
234
235 /* if we get here we are doing it synchronously */
236
237 status = HIFReadWrite(pDev->HIFDevice,
238 GMBOX_INT_STATUS_ENABLE_REG,
239 GMboxIntControl,
240 sizeof(GMboxIntControl),
241 HIF_WR_SYNC_BYTE_FIX,
242 NULL);
243
244 } while (false);
245
246 if (status) {
247 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
248 (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));
249 } else {
250 if (!AsyncMode) {
251 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
252 (" IRQAction Operation (%d) success \n", IrqAction));
253 }
254 }
255
256 if (pIOPacket != NULL) {
257 AR6KFreeIOPacket(pDev,pIOPacket);
258 }
259
260 return status;
261}
262
263void DevCleanupGMbox(struct ar6k_device *pDev)
264{
265 if (pDev->GMboxEnabled) {
266 pDev->GMboxEnabled = false;
267 GMboxProtocolUninstall(pDev);
268 }
269}
270
271int DevSetupGMbox(struct ar6k_device *pDev)
272{
273 int status = 0;
274 u8 muxControl[4];
275
276 do {
277
278 if (0 == pDev->MailBoxInfo.GMboxAddress) {
279 break;
280 }
281
282 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" GMBOX Advertised: Address:0x%X , size:%d \n",
283 pDev->MailBoxInfo.GMboxAddress, pDev->MailBoxInfo.GMboxSize));
284
285 status = DevGMboxIRQAction(pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC);
286
287 if (status) {
288 break;
289 }
290
291 /* write to mailbox look ahead mux control register, we want the
292 * GMBOX lookaheads to appear on lookaheads 2 and 3
293 * the register is 1-byte wide so we need to hit it 4 times to align the operation
294 * to 4-bytes */
295 muxControl[0] = GMBOX_LA_MUX_OVERRIDE_2_3;
296 muxControl[1] = GMBOX_LA_MUX_OVERRIDE_2_3;
297 muxControl[2] = GMBOX_LA_MUX_OVERRIDE_2_3;
298 muxControl[3] = GMBOX_LA_MUX_OVERRIDE_2_3;
299
300 status = HIFReadWrite(pDev->HIFDevice,
301 GMBOX_LOOKAHEAD_MUX_REG,
302 muxControl,
303 sizeof(muxControl),
304 HIF_WR_SYNC_BYTE_FIX, /* hit this register 4 times */
305 NULL);
306
307 if (status) {
308 break;
309 }
310
311 status = GMboxProtocolInstall(pDev);
312
313 if (status) {
314 break;
315 }
316
317 pDev->GMboxEnabled = true;
318
319 } while (false);
320
321 return status;
322}
323
324int DevCheckGMboxInterrupts(struct ar6k_device *pDev)
325{
326 int status = 0;
327 u8 counter_int_status;
328 int credits;
329 u8 host_int_status2;
330
331 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("+DevCheckGMboxInterrupts \n"));
332
333 /* the caller guarantees that this is a context that allows for blocking I/O */
334
335 do {
336
337 host_int_status2 = pDev->IrqProcRegisters.host_int_status2 &
338 pDev->GMboxControlRegisters.int_status_enable;
339
340 if (host_int_status2 & GMBOX_INT_STATUS_TX_OVERFLOW) {
341 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : TX Overflow \n"));
342 status = A_ECOMM;
343 }
344
345 if (host_int_status2 & GMBOX_INT_STATUS_RX_OVERFLOW) {
346 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : RX Overflow \n"));
347 status = A_ECOMM;
348 }
349
350 if (status) {
351 if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
352 pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, status);
353 }
354 break;
355 }
356
357 if (host_int_status2 & GMBOX_INT_STATUS_RX_DATA) {
358 if (pDev->IrqProcRegisters.gmbox_rx_avail > 0) {
359 A_ASSERT(pDev->GMboxInfo.pMessagePendingCallBack != NULL);
360 status = pDev->GMboxInfo.pMessagePendingCallBack(
361 pDev->GMboxInfo.pProtocolContext,
362 (u8 *)&pDev->IrqProcRegisters.rx_gmbox_lookahead_alias[0],
363 pDev->IrqProcRegisters.gmbox_rx_avail);
364 }
365 }
366
367 if (status) {
368 break;
369 }
370
371 counter_int_status = pDev->IrqProcRegisters.counter_int_status &
372 pDev->IrqEnableRegisters.counter_int_status_enable;
373
374 /* check if credit interrupt is pending */
375 if (counter_int_status & (COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER))) {
376
377 /* do synchronous read */
378 status = DevGMboxReadCreditCounter(pDev, PROC_IO_SYNC, &credits);
379
380 if (status) {
381 break;
382 }
383
384 A_ASSERT(pDev->GMboxInfo.pCreditsPendingCallback != NULL);
385 status = pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext,
386 credits,
387 pDev->GMboxInfo.CreditCountIRQEnabled);
388 }
389
390 } while (false);
391
392 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("-DevCheckGMboxInterrupts (%d) \n",status));
393
394 return status;
395}
396
397
398int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength)
399{
400 u32 paddedLength;
401 bool sync = (pPacket->Completion == NULL) ? true : false;
402 int status;
403 u32 address;
404
405 /* adjust the length to be a multiple of block size if appropriate */
406 paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, WriteLength);
407
408 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
409 ("DevGMboxWrite, Padded Length: %d Mbox:0x%X (mode:%s)\n",
410 WriteLength,
411 pDev->MailBoxInfo.GMboxAddress,
412 sync ? "SYNC" : "ASYNC"));
413
414 /* last byte of packet has to hit the EOM marker */
415 address = pDev->MailBoxInfo.GMboxAddress + pDev->MailBoxInfo.GMboxSize - paddedLength;
416
417 status = HIFReadWrite(pDev->HIFDevice,
418 address,
419 pPacket->pBuffer,
420 paddedLength, /* the padded length */
421 sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
422 sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
423
424 if (sync) {
425 pPacket->Status = status;
426 } else {
427 if (status == A_PENDING) {
428 status = 0;
429 }
430 }
431
432 return status;
433}
434
435int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength)
436{
437
438 u32 paddedLength;
439 int status;
440 bool sync = (pPacket->Completion == NULL) ? true : false;
441
442 /* adjust the length to be a multiple of block size if appropriate */
443 paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, ReadLength);
444
445 if (paddedLength > pPacket->BufferLength) {
446 A_ASSERT(false);
447 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
448 ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
449 paddedLength,ReadLength,pPacket->BufferLength));
450 if (pPacket->Completion != NULL) {
451 COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
452 return 0;
453 }
454 return A_EINVAL;
455 }
456
457 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
458 ("DevGMboxRead (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
459 (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
460 paddedLength,
461 pDev->MailBoxInfo.GMboxAddress,
462 sync ? "SYNC" : "ASYNC"));
463
464 status = HIFReadWrite(pDev->HIFDevice,
465 pDev->MailBoxInfo.GMboxAddress,
466 pPacket->pBuffer,
467 paddedLength,
468 sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
469 sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
470
471 if (sync) {
472 pPacket->Status = status;
473 }
474
475 return status;
476}
477
478
479static int ProcessCreditCounterReadBuffer(u8 *pBuffer, int Length)
480{
481 int credits = 0;
482
483 /* theory of how this works:
484 * We read the credit decrement register multiple times on a byte-wide basis.
485 * The number of times (32) aligns the I/O operation to be a multiple of 4 bytes and provides a
486 * reasonable chance to acquire "all" pending credits in a single I/O operation.
487 *
488 * Once we obtain the filled buffer, we can walk through it looking for credit decrement transitions.
489 * Each non-zero byte represents a single credit decrement (which is a credit given back to the host)
490 * For example if the target provides 3 credits and added 4 more during the 32-byte read operation the following
491 * pattern "could" appear:
492 *
493 * 0x3 0x2 0x1 0x0 0x0 0x0 0x0 0x0 0x1 0x0 0x1 0x0 0x1 0x0 0x1 0x0 ......rest zeros
494 * <---------> <----------------------------->
495 * \_ credits aleady there \_ target adding 4 more credits
496 *
497 * The total available credits would be 7, since there are 7 non-zero bytes in the buffer.
498 *
499 * */
500
501 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
502 DebugDumpBytes(pBuffer, Length, "GMBOX Credit read buffer");
503 }
504
505 while (Length) {
506 if (*pBuffer != 0) {
507 credits++;
508 }
509 Length--;
510 pBuffer++;
511 }
512
513 return credits;
514}
515
516
517/* callback when our fetch to enable/disable completes */
518static void DevGMboxReadCreditsAsyncHandler(void *Context, struct htc_packet *pPacket)
519{
520 struct ar6k_device *pDev = (struct ar6k_device *)Context;
521
522 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
523
524 if (pPacket->Status) {
525 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
526 ("Read Credit Operation failed! status:%d \n", pPacket->Status));
527 } else {
528 int credits = 0;
529 credits = ProcessCreditCounterReadBuffer(pPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);
530 pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext,
531 credits,
532 pDev->GMboxInfo.CreditCountIRQEnabled);
533
534
535 }
536 /* free this IO packet */
537 AR6KFreeIOPacket(pDev,pPacket);
538 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n"));
539}
540
541int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits)
542{
543 int status = 0;
544 struct htc_packet *pIOPacket = NULL;
545
546 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC"));
547
548 do {
549
550 pIOPacket = AR6KAllocIOPacket(pDev);
551
552 if (NULL == pIOPacket) {
553 status = A_NO_MEMORY;
554 A_ASSERT(false);
555 break;
556 }
557
558 A_MEMZERO(pIOPacket->pBuffer,AR6K_REG_IO_BUFFER_SIZE);
559
560 if (AsyncMode) {
561 /* stick in our completion routine when the I/O operation completes */
562 pIOPacket->Completion = DevGMboxReadCreditsAsyncHandler;
563 pIOPacket->pContext = pDev;
564 /* read registers asynchronously */
565 HIFReadWrite(pDev->HIFDevice,
566 AR6K_GMBOX_CREDIT_DEC_ADDRESS,
567 pIOPacket->pBuffer,
568 AR6K_REG_IO_BUFFER_SIZE, /* hit the register multiple times */
569 HIF_RD_ASYNC_BYTE_FIX,
570 pIOPacket);
571 pIOPacket = NULL;
572 break;
573 }
574
575 pIOPacket->Completion = NULL;
576 /* if we get here we are doing it synchronously */
577 status = HIFReadWrite(pDev->HIFDevice,
578 AR6K_GMBOX_CREDIT_DEC_ADDRESS,
579 pIOPacket->pBuffer,
580 AR6K_REG_IO_BUFFER_SIZE,
581 HIF_RD_SYNC_BYTE_FIX,
582 NULL);
583 } while (false);
584
585 if (status) {
586 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
587 (" DevGMboxReadCreditCounter failed! status:%d \n", status));
588 }
589
590 if (pIOPacket != NULL) {
591 if (!status) {
592 /* sync mode processing */
593 *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);
594 }
595 AR6KFreeIOPacket(pDev,pIOPacket);
596 }
597
598 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-DevGMboxReadCreditCounter (%s) (%d) \n",
599 AsyncMode ? "ASYNC" : "SYNC", status));
600
601 return status;
602}
603
604int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize)
605{
606 int status;
607 u8 buffer[4];
608
609 status = HIFReadWrite(pDev->HIFDevice,
610 AR6K_GMBOX_CREDIT_SIZE_ADDRESS,
611 buffer,
612 sizeof(buffer),
613 HIF_RD_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */
614 NULL);
615
616 if (!status) {
617 if (buffer[0] == 0) {
618 *pCreditSize = 256;
619 } else {
620 *pCreditSize = buffer[0];
621 }
622
623 }
624
625 return status;
626}
627
628void DevNotifyGMboxTargetFailure(struct ar6k_device *pDev)
629{
630 /* Target ASSERTED!!! */
631 if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
632 pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, A_HARDWARE);
633 }
634}
635
636int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes)
637{
638
639 int status = 0;
640 struct ar6k_irq_proc_registers procRegs;
641 int maxCopy;
642
643 do {
644 /* on entry the caller provides the length of the lookahead buffer */
645 if (*pLookAheadBytes > sizeof(procRegs.rx_gmbox_lookahead_alias)) {
646 A_ASSERT(false);
647 status = A_EINVAL;
648 break;
649 }
650
651 maxCopy = *pLookAheadBytes;
652 *pLookAheadBytes = 0;
653 /* load the register table from the device */
654 status = HIFReadWrite(pDev->HIFDevice,
655 HOST_INT_STATUS_ADDRESS,
656 (u8 *)&procRegs,
657 AR6K_IRQ_PROC_REGS_SIZE,
658 HIF_RD_SYNC_BYTE_INC,
659 NULL);
660
661 if (status) {
662 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
663 ("DevGMboxRecvLookAheadPeek : Failed to read register table (%d) \n",status));
664 break;
665 }
666
667 if (procRegs.gmbox_rx_avail > 0) {
668 int bytes = procRegs.gmbox_rx_avail > maxCopy ? maxCopy : procRegs.gmbox_rx_avail;
669 memcpy(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],bytes);
670 *pLookAheadBytes = bytes;
671 }
672
673 } while (false);
674
675 return status;
676}
677
678int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int Signal, int AckTimeoutMS)
679{
680 int status = 0;
681 int i;
682 u8 buffer[4];
683
684 A_MEMZERO(buffer, sizeof(buffer));
685
686 do {
687
688 if (Signal >= MBOX_SIG_HCI_BRIDGE_MAX) {
689 status = A_EINVAL;
690 break;
691 }
692
693 /* set the last buffer to do the actual signal trigger */
694 buffer[3] = (1 << Signal);
695
696 status = HIFReadWrite(pDev->HIFDevice,
697 INT_WLAN_ADDRESS,
698 buffer,
699 sizeof(buffer),
700 HIF_WR_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */
701 NULL);
702
703 if (status) {
704 break;
705 }
706
707 } while (false);
708
709
710 if (!status) {
711 /* now read back the register to see if the bit cleared */
712 while (AckTimeoutMS) {
713 status = HIFReadWrite(pDev->HIFDevice,
714 INT_WLAN_ADDRESS,
715 buffer,
716 sizeof(buffer),
717 HIF_RD_SYNC_BYTE_FIX,
718 NULL);
719
720 if (status) {
721 break;
722 }
723
724 for (i = 0; i < sizeof(buffer); i++) {
725 if (buffer[i] & (1 << Signal)) {
726 /* bit is still set */
727 break;
728 }
729 }
730
731 if (i >= sizeof(buffer)) {
732 /* done */
733 break;
734 }
735
736 AckTimeoutMS--;
737 A_MDELAY(1);
738 }
739
740 if (0 == AckTimeoutMS) {
741 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
742 ("DevGMboxSetTargetInterrupt : Ack Timed-out (sig:%d) \n",Signal));
743 status = A_ERROR;
744 }
745 }
746
747 return status;
748
749}
750
751#endif //ATH_AR6K_ENABLE_GMBOX
752
753
754
755
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c
new file mode 100644
index 00000000000..56a0d714380
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c
@@ -0,0 +1,1284 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6k_prot_hciUart.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Protocol module for use in bridging HCI-UART packets over the GMBOX interface
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include "a_config.h"
26#include "athdefs.h"
27#include "a_osapi.h"
28#include "../htc_debug.h"
29#include "hif.h"
30#include "htc_packet.h"
31#include "ar6k.h"
32#include "hci_transport_api.h"
33#include "gmboxif.h"
34#include "ar6000_diag.h"
35#include "hw/apb_map.h"
36#include "hw/mbox_reg.h"
37
38#ifdef ATH_AR6K_ENABLE_GMBOX
39#define HCI_UART_COMMAND_PKT 0x01
40#define HCI_UART_ACL_PKT 0x02
41#define HCI_UART_SCO_PKT 0x03
42#define HCI_UART_EVENT_PKT 0x04
43
44#define HCI_RECV_WAIT_BUFFERS (1 << 0)
45
46#define HCI_SEND_WAIT_CREDITS (1 << 0)
47
48#define HCI_UART_BRIDGE_CREDIT_SIZE 128
49
50#define CREDIT_POLL_COUNT 256
51
52#define HCI_DELAY_PER_INTERVAL_MS 10
53#define BTON_TIMEOUT_MS 500
54#define BTOFF_TIMEOUT_MS 500
55#define BAUD_TIMEOUT_MS 1
56#define BTPWRSAV_TIMEOUT_MS 1
57
58struct gmbox_proto_hci_uart {
59 struct hci_transport_config_info HCIConfig;
60 bool HCIAttached;
61 bool HCIStopped;
62 u32 RecvStateFlags;
63 u32 SendStateFlags;
64 HCI_TRANSPORT_PACKET_TYPE WaitBufferType;
65 struct htc_packet_queue SendQueue; /* write queue holding HCI Command and ACL packets */
66 struct htc_packet_queue HCIACLRecvBuffers; /* recv queue holding buffers for incomming ACL packets */
67 struct htc_packet_queue HCIEventBuffers; /* recv queue holding buffers for incomming event packets */
68 struct ar6k_device *pDev;
69 A_MUTEX_T HCIRxLock;
70 A_MUTEX_T HCITxLock;
71 int CreditsMax;
72 int CreditsConsumed;
73 int CreditsAvailable;
74 int CreditSize;
75 int CreditsCurrentSeek;
76 int SendProcessCount;
77};
78
79#define LOCK_HCI_RX(t) A_MUTEX_LOCK(&(t)->HCIRxLock);
80#define UNLOCK_HCI_RX(t) A_MUTEX_UNLOCK(&(t)->HCIRxLock);
81#define LOCK_HCI_TX(t) A_MUTEX_LOCK(&(t)->HCITxLock);
82#define UNLOCK_HCI_TX(t) A_MUTEX_UNLOCK(&(t)->HCITxLock);
83
84#define DO_HCI_RECV_INDICATION(p, pt) \
85do { \
86 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, \
87 ("HCI: Indicate Recv on packet:0x%lX status:%d len:%d type:%d \n", \
88 (unsigned long)(pt), \
89 (pt)->Status, \
90 !(pt)->Status ? (pt)->ActualLength : 0, \
91 HCI_GET_PACKET_TYPE(pt))); \
92 (p)->HCIConfig.pHCIPktRecv((p)->HCIConfig.pContext, (pt)); \
93} while (0)
94
95#define DO_HCI_SEND_INDICATION(p,pt) \
96{ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Indicate Send on packet:0x%lX status:%d type:%d \n", \
97 (unsigned long)(pt),(pt)->Status,HCI_GET_PACKET_TYPE(pt))); \
98 (p)->HCIConfig.pHCISendComplete((p)->HCIConfig.pContext, (pt)); \
99}
100
101static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous);
102
103static void HCIUartCleanup(struct gmbox_proto_hci_uart *pProtocol)
104{
105 A_ASSERT(pProtocol != NULL);
106
107 A_MUTEX_DELETE(&pProtocol->HCIRxLock);
108 A_MUTEX_DELETE(&pProtocol->HCITxLock);
109
110 kfree(pProtocol);
111}
112
113static int InitTxCreditState(struct gmbox_proto_hci_uart *pProt)
114{
115 int status;
116 int credits;
117 int creditPollCount = CREDIT_POLL_COUNT;
118 bool gotCredits = false;
119
120 pProt->CreditsConsumed = 0;
121
122 do {
123
124 if (pProt->CreditsMax != 0) {
125 /* we can only call this only once per target reset */
126 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI: InitTxCreditState - already called! \n"));
127 A_ASSERT(false);
128 status = A_EINVAL;
129 break;
130 }
131
132 /* read the credit counter. At startup the target will set the credit counter
133 * to the max available, we read this in a loop because it may take
134 * multiple credit counter reads to get all credits */
135
136 while (creditPollCount) {
137
138 credits = 0;
139
140 status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits);
141
142 if (status) {
143 break;
144 }
145
146 if (!gotCredits && (0 == credits)) {
147 creditPollCount--;
148 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: credit is 0, retrying (%d) \n",creditPollCount));
149 A_MDELAY(HCI_DELAY_PER_INTERVAL_MS);
150 continue;
151 } else {
152 gotCredits = true;
153 }
154
155 if (0 == credits) {
156 break;
157 }
158
159 pProt->CreditsMax += credits;
160 }
161
162 if (status) {
163 break;
164 }
165
166 if (0 == creditPollCount) {
167 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
168 ("** HCI : Failed to get credits! GMBOX Target was not available \n"));
169 status = A_ERROR;
170 break;
171 }
172
173 /* now get the size */
174 status = DevGMboxReadCreditSize(pProt->pDev, &pProt->CreditSize);
175
176 if (status) {
177 break;
178 }
179
180 } while (false);
181
182 if (!status) {
183 pProt->CreditsAvailable = pProt->CreditsMax;
184 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI : InitTxCreditState - credits avail: %d, size: %d \n",
185 pProt->CreditsAvailable, pProt->CreditSize));
186 }
187
188 return status;
189}
190
191static int CreditsAvailableCallback(void *pContext, int Credits, bool CreditIRQEnabled)
192{
193 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext;
194 bool enableCreditIrq = false;
195 bool disableCreditIrq = false;
196 bool doPendingSends = false;
197 int status = 0;
198
199 /** this callback is called under 2 conditions:
200 * 1. The credit IRQ interrupt was enabled and signaled.
201 * 2. A credit counter read completed.
202 *
203 * The function must not assume that the calling context can block !
204 */
205
206 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback (Credits:%d, IRQ:%s) \n",
207 Credits, CreditIRQEnabled ? "ON" : "OFF"));
208
209 LOCK_HCI_TX(pProt);
210
211 do {
212
213 if (0 == Credits) {
214 if (!CreditIRQEnabled) {
215 /* enable credit IRQ */
216 enableCreditIrq = true;
217 }
218 break;
219 }
220
221 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: current credit state, consumed:%d available:%d max:%d seek:%d\n",
222 pProt->CreditsConsumed,
223 pProt->CreditsAvailable,
224 pProt->CreditsMax,
225 pProt->CreditsCurrentSeek));
226
227 pProt->CreditsAvailable += Credits;
228 A_ASSERT(pProt->CreditsAvailable <= pProt->CreditsMax);
229 pProt->CreditsConsumed -= Credits;
230 A_ASSERT(pProt->CreditsConsumed >= 0);
231
232 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: new credit state, consumed:%d available:%d max:%d seek:%d\n",
233 pProt->CreditsConsumed,
234 pProt->CreditsAvailable,
235 pProt->CreditsMax,
236 pProt->CreditsCurrentSeek));
237
238 if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) {
239 /* we have enough credits to fulfill at least 1 packet waiting in the queue */
240 pProt->CreditsCurrentSeek = 0;
241 pProt->SendStateFlags &= ~HCI_SEND_WAIT_CREDITS;
242 doPendingSends = true;
243 if (CreditIRQEnabled) {
244 /* credit IRQ was enabled, we shouldn't need it anymore */
245 disableCreditIrq = true;
246 }
247 } else {
248 /* not enough credits yet, enable credit IRQ if we haven't already */
249 if (!CreditIRQEnabled) {
250 enableCreditIrq = true;
251 }
252 }
253
254 } while (false);
255
256 UNLOCK_HCI_TX(pProt);
257
258 if (enableCreditIrq) {
259 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Enabling credit count IRQ...\n"));
260 /* must use async only */
261 status = DevGMboxIRQAction(pProt->pDev, GMBOX_CREDIT_IRQ_ENABLE, PROC_IO_ASYNC);
262 } else if (disableCreditIrq) {
263 /* must use async only */
264 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Disabling credit count IRQ...\n"));
265 status = DevGMboxIRQAction(pProt->pDev, GMBOX_CREDIT_IRQ_DISABLE, PROC_IO_ASYNC);
266 }
267
268 if (doPendingSends) {
269 HCITrySend(pProt, NULL, false);
270 }
271
272 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback \n"));
273 return status;
274}
275
276static INLINE void NotifyTransportFailure(struct gmbox_proto_hci_uart *pProt, int status)
277{
278 if (pProt->HCIConfig.TransportFailure != NULL) {
279 pProt->HCIConfig.TransportFailure(pProt->HCIConfig.pContext, status);
280 }
281}
282
283static void FailureCallback(void *pContext, int Status)
284{
285 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext;
286
287 /* target assertion occurred */
288 NotifyTransportFailure(pProt, Status);
289}
290
291static void StateDumpCallback(void *pContext)
292{
293 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext;
294
295 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("============ HCIUart State ======================\n"));
296 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("RecvStateFlags : 0x%X \n",pProt->RecvStateFlags));
297 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("SendStateFlags : 0x%X \n",pProt->SendStateFlags));
298 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("WaitBufferType : %d \n",pProt->WaitBufferType));
299 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("SendQueue Depth : %d \n",HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue)));
300 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsMax : %d \n",pProt->CreditsMax));
301 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsConsumed : %d \n",pProt->CreditsConsumed));
302 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsAvailable : %d \n",pProt->CreditsAvailable));
303 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("==================================================\n"));
304}
305
306static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidBytes)
307{
308 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext;
309 int status = 0;
310 int totalRecvLength = 0;
311 HCI_TRANSPORT_PACKET_TYPE pktType = HCI_PACKET_INVALID;
312 bool recvRefillCalled = false;
313 bool blockRecv = false;
314 struct htc_packet *pPacket = NULL;
315
316 /** caller guarantees that this is a fully block-able context (synch I/O is allowed) */
317
318 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCIUartMessagePending Lookahead Bytes:%d \n",ValidBytes));
319
320 LOCK_HCI_RX(pProt);
321
322 do {
323
324 if (ValidBytes < 3) {
325 /* not enough for ACL or event header */
326 break;
327 }
328
329 if ((LookAheadBytes[0] == HCI_UART_ACL_PKT) && (ValidBytes < 5)) {
330 /* not enough for ACL data header */
331 break;
332 }
333
334 switch (LookAheadBytes[0]) {
335 case HCI_UART_EVENT_PKT:
336 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI Event: %d param length: %d \n",
337 LookAheadBytes[1], LookAheadBytes[2]));
338 totalRecvLength = LookAheadBytes[2];
339 totalRecvLength += 3; /* add type + event code + length field */
340 pktType = HCI_EVENT_TYPE;
341 break;
342 case HCI_UART_ACL_PKT:
343 totalRecvLength = (LookAheadBytes[4] << 8) | LookAheadBytes[3];
344 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI ACL: conn:0x%X length: %d \n",
345 ((LookAheadBytes[2] & 0xF0) << 8) | LookAheadBytes[1], totalRecvLength));
346 totalRecvLength += 5; /* add type + connection handle + length field */
347 pktType = HCI_ACL_TYPE;
348 break;
349 default:
350 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("**Invalid HCI packet type: %d \n",LookAheadBytes[0]));
351 status = A_EPROTO;
352 break;
353 }
354
355 if (status) {
356 break;
357 }
358
359 if (pProt->HCIConfig.pHCIPktRecvAlloc != NULL) {
360 UNLOCK_HCI_RX(pProt);
361 /* user is using a per-packet allocation callback */
362 pPacket = pProt->HCIConfig.pHCIPktRecvAlloc(pProt->HCIConfig.pContext,
363 pktType,
364 totalRecvLength);
365 LOCK_HCI_RX(pProt);
366
367 } else {
368 struct htc_packet_queue *pQueue;
369 /* user is using a refill handler that can refill multiple HTC buffers */
370
371 /* select buffer queue */
372 if (pktType == HCI_ACL_TYPE) {
373 pQueue = &pProt->HCIACLRecvBuffers;
374 } else {
375 pQueue = &pProt->HCIEventBuffers;
376 }
377
378 if (HTC_QUEUE_EMPTY(pQueue)) {
379 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
380 ("** HCI pkt type: %d has no buffers available calling allocation handler \n",
381 pktType));
382 /* check for refill handler */
383 if (pProt->HCIConfig.pHCIPktRecvRefill != NULL) {
384 recvRefillCalled = true;
385 UNLOCK_HCI_RX(pProt);
386 /* call the re-fill handler */
387 pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext,
388 pktType,
389 0);
390 LOCK_HCI_RX(pProt);
391 /* check if we have more buffers */
392 pPacket = HTC_PACKET_DEQUEUE(pQueue);
393 /* fall through */
394 }
395 } else {
396 pPacket = HTC_PACKET_DEQUEUE(pQueue);
397 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
398 ("HCI pkt type: %d now has %d recv buffers left \n",
399 pktType, HTC_PACKET_QUEUE_DEPTH(pQueue)));
400 }
401 }
402
403 if (NULL == pPacket) {
404 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
405 ("** HCI pkt type: %d has no buffers available stopping recv...\n", pktType));
406 /* this is not an error, we simply need to mark that we are waiting for buffers.*/
407 pProt->RecvStateFlags |= HCI_RECV_WAIT_BUFFERS;
408 pProt->WaitBufferType = pktType;
409 blockRecv = true;
410 break;
411 }
412
413 if (totalRecvLength > (int)pPacket->BufferLength) {
414 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI-UART pkt: %d requires %d bytes (%d buffer bytes avail) ! \n",
415 LookAheadBytes[0], totalRecvLength, pPacket->BufferLength));
416 status = A_EINVAL;
417 break;
418 }
419
420 } while (false);
421
422 UNLOCK_HCI_RX(pProt);
423
424 /* locks are released, we can go fetch the packet */
425
426 do {
427
428 if (status || (NULL == pPacket)) {
429 break;
430 }
431
432 /* do this synchronously, we don't need to be fast here */
433 pPacket->Completion = NULL;
434
435 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI : getting recv packet len:%d hci-uart-type: %s \n",
436 totalRecvLength, (LookAheadBytes[0] == HCI_UART_EVENT_PKT) ? "EVENT" : "ACL"));
437
438 status = DevGMboxRead(pProt->pDev, pPacket, totalRecvLength);
439
440 if (status) {
441 break;
442 }
443
444 if (pPacket->pBuffer[0] != LookAheadBytes[0]) {
445 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not contain expected packet type: %d ! \n",
446 pPacket->pBuffer[0]));
447 status = A_EPROTO;
448 break;
449 }
450
451 if (pPacket->pBuffer[0] == HCI_UART_EVENT_PKT) {
452 /* validate event header fields */
453 if ((pPacket->pBuffer[1] != LookAheadBytes[1]) ||
454 (pPacket->pBuffer[2] != LookAheadBytes[2])) {
455 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not match lookahead! \n"));
456 DebugDumpBytes(LookAheadBytes, 3, "Expected HCI-UART Header");
457 DebugDumpBytes(pPacket->pBuffer, 3, "** Bad HCI-UART Header");
458 status = A_EPROTO;
459 break;
460 }
461 } else if (pPacket->pBuffer[0] == HCI_UART_ACL_PKT) {
462 /* validate acl header fields */
463 if ((pPacket->pBuffer[1] != LookAheadBytes[1]) ||
464 (pPacket->pBuffer[2] != LookAheadBytes[2]) ||
465 (pPacket->pBuffer[3] != LookAheadBytes[3]) ||
466 (pPacket->pBuffer[4] != LookAheadBytes[4])) {
467 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not match lookahead! \n"));
468 DebugDumpBytes(LookAheadBytes, 5, "Expected HCI-UART Header");
469 DebugDumpBytes(pPacket->pBuffer, 5, "** Bad HCI-UART Header");
470 status = A_EPROTO;
471 break;
472 }
473 }
474
475 /* adjust buffer to move past packet ID */
476 pPacket->pBuffer++;
477 pPacket->ActualLength = totalRecvLength - 1;
478 pPacket->Status = 0;
479 /* indicate packet */
480 DO_HCI_RECV_INDICATION(pProt,pPacket);
481 pPacket = NULL;
482
483 /* check if we need to refill recv buffers */
484 if ((pProt->HCIConfig.pHCIPktRecvRefill != NULL) && !recvRefillCalled) {
485 struct htc_packet_queue *pQueue;
486 int watermark;
487
488 if (pktType == HCI_ACL_TYPE) {
489 watermark = pProt->HCIConfig.ACLRecvBufferWaterMark;
490 pQueue = &pProt->HCIACLRecvBuffers;
491 } else {
492 watermark = pProt->HCIConfig.EventRecvBufferWaterMark;
493 pQueue = &pProt->HCIEventBuffers;
494 }
495
496 if (HTC_PACKET_QUEUE_DEPTH(pQueue) < watermark) {
497 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
498 ("** HCI pkt type: %d watermark hit (%d) current:%d \n",
499 pktType, watermark, HTC_PACKET_QUEUE_DEPTH(pQueue)));
500 /* call the re-fill handler */
501 pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext,
502 pktType,
503 HTC_PACKET_QUEUE_DEPTH(pQueue));
504 }
505 }
506
507 } while (false);
508
509 /* check if we need to disable the receiver */
510 if (status || blockRecv) {
511 DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_DISABLE, PROC_IO_SYNC);
512 }
513
514 /* see if we need to recycle the recv buffer */
515 if (status && (pPacket != NULL)) {
516 struct htc_packet_queue queue;
517
518 if (A_EPROTO == status) {
519 DebugDumpBytes(pPacket->pBuffer, totalRecvLength, "Bad HCI-UART Recv packet");
520 }
521 /* recycle packet */
522 HTC_PACKET_RESET_RX(pPacket);
523 INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
524 HCI_TransportAddReceivePkts(pProt,&queue);
525 NotifyTransportFailure(pProt,status);
526 }
527
528
529 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCIUartMessagePending \n"));
530
531 return status;
532}
533
534static void HCISendPacketCompletion(void *Context, struct htc_packet *pPacket)
535{
536 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)Context;
537 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion (pPacket:0x%lX) \n",(unsigned long)pPacket));
538
539 if (pPacket->Status) {
540 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Send Packet (0x%lX) failed: %d , len:%d \n",
541 (unsigned long)pPacket, pPacket->Status, pPacket->ActualLength));
542 }
543
544 DO_HCI_SEND_INDICATION(pProt,pPacket);
545
546 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion \n"));
547}
548
549static int SeekCreditsSynch(struct gmbox_proto_hci_uart *pProt)
550{
551 int status = 0;
552 int credits;
553 int retry = 100;
554
555 while (true) {
556 credits = 0;
557 status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits);
558 if (status) {
559 break;
560 }
561 LOCK_HCI_TX(pProt);
562 pProt->CreditsAvailable += credits;
563 pProt->CreditsConsumed -= credits;
564 if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) {
565 pProt->CreditsCurrentSeek = 0;
566 UNLOCK_HCI_TX(pProt);
567 break;
568 }
569 UNLOCK_HCI_TX(pProt);
570 retry--;
571 if (0 == retry) {
572 status = A_EBUSY;
573 break;
574 }
575 A_MDELAY(20);
576 }
577
578 return status;
579}
580
581static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous)
582{
583 int status = 0;
584 int transferLength;
585 int creditsRequired, remainder;
586 u8 hciUartType;
587 bool synchSendComplete = false;
588
589 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCITrySend (pPacket:0x%lX) %s \n",(unsigned long)pPacket,
590 Synchronous ? "SYNC" :"ASYNC"));
591
592 LOCK_HCI_TX(pProt);
593
594 /* increment write processing count on entry */
595 pProt->SendProcessCount++;
596
597 do {
598
599 if (pProt->HCIStopped) {
600 status = A_ECANCELED;
601 break;
602 }
603
604 if (pPacket != NULL) {
605 /* packet was supplied */
606 if (Synchronous) {
607 /* in synchronous mode, the send queue can only hold 1 packet */
608 if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
609 status = A_EBUSY;
610 A_ASSERT(false);
611 break;
612 }
613
614 if (pProt->SendProcessCount > 1) {
615 /* another thread or task is draining the TX queues */
616 status = A_EBUSY;
617 A_ASSERT(false);
618 break;
619 }
620
621 HTC_PACKET_ENQUEUE(&pProt->SendQueue,pPacket);
622
623 } else {
624 /* see if adding this packet hits the max depth (asynchronous mode only) */
625 if ((pProt->HCIConfig.MaxSendQueueDepth > 0) &&
626 ((HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue) + 1) >= pProt->HCIConfig.MaxSendQueueDepth)) {
627 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("HCI Send queue is full, Depth:%d, Max:%d \n",
628 HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue),
629 pProt->HCIConfig.MaxSendQueueDepth));
630 /* queue will be full, invoke any callbacks to determine what action to take */
631 if (pProt->HCIConfig.pHCISendFull != NULL) {
632 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
633 ("HCI : Calling driver's send full callback.... \n"));
634 if (pProt->HCIConfig.pHCISendFull(pProt->HCIConfig.pContext,
635 pPacket) == HCI_SEND_FULL_DROP) {
636 /* drop it */
637 status = A_NO_RESOURCE;
638 break;
639 }
640 }
641 }
642
643 HTC_PACKET_ENQUEUE(&pProt->SendQueue,pPacket);
644 }
645
646 }
647
648 if (pProt->SendStateFlags & HCI_SEND_WAIT_CREDITS) {
649 break;
650 }
651
652 if (pProt->SendProcessCount > 1) {
653 /* another thread or task is draining the TX queues */
654 break;
655 }
656
657 /***** beyond this point only 1 thread may enter ******/
658
659 /* now drain the send queue for transmission as long as we have enough
660 * credits */
661 while (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
662
663 pPacket = HTC_PACKET_DEQUEUE(&pProt->SendQueue);
664
665 switch (HCI_GET_PACKET_TYPE(pPacket)) {
666 case HCI_COMMAND_TYPE:
667 hciUartType = HCI_UART_COMMAND_PKT;
668 break;
669 case HCI_ACL_TYPE:
670 hciUartType = HCI_UART_ACL_PKT;
671 break;
672 default:
673 status = A_EINVAL;
674 A_ASSERT(false);
675 break;
676 }
677
678 if (status) {
679 break;
680 }
681
682 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Got head packet:0x%lX , Type:%d Length: %d Remaining Queue Depth: %d\n",
683 (unsigned long)pPacket, HCI_GET_PACKET_TYPE(pPacket), pPacket->ActualLength,
684 HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue)));
685
686 transferLength = 1; /* UART type header is 1 byte */
687 transferLength += pPacket->ActualLength;
688 transferLength = DEV_CALC_SEND_PADDED_LEN(pProt->pDev, transferLength);
689
690 /* figure out how many credits this message requires */
691 creditsRequired = transferLength / pProt->CreditSize;
692 remainder = transferLength % pProt->CreditSize;
693
694 if (remainder) {
695 creditsRequired++;
696 }
697
698 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Creds Required:%d Got:%d\n",
699 creditsRequired, pProt->CreditsAvailable));
700
701 if (creditsRequired > pProt->CreditsAvailable) {
702 if (Synchronous) {
703 /* in synchronous mode we need to seek credits in synchronously */
704 pProt->CreditsCurrentSeek = creditsRequired;
705 UNLOCK_HCI_TX(pProt);
706 status = SeekCreditsSynch(pProt);
707 LOCK_HCI_TX(pProt);
708 if (status) {
709 break;
710 }
711 /* fall through and continue processing this send op */
712 } else {
713 /* not enough credits, queue back to the head */
714 HTC_PACKET_ENQUEUE_TO_HEAD(&pProt->SendQueue,pPacket);
715 /* waiting for credits */
716 pProt->SendStateFlags |= HCI_SEND_WAIT_CREDITS;
717 /* provide a hint to reduce attempts to re-send if credits are dribbling back
718 * this hint is the short fall of credits */
719 pProt->CreditsCurrentSeek = creditsRequired;
720 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: packet:0x%lX placed back in queue. head packet needs: %d credits \n",
721 (unsigned long)pPacket, pProt->CreditsCurrentSeek));
722 pPacket = NULL;
723 UNLOCK_HCI_TX(pProt);
724
725 /* schedule a credit counter read, our CreditsAvailableCallback callback will be called
726 * with the result */
727 DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_ASYNC, NULL);
728
729 LOCK_HCI_TX(pProt);
730 break;
731 }
732 }
733
734 /* caller guarantees some head room */
735 pPacket->pBuffer--;
736 pPacket->pBuffer[0] = hciUartType;
737
738 pProt->CreditsAvailable -= creditsRequired;
739 pProt->CreditsConsumed += creditsRequired;
740 A_ASSERT(pProt->CreditsConsumed <= pProt->CreditsMax);
741
742 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: new credit state: consumed:%d available:%d max:%d\n",
743 pProt->CreditsConsumed, pProt->CreditsAvailable, pProt->CreditsMax));
744
745 UNLOCK_HCI_TX(pProt);
746
747 /* write it out */
748 if (Synchronous) {
749 pPacket->Completion = NULL;
750 pPacket->pContext = NULL;
751 } else {
752 pPacket->Completion = HCISendPacketCompletion;
753 pPacket->pContext = pProt;
754 }
755
756 status = DevGMboxWrite(pProt->pDev,pPacket,transferLength);
757 if (Synchronous) {
758 synchSendComplete = true;
759 } else {
760 pPacket = NULL;
761 }
762
763 LOCK_HCI_TX(pProt);
764
765 }
766
767 } while (false);
768
769 pProt->SendProcessCount--;
770 A_ASSERT(pProt->SendProcessCount >= 0);
771 UNLOCK_HCI_TX(pProt);
772
773 if (Synchronous) {
774 A_ASSERT(pPacket != NULL);
775 if (!status && (!synchSendComplete)) {
776 status = A_EBUSY;
777 A_ASSERT(false);
778 LOCK_HCI_TX(pProt);
779 if (pPacket->ListLink.pNext != NULL) {
780 /* remove from the queue */
781 HTC_PACKET_REMOVE(&pProt->SendQueue,pPacket);
782 }
783 UNLOCK_HCI_TX(pProt);
784 }
785 } else {
786 if (status && (pPacket != NULL)) {
787 pPacket->Status = status;
788 DO_HCI_SEND_INDICATION(pProt,pPacket);
789 }
790 }
791
792 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HCITrySend: \n"));
793 return status;
794}
795
796static void FlushSendQueue(struct gmbox_proto_hci_uart *pProt)
797{
798 struct htc_packet *pPacket;
799 struct htc_packet_queue discardQueue;
800
801 INIT_HTC_PACKET_QUEUE(&discardQueue);
802
803 LOCK_HCI_TX(pProt);
804
805 if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
806 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->SendQueue);
807 }
808
809 UNLOCK_HCI_TX(pProt);
810
811 /* discard packets */
812 while (!HTC_QUEUE_EMPTY(&discardQueue)) {
813 pPacket = HTC_PACKET_DEQUEUE(&discardQueue);
814 pPacket->Status = A_ECANCELED;
815 DO_HCI_SEND_INDICATION(pProt,pPacket);
816 }
817
818}
819
820static void FlushRecvBuffers(struct gmbox_proto_hci_uart *pProt)
821{
822 struct htc_packet_queue discardQueue;
823 struct htc_packet *pPacket;
824
825 INIT_HTC_PACKET_QUEUE(&discardQueue);
826
827 LOCK_HCI_RX(pProt);
828 /*transfer list items from ACL and event buffer queues to the discard queue */
829 if (!HTC_QUEUE_EMPTY(&pProt->HCIACLRecvBuffers)) {
830 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->HCIACLRecvBuffers);
831 }
832 if (!HTC_QUEUE_EMPTY(&pProt->HCIEventBuffers)) {
833 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->HCIEventBuffers);
834 }
835 UNLOCK_HCI_RX(pProt);
836
837 /* now empty the discard queue */
838 while (!HTC_QUEUE_EMPTY(&discardQueue)) {
839 pPacket = HTC_PACKET_DEQUEUE(&discardQueue);
840 pPacket->Status = A_ECANCELED;
841 DO_HCI_RECV_INDICATION(pProt,pPacket);
842 }
843
844}
845
846/*** protocol module install entry point ***/
847
848int GMboxProtocolInstall(struct ar6k_device *pDev)
849{
850 int status = 0;
851 struct gmbox_proto_hci_uart *pProtocol = NULL;
852
853 do {
854
855 pProtocol = A_MALLOC(sizeof(struct gmbox_proto_hci_uart));
856
857 if (NULL == pProtocol) {
858 status = A_NO_MEMORY;
859 break;
860 }
861
862 A_MEMZERO(pProtocol, sizeof(*pProtocol));
863 pProtocol->pDev = pDev;
864 INIT_HTC_PACKET_QUEUE(&pProtocol->SendQueue);
865 INIT_HTC_PACKET_QUEUE(&pProtocol->HCIACLRecvBuffers);
866 INIT_HTC_PACKET_QUEUE(&pProtocol->HCIEventBuffers);
867 A_MUTEX_INIT(&pProtocol->HCIRxLock);
868 A_MUTEX_INIT(&pProtocol->HCITxLock);
869
870 } while (false);
871
872 if (!status) {
873 LOCK_AR6K(pDev);
874 DEV_GMBOX_SET_PROTOCOL(pDev,
875 HCIUartMessagePending,
876 CreditsAvailableCallback,
877 FailureCallback,
878 StateDumpCallback,
879 pProtocol);
880 UNLOCK_AR6K(pDev);
881 } else {
882 if (pProtocol != NULL) {
883 HCIUartCleanup(pProtocol);
884 }
885 }
886
887 return status;
888}
889
890/*** protocol module uninstall entry point ***/
891void GMboxProtocolUninstall(struct ar6k_device *pDev)
892{
893 struct gmbox_proto_hci_uart *pProtocol = (struct gmbox_proto_hci_uart *)DEV_GMBOX_GET_PROTOCOL(pDev);
894
895 if (pProtocol != NULL) {
896
897 /* notify anyone attached */
898 if (pProtocol->HCIAttached) {
899 A_ASSERT(pProtocol->HCIConfig.TransportRemoved != NULL);
900 pProtocol->HCIConfig.TransportRemoved(pProtocol->HCIConfig.pContext);
901 pProtocol->HCIAttached = false;
902 }
903
904 HCIUartCleanup(pProtocol);
905 DEV_GMBOX_SET_PROTOCOL(pDev,NULL,NULL,NULL,NULL,NULL);
906 }
907
908}
909
910static int NotifyTransportReady(struct gmbox_proto_hci_uart *pProt)
911{
912 struct hci_transport_properties props;
913 int status = 0;
914
915 do {
916
917 A_MEMZERO(&props,sizeof(props));
918
919 /* HCI UART only needs one extra byte at the head to indicate the packet TYPE */
920 props.HeadRoom = 1;
921 props.TailRoom = 0;
922 props.IOBlockPad = pProt->pDev->BlockSize;
923 if (pProt->HCIAttached) {
924 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI: notifying attached client to transport... \n"));
925 A_ASSERT(pProt->HCIConfig.TransportReady != NULL);
926 status = pProt->HCIConfig.TransportReady(pProt,
927 &props,
928 pProt->HCIConfig.pContext);
929 }
930
931 } while (false);
932
933 return status;
934}
935
936/*********** HCI UART protocol implementation ************************************************/
937
938HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, struct hci_transport_config_info *pInfo)
939{
940 struct gmbox_proto_hci_uart *pProtocol = NULL;
941 struct ar6k_device *pDev;
942
943 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportAttach \n"));
944
945 pDev = HTCGetAR6KDevice(HTCHandle);
946
947 LOCK_AR6K(pDev);
948
949 do {
950
951 pProtocol = (struct gmbox_proto_hci_uart *)DEV_GMBOX_GET_PROTOCOL(pDev);
952
953 if (NULL == pProtocol) {
954 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not installed! \n"));
955 break;
956 }
957
958 if (pProtocol->HCIAttached) {
959 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol already attached! \n"));
960 break;
961 }
962
963 memcpy(&pProtocol->HCIConfig, pInfo, sizeof(struct hci_transport_config_info));
964
965 A_ASSERT(pProtocol->HCIConfig.pHCIPktRecv != NULL);
966 A_ASSERT(pProtocol->HCIConfig.pHCISendComplete != NULL);
967
968 pProtocol->HCIAttached = true;
969
970 } while (false);
971
972 UNLOCK_AR6K(pDev);
973
974 if (pProtocol != NULL) {
975 /* TODO ... should we use a worker? */
976 NotifyTransportReady(pProtocol);
977 }
978
979 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach (0x%lX) \n",(unsigned long)pProtocol));
980 return (HCI_TRANSPORT_HANDLE)pProtocol;
981}
982
983void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans)
984{
985 struct gmbox_proto_hci_uart *pProtocol = (struct gmbox_proto_hci_uart *)HciTrans;
986 struct ar6k_device *pDev = pProtocol->pDev;
987
988 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportDetach \n"));
989
990 LOCK_AR6K(pDev);
991 if (!pProtocol->HCIAttached) {
992 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not attached! \n"));
993 UNLOCK_AR6K(pDev);
994 return;
995 }
996 pProtocol->HCIAttached = false;
997 UNLOCK_AR6K(pDev);
998
999 HCI_TransportStop(HciTrans);
1000 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach \n"));
1001}
1002
1003int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue)
1004{
1005 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1006 int status = 0;
1007 bool unblockRecv = false;
1008 struct htc_packet *pPacket;
1009
1010 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCI_TransportAddReceivePkt \n"));
1011
1012 LOCK_HCI_RX(pProt);
1013
1014 do {
1015
1016 if (pProt->HCIStopped) {
1017 status = A_ECANCELED;
1018 break;
1019 }
1020
1021 pPacket = HTC_GET_PKT_AT_HEAD(pQueue);
1022
1023 if (NULL == pPacket) {
1024 status = A_EINVAL;
1025 break;
1026 }
1027
1028 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" HCI recv packet added, type :%d, len:%d num:%d \n",
1029 HCI_GET_PACKET_TYPE(pPacket), pPacket->BufferLength, HTC_PACKET_QUEUE_DEPTH(pQueue)));
1030
1031 if (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) {
1032 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pProt->HCIEventBuffers, pQueue);
1033 } else if (HCI_GET_PACKET_TYPE(pPacket) == HCI_ACL_TYPE) {
1034 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pProt->HCIACLRecvBuffers, pQueue);
1035 } else {
1036 status = A_EINVAL;
1037 break;
1038 }
1039
1040 if (pProt->RecvStateFlags & HCI_RECV_WAIT_BUFFERS) {
1041 if (pProt->WaitBufferType == HCI_GET_PACKET_TYPE(pPacket)) {
1042 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" HCI recv was blocked on packet type :%d, unblocking.. \n",
1043 pProt->WaitBufferType));
1044 pProt->RecvStateFlags &= ~HCI_RECV_WAIT_BUFFERS;
1045 pProt->WaitBufferType = HCI_PACKET_INVALID;
1046 unblockRecv = true;
1047 }
1048 }
1049
1050 } while (false);
1051
1052 UNLOCK_HCI_RX(pProt);
1053
1054 if (status) {
1055 while (!HTC_QUEUE_EMPTY(pQueue)) {
1056 pPacket = HTC_PACKET_DEQUEUE(pQueue);
1057 pPacket->Status = A_ECANCELED;
1058 DO_HCI_RECV_INDICATION(pProt,pPacket);
1059 }
1060 }
1061
1062 if (unblockRecv) {
1063 DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_ASYNC);
1064 }
1065
1066 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCI_TransportAddReceivePkt \n"));
1067
1068 return 0;
1069}
1070
1071int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous)
1072{
1073 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1074
1075 return HCITrySend(pProt,pPacket,Synchronous);
1076}
1077
1078void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans)
1079{
1080 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1081
1082 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStop \n"));
1083
1084 LOCK_AR6K(pProt->pDev);
1085 if (pProt->HCIStopped) {
1086 UNLOCK_AR6K(pProt->pDev);
1087 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n"));
1088 return;
1089 }
1090 pProt->HCIStopped = true;
1091 UNLOCK_AR6K(pProt->pDev);
1092
1093 /* disable interrupts */
1094 DevGMboxIRQAction(pProt->pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC);
1095 FlushSendQueue(pProt);
1096 FlushRecvBuffers(pProt);
1097
1098 /* signal bridge side to power down BT */
1099 DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_OFF, BTOFF_TIMEOUT_MS);
1100
1101 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n"));
1102}
1103
1104int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans)
1105{
1106 int status;
1107 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1108
1109 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStart \n"));
1110
1111 /* set stopped in case we have a problem in starting */
1112 pProt->HCIStopped = true;
1113
1114 do {
1115
1116 status = InitTxCreditState(pProt);
1117
1118 if (status) {
1119 break;
1120 }
1121
1122 status = DevGMboxIRQAction(pProt->pDev, GMBOX_ERRORS_IRQ_ENABLE, PROC_IO_SYNC);
1123
1124 if (status) {
1125 break;
1126 }
1127 /* enable recv */
1128 status = DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_SYNC);
1129
1130 if (status) {
1131 break;
1132 }
1133 /* signal bridge side to power up BT */
1134 status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_ON, BTON_TIMEOUT_MS);
1135
1136 if (status) {
1137 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI_TransportStart : Failed to trigger BT ON \n"));
1138 break;
1139 }
1140
1141 /* we made it */
1142 pProt->HCIStopped = false;
1143
1144 } while (false);
1145
1146 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStart \n"));
1147
1148 return status;
1149}
1150
1151int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable)
1152{
1153 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1154 return DevGMboxIRQAction(pProt->pDev,
1155 Enable ? GMBOX_RECV_IRQ_ENABLE : GMBOX_RECV_IRQ_DISABLE,
1156 PROC_IO_SYNC);
1157
1158}
1159
1160int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans,
1161 struct htc_packet *pPacket,
1162 int MaxPollMS)
1163{
1164 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1165 int status = 0;
1166 u8 lookAhead[8];
1167 int bytes;
1168 int totalRecvLength;
1169
1170 MaxPollMS = MaxPollMS / 16;
1171
1172 if (MaxPollMS < 2) {
1173 MaxPollMS = 2;
1174 }
1175
1176 while (MaxPollMS) {
1177
1178 bytes = sizeof(lookAhead);
1179 status = DevGMboxRecvLookAheadPeek(pProt->pDev,lookAhead,&bytes);
1180 if (status) {
1181 break;
1182 }
1183
1184 if (bytes < 3) {
1185 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI recv poll got bytes: %d, retry : %d \n",
1186 bytes, MaxPollMS));
1187 A_MDELAY(16);
1188 MaxPollMS--;
1189 continue;
1190 }
1191
1192 totalRecvLength = 0;
1193 switch (lookAhead[0]) {
1194 case HCI_UART_EVENT_PKT:
1195 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI Event: %d param length: %d \n",
1196 lookAhead[1], lookAhead[2]));
1197 totalRecvLength = lookAhead[2];
1198 totalRecvLength += 3; /* add type + event code + length field */
1199 break;
1200 default:
1201 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("**Invalid HCI packet type: %d \n",lookAhead[0]));
1202 status = A_EPROTO;
1203 break;
1204 }
1205
1206 if (status) {
1207 break;
1208 }
1209
1210 pPacket->Completion = NULL;
1211 status = DevGMboxRead(pProt->pDev,pPacket,totalRecvLength);
1212 if (status) {
1213 break;
1214 }
1215
1216 pPacket->pBuffer++;
1217 pPacket->ActualLength = totalRecvLength - 1;
1218 pPacket->Status = 0;
1219 break;
1220 }
1221
1222 if (MaxPollMS == 0) {
1223 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI recv poll timeout! \n"));
1224 status = A_ERROR;
1225 }
1226
1227 return status;
1228}
1229
1230#define LSB_SCRATCH_IDX 4
1231#define MSB_SCRATCH_IDX 5
1232int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud)
1233{
1234 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1235 struct hif_device *pHIFDevice = (struct hif_device *)(pProt->pDev->HIFDevice);
1236 u32 scaledBaud, scratchAddr;
1237 int status = 0;
1238
1239 /* Divide the desired baud rate by 100
1240 * Store the LSB in the local scratch register 4 and the MSB in the local
1241 * scratch register 5 for the target to read
1242 */
1243 scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * LSB_SCRATCH_IDX);
1244 scaledBaud = (Baud / 100) & LOCAL_SCRATCH_VALUE_MASK;
1245 status = ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud);
1246 scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * MSB_SCRATCH_IDX);
1247 scaledBaud = ((Baud / 100) >> (LOCAL_SCRATCH_VALUE_MSB+1)) & LOCAL_SCRATCH_VALUE_MASK;
1248 status |= ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud);
1249 if (0 != status) {
1250 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to set up baud rate in scratch register!"));
1251 return status;
1252 }
1253
1254 /* Now interrupt the target to tell it about the baud rate */
1255 status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BAUD_SET, BAUD_TIMEOUT_MS);
1256 if (0 != status) {
1257 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to tell target to change baud rate!"));
1258 }
1259
1260 return status;
1261}
1262
1263int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable)
1264{
1265 int status;
1266 struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
1267
1268 if (Enable) {
1269 status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON, BTPWRSAV_TIMEOUT_MS);
1270 } else {
1271 status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF, BTPWRSAV_TIMEOUT_MS);
1272 }
1273
1274 if (status) {
1275 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to enable/disable HCI power management!\n"));
1276 } else {
1277 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI power management enabled/disabled!\n"));
1278 }
1279
1280 return status;
1281}
1282
1283#endif //ATH_AR6K_ENABLE_GMBOX
1284
diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c
new file mode 100644
index 00000000000..ae54e64b624
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc.c
@@ -0,0 +1,575 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#include "htc_internal.h"
24
25#ifdef ATH_DEBUG_MODULE
26static struct ath_debug_mask_description g_HTCDebugDescription[] = {
27 { ATH_DEBUG_SEND , "Send"},
28 { ATH_DEBUG_RECV , "Recv"},
29 { ATH_DEBUG_SYNC , "Sync"},
30 { ATH_DEBUG_DUMP , "Dump Data (RX or TX)"},
31 { ATH_DEBUG_IRQ , "Interrupt Processing"}
32};
33
34ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc,
35 "htc",
36 "Host Target Communications",
37 ATH_DEBUG_MASK_DEFAULTS,
38 ATH_DEBUG_DESCRIPTION_COUNT(g_HTCDebugDescription),
39 g_HTCDebugDescription);
40
41#endif
42
43static void HTCReportFailure(void *Context);
44static void ResetEndpointStates(struct htc_target *target);
45
46void HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList)
47{
48 LOCK_HTC(target);
49 HTC_PACKET_ENQUEUE(pList,pPacket);
50 UNLOCK_HTC(target);
51}
52
53struct htc_packet *HTCAllocControlBuffer(struct htc_target *target, struct htc_packet_queue *pList)
54{
55 struct htc_packet *pPacket;
56
57 LOCK_HTC(target);
58 pPacket = HTC_PACKET_DEQUEUE(pList);
59 UNLOCK_HTC(target);
60
61 return pPacket;
62}
63
64/* cleanup the HTC instance */
65static void HTCCleanup(struct htc_target *target)
66{
67 s32 i;
68
69 DevCleanup(&target->Device);
70
71 for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
72 if (target->HTCControlBuffers[i].Buffer) {
73 kfree(target->HTCControlBuffers[i].Buffer);
74 }
75 }
76
77 if (A_IS_MUTEX_VALID(&target->HTCLock)) {
78 A_MUTEX_DELETE(&target->HTCLock);
79 }
80
81 if (A_IS_MUTEX_VALID(&target->HTCRxLock)) {
82 A_MUTEX_DELETE(&target->HTCRxLock);
83 }
84
85 if (A_IS_MUTEX_VALID(&target->HTCTxLock)) {
86 A_MUTEX_DELETE(&target->HTCTxLock);
87 }
88 /* free our instance */
89 kfree(target);
90}
91
92/* registered target arrival callback from the HIF layer */
93HTC_HANDLE HTCCreate(void *hif_handle, struct htc_init_info *pInfo)
94{
95 struct htc_target *target = NULL;
96 int status = 0;
97 int i;
98 u32 ctrl_bufsz;
99 u32 blocksizes[HTC_MAILBOX_NUM_MAX];
100
101 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Enter\n"));
102
103 A_REGISTER_MODULE_DEBUG_INFO(htc);
104
105 do {
106
107 /* allocate target memory */
108 if ((target = (struct htc_target *)A_MALLOC(sizeof(struct htc_target))) == NULL) {
109 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
110 status = A_ERROR;
111 break;
112 }
113
114 A_MEMZERO(target, sizeof(struct htc_target));
115 A_MUTEX_INIT(&target->HTCLock);
116 A_MUTEX_INIT(&target->HTCRxLock);
117 A_MUTEX_INIT(&target->HTCTxLock);
118 INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);
119 INIT_HTC_PACKET_QUEUE(&target->ControlBufferRXFreeList);
120
121 /* give device layer the hif device handle */
122 target->Device.HIFDevice = hif_handle;
123 /* give the device layer our context (for event processing)
124 * the device layer will register it's own context with HIF
125 * so we need to set this so we can fetch it in the target remove handler */
126 target->Device.HTCContext = target;
127 /* set device layer target failure callback */
128 target->Device.TargetFailureCallback = HTCReportFailure;
129 /* set device layer recv message pending callback */
130 target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler;
131 target->EpWaitingForBuffers = ENDPOINT_MAX;
132
133 memcpy(&target->HTCInitInfo,pInfo,sizeof(struct htc_init_info));
134
135 ResetEndpointStates(target);
136
137 /* setup device layer */
138 status = DevSetup(&target->Device);
139
140 if (status) {
141 break;
142 }
143
144
145 /* get the block sizes */
146 status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
147 blocksizes, sizeof(blocksizes));
148 if (status) {
149 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get block size info from HIF layer...\n"));
150 break;
151 }
152
153 /* Set the control buffer size based on the block size */
154 if (blocksizes[1] > HTC_MAX_CONTROL_MESSAGE_LENGTH) {
155 ctrl_bufsz = blocksizes[1] + HTC_HDR_LENGTH;
156 } else {
157 ctrl_bufsz = HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH;
158 }
159 for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
160 target->HTCControlBuffers[i].Buffer = A_MALLOC(ctrl_bufsz);
161 if (target->HTCControlBuffers[i].Buffer == NULL) {
162 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
163 status = A_ERROR;
164 break;
165 }
166 }
167
168 if (status) {
169 break;
170 }
171
172 /* carve up buffers/packets for control messages */
173 for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) {
174 struct htc_packet *pControlPacket;
175 pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
176 SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket,
177 target,
178 target->HTCControlBuffers[i].Buffer,
179 ctrl_bufsz,
180 ENDPOINT_0);
181 HTC_FREE_CONTROL_RX(target,pControlPacket);
182 }
183
184 for (;i < NUM_CONTROL_BUFFERS;i++) {
185 struct htc_packet *pControlPacket;
186 pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
187 INIT_HTC_PACKET_INFO(pControlPacket,
188 target->HTCControlBuffers[i].Buffer,
189 ctrl_bufsz);
190 HTC_FREE_CONTROL_TX(target,pControlPacket);
191 }
192
193 } while (false);
194
195 if (status) {
196 if (target != NULL) {
197 HTCCleanup(target);
198 target = NULL;
199 }
200 }
201
202 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Exit\n"));
203
204 return target;
205}
206
207void HTCDestroy(HTC_HANDLE HTCHandle)
208{
209 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
210 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCDestroy .. Destroying :0x%lX \n",(unsigned long)target));
211 HTCCleanup(target);
212 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCDestroy \n"));
213}
214
215/* get the low level HIF device for the caller , the caller may wish to do low level
216 * HIF requests */
217void *HTCGetHifDevice(HTC_HANDLE HTCHandle)
218{
219 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
220 return target->Device.HIFDevice;
221}
222
223/* wait for the target to arrive (sends HTC Ready message)
224 * this operation is fully synchronous and the message is polled for */
225int HTCWaitTarget(HTC_HANDLE HTCHandle)
226{
227 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
228 int status;
229 struct htc_packet *pPacket = NULL;
230 HTC_READY_EX_MSG *pRdyMsg;
231
232 struct htc_service_connect_req connect;
233 struct htc_service_connect_resp resp;
234
235 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%lX) \n", (unsigned long)target));
236
237 do {
238
239#ifdef MBOXHW_UNIT_TEST
240
241 status = DoMboxHWTest(&target->Device);
242
243 if (status) {
244 break;
245 }
246
247#endif
248
249 /* we should be getting 1 control message that the target is ready */
250 status = HTCWaitforControlMessage(target, &pPacket);
251
252 if (status) {
253 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n"));
254 break;
255 }
256
257 /* we controlled the buffer creation so it has to be properly aligned */
258 pRdyMsg = (HTC_READY_EX_MSG *)pPacket->pBuffer;
259
260 if ((pRdyMsg->Version2_0_Info.MessageID != HTC_MSG_READY_ID) ||
261 (pPacket->ActualLength < sizeof(HTC_READY_MSG))) {
262 /* this message is not valid */
263 AR_DEBUG_ASSERT(false);
264 status = A_EPROTO;
265 break;
266 }
267
268
269 if (pRdyMsg->Version2_0_Info.CreditCount == 0 || pRdyMsg->Version2_0_Info.CreditSize == 0) {
270 /* this message is not valid */
271 AR_DEBUG_ASSERT(false);
272 status = A_EPROTO;
273 break;
274 }
275
276 target->TargetCredits = pRdyMsg->Version2_0_Info.CreditCount;
277 target->TargetCreditSize = pRdyMsg->Version2_0_Info.CreditSize;
278
279 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, (" Target Ready: credits: %d credit size: %d\n",
280 target->TargetCredits, target->TargetCreditSize));
281
282 /* check if this is an extended ready message */
283 if (pPacket->ActualLength >= sizeof(HTC_READY_EX_MSG)) {
284 /* this is an extended message */
285 target->HTCTargetVersion = pRdyMsg->HTCVersion;
286 target->MaxMsgPerBundle = pRdyMsg->MaxMsgsPerHTCBundle;
287 } else {
288 /* legacy */
289 target->HTCTargetVersion = HTC_VERSION_2P0;
290 target->MaxMsgPerBundle = 0;
291 }
292
293#ifdef HTC_FORCE_LEGACY_2P0
294 /* for testing and comparison...*/
295 target->HTCTargetVersion = HTC_VERSION_2P0;
296 target->MaxMsgPerBundle = 0;
297#endif
298
299 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
300 ("Using HTC Protocol Version : %s (%d)\n ",
301 (target->HTCTargetVersion == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
302 target->HTCTargetVersion));
303
304 if (target->MaxMsgPerBundle > 0) {
305 /* limit what HTC can handle */
306 target->MaxMsgPerBundle = min(HTC_HOST_MAX_MSG_PER_BUNDLE, target->MaxMsgPerBundle);
307 /* target supports message bundling, setup device layer */
308 if (DevSetupMsgBundling(&target->Device,target->MaxMsgPerBundle)) {
309 /* device layer can't handle bundling */
310 target->MaxMsgPerBundle = 0;
311 } else {
312 /* limit bundle what the device layer can handle */
313 target->MaxMsgPerBundle = min(DEV_GET_MAX_MSG_PER_BUNDLE(&target->Device),
314 target->MaxMsgPerBundle);
315 }
316 }
317
318 if (target->MaxMsgPerBundle > 0) {
319 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
320 (" HTC bundling allowed. Max Msg Per HTC Bundle: %d\n", target->MaxMsgPerBundle));
321
322 if (DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device) != 0) {
323 target->SendBundlingEnabled = true;
324 }
325 if (DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device) != 0) {
326 target->RecvBundlingEnabled = true;
327 }
328
329 if (!DEV_IS_LEN_BLOCK_ALIGNED(&target->Device,target->TargetCreditSize)) {
330 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("*** Credit size: %d is not block aligned! Disabling send bundling \n",
331 target->TargetCreditSize));
332 /* disallow send bundling since the credit size is not aligned to a block size
333 * the I/O block padding will spill into the next credit buffer which is fatal */
334 target->SendBundlingEnabled = false;
335 }
336 }
337
338 /* setup our pseudo HTC control endpoint connection */
339 A_MEMZERO(&connect,sizeof(connect));
340 A_MEMZERO(&resp,sizeof(resp));
341 connect.EpCallbacks.pContext = target;
342 connect.EpCallbacks.EpTxComplete = HTCControlTxComplete;
343 connect.EpCallbacks.EpRecv = HTCControlRecv;
344 connect.EpCallbacks.EpRecvRefill = NULL; /* not needed */
345 connect.EpCallbacks.EpSendFull = NULL; /* not nedded */
346 connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS;
347 connect.ServiceID = HTC_CTRL_RSVD_SVC;
348
349 /* connect fake service */
350 status = HTCConnectService((HTC_HANDLE)target,
351 &connect,
352 &resp);
353
354 if (!status) {
355 break;
356 }
357
358 } while (false);
359
360 if (pPacket != NULL) {
361 HTC_FREE_CONTROL_RX(target,pPacket);
362 }
363
364 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit\n"));
365
366 return status;
367}
368
369
370
371/* Start HTC, enable interrupts and let the target know host has finished setup */
372int HTCStart(HTC_HANDLE HTCHandle)
373{
374 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
375 struct htc_packet *pPacket;
376 int status;
377
378 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n"));
379
380 /* make sure interrupts are disabled at the chip level,
381 * this function can be called again from a reboot of the target without shutting down HTC */
382 DevDisableInterrupts(&target->Device);
383 /* make sure state is cleared again */
384 target->OpStateFlags = 0;
385 target->RecvStateFlags = 0;
386
387 /* now that we are starting, push control receive buffers into the
388 * HTC control endpoint */
389
390 while (1) {
391 pPacket = HTC_ALLOC_CONTROL_RX(target);
392 if (NULL == pPacket) {
393 break;
394 }
395 HTCAddReceivePkt((HTC_HANDLE)target,pPacket);
396 }
397
398 do {
399
400 AR_DEBUG_ASSERT(target->InitCredits != NULL);
401 AR_DEBUG_ASSERT(target->EpCreditDistributionListHead != NULL);
402 AR_DEBUG_ASSERT(target->EpCreditDistributionListHead->pNext != NULL);
403
404 /* call init credits callback to do the distribution ,
405 * NOTE: the first entry in the distribution list is ENDPOINT_0, so
406 * we pass the start of the list after this one. */
407 target->InitCredits(target->pCredDistContext,
408 target->EpCreditDistributionListHead->pNext,
409 target->TargetCredits);
410
411#ifdef ATH_DEBUG_MODULE
412
413 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
414 DumpCreditDistStates(target);
415 }
416#endif
417
418 /* the caller is done connecting to services, so we can indicate to the
419 * target that the setup phase is complete */
420 status = HTCSendSetupComplete(target);
421
422 if (status) {
423 break;
424 }
425
426 /* unmask interrupts */
427 status = DevUnmaskInterrupts(&target->Device);
428
429 if (status) {
430 HTCStop(target);
431 }
432
433 } while (false);
434
435 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));
436 return status;
437}
438
439static void ResetEndpointStates(struct htc_target *target)
440{
441 struct htc_endpoint *pEndpoint;
442 int i;
443
444 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
445 pEndpoint = &target->EndPoint[i];
446
447 A_MEMZERO(&pEndpoint->CreditDist, sizeof(pEndpoint->CreditDist));
448 pEndpoint->ServiceID = 0;
449 pEndpoint->MaxMsgLength = 0;
450 pEndpoint->MaxTxQueueDepth = 0;
451 A_MEMZERO(&pEndpoint->EndPointStats,sizeof(pEndpoint->EndPointStats));
452 INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers);
453 INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
454 INIT_HTC_PACKET_QUEUE(&pEndpoint->RecvIndicationQueue);
455 pEndpoint->target = target;
456 }
457 /* reset distribution list */
458 target->EpCreditDistributionListHead = NULL;
459}
460
461/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */
462void HTCStop(HTC_HANDLE HTCHandle)
463{
464 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
465 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n"));
466
467 LOCK_HTC(target);
468 /* mark that we are shutting down .. */
469 target->OpStateFlags |= HTC_OP_STATE_STOPPING;
470 UNLOCK_HTC(target);
471
472 /* Masking interrupts is a synchronous operation, when this function returns
473 * all pending HIF I/O has completed, we can safely flush the queues */
474 DevMaskInterrupts(&target->Device);
475
476#ifdef THREAD_X
477 //
478 // Is this delay required
479 //
480 A_MDELAY(200); // wait for IRQ process done
481#endif
482 /* flush all send packets */
483 HTCFlushSendPkts(target);
484 /* flush all recv buffers */
485 HTCFlushRecvBuffers(target);
486
487 DevCleanupMsgBundling(&target->Device);
488
489 ResetEndpointStates(target);
490
491 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n"));
492}
493
494#ifdef ATH_DEBUG_MODULE
495void HTCDumpCreditStates(HTC_HANDLE HTCHandle)
496{
497 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
498
499 LOCK_HTC_TX(target);
500
501 DumpCreditDistStates(target);
502
503 UNLOCK_HTC_TX(target);
504
505 DumpAR6KDevState(&target->Device);
506}
507#endif
508/* report a target failure from the device, this is a callback from the device layer
509 * which uses a mechanism to report errors from the target (i.e. special interrupts) */
510static void HTCReportFailure(void *Context)
511{
512 struct htc_target *target = (struct htc_target *)Context;
513
514 target->TargetFailure = true;
515
516 if (target->HTCInitInfo.TargetFailure != NULL) {
517 /* let upper layer know, it needs to call HTCStop() */
518 target->HTCInitInfo.TargetFailure(target->HTCInitInfo.pContext, A_ERROR);
519 }
520}
521
522bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle,
523 HTC_ENDPOINT_ID Endpoint,
524 HTC_ENDPOINT_STAT_ACTION Action,
525 struct htc_endpoint_stats *pStats)
526{
527
528 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
529 bool clearStats = false;
530 bool sample = false;
531
532 switch (Action) {
533 case HTC_EP_STAT_SAMPLE :
534 sample = true;
535 break;
536 case HTC_EP_STAT_SAMPLE_AND_CLEAR :
537 sample = true;
538 clearStats = true;
539 break;
540 case HTC_EP_STAT_CLEAR :
541 clearStats = true;
542 break;
543 default:
544 break;
545 }
546
547 A_ASSERT(Endpoint < ENDPOINT_MAX);
548
549 /* lock out TX and RX while we sample and/or clear */
550 LOCK_HTC_TX(target);
551 LOCK_HTC_RX(target);
552
553 if (sample) {
554 A_ASSERT(pStats != NULL);
555 /* return the stats to the caller */
556 memcpy(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(struct htc_endpoint_stats));
557 }
558
559 if (clearStats) {
560 /* reset stats */
561 A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(struct htc_endpoint_stats));
562 }
563
564 UNLOCK_HTC_RX(target);
565 UNLOCK_HTC_TX(target);
566
567 return true;
568}
569
570struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle)
571{
572 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
573 return &target->Device;
574}
575
diff --git a/drivers/staging/ath6kl/htc2/htc_debug.h b/drivers/staging/ath6kl/htc2/htc_debug.h
new file mode 100644
index 00000000000..8455703e221
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc_debug.h
@@ -0,0 +1,38 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_debug.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef HTC_DEBUG_H_
24#define HTC_DEBUG_H_
25
26#define ATH_MODULE_NAME htc
27#include "a_debug.h"
28
29/* ------- Debug related stuff ------- */
30
31#define ATH_DEBUG_SEND ATH_DEBUG_MAKE_MODULE_MASK(0)
32#define ATH_DEBUG_RECV ATH_DEBUG_MAKE_MODULE_MASK(1)
33#define ATH_DEBUG_SYNC ATH_DEBUG_MAKE_MODULE_MASK(2)
34#define ATH_DEBUG_DUMP ATH_DEBUG_MAKE_MODULE_MASK(3)
35#define ATH_DEBUG_IRQ ATH_DEBUG_MAKE_MODULE_MASK(4)
36
37
38#endif /*HTC_DEBUG_H_*/
diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h
new file mode 100644
index 00000000000..cac97351769
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc_internal.h
@@ -0,0 +1,211 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_internal.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _HTC_INTERNAL_H_
24#define _HTC_INTERNAL_H_
25
26/* for debugging, uncomment this to capture the last frame header, on frame header
27 * processing errors, the last frame header is dump for comparison */
28//#define HTC_CAPTURE_LAST_FRAME
29
30
31#ifdef __cplusplus
32extern "C" {
33#endif /* __cplusplus */
34
35/* Header files */
36
37#include "a_config.h"
38#include "athdefs.h"
39#include "a_osapi.h"
40#include "htc_debug.h"
41#include "htc.h"
42#include "htc_api.h"
43#include "bmi_msg.h"
44#include "hif.h"
45#include "AR6000/ar6k.h"
46
47/* HTC operational parameters */
48#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
49#define HTC_TARGET_DEBUG_INTR_MASK 0x01
50#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
51
52#define HTC_HOST_MAX_MSG_PER_BUNDLE 8
53#define HTC_MIN_HTC_MSGS_TO_BUNDLE 2
54
55/* packet flags */
56
57#define HTC_RX_PKT_IGNORE_LOOKAHEAD (1 << 0)
58#define HTC_RX_PKT_REFRESH_HDR (1 << 1)
59#define HTC_RX_PKT_PART_OF_BUNDLE (1 << 2)
60#define HTC_RX_PKT_NO_RECYCLE (1 << 3)
61
62/* scatter request flags */
63
64#define HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE (1 << 0)
65
66struct htc_endpoint {
67 HTC_ENDPOINT_ID Id;
68 HTC_SERVICE_ID ServiceID; /* service ID this endpoint is bound to
69 non-zero value means this endpoint is in use */
70 struct htc_packet_queue TxQueue; /* HTC frame buffer TX queue */
71 struct htc_packet_queue RxBuffers; /* HTC frame buffer RX list */
72 struct htc_endpoint_credit_dist CreditDist; /* credit distribution structure (exposed to driver layer) */
73 struct htc_ep_callbacks EpCallBacks; /* callbacks associated with this endpoint */
74 int MaxTxQueueDepth; /* max depth of the TX queue before we need to
75 call driver's full handler */
76 int MaxMsgLength; /* max length of endpoint message */
77 int TxProcessCount; /* reference count to continue tx processing */
78 struct htc_packet_queue RecvIndicationQueue; /* recv packets ready to be indicated */
79 int RxProcessCount; /* reference count to allow single processing context */
80 struct htc_target *target; /* back pointer to target */
81 u8 SeqNo; /* TX seq no (helpful) for debugging */
82 u32 LocalConnectionFlags; /* local connection flags */
83 struct htc_endpoint_stats EndPointStats; /* endpoint statistics */
84};
85
86#define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count);
87#define HTC_SERVICE_TX_PACKET_TAG HTC_TX_PACKET_TAG_INTERNAL
88
89#define NUM_CONTROL_BUFFERS 8
90#define NUM_CONTROL_TX_BUFFERS 2
91#define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS)
92
93struct htc_control_buffer {
94 struct htc_packet HtcPacket;
95 u8 *Buffer;
96};
97
98#define HTC_RECV_WAIT_BUFFERS (1 << 0)
99#define HTC_OP_STATE_STOPPING (1 << 0)
100
101/* our HTC target state */
102struct htc_target {
103 struct htc_endpoint EndPoint[ENDPOINT_MAX];
104 struct htc_control_buffer HTCControlBuffers[NUM_CONTROL_BUFFERS];
105 struct htc_endpoint_credit_dist *EpCreditDistributionListHead;
106 struct htc_packet_queue ControlBufferTXFreeList;
107 struct htc_packet_queue ControlBufferRXFreeList;
108 HTC_CREDIT_DIST_CALLBACK DistributeCredits;
109 HTC_CREDIT_INIT_CALLBACK InitCredits;
110 void *pCredDistContext;
111 int TargetCredits;
112 unsigned int TargetCreditSize;
113 A_MUTEX_T HTCLock;
114 A_MUTEX_T HTCRxLock;
115 A_MUTEX_T HTCTxLock;
116 struct ar6k_device Device; /* AR6K - specific state */
117 u32 OpStateFlags;
118 u32 RecvStateFlags;
119 HTC_ENDPOINT_ID EpWaitingForBuffers;
120 bool TargetFailure;
121#ifdef HTC_CAPTURE_LAST_FRAME
122 struct htc_frame_hdr LastFrameHdr; /* useful for debugging */
123 u8 LastTrailer[256];
124 u8 LastTrailerLength;
125#endif
126 struct htc_init_info HTCInitInfo;
127 u8 HTCTargetVersion;
128 int MaxMsgPerBundle; /* max messages per bundle for HTC */
129 bool SendBundlingEnabled; /* run time enable for send bundling (dynamic) */
130 int RecvBundlingEnabled; /* run time enable for recv bundling (dynamic) */
131};
132
133#define HTC_STOPPING(t) ((t)->OpStateFlags & HTC_OP_STATE_STOPPING)
134#define LOCK_HTC(t) A_MUTEX_LOCK(&(t)->HTCLock);
135#define UNLOCK_HTC(t) A_MUTEX_UNLOCK(&(t)->HTCLock);
136#define LOCK_HTC_RX(t) A_MUTEX_LOCK(&(t)->HTCRxLock);
137#define UNLOCK_HTC_RX(t) A_MUTEX_UNLOCK(&(t)->HTCRxLock);
138#define LOCK_HTC_TX(t) A_MUTEX_LOCK(&(t)->HTCTxLock);
139#define UNLOCK_HTC_TX(t) A_MUTEX_UNLOCK(&(t)->HTCTxLock);
140
141#define GET_HTC_TARGET_FROM_HANDLE(hnd) ((struct htc_target *)(hnd))
142#define HTC_RECYCLE_RX_PKT(target,p,e) \
143{ \
144 if ((p)->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_NO_RECYCLE) { \
145 HTC_PACKET_RESET_RX(pPacket); \
146 pPacket->Status = A_ECANCELED; \
147 (e)->EpCallBacks.EpRecv((e)->EpCallBacks.pContext, \
148 (p)); \
149 } else { \
150 HTC_PACKET_RESET_RX(pPacket); \
151 HTCAddReceivePkt((HTC_HANDLE)(target),(p)); \
152 } \
153}
154
155/* internal HTC functions */
156void HTCControlTxComplete(void *Context, struct htc_packet *pPacket);
157void HTCControlRecv(void *Context, struct htc_packet *pPacket);
158int HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket);
159struct htc_packet *HTCAllocControlBuffer(struct htc_target *target, struct htc_packet_queue *pList);
160void HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList);
161int HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket);
162void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket);
163int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched);
164void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint);
165int HTCSendSetupComplete(struct htc_target *target);
166void HTCFlushRecvBuffers(struct htc_target *target);
167void HTCFlushSendPkts(struct htc_target *target);
168
169#ifdef ATH_DEBUG_MODULE
170void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist);
171void DumpCreditDistStates(struct htc_target *target);
172void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription);
173#endif
174
175static INLINE struct htc_packet *HTC_ALLOC_CONTROL_TX(struct htc_target *target) {
176 struct htc_packet *pPacket = HTCAllocControlBuffer(target,&target->ControlBufferTXFreeList);
177 if (pPacket != NULL) {
178 /* set payload pointer area with some headroom */
179 pPacket->pBuffer = pPacket->pBufferStart + HTC_HDR_LENGTH;
180 }
181 return pPacket;
182}
183
184#define HTC_FREE_CONTROL_TX(t,p) HTCFreeControlBuffer((t),(p),&(t)->ControlBufferTXFreeList)
185#define HTC_ALLOC_CONTROL_RX(t) HTCAllocControlBuffer((t),&(t)->ControlBufferRXFreeList)
186#define HTC_FREE_CONTROL_RX(t,p) \
187{ \
188 HTC_PACKET_RESET_RX(p); \
189 HTCFreeControlBuffer((t),(p),&(t)->ControlBufferRXFreeList); \
190}
191
192#define HTC_PREPARE_SEND_PKT(pP,sendflags,ctrl0,ctrl1) \
193{ \
194 u8 *pHdrBuf; \
195 (pP)->pBuffer -= HTC_HDR_LENGTH; \
196 pHdrBuf = (pP)->pBuffer; \
197 A_SET_UINT16_FIELD(pHdrBuf,struct htc_frame_hdr,PayloadLen,(u16)(pP)->ActualLength); \
198 A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,Flags,(sendflags)); \
199 A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,EndpointID, (u8)(pP)->Endpoint); \
200 A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,ControlBytes[0], (u8)(ctrl0)); \
201 A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,ControlBytes[1], (u8)(ctrl1)); \
202}
203
204#define HTC_UNPREPARE_SEND_PKT(pP) \
205 (pP)->pBuffer += HTC_HDR_LENGTH; \
206
207#ifdef __cplusplus
208}
209#endif
210
211#endif /* _HTC_INTERNAL_H_ */
diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c
new file mode 100644
index 00000000000..974cc8cd693
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc_recv.c
@@ -0,0 +1,1572 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_recv.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#include "htc_internal.h"
24
25#define HTCIssueRecv(t, p) \
26 DevRecvPacket(&(t)->Device, \
27 (p), \
28 (p)->ActualLength)
29
30#define DO_RCV_COMPLETION(e,q) DoRecvCompletion(e,q)
31
32#define DUMP_RECV_PKT_INFO(pP) \
33 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC RECV packet 0x%lX (%d bytes) (hdr:0x%X) on ep : %d \n", \
34 (unsigned long)(pP), \
35 (pP)->ActualLength, \
36 (pP)->PktInfo.AsRx.ExpectedHdr, \
37 (pP)->Endpoint))
38
39#define HTC_RX_STAT_PROFILE(t,ep,numLookAheads) \
40{ \
41 INC_HTC_EP_STAT((ep), RxReceived, 1); \
42 if ((numLookAheads) == 1) { \
43 INC_HTC_EP_STAT((ep), RxLookAheads, 1); \
44 } else if ((numLookAheads) > 1) { \
45 INC_HTC_EP_STAT((ep), RxBundleLookAheads, 1); \
46 } \
47}
48
49static void DoRecvCompletion(struct htc_endpoint *pEndpoint,
50 struct htc_packet_queue *pQueueToIndicate)
51{
52
53 do {
54
55 if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
56 /* nothing to indicate */
57 break;
58 }
59
60 if (pEndpoint->EpCallBacks.EpRecvPktMultiple != NULL) {
61 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d, recv multiple callback (%d pkts) \n",
62 pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
63 /* a recv multiple handler is being used, pass the queue to the handler */
64 pEndpoint->EpCallBacks.EpRecvPktMultiple(pEndpoint->EpCallBacks.pContext,
65 pQueueToIndicate);
66 INIT_HTC_PACKET_QUEUE(pQueueToIndicate);
67 } else {
68 struct htc_packet *pPacket;
69 /* using legacy EpRecv */
70 do {
71 pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
72 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d recv callback on packet 0x%lX \n", \
73 pEndpoint->Id, (unsigned long)(pPacket)));
74 pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, pPacket);
75 } while (!HTC_QUEUE_EMPTY(pQueueToIndicate));
76 }
77
78 } while (false);
79
80}
81
82static INLINE int HTCProcessTrailer(struct htc_target *target,
83 u8 *pBuffer,
84 int Length,
85 u32 *pNextLookAheads,
86 int *pNumLookAheads,
87 HTC_ENDPOINT_ID FromEndpoint)
88{
89 HTC_RECORD_HDR *pRecord;
90 u8 *pRecordBuf;
91 HTC_LOOKAHEAD_REPORT *pLookAhead;
92 u8 *pOrigBuffer;
93 int origLength;
94 int status;
95
96 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessTrailer (length:%d) \n", Length));
97
98 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
99 AR_DEBUG_PRINTBUF(pBuffer,Length,"Recv Trailer");
100 }
101
102 pOrigBuffer = pBuffer;
103 origLength = Length;
104 status = 0;
105
106 while (Length > 0) {
107
108 if (Length < sizeof(HTC_RECORD_HDR)) {
109 status = A_EPROTO;
110 break;
111 }
112 /* these are byte aligned structs */
113 pRecord = (HTC_RECORD_HDR *)pBuffer;
114 Length -= sizeof(HTC_RECORD_HDR);
115 pBuffer += sizeof(HTC_RECORD_HDR);
116
117 if (pRecord->Length > Length) {
118 /* no room left in buffer for record */
119 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
120 (" invalid record length: %d (id:%d) buffer has: %d bytes left \n",
121 pRecord->Length, pRecord->RecordID, Length));
122 status = A_EPROTO;
123 break;
124 }
125 /* start of record follows the header */
126 pRecordBuf = pBuffer;
127
128 switch (pRecord->RecordID) {
129 case HTC_RECORD_CREDITS:
130 AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_CREDIT_REPORT));
131 HTCProcessCreditRpt(target,
132 (HTC_CREDIT_REPORT *)pRecordBuf,
133 pRecord->Length / (sizeof(HTC_CREDIT_REPORT)),
134 FromEndpoint);
135 break;
136 case HTC_RECORD_LOOKAHEAD:
137 AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_LOOKAHEAD_REPORT));
138 pLookAhead = (HTC_LOOKAHEAD_REPORT *)pRecordBuf;
139 if ((pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF)) &&
140 (pNextLookAheads != NULL)) {
141
142 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
143 (" LookAhead Report Found (pre valid:0x%X, post valid:0x%X) \n",
144 pLookAhead->PreValid,
145 pLookAhead->PostValid));
146
147 /* look ahead bytes are valid, copy them over */
148 ((u8 *)(&pNextLookAheads[0]))[0] = pLookAhead->LookAhead[0];
149 ((u8 *)(&pNextLookAheads[0]))[1] = pLookAhead->LookAhead[1];
150 ((u8 *)(&pNextLookAheads[0]))[2] = pLookAhead->LookAhead[2];
151 ((u8 *)(&pNextLookAheads[0]))[3] = pLookAhead->LookAhead[3];
152
153#ifdef ATH_DEBUG_MODULE
154 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
155 DebugDumpBytes((u8 *)pNextLookAheads,4,"Next Look Ahead");
156 }
157#endif
158 /* just one normal lookahead */
159 *pNumLookAheads = 1;
160 }
161 break;
162 case HTC_RECORD_LOOKAHEAD_BUNDLE:
163 AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT));
164 if (pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT) &&
165 (pNextLookAheads != NULL)) {
166 HTC_BUNDLED_LOOKAHEAD_REPORT *pBundledLookAheadRpt;
167 int i;
168
169 pBundledLookAheadRpt = (HTC_BUNDLED_LOOKAHEAD_REPORT *)pRecordBuf;
170
171#ifdef ATH_DEBUG_MODULE
172 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
173 DebugDumpBytes(pRecordBuf,pRecord->Length,"Bundle LookAhead");
174 }
175#endif
176
177 if ((pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))) >
178 HTC_HOST_MAX_MSG_PER_BUNDLE) {
179 /* this should never happen, the target restricts the number
180 * of messages per bundle configured by the host */
181 A_ASSERT(false);
182 status = A_EPROTO;
183 break;
184 }
185
186 for (i = 0; i < (int)(pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) {
187 ((u8 *)(&pNextLookAheads[i]))[0] = pBundledLookAheadRpt->LookAhead[0];
188 ((u8 *)(&pNextLookAheads[i]))[1] = pBundledLookAheadRpt->LookAhead[1];
189 ((u8 *)(&pNextLookAheads[i]))[2] = pBundledLookAheadRpt->LookAhead[2];
190 ((u8 *)(&pNextLookAheads[i]))[3] = pBundledLookAheadRpt->LookAhead[3];
191 pBundledLookAheadRpt++;
192 }
193
194 *pNumLookAheads = i;
195 }
196 break;
197 default:
198 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" unhandled record: id:%d length:%d \n",
199 pRecord->RecordID, pRecord->Length));
200 break;
201 }
202
203 if (status) {
204 break;
205 }
206
207 /* advance buffer past this record for next time around */
208 pBuffer += pRecord->Length;
209 Length -= pRecord->Length;
210 }
211
212#ifdef ATH_DEBUG_MODULE
213 if (status) {
214 DebugDumpBytes(pOrigBuffer,origLength,"BAD Recv Trailer");
215 }
216#endif
217
218 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessTrailer \n"));
219 return status;
220
221}
222
223/* process a received message (i.e. strip off header, process any trailer data)
224 * note : locks must be released when this function is called */
225static int HTCProcessRecvHeader(struct htc_target *target,
226 struct htc_packet *pPacket,
227 u32 *pNextLookAheads,
228 int *pNumLookAheads)
229{
230 u8 temp;
231 u8 *pBuf;
232 int status = 0;
233 u16 payloadLen;
234 u32 lookAhead;
235
236 pBuf = pPacket->pBuffer;
237
238 if (pNumLookAheads != NULL) {
239 *pNumLookAheads = 0;
240 }
241
242 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessRecvHeader \n"));
243
244 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
245 AR_DEBUG_PRINTBUF(pBuf,pPacket->ActualLength,"HTC Recv PKT");
246 }
247
248 do {
249 /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to
250 * retrieve 16 bit fields */
251 payloadLen = A_GET_UINT16_FIELD(pBuf, struct htc_frame_hdr, PayloadLen);
252
253 ((u8 *)&lookAhead)[0] = pBuf[0];
254 ((u8 *)&lookAhead)[1] = pBuf[1];
255 ((u8 *)&lookAhead)[2] = pBuf[2];
256 ((u8 *)&lookAhead)[3] = pBuf[3];
257
258 if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_REFRESH_HDR) {
259 /* refresh expected hdr, since this was unknown at the time we grabbed the packets
260 * as part of a bundle */
261 pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead;
262 /* refresh actual length since we now have the real header */
263 pPacket->ActualLength = payloadLen + HTC_HDR_LENGTH;
264
265 /* validate the actual header that was refreshed */
266 if (pPacket->ActualLength > pPacket->BufferLength) {
267 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
268 ("Refreshed HDR payload length (%d) in bundled RECV is invalid (hdr: 0x%X) \n",
269 payloadLen, lookAhead));
270 /* limit this to max buffer just to print out some of the buffer */
271 pPacket->ActualLength = min(pPacket->ActualLength, pPacket->BufferLength);
272 status = A_EPROTO;
273 break;
274 }
275
276 if (pPacket->Endpoint != A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, EndpointID)) {
277 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
278 ("Refreshed HDR endpoint (%d) does not match expected endpoint (%d) \n",
279 A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, EndpointID), pPacket->Endpoint));
280 status = A_EPROTO;
281 break;
282 }
283 }
284
285 if (lookAhead != pPacket->PktInfo.AsRx.ExpectedHdr) {
286 /* somehow the lookahead that gave us the full read length did not
287 * reflect the actual header in the pending message */
288 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
289 ("HTCProcessRecvHeader, lookahead mismatch! (pPkt:0x%lX flags:0x%X) \n",
290 (unsigned long)pPacket, pPacket->PktInfo.AsRx.HTCRxFlags));
291#ifdef ATH_DEBUG_MODULE
292 DebugDumpBytes((u8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead");
293 DebugDumpBytes(pBuf,sizeof(struct htc_frame_hdr),"Current Frame Header");
294#ifdef HTC_CAPTURE_LAST_FRAME
295 DebugDumpBytes((u8 *)&target->LastFrameHdr,sizeof(struct htc_frame_hdr),"Last Frame Header");
296 if (target->LastTrailerLength != 0) {
297 DebugDumpBytes(target->LastTrailer,
298 target->LastTrailerLength,
299 "Last trailer");
300 }
301#endif
302#endif
303 status = A_EPROTO;
304 break;
305 }
306
307 /* get flags */
308 temp = A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, Flags);
309
310 if (temp & HTC_FLAGS_RECV_TRAILER) {
311 /* this packet has a trailer */
312
313 /* extract the trailer length in control byte 0 */
314 temp = A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, ControlBytes[0]);
315
316 if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) {
317 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
318 ("HTCProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n",
319 payloadLen, temp));
320 status = A_EPROTO;
321 break;
322 }
323
324 if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
325 /* this packet was fetched as part of an HTC bundle, the embedded lookahead is
326 * not valid since the next packet may have already been fetched as part of the
327 * bundle */
328 pNextLookAheads = NULL;
329 pNumLookAheads = NULL;
330 }
331
332 /* process trailer data that follows HDR + application payload */
333 status = HTCProcessTrailer(target,
334 (pBuf + HTC_HDR_LENGTH + payloadLen - temp),
335 temp,
336 pNextLookAheads,
337 pNumLookAheads,
338 pPacket->Endpoint);
339
340 if (status) {
341 break;
342 }
343
344#ifdef HTC_CAPTURE_LAST_FRAME
345 memcpy(target->LastTrailer, (pBuf + HTC_HDR_LENGTH + payloadLen - temp), temp);
346 target->LastTrailerLength = temp;
347#endif
348 /* trim length by trailer bytes */
349 pPacket->ActualLength -= temp;
350 }
351#ifdef HTC_CAPTURE_LAST_FRAME
352 else {
353 target->LastTrailerLength = 0;
354 }
355#endif
356
357 /* if we get to this point, the packet is good */
358 /* remove header and adjust length */
359 pPacket->pBuffer += HTC_HDR_LENGTH;
360 pPacket->ActualLength -= HTC_HDR_LENGTH;
361
362 } while (false);
363
364 if (status) {
365 /* dump the whole packet */
366#ifdef ATH_DEBUG_MODULE
367 DebugDumpBytes(pBuf,pPacket->ActualLength < 256 ? pPacket->ActualLength : 256 ,"BAD HTC Recv PKT");
368#endif
369 } else {
370#ifdef HTC_CAPTURE_LAST_FRAME
371 memcpy(&target->LastFrameHdr,pBuf,sizeof(struct htc_frame_hdr));
372#endif
373 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
374 if (pPacket->ActualLength > 0) {
375 AR_DEBUG_PRINTBUF(pPacket->pBuffer,pPacket->ActualLength,"HTC - Application Msg");
376 }
377 }
378 }
379
380 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessRecvHeader \n"));
381 return status;
382}
383
384static INLINE void HTCAsyncRecvCheckMorePackets(struct htc_target *target,
385 u32 NextLookAheads[],
386 int NumLookAheads,
387 bool CheckMoreMsgs)
388{
389 /* was there a lookahead for the next packet? */
390 if (NumLookAheads > 0) {
391 int nextStatus;
392 int fetched = 0;
393 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
394 ("HTCAsyncRecvCheckMorePackets - num lookaheads were non-zero : %d \n",
395 NumLookAheads));
396 /* force status re-check */
397 REF_IRQ_STATUS_RECHECK(&target->Device);
398 /* we have more packets, get the next packet fetch started */
399 nextStatus = HTCRecvMessagePendingHandler(target, NextLookAheads, NumLookAheads, NULL, &fetched);
400 if (A_EPROTO == nextStatus) {
401 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
402 ("Next look ahead from recv header was INVALID\n"));
403#ifdef ATH_DEBUG_MODULE
404 DebugDumpBytes((u8 *)NextLookAheads,
405 NumLookAheads * (sizeof(u32)),
406 "BAD lookaheads from lookahead report");
407#endif
408 }
409 if (!nextStatus && !fetched) {
410 /* we could not fetch any more packets due to resources */
411 DevAsyncIrqProcessComplete(&target->Device);
412 }
413 } else {
414 if (CheckMoreMsgs) {
415 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
416 ("HTCAsyncRecvCheckMorePackets - rechecking for more messages...\n"));
417 /* if we did not get anything on the look-ahead,
418 * call device layer to asynchronously re-check for messages. If we can keep the async
419 * processing going we get better performance. If there is a pending message we will keep processing
420 * messages asynchronously which should pipeline things nicely */
421 DevCheckPendingRecvMsgsAsync(&target->Device);
422 } else {
423 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("HTCAsyncRecvCheckMorePackets - no check \n"));
424 }
425 }
426
427
428}
429
430 /* unload the recv completion queue */
431static INLINE void DrainRecvIndicationQueue(struct htc_target *target, struct htc_endpoint *pEndpoint)
432{
433 struct htc_packet_queue recvCompletions;
434
435 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+DrainRecvIndicationQueue \n"));
436
437 INIT_HTC_PACKET_QUEUE(&recvCompletions);
438
439 LOCK_HTC_RX(target);
440
441 /* increment rx processing count on entry */
442 pEndpoint->RxProcessCount++;
443 if (pEndpoint->RxProcessCount > 1) {
444 pEndpoint->RxProcessCount--;
445 /* another thread or task is draining the RX completion queue on this endpoint
446 * that thread will reset the rx processing count when the queue is drained */
447 UNLOCK_HTC_RX(target);
448 return;
449 }
450
451 /******* at this point only 1 thread may enter ******/
452
453 while (true) {
454
455 /* transfer items from main recv queue to the local one so we can release the lock */
456 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&recvCompletions, &pEndpoint->RecvIndicationQueue);
457
458 if (HTC_QUEUE_EMPTY(&recvCompletions)) {
459 /* all drained */
460 break;
461 }
462
463 /* release lock while we do the recv completions
464 * other threads can now queue more recv completions */
465 UNLOCK_HTC_RX(target);
466
467 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
468 ("DrainRecvIndicationQueue : completing %d RECV packets \n",
469 HTC_PACKET_QUEUE_DEPTH(&recvCompletions)));
470 /* do completion */
471 DO_RCV_COMPLETION(pEndpoint,&recvCompletions);
472
473 /* re-acquire lock to grab some more completions */
474 LOCK_HTC_RX(target);
475 }
476
477 /* reset count */
478 pEndpoint->RxProcessCount = 0;
479 UNLOCK_HTC_RX(target);
480
481 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-DrainRecvIndicationQueue \n"));
482
483}
484
485 /* optimization for recv packets, we can indicate a "hint" that there are more
486 * single-packets to fetch on this endpoint */
487#define SET_MORE_RX_PACKET_INDICATION_FLAG(L,N,E,P) \
488 if ((N) > 0) { SetRxPacketIndicationFlags((L)[0],(E),(P)); }
489
490 /* for bundled frames, we can force the flag to indicate there are more packets */
491#define FORCE_MORE_RX_PACKET_INDICATION_FLAG(P) \
492 (P)->PktInfo.AsRx.IndicationFlags |= HTC_RX_FLAGS_INDICATE_MORE_PKTS;
493
494 /* note: this function can be called with the RX lock held */
495static INLINE void SetRxPacketIndicationFlags(u32 LookAhead,
496 struct htc_endpoint *pEndpoint,
497 struct htc_packet *pPacket)
498{
499 struct htc_frame_hdr *pHdr = (struct htc_frame_hdr *)&LookAhead;
500 /* check to see if the "next" packet is from the same endpoint of the
501 completing packet */
502 if (pHdr->EndpointID == pPacket->Endpoint) {
503 /* check that there is a buffer available to actually fetch it */
504 if (!HTC_QUEUE_EMPTY(&pEndpoint->RxBuffers)) {
505 /* provide a hint that there are more RX packets to fetch */
506 FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
507 }
508 }
509}
510
511
512/* asynchronous completion handler for recv packet fetching, when the device layer
513 * completes a read request, it will call this completion handler */
514void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket)
515{
516 struct htc_target *target = (struct htc_target *)Context;
517 struct htc_endpoint *pEndpoint;
518 u32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
519 int numLookAheads = 0;
520 int status;
521 bool checkMorePkts = true;
522
523 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCRecvCompleteHandler (pkt:0x%lX, status:%d, ep:%d) \n",
524 (unsigned long)pPacket, pPacket->Status, pPacket->Endpoint));
525
526 A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device));
527 AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);
528 pEndpoint = &target->EndPoint[pPacket->Endpoint];
529 pPacket->Completion = NULL;
530
531 /* get completion status */
532 status = pPacket->Status;
533
534 do {
535
536 if (status) {
537 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCRecvCompleteHandler: request failed (status:%d, ep:%d) \n",
538 pPacket->Status, pPacket->Endpoint));
539 break;
540 }
541 /* process the header for any trailer data */
542 status = HTCProcessRecvHeader(target,pPacket,nextLookAheads,&numLookAheads);
543
544 if (status) {
545 break;
546 }
547
548 if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
549 /* this packet was part of a bundle that had to be broken up.
550 * It was fetched one message at a time. There may be other asynchronous reads queued behind this one.
551 * Do no issue another check for more packets since the last one in the series of requests
552 * will handle it */
553 checkMorePkts = false;
554 }
555
556 DUMP_RECV_PKT_INFO(pPacket);
557 LOCK_HTC_RX(target);
558 SET_MORE_RX_PACKET_INDICATION_FLAG(nextLookAheads,numLookAheads,pEndpoint,pPacket);
559 /* we have a good packet, queue it to the completion queue */
560 HTC_PACKET_ENQUEUE(&pEndpoint->RecvIndicationQueue,pPacket);
561 HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads);
562 UNLOCK_HTC_RX(target);
563
564 /* check for more recv packets before indicating */
565 HTCAsyncRecvCheckMorePackets(target,nextLookAheads,numLookAheads,checkMorePkts);
566
567 } while (false);
568
569 if (status) {
570 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
571 ("HTCRecvCompleteHandler , message fetch failed (status = %d) \n",
572 status));
573 /* recycle this packet */
574 HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint);
575 } else {
576 /* a good packet was queued, drain the queue */
577 DrainRecvIndicationQueue(target,pEndpoint);
578 }
579
580 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCRecvCompleteHandler\n"));
581}
582
583/* synchronously wait for a control message from the target,
584 * This function is used at initialization time ONLY. At init messages
585 * on ENDPOINT 0 are expected. */
586int HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket)
587{
588 int status;
589 u32 lookAhead;
590 struct htc_packet *pPacket = NULL;
591 struct htc_frame_hdr *pHdr;
592
593 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCWaitforControlMessage \n"));
594
595 do {
596
597 *ppControlPacket = NULL;
598
599 /* call the polling function to see if we have a message */
600 status = DevPollMboxMsgRecv(&target->Device,
601 &lookAhead,
602 HTC_TARGET_RESPONSE_TIMEOUT);
603
604 if (status) {
605 break;
606 }
607
608 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
609 ("HTCWaitforControlMessage : lookAhead : 0x%X \n", lookAhead));
610
611 /* check the lookahead */
612 pHdr = (struct htc_frame_hdr *)&lookAhead;
613
614 if (pHdr->EndpointID != ENDPOINT_0) {
615 /* unexpected endpoint number, should be zero */
616 AR_DEBUG_ASSERT(false);
617 status = A_EPROTO;
618 break;
619 }
620
621 if (status) {
622 /* bad message */
623 AR_DEBUG_ASSERT(false);
624 status = A_EPROTO;
625 break;
626 }
627
628 pPacket = HTC_ALLOC_CONTROL_RX(target);
629
630 if (pPacket == NULL) {
631 AR_DEBUG_ASSERT(false);
632 status = A_NO_MEMORY;
633 break;
634 }
635
636 pPacket->PktInfo.AsRx.HTCRxFlags = 0;
637 pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead;
638 pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
639
640 if (pPacket->ActualLength > pPacket->BufferLength) {
641 AR_DEBUG_ASSERT(false);
642 status = A_EPROTO;
643 break;
644 }
645
646 /* we want synchronous operation */
647 pPacket->Completion = NULL;
648
649 /* get the message from the device, this will block */
650 status = HTCIssueRecv(target, pPacket);
651
652 if (status) {
653 break;
654 }
655
656 /* process receive header */
657 status = HTCProcessRecvHeader(target,pPacket,NULL,NULL);
658
659 pPacket->Status = status;
660
661 if (status) {
662 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
663 ("HTCWaitforControlMessage, HTCProcessRecvHeader failed (status = %d) \n",
664 status));
665 break;
666 }
667
668 /* give the caller this control message packet, they are responsible to free */
669 *ppControlPacket = pPacket;
670
671 } while (false);
672
673 if (status) {
674 if (pPacket != NULL) {
675 /* cleanup buffer on error */
676 HTC_FREE_CONTROL_RX(target,pPacket);
677 }
678 }
679
680 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCWaitforControlMessage \n"));
681
682 return status;
683}
684
685static int AllocAndPrepareRxPackets(struct htc_target *target,
686 u32 LookAheads[],
687 int Messages,
688 struct htc_endpoint *pEndpoint,
689 struct htc_packet_queue *pQueue)
690{
691 int status = 0;
692 struct htc_packet *pPacket;
693 struct htc_frame_hdr *pHdr;
694 int i,j;
695 int numMessages;
696 int fullLength;
697 bool noRecycle;
698
699 /* lock RX while we assemble the packet buffers */
700 LOCK_HTC_RX(target);
701
702 for (i = 0; i < Messages; i++) {
703
704 pHdr = (struct htc_frame_hdr *)&LookAheads[i];
705
706 if (pHdr->EndpointID >= ENDPOINT_MAX) {
707 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d \n",pHdr->EndpointID));
708 /* invalid endpoint */
709 status = A_EPROTO;
710 break;
711 }
712
713 if (pHdr->EndpointID != pEndpoint->Id) {
714 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d should be : %d (index:%d)\n",
715 pHdr->EndpointID, pEndpoint->Id, i));
716 /* invalid endpoint */
717 status = A_EPROTO;
718 break;
719 }
720
721 if (pHdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) {
722 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Payload length %d exceeds max HTC : %d !\n",
723 pHdr->PayloadLen, (u32)HTC_MAX_PAYLOAD_LENGTH));
724 status = A_EPROTO;
725 break;
726 }
727
728 if (0 == pEndpoint->ServiceID) {
729 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Endpoint %d is not connected !\n",pHdr->EndpointID));
730 /* endpoint isn't even connected */
731 status = A_EPROTO;
732 break;
733 }
734
735 if ((pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) == 0) {
736 /* HTC header only indicates 1 message to fetch */
737 numMessages = 1;
738 } else {
739 /* HTC header indicates that every packet to follow has the same padded length so that it can
740 * be optimally fetched as a full bundle */
741 numMessages = (pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) >> HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT;
742 /* the count doesn't include the starter frame, just a count of frames to follow */
743 numMessages++;
744 A_ASSERT(numMessages <= target->MaxMsgPerBundle);
745 INC_HTC_EP_STAT(pEndpoint, RxBundleIndFromHdr, 1);
746 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
747 ("HTC header indicates :%d messages can be fetched as a bundle \n",numMessages));
748 }
749
750 fullLength = DEV_CALC_RECV_PADDED_LEN(&target->Device,pHdr->PayloadLen + sizeof(struct htc_frame_hdr));
751
752 /* get packet buffers for each message, if there was a bundle detected in the header,
753 * use pHdr as a template to fetch all packets in the bundle */
754 for (j = 0; j < numMessages; j++) {
755
756 /* reset flag, any packets allocated using the RecvAlloc() API cannot be recycled on cleanup,
757 * they must be explicitly returned */
758 noRecycle = false;
759
760 if (pEndpoint->EpCallBacks.EpRecvAlloc != NULL) {
761 UNLOCK_HTC_RX(target);
762 noRecycle = true;
763 /* user is using a per-packet allocation callback */
764 pPacket = pEndpoint->EpCallBacks.EpRecvAlloc(pEndpoint->EpCallBacks.pContext,
765 pEndpoint->Id,
766 fullLength);
767 LOCK_HTC_RX(target);
768
769 } else if ((pEndpoint->EpCallBacks.EpRecvAllocThresh != NULL) &&
770 (fullLength > pEndpoint->EpCallBacks.RecvAllocThreshold)) {
771 INC_HTC_EP_STAT(pEndpoint,RxAllocThreshHit,1);
772 INC_HTC_EP_STAT(pEndpoint,RxAllocThreshBytes,pHdr->PayloadLen);
773 /* threshold was hit, call the special recv allocation callback */
774 UNLOCK_HTC_RX(target);
775 noRecycle = true;
776 /* user wants to allocate packets above a certain threshold */
777 pPacket = pEndpoint->EpCallBacks.EpRecvAllocThresh(pEndpoint->EpCallBacks.pContext,
778 pEndpoint->Id,
779 fullLength);
780 LOCK_HTC_RX(target);
781
782 } else {
783 /* user is using a refill handler that can refill multiple HTC buffers */
784
785 /* get a packet from the endpoint recv queue */
786 pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);
787
788 if (NULL == pPacket) {
789 /* check for refill handler */
790 if (pEndpoint->EpCallBacks.EpRecvRefill != NULL) {
791 UNLOCK_HTC_RX(target);
792 /* call the re-fill handler */
793 pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext,
794 pEndpoint->Id);
795 LOCK_HTC_RX(target);
796 /* check if we have more buffers */
797 pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);
798 /* fall through */
799 }
800 }
801 }
802
803 if (NULL == pPacket) {
804 /* this is not an error, we simply need to mark that we are waiting for buffers.*/
805 target->RecvStateFlags |= HTC_RECV_WAIT_BUFFERS;
806 target->EpWaitingForBuffers = pEndpoint->Id;
807 status = A_NO_RESOURCE;
808 break;
809 }
810
811 AR_DEBUG_ASSERT(pPacket->Endpoint == pEndpoint->Id);
812 /* clear flags */
813 pPacket->PktInfo.AsRx.HTCRxFlags = 0;
814 pPacket->PktInfo.AsRx.IndicationFlags = 0;
815 pPacket->Status = 0;
816
817 if (noRecycle) {
818 /* flag that these packets cannot be recycled, they have to be returned to the
819 * user */
820 pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_NO_RECYCLE;
821 }
822 /* add packet to queue (also incase we need to cleanup down below) */
823 HTC_PACKET_ENQUEUE(pQueue,pPacket);
824
825 if (HTC_STOPPING(target)) {
826 status = A_ECANCELED;
827 break;
828 }
829
830 /* make sure this message can fit in the endpoint buffer */
831 if ((u32)fullLength > pPacket->BufferLength) {
832 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
833 ("Payload Length Error : header reports payload of: %d (%d) endpoint buffer size: %d \n",
834 pHdr->PayloadLen, fullLength, pPacket->BufferLength));
835 status = A_EPROTO;
836 break;
837 }
838
839 if (j > 0) {
840 /* for messages fetched in a bundle the expected lookahead is unknown since we
841 * are only using the lookahead of the first packet as a template of what to
842 * expect for lengths */
843 /* flag that once we get the real HTC header we need to refesh the information */
844 pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_REFRESH_HDR;
845 /* set it to something invalid */
846 pPacket->PktInfo.AsRx.ExpectedHdr = 0xFFFFFFFF;
847 } else {
848
849 pPacket->PktInfo.AsRx.ExpectedHdr = LookAheads[i]; /* set expected look ahead */
850 }
851 /* set the amount of data to fetch */
852 pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
853 }
854
855 if (status) {
856 if (A_NO_RESOURCE == status) {
857 /* this is actually okay */
858 status = 0;
859 }
860 break;
861 }
862
863 }
864
865 UNLOCK_HTC_RX(target);
866
867 if (status) {
868 while (!HTC_QUEUE_EMPTY(pQueue)) {
869 pPacket = HTC_PACKET_DEQUEUE(pQueue);
870 /* recycle all allocated packets */
871 HTC_RECYCLE_RX_PKT(target,pPacket,&target->EndPoint[pPacket->Endpoint]);
872 }
873 }
874
875 return status;
876}
877
878static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq)
879{
880 int i;
881 struct htc_packet *pPacket;
882 struct htc_endpoint *pEndpoint;
883 u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
884 int numLookAheads = 0;
885 struct htc_target *target = (struct htc_target *)pScatterReq->Context;
886 int status;
887 bool partialBundle = false;
888 struct htc_packet_queue localRecvQueue;
889 bool procError = false;
890
891 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCAsyncRecvScatterCompletion TotLen: %d Entries: %d\n",
892 pScatterReq->TotalLength, pScatterReq->ValidScatterEntries));
893
894 A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device));
895
896 if (pScatterReq->CompletionStatus) {
897 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Recv Scatter Request Failed: %d \n",pScatterReq->CompletionStatus));
898 }
899
900 if (pScatterReq->CallerFlags & HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE) {
901 partialBundle = true;
902 }
903
904 DEV_FINISH_SCATTER_OPERATION(pScatterReq);
905
906 INIT_HTC_PACKET_QUEUE(&localRecvQueue);
907
908 pPacket = (struct htc_packet *)pScatterReq->ScatterList[0].pCallerContexts[0];
909 /* note: all packets in a scatter req are for the same endpoint ! */
910 pEndpoint = &target->EndPoint[pPacket->Endpoint];
911
912 /* walk through the scatter list and process */
913 /* **** NOTE: DO NOT HOLD ANY LOCKS here, HTCProcessRecvHeader can take the TX lock
914 * as it processes credit reports */
915 for (i = 0; i < pScatterReq->ValidScatterEntries; i++) {
916 pPacket = (struct htc_packet *)pScatterReq->ScatterList[i].pCallerContexts[0];
917 A_ASSERT(pPacket != NULL);
918 /* reset count, we are only interested in the look ahead in the last packet when we
919 * break out of this loop */
920 numLookAheads = 0;
921
922 if (!pScatterReq->CompletionStatus) {
923 /* process header for each of the recv packets */
924 status = HTCProcessRecvHeader(target,pPacket,lookAheads,&numLookAheads);
925 } else {
926 status = A_ERROR;
927 }
928
929 if (!status) {
930 LOCK_HTC_RX(target);
931 HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads);
932 INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1);
933 UNLOCK_HTC_RX(target);
934 if (i == (pScatterReq->ValidScatterEntries - 1)) {
935 /* last packet's more packets flag is set based on the lookahead */
936 SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,numLookAheads,pEndpoint,pPacket);
937 } else {
938 /* packets in a bundle automatically have this flag set */
939 FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
940 }
941
942 DUMP_RECV_PKT_INFO(pPacket);
943 /* since we can't hold a lock in this loop, we insert into our local recv queue for
944 * storage until we can transfer them to the recv completion queue */
945 HTC_PACKET_ENQUEUE(&localRecvQueue,pPacket);
946
947 } else {
948 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Recv packet scatter entry %d failed (out of %d) \n",
949 i, pScatterReq->ValidScatterEntries));
950 /* recycle failed recv */
951 HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint);
952 /* set flag and continue processing the remaining scatter entries */
953 procError = true;
954 }
955
956 }
957
958 /* free scatter request */
959 DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
960
961 LOCK_HTC_RX(target);
962 /* transfer the packets in the local recv queue to the recv completion queue */
963 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RecvIndicationQueue, &localRecvQueue);
964
965 UNLOCK_HTC_RX(target);
966
967 if (!procError) {
968 /* pipeline the next check (asynchronously) for more packets */
969 HTCAsyncRecvCheckMorePackets(target,
970 lookAheads,
971 numLookAheads,
972 partialBundle ? false : true);
973 }
974
975 /* now drain the indication queue */
976 DrainRecvIndicationQueue(target,pEndpoint);
977
978 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCAsyncRecvScatterCompletion \n"));
979}
980
981static int HTCIssueRecvPacketBundle(struct htc_target *target,
982 struct htc_packet_queue *pRecvPktQueue,
983 struct htc_packet_queue *pSyncCompletionQueue,
984 int *pNumPacketsFetched,
985 bool PartialBundle)
986{
987 int status = 0;
988 struct hif_scatter_req *pScatterReq;
989 int i, totalLength;
990 int pktsToScatter;
991 struct htc_packet *pPacket;
992 bool asyncMode = (pSyncCompletionQueue == NULL) ? true : false;
993 int scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device);
994
995 pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue);
996 pktsToScatter = min(pktsToScatter, target->MaxMsgPerBundle);
997
998 if ((HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue) - pktsToScatter) > 0) {
999 /* we were forced to split this bundle receive operation
1000 * all packets in this partial bundle must have their lookaheads ignored */
1001 PartialBundle = true;
1002 /* this would only happen if the target ignored our max bundle limit */
1003 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
1004 ("HTCIssueRecvPacketBundle : partial bundle detected num:%d , %d \n",
1005 HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), pktsToScatter));
1006 }
1007
1008 totalLength = 0;
1009
1010 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCIssueRecvPacketBundle (Numpackets: %d , actual : %d) \n",
1011 HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), pktsToScatter));
1012
1013 do {
1014
1015 pScatterReq = DEV_ALLOC_SCATTER_REQ(&target->Device);
1016
1017 if (pScatterReq == NULL) {
1018 /* no scatter resources left, just let caller handle it the legacy way */
1019 break;
1020 }
1021
1022 pScatterReq->CallerFlags = 0;
1023
1024 if (PartialBundle) {
1025 /* mark that this is a partial bundle, this has special ramifications to the
1026 * scatter completion routine */
1027 pScatterReq->CallerFlags |= HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE;
1028 }
1029
1030 /* convert HTC packets to scatter list */
1031 for (i = 0; i < pktsToScatter; i++) {
1032 int paddedLength;
1033
1034 pPacket = HTC_PACKET_DEQUEUE(pRecvPktQueue);
1035 A_ASSERT(pPacket != NULL);
1036
1037 paddedLength = DEV_CALC_RECV_PADDED_LEN(&target->Device, pPacket->ActualLength);
1038
1039 if ((scatterSpaceRemaining - paddedLength) < 0) {
1040 /* exceeds what we can transfer, put the packet back */
1041 HTC_PACKET_ENQUEUE_TO_HEAD(pRecvPktQueue,pPacket);
1042 break;
1043 }
1044
1045 scatterSpaceRemaining -= paddedLength;
1046
1047 if (PartialBundle || (i < (pktsToScatter - 1))) {
1048 /* packet 0..n-1 cannot be checked for look-aheads since we are fetching a bundle
1049 * the last packet however can have it's lookahead used */
1050 pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD;
1051 }
1052
1053 /* note: 1 HTC packet per scatter entry */
1054 /* setup packet into */
1055 pScatterReq->ScatterList[i].pBuffer = pPacket->pBuffer;
1056 pScatterReq->ScatterList[i].Length = paddedLength;
1057
1058 pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_PART_OF_BUNDLE;
1059
1060 if (asyncMode) {
1061 /* save HTC packet for async completion routine */
1062 pScatterReq->ScatterList[i].pCallerContexts[0] = pPacket;
1063 } else {
1064 /* queue to caller's sync completion queue, caller will unload this when we return */
1065 HTC_PACKET_ENQUEUE(pSyncCompletionQueue,pPacket);
1066 }
1067
1068 A_ASSERT(pScatterReq->ScatterList[i].Length);
1069 totalLength += pScatterReq->ScatterList[i].Length;
1070 }
1071
1072 pScatterReq->TotalLength = totalLength;
1073 pScatterReq->ValidScatterEntries = i;
1074
1075 if (asyncMode) {
1076 pScatterReq->CompletionRoutine = HTCAsyncRecvScatterCompletion;
1077 pScatterReq->Context = target;
1078 }
1079
1080 status = DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_READ, asyncMode);
1081
1082 if (!status) {
1083 *pNumPacketsFetched = i;
1084 }
1085
1086 if (!asyncMode) {
1087 /* free scatter request */
1088 DEV_FREE_SCATTER_REQ(&target->Device, pScatterReq);
1089 }
1090
1091 } while (false);
1092
1093 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCIssueRecvPacketBundle (status:%d) (fetched:%d) \n",
1094 status,*pNumPacketsFetched));
1095
1096 return status;
1097}
1098
1099static INLINE void CheckRecvWaterMark(struct htc_endpoint *pEndpoint)
1100{
1101 /* see if endpoint is using a refill watermark
1102 * ** no need to use a lock here, since we are only inspecting...
1103 * caller may must not hold locks when calling this function */
1104 if (pEndpoint->EpCallBacks.RecvRefillWaterMark > 0) {
1105 if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->RxBuffers) < pEndpoint->EpCallBacks.RecvRefillWaterMark) {
1106 /* call the re-fill handler before we continue */
1107 pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext,
1108 pEndpoint->Id);
1109 }
1110 }
1111}
1112
1113/* callback when device layer or lookahead report parsing detects a pending message */
1114int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched)
1115{
1116 struct htc_target *target = (struct htc_target *)Context;
1117 int status = 0;
1118 struct htc_packet *pPacket;
1119 struct htc_endpoint *pEndpoint;
1120 bool asyncProc = false;
1121 u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
1122 int pktsFetched;
1123 struct htc_packet_queue recvPktQueue, syncCompletedPktsQueue;
1124 bool partialBundle;
1125 HTC_ENDPOINT_ID id;
1126 int totalFetched = 0;
1127
1128 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCRecvMessagePendingHandler NumLookAheads: %d \n",NumLookAheads));
1129
1130 if (pNumPktsFetched != NULL) {
1131 *pNumPktsFetched = 0;
1132 }
1133
1134 if (IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(&target->Device)) {
1135 /* We use async mode to get the packets if the device layer supports it.
1136 * The device layer interfaces with HIF in which HIF may have restrictions on
1137 * how interrupts are processed */
1138 asyncProc = true;
1139 }
1140
1141 if (pAsyncProc != NULL) {
1142 /* indicate to caller how we decided to process this */
1143 *pAsyncProc = asyncProc;
1144 }
1145
1146 if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) {
1147 A_ASSERT(false);
1148 return A_EPROTO;
1149 }
1150
1151 /* on first entry copy the lookaheads into our temp array for processing */
1152 memcpy(lookAheads, MsgLookAheads, (sizeof(u32)) * NumLookAheads);
1153
1154 while (true) {
1155
1156 /* reset packets queues */
1157 INIT_HTC_PACKET_QUEUE(&recvPktQueue);
1158 INIT_HTC_PACKET_QUEUE(&syncCompletedPktsQueue);
1159
1160 if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) {
1161 status = A_EPROTO;
1162 A_ASSERT(false);
1163 break;
1164 }
1165
1166 /* first lookahead sets the expected endpoint IDs for all packets in a bundle */
1167 id = ((struct htc_frame_hdr *)&lookAheads[0])->EndpointID;
1168 pEndpoint = &target->EndPoint[id];
1169
1170 if (id >= ENDPOINT_MAX) {
1171 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MsgPend, Invalid Endpoint in look-ahead: %d \n",id));
1172 status = A_EPROTO;
1173 break;
1174 }
1175
1176 /* try to allocate as many HTC RX packets indicated by the lookaheads
1177 * these packets are stored in the recvPkt queue */
1178 status = AllocAndPrepareRxPackets(target,
1179 lookAheads,
1180 NumLookAheads,
1181 pEndpoint,
1182 &recvPktQueue);
1183 if (status) {
1184 break;
1185 }
1186
1187 if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) >= 2) {
1188 /* a recv bundle was detected, force IRQ status re-check again */
1189 REF_IRQ_STATUS_RECHECK(&target->Device);
1190 }
1191
1192 totalFetched += HTC_PACKET_QUEUE_DEPTH(&recvPktQueue);
1193
1194 /* we've got packet buffers for all we can currently fetch,
1195 * this count is not valid anymore */
1196 NumLookAheads = 0;
1197 partialBundle = false;
1198
1199 /* now go fetch the list of HTC packets */
1200 while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
1201
1202 pktsFetched = 0;
1203
1204 if (target->RecvBundlingEnabled && (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 1)) {
1205 /* there are enough packets to attempt a bundle transfer and recv bundling is allowed */
1206 status = HTCIssueRecvPacketBundle(target,
1207 &recvPktQueue,
1208 asyncProc ? NULL : &syncCompletedPktsQueue,
1209 &pktsFetched,
1210 partialBundle);
1211 if (status) {
1212 break;
1213 }
1214
1215 if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) != 0) {
1216 /* we couldn't fetch all packets at one time, this creates a broken
1217 * bundle */
1218 partialBundle = true;
1219 }
1220 }
1221
1222 /* see if the previous operation fetched any packets using bundling */
1223 if (0 == pktsFetched) {
1224 /* dequeue one packet */
1225 pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
1226 A_ASSERT(pPacket != NULL);
1227
1228 if (asyncProc) {
1229 /* we use async mode to get the packet if the device layer supports it
1230 * set our callback and context */
1231 pPacket->Completion = HTCRecvCompleteHandler;
1232 pPacket->pContext = target;
1233 } else {
1234 /* fully synchronous */
1235 pPacket->Completion = NULL;
1236 }
1237
1238 if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 0) {
1239 /* lookaheads in all packets except the last one in the bundle must be ignored */
1240 pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD;
1241 }
1242
1243 /* go fetch the packet */
1244 status = HTCIssueRecv(target, pPacket);
1245 if (status) {
1246 break;
1247 }
1248
1249 if (!asyncProc) {
1250 /* sent synchronously, queue this packet for synchronous completion */
1251 HTC_PACKET_ENQUEUE(&syncCompletedPktsQueue,pPacket);
1252 }
1253
1254 }
1255
1256 }
1257
1258 if (!status) {
1259 CheckRecvWaterMark(pEndpoint);
1260 }
1261
1262 if (asyncProc) {
1263 /* we did this asynchronously so we can get out of the loop, the asynch processing
1264 * creates a chain of requests to continue processing pending messages in the
1265 * context of callbacks */
1266 break;
1267 }
1268
1269 /* synchronous handling */
1270 if (target->Device.DSRCanYield) {
1271 /* for the SYNC case, increment count that tracks when the DSR should yield */
1272 target->Device.CurrentDSRRecvCount++;
1273 }
1274
1275 /* in the sync case, all packet buffers are now filled,
1276 * we can process each packet, check lookaheads and then repeat */
1277
1278 /* unload sync completion queue */
1279 while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
1280 struct htc_packet_queue container;
1281
1282 pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue);
1283 A_ASSERT(pPacket != NULL);
1284
1285 pEndpoint = &target->EndPoint[pPacket->Endpoint];
1286 /* reset count on each iteration, we are only interested in the last packet's lookahead
1287 * information when we break out of this loop */
1288 NumLookAheads = 0;
1289 /* process header for each of the recv packets
1290 * note: the lookahead of the last packet is useful for us to continue in this loop */
1291 status = HTCProcessRecvHeader(target,pPacket,lookAheads,&NumLookAheads);
1292 if (status) {
1293 break;
1294 }
1295
1296 if (HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
1297 /* last packet's more packets flag is set based on the lookahead */
1298 SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,NumLookAheads,pEndpoint,pPacket);
1299 } else {
1300 /* packets in a bundle automatically have this flag set */
1301 FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
1302 }
1303 /* good packet, indicate it */
1304 HTC_RX_STAT_PROFILE(target,pEndpoint,NumLookAheads);
1305
1306 if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_PART_OF_BUNDLE) {
1307 INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1);
1308 }
1309
1310 INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
1311 DO_RCV_COMPLETION(pEndpoint,&container);
1312 }
1313
1314 if (status) {
1315 break;
1316 }
1317
1318 if (NumLookAheads == 0) {
1319 /* no more look aheads */
1320 break;
1321 }
1322
1323 /* when we process recv synchronously we need to check if we should yield and stop
1324 * fetching more packets indicated by the embedded lookaheads */
1325 if (target->Device.DSRCanYield) {
1326 if (DEV_CHECK_RECV_YIELD(&target->Device)) {
1327 /* break out, don't fetch any more packets */
1328 break;
1329 }
1330 }
1331
1332
1333 /* check whether other OS contexts have queued any WMI command/data for WLAN.
1334 * This check is needed only if WLAN Tx and Rx happens in same thread context */
1335 A_CHECK_DRV_TX();
1336
1337 /* for SYNCH processing, if we get here, we are running through the loop again due to a detected lookahead.
1338 * Set flag that we should re-check IRQ status registers again before leaving IRQ processing,
1339 * this can net better performance in high throughput situations */
1340 REF_IRQ_STATUS_RECHECK(&target->Device);
1341 }
1342
1343 if (status) {
1344 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1345 ("Failed to get pending recv messages (%d) \n",status));
1346 /* cleanup any packets we allocated but didn't use to actually fetch any packets */
1347 while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
1348 pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
1349 /* clean up packets */
1350 HTC_RECYCLE_RX_PKT(target, pPacket, &target->EndPoint[pPacket->Endpoint]);
1351 }
1352 /* cleanup any packets in sync completion queue */
1353 while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
1354 pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue);
1355 /* clean up packets */
1356 HTC_RECYCLE_RX_PKT(target, pPacket, &target->EndPoint[pPacket->Endpoint]);
1357 }
1358 if (HTC_STOPPING(target)) {
1359 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
1360 (" Host is going to stop. blocking receiver for HTCStop.. \n"));
1361 DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC);
1362 }
1363 }
1364 /* before leaving, check to see if host ran out of buffers and needs to stop the
1365 * receiver */
1366 if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
1367 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
1368 (" Host has no RX buffers, blocking receiver to prevent overrun.. \n"));
1369 /* try to stop receive at the device layer */
1370 DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC);
1371 }
1372
1373 if (pNumPktsFetched != NULL) {
1374 *pNumPktsFetched = totalFetched;
1375 }
1376
1377 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCRecvMessagePendingHandler \n"));
1378
1379 return status;
1380}
1381
1382int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue)
1383{
1384 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1385 struct htc_endpoint *pEndpoint;
1386 bool unblockRecv = false;
1387 int status = 0;
1388 struct htc_packet *pFirstPacket;
1389
1390 pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue);
1391
1392 if (NULL == pFirstPacket) {
1393 A_ASSERT(false);
1394 return A_EINVAL;
1395 }
1396
1397 AR_DEBUG_ASSERT(pFirstPacket->Endpoint < ENDPOINT_MAX);
1398
1399 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
1400 ("+- HTCAddReceivePktMultiple : endPointId: %d, cnt:%d, length: %d\n",
1401 pFirstPacket->Endpoint,
1402 HTC_PACKET_QUEUE_DEPTH(pPktQueue),
1403 pFirstPacket->BufferLength));
1404
1405 do {
1406
1407 pEndpoint = &target->EndPoint[pFirstPacket->Endpoint];
1408
1409 LOCK_HTC_RX(target);
1410
1411 if (HTC_STOPPING(target)) {
1412 struct htc_packet *pPacket;
1413
1414 UNLOCK_HTC_RX(target);
1415
1416 /* walk through queue and mark each one canceled */
1417 HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
1418 pPacket->Status = A_ECANCELED;
1419 } HTC_PACKET_QUEUE_ITERATE_END;
1420
1421 DO_RCV_COMPLETION(pEndpoint,pPktQueue);
1422 break;
1423 }
1424
1425 /* store receive packets */
1426 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RxBuffers, pPktQueue);
1427
1428 /* check if we are blocked waiting for a new buffer */
1429 if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
1430 if (target->EpWaitingForBuffers == pFirstPacket->Endpoint) {
1431 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" receiver was blocked on ep:%d, unblocking.. \n",
1432 target->EpWaitingForBuffers));
1433 target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS;
1434 target->EpWaitingForBuffers = ENDPOINT_MAX;
1435 unblockRecv = true;
1436 }
1437 }
1438
1439 UNLOCK_HTC_RX(target);
1440
1441 if (unblockRecv && !HTC_STOPPING(target)) {
1442 /* TODO : implement a buffer threshold count? */
1443 DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
1444 }
1445
1446 } while (false);
1447
1448 return status;
1449}
1450
1451/* Makes a buffer available to the HTC module */
1452int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket)
1453{
1454 struct htc_packet_queue queue;
1455 INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
1456 return HTCAddReceivePktMultiple(HTCHandle, &queue);
1457}
1458
1459void HTCUnblockRecv(HTC_HANDLE HTCHandle)
1460{
1461 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1462 bool unblockRecv = false;
1463
1464 LOCK_HTC_RX(target);
1465
1466 /* check if we are blocked waiting for a new buffer */
1467 if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
1468 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HTCUnblockRx : receiver was blocked on ep:%d, unblocking.. \n",
1469 target->EpWaitingForBuffers));
1470 target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS;
1471 target->EpWaitingForBuffers = ENDPOINT_MAX;
1472 unblockRecv = true;
1473 }
1474
1475 UNLOCK_HTC_RX(target);
1476
1477 if (unblockRecv && !HTC_STOPPING(target)) {
1478 /* re-enable */
1479 DevEnableRecv(&target->Device,DEV_ENABLE_RECV_ASYNC);
1480 }
1481}
1482
1483static void HTCFlushRxQueue(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet_queue *pQueue)
1484{
1485 struct htc_packet *pPacket;
1486 struct htc_packet_queue container;
1487
1488 LOCK_HTC_RX(target);
1489
1490 while (1) {
1491 pPacket = HTC_PACKET_DEQUEUE(pQueue);
1492 if (NULL == pPacket) {
1493 break;
1494 }
1495 UNLOCK_HTC_RX(target);
1496 pPacket->Status = A_ECANCELED;
1497 pPacket->ActualLength = 0;
1498 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" Flushing RX packet:0x%lX, length:%d, ep:%d \n",
1499 (unsigned long)pPacket, pPacket->BufferLength, pPacket->Endpoint));
1500 INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
1501 /* give the packet back */
1502 DO_RCV_COMPLETION(pEndpoint,&container);
1503 LOCK_HTC_RX(target);
1504 }
1505
1506 UNLOCK_HTC_RX(target);
1507}
1508
1509static void HTCFlushEndpointRX(struct htc_target *target, struct htc_endpoint *pEndpoint)
1510{
1511 /* flush any recv indications not already made */
1512 HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RecvIndicationQueue);
1513 /* flush any rx buffers */
1514 HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RxBuffers);
1515}
1516
1517void HTCFlushRecvBuffers(struct htc_target *target)
1518{
1519 struct htc_endpoint *pEndpoint;
1520 int i;
1521
1522 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
1523 pEndpoint = &target->EndPoint[i];
1524 if (pEndpoint->ServiceID == 0) {
1525 /* not in use.. */
1526 continue;
1527 }
1528 HTCFlushEndpointRX(target,pEndpoint);
1529 }
1530}
1531
1532
1533void HTCEnableRecv(HTC_HANDLE HTCHandle)
1534{
1535 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1536
1537 if (!HTC_STOPPING(target)) {
1538 /* re-enable */
1539 DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
1540 }
1541}
1542
1543void HTCDisableRecv(HTC_HANDLE HTCHandle)
1544{
1545 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1546
1547 if (!HTC_STOPPING(target)) {
1548 /* disable */
1549 DevStopRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
1550 }
1551}
1552
1553int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle,
1554 HTC_ENDPOINT_ID Endpoint)
1555{
1556 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1557 return HTC_PACKET_QUEUE_DEPTH(&(target->EndPoint[Endpoint].RxBuffers));
1558}
1559
1560int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle,
1561 u32 TimeoutInMs,
1562 bool *pbIsRecvPending)
1563{
1564 int status = 0;
1565 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1566
1567 status = DevWaitForPendingRecv(&target->Device,
1568 TimeoutInMs,
1569 pbIsRecvPending);
1570
1571 return status;
1572}
diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c
new file mode 100644
index 00000000000..9310d4d5c99
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc_send.c
@@ -0,0 +1,1018 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_send.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#include "htc_internal.h"
24
25typedef enum _HTC_SEND_QUEUE_RESULT {
26 HTC_SEND_QUEUE_OK = 0, /* packet was queued */
27 HTC_SEND_QUEUE_DROP = 1, /* this packet should be dropped */
28} HTC_SEND_QUEUE_RESULT;
29
30#define DO_EP_TX_COMPLETION(ep,q) DoSendCompletion(ep,q)
31
32/* call the distribute credits callback with the distribution */
33#define DO_DISTRIBUTION(t,reason,description,pList) \
34{ \
35 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, \
36 (" calling distribute function (%s) (dfn:0x%lX, ctxt:0x%lX, dist:0x%lX) \n", \
37 (description), \
38 (unsigned long)(t)->DistributeCredits, \
39 (unsigned long)(t)->pCredDistContext, \
40 (unsigned long)pList)); \
41 (t)->DistributeCredits((t)->pCredDistContext, \
42 (pList), \
43 (reason)); \
44}
45
46static void DoSendCompletion(struct htc_endpoint *pEndpoint,
47 struct htc_packet_queue *pQueueToIndicate)
48{
49 do {
50
51 if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
52 /* nothing to indicate */
53 break;
54 }
55
56 if (pEndpoint->EpCallBacks.EpTxCompleteMultiple != NULL) {
57 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d, send complete multiple callback (%d pkts) \n",
58 pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
59 /* a multiple send complete handler is being used, pass the queue to the handler */
60 pEndpoint->EpCallBacks.EpTxCompleteMultiple(pEndpoint->EpCallBacks.pContext,
61 pQueueToIndicate);
62 /* all packets are now owned by the callback, reset queue to be safe */
63 INIT_HTC_PACKET_QUEUE(pQueueToIndicate);
64 } else {
65 struct htc_packet *pPacket;
66 /* using legacy EpTxComplete */
67 do {
68 pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
69 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d send complete callback on packet 0x%lX \n", \
70 pEndpoint->Id, (unsigned long)(pPacket)));
71 pEndpoint->EpCallBacks.EpTxComplete(pEndpoint->EpCallBacks.pContext, pPacket);
72 } while (!HTC_QUEUE_EMPTY(pQueueToIndicate));
73 }
74
75 } while (false);
76
77}
78
79/* do final completion on sent packet */
80static INLINE void CompleteSentPacket(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet *pPacket)
81{
82 pPacket->Completion = NULL;
83
84 if (pPacket->Status) {
85 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
86 ("CompleteSentPacket: request failed (status:%d, ep:%d, length:%d creds:%d) \n",
87 pPacket->Status, pPacket->Endpoint, pPacket->ActualLength, pPacket->PktInfo.AsTx.CreditsUsed));
88 /* on failure to submit, reclaim credits for this packet */
89 LOCK_HTC_TX(target);
90 pEndpoint->CreditDist.TxCreditsToDist += pPacket->PktInfo.AsTx.CreditsUsed;
91 pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
92 DO_DISTRIBUTION(target,
93 HTC_CREDIT_DIST_SEND_COMPLETE,
94 "Send Complete",
95 target->EpCreditDistributionListHead->pNext);
96 UNLOCK_HTC_TX(target);
97 }
98 /* first, fixup the head room we allocated */
99 pPacket->pBuffer += HTC_HDR_LENGTH;
100}
101
102/* our internal send packet completion handler when packets are submited to the AR6K device
103 * layer */
104static void HTCSendPktCompletionHandler(void *Context, struct htc_packet *pPacket)
105{
106 struct htc_target *target = (struct htc_target *)Context;
107 struct htc_endpoint *pEndpoint = &target->EndPoint[pPacket->Endpoint];
108 struct htc_packet_queue container;
109
110 CompleteSentPacket(target,pEndpoint,pPacket);
111 INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
112 /* do completion */
113 DO_EP_TX_COMPLETION(pEndpoint,&container);
114}
115
116int HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket)
117{
118 int status;
119 bool sync = false;
120
121 if (pPacket->Completion == NULL) {
122 /* mark that this request was synchronously issued */
123 sync = true;
124 }
125
126 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
127 ("+-HTCIssueSend: transmit length : %d (%s) \n",
128 pPacket->ActualLength + (u32)HTC_HDR_LENGTH,
129 sync ? "SYNC" : "ASYNC" ));
130
131 /* send message to device */
132 status = DevSendPacket(&target->Device,
133 pPacket,
134 pPacket->ActualLength + HTC_HDR_LENGTH);
135
136 if (sync) {
137 /* use local sync variable. If this was issued asynchronously, pPacket is no longer
138 * safe to access. */
139 pPacket->pBuffer += HTC_HDR_LENGTH;
140 }
141
142 /* if this request was asynchronous, the packet completion routine will be invoked by
143 * the device layer when the HIF layer completes the request */
144
145 return status;
146}
147
148 /* get HTC send packets from the TX queue on an endpoint */
149static INLINE void GetHTCSendPackets(struct htc_target *target,
150 struct htc_endpoint *pEndpoint,
151 struct htc_packet_queue *pQueue)
152{
153 int creditsRequired;
154 int remainder;
155 u8 sendFlags;
156 struct htc_packet *pPacket;
157 unsigned int transferLength;
158
159 /****** NOTE : the TX lock is held when this function is called *****************/
160 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+GetHTCSendPackets \n"));
161
162 /* loop until we can grab as many packets out of the queue as we can */
163 while (true) {
164
165 sendFlags = 0;
166 /* get packet at head, but don't remove it */
167 pPacket = HTC_GET_PKT_AT_HEAD(&pEndpoint->TxQueue);
168 if (pPacket == NULL) {
169 break;
170 }
171
172 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got head packet:0x%lX , Queue Depth: %d\n",
173 (unsigned long)pPacket, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
174
175 transferLength = DEV_CALC_SEND_PADDED_LEN(&target->Device, pPacket->ActualLength + HTC_HDR_LENGTH);
176
177 if (transferLength <= target->TargetCreditSize) {
178 creditsRequired = 1;
179 } else {
180 /* figure out how many credits this message requires */
181 creditsRequired = transferLength / target->TargetCreditSize;
182 remainder = transferLength % target->TargetCreditSize;
183
184 if (remainder) {
185 creditsRequired++;
186 }
187 }
188
189 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Creds Required:%d Got:%d\n",
190 creditsRequired, pEndpoint->CreditDist.TxCredits));
191
192 if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
193
194 /* not enough credits */
195 if (pPacket->Endpoint == ENDPOINT_0) {
196 /* leave it in the queue */
197 break;
198 }
199 /* invoke the registered distribution function only if this is not
200 * endpoint 0, we let the driver layer provide more credits if it can.
201 * We pass the credit distribution list starting at the endpoint in question
202 * */
203
204 /* set how many credits we need */
205 pEndpoint->CreditDist.TxCreditsSeek =
206 creditsRequired - pEndpoint->CreditDist.TxCredits;
207 DO_DISTRIBUTION(target,
208 HTC_CREDIT_DIST_SEEK_CREDITS,
209 "Seek Credits",
210 &pEndpoint->CreditDist);
211 pEndpoint->CreditDist.TxCreditsSeek = 0;
212
213 if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
214 /* still not enough credits to send, leave packet in the queue */
215 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
216 (" Not enough credits for ep %d leaving packet in queue..\n",
217 pPacket->Endpoint));
218 break;
219 }
220
221 }
222
223 pEndpoint->CreditDist.TxCredits -= creditsRequired;
224 INC_HTC_EP_STAT(pEndpoint, TxCreditsConsummed, creditsRequired);
225
226 /* check if we need credits back from the target */
227 if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
228 /* we are getting low on credits, see if we can ask for more from the distribution function */
229 pEndpoint->CreditDist.TxCreditsSeek =
230 pEndpoint->CreditDist.TxCreditsPerMaxMsg - pEndpoint->CreditDist.TxCredits;
231
232 DO_DISTRIBUTION(target,
233 HTC_CREDIT_DIST_SEEK_CREDITS,
234 "Seek Credits",
235 &pEndpoint->CreditDist);
236
237 pEndpoint->CreditDist.TxCreditsSeek = 0;
238 /* see if we were successful in getting more */
239 if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
240 /* tell the target we need credits ASAP! */
241 sendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
242 INC_HTC_EP_STAT(pEndpoint, TxCreditLowIndications, 1);
243 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Host Needs Credits \n"));
244 }
245 }
246
247 /* now we can fully dequeue */
248 pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue);
249 /* save the number of credits this packet consumed */
250 pPacket->PktInfo.AsTx.CreditsUsed = creditsRequired;
251 /* all TX packets are handled asynchronously */
252 pPacket->Completion = HTCSendPktCompletionHandler;
253 pPacket->pContext = target;
254 INC_HTC_EP_STAT(pEndpoint, TxIssued, 1);
255 /* save send flags */
256 pPacket->PktInfo.AsTx.SendFlags = sendFlags;
257 pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo;
258 pEndpoint->SeqNo++;
259 /* queue this packet into the caller's queue */
260 HTC_PACKET_ENQUEUE(pQueue,pPacket);
261 }
262
263 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-GetHTCSendPackets \n"));
264
265}
266
267static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq)
268{
269 int i;
270 struct htc_packet *pPacket;
271 struct htc_endpoint *pEndpoint = (struct htc_endpoint *)pScatterReq->Context;
272 struct htc_target *target = (struct htc_target *)pEndpoint->target;
273 int status = 0;
274 struct htc_packet_queue sendCompletes;
275
276 INIT_HTC_PACKET_QUEUE(&sendCompletes);
277
278 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCAsyncSendScatterCompletion TotLen: %d Entries: %d\n",
279 pScatterReq->TotalLength, pScatterReq->ValidScatterEntries));
280
281 DEV_FINISH_SCATTER_OPERATION(pScatterReq);
282
283 if (pScatterReq->CompletionStatus) {
284 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Send Scatter Request Failed: %d \n",pScatterReq->CompletionStatus));
285 status = A_ERROR;
286 }
287
288 /* walk through the scatter list and process */
289 for (i = 0; i < pScatterReq->ValidScatterEntries; i++) {
290 pPacket = (struct htc_packet *)(pScatterReq->ScatterList[i].pCallerContexts[0]);
291 A_ASSERT(pPacket != NULL);
292 pPacket->Status = status;
293 CompleteSentPacket(target,pEndpoint,pPacket);
294 /* add it to the completion queue */
295 HTC_PACKET_ENQUEUE(&sendCompletes, pPacket);
296 }
297
298 /* free scatter request */
299 DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
300 /* complete all packets */
301 DO_EP_TX_COMPLETION(pEndpoint,&sendCompletes);
302
303 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCAsyncSendScatterCompletion \n"));
304}
305
306 /* drain a queue and send as bundles
307 * this function may return without fully draining the queue under the following conditions :
308 * - scatter resources are exhausted
309 * - a message that will consume a partial credit will stop the bundling process early
310 * - we drop below the minimum number of messages for a bundle
311 * */
312static void HTCIssueSendBundle(struct htc_endpoint *pEndpoint,
313 struct htc_packet_queue *pQueue,
314 int *pBundlesSent,
315 int *pTotalBundlesPkts)
316{
317 int pktsToScatter;
318 unsigned int scatterSpaceRemaining;
319 struct hif_scatter_req *pScatterReq = NULL;
320 int i, packetsInScatterReq;
321 unsigned int transferLength;
322 struct htc_packet *pPacket;
323 bool done = false;
324 int bundlesSent = 0;
325 int totalPktsInBundle = 0;
326 struct htc_target *target = pEndpoint->target;
327 int creditRemainder = 0;
328 int creditPad;
329
330 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCIssueSendBundle \n"));
331
332 while (!done) {
333
334 pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pQueue);
335 pktsToScatter = min(pktsToScatter, target->MaxMsgPerBundle);
336
337 if (pktsToScatter < HTC_MIN_HTC_MSGS_TO_BUNDLE) {
338 /* not enough to bundle */
339 break;
340 }
341
342 pScatterReq = DEV_ALLOC_SCATTER_REQ(&target->Device);
343
344 if (pScatterReq == NULL) {
345 /* no scatter resources */
346 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" No more scatter resources \n"));
347 break;
348 }
349
350 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" pkts to scatter: %d \n", pktsToScatter));
351
352 pScatterReq->TotalLength = 0;
353 pScatterReq->ValidScatterEntries = 0;
354
355 packetsInScatterReq = 0;
356 scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device);
357
358 for (i = 0; i < pktsToScatter; i++) {
359
360 pScatterReq->ScatterList[i].pCallerContexts[0] = NULL;
361
362 pPacket = HTC_GET_PKT_AT_HEAD(pQueue);
363 if (pPacket == NULL) {
364 A_ASSERT(false);
365 break;
366 }
367
368 creditPad = 0;
369 transferLength = DEV_CALC_SEND_PADDED_LEN(&target->Device,
370 pPacket->ActualLength + HTC_HDR_LENGTH);
371 /* see if the padded transfer length falls on a credit boundary */
372 creditRemainder = transferLength % target->TargetCreditSize;
373
374 if (creditRemainder != 0) {
375 /* the transfer consumes a "partial" credit, this packet cannot be bundled unless
376 * we add additional "dummy" padding (max 255 bytes) to consume the entire credit
377 *** NOTE: only allow the send padding if the endpoint is allowed to */
378 if (pEndpoint->LocalConnectionFlags & HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING) {
379 if (transferLength < target->TargetCreditSize) {
380 /* special case where the transfer is less than a credit */
381 creditPad = target->TargetCreditSize - transferLength;
382 } else {
383 creditPad = creditRemainder;
384 }
385
386 /* now check to see if we can indicate padding in the HTC header */
387 if ((creditPad > 0) && (creditPad <= 255)) {
388 /* adjust the transferlength of this packet with the new credit padding */
389 transferLength += creditPad;
390 } else {
391 /* the amount to pad is too large, bail on this packet, we have to
392 * send it using the non-bundled method */
393 pPacket = NULL;
394 }
395 } else {
396 /* bail on this packet, user does not want padding applied */
397 pPacket = NULL;
398 }
399 }
400
401 if (NULL == pPacket) {
402 /* can't bundle */
403 done = true;
404 break;
405 }
406
407 if (scatterSpaceRemaining < transferLength) {
408 /* exceeds what we can transfer */
409 break;
410 }
411
412 scatterSpaceRemaining -= transferLength;
413 /* now remove it from the queue */
414 pPacket = HTC_PACKET_DEQUEUE(pQueue);
415 /* save it in the scatter list */
416 pScatterReq->ScatterList[i].pCallerContexts[0] = pPacket;
417 /* prepare packet and flag message as part of a send bundle */
418 HTC_PREPARE_SEND_PKT(pPacket,
419 pPacket->PktInfo.AsTx.SendFlags | HTC_FLAGS_SEND_BUNDLE,
420 creditPad,
421 pPacket->PktInfo.AsTx.SeqNo);
422 pScatterReq->ScatterList[i].pBuffer = pPacket->pBuffer;
423 pScatterReq->ScatterList[i].Length = transferLength;
424 A_ASSERT(transferLength);
425 pScatterReq->TotalLength += transferLength;
426 pScatterReq->ValidScatterEntries++;
427 packetsInScatterReq++;
428 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" %d, Adding packet : 0x%lX, len:%d (remaining space:%d) \n",
429 i, (unsigned long)pPacket,transferLength,scatterSpaceRemaining));
430 }
431
432 if (packetsInScatterReq >= HTC_MIN_HTC_MSGS_TO_BUNDLE) {
433 /* send path is always asynchronous */
434 pScatterReq->CompletionRoutine = HTCAsyncSendScatterCompletion;
435 pScatterReq->Context = pEndpoint;
436 bundlesSent++;
437 totalPktsInBundle += packetsInScatterReq;
438 packetsInScatterReq = 0;
439 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Send Scatter total bytes: %d , entries: %d\n",
440 pScatterReq->TotalLength,pScatterReq->ValidScatterEntries));
441 DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_WRITE, DEV_SCATTER_ASYNC);
442 /* we don't own this anymore */
443 pScatterReq = NULL;
444 /* try to send some more */
445 continue;
446 }
447
448 /* not enough packets to use the scatter request, cleanup */
449 if (pScatterReq != NULL) {
450 if (packetsInScatterReq > 0) {
451 /* work backwards to requeue requests */
452 for (i = (packetsInScatterReq - 1); i >= 0; i--) {
453 pPacket = (struct htc_packet *)(pScatterReq->ScatterList[i].pCallerContexts[0]);
454 if (pPacket != NULL) {
455 /* undo any prep */
456 HTC_UNPREPARE_SEND_PKT(pPacket);
457 /* queue back to the head */
458 HTC_PACKET_ENQUEUE_TO_HEAD(pQueue,pPacket);
459 }
460 }
461 }
462 DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
463 }
464
465 /* if we get here, we sent all that we could, get out */
466 break;
467
468 }
469
470 *pBundlesSent = bundlesSent;
471 *pTotalBundlesPkts = totalPktsInBundle;
472 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCIssueSendBundle (sent:%d) \n",bundlesSent));
473
474 return;
475}
476
477/*
478 * if there are no credits, the packet(s) remains in the queue.
479 * this function returns the result of the attempt to send a queue of HTC packets */
480static HTC_SEND_QUEUE_RESULT HTCTrySend(struct htc_target *target,
481 struct htc_endpoint *pEndpoint,
482 struct htc_packet_queue *pCallersSendQueue)
483{
484 struct htc_packet_queue sendQueue; /* temp queue to hold packets at various stages */
485 struct htc_packet *pPacket;
486 int bundlesSent;
487 int pktsInBundles;
488 int overflow;
489 HTC_SEND_QUEUE_RESULT result = HTC_SEND_QUEUE_OK;
490
491 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (Queue:0x%lX Depth:%d)\n",
492 (unsigned long)pCallersSendQueue,
493 (pCallersSendQueue == NULL) ? 0 : HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue)));
494
495 /* init the local send queue */
496 INIT_HTC_PACKET_QUEUE(&sendQueue);
497
498 do {
499
500 if (NULL == pCallersSendQueue) {
501 /* caller didn't provide a queue, just wants us to check queues and send */
502 break;
503 }
504
505 if (HTC_QUEUE_EMPTY(pCallersSendQueue)) {
506 /* empty queue */
507 result = HTC_SEND_QUEUE_DROP;
508 break;
509 }
510
511 if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) >= pEndpoint->MaxTxQueueDepth) {
512 /* we've already overflowed */
513 overflow = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue);
514 } else {
515 /* figure out how much we will overflow by */
516 overflow = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
517 overflow += HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue);
518 /* figure out how much we will overflow the TX queue by */
519 overflow -= pEndpoint->MaxTxQueueDepth;
520 }
521
522 /* if overflow is negative or zero, we are okay */
523 if (overflow > 0) {
524 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
525 (" Endpoint %d, TX queue will overflow :%d , Tx Depth:%d, Max:%d \n",
526 pEndpoint->Id, overflow, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue), pEndpoint->MaxTxQueueDepth));
527 }
528 if ((overflow <= 0) || (pEndpoint->EpCallBacks.EpSendFull == NULL)) {
529 /* all packets will fit or caller did not provide send full indication handler
530 * -- just move all of them to the local sendQueue object */
531 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&sendQueue, pCallersSendQueue);
532 } else {
533 int i;
534 int goodPkts = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue) - overflow;
535
536 A_ASSERT(goodPkts >= 0);
537 /* we have overflowed, and a callback is provided */
538 /* dequeue all non-overflow packets into the sendqueue */
539 for (i = 0; i < goodPkts; i++) {
540 /* pop off caller's queue*/
541 pPacket = HTC_PACKET_DEQUEUE(pCallersSendQueue);
542 A_ASSERT(pPacket != NULL);
543 /* insert into local queue */
544 HTC_PACKET_ENQUEUE(&sendQueue,pPacket);
545 }
546
547 /* the caller's queue has all the packets that won't fit*/
548 /* walk through the caller's queue and indicate each one to the send full handler */
549 ITERATE_OVER_LIST_ALLOW_REMOVE(&pCallersSendQueue->QueueHead, pPacket, struct htc_packet, ListLink) {
550
551 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Indicating overflowed TX packet: 0x%lX \n",
552 (unsigned long)pPacket));
553 if (pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext,
554 pPacket) == HTC_SEND_FULL_DROP) {
555 /* callback wants the packet dropped */
556 INC_HTC_EP_STAT(pEndpoint, TxDropped, 1);
557 /* leave this one in the caller's queue for cleanup */
558 } else {
559 /* callback wants to keep this packet, remove from caller's queue */
560 HTC_PACKET_REMOVE(pCallersSendQueue, pPacket);
561 /* put it in the send queue */
562 HTC_PACKET_ENQUEUE(&sendQueue,pPacket);
563 }
564
565 } ITERATE_END;
566
567 if (HTC_QUEUE_EMPTY(&sendQueue)) {
568 /* no packets made it in, caller will cleanup */
569 result = HTC_SEND_QUEUE_DROP;
570 break;
571 }
572 }
573
574 } while (false);
575
576 if (result != HTC_SEND_QUEUE_OK) {
577 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n"));
578 return result;
579 }
580
581 LOCK_HTC_TX(target);
582
583 if (!HTC_QUEUE_EMPTY(&sendQueue)) {
584 /* transfer packets */
585 HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->TxQueue,&sendQueue);
586 A_ASSERT(HTC_QUEUE_EMPTY(&sendQueue));
587 INIT_HTC_PACKET_QUEUE(&sendQueue);
588 }
589
590 /* increment tx processing count on entry */
591 pEndpoint->TxProcessCount++;
592 if (pEndpoint->TxProcessCount > 1) {
593 /* another thread or task is draining the TX queues on this endpoint
594 * that thread will reset the tx processing count when the queue is drained */
595 pEndpoint->TxProcessCount--;
596 UNLOCK_HTC_TX(target);
597 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend (busy) \n"));
598 return HTC_SEND_QUEUE_OK;
599 }
600
601 /***** beyond this point only 1 thread may enter ******/
602
603 /* now drain the endpoint TX queue for transmission as long as we have enough
604 * credits */
605 while (true) {
606
607 if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) == 0) {
608 break;
609 }
610
611 /* get all the packets for this endpoint that we can for this pass */
612 GetHTCSendPackets(target, pEndpoint, &sendQueue);
613
614 if (HTC_PACKET_QUEUE_DEPTH(&sendQueue) == 0) {
615 /* didn't get any packets due to a lack of credits */
616 break;
617 }
618
619 UNLOCK_HTC_TX(target);
620
621 /* any packets to send are now in our local send queue */
622
623 bundlesSent = 0;
624 pktsInBundles = 0;
625
626 while (true) {
627
628 /* try to send a bundle on each pass */
629 if ((target->SendBundlingEnabled) &&
630 (HTC_PACKET_QUEUE_DEPTH(&sendQueue) >= HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
631 int temp1,temp2;
632 /* bundling is enabled and there is at least a minimum number of packets in the send queue
633 * send what we can in this pass */
634 HTCIssueSendBundle(pEndpoint, &sendQueue, &temp1, &temp2);
635 bundlesSent += temp1;
636 pktsInBundles += temp2;
637 }
638
639 /* if not bundling or there was a packet that could not be placed in a bundle, pull it out
640 * and send it the normal way */
641 pPacket = HTC_PACKET_DEQUEUE(&sendQueue);
642 if (NULL == pPacket) {
643 /* local queue is fully drained */
644 break;
645 }
646 HTC_PREPARE_SEND_PKT(pPacket,
647 pPacket->PktInfo.AsTx.SendFlags,
648 0,
649 pPacket->PktInfo.AsTx.SeqNo);
650 HTCIssueSend(target, pPacket);
651
652 /* go back and see if we can bundle some more */
653 }
654
655 LOCK_HTC_TX(target);
656
657 INC_HTC_EP_STAT(pEndpoint, TxBundles, bundlesSent);
658 INC_HTC_EP_STAT(pEndpoint, TxPacketsBundled, pktsInBundles);
659
660 }
661
662 /* done with this endpoint, we can clear the count */
663 pEndpoint->TxProcessCount = 0;
664 UNLOCK_HTC_TX(target);
665
666 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n"));
667
668 return HTC_SEND_QUEUE_OK;
669}
670
671int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue)
672{
673 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
674 struct htc_endpoint *pEndpoint;
675 struct htc_packet *pPacket;
676
677 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCSendPktsMultiple: Queue: 0x%lX, Pkts %d \n",
678 (unsigned long)pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue)));
679
680 /* get packet at head to figure out which endpoint these packets will go into */
681 pPacket = HTC_GET_PKT_AT_HEAD(pPktQueue);
682 if (NULL == pPacket) {
683 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n"));
684 return A_EINVAL;
685 }
686
687 AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);
688 pEndpoint = &target->EndPoint[pPacket->Endpoint];
689
690 HTCTrySend(target, pEndpoint, pPktQueue);
691
692 /* do completion on any packets that couldn't get in */
693 if (!HTC_QUEUE_EMPTY(pPktQueue)) {
694
695 HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
696 if (HTC_STOPPING(target)) {
697 pPacket->Status = A_ECANCELED;
698 } else {
699 pPacket->Status = A_NO_RESOURCE;
700 }
701 } HTC_PACKET_QUEUE_ITERATE_END;
702
703 DO_EP_TX_COMPLETION(pEndpoint,pPktQueue);
704 }
705
706 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n"));
707
708 return 0;
709}
710
711/* HTC API - HTCSendPkt */
712int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket)
713{
714 struct htc_packet_queue queue;
715
716 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
717 ("+-HTCSendPkt: Enter endPointId: %d, buffer: 0x%lX, length: %d \n",
718 pPacket->Endpoint, (unsigned long)pPacket->pBuffer, pPacket->ActualLength));
719 INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
720 return HTCSendPktsMultiple(HTCHandle, &queue);
721}
722
723/* check TX queues to drain because of credit distribution update */
724static INLINE void HTCCheckEndpointTxQueues(struct htc_target *target)
725{
726 struct htc_endpoint *pEndpoint;
727 struct htc_endpoint_credit_dist *pDistItem;
728
729 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCCheckEndpointTxQueues \n"));
730 pDistItem = target->EpCreditDistributionListHead;
731
732 /* run through the credit distribution list to see
733 * if there are packets queued
734 * NOTE: no locks need to be taken since the distribution list
735 * is not dynamic (cannot be re-ordered) and we are not modifying any state */
736 while (pDistItem != NULL) {
737 pEndpoint = (struct htc_endpoint *)pDistItem->pHTCReserved;
738
739 if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) > 0) {
740 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Ep %d has %d credits and %d Packets in TX Queue \n",
741 pDistItem->Endpoint, pEndpoint->CreditDist.TxCredits, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
742 /* try to start the stalled queue, this list is ordered by priority.
743 * Highest priority queue get's processed first, if there are credits available the
744 * highest priority queue will get a chance to reclaim credits from lower priority
745 * ones */
746 HTCTrySend(target, pEndpoint, NULL);
747 }
748
749 pDistItem = pDistItem->pNext;
750 }
751
752 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCCheckEndpointTxQueues \n"));
753}
754
755/* process credit reports and call distribution function */
756void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint)
757{
758 int i;
759 struct htc_endpoint *pEndpoint;
760 int totalCredits = 0;
761 bool doDist = false;
762
763 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCProcessCreditRpt, Credit Report Entries:%d \n", NumEntries));
764
765 /* lock out TX while we update credits */
766 LOCK_HTC_TX(target);
767
768 for (i = 0; i < NumEntries; i++, pRpt++) {
769 if (pRpt->EndpointID >= ENDPOINT_MAX) {
770 AR_DEBUG_ASSERT(false);
771 break;
772 }
773
774 pEndpoint = &target->EndPoint[pRpt->EndpointID];
775
776 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d got %d credits \n",
777 pRpt->EndpointID, pRpt->Credits));
778
779 INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1);
780 INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, pRpt->Credits);
781
782 if (FromEndpoint == pRpt->EndpointID) {
783 /* this credit report arrived on the same endpoint indicating it arrived in an RX
784 * packet */
785 INC_HTC_EP_STAT(pEndpoint, TxCreditsFromRx, pRpt->Credits);
786 INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromRx, 1);
787 } else if (FromEndpoint == ENDPOINT_0) {
788 /* this credit arrived on endpoint 0 as a NULL message */
789 INC_HTC_EP_STAT(pEndpoint, TxCreditsFromEp0, pRpt->Credits);
790 INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromEp0, 1);
791 } else {
792 /* arrived on another endpoint */
793 INC_HTC_EP_STAT(pEndpoint, TxCreditsFromOther, pRpt->Credits);
794 INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1);
795 }
796
797 if (ENDPOINT_0 == pRpt->EndpointID) {
798 /* always give endpoint 0 credits back */
799 pEndpoint->CreditDist.TxCredits += pRpt->Credits;
800 } else {
801 /* for all other endpoints, update credits to distribute, the distribution function
802 * will handle giving out credits back to the endpoints */
803 pEndpoint->CreditDist.TxCreditsToDist += pRpt->Credits;
804 /* flag that we have to do the distribution */
805 doDist = true;
806 }
807
808 /* refresh tx depth for distribution function that will recover these credits
809 * NOTE: this is only valid when there are credits to recover! */
810 pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
811
812 totalCredits += pRpt->Credits;
813 }
814
815 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Report indicated %d credits to distribute \n", totalCredits));
816
817 if (doDist) {
818 /* this was a credit return based on a completed send operations
819 * note, this is done with the lock held */
820 DO_DISTRIBUTION(target,
821 HTC_CREDIT_DIST_SEND_COMPLETE,
822 "Send Complete",
823 target->EpCreditDistributionListHead->pNext);
824 }
825
826 UNLOCK_HTC_TX(target);
827
828 if (totalCredits) {
829 HTCCheckEndpointTxQueues(target);
830 }
831
832 AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCProcessCreditRpt \n"));
833}
834
835/* flush endpoint TX queue */
836static void HTCFlushEndpointTX(struct htc_target *target, struct htc_endpoint *pEndpoint, HTC_TX_TAG Tag)
837{
838 struct htc_packet *pPacket;
839 struct htc_packet_queue discardQueue;
840 struct htc_packet_queue container;
841
842 /* initialize the discard queue */
843 INIT_HTC_PACKET_QUEUE(&discardQueue);
844
845 LOCK_HTC_TX(target);
846
847 /* interate from the front of the TX queue and flush out packets */
848 ITERATE_OVER_LIST_ALLOW_REMOVE(&pEndpoint->TxQueue.QueueHead, pPacket, struct htc_packet, ListLink) {
849
850 /* check for removal */
851 if ((HTC_TX_PACKET_TAG_ALL == Tag) || (Tag == pPacket->PktInfo.AsTx.Tag)) {
852 /* remove from queue */
853 HTC_PACKET_REMOVE(&pEndpoint->TxQueue, pPacket);
854 /* add it to the discard pile */
855 HTC_PACKET_ENQUEUE(&discardQueue, pPacket);
856 }
857
858 } ITERATE_END;
859
860 UNLOCK_HTC_TX(target);
861
862 /* empty the discard queue */
863 while (1) {
864 pPacket = HTC_PACKET_DEQUEUE(&discardQueue);
865 if (NULL == pPacket) {
866 break;
867 }
868 pPacket->Status = A_ECANCELED;
869 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" Flushing TX packet:0x%lX, length:%d, ep:%d tag:0x%X \n",
870 (unsigned long)pPacket, pPacket->ActualLength, pPacket->Endpoint, pPacket->PktInfo.AsTx.Tag));
871 INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
872 DO_EP_TX_COMPLETION(pEndpoint,&container);
873 }
874
875}
876
877void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist)
878{
879 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("--- EP : %d ServiceID: 0x%X --------------\n",
880 pEPDist->Endpoint, pEPDist->ServiceID));
881 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" this:0x%lX next:0x%lX prev:0x%lX\n",
882 (unsigned long)pEPDist, (unsigned long)pEPDist->pNext, (unsigned long)pEPDist->pPrev));
883 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" DistFlags : 0x%X \n", pEPDist->DistFlags));
884 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsNorm : %d \n", pEPDist->TxCreditsNorm));
885 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsMin : %d \n", pEPDist->TxCreditsMin));
886 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCredits : %d \n", pEPDist->TxCredits));
887 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsAssigned : %d \n", pEPDist->TxCreditsAssigned));
888 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsSeek : %d \n", pEPDist->TxCreditsSeek));
889 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditSize : %d \n", pEPDist->TxCreditSize));
890 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsPerMaxMsg : %d \n", pEPDist->TxCreditsPerMaxMsg));
891 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsToDist : %d \n", pEPDist->TxCreditsToDist));
892 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxQueueDepth : %d \n",
893 HTC_PACKET_QUEUE_DEPTH(&((struct htc_endpoint *)pEPDist->pHTCReserved)->TxQueue)));
894 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("----------------------------------------------------\n"));
895}
896
897void DumpCreditDistStates(struct htc_target *target)
898{
899 struct htc_endpoint_credit_dist *pEPList = target->EpCreditDistributionListHead;
900
901 while (pEPList != NULL) {
902 DumpCreditDist(pEPList);
903 pEPList = pEPList->pNext;
904 }
905
906 if (target->DistributeCredits != NULL) {
907 DO_DISTRIBUTION(target,
908 HTC_DUMP_CREDIT_STATE,
909 "Dump State",
910 NULL);
911 }
912}
913
914/* flush all send packets from all endpoint queues */
915void HTCFlushSendPkts(struct htc_target *target)
916{
917 struct htc_endpoint *pEndpoint;
918 int i;
919
920 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
921 DumpCreditDistStates(target);
922 }
923
924 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
925 pEndpoint = &target->EndPoint[i];
926 if (pEndpoint->ServiceID == 0) {
927 /* not in use.. */
928 continue;
929 }
930 HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL);
931 }
932
933
934}
935
936/* HTC API to flush an endpoint's TX queue*/
937void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag)
938{
939 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
940 struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint];
941
942 if (pEndpoint->ServiceID == 0) {
943 AR_DEBUG_ASSERT(false);
944 /* not in use.. */
945 return;
946 }
947
948 HTCFlushEndpointTX(target, pEndpoint, Tag);
949}
950
951/* HTC API to indicate activity to the credit distribution function */
952void HTCIndicateActivityChange(HTC_HANDLE HTCHandle,
953 HTC_ENDPOINT_ID Endpoint,
954 bool Active)
955{
956 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
957 struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint];
958 bool doDist = false;
959
960 if (pEndpoint->ServiceID == 0) {
961 AR_DEBUG_ASSERT(false);
962 /* not in use.. */
963 return;
964 }
965
966 LOCK_HTC_TX(target);
967
968 if (Active) {
969 if (!(pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE)) {
970 /* mark active now */
971 pEndpoint->CreditDist.DistFlags |= HTC_EP_ACTIVE;
972 doDist = true;
973 }
974 } else {
975 if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) {
976 /* mark inactive now */
977 pEndpoint->CreditDist.DistFlags &= ~HTC_EP_ACTIVE;
978 doDist = true;
979 }
980 }
981
982 if (doDist) {
983 /* indicate current Tx Queue depth to the credit distribution function */
984 pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
985 /* do distribution again based on activity change
986 * note, this is done with the lock held */
987 DO_DISTRIBUTION(target,
988 HTC_CREDIT_DIST_ACTIVITY_CHANGE,
989 "Activity Change",
990 target->EpCreditDistributionListHead->pNext);
991 }
992
993 UNLOCK_HTC_TX(target);
994
995 if (doDist && !Active) {
996 /* if a stream went inactive and this resulted in a credit distribution change,
997 * some credits may now be available for HTC packets that are stuck in
998 * HTC queues */
999 HTCCheckEndpointTxQueues(target);
1000 }
1001}
1002
1003bool HTCIsEndpointActive(HTC_HANDLE HTCHandle,
1004 HTC_ENDPOINT_ID Endpoint)
1005{
1006 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
1007 struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint];
1008
1009 if (pEndpoint->ServiceID == 0) {
1010 return false;
1011 }
1012
1013 if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) {
1014 return true;
1015 }
1016
1017 return false;
1018}
diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c
new file mode 100644
index 00000000000..c48070cbd54
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc_services.c
@@ -0,0 +1,450 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_services.c" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#include "htc_internal.h"
24
25void HTCControlTxComplete(void *Context, struct htc_packet *pPacket)
26{
27 /* not implemented
28 * we do not send control TX frames during normal runtime, only during setup */
29 AR_DEBUG_ASSERT(false);
30}
31
32 /* callback when a control message arrives on this endpoint */
33void HTCControlRecv(void *Context, struct htc_packet *pPacket)
34{
35 AR_DEBUG_ASSERT(pPacket->Endpoint == ENDPOINT_0);
36
37 if (pPacket->Status == A_ECANCELED) {
38 /* this is a flush operation, return the control packet back to the pool */
39 HTC_FREE_CONTROL_RX((struct htc_target*)Context,pPacket);
40 return;
41 }
42
43 /* the only control messages we are expecting are NULL messages (credit resports) */
44 if (pPacket->ActualLength > 0) {
45 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
46 ("HTCControlRecv, got message with length:%d \n",
47 pPacket->ActualLength + (u32)HTC_HDR_LENGTH));
48
49#ifdef ATH_DEBUG_MODULE
50 /* dump header and message */
51 DebugDumpBytes(pPacket->pBuffer - HTC_HDR_LENGTH,
52 pPacket->ActualLength + HTC_HDR_LENGTH,
53 "Unexpected ENDPOINT 0 Message");
54#endif
55 }
56
57 HTC_RECYCLE_RX_PKT((struct htc_target*)Context,pPacket,&((struct htc_target*)Context)->EndPoint[0]);
58}
59
60int HTCSendSetupComplete(struct htc_target *target)
61{
62 struct htc_packet *pSendPacket = NULL;
63 int status;
64
65 do {
66 /* allocate a packet to send to the target */
67 pSendPacket = HTC_ALLOC_CONTROL_TX(target);
68
69 if (NULL == pSendPacket) {
70 status = A_NO_MEMORY;
71 break;
72 }
73
74 if (target->HTCTargetVersion >= HTC_VERSION_2P1) {
75 HTC_SETUP_COMPLETE_EX_MSG *pSetupCompleteEx;
76 u32 setupFlags = 0;
77
78 pSetupCompleteEx = (HTC_SETUP_COMPLETE_EX_MSG *)pSendPacket->pBuffer;
79 A_MEMZERO(pSetupCompleteEx, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
80 pSetupCompleteEx->MessageID = HTC_MSG_SETUP_COMPLETE_EX_ID;
81 if (target->MaxMsgPerBundle > 0) {
82 /* host can do HTC bundling, indicate this to the target */
83 setupFlags |= HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV;
84 pSetupCompleteEx->MaxMsgsPerBundledRecv = target->MaxMsgPerBundle;
85 }
86 memcpy(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCompleteEx->SetupFlags));
87 SET_HTC_PACKET_INFO_TX(pSendPacket,
88 NULL,
89 (u8 *)pSetupCompleteEx,
90 sizeof(HTC_SETUP_COMPLETE_EX_MSG),
91 ENDPOINT_0,
92 HTC_SERVICE_TX_PACKET_TAG);
93
94 } else {
95 HTC_SETUP_COMPLETE_MSG *pSetupComplete;
96 /* assemble setup complete message */
97 pSetupComplete = (HTC_SETUP_COMPLETE_MSG *)pSendPacket->pBuffer;
98 A_MEMZERO(pSetupComplete, sizeof(HTC_SETUP_COMPLETE_MSG));
99 pSetupComplete->MessageID = HTC_MSG_SETUP_COMPLETE_ID;
100 SET_HTC_PACKET_INFO_TX(pSendPacket,
101 NULL,
102 (u8 *)pSetupComplete,
103 sizeof(HTC_SETUP_COMPLETE_MSG),
104 ENDPOINT_0,
105 HTC_SERVICE_TX_PACKET_TAG);
106 }
107
108 /* we want synchronous operation */
109 pSendPacket->Completion = NULL;
110 HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
111 /* send the message */
112 status = HTCIssueSend(target,pSendPacket);
113
114 } while (false);
115
116 if (pSendPacket != NULL) {
117 HTC_FREE_CONTROL_TX(target,pSendPacket);
118 }
119
120 return status;
121}
122
123
124int HTCConnectService(HTC_HANDLE HTCHandle,
125 struct htc_service_connect_req *pConnectReq,
126 struct htc_service_connect_resp *pConnectResp)
127{
128 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
129 int status = 0;
130 struct htc_packet *pRecvPacket = NULL;
131 struct htc_packet *pSendPacket = NULL;
132 HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg;
133 HTC_CONNECT_SERVICE_MSG *pConnectMsg;
134 HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX;
135 struct htc_endpoint *pEndpoint;
136 unsigned int maxMsgSize = 0;
137
138 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:0x%lX SvcID:0x%X \n",
139 (unsigned long)target, pConnectReq->ServiceID));
140
141 do {
142
143 AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0);
144
145 if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) {
146 /* special case for pseudo control service */
147 assignedEndpoint = ENDPOINT_0;
148 maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH;
149 } else {
150 /* allocate a packet to send to the target */
151 pSendPacket = HTC_ALLOC_CONTROL_TX(target);
152
153 if (NULL == pSendPacket) {
154 AR_DEBUG_ASSERT(false);
155 status = A_NO_MEMORY;
156 break;
157 }
158 /* assemble connect service message */
159 pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)pSendPacket->pBuffer;
160 AR_DEBUG_ASSERT(pConnectMsg != NULL);
161 A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG));
162 pConnectMsg->MessageID = HTC_MSG_CONNECT_SERVICE_ID;
163 pConnectMsg->ServiceID = pConnectReq->ServiceID;
164 pConnectMsg->ConnectionFlags = pConnectReq->ConnectionFlags;
165 /* check caller if it wants to transfer meta data */
166 if ((pConnectReq->pMetaData != NULL) &&
167 (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
168 /* copy meta data into message buffer (after header ) */
169 memcpy((u8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG),
170 pConnectReq->pMetaData,
171 pConnectReq->MetaDataLength);
172 pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength;
173 }
174
175 SET_HTC_PACKET_INFO_TX(pSendPacket,
176 NULL,
177 (u8 *)pConnectMsg,
178 sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectMsg->ServiceMetaLength,
179 ENDPOINT_0,
180 HTC_SERVICE_TX_PACKET_TAG);
181
182 /* we want synchronous operation */
183 pSendPacket->Completion = NULL;
184 HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
185 status = HTCIssueSend(target,pSendPacket);
186
187 if (status) {
188 break;
189 }
190
191 /* wait for response */
192 status = HTCWaitforControlMessage(target, &pRecvPacket);
193
194 if (status) {
195 break;
196 }
197 /* we controlled the buffer creation so it has to be properly aligned */
198 pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)pRecvPacket->pBuffer;
199
200 if ((pResponseMsg->MessageID != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) ||
201 (pRecvPacket->ActualLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) {
202 /* this message is not valid */
203 AR_DEBUG_ASSERT(false);
204 status = A_EPROTO;
205 break;
206 }
207
208 pConnectResp->ConnectRespCode = pResponseMsg->Status;
209 /* check response status */
210 if (pResponseMsg->Status != HTC_SERVICE_SUCCESS) {
211 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
212 (" Target failed service 0x%X connect request (status:%d)\n",
213 pResponseMsg->ServiceID, pResponseMsg->Status));
214 status = A_EPROTO;
215 break;
216 }
217
218 assignedEndpoint = (HTC_ENDPOINT_ID) pResponseMsg->EndpointID;
219 maxMsgSize = pResponseMsg->MaxMsgSize;
220
221 if ((pConnectResp->pMetaData != NULL) &&
222 (pResponseMsg->ServiceMetaLength > 0) &&
223 (pResponseMsg->ServiceMetaLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
224 /* caller supplied a buffer and the target responded with data */
225 int copyLength = min((int)pConnectResp->BufferLength, (int)pResponseMsg->ServiceMetaLength);
226 /* copy the meta data */
227 memcpy(pConnectResp->pMetaData,
228 ((u8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG),
229 copyLength);
230 pConnectResp->ActualLength = copyLength;
231 }
232
233 }
234
235 /* the rest of these are parameter checks so set the error status */
236 status = A_EPROTO;
237
238 if (assignedEndpoint >= ENDPOINT_MAX) {
239 AR_DEBUG_ASSERT(false);
240 break;
241 }
242
243 if (0 == maxMsgSize) {
244 AR_DEBUG_ASSERT(false);
245 break;
246 }
247
248 pEndpoint = &target->EndPoint[assignedEndpoint];
249 pEndpoint->Id = assignedEndpoint;
250 if (pEndpoint->ServiceID != 0) {
251 /* endpoint already in use! */
252 AR_DEBUG_ASSERT(false);
253 break;
254 }
255
256 /* return assigned endpoint to caller */
257 pConnectResp->Endpoint = assignedEndpoint;
258 pConnectResp->MaxMsgLength = maxMsgSize;
259
260 /* setup the endpoint */
261 pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */
262 pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth;
263 pEndpoint->MaxMsgLength = maxMsgSize;
264 /* copy all the callbacks */
265 pEndpoint->EpCallBacks = pConnectReq->EpCallbacks;
266 /* set the credit distribution info for this endpoint, this information is
267 * passed back to the credit distribution callback function */
268 pEndpoint->CreditDist.ServiceID = pConnectReq->ServiceID;
269 pEndpoint->CreditDist.pHTCReserved = pEndpoint;
270 pEndpoint->CreditDist.Endpoint = assignedEndpoint;
271 pEndpoint->CreditDist.TxCreditSize = target->TargetCreditSize;
272
273 if (pConnectReq->MaxSendMsgSize != 0) {
274 /* override TxCreditsPerMaxMsg calculation, this optimizes the credit-low indications
275 * since the host will actually issue smaller messages in the Send path */
276 if (pConnectReq->MaxSendMsgSize > maxMsgSize) {
277 /* can't be larger than the maximum the target can support */
278 AR_DEBUG_ASSERT(false);
279 break;
280 }
281 pEndpoint->CreditDist.TxCreditsPerMaxMsg = pConnectReq->MaxSendMsgSize / target->TargetCreditSize;
282 } else {
283 pEndpoint->CreditDist.TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize;
284 }
285
286 if (0 == pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
287 pEndpoint->CreditDist.TxCreditsPerMaxMsg = 1;
288 }
289
290 /* save local connection flags */
291 pEndpoint->LocalConnectionFlags = pConnectReq->LocalConnectionFlags;
292
293 status = 0;
294
295 } while (false);
296
297 if (pSendPacket != NULL) {
298 HTC_FREE_CONTROL_TX(target,pSendPacket);
299 }
300
301 if (pRecvPacket != NULL) {
302 HTC_FREE_CONTROL_RX(target,pRecvPacket);
303 }
304
305 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n"));
306
307 return status;
308}
309
310static void AddToEndpointDistList(struct htc_target *target, struct htc_endpoint_credit_dist *pEpDist)
311{
312 struct htc_endpoint_credit_dist *pCurEntry,*pLastEntry;
313
314 if (NULL == target->EpCreditDistributionListHead) {
315 target->EpCreditDistributionListHead = pEpDist;
316 pEpDist->pNext = NULL;
317 pEpDist->pPrev = NULL;
318 return;
319 }
320
321 /* queue to the end of the list, this does not have to be very
322 * fast since this list is built at startup time */
323 pCurEntry = target->EpCreditDistributionListHead;
324
325 while (pCurEntry) {
326 pLastEntry = pCurEntry;
327 pCurEntry = pCurEntry->pNext;
328 }
329
330 pLastEntry->pNext = pEpDist;
331 pEpDist->pPrev = pLastEntry;
332 pEpDist->pNext = NULL;
333}
334
335
336
337/* default credit init callback */
338static void HTCDefaultCreditInit(void *Context,
339 struct htc_endpoint_credit_dist *pEPList,
340 int TotalCredits)
341{
342 struct htc_endpoint_credit_dist *pCurEpDist;
343 int totalEps = 0;
344 int creditsPerEndpoint;
345
346 pCurEpDist = pEPList;
347 /* first run through the list and figure out how many endpoints we are dealing with */
348 while (pCurEpDist != NULL) {
349 pCurEpDist = pCurEpDist->pNext;
350 totalEps++;
351 }
352
353 /* even distribution */
354 creditsPerEndpoint = TotalCredits/totalEps;
355
356 pCurEpDist = pEPList;
357 /* run through the list and set minimum and normal credits and
358 * provide the endpoint with some credits to start */
359 while (pCurEpDist != NULL) {
360
361 if (creditsPerEndpoint < pCurEpDist->TxCreditsPerMaxMsg) {
362 /* too many endpoints and not enough credits */
363 AR_DEBUG_ASSERT(false);
364 break;
365 }
366 /* our minimum is set for at least 1 max message */
367 pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg;
368 /* this value is ignored by our credit alg, since we do
369 * not dynamically adjust credits, this is the policy of
370 * the "default" credit distribution, something simple and easy */
371 pCurEpDist->TxCreditsNorm = 0xFFFF;
372 /* give the endpoint minimum credits */
373 pCurEpDist->TxCredits = creditsPerEndpoint;
374 pCurEpDist->TxCreditsAssigned = creditsPerEndpoint;
375 pCurEpDist = pCurEpDist->pNext;
376 }
377
378}
379
380/* default credit distribution callback, NOTE, this callback holds the TX lock */
381void HTCDefaultCreditDist(void *Context,
382 struct htc_endpoint_credit_dist *pEPDistList,
383 HTC_CREDIT_DIST_REASON Reason)
384{
385 struct htc_endpoint_credit_dist *pCurEpDist;
386
387 if (Reason == HTC_CREDIT_DIST_SEND_COMPLETE) {
388 pCurEpDist = pEPDistList;
389 /* simple distribution */
390 while (pCurEpDist != NULL) {
391 if (pCurEpDist->TxCreditsToDist > 0) {
392 /* just give the endpoint back the credits */
393 pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist;
394 pCurEpDist->TxCreditsToDist = 0;
395 }
396 pCurEpDist = pCurEpDist->pNext;
397 }
398 }
399
400 /* note we do not need to handle the other reason codes as this is a very
401 * simple distribution scheme, no need to seek for more credits or handle inactivity */
402}
403
404void HTCSetCreditDistribution(HTC_HANDLE HTCHandle,
405 void *pCreditDistContext,
406 HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
407 HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
408 HTC_SERVICE_ID ServicePriorityOrder[],
409 int ListLength)
410{
411 struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
412 int i;
413 int ep;
414
415 if (CreditInitFunc != NULL) {
416 /* caller has supplied their own distribution functions */
417 target->InitCredits = CreditInitFunc;
418 AR_DEBUG_ASSERT(CreditDistFunc != NULL);
419 target->DistributeCredits = CreditDistFunc;
420 target->pCredDistContext = pCreditDistContext;
421 } else {
422 /* caller wants HTC to do distribution */
423 /* if caller wants service to handle distributions then
424 * it must set both of these to NULL! */
425 AR_DEBUG_ASSERT(CreditDistFunc == NULL);
426 target->InitCredits = HTCDefaultCreditInit;
427 target->DistributeCredits = HTCDefaultCreditDist;
428 target->pCredDistContext = target;
429 }
430
431 /* always add HTC control endpoint first, we only expose the list after the
432 * first one, this is added for TX queue checking */
433 AddToEndpointDistList(target, &target->EndPoint[ENDPOINT_0].CreditDist);
434
435 /* build the list of credit distribution structures in priority order
436 * supplied by the caller, these will follow endpoint 0 */
437 for (i = 0; i < ListLength; i++) {
438 /* match services with endpoints and add the endpoints to the distribution list
439 * in FIFO order */
440 for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
441 if (target->EndPoint[ep].ServiceID == ServicePriorityOrder[i]) {
442 /* queue this one to the list */
443 AddToEndpointDistList(target, &target->EndPoint[ep].CreditDist);
444 break;
445 }
446 }
447 AR_DEBUG_ASSERT(ep < ENDPOINT_MAX);
448 }
449
450}
diff --git a/drivers/staging/ath6kl/include/a_config.h b/drivers/staging/ath6kl/include/a_config.h
new file mode 100644
index 00000000000..f7c09319433
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_config.h
@@ -0,0 +1,31 @@
1//------------------------------------------------------------------------------
2// <copyright file="a_config.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains software configuration options that enables
22// specific software "features"
23//
24// Author(s): ="Atheros"
25//==============================================================================
26#ifndef _A_CONFIG_H_
27#define _A_CONFIG_H_
28
29#include "../os/linux/include/config_linux.h"
30
31#endif
diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h
new file mode 100644
index 00000000000..5154fcb1ca6
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_debug.h
@@ -0,0 +1,195 @@
1//------------------------------------------------------------------------------
2// <copyright file="a_debug.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _A_DEBUG_H_
24#define _A_DEBUG_H_
25
26#ifdef __cplusplus
27extern "C" {
28#endif /* __cplusplus */
29
30#include <a_osapi.h>
31
32 /* standard debug print masks bits 0..7 */
33#define ATH_DEBUG_ERR (1 << 0) /* errors */
34#define ATH_DEBUG_WARN (1 << 1) /* warnings */
35#define ATH_DEBUG_INFO (1 << 2) /* informational (module startup info) */
36#define ATH_DEBUG_TRC (1 << 3) /* generic function call tracing */
37#define ATH_DEBUG_RSVD1 (1 << 4)
38#define ATH_DEBUG_RSVD2 (1 << 5)
39#define ATH_DEBUG_RSVD3 (1 << 6)
40#define ATH_DEBUG_RSVD4 (1 << 7)
41
42#define ATH_DEBUG_MASK_DEFAULTS (ATH_DEBUG_ERR | ATH_DEBUG_WARN)
43#define ATH_DEBUG_ANY 0xFFFF
44
45 /* other aliases used throughout */
46#define ATH_DEBUG_ERROR ATH_DEBUG_ERR
47#define ATH_LOG_ERR ATH_DEBUG_ERR
48#define ATH_LOG_INF ATH_DEBUG_INFO
49#define ATH_LOG_TRC ATH_DEBUG_TRC
50#define ATH_DEBUG_TRACE ATH_DEBUG_TRC
51#define ATH_DEBUG_INIT ATH_DEBUG_INFO
52
53 /* bits 8..31 are module-specific masks */
54#define ATH_DEBUG_MODULE_MASK_SHIFT 8
55
56 /* macro to make a module-specific masks */
57#define ATH_DEBUG_MAKE_MODULE_MASK(index) (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index)))
58
59void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription);
60
61/* Debug support on a per-module basis
62 *
63 * Usage:
64 *
65 * Each module can utilize it's own debug mask variable. A set of commonly used
66 * masks are provided (ERRORS, WARNINGS, TRACE etc..). It is up to each module
67 * to define module-specific masks using the macros above.
68 *
69 * Each module defines a single debug mask variable debug_XXX where the "name" of the module is
70 * common to all C-files within that module. This requires every C-file that includes a_debug.h
71 * to define the module name in that file.
72 *
73 * Example:
74 *
75 * #define ATH_MODULE_NAME htc
76 * #include "a_debug.h"
77 *
78 * This will define a debug mask structure called debug_htc and all debug macros will reference this
79 * variable.
80 *
81 * A module can define module-specific bit masks using the ATH_DEBUG_MAKE_MODULE_MASK() macro:
82 *
83 * #define ATH_DEBUG_MY_MASK1 ATH_DEBUG_MAKE_MODULE_MASK(0)
84 * #define ATH_DEBUG_MY_MASK2 ATH_DEBUG_MAKE_MODULE_MASK(1)
85 *
86 * The instantiation of the debug structure should be made by the module. When a module is
87 * instantiated, the module can set a description string, a default mask and an array of description
88 * entries containing information on each module-defined debug mask.
89 * NOTE: The instantiation is statically allocated, only one instance can exist per module.
90 *
91 * Example:
92 *
93 *
94 * #define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0)
95 *
96 * #ifdef DEBUG
97 * static struct ath_debug_mask_description bmi_debug_desc[] = {
98 * { ATH_DEBUG_BMI , "BMI Tracing"}, <== description of the module specific mask
99 * };
100 *
101 * ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
102 * "bmi" <== module name
103 * "Boot Manager Interface", <== description of module
104 * ATH_DEBUG_MASK_DEFAULTS, <== defaults
105 * ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
106 * bmi_debug_desc);
107 *
108 * #endif
109 *
110 * A module can optionally register it's debug module information in order for other tools to change the
111 * bit mask at runtime. A module can call A_REGISTER_MODULE_DEBUG_INFO() in it's module
112 * init code. This macro can be called multiple times without consequence. The debug info maintains
113 * state to indicate whether the information was previously registered.
114 *
115 * */
116
117#define ATH_DEBUG_MAX_MASK_DESC_LENGTH 32
118#define ATH_DEBUG_MAX_MOD_DESC_LENGTH 64
119
120struct ath_debug_mask_description {
121 u32 Mask;
122 char Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH];
123};
124
125#define ATH_DEBUG_INFO_FLAGS_REGISTERED (1 << 0)
126
127typedef struct _ATH_DEBUG_MODULE_DBG_INFO{
128 struct _ATH_DEBUG_MODULE_DBG_INFO *pNext;
129 char ModuleName[16];
130 char ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH];
131 u32 Flags;
132 u32 CurrentMask;
133 int MaxDescriptions;
134 struct ath_debug_mask_description *pMaskDescriptions; /* pointer to array of descriptions */
135} ATH_DEBUG_MODULE_DBG_INFO;
136
137#define ATH_DEBUG_DESCRIPTION_COUNT(d) (int)((sizeof((d))) / (sizeof(struct ath_debug_mask_description)))
138
139#define GET_ATH_MODULE_DEBUG_VAR_NAME(s) _XGET_ATH_MODULE_NAME_DEBUG_(s)
140#define GET_ATH_MODULE_DEBUG_VAR_MASK(s) _XGET_ATH_MODULE_NAME_DEBUG_(s).CurrentMask
141#define _XGET_ATH_MODULE_NAME_DEBUG_(s) debug_ ## s
142
143#ifdef ATH_DEBUG_MODULE
144
145 /* for source files that will instantiate the debug variables */
146#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions) \
147ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s) = \
148 {NULL,(name),(moddesc),0,(initmask),count,(descriptions)}
149
150#ifdef ATH_MODULE_NAME
151extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(ATH_MODULE_NAME);
152#define AR_DEBUG_LVL_CHECK(lvl) (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (lvl))
153#endif /* ATH_MODULE_NAME */
154
155#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl) GET_ATH_MODULE_DEBUG_VAR_MASK(s) = (lvl)
156
157#define ATH_DEBUG_DECLARE_EXTERN(s) \
158 extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s)
159
160#define AR_DEBUG_PRINTBUF(buffer, length, desc) DebugDumpBytes(buffer,length,desc)
161
162
163#define AR_DEBUG_ASSERT A_ASSERT
164
165void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo);
166void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo);
167#define A_DUMP_MODULE_DEBUG_INFO(s) a_dump_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s)))
168#define A_REGISTER_MODULE_DEBUG_INFO(s) a_register_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s)))
169
170#else /* !ATH_DEBUG_MODULE */
171 /* NON ATH_DEBUG_MODULE */
172#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions)
173#define AR_DEBUG_LVL_CHECK(lvl) 0
174#define AR_DEBUG_PRINTBUF(buffer, length, desc)
175#define AR_DEBUG_ASSERT(test)
176#define ATH_DEBUG_DECLARE_EXTERN(s)
177#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl)
178#define A_DUMP_MODULE_DEBUG_INFO(s)
179#define A_REGISTER_MODULE_DEBUG_INFO(s)
180
181#endif
182
183int a_get_module_mask(char *module_name, u32 *pMask);
184int a_set_module_mask(char *module_name, u32 Mask);
185void a_dump_module_debug_info_by_name(char *module_name);
186void a_module_debug_support_init(void);
187void a_module_debug_support_cleanup(void);
188
189#include "../os/linux/include/debug_linux.h"
190
191#ifdef __cplusplus
192}
193#endif /* __cplusplus */
194
195#endif
diff --git a/drivers/staging/ath6kl/include/a_drv.h b/drivers/staging/ath6kl/include/a_drv.h
new file mode 100644
index 00000000000..1548604e846
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_drv.h
@@ -0,0 +1,32 @@
1//------------------------------------------------------------------------------
2// <copyright file="a_drv.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains the definitions of the basic atheros data types.
22// It is used to map the data types in atheros files to a platform specific
23// type.
24//
25// Author(s): ="Atheros"
26//==============================================================================
27#ifndef _A_DRV_H_
28#define _A_DRV_H_
29
30#include "../os/linux/include/athdrv_linux.h"
31
32#endif /* _ADRV_H_ */
diff --git a/drivers/staging/ath6kl/include/a_drv_api.h b/drivers/staging/ath6kl/include/a_drv_api.h
new file mode 100644
index 00000000000..a40d97a84ff
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_drv_api.h
@@ -0,0 +1,204 @@
1//------------------------------------------------------------------------------
2// <copyright file="a_drv_api.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _A_DRV_API_H_
24#define _A_DRV_API_H_
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/****************************************************************************/
31/****************************************************************************/
32/** **/
33/** WMI related hooks **/
34/** **/
35/****************************************************************************/
36/****************************************************************************/
37
38#include <ar6000_api.h>
39
40#define A_WMI_CHANNELLIST_RX(devt, numChan, chanList) \
41 ar6000_channelList_rx((devt), (numChan), (chanList))
42
43#define A_WMI_SET_NUMDATAENDPTS(devt, num) \
44 ar6000_set_numdataendpts((devt), (num))
45
46#define A_WMI_CONTROL_TX(devt, osbuf, streamID) \
47 ar6000_control_tx((devt), (osbuf), (streamID))
48
49#define A_WMI_TARGETSTATS_EVENT(devt, pStats, len) \
50 ar6000_targetStats_event((devt), (pStats), (len))
51
52#define A_WMI_SCANCOMPLETE_EVENT(devt, status) \
53 ar6000_scanComplete_event((devt), (status))
54
55#ifdef CONFIG_HOST_DSET_SUPPORT
56
57#define A_WMI_DSET_DATA_REQ(devt, access_cookie, offset, length, targ_buf, targ_reply_fn, targ_reply_arg) \
58 ar6000_dset_data_req((devt), (access_cookie), (offset), (length), (targ_buf), (targ_reply_fn), (targ_reply_arg))
59
60#define A_WMI_DSET_CLOSE(devt, access_cookie) \
61 ar6000_dset_close((devt), (access_cookie))
62
63#endif
64
65#define A_WMI_DSET_OPEN_REQ(devt, id, targ_handle, targ_reply_fn, targ_reply_arg) \
66 ar6000_dset_open_req((devt), (id), (targ_handle), (targ_reply_fn), (targ_reply_arg))
67
68#define A_WMI_CONNECT_EVENT(devt, channel, bssid, listenInterval, beaconInterval, networkType, beaconIeLen, assocReqLen, assocRespLen, assocInfo) \
69 ar6000_connect_event((devt), (channel), (bssid), (listenInterval), (beaconInterval), (networkType), (beaconIeLen), (assocReqLen), (assocRespLen), (assocInfo))
70
71#define A_WMI_PSPOLL_EVENT(devt, aid)\
72 ar6000_pspoll_event((devt),(aid))
73
74#define A_WMI_DTIMEXPIRY_EVENT(devt)\
75 ar6000_dtimexpiry_event((devt))
76
77#ifdef WAPI_ENABLE
78#define A_WMI_WAPI_REKEY_EVENT(devt, type, mac)\
79 ap_wapi_rekey_event((devt),(type),(mac))
80#endif
81
82#define A_WMI_REGDOMAIN_EVENT(devt, regCode) \
83 ar6000_regDomain_event((devt), (regCode))
84
85#define A_WMI_NEIGHBORREPORT_EVENT(devt, numAps, info) \
86 ar6000_neighborReport_event((devt), (numAps), (info))
87
88#define A_WMI_DISCONNECT_EVENT(devt, reason, bssid, assocRespLen, assocInfo, protocolReasonStatus) \
89 ar6000_disconnect_event((devt), (reason), (bssid), (assocRespLen), (assocInfo), (protocolReasonStatus))
90
91#define A_WMI_TKIP_MICERR_EVENT(devt, keyid, ismcast) \
92 ar6000_tkip_micerr_event((devt), (keyid), (ismcast))
93
94#define A_WMI_BITRATE_RX(devt, rateKbps) \
95 ar6000_bitrate_rx((devt), (rateKbps))
96
97#define A_WMI_TXPWR_RX(devt, txPwr) \
98 ar6000_txPwr_rx((devt), (txPwr))
99
100#define A_WMI_READY_EVENT(devt, datap, phyCap, sw_ver, abi_ver) \
101 ar6000_ready_event((devt), (datap), (phyCap), (sw_ver), (abi_ver))
102
103#define A_WMI_DBGLOG_INIT_DONE(ar) \
104 ar6000_dbglog_init_done(ar);
105
106#define A_WMI_RSSI_THRESHOLD_EVENT(devt, newThreshold, rssi) \
107 ar6000_rssiThreshold_event((devt), (newThreshold), (rssi))
108
109#define A_WMI_REPORT_ERROR_EVENT(devt, errorVal) \
110 ar6000_reportError_event((devt), (errorVal))
111
112#define A_WMI_ROAM_TABLE_EVENT(devt, pTbl) \
113 ar6000_roam_tbl_event((devt), (pTbl))
114
115#define A_WMI_ROAM_DATA_EVENT(devt, p) \
116 ar6000_roam_data_event((devt), (p))
117
118#define A_WMI_WOW_LIST_EVENT(devt, num_filters, wow_filters) \
119 ar6000_wow_list_event((devt), (num_filters), (wow_filters))
120
121#define A_WMI_CAC_EVENT(devt, ac, cac_indication, statusCode, tspecSuggestion) \
122 ar6000_cac_event((devt), (ac), (cac_indication), (statusCode), (tspecSuggestion))
123
124#define A_WMI_CHANNEL_CHANGE_EVENT(devt, oldChannel, newChannel) \
125 ar6000_channel_change_event((devt), (oldChannel), (newChannel))
126
127#define A_WMI_PMKID_LIST_EVENT(devt, num_pmkid, pmkid_list, bssid_list) \
128 ar6000_pmkid_list_event((devt), (num_pmkid), (pmkid_list), (bssid_list))
129
130#define A_WMI_PEER_EVENT(devt, eventCode, bssid) \
131 ar6000_peer_event ((devt), (eventCode), (bssid))
132
133#ifdef CONFIG_HOST_TCMD_SUPPORT
134#define A_WMI_TCMD_RX_REPORT_EVENT(devt, results, len) \
135 ar6000_tcmd_rx_report_event((devt), (results), (len))
136#endif
137
138#define A_WMI_HBCHALLENGERESP_EVENT(devt, cookie, source) \
139 ar6000_hbChallengeResp_event((devt), (cookie), (source))
140
141#define A_WMI_TX_RETRY_ERR_EVENT(devt) \
142 ar6000_tx_retry_err_event((devt))
143
144#define A_WMI_SNR_THRESHOLD_EVENT_RX(devt, newThreshold, snr) \
145 ar6000_snrThresholdEvent_rx((devt), (newThreshold), (snr))
146
147#define A_WMI_LQ_THRESHOLD_EVENT_RX(devt, range, lqVal) \
148 ar6000_lqThresholdEvent_rx((devt), (range), (lqVal))
149
150#define A_WMI_RATEMASK_RX(devt, ratemask) \
151 ar6000_ratemask_rx((devt), (ratemask))
152
153#define A_WMI_KEEPALIVE_RX(devt, configured) \
154 ar6000_keepalive_rx((devt), (configured))
155
156#define A_WMI_BSSINFO_EVENT_RX(ar, datp, len) \
157 ar6000_bssInfo_event_rx((ar), (datap), (len))
158
159#define A_WMI_DBGLOG_EVENT(ar, dropped, buffer, length) \
160 ar6000_dbglog_event((ar), (dropped), (buffer), (length));
161
162#define A_WMI_STREAM_TX_ACTIVE(devt,trafficClass) \
163 ar6000_indicate_tx_activity((devt),(trafficClass), true)
164
165#define A_WMI_STREAM_TX_INACTIVE(devt,trafficClass) \
166 ar6000_indicate_tx_activity((devt),(trafficClass), false)
167#define A_WMI_Ac2EndpointID(devht, ac)\
168 ar6000_ac2_endpoint_id((devht), (ac))
169
170#define A_WMI_AGGR_RECV_ADDBA_REQ_EVT(devt, cmd)\
171 ar6000_aggr_rcv_addba_req_evt((devt), (cmd))
172#define A_WMI_AGGR_RECV_ADDBA_RESP_EVT(devt, cmd)\
173 ar6000_aggr_rcv_addba_resp_evt((devt), (cmd))
174#define A_WMI_AGGR_RECV_DELBA_REQ_EVT(devt, cmd)\
175 ar6000_aggr_rcv_delba_req_evt((devt), (cmd))
176#define A_WMI_HCI_EVENT_EVT(devt, cmd)\
177 ar6000_hci_event_rcv_evt((devt), (cmd))
178
179#define A_WMI_Endpoint2Ac(devt, ep) \
180 ar6000_endpoint_id2_ac((devt), (ep))
181
182#define A_WMI_BTCOEX_CONFIG_EVENT(devt, evt, len)\
183 ar6000_btcoex_config_event((devt), (evt), (len))
184
185#define A_WMI_BTCOEX_STATS_EVENT(devt, datap, len)\
186 ar6000_btcoex_stats_event((devt), (datap), (len))
187
188/****************************************************************************/
189/****************************************************************************/
190/** **/
191/** HTC related hooks **/
192/** **/
193/****************************************************************************/
194/****************************************************************************/
195
196#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
197#define A_WMI_PROF_COUNT_RX(addr, count) prof_count_rx((addr), (count))
198#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
199
200#ifdef __cplusplus
201}
202#endif
203
204#endif
diff --git a/drivers/staging/ath6kl/include/a_osapi.h b/drivers/staging/ath6kl/include/a_osapi.h
new file mode 100644
index 00000000000..fd7ae0d612c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_osapi.h
@@ -0,0 +1,32 @@
1//------------------------------------------------------------------------------
2// <copyright file="a_osapi.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains the definitions of the basic atheros data types.
22// It is used to map the data types in atheros files to a platform specific
23// type.
24//
25// Author(s): ="Atheros"
26//==============================================================================
27#ifndef _A_OSAPI_H_
28#define _A_OSAPI_H_
29
30#include "../os/linux/include/osapi_linux.h"
31
32#endif /* _OSAPI_H_ */
diff --git a/drivers/staging/ath6kl/include/aggr_recv_api.h b/drivers/staging/ath6kl/include/aggr_recv_api.h
new file mode 100644
index 00000000000..5ead58d5feb
--- /dev/null
+++ b/drivers/staging/ath6kl/include/aggr_recv_api.h
@@ -0,0 +1,140 @@
1/*
2 *
3 * Copyright (c) 2004-2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7//
8// Permission to use, copy, modify, and/or distribute this software for any
9// purpose with or without fee is hereby granted, provided that the above
10// copyright notice and this permission notice appear in all copies.
11//
12// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19//
20//
21 *
22 */
23
24#ifndef __AGGR_RECV_API_H__
25#define __AGGR_RECV_API_H__
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31typedef void (* RX_CALLBACK)(void * dev, void *osbuf);
32
33typedef void (* ALLOC_NETBUFS)(A_NETBUF_QUEUE_T *q, u16 num);
34
35/*
36 * aggr_init:
37 * Initialises the data structures, allocates data queues and
38 * os buffers. Netbuf allocator is the input param, used by the
39 * aggr module for allocation of NETBUFs from driver context.
40 * These NETBUFs are used for AMSDU processing.
41 * Returns the context for the aggr module.
42 */
43void *
44aggr_init(ALLOC_NETBUFS netbuf_allocator);
45
46
47/*
48 * aggr_register_rx_dispatcher:
49 * Registers OS call back function to deliver the
50 * frames to OS. This is generally the topmost layer of
51 * the driver context, after which the frames go to
52 * IP stack via the call back function.
53 * This dispatcher is active only when aggregation is ON.
54 */
55void
56aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn);
57
58
59/*
60 * aggr_process_bar:
61 * When target receives BAR, it communicates to host driver
62 * for modifying window parameters. Target indicates this via the
63 * event: WMI_ADDBA_REQ_EVENTID. Host will dequeue all frames
64 * up to the indicated sequence number.
65 */
66void
67aggr_process_bar(void *cntxt, u8 tid, u16 seq_no);
68
69
70/*
71 * aggr_recv_addba_req_evt:
72 * This event is to initiate/modify the receive side window.
73 * Target will send WMI_ADDBA_REQ_EVENTID event to host - to setup
74 * recv re-ordering queues. Target will negotiate ADDBA with peer,
75 * and indicate via this event after successfully completing the
76 * negotiation. This happens in two situations:
77 * 1. Initial setup of aggregation
78 * 2. Renegotiation of current recv window.
79 * Window size for re-ordering is limited by target buffer
80 * space, which is reflected in win_sz.
81 * (Re)Start the periodic timer to deliver long standing frames,
82 * in hold_q to OS.
83 */
84void
85aggr_recv_addba_req_evt(void * cntxt, u8 tid, u16 seq_no, u8 win_sz);
86
87
88/*
89 * aggr_recv_delba_req_evt:
90 * Target indicates deletion of a BA window for a tid via the
91 * WMI_DELBA_EVENTID. Host would deliver all the frames in the
92 * hold_q, reset tid config and disable the periodic timer, if
93 * aggr is not enabled on any tid.
94 */
95void
96aggr_recv_delba_req_evt(void * cntxt, u8 tid);
97
98
99
100/*
101 * aggr_process_recv_frm:
102 * Called only for data frames. When aggr is ON for a tid, the buffer
103 * is always consumed, and osbuf would be NULL. For a non-aggr case,
104 * osbuf is not modified.
105 * AMSDU frames are consumed and are later freed. They are sliced and
106 * diced to individual frames and dispatched to stack.
107 * After consuming a osbuf(when aggr is ON), a previously registered
108 * callback may be called to deliver frames in order.
109 */
110void
111aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf);
112
113
114/*
115 * aggr_module_destroy:
116 * Frees up all the queues and frames in them. Releases the cntxt to OS.
117 */
118void
119aggr_module_destroy(void *cntxt);
120
121/*
122 * Dumps the aggregation stats
123 */
124void
125aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf);
126
127/*
128 * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate
129 * hold Q state. Examples include when a Connect event or disconnect event is
130 * received.
131 */
132void
133aggr_reset_state(void *cntxt);
134
135
136#ifdef __cplusplus
137}
138#endif
139
140#endif /*__AGGR_RECV_API_H__ */
diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h
new file mode 100644
index 00000000000..91bc4ee3512
--- /dev/null
+++ b/drivers/staging/ath6kl/include/ar3kconfig.h
@@ -0,0 +1,65 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22
23/* AR3K module configuration APIs for HCI-bridge operation */
24
25#ifndef AR3KCONFIG_H_
26#define AR3KCONFIG_H_
27
28#include <net/bluetooth/bluetooth.h>
29#include <net/bluetooth/hci_core.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#define AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT (1 << 0)
36#define AR3K_CONFIG_FLAG_SET_AR3K_BAUD (1 << 1)
37#define AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY (1 << 2)
38#define AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP (1 << 3)
39
40
41struct ar3k_config_info {
42 u32 Flags; /* config flags */
43 void *pHCIDev; /* HCI bridge device */
44 struct hci_transport_properties *pHCIProps; /* HCI bridge props */
45 struct hif_device *pHIFDevice; /* HIF layer device */
46
47 u32 AR3KBaudRate; /* AR3K operational baud rate */
48 u16 AR6KScale; /* AR6K UART scale value */
49 u16 AR6KStep; /* AR6K UART step value */
50 struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */
51 u32 PwrMgmtEnabled; /* TLPM enabled? */
52 u16 IdleTimeout; /* TLPM idle timeout */
53 u16 WakeupTimeout; /* TLPM wakeup timeout */
54 u8 bdaddr[6]; /* Bluetooth device address */
55};
56
57int AR3KConfigure(struct ar3k_config_info *pConfigInfo);
58
59int AR3KConfigureExit(void *config);
60
61#ifdef __cplusplus
62}
63#endif
64
65#endif /*AR3KCONFIG_H_*/
diff --git a/drivers/staging/ath6kl/include/ar6000_api.h b/drivers/staging/ath6kl/include/ar6000_api.h
new file mode 100644
index 00000000000..e9460800272
--- /dev/null
+++ b/drivers/staging/ath6kl/include/ar6000_api.h
@@ -0,0 +1,32 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6000_api.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains the API to access the OS dependent atheros host driver
22// by the WMI or WLAN generic modules.
23//
24// Author(s): ="Atheros"
25//==============================================================================
26#ifndef _AR6000_API_H_
27#define _AR6000_API_H_
28
29#include "../os/linux/include/ar6xapi_linux.h"
30
31#endif /* _AR6000_API_H */
32
diff --git a/drivers/staging/ath6kl/include/ar6000_diag.h b/drivers/staging/ath6kl/include/ar6000_diag.h
new file mode 100644
index 00000000000..739c01c53f0
--- /dev/null
+++ b/drivers/staging/ath6kl/include/ar6000_diag.h
@@ -0,0 +1,48 @@
1//------------------------------------------------------------------------------
2// <copyright file="ar6000_diag.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef AR6000_DIAG_H_
25#define AR6000_DIAG_H_
26
27
28int
29ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
30
31int
32ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
33
34int
35ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address,
36 u8 *data, u32 length);
37
38int
39ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address,
40 u8 *data, u32 length);
41
42int
43ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval);
44
45void
46ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs);
47
48#endif /*AR6000_DIAG_H_*/
diff --git a/drivers/staging/ath6kl/include/ar6kap_common.h b/drivers/staging/ath6kl/include/ar6kap_common.h
new file mode 100644
index 00000000000..532d8eba932
--- /dev/null
+++ b/drivers/staging/ath6kl/include/ar6kap_common.h
@@ -0,0 +1,44 @@
1//------------------------------------------------------------------------------
2
3// <copyright file="ar6kap_common.h" company="Atheros">
4// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//------------------------------------------------------------------------------
21
22//==============================================================================
23
24// This file contains the definitions of common AP mode data structures.
25//
26// Author(s): ="Atheros"
27//==============================================================================
28
29#ifndef _AR6KAP_COMMON_H_
30#define _AR6KAP_COMMON_H_
31/*
32 * Used with AR6000_XIOCTL_AP_GET_STA_LIST
33 */
34typedef struct {
35 u8 mac[ATH_MAC_LEN];
36 u8 aid;
37 u8 keymgmt;
38 u8 ucipher;
39 u8 auth;
40} station_t;
41typedef struct {
42 station_t sta[AP_MAX_NUM_STA];
43} ap_get_sta_t;
44#endif /* _AR6KAP_COMMON_H_ */
diff --git a/drivers/staging/ath6kl/include/athbtfilter.h b/drivers/staging/ath6kl/include/athbtfilter.h
new file mode 100644
index 00000000000..81456eea3b0
--- /dev/null
+++ b/drivers/staging/ath6kl/include/athbtfilter.h
@@ -0,0 +1,135 @@
1//------------------------------------------------------------------------------
2// <copyright file="athbtfilter.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Public Bluetooth filter APIs
22// Author(s): ="Atheros"
23//==============================================================================
24#ifndef ATHBTFILTER_H_
25#define ATHBTFILTER_H_
26
27#define ATH_DEBUG_INFO (1 << 2)
28#define ATH_DEBUG_INF ATH_DEBUG_INFO
29
30typedef enum _ATHBT_HCI_CTRL_TYPE {
31 ATHBT_HCI_COMMAND = 0,
32 ATHBT_HCI_EVENT = 1,
33} ATHBT_HCI_CTRL_TYPE;
34
35typedef enum _ATHBT_STATE_INDICATION {
36 ATH_BT_NOOP = 0,
37 ATH_BT_INQUIRY = 1,
38 ATH_BT_CONNECT = 2,
39 ATH_BT_SCO = 3,
40 ATH_BT_ACL = 4,
41 ATH_BT_A2DP = 5,
42 ATH_BT_ESCO = 6,
43 /* new states go here.. */
44
45 ATH_BT_MAX_STATE_INDICATION
46} ATHBT_STATE_INDICATION;
47
48 /* filter function for OUTGOING commands and INCOMMING events */
49typedef void (*ATHBT_FILTER_CMD_EVENTS_FN)(void *pContext, ATHBT_HCI_CTRL_TYPE Type, unsigned char *pBuffer, int Length);
50
51 /* filter function for OUTGOING data HCI packets */
52typedef void (*ATHBT_FILTER_DATA_FN)(void *pContext, unsigned char *pBuffer, int Length);
53
54typedef enum _ATHBT_STATE {
55 STATE_OFF = 0,
56 STATE_ON = 1,
57 STATE_MAX
58} ATHBT_STATE;
59
60 /* BT state indication (when filter functions are not used) */
61
62typedef void (*ATHBT_INDICATE_STATE_FN)(void *pContext, ATHBT_STATE_INDICATION Indication, ATHBT_STATE State, unsigned char LMPVersion);
63
64struct athbt_filter_instance {
65#ifdef UNDER_CE
66 WCHAR *pWlanAdapterName; /* filled in by user */
67#else
68 char *pWlanAdapterName; /* filled in by user */
69#endif /* UNDER_CE */
70 int FilterEnabled; /* filtering is enabled */
71 int Attached; /* filter library is attached */
72 void *pContext; /* private context for filter library */
73 ATHBT_FILTER_CMD_EVENTS_FN pFilterCmdEvents; /* function ptr to filter a command or event */
74 ATHBT_FILTER_DATA_FN pFilterAclDataOut; /* function ptr to filter ACL data out (to radio) */
75 ATHBT_FILTER_DATA_FN pFilterAclDataIn; /* function ptr to filter ACL data in (from radio) */
76 ATHBT_INDICATE_STATE_FN pIndicateState; /* function ptr to indicate a state */
77}; /* XXX: unused ? */
78
79
80/* API MACROS */
81
82#define AthBtFilterHciCommand(instance,packet,length) \
83 if ((instance)->FilterEnabled) { \
84 (instance)->pFilterCmdEvents((instance)->pContext, \
85 ATHBT_HCI_COMMAND, \
86 (unsigned char *)(packet), \
87 (length)); \
88 }
89
90#define AthBtFilterHciEvent(instance,packet,length) \
91 if ((instance)->FilterEnabled) { \
92 (instance)->pFilterCmdEvents((instance)->pContext, \
93 ATHBT_HCI_EVENT, \
94 (unsigned char *)(packet), \
95 (length)); \
96 }
97
98#define AthBtFilterHciAclDataOut(instance,packet,length) \
99 if ((instance)->FilterEnabled) { \
100 (instance)->pFilterAclDataOut((instance)->pContext, \
101 (unsigned char *)(packet), \
102 (length)); \
103 }
104
105#define AthBtFilterHciAclDataIn(instance,packet,length) \
106 if ((instance)->FilterEnabled) { \
107 (instance)->pFilterAclDataIn((instance)->pContext, \
108 (unsigned char *)(packet), \
109 (length)); \
110 }
111
112/* if filtering is not desired, the application can indicate the state directly using this
113 * macro:
114 */
115#define AthBtIndicateState(instance,indication,state) \
116 if ((instance)->FilterEnabled) { \
117 (instance)->pIndicateState((instance)->pContext, \
118 (indication), \
119 (state), \
120 0); \
121 }
122
123#ifdef __cplusplus
124extern "C" {
125#endif
126
127/* API prototypes */
128int AthBtFilter_Attach(ATH_BT_FILTER_INSTANCE *pInstance, unsigned int flags);
129void AthBtFilter_Detach(ATH_BT_FILTER_INSTANCE *pInstance);
130
131#ifdef __cplusplus
132}
133#endif
134
135#endif /*ATHBTFILTER_H_*/
diff --git a/drivers/staging/ath6kl/include/bmi.h b/drivers/staging/ath6kl/include/bmi.h
new file mode 100644
index 00000000000..d3227f77fa5
--- /dev/null
+++ b/drivers/staging/ath6kl/include/bmi.h
@@ -0,0 +1,134 @@
1//------------------------------------------------------------------------------
2// <copyright file="bmi.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// BMI declarations and prototypes
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _BMI_H_
26#define _BMI_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* Header files */
33#include "a_config.h"
34#include "athdefs.h"
35#include "hif.h"
36#include "a_osapi.h"
37#include "bmi_msg.h"
38
39void
40BMIInit(void);
41
42void
43BMICleanup(void);
44
45int
46BMIDone(struct hif_device *device);
47
48int
49BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info);
50
51int
52BMIReadMemory(struct hif_device *device,
53 u32 address,
54 u8 *buffer,
55 u32 length);
56
57int
58BMIWriteMemory(struct hif_device *device,
59 u32 address,
60 u8 *buffer,
61 u32 length);
62
63int
64BMIExecute(struct hif_device *device,
65 u32 address,
66 u32 *param);
67
68int
69BMISetAppStart(struct hif_device *device,
70 u32 address);
71
72int
73BMIReadSOCRegister(struct hif_device *device,
74 u32 address,
75 u32 *param);
76
77int
78BMIWriteSOCRegister(struct hif_device *device,
79 u32 address,
80 u32 param);
81
82int
83BMIrompatchInstall(struct hif_device *device,
84 u32 ROM_addr,
85 u32 RAM_addr,
86 u32 nbytes,
87 u32 do_activate,
88 u32 *patch_id);
89
90int
91BMIrompatchUninstall(struct hif_device *device,
92 u32 rompatch_id);
93
94int
95BMIrompatchActivate(struct hif_device *device,
96 u32 rompatch_count,
97 u32 *rompatch_list);
98
99int
100BMIrompatchDeactivate(struct hif_device *device,
101 u32 rompatch_count,
102 u32 *rompatch_list);
103
104int
105BMILZStreamStart(struct hif_device *device,
106 u32 address);
107
108int
109BMILZData(struct hif_device *device,
110 u8 *buffer,
111 u32 length);
112
113int
114BMIFastDownload(struct hif_device *device,
115 u32 address,
116 u8 *buffer,
117 u32 length);
118
119int
120BMIRawWrite(struct hif_device *device,
121 u8 *buffer,
122 u32 length);
123
124int
125BMIRawRead(struct hif_device *device,
126 u8 *buffer,
127 u32 length,
128 bool want_timeout);
129
130#ifdef __cplusplus
131}
132#endif
133
134#endif /* _BMI_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h b/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h
new file mode 100644
index 00000000000..5407e05d9b0
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h
@@ -0,0 +1,52 @@
1//------------------------------------------------------------------------------
2// <copyright file="AR6K_version.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#define __VER_MAJOR_ 3
25#define __VER_MINOR_ 0
26#define __VER_PATCH_ 0
27
28/* The makear6ksdk script (used for release builds) modifies the following line. */
29#define __BUILD_NUMBER_ 233
30
31
32/* Format of the version number. */
33#define VER_MAJOR_BIT_OFFSET 28
34#define VER_MINOR_BIT_OFFSET 24
35#define VER_PATCH_BIT_OFFSET 16
36#define VER_BUILD_NUM_BIT_OFFSET 0
37
38
39/*
40 * The version has the following format:
41 * Bits 28-31: Major version
42 * Bits 24-27: Minor version
43 * Bits 16-23: Patch version
44 * Bits 0-15: Build number (automatically generated during build process )
45 * E.g. Build 1.1.3.7 would be represented as 0x11030007.
46 *
47 * DO NOT split the following macro into multiple lines as this may confuse the build scripts.
48 */
49#define AR6K_SW_VERSION ( ( __VER_MAJOR_ << VER_MAJOR_BIT_OFFSET ) + ( __VER_MINOR_ << VER_MINOR_BIT_OFFSET ) + ( __VER_PATCH_ << VER_PATCH_BIT_OFFSET ) + ( __BUILD_NUMBER_ << VER_BUILD_NUM_BIT_OFFSET ) )
50
51/* ABI Version. Reflects the version of binary interface exposed by AR6K target firmware. Needs to be incremented by 1 for any change in the firmware that requires upgrade of the driver on the host side for the change to work correctly */
52#define AR6K_ABI_VERSION 1
diff --git a/drivers/staging/ath6kl/include/common/AR6002/addrs.h b/drivers/staging/ath6kl/include/common/AR6002/addrs.h
new file mode 100644
index 00000000000..bbf8d42828c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/addrs.h
@@ -0,0 +1,90 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//
19// Author(s): ="Atheros"
20//------------------------------------------------------------------------------
21
22#ifndef __ADDRS_H__
23#define __ADDRS_H__
24
25/*
26 * Special AR6002 Addresses that may be needed by special
27 * applications (e.g. ART) on the Host as well as Target.
28 */
29
30#if defined(AR6002_REV2)
31#define AR6K_RAM_START 0x00500000
32#define TARG_RAM_OFFSET(vaddr) ((u32)(vaddr) & 0xfffff)
33#define TARG_RAM_SZ (184*1024)
34#define TARG_ROM_SZ (80*1024)
35#endif
36#if defined(AR6002_REV4) || defined(AR6003)
37#define AR6K_RAM_START 0x00540000
38#define TARG_RAM_OFFSET(vaddr) (((u32)(vaddr) & 0xfffff) - 0x40000)
39#define TARG_RAM_SZ (256*1024)
40#define TARG_ROM_SZ (256*1024)
41#endif
42
43#define AR6002_BOARD_DATA_SZ 768
44#define AR6002_BOARD_EXT_DATA_SZ 0
45#define AR6003_BOARD_DATA_SZ 1024
46#define AR6003_BOARD_EXT_DATA_SZ 768
47
48#define AR6K_RAM_ADDR(byte_offset) (AR6K_RAM_START+(byte_offset))
49#define TARG_RAM_ADDRS(byte_offset) AR6K_RAM_ADDR(byte_offset)
50
51#define AR6K_ROM_START 0x004e0000
52#define TARG_ROM_OFFSET(vaddr) (((u32)(vaddr) & 0x1fffff) - 0xe0000)
53#define AR6K_ROM_ADDR(byte_offset) (AR6K_ROM_START+(byte_offset))
54#define TARG_ROM_ADDRS(byte_offset) AR6K_ROM_ADDR(byte_offset)
55
56/*
57 * At this ROM address is a pointer to the start of the ROM DataSet Index.
58 * If there are no ROM DataSets, there's a 0 at this address.
59 */
60#define ROM_DATASET_INDEX_ADDR (TARG_ROM_ADDRS(TARG_ROM_SZ)-8)
61#define ROM_MBIST_CKSUM_ADDR (TARG_ROM_ADDRS(TARG_ROM_SZ)-4)
62
63/*
64 * The API A_BOARD_DATA_ADDR() is the proper way to get a read pointer to
65 * board data.
66 */
67
68/* Size of Board Data, in bytes */
69#if defined(AR6002_REV4) || defined(AR6003)
70#define BOARD_DATA_SZ AR6003_BOARD_DATA_SZ
71#else
72#define BOARD_DATA_SZ AR6002_BOARD_DATA_SZ
73#endif
74
75
76/*
77 * Constants used by ASM code to access fields of host_interest_s,
78 * which is at a fixed location in RAM.
79 */
80#if defined(AR6002_REV4) || defined(AR6003)
81#define HOST_INTEREST_FLASH_IS_PRESENT_ADDR (AR6K_RAM_START + 0x60c)
82#else
83#define HOST_INTEREST_FLASH_IS_PRESENT_ADDR (AR6K_RAM_START + 0x40c)
84#endif
85#define FLASH_IS_PRESENT_TARGADDR HOST_INTEREST_FLASH_IS_PRESENT_ADDR
86
87#endif /* __ADDRS_H__ */
88
89
90
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h
new file mode 100644
index 00000000000..609eb9841f5
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h
@@ -0,0 +1,40 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#ifndef _APB_ATHR_WLAN_MAP_H_
25#define _APB_ATHR_WLAN_MAP_H_
26
27#define WLAN_RTC_BASE_ADDRESS 0x00004000
28#define WLAN_VMC_BASE_ADDRESS 0x00008000
29#define WLAN_UART_BASE_ADDRESS 0x0000c000
30#define WLAN_DBG_UART_BASE_ADDRESS 0x0000d000
31#define WLAN_UMBOX_BASE_ADDRESS 0x0000e000
32#define WLAN_SI_BASE_ADDRESS 0x00010000
33#define WLAN_GPIO_BASE_ADDRESS 0x00014000
34#define WLAN_MBOX_BASE_ADDRESS 0x00018000
35#define WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000
36#define WLAN_MAC_BASE_ADDRESS 0x00020000
37#define WLAN_RDMA_BASE_ADDRESS 0x00030100
38#define EFUSE_BASE_ADDRESS 0x00031000
39
40#endif /* _APB_ATHR_WLAN_MAP_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h
new file mode 100644
index 00000000000..0068ca31b05
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h
@@ -0,0 +1,40 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#include "apb_athr_wlan_map.h"
25
26#ifndef BT_HEADERS
27
28#define RTC_BASE_ADDRESS WLAN_RTC_BASE_ADDRESS
29#define VMC_BASE_ADDRESS WLAN_VMC_BASE_ADDRESS
30#define UART_BASE_ADDRESS WLAN_UART_BASE_ADDRESS
31#define DBG_UART_BASE_ADDRESS WLAN_DBG_UART_BASE_ADDRESS
32#define UMBOX_BASE_ADDRESS WLAN_UMBOX_BASE_ADDRESS
33#define SI_BASE_ADDRESS WLAN_SI_BASE_ADDRESS
34#define GPIO_BASE_ADDRESS WLAN_GPIO_BASE_ADDRESS
35#define MBOX_BASE_ADDRESS WLAN_MBOX_BASE_ADDRESS
36#define ANALOG_INTF_BASE_ADDRESS WLAN_ANALOG_INTF_BASE_ADDRESS
37#define MAC_BASE_ADDRESS WLAN_MAC_BASE_ADDRESS
38#define RDMA_BASE_ADDRESS WLAN_RDMA_BASE_ADDRESS
39
40#endif
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h
new file mode 100644
index 00000000000..109f24e10a6
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h
@@ -0,0 +1,24 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#include "mbox_wlan_host_reg.h"
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h
new file mode 100644
index 00000000000..72fa483450d
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h
@@ -0,0 +1,552 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#include "mbox_wlan_reg.h"
25
26#ifndef BT_HEADERS
27
28#define MBOX_FIFO_ADDRESS WLAN_MBOX_FIFO_ADDRESS
29#define MBOX_FIFO_OFFSET WLAN_MBOX_FIFO_OFFSET
30#define MBOX_FIFO_DATA_MSB WLAN_MBOX_FIFO_DATA_MSB
31#define MBOX_FIFO_DATA_LSB WLAN_MBOX_FIFO_DATA_LSB
32#define MBOX_FIFO_DATA_MASK WLAN_MBOX_FIFO_DATA_MASK
33#define MBOX_FIFO_DATA_GET(x) WLAN_MBOX_FIFO_DATA_GET(x)
34#define MBOX_FIFO_DATA_SET(x) WLAN_MBOX_FIFO_DATA_SET(x)
35#define MBOX_FIFO_STATUS_ADDRESS WLAN_MBOX_FIFO_STATUS_ADDRESS
36#define MBOX_FIFO_STATUS_OFFSET WLAN_MBOX_FIFO_STATUS_OFFSET
37#define MBOX_FIFO_STATUS_EMPTY_MSB WLAN_MBOX_FIFO_STATUS_EMPTY_MSB
38#define MBOX_FIFO_STATUS_EMPTY_LSB WLAN_MBOX_FIFO_STATUS_EMPTY_LSB
39#define MBOX_FIFO_STATUS_EMPTY_MASK WLAN_MBOX_FIFO_STATUS_EMPTY_MASK
40#define MBOX_FIFO_STATUS_EMPTY_GET(x) WLAN_MBOX_FIFO_STATUS_EMPTY_GET(x)
41#define MBOX_FIFO_STATUS_EMPTY_SET(x) WLAN_MBOX_FIFO_STATUS_EMPTY_SET(x)
42#define MBOX_FIFO_STATUS_FULL_MSB WLAN_MBOX_FIFO_STATUS_FULL_MSB
43#define MBOX_FIFO_STATUS_FULL_LSB WLAN_MBOX_FIFO_STATUS_FULL_LSB
44#define MBOX_FIFO_STATUS_FULL_MASK WLAN_MBOX_FIFO_STATUS_FULL_MASK
45#define MBOX_FIFO_STATUS_FULL_GET(x) WLAN_MBOX_FIFO_STATUS_FULL_GET(x)
46#define MBOX_FIFO_STATUS_FULL_SET(x) WLAN_MBOX_FIFO_STATUS_FULL_SET(x)
47#define MBOX_DMA_POLICY_ADDRESS WLAN_MBOX_DMA_POLICY_ADDRESS
48#define MBOX_DMA_POLICY_OFFSET WLAN_MBOX_DMA_POLICY_OFFSET
49#define MBOX_DMA_POLICY_TX_QUANTUM_MSB WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MSB
50#define MBOX_DMA_POLICY_TX_QUANTUM_LSB WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB
51#define MBOX_DMA_POLICY_TX_QUANTUM_MASK WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK
52#define MBOX_DMA_POLICY_TX_QUANTUM_GET(x) WLAN_MBOX_DMA_POLICY_TX_QUANTUM_GET(x)
53#define MBOX_DMA_POLICY_TX_QUANTUM_SET(x) WLAN_MBOX_DMA_POLICY_TX_QUANTUM_SET(x)
54#define MBOX_DMA_POLICY_TX_ORDER_MSB WLAN_MBOX_DMA_POLICY_TX_ORDER_MSB
55#define MBOX_DMA_POLICY_TX_ORDER_LSB WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB
56#define MBOX_DMA_POLICY_TX_ORDER_MASK WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK
57#define MBOX_DMA_POLICY_TX_ORDER_GET(x) WLAN_MBOX_DMA_POLICY_TX_ORDER_GET(x)
58#define MBOX_DMA_POLICY_TX_ORDER_SET(x) WLAN_MBOX_DMA_POLICY_TX_ORDER_SET(x)
59#define MBOX_DMA_POLICY_RX_QUANTUM_MSB WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MSB
60#define MBOX_DMA_POLICY_RX_QUANTUM_LSB WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB
61#define MBOX_DMA_POLICY_RX_QUANTUM_MASK WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK
62#define MBOX_DMA_POLICY_RX_QUANTUM_GET(x) WLAN_MBOX_DMA_POLICY_RX_QUANTUM_GET(x)
63#define MBOX_DMA_POLICY_RX_QUANTUM_SET(x) WLAN_MBOX_DMA_POLICY_RX_QUANTUM_SET(x)
64#define MBOX_DMA_POLICY_RX_ORDER_MSB WLAN_MBOX_DMA_POLICY_RX_ORDER_MSB
65#define MBOX_DMA_POLICY_RX_ORDER_LSB WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB
66#define MBOX_DMA_POLICY_RX_ORDER_MASK WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK
67#define MBOX_DMA_POLICY_RX_ORDER_GET(x) WLAN_MBOX_DMA_POLICY_RX_ORDER_GET(x)
68#define MBOX_DMA_POLICY_RX_ORDER_SET(x) WLAN_MBOX_DMA_POLICY_RX_ORDER_SET(x)
69#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS
70#define MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET
71#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
72#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
73#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
74#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
75#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
76#define MBOX0_DMA_RX_CONTROL_ADDRESS WLAN_MBOX0_DMA_RX_CONTROL_ADDRESS
77#define MBOX0_DMA_RX_CONTROL_OFFSET WLAN_MBOX0_DMA_RX_CONTROL_OFFSET
78#define MBOX0_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MSB
79#define MBOX0_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB
80#define MBOX0_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK
81#define MBOX0_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_RESUME_GET(x)
82#define MBOX0_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_RESUME_SET(x)
83#define MBOX0_DMA_RX_CONTROL_START_MSB WLAN_MBOX0_DMA_RX_CONTROL_START_MSB
84#define MBOX0_DMA_RX_CONTROL_START_LSB WLAN_MBOX0_DMA_RX_CONTROL_START_LSB
85#define MBOX0_DMA_RX_CONTROL_START_MASK WLAN_MBOX0_DMA_RX_CONTROL_START_MASK
86#define MBOX0_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_START_GET(x)
87#define MBOX0_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_START_SET(x)
88#define MBOX0_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX0_DMA_RX_CONTROL_STOP_MSB
89#define MBOX0_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB
90#define MBOX0_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK
91#define MBOX0_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_STOP_GET(x)
92#define MBOX0_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_STOP_SET(x)
93#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS
94#define MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET
95#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
96#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
97#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
98#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
99#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
100#define MBOX0_DMA_TX_CONTROL_ADDRESS WLAN_MBOX0_DMA_TX_CONTROL_ADDRESS
101#define MBOX0_DMA_TX_CONTROL_OFFSET WLAN_MBOX0_DMA_TX_CONTROL_OFFSET
102#define MBOX0_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MSB
103#define MBOX0_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB
104#define MBOX0_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK
105#define MBOX0_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_RESUME_GET(x)
106#define MBOX0_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_RESUME_SET(x)
107#define MBOX0_DMA_TX_CONTROL_START_MSB WLAN_MBOX0_DMA_TX_CONTROL_START_MSB
108#define MBOX0_DMA_TX_CONTROL_START_LSB WLAN_MBOX0_DMA_TX_CONTROL_START_LSB
109#define MBOX0_DMA_TX_CONTROL_START_MASK WLAN_MBOX0_DMA_TX_CONTROL_START_MASK
110#define MBOX0_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_START_GET(x)
111#define MBOX0_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_START_SET(x)
112#define MBOX0_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX0_DMA_TX_CONTROL_STOP_MSB
113#define MBOX0_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB
114#define MBOX0_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK
115#define MBOX0_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_STOP_GET(x)
116#define MBOX0_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_STOP_SET(x)
117#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS
118#define MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET
119#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
120#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
121#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
122#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
123#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
124#define MBOX1_DMA_RX_CONTROL_ADDRESS WLAN_MBOX1_DMA_RX_CONTROL_ADDRESS
125#define MBOX1_DMA_RX_CONTROL_OFFSET WLAN_MBOX1_DMA_RX_CONTROL_OFFSET
126#define MBOX1_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MSB
127#define MBOX1_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB
128#define MBOX1_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK
129#define MBOX1_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_RESUME_GET(x)
130#define MBOX1_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_RESUME_SET(x)
131#define MBOX1_DMA_RX_CONTROL_START_MSB WLAN_MBOX1_DMA_RX_CONTROL_START_MSB
132#define MBOX1_DMA_RX_CONTROL_START_LSB WLAN_MBOX1_DMA_RX_CONTROL_START_LSB
133#define MBOX1_DMA_RX_CONTROL_START_MASK WLAN_MBOX1_DMA_RX_CONTROL_START_MASK
134#define MBOX1_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_START_GET(x)
135#define MBOX1_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_START_SET(x)
136#define MBOX1_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX1_DMA_RX_CONTROL_STOP_MSB
137#define MBOX1_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB
138#define MBOX1_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK
139#define MBOX1_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_STOP_GET(x)
140#define MBOX1_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_STOP_SET(x)
141#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS
142#define MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET
143#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
144#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
145#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
146#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
147#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
148#define MBOX1_DMA_TX_CONTROL_ADDRESS WLAN_MBOX1_DMA_TX_CONTROL_ADDRESS
149#define MBOX1_DMA_TX_CONTROL_OFFSET WLAN_MBOX1_DMA_TX_CONTROL_OFFSET
150#define MBOX1_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MSB
151#define MBOX1_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB
152#define MBOX1_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK
153#define MBOX1_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_RESUME_GET(x)
154#define MBOX1_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_RESUME_SET(x)
155#define MBOX1_DMA_TX_CONTROL_START_MSB WLAN_MBOX1_DMA_TX_CONTROL_START_MSB
156#define MBOX1_DMA_TX_CONTROL_START_LSB WLAN_MBOX1_DMA_TX_CONTROL_START_LSB
157#define MBOX1_DMA_TX_CONTROL_START_MASK WLAN_MBOX1_DMA_TX_CONTROL_START_MASK
158#define MBOX1_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_START_GET(x)
159#define MBOX1_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_START_SET(x)
160#define MBOX1_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX1_DMA_TX_CONTROL_STOP_MSB
161#define MBOX1_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB
162#define MBOX1_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK
163#define MBOX1_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_STOP_GET(x)
164#define MBOX1_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_STOP_SET(x)
165#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS
166#define MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET
167#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
168#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
169#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
170#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
171#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
172#define MBOX2_DMA_RX_CONTROL_ADDRESS WLAN_MBOX2_DMA_RX_CONTROL_ADDRESS
173#define MBOX2_DMA_RX_CONTROL_OFFSET WLAN_MBOX2_DMA_RX_CONTROL_OFFSET
174#define MBOX2_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MSB
175#define MBOX2_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB
176#define MBOX2_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK
177#define MBOX2_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_RESUME_GET(x)
178#define MBOX2_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_RESUME_SET(x)
179#define MBOX2_DMA_RX_CONTROL_START_MSB WLAN_MBOX2_DMA_RX_CONTROL_START_MSB
180#define MBOX2_DMA_RX_CONTROL_START_LSB WLAN_MBOX2_DMA_RX_CONTROL_START_LSB
181#define MBOX2_DMA_RX_CONTROL_START_MASK WLAN_MBOX2_DMA_RX_CONTROL_START_MASK
182#define MBOX2_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_START_GET(x)
183#define MBOX2_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_START_SET(x)
184#define MBOX2_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX2_DMA_RX_CONTROL_STOP_MSB
185#define MBOX2_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB
186#define MBOX2_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK
187#define MBOX2_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_STOP_GET(x)
188#define MBOX2_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_STOP_SET(x)
189#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS
190#define MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET
191#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
192#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
193#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
194#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
195#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
196#define MBOX2_DMA_TX_CONTROL_ADDRESS WLAN_MBOX2_DMA_TX_CONTROL_ADDRESS
197#define MBOX2_DMA_TX_CONTROL_OFFSET WLAN_MBOX2_DMA_TX_CONTROL_OFFSET
198#define MBOX2_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MSB
199#define MBOX2_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB
200#define MBOX2_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK
201#define MBOX2_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_RESUME_GET(x)
202#define MBOX2_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_RESUME_SET(x)
203#define MBOX2_DMA_TX_CONTROL_START_MSB WLAN_MBOX2_DMA_TX_CONTROL_START_MSB
204#define MBOX2_DMA_TX_CONTROL_START_LSB WLAN_MBOX2_DMA_TX_CONTROL_START_LSB
205#define MBOX2_DMA_TX_CONTROL_START_MASK WLAN_MBOX2_DMA_TX_CONTROL_START_MASK
206#define MBOX2_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_START_GET(x)
207#define MBOX2_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_START_SET(x)
208#define MBOX2_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX2_DMA_TX_CONTROL_STOP_MSB
209#define MBOX2_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB
210#define MBOX2_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK
211#define MBOX2_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_STOP_GET(x)
212#define MBOX2_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_STOP_SET(x)
213#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS
214#define MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET
215#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
216#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
217#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
218#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
219#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
220#define MBOX3_DMA_RX_CONTROL_ADDRESS WLAN_MBOX3_DMA_RX_CONTROL_ADDRESS
221#define MBOX3_DMA_RX_CONTROL_OFFSET WLAN_MBOX3_DMA_RX_CONTROL_OFFSET
222#define MBOX3_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MSB
223#define MBOX3_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB
224#define MBOX3_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK
225#define MBOX3_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_RESUME_GET(x)
226#define MBOX3_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_RESUME_SET(x)
227#define MBOX3_DMA_RX_CONTROL_START_MSB WLAN_MBOX3_DMA_RX_CONTROL_START_MSB
228#define MBOX3_DMA_RX_CONTROL_START_LSB WLAN_MBOX3_DMA_RX_CONTROL_START_LSB
229#define MBOX3_DMA_RX_CONTROL_START_MASK WLAN_MBOX3_DMA_RX_CONTROL_START_MASK
230#define MBOX3_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_START_GET(x)
231#define MBOX3_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_START_SET(x)
232#define MBOX3_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX3_DMA_RX_CONTROL_STOP_MSB
233#define MBOX3_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB
234#define MBOX3_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK
235#define MBOX3_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_STOP_GET(x)
236#define MBOX3_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_STOP_SET(x)
237#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS
238#define MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET
239#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
240#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
241#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
242#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
243#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
244#define MBOX3_DMA_TX_CONTROL_ADDRESS WLAN_MBOX3_DMA_TX_CONTROL_ADDRESS
245#define MBOX3_DMA_TX_CONTROL_OFFSET WLAN_MBOX3_DMA_TX_CONTROL_OFFSET
246#define MBOX3_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MSB
247#define MBOX3_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB
248#define MBOX3_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK
249#define MBOX3_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_RESUME_GET(x)
250#define MBOX3_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_RESUME_SET(x)
251#define MBOX3_DMA_TX_CONTROL_START_MSB WLAN_MBOX3_DMA_TX_CONTROL_START_MSB
252#define MBOX3_DMA_TX_CONTROL_START_LSB WLAN_MBOX3_DMA_TX_CONTROL_START_LSB
253#define MBOX3_DMA_TX_CONTROL_START_MASK WLAN_MBOX3_DMA_TX_CONTROL_START_MASK
254#define MBOX3_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_START_GET(x)
255#define MBOX3_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_START_SET(x)
256#define MBOX3_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX3_DMA_TX_CONTROL_STOP_MSB
257#define MBOX3_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB
258#define MBOX3_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK
259#define MBOX3_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_STOP_GET(x)
260#define MBOX3_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_STOP_SET(x)
261#define MBOX_INT_STATUS_ADDRESS WLAN_MBOX_INT_STATUS_ADDRESS
262#define MBOX_INT_STATUS_OFFSET WLAN_MBOX_INT_STATUS_OFFSET
263#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB
264#define MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB
265#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK
266#define MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)
267#define MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)
268#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB
269#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB
270#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK
271#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x)
272#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x)
273#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB
274#define MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB
275#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK
276#define MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)
277#define MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)
278#define MBOX_INT_STATUS_TX_OVERFLOW_MSB WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MSB
279#define MBOX_INT_STATUS_TX_OVERFLOW_LSB WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB
280#define MBOX_INT_STATUS_TX_OVERFLOW_MASK WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK
281#define MBOX_INT_STATUS_TX_OVERFLOW_GET(x) WLAN_MBOX_INT_STATUS_TX_OVERFLOW_GET(x)
282#define MBOX_INT_STATUS_TX_OVERFLOW_SET(x) WLAN_MBOX_INT_STATUS_TX_OVERFLOW_SET(x)
283#define MBOX_INT_STATUS_RX_UNDERFLOW_MSB WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MSB
284#define MBOX_INT_STATUS_RX_UNDERFLOW_LSB WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB
285#define MBOX_INT_STATUS_RX_UNDERFLOW_MASK WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK
286#define MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_GET(x)
287#define MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_SET(x)
288#define MBOX_INT_STATUS_TX_NOT_EMPTY_MSB WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MSB
289#define MBOX_INT_STATUS_TX_NOT_EMPTY_LSB WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB
290#define MBOX_INT_STATUS_TX_NOT_EMPTY_MASK WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK
291#define MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)
292#define MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)
293#define MBOX_INT_STATUS_RX_NOT_FULL_MSB WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MSB
294#define MBOX_INT_STATUS_RX_NOT_FULL_LSB WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB
295#define MBOX_INT_STATUS_RX_NOT_FULL_MASK WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK
296#define MBOX_INT_STATUS_RX_NOT_FULL_GET(x) WLAN_MBOX_INT_STATUS_RX_NOT_FULL_GET(x)
297#define MBOX_INT_STATUS_RX_NOT_FULL_SET(x) WLAN_MBOX_INT_STATUS_RX_NOT_FULL_SET(x)
298#define MBOX_INT_STATUS_HOST_MSB WLAN_MBOX_INT_STATUS_HOST_MSB
299#define MBOX_INT_STATUS_HOST_LSB WLAN_MBOX_INT_STATUS_HOST_LSB
300#define MBOX_INT_STATUS_HOST_MASK WLAN_MBOX_INT_STATUS_HOST_MASK
301#define MBOX_INT_STATUS_HOST_GET(x) WLAN_MBOX_INT_STATUS_HOST_GET(x)
302#define MBOX_INT_STATUS_HOST_SET(x) WLAN_MBOX_INT_STATUS_HOST_SET(x)
303#define MBOX_INT_ENABLE_ADDRESS WLAN_MBOX_INT_ENABLE_ADDRESS
304#define MBOX_INT_ENABLE_OFFSET WLAN_MBOX_INT_ENABLE_OFFSET
305#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB
306#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB
307#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK
308#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)
309#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)
310#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB
311#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB
312#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK
313#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x)
314#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x)
315#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB
316#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB
317#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK
318#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)
319#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)
320#define MBOX_INT_ENABLE_TX_OVERFLOW_MSB WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MSB
321#define MBOX_INT_ENABLE_TX_OVERFLOW_LSB WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB
322#define MBOX_INT_ENABLE_TX_OVERFLOW_MASK WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK
323#define MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_GET(x)
324#define MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_SET(x)
325#define MBOX_INT_ENABLE_RX_UNDERFLOW_MSB WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MSB
326#define MBOX_INT_ENABLE_RX_UNDERFLOW_LSB WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB
327#define MBOX_INT_ENABLE_RX_UNDERFLOW_MASK WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK
328#define MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)
329#define MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)
330#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB
331#define MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB
332#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK
333#define MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)
334#define MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)
335#define MBOX_INT_ENABLE_RX_NOT_FULL_MSB WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MSB
336#define MBOX_INT_ENABLE_RX_NOT_FULL_LSB WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB
337#define MBOX_INT_ENABLE_RX_NOT_FULL_MASK WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK
338#define MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_GET(x)
339#define MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_SET(x)
340#define MBOX_INT_ENABLE_HOST_MSB WLAN_MBOX_INT_ENABLE_HOST_MSB
341#define MBOX_INT_ENABLE_HOST_LSB WLAN_MBOX_INT_ENABLE_HOST_LSB
342#define MBOX_INT_ENABLE_HOST_MASK WLAN_MBOX_INT_ENABLE_HOST_MASK
343#define MBOX_INT_ENABLE_HOST_GET(x) WLAN_MBOX_INT_ENABLE_HOST_GET(x)
344#define MBOX_INT_ENABLE_HOST_SET(x) WLAN_MBOX_INT_ENABLE_HOST_SET(x)
345#define INT_HOST_ADDRESS WLAN_INT_HOST_ADDRESS
346#define INT_HOST_OFFSET WLAN_INT_HOST_OFFSET
347#define INT_HOST_VECTOR_MSB WLAN_INT_HOST_VECTOR_MSB
348#define INT_HOST_VECTOR_LSB WLAN_INT_HOST_VECTOR_LSB
349#define INT_HOST_VECTOR_MASK WLAN_INT_HOST_VECTOR_MASK
350#define INT_HOST_VECTOR_GET(x) WLAN_INT_HOST_VECTOR_GET(x)
351#define INT_HOST_VECTOR_SET(x) WLAN_INT_HOST_VECTOR_SET(x)
352#define LOCAL_COUNT_ADDRESS WLAN_LOCAL_COUNT_ADDRESS
353#define LOCAL_COUNT_OFFSET WLAN_LOCAL_COUNT_OFFSET
354#define LOCAL_COUNT_VALUE_MSB WLAN_LOCAL_COUNT_VALUE_MSB
355#define LOCAL_COUNT_VALUE_LSB WLAN_LOCAL_COUNT_VALUE_LSB
356#define LOCAL_COUNT_VALUE_MASK WLAN_LOCAL_COUNT_VALUE_MASK
357#define LOCAL_COUNT_VALUE_GET(x) WLAN_LOCAL_COUNT_VALUE_GET(x)
358#define LOCAL_COUNT_VALUE_SET(x) WLAN_LOCAL_COUNT_VALUE_SET(x)
359#define COUNT_INC_ADDRESS WLAN_COUNT_INC_ADDRESS
360#define COUNT_INC_OFFSET WLAN_COUNT_INC_OFFSET
361#define COUNT_INC_VALUE_MSB WLAN_COUNT_INC_VALUE_MSB
362#define COUNT_INC_VALUE_LSB WLAN_COUNT_INC_VALUE_LSB
363#define COUNT_INC_VALUE_MASK WLAN_COUNT_INC_VALUE_MASK
364#define COUNT_INC_VALUE_GET(x) WLAN_COUNT_INC_VALUE_GET(x)
365#define COUNT_INC_VALUE_SET(x) WLAN_COUNT_INC_VALUE_SET(x)
366#define LOCAL_SCRATCH_ADDRESS WLAN_LOCAL_SCRATCH_ADDRESS
367#define LOCAL_SCRATCH_OFFSET WLAN_LOCAL_SCRATCH_OFFSET
368#define LOCAL_SCRATCH_VALUE_MSB WLAN_LOCAL_SCRATCH_VALUE_MSB
369#define LOCAL_SCRATCH_VALUE_LSB WLAN_LOCAL_SCRATCH_VALUE_LSB
370#define LOCAL_SCRATCH_VALUE_MASK WLAN_LOCAL_SCRATCH_VALUE_MASK
371#define LOCAL_SCRATCH_VALUE_GET(x) WLAN_LOCAL_SCRATCH_VALUE_GET(x)
372#define LOCAL_SCRATCH_VALUE_SET(x) WLAN_LOCAL_SCRATCH_VALUE_SET(x)
373#define USE_LOCAL_BUS_ADDRESS WLAN_USE_LOCAL_BUS_ADDRESS
374#define USE_LOCAL_BUS_OFFSET WLAN_USE_LOCAL_BUS_OFFSET
375#define USE_LOCAL_BUS_PIN_INIT_MSB WLAN_USE_LOCAL_BUS_PIN_INIT_MSB
376#define USE_LOCAL_BUS_PIN_INIT_LSB WLAN_USE_LOCAL_BUS_PIN_INIT_LSB
377#define USE_LOCAL_BUS_PIN_INIT_MASK WLAN_USE_LOCAL_BUS_PIN_INIT_MASK
378#define USE_LOCAL_BUS_PIN_INIT_GET(x) WLAN_USE_LOCAL_BUS_PIN_INIT_GET(x)
379#define USE_LOCAL_BUS_PIN_INIT_SET(x) WLAN_USE_LOCAL_BUS_PIN_INIT_SET(x)
380#define SDIO_CONFIG_ADDRESS WLAN_SDIO_CONFIG_ADDRESS
381#define SDIO_CONFIG_OFFSET WLAN_SDIO_CONFIG_OFFSET
382#define SDIO_CONFIG_CCCR_IOR1_MSB WLAN_SDIO_CONFIG_CCCR_IOR1_MSB
383#define SDIO_CONFIG_CCCR_IOR1_LSB WLAN_SDIO_CONFIG_CCCR_IOR1_LSB
384#define SDIO_CONFIG_CCCR_IOR1_MASK WLAN_SDIO_CONFIG_CCCR_IOR1_MASK
385#define SDIO_CONFIG_CCCR_IOR1_GET(x) WLAN_SDIO_CONFIG_CCCR_IOR1_GET(x)
386#define SDIO_CONFIG_CCCR_IOR1_SET(x) WLAN_SDIO_CONFIG_CCCR_IOR1_SET(x)
387#define MBOX_DEBUG_ADDRESS WLAN_MBOX_DEBUG_ADDRESS
388#define MBOX_DEBUG_OFFSET WLAN_MBOX_DEBUG_OFFSET
389#define MBOX_DEBUG_SEL_MSB WLAN_MBOX_DEBUG_SEL_MSB
390#define MBOX_DEBUG_SEL_LSB WLAN_MBOX_DEBUG_SEL_LSB
391#define MBOX_DEBUG_SEL_MASK WLAN_MBOX_DEBUG_SEL_MASK
392#define MBOX_DEBUG_SEL_GET(x) WLAN_MBOX_DEBUG_SEL_GET(x)
393#define MBOX_DEBUG_SEL_SET(x) WLAN_MBOX_DEBUG_SEL_SET(x)
394#define MBOX_FIFO_RESET_ADDRESS WLAN_MBOX_FIFO_RESET_ADDRESS
395#define MBOX_FIFO_RESET_OFFSET WLAN_MBOX_FIFO_RESET_OFFSET
396#define MBOX_FIFO_RESET_INIT_MSB WLAN_MBOX_FIFO_RESET_INIT_MSB
397#define MBOX_FIFO_RESET_INIT_LSB WLAN_MBOX_FIFO_RESET_INIT_LSB
398#define MBOX_FIFO_RESET_INIT_MASK WLAN_MBOX_FIFO_RESET_INIT_MASK
399#define MBOX_FIFO_RESET_INIT_GET(x) WLAN_MBOX_FIFO_RESET_INIT_GET(x)
400#define MBOX_FIFO_RESET_INIT_SET(x) WLAN_MBOX_FIFO_RESET_INIT_SET(x)
401#define MBOX_TXFIFO_POP_ADDRESS WLAN_MBOX_TXFIFO_POP_ADDRESS
402#define MBOX_TXFIFO_POP_OFFSET WLAN_MBOX_TXFIFO_POP_OFFSET
403#define MBOX_TXFIFO_POP_DATA_MSB WLAN_MBOX_TXFIFO_POP_DATA_MSB
404#define MBOX_TXFIFO_POP_DATA_LSB WLAN_MBOX_TXFIFO_POP_DATA_LSB
405#define MBOX_TXFIFO_POP_DATA_MASK WLAN_MBOX_TXFIFO_POP_DATA_MASK
406#define MBOX_TXFIFO_POP_DATA_GET(x) WLAN_MBOX_TXFIFO_POP_DATA_GET(x)
407#define MBOX_TXFIFO_POP_DATA_SET(x) WLAN_MBOX_TXFIFO_POP_DATA_SET(x)
408#define MBOX_RXFIFO_POP_ADDRESS WLAN_MBOX_RXFIFO_POP_ADDRESS
409#define MBOX_RXFIFO_POP_OFFSET WLAN_MBOX_RXFIFO_POP_OFFSET
410#define MBOX_RXFIFO_POP_DATA_MSB WLAN_MBOX_RXFIFO_POP_DATA_MSB
411#define MBOX_RXFIFO_POP_DATA_LSB WLAN_MBOX_RXFIFO_POP_DATA_LSB
412#define MBOX_RXFIFO_POP_DATA_MASK WLAN_MBOX_RXFIFO_POP_DATA_MASK
413#define MBOX_RXFIFO_POP_DATA_GET(x) WLAN_MBOX_RXFIFO_POP_DATA_GET(x)
414#define MBOX_RXFIFO_POP_DATA_SET(x) WLAN_MBOX_RXFIFO_POP_DATA_SET(x)
415#define SDIO_DEBUG_ADDRESS WLAN_SDIO_DEBUG_ADDRESS
416#define SDIO_DEBUG_OFFSET WLAN_SDIO_DEBUG_OFFSET
417#define SDIO_DEBUG_SEL_MSB WLAN_SDIO_DEBUG_SEL_MSB
418#define SDIO_DEBUG_SEL_LSB WLAN_SDIO_DEBUG_SEL_LSB
419#define SDIO_DEBUG_SEL_MASK WLAN_SDIO_DEBUG_SEL_MASK
420#define SDIO_DEBUG_SEL_GET(x) WLAN_SDIO_DEBUG_SEL_GET(x)
421#define SDIO_DEBUG_SEL_SET(x) WLAN_SDIO_DEBUG_SEL_SET(x)
422#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS
423#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET
424#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
425#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
426#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
427#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
428#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
429#define GMBOX0_DMA_RX_CONTROL_ADDRESS WLAN_GMBOX0_DMA_RX_CONTROL_ADDRESS
430#define GMBOX0_DMA_RX_CONTROL_OFFSET WLAN_GMBOX0_DMA_RX_CONTROL_OFFSET
431#define GMBOX0_DMA_RX_CONTROL_RESUME_MSB WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MSB
432#define GMBOX0_DMA_RX_CONTROL_RESUME_LSB WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB
433#define GMBOX0_DMA_RX_CONTROL_RESUME_MASK WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK
434#define GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_GET(x)
435#define GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_SET(x)
436#define GMBOX0_DMA_RX_CONTROL_START_MSB WLAN_GMBOX0_DMA_RX_CONTROL_START_MSB
437#define GMBOX0_DMA_RX_CONTROL_START_LSB WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB
438#define GMBOX0_DMA_RX_CONTROL_START_MASK WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK
439#define GMBOX0_DMA_RX_CONTROL_START_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_START_GET(x)
440#define GMBOX0_DMA_RX_CONTROL_START_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_START_SET(x)
441#define GMBOX0_DMA_RX_CONTROL_STOP_MSB WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MSB
442#define GMBOX0_DMA_RX_CONTROL_STOP_LSB WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB
443#define GMBOX0_DMA_RX_CONTROL_STOP_MASK WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK
444#define GMBOX0_DMA_RX_CONTROL_STOP_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_STOP_GET(x)
445#define GMBOX0_DMA_RX_CONTROL_STOP_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_STOP_SET(x)
446#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS
447#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET
448#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
449#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
450#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
451#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
452#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
453#define GMBOX0_DMA_TX_CONTROL_ADDRESS WLAN_GMBOX0_DMA_TX_CONTROL_ADDRESS
454#define GMBOX0_DMA_TX_CONTROL_OFFSET WLAN_GMBOX0_DMA_TX_CONTROL_OFFSET
455#define GMBOX0_DMA_TX_CONTROL_RESUME_MSB WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MSB
456#define GMBOX0_DMA_TX_CONTROL_RESUME_LSB WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB
457#define GMBOX0_DMA_TX_CONTROL_RESUME_MASK WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK
458#define GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_GET(x)
459#define GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_SET(x)
460#define GMBOX0_DMA_TX_CONTROL_START_MSB WLAN_GMBOX0_DMA_TX_CONTROL_START_MSB
461#define GMBOX0_DMA_TX_CONTROL_START_LSB WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB
462#define GMBOX0_DMA_TX_CONTROL_START_MASK WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK
463#define GMBOX0_DMA_TX_CONTROL_START_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_START_GET(x)
464#define GMBOX0_DMA_TX_CONTROL_START_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_START_SET(x)
465#define GMBOX0_DMA_TX_CONTROL_STOP_MSB WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MSB
466#define GMBOX0_DMA_TX_CONTROL_STOP_LSB WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB
467#define GMBOX0_DMA_TX_CONTROL_STOP_MASK WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK
468#define GMBOX0_DMA_TX_CONTROL_STOP_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_STOP_GET(x)
469#define GMBOX0_DMA_TX_CONTROL_STOP_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_STOP_SET(x)
470#define GMBOX_INT_STATUS_ADDRESS WLAN_GMBOX_INT_STATUS_ADDRESS
471#define GMBOX_INT_STATUS_OFFSET WLAN_GMBOX_INT_STATUS_OFFSET
472#define GMBOX_INT_STATUS_TX_OVERFLOW_MSB WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MSB
473#define GMBOX_INT_STATUS_TX_OVERFLOW_LSB WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB
474#define GMBOX_INT_STATUS_TX_OVERFLOW_MASK WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK
475#define GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_GET(x)
476#define GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_SET(x)
477#define GMBOX_INT_STATUS_RX_UNDERFLOW_MSB WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MSB
478#define GMBOX_INT_STATUS_RX_UNDERFLOW_LSB WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB
479#define GMBOX_INT_STATUS_RX_UNDERFLOW_MASK WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK
480#define GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x)
481#define GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x)
482#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB
483#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB
484#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK
485#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)
486#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)
487#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB
488#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB
489#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK
490#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x)
491#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x)
492#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB
493#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB
494#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK
495#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)
496#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)
497#define GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB
498#define GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB
499#define GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK
500#define GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)
501#define GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)
502#define GMBOX_INT_STATUS_RX_NOT_FULL_MSB WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MSB
503#define GMBOX_INT_STATUS_RX_NOT_FULL_LSB WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB
504#define GMBOX_INT_STATUS_RX_NOT_FULL_MASK WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK
505#define GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_GET(x)
506#define GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_SET(x)
507#define GMBOX_INT_ENABLE_ADDRESS WLAN_GMBOX_INT_ENABLE_ADDRESS
508#define GMBOX_INT_ENABLE_OFFSET WLAN_GMBOX_INT_ENABLE_OFFSET
509#define GMBOX_INT_ENABLE_TX_OVERFLOW_MSB WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MSB
510#define GMBOX_INT_ENABLE_TX_OVERFLOW_LSB WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB
511#define GMBOX_INT_ENABLE_TX_OVERFLOW_MASK WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK
512#define GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x)
513#define GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x)
514#define GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB
515#define GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB
516#define GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK
517#define GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)
518#define GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)
519#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB
520#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB
521#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK
522#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)
523#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)
524#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB
525#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB
526#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK
527#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x)
528#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x)
529#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB
530#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB
531#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK
532#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)
533#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)
534#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB
535#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB
536#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK
537#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)
538#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)
539#define GMBOX_INT_ENABLE_RX_NOT_FULL_MSB WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MSB
540#define GMBOX_INT_ENABLE_RX_NOT_FULL_LSB WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB
541#define GMBOX_INT_ENABLE_RX_NOT_FULL_MASK WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK
542#define GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x)
543#define GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x)
544#define HOST_IF_WINDOW_ADDRESS WLAN_HOST_IF_WINDOW_ADDRESS
545#define HOST_IF_WINDOW_OFFSET WLAN_HOST_IF_WINDOW_OFFSET
546#define HOST_IF_WINDOW_DATA_MSB WLAN_HOST_IF_WINDOW_DATA_MSB
547#define HOST_IF_WINDOW_DATA_LSB WLAN_HOST_IF_WINDOW_DATA_LSB
548#define HOST_IF_WINDOW_DATA_MASK WLAN_HOST_IF_WINDOW_DATA_MASK
549#define HOST_IF_WINDOW_DATA_GET(x) WLAN_HOST_IF_WINDOW_DATA_GET(x)
550#define HOST_IF_WINDOW_DATA_SET(x) WLAN_HOST_IF_WINDOW_DATA_SET(x)
551
552#endif
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h
new file mode 100644
index 00000000000..038d0d01927
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h
@@ -0,0 +1,471 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#ifndef _MBOX_WLAN_HOST_REG_REG_H_
25#define _MBOX_WLAN_HOST_REG_REG_H_
26
27#define HOST_INT_STATUS_ADDRESS 0x00000400
28#define HOST_INT_STATUS_OFFSET 0x00000400
29#define HOST_INT_STATUS_ERROR_MSB 7
30#define HOST_INT_STATUS_ERROR_LSB 7
31#define HOST_INT_STATUS_ERROR_MASK 0x00000080
32#define HOST_INT_STATUS_ERROR_GET(x) (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB)
33#define HOST_INT_STATUS_ERROR_SET(x) (((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK)
34#define HOST_INT_STATUS_CPU_MSB 6
35#define HOST_INT_STATUS_CPU_LSB 6
36#define HOST_INT_STATUS_CPU_MASK 0x00000040
37#define HOST_INT_STATUS_CPU_GET(x) (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB)
38#define HOST_INT_STATUS_CPU_SET(x) (((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK)
39#define HOST_INT_STATUS_INT_MSB 5
40#define HOST_INT_STATUS_INT_LSB 5
41#define HOST_INT_STATUS_INT_MASK 0x00000020
42#define HOST_INT_STATUS_INT_GET(x) (((x) & HOST_INT_STATUS_INT_MASK) >> HOST_INT_STATUS_INT_LSB)
43#define HOST_INT_STATUS_INT_SET(x) (((x) << HOST_INT_STATUS_INT_LSB) & HOST_INT_STATUS_INT_MASK)
44#define HOST_INT_STATUS_COUNTER_MSB 4
45#define HOST_INT_STATUS_COUNTER_LSB 4
46#define HOST_INT_STATUS_COUNTER_MASK 0x00000010
47#define HOST_INT_STATUS_COUNTER_GET(x) (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB)
48#define HOST_INT_STATUS_COUNTER_SET(x) (((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK)
49#define HOST_INT_STATUS_MBOX_DATA_MSB 3
50#define HOST_INT_STATUS_MBOX_DATA_LSB 0
51#define HOST_INT_STATUS_MBOX_DATA_MASK 0x0000000f
52#define HOST_INT_STATUS_MBOX_DATA_GET(x) (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB)
53#define HOST_INT_STATUS_MBOX_DATA_SET(x) (((x) << HOST_INT_STATUS_MBOX_DATA_LSB) & HOST_INT_STATUS_MBOX_DATA_MASK)
54
55#define CPU_INT_STATUS_ADDRESS 0x00000401
56#define CPU_INT_STATUS_OFFSET 0x00000401
57#define CPU_INT_STATUS_BIT_MSB 7
58#define CPU_INT_STATUS_BIT_LSB 0
59#define CPU_INT_STATUS_BIT_MASK 0x000000ff
60#define CPU_INT_STATUS_BIT_GET(x) (((x) & CPU_INT_STATUS_BIT_MASK) >> CPU_INT_STATUS_BIT_LSB)
61#define CPU_INT_STATUS_BIT_SET(x) (((x) << CPU_INT_STATUS_BIT_LSB) & CPU_INT_STATUS_BIT_MASK)
62
63#define ERROR_INT_STATUS_ADDRESS 0x00000402
64#define ERROR_INT_STATUS_OFFSET 0x00000402
65#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MSB 6
66#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB 6
67#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK 0x00000040
68#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB)
69#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK)
70#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MSB 5
71#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB 5
72#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK 0x00000020
73#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB)
74#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK)
75#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MSB 4
76#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB 4
77#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK 0x00000010
78#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB)
79#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK)
80#define ERROR_INT_STATUS_SPI_MSB 3
81#define ERROR_INT_STATUS_SPI_LSB 3
82#define ERROR_INT_STATUS_SPI_MASK 0x00000008
83#define ERROR_INT_STATUS_SPI_GET(x) (((x) & ERROR_INT_STATUS_SPI_MASK) >> ERROR_INT_STATUS_SPI_LSB)
84#define ERROR_INT_STATUS_SPI_SET(x) (((x) << ERROR_INT_STATUS_SPI_LSB) & ERROR_INT_STATUS_SPI_MASK)
85#define ERROR_INT_STATUS_WAKEUP_MSB 2
86#define ERROR_INT_STATUS_WAKEUP_LSB 2
87#define ERROR_INT_STATUS_WAKEUP_MASK 0x00000004
88#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB)
89#define ERROR_INT_STATUS_WAKEUP_SET(x) (((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK)
90#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB 1
91#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB 1
92#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00000002
93#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
94#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK)
95#define ERROR_INT_STATUS_TX_OVERFLOW_MSB 0
96#define ERROR_INT_STATUS_TX_OVERFLOW_LSB 0
97#define ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00000001
98#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB)
99#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & ERROR_INT_STATUS_TX_OVERFLOW_MASK)
100
101#define COUNTER_INT_STATUS_ADDRESS 0x00000403
102#define COUNTER_INT_STATUS_OFFSET 0x00000403
103#define COUNTER_INT_STATUS_COUNTER_MSB 7
104#define COUNTER_INT_STATUS_COUNTER_LSB 0
105#define COUNTER_INT_STATUS_COUNTER_MASK 0x000000ff
106#define COUNTER_INT_STATUS_COUNTER_GET(x) (((x) & COUNTER_INT_STATUS_COUNTER_MASK) >> COUNTER_INT_STATUS_COUNTER_LSB)
107#define COUNTER_INT_STATUS_COUNTER_SET(x) (((x) << COUNTER_INT_STATUS_COUNTER_LSB) & COUNTER_INT_STATUS_COUNTER_MASK)
108
109#define MBOX_FRAME_ADDRESS 0x00000404
110#define MBOX_FRAME_OFFSET 0x00000404
111#define MBOX_FRAME_RX_EOM_MSB 7
112#define MBOX_FRAME_RX_EOM_LSB 4
113#define MBOX_FRAME_RX_EOM_MASK 0x000000f0
114#define MBOX_FRAME_RX_EOM_GET(x) (((x) & MBOX_FRAME_RX_EOM_MASK) >> MBOX_FRAME_RX_EOM_LSB)
115#define MBOX_FRAME_RX_EOM_SET(x) (((x) << MBOX_FRAME_RX_EOM_LSB) & MBOX_FRAME_RX_EOM_MASK)
116#define MBOX_FRAME_RX_SOM_MSB 3
117#define MBOX_FRAME_RX_SOM_LSB 0
118#define MBOX_FRAME_RX_SOM_MASK 0x0000000f
119#define MBOX_FRAME_RX_SOM_GET(x) (((x) & MBOX_FRAME_RX_SOM_MASK) >> MBOX_FRAME_RX_SOM_LSB)
120#define MBOX_FRAME_RX_SOM_SET(x) (((x) << MBOX_FRAME_RX_SOM_LSB) & MBOX_FRAME_RX_SOM_MASK)
121
122#define RX_LOOKAHEAD_VALID_ADDRESS 0x00000405
123#define RX_LOOKAHEAD_VALID_OFFSET 0x00000405
124#define RX_LOOKAHEAD_VALID_MBOX_MSB 3
125#define RX_LOOKAHEAD_VALID_MBOX_LSB 0
126#define RX_LOOKAHEAD_VALID_MBOX_MASK 0x0000000f
127#define RX_LOOKAHEAD_VALID_MBOX_GET(x) (((x) & RX_LOOKAHEAD_VALID_MBOX_MASK) >> RX_LOOKAHEAD_VALID_MBOX_LSB)
128#define RX_LOOKAHEAD_VALID_MBOX_SET(x) (((x) << RX_LOOKAHEAD_VALID_MBOX_LSB) & RX_LOOKAHEAD_VALID_MBOX_MASK)
129
130#define HOST_INT_STATUS2_ADDRESS 0x00000406
131#define HOST_INT_STATUS2_OFFSET 0x00000406
132#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MSB 2
133#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB 2
134#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK 0x00000004
135#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK) >> HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB)
136#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB) & HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK)
137#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MSB 1
138#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB 1
139#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK 0x00000002
140#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK) >> HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB)
141#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB) & HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK)
142#define HOST_INT_STATUS2_GMBOX_DATA_MSB 0
143#define HOST_INT_STATUS2_GMBOX_DATA_LSB 0
144#define HOST_INT_STATUS2_GMBOX_DATA_MASK 0x00000001
145#define HOST_INT_STATUS2_GMBOX_DATA_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_DATA_MASK) >> HOST_INT_STATUS2_GMBOX_DATA_LSB)
146#define HOST_INT_STATUS2_GMBOX_DATA_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_DATA_LSB) & HOST_INT_STATUS2_GMBOX_DATA_MASK)
147
148#define GMBOX_RX_AVAIL_ADDRESS 0x00000407
149#define GMBOX_RX_AVAIL_OFFSET 0x00000407
150#define GMBOX_RX_AVAIL_BYTE_MSB 6
151#define GMBOX_RX_AVAIL_BYTE_LSB 0
152#define GMBOX_RX_AVAIL_BYTE_MASK 0x0000007f
153#define GMBOX_RX_AVAIL_BYTE_GET(x) (((x) & GMBOX_RX_AVAIL_BYTE_MASK) >> GMBOX_RX_AVAIL_BYTE_LSB)
154#define GMBOX_RX_AVAIL_BYTE_SET(x) (((x) << GMBOX_RX_AVAIL_BYTE_LSB) & GMBOX_RX_AVAIL_BYTE_MASK)
155
156#define RX_LOOKAHEAD0_ADDRESS 0x00000408
157#define RX_LOOKAHEAD0_OFFSET 0x00000408
158#define RX_LOOKAHEAD0_DATA_MSB 7
159#define RX_LOOKAHEAD0_DATA_LSB 0
160#define RX_LOOKAHEAD0_DATA_MASK 0x000000ff
161#define RX_LOOKAHEAD0_DATA_GET(x) (((x) & RX_LOOKAHEAD0_DATA_MASK) >> RX_LOOKAHEAD0_DATA_LSB)
162#define RX_LOOKAHEAD0_DATA_SET(x) (((x) << RX_LOOKAHEAD0_DATA_LSB) & RX_LOOKAHEAD0_DATA_MASK)
163
164#define RX_LOOKAHEAD1_ADDRESS 0x0000040c
165#define RX_LOOKAHEAD1_OFFSET 0x0000040c
166#define RX_LOOKAHEAD1_DATA_MSB 7
167#define RX_LOOKAHEAD1_DATA_LSB 0
168#define RX_LOOKAHEAD1_DATA_MASK 0x000000ff
169#define RX_LOOKAHEAD1_DATA_GET(x) (((x) & RX_LOOKAHEAD1_DATA_MASK) >> RX_LOOKAHEAD1_DATA_LSB)
170#define RX_LOOKAHEAD1_DATA_SET(x) (((x) << RX_LOOKAHEAD1_DATA_LSB) & RX_LOOKAHEAD1_DATA_MASK)
171
172#define RX_LOOKAHEAD2_ADDRESS 0x00000410
173#define RX_LOOKAHEAD2_OFFSET 0x00000410
174#define RX_LOOKAHEAD2_DATA_MSB 7
175#define RX_LOOKAHEAD2_DATA_LSB 0
176#define RX_LOOKAHEAD2_DATA_MASK 0x000000ff
177#define RX_LOOKAHEAD2_DATA_GET(x) (((x) & RX_LOOKAHEAD2_DATA_MASK) >> RX_LOOKAHEAD2_DATA_LSB)
178#define RX_LOOKAHEAD2_DATA_SET(x) (((x) << RX_LOOKAHEAD2_DATA_LSB) & RX_LOOKAHEAD2_DATA_MASK)
179
180#define RX_LOOKAHEAD3_ADDRESS 0x00000414
181#define RX_LOOKAHEAD3_OFFSET 0x00000414
182#define RX_LOOKAHEAD3_DATA_MSB 7
183#define RX_LOOKAHEAD3_DATA_LSB 0
184#define RX_LOOKAHEAD3_DATA_MASK 0x000000ff
185#define RX_LOOKAHEAD3_DATA_GET(x) (((x) & RX_LOOKAHEAD3_DATA_MASK) >> RX_LOOKAHEAD3_DATA_LSB)
186#define RX_LOOKAHEAD3_DATA_SET(x) (((x) << RX_LOOKAHEAD3_DATA_LSB) & RX_LOOKAHEAD3_DATA_MASK)
187
188#define INT_STATUS_ENABLE_ADDRESS 0x00000418
189#define INT_STATUS_ENABLE_OFFSET 0x00000418
190#define INT_STATUS_ENABLE_ERROR_MSB 7
191#define INT_STATUS_ENABLE_ERROR_LSB 7
192#define INT_STATUS_ENABLE_ERROR_MASK 0x00000080
193#define INT_STATUS_ENABLE_ERROR_GET(x) (((x) & INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB)
194#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK)
195#define INT_STATUS_ENABLE_CPU_MSB 6
196#define INT_STATUS_ENABLE_CPU_LSB 6
197#define INT_STATUS_ENABLE_CPU_MASK 0x00000040
198#define INT_STATUS_ENABLE_CPU_GET(x) (((x) & INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB)
199#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK)
200#define INT_STATUS_ENABLE_INT_MSB 5
201#define INT_STATUS_ENABLE_INT_LSB 5
202#define INT_STATUS_ENABLE_INT_MASK 0x00000020
203#define INT_STATUS_ENABLE_INT_GET(x) (((x) & INT_STATUS_ENABLE_INT_MASK) >> INT_STATUS_ENABLE_INT_LSB)
204#define INT_STATUS_ENABLE_INT_SET(x) (((x) << INT_STATUS_ENABLE_INT_LSB) & INT_STATUS_ENABLE_INT_MASK)
205#define INT_STATUS_ENABLE_COUNTER_MSB 4
206#define INT_STATUS_ENABLE_COUNTER_LSB 4
207#define INT_STATUS_ENABLE_COUNTER_MASK 0x00000010
208#define INT_STATUS_ENABLE_COUNTER_GET(x) (((x) & INT_STATUS_ENABLE_COUNTER_MASK) >> INT_STATUS_ENABLE_COUNTER_LSB)
209#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK)
210#define INT_STATUS_ENABLE_MBOX_DATA_MSB 3
211#define INT_STATUS_ENABLE_MBOX_DATA_LSB 0
212#define INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f
213#define INT_STATUS_ENABLE_MBOX_DATA_GET(x) (((x) & INT_STATUS_ENABLE_MBOX_DATA_MASK) >> INT_STATUS_ENABLE_MBOX_DATA_LSB)
214#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK)
215
216#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419
217#define CPU_INT_STATUS_ENABLE_OFFSET 0x00000419
218#define CPU_INT_STATUS_ENABLE_BIT_MSB 7
219#define CPU_INT_STATUS_ENABLE_BIT_LSB 0
220#define CPU_INT_STATUS_ENABLE_BIT_MASK 0x000000ff
221#define CPU_INT_STATUS_ENABLE_BIT_GET(x) (((x) & CPU_INT_STATUS_ENABLE_BIT_MASK) >> CPU_INT_STATUS_ENABLE_BIT_LSB)
222#define CPU_INT_STATUS_ENABLE_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK)
223
224#define ERROR_STATUS_ENABLE_ADDRESS 0x0000041a
225#define ERROR_STATUS_ENABLE_OFFSET 0x0000041a
226#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MSB 6
227#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB 6
228#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK 0x00000040
229#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB)
230#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK)
231#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MSB 5
232#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB 5
233#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK 0x00000020
234#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB)
235#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK)
236#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MSB 4
237#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB 4
238#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK 0x00000010
239#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB)
240#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK)
241#define ERROR_STATUS_ENABLE_WAKEUP_MSB 2
242#define ERROR_STATUS_ENABLE_WAKEUP_LSB 2
243#define ERROR_STATUS_ENABLE_WAKEUP_MASK 0x00000004
244#define ERROR_STATUS_ENABLE_WAKEUP_GET(x) (((x) & ERROR_STATUS_ENABLE_WAKEUP_MASK) >> ERROR_STATUS_ENABLE_WAKEUP_LSB)
245#define ERROR_STATUS_ENABLE_WAKEUP_SET(x) (((x) << ERROR_STATUS_ENABLE_WAKEUP_LSB) & ERROR_STATUS_ENABLE_WAKEUP_MASK)
246#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB 1
247#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 1
248#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00000002
249#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB)
250#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
251#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB 0
252#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 0
253#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00000001
254#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB)
255#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
256
257#define COUNTER_INT_STATUS_ENABLE_ADDRESS 0x0000041b
258#define COUNTER_INT_STATUS_ENABLE_OFFSET 0x0000041b
259#define COUNTER_INT_STATUS_ENABLE_BIT_MSB 7
260#define COUNTER_INT_STATUS_ENABLE_BIT_LSB 0
261#define COUNTER_INT_STATUS_ENABLE_BIT_MASK 0x000000ff
262#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x) (((x) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> COUNTER_INT_STATUS_ENABLE_BIT_LSB)
263#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK)
264
265#define COUNT_ADDRESS 0x00000420
266#define COUNT_OFFSET 0x00000420
267#define COUNT_VALUE_MSB 7
268#define COUNT_VALUE_LSB 0
269#define COUNT_VALUE_MASK 0x000000ff
270#define COUNT_VALUE_GET(x) (((x) & COUNT_VALUE_MASK) >> COUNT_VALUE_LSB)
271#define COUNT_VALUE_SET(x) (((x) << COUNT_VALUE_LSB) & COUNT_VALUE_MASK)
272
273#define COUNT_DEC_ADDRESS 0x00000440
274#define COUNT_DEC_OFFSET 0x00000440
275#define COUNT_DEC_VALUE_MSB 7
276#define COUNT_DEC_VALUE_LSB 0
277#define COUNT_DEC_VALUE_MASK 0x000000ff
278#define COUNT_DEC_VALUE_GET(x) (((x) & COUNT_DEC_VALUE_MASK) >> COUNT_DEC_VALUE_LSB)
279#define COUNT_DEC_VALUE_SET(x) (((x) << COUNT_DEC_VALUE_LSB) & COUNT_DEC_VALUE_MASK)
280
281#define SCRATCH_ADDRESS 0x00000460
282#define SCRATCH_OFFSET 0x00000460
283#define SCRATCH_VALUE_MSB 7
284#define SCRATCH_VALUE_LSB 0
285#define SCRATCH_VALUE_MASK 0x000000ff
286#define SCRATCH_VALUE_GET(x) (((x) & SCRATCH_VALUE_MASK) >> SCRATCH_VALUE_LSB)
287#define SCRATCH_VALUE_SET(x) (((x) << SCRATCH_VALUE_LSB) & SCRATCH_VALUE_MASK)
288
289#define FIFO_TIMEOUT_ADDRESS 0x00000468
290#define FIFO_TIMEOUT_OFFSET 0x00000468
291#define FIFO_TIMEOUT_VALUE_MSB 7
292#define FIFO_TIMEOUT_VALUE_LSB 0
293#define FIFO_TIMEOUT_VALUE_MASK 0x000000ff
294#define FIFO_TIMEOUT_VALUE_GET(x) (((x) & FIFO_TIMEOUT_VALUE_MASK) >> FIFO_TIMEOUT_VALUE_LSB)
295#define FIFO_TIMEOUT_VALUE_SET(x) (((x) << FIFO_TIMEOUT_VALUE_LSB) & FIFO_TIMEOUT_VALUE_MASK)
296
297#define FIFO_TIMEOUT_ENABLE_ADDRESS 0x00000469
298#define FIFO_TIMEOUT_ENABLE_OFFSET 0x00000469
299#define FIFO_TIMEOUT_ENABLE_SET_MSB 0
300#define FIFO_TIMEOUT_ENABLE_SET_LSB 0
301#define FIFO_TIMEOUT_ENABLE_SET_MASK 0x00000001
302#define FIFO_TIMEOUT_ENABLE_SET_GET(x) (((x) & FIFO_TIMEOUT_ENABLE_SET_MASK) >> FIFO_TIMEOUT_ENABLE_SET_LSB)
303#define FIFO_TIMEOUT_ENABLE_SET_SET(x) (((x) << FIFO_TIMEOUT_ENABLE_SET_LSB) & FIFO_TIMEOUT_ENABLE_SET_MASK)
304
305#define DISABLE_SLEEP_ADDRESS 0x0000046a
306#define DISABLE_SLEEP_OFFSET 0x0000046a
307#define DISABLE_SLEEP_FOR_INT_MSB 1
308#define DISABLE_SLEEP_FOR_INT_LSB 1
309#define DISABLE_SLEEP_FOR_INT_MASK 0x00000002
310#define DISABLE_SLEEP_FOR_INT_GET(x) (((x) & DISABLE_SLEEP_FOR_INT_MASK) >> DISABLE_SLEEP_FOR_INT_LSB)
311#define DISABLE_SLEEP_FOR_INT_SET(x) (((x) << DISABLE_SLEEP_FOR_INT_LSB) & DISABLE_SLEEP_FOR_INT_MASK)
312#define DISABLE_SLEEP_ON_MSB 0
313#define DISABLE_SLEEP_ON_LSB 0
314#define DISABLE_SLEEP_ON_MASK 0x00000001
315#define DISABLE_SLEEP_ON_GET(x) (((x) & DISABLE_SLEEP_ON_MASK) >> DISABLE_SLEEP_ON_LSB)
316#define DISABLE_SLEEP_ON_SET(x) (((x) << DISABLE_SLEEP_ON_LSB) & DISABLE_SLEEP_ON_MASK)
317
318#define LOCAL_BUS_ADDRESS 0x00000470
319#define LOCAL_BUS_OFFSET 0x00000470
320#define LOCAL_BUS_STATE_MSB 1
321#define LOCAL_BUS_STATE_LSB 0
322#define LOCAL_BUS_STATE_MASK 0x00000003
323#define LOCAL_BUS_STATE_GET(x) (((x) & LOCAL_BUS_STATE_MASK) >> LOCAL_BUS_STATE_LSB)
324#define LOCAL_BUS_STATE_SET(x) (((x) << LOCAL_BUS_STATE_LSB) & LOCAL_BUS_STATE_MASK)
325
326#define INT_WLAN_ADDRESS 0x00000472
327#define INT_WLAN_OFFSET 0x00000472
328#define INT_WLAN_VECTOR_MSB 7
329#define INT_WLAN_VECTOR_LSB 0
330#define INT_WLAN_VECTOR_MASK 0x000000ff
331#define INT_WLAN_VECTOR_GET(x) (((x) & INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB)
332#define INT_WLAN_VECTOR_SET(x) (((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK)
333
334#define WINDOW_DATA_ADDRESS 0x00000474
335#define WINDOW_DATA_OFFSET 0x00000474
336#define WINDOW_DATA_DATA_MSB 7
337#define WINDOW_DATA_DATA_LSB 0
338#define WINDOW_DATA_DATA_MASK 0x000000ff
339#define WINDOW_DATA_DATA_GET(x) (((x) & WINDOW_DATA_DATA_MASK) >> WINDOW_DATA_DATA_LSB)
340#define WINDOW_DATA_DATA_SET(x) (((x) << WINDOW_DATA_DATA_LSB) & WINDOW_DATA_DATA_MASK)
341
342#define WINDOW_WRITE_ADDR_ADDRESS 0x00000478
343#define WINDOW_WRITE_ADDR_OFFSET 0x00000478
344#define WINDOW_WRITE_ADDR_ADDR_MSB 7
345#define WINDOW_WRITE_ADDR_ADDR_LSB 0
346#define WINDOW_WRITE_ADDR_ADDR_MASK 0x000000ff
347#define WINDOW_WRITE_ADDR_ADDR_GET(x) (((x) & WINDOW_WRITE_ADDR_ADDR_MASK) >> WINDOW_WRITE_ADDR_ADDR_LSB)
348#define WINDOW_WRITE_ADDR_ADDR_SET(x) (((x) << WINDOW_WRITE_ADDR_ADDR_LSB) & WINDOW_WRITE_ADDR_ADDR_MASK)
349
350#define WINDOW_READ_ADDR_ADDRESS 0x0000047c
351#define WINDOW_READ_ADDR_OFFSET 0x0000047c
352#define WINDOW_READ_ADDR_ADDR_MSB 7
353#define WINDOW_READ_ADDR_ADDR_LSB 0
354#define WINDOW_READ_ADDR_ADDR_MASK 0x000000ff
355#define WINDOW_READ_ADDR_ADDR_GET(x) (((x) & WINDOW_READ_ADDR_ADDR_MASK) >> WINDOW_READ_ADDR_ADDR_LSB)
356#define WINDOW_READ_ADDR_ADDR_SET(x) (((x) << WINDOW_READ_ADDR_ADDR_LSB) & WINDOW_READ_ADDR_ADDR_MASK)
357
358#define HOST_CTRL_SPI_CONFIG_ADDRESS 0x00000480
359#define HOST_CTRL_SPI_CONFIG_OFFSET 0x00000480
360#define HOST_CTRL_SPI_CONFIG_SPI_RESET_MSB 4
361#define HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB 4
362#define HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK 0x00000010
363#define HOST_CTRL_SPI_CONFIG_SPI_RESET_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK) >> HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB)
364#define HOST_CTRL_SPI_CONFIG_SPI_RESET_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB) & HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK)
365#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MSB 3
366#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB 3
367#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK 0x00000008
368#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK) >> HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB)
369#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB) & HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK)
370#define HOST_CTRL_SPI_CONFIG_TEST_MODE_MSB 2
371#define HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB 2
372#define HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK 0x00000004
373#define HOST_CTRL_SPI_CONFIG_TEST_MODE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK) >> HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB)
374#define HOST_CTRL_SPI_CONFIG_TEST_MODE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB) & HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK)
375#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_MSB 1
376#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB 0
377#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK 0x00000003
378#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK) >> HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB)
379#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB) & HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK)
380
381#define HOST_CTRL_SPI_STATUS_ADDRESS 0x00000481
382#define HOST_CTRL_SPI_STATUS_OFFSET 0x00000481
383#define HOST_CTRL_SPI_STATUS_ADDR_ERR_MSB 3
384#define HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB 3
385#define HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK 0x00000008
386#define HOST_CTRL_SPI_STATUS_ADDR_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK) >> HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB)
387#define HOST_CTRL_SPI_STATUS_ADDR_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB) & HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK)
388#define HOST_CTRL_SPI_STATUS_RD_ERR_MSB 2
389#define HOST_CTRL_SPI_STATUS_RD_ERR_LSB 2
390#define HOST_CTRL_SPI_STATUS_RD_ERR_MASK 0x00000004
391#define HOST_CTRL_SPI_STATUS_RD_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_RD_ERR_MASK) >> HOST_CTRL_SPI_STATUS_RD_ERR_LSB)
392#define HOST_CTRL_SPI_STATUS_RD_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_RD_ERR_LSB) & HOST_CTRL_SPI_STATUS_RD_ERR_MASK)
393#define HOST_CTRL_SPI_STATUS_WR_ERR_MSB 1
394#define HOST_CTRL_SPI_STATUS_WR_ERR_LSB 1
395#define HOST_CTRL_SPI_STATUS_WR_ERR_MASK 0x00000002
396#define HOST_CTRL_SPI_STATUS_WR_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_WR_ERR_MASK) >> HOST_CTRL_SPI_STATUS_WR_ERR_LSB)
397#define HOST_CTRL_SPI_STATUS_WR_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_WR_ERR_LSB) & HOST_CTRL_SPI_STATUS_WR_ERR_MASK)
398#define HOST_CTRL_SPI_STATUS_READY_MSB 0
399#define HOST_CTRL_SPI_STATUS_READY_LSB 0
400#define HOST_CTRL_SPI_STATUS_READY_MASK 0x00000001
401#define HOST_CTRL_SPI_STATUS_READY_GET(x) (((x) & HOST_CTRL_SPI_STATUS_READY_MASK) >> HOST_CTRL_SPI_STATUS_READY_LSB)
402#define HOST_CTRL_SPI_STATUS_READY_SET(x) (((x) << HOST_CTRL_SPI_STATUS_READY_LSB) & HOST_CTRL_SPI_STATUS_READY_MASK)
403
404#define NON_ASSOC_SLEEP_EN_ADDRESS 0x00000482
405#define NON_ASSOC_SLEEP_EN_OFFSET 0x00000482
406#define NON_ASSOC_SLEEP_EN_BIT_MSB 0
407#define NON_ASSOC_SLEEP_EN_BIT_LSB 0
408#define NON_ASSOC_SLEEP_EN_BIT_MASK 0x00000001
409#define NON_ASSOC_SLEEP_EN_BIT_GET(x) (((x) & NON_ASSOC_SLEEP_EN_BIT_MASK) >> NON_ASSOC_SLEEP_EN_BIT_LSB)
410#define NON_ASSOC_SLEEP_EN_BIT_SET(x) (((x) << NON_ASSOC_SLEEP_EN_BIT_LSB) & NON_ASSOC_SLEEP_EN_BIT_MASK)
411
412#define CPU_DBG_SEL_ADDRESS 0x00000483
413#define CPU_DBG_SEL_OFFSET 0x00000483
414#define CPU_DBG_SEL_BIT_MSB 5
415#define CPU_DBG_SEL_BIT_LSB 0
416#define CPU_DBG_SEL_BIT_MASK 0x0000003f
417#define CPU_DBG_SEL_BIT_GET(x) (((x) & CPU_DBG_SEL_BIT_MASK) >> CPU_DBG_SEL_BIT_LSB)
418#define CPU_DBG_SEL_BIT_SET(x) (((x) << CPU_DBG_SEL_BIT_LSB) & CPU_DBG_SEL_BIT_MASK)
419
420#define CPU_DBG_ADDRESS 0x00000484
421#define CPU_DBG_OFFSET 0x00000484
422#define CPU_DBG_DATA_MSB 7
423#define CPU_DBG_DATA_LSB 0
424#define CPU_DBG_DATA_MASK 0x000000ff
425#define CPU_DBG_DATA_GET(x) (((x) & CPU_DBG_DATA_MASK) >> CPU_DBG_DATA_LSB)
426#define CPU_DBG_DATA_SET(x) (((x) << CPU_DBG_DATA_LSB) & CPU_DBG_DATA_MASK)
427
428#define INT_STATUS2_ENABLE_ADDRESS 0x00000488
429#define INT_STATUS2_ENABLE_OFFSET 0x00000488
430#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MSB 2
431#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB 2
432#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK 0x00000004
433#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK) >> INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB)
434#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB) & INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK)
435#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MSB 1
436#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB 1
437#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK 0x00000002
438#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK) >> INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB)
439#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB) & INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK)
440#define INT_STATUS2_ENABLE_GMBOX_DATA_MSB 0
441#define INT_STATUS2_ENABLE_GMBOX_DATA_LSB 0
442#define INT_STATUS2_ENABLE_GMBOX_DATA_MASK 0x00000001
443#define INT_STATUS2_ENABLE_GMBOX_DATA_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_DATA_MASK) >> INT_STATUS2_ENABLE_GMBOX_DATA_LSB)
444#define INT_STATUS2_ENABLE_GMBOX_DATA_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_DATA_LSB) & INT_STATUS2_ENABLE_GMBOX_DATA_MASK)
445
446#define GMBOX_RX_LOOKAHEAD_ADDRESS 0x00000490
447#define GMBOX_RX_LOOKAHEAD_OFFSET 0x00000490
448#define GMBOX_RX_LOOKAHEAD_DATA_MSB 7
449#define GMBOX_RX_LOOKAHEAD_DATA_LSB 0
450#define GMBOX_RX_LOOKAHEAD_DATA_MASK 0x000000ff
451#define GMBOX_RX_LOOKAHEAD_DATA_GET(x) (((x) & GMBOX_RX_LOOKAHEAD_DATA_MASK) >> GMBOX_RX_LOOKAHEAD_DATA_LSB)
452#define GMBOX_RX_LOOKAHEAD_DATA_SET(x) (((x) << GMBOX_RX_LOOKAHEAD_DATA_LSB) & GMBOX_RX_LOOKAHEAD_DATA_MASK)
453
454#define GMBOX_RX_LOOKAHEAD_MUX_ADDRESS 0x00000498
455#define GMBOX_RX_LOOKAHEAD_MUX_OFFSET 0x00000498
456#define GMBOX_RX_LOOKAHEAD_MUX_SEL_MSB 0
457#define GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB 0
458#define GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK 0x00000001
459#define GMBOX_RX_LOOKAHEAD_MUX_SEL_GET(x) (((x) & GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK) >> GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB)
460#define GMBOX_RX_LOOKAHEAD_MUX_SEL_SET(x) (((x) << GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB) & GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK)
461
462#define CIS_WINDOW_ADDRESS 0x00000600
463#define CIS_WINDOW_OFFSET 0x00000600
464#define CIS_WINDOW_DATA_MSB 7
465#define CIS_WINDOW_DATA_LSB 0
466#define CIS_WINDOW_DATA_MASK 0x000000ff
467#define CIS_WINDOW_DATA_GET(x) (((x) & CIS_WINDOW_DATA_MASK) >> CIS_WINDOW_DATA_LSB)
468#define CIS_WINDOW_DATA_SET(x) (((x) << CIS_WINDOW_DATA_LSB) & CIS_WINDOW_DATA_MASK)
469
470
471#endif /* _MBOX_WLAN_HOST_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h
new file mode 100644
index 00000000000..f5167b9ae8d
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h
@@ -0,0 +1,589 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#ifndef _MBOX_WLAN_REG_REG_H_
25#define _MBOX_WLAN_REG_REG_H_
26
27#define WLAN_MBOX_FIFO_ADDRESS 0x00000000
28#define WLAN_MBOX_FIFO_OFFSET 0x00000000
29#define WLAN_MBOX_FIFO_DATA_MSB 19
30#define WLAN_MBOX_FIFO_DATA_LSB 0
31#define WLAN_MBOX_FIFO_DATA_MASK 0x000fffff
32#define WLAN_MBOX_FIFO_DATA_GET(x) (((x) & WLAN_MBOX_FIFO_DATA_MASK) >> WLAN_MBOX_FIFO_DATA_LSB)
33#define WLAN_MBOX_FIFO_DATA_SET(x) (((x) << WLAN_MBOX_FIFO_DATA_LSB) & WLAN_MBOX_FIFO_DATA_MASK)
34
35#define WLAN_MBOX_FIFO_STATUS_ADDRESS 0x00000010
36#define WLAN_MBOX_FIFO_STATUS_OFFSET 0x00000010
37#define WLAN_MBOX_FIFO_STATUS_EMPTY_MSB 19
38#define WLAN_MBOX_FIFO_STATUS_EMPTY_LSB 16
39#define WLAN_MBOX_FIFO_STATUS_EMPTY_MASK 0x000f0000
40#define WLAN_MBOX_FIFO_STATUS_EMPTY_GET(x) (((x) & WLAN_MBOX_FIFO_STATUS_EMPTY_MASK) >> WLAN_MBOX_FIFO_STATUS_EMPTY_LSB)
41#define WLAN_MBOX_FIFO_STATUS_EMPTY_SET(x) (((x) << WLAN_MBOX_FIFO_STATUS_EMPTY_LSB) & WLAN_MBOX_FIFO_STATUS_EMPTY_MASK)
42#define WLAN_MBOX_FIFO_STATUS_FULL_MSB 15
43#define WLAN_MBOX_FIFO_STATUS_FULL_LSB 12
44#define WLAN_MBOX_FIFO_STATUS_FULL_MASK 0x0000f000
45#define WLAN_MBOX_FIFO_STATUS_FULL_GET(x) (((x) & WLAN_MBOX_FIFO_STATUS_FULL_MASK) >> WLAN_MBOX_FIFO_STATUS_FULL_LSB)
46#define WLAN_MBOX_FIFO_STATUS_FULL_SET(x) (((x) << WLAN_MBOX_FIFO_STATUS_FULL_LSB) & WLAN_MBOX_FIFO_STATUS_FULL_MASK)
47
48#define WLAN_MBOX_DMA_POLICY_ADDRESS 0x00000014
49#define WLAN_MBOX_DMA_POLICY_OFFSET 0x00000014
50#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MSB 3
51#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB 3
52#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK 0x00000008
53#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK) >> WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB)
54#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB) & WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK)
55#define WLAN_MBOX_DMA_POLICY_TX_ORDER_MSB 2
56#define WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB 2
57#define WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK 0x00000004
58#define WLAN_MBOX_DMA_POLICY_TX_ORDER_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK) >> WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB)
59#define WLAN_MBOX_DMA_POLICY_TX_ORDER_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB) & WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK)
60#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MSB 1
61#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB 1
62#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK 0x00000002
63#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK) >> WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB)
64#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB) & WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK)
65#define WLAN_MBOX_DMA_POLICY_RX_ORDER_MSB 0
66#define WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB 0
67#define WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK 0x00000001
68#define WLAN_MBOX_DMA_POLICY_RX_ORDER_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK) >> WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB)
69#define WLAN_MBOX_DMA_POLICY_RX_ORDER_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB) & WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK)
70
71#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000018
72#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000018
73#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
74#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
75#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
76#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
77#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
78
79#define WLAN_MBOX0_DMA_RX_CONTROL_ADDRESS 0x0000001c
80#define WLAN_MBOX0_DMA_RX_CONTROL_OFFSET 0x0000001c
81#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MSB 2
82#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB 2
83#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004
84#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB)
85#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK)
86#define WLAN_MBOX0_DMA_RX_CONTROL_START_MSB 1
87#define WLAN_MBOX0_DMA_RX_CONTROL_START_LSB 1
88#define WLAN_MBOX0_DMA_RX_CONTROL_START_MASK 0x00000002
89#define WLAN_MBOX0_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_START_LSB)
90#define WLAN_MBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_START_MASK)
91#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_MSB 0
92#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB 0
93#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001
94#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB)
95#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK)
96
97#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000020
98#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000020
99#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
100#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
101#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
102#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
103#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
104
105#define WLAN_MBOX0_DMA_TX_CONTROL_ADDRESS 0x00000024
106#define WLAN_MBOX0_DMA_TX_CONTROL_OFFSET 0x00000024
107#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MSB 2
108#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB 2
109#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004
110#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB)
111#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK)
112#define WLAN_MBOX0_DMA_TX_CONTROL_START_MSB 1
113#define WLAN_MBOX0_DMA_TX_CONTROL_START_LSB 1
114#define WLAN_MBOX0_DMA_TX_CONTROL_START_MASK 0x00000002
115#define WLAN_MBOX0_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_START_LSB)
116#define WLAN_MBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_START_MASK)
117#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_MSB 0
118#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB 0
119#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001
120#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB)
121#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK)
122
123#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000028
124#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000028
125#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
126#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
127#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
128#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
129#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
130
131#define WLAN_MBOX1_DMA_RX_CONTROL_ADDRESS 0x0000002c
132#define WLAN_MBOX1_DMA_RX_CONTROL_OFFSET 0x0000002c
133#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MSB 2
134#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB 2
135#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK 0x00000004
136#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB)
137#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK)
138#define WLAN_MBOX1_DMA_RX_CONTROL_START_MSB 1
139#define WLAN_MBOX1_DMA_RX_CONTROL_START_LSB 1
140#define WLAN_MBOX1_DMA_RX_CONTROL_START_MASK 0x00000002
141#define WLAN_MBOX1_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_START_LSB)
142#define WLAN_MBOX1_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_START_MASK)
143#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_MSB 0
144#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB 0
145#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK 0x00000001
146#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB)
147#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK)
148
149#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000030
150#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000030
151#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
152#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
153#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
154#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
155#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
156
157#define WLAN_MBOX1_DMA_TX_CONTROL_ADDRESS 0x00000034
158#define WLAN_MBOX1_DMA_TX_CONTROL_OFFSET 0x00000034
159#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MSB 2
160#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB 2
161#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK 0x00000004
162#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB)
163#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK)
164#define WLAN_MBOX1_DMA_TX_CONTROL_START_MSB 1
165#define WLAN_MBOX1_DMA_TX_CONTROL_START_LSB 1
166#define WLAN_MBOX1_DMA_TX_CONTROL_START_MASK 0x00000002
167#define WLAN_MBOX1_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_START_LSB)
168#define WLAN_MBOX1_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_START_MASK)
169#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_MSB 0
170#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB 0
171#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK 0x00000001
172#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB)
173#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK)
174
175#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000038
176#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000038
177#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
178#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
179#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
180#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
181#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
182
183#define WLAN_MBOX2_DMA_RX_CONTROL_ADDRESS 0x0000003c
184#define WLAN_MBOX2_DMA_RX_CONTROL_OFFSET 0x0000003c
185#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MSB 2
186#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB 2
187#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK 0x00000004
188#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB)
189#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK)
190#define WLAN_MBOX2_DMA_RX_CONTROL_START_MSB 1
191#define WLAN_MBOX2_DMA_RX_CONTROL_START_LSB 1
192#define WLAN_MBOX2_DMA_RX_CONTROL_START_MASK 0x00000002
193#define WLAN_MBOX2_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_START_LSB)
194#define WLAN_MBOX2_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_START_MASK)
195#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_MSB 0
196#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB 0
197#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK 0x00000001
198#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB)
199#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK)
200
201#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000040
202#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000040
203#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
204#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
205#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
206#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
207#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
208
209#define WLAN_MBOX2_DMA_TX_CONTROL_ADDRESS 0x00000044
210#define WLAN_MBOX2_DMA_TX_CONTROL_OFFSET 0x00000044
211#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MSB 2
212#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB 2
213#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK 0x00000004
214#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB)
215#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK)
216#define WLAN_MBOX2_DMA_TX_CONTROL_START_MSB 1
217#define WLAN_MBOX2_DMA_TX_CONTROL_START_LSB 1
218#define WLAN_MBOX2_DMA_TX_CONTROL_START_MASK 0x00000002
219#define WLAN_MBOX2_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_START_LSB)
220#define WLAN_MBOX2_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_START_MASK)
221#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_MSB 0
222#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB 0
223#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK 0x00000001
224#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB)
225#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK)
226
227#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000048
228#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000048
229#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
230#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
231#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
232#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
233#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
234
235#define WLAN_MBOX3_DMA_RX_CONTROL_ADDRESS 0x0000004c
236#define WLAN_MBOX3_DMA_RX_CONTROL_OFFSET 0x0000004c
237#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MSB 2
238#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB 2
239#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK 0x00000004
240#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB)
241#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK)
242#define WLAN_MBOX3_DMA_RX_CONTROL_START_MSB 1
243#define WLAN_MBOX3_DMA_RX_CONTROL_START_LSB 1
244#define WLAN_MBOX3_DMA_RX_CONTROL_START_MASK 0x00000002
245#define WLAN_MBOX3_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_START_LSB)
246#define WLAN_MBOX3_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_START_MASK)
247#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_MSB 0
248#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB 0
249#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK 0x00000001
250#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB)
251#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK)
252
253#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000050
254#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000050
255#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
256#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
257#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
258#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
259#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
260
261#define WLAN_MBOX3_DMA_TX_CONTROL_ADDRESS 0x00000054
262#define WLAN_MBOX3_DMA_TX_CONTROL_OFFSET 0x00000054
263#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MSB 2
264#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB 2
265#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK 0x00000004
266#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB)
267#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK)
268#define WLAN_MBOX3_DMA_TX_CONTROL_START_MSB 1
269#define WLAN_MBOX3_DMA_TX_CONTROL_START_LSB 1
270#define WLAN_MBOX3_DMA_TX_CONTROL_START_MASK 0x00000002
271#define WLAN_MBOX3_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_START_LSB)
272#define WLAN_MBOX3_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_START_MASK)
273#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_MSB 0
274#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB 0
275#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK 0x00000001
276#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB)
277#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK)
278
279#define WLAN_MBOX_INT_STATUS_ADDRESS 0x00000058
280#define WLAN_MBOX_INT_STATUS_OFFSET 0x00000058
281#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 31
282#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 28
283#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0xf0000000
284#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
285#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
286#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 27
287#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 24
288#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
289#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
290#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
291#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 23
292#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 20
293#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00f00000
294#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
295#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
296#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MSB 17
297#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB 17
298#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00020000
299#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK) >> WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB)
300#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB) & WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK)
301#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MSB 16
302#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB 16
303#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00010000
304#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB)
305#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB) & WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK)
306#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MSB 15
307#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB 12
308#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x0000f000
309#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
310#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
311#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MSB 11
312#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB 8
313#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000f00
314#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK) >> WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB)
315#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB) & WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK)
316#define WLAN_MBOX_INT_STATUS_HOST_MSB 7
317#define WLAN_MBOX_INT_STATUS_HOST_LSB 0
318#define WLAN_MBOX_INT_STATUS_HOST_MASK 0x000000ff
319#define WLAN_MBOX_INT_STATUS_HOST_GET(x) (((x) & WLAN_MBOX_INT_STATUS_HOST_MASK) >> WLAN_MBOX_INT_STATUS_HOST_LSB)
320#define WLAN_MBOX_INT_STATUS_HOST_SET(x) (((x) << WLAN_MBOX_INT_STATUS_HOST_LSB) & WLAN_MBOX_INT_STATUS_HOST_MASK)
321
322#define WLAN_MBOX_INT_ENABLE_ADDRESS 0x0000005c
323#define WLAN_MBOX_INT_ENABLE_OFFSET 0x0000005c
324#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 31
325#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 28
326#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0xf0000000
327#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
328#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
329#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 27
330#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 24
331#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
332#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
333#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
334#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 23
335#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 20
336#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00f00000
337#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
338#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
339#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MSB 17
340#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB 17
341#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00020000
342#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB)
343#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB) & WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK)
344#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MSB 16
345#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB 16
346#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00010000
347#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
348#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
349#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 15
350#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 12
351#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x0000f000
352#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
353#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
354#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MSB 11
355#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB 8
356#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000f00
357#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB)
358#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB) & WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK)
359#define WLAN_MBOX_INT_ENABLE_HOST_MSB 7
360#define WLAN_MBOX_INT_ENABLE_HOST_LSB 0
361#define WLAN_MBOX_INT_ENABLE_HOST_MASK 0x000000ff
362#define WLAN_MBOX_INT_ENABLE_HOST_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_HOST_MASK) >> WLAN_MBOX_INT_ENABLE_HOST_LSB)
363#define WLAN_MBOX_INT_ENABLE_HOST_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_HOST_LSB) & WLAN_MBOX_INT_ENABLE_HOST_MASK)
364
365#define WLAN_INT_HOST_ADDRESS 0x00000060
366#define WLAN_INT_HOST_OFFSET 0x00000060
367#define WLAN_INT_HOST_VECTOR_MSB 7
368#define WLAN_INT_HOST_VECTOR_LSB 0
369#define WLAN_INT_HOST_VECTOR_MASK 0x000000ff
370#define WLAN_INT_HOST_VECTOR_GET(x) (((x) & WLAN_INT_HOST_VECTOR_MASK) >> WLAN_INT_HOST_VECTOR_LSB)
371#define WLAN_INT_HOST_VECTOR_SET(x) (((x) << WLAN_INT_HOST_VECTOR_LSB) & WLAN_INT_HOST_VECTOR_MASK)
372
373#define WLAN_LOCAL_COUNT_ADDRESS 0x00000080
374#define WLAN_LOCAL_COUNT_OFFSET 0x00000080
375#define WLAN_LOCAL_COUNT_VALUE_MSB 7
376#define WLAN_LOCAL_COUNT_VALUE_LSB 0
377#define WLAN_LOCAL_COUNT_VALUE_MASK 0x000000ff
378#define WLAN_LOCAL_COUNT_VALUE_GET(x) (((x) & WLAN_LOCAL_COUNT_VALUE_MASK) >> WLAN_LOCAL_COUNT_VALUE_LSB)
379#define WLAN_LOCAL_COUNT_VALUE_SET(x) (((x) << WLAN_LOCAL_COUNT_VALUE_LSB) & WLAN_LOCAL_COUNT_VALUE_MASK)
380
381#define WLAN_COUNT_INC_ADDRESS 0x000000a0
382#define WLAN_COUNT_INC_OFFSET 0x000000a0
383#define WLAN_COUNT_INC_VALUE_MSB 7
384#define WLAN_COUNT_INC_VALUE_LSB 0
385#define WLAN_COUNT_INC_VALUE_MASK 0x000000ff
386#define WLAN_COUNT_INC_VALUE_GET(x) (((x) & WLAN_COUNT_INC_VALUE_MASK) >> WLAN_COUNT_INC_VALUE_LSB)
387#define WLAN_COUNT_INC_VALUE_SET(x) (((x) << WLAN_COUNT_INC_VALUE_LSB) & WLAN_COUNT_INC_VALUE_MASK)
388
389#define WLAN_LOCAL_SCRATCH_ADDRESS 0x000000c0
390#define WLAN_LOCAL_SCRATCH_OFFSET 0x000000c0
391#define WLAN_LOCAL_SCRATCH_VALUE_MSB 7
392#define WLAN_LOCAL_SCRATCH_VALUE_LSB 0
393#define WLAN_LOCAL_SCRATCH_VALUE_MASK 0x000000ff
394#define WLAN_LOCAL_SCRATCH_VALUE_GET(x) (((x) & WLAN_LOCAL_SCRATCH_VALUE_MASK) >> WLAN_LOCAL_SCRATCH_VALUE_LSB)
395#define WLAN_LOCAL_SCRATCH_VALUE_SET(x) (((x) << WLAN_LOCAL_SCRATCH_VALUE_LSB) & WLAN_LOCAL_SCRATCH_VALUE_MASK)
396
397#define WLAN_USE_LOCAL_BUS_ADDRESS 0x000000e0
398#define WLAN_USE_LOCAL_BUS_OFFSET 0x000000e0
399#define WLAN_USE_LOCAL_BUS_PIN_INIT_MSB 0
400#define WLAN_USE_LOCAL_BUS_PIN_INIT_LSB 0
401#define WLAN_USE_LOCAL_BUS_PIN_INIT_MASK 0x00000001
402#define WLAN_USE_LOCAL_BUS_PIN_INIT_GET(x) (((x) & WLAN_USE_LOCAL_BUS_PIN_INIT_MASK) >> WLAN_USE_LOCAL_BUS_PIN_INIT_LSB)
403#define WLAN_USE_LOCAL_BUS_PIN_INIT_SET(x) (((x) << WLAN_USE_LOCAL_BUS_PIN_INIT_LSB) & WLAN_USE_LOCAL_BUS_PIN_INIT_MASK)
404
405#define WLAN_SDIO_CONFIG_ADDRESS 0x000000e4
406#define WLAN_SDIO_CONFIG_OFFSET 0x000000e4
407#define WLAN_SDIO_CONFIG_CCCR_IOR1_MSB 0
408#define WLAN_SDIO_CONFIG_CCCR_IOR1_LSB 0
409#define WLAN_SDIO_CONFIG_CCCR_IOR1_MASK 0x00000001
410#define WLAN_SDIO_CONFIG_CCCR_IOR1_GET(x) (((x) & WLAN_SDIO_CONFIG_CCCR_IOR1_MASK) >> WLAN_SDIO_CONFIG_CCCR_IOR1_LSB)
411#define WLAN_SDIO_CONFIG_CCCR_IOR1_SET(x) (((x) << WLAN_SDIO_CONFIG_CCCR_IOR1_LSB) & WLAN_SDIO_CONFIG_CCCR_IOR1_MASK)
412
413#define WLAN_MBOX_DEBUG_ADDRESS 0x000000e8
414#define WLAN_MBOX_DEBUG_OFFSET 0x000000e8
415#define WLAN_MBOX_DEBUG_SEL_MSB 2
416#define WLAN_MBOX_DEBUG_SEL_LSB 0
417#define WLAN_MBOX_DEBUG_SEL_MASK 0x00000007
418#define WLAN_MBOX_DEBUG_SEL_GET(x) (((x) & WLAN_MBOX_DEBUG_SEL_MASK) >> WLAN_MBOX_DEBUG_SEL_LSB)
419#define WLAN_MBOX_DEBUG_SEL_SET(x) (((x) << WLAN_MBOX_DEBUG_SEL_LSB) & WLAN_MBOX_DEBUG_SEL_MASK)
420
421#define WLAN_MBOX_FIFO_RESET_ADDRESS 0x000000ec
422#define WLAN_MBOX_FIFO_RESET_OFFSET 0x000000ec
423#define WLAN_MBOX_FIFO_RESET_INIT_MSB 0
424#define WLAN_MBOX_FIFO_RESET_INIT_LSB 0
425#define WLAN_MBOX_FIFO_RESET_INIT_MASK 0x00000001
426#define WLAN_MBOX_FIFO_RESET_INIT_GET(x) (((x) & WLAN_MBOX_FIFO_RESET_INIT_MASK) >> WLAN_MBOX_FIFO_RESET_INIT_LSB)
427#define WLAN_MBOX_FIFO_RESET_INIT_SET(x) (((x) << WLAN_MBOX_FIFO_RESET_INIT_LSB) & WLAN_MBOX_FIFO_RESET_INIT_MASK)
428
429#define WLAN_MBOX_TXFIFO_POP_ADDRESS 0x000000f0
430#define WLAN_MBOX_TXFIFO_POP_OFFSET 0x000000f0
431#define WLAN_MBOX_TXFIFO_POP_DATA_MSB 0
432#define WLAN_MBOX_TXFIFO_POP_DATA_LSB 0
433#define WLAN_MBOX_TXFIFO_POP_DATA_MASK 0x00000001
434#define WLAN_MBOX_TXFIFO_POP_DATA_GET(x) (((x) & WLAN_MBOX_TXFIFO_POP_DATA_MASK) >> WLAN_MBOX_TXFIFO_POP_DATA_LSB)
435#define WLAN_MBOX_TXFIFO_POP_DATA_SET(x) (((x) << WLAN_MBOX_TXFIFO_POP_DATA_LSB) & WLAN_MBOX_TXFIFO_POP_DATA_MASK)
436
437#define WLAN_MBOX_RXFIFO_POP_ADDRESS 0x00000100
438#define WLAN_MBOX_RXFIFO_POP_OFFSET 0x00000100
439#define WLAN_MBOX_RXFIFO_POP_DATA_MSB 0
440#define WLAN_MBOX_RXFIFO_POP_DATA_LSB 0
441#define WLAN_MBOX_RXFIFO_POP_DATA_MASK 0x00000001
442#define WLAN_MBOX_RXFIFO_POP_DATA_GET(x) (((x) & WLAN_MBOX_RXFIFO_POP_DATA_MASK) >> WLAN_MBOX_RXFIFO_POP_DATA_LSB)
443#define WLAN_MBOX_RXFIFO_POP_DATA_SET(x) (((x) << WLAN_MBOX_RXFIFO_POP_DATA_LSB) & WLAN_MBOX_RXFIFO_POP_DATA_MASK)
444
445#define WLAN_SDIO_DEBUG_ADDRESS 0x00000110
446#define WLAN_SDIO_DEBUG_OFFSET 0x00000110
447#define WLAN_SDIO_DEBUG_SEL_MSB 3
448#define WLAN_SDIO_DEBUG_SEL_LSB 0
449#define WLAN_SDIO_DEBUG_SEL_MASK 0x0000000f
450#define WLAN_SDIO_DEBUG_SEL_GET(x) (((x) & WLAN_SDIO_DEBUG_SEL_MASK) >> WLAN_SDIO_DEBUG_SEL_LSB)
451#define WLAN_SDIO_DEBUG_SEL_SET(x) (((x) << WLAN_SDIO_DEBUG_SEL_LSB) & WLAN_SDIO_DEBUG_SEL_MASK)
452
453#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000114
454#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000114
455#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
456#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
457#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
458#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
459#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
460
461#define WLAN_GMBOX0_DMA_RX_CONTROL_ADDRESS 0x00000118
462#define WLAN_GMBOX0_DMA_RX_CONTROL_OFFSET 0x00000118
463#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MSB 2
464#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB 2
465#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004
466#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB)
467#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK)
468#define WLAN_GMBOX0_DMA_RX_CONTROL_START_MSB 1
469#define WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB 1
470#define WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK 0x00000002
471#define WLAN_GMBOX0_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB)
472#define WLAN_GMBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK)
473#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MSB 0
474#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB 0
475#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001
476#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB)
477#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK)
478
479#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x0000011c
480#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x0000011c
481#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
482#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
483#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
484#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
485#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
486
487#define WLAN_GMBOX0_DMA_TX_CONTROL_ADDRESS 0x00000120
488#define WLAN_GMBOX0_DMA_TX_CONTROL_OFFSET 0x00000120
489#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MSB 2
490#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB 2
491#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004
492#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB)
493#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK)
494#define WLAN_GMBOX0_DMA_TX_CONTROL_START_MSB 1
495#define WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB 1
496#define WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK 0x00000002
497#define WLAN_GMBOX0_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB)
498#define WLAN_GMBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK)
499#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MSB 0
500#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB 0
501#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001
502#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB)
503#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK)
504
505#define WLAN_GMBOX_INT_STATUS_ADDRESS 0x00000124
506#define WLAN_GMBOX_INT_STATUS_OFFSET 0x00000124
507#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MSB 6
508#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB 6
509#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00000040
510#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK) >> WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB)
511#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB) & WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK)
512#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MSB 5
513#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB 5
514#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00000020
515#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB)
516#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB) & WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK)
517#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 4
518#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 4
519#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0x00000010
520#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
521#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
522#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 3
523#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 3
524#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x00000008
525#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
526#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
527#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 2
528#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 2
529#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00000004
530#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
531#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
532#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB 1
533#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB 1
534#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x00000002
535#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
536#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
537#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MSB 0
538#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB 0
539#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000001
540#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK) >> WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB)
541#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB) & WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK)
542
543#define WLAN_GMBOX_INT_ENABLE_ADDRESS 0x00000128
544#define WLAN_GMBOX_INT_ENABLE_OFFSET 0x00000128
545#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MSB 6
546#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB 6
547#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00000040
548#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB)
549#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB) & WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK)
550#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB 5
551#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB 5
552#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00000020
553#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
554#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
555#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 4
556#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 4
557#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0x00000010
558#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
559#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
560#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 3
561#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 3
562#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x00000008
563#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
564#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
565#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 2
566#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 2
567#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00000004
568#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
569#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
570#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 1
571#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 1
572#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x00000002
573#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
574#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
575#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MSB 0
576#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB 0
577#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000001
578#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB)
579#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB) & WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK)
580
581#define WLAN_HOST_IF_WINDOW_ADDRESS 0x00002000
582#define WLAN_HOST_IF_WINDOW_OFFSET 0x00002000
583#define WLAN_HOST_IF_WINDOW_DATA_MSB 7
584#define WLAN_HOST_IF_WINDOW_DATA_LSB 0
585#define WLAN_HOST_IF_WINDOW_DATA_MASK 0x000000ff
586#define WLAN_HOST_IF_WINDOW_DATA_GET(x) (((x) & WLAN_HOST_IF_WINDOW_DATA_MASK) >> WLAN_HOST_IF_WINDOW_DATA_LSB)
587#define WLAN_HOST_IF_WINDOW_DATA_SET(x) (((x) << WLAN_HOST_IF_WINDOW_DATA_LSB) & WLAN_HOST_IF_WINDOW_DATA_MASK)
588
589#endif /* _MBOX_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h
new file mode 100644
index 00000000000..fcafec88a6b
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h
@@ -0,0 +1,187 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#include "rtc_wlan_reg.h"
25
26#ifndef BT_HEADERS
27
28#define RESET_CONTROL_ADDRESS WLAN_RESET_CONTROL_ADDRESS
29#define RESET_CONTROL_OFFSET WLAN_RESET_CONTROL_OFFSET
30#define RESET_CONTROL_DEBUG_UART_RST_MSB WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB
31#define RESET_CONTROL_DEBUG_UART_RST_LSB WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB
32#define RESET_CONTROL_DEBUG_UART_RST_MASK WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK
33#define RESET_CONTROL_DEBUG_UART_RST_GET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x)
34#define RESET_CONTROL_DEBUG_UART_RST_SET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x)
35#define RESET_CONTROL_BB_COLD_RST_MSB WLAN_RESET_CONTROL_BB_COLD_RST_MSB
36#define RESET_CONTROL_BB_COLD_RST_LSB WLAN_RESET_CONTROL_BB_COLD_RST_LSB
37#define RESET_CONTROL_BB_COLD_RST_MASK WLAN_RESET_CONTROL_BB_COLD_RST_MASK
38#define RESET_CONTROL_BB_COLD_RST_GET(x) WLAN_RESET_CONTROL_BB_COLD_RST_GET(x)
39#define RESET_CONTROL_BB_COLD_RST_SET(x) WLAN_RESET_CONTROL_BB_COLD_RST_SET(x)
40#define RESET_CONTROL_BB_WARM_RST_MSB WLAN_RESET_CONTROL_BB_WARM_RST_MSB
41#define RESET_CONTROL_BB_WARM_RST_LSB WLAN_RESET_CONTROL_BB_WARM_RST_LSB
42#define RESET_CONTROL_BB_WARM_RST_MASK WLAN_RESET_CONTROL_BB_WARM_RST_MASK
43#define RESET_CONTROL_BB_WARM_RST_GET(x) WLAN_RESET_CONTROL_BB_WARM_RST_GET(x)
44#define RESET_CONTROL_BB_WARM_RST_SET(x) WLAN_RESET_CONTROL_BB_WARM_RST_SET(x)
45#define RESET_CONTROL_CPU_INIT_RESET_MSB WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB
46#define RESET_CONTROL_CPU_INIT_RESET_LSB WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB
47#define RESET_CONTROL_CPU_INIT_RESET_MASK WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK
48#define RESET_CONTROL_CPU_INIT_RESET_GET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x)
49#define RESET_CONTROL_CPU_INIT_RESET_SET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x)
50#define RESET_CONTROL_VMC_REMAP_RESET_MSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB
51#define RESET_CONTROL_VMC_REMAP_RESET_LSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB
52#define RESET_CONTROL_VMC_REMAP_RESET_MASK WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK
53#define RESET_CONTROL_VMC_REMAP_RESET_GET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x)
54#define RESET_CONTROL_VMC_REMAP_RESET_SET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x)
55#define RESET_CONTROL_RST_OUT_MSB WLAN_RESET_CONTROL_RST_OUT_MSB
56#define RESET_CONTROL_RST_OUT_LSB WLAN_RESET_CONTROL_RST_OUT_LSB
57#define RESET_CONTROL_RST_OUT_MASK WLAN_RESET_CONTROL_RST_OUT_MASK
58#define RESET_CONTROL_RST_OUT_GET(x) WLAN_RESET_CONTROL_RST_OUT_GET(x)
59#define RESET_CONTROL_RST_OUT_SET(x) WLAN_RESET_CONTROL_RST_OUT_SET(x)
60#define RESET_CONTROL_COLD_RST_MSB WLAN_RESET_CONTROL_COLD_RST_MSB
61#define RESET_CONTROL_COLD_RST_LSB WLAN_RESET_CONTROL_COLD_RST_LSB
62#define RESET_CONTROL_COLD_RST_MASK WLAN_RESET_CONTROL_COLD_RST_MASK
63#define RESET_CONTROL_COLD_RST_GET(x) WLAN_RESET_CONTROL_COLD_RST_GET(x)
64#define RESET_CONTROL_COLD_RST_SET(x) WLAN_RESET_CONTROL_COLD_RST_SET(x)
65#define RESET_CONTROL_WARM_RST_MSB WLAN_RESET_CONTROL_WARM_RST_MSB
66#define RESET_CONTROL_WARM_RST_LSB WLAN_RESET_CONTROL_WARM_RST_LSB
67#define RESET_CONTROL_WARM_RST_MASK WLAN_RESET_CONTROL_WARM_RST_MASK
68#define RESET_CONTROL_WARM_RST_GET(x) WLAN_RESET_CONTROL_WARM_RST_GET(x)
69#define RESET_CONTROL_WARM_RST_SET(x) WLAN_RESET_CONTROL_WARM_RST_SET(x)
70#define RESET_CONTROL_CPU_WARM_RST_MSB WLAN_RESET_CONTROL_CPU_WARM_RST_MSB
71#define RESET_CONTROL_CPU_WARM_RST_LSB WLAN_RESET_CONTROL_CPU_WARM_RST_LSB
72#define RESET_CONTROL_CPU_WARM_RST_MASK WLAN_RESET_CONTROL_CPU_WARM_RST_MASK
73#define RESET_CONTROL_CPU_WARM_RST_GET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x)
74#define RESET_CONTROL_CPU_WARM_RST_SET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x)
75#define RESET_CONTROL_MAC_COLD_RST_MSB WLAN_RESET_CONTROL_MAC_COLD_RST_MSB
76#define RESET_CONTROL_MAC_COLD_RST_LSB WLAN_RESET_CONTROL_MAC_COLD_RST_LSB
77#define RESET_CONTROL_MAC_COLD_RST_MASK WLAN_RESET_CONTROL_MAC_COLD_RST_MASK
78#define RESET_CONTROL_MAC_COLD_RST_GET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x)
79#define RESET_CONTROL_MAC_COLD_RST_SET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x)
80#define RESET_CONTROL_MAC_WARM_RST_MSB WLAN_RESET_CONTROL_MAC_WARM_RST_MSB
81#define RESET_CONTROL_MAC_WARM_RST_LSB WLAN_RESET_CONTROL_MAC_WARM_RST_LSB
82#define RESET_CONTROL_MAC_WARM_RST_MASK WLAN_RESET_CONTROL_MAC_WARM_RST_MASK
83#define RESET_CONTROL_MAC_WARM_RST_GET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x)
84#define RESET_CONTROL_MAC_WARM_RST_SET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x)
85#define RESET_CONTROL_MBOX_RST_MSB WLAN_RESET_CONTROL_MBOX_RST_MSB
86#define RESET_CONTROL_MBOX_RST_LSB WLAN_RESET_CONTROL_MBOX_RST_LSB
87#define RESET_CONTROL_MBOX_RST_MASK WLAN_RESET_CONTROL_MBOX_RST_MASK
88#define RESET_CONTROL_MBOX_RST_GET(x) WLAN_RESET_CONTROL_MBOX_RST_GET(x)
89#define RESET_CONTROL_MBOX_RST_SET(x) WLAN_RESET_CONTROL_MBOX_RST_SET(x)
90#define RESET_CONTROL_UART_RST_MSB WLAN_RESET_CONTROL_UART_RST_MSB
91#define RESET_CONTROL_UART_RST_LSB WLAN_RESET_CONTROL_UART_RST_LSB
92#define RESET_CONTROL_UART_RST_MASK WLAN_RESET_CONTROL_UART_RST_MASK
93#define RESET_CONTROL_UART_RST_GET(x) WLAN_RESET_CONTROL_UART_RST_GET(x)
94#define RESET_CONTROL_UART_RST_SET(x) WLAN_RESET_CONTROL_UART_RST_SET(x)
95#define RESET_CONTROL_SI0_RST_MSB WLAN_RESET_CONTROL_SI0_RST_MSB
96#define RESET_CONTROL_SI0_RST_LSB WLAN_RESET_CONTROL_SI0_RST_LSB
97#define RESET_CONTROL_SI0_RST_MASK WLAN_RESET_CONTROL_SI0_RST_MASK
98#define RESET_CONTROL_SI0_RST_GET(x) WLAN_RESET_CONTROL_SI0_RST_GET(x)
99#define RESET_CONTROL_SI0_RST_SET(x) WLAN_RESET_CONTROL_SI0_RST_SET(x)
100#define CPU_CLOCK_ADDRESS WLAN_CPU_CLOCK_ADDRESS
101#define CPU_CLOCK_OFFSET WLAN_CPU_CLOCK_OFFSET
102#define CPU_CLOCK_STANDARD_MSB WLAN_CPU_CLOCK_STANDARD_MSB
103#define CPU_CLOCK_STANDARD_LSB WLAN_CPU_CLOCK_STANDARD_LSB
104#define CPU_CLOCK_STANDARD_MASK WLAN_CPU_CLOCK_STANDARD_MASK
105#define CPU_CLOCK_STANDARD_GET(x) WLAN_CPU_CLOCK_STANDARD_GET(x)
106#define CPU_CLOCK_STANDARD_SET(x) WLAN_CPU_CLOCK_STANDARD_SET(x)
107#define CLOCK_OUT_ADDRESS WLAN_CLOCK_OUT_ADDRESS
108#define CLOCK_OUT_OFFSET WLAN_CLOCK_OUT_OFFSET
109#define CLOCK_OUT_SELECT_MSB WLAN_CLOCK_OUT_SELECT_MSB
110#define CLOCK_OUT_SELECT_LSB WLAN_CLOCK_OUT_SELECT_LSB
111#define CLOCK_OUT_SELECT_MASK WLAN_CLOCK_OUT_SELECT_MASK
112#define CLOCK_OUT_SELECT_GET(x) WLAN_CLOCK_OUT_SELECT_GET(x)
113#define CLOCK_OUT_SELECT_SET(x) WLAN_CLOCK_OUT_SELECT_SET(x)
114#define CLOCK_CONTROL_ADDRESS WLAN_CLOCK_CONTROL_ADDRESS
115#define CLOCK_CONTROL_OFFSET WLAN_CLOCK_CONTROL_OFFSET
116#define CLOCK_CONTROL_LF_CLK32_MSB WLAN_CLOCK_CONTROL_LF_CLK32_MSB
117#define CLOCK_CONTROL_LF_CLK32_LSB WLAN_CLOCK_CONTROL_LF_CLK32_LSB
118#define CLOCK_CONTROL_LF_CLK32_MASK WLAN_CLOCK_CONTROL_LF_CLK32_MASK
119#define CLOCK_CONTROL_LF_CLK32_GET(x) WLAN_CLOCK_CONTROL_LF_CLK32_GET(x)
120#define CLOCK_CONTROL_LF_CLK32_SET(x) WLAN_CLOCK_CONTROL_LF_CLK32_SET(x)
121#define CLOCK_CONTROL_SI0_CLK_MSB WLAN_CLOCK_CONTROL_SI0_CLK_MSB
122#define CLOCK_CONTROL_SI0_CLK_LSB WLAN_CLOCK_CONTROL_SI0_CLK_LSB
123#define CLOCK_CONTROL_SI0_CLK_MASK WLAN_CLOCK_CONTROL_SI0_CLK_MASK
124#define CLOCK_CONTROL_SI0_CLK_GET(x) WLAN_CLOCK_CONTROL_SI0_CLK_GET(x)
125#define CLOCK_CONTROL_SI0_CLK_SET(x) WLAN_CLOCK_CONTROL_SI0_CLK_SET(x)
126#define RESET_CAUSE_ADDRESS WLAN_RESET_CAUSE_ADDRESS
127#define RESET_CAUSE_OFFSET WLAN_RESET_CAUSE_OFFSET
128#define RESET_CAUSE_LAST_MSB WLAN_RESET_CAUSE_LAST_MSB
129#define RESET_CAUSE_LAST_LSB WLAN_RESET_CAUSE_LAST_LSB
130#define RESET_CAUSE_LAST_MASK WLAN_RESET_CAUSE_LAST_MASK
131#define RESET_CAUSE_LAST_GET(x) WLAN_RESET_CAUSE_LAST_GET(x)
132#define RESET_CAUSE_LAST_SET(x) WLAN_RESET_CAUSE_LAST_SET(x)
133#define SYSTEM_SLEEP_ADDRESS WLAN_SYSTEM_SLEEP_ADDRESS
134#define SYSTEM_SLEEP_OFFSET WLAN_SYSTEM_SLEEP_OFFSET
135#define SYSTEM_SLEEP_HOST_IF_MSB WLAN_SYSTEM_SLEEP_HOST_IF_MSB
136#define SYSTEM_SLEEP_HOST_IF_LSB WLAN_SYSTEM_SLEEP_HOST_IF_LSB
137#define SYSTEM_SLEEP_HOST_IF_MASK WLAN_SYSTEM_SLEEP_HOST_IF_MASK
138#define SYSTEM_SLEEP_HOST_IF_GET(x) WLAN_SYSTEM_SLEEP_HOST_IF_GET(x)
139#define SYSTEM_SLEEP_HOST_IF_SET(x) WLAN_SYSTEM_SLEEP_HOST_IF_SET(x)
140#define SYSTEM_SLEEP_MBOX_MSB WLAN_SYSTEM_SLEEP_MBOX_MSB
141#define SYSTEM_SLEEP_MBOX_LSB WLAN_SYSTEM_SLEEP_MBOX_LSB
142#define SYSTEM_SLEEP_MBOX_MASK WLAN_SYSTEM_SLEEP_MBOX_MASK
143#define SYSTEM_SLEEP_MBOX_GET(x) WLAN_SYSTEM_SLEEP_MBOX_GET(x)
144#define SYSTEM_SLEEP_MBOX_SET(x) WLAN_SYSTEM_SLEEP_MBOX_SET(x)
145#define SYSTEM_SLEEP_MAC_IF_MSB WLAN_SYSTEM_SLEEP_MAC_IF_MSB
146#define SYSTEM_SLEEP_MAC_IF_LSB WLAN_SYSTEM_SLEEP_MAC_IF_LSB
147#define SYSTEM_SLEEP_MAC_IF_MASK WLAN_SYSTEM_SLEEP_MAC_IF_MASK
148#define SYSTEM_SLEEP_MAC_IF_GET(x) WLAN_SYSTEM_SLEEP_MAC_IF_GET(x)
149#define SYSTEM_SLEEP_MAC_IF_SET(x) WLAN_SYSTEM_SLEEP_MAC_IF_SET(x)
150#define SYSTEM_SLEEP_LIGHT_MSB WLAN_SYSTEM_SLEEP_LIGHT_MSB
151#define SYSTEM_SLEEP_LIGHT_LSB WLAN_SYSTEM_SLEEP_LIGHT_LSB
152#define SYSTEM_SLEEP_LIGHT_MASK WLAN_SYSTEM_SLEEP_LIGHT_MASK
153#define SYSTEM_SLEEP_LIGHT_GET(x) WLAN_SYSTEM_SLEEP_LIGHT_GET(x)
154#define SYSTEM_SLEEP_LIGHT_SET(x) WLAN_SYSTEM_SLEEP_LIGHT_SET(x)
155#define SYSTEM_SLEEP_DISABLE_MSB WLAN_SYSTEM_SLEEP_DISABLE_MSB
156#define SYSTEM_SLEEP_DISABLE_LSB WLAN_SYSTEM_SLEEP_DISABLE_LSB
157#define SYSTEM_SLEEP_DISABLE_MASK WLAN_SYSTEM_SLEEP_DISABLE_MASK
158#define SYSTEM_SLEEP_DISABLE_GET(x) WLAN_SYSTEM_SLEEP_DISABLE_GET(x)
159#define SYSTEM_SLEEP_DISABLE_SET(x) WLAN_SYSTEM_SLEEP_DISABLE_SET(x)
160#define LPO_INIT_DIVIDEND_INT_ADDRESS WLAN_LPO_INIT_DIVIDEND_INT_ADDRESS
161#define LPO_INIT_DIVIDEND_INT_OFFSET WLAN_LPO_INIT_DIVIDEND_INT_OFFSET
162#define LPO_INIT_DIVIDEND_INT_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MSB
163#define LPO_INIT_DIVIDEND_INT_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB
164#define LPO_INIT_DIVIDEND_INT_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK
165#define LPO_INIT_DIVIDEND_INT_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_GET(x)
166#define LPO_INIT_DIVIDEND_INT_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_SET(x)
167#define LPO_INIT_DIVIDEND_FRACTION_ADDRESS WLAN_LPO_INIT_DIVIDEND_FRACTION_ADDRESS
168#define LPO_INIT_DIVIDEND_FRACTION_OFFSET WLAN_LPO_INIT_DIVIDEND_FRACTION_OFFSET
169#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB
170#define LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB
171#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK
172#define LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x)
173#define LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x)
174#define LPO_CAL_ADDRESS WLAN_LPO_CAL_ADDRESS
175#define LPO_CAL_OFFSET WLAN_LPO_CAL_OFFSET
176#define LPO_CAL_ENABLE_MSB WLAN_LPO_CAL_ENABLE_MSB
177#define LPO_CAL_ENABLE_LSB WLAN_LPO_CAL_ENABLE_LSB
178#define LPO_CAL_ENABLE_MASK WLAN_LPO_CAL_ENABLE_MASK
179#define LPO_CAL_ENABLE_GET(x) WLAN_LPO_CAL_ENABLE_GET(x)
180#define LPO_CAL_ENABLE_SET(x) WLAN_LPO_CAL_ENABLE_SET(x)
181#define LPO_CAL_COUNT_MSB WLAN_LPO_CAL_COUNT_MSB
182#define LPO_CAL_COUNT_LSB WLAN_LPO_CAL_COUNT_LSB
183#define LPO_CAL_COUNT_MASK WLAN_LPO_CAL_COUNT_MASK
184#define LPO_CAL_COUNT_GET(x) WLAN_LPO_CAL_COUNT_GET(x)
185#define LPO_CAL_COUNT_SET(x) WLAN_LPO_CAL_COUNT_SET(x)
186
187#endif
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h
new file mode 100644
index 00000000000..5c048ff51b0
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h
@@ -0,0 +1,162 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#ifndef _RTC_WLAN_REG_REG_H_
25#define _RTC_WLAN_REG_REG_H_
26
27#define WLAN_RESET_CONTROL_ADDRESS 0x00000000
28#define WLAN_RESET_CONTROL_OFFSET 0x00000000
29#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB 14
30#define WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB 14
31#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK 0x00004000
32#define WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x) (((x) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK) >> WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB)
33#define WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x) (((x) << WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK)
34#define WLAN_RESET_CONTROL_BB_COLD_RST_MSB 13
35#define WLAN_RESET_CONTROL_BB_COLD_RST_LSB 13
36#define WLAN_RESET_CONTROL_BB_COLD_RST_MASK 0x00002000
37#define WLAN_RESET_CONTROL_BB_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK) >> WLAN_RESET_CONTROL_BB_COLD_RST_LSB)
38#define WLAN_RESET_CONTROL_BB_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_BB_COLD_RST_LSB) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK)
39#define WLAN_RESET_CONTROL_BB_WARM_RST_MSB 12
40#define WLAN_RESET_CONTROL_BB_WARM_RST_LSB 12
41#define WLAN_RESET_CONTROL_BB_WARM_RST_MASK 0x00001000
42#define WLAN_RESET_CONTROL_BB_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK) >> WLAN_RESET_CONTROL_BB_WARM_RST_LSB)
43#define WLAN_RESET_CONTROL_BB_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_BB_WARM_RST_LSB) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK)
44#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB 11
45#define WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB 11
46#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK 0x00000800
47#define WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x) (((x) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK) >> WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB)
48#define WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x) (((x) << WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK)
49#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB 10
50#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB 10
51#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK 0x00000400
52#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x) (((x) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK) >> WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB)
53#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x) (((x) << WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK)
54#define WLAN_RESET_CONTROL_RST_OUT_MSB 9
55#define WLAN_RESET_CONTROL_RST_OUT_LSB 9
56#define WLAN_RESET_CONTROL_RST_OUT_MASK 0x00000200
57#define WLAN_RESET_CONTROL_RST_OUT_GET(x) (((x) & WLAN_RESET_CONTROL_RST_OUT_MASK) >> WLAN_RESET_CONTROL_RST_OUT_LSB)
58#define WLAN_RESET_CONTROL_RST_OUT_SET(x) (((x) << WLAN_RESET_CONTROL_RST_OUT_LSB) & WLAN_RESET_CONTROL_RST_OUT_MASK)
59#define WLAN_RESET_CONTROL_COLD_RST_MSB 8
60#define WLAN_RESET_CONTROL_COLD_RST_LSB 8
61#define WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000100
62#define WLAN_RESET_CONTROL_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_COLD_RST_MASK) >> WLAN_RESET_CONTROL_COLD_RST_LSB)
63#define WLAN_RESET_CONTROL_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_COLD_RST_LSB) & WLAN_RESET_CONTROL_COLD_RST_MASK)
64#define WLAN_RESET_CONTROL_WARM_RST_MSB 7
65#define WLAN_RESET_CONTROL_WARM_RST_LSB 7
66#define WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000080
67#define WLAN_RESET_CONTROL_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_WARM_RST_MASK) >> WLAN_RESET_CONTROL_WARM_RST_LSB)
68#define WLAN_RESET_CONTROL_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_WARM_RST_LSB) & WLAN_RESET_CONTROL_WARM_RST_MASK)
69#define WLAN_RESET_CONTROL_CPU_WARM_RST_MSB 6
70#define WLAN_RESET_CONTROL_CPU_WARM_RST_LSB 6
71#define WLAN_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040
72#define WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK) >> WLAN_RESET_CONTROL_CPU_WARM_RST_LSB)
73#define WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_CPU_WARM_RST_LSB) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK)
74#define WLAN_RESET_CONTROL_MAC_COLD_RST_MSB 5
75#define WLAN_RESET_CONTROL_MAC_COLD_RST_LSB 5
76#define WLAN_RESET_CONTROL_MAC_COLD_RST_MASK 0x00000020
77#define WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK) >> WLAN_RESET_CONTROL_MAC_COLD_RST_LSB)
78#define WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MAC_COLD_RST_LSB) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK)
79#define WLAN_RESET_CONTROL_MAC_WARM_RST_MSB 4
80#define WLAN_RESET_CONTROL_MAC_WARM_RST_LSB 4
81#define WLAN_RESET_CONTROL_MAC_WARM_RST_MASK 0x00000010
82#define WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK) >> WLAN_RESET_CONTROL_MAC_WARM_RST_LSB)
83#define WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MAC_WARM_RST_LSB) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK)
84#define WLAN_RESET_CONTROL_MBOX_RST_MSB 2
85#define WLAN_RESET_CONTROL_MBOX_RST_LSB 2
86#define WLAN_RESET_CONTROL_MBOX_RST_MASK 0x00000004
87#define WLAN_RESET_CONTROL_MBOX_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MBOX_RST_MASK) >> WLAN_RESET_CONTROL_MBOX_RST_LSB)
88#define WLAN_RESET_CONTROL_MBOX_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MBOX_RST_LSB) & WLAN_RESET_CONTROL_MBOX_RST_MASK)
89#define WLAN_RESET_CONTROL_UART_RST_MSB 1
90#define WLAN_RESET_CONTROL_UART_RST_LSB 1
91#define WLAN_RESET_CONTROL_UART_RST_MASK 0x00000002
92#define WLAN_RESET_CONTROL_UART_RST_GET(x) (((x) & WLAN_RESET_CONTROL_UART_RST_MASK) >> WLAN_RESET_CONTROL_UART_RST_LSB)
93#define WLAN_RESET_CONTROL_UART_RST_SET(x) (((x) << WLAN_RESET_CONTROL_UART_RST_LSB) & WLAN_RESET_CONTROL_UART_RST_MASK)
94#define WLAN_RESET_CONTROL_SI0_RST_MSB 0
95#define WLAN_RESET_CONTROL_SI0_RST_LSB 0
96#define WLAN_RESET_CONTROL_SI0_RST_MASK 0x00000001
97#define WLAN_RESET_CONTROL_SI0_RST_GET(x) (((x) & WLAN_RESET_CONTROL_SI0_RST_MASK) >> WLAN_RESET_CONTROL_SI0_RST_LSB)
98#define WLAN_RESET_CONTROL_SI0_RST_SET(x) (((x) << WLAN_RESET_CONTROL_SI0_RST_LSB) & WLAN_RESET_CONTROL_SI0_RST_MASK)
99
100#define WLAN_CPU_CLOCK_ADDRESS 0x00000020
101#define WLAN_CPU_CLOCK_OFFSET 0x00000020
102#define WLAN_CPU_CLOCK_STANDARD_MSB 1
103#define WLAN_CPU_CLOCK_STANDARD_LSB 0
104#define WLAN_CPU_CLOCK_STANDARD_MASK 0x00000003
105#define WLAN_CPU_CLOCK_STANDARD_GET(x) (((x) & WLAN_CPU_CLOCK_STANDARD_MASK) >> WLAN_CPU_CLOCK_STANDARD_LSB)
106#define WLAN_CPU_CLOCK_STANDARD_SET(x) (((x) << WLAN_CPU_CLOCK_STANDARD_LSB) & WLAN_CPU_CLOCK_STANDARD_MASK)
107
108#define WLAN_CLOCK_CONTROL_ADDRESS 0x00000028
109#define WLAN_CLOCK_CONTROL_OFFSET 0x00000028
110#define WLAN_CLOCK_CONTROL_LF_CLK32_MSB 2
111#define WLAN_CLOCK_CONTROL_LF_CLK32_LSB 2
112#define WLAN_CLOCK_CONTROL_LF_CLK32_MASK 0x00000004
113#define WLAN_CLOCK_CONTROL_LF_CLK32_GET(x) (((x) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK) >> WLAN_CLOCK_CONTROL_LF_CLK32_LSB)
114#define WLAN_CLOCK_CONTROL_LF_CLK32_SET(x) (((x) << WLAN_CLOCK_CONTROL_LF_CLK32_LSB) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK)
115#define WLAN_CLOCK_CONTROL_SI0_CLK_MSB 0
116#define WLAN_CLOCK_CONTROL_SI0_CLK_LSB 0
117#define WLAN_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001
118#define WLAN_CLOCK_CONTROL_SI0_CLK_GET(x) (((x) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK) >> WLAN_CLOCK_CONTROL_SI0_CLK_LSB)
119#define WLAN_CLOCK_CONTROL_SI0_CLK_SET(x) (((x) << WLAN_CLOCK_CONTROL_SI0_CLK_LSB) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK)
120
121#define WLAN_SYSTEM_SLEEP_ADDRESS 0x000000c4
122#define WLAN_SYSTEM_SLEEP_OFFSET 0x000000c4
123#define WLAN_SYSTEM_SLEEP_HOST_IF_MSB 4
124#define WLAN_SYSTEM_SLEEP_HOST_IF_LSB 4
125#define WLAN_SYSTEM_SLEEP_HOST_IF_MASK 0x00000010
126#define WLAN_SYSTEM_SLEEP_HOST_IF_GET(x) (((x) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK) >> WLAN_SYSTEM_SLEEP_HOST_IF_LSB)
127#define WLAN_SYSTEM_SLEEP_HOST_IF_SET(x) (((x) << WLAN_SYSTEM_SLEEP_HOST_IF_LSB) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK)
128#define WLAN_SYSTEM_SLEEP_MBOX_MSB 3
129#define WLAN_SYSTEM_SLEEP_MBOX_LSB 3
130#define WLAN_SYSTEM_SLEEP_MBOX_MASK 0x00000008
131#define WLAN_SYSTEM_SLEEP_MBOX_GET(x) (((x) & WLAN_SYSTEM_SLEEP_MBOX_MASK) >> WLAN_SYSTEM_SLEEP_MBOX_LSB)
132#define WLAN_SYSTEM_SLEEP_MBOX_SET(x) (((x) << WLAN_SYSTEM_SLEEP_MBOX_LSB) & WLAN_SYSTEM_SLEEP_MBOX_MASK)
133#define WLAN_SYSTEM_SLEEP_MAC_IF_MSB 2
134#define WLAN_SYSTEM_SLEEP_MAC_IF_LSB 2
135#define WLAN_SYSTEM_SLEEP_MAC_IF_MASK 0x00000004
136#define WLAN_SYSTEM_SLEEP_MAC_IF_GET(x) (((x) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK) >> WLAN_SYSTEM_SLEEP_MAC_IF_LSB)
137#define WLAN_SYSTEM_SLEEP_MAC_IF_SET(x) (((x) << WLAN_SYSTEM_SLEEP_MAC_IF_LSB) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK)
138#define WLAN_SYSTEM_SLEEP_LIGHT_MSB 1
139#define WLAN_SYSTEM_SLEEP_LIGHT_LSB 1
140#define WLAN_SYSTEM_SLEEP_LIGHT_MASK 0x00000002
141#define WLAN_SYSTEM_SLEEP_LIGHT_GET(x) (((x) & WLAN_SYSTEM_SLEEP_LIGHT_MASK) >> WLAN_SYSTEM_SLEEP_LIGHT_LSB)
142#define WLAN_SYSTEM_SLEEP_LIGHT_SET(x) (((x) << WLAN_SYSTEM_SLEEP_LIGHT_LSB) & WLAN_SYSTEM_SLEEP_LIGHT_MASK)
143#define WLAN_SYSTEM_SLEEP_DISABLE_MSB 0
144#define WLAN_SYSTEM_SLEEP_DISABLE_LSB 0
145#define WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001
146#define WLAN_SYSTEM_SLEEP_DISABLE_GET(x) (((x) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) >> WLAN_SYSTEM_SLEEP_DISABLE_LSB)
147#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x) (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK)
148
149#define WLAN_LPO_CAL_ADDRESS 0x000000e0
150#define WLAN_LPO_CAL_OFFSET 0x000000e0
151#define WLAN_LPO_CAL_ENABLE_MSB 20
152#define WLAN_LPO_CAL_ENABLE_LSB 20
153#define WLAN_LPO_CAL_ENABLE_MASK 0x00100000
154#define WLAN_LPO_CAL_ENABLE_GET(x) (((x) & WLAN_LPO_CAL_ENABLE_MASK) >> WLAN_LPO_CAL_ENABLE_LSB)
155#define WLAN_LPO_CAL_ENABLE_SET(x) (((x) << WLAN_LPO_CAL_ENABLE_LSB) & WLAN_LPO_CAL_ENABLE_MASK)
156#define WLAN_LPO_CAL_COUNT_MSB 19
157#define WLAN_LPO_CAL_COUNT_LSB 0
158#define WLAN_LPO_CAL_COUNT_MASK 0x000fffff
159#define WLAN_LPO_CAL_COUNT_GET(x) (((x) & WLAN_LPO_CAL_COUNT_MASK) >> WLAN_LPO_CAL_COUNT_LSB)
160#define WLAN_LPO_CAL_COUNT_SET(x) (((x) << WLAN_LPO_CAL_COUNT_LSB) & WLAN_LPO_CAL_COUNT_MASK)
161
162#endif /* _RTC_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h
new file mode 100644
index 00000000000..302b20bc1ba
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h
@@ -0,0 +1,40 @@
1// ------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18// ------------------------------------------------------------------
19//===================================================================
20// Author(s): ="Atheros"
21//===================================================================
22
23
24#ifndef _UART_REG_REG_H_
25#define _UART_REG_REG_H_
26
27#define UART_CLKDIV_ADDRESS 0x00000008
28#define UART_CLKDIV_OFFSET 0x00000008
29#define UART_CLKDIV_CLK_SCALE_MSB 23
30#define UART_CLKDIV_CLK_SCALE_LSB 16
31#define UART_CLKDIV_CLK_SCALE_MASK 0x00ff0000
32#define UART_CLKDIV_CLK_SCALE_GET(x) (((x) & UART_CLKDIV_CLK_SCALE_MASK) >> UART_CLKDIV_CLK_SCALE_LSB)
33#define UART_CLKDIV_CLK_SCALE_SET(x) (((x) << UART_CLKDIV_CLK_SCALE_LSB) & UART_CLKDIV_CLK_SCALE_MASK)
34#define UART_CLKDIV_CLK_STEP_MSB 15
35#define UART_CLKDIV_CLK_STEP_LSB 0
36#define UART_CLKDIV_CLK_STEP_MASK 0x0000ffff
37#define UART_CLKDIV_CLK_STEP_GET(x) (((x) & UART_CLKDIV_CLK_STEP_MASK) >> UART_CLKDIV_CLK_STEP_LSB)
38#define UART_CLKDIV_CLK_STEP_SET(x) (((x) << UART_CLKDIV_CLK_STEP_LSB) & UART_CLKDIV_CLK_STEP_MASK)
39
40#endif /* _UART_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/athdefs.h b/drivers/staging/ath6kl/include/common/athdefs.h
new file mode 100644
index 00000000000..74922481e06
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/athdefs.h
@@ -0,0 +1,75 @@
1//------------------------------------------------------------------------------
2// <copyright file="athdefs.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef __ATHDEFS_H__
24#define __ATHDEFS_H__
25
26/*
27 * This file contains definitions that may be used across both
28 * Host and Target software. Nothing here is module-dependent
29 * or platform-dependent.
30 */
31
32/*
33 * Generic error codes that can be used by hw, sta, ap, sim, dk
34 * and any other environments.
35 * Feel free to add any more non-zero codes that you need.
36 */
37
38#define A_ERROR (-1) /* Generic error return */
39#define A_DEVICE_NOT_FOUND 1 /* not able to find PCI device */
40#define A_NO_MEMORY 2 /* not able to allocate memory,
41 * not avail#defineable */
42#define A_MEMORY_NOT_AVAIL 3 /* memory region is not free for
43 * mapping */
44#define A_NO_FREE_DESC 4 /* no free descriptors available */
45#define A_BAD_ADDRESS 5 /* address does not match descriptor */
46#define A_WIN_DRIVER_ERROR 6 /* used in NT_HW version,
47 * if problem at init */
48#define A_REGS_NOT_MAPPED 7 /* registers not correctly mapped */
49#define A_EPERM 8 /* Not superuser */
50#define A_EACCES 0 /* Access denied */
51#define A_ENOENT 10 /* No such entry, search failed, etc. */
52#define A_EEXIST 11 /* The object already exists
53 * (can't create) */
54#define A_EFAULT 12 /* Bad address fault */
55#define A_EBUSY 13 /* Object is busy */
56#define A_EINVAL 14 /* Invalid parameter */
57#define A_EMSGSIZE 15 /* Bad message buffer length */
58#define A_ECANCELED 16 /* Operation canceled */
59#define A_ENOTSUP 17 /* Operation not supported */
60#define A_ECOMM 18 /* Communication error on send */
61#define A_EPROTO 19 /* Protocol error */
62#define A_ENODEV 20 /* No such device */
63#define A_EDEVNOTUP 21 /* device is not UP */
64#define A_NO_RESOURCE 22 /* No resources for
65 * requested operation */
66#define A_HARDWARE 23 /* Hardware failure */
67#define A_PENDING 24 /* Asynchronous routine; will send up
68 * results later
69 * (typically in callback) */
70#define A_EBADCHANNEL 25 /* The channel cannot be used */
71#define A_DECRYPT_ERROR 26 /* Decryption error */
72#define A_PHY_ERROR 27 /* RX PHY error */
73#define A_CONSUMED 28 /* Object was consumed */
74
75#endif /* __ATHDEFS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/bmi_msg.h b/drivers/staging/ath6kl/include/common/bmi_msg.h
new file mode 100644
index 00000000000..84e8db569a9
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/bmi_msg.h
@@ -0,0 +1,233 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//
19// Author(s): ="Atheros"
20//------------------------------------------------------------------------------
21
22#ifndef __BMI_MSG_H__
23#define __BMI_MSG_H__
24
25/*
26 * Bootloader Messaging Interface (BMI)
27 *
28 * BMI is a very simple messaging interface used during initialization
29 * to read memory, write memory, execute code, and to define an
30 * application entry PC.
31 *
32 * It is used to download an application to AR6K, to provide
33 * patches to code that is already resident on AR6K, and generally
34 * to examine and modify state. The Host has an opportunity to use
35 * BMI only once during bootup. Once the Host issues a BMI_DONE
36 * command, this opportunity ends.
37 *
38 * The Host writes BMI requests to mailbox0, and reads BMI responses
39 * from mailbox0. BMI requests all begin with a command
40 * (see below for specific commands), and are followed by
41 * command-specific data.
42 *
43 * Flow control:
44 * The Host can only issue a command once the Target gives it a
45 * "BMI Command Credit", using AR6K Counter #4. As soon as the
46 * Target has completed a command, it issues another BMI Command
47 * Credit (so the Host can issue the next command).
48 *
49 * BMI handles all required Target-side cache flushing.
50 */
51
52
53/* Maximum data size used for BMI transfers */
54#define BMI_DATASZ_MAX 256
55
56/* BMI Commands */
57
58#define BMI_NO_COMMAND 0
59
60#define BMI_DONE 1
61 /*
62 * Semantics: Host is done using BMI
63 * Request format:
64 * u32 command (BMI_DONE)
65 * Response format: none
66 */
67
68#define BMI_READ_MEMORY 2
69 /*
70 * Semantics: Host reads AR6K memory
71 * Request format:
72 * u32 command (BMI_READ_MEMORY)
73 * u32 address
74 * u32 length, at most BMI_DATASZ_MAX
75 * Response format:
76 * u8 data[length]
77 */
78
79#define BMI_WRITE_MEMORY 3
80 /*
81 * Semantics: Host writes AR6K memory
82 * Request format:
83 * u32 command (BMI_WRITE_MEMORY)
84 * u32 address
85 * u32 length, at most BMI_DATASZ_MAX
86 * u8 data[length]
87 * Response format: none
88 */
89
90#define BMI_EXECUTE 4
91 /*
92 * Semantics: Causes AR6K to execute code
93 * Request format:
94 * u32 command (BMI_EXECUTE)
95 * u32 address
96 * u32 parameter
97 * Response format:
98 * u32 return value
99 */
100
101#define BMI_SET_APP_START 5
102 /*
103 * Semantics: Set Target application starting address
104 * Request format:
105 * u32 command (BMI_SET_APP_START)
106 * u32 address
107 * Response format: none
108 */
109
110#define BMI_READ_SOC_REGISTER 6
111 /*
112 * Semantics: Read a 32-bit Target SOC register.
113 * Request format:
114 * u32 command (BMI_READ_REGISTER)
115 * u32 address
116 * Response format:
117 * u32 value
118 */
119
120#define BMI_WRITE_SOC_REGISTER 7
121 /*
122 * Semantics: Write a 32-bit Target SOC register.
123 * Request format:
124 * u32 command (BMI_WRITE_REGISTER)
125 * u32 address
126 * u32 value
127 *
128 * Response format: none
129 */
130
131#define BMI_GET_TARGET_ID 8
132#define BMI_GET_TARGET_INFO 8
133 /*
134 * Semantics: Fetch the 4-byte Target information
135 * Request format:
136 * u32 command (BMI_GET_TARGET_ID/INFO)
137 * Response format1 (old firmware):
138 * u32 TargetVersionID
139 * Response format2 (newer firmware):
140 * u32 TARGET_VERSION_SENTINAL
141 * struct bmi_target_info;
142 */
143
144PREPACK struct bmi_target_info {
145 u32 target_info_byte_count; /* size of this structure */
146 u32 target_ver; /* Target Version ID */
147 u32 target_type; /* Target type */
148} POSTPACK;
149#define TARGET_VERSION_SENTINAL 0xffffffff
150#define TARGET_TYPE_AR6001 1
151#define TARGET_TYPE_AR6002 2
152#define TARGET_TYPE_AR6003 3
153
154
155#define BMI_ROMPATCH_INSTALL 9
156 /*
157 * Semantics: Install a ROM Patch.
158 * Request format:
159 * u32 command (BMI_ROMPATCH_INSTALL)
160 * u32 Target ROM Address
161 * u32 Target RAM Address or Value (depending on Target Type)
162 * u32 Size, in bytes
163 * u32 Activate? 1-->activate;
164 * 0-->install but do not activate
165 * Response format:
166 * u32 PatchID
167 */
168
169#define BMI_ROMPATCH_UNINSTALL 10
170 /*
171 * Semantics: Uninstall a previously-installed ROM Patch,
172 * automatically deactivating, if necessary.
173 * Request format:
174 * u32 command (BMI_ROMPATCH_UNINSTALL)
175 * u32 PatchID
176 *
177 * Response format: none
178 */
179
180#define BMI_ROMPATCH_ACTIVATE 11
181 /*
182 * Semantics: Activate a list of previously-installed ROM Patches.
183 * Request format:
184 * u32 command (BMI_ROMPATCH_ACTIVATE)
185 * u32 rompatch_count
186 * u32 PatchID[rompatch_count]
187 *
188 * Response format: none
189 */
190
191#define BMI_ROMPATCH_DEACTIVATE 12
192 /*
193 * Semantics: Deactivate a list of active ROM Patches.
194 * Request format:
195 * u32 command (BMI_ROMPATCH_DEACTIVATE)
196 * u32 rompatch_count
197 * u32 PatchID[rompatch_count]
198 *
199 * Response format: none
200 */
201
202
203#define BMI_LZ_STREAM_START 13
204 /*
205 * Semantics: Begin an LZ-compressed stream of input
206 * which is to be uncompressed by the Target to an
207 * output buffer at address. The output buffer must
208 * be sufficiently large to hold the uncompressed
209 * output from the compressed input stream. This BMI
210 * command should be followed by a series of 1 or more
211 * BMI_LZ_DATA commands.
212 * u32 command (BMI_LZ_STREAM_START)
213 * u32 address
214 * Note: Not supported on all versions of ROM firmware.
215 */
216
217#define BMI_LZ_DATA 14
218 /*
219 * Semantics: Host writes AR6K memory with LZ-compressed
220 * data which is uncompressed by the Target. This command
221 * must be preceded by a BMI_LZ_STREAM_START command. A series
222 * of BMI_LZ_DATA commands are considered part of a single
223 * input stream until another BMI_LZ_STREAM_START is issued.
224 * Request format:
225 * u32 command (BMI_LZ_DATA)
226 * u32 length (of compressed data),
227 * at most BMI_DATASZ_MAX
228 * u8 CompressedData[length]
229 * Response format: none
230 * Note: Not supported on all versions of ROM firmware.
231 */
232
233#endif /* __BMI_MSG_H__ */
diff --git a/drivers/staging/ath6kl/include/common/cnxmgmt.h b/drivers/staging/ath6kl/include/common/cnxmgmt.h
new file mode 100644
index 00000000000..7a902cb5483
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/cnxmgmt.h
@@ -0,0 +1,36 @@
1//------------------------------------------------------------------------------
2// <copyright file="cnxmgmt.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef _CNXMGMT_H_
25#define _CNXMGMT_H_
26
27typedef enum {
28 CM_CONNECT_WITHOUT_SCAN = 0x0001,
29 CM_CONNECT_ASSOC_POLICY_USER = 0x0002,
30 CM_CONNECT_SEND_REASSOC = 0x0004,
31 CM_CONNECT_WITHOUT_ROAMTABLE_UPDATE = 0x0008,
32 CM_CONNECT_DO_WPA_OFFLOAD = 0x0010,
33 CM_CONNECT_DO_NOT_DEAUTH = 0x0020,
34} CM_CONNECT_TYPE;
35
36#endif /* _CNXMGMT_H_ */
diff --git a/drivers/staging/ath6kl/include/common/dbglog.h b/drivers/staging/ath6kl/include/common/dbglog.h
new file mode 100644
index 00000000000..5566e568b83
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/dbglog.h
@@ -0,0 +1,126 @@
1//------------------------------------------------------------------------------
2// <copyright file="dbglog.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef _DBGLOG_H_
25#define _DBGLOG_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#define DBGLOG_TIMESTAMP_OFFSET 0
32#define DBGLOG_TIMESTAMP_MASK 0x0000FFFF /* Bit 0-15. Contains bit
33 8-23 of the LF0 timer */
34#define DBGLOG_DBGID_OFFSET 16
35#define DBGLOG_DBGID_MASK 0x03FF0000 /* Bit 16-25 */
36#define DBGLOG_DBGID_NUM_MAX 256 /* Upper limit is width of mask */
37
38#define DBGLOG_MODULEID_OFFSET 26
39#define DBGLOG_MODULEID_MASK 0x3C000000 /* Bit 26-29 */
40#define DBGLOG_MODULEID_NUM_MAX 16 /* Upper limit is width of mask */
41
42/*
43 * Please ensure that the definition of any new module introduced is captured
44 * between the DBGLOG_MODULEID_START and DBGLOG_MODULEID_END defines. The
45 * structure is required for the parser to correctly pick up the values for
46 * different modules.
47 */
48#define DBGLOG_MODULEID_START
49#define DBGLOG_MODULEID_INF 0
50#define DBGLOG_MODULEID_WMI 1
51#define DBGLOG_MODULEID_MISC 2
52#define DBGLOG_MODULEID_PM 3
53#define DBGLOG_MODULEID_TXRX_MGMTBUF 4
54#define DBGLOG_MODULEID_TXRX_TXBUF 5
55#define DBGLOG_MODULEID_TXRX_RXBUF 6
56#define DBGLOG_MODULEID_WOW 7
57#define DBGLOG_MODULEID_WHAL 8
58#define DBGLOG_MODULEID_DC 9
59#define DBGLOG_MODULEID_CO 10
60#define DBGLOG_MODULEID_RO 11
61#define DBGLOG_MODULEID_CM 12
62#define DBGLOG_MODULEID_MGMT 13
63#define DBGLOG_MODULEID_TMR 14
64#define DBGLOG_MODULEID_BTCOEX 15
65#define DBGLOG_MODULEID_END
66
67#define DBGLOG_NUM_ARGS_OFFSET 30
68#define DBGLOG_NUM_ARGS_MASK 0xC0000000 /* Bit 30-31 */
69#define DBGLOG_NUM_ARGS_MAX 2 /* Upper limit is width of mask */
70
71#define DBGLOG_MODULE_LOG_ENABLE_OFFSET 0
72#define DBGLOG_MODULE_LOG_ENABLE_MASK 0x0000FFFF
73
74#define DBGLOG_REPORTING_ENABLED_OFFSET 16
75#define DBGLOG_REPORTING_ENABLED_MASK 0x00010000
76
77#define DBGLOG_TIMESTAMP_RESOLUTION_OFFSET 17
78#define DBGLOG_TIMESTAMP_RESOLUTION_MASK 0x000E0000
79
80#define DBGLOG_REPORT_SIZE_OFFSET 20
81#define DBGLOG_REPORT_SIZE_MASK 0x3FF00000
82
83#define DBGLOG_LOG_BUFFER_SIZE 1500
84#define DBGLOG_DBGID_DEFINITION_LEN_MAX 90
85
86PREPACK struct dbglog_buf_s {
87 struct dbglog_buf_s *next;
88 u8 *buffer;
89 u32 bufsize;
90 u32 length;
91 u32 count;
92 u32 free;
93} POSTPACK;
94
95PREPACK struct dbglog_hdr_s {
96 struct dbglog_buf_s *dbuf;
97 u32 dropped;
98} POSTPACK;
99
100PREPACK struct dbglog_config_s {
101 u32 cfgvalid; /* Mask with valid config bits */
102 union {
103 /* TODO: Take care of endianness */
104 struct {
105 u32 mmask:16; /* Mask of modules with logging on */
106 u32 rep:1; /* Reporting enabled or not */
107 u32 tsr:3; /* Time stamp resolution. Def: 1 ms */
108 u32 size:10; /* Report size in number of messages */
109 u32 reserved:2;
110 } dbglog_config;
111
112 u32 value;
113 } u;
114} POSTPACK;
115
116#define cfgmmask u.dbglog_config.mmask
117#define cfgrep u.dbglog_config.rep
118#define cfgtsr u.dbglog_config.tsr
119#define cfgsize u.dbglog_config.size
120#define cfgvalue u.value
121
122#ifdef __cplusplus
123}
124#endif
125
126#endif /* _DBGLOG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/dbglog_id.h b/drivers/staging/ath6kl/include/common/dbglog_id.h
new file mode 100644
index 00000000000..15ef829cab2
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/dbglog_id.h
@@ -0,0 +1,558 @@
1//------------------------------------------------------------------------------
2// <copyright file="dbglog_id.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef _DBGLOG_ID_H_
25#define _DBGLOG_ID_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/*
32 * The nomenclature for the debug identifiers is MODULE_DESCRIPTION.
33 * Please ensure that the definition of any new debugid introduced is captured
34 * between the <MODULE>_DBGID_DEFINITION_START and
35 * <MODULE>_DBGID_DEFINITION_END defines. The structure is required for the
36 * parser to correctly pick up the values for different debug identifiers.
37 */
38
39/* INF debug identifier definitions */
40#define INF_DBGID_DEFINITION_START
41#define INF_ASSERTION_FAILED 1
42#define INF_TARGET_ID 2
43#define INF_DBGID_DEFINITION_END
44
45/* WMI debug identifier definitions */
46#define WMI_DBGID_DEFINITION_START
47#define WMI_CMD_RX_XTND_PKT_TOO_SHORT 1
48#define WMI_EXTENDED_CMD_NOT_HANDLED 2
49#define WMI_CMD_RX_PKT_TOO_SHORT 3
50#define WMI_CALLING_WMI_EXTENSION_FN 4
51#define WMI_CMD_NOT_HANDLED 5
52#define WMI_IN_SYNC 6
53#define WMI_TARGET_WMI_SYNC_CMD 7
54#define WMI_SET_SNR_THRESHOLD_PARAMS 8
55#define WMI_SET_RSSI_THRESHOLD_PARAMS 9
56#define WMI_SET_LQ_TRESHOLD_PARAMS 10
57#define WMI_TARGET_CREATE_PSTREAM_CMD 11
58#define WMI_WI_DTM_INUSE 12
59#define WMI_TARGET_DELETE_PSTREAM_CMD 13
60#define WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD 14
61#define WMI_TARGET_GET_BIT_RATE_CMD 15
62#define WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS 16
63#define WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD 17
64#define WMI_TARGET_GET_TX_PWR_CMD 18
65#define WMI_FREE_EVBUF_WMIBUF 19
66#define WMI_FREE_EVBUF_DATABUF 20
67#define WMI_FREE_EVBUF_BADFLAG 21
68#define WMI_HTC_RX_ERROR_DATA_PACKET 22
69#define WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX 23
70#define WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT 24
71#define WMI_SENDING_READY_EVENT 25
72#define WMI_SETPOWER_MDOE_TO_MAXPERF 26
73#define WMI_SETPOWER_MDOE_TO_REC 27
74#define WMI_BSSINFO_EVENT_FROM 28
75#define WMI_TARGET_GET_STATS_CMD 29
76#define WMI_SENDING_SCAN_COMPLETE_EVENT 30
77#define WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT 31
78#define WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT 32
79#define WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT 33
80#define WMI_SENDING_ERROR_REPORT_EVENT 34
81#define WMI_SENDING_CAC_EVENT 35
82#define WMI_TARGET_GET_ROAM_TABLE_CMD 36
83#define WMI_TARGET_GET_ROAM_DATA_CMD 37
84#define WMI_SENDING_GPIO_INTR_EVENT 38
85#define WMI_SENDING_GPIO_ACK_EVENT 39
86#define WMI_SENDING_GPIO_DATA_EVENT 40
87#define WMI_CMD_RX 41
88#define WMI_CMD_RX_XTND 42
89#define WMI_EVENT_SEND 43
90#define WMI_EVENT_SEND_XTND 44
91#define WMI_CMD_PARAMS_DUMP_START 45
92#define WMI_CMD_PARAMS_DUMP_END 46
93#define WMI_CMD_PARAMS 47
94#define WMI_DBGID_DEFINITION_END
95
96/* MISC debug identifier definitions */
97#define MISC_DBGID_DEFINITION_START
98#define MISC_WLAN_SCHEDULER_EVENT_REGISTER_ERROR 1
99#define TLPM_INIT 2
100#define TLPM_FILTER_POWER_STATE 3
101#define TLPM_NOTIFY_NOT_IDLE 4
102#define TLPM_TIMEOUT_IDLE_HANDLER 5
103#define TLPM_TIMEOUT_WAKEUP_HANDLER 6
104#define TLPM_WAKEUP_SIGNAL_HANDLER 7
105#define TLPM_UNEXPECTED_GPIO_INTR_ERROR 8
106#define TLPM_BREAK_ON_NOT_RECEIVED_ERROR 9
107#define TLPM_BREAK_OFF_NOT_RECIVED_ERROR 10
108#define TLPM_ACK_GPIO_INTR 11
109#define TLPM_ON 12
110#define TLPM_OFF 13
111#define TLPM_WAKEUP_FROM_HOST 14
112#define TLPM_WAKEUP_FROM_BT 15
113#define TLPM_TX_BREAK_RECIVED 16
114#define TLPM_IDLE_TIMER_NOT_RUNNING 17
115#define MISC_DBGID_DEFINITION_END
116
117/* TXRX debug identifier definitions */
118#define TXRX_TXBUF_DBGID_DEFINITION_START
119#define TXRX_TXBUF_ALLOCATE_BUF 1
120#define TXRX_TXBUF_QUEUE_BUF_TO_MBOX 2
121#define TXRX_TXBUF_QUEUE_BUF_TO_TXQ 3
122#define TXRX_TXBUF_TXQ_DEPTH 4
123#define TXRX_TXBUF_IBSS_QUEUE_TO_SFQ 5
124#define TXRX_TXBUF_IBSS_QUEUE_TO_TXQ_FRM_SFQ 6
125#define TXRX_TXBUF_INITIALIZE_TIMER 7
126#define TXRX_TXBUF_ARM_TIMER 8
127#define TXRX_TXBUF_DISARM_TIMER 9
128#define TXRX_TXBUF_UNINITIALIZE_TIMER 10
129#define TXRX_TXBUF_DBGID_DEFINITION_END
130
131#define TXRX_RXBUF_DBGID_DEFINITION_START
132#define TXRX_RXBUF_ALLOCATE_BUF 1
133#define TXRX_RXBUF_QUEUE_TO_HOST 2
134#define TXRX_RXBUF_QUEUE_TO_WLAN 3
135#define TXRX_RXBUF_ZERO_LEN_BUF 4
136#define TXRX_RXBUF_QUEUE_TO_HOST_LASTBUF_IN_RXCHAIN 5
137#define TXRX_RXBUF_LASTBUF_IN_RXCHAIN_ZEROBUF 6
138#define TXRX_RXBUF_QUEUE_EMPTY_QUEUE_TO_WLAN 7
139#define TXRX_RXBUF_SEND_TO_RECV_MGMT 8
140#define TXRX_RXBUF_SEND_TO_IEEE_LAYER 9
141#define TXRX_RXBUF_REQUEUE_ERROR 10
142#define TXRX_RXBUF_DBGID_DEFINITION_END
143
144#define TXRX_MGMTBUF_DBGID_DEFINITION_START
145#define TXRX_MGMTBUF_ALLOCATE_BUF 1
146#define TXRX_MGMTBUF_ALLOCATE_SM_BUF 2
147#define TXRX_MGMTBUF_ALLOCATE_RMBUF 3
148#define TXRX_MGMTBUF_GET_BUF 4
149#define TXRX_MGMTBUF_GET_SM_BUF 5
150#define TXRX_MGMTBUF_QUEUE_BUF_TO_TXQ 6
151#define TXRX_MGMTBUF_REAPED_BUF 7
152#define TXRX_MGMTBUF_REAPED_SM_BUF 8
153#define TXRX_MGMTBUF_WAIT_FOR_TXQ_DRAIN 9
154#define TXRX_MGMTBUF_WAIT_FOR_TXQ_SFQ_DRAIN 10
155#define TXRX_MGMTBUF_ENQUEUE_INTO_DATA_SFQ 11
156#define TXRX_MGMTBUF_DEQUEUE_FROM_DATA_SFQ 12
157#define TXRX_MGMTBUF_PAUSE_DATA_TXQ 13
158#define TXRX_MGMTBUF_RESUME_DATA_TXQ 14
159#define TXRX_MGMTBUF_WAIT_FORTXQ_DRAIN_TIMEOUT 15
160#define TXRX_MGMTBUF_DRAINQ 16
161#define TXRX_MGMTBUF_INDICATE_Q_DRAINED 17
162#define TXRX_MGMTBUF_ENQUEUE_INTO_HW_SFQ 18
163#define TXRX_MGMTBUF_DEQUEUE_FROM_HW_SFQ 19
164#define TXRX_MGMTBUF_PAUSE_HW_TXQ 20
165#define TXRX_MGMTBUF_RESUME_HW_TXQ 21
166#define TXRX_MGMTBUF_TEAR_DOWN_BA 22
167#define TXRX_MGMTBUF_PROCESS_ADDBA_REQ 23
168#define TXRX_MGMTBUF_PROCESS_DELBA 24
169#define TXRX_MGMTBUF_PERFORM_BA 25
170#define TXRX_MGMTBUF_WLAN_RESET_ON_ERROR 26
171#define TXRX_MGMTBUF_DBGID_DEFINITION_END
172
173/* PM (Power Module) debug identifier definitions */
174#define PM_DBGID_DEFINITION_START
175#define PM_INIT 1
176#define PM_ENABLE 2
177#define PM_SET_STATE 3
178#define PM_SET_POWERMODE 4
179#define PM_CONN_NOTIFY 5
180#define PM_REF_COUNT_NEGATIVE 6
181#define PM_INFRA_STA_APSD_ENABLE 7
182#define PM_INFRA_STA_UPDATE_APSD_STATE 8
183#define PM_CHAN_OP_REQ 9
184#define PM_SET_MY_BEACON_POLICY 10
185#define PM_SET_ALL_BEACON_POLICY 11
186#define PM_INFRA_STA_SET_PM_PARAMS1 12
187#define PM_INFRA_STA_SET_PM_PARAMS2 13
188#define PM_ADHOC_SET_PM_CAPS_FAIL 14
189#define PM_ADHOC_UNKNOWN_IBSS_ATTRIB_ID 15
190#define PM_ADHOC_SET_PM_PARAMS 16
191#define PM_ADHOC_STATE1 18
192#define PM_ADHOC_STATE2 19
193#define PM_ADHOC_CONN_MAP 20
194#define PM_FAKE_SLEEP 21
195#define PM_AP_STATE1 22
196#define PM_AP_SET_PM_PARAMS 23
197#define PM_DBGID_DEFINITION_END
198
199/* Wake on Wireless debug identifier definitions */
200#define WOW_DBGID_DEFINITION_START
201#define WOW_INIT 1
202#define WOW_GET_CONFIG_DSET 2
203#define WOW_NO_CONFIG_DSET 3
204#define WOW_INVALID_CONFIG_DSET 4
205#define WOW_USE_DEFAULT_CONFIG 5
206#define WOW_SETUP_GPIO 6
207#define WOW_INIT_DONE 7
208#define WOW_SET_GPIO_PIN 8
209#define WOW_CLEAR_GPIO_PIN 9
210#define WOW_SET_WOW_MODE_CMD 10
211#define WOW_SET_HOST_MODE_CMD 11
212#define WOW_ADD_WOW_PATTERN_CMD 12
213#define WOW_NEW_WOW_PATTERN_AT_INDEX 13
214#define WOW_DEL_WOW_PATTERN_CMD 14
215#define WOW_LIST_CONTAINS_PATTERNS 15
216#define WOW_GET_WOW_LIST_CMD 16
217#define WOW_INVALID_FILTER_ID 17
218#define WOW_INVALID_FILTER_LISTID 18
219#define WOW_NO_VALID_FILTER_AT_ID 19
220#define WOW_NO_VALID_LIST_AT_ID 20
221#define WOW_NUM_PATTERNS_EXCEEDED 21
222#define WOW_NUM_LISTS_EXCEEDED 22
223#define WOW_GET_WOW_STATS 23
224#define WOW_CLEAR_WOW_STATS 24
225#define WOW_WAKEUP_HOST 25
226#define WOW_EVENT_WAKEUP_HOST 26
227#define WOW_EVENT_DISCARD 27
228#define WOW_PATTERN_MATCH 28
229#define WOW_PATTERN_NOT_MATCH 29
230#define WOW_PATTERN_NOT_MATCH_OFFSET 30
231#define WOW_DISABLED_HOST_ASLEEP 31
232#define WOW_ENABLED_HOST_ASLEEP_NO_PATTERNS 32
233#define WOW_ENABLED_HOST_ASLEEP_NO_MATCH_FOUND 33
234#define WOW_DBGID_DEFINITION_END
235
236/* WHAL debug identifier definitions */
237#define WHAL_DBGID_DEFINITION_START
238#define WHAL_ERROR_ANI_CONTROL 1
239#define WHAL_ERROR_CHIP_TEST1 2
240#define WHAL_ERROR_CHIP_TEST2 3
241#define WHAL_ERROR_EEPROM_CHECKSUM 4
242#define WHAL_ERROR_EEPROM_MACADDR 5
243#define WHAL_ERROR_INTERRUPT_HIU 6
244#define WHAL_ERROR_KEYCACHE_RESET 7
245#define WHAL_ERROR_KEYCACHE_SET 8
246#define WHAL_ERROR_KEYCACHE_TYPE 9
247#define WHAL_ERROR_KEYCACHE_TKIPENTRY 10
248#define WHAL_ERROR_KEYCACHE_WEPLENGTH 11
249#define WHAL_ERROR_PHY_INVALID_CHANNEL 12
250#define WHAL_ERROR_POWER_AWAKE 13
251#define WHAL_ERROR_POWER_SET 14
252#define WHAL_ERROR_RECV_STOPDMA 15
253#define WHAL_ERROR_RECV_STOPPCU 16
254#define WHAL_ERROR_RESET_CHANNF1 17
255#define WHAL_ERROR_RESET_CHANNF2 18
256#define WHAL_ERROR_RESET_PM 19
257#define WHAL_ERROR_RESET_OFFSETCAL 20
258#define WHAL_ERROR_RESET_RFGRANT 21
259#define WHAL_ERROR_RESET_RXFRAME 22
260#define WHAL_ERROR_RESET_STOPDMA 23
261#define WHAL_ERROR_RESET_RECOVER 24
262#define WHAL_ERROR_XMIT_COMPUTE 25
263#define WHAL_ERROR_XMIT_NOQUEUE 26
264#define WHAL_ERROR_XMIT_ACTIVEQUEUE 27
265#define WHAL_ERROR_XMIT_BADTYPE 28
266#define WHAL_ERROR_XMIT_STOPDMA 29
267#define WHAL_ERROR_INTERRUPT_BB_PANIC 30
268#define WHAL_ERROR_RESET_TXIQCAL 31
269#define WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW 32
270#define WHAL_DBGID_DEFINITION_END
271
272/* DC debug identifier definitions */
273#define DC_DBGID_DEFINITION_START
274#define DC_SCAN_CHAN_START 1
275#define DC_SCAN_CHAN_FINISH 2
276#define DC_BEACON_RECEIVE7 3
277#define DC_SSID_PROBE_CB 4
278#define DC_SEND_NEXT_SSID_PROBE 5
279#define DC_START_SEARCH 6
280#define DC_CANCEL_SEARCH_CB 7
281#define DC_STOP_SEARCH 8
282#define DC_END_SEARCH 9
283#define DC_MIN_CHDWELL_TIMEOUT 10
284#define DC_START_SEARCH_CANCELED 11
285#define DC_SET_POWER_MODE 12
286#define DC_INIT 13
287#define DC_SEARCH_OPPORTUNITY 14
288#define DC_RECEIVED_ANY_BEACON 15
289#define DC_RECEIVED_MY_BEACON 16
290#define DC_PROFILE_IS_ADHOC_BUT_BSS_IS_INFRA 17
291#define DC_PS_ENABLED_BUT_ATHEROS_IE_ABSENT 18
292#define DC_BSS_ADHOC_CHANNEL_NOT_ALLOWED 19
293#define DC_SET_BEACON_UPDATE 20
294#define DC_BEACON_UPDATE_COMPLETE 21
295#define DC_END_SEARCH_BEACON_UPDATE_COMP_CB 22
296#define DC_BSSINFO_EVENT_DROPPED 23
297#define DC_IEEEPS_ENABLED_BUT_ATIM_ABSENT 24
298#define DC_DBGID_DEFINITION_END
299
300/* CO debug identifier definitions */
301#define CO_DBGID_DEFINITION_START
302#define CO_INIT 1
303#define CO_ACQUIRE_LOCK 2
304#define CO_START_OP1 3
305#define CO_START_OP2 4
306#define CO_DRAIN_TX_COMPLETE_CB 5
307#define CO_CHANGE_CHANNEL_CB 6
308#define CO_RETURN_TO_HOME_CHANNEL 7
309#define CO_FINISH_OP_TIMEOUT 8
310#define CO_OP_END 9
311#define CO_CANCEL_OP 10
312#define CO_CHANGE_CHANNEL 11
313#define CO_RELEASE_LOCK 12
314#define CO_CHANGE_STATE 13
315#define CO_DBGID_DEFINITION_END
316
317/* RO debug identifier definitions */
318#define RO_DBGID_DEFINITION_START
319#define RO_REFRESH_ROAM_TABLE 1
320#define RO_UPDATE_ROAM_CANDIDATE 2
321#define RO_UPDATE_ROAM_CANDIDATE_CB 3
322#define RO_UPDATE_ROAM_CANDIDATE_FINISH 4
323#define RO_REFRESH_ROAM_TABLE_DONE 5
324#define RO_PERIODIC_SEARCH_CB 6
325#define RO_PERIODIC_SEARCH_TIMEOUT 7
326#define RO_INIT 8
327#define RO_BMISS_STATE1 9
328#define RO_BMISS_STATE2 10
329#define RO_SET_PERIODIC_SEARCH_ENABLE 11
330#define RO_SET_PERIODIC_SEARCH_DISABLE 12
331#define RO_ENABLE_SQ_THRESHOLD 13
332#define RO_DISABLE_SQ_THRESHOLD 14
333#define RO_ADD_BSS_TO_ROAM_TABLE 15
334#define RO_SET_PERIODIC_SEARCH_MODE 16
335#define RO_CONFIGURE_SQ_THRESHOLD1 17
336#define RO_CONFIGURE_SQ_THRESHOLD2 18
337#define RO_CONFIGURE_SQ_PARAMS 19
338#define RO_LOW_SIGNAL_QUALITY_EVENT 20
339#define RO_HIGH_SIGNAL_QUALITY_EVENT 21
340#define RO_REMOVE_BSS_FROM_ROAM_TABLE 22
341#define RO_UPDATE_CONNECTION_STATE_METRIC 23
342#define RO_DBGID_DEFINITION_END
343
344/* CM debug identifier definitions */
345#define CM_DBGID_DEFINITION_START
346#define CM_INITIATE_HANDOFF 1
347#define CM_INITIATE_HANDOFF_CB 2
348#define CM_CONNECT_EVENT 3
349#define CM_DISCONNECT_EVENT 4
350#define CM_INIT 5
351#define CM_HANDOFF_SOURCE 6
352#define CM_SET_HANDOFF_TRIGGERS 7
353#define CM_CONNECT_REQUEST 8
354#define CM_CONNECT_REQUEST_CB 9
355#define CM_CONTINUE_SCAN_CB 10
356#define CM_DBGID_DEFINITION_END
357
358
359/* mgmt debug identifier definitions */
360#define MGMT_DBGID_DEFINITION_START
361#define KEYMGMT_CONNECTION_INIT 1
362#define KEYMGMT_CONNECTION_COMPLETE 2
363#define KEYMGMT_CONNECTION_CLOSE 3
364#define KEYMGMT_ADD_KEY 4
365#define MLME_NEW_STATE 5
366#define MLME_CONN_INIT 6
367#define MLME_CONN_COMPLETE 7
368#define MLME_CONN_CLOSE 8
369#define MGMT_DBGID_DEFINITION_END
370
371/* TMR debug identifier definitions */
372#define TMR_DBGID_DEFINITION_START
373#define TMR_HANG_DETECTED 1
374#define TMR_WDT_TRIGGERED 2
375#define TMR_WDT_RESET 3
376#define TMR_HANDLER_ENTRY 4
377#define TMR_HANDLER_EXIT 5
378#define TMR_SAVED_START 6
379#define TMR_SAVED_END 7
380#define TMR_DBGID_DEFINITION_END
381
382/* BTCOEX debug identifier definitions */
383#define BTCOEX_DBGID_DEFINITION_START
384#define BTCOEX_STATUS_CMD 1
385#define BTCOEX_PARAMS_CMD 2
386#define BTCOEX_ANT_CONFIG 3
387#define BTCOEX_COLOCATED_BT_DEVICE 4
388#define BTCOEX_CLOSE_RANGE_SCO_ON 5
389#define BTCOEX_CLOSE_RANGE_SCO_OFF 6
390#define BTCOEX_CLOSE_RANGE_A2DP_ON 7
391#define BTCOEX_CLOSE_RANGE_A2DP_OFF 8
392#define BTCOEX_A2DP_PROTECT_ON 9
393#define BTCOEX_A2DP_PROTECT_OFF 10
394#define BTCOEX_SCO_PROTECT_ON 11
395#define BTCOEX_SCO_PROTECT_OFF 12
396#define BTCOEX_CLOSE_RANGE_DETECTOR_START 13
397#define BTCOEX_CLOSE_RANGE_DETECTOR_STOP 14
398#define BTCOEX_CLOSE_RANGE_TOGGLE 15
399#define BTCOEX_CLOSE_RANGE_TOGGLE_RSSI_LRCNT 16
400#define BTCOEX_CLOSE_RANGE_RSSI_THRESH 17
401#define BTCOEX_CLOSE_RANGE_LOW_RATE_THRESH 18
402#define BTCOEX_PTA_PRI_INTR_HANDLER 19
403#define BTCOEX_PSPOLL_QUEUED 20
404#define BTCOEX_PSPOLL_COMPLETE 21
405#define BTCOEX_DBG_PM_AWAKE 22
406#define BTCOEX_DBG_PM_SLEEP 23
407#define BTCOEX_DBG_SCO_COEX_ON 24
408#define BTCOEX_SCO_DATARECEIVE 25
409#define BTCOEX_INTR_INIT 26
410#define BTCOEX_PTA_PRI_DIFF 27
411#define BTCOEX_TIM_NOTIFICATION 28
412#define BTCOEX_SCO_WAKEUP_ON_DATA 29
413#define BTCOEX_SCO_SLEEP 30
414#define BTCOEX_SET_WEIGHTS 31
415#define BTCOEX_SCO_DATARECEIVE_LATENCY_VAL 32
416#define BTCOEX_SCO_MEASURE_TIME_DIFF 33
417#define BTCOEX_SET_EOL_VAL 34
418#define BTCOEX_OPT_DETECT_HANDLER 35
419#define BTCOEX_SCO_TOGGLE_STATE 36
420#define BTCOEX_SCO_STOMP 37
421#define BTCOEX_NULL_COMP_CALLBACK 38
422#define BTCOEX_RX_INCOMING 39
423#define BTCOEX_RX_INCOMING_CTL 40
424#define BTCOEX_RX_INCOMING_MGMT 41
425#define BTCOEX_RX_INCOMING_DATA 42
426#define BTCOEX_RTS_RECEPTION 43
427#define BTCOEX_FRAME_PRI_LOW_RATE_THRES 44
428#define BTCOEX_PM_FAKE_SLEEP 45
429#define BTCOEX_ACL_COEX_STATUS 46
430#define BTCOEX_ACL_COEX_DETECTION 47
431#define BTCOEX_A2DP_COEX_STATUS 48
432#define BTCOEX_SCO_STATUS 49
433#define BTCOEX_WAKEUP_ON_DATA 50
434#define BTCOEX_DATARECEIVE 51
435#define BTCOEX_GET_MAX_AGGR_SIZE 53
436#define BTCOEX_MAX_AGGR_AVAIL_TIME 54
437#define BTCOEX_DBG_WBTIMER_INTR 55
438#define BTCOEX_DBG_SCO_SYNC 57
439#define BTCOEX_UPLINK_QUEUED_RATE 59
440#define BTCOEX_DBG_UPLINK_ENABLE_EOL 60
441#define BTCOEX_UPLINK_FRAME_DURATION 61
442#define BTCOEX_UPLINK_SET_EOL 62
443#define BTCOEX_DBG_EOL_EXPIRED 63
444#define BTCOEX_DBG_DATA_COMPLETE 64
445#define BTCOEX_UPLINK_QUEUED_TIMESTAMP 65
446#define BTCOEX_DBG_DATA_COMPLETE_TIME 66
447#define BTCOEX_DBG_A2DP_ROLE_IS_SLAVE 67
448#define BTCOEX_DBG_A2DP_ROLE_IS_MASTER 68
449#define BTCOEX_DBG_UPLINK_SEQ_NUM 69
450#define BTCOEX_UPLINK_AGGR_SEQ 70
451#define BTCOEX_DBG_TX_COMP_SEQ_NO 71
452#define BTCOEX_DBG_MAX_AGGR_PAUSE_STATE 72
453#define BTCOEX_DBG_ACL_TRAFFIC 73
454#define BTCOEX_CURR_AGGR_PROP 74
455#define BTCOEX_DBG_SCO_GET_PER_TIME_DIFF 75
456#define BTCOEX_PSPOLL_PROCESS 76
457#define BTCOEX_RETURN_FROM_MAC 77
458#define BTCOEX_FREED_REQUEUED_CNT 78
459#define BTCOEX_DBG_TOGGLE_LOW_RATES 79
460#define BTCOEX_MAC_GOES_TO_SLEEP 80
461#define BTCOEX_DBG_A2DP_NO_SYNC 81
462#define BTCOEX_RETURN_FROM_MAC_HOLD_Q_INFO 82
463#define BTCOEX_RETURN_FROM_MAC_AC 83
464#define BTCOEX_DBG_DTIM_RECV 84
465#define BTCOEX_IS_PRE_UPDATE 86
466#define BTCOEX_ENQUEUED_BIT_MAP 87
467#define BTCOEX_TX_COMPLETE_FIRST_DESC_STATS 88
468#define BTCOEX_UPLINK_DESC 89
469#define BTCOEX_SCO_GET_PER_FIRST_FRM_TIMESTAMP 90
470#define BTCOEX_DBG_RECV_ACK 94
471#define BTCOEX_DBG_ADDBA_INDICATION 95
472#define BTCOEX_TX_COMPLETE_EOL_FAILED 96
473#define BTCOEX_DBG_A2DP_USAGE_COMPLETE 97
474#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_HANDLER 98
475#define BTCOEX_DBG_A2DP_SYNC_INTR 99
476#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_RECEPTION 100
477#define BTCOEX_FORM_AGGR_CURR_AGGR 101
478#define BTCOEX_DBG_TOGGLE_A2DP_BURST_CNT 102
479#define BTCOEX_DBG_BT_TRAFFIC 103
480#define BTCOEX_DBG_STOMP_BT_TRAFFIC 104
481#define BTCOEX_RECV_NULL 105
482#define BTCOEX_DBG_A2DP_MASTER_BT_END 106
483#define BTCOEX_DBG_A2DP_BT_START 107
484#define BTCOEX_DBG_A2DP_SLAVE_BT_END 108
485#define BTCOEX_DBG_A2DP_STOMP_BT 109
486#define BTCOEX_DBG_GO_TO_SLEEP 110
487#define BTCOEX_DBG_A2DP_PKT 111
488#define BTCOEX_DBG_A2DP_PSPOLL_DATA_RECV 112
489#define BTCOEX_DBG_A2DP_NULL 113
490#define BTCOEX_DBG_UPLINK_DATA 114
491#define BTCOEX_DBG_A2DP_STOMP_LOW_PRIO_NULL 115
492#define BTCOEX_DBG_ADD_BA_RESP_TIMEOUT 116
493#define BTCOEX_DBG_TXQ_STATE 117
494#define BTCOEX_DBG_ALLOW_SCAN 118
495#define BTCOEX_DBG_SCAN_REQUEST 119
496#define BTCOEX_A2DP_SLEEP 127
497#define BTCOEX_DBG_DATA_ACTIV_TIMEOUT 128
498#define BTCOEX_DBG_SWITCH_TO_PSPOLL_ON_MODE 129
499#define BTCOEX_DBG_SWITCH_TO_PSPOLL_OFF_MODE 130
500#define BTCOEX_DATARECEIVE_AGGR 131
501#define BTCOEX_DBG_DATA_RECV_SLEEPING_PENDING 132
502#define BTCOEX_DBG_DATARESP_TIMEOUT 133
503#define BTCOEX_BDG_BMISS 134
504#define BTCOEX_DBG_DATA_RECV_WAKEUP_TIM 135
505#define BTCOEX_DBG_SECOND_BMISS 136
506#define BTCOEX_DBG_SET_WLAN_STATE 138
507#define BTCOEX_BDG_FIRST_BMISS 139
508#define BTCOEX_DBG_A2DP_CHAN_OP 140
509#define BTCOEX_DBG_A2DP_INTR 141
510#define BTCOEX_DBG_BT_INQUIRY 142
511#define BTCOEX_DBG_BT_INQUIRY_DATA_FETCH 143
512#define BTCOEX_DBG_POST_INQUIRY_FINISH 144
513#define BTCOEX_DBG_SCO_OPT_MODE_TIMER_HANDLER 145
514#define BTCOEX_DBG_NULL_FRAME_SLEEP 146
515#define BTCOEX_DBG_NULL_FRAME_AWAKE 147
516#define BTCOEX_DBG_SET_AGGR_SIZE 152
517#define BTCOEX_DBG_TEAR_BA_TIMEOUT 153
518#define BTCOEX_DBG_MGMT_FRAME_SEQ_NO 154
519#define BTCOEX_DBG_SCO_STOMP_HIGH_PRI 155
520#define BTCOEX_DBG_COLOCATED_BT_DEV 156
521#define BTCOEX_DBG_FE_ANT_TYPE 157
522#define BTCOEX_DBG_BT_INQUIRY_CMD 158
523#define BTCOEX_DBG_SCO_CONFIG 159
524#define BTCOEX_DBG_SCO_PSPOLL_CONFIG 160
525#define BTCOEX_DBG_SCO_OPTMODE_CONFIG 161
526#define BTCOEX_DBG_A2DP_CONFIG 162
527#define BTCOEX_DBG_A2DP_PSPOLL_CONFIG 163
528#define BTCOEX_DBG_A2DP_OPTMODE_CONFIG 164
529#define BTCOEX_DBG_ACLCOEX_CONFIG 165
530#define BTCOEX_DBG_ACLCOEX_PSPOLL_CONFIG 166
531#define BTCOEX_DBG_ACLCOEX_OPTMODE_CONFIG 167
532#define BTCOEX_DBG_DEBUG_CMD 168
533#define BTCOEX_DBG_SET_BT_OPERATING_STATUS 169
534#define BTCOEX_DBG_GET_CONFIG 170
535#define BTCOEX_DBG_GET_STATS 171
536#define BTCOEX_DBG_BT_OPERATING_STATUS 172
537#define BTCOEX_DBG_PERFORM_RECONNECT 173
538#define BTCOEX_DBG_ACL_WLAN_MED 175
539#define BTCOEX_DBG_ACL_BT_MED 176
540#define BTCOEX_DBG_WLAN_CONNECT 177
541#define BTCOEX_DBG_A2DP_DUAL_START 178
542#define BTCOEX_DBG_PMAWAKE_NOTIFY 179
543#define BTCOEX_DBG_BEACON_SCAN_ENABLE 180
544#define BTCOEX_DBG_BEACON_SCAN_DISABLE 181
545#define BTCOEX_DBG_RX_NOTIFY 182
546#define BTCOEX_SCO_GET_PER_SECOND_FRM_TIMESTAMP 183
547#define BTCOEX_DBG_TXQ_DETAILS 184
548#define BTCOEX_DBG_SCO_STOMP_LOW_PRI 185
549#define BTCOEX_DBG_A2DP_FORCE_SCAN 186
550#define BTCOEX_DBG_DTIM_STOMP_COMP 187
551#define BTCOEX_ACL_PRESENCE_TIMER 188
552#define BTCOEX_DBGID_DEFINITION_END
553
554#ifdef __cplusplus
555}
556#endif
557
558#endif /* _DBGLOG_ID_H_ */
diff --git a/drivers/staging/ath6kl/include/common/discovery.h b/drivers/staging/ath6kl/include/common/discovery.h
new file mode 100644
index 00000000000..da1b3324506
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/discovery.h
@@ -0,0 +1,75 @@
1//------------------------------------------------------------------------------
2// <copyright file="discovery.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef _DISCOVERY_H_
25#define _DISCOVERY_H_
26
27/*
28 * DC_SCAN_PRIORITY is an 8-bit bitmap of the scan priority of a channel
29 */
30typedef enum {
31 DEFAULT_SCPRI = 0x01,
32 POPULAR_SCPRI = 0x02,
33 SSIDS_SCPRI = 0x04,
34 PROF_SCPRI = 0x08,
35} DC_SCAN_PRIORITY;
36
37/* The following search type construct can be used to manipulate the behavior of the search module based on different bits set */
38typedef enum {
39 SCAN_RESET = 0,
40 SCAN_ALL = (DEFAULT_SCPRI | POPULAR_SCPRI | \
41 SSIDS_SCPRI | PROF_SCPRI),
42
43 SCAN_POPULAR = (POPULAR_SCPRI | SSIDS_SCPRI | PROF_SCPRI),
44 SCAN_SSIDS = (SSIDS_SCPRI | PROF_SCPRI),
45 SCAN_PROF_MASK = (PROF_SCPRI),
46 SCAN_MULTI_CHANNEL = 0x000100,
47 SCAN_DETERMINISTIC = 0x000200,
48 SCAN_PROFILE_MATCH_TERMINATED = 0x000400,
49 SCAN_HOME_CHANNEL_SKIP = 0x000800,
50 SCAN_CHANNEL_LIST_CONTINUE = 0x001000,
51 SCAN_CURRENT_SSID_SKIP = 0x002000,
52 SCAN_ACTIVE_PROBE_DISABLE = 0x004000,
53 SCAN_CHANNEL_HINT_ONLY = 0x008000,
54 SCAN_ACTIVE_CHANNELS_ONLY = 0x010000,
55 SCAN_UNUSED1 = 0x020000, /* unused */
56 SCAN_PERIODIC = 0x040000,
57 SCAN_FIXED_DURATION = 0x080000,
58 SCAN_AP_ASSISTED = 0x100000,
59} DC_SCAN_TYPE;
60
61typedef enum {
62 BSS_REPORTING_DEFAULT = 0x0,
63 EXCLUDE_NON_SCAN_RESULTS = 0x1, /* Exclude results outside of scan */
64} DC_BSS_REPORTING_POLICY;
65
66typedef enum {
67 DC_IGNORE_WPAx_GROUP_CIPHER = 0x01,
68 DC_PROFILE_MATCH_DONE = 0x02,
69 DC_IGNORE_AAC_BEACON = 0x04,
70 DC_CSA_FOLLOW_BSS = 0x08,
71} DC_PROFILE_FILTER;
72
73#define DEFAULT_DC_PROFILE_FILTER (DC_CSA_FOLLOW_BSS)
74
75#endif /* _DISCOVERY_H_ */
diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h
new file mode 100644
index 00000000000..9eb5fdfa746
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/epping_test.h
@@ -0,0 +1,111 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//
22
23/* This file contains shared definitions for the host/target endpoint ping test */
24
25#ifndef EPPING_TEST_H_
26#define EPPING_TEST_H_
27
28 /* alignment to 4-bytes */
29#define EPPING_ALIGNMENT_PAD (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) - sizeof(struct htc_frame_hdr))
30
31#ifndef A_OFFSETOF
32#define A_OFFSETOF(type,field) (int)(&(((type *)NULL)->field))
33#endif
34
35#define EPPING_RSVD_FILL 0xCC
36
37#define HCI_RSVD_EXPECTED_PKT_TYPE_RECV_OFFSET 7
38
39typedef PREPACK struct {
40 u8 _HCIRsvd[8]; /* reserved for HCI packet header (GMBOX) testing */
41 u8 StreamEcho_h; /* stream no. to echo this packet on (filled by host) */
42 u8 StreamEchoSent_t; /* stream no. packet was echoed to (filled by target)
43 When echoed: StreamEchoSent_t == StreamEcho_h */
44 u8 StreamRecv_t; /* stream no. that target received this packet on (filled by target) */
45 u8 StreamNo_h; /* stream number to send on (filled by host) */
46 u8 Magic_h[4]; /* magic number to filter for this packet on the host*/
47 u8 _rsvd[6]; /* reserved fields that must be set to a "reserved" value
48 since this packet maps to a 14-byte ethernet frame we want
49 to make sure ethertype field is set to something unknown */
50
51 u8 _pad[2]; /* padding for alignment */
52 u8 TimeStamp[8]; /* timestamp of packet (host or target) */
53 u32 HostContext_h; /* 4 byte host context, target echos this back */
54 u32 SeqNo; /* sequence number (set by host or target) */
55 u16 Cmd_h; /* ping command (filled by host) */
56 u16 CmdFlags_h; /* optional flags */
57 u8 CmdBuffer_h[8]; /* buffer for command (host -> target) */
58 u8 CmdBuffer_t[8]; /* buffer for command (target -> host) */
59 u16 DataLength; /* length of data */
60 u16 DataCRC; /* 16 bit CRC of data */
61 u16 HeaderCRC; /* header CRC (fields : StreamNo_h to end, minus HeaderCRC) */
62} POSTPACK EPPING_HEADER;
63
64#define EPPING_PING_MAGIC_0 0xAA
65#define EPPING_PING_MAGIC_1 0x55
66#define EPPING_PING_MAGIC_2 0xCE
67#define EPPING_PING_MAGIC_3 0xEC
68
69
70
71#define IS_EPPING_PACKET(pPkt) (((pPkt)->Magic_h[0] == EPPING_PING_MAGIC_0) && \
72 ((pPkt)->Magic_h[1] == EPPING_PING_MAGIC_1) && \
73 ((pPkt)->Magic_h[2] == EPPING_PING_MAGIC_2) && \
74 ((pPkt)->Magic_h[3] == EPPING_PING_MAGIC_3))
75
76#define SET_EPPING_PACKET_MAGIC(pPkt) { (pPkt)->Magic_h[0] = EPPING_PING_MAGIC_0; \
77 (pPkt)->Magic_h[1] = EPPING_PING_MAGIC_1; \
78 (pPkt)->Magic_h[2] = EPPING_PING_MAGIC_2; \
79 (pPkt)->Magic_h[3] = EPPING_PING_MAGIC_3;}
80
81#define CMD_FLAGS_DATA_CRC (1 << 0) /* DataCRC field is valid */
82#define CMD_FLAGS_DELAY_ECHO (1 << 1) /* delay the echo of the packet */
83#define CMD_FLAGS_NO_DROP (1 << 2) /* do not drop at HTC layer no matter what the stream is */
84
85#define IS_EPING_PACKET_NO_DROP(pPkt) ((pPkt)->CmdFlags_h & CMD_FLAGS_NO_DROP)
86
87#define EPPING_CMD_ECHO_PACKET 1 /* echo packet test */
88#define EPPING_CMD_RESET_RECV_CNT 2 /* reset recv count */
89#define EPPING_CMD_CAPTURE_RECV_CNT 3 /* fetch recv count, 4-byte count returned in CmdBuffer_t */
90#define EPPING_CMD_NO_ECHO 4 /* non-echo packet test (tx-only) */
91#define EPPING_CMD_CONT_RX_START 5 /* continuous RX packets, parameters are in CmdBuffer_h */
92#define EPPING_CMD_CONT_RX_STOP 6 /* stop continuous RX packet transmission */
93
94 /* test command parameters may be no more than 8 bytes */
95typedef PREPACK struct {
96 u16 BurstCnt; /* number of packets to burst together (for HTC 2.1 testing) */
97 u16 PacketLength; /* length of packet to generate including header */
98 u16 Flags; /* flags */
99
100#define EPPING_CONT_RX_DATA_CRC (1 << 0) /* Add CRC to all data */
101#define EPPING_CONT_RX_RANDOM_DATA (1 << 1) /* randomize the data pattern */
102#define EPPING_CONT_RX_RANDOM_LEN (1 << 2) /* randomize the packet lengths */
103} POSTPACK EPPING_CONT_RX_PARAMS;
104
105#define EPPING_HDR_CRC_OFFSET A_OFFSETOF(EPPING_HEADER,StreamNo_h)
106#define EPPING_HDR_BYTES_CRC (sizeof(EPPING_HEADER) - EPPING_HDR_CRC_OFFSET - (sizeof(u16)))
107
108#define HCI_TRANSPORT_STREAM_NUM 16 /* this number is higher than the define WMM AC classes so we
109 can use this to distinguish packets */
110
111#endif /*EPPING_TEST_H_*/
diff --git a/drivers/staging/ath6kl/include/common/gmboxif.h b/drivers/staging/ath6kl/include/common/gmboxif.h
new file mode 100644
index 00000000000..ea11c14def4
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/gmboxif.h
@@ -0,0 +1,70 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22
23#ifndef __GMBOXIF_H__
24#define __GMBOXIF_H__
25
26/* GMBOX interface definitions */
27
28#define AR6K_GMBOX_CREDIT_COUNTER 1 /* we use credit counter 1 to track credits */
29#define AR6K_GMBOX_CREDIT_SIZE_COUNTER 2 /* credit counter 2 is used to pass the size of each credit */
30
31
32 /* HCI UART transport definitions when used over GMBOX interface */
33#define HCI_UART_COMMAND_PKT 0x01
34#define HCI_UART_ACL_PKT 0x02
35#define HCI_UART_SCO_PKT 0x03
36#define HCI_UART_EVENT_PKT 0x04
37
38 /* definitions for BT HCI packets */
39typedef PREPACK struct {
40 u16 Flags_ConnHandle;
41 u16 Length;
42} POSTPACK BT_HCI_ACL_HEADER;
43
44typedef PREPACK struct {
45 u16 Flags_ConnHandle;
46 u8 Length;
47} POSTPACK BT_HCI_SCO_HEADER;
48
49typedef PREPACK struct {
50 u16 OpCode;
51 u8 ParamLength;
52} POSTPACK BT_HCI_COMMAND_HEADER;
53
54typedef PREPACK struct {
55 u8 EventCode;
56 u8 ParamLength;
57} POSTPACK BT_HCI_EVENT_HEADER;
58
59/* MBOX host interrupt signal assignments */
60
61#define MBOX_SIG_HCI_BRIDGE_MAX 8
62#define MBOX_SIG_HCI_BRIDGE_BT_ON 0
63#define MBOX_SIG_HCI_BRIDGE_BT_OFF 1
64#define MBOX_SIG_HCI_BRIDGE_BAUD_SET 2
65#define MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON 3
66#define MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF 4
67
68
69#endif /* __GMBOXIF_H__ */
70
diff --git a/drivers/staging/ath6kl/include/common/gpio_reg.h b/drivers/staging/ath6kl/include/common/gpio_reg.h
new file mode 100644
index 00000000000..f9d425d48dc
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/gpio_reg.h
@@ -0,0 +1,9 @@
1#ifndef _GPIO_REG_REG_H_
2#define _GPIO_REG_REG_H_
3
4#define GPIO_PIN10_ADDRESS 0x00000050
5#define GPIO_PIN11_ADDRESS 0x00000054
6#define GPIO_PIN12_ADDRESS 0x00000058
7#define GPIO_PIN13_ADDRESS 0x0000005c
8
9#endif /* _GPIO_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/htc.h b/drivers/staging/ath6kl/include/common/htc.h
new file mode 100644
index 00000000000..85cbfa89d67
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/htc.h
@@ -0,0 +1,227 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef __HTC_H__
25#define __HTC_H__
26
27#define A_OFFSETOF(type,field) (unsigned long)(&(((type *)NULL)->field))
28
29#define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \
30 (((u16)(((u8 *)(p))[(highbyte)])) << 8 | (u16)(((u8 *)(p))[(lowbyte)]))
31
32/* alignment independent macros (little-endian) to fetch UINT16s or UINT8s from a
33 * structure using only the type and field name.
34 * Use these macros if there is the potential for unaligned buffer accesses. */
35#define A_GET_UINT16_FIELD(p,type,field) \
36 ASSEMBLE_UNALIGNED_UINT16(p,\
37 A_OFFSETOF(type,field) + 1, \
38 A_OFFSETOF(type,field))
39
40#define A_SET_UINT16_FIELD(p,type,field,value) \
41{ \
42 ((u8 *)(p))[A_OFFSETOF(type,field)] = (u8)(value); \
43 ((u8 *)(p))[A_OFFSETOF(type,field) + 1] = (u8)((value) >> 8); \
44}
45
46#define A_GET_UINT8_FIELD(p,type,field) \
47 ((u8 *)(p))[A_OFFSETOF(type,field)]
48
49#define A_SET_UINT8_FIELD(p,type,field,value) \
50 ((u8 *)(p))[A_OFFSETOF(type,field)] = (value)
51
52/****** DANGER DANGER ***************
53 *
54 * The frame header length and message formats defined herein were
55 * selected to accommodate optimal alignment for target processing. This reduces code
56 * size and improves performance.
57 *
58 * Any changes to the header length may alter the alignment and cause exceptions
59 * on the target. When adding to the message structures insure that fields are
60 * properly aligned.
61 *
62 */
63
64/* HTC frame header */
65PREPACK struct htc_frame_hdr {
66 /* do not remove or re-arrange these fields, these are minimally required
67 * to take advantage of 4-byte lookaheads in some hardware implementations */
68 u8 EndpointID;
69 u8 Flags;
70 u16 PayloadLen; /* length of data (including trailer) that follows the header */
71
72 /***** end of 4-byte lookahead ****/
73
74 u8 ControlBytes[2];
75
76 /* message payload starts after the header */
77
78} POSTPACK;
79
80/* frame header flags */
81
82 /* send direction */
83#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
84#define HTC_FLAGS_SEND_BUNDLE (1 << 1) /* start or part of bundle */
85 /* receive direction */
86#define HTC_FLAGS_RECV_UNUSED_0 (1 << 0) /* bit 0 unused */
87#define HTC_FLAGS_RECV_TRAILER (1 << 1) /* bit 1 trailer data present */
88#define HTC_FLAGS_RECV_UNUSED_2 (1 << 0) /* bit 2 unused */
89#define HTC_FLAGS_RECV_UNUSED_3 (1 << 0) /* bit 3 unused */
90#define HTC_FLAGS_RECV_BUNDLE_CNT_MASK (0xF0) /* bits 7..4 */
91#define HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT 4
92
93#define HTC_HDR_LENGTH (sizeof(struct htc_frame_hdr))
94#define HTC_MAX_TRAILER_LENGTH 255
95#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(struct htc_frame_hdr))
96
97/* HTC control message IDs */
98
99#define HTC_MSG_READY_ID 1
100#define HTC_MSG_CONNECT_SERVICE_ID 2
101#define HTC_MSG_CONNECT_SERVICE_RESPONSE_ID 3
102#define HTC_MSG_SETUP_COMPLETE_ID 4
103#define HTC_MSG_SETUP_COMPLETE_EX_ID 5
104
105#define HTC_MAX_CONTROL_MESSAGE_LENGTH 256
106
107/* base message ID header */
108typedef PREPACK struct {
109 u16 MessageID;
110} POSTPACK HTC_UNKNOWN_MSG;
111
112/* HTC ready message
113 * direction : target-to-host */
114typedef PREPACK struct {
115 u16 MessageID; /* ID */
116 u16 CreditCount; /* number of credits the target can offer */
117 u16 CreditSize; /* size of each credit */
118 u8 MaxEndpoints; /* maximum number of endpoints the target has resources for */
119 u8 _Pad1;
120} POSTPACK HTC_READY_MSG;
121
122 /* extended HTC ready message */
123typedef PREPACK struct {
124 HTC_READY_MSG Version2_0_Info; /* legacy version 2.0 information at the front... */
125 /* extended information */
126 u8 HTCVersion;
127 u8 MaxMsgsPerHTCBundle;
128} POSTPACK HTC_READY_EX_MSG;
129
130#define HTC_VERSION_2P0 0x00
131#define HTC_VERSION_2P1 0x01 /* HTC 2.1 */
132
133#define HTC_SERVICE_META_DATA_MAX_LENGTH 128
134
135/* connect service
136 * direction : host-to-target */
137typedef PREPACK struct {
138 u16 MessageID;
139 u16 ServiceID; /* service ID of the service to connect to */
140 u16 ConnectionFlags; /* connection flags */
141
142#define HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE (1 << 2) /* reduce credit dribbling when
143 the host needs credits */
144#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK (0x3)
145#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH 0x0
146#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF 0x1
147#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS 0x2
148#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_UNITY 0x3
149
150 u8 ServiceMetaLength; /* length of meta data that follows */
151 u8 _Pad1;
152
153 /* service-specific meta data starts after the header */
154
155} POSTPACK HTC_CONNECT_SERVICE_MSG;
156
157/* connect response
158 * direction : target-to-host */
159typedef PREPACK struct {
160 u16 MessageID;
161 u16 ServiceID; /* service ID that the connection request was made */
162 u8 Status; /* service connection status */
163 u8 EndpointID; /* assigned endpoint ID */
164 u16 MaxMsgSize; /* maximum expected message size on this endpoint */
165 u8 ServiceMetaLength; /* length of meta data that follows */
166 u8 _Pad1;
167
168 /* service-specific meta data starts after the header */
169
170} POSTPACK HTC_CONNECT_SERVICE_RESPONSE_MSG;
171
172typedef PREPACK struct {
173 u16 MessageID;
174 /* currently, no other fields */
175} POSTPACK HTC_SETUP_COMPLETE_MSG;
176
177 /* extended setup completion message */
178typedef PREPACK struct {
179 u16 MessageID;
180 u32 SetupFlags;
181 u8 MaxMsgsPerBundledRecv;
182 u8 Rsvd[3];
183} POSTPACK HTC_SETUP_COMPLETE_EX_MSG;
184
185#define HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV (1 << 0)
186
187/* connect response status codes */
188#define HTC_SERVICE_SUCCESS 0 /* success */
189#define HTC_SERVICE_NOT_FOUND 1 /* service could not be found */
190#define HTC_SERVICE_FAILED 2 /* specific service failed the connect */
191#define HTC_SERVICE_NO_RESOURCES 3 /* no resources (i.e. no more endpoints) */
192#define HTC_SERVICE_NO_MORE_EP 4 /* specific service is not allowing any more
193 endpoints */
194
195/* report record IDs */
196
197#define HTC_RECORD_NULL 0
198#define HTC_RECORD_CREDITS 1
199#define HTC_RECORD_LOOKAHEAD 2
200#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
201
202typedef PREPACK struct {
203 u8 RecordID; /* Record ID */
204 u8 Length; /* Length of record */
205} POSTPACK HTC_RECORD_HDR;
206
207typedef PREPACK struct {
208 u8 EndpointID; /* Endpoint that owns these credits */
209 u8 Credits; /* credits to report since last report */
210} POSTPACK HTC_CREDIT_REPORT;
211
212typedef PREPACK struct {
213 u8 PreValid; /* pre valid guard */
214 u8 LookAhead[4]; /* 4 byte lookahead */
215 u8 PostValid; /* post valid guard */
216
217 /* NOTE: the LookAhead array is guarded by a PreValid and Post Valid guard bytes.
218 * The PreValid bytes must equal the inverse of the PostValid byte */
219
220} POSTPACK HTC_LOOKAHEAD_REPORT;
221
222typedef PREPACK struct {
223 u8 LookAhead[4]; /* 4 byte lookahead */
224} POSTPACK HTC_BUNDLED_LOOKAHEAD_REPORT;
225
226#endif /* __HTC_H__ */
227
diff --git a/drivers/staging/ath6kl/include/common/htc_services.h b/drivers/staging/ath6kl/include/common/htc_services.h
new file mode 100644
index 00000000000..fb22268a8d8
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/htc_services.h
@@ -0,0 +1,52 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_services.h" company="Atheros">
3// Copyright (c) 2007 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef __HTC_SERVICES_H__
25#define __HTC_SERVICES_H__
26
27/* Current service IDs */
28
29typedef enum {
30 RSVD_SERVICE_GROUP = 0,
31 WMI_SERVICE_GROUP = 1,
32
33 HTC_TEST_GROUP = 254,
34 HTC_SERVICE_GROUP_LAST = 255
35}HTC_SERVICE_GROUP_IDS;
36
37#define MAKE_SERVICE_ID(group,index) \
38 (int)(((int)group << 8) | (int)(index))
39
40/* NOTE: service ID of 0x0000 is reserved and should never be used */
41#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP,1)
42#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,0)
43#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,1)
44#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,2)
45#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,3)
46#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,4)
47#define WMI_MAX_SERVICES 5
48
49/* raw stream service (i.e. flash, tcmd, calibration apps) */
50#define HTC_RAW_STREAMS_SVC MAKE_SERVICE_ID(HTC_TEST_GROUP,0)
51
52#endif /*HTC_SERVICES_H_*/
diff --git a/drivers/staging/ath6kl/include/common/pkt_log.h b/drivers/staging/ath6kl/include/common/pkt_log.h
new file mode 100644
index 00000000000..a3719adf54c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/pkt_log.h
@@ -0,0 +1,45 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2005-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22
23#ifndef __PKT_LOG_H__
24#define __PKT_LOG_H__
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30
31/* Pkt log info */
32typedef PREPACK struct pkt_log_t {
33 struct info_t {
34 u16 st;
35 u16 end;
36 u16 cur;
37 }info[4096];
38 u16 last_idx;
39}POSTPACK PACKET_LOG;
40
41
42#ifdef __cplusplus
43}
44#endif
45#endif /* __PKT_LOG_H__ */
diff --git a/drivers/staging/ath6kl/include/common/roaming.h b/drivers/staging/ath6kl/include/common/roaming.h
new file mode 100644
index 00000000000..8019850a057
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/roaming.h
@@ -0,0 +1,41 @@
1//------------------------------------------------------------------------------
2// <copyright file="roaming.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef _ROAMING_H_
25#define _ROAMING_H_
26
27/*
28 * The signal quality could be in terms of either snr or rssi. We should
29 * have an enum for both of them. For the time being, we are going to move
30 * it to wmi.h that is shared by both host and the target, since we are
31 * repartitioning the code to the host
32 */
33#define SIGNAL_QUALITY_NOISE_FLOOR -96
34#define SIGNAL_QUALITY_METRICS_NUM_MAX 2
35typedef enum {
36 SIGNAL_QUALITY_METRICS_SNR = 0,
37 SIGNAL_QUALITY_METRICS_RSSI,
38 SIGNAL_QUALITY_METRICS_ALL,
39} SIGNAL_QUALITY_METRICS_TYPE;
40
41#endif /* _ROAMING_H_ */
diff --git a/drivers/staging/ath6kl/include/common/targaddrs.h b/drivers/staging/ath6kl/include/common/targaddrs.h
new file mode 100644
index 00000000000..c866cefbd8f
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/targaddrs.h
@@ -0,0 +1,395 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//
19// Author(s): ="Atheros"
20//------------------------------------------------------------------------------
21
22#ifndef __TARGADDRS_H__
23#define __TARGADDRS_H__
24
25#if defined(AR6002)
26#include "AR6002/addrs.h"
27#endif
28
29/*
30 * AR6K option bits, to enable/disable various features.
31 * By default, all option bits are 0.
32 * These bits can be set in LOCAL_SCRATCH register 0.
33 */
34#define AR6K_OPTION_BMI_DISABLE 0x01 /* Disable BMI comm with Host */
35#define AR6K_OPTION_SERIAL_ENABLE 0x02 /* Enable serial port msgs */
36#define AR6K_OPTION_WDT_DISABLE 0x04 /* WatchDog Timer override */
37#define AR6K_OPTION_SLEEP_DISABLE 0x08 /* Disable system sleep */
38#define AR6K_OPTION_STOP_BOOT 0x10 /* Stop boot processes (for ATE) */
39#define AR6K_OPTION_ENABLE_NOANI 0x20 /* Operate without ANI */
40#define AR6K_OPTION_DSET_DISABLE 0x40 /* Ignore DataSets */
41#define AR6K_OPTION_IGNORE_FLASH 0x80 /* Ignore flash during bootup */
42
43/*
44 * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the
45 * host_interest structure. It must match the address of the _host_interest
46 * symbol (see linker script).
47 *
48 * Host Interest is shared between Host and Target in order to coordinate
49 * between the two, and is intended to remain constant (with additions only
50 * at the end) across software releases.
51 *
52 * All addresses are available here so that it's possible to
53 * write a single binary that works with all Target Types.
54 * May be used in assembler code as well as C.
55 */
56#define AR6002_HOST_INTEREST_ADDRESS 0x00500400
57#define AR6003_HOST_INTEREST_ADDRESS 0x00540600
58
59
60#define HOST_INTEREST_MAX_SIZE 0x100
61
62#if !defined(__ASSEMBLER__)
63struct register_dump_s;
64struct dbglog_hdr_s;
65
66/*
67 * These are items that the Host may need to access
68 * via BMI or via the Diagnostic Window. The position
69 * of items in this structure must remain constant
70 * across firmware revisions!
71 *
72 * Types for each item must be fixed size across
73 * target and host platforms.
74 *
75 * More items may be added at the end.
76 */
77PREPACK struct host_interest_s {
78 /*
79 * Pointer to application-defined area, if any.
80 * Set by Target application during startup.
81 */
82 u32 hi_app_host_interest; /* 0x00 */
83
84 /* Pointer to register dump area, valid after Target crash. */
85 u32 hi_failure_state; /* 0x04 */
86
87 /* Pointer to debug logging header */
88 u32 hi_dbglog_hdr; /* 0x08 */
89
90 u32 hi_unused1; /* 0x0c */
91
92 /*
93 * General-purpose flag bits, similar to AR6000_OPTION_* flags.
94 * Can be used by application rather than by OS.
95 */
96 u32 hi_option_flag; /* 0x10 */
97
98 /*
99 * Boolean that determines whether or not to
100 * display messages on the serial port.
101 */
102 u32 hi_serial_enable; /* 0x14 */
103
104 /* Start address of DataSet index, if any */
105 u32 hi_dset_list_head; /* 0x18 */
106
107 /* Override Target application start address */
108 u32 hi_app_start; /* 0x1c */
109
110 /* Clock and voltage tuning */
111 u32 hi_skip_clock_init; /* 0x20 */
112 u32 hi_core_clock_setting; /* 0x24 */
113 u32 hi_cpu_clock_setting; /* 0x28 */
114 u32 hi_system_sleep_setting; /* 0x2c */
115 u32 hi_xtal_control_setting; /* 0x30 */
116 u32 hi_pll_ctrl_setting_24ghz; /* 0x34 */
117 u32 hi_pll_ctrl_setting_5ghz; /* 0x38 */
118 u32 hi_ref_voltage_trim_setting; /* 0x3c */
119 u32 hi_clock_info; /* 0x40 */
120
121 /*
122 * Flash configuration overrides, used only
123 * when firmware is not executing from flash.
124 * (When using flash, modify the global variables
125 * with equivalent names.)
126 */
127 u32 hi_bank0_addr_value; /* 0x44 */
128 u32 hi_bank0_read_value; /* 0x48 */
129 u32 hi_bank0_write_value; /* 0x4c */
130 u32 hi_bank0_config_value; /* 0x50 */
131
132 /* Pointer to Board Data */
133 u32 hi_board_data; /* 0x54 */
134 u32 hi_board_data_initialized; /* 0x58 */
135
136 u32 hi_dset_RAM_index_table; /* 0x5c */
137
138 u32 hi_desired_baud_rate; /* 0x60 */
139 u32 hi_dbglog_config; /* 0x64 */
140 u32 hi_end_RAM_reserve_sz; /* 0x68 */
141 u32 hi_mbox_io_block_sz; /* 0x6c */
142
143 u32 hi_num_bpatch_streams; /* 0x70 -- unused */
144 u32 hi_mbox_isr_yield_limit; /* 0x74 */
145
146 u32 hi_refclk_hz; /* 0x78 */
147 u32 hi_ext_clk_detected; /* 0x7c */
148 u32 hi_dbg_uart_txpin; /* 0x80 */
149 u32 hi_dbg_uart_rxpin; /* 0x84 */
150 u32 hi_hci_uart_baud; /* 0x88 */
151 u32 hi_hci_uart_pin_assignments; /* 0x8C */
152 /* NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts pin */
153 u32 hi_hci_uart_baud_scale_val; /* 0x90 */
154 u32 hi_hci_uart_baud_step_val; /* 0x94 */
155
156 u32 hi_allocram_start; /* 0x98 */
157 u32 hi_allocram_sz; /* 0x9c */
158 u32 hi_hci_bridge_flags; /* 0xa0 */
159 u32 hi_hci_uart_support_pins; /* 0xa4 */
160 /* NOTE: byte [0] = RESET pin (bit 7 is polarity), bytes[1]..bytes[3] are for future use */
161 u32 hi_hci_uart_pwr_mgmt_params; /* 0xa8 */
162 /*
163 * 0xa8 - [1]: 0 = UART FC active low, 1 = UART FC active high
164 * [31:16]: wakeup timeout in ms
165 */
166
167 /* Pointer to extended board data */
168 u32 hi_board_ext_data; /* 0xac */
169 u32 hi_board_ext_data_config; /* 0xb0 */
170
171 /*
172 * Bit [0] : valid
173 * Bit[31:16: size
174 */
175 /*
176 * hi_reset_flag is used to do some stuff when target reset.
177 * such as restore app_start after warm reset or
178 * preserve host Interest area, or preserve ROM data, literals etc.
179 */
180 u32 hi_reset_flag; /* 0xb4 */
181 /* indicate hi_reset_flag is valid */
182 u32 hi_reset_flag_valid; /* 0xb8 */
183 u32 hi_hci_uart_pwr_mgmt_params_ext; /* 0xbc */
184 /*
185 * 0xbc - [31:0]: idle timeout in ms
186 */
187 /* ACS flags */
188 u32 hi_acs_flags; /* 0xc0 */
189 u32 hi_console_flags; /* 0xc4 */
190 u32 hi_nvram_state; /* 0xc8 */
191 u32 hi_option_flag2; /* 0xcc */
192
193 /* If non-zero, override values sent to Host in WMI_READY event. */
194 u32 hi_sw_version_override; /* 0xd0 */
195 u32 hi_abi_version_override; /* 0xd4 */
196
197 /*
198 * Percentage of high priority RX traffic to total expected RX traffic -
199 * applicable only to ar6004
200 */
201 u32 hi_hp_rx_traffic_ratio; /* 0xd8 */
202
203 /* test applications flags */
204 u32 hi_test_apps_related ; /* 0xdc */
205 /* location of test script */
206 u32 hi_ota_testscript; /* 0xe0 */
207 /* location of CAL data */
208 u32 hi_cal_data; /* 0xe4 */
209 /* Number of packet log buffers */
210 u32 hi_pktlog_num_buffers; /* 0xe8 */
211
212} POSTPACK;
213
214/* Bits defined in hi_option_flag */
215#define HI_OPTION_TIMER_WAR 0x01 /* Enable timer workaround */
216#define HI_OPTION_BMI_CRED_LIMIT 0x02 /* Limit BMI command credits */
217#define HI_OPTION_RELAY_DOT11_HDR 0x04 /* Relay Dot11 hdr to/from host */
218/* MAC addr method 0-locally administred 1-globally unique addrs */
219#define HI_OPTION_MAC_ADDR_METHOD 0x08
220#define HI_OPTION_FW_BRIDGE 0x10 /* Firmware Bridging */
221#define HI_OPTION_ENABLE_PROFILE 0x20 /* Enable CPU profiling */
222#define HI_OPTION_DISABLE_DBGLOG 0x40 /* Disable debug logging */
223#define HI_OPTION_SKIP_ERA_TRACKING 0x80 /* Skip Era Tracking */
224#define HI_OPTION_PAPRD_DISABLE 0x100 /* Disable PAPRD (debug) */
225#define HI_OPTION_NUM_DEV_LSB 0x200
226#define HI_OPTION_NUM_DEV_MSB 0x800
227#define HI_OPTION_DEV_MODE_LSB 0x1000
228#define HI_OPTION_DEV_MODE_MSB 0x8000000
229/* Disable LowFreq Timer Stabilization */
230#define HI_OPTION_NO_LFT_STBL 0x10000000
231#define HI_OPTION_SKIP_REG_SCAN 0x20000000 /* Skip regulatory scan */
232/* Do regulatory scan during init beforesending WMI ready event to host */
233#define HI_OPTION_INIT_REG_SCAN 0x40000000
234#define HI_OPTION_SKIP_MEMMAP 0x80000000 /* REV6: Do not adjust memory
235 map */
236
237/* hi_option_flag2 options */
238#define HI_OPTION_OFFLOAD_AMSDU 0x01
239#define HI_OPTION_DFS_SUPPORT 0x02 /* Enable DFS support */
240
241#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3
242
243/* 2 bits of hi_option_flag are used to represent 3 modes */
244#define HI_OPTION_FW_MODE_IBSS 0x0 /* IBSS Mode */
245#define HI_OPTION_FW_MODE_BSS_STA 0x1 /* STA Mode */
246#define HI_OPTION_FW_MODE_AP 0x2 /* AP Mode */
247
248/* 2 bits of hi_option flag are usedto represent 4 submodes */
249#define HI_OPTION_FW_SUBMODE_NONE 0x0 /* Normal mode */
250#define HI_OPTION_FW_SUBMODE_P2PDEV 0x1 /* p2p device mode */
251#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2 /* p2p client mode */
252#define HI_OPTION_FW_SUBMODE_P2PGO 0x3 /* p2p go mode */
253
254/* Num dev Mask */
255#define HI_OPTION_NUM_DEV_MASK 0x7
256#define HI_OPTION_NUM_DEV_SHIFT 0x9
257
258/* firmware bridging */
259#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
260
261/* Fw Mode/SubMode Mask
262|------------------------------------------------------------------------------|
263| SUB | SUB | SUB | SUB | | | |
264| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0|
265| (2) | (2) | (2) | (2) | (2) | (2) | (2) | (2)
266|------------------------------------------------------------------------------|
267*/
268#define HI_OPTION_FW_MODE_BITS 0x2
269#define HI_OPTION_FW_MODE_MASK 0x3
270#define HI_OPTION_FW_MODE_SHIFT 0xC
271#define HI_OPTION_ALL_FW_MODE_MASK 0xFF
272
273#define HI_OPTION_FW_SUBMODE_BITS 0x2
274#define HI_OPTION_FW_SUBMODE_MASK 0x3
275#define HI_OPTION_FW_SUBMODE_SHIFT 0x14
276#define HI_OPTION_ALL_FW_SUBMODE_MASK 0xFF00
277#define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8
278
279/* hi_reset_flag */
280
281/* preserve App Start address */
282#define HI_RESET_FLAG_PRESERVE_APP_START 0x01
283/* preserve host interest */
284#define HI_RESET_FLAG_PRESERVE_HOST_INTEREST 0x02
285#define HI_RESET_FLAG_PRESERVE_ROMDATA 0x04 /* preserve ROM data */
286#define HI_RESET_FLAG_PRESERVE_NVRAM_STATE 0x08
287#define HI_RESET_FLAG_PRESERVE_BOOT_INFO 0x10
288
289#define HI_RESET_FLAG_IS_VALID 0x12345678 /* indicate the reset flag is
290valid */
291
292#define ON_RESET_FLAGS_VALID() \
293 (HOST_INTEREST->hi_reset_flag_valid == HI_RESET_FLAG_IS_VALID)
294
295#define RESET_FLAGS_VALIDATE() \
296 (HOST_INTEREST->hi_reset_flag_valid = HI_RESET_FLAG_IS_VALID)
297
298#define RESET_FLAGS_INVALIDATE() \
299 (HOST_INTEREST->hi_reset_flag_valid = 0)
300
301#define ON_RESET_PRESERVE_APP_START() \
302 (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_APP_START)
303
304#define ON_RESET_PRESERVE_NVRAM_STATE() \
305 (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_NVRAM_STATE)
306
307#define ON_RESET_PRESERVE_HOST_INTEREST() \
308 (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_HOST_INTEREST)
309
310#define ON_RESET_PRESERVE_ROMDATA() \
311 (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_ROMDATA)
312
313#define ON_RESET_PRESERVE_BOOT_INFO() \
314 (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_BOOT_INFO)
315
316#define HI_ACS_FLAGS_ENABLED (1 << 0) /* ACS is enabled */
317#define HI_ACS_FLAGS_USE_WWAN (1 << 1) /* Use physical WWAN device */
318#define HI_ACS_FLAGS_TEST_VAP (1 << 2) /* Use test VAP */
319
320/* CONSOLE FLAGS
321 *
322 * Bit Range Meaning
323 * --------- --------------------------------
324 * 2..0 UART ID (0 = Default)
325 * 3 Baud Select (0 = 9600, 1 = 115200)
326 * 30..4 Reserved
327 * 31 Enable Console
328 *
329 */
330
331#define HI_CONSOLE_FLAGS_ENABLE (1 << 31)
332#define HI_CONSOLE_FLAGS_UART_MASK (0x7)
333#define HI_CONSOLE_FLAGS_UART_SHIFT 0
334#define HI_CONSOLE_FLAGS_BAUD_SELECT (1 << 3)
335
336/*
337 * Intended for use by Host software, this macro returns the Target RAM
338 * address of any item in the host_interest structure.
339 * Example: target_addr = AR6002_HOST_INTEREST_ITEM_ADDRESS(hi_board_data);
340 */
341#define AR6002_HOST_INTEREST_ITEM_ADDRESS(item) \
342 (u32)((unsigned long)&((((struct host_interest_s *)(AR6002_HOST_INTEREST_ADDRESS))->item)))
343
344#define AR6003_HOST_INTEREST_ITEM_ADDRESS(item) \
345 (u32)((unsigned long)&((((struct host_interest_s *)(AR6003_HOST_INTEREST_ADDRESS))->item)))
346
347#define AR6004_HOST_INTEREST_ITEM_ADDRESS(item) \
348 ((u32)&((((struct host_interest_s *)(AR6004_HOST_INTEREST_ADDRESS))->item)))
349
350
351#define HOST_INTEREST_DBGLOG_IS_ENABLED() \
352 (!(HOST_INTEREST->hi_option_flag & HI_OPTION_DISABLE_DBGLOG))
353
354#define HOST_INTEREST_PKTLOG_IS_ENABLED() \
355 ((HOST_INTEREST->hi_pktlog_num_buffers))
356
357
358#define HOST_INTEREST_PROFILE_IS_ENABLED() \
359 (HOST_INTEREST->hi_option_flag & HI_OPTION_ENABLE_PROFILE)
360
361#define LF_TIMER_STABILIZATION_IS_ENABLED() \
362 (!(HOST_INTEREST->hi_option_flag & HI_OPTION_NO_LFT_STBL))
363
364#define IS_AMSDU_OFFLAOD_ENABLED() \
365 ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_OFFLOAD_AMSDU))
366
367#define HOST_INTEREST_DFS_IS_ENABLED() \
368 ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_DFS_SUPPORT))
369
370/* Convert a Target virtual address into a Target physical address */
371#define AR6002_VTOP(vaddr) ((vaddr) & 0x001fffff)
372#define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff)
373#define TARG_VTOP(TargetType, vaddr) \
374 (((TargetType) == TARGET_TYPE_AR6002) ? AR6002_VTOP(vaddr) : AR6003_VTOP(vaddr))
375
376#define AR6003_REV2_APP_START_OVERRIDE 0x944C00
377#define AR6003_REV2_APP_LOAD_ADDRESS 0x543180
378#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500
379#define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884
380#define AR6003_REV2_RAM_RESERVE_SIZE 6912
381
382#define AR6003_REV3_APP_START_OVERRIDE 0x945d00
383#define AR6003_REV3_APP_LOAD_ADDRESS 0x545000
384#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330
385#define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74
386#define AR6003_REV3_RAM_RESERVE_SIZE 512
387
388#define AR6003_BOARD_EXT_DATA_ADDRESS 0x57E600
389
390/* # of u32 entries in targregs, used by DIAG_FETCH_TARG_REGS */
391#define AR6003_FETCH_TARG_REGS_COUNT 64
392
393#endif /* !__ASSEMBLER__ */
394
395#endif /* __TARGADDRS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/testcmd.h b/drivers/staging/ath6kl/include/common/testcmd.h
new file mode 100644
index 00000000000..7d94aee508b
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/testcmd.h
@@ -0,0 +1,185 @@
1//------------------------------------------------------------------------------
2// <copyright file="testcmd.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#ifndef TESTCMD_H_
25#define TESTCMD_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#ifdef AR6002_REV2
32#define TCMD_MAX_RATES 12
33#else
34#define TCMD_MAX_RATES 28
35#endif
36
37typedef enum {
38 ZEROES_PATTERN = 0,
39 ONES_PATTERN,
40 REPEATING_10,
41 PN7_PATTERN,
42 PN9_PATTERN,
43 PN15_PATTERN
44}TX_DATA_PATTERN;
45
46/* Continuous tx
47 mode : TCMD_CONT_TX_OFF - Disabling continuous tx
48 TCMD_CONT_TX_SINE - Enable continuous unmodulated tx
49 TCMD_CONT_TX_FRAME- Enable continuous modulated tx
50 freq : Channel freq in Mhz. (e.g 2412 for channel 1 in 11 g)
51dataRate: 0 - 1 Mbps
52 1 - 2 Mbps
53 2 - 5.5 Mbps
54 3 - 11 Mbps
55 4 - 6 Mbps
56 5 - 9 Mbps
57 6 - 12 Mbps
58 7 - 18 Mbps
59 8 - 24 Mbps
60 9 - 36 Mbps
61 10 - 28 Mbps
62 11 - 54 Mbps
63 txPwr: Tx power in dBm[5 -11] for unmod Tx, [5-14] for mod Tx
64antenna: 1 - one antenna
65 2 - two antenna
66Note : Enable/disable continuous tx test cmd works only when target is awake.
67*/
68
69typedef enum {
70 TCMD_CONT_TX_OFF = 0,
71 TCMD_CONT_TX_SINE,
72 TCMD_CONT_TX_FRAME,
73 TCMD_CONT_TX_TX99,
74 TCMD_CONT_TX_TX100
75} TCMD_CONT_TX_MODE;
76
77typedef enum {
78 TCMD_WLAN_MODE_NOHT = 0,
79 TCMD_WLAN_MODE_HT20 = 1,
80 TCMD_WLAN_MODE_HT40PLUS = 2,
81 TCMD_WLAN_MODE_HT40MINUS = 3,
82} TCMD_WLAN_MODE;
83
84typedef PREPACK struct {
85 u32 testCmdId;
86 u32 mode;
87 u32 freq;
88 u32 dataRate;
89 s32 txPwr;
90 u32 antenna;
91 u32 enANI;
92 u32 scramblerOff;
93 u32 aifsn;
94 u16 pktSz;
95 u16 txPattern;
96 u32 shortGuard;
97 u32 numPackets;
98 u32 wlanMode;
99} POSTPACK TCMD_CONT_TX;
100
101#define TCMD_TXPATTERN_ZERONE 0x1
102#define TCMD_TXPATTERN_ZERONE_DIS_SCRAMBLE 0x2
103
104/* Continuous Rx
105 act: TCMD_CONT_RX_PROMIS - promiscuous mode (accept all incoming frames)
106 TCMD_CONT_RX_FILTER - filter mode (accept only frames with dest
107 address equal specified
108 mac address (set via act =3)
109 TCMD_CONT_RX_REPORT off mode (disable cont rx mode and get the
110 report from the last cont
111 Rx test)
112
113 TCMD_CONT_RX_SETMAC - set MacAddr mode (sets the MAC address for the
114 target. This Overrides
115 the default MAC address.)
116
117*/
118typedef enum {
119 TCMD_CONT_RX_PROMIS =0,
120 TCMD_CONT_RX_FILTER,
121 TCMD_CONT_RX_REPORT,
122 TCMD_CONT_RX_SETMAC,
123 TCMD_CONT_RX_SET_ANT_SWITCH_TABLE
124} TCMD_CONT_RX_ACT;
125
126typedef PREPACK struct {
127 u32 testCmdId;
128 u32 act;
129 u32 enANI;
130 PREPACK union {
131 struct PREPACK TCMD_CONT_RX_PARA {
132 u32 freq;
133 u32 antenna;
134 u32 wlanMode;
135 } POSTPACK para;
136 struct PREPACK TCMD_CONT_RX_REPORT {
137 u32 totalPkt;
138 s32 rssiInDBm;
139 u32 crcErrPkt;
140 u32 secErrPkt;
141 u16 rateCnt[TCMD_MAX_RATES];
142 u16 rateCntShortGuard[TCMD_MAX_RATES];
143 } POSTPACK report;
144 struct PREPACK TCMD_CONT_RX_MAC {
145 u8 addr[ATH_MAC_LEN];
146 } POSTPACK mac;
147 struct PREPACK TCMD_CONT_RX_ANT_SWITCH_TABLE {
148 u32 antswitch1;
149 u32 antswitch2;
150 }POSTPACK antswitchtable;
151 } POSTPACK u;
152} POSTPACK TCMD_CONT_RX;
153
154/* Force sleep/wake test cmd
155 mode: TCMD_PM_WAKEUP - Wakeup the target
156 TCMD_PM_SLEEP - Force the target to sleep.
157 */
158typedef enum {
159 TCMD_PM_WAKEUP = 1, /* be consistent with target */
160 TCMD_PM_SLEEP,
161 TCMD_PM_DEEPSLEEP
162} TCMD_PM_MODE;
163
164typedef PREPACK struct {
165 u32 testCmdId;
166 u32 mode;
167} POSTPACK TCMD_PM;
168
169typedef enum {
170 TCMD_CONT_TX_ID,
171 TCMD_CONT_RX_ID,
172 TCMD_PM_ID
173} TCMD_ID;
174
175typedef PREPACK union {
176 TCMD_CONT_TX contTx;
177 TCMD_CONT_RX contRx;
178 TCMD_PM pm;
179} POSTPACK TEST_CMD;
180
181#ifdef __cplusplus
182}
183#endif
184
185#endif /* TESTCMD_H_ */
diff --git a/drivers/staging/ath6kl/include/common/tlpm.h b/drivers/staging/ath6kl/include/common/tlpm.h
new file mode 100644
index 00000000000..659b1c07ba9
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/tlpm.h
@@ -0,0 +1,38 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22
23#ifndef __TLPM_H__
24#define __TLPM_H__
25
26/* idle timeout in 16-bit value as in HOST_INTEREST hi_hci_uart_pwr_mgmt_params */
27#define TLPM_DEFAULT_IDLE_TIMEOUT_MS 1000
28/* hex in LSB and MSB for HCI command */
29#define TLPM_DEFAULT_IDLE_TIMEOUT_LSB 0xE8
30#define TLPM_DEFAULT_IDLE_TIMEOUT_MSB 0x3
31
32/* wakeup timeout in 8-bit value as in HOST_INTEREST hi_hci_uart_pwr_mgmt_params */
33#define TLPM_DEFAULT_WAKEUP_TIMEOUT_MS 10
34
35/* default UART FC polarity is low */
36#define TLPM_DEFAULT_UART_FC_POLARITY 0
37
38#endif
diff --git a/drivers/staging/ath6kl/include/common/wlan_defs.h b/drivers/staging/ath6kl/include/common/wlan_defs.h
new file mode 100644
index 00000000000..03e4d23788c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/wlan_defs.h
@@ -0,0 +1,79 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_defs.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef __WLAN_DEFS_H__
24#define __WLAN_DEFS_H__
25
26/*
27 * This file contains WLAN definitions that may be used across both
28 * Host and Target software.
29 */
30
31typedef enum {
32 MODE_11A = 0, /* 11a Mode */
33 MODE_11G = 1, /* 11b/g Mode */
34 MODE_11B = 2, /* 11b Mode */
35 MODE_11GONLY = 3, /* 11g only Mode */
36#ifdef SUPPORT_11N
37 MODE_11NA_HT20 = 4, /* 11a HT20 mode */
38 MODE_11NG_HT20 = 5, /* 11g HT20 mode */
39 MODE_11NA_HT40 = 6, /* 11a HT40 mode */
40 MODE_11NG_HT40 = 7, /* 11g HT40 mode */
41 MODE_UNKNOWN = 8,
42 MODE_MAX = 8
43#else
44 MODE_UNKNOWN = 4,
45 MODE_MAX = 4
46#endif
47} WLAN_PHY_MODE;
48
49typedef enum {
50 WLAN_11A_CAPABILITY = 1,
51 WLAN_11G_CAPABILITY = 2,
52 WLAN_11AG_CAPABILITY = 3,
53}WLAN_CAPABILITY;
54
55#ifdef SUPPORT_11N
56typedef unsigned long A_RATEMASK;
57#else
58typedef unsigned short A_RATEMASK;
59#endif
60
61#ifdef SUPPORT_11N
62#define IS_MODE_11A(mode) (((mode) == MODE_11A) || \
63 ((mode) == MODE_11NA_HT20) || \
64 ((mode) == MODE_11NA_HT40))
65#define IS_MODE_11B(mode) ((mode) == MODE_11B)
66#define IS_MODE_11G(mode) (((mode) == MODE_11G) || \
67 ((mode) == MODE_11GONLY) || \
68 ((mode) == MODE_11NG_HT20) || \
69 ((mode) == MODE_11NG_HT40))
70#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY)
71#else
72#define IS_MODE_11A(mode) ((mode) == MODE_11A)
73#define IS_MODE_11B(mode) ((mode) == MODE_11B)
74#define IS_MODE_11G(mode) (((mode) == MODE_11G) || \
75 ((mode) == MODE_11GONLY))
76#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY)
77#endif /* SUPPORT_11N */
78
79#endif /* __WLANDEFS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h
new file mode 100644
index 00000000000..d9687443d32
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/wmi.h
@@ -0,0 +1,3220 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//
19// Author(s): ="Atheros"
20//------------------------------------------------------------------------------
21
22/*
23 * This file contains the definitions of the WMI protocol specified in the
24 * Wireless Module Interface (WMI). It includes definitions of all the
25 * commands and events. Commands are messages from the host to the WM.
26 * Events and Replies are messages from the WM to the host.
27 *
28 * Ownership of correctness in regards to commands
29 * belongs to the host driver and the WMI is not required to validate
30 * parameters for value, proper range, or any other checking.
31 *
32 */
33
34#ifndef _WMI_H_
35#define _WMI_H_
36
37#include "wmix.h"
38#include "wlan_defs.h"
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#define HTC_PROTOCOL_VERSION 0x0002
45#define HTC_PROTOCOL_REVISION 0x0000
46
47#define WMI_PROTOCOL_VERSION 0x0002
48#define WMI_PROTOCOL_REVISION 0x0000
49
50#define ATH_MAC_LEN 6 /* length of mac in bytes */
51#define WMI_CMD_MAX_LEN 100
52#define WMI_CONTROL_MSG_MAX_LEN 256
53#define WMI_OPT_CONTROL_MSG_MAX_LEN 1536
54#define IS_ETHERTYPE(_typeOrLen) ((_typeOrLen) >= 0x0600)
55#define RFC1042OUI {0x00, 0x00, 0x00}
56
57#define IP_ETHERTYPE 0x0800
58
59#define WMI_IMPLICIT_PSTREAM 0xFF
60#define WMI_MAX_THINSTREAM 15
61
62#ifdef AR6002_REV2
63#define IBSS_MAX_NUM_STA 4
64#else
65#define IBSS_MAX_NUM_STA 8
66#endif
67
68PREPACK struct host_app_area_s {
69 u32 wmi_protocol_ver;
70} POSTPACK;
71
72/*
73 * Data Path
74 */
75typedef PREPACK struct {
76 u8 dstMac[ATH_MAC_LEN];
77 u8 srcMac[ATH_MAC_LEN];
78 u16 typeOrLen;
79} POSTPACK ATH_MAC_HDR;
80
81typedef PREPACK struct {
82 u8 dsap;
83 u8 ssap;
84 u8 cntl;
85 u8 orgCode[3];
86 u16 etherType;
87} POSTPACK ATH_LLC_SNAP_HDR;
88
89typedef enum {
90 DATA_MSGTYPE = 0x0,
91 CNTL_MSGTYPE,
92 SYNC_MSGTYPE,
93 OPT_MSGTYPE,
94} WMI_MSG_TYPE;
95
96
97/*
98 * Macros for operating on WMI_DATA_HDR (info) field
99 */
100
101#define WMI_DATA_HDR_MSG_TYPE_MASK 0x03
102#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0
103#define WMI_DATA_HDR_UP_MASK 0x07
104#define WMI_DATA_HDR_UP_SHIFT 2
105/* In AP mode, the same bit (b5) is used to indicate Power save state in
106 * the Rx dir and More data bit state in the tx direction.
107 */
108#define WMI_DATA_HDR_PS_MASK 0x1
109#define WMI_DATA_HDR_PS_SHIFT 5
110
111#define WMI_DATA_HDR_MORE_MASK 0x1
112#define WMI_DATA_HDR_MORE_SHIFT 5
113
114typedef enum {
115 WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
116 WMI_DATA_HDR_DATA_TYPE_802_11,
117 WMI_DATA_HDR_DATA_TYPE_ACL, /* used to be used for the PAL */
118} WMI_DATA_HDR_DATA_TYPE;
119
120#define WMI_DATA_HDR_DATA_TYPE_MASK 0x3
121#define WMI_DATA_HDR_DATA_TYPE_SHIFT 6
122
123#define WMI_DATA_HDR_SET_MORE_BIT(h) ((h)->info |= (WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT))
124
125#define WMI_DATA_HDR_IS_MSG_TYPE(h, t) (((h)->info & (WMI_DATA_HDR_MSG_TYPE_MASK)) == (t))
126#define WMI_DATA_HDR_SET_MSG_TYPE(h, t) (h)->info = (((h)->info & ~(WMI_DATA_HDR_MSG_TYPE_MASK << WMI_DATA_HDR_MSG_TYPE_SHIFT)) | (t << WMI_DATA_HDR_MSG_TYPE_SHIFT))
127#define WMI_DATA_HDR_GET_UP(h) (((h)->info >> WMI_DATA_HDR_UP_SHIFT) & WMI_DATA_HDR_UP_MASK)
128#define WMI_DATA_HDR_SET_UP(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT)) | (p << WMI_DATA_HDR_UP_SHIFT))
129
130#define WMI_DATA_HDR_GET_DATA_TYPE(h) (((h)->info >> WMI_DATA_HDR_DATA_TYPE_SHIFT) & WMI_DATA_HDR_DATA_TYPE_MASK)
131#define WMI_DATA_HDR_SET_DATA_TYPE(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_DATA_TYPE_MASK << WMI_DATA_HDR_DATA_TYPE_SHIFT)) | ((p) << WMI_DATA_HDR_DATA_TYPE_SHIFT))
132
133#define WMI_DATA_HDR_GET_DOT11(h) (WMI_DATA_HDR_GET_DATA_TYPE((h)) == WMI_DATA_HDR_DATA_TYPE_802_11)
134#define WMI_DATA_HDR_SET_DOT11(h, p) WMI_DATA_HDR_SET_DATA_TYPE((h), (p))
135
136/* Macros for operating on WMI_DATA_HDR (info2) field */
137#define WMI_DATA_HDR_SEQNO_MASK 0xFFF
138#define WMI_DATA_HDR_SEQNO_SHIFT 0
139
140#define WMI_DATA_HDR_AMSDU_MASK 0x1
141#define WMI_DATA_HDR_AMSDU_SHIFT 12
142
143#define WMI_DATA_HDR_META_MASK 0x7
144#define WMI_DATA_HDR_META_SHIFT 13
145
146#define GET_SEQ_NO(_v) ((_v) & WMI_DATA_HDR_SEQNO_MASK)
147#define GET_ISMSDU(_v) ((_v) & WMI_DATA_HDR_AMSDU_MASK)
148
149#define WMI_DATA_HDR_GET_SEQNO(h) GET_SEQ_NO((h)->info2 >> WMI_DATA_HDR_SEQNO_SHIFT)
150#define WMI_DATA_HDR_SET_SEQNO(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_SEQNO_MASK << WMI_DATA_HDR_SEQNO_SHIFT)) | (GET_SEQ_NO(_v) << WMI_DATA_HDR_SEQNO_SHIFT))
151
152#define WMI_DATA_HDR_IS_AMSDU(h) GET_ISMSDU((h)->info2 >> WMI_DATA_HDR_AMSDU_SHIFT)
153#define WMI_DATA_HDR_SET_AMSDU(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_AMSDU_MASK << WMI_DATA_HDR_AMSDU_SHIFT)) | (GET_ISMSDU(_v) << WMI_DATA_HDR_AMSDU_SHIFT))
154
155#define WMI_DATA_HDR_GET_META(h) (((h)->info2 >> WMI_DATA_HDR_META_SHIFT) & WMI_DATA_HDR_META_MASK)
156#define WMI_DATA_HDR_SET_META(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_META_MASK << WMI_DATA_HDR_META_SHIFT)) | ((_v) << WMI_DATA_HDR_META_SHIFT))
157
158/* Macros for operating on WMI_DATA_HDR (info3) field */
159#define WMI_DATA_HDR_DEVID_MASK 0xF
160#define WMI_DATA_HDR_DEVID_SHIFT 0
161#define GET_DEVID(_v) ((_v) & WMI_DATA_HDR_DEVID_MASK)
162
163#define WMI_DATA_HDR_GET_DEVID(h) \
164 (((h)->info3 >> WMI_DATA_HDR_DEVID_SHIFT) & WMI_DATA_HDR_DEVID_MASK)
165#define WMI_DATA_HDR_SET_DEVID(h, _v) \
166 ((h)->info3 = ((h)->info3 & ~(WMI_DATA_HDR_DEVID_MASK << WMI_DATA_HDR_DEVID_SHIFT)) | (GET_DEVID(_v) << WMI_DATA_HDR_DEVID_SHIFT))
167
168typedef PREPACK struct {
169 s8 rssi;
170 u8 info; /* usage of 'info' field(8-bit):
171 * b1:b0 - WMI_MSG_TYPE
172 * b4:b3:b2 - UP(tid)
173 * b5 - Used in AP mode. More-data in tx dir, PS in rx.
174 * b7:b6 - Dot3 header(0),
175 * Dot11 Header(1),
176 * ACL data(2)
177 */
178
179 u16 info2; /* usage of 'info2' field(16-bit):
180 * b11:b0 - seq_no
181 * b12 - A-MSDU?
182 * b15:b13 - META_DATA_VERSION 0 - 7
183 */
184 u16 info3;
185} POSTPACK WMI_DATA_HDR;
186
187/*
188 * TX META VERSION DEFINITIONS
189 */
190#define WMI_MAX_TX_META_SZ (12)
191#define WMI_MAX_TX_META_VERSION (7)
192#define WMI_META_VERSION_1 (0x01)
193#define WMI_META_VERSION_2 (0X02)
194
195#define WMI_ACL_TO_DOT11_HEADROOM 36
196
197#if 0 /* removed to prevent compile errors for WM.. */
198typedef PREPACK struct {
199/* intentionally empty. Default version is no meta data. */
200} POSTPACK WMI_TX_META_V0;
201#endif
202
203typedef PREPACK struct {
204 u8 pktID; /* The packet ID to identify the tx request */
205 u8 ratePolicyID; /* The rate policy to be used for the tx of this frame */
206} POSTPACK WMI_TX_META_V1;
207
208
209#define WMI_CSUM_DIR_TX (0x1)
210#define TX_CSUM_CALC_FILL (0x1)
211typedef PREPACK struct {
212 u8 csumStart; /*Offset from start of the WMI header for csum calculation to begin */
213 u8 csumDest; /*Offset from start of WMI header where final csum goes*/
214 u8 csumFlags; /*number of bytes over which csum is calculated*/
215} POSTPACK WMI_TX_META_V2;
216
217
218/*
219 * RX META VERSION DEFINITIONS
220 */
221/* if RX meta data is present at all then the meta data field
222 * will consume WMI_MAX_RX_META_SZ bytes of space between the
223 * WMI_DATA_HDR and the payload. How much of the available
224 * Meta data is actually used depends on which meta data
225 * version is active. */
226#define WMI_MAX_RX_META_SZ (12)
227#define WMI_MAX_RX_META_VERSION (7)
228
229#define WMI_RX_STATUS_OK 0 /* success */
230#define WMI_RX_STATUS_DECRYPT_ERR 1 /* decrypt error */
231#define WMI_RX_STATUS_MIC_ERR 2 /* tkip MIC error */
232#define WMI_RX_STATUS_ERR 3 /* undefined error */
233
234#define WMI_RX_FLAGS_AGGR 0x0001 /* part of AGGR */
235#define WMI_RX_FlAGS_STBC 0x0002 /* used STBC */
236#define WMI_RX_FLAGS_SGI 0x0004 /* used SGI */
237#define WMI_RX_FLAGS_HT 0x0008 /* is HT packet */
238/* the flags field is also used to store the CRYPTO_TYPE of the frame
239 * that value is shifted by WMI_RX_FLAGS_CRYPTO_SHIFT */
240#define WMI_RX_FLAGS_CRYPTO_SHIFT 4
241#define WMI_RX_FLAGS_CRYPTO_MASK 0x1f
242#define WMI_RX_META_GET_CRYPTO(flags) (((flags) >> WMI_RX_FLAGS_CRYPTO_SHIFT) & WMI_RX_FLAGS_CRYPTO_MASK)
243
244#if 0 /* removed to prevent compile errors for WM.. */
245typedef PREPACK struct {
246/* intentionally empty. Default version is no meta data. */
247} POSTPACK WMI_RX_META_VERSION_0;
248#endif
249
250typedef PREPACK struct {
251 u8 status; /* one of WMI_RX_STATUS_... */
252 u8 rix; /* rate index mapped to rate at which this packet was received. */
253 u8 rssi; /* rssi of packet */
254 u8 channel;/* rf channel during packet reception */
255 u16 flags; /* a combination of WMI_RX_FLAGS_... */
256} POSTPACK WMI_RX_META_V1;
257
258#define RX_CSUM_VALID_FLAG (0x1)
259typedef PREPACK struct {
260 u16 csum;
261 u8 csumFlags;/* bit 0 set -partial csum valid
262 bit 1 set -test mode */
263} POSTPACK WMI_RX_META_V2;
264
265
266
267#define WMI_GET_DEVICE_ID(info1) ((info1) & 0xF)
268/* Macros for operating on WMI_CMD_HDR (info1) field */
269#define WMI_CMD_HDR_DEVID_MASK 0xF
270#define WMI_CMD_HDR_DEVID_SHIFT 0
271#define GET_CMD_DEVID(_v) ((_v) & WMI_CMD_HDR_DEVID_MASK)
272
273#define WMI_CMD_HDR_GET_DEVID(h) \
274 (((h)->info1 >> WMI_CMD_HDR_DEVID_SHIFT) & WMI_CMD_HDR_DEVID_MASK)
275#define WMI_CMD_HDR_SET_DEVID(h, _v) \
276 ((h)->info1 = ((h)->info1 & \
277 ~(WMI_CMD_HDR_DEVID_MASK << WMI_CMD_HDR_DEVID_SHIFT)) | \
278 (GET_CMD_DEVID(_v) << WMI_CMD_HDR_DEVID_SHIFT))
279
280/*
281 * Control Path
282 */
283typedef PREPACK struct {
284 u16 commandId;
285/*
286 * info1 - 16 bits
287 * b03:b00 - id
288 * b15:b04 - unused
289 */
290 u16 info1;
291
292 u16 reserved; /* For alignment */
293} POSTPACK WMI_CMD_HDR; /* used for commands and events */
294
295/*
296 * List of Commnands
297 */
298typedef enum {
299 WMI_CONNECT_CMDID = 0x0001,
300 WMI_RECONNECT_CMDID,
301 WMI_DISCONNECT_CMDID,
302 WMI_SYNCHRONIZE_CMDID,
303 WMI_CREATE_PSTREAM_CMDID,
304 WMI_DELETE_PSTREAM_CMDID,
305 WMI_START_SCAN_CMDID,
306 WMI_SET_SCAN_PARAMS_CMDID,
307 WMI_SET_BSS_FILTER_CMDID,
308 WMI_SET_PROBED_SSID_CMDID, /* 10 */
309 WMI_SET_LISTEN_INT_CMDID,
310 WMI_SET_BMISS_TIME_CMDID,
311 WMI_SET_DISC_TIMEOUT_CMDID,
312 WMI_GET_CHANNEL_LIST_CMDID,
313 WMI_SET_BEACON_INT_CMDID,
314 WMI_GET_STATISTICS_CMDID,
315 WMI_SET_CHANNEL_PARAMS_CMDID,
316 WMI_SET_POWER_MODE_CMDID,
317 WMI_SET_IBSS_PM_CAPS_CMDID,
318 WMI_SET_POWER_PARAMS_CMDID, /* 20 */
319 WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
320 WMI_ADD_CIPHER_KEY_CMDID,
321 WMI_DELETE_CIPHER_KEY_CMDID,
322 WMI_ADD_KRK_CMDID,
323 WMI_DELETE_KRK_CMDID,
324 WMI_SET_PMKID_CMDID,
325 WMI_SET_TX_PWR_CMDID,
326 WMI_GET_TX_PWR_CMDID,
327 WMI_SET_ASSOC_INFO_CMDID,
328 WMI_ADD_BAD_AP_CMDID, /* 30 */
329 WMI_DELETE_BAD_AP_CMDID,
330 WMI_SET_TKIP_COUNTERMEASURES_CMDID,
331 WMI_RSSI_THRESHOLD_PARAMS_CMDID,
332 WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
333 WMI_SET_ACCESS_PARAMS_CMDID,
334 WMI_SET_RETRY_LIMITS_CMDID,
335 WMI_SET_OPT_MODE_CMDID,
336 WMI_OPT_TX_FRAME_CMDID,
337 WMI_SET_VOICE_PKT_SIZE_CMDID,
338 WMI_SET_MAX_SP_LEN_CMDID, /* 40 */
339 WMI_SET_ROAM_CTRL_CMDID,
340 WMI_GET_ROAM_TBL_CMDID,
341 WMI_GET_ROAM_DATA_CMDID,
342 WMI_ENABLE_RM_CMDID,
343 WMI_SET_MAX_OFFHOME_DURATION_CMDID,
344 WMI_EXTENSION_CMDID, /* Non-wireless extensions */
345 WMI_SNR_THRESHOLD_PARAMS_CMDID,
346 WMI_LQ_THRESHOLD_PARAMS_CMDID,
347 WMI_SET_LPREAMBLE_CMDID,
348 WMI_SET_RTS_CMDID, /* 50 */
349 WMI_CLR_RSSI_SNR_CMDID,
350 WMI_SET_FIXRATES_CMDID,
351 WMI_GET_FIXRATES_CMDID,
352 WMI_SET_AUTH_MODE_CMDID,
353 WMI_SET_REASSOC_MODE_CMDID,
354 WMI_SET_WMM_CMDID,
355 WMI_SET_WMM_TXOP_CMDID,
356 WMI_TEST_CMDID,
357 /* COEX AR6002 only*/
358 WMI_SET_BT_STATUS_CMDID,
359 WMI_SET_BT_PARAMS_CMDID, /* 60 */
360
361 WMI_SET_KEEPALIVE_CMDID,
362 WMI_GET_KEEPALIVE_CMDID,
363 WMI_SET_APPIE_CMDID,
364 WMI_GET_APPIE_CMDID,
365 WMI_SET_WSC_STATUS_CMDID,
366
367 /* Wake on Wireless */
368 WMI_SET_HOST_SLEEP_MODE_CMDID,
369 WMI_SET_WOW_MODE_CMDID,
370 WMI_GET_WOW_LIST_CMDID,
371 WMI_ADD_WOW_PATTERN_CMDID,
372 WMI_DEL_WOW_PATTERN_CMDID, /* 70 */
373
374 WMI_SET_FRAMERATES_CMDID,
375 WMI_SET_AP_PS_CMDID,
376 WMI_SET_QOS_SUPP_CMDID,
377 /* WMI_THIN_RESERVED_... mark the start and end
378 * values for WMI_THIN_RESERVED command IDs. These
379 * command IDs can be found in wmi_thin.h */
380 WMI_THIN_RESERVED_START = 0x8000,
381 WMI_THIN_RESERVED_END = 0x8fff,
382 /*
383 * Developer commands starts at 0xF000
384 */
385 WMI_SET_BITRATE_CMDID = 0xF000,
386 WMI_GET_BITRATE_CMDID,
387 WMI_SET_WHALPARAM_CMDID,
388
389
390 /*Should add the new command to the tail for compatible with
391 * etna.
392 */
393 WMI_SET_MAC_ADDRESS_CMDID,
394 WMI_SET_AKMP_PARAMS_CMDID,
395 WMI_SET_PMKID_LIST_CMDID,
396 WMI_GET_PMKID_LIST_CMDID,
397 WMI_ABORT_SCAN_CMDID,
398 WMI_SET_TARGET_EVENT_REPORT_CMDID,
399
400 // Unused
401 WMI_UNUSED1,
402 WMI_UNUSED2,
403
404 /*
405 * AP mode commands
406 */
407 WMI_AP_HIDDEN_SSID_CMDID,
408 WMI_AP_SET_NUM_STA_CMDID,
409 WMI_AP_ACL_POLICY_CMDID,
410 WMI_AP_ACL_MAC_LIST_CMDID,
411 WMI_AP_CONFIG_COMMIT_CMDID,
412 WMI_AP_SET_MLME_CMDID,
413 WMI_AP_SET_PVB_CMDID,
414 WMI_AP_CONN_INACT_CMDID,
415 WMI_AP_PROT_SCAN_TIME_CMDID,
416 WMI_AP_SET_COUNTRY_CMDID,
417 WMI_AP_SET_DTIM_CMDID,
418 WMI_AP_MODE_STAT_CMDID,
419
420 WMI_SET_IP_CMDID,
421 WMI_SET_PARAMS_CMDID,
422 WMI_SET_MCAST_FILTER_CMDID,
423 WMI_DEL_MCAST_FILTER_CMDID,
424
425 WMI_ALLOW_AGGR_CMDID,
426 WMI_ADDBA_REQ_CMDID,
427 WMI_DELBA_REQ_CMDID,
428 WMI_SET_HT_CAP_CMDID,
429 WMI_SET_HT_OP_CMDID,
430 WMI_SET_TX_SELECT_RATES_CMDID,
431 WMI_SET_TX_SGI_PARAM_CMDID,
432 WMI_SET_RATE_POLICY_CMDID,
433
434 WMI_HCI_CMD_CMDID,
435 WMI_RX_FRAME_FORMAT_CMDID,
436 WMI_SET_THIN_MODE_CMDID,
437 WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
438
439 WMI_AP_SET_11BG_RATESET_CMDID,
440 WMI_SET_PMK_CMDID,
441 WMI_MCAST_FILTER_CMDID,
442 /* COEX CMDID AR6003*/
443 WMI_SET_BTCOEX_FE_ANT_CMDID,
444 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
445 WMI_SET_BTCOEX_SCO_CONFIG_CMDID,
446 WMI_SET_BTCOEX_A2DP_CONFIG_CMDID,
447 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID,
448 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
449 WMI_SET_BTCOEX_DEBUG_CMDID,
450 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
451 WMI_GET_BTCOEX_STATS_CMDID,
452 WMI_GET_BTCOEX_CONFIG_CMDID,
453
454 WMI_SET_DFS_ENABLE_CMDID, /* F034 */
455 WMI_SET_DFS_MINRSSITHRESH_CMDID,
456 WMI_SET_DFS_MAXPULSEDUR_CMDID,
457 WMI_DFS_RADAR_DETECTED_CMDID,
458
459 /* P2P CMDS */
460 WMI_P2P_SET_CONFIG_CMDID, /* F038 */
461 WMI_WPS_SET_CONFIG_CMDID,
462 WMI_SET_REQ_DEV_ATTR_CMDID,
463 WMI_P2P_FIND_CMDID,
464 WMI_P2P_STOP_FIND_CMDID,
465 WMI_P2P_GO_NEG_START_CMDID,
466 WMI_P2P_LISTEN_CMDID,
467
468 WMI_CONFIG_TX_MAC_RULES_CMDID, /* F040 */
469 WMI_SET_PROMISCUOUS_MODE_CMDID,
470 WMI_RX_FRAME_FILTER_CMDID,
471 WMI_SET_CHANNEL_CMDID,
472
473 /* WAC commands */
474 WMI_ENABLE_WAC_CMDID,
475 WMI_WAC_SCAN_REPLY_CMDID,
476 WMI_WAC_CTRL_REQ_CMDID,
477 WMI_SET_DIV_PARAMS_CMDID,
478
479 WMI_GET_PMK_CMDID,
480 WMI_SET_PASSPHRASE_CMDID,
481 WMI_SEND_ASSOC_RES_CMDID,
482 WMI_SET_ASSOC_REQ_RELAY_CMDID,
483 WMI_GET_RFKILL_MODE_CMDID,
484
485 /* ACS command, consists of sub-commands */
486 WMI_ACS_CTRL_CMDID,
487
488 /* Ultra low power store / recall commands */
489 WMI_STORERECALL_CONFIGURE_CMDID,
490 WMI_STORERECALL_RECALL_CMDID,
491 WMI_STORERECALL_HOST_READY_CMDID,
492 WMI_FORCE_TARGET_ASSERT_CMDID,
493 WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
494} WMI_COMMAND_ID;
495
496/*
497 * Frame Types
498 */
499typedef enum {
500 WMI_FRAME_BEACON = 0,
501 WMI_FRAME_PROBE_REQ,
502 WMI_FRAME_PROBE_RESP,
503 WMI_FRAME_ASSOC_REQ,
504 WMI_FRAME_ASSOC_RESP,
505 WMI_NUM_MGMT_FRAME
506} WMI_MGMT_FRAME_TYPE;
507
508/*
509 * Connect Command
510 */
511typedef enum {
512 INFRA_NETWORK = 0x01,
513 ADHOC_NETWORK = 0x02,
514 ADHOC_CREATOR = 0x04,
515 AP_NETWORK = 0x10,
516} NETWORK_TYPE;
517
518typedef enum {
519 OPEN_AUTH = 0x01,
520 SHARED_AUTH = 0x02,
521 LEAP_AUTH = 0x04, /* different from IEEE_AUTH_MODE definitions */
522} DOT11_AUTH_MODE;
523
524enum {
525 AUTH_IDLE,
526 AUTH_OPEN_IN_PROGRESS,
527};
528
529typedef enum {
530 NONE_AUTH = 0x01,
531 WPA_AUTH = 0x02,
532 WPA2_AUTH = 0x04,
533 WPA_PSK_AUTH = 0x08,
534 WPA2_PSK_AUTH = 0x10,
535 WPA_AUTH_CCKM = 0x20,
536 WPA2_AUTH_CCKM = 0x40,
537} AUTH_MODE;
538
539typedef enum {
540 NONE_CRYPT = 0x01,
541 WEP_CRYPT = 0x02,
542 TKIP_CRYPT = 0x04,
543 AES_CRYPT = 0x08,
544#ifdef WAPI_ENABLE
545 WAPI_CRYPT = 0x10,
546#endif /*WAPI_ENABLE*/
547} CRYPTO_TYPE;
548
549#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT
550#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1)
551
552#ifdef WAPI_ENABLE
553#undef WMI_MAX_CRYPTO_TYPE
554#define WMI_MAX_CRYPTO_TYPE (WAPI_CRYPT + 1)
555#endif /* WAPI_ENABLE */
556
557#ifdef WAPI_ENABLE
558#define IW_ENCODE_ALG_SM4 0x20
559#define IW_AUTH_WAPI_ENABLED 0x20
560#endif
561
562#define WMI_MIN_KEY_INDEX 0
563#define WMI_MAX_KEY_INDEX 3
564
565#ifdef WAPI_ENABLE
566#undef WMI_MAX_KEY_INDEX
567#define WMI_MAX_KEY_INDEX 7 /* wapi grpKey 0-3, prwKey 4-7 */
568#endif /* WAPI_ENABLE */
569
570#define WMI_MAX_KEY_LEN 32
571
572#define WMI_MAX_SSID_LEN 32
573
574typedef enum {
575 CONNECT_ASSOC_POLICY_USER = 0x0001,
576 CONNECT_SEND_REASSOC = 0x0002,
577 CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
578 CONNECT_PROFILE_MATCH_DONE = 0x0008,
579 CONNECT_IGNORE_AAC_BEACON = 0x0010,
580 CONNECT_CSA_FOLLOW_BSS = 0x0020,
581 CONNECT_DO_WPA_OFFLOAD = 0x0040,
582 CONNECT_DO_NOT_DEAUTH = 0x0080,
583} WMI_CONNECT_CTRL_FLAGS_BITS;
584
585#define DEFAULT_CONNECT_CTRL_FLAGS (CONNECT_CSA_FOLLOW_BSS)
586
587typedef PREPACK struct {
588 u8 networkType;
589 u8 dot11AuthMode;
590 u8 authMode;
591 u8 pairwiseCryptoType;
592 u8 pairwiseCryptoLen;
593 u8 groupCryptoType;
594 u8 groupCryptoLen;
595 u8 ssidLength;
596 u8 ssid[WMI_MAX_SSID_LEN];
597 u16 channel;
598 u8 bssid[ATH_MAC_LEN];
599 u32 ctrl_flags;
600} POSTPACK WMI_CONNECT_CMD;
601
602/*
603 * WMI_RECONNECT_CMDID
604 */
605typedef PREPACK struct {
606 u16 channel; /* hint */
607 u8 bssid[ATH_MAC_LEN]; /* mandatory if set */
608} POSTPACK WMI_RECONNECT_CMD;
609
610#define WMI_PMK_LEN 32
611typedef PREPACK struct {
612 u8 pmk[WMI_PMK_LEN];
613} POSTPACK WMI_SET_PMK_CMD;
614
615/*
616 * WMI_SET_EXCESS_TX_RETRY_THRES_CMDID
617 */
618typedef PREPACK struct {
619 u32 threshold;
620} POSTPACK WMI_SET_EXCESS_TX_RETRY_THRES_CMD;
621
622/*
623 * WMI_ADD_CIPHER_KEY_CMDID
624 */
625typedef enum {
626 PAIRWISE_USAGE = 0x00,
627 GROUP_USAGE = 0x01,
628 TX_USAGE = 0x02, /* default Tx Key - Static WEP only */
629} KEY_USAGE;
630
631/*
632 * Bit Flag
633 * Bit 0 - Initialise TSC - default is Initialize
634 */
635#define KEY_OP_INIT_TSC 0x01
636#define KEY_OP_INIT_RSC 0x02
637#ifdef WAPI_ENABLE
638#define KEY_OP_INIT_WAPIPN 0x10
639#endif /* WAPI_ENABLE */
640
641#define KEY_OP_INIT_VAL 0x03 /* Default Initialise the TSC & RSC */
642#define KEY_OP_VALID_MASK 0x03
643
644typedef PREPACK struct {
645 u8 keyIndex;
646 u8 keyType;
647 u8 keyUsage; /* KEY_USAGE */
648 u8 keyLength;
649 u8 keyRSC[8]; /* key replay sequence counter */
650 u8 key[WMI_MAX_KEY_LEN];
651 u8 key_op_ctrl; /* Additional Key Control information */
652 u8 key_macaddr[ATH_MAC_LEN];
653} POSTPACK WMI_ADD_CIPHER_KEY_CMD;
654
655/*
656 * WMI_DELETE_CIPHER_KEY_CMDID
657 */
658typedef PREPACK struct {
659 u8 keyIndex;
660} POSTPACK WMI_DELETE_CIPHER_KEY_CMD;
661
662#define WMI_KRK_LEN 16
663/*
664 * WMI_ADD_KRK_CMDID
665 */
666typedef PREPACK struct {
667 u8 krk[WMI_KRK_LEN];
668} POSTPACK WMI_ADD_KRK_CMD;
669
670/*
671 * WMI_SET_TKIP_COUNTERMEASURES_CMDID
672 */
673typedef enum {
674 WMI_TKIP_CM_DISABLE = 0x0,
675 WMI_TKIP_CM_ENABLE = 0x1,
676} WMI_TKIP_CM_CONTROL;
677
678typedef PREPACK struct {
679 u8 cm_en; /* WMI_TKIP_CM_CONTROL */
680} POSTPACK WMI_SET_TKIP_COUNTERMEASURES_CMD;
681
682/*
683 * WMI_SET_PMKID_CMDID
684 */
685
686#define WMI_PMKID_LEN 16
687
688typedef enum {
689 PMKID_DISABLE = 0,
690 PMKID_ENABLE = 1,
691} PMKID_ENABLE_FLG;
692
693typedef PREPACK struct {
694 u8 bssid[ATH_MAC_LEN];
695 u8 enable; /* PMKID_ENABLE_FLG */
696 u8 pmkid[WMI_PMKID_LEN];
697} POSTPACK WMI_SET_PMKID_CMD;
698
699/*
700 * WMI_START_SCAN_CMD
701 */
702typedef enum {
703 WMI_LONG_SCAN = 0,
704 WMI_SHORT_SCAN = 1,
705} WMI_SCAN_TYPE;
706
707typedef PREPACK struct {
708 u32 forceFgScan;
709 u32 isLegacy; /* For Legacy Cisco AP compatibility */
710 u32 homeDwellTime; /* Maximum duration in the home channel(milliseconds) */
711 u32 forceScanInterval; /* Time interval between scans (milliseconds)*/
712 u8 scanType; /* WMI_SCAN_TYPE */
713 u8 numChannels; /* how many channels follow */
714 u16 channelList[1]; /* channels in Mhz */
715} POSTPACK WMI_START_SCAN_CMD;
716
717/*
718 * WMI_SET_SCAN_PARAMS_CMDID
719 */
720#define WMI_SHORTSCANRATIO_DEFAULT 3
721/*
722 * Warning: ScanCtrlFlag value of 0xFF is used to disable all flags in WMI_SCAN_PARAMS_CMD
723 * Do not add any more flags to WMI_SCAN_CTRL_FLAG_BITS
724 */
725typedef enum {
726 CONNECT_SCAN_CTRL_FLAGS = 0x01, /* set if can scan in the Connect cmd */
727 SCAN_CONNECTED_CTRL_FLAGS = 0x02, /* set if scan for the SSID it is */
728 /* already connected to */
729 ACTIVE_SCAN_CTRL_FLAGS = 0x04, /* set if enable active scan */
730 ROAM_SCAN_CTRL_FLAGS = 0x08, /* set if enable roam scan when bmiss and lowrssi */
731 REPORT_BSSINFO_CTRL_FLAGS = 0x10, /* set if follows customer BSSINFO reporting rule */
732 ENABLE_AUTO_CTRL_FLAGS = 0x20, /* if disabled, target doesn't
733 scan after a disconnect event */
734 ENABLE_SCAN_ABORT_EVENT = 0x40 /* Scan complete event with canceled status will be generated when a scan is prempted before it gets completed */
735} WMI_SCAN_CTRL_FLAGS_BITS;
736
737#define CAN_SCAN_IN_CONNECT(flags) (flags & CONNECT_SCAN_CTRL_FLAGS)
738#define CAN_SCAN_CONNECTED(flags) (flags & SCAN_CONNECTED_CTRL_FLAGS)
739#define ENABLE_ACTIVE_SCAN(flags) (flags & ACTIVE_SCAN_CTRL_FLAGS)
740#define ENABLE_ROAM_SCAN(flags) (flags & ROAM_SCAN_CTRL_FLAGS)
741#define CONFIG_REPORT_BSSINFO(flags) (flags & REPORT_BSSINFO_CTRL_FLAGS)
742#define IS_AUTO_SCAN_ENABLED(flags) (flags & ENABLE_AUTO_CTRL_FLAGS)
743#define SCAN_ABORT_EVENT_ENABLED(flags) (flags & ENABLE_SCAN_ABORT_EVENT)
744
745#define DEFAULT_SCAN_CTRL_FLAGS (CONNECT_SCAN_CTRL_FLAGS| SCAN_CONNECTED_CTRL_FLAGS| ACTIVE_SCAN_CTRL_FLAGS| ROAM_SCAN_CTRL_FLAGS | ENABLE_AUTO_CTRL_FLAGS)
746
747
748typedef PREPACK struct {
749 u16 fg_start_period; /* seconds */
750 u16 fg_end_period; /* seconds */
751 u16 bg_period; /* seconds */
752 u16 maxact_chdwell_time; /* msec */
753 u16 pas_chdwell_time; /* msec */
754 u8 shortScanRatio; /* how many shorts scan for one long */
755 u8 scanCtrlFlags;
756 u16 minact_chdwell_time; /* msec */
757 u16 maxact_scan_per_ssid; /* max active scans per ssid */
758 u32 max_dfsch_act_time; /* msecs */
759} POSTPACK WMI_SCAN_PARAMS_CMD;
760
761/*
762 * WMI_SET_BSS_FILTER_CMDID
763 */
764typedef enum {
765 NONE_BSS_FILTER = 0x0, /* no beacons forwarded */
766 ALL_BSS_FILTER, /* all beacons forwarded */
767 PROFILE_FILTER, /* only beacons matching profile */
768 ALL_BUT_PROFILE_FILTER, /* all but beacons matching profile */
769 CURRENT_BSS_FILTER, /* only beacons matching current BSS */
770 ALL_BUT_BSS_FILTER, /* all but beacons matching BSS */
771 PROBED_SSID_FILTER, /* beacons matching probed ssid */
772 LAST_BSS_FILTER, /* marker only */
773} WMI_BSS_FILTER;
774
775typedef PREPACK struct {
776 u8 bssFilter; /* see WMI_BSS_FILTER */
777 u8 reserved1; /* For alignment */
778 u16 reserved2; /* For alignment */
779 u32 ieMask;
780} POSTPACK WMI_BSS_FILTER_CMD;
781
782/*
783 * WMI_SET_PROBED_SSID_CMDID
784 */
785#define MAX_PROBED_SSID_INDEX 9
786
787typedef enum {
788 DISABLE_SSID_FLAG = 0, /* disables entry */
789 SPECIFIC_SSID_FLAG = 0x01, /* probes specified ssid */
790 ANY_SSID_FLAG = 0x02, /* probes for any ssid */
791} WMI_SSID_FLAG;
792
793typedef PREPACK struct {
794 u8 entryIndex; /* 0 to MAX_PROBED_SSID_INDEX */
795 u8 flag; /* WMI_SSID_FLG */
796 u8 ssidLength;
797 u8 ssid[32];
798} POSTPACK WMI_PROBED_SSID_CMD;
799
800/*
801 * WMI_SET_LISTEN_INT_CMDID
802 * The Listen interval is between 15 and 3000 TUs
803 */
804#define MIN_LISTEN_INTERVAL 15
805#define MAX_LISTEN_INTERVAL 5000
806#define MIN_LISTEN_BEACONS 1
807#define MAX_LISTEN_BEACONS 50
808
809typedef PREPACK struct {
810 u16 listenInterval;
811 u16 numBeacons;
812} POSTPACK WMI_LISTEN_INT_CMD;
813
814/*
815 * WMI_SET_BEACON_INT_CMDID
816 */
817typedef PREPACK struct {
818 u16 beaconInterval;
819} POSTPACK WMI_BEACON_INT_CMD;
820
821/*
822 * WMI_SET_BMISS_TIME_CMDID
823 * valid values are between 1000 and 5000 TUs
824 */
825
826#define MIN_BMISS_TIME 1000
827#define MAX_BMISS_TIME 5000
828#define MIN_BMISS_BEACONS 1
829#define MAX_BMISS_BEACONS 50
830
831typedef PREPACK struct {
832 u16 bmissTime;
833 u16 numBeacons;
834} POSTPACK WMI_BMISS_TIME_CMD;
835
836/*
837 * WMI_SET_POWER_MODE_CMDID
838 */
839typedef enum {
840 REC_POWER = 0x01,
841 MAX_PERF_POWER,
842} WMI_POWER_MODE;
843
844typedef PREPACK struct {
845 u8 powerMode; /* WMI_POWER_MODE */
846} POSTPACK WMI_POWER_MODE_CMD;
847
848typedef PREPACK struct {
849 s8 status; /* WMI_SET_PARAMS_REPLY */
850} POSTPACK WMI_SET_PARAMS_REPLY;
851
852typedef PREPACK struct {
853 u32 opcode;
854 u32 length;
855 char buffer[1]; /* WMI_SET_PARAMS */
856} POSTPACK WMI_SET_PARAMS_CMD;
857
858typedef PREPACK struct {
859 u8 multicast_mac[ATH_MAC_LEN]; /* WMI_SET_MCAST_FILTER */
860} POSTPACK WMI_SET_MCAST_FILTER_CMD;
861
862typedef PREPACK struct {
863 u8 enable; /* WMI_MCAST_FILTER */
864} POSTPACK WMI_MCAST_FILTER_CMD;
865
866/*
867 * WMI_SET_POWER_PARAMS_CMDID
868 */
869typedef enum {
870 IGNORE_DTIM = 0x01,
871 NORMAL_DTIM = 0x02,
872 STICK_DTIM = 0x03,
873 AUTO_DTIM = 0x04,
874} WMI_DTIM_POLICY;
875
876/* Policy to determnine whether TX should wakeup WLAN if sleeping */
877typedef enum {
878 TX_WAKEUP_UPON_SLEEP = 1,
879 TX_DONT_WAKEUP_UPON_SLEEP = 2
880} WMI_TX_WAKEUP_POLICY_UPON_SLEEP;
881
882/*
883 * Policy to determnine whether power save failure event should be sent to
884 * host during scanning
885 */
886typedef enum {
887 SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1,
888 IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2,
889} POWER_SAVE_FAIL_EVENT_POLICY;
890
891typedef PREPACK struct {
892 u16 idle_period; /* msec */
893 u16 pspoll_number;
894 u16 dtim_policy;
895 u16 tx_wakeup_policy;
896 u16 num_tx_to_wakeup;
897 u16 ps_fail_event_policy;
898} POSTPACK WMI_POWER_PARAMS_CMD;
899
900/* Adhoc power save types */
901typedef enum {
902 ADHOC_PS_DISABLE=1,
903 ADHOC_PS_ATH=2,
904 ADHOC_PS_IEEE=3,
905 ADHOC_PS_OTHER=4,
906} WMI_ADHOC_PS_TYPE;
907
908typedef PREPACK struct {
909 u8 power_saving;
910 u8 ttl; /* number of beacon periods */
911 u16 atim_windows; /* msec */
912 u16 timeout_value; /* msec */
913} POSTPACK WMI_IBSS_PM_CAPS_CMD;
914
915/* AP power save types */
916typedef enum {
917 AP_PS_DISABLE=1,
918 AP_PS_ATH=2,
919} WMI_AP_PS_TYPE;
920
921typedef PREPACK struct {
922 u32 idle_time; /* in msec */
923 u32 ps_period; /* in usec */
924 u8 sleep_period; /* in ps periods */
925 u8 psType;
926} POSTPACK WMI_AP_PS_CMD;
927
928/*
929 * WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID
930 */
931typedef enum {
932 IGNORE_TIM_ALL_QUEUES_APSD = 0,
933 PROCESS_TIM_ALL_QUEUES_APSD = 1,
934 IGNORE_TIM_SIMULATED_APSD = 2,
935 PROCESS_TIM_SIMULATED_APSD = 3,
936} APSD_TIM_POLICY;
937
938typedef PREPACK struct {
939 u16 psPollTimeout; /* msec */
940 u16 triggerTimeout; /* msec */
941 u32 apsdTimPolicy; /* TIM behavior with ques APSD enabled. Default is IGNORE_TIM_ALL_QUEUES_APSD */
942 u32 simulatedAPSDTimPolicy; /* TIM behavior with simulated APSD enabled. Default is PROCESS_TIM_SIMULATED_APSD */
943} POSTPACK WMI_POWERSAVE_TIMERS_POLICY_CMD;
944
945/*
946 * WMI_SET_VOICE_PKT_SIZE_CMDID
947 */
948typedef PREPACK struct {
949 u16 voicePktSize;
950} POSTPACK WMI_SET_VOICE_PKT_SIZE_CMD;
951
952/*
953 * WMI_SET_MAX_SP_LEN_CMDID
954 */
955typedef enum {
956 DELIVER_ALL_PKT = 0x0,
957 DELIVER_2_PKT = 0x1,
958 DELIVER_4_PKT = 0x2,
959 DELIVER_6_PKT = 0x3,
960} APSD_SP_LEN_TYPE;
961
962typedef PREPACK struct {
963 u8 maxSPLen;
964} POSTPACK WMI_SET_MAX_SP_LEN_CMD;
965
966/*
967 * WMI_SET_DISC_TIMEOUT_CMDID
968 */
969typedef PREPACK struct {
970 u8 disconnectTimeout; /* seconds */
971} POSTPACK WMI_DISC_TIMEOUT_CMD;
972
973typedef enum {
974 UPLINK_TRAFFIC = 0,
975 DNLINK_TRAFFIC = 1,
976 BIDIR_TRAFFIC = 2,
977} DIR_TYPE;
978
979typedef enum {
980 DISABLE_FOR_THIS_AC = 0,
981 ENABLE_FOR_THIS_AC = 1,
982 ENABLE_FOR_ALL_AC = 2,
983} VOICEPS_CAP_TYPE;
984
985typedef enum {
986 TRAFFIC_TYPE_APERIODIC = 0,
987 TRAFFIC_TYPE_PERIODIC = 1,
988}TRAFFIC_TYPE;
989
990/*
991 * WMI_SYNCHRONIZE_CMDID
992 */
993typedef PREPACK struct {
994 u8 dataSyncMap;
995} POSTPACK WMI_SYNC_CMD;
996
997/*
998 * WMI_CREATE_PSTREAM_CMDID
999 */
1000typedef PREPACK struct {
1001 u32 minServiceInt; /* in milli-sec */
1002 u32 maxServiceInt; /* in milli-sec */
1003 u32 inactivityInt; /* in milli-sec */
1004 u32 suspensionInt; /* in milli-sec */
1005 u32 serviceStartTime;
1006 u32 minDataRate; /* in bps */
1007 u32 meanDataRate; /* in bps */
1008 u32 peakDataRate; /* in bps */
1009 u32 maxBurstSize;
1010 u32 delayBound;
1011 u32 minPhyRate; /* in bps */
1012 u32 sba;
1013 u32 mediumTime;
1014 u16 nominalMSDU; /* in octects */
1015 u16 maxMSDU; /* in octects */
1016 u8 trafficClass;
1017 u8 trafficDirection; /* DIR_TYPE */
1018 u8 rxQueueNum;
1019 u8 trafficType; /* TRAFFIC_TYPE */
1020 u8 voicePSCapability; /* VOICEPS_CAP_TYPE */
1021 u8 tsid;
1022 u8 userPriority; /* 802.1D user priority */
1023 u8 nominalPHY; /* nominal phy rate */
1024} POSTPACK WMI_CREATE_PSTREAM_CMD;
1025
1026/*
1027 * WMI_DELETE_PSTREAM_CMDID
1028 */
1029typedef PREPACK struct {
1030 u8 txQueueNumber;
1031 u8 rxQueueNumber;
1032 u8 trafficDirection;
1033 u8 trafficClass;
1034 u8 tsid;
1035} POSTPACK WMI_DELETE_PSTREAM_CMD;
1036
1037/*
1038 * WMI_SET_CHANNEL_PARAMS_CMDID
1039 */
1040typedef enum {
1041 WMI_11A_MODE = 0x1,
1042 WMI_11G_MODE = 0x2,
1043 WMI_11AG_MODE = 0x3,
1044 WMI_11B_MODE = 0x4,
1045 WMI_11GONLY_MODE = 0x5,
1046} WMI_PHY_MODE;
1047
1048#define WMI_MAX_CHANNELS 32
1049
1050typedef PREPACK struct {
1051 u8 reserved1;
1052 u8 scanParam; /* set if enable scan */
1053 u8 phyMode; /* see WMI_PHY_MODE */
1054 u8 numChannels; /* how many channels follow */
1055 u16 channelList[1]; /* channels in Mhz */
1056} POSTPACK WMI_CHANNEL_PARAMS_CMD;
1057
1058
1059/*
1060 * WMI_RSSI_THRESHOLD_PARAMS_CMDID
1061 * Setting the polltime to 0 would disable polling.
1062 * Threshold values are in the ascending order, and should agree to:
1063 * (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal
1064 * < highThreshold_upperVal)
1065 */
1066
1067typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{
1068 u32 pollTime; /* Polling time as a factor of LI */
1069 s16 thresholdAbove1_Val; /* lowest of upper */
1070 s16 thresholdAbove2_Val;
1071 s16 thresholdAbove3_Val;
1072 s16 thresholdAbove4_Val;
1073 s16 thresholdAbove5_Val;
1074 s16 thresholdAbove6_Val; /* highest of upper */
1075 s16 thresholdBelow1_Val; /* lowest of bellow */
1076 s16 thresholdBelow2_Val;
1077 s16 thresholdBelow3_Val;
1078 s16 thresholdBelow4_Val;
1079 s16 thresholdBelow5_Val;
1080 s16 thresholdBelow6_Val; /* highest of bellow */
1081 u8 weight; /* "alpha" */
1082 u8 reserved[3];
1083} POSTPACK WMI_RSSI_THRESHOLD_PARAMS_CMD;
1084
1085/*
1086 * WMI_SNR_THRESHOLD_PARAMS_CMDID
1087 * Setting the polltime to 0 would disable polling.
1088 */
1089
1090typedef PREPACK struct WMI_SNR_THRESHOLD_PARAMS{
1091 u32 pollTime; /* Polling time as a factor of LI */
1092 u8 weight; /* "alpha" */
1093 u8 thresholdAbove1_Val; /* lowest of uppper*/
1094 u8 thresholdAbove2_Val;
1095 u8 thresholdAbove3_Val;
1096 u8 thresholdAbove4_Val; /* highest of upper */
1097 u8 thresholdBelow1_Val; /* lowest of bellow */
1098 u8 thresholdBelow2_Val;
1099 u8 thresholdBelow3_Val;
1100 u8 thresholdBelow4_Val; /* highest of bellow */
1101 u8 reserved[3];
1102} POSTPACK WMI_SNR_THRESHOLD_PARAMS_CMD;
1103
1104/*
1105 * WMI_LQ_THRESHOLD_PARAMS_CMDID
1106 */
1107typedef PREPACK struct WMI_LQ_THRESHOLD_PARAMS {
1108 u8 enable;
1109 u8 thresholdAbove1_Val;
1110 u8 thresholdAbove2_Val;
1111 u8 thresholdAbove3_Val;
1112 u8 thresholdAbove4_Val;
1113 u8 thresholdBelow1_Val;
1114 u8 thresholdBelow2_Val;
1115 u8 thresholdBelow3_Val;
1116 u8 thresholdBelow4_Val;
1117 u8 reserved[3];
1118} POSTPACK WMI_LQ_THRESHOLD_PARAMS_CMD;
1119
1120typedef enum {
1121 WMI_LPREAMBLE_DISABLED = 0,
1122 WMI_LPREAMBLE_ENABLED
1123} WMI_LPREAMBLE_STATUS;
1124
1125typedef enum {
1126 WMI_IGNORE_BARKER_IN_ERP = 0,
1127 WMI_DONOT_IGNORE_BARKER_IN_ERP
1128} WMI_PREAMBLE_POLICY;
1129
1130typedef PREPACK struct {
1131 u8 status;
1132 u8 preamblePolicy;
1133}POSTPACK WMI_SET_LPREAMBLE_CMD;
1134
1135typedef PREPACK struct {
1136 u16 threshold;
1137}POSTPACK WMI_SET_RTS_CMD;
1138
1139/*
1140 * WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
1141 * Sets the error reporting event bitmask in target. Target clears it
1142 * upon an error. Subsequent errors are counted, but not reported
1143 * via event, unless the bitmask is set again.
1144 */
1145typedef PREPACK struct {
1146 u32 bitmask;
1147} POSTPACK WMI_TARGET_ERROR_REPORT_BITMASK;
1148
1149/*
1150 * WMI_SET_TX_PWR_CMDID
1151 */
1152typedef PREPACK struct {
1153 u8 dbM; /* in dbM units */
1154} POSTPACK WMI_SET_TX_PWR_CMD, WMI_TX_PWR_REPLY;
1155
1156/*
1157 * WMI_SET_ASSOC_INFO_CMDID
1158 *
1159 * A maximum of 2 private IEs can be sent in the [Re]Assoc request.
1160 * A 3rd one, the CCX version IE can also be set from the host.
1161 */
1162#define WMI_MAX_ASSOC_INFO_TYPE 2
1163#define WMI_CCX_VER_IE 2 /* ieType to set CCX Version IE */
1164
1165#define WMI_MAX_ASSOC_INFO_LEN 240
1166
1167typedef PREPACK struct {
1168 u8 ieType;
1169 u8 bufferSize;
1170 u8 assocInfo[1]; /* up to WMI_MAX_ASSOC_INFO_LEN */
1171} POSTPACK WMI_SET_ASSOC_INFO_CMD;
1172
1173
1174/*
1175 * WMI_GET_TX_PWR_CMDID does not take any parameters
1176 */
1177
1178/*
1179 * WMI_ADD_BAD_AP_CMDID
1180 */
1181#define WMI_MAX_BAD_AP_INDEX 1
1182
1183typedef PREPACK struct {
1184 u8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */
1185 u8 bssid[ATH_MAC_LEN];
1186} POSTPACK WMI_ADD_BAD_AP_CMD;
1187
1188/*
1189 * WMI_DELETE_BAD_AP_CMDID
1190 */
1191typedef PREPACK struct {
1192 u8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */
1193} POSTPACK WMI_DELETE_BAD_AP_CMD;
1194
1195/*
1196 * WMI_SET_ACCESS_PARAMS_CMDID
1197 */
1198#define WMI_DEFAULT_TXOP_ACPARAM 0 /* implies one MSDU */
1199#define WMI_DEFAULT_ECWMIN_ACPARAM 4 /* corresponds to CWmin of 15 */
1200#define WMI_DEFAULT_ECWMAX_ACPARAM 10 /* corresponds to CWmax of 1023 */
1201#define WMI_MAX_CW_ACPARAM 15 /* maximum eCWmin or eCWmax */
1202#define WMI_DEFAULT_AIFSN_ACPARAM 2
1203#define WMI_MAX_AIFSN_ACPARAM 15
1204typedef PREPACK struct {
1205 u16 txop; /* in units of 32 usec */
1206 u8 eCWmin;
1207 u8 eCWmax;
1208 u8 aifsn;
1209 u8 ac;
1210} POSTPACK WMI_SET_ACCESS_PARAMS_CMD;
1211
1212
1213/*
1214 * WMI_SET_RETRY_LIMITS_CMDID
1215 *
1216 * This command is used to customize the number of retries the
1217 * wlan device will perform on a given frame.
1218 */
1219#define WMI_MIN_RETRIES 2
1220#define WMI_MAX_RETRIES 13
1221typedef enum {
1222 MGMT_FRAMETYPE = 0,
1223 CONTROL_FRAMETYPE = 1,
1224 DATA_FRAMETYPE = 2
1225} WMI_FRAMETYPE;
1226
1227typedef PREPACK struct {
1228 u8 frameType; /* WMI_FRAMETYPE */
1229 u8 trafficClass; /* applies only to DATA_FRAMETYPE */
1230 u8 maxRetries;
1231 u8 enableNotify;
1232} POSTPACK WMI_SET_RETRY_LIMITS_CMD;
1233
1234/*
1235 * WMI_SET_ROAM_CTRL_CMDID
1236 *
1237 * This command is used to influence the Roaming behaviour
1238 * Set the host biases of the BSSs before setting the roam mode as bias
1239 * based.
1240 */
1241
1242/*
1243 * Different types of Roam Control
1244 */
1245
1246typedef enum {
1247 WMI_FORCE_ROAM = 1, /* Roam to the specified BSSID */
1248 WMI_SET_ROAM_MODE = 2, /* default ,progd bias, no roam */
1249 WMI_SET_HOST_BIAS = 3, /* Set the Host Bias */
1250 WMI_SET_LOWRSSI_SCAN_PARAMS = 4, /* Set lowrssi Scan parameters */
1251} WMI_ROAM_CTRL_TYPE;
1252
1253#define WMI_MIN_ROAM_CTRL_TYPE WMI_FORCE_ROAM
1254#define WMI_MAX_ROAM_CTRL_TYPE WMI_SET_LOWRSSI_SCAN_PARAMS
1255
1256/*
1257 * ROAM MODES
1258 */
1259
1260typedef enum {
1261 WMI_DEFAULT_ROAM_MODE = 1, /* RSSI based ROAM */
1262 WMI_HOST_BIAS_ROAM_MODE = 2, /* HOST BIAS based ROAM */
1263 WMI_LOCK_BSS_MODE = 3 /* Lock to the Current BSS - no Roam */
1264} WMI_ROAM_MODE;
1265
1266/*
1267 * BSS HOST BIAS INFO
1268 */
1269
1270typedef PREPACK struct {
1271 u8 bssid[ATH_MAC_LEN];
1272 s8 bias;
1273} POSTPACK WMI_BSS_BIAS;
1274
1275typedef PREPACK struct {
1276 u8 numBss;
1277 WMI_BSS_BIAS bssBias[1];
1278} POSTPACK WMI_BSS_BIAS_INFO;
1279
1280typedef PREPACK struct WMI_LOWRSSI_SCAN_PARAMS {
1281 u16 lowrssi_scan_period;
1282 s16 lowrssi_scan_threshold;
1283 s16 lowrssi_roam_threshold;
1284 u8 roam_rssi_floor;
1285 u8 reserved[1]; /* For alignment */
1286} POSTPACK WMI_LOWRSSI_SCAN_PARAMS;
1287
1288typedef PREPACK struct {
1289 PREPACK union {
1290 u8 bssid[ATH_MAC_LEN]; /* WMI_FORCE_ROAM */
1291 u8 roamMode; /* WMI_SET_ROAM_MODE */
1292 WMI_BSS_BIAS_INFO bssBiasInfo; /* WMI_SET_HOST_BIAS */
1293 WMI_LOWRSSI_SCAN_PARAMS lrScanParams;
1294 } POSTPACK info;
1295 u8 roamCtrlType ;
1296} POSTPACK WMI_SET_ROAM_CTRL_CMD;
1297
1298/*
1299 * WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID
1300 */
1301typedef enum {
1302 BT_WLAN_CONN_PRECDENCE_WLAN=0, /* Default */
1303 BT_WLAN_CONN_PRECDENCE_PAL,
1304} BT_WLAN_CONN_PRECEDENCE;
1305
1306typedef PREPACK struct {
1307 u8 precedence;
1308} POSTPACK WMI_SET_BT_WLAN_CONN_PRECEDENCE;
1309
1310/*
1311 * WMI_ENABLE_RM_CMDID
1312 */
1313typedef PREPACK struct {
1314 u32 enable_radio_measurements;
1315} POSTPACK WMI_ENABLE_RM_CMD;
1316
1317/*
1318 * WMI_SET_MAX_OFFHOME_DURATION_CMDID
1319 */
1320typedef PREPACK struct {
1321 u8 max_offhome_duration;
1322} POSTPACK WMI_SET_MAX_OFFHOME_DURATION_CMD;
1323
1324typedef PREPACK struct {
1325 u32 frequency;
1326 u8 threshold;
1327} POSTPACK WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD;
1328/*---------------------- BTCOEX RELATED -------------------------------------*/
1329/*----------------------COMMON to AR6002 and AR6003 -------------------------*/
1330typedef enum {
1331 BT_STREAM_UNDEF = 0,
1332 BT_STREAM_SCO, /* SCO stream */
1333 BT_STREAM_A2DP, /* A2DP stream */
1334 BT_STREAM_SCAN, /* BT Discovery or Page */
1335 BT_STREAM_ESCO,
1336 BT_STREAM_MAX
1337} BT_STREAM_TYPE;
1338
1339typedef enum {
1340 BT_PARAM_SCO_PSPOLL_LATENCY_ONE_FOURTH =1,
1341 BT_PARAM_SCO_PSPOLL_LATENCY_HALF,
1342 BT_PARAM_SCO_PSPOLL_LATENCY_THREE_FOURTH,
1343} BT_PARAMS_SCO_PSPOLL_LATENCY;
1344
1345typedef enum {
1346 BT_PARAMS_SCO_STOMP_SCO_NEVER =1,
1347 BT_PARAMS_SCO_STOMP_SCO_ALWAYS,
1348 BT_PARAMS_SCO_STOMP_SCO_IN_LOWRSSI,
1349} BT_PARAMS_SCO_STOMP_RULES;
1350
1351typedef enum {
1352 BT_STATUS_UNDEF = 0,
1353 BT_STATUS_ON,
1354 BT_STATUS_OFF,
1355 BT_STATUS_MAX
1356} BT_STREAM_STATUS;
1357
1358typedef PREPACK struct {
1359 u8 streamType;
1360 u8 status;
1361} POSTPACK WMI_SET_BT_STATUS_CMD;
1362
1363typedef enum {
1364 BT_ANT_TYPE_UNDEF=0,
1365 BT_ANT_TYPE_DUAL,
1366 BT_ANT_TYPE_SPLITTER,
1367 BT_ANT_TYPE_SWITCH,
1368 BT_ANT_TYPE_HIGH_ISO_DUAL
1369} BT_ANT_FRONTEND_CONFIG;
1370
1371typedef enum {
1372 BT_COLOCATED_DEV_BTS4020=0,
1373 BT_COLCATED_DEV_CSR ,
1374 BT_COLOCATED_DEV_VALKYRIE
1375} BT_COLOCATED_DEV_TYPE;
1376
1377/*********************** Applicable to AR6002 ONLY ******************************/
1378
1379typedef enum {
1380 BT_PARAM_SCO = 1, /* SCO stream parameters */
1381 BT_PARAM_A2DP ,
1382 BT_PARAM_ANTENNA_CONFIG,
1383 BT_PARAM_COLOCATED_BT_DEVICE,
1384 BT_PARAM_ACLCOEX,
1385 BT_PARAM_11A_SEPARATE_ANT,
1386 BT_PARAM_MAX
1387} BT_PARAM_TYPE;
1388
1389
1390#define BT_SCO_ALLOW_CLOSE_RANGE_OPT (1 << 0)
1391#define BT_SCO_FORCE_AWAKE_OPT (1 << 1)
1392#define BT_SCO_SET_RSSI_OVERRIDE(flags) ((flags) |= (1 << 2))
1393#define BT_SCO_GET_RSSI_OVERRIDE(flags) (((flags) >> 2) & 0x1)
1394#define BT_SCO_SET_RTS_OVERRIDE(flags) ((flags) |= (1 << 3))
1395#define BT_SCO_GET_RTS_OVERRIDE(flags) (((flags) >> 3) & 0x1)
1396#define BT_SCO_GET_MIN_LOW_RATE_CNT(flags) (((flags) >> 8) & 0xFF)
1397#define BT_SCO_GET_MAX_LOW_RATE_CNT(flags) (((flags) >> 16) & 0xFF)
1398#define BT_SCO_SET_MIN_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 8)
1399#define BT_SCO_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16)
1400
1401typedef PREPACK struct {
1402 u32 numScoCyclesForceTrigger; /* Number SCO cycles after which
1403 force a pspoll. default = 10 */
1404 u32 dataResponseTimeout; /* Timeout Waiting for Downlink pkt
1405 in response for ps-poll,
1406 default = 10 msecs */
1407 u32 stompScoRules;
1408 u32 scoOptFlags; /* SCO Options Flags :
1409 bits: meaning:
1410 0 Allow Close Range Optimization
1411 1 Force awake during close range
1412 2 If set use host supplied RSSI for OPT
1413 3 If set use host supplied RTS COUNT for OPT
1414 4..7 Unused
1415 8..15 Low Data Rate Min Cnt
1416 16..23 Low Data Rate Max Cnt
1417 */
1418
1419 u8 stompDutyCyleVal; /* Sco cycles to limit ps-poll queuing
1420 if stomped */
1421 u8 stompDutyCyleMaxVal; /*firm ware increases stomp duty cycle
1422 gradually uptill this value on need basis*/
1423 u8 psPollLatencyFraction; /* Fraction of idle
1424 period, within which
1425 additional ps-polls
1426 can be queued */
1427 u8 noSCOSlots; /* Number of SCO Tx/Rx slots.
1428 HVx, EV3, 2EV3 = 2 */
1429 u8 noIdleSlots; /* Number of Bluetooth idle slots between
1430 consecutive SCO Tx/Rx slots
1431 HVx, EV3 = 4
1432 2EV3 = 10 */
1433 u8 scoOptOffRssi;/*RSSI value below which we go to ps poll*/
1434 u8 scoOptOnRssi; /*RSSI value above which we reenter opt mode*/
1435 u8 scoOptRtsCount;
1436} POSTPACK BT_PARAMS_SCO;
1437
1438#define BT_A2DP_ALLOW_CLOSE_RANGE_OPT (1 << 0)
1439#define BT_A2DP_FORCE_AWAKE_OPT (1 << 1)
1440#define BT_A2DP_SET_RSSI_OVERRIDE(flags) ((flags) |= (1 << 2))
1441#define BT_A2DP_GET_RSSI_OVERRIDE(flags) (((flags) >> 2) & 0x1)
1442#define BT_A2DP_SET_RTS_OVERRIDE(flags) ((flags) |= (1 << 3))
1443#define BT_A2DP_GET_RTS_OVERRIDE(flags) (((flags) >> 3) & 0x1)
1444#define BT_A2DP_GET_MIN_LOW_RATE_CNT(flags) (((flags) >> 8) & 0xFF)
1445#define BT_A2DP_GET_MAX_LOW_RATE_CNT(flags) (((flags) >> 16) & 0xFF)
1446#define BT_A2DP_SET_MIN_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 8)
1447#define BT_A2DP_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16)
1448
1449typedef PREPACK struct {
1450 u32 a2dpWlanUsageLimit; /* MAX time firmware uses the medium for
1451 wlan, after it identifies the idle time
1452 default (30 msecs) */
1453 u32 a2dpBurstCntMin; /* Minimum number of bluetooth data frames
1454 to replenish Wlan Usage limit (default 3) */
1455 u32 a2dpDataRespTimeout;
1456 u32 a2dpOptFlags; /* A2DP Option flags:
1457 bits: meaning:
1458 0 Allow Close Range Optimization
1459 1 Force awake during close range
1460 2 If set use host supplied RSSI for OPT
1461 3 If set use host supplied RTS COUNT for OPT
1462 4..7 Unused
1463 8..15 Low Data Rate Min Cnt
1464 16..23 Low Data Rate Max Cnt
1465 */
1466 u8 isCoLocatedBtRoleMaster;
1467 u8 a2dpOptOffRssi;/*RSSI value below which we go to ps poll*/
1468 u8 a2dpOptOnRssi; /*RSSI value above which we reenter opt mode*/
1469 u8 a2dpOptRtsCount;
1470}POSTPACK BT_PARAMS_A2DP;
1471
1472/* During BT ftp/ BT OPP or any another data based acl profile on bluetooth
1473 (non a2dp).*/
1474typedef PREPACK struct {
1475 u32 aclWlanMediumUsageTime; /* Wlan usage time during Acl (non-a2dp)
1476 coexistence (default 30 msecs) */
1477 u32 aclBtMediumUsageTime; /* Bt usage time during acl coexistence
1478 (default 30 msecs)*/
1479 u32 aclDataRespTimeout;
1480 u32 aclDetectTimeout; /* ACL coexistence enabled if we get
1481 10 Pkts in X msec(default 100 msecs) */
1482 u32 aclmaxPktCnt; /* No of ACL pkts to receive before
1483 enabling ACL coex */
1484
1485}POSTPACK BT_PARAMS_ACLCOEX;
1486
1487typedef PREPACK struct {
1488 PREPACK union {
1489 BT_PARAMS_SCO scoParams;
1490 BT_PARAMS_A2DP a2dpParams;
1491 BT_PARAMS_ACLCOEX aclCoexParams;
1492 u8 antType; /* 0 -Disabled (default)
1493 1 - BT_ANT_TYPE_DUAL
1494 2 - BT_ANT_TYPE_SPLITTER
1495 3 - BT_ANT_TYPE_SWITCH */
1496 u8 coLocatedBtDev; /* 0 - BT_COLOCATED_DEV_BTS4020 (default)
1497 1 - BT_COLCATED_DEV_CSR
1498 2 - BT_COLOCATED_DEV_VALKYRIe
1499 */
1500 } POSTPACK info;
1501 u8 paramType ;
1502} POSTPACK WMI_SET_BT_PARAMS_CMD;
1503
1504/************************ END AR6002 BTCOEX *******************************/
1505/*-----------------------AR6003 BTCOEX -----------------------------------*/
1506
1507/* ---------------WMI_SET_BTCOEX_FE_ANT_CMDID --------------------------*/
1508/* Indicates front end antenna configuration. This command needs to be issued
1509 * right after initialization and after WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID.
1510 * AR6003 enables coexistence and antenna switching based on the configuration.
1511 */
1512typedef enum {
1513 WMI_BTCOEX_NOT_ENABLED = 0,
1514 WMI_BTCOEX_FE_ANT_SINGLE =1,
1515 WMI_BTCOEX_FE_ANT_DUAL=2,
1516 WMI_BTCOEX_FE_ANT_DUAL_HIGH_ISO=3,
1517 WMI_BTCOEX_FE_ANT_TYPE_MAX
1518}WMI_BTCOEX_FE_ANT_TYPE;
1519
1520typedef PREPACK struct {
1521 u8 btcoexFeAntType; /* 1 - WMI_BTCOEX_FE_ANT_SINGLE for single antenna front end
1522 2 - WMI_BTCOEX_FE_ANT_DUAL for dual antenna front end
1523 (for isolations less 35dB, for higher isolation there
1524 is not need to pass this command).
1525 (not implemented)
1526 */
1527}POSTPACK WMI_SET_BTCOEX_FE_ANT_CMD;
1528
1529/* -------------WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID ----------------*/
1530/* Indicate the bluetooth chip to the firmware. Firmware can have different algorithm based
1531 * bluetooth chip type.Based on bluetooth device, different coexistence protocol would be used.
1532 */
1533typedef PREPACK struct {
1534 u8 btcoexCoLocatedBTdev; /*1 - Qcom BT (3 -wire PTA)
1535 2 - CSR BT (3 wire PTA)
1536 3 - Atheros 3001 BT (3 wire PTA)
1537 4 - STE bluetooth (4-wire ePTA)
1538 5 - Atheros 3002 BT (4-wire MCI)
1539 defaults= 3 (Atheros 3001 BT )
1540 */
1541}POSTPACK WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD;
1542
1543/* -------------WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID ------------*/
1544/* Configuration parameters during bluetooth inquiry and page. Page configuration
1545 * is applicable only on interfaces which can distinguish page (applicable only for ePTA -
1546 * STE bluetooth).
1547 * Bluetooth inquiry start and end is indicated via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID.
1548 * During this the station will be power-save mode.
1549 */
1550typedef PREPACK struct {
1551 u32 btInquiryDataFetchFrequency;/* The frequency of querying the AP for data
1552 (via pspoll) is configured by this parameter.
1553 "default = 10 ms" */
1554
1555 u32 protectBmissDurPostBtInquiry;/* The firmware will continue to be in inquiry state
1556 for configured duration, after inquiry completion
1557 . This is to ensure other bluetooth transactions
1558 (RDP, SDP profiles, link key exchange ...etc)
1559 goes through smoothly without wifi stomping.
1560 default = 10 secs*/
1561
1562 u32 maxpageStomp; /*Applicable only for STE-BT interface. Currently not
1563 used */
1564 u32 btInquiryPageFlag; /* Not used */
1565}POSTPACK WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD;
1566
1567/*---------------------WMI_SET_BTCOEX_SCO_CONFIG_CMDID ---------------*/
1568/* Configure SCO parameters. These parameters would be used whenever firmware is indicated
1569 * of (e)SCO profile on bluetooth ( via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID).
1570 * Configration of BTCOEX_SCO_CONFIG data structure are common configuration and applies
1571 * ps-poll mode and opt mode.
1572 * Ps-poll Mode - Station is in power-save and retrieves downlink data between sco gaps.
1573 * Opt Mode - station is in awake state and access point can send data to station any time.
1574 * BTCOEX_PSPOLLMODE_SCO_CONFIG - Configuration applied only during ps-poll mode.
1575 * BTCOEX_OPTMODE_SCO_CONFIG - Configuration applied only during opt mode.
1576 */
1577#define WMI_SCO_CONFIG_FLAG_ALLOW_OPTIMIZATION (1 << 0)
1578#define WMI_SCO_CONFIG_FLAG_IS_EDR_CAPABLE (1 << 1)
1579#define WMI_SCO_CONFIG_FLAG_IS_BT_MASTER (1 << 2)
1580#define WMI_SCO_CONFIG_FLAG_FW_DETECT_OF_PER (1 << 3)
1581typedef PREPACK struct {
1582 u32 scoSlots; /* Number of SCO Tx/Rx slots.
1583 HVx, EV3, 2EV3 = 2 */
1584 u32 scoIdleSlots; /* Number of Bluetooth idle slots between
1585 consecutive SCO Tx/Rx slots
1586 HVx, EV3 = 4
1587 2EV3 = 10
1588 */
1589 u32 scoFlags; /* SCO Options Flags :
1590 bits: meaning:
1591 0 Allow Close Range Optimization
1592 1 Is EDR capable or Not
1593 2 IS Co-located Bt role Master
1594 3 Firmware determines the periodicity of SCO.
1595 */
1596
1597 u32 linkId; /* applicable to STE-BT - not used */
1598}POSTPACK BTCOEX_SCO_CONFIG;
1599
1600typedef PREPACK struct {
1601 u32 scoCyclesForceTrigger; /* Number SCO cycles after which
1602 force a pspoll. default = 10 */
1603 u32 scoDataResponseTimeout; /* Timeout Waiting for Downlink pkt
1604 in response for ps-poll,
1605 default = 20 msecs */
1606
1607 u32 scoStompDutyCyleVal; /* not implemented */
1608
1609 u32 scoStompDutyCyleMaxVal; /*Not implemented */
1610
1611 u32 scoPsPollLatencyFraction; /* Fraction of idle
1612 period, within which
1613 additional ps-polls can be queued
1614 1 - 1/4 of idle duration
1615 2 - 1/2 of idle duration
1616 3 - 3/4 of idle duration
1617 default =2 (1/2)
1618 */
1619}POSTPACK BTCOEX_PSPOLLMODE_SCO_CONFIG;
1620
1621typedef PREPACK struct {
1622 u32 scoStompCntIn100ms;/*max number of SCO stomp in 100ms allowed in
1623 opt mode. If exceeds the configured value,
1624 switch to ps-poll mode
1625 default = 3 */
1626
1627 u32 scoContStompMax; /* max number of continuous stomp allowed in opt mode.
1628 if exceeded switch to pspoll mode
1629 default = 3 */
1630
1631 u32 scoMinlowRateMbps; /* Low rate threshold */
1632
1633 u32 scoLowRateCnt; /* number of low rate pkts (< scoMinlowRateMbps) allowed in 100 ms.
1634 If exceeded switch/stay to ps-poll mode, lower stay in opt mode.
1635 default = 36
1636 */
1637
1638 u32 scoHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/
1639 ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms,
1640 if exceeded switch/stay in opt mode and if lower switch/stay in pspoll mode.
1641 default = 5 (80% of high rates)
1642 */
1643
1644 u32 scoMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates
1645 max number of aggregates if it was negogiated to higher value
1646 default = 1
1647 Recommended value Basic rate headsets = 1, EDR (2-EV3) =4.
1648 */
1649}POSTPACK BTCOEX_OPTMODE_SCO_CONFIG;
1650
1651typedef PREPACK struct {
1652 u32 scanInterval;
1653 u32 maxScanStompCnt;
1654}POSTPACK BTCOEX_WLANSCAN_SCO_CONFIG;
1655
1656typedef PREPACK struct {
1657 BTCOEX_SCO_CONFIG scoConfig;
1658 BTCOEX_PSPOLLMODE_SCO_CONFIG scoPspollConfig;
1659 BTCOEX_OPTMODE_SCO_CONFIG scoOptModeConfig;
1660 BTCOEX_WLANSCAN_SCO_CONFIG scoWlanScanConfig;
1661}POSTPACK WMI_SET_BTCOEX_SCO_CONFIG_CMD;
1662
1663/* ------------------WMI_SET_BTCOEX_A2DP_CONFIG_CMDID -------------------*/
1664/* Configure A2DP profile parameters. These parameters would be used whenver firmware is indicated
1665 * of A2DP profile on bluetooth ( via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID).
1666 * Configuration of BTCOEX_A2DP_CONFIG data structure are common configuration and applies to
1667 * ps-poll mode and opt mode.
1668 * Ps-poll Mode - Station is in power-save and retrieves downlink data between a2dp data bursts.
1669 * Opt Mode - station is in power save during a2dp bursts and awake in the gaps.
1670 * BTCOEX_PSPOLLMODE_A2DP_CONFIG - Configuration applied only during ps-poll mode.
1671 * BTCOEX_OPTMODE_A2DP_CONFIG - Configuration applied only during opt mode.
1672 */
1673
1674#define WMI_A2DP_CONFIG_FLAG_ALLOW_OPTIMIZATION (1 << 0)
1675#define WMI_A2DP_CONFIG_FLAG_IS_EDR_CAPABLE (1 << 1)
1676#define WMI_A2DP_CONFIG_FLAG_IS_BT_ROLE_MASTER (1 << 2)
1677#define WMI_A2DP_CONFIG_FLAG_IS_A2DP_HIGH_PRI (1 << 3)
1678#define WMI_A2DP_CONFIG_FLAG_FIND_BT_ROLE (1 << 4)
1679
1680typedef PREPACK struct {
1681 u32 a2dpFlags; /* A2DP Option flags:
1682 bits: meaning:
1683 0 Allow Close Range Optimization
1684 1 IS EDR capable
1685 2 IS Co-located Bt role Master
1686 3 a2dp traffic is high priority
1687 4 Fw detect the role of bluetooth.
1688 */
1689 u32 linkId; /* Applicable only to STE-BT - not used */
1690
1691}POSTPACK BTCOEX_A2DP_CONFIG;
1692
1693typedef PREPACK struct {
1694 u32 a2dpWlanMaxDur; /* MAX time firmware uses the medium for
1695 wlan, after it identifies the idle time
1696 default (30 msecs) */
1697
1698 u32 a2dpMinBurstCnt; /* Minimum number of bluetooth data frames
1699 to replenish Wlan Usage limit (default 3) */
1700
1701 u32 a2dpDataRespTimeout; /* Max duration firmware waits for downlink
1702 by stomping on bluetooth
1703 after ps-poll is acknowledged.
1704 default = 20 ms
1705 */
1706}POSTPACK BTCOEX_PSPOLLMODE_A2DP_CONFIG;
1707
1708typedef PREPACK struct {
1709 u32 a2dpMinlowRateMbps; /* Low rate threshold */
1710
1711 u32 a2dpLowRateCnt; /* number of low rate pkts (< a2dpMinlowRateMbps) allowed in 100 ms.
1712 If exceeded switch/stay to ps-poll mode, lower stay in opt mode.
1713 default = 36
1714 */
1715
1716 u32 a2dpHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/
1717 ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms,
1718 if exceeded switch/stay in opt mode and if lower switch/stay in pspoll mode.
1719 default = 5 (80% of high rates)
1720 */
1721
1722 u32 a2dpMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates
1723 max number of aggregates if it was negogiated to higher value
1724 default = 1
1725 Recommended value Basic rate headsets = 1, EDR (2-EV3) =8.
1726 */
1727 u32 a2dpPktStompCnt; /*number of a2dp pkts that can be stomped per burst.
1728 default = 6*/
1729
1730}POSTPACK BTCOEX_OPTMODE_A2DP_CONFIG;
1731
1732typedef PREPACK struct {
1733 BTCOEX_A2DP_CONFIG a2dpConfig;
1734 BTCOEX_PSPOLLMODE_A2DP_CONFIG a2dppspollConfig;
1735 BTCOEX_OPTMODE_A2DP_CONFIG a2dpOptConfig;
1736}POSTPACK WMI_SET_BTCOEX_A2DP_CONFIG_CMD;
1737
1738/*------------ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID---------------------*/
1739/* Configure non-A2dp ACL profile parameters.The starts of ACL profile can either be
1740 * indicated via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID orenabled via firmware detection
1741 * which is configured via "aclCoexFlags".
1742 * Configration of BTCOEX_ACLCOEX_CONFIG data structure are common configuration and applies
1743 * ps-poll mode and opt mode.
1744 * Ps-poll Mode - Station is in power-save and retrieves downlink data during wlan medium.
1745 * Opt Mode - station is in power save during bluetooth medium time and awake during wlan duration.
1746 * (Not implemented yet)
1747 *
1748 * BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG - Configuration applied only during ps-poll mode.
1749 * BTCOEX_OPTMODE_ACLCOEX_CONFIG - Configuration applied only during opt mode.
1750 */
1751
1752#define WMI_ACLCOEX_FLAGS_ALLOW_OPTIMIZATION (1 << 0)
1753#define WMI_ACLCOEX_FLAGS_DISABLE_FW_DETECTION (1 << 1)
1754
1755typedef PREPACK struct {
1756 u32 aclWlanMediumDur; /* Wlan usage time during Acl (non-a2dp)
1757 coexistence (default 30 msecs)
1758 */
1759
1760 u32 aclBtMediumDur; /* Bt usage time during acl coexistence
1761 (default 30 msecs)
1762 */
1763
1764 u32 aclDetectTimeout; /* BT activity observation time limit.
1765 In this time duration, number of bt pkts are counted.
1766 If the Cnt reaches "aclPktCntLowerLimit" value
1767 for "aclIterToEnableCoex" iteration continuously,
1768 firmware gets into ACL coexistence mode.
1769 Similarly, if bt traffic count during ACL coexistence
1770 has not reached "aclPktCntLowerLimit" continuously
1771 for "aclIterToEnableCoex", then ACL coexistence is
1772 disabled.
1773 -default 100 msecs
1774 */
1775
1776 u32 aclPktCntLowerLimit; /* Acl Pkt Cnt to be received in duration of
1777 "aclDetectTimeout" for
1778 "aclIterForEnDis" times to enabling ACL coex.
1779 Similar logic is used to disable acl coexistence.
1780 (If "aclPktCntLowerLimit" cnt of acl pkts
1781 are not seen by the for "aclIterForEnDis"
1782 then acl coexistence is disabled).
1783 default = 10
1784 */
1785
1786 u32 aclIterForEnDis; /* number of Iteration of "aclPktCntLowerLimit" for Enabling and
1787 Disabling Acl Coexistence.
1788 default = 3
1789 */
1790
1791 u32 aclPktCntUpperLimit; /* This is upperBound limit, if there is more than
1792 "aclPktCntUpperLimit" seen in "aclDetectTimeout",
1793 ACL coexistence is enabled right away.
1794 - default 15*/
1795
1796 u32 aclCoexFlags; /* A2DP Option flags:
1797 bits: meaning:
1798 0 Allow Close Range Optimization
1799 1 disable Firmware detection
1800 (Currently supported configuration is aclCoexFlags =0)
1801 */
1802 u32 linkId; /* Applicable only for STE-BT - not used */
1803
1804}POSTPACK BTCOEX_ACLCOEX_CONFIG;
1805
1806typedef PREPACK struct {
1807 u32 aclDataRespTimeout; /* Max duration firmware waits for downlink
1808 by stomping on bluetooth
1809 after ps-poll is acknowledged.
1810 default = 20 ms */
1811
1812}POSTPACK BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG;
1813
1814
1815/* Not implemented yet*/
1816typedef PREPACK struct {
1817 u32 aclCoexMinlowRateMbps;
1818 u32 aclCoexLowRateCnt;
1819 u32 aclCoexHighPktRatio;
1820 u32 aclCoexMaxAggrSize;
1821 u32 aclPktStompCnt;
1822}POSTPACK BTCOEX_OPTMODE_ACLCOEX_CONFIG;
1823
1824typedef PREPACK struct {
1825 BTCOEX_ACLCOEX_CONFIG aclCoexConfig;
1826 BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG aclCoexPspollConfig;
1827 BTCOEX_OPTMODE_ACLCOEX_CONFIG aclCoexOptConfig;
1828}POSTPACK WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD;
1829
1830/* -----------WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ------------------*/
1831typedef enum {
1832 WMI_BTCOEX_BT_PROFILE_SCO =1,
1833 WMI_BTCOEX_BT_PROFILE_A2DP,
1834 WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE,
1835 WMI_BTCOEX_BT_PROFILE_ACLCOEX,
1836}WMI_BTCOEX_BT_PROFILE;
1837
1838typedef PREPACK struct {
1839 u32 btProfileType;
1840 u32 btOperatingStatus;
1841 u32 btLinkId;
1842}WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD;
1843
1844/*--------------------- WMI_SET_BTCOEX_DEBUG_CMDID ---------------------*/
1845/* Used for firmware development and debugging */
1846typedef PREPACK struct {
1847 u32 btcoexDbgParam1;
1848 u32 btcoexDbgParam2;
1849 u32 btcoexDbgParam3;
1850 u32 btcoexDbgParam4;
1851 u32 btcoexDbgParam5;
1852}WMI_SET_BTCOEX_DEBUG_CMD;
1853
1854/*---------------------WMI_GET_BTCOEX_CONFIG_CMDID --------------------- */
1855/* Command to firmware to get configuration parameters of the bt profile
1856 * reported via WMI_BTCOEX_CONFIG_EVENTID */
1857typedef PREPACK struct {
1858 u32 btProfileType; /* 1 - SCO
1859 2 - A2DP
1860 3 - INQUIRY_PAGE
1861 4 - ACLCOEX
1862 */
1863 u32 linkId; /* not used */
1864}WMI_GET_BTCOEX_CONFIG_CMD;
1865
1866/*------------------WMI_REPORT_BTCOEX_CONFIG_EVENTID------------------- */
1867/* Event from firmware to host, sent in response to WMI_GET_BTCOEX_CONFIG_CMDID
1868 * */
1869typedef PREPACK struct {
1870 u32 btProfileType;
1871 u32 linkId; /* not used */
1872 PREPACK union {
1873 WMI_SET_BTCOEX_SCO_CONFIG_CMD scoConfigCmd;
1874 WMI_SET_BTCOEX_A2DP_CONFIG_CMD a2dpConfigCmd;
1875 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD aclcoexConfig;
1876 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD btinquiryPageConfigCmd;
1877 } POSTPACK info;
1878} POSTPACK WMI_BTCOEX_CONFIG_EVENT;
1879
1880/*------------- WMI_REPORT_BTCOEX_BTCOEX_STATS_EVENTID--------------------*/
1881/* Used for firmware development and debugging*/
1882typedef PREPACK struct {
1883 u32 highRatePktCnt;
1884 u32 firstBmissCnt;
1885 u32 psPollFailureCnt;
1886 u32 nullFrameFailureCnt;
1887 u32 optModeTransitionCnt;
1888}BTCOEX_GENERAL_STATS;
1889
1890typedef PREPACK struct {
1891 u32 scoStompCntAvg;
1892 u32 scoStompIn100ms;
1893 u32 scoMaxContStomp;
1894 u32 scoAvgNoRetries;
1895 u32 scoMaxNoRetriesIn100ms;
1896}BTCOEX_SCO_STATS;
1897
1898typedef PREPACK struct {
1899 u32 a2dpBurstCnt;
1900 u32 a2dpMaxBurstCnt;
1901 u32 a2dpAvgIdletimeIn100ms;
1902 u32 a2dpAvgStompCnt;
1903}BTCOEX_A2DP_STATS;
1904
1905typedef PREPACK struct {
1906 u32 aclPktCntInBtTime;
1907 u32 aclStompCntInWlanTime;
1908 u32 aclPktCntIn100ms;
1909}BTCOEX_ACLCOEX_STATS;
1910
1911typedef PREPACK struct {
1912 BTCOEX_GENERAL_STATS coexStats;
1913 BTCOEX_SCO_STATS scoStats;
1914 BTCOEX_A2DP_STATS a2dpStats;
1915 BTCOEX_ACLCOEX_STATS aclCoexStats;
1916}WMI_BTCOEX_STATS_EVENT;
1917
1918
1919/*--------------------------END OF BTCOEX -------------------------------------*/
1920typedef PREPACK struct {
1921 u32 sleepState;
1922}WMI_REPORT_SLEEP_STATE_EVENT;
1923
1924typedef enum {
1925 WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP =0,
1926 WMI_REPORT_SLEEP_STATUS_IS_AWAKE
1927} WMI_REPORT_SLEEP_STATUS;
1928typedef enum {
1929 DISCONN_EVT_IN_RECONN = 0, /* default */
1930 NO_DISCONN_EVT_IN_RECONN
1931} TARGET_EVENT_REPORT_CONFIG;
1932
1933typedef PREPACK struct {
1934 u32 evtConfig;
1935} POSTPACK WMI_SET_TARGET_EVENT_REPORT_CMD;
1936
1937
1938typedef PREPACK struct {
1939 u16 cmd_buf_sz; /* HCI cmd buffer size */
1940 u8 buf[1]; /* Absolute HCI cmd */
1941} POSTPACK WMI_HCI_CMD;
1942
1943/*
1944 * Command Replies
1945 */
1946
1947/*
1948 * WMI_GET_CHANNEL_LIST_CMDID reply
1949 */
1950typedef PREPACK struct {
1951 u8 reserved1;
1952 u8 numChannels; /* number of channels in reply */
1953 u16 channelList[1]; /* channel in Mhz */
1954} POSTPACK WMI_CHANNEL_LIST_REPLY;
1955
1956typedef enum {
1957 A_SUCCEEDED = 0,
1958 A_FAILED_DELETE_STREAM_DOESNOT_EXIST=250,
1959 A_SUCCEEDED_MODIFY_STREAM=251,
1960 A_FAILED_INVALID_STREAM = 252,
1961 A_FAILED_MAX_THINSTREAMS = 253,
1962 A_FAILED_CREATE_REMOVE_PSTREAM_FIRST = 254,
1963} PSTREAM_REPLY_STATUS;
1964
1965typedef PREPACK struct {
1966 u8 status; /* PSTREAM_REPLY_STATUS */
1967 u8 txQueueNumber;
1968 u8 rxQueueNumber;
1969 u8 trafficClass;
1970 u8 trafficDirection; /* DIR_TYPE */
1971} POSTPACK WMI_CRE_PRIORITY_STREAM_REPLY;
1972
1973typedef PREPACK struct {
1974 u8 status; /* PSTREAM_REPLY_STATUS */
1975 u8 txQueueNumber;
1976 u8 rxQueueNumber;
1977 u8 trafficDirection; /* DIR_TYPE */
1978 u8 trafficClass;
1979} POSTPACK WMI_DEL_PRIORITY_STREAM_REPLY;
1980
1981/*
1982 * List of Events (target to host)
1983 */
1984typedef enum {
1985 WMI_READY_EVENTID = 0x1001,
1986 WMI_CONNECT_EVENTID,
1987 WMI_DISCONNECT_EVENTID,
1988 WMI_BSSINFO_EVENTID,
1989 WMI_CMDERROR_EVENTID,
1990 WMI_REGDOMAIN_EVENTID,
1991 WMI_PSTREAM_TIMEOUT_EVENTID,
1992 WMI_NEIGHBOR_REPORT_EVENTID,
1993 WMI_TKIP_MICERR_EVENTID,
1994 WMI_SCAN_COMPLETE_EVENTID, /* 0x100a */
1995 WMI_REPORT_STATISTICS_EVENTID,
1996 WMI_RSSI_THRESHOLD_EVENTID,
1997 WMI_ERROR_REPORT_EVENTID,
1998 WMI_OPT_RX_FRAME_EVENTID,
1999 WMI_REPORT_ROAM_TBL_EVENTID,
2000 WMI_EXTENSION_EVENTID,
2001 WMI_CAC_EVENTID,
2002 WMI_SNR_THRESHOLD_EVENTID,
2003 WMI_LQ_THRESHOLD_EVENTID,
2004 WMI_TX_RETRY_ERR_EVENTID, /* 0x1014 */
2005 WMI_REPORT_ROAM_DATA_EVENTID,
2006 WMI_TEST_EVENTID,
2007 WMI_APLIST_EVENTID,
2008 WMI_GET_WOW_LIST_EVENTID,
2009 WMI_GET_PMKID_LIST_EVENTID,
2010 WMI_CHANNEL_CHANGE_EVENTID,
2011 WMI_PEER_NODE_EVENTID,
2012 WMI_PSPOLL_EVENTID,
2013 WMI_DTIMEXPIRY_EVENTID,
2014 WMI_WLAN_VERSION_EVENTID,
2015 WMI_SET_PARAMS_REPLY_EVENTID,
2016 WMI_ADDBA_REQ_EVENTID, /*0x1020 */
2017 WMI_ADDBA_RESP_EVENTID,
2018 WMI_DELBA_REQ_EVENTID,
2019 WMI_TX_COMPLETE_EVENTID,
2020 WMI_HCI_EVENT_EVENTID,
2021 WMI_ACL_DATA_EVENTID,
2022 WMI_REPORT_SLEEP_STATE_EVENTID,
2023#ifdef WAPI_ENABLE
2024 WMI_WAPI_REKEY_EVENTID,
2025#endif
2026 WMI_REPORT_BTCOEX_STATS_EVENTID,
2027 WMI_REPORT_BTCOEX_CONFIG_EVENTID,
2028 WMI_GET_PMK_EVENTID,
2029
2030 /* DFS Events */
2031 WMI_DFS_HOST_ATTACH_EVENTID,
2032 WMI_DFS_HOST_INIT_EVENTID,
2033 WMI_DFS_RESET_DELAYLINES_EVENTID,
2034 WMI_DFS_RESET_RADARQ_EVENTID,
2035 WMI_DFS_RESET_AR_EVENTID,
2036 WMI_DFS_RESET_ARQ_EVENTID,
2037 WMI_DFS_SET_DUR_MULTIPLIER_EVENTID,
2038 WMI_DFS_SET_BANGRADAR_EVENTID,
2039 WMI_DFS_SET_DEBUGLEVEL_EVENTID,
2040 WMI_DFS_PHYERR_EVENTID,
2041 /* CCX Evants */
2042 WMI_CCX_RM_STATUS_EVENTID,
2043
2044 /* P2P Events */
2045 WMI_P2P_GO_NEG_RESULT_EVENTID,
2046
2047 WMI_WAC_SCAN_DONE_EVENTID,
2048 WMI_WAC_REPORT_BSS_EVENTID,
2049 WMI_WAC_START_WPS_EVENTID,
2050 WMI_WAC_CTRL_REQ_REPLY_EVENTID,
2051
2052 /* RFKILL Events */
2053 WMI_RFKILL_STATE_CHANGE_EVENTID,
2054 WMI_RFKILL_GET_MODE_CMD_EVENTID,
2055 WMI_THIN_RESERVED_START_EVENTID = 0x8000,
2056
2057 /*
2058 * Events in this range are reserved for thinmode
2059 * See wmi_thin.h for actual definitions
2060 */
2061 WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
2062
2063 WMI_SET_CHANNEL_EVENTID,
2064 WMI_ASSOC_REQ_EVENTID,
2065
2066 /* generic ACS event */
2067 WMI_ACS_EVENTID,
2068 WMI_REPORT_WMM_PARAMS_EVENTID
2069} WMI_EVENT_ID;
2070
2071
2072typedef enum {
2073 WMI_11A_CAPABILITY = 1,
2074 WMI_11G_CAPABILITY = 2,
2075 WMI_11AG_CAPABILITY = 3,
2076 WMI_11NA_CAPABILITY = 4,
2077 WMI_11NG_CAPABILITY = 5,
2078 WMI_11NAG_CAPABILITY = 6,
2079 // END CAPABILITY
2080 WMI_11N_CAPABILITY_OFFSET = (WMI_11NA_CAPABILITY - WMI_11A_CAPABILITY),
2081} WMI_PHY_CAPABILITY;
2082
2083typedef PREPACK struct {
2084 u8 macaddr[ATH_MAC_LEN];
2085 u8 phyCapability; /* WMI_PHY_CAPABILITY */
2086} POSTPACK WMI_READY_EVENT_1;
2087
2088typedef PREPACK struct {
2089 u32 sw_version;
2090 u32 abi_version;
2091 u8 macaddr[ATH_MAC_LEN];
2092 u8 phyCapability; /* WMI_PHY_CAPABILITY */
2093} POSTPACK WMI_READY_EVENT_2;
2094
2095#if defined(ATH_TARGET)
2096#ifdef AR6002_REV2
2097#define WMI_READY_EVENT WMI_READY_EVENT_1 /* AR6002_REV2 target code */
2098#else
2099#define WMI_READY_EVENT WMI_READY_EVENT_2 /* AR6001, AR6002_REV4, AR6002_REV5 */
2100#endif
2101#else
2102#define WMI_READY_EVENT WMI_READY_EVENT_2 /* host code */
2103#endif
2104
2105
2106/*
2107 * Connect Event
2108 */
2109typedef PREPACK struct {
2110 u16 channel;
2111 u8 bssid[ATH_MAC_LEN];
2112 u16 listenInterval;
2113 u16 beaconInterval;
2114 u32 networkType;
2115 u8 beaconIeLen;
2116 u8 assocReqLen;
2117 u8 assocRespLen;
2118 u8 assocInfo[1];
2119} POSTPACK WMI_CONNECT_EVENT;
2120
2121/*
2122 * Disconnect Event
2123 */
2124typedef enum {
2125 NO_NETWORK_AVAIL = 0x01,
2126 LOST_LINK = 0x02, /* bmiss */
2127 DISCONNECT_CMD = 0x03,
2128 BSS_DISCONNECTED = 0x04,
2129 AUTH_FAILED = 0x05,
2130 ASSOC_FAILED = 0x06,
2131 NO_RESOURCES_AVAIL = 0x07,
2132 CSERV_DISCONNECT = 0x08,
2133 INVALID_PROFILE = 0x0a,
2134 DOT11H_CHANNEL_SWITCH = 0x0b,
2135 PROFILE_MISMATCH = 0x0c,
2136 CONNECTION_EVICTED = 0x0d,
2137 IBSS_MERGE = 0xe,
2138} WMI_DISCONNECT_REASON;
2139
2140typedef PREPACK struct {
2141 u16 protocolReasonStatus; /* reason code, see 802.11 spec. */
2142 u8 bssid[ATH_MAC_LEN]; /* set if known */
2143 u8 disconnectReason ; /* see WMI_DISCONNECT_REASON */
2144 u8 assocRespLen;
2145 u8 assocInfo[1];
2146} POSTPACK WMI_DISCONNECT_EVENT;
2147
2148/*
2149 * BSS Info Event.
2150 * Mechanism used to inform host of the presence and characteristic of
2151 * wireless networks present. Consists of bss info header followed by
2152 * the beacon or probe-response frame body. The 802.11 header is not included.
2153 */
2154typedef enum {
2155 BEACON_FTYPE = 0x1,
2156 PROBERESP_FTYPE,
2157 ACTION_MGMT_FTYPE,
2158 PROBEREQ_FTYPE,
2159} WMI_BI_FTYPE;
2160
2161enum {
2162 BSS_ELEMID_CHANSWITCH = 0x01,
2163 BSS_ELEMID_ATHEROS = 0x02,
2164};
2165
2166typedef PREPACK struct {
2167 u16 channel;
2168 u8 frameType; /* see WMI_BI_FTYPE */
2169 u8 snr;
2170 s16 rssi;
2171 u8 bssid[ATH_MAC_LEN];
2172 u32 ieMask;
2173} POSTPACK WMI_BSS_INFO_HDR;
2174
2175/*
2176 * BSS INFO HDR version 2.0
2177 * With 6 bytes HTC header and 6 bytes of WMI header
2178 * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management
2179 * header space.
2180 * - Reduce the ieMask to 2 bytes as only two bit flags are used
2181 * - Remove rssi and compute it on the host. rssi = snr - 95
2182 */
2183typedef PREPACK struct {
2184 u16 channel;
2185 u8 frameType; /* see WMI_BI_FTYPE */
2186 u8 snr;
2187 u8 bssid[ATH_MAC_LEN];
2188 u16 ieMask;
2189} POSTPACK WMI_BSS_INFO_HDR2;
2190
2191/*
2192 * Command Error Event
2193 */
2194typedef enum {
2195 INVALID_PARAM = 0x01,
2196 ILLEGAL_STATE = 0x02,
2197 INTERNAL_ERROR = 0x03,
2198} WMI_ERROR_CODE;
2199
2200typedef PREPACK struct {
2201 u16 commandId;
2202 u8 errorCode;
2203} POSTPACK WMI_CMD_ERROR_EVENT;
2204
2205/*
2206 * New Regulatory Domain Event
2207 */
2208typedef PREPACK struct {
2209 u32 regDomain;
2210} POSTPACK WMI_REG_DOMAIN_EVENT;
2211
2212typedef PREPACK struct {
2213 u8 txQueueNumber;
2214 u8 rxQueueNumber;
2215 u8 trafficDirection;
2216 u8 trafficClass;
2217} POSTPACK WMI_PSTREAM_TIMEOUT_EVENT;
2218
2219typedef PREPACK struct {
2220 u8 reserve1;
2221 u8 reserve2;
2222 u8 reserve3;
2223 u8 trafficClass;
2224} POSTPACK WMI_ACM_REJECT_EVENT;
2225
2226/*
2227 * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform
2228 * the host of BSS's it has found that matches the current profile.
2229 * It can be used by the host to cache PMKs and/to initiate pre-authentication
2230 * if the BSS supports it. The first bssid is always the current associated
2231 * BSS.
2232 * The bssid and bssFlags information repeats according to the number
2233 * or APs reported.
2234 */
2235typedef enum {
2236 WMI_DEFAULT_BSS_FLAGS = 0x00,
2237 WMI_PREAUTH_CAPABLE_BSS = 0x01,
2238 WMI_PMKID_VALID_BSS = 0x02,
2239} WMI_BSS_FLAGS;
2240
2241typedef PREPACK struct {
2242 u8 bssid[ATH_MAC_LEN];
2243 u8 bssFlags; /* see WMI_BSS_FLAGS */
2244} POSTPACK WMI_NEIGHBOR_INFO;
2245
2246typedef PREPACK struct {
2247 s8 numberOfAps;
2248 WMI_NEIGHBOR_INFO neighbor[1];
2249} POSTPACK WMI_NEIGHBOR_REPORT_EVENT;
2250
2251/*
2252 * TKIP MIC Error Event
2253 */
2254typedef PREPACK struct {
2255 u8 keyid;
2256 u8 ismcast;
2257} POSTPACK WMI_TKIP_MICERR_EVENT;
2258
2259/*
2260 * WMI_SCAN_COMPLETE_EVENTID - no parameters (old), staus parameter (new)
2261 */
2262typedef PREPACK struct {
2263 s32 status;
2264} POSTPACK WMI_SCAN_COMPLETE_EVENT;
2265
2266#define MAX_OPT_DATA_LEN 1400
2267
2268/*
2269 * WMI_SET_ADHOC_BSSID_CMDID
2270 */
2271typedef PREPACK struct {
2272 u8 bssid[ATH_MAC_LEN];
2273} POSTPACK WMI_SET_ADHOC_BSSID_CMD;
2274
2275/*
2276 * WMI_SET_OPT_MODE_CMDID
2277 */
2278typedef enum {
2279 SPECIAL_OFF,
2280 SPECIAL_ON,
2281} OPT_MODE_TYPE;
2282
2283typedef PREPACK struct {
2284 u8 optMode;
2285} POSTPACK WMI_SET_OPT_MODE_CMD;
2286
2287/*
2288 * WMI_TX_OPT_FRAME_CMDID
2289 */
2290typedef enum {
2291 OPT_PROBE_REQ = 0x01,
2292 OPT_PROBE_RESP = 0x02,
2293 OPT_CPPP_START = 0x03,
2294 OPT_CPPP_STOP = 0x04,
2295} WMI_OPT_FTYPE;
2296
2297typedef PREPACK struct {
2298 u16 optIEDataLen;
2299 u8 frmType;
2300 u8 dstAddr[ATH_MAC_LEN];
2301 u8 bssid[ATH_MAC_LEN];
2302 u8 reserved; /* For alignment */
2303 u8 optIEData[1];
2304} POSTPACK WMI_OPT_TX_FRAME_CMD;
2305
2306/*
2307 * Special frame receive Event.
2308 * Mechanism used to inform host of the receiption of the special frames.
2309 * Consists of special frame info header followed by special frame body.
2310 * The 802.11 header is not included.
2311 */
2312typedef PREPACK struct {
2313 u16 channel;
2314 u8 frameType; /* see WMI_OPT_FTYPE */
2315 s8 snr;
2316 u8 srcAddr[ATH_MAC_LEN];
2317 u8 bssid[ATH_MAC_LEN];
2318} POSTPACK WMI_OPT_RX_INFO_HDR;
2319
2320/*
2321 * Reporting statistics.
2322 */
2323typedef PREPACK struct {
2324 u32 tx_packets;
2325 u32 tx_bytes;
2326 u32 tx_unicast_pkts;
2327 u32 tx_unicast_bytes;
2328 u32 tx_multicast_pkts;
2329 u32 tx_multicast_bytes;
2330 u32 tx_broadcast_pkts;
2331 u32 tx_broadcast_bytes;
2332 u32 tx_rts_success_cnt;
2333 u32 tx_packet_per_ac[4];
2334 u32 tx_errors_per_ac[4];
2335
2336 u32 tx_errors;
2337 u32 tx_failed_cnt;
2338 u32 tx_retry_cnt;
2339 u32 tx_mult_retry_cnt;
2340 u32 tx_rts_fail_cnt;
2341 s32 tx_unicast_rate;
2342}POSTPACK tx_stats_t;
2343
2344typedef PREPACK struct {
2345 u32 rx_packets;
2346 u32 rx_bytes;
2347 u32 rx_unicast_pkts;
2348 u32 rx_unicast_bytes;
2349 u32 rx_multicast_pkts;
2350 u32 rx_multicast_bytes;
2351 u32 rx_broadcast_pkts;
2352 u32 rx_broadcast_bytes;
2353 u32 rx_fragment_pkt;
2354
2355 u32 rx_errors;
2356 u32 rx_crcerr;
2357 u32 rx_key_cache_miss;
2358 u32 rx_decrypt_err;
2359 u32 rx_duplicate_frames;
2360 s32 rx_unicast_rate;
2361}POSTPACK rx_stats_t;
2362
2363typedef PREPACK struct {
2364 u32 tkip_local_mic_failure;
2365 u32 tkip_counter_measures_invoked;
2366 u32 tkip_replays;
2367 u32 tkip_format_errors;
2368 u32 ccmp_format_errors;
2369 u32 ccmp_replays;
2370}POSTPACK tkip_ccmp_stats_t;
2371
2372typedef PREPACK struct {
2373 u32 power_save_failure_cnt;
2374 u16 stop_tx_failure_cnt;
2375 u16 atim_tx_failure_cnt;
2376 u16 atim_rx_failure_cnt;
2377 u16 bcn_rx_failure_cnt;
2378}POSTPACK pm_stats_t;
2379
2380typedef PREPACK struct {
2381 u32 cs_bmiss_cnt;
2382 u32 cs_lowRssi_cnt;
2383 u16 cs_connect_cnt;
2384 u16 cs_disconnect_cnt;
2385 s16 cs_aveBeacon_rssi;
2386 u16 cs_roam_count;
2387 s16 cs_rssi;
2388 u8 cs_snr;
2389 u8 cs_aveBeacon_snr;
2390 u8 cs_lastRoam_msec;
2391} POSTPACK cserv_stats_t;
2392
2393typedef PREPACK struct {
2394 tx_stats_t tx_stats;
2395 rx_stats_t rx_stats;
2396 tkip_ccmp_stats_t tkipCcmpStats;
2397}POSTPACK wlan_net_stats_t;
2398
2399typedef PREPACK struct {
2400 u32 arp_received;
2401 u32 arp_matched;
2402 u32 arp_replied;
2403} POSTPACK arp_stats_t;
2404
2405typedef PREPACK struct {
2406 u32 wow_num_pkts_dropped;
2407 u16 wow_num_events_discarded;
2408 u8 wow_num_host_pkt_wakeups;
2409 u8 wow_num_host_event_wakeups;
2410} POSTPACK wlan_wow_stats_t;
2411
2412typedef PREPACK struct {
2413 u32 lqVal;
2414 s32 noise_floor_calibation;
2415 pm_stats_t pmStats;
2416 wlan_net_stats_t txrxStats;
2417 wlan_wow_stats_t wowStats;
2418 arp_stats_t arpStats;
2419 cserv_stats_t cservStats;
2420} POSTPACK WMI_TARGET_STATS;
2421
2422/*
2423 * WMI_RSSI_THRESHOLD_EVENTID.
2424 * Indicate the RSSI events to host. Events are indicated when we breach a
2425 * thresold value.
2426 */
2427typedef enum{
2428 WMI_RSSI_THRESHOLD1_ABOVE = 0,
2429 WMI_RSSI_THRESHOLD2_ABOVE,
2430 WMI_RSSI_THRESHOLD3_ABOVE,
2431 WMI_RSSI_THRESHOLD4_ABOVE,
2432 WMI_RSSI_THRESHOLD5_ABOVE,
2433 WMI_RSSI_THRESHOLD6_ABOVE,
2434 WMI_RSSI_THRESHOLD1_BELOW,
2435 WMI_RSSI_THRESHOLD2_BELOW,
2436 WMI_RSSI_THRESHOLD3_BELOW,
2437 WMI_RSSI_THRESHOLD4_BELOW,
2438 WMI_RSSI_THRESHOLD5_BELOW,
2439 WMI_RSSI_THRESHOLD6_BELOW
2440}WMI_RSSI_THRESHOLD_VAL;
2441
2442typedef PREPACK struct {
2443 s16 rssi;
2444 u8 range;
2445}POSTPACK WMI_RSSI_THRESHOLD_EVENT;
2446
2447/*
2448 * WMI_ERROR_REPORT_EVENTID
2449 */
2450typedef enum{
2451 WMI_TARGET_PM_ERR_FAIL = 0x00000001,
2452 WMI_TARGET_KEY_NOT_FOUND = 0x00000002,
2453 WMI_TARGET_DECRYPTION_ERR = 0x00000004,
2454 WMI_TARGET_BMISS = 0x00000008,
2455 WMI_PSDISABLE_NODE_JOIN = 0x00000010,
2456 WMI_TARGET_COM_ERR = 0x00000020,
2457 WMI_TARGET_FATAL_ERR = 0x00000040
2458} WMI_TARGET_ERROR_VAL;
2459
2460typedef PREPACK struct {
2461 u32 errorVal;
2462}POSTPACK WMI_TARGET_ERROR_REPORT_EVENT;
2463
2464typedef PREPACK struct {
2465 u8 retrys;
2466}POSTPACK WMI_TX_RETRY_ERR_EVENT;
2467
2468typedef enum{
2469 WMI_SNR_THRESHOLD1_ABOVE = 1,
2470 WMI_SNR_THRESHOLD1_BELOW,
2471 WMI_SNR_THRESHOLD2_ABOVE,
2472 WMI_SNR_THRESHOLD2_BELOW,
2473 WMI_SNR_THRESHOLD3_ABOVE,
2474 WMI_SNR_THRESHOLD3_BELOW,
2475 WMI_SNR_THRESHOLD4_ABOVE,
2476 WMI_SNR_THRESHOLD4_BELOW
2477} WMI_SNR_THRESHOLD_VAL;
2478
2479typedef PREPACK struct {
2480 u8 range; /* WMI_SNR_THRESHOLD_VAL */
2481 u8 snr;
2482}POSTPACK WMI_SNR_THRESHOLD_EVENT;
2483
2484typedef enum{
2485 WMI_LQ_THRESHOLD1_ABOVE = 1,
2486 WMI_LQ_THRESHOLD1_BELOW,
2487 WMI_LQ_THRESHOLD2_ABOVE,
2488 WMI_LQ_THRESHOLD2_BELOW,
2489 WMI_LQ_THRESHOLD3_ABOVE,
2490 WMI_LQ_THRESHOLD3_BELOW,
2491 WMI_LQ_THRESHOLD4_ABOVE,
2492 WMI_LQ_THRESHOLD4_BELOW
2493} WMI_LQ_THRESHOLD_VAL;
2494
2495typedef PREPACK struct {
2496 s32 lq;
2497 u8 range; /* WMI_LQ_THRESHOLD_VAL */
2498}POSTPACK WMI_LQ_THRESHOLD_EVENT;
2499/*
2500 * WMI_REPORT_ROAM_TBL_EVENTID
2501 */
2502#define MAX_ROAM_TBL_CAND 5
2503
2504typedef PREPACK struct {
2505 s32 roam_util;
2506 u8 bssid[ATH_MAC_LEN];
2507 s8 rssi;
2508 s8 rssidt;
2509 s8 last_rssi;
2510 s8 util;
2511 s8 bias;
2512 u8 reserved; /* For alignment */
2513} POSTPACK WMI_BSS_ROAM_INFO;
2514
2515
2516typedef PREPACK struct {
2517 u16 roamMode;
2518 u16 numEntries;
2519 WMI_BSS_ROAM_INFO bssRoamInfo[1];
2520} POSTPACK WMI_TARGET_ROAM_TBL;
2521
2522/*
2523 * WMI_HCI_EVENT_EVENTID
2524 */
2525typedef PREPACK struct {
2526 u16 evt_buf_sz; /* HCI event buffer size */
2527 u8 buf[1]; /* HCI event */
2528} POSTPACK WMI_HCI_EVENT;
2529
2530/*
2531 * WMI_CAC_EVENTID
2532 */
2533typedef enum {
2534 CAC_INDICATION_ADMISSION = 0x00,
2535 CAC_INDICATION_ADMISSION_RESP = 0x01,
2536 CAC_INDICATION_DELETE = 0x02,
2537 CAC_INDICATION_NO_RESP = 0x03,
2538}CAC_INDICATION;
2539
2540#define WMM_TSPEC_IE_LEN 63
2541
2542typedef PREPACK struct {
2543 u8 ac;
2544 u8 cac_indication;
2545 u8 statusCode;
2546 u8 tspecSuggestion[WMM_TSPEC_IE_LEN];
2547}POSTPACK WMI_CAC_EVENT;
2548
2549/*
2550 * WMI_APLIST_EVENTID
2551 */
2552
2553typedef enum {
2554 APLIST_VER1 = 1,
2555} APLIST_VER;
2556
2557typedef PREPACK struct {
2558 u8 bssid[ATH_MAC_LEN];
2559 u16 channel;
2560} POSTPACK WMI_AP_INFO_V1;
2561
2562typedef PREPACK union {
2563 WMI_AP_INFO_V1 apInfoV1;
2564} POSTPACK WMI_AP_INFO;
2565
2566typedef PREPACK struct {
2567 u8 apListVer;
2568 u8 numAP;
2569 WMI_AP_INFO apList[1];
2570} POSTPACK WMI_APLIST_EVENT;
2571
2572/*
2573 * developer commands
2574 */
2575
2576/*
2577 * WMI_SET_BITRATE_CMDID
2578 *
2579 * Get bit rate cmd uses same definition as set bit rate cmd
2580 */
2581typedef enum {
2582 RATE_AUTO = -1,
2583 RATE_1Mb = 0,
2584 RATE_2Mb = 1,
2585 RATE_5_5Mb = 2,
2586 RATE_11Mb = 3,
2587 RATE_6Mb = 4,
2588 RATE_9Mb = 5,
2589 RATE_12Mb = 6,
2590 RATE_18Mb = 7,
2591 RATE_24Mb = 8,
2592 RATE_36Mb = 9,
2593 RATE_48Mb = 10,
2594 RATE_54Mb = 11,
2595 RATE_MCS_0_20 = 12,
2596 RATE_MCS_1_20 = 13,
2597 RATE_MCS_2_20 = 14,
2598 RATE_MCS_3_20 = 15,
2599 RATE_MCS_4_20 = 16,
2600 RATE_MCS_5_20 = 17,
2601 RATE_MCS_6_20 = 18,
2602 RATE_MCS_7_20 = 19,
2603 RATE_MCS_0_40 = 20,
2604 RATE_MCS_1_40 = 21,
2605 RATE_MCS_2_40 = 22,
2606 RATE_MCS_3_40 = 23,
2607 RATE_MCS_4_40 = 24,
2608 RATE_MCS_5_40 = 25,
2609 RATE_MCS_6_40 = 26,
2610 RATE_MCS_7_40 = 27,
2611} WMI_BIT_RATE;
2612
2613typedef PREPACK struct {
2614 s8 rateIndex; /* see WMI_BIT_RATE */
2615 s8 mgmtRateIndex;
2616 s8 ctlRateIndex;
2617} POSTPACK WMI_BIT_RATE_CMD;
2618
2619
2620typedef PREPACK struct {
2621 s8 rateIndex; /* see WMI_BIT_RATE */
2622} POSTPACK WMI_BIT_RATE_REPLY;
2623
2624
2625/*
2626 * WMI_SET_FIXRATES_CMDID
2627 *
2628 * Get fix rates cmd uses same definition as set fix rates cmd
2629 */
2630#define FIX_RATE_1Mb ((u32)0x1)
2631#define FIX_RATE_2Mb ((u32)0x2)
2632#define FIX_RATE_5_5Mb ((u32)0x4)
2633#define FIX_RATE_11Mb ((u32)0x8)
2634#define FIX_RATE_6Mb ((u32)0x10)
2635#define FIX_RATE_9Mb ((u32)0x20)
2636#define FIX_RATE_12Mb ((u32)0x40)
2637#define FIX_RATE_18Mb ((u32)0x80)
2638#define FIX_RATE_24Mb ((u32)0x100)
2639#define FIX_RATE_36Mb ((u32)0x200)
2640#define FIX_RATE_48Mb ((u32)0x400)
2641#define FIX_RATE_54Mb ((u32)0x800)
2642#define FIX_RATE_MCS_0_20 ((u32)0x1000)
2643#define FIX_RATE_MCS_1_20 ((u32)0x2000)
2644#define FIX_RATE_MCS_2_20 ((u32)0x4000)
2645#define FIX_RATE_MCS_3_20 ((u32)0x8000)
2646#define FIX_RATE_MCS_4_20 ((u32)0x10000)
2647#define FIX_RATE_MCS_5_20 ((u32)0x20000)
2648#define FIX_RATE_MCS_6_20 ((u32)0x40000)
2649#define FIX_RATE_MCS_7_20 ((u32)0x80000)
2650#define FIX_RATE_MCS_0_40 ((u32)0x100000)
2651#define FIX_RATE_MCS_1_40 ((u32)0x200000)
2652#define FIX_RATE_MCS_2_40 ((u32)0x400000)
2653#define FIX_RATE_MCS_3_40 ((u32)0x800000)
2654#define FIX_RATE_MCS_4_40 ((u32)0x1000000)
2655#define FIX_RATE_MCS_5_40 ((u32)0x2000000)
2656#define FIX_RATE_MCS_6_40 ((u32)0x4000000)
2657#define FIX_RATE_MCS_7_40 ((u32)0x8000000)
2658
2659typedef PREPACK struct {
2660 u32 fixRateMask; /* see WMI_BIT_RATE */
2661} POSTPACK WMI_FIX_RATES_CMD, WMI_FIX_RATES_REPLY;
2662
2663typedef PREPACK struct {
2664 u8 bEnableMask;
2665 u8 frameType; /*type and subtype*/
2666 u32 frameRateMask; /* see WMI_BIT_RATE */
2667} POSTPACK WMI_FRAME_RATES_CMD, WMI_FRAME_RATES_REPLY;
2668
2669/*
2670 * WMI_SET_RECONNECT_AUTH_MODE_CMDID
2671 *
2672 * Set authentication mode
2673 */
2674typedef enum {
2675 RECONN_DO_AUTH = 0x00,
2676 RECONN_NOT_AUTH = 0x01
2677} WMI_AUTH_MODE;
2678
2679typedef PREPACK struct {
2680 u8 mode;
2681} POSTPACK WMI_SET_AUTH_MODE_CMD;
2682
2683/*
2684 * WMI_SET_REASSOC_MODE_CMDID
2685 *
2686 * Set authentication mode
2687 */
2688typedef enum {
2689 REASSOC_DO_DISASSOC = 0x00,
2690 REASSOC_DONOT_DISASSOC = 0x01
2691} WMI_REASSOC_MODE;
2692
2693typedef PREPACK struct {
2694 u8 mode;
2695}POSTPACK WMI_SET_REASSOC_MODE_CMD;
2696
2697typedef enum {
2698 ROAM_DATA_TIME = 1, /* Get The Roam Time Data */
2699} ROAM_DATA_TYPE;
2700
2701typedef PREPACK struct {
2702 u32 disassoc_time;
2703 u32 no_txrx_time;
2704 u32 assoc_time;
2705 u32 allow_txrx_time;
2706 u8 disassoc_bssid[ATH_MAC_LEN];
2707 s8 disassoc_bss_rssi;
2708 u8 assoc_bssid[ATH_MAC_LEN];
2709 s8 assoc_bss_rssi;
2710} POSTPACK WMI_TARGET_ROAM_TIME;
2711
2712typedef PREPACK struct {
2713 PREPACK union {
2714 WMI_TARGET_ROAM_TIME roamTime;
2715 } POSTPACK u;
2716 u8 roamDataType ;
2717} POSTPACK WMI_TARGET_ROAM_DATA;
2718
2719typedef enum {
2720 WMI_WMM_DISABLED = 0,
2721 WMI_WMM_ENABLED
2722} WMI_WMM_STATUS;
2723
2724typedef PREPACK struct {
2725 u8 status;
2726}POSTPACK WMI_SET_WMM_CMD;
2727
2728typedef PREPACK struct {
2729 u8 status;
2730}POSTPACK WMI_SET_QOS_SUPP_CMD;
2731
2732typedef enum {
2733 WMI_TXOP_DISABLED = 0,
2734 WMI_TXOP_ENABLED
2735} WMI_TXOP_CFG;
2736
2737typedef PREPACK struct {
2738 u8 txopEnable;
2739}POSTPACK WMI_SET_WMM_TXOP_CMD;
2740
2741typedef PREPACK struct {
2742 u8 keepaliveInterval;
2743} POSTPACK WMI_SET_KEEPALIVE_CMD;
2744
2745typedef PREPACK struct {
2746 u32 configured;
2747 u8 keepaliveInterval;
2748} POSTPACK WMI_GET_KEEPALIVE_CMD;
2749
2750/*
2751 * Add Application specified IE to a management frame
2752 */
2753#define WMI_MAX_IE_LEN 255
2754
2755typedef PREPACK struct {
2756 u8 mgmtFrmType; /* one of WMI_MGMT_FRAME_TYPE */
2757 u8 ieLen; /* Length of the IE that should be added to the MGMT frame */
2758 u8 ieInfo[1];
2759} POSTPACK WMI_SET_APPIE_CMD;
2760
2761/*
2762 * Notify the WSC registration status to the target
2763 */
2764#define WSC_REG_ACTIVE 1
2765#define WSC_REG_INACTIVE 0
2766/* Generic Hal Interface for setting hal paramters. */
2767/* Add new Set HAL Param cmdIds here for newer params */
2768typedef enum {
2769 WHAL_SETCABTO_CMDID = 1,
2770}WHAL_CMDID;
2771
2772typedef PREPACK struct {
2773 u8 cabTimeOut;
2774} POSTPACK WHAL_SETCABTO_PARAM;
2775
2776typedef PREPACK struct {
2777 u8 whalCmdId;
2778 u8 data[1];
2779} POSTPACK WHAL_PARAMCMD;
2780
2781
2782#define WOW_MAX_FILTER_LISTS 1 /*4*/
2783#define WOW_MAX_FILTERS_PER_LIST 4
2784#define WOW_PATTERN_SIZE 64
2785#define WOW_MASK_SIZE 64
2786
2787#define MAC_MAX_FILTERS_PER_LIST 4
2788
2789typedef PREPACK struct {
2790 u8 wow_valid_filter;
2791 u8 wow_filter_id;
2792 u8 wow_filter_size;
2793 u8 wow_filter_offset;
2794 u8 wow_filter_mask[WOW_MASK_SIZE];
2795 u8 wow_filter_pattern[WOW_PATTERN_SIZE];
2796} POSTPACK WOW_FILTER;
2797
2798
2799typedef PREPACK struct {
2800 u8 wow_valid_list;
2801 u8 wow_list_id;
2802 u8 wow_num_filters;
2803 u8 wow_total_list_size;
2804 WOW_FILTER list[WOW_MAX_FILTERS_PER_LIST];
2805} POSTPACK WOW_FILTER_LIST;
2806
2807typedef PREPACK struct {
2808 u8 valid_filter;
2809 u8 mac_addr[ATH_MAC_LEN];
2810} POSTPACK MAC_FILTER;
2811
2812
2813typedef PREPACK struct {
2814 u8 total_list_size;
2815 u8 enable;
2816 MAC_FILTER list[MAC_MAX_FILTERS_PER_LIST];
2817} POSTPACK MAC_FILTER_LIST;
2818
2819#define MAX_IP_ADDRS 2
2820typedef PREPACK struct {
2821 u32 ips[MAX_IP_ADDRS]; /* IP in Network Byte Order */
2822} POSTPACK WMI_SET_IP_CMD;
2823
2824typedef PREPACK struct {
2825 u32 awake;
2826 u32 asleep;
2827} POSTPACK WMI_SET_HOST_SLEEP_MODE_CMD;
2828
2829typedef enum {
2830 WOW_FILTER_SSID = 0x1
2831} WMI_WOW_FILTER;
2832
2833typedef PREPACK struct {
2834 u32 enable_wow;
2835 WMI_WOW_FILTER filter;
2836 u16 hostReqDelay;
2837} POSTPACK WMI_SET_WOW_MODE_CMD;
2838
2839typedef PREPACK struct {
2840 u8 filter_list_id;
2841} POSTPACK WMI_GET_WOW_LIST_CMD;
2842
2843/*
2844 * WMI_GET_WOW_LIST_CMD reply
2845 */
2846typedef PREPACK struct {
2847 u8 num_filters; /* number of patterns in reply */
2848 u8 this_filter_num; /* this is filter # x of total num_filters */
2849 u8 wow_mode;
2850 u8 host_mode;
2851 WOW_FILTER wow_filters[1];
2852} POSTPACK WMI_GET_WOW_LIST_REPLY;
2853
2854typedef PREPACK struct {
2855 u8 filter_list_id;
2856 u8 filter_size;
2857 u8 filter_offset;
2858 u8 filter[1];
2859} POSTPACK WMI_ADD_WOW_PATTERN_CMD;
2860
2861typedef PREPACK struct {
2862 u16 filter_list_id;
2863 u16 filter_id;
2864} POSTPACK WMI_DEL_WOW_PATTERN_CMD;
2865
2866typedef PREPACK struct {
2867 u8 macaddr[ATH_MAC_LEN];
2868} POSTPACK WMI_SET_MAC_ADDRESS_CMD;
2869
2870/*
2871 * WMI_SET_AKMP_PARAMS_CMD
2872 */
2873
2874#define WMI_AKMP_MULTI_PMKID_EN 0x000001
2875
2876typedef PREPACK struct {
2877 u32 akmpInfo;
2878} POSTPACK WMI_SET_AKMP_PARAMS_CMD;
2879
2880typedef PREPACK struct {
2881 u8 pmkid[WMI_PMKID_LEN];
2882} POSTPACK WMI_PMKID;
2883
2884/*
2885 * WMI_SET_PMKID_LIST_CMD
2886 */
2887#define WMI_MAX_PMKID_CACHE 8
2888
2889typedef PREPACK struct {
2890 u32 numPMKID;
2891 WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE];
2892} POSTPACK WMI_SET_PMKID_LIST_CMD;
2893
2894/*
2895 * WMI_GET_PMKID_LIST_CMD Reply
2896 * Following the Number of PMKIDs is the list of PMKIDs
2897 */
2898typedef PREPACK struct {
2899 u32 numPMKID;
2900 u8 bssidList[ATH_MAC_LEN][1];
2901 WMI_PMKID pmkidList[1];
2902} POSTPACK WMI_PMKID_LIST_REPLY;
2903
2904typedef PREPACK struct {
2905 u16 oldChannel;
2906 u32 newChannel;
2907} POSTPACK WMI_CHANNEL_CHANGE_EVENT;
2908
2909typedef PREPACK struct {
2910 u32 version;
2911} POSTPACK WMI_WLAN_VERSION_EVENT;
2912
2913
2914/* WMI_ADDBA_REQ_EVENTID */
2915typedef PREPACK struct {
2916 u8 tid;
2917 u8 win_sz;
2918 u16 st_seq_no;
2919 u8 status; /* f/w response for ADDBA Req; OK(0) or failure(!=0) */
2920} POSTPACK WMI_ADDBA_REQ_EVENT;
2921
2922/* WMI_ADDBA_RESP_EVENTID */
2923typedef PREPACK struct {
2924 u8 tid;
2925 u8 status; /* OK(0), failure (!=0) */
2926 u16 amsdu_sz; /* Three values: Not supported(0), 3839, 8k */
2927} POSTPACK WMI_ADDBA_RESP_EVENT;
2928
2929/* WMI_DELBA_EVENTID
2930 * f/w received a DELBA for peer and processed it.
2931 * Host is notified of this
2932 */
2933typedef PREPACK struct {
2934 u8 tid;
2935 u8 is_peer_initiator;
2936 u16 reason_code;
2937} POSTPACK WMI_DELBA_EVENT;
2938
2939
2940#ifdef WAPI_ENABLE
2941#define WAPI_REKEY_UCAST 1
2942#define WAPI_REKEY_MCAST 2
2943typedef PREPACK struct {
2944 u8 type;
2945 u8 macAddr[ATH_MAC_LEN];
2946} POSTPACK WMI_WAPIREKEY_EVENT;
2947#endif
2948
2949
2950/* WMI_ALLOW_AGGR_CMDID
2951 * Configures tid's to allow ADDBA negotiations
2952 * on each tid, in each direction
2953 */
2954typedef PREPACK struct {
2955 u16 tx_allow_aggr; /* 16-bit mask to allow uplink ADDBA negotiation - bit position indicates tid*/
2956 u16 rx_allow_aggr; /* 16-bit mask to allow donwlink ADDBA negotiation - bit position indicates tid*/
2957} POSTPACK WMI_ALLOW_AGGR_CMD;
2958
2959/* WMI_ADDBA_REQ_CMDID
2960 * f/w starts performing ADDBA negotiations with peer
2961 * on the given tid
2962 */
2963typedef PREPACK struct {
2964 u8 tid;
2965} POSTPACK WMI_ADDBA_REQ_CMD;
2966
2967/* WMI_DELBA_REQ_CMDID
2968 * f/w would teardown BA with peer.
2969 * is_send_initiator indicates if it's or tx or rx side
2970 */
2971typedef PREPACK struct {
2972 u8 tid;
2973 u8 is_sender_initiator;
2974
2975} POSTPACK WMI_DELBA_REQ_CMD;
2976
2977#define PEER_NODE_JOIN_EVENT 0x00
2978#define PEER_NODE_LEAVE_EVENT 0x01
2979#define PEER_FIRST_NODE_JOIN_EVENT 0x10
2980#define PEER_LAST_NODE_LEAVE_EVENT 0x11
2981typedef PREPACK struct {
2982 u8 eventCode;
2983 u8 peerMacAddr[ATH_MAC_LEN];
2984} POSTPACK WMI_PEER_NODE_EVENT;
2985
2986#define IEEE80211_FRAME_TYPE_MGT 0x00
2987#define IEEE80211_FRAME_TYPE_CTL 0x04
2988
2989/*
2990 * Transmit complete event data structure(s)
2991 */
2992
2993
2994typedef PREPACK struct {
2995#define TX_COMPLETE_STATUS_SUCCESS 0
2996#define TX_COMPLETE_STATUS_RETRIES 1
2997#define TX_COMPLETE_STATUS_NOLINK 2
2998#define TX_COMPLETE_STATUS_TIMEOUT 3
2999#define TX_COMPLETE_STATUS_OTHER 4
3000
3001 u8 status; /* one of TX_COMPLETE_STATUS_... */
3002 u8 pktID; /* packet ID to identify parent packet */
3003 u8 rateIdx; /* rate index on successful transmission */
3004 u8 ackFailures; /* number of ACK failures in tx attempt */
3005#if 0 /* optional params currently omitted. */
3006 u32 queueDelay; // usec delay measured Tx Start time - host delivery time
3007 u32 mediaDelay; // usec delay measured ACK rx time - host delivery time
3008#endif
3009} POSTPACK TX_COMPLETE_MSG_V1; /* version 1 of tx complete msg */
3010
3011typedef PREPACK struct {
3012 u8 numMessages; /* number of tx comp msgs following this struct */
3013 u8 msgLen; /* length in bytes for each individual msg following this struct */
3014 u8 msgType; /* version of tx complete msg data following this struct */
3015 u8 reserved; /* individual messages follow this header */
3016} POSTPACK WMI_TX_COMPLETE_EVENT;
3017
3018#define WMI_TXCOMPLETE_VERSION_1 (0x01)
3019
3020
3021/*
3022 * ------- AP Mode definitions --------------
3023 */
3024
3025/*
3026 * !!! Warning !!!
3027 * -Changing the following values needs compilation of both driver and firmware
3028 */
3029#ifdef AR6002_REV2
3030#define AP_MAX_NUM_STA 4
3031#else
3032#define AP_MAX_NUM_STA 8
3033#endif
3034#define AP_ACL_SIZE 10
3035#define IEEE80211_MAX_IE 256
3036#define MCAST_AID 0xFF /* Spl. AID used to set DTIM flag in the beacons */
3037#define DEF_AP_COUNTRY_CODE "US "
3038#define DEF_AP_WMODE_G WMI_11G_MODE
3039#define DEF_AP_WMODE_AG WMI_11AG_MODE
3040#define DEF_AP_DTIM 5
3041#define DEF_BEACON_INTERVAL 100
3042
3043/* AP mode disconnect reasons */
3044#define AP_DISCONNECT_STA_LEFT 101
3045#define AP_DISCONNECT_FROM_HOST 102
3046#define AP_DISCONNECT_COMM_TIMEOUT 103
3047
3048/*
3049 * Used with WMI_AP_HIDDEN_SSID_CMDID
3050 */
3051#define HIDDEN_SSID_FALSE 0
3052#define HIDDEN_SSID_TRUE 1
3053typedef PREPACK struct {
3054 u8 hidden_ssid;
3055} POSTPACK WMI_AP_HIDDEN_SSID_CMD;
3056
3057/*
3058 * Used with WMI_AP_ACL_POLICY_CMDID
3059 */
3060#define AP_ACL_DISABLE 0x00
3061#define AP_ACL_ALLOW_MAC 0x01
3062#define AP_ACL_DENY_MAC 0x02
3063#define AP_ACL_RETAIN_LIST_MASK 0x80
3064typedef PREPACK struct {
3065 u8 policy;
3066} POSTPACK WMI_AP_ACL_POLICY_CMD;
3067
3068/*
3069 * Used with WMI_AP_ACL_MAC_LIST_CMDID
3070 */
3071#define ADD_MAC_ADDR 1
3072#define DEL_MAC_ADDR 2
3073typedef PREPACK struct {
3074 u8 action;
3075 u8 index;
3076 u8 mac[ATH_MAC_LEN];
3077 u8 wildcard;
3078} POSTPACK WMI_AP_ACL_MAC_CMD;
3079
3080typedef PREPACK struct {
3081 u16 index;
3082 u8 acl_mac[AP_ACL_SIZE][ATH_MAC_LEN];
3083 u8 wildcard[AP_ACL_SIZE];
3084 u8 policy;
3085} POSTPACK WMI_AP_ACL;
3086
3087/*
3088 * Used with WMI_AP_SET_NUM_STA_CMDID
3089 */
3090typedef PREPACK struct {
3091 u8 num_sta;
3092} POSTPACK WMI_AP_SET_NUM_STA_CMD;
3093
3094/*
3095 * Used with WMI_AP_SET_MLME_CMDID
3096 */
3097typedef PREPACK struct {
3098 u8 mac[ATH_MAC_LEN];
3099 u16 reason; /* 802.11 reason code */
3100 u8 cmd; /* operation to perform */
3101#define WMI_AP_MLME_ASSOC 1 /* associate station */
3102#define WMI_AP_DISASSOC 2 /* disassociate station */
3103#define WMI_AP_DEAUTH 3 /* deauthenticate station */
3104#define WMI_AP_MLME_AUTHORIZE 4 /* authorize station */
3105#define WMI_AP_MLME_UNAUTHORIZE 5 /* unauthorize station */
3106} POSTPACK WMI_AP_SET_MLME_CMD;
3107
3108typedef PREPACK struct {
3109 u32 period;
3110} POSTPACK WMI_AP_CONN_INACT_CMD;
3111
3112typedef PREPACK struct {
3113 u32 period_min;
3114 u32 dwell_ms;
3115} POSTPACK WMI_AP_PROT_SCAN_TIME_CMD;
3116
3117typedef PREPACK struct {
3118 u32 flag;
3119 u16 aid;
3120} POSTPACK WMI_AP_SET_PVB_CMD;
3121
3122#define WMI_DISABLE_REGULATORY_CODE "FF"
3123
3124typedef PREPACK struct {
3125 u8 countryCode[3];
3126} POSTPACK WMI_AP_SET_COUNTRY_CMD;
3127
3128typedef PREPACK struct {
3129 u8 dtim;
3130} POSTPACK WMI_AP_SET_DTIM_CMD;
3131
3132typedef PREPACK struct {
3133 u8 band; /* specifies which band to apply these values */
3134 u8 enable; /* allows 11n to be disabled on a per band basis */
3135 u8 chan_width_40M_supported;
3136 u8 short_GI_20MHz;
3137 u8 short_GI_40MHz;
3138 u8 intolerance_40MHz;
3139 u8 max_ampdu_len_exp;
3140} POSTPACK WMI_SET_HT_CAP_CMD;
3141
3142typedef PREPACK struct {
3143 u8 sta_chan_width;
3144} POSTPACK WMI_SET_HT_OP_CMD;
3145
3146typedef PREPACK struct {
3147 u32 rateMasks[8];
3148} POSTPACK WMI_SET_TX_SELECT_RATES_CMD;
3149
3150typedef PREPACK struct {
3151 u32 sgiMask;
3152 u8 sgiPERThreshold;
3153} POSTPACK WMI_SET_TX_SGI_PARAM_CMD;
3154
3155#define DEFAULT_SGI_MASK 0x08080000
3156#define DEFAULT_SGI_PER 10
3157
3158typedef PREPACK struct {
3159 u32 rateField; /* 1 bit per rate corresponding to index */
3160 u8 id;
3161 u8 shortTrys;
3162 u8 longTrys;
3163 u8 reserved; /* padding */
3164} POSTPACK WMI_SET_RATE_POLICY_CMD;
3165
3166typedef PREPACK struct {
3167 u8 metaVersion; /* version of meta data for rx packets <0 = default> (0-7 = valid) */
3168 u8 dot11Hdr; /* 1 == leave .11 header intact , 0 == replace .11 header with .3 <default> */
3169 u8 defragOnHost; /* 1 == defragmentation is performed by host, 0 == performed by target <default> */
3170 u8 reserved[1]; /* alignment */
3171} POSTPACK WMI_RX_FRAME_FORMAT_CMD;
3172
3173
3174typedef PREPACK struct {
3175 u8 enable; /* 1 == device operates in thin mode , 0 == normal mode <default> */
3176 u8 reserved[3];
3177} POSTPACK WMI_SET_THIN_MODE_CMD;
3178
3179/* AP mode events */
3180/* WMI_PS_POLL_EVENT */
3181typedef PREPACK struct {
3182 u16 aid;
3183} POSTPACK WMI_PSPOLL_EVENT;
3184
3185typedef PREPACK struct {
3186 u32 tx_bytes;
3187 u32 tx_pkts;
3188 u32 tx_error;
3189 u32 tx_discard;
3190 u32 rx_bytes;
3191 u32 rx_pkts;
3192 u32 rx_error;
3193 u32 rx_discard;
3194 u32 aid;
3195} POSTPACK WMI_PER_STA_STAT;
3196
3197#define AP_GET_STATS 0
3198#define AP_CLEAR_STATS 1
3199
3200typedef PREPACK struct {
3201 u32 action;
3202 WMI_PER_STA_STAT sta[AP_MAX_NUM_STA+1];
3203} POSTPACK WMI_AP_MODE_STAT;
3204#define WMI_AP_MODE_STAT_SIZE(numSta) (sizeof(u32) + ((numSta + 1) * sizeof(WMI_PER_STA_STAT)))
3205
3206#define AP_11BG_RATESET1 1
3207#define AP_11BG_RATESET2 2
3208#define DEF_AP_11BG_RATESET AP_11BG_RATESET1
3209typedef PREPACK struct {
3210 u8 rateset;
3211} POSTPACK WMI_AP_SET_11BG_RATESET_CMD;
3212/*
3213 * End of AP mode definitions
3214 */
3215
3216#ifdef __cplusplus
3217}
3218#endif
3219
3220#endif /* _WMI_H_ */
diff --git a/drivers/staging/ath6kl/include/common/wmix.h b/drivers/staging/ath6kl/include/common/wmix.h
new file mode 100644
index 00000000000..9435eab1b7f
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/wmix.h
@@ -0,0 +1,271 @@
1//------------------------------------------------------------------------------
2// <copyright file="wmix.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24/*
25 * This file contains extensions of the WMI protocol specified in the
26 * Wireless Module Interface (WMI). It includes definitions of all
27 * extended commands and events. Extensions include useful commands
28 * that are not directly related to wireless activities. They may
29 * be hardware-specific, and they might not be supported on all
30 * implementations.
31 *
32 * Extended WMIX commands are encapsulated in a WMI message with
33 * cmd=WMI_EXTENSION_CMD.
34 */
35
36#ifndef _WMIX_H_
37#define _WMIX_H_
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43#include "dbglog.h"
44
45/*
46 * Extended WMI commands are those that are needed during wireless
47 * operation, but which are not really wireless commands. This allows,
48 * for instance, platform-specific commands. Extended WMI commands are
49 * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID.
50 * Extended WMI events are similarly embedded in a WMI event message with
51 * WMI_EVENT_ID=WMI_EXTENSION_EVENTID.
52 */
53typedef PREPACK struct {
54 u32 commandId;
55} POSTPACK WMIX_CMD_HDR;
56
57typedef enum {
58 WMIX_DSETOPEN_REPLY_CMDID = 0x2001,
59 WMIX_DSETDATA_REPLY_CMDID,
60 WMIX_GPIO_OUTPUT_SET_CMDID,
61 WMIX_GPIO_INPUT_GET_CMDID,
62 WMIX_GPIO_REGISTER_SET_CMDID,
63 WMIX_GPIO_REGISTER_GET_CMDID,
64 WMIX_GPIO_INTR_ACK_CMDID,
65 WMIX_HB_CHALLENGE_RESP_CMDID,
66 WMIX_DBGLOG_CFG_MODULE_CMDID,
67 WMIX_PROF_CFG_CMDID, /* 0x200a */
68 WMIX_PROF_ADDR_SET_CMDID,
69 WMIX_PROF_START_CMDID,
70 WMIX_PROF_STOP_CMDID,
71 WMIX_PROF_COUNT_GET_CMDID,
72} WMIX_COMMAND_ID;
73
74typedef enum {
75 WMIX_DSETOPENREQ_EVENTID = 0x3001,
76 WMIX_DSETCLOSE_EVENTID,
77 WMIX_DSETDATAREQ_EVENTID,
78 WMIX_GPIO_INTR_EVENTID,
79 WMIX_GPIO_DATA_EVENTID,
80 WMIX_GPIO_ACK_EVENTID,
81 WMIX_HB_CHALLENGE_RESP_EVENTID,
82 WMIX_DBGLOG_EVENTID,
83 WMIX_PROF_COUNT_EVENTID,
84} WMIX_EVENT_ID;
85
86/*
87 * =============DataSet support=================
88 */
89
90/*
91 * WMIX_DSETOPENREQ_EVENTID
92 * DataSet Open Request Event
93 */
94typedef PREPACK struct {
95 u32 dset_id;
96 u32 targ_dset_handle; /* echo'ed, not used by Host, */
97 u32 targ_reply_fn; /* echo'ed, not used by Host, */
98 u32 targ_reply_arg; /* echo'ed, not used by Host, */
99} POSTPACK WMIX_DSETOPENREQ_EVENT;
100
101/*
102 * WMIX_DSETCLOSE_EVENTID
103 * DataSet Close Event
104 */
105typedef PREPACK struct {
106 u32 access_cookie;
107} POSTPACK WMIX_DSETCLOSE_EVENT;
108
109/*
110 * WMIX_DSETDATAREQ_EVENTID
111 * DataSet Data Request Event
112 */
113typedef PREPACK struct {
114 u32 access_cookie;
115 u32 offset;
116 u32 length;
117 u32 targ_buf; /* echo'ed, not used by Host, */
118 u32 targ_reply_fn; /* echo'ed, not used by Host, */
119 u32 targ_reply_arg; /* echo'ed, not used by Host, */
120} POSTPACK WMIX_DSETDATAREQ_EVENT;
121
122typedef PREPACK struct {
123 u32 status;
124 u32 targ_dset_handle;
125 u32 targ_reply_fn;
126 u32 targ_reply_arg;
127 u32 access_cookie;
128 u32 size;
129 u32 version;
130} POSTPACK WMIX_DSETOPEN_REPLY_CMD;
131
132typedef PREPACK struct {
133 u32 status;
134 u32 targ_buf;
135 u32 targ_reply_fn;
136 u32 targ_reply_arg;
137 u32 length;
138 u8 buf[1];
139} POSTPACK WMIX_DSETDATA_REPLY_CMD;
140
141
142/*
143 * =============GPIO support=================
144 * All masks are 18-bit masks with bit N operating on GPIO pin N.
145 */
146
147
148/*
149 * Set GPIO pin output state.
150 * In order for output to be driven, a pin must be enabled for output.
151 * This can be done during initialization through the GPIO Configuration
152 * DataSet, or during operation with the enable_mask.
153 *
154 * If a request is made to simultaneously set/clear or set/disable or
155 * clear/disable or disable/enable, results are undefined.
156 */
157typedef PREPACK struct {
158 u32 set_mask; /* pins to set */
159 u32 clear_mask; /* pins to clear */
160 u32 enable_mask; /* pins to enable for output */
161 u32 disable_mask; /* pins to disable/tristate */
162} POSTPACK WMIX_GPIO_OUTPUT_SET_CMD;
163
164/*
165 * Set a GPIO register. For debug/exceptional cases.
166 * Values for gpioreg_id are GPIO_REGISTER_IDs, defined in a
167 * platform-dependent header.
168 */
169typedef PREPACK struct {
170 u32 gpioreg_id; /* GPIO register ID */
171 u32 value; /* value to write */
172} POSTPACK WMIX_GPIO_REGISTER_SET_CMD;
173
174/* Get a GPIO register. For debug/exceptional cases. */
175typedef PREPACK struct {
176 u32 gpioreg_id; /* GPIO register to read */
177} POSTPACK WMIX_GPIO_REGISTER_GET_CMD;
178
179/*
180 * Host acknowledges and re-arms GPIO interrupts. A single
181 * message should be used to acknowledge all interrupts that
182 * were delivered in an earlier WMIX_GPIO_INTR_EVENT message.
183 */
184typedef PREPACK struct {
185 u32 ack_mask; /* interrupts to acknowledge */
186} POSTPACK WMIX_GPIO_INTR_ACK_CMD;
187
188/*
189 * Target informs Host of GPIO interrupts that have occurred since the
190 * last WMIX_GIPO_INTR_ACK_CMD was received. Additional information --
191 * the current GPIO input values is provided -- in order to support
192 * use of a GPIO interrupt as a Data Valid signal for other GPIO pins.
193 */
194typedef PREPACK struct {
195 u32 intr_mask; /* pending GPIO interrupts */
196 u32 input_values; /* recent GPIO input values */
197} POSTPACK WMIX_GPIO_INTR_EVENT;
198
199/*
200 * Target responds to Host's earlier WMIX_GPIO_INPUT_GET_CMDID request
201 * using a GPIO_DATA_EVENT with
202 * value set to the mask of GPIO pin inputs and
203 * reg_id set to GPIO_ID_NONE
204 *
205 *
206 * Target responds to Hosts's earlier WMIX_GPIO_REGISTER_GET_CMDID request
207 * using a GPIO_DATA_EVENT with
208 * value set to the value of the requested register and
209 * reg_id identifying the register (reflects the original request)
210 * NB: reg_id supports the future possibility of unsolicited
211 * WMIX_GPIO_DATA_EVENTs (for polling GPIO input), and it may
212 * simplify Host GPIO support.
213 */
214typedef PREPACK struct {
215 u32 value;
216 u32 reg_id;
217} POSTPACK WMIX_GPIO_DATA_EVENT;
218
219/*
220 * =============Error Detection support=================
221 */
222
223/*
224 * WMIX_HB_CHALLENGE_RESP_CMDID
225 * Heartbeat Challenge Response command
226 */
227typedef PREPACK struct {
228 u32 cookie;
229 u32 source;
230} POSTPACK WMIX_HB_CHALLENGE_RESP_CMD;
231
232/*
233 * WMIX_HB_CHALLENGE_RESP_EVENTID
234 * Heartbeat Challenge Response Event
235 */
236#define WMIX_HB_CHALLENGE_RESP_EVENT WMIX_HB_CHALLENGE_RESP_CMD
237
238typedef PREPACK struct {
239 struct dbglog_config_s config;
240} POSTPACK WMIX_DBGLOG_CFG_MODULE_CMD;
241
242/*
243 * =============Target Profiling support=================
244 */
245
246typedef PREPACK struct {
247 u32 period; /* Time (in 30.5us ticks) between samples */
248 u32 nbins;
249} POSTPACK WMIX_PROF_CFG_CMD;
250
251typedef PREPACK struct {
252 u32 addr;
253} POSTPACK WMIX_PROF_ADDR_SET_CMD;
254
255/*
256 * Target responds to Hosts's earlier WMIX_PROF_COUNT_GET_CMDID request
257 * using a WMIX_PROF_COUNT_EVENT with
258 * addr set to the next address
259 * count set to the corresponding count
260 */
261typedef PREPACK struct {
262 u32 addr;
263 u32 count;
264} POSTPACK WMIX_PROF_COUNT_EVENT;
265
266
267#ifdef __cplusplus
268}
269#endif
270
271#endif /* _WMIX_H_ */
diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h
new file mode 100644
index 00000000000..34db29958bc
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common_drv.h
@@ -0,0 +1,104 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22#ifndef COMMON_DRV_H_
23#define COMMON_DRV_H_
24
25#include "hif.h"
26#include "htc_packet.h"
27#include "htc_api.h"
28
29/* structure that is the state information for the default credit distribution callback
30 * drivers should instantiate (zero-init as well) this structure in their driver instance
31 * and pass it as a context to the HTC credit distribution functions */
32struct common_credit_state_info {
33 int TotalAvailableCredits; /* total credits in the system at startup */
34 int CurrentFreeCredits; /* credits available in the pool that have not been
35 given out to endpoints */
36 struct htc_endpoint_credit_dist *pLowestPriEpDist; /* pointer to the lowest priority endpoint dist struct */
37};
38
39struct hci_transport_callbacks {
40 s32 (*setupTransport)(void *ar);
41 void (*cleanupTransport)(void *ar);
42};
43
44struct hci_transport_misc_handles {
45 void *netDevice;
46 void *hifDevice;
47 void *htcHandle;
48};
49
50/* HTC TX packet tagging definitions */
51#define AR6K_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED
52#define AR6K_DATA_PKT_TAG (AR6K_CONTROL_PKT_TAG + 1)
53
54#define AR6002_VERSION_REV1 0x20000086
55#define AR6002_VERSION_REV2 0x20000188
56#define AR6003_VERSION_REV1 0x300002ba
57#define AR6003_VERSION_REV2 0x30000384
58
59#define AR6002_CUST_DATA_SIZE 112
60#define AR6003_CUST_DATA_SIZE 16
61
62#ifdef __cplusplus
63extern "C" {
64#endif
65
66/* OS-independent APIs */
67int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo);
68
69int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
70
71int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
72
73int ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address, u8 *data, u32 length);
74
75int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset);
76
77void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType);
78
79int ar6000_set_htc_params(struct hif_device *hifDevice,
80 u32 TargetType,
81 u32 MboxIsrYieldValue,
82 u8 HtcControlBuffers);
83
84int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice,
85 u32 TargetType,
86 u32 Flags);
87
88void ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType);
89
90u8 *ar6000_get_cust_data_buffer(u32 TargetType);
91
92int ar6000_setBTState(void *context, u8 *pInBuf, u32 InBufSize);
93
94int ar6000_setDevicePowerState(void *context, u8 *pInBuf, u32 InBufSize);
95
96int ar6000_setWowMode(void *context, u8 *pInBuf, u32 InBufSize);
97
98int ar6000_setHostMode(void *context, u8 *pInBuf, u32 InBufSize);
99
100#ifdef __cplusplus
101}
102#endif
103
104#endif /*COMMON_DRV_H_*/
diff --git a/drivers/staging/ath6kl/include/dbglog_api.h b/drivers/staging/ath6kl/include/dbglog_api.h
new file mode 100644
index 00000000000..a53aed316e3
--- /dev/null
+++ b/drivers/staging/ath6kl/include/dbglog_api.h
@@ -0,0 +1,52 @@
1//------------------------------------------------------------------------------
2// <copyright file="dbglog_api.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains host side debug primitives.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _DBGLOG_API_H_
26#define _DBGLOG_API_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#include "dbglog.h"
33
34#define DBGLOG_HOST_LOG_BUFFER_SIZE DBGLOG_LOG_BUFFER_SIZE
35
36#define DBGLOG_GET_DBGID(arg) \
37 ((arg & DBGLOG_DBGID_MASK) >> DBGLOG_DBGID_OFFSET)
38
39#define DBGLOG_GET_MODULEID(arg) \
40 ((arg & DBGLOG_MODULEID_MASK) >> DBGLOG_MODULEID_OFFSET)
41
42#define DBGLOG_GET_NUMARGS(arg) \
43 ((arg & DBGLOG_NUM_ARGS_MASK) >> DBGLOG_NUM_ARGS_OFFSET)
44
45#define DBGLOG_GET_TIMESTAMP(arg) \
46 ((arg & DBGLOG_TIMESTAMP_MASK) >> DBGLOG_TIMESTAMP_OFFSET)
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif /* _DBGLOG_API_H_ */
diff --git a/drivers/staging/ath6kl/include/dl_list.h b/drivers/staging/ath6kl/include/dl_list.h
new file mode 100644
index 00000000000..13b1e6956c2
--- /dev/null
+++ b/drivers/staging/ath6kl/include/dl_list.h
@@ -0,0 +1,153 @@
1//------------------------------------------------------------------------------
2// <copyright file="dl_list.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Double-link list definitions (adapted from Atheros SDIO stack)
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef __DL_LIST_H___
26#define __DL_LIST_H___
27
28#include "a_osapi.h"
29
30#define A_CONTAINING_STRUCT(address, struct_type, field_name)\
31 ((struct_type *)((unsigned long)(address) - (unsigned long)(&((struct_type *)0)->field_name)))
32
33/* list functions */
34/* pointers for the list */
35struct dl_list {
36 struct dl_list *pPrev;
37 struct dl_list *pNext;
38};
39/*
40 * DL_LIST_INIT , initialize doubly linked list
41*/
42#define DL_LIST_INIT(pList)\
43 {(pList)->pPrev = pList; (pList)->pNext = pList;}
44
45/* faster macro to init list and add a single item */
46#define DL_LIST_INIT_AND_ADD(pList,pItem) \
47{ (pList)->pPrev = (pItem); \
48 (pList)->pNext = (pItem); \
49 (pItem)->pNext = (pList); \
50 (pItem)->pPrev = (pList); \
51}
52
53#define DL_LIST_IS_EMPTY(pList) (((pList)->pPrev == (pList)) && ((pList)->pNext == (pList)))
54#define DL_LIST_GET_ITEM_AT_HEAD(pList) (pList)->pNext
55#define DL_LIST_GET_ITEM_AT_TAIL(pList) (pList)->pPrev
56/*
57 * ITERATE_OVER_LIST pStart is the list, pTemp is a temp list member
58 * NOT: do not use this function if the items in the list are deleted inside the
59 * iteration loop
60*/
61#define ITERATE_OVER_LIST(pStart, pTemp) \
62 for((pTemp) =(pStart)->pNext; pTemp != (pStart); (pTemp) = (pTemp)->pNext)
63
64
65/* safe iterate macro that allows the item to be removed from the list
66 * the iteration continues to the next item in the list
67 */
68#define ITERATE_OVER_LIST_ALLOW_REMOVE(pStart,pItem,st,offset) \
69{ \
70 struct dl_list * pTemp; \
71 pTemp = (pStart)->pNext; \
72 while (pTemp != (pStart)) { \
73 (pItem) = A_CONTAINING_STRUCT(pTemp,st,offset); \
74 pTemp = pTemp->pNext; \
75
76#define ITERATE_END }}
77
78/*
79 * DL_ListInsertTail - insert pAdd to the end of the list
80*/
81static INLINE struct dl_list *DL_ListInsertTail(struct dl_list *pList, struct dl_list *pAdd) {
82 /* insert at tail */
83 pAdd->pPrev = pList->pPrev;
84 pAdd->pNext = pList;
85 pList->pPrev->pNext = pAdd;
86 pList->pPrev = pAdd;
87 return pAdd;
88}
89
90/*
91 * DL_ListInsertHead - insert pAdd into the head of the list
92*/
93static INLINE struct dl_list * DL_ListInsertHead(struct dl_list * pList, struct dl_list * pAdd) {
94 /* insert at head */
95 pAdd->pPrev = pList;
96 pAdd->pNext = pList->pNext;
97 pList->pNext->pPrev = pAdd;
98 pList->pNext = pAdd;
99 return pAdd;
100}
101
102#define DL_ListAdd(pList,pItem) DL_ListInsertHead((pList),(pItem))
103/*
104 * DL_ListRemove - remove pDel from list
105*/
106static INLINE struct dl_list * DL_ListRemove(struct dl_list * pDel) {
107 pDel->pNext->pPrev = pDel->pPrev;
108 pDel->pPrev->pNext = pDel->pNext;
109 /* point back to itself just to be safe, incase remove is called again */
110 pDel->pNext = pDel;
111 pDel->pPrev = pDel;
112 return pDel;
113}
114
115/*
116 * DL_ListRemoveItemFromHead - get a list item from the head
117*/
118static INLINE struct dl_list * DL_ListRemoveItemFromHead(struct dl_list * pList) {
119 struct dl_list * pItem = NULL;
120 if (pList->pNext != pList) {
121 pItem = pList->pNext;
122 /* remove the first item from head */
123 DL_ListRemove(pItem);
124 }
125 return pItem;
126}
127
128static INLINE struct dl_list * DL_ListRemoveItemFromTail(struct dl_list * pList) {
129 struct dl_list * pItem = NULL;
130 if (pList->pPrev != pList) {
131 pItem = pList->pPrev;
132 /* remove the item from tail */
133 DL_ListRemove(pItem);
134 }
135 return pItem;
136}
137
138/* transfer src list items to the tail of the destination list */
139static INLINE void DL_ListTransferItemsToTail(struct dl_list * pDest, struct dl_list * pSrc) {
140 /* only concatenate if src is not empty */
141 if (!DL_LIST_IS_EMPTY(pSrc)) {
142 /* cut out circular list in src and re-attach to end of dest */
143 pSrc->pPrev->pNext = pDest;
144 pSrc->pNext->pPrev = pDest->pPrev;
145 pDest->pPrev->pNext = pSrc->pNext;
146 pDest->pPrev = pSrc->pPrev;
147 /* terminate src list, it is now empty */
148 pSrc->pPrev = pSrc;
149 pSrc->pNext = pSrc;
150 }
151}
152
153#endif /* __DL_LIST_H___ */
diff --git a/drivers/staging/ath6kl/include/dset_api.h b/drivers/staging/ath6kl/include/dset_api.h
new file mode 100644
index 00000000000..fe901ba40ec
--- /dev/null
+++ b/drivers/staging/ath6kl/include/dset_api.h
@@ -0,0 +1,65 @@
1//------------------------------------------------------------------------------
2// <copyright file="dset_api.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Host-side DataSet API.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _DSET_API_H_
26#define _DSET_API_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/*
33 * Host-side DataSet support is optional, and is not
34 * currently required for correct operation. To disable
35 * Host-side DataSet support, set this to 0.
36 */
37#ifndef CONFIG_HOST_DSET_SUPPORT
38#define CONFIG_HOST_DSET_SUPPORT 1
39#endif
40
41/* Called to send a DataSet Open Reply back to the Target. */
42int wmi_dset_open_reply(struct wmi_t *wmip,
43 u32 status,
44 u32 access_cookie,
45 u32 size,
46 u32 version,
47 u32 targ_handle,
48 u32 targ_reply_fn,
49 u32 targ_reply_arg);
50
51/* Called to send a DataSet Data Reply back to the Target. */
52int wmi_dset_data_reply(struct wmi_t *wmip,
53 u32 status,
54 u8 *host_buf,
55 u32 length,
56 u32 targ_buf,
57 u32 targ_reply_fn,
58 u32 targ_reply_arg);
59
60#ifdef __cplusplus
61}
62#endif /* __cplusplus */
63
64
65#endif /* _DSET_API_H_ */
diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h
new file mode 100644
index 00000000000..5e903fad23f
--- /dev/null
+++ b/drivers/staging/ath6kl/include/hci_transport_api.h
@@ -0,0 +1,259 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22#ifndef _HCI_TRANSPORT_API_H_
23#define _HCI_TRANSPORT_API_H_
24
25 /* Bluetooth HCI packets are stored in HTC packet containers */
26#include "htc_packet.h"
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32typedef void *HCI_TRANSPORT_HANDLE;
33
34typedef HTC_ENDPOINT_ID HCI_TRANSPORT_PACKET_TYPE;
35
36 /* we map each HCI packet class to a static Endpoint ID */
37#define HCI_COMMAND_TYPE ENDPOINT_1
38#define HCI_EVENT_TYPE ENDPOINT_2
39#define HCI_ACL_TYPE ENDPOINT_3
40#define HCI_PACKET_INVALID ENDPOINT_MAX
41
42#define HCI_GET_PACKET_TYPE(pP) (pP)->Endpoint
43#define HCI_SET_PACKET_TYPE(pP,s) (pP)->Endpoint = (s)
44
45/* callback when an HCI packet was completely sent */
46typedef void (*HCI_TRANSPORT_SEND_PKT_COMPLETE)(void *, struct htc_packet *);
47/* callback when an HCI packet is received */
48typedef void (*HCI_TRANSPORT_RECV_PKT)(void *, struct htc_packet *);
49/* Optional receive buffer re-fill callback,
50 * On some OSes (like Linux) packets are allocated from a global pool and indicated up
51 * to the network stack. The driver never gets the packets back from the OS. For these OSes
52 * a refill callback can be used to allocate and re-queue buffers into HTC.
53 * A refill callback is used for the reception of ACL and EVENT packets. The caller must
54 * set the watermark trigger point to cause a refill.
55 */
56typedef void (*HCI_TRANSPORT_RECV_REFILL)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable);
57/* Optional receive packet refill
58 * On some systems packet buffers are an extremely limited resource. Rather than
59 * queue largest-possible-sized buffers to the HCI bridge, some systems would rather
60 * allocate a specific size as the packet is received. The trade off is
61 * slightly more processing (callback invoked for each RX packet)
62 * for the benefit of committing fewer buffer resources into the bridge.
63 *
64 * The callback is provided the length of the pending packet to fetch. This includes the
65 * full transport header, HCI header, plus the length of payload. The callback can return a pointer to
66 * the allocated HTC packet for immediate use.
67 *
68 * NOTE*** This callback is mutually exclusive with the the refill callback above.
69 *
70 * */
71typedef struct htc_packet *(*HCI_TRANSPORT_RECV_ALLOC)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int Length);
72
73typedef enum _HCI_SEND_FULL_ACTION {
74 HCI_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */
75 HCI_SEND_FULL_DROP = 1, /* packet that overflowed should be dropped */
76} HCI_SEND_FULL_ACTION;
77
78/* callback when an HCI send queue exceeds the caller's MaxSendQueueDepth threshold,
79 * the callback must return the send full action to take (either DROP or KEEP) */
80typedef HCI_SEND_FULL_ACTION (*HCI_TRANSPORT_SEND_FULL)(void *, struct htc_packet *);
81
82struct hci_transport_properties {
83 int HeadRoom; /* number of bytes in front of HCI packet for header space */
84 int TailRoom; /* number of bytes at the end of the HCI packet for tail space */
85 int IOBlockPad; /* I/O block padding required (always a power of 2) */
86};
87
88struct hci_transport_config_info {
89 int ACLRecvBufferWaterMark; /* low watermark to trigger recv refill */
90 int EventRecvBufferWaterMark; /* low watermark to trigger recv refill */
91 int MaxSendQueueDepth; /* max number of packets in the single send queue */
92 void *pContext; /* context for all callbacks */
93 void (*TransportFailure)(void *pContext, int Status); /* transport failure callback */
94 int (*TransportReady)(HCI_TRANSPORT_HANDLE, struct hci_transport_properties *,void *pContext); /* transport is ready */
95 void (*TransportRemoved)(void *pContext); /* transport was removed */
96 /* packet processing callbacks */
97 HCI_TRANSPORT_SEND_PKT_COMPLETE pHCISendComplete;
98 HCI_TRANSPORT_RECV_PKT pHCIPktRecv;
99 HCI_TRANSPORT_RECV_REFILL pHCIPktRecvRefill;
100 HCI_TRANSPORT_RECV_ALLOC pHCIPktRecvAlloc;
101 HCI_TRANSPORT_SEND_FULL pHCISendFull;
102};
103
104/* ------ Function Prototypes ------ */
105/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
106 @desc: Attach to the HCI transport module
107 @function name: HCI_TransportAttach
108 @input: HTCHandle - HTC handle (see HTC apis)
109 pInfo - initialization information
110 @output:
111 @return: HCI_TRANSPORT_HANDLE on success, NULL on failure
112 @notes: The HTC module provides HCI transport services.
113 @example:
114 @see also: HCI_TransportDetach
115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
116HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, struct hci_transport_config_info *pInfo);
117
118/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
119 @desc: Detach from the HCI transport module
120 @function name: HCI_TransportDetach
121 @input: HciTrans - HCI transport handle
122 pInfo - initialization information
123 @output:
124 @return:
125 @notes:
126 @example:
127 @see also:
128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
129void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans);
130
131/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
132 @desc: Add receive packets to the HCI transport
133 @function name: HCI_TransportAddReceivePkts
134 @input: HciTrans - HCI transport handle
135 pQueue - a queue holding one or more packets
136 @output:
137 @return: 0 on success
138 @notes: user must supply HTC packets for capturing incomming HCI packets. The caller
139 must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
140 macro. Each packet in the queue must be of the same type and length
141 @example:
142 @see also:
143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
144int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
145
146/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
147 @desc: Send an HCI packet packet
148 @function name: HCI_TransportSendPkt
149 @input: HciTrans - HCI transport handle
150 pPacket - packet to send
151 Synchronous - send the packet synchronously (blocking)
152 @output:
153 @return: 0
154 @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() and
155 HCI_SET_PACKET_TYPE() macros to prepare the packet.
156 If Synchronous is set to false the call is fully asynchronous. On error or completion,
157 the registered send complete callback will be called.
158 If Synchronous is set to true, the call will block until the packet is sent, if the
159 interface cannot send the packet within a 2 second timeout, the function will return
160 the failure code : A_EBUSY.
161
162 Synchronous Mode should only be used at start-up to initialize the HCI device using
163 custom HCI commands. It should NOT be mixed with Asynchronous operations. Mixed synchronous
164 and asynchronous operation behavior is undefined.
165
166 @example:
167 @see also:
168+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
169int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
170
171
172/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
173 @desc: Stop HCI transport
174 @function name: HCI_TransportStop
175 @input: HciTrans - hci transport handle
176 @output:
177 @return:
178 @notes: HCI transport communication will be halted. All receive and pending TX packets will
179 be flushed.
180 @example:
181 @see also:
182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
183void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans);
184
185/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
186 @desc: Start the HCI transport
187 @function name: HCI_TransportStart
188 @input: HciTrans - hci transport handle
189 @output:
190 @return: 0 on success
191 @notes: HCI transport communication will begin, the caller can expect the arrival
192 of HCI recv packets as soon as this call returns.
193 @example:
194 @see also:
195+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
196int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans);
197
198/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
199 @desc: Enable or Disable Asynchronous Recv
200 @function name: HCI_TransportEnableDisableAsyncRecv
201 @input: HciTrans - hci transport handle
202 Enable - enable or disable asynchronous recv
203 @output:
204 @return: 0 on success
205 @notes: This API must be called when HCI recv is handled synchronously
206 @example:
207 @see also:
208+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
209int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
210
211/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
212 @desc: Receive an event packet from the HCI transport synchronously using polling
213 @function name: HCI_TransportRecvHCIEventSync
214 @input: HciTrans - hci transport handle
215 pPacket - HTC packet to hold the recv data
216 MaxPollMS - maximum polling duration in Milliseconds;
217 @output:
218 @return: 0 on success
219 @notes: This API should be used only during HCI device initialization, the caller must call
220 HCI_TransportEnableDisableAsyncRecv with Enable=false prior to using this API.
221 This API will only capture HCI Event packets.
222 @example:
223 @see also: HCI_TransportEnableDisableAsyncRecv
224+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
225int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans,
226 struct htc_packet *pPacket,
227 int MaxPollMS);
228
229/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
230 @desc: Set the desired baud rate for the underlying transport layer
231 @function name: HCI_TransportSetBaudRate
232 @input: HciTrans - hci transport handle
233 Baud - baud rate in bps
234 @output:
235 @return: 0 on success
236 @notes: This API should be used only after HCI device initialization
237 @example:
238 @see also:
239+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
240int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
241
242/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
243 @desc: Enable/Disable HCI Transport Power Management
244 @function name: HCI_TransportEnablePowerMgmt
245 @input: HciTrans - hci transport handle
246 Enable - 1 = Enable, 0 = Disable
247 @output:
248 @return: 0 on success
249 @notes:
250 @example:
251 @see also:
252+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
253int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
254
255#ifdef __cplusplus
256}
257#endif
258
259#endif /* _HCI_TRANSPORT_API_H_ */
diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h
new file mode 100644
index 00000000000..24200e778c3
--- /dev/null
+++ b/drivers/staging/ath6kl/include/hif.h
@@ -0,0 +1,456 @@
1//------------------------------------------------------------------------------
2// <copyright file="hif.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// HIF specific declarations and prototypes
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _HIF_H_
26#define _HIF_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* Header files */
33#include "a_config.h"
34#include "athdefs.h"
35#include "a_osapi.h"
36#include "dl_list.h"
37
38
39typedef struct htc_callbacks HTC_CALLBACKS;
40struct hif_device;
41
42/*
43 * direction - Direction of transfer (HIF_READ/HIF_WRITE).
44 */
45#define HIF_READ 0x00000001
46#define HIF_WRITE 0x00000002
47#define HIF_DIR_MASK (HIF_READ | HIF_WRITE)
48
49/*
50 * type - An interface may support different kind of read/write commands.
51 * For example: SDIO supports CMD52/CMD53s. In case of MSIO it
52 * translates to using different kinds of TPCs. The command type
53 * is thus divided into a basic and an extended command and can
54 * be specified using HIF_BASIC_IO/HIF_EXTENDED_IO.
55 */
56#define HIF_BASIC_IO 0x00000004
57#define HIF_EXTENDED_IO 0x00000008
58#define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO)
59
60/*
61 * emode - This indicates the whether the command is to be executed in a
62 * blocking or non-blocking fashion (HIF_SYNCHRONOUS/
63 * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
64 * implemented using the asynchronous mode allowing the the bus
65 * driver to indicate the completion of operation through the
66 * registered callback routine. The requirement primarily comes
67 * from the contexts these operations get called from (a driver's
68 * transmit context or the ISR context in case of receive).
69 * Support for both of these modes is essential.
70 */
71#define HIF_SYNCHRONOUS 0x00000010
72#define HIF_ASYNCHRONOUS 0x00000020
73#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
74
75/*
76 * dmode - An interface may support different kinds of commands based on
77 * the tradeoff between the amount of data it can carry and the
78 * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
79 * HIF_BLOCK_BASIS). In case of latter, the data is rounded off
80 * to the nearest block size by padding. The size of the block is
81 * configurable at compile time using the HIF_BLOCK_SIZE and is
82 * negotiated with the target during initialization after the
83 * AR6000 interrupts are enabled.
84 */
85#define HIF_BYTE_BASIS 0x00000040
86#define HIF_BLOCK_BASIS 0x00000080
87#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
88
89/*
90 * amode - This indicates if the address has to be incremented on AR6000
91 * after every read/write operation (HIF?FIXED_ADDRESS/
92 * HIF_INCREMENTAL_ADDRESS).
93 */
94#define HIF_FIXED_ADDRESS 0x00000100
95#define HIF_INCREMENTAL_ADDRESS 0x00000200
96#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
97
98#define HIF_WR_ASYNC_BYTE_FIX \
99 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
100#define HIF_WR_ASYNC_BYTE_INC \
101 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
102#define HIF_WR_ASYNC_BLOCK_INC \
103 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
104#define HIF_WR_SYNC_BYTE_FIX \
105 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
106#define HIF_WR_SYNC_BYTE_INC \
107 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
108#define HIF_WR_SYNC_BLOCK_INC \
109 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
110#define HIF_WR_ASYNC_BLOCK_FIX \
111 (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
112#define HIF_WR_SYNC_BLOCK_FIX \
113 (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
114#define HIF_RD_SYNC_BYTE_INC \
115 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
116#define HIF_RD_SYNC_BYTE_FIX \
117 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
118#define HIF_RD_ASYNC_BYTE_FIX \
119 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
120#define HIF_RD_ASYNC_BLOCK_FIX \
121 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
122#define HIF_RD_ASYNC_BYTE_INC \
123 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
124#define HIF_RD_ASYNC_BLOCK_INC \
125 (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
126#define HIF_RD_SYNC_BLOCK_INC \
127 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
128#define HIF_RD_SYNC_BLOCK_FIX \
129 (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
130
131typedef enum {
132 HIF_DEVICE_POWER_STATE = 0,
133 HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
134 HIF_DEVICE_GET_MBOX_ADDR,
135 HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
136 HIF_DEVICE_GET_IRQ_PROC_MODE,
137 HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
138 HIF_DEVICE_POWER_STATE_CHANGE,
139 HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
140 HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT,
141 HIF_DEVICE_GET_OS_DEVICE,
142 HIF_DEVICE_DEBUG_BUS_STATE,
143} HIF_DEVICE_CONFIG_OPCODE;
144
145/*
146 * HIF CONFIGURE definitions:
147 *
148 * HIF_DEVICE_GET_MBOX_BLOCK_SIZE
149 * input : none
150 * output : array of 4 u32s
151 * notes: block size is returned for each mailbox (4)
152 *
153 * HIF_DEVICE_GET_MBOX_ADDR
154 * input : none
155 * output : struct hif_device_mbox_info
156 * notes:
157 *
158 * HIF_DEVICE_GET_PENDING_EVENTS_FUNC
159 * input : none
160 * output: HIF_PENDING_EVENTS_FUNC function pointer
161 * notes: this is optional for the HIF layer, if the request is
162 * not handled then it indicates that the upper layer can use
163 * the standard device methods to get pending events (IRQs, mailbox messages etc..)
164 * otherwise it can call the function pointer to check pending events.
165 *
166 * HIF_DEVICE_GET_IRQ_PROC_MODE
167 * input : none
168 * output : HIF_DEVICE_IRQ_PROCESSING_MODE (interrupt processing mode)
169 * note: the hif layer interfaces with the underlying OS-specific bus driver. The HIF
170 * layer can report whether IRQ processing is requires synchronous behavior or
171 * can be processed using asynchronous bus requests (typically faster).
172 *
173 * HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC
174 * input :
175 * output : HIF_MASK_UNMASK_RECV_EVENT function pointer
176 * notes: this is optional for the HIF layer. The HIF layer may require a special mechanism
177 * to mask receive message events. The upper layer can call this pointer when it needs
178 * to mask/unmask receive events (in case it runs out of buffers).
179 *
180 * HIF_DEVICE_POWER_STATE_CHANGE
181 *
182 * input : HIF_DEVICE_POWER_CHANGE_TYPE
183 * output : none
184 * note: this is optional for the HIF layer. The HIF layer can handle power on/off state change
185 * requests in an interconnect specific way. This is highly OS and bus driver dependent.
186 * The caller must guarantee that no HIF read/write requests will be made after the device
187 * is powered down.
188 *
189 * HIF_DEVICE_GET_IRQ_YIELD_PARAMS
190 *
191 * input : none
192 * output : struct hif_device_irq_yield_params
193 * note: This query checks if the HIF layer wishes to impose a processing yield count for the DSR handler.
194 * The DSR callback handler will exit after a fixed number of RX packets or events are processed.
195 * This query is only made if the device reports an IRQ processing mode of HIF_DEVICE_IRQ_SYNC_ONLY.
196 * The HIF implementation can ignore this command if it does not desire the DSR callback to yield.
197 * The HIF layer can indicate the maximum number of IRQ processing units (RX packets) before the
198 * DSR handler callback must yield and return control back to the HIF layer. When a yield limit is
199 * used the DSR callback will not call HIFAckInterrupts() as it would normally do before returning.
200 * The HIF implementation that requires a yield count must call HIFAckInterrupt() when it is prepared
201 * to process interrupts again.
202 *
203 * HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT
204 * input : none
205 * output : struct hif_device_scatter_support_info
206 * note: This query checks if the HIF layer implements the SCATTER request interface. Scatter requests
207 * allows upper layers to submit mailbox I/O operations using a list of buffers. This is useful for
208 * multi-message transfers that can better utilize the bus interconnect.
209 *
210 *
211 * HIF_DEVICE_GET_OS_DEVICE
212 * intput : none
213 * output : struct hif_device_os_device_info;
214 * note: On some operating systems, the HIF layer has a parent device object for the bus. This object
215 * may be required to register certain types of logical devices.
216 *
217 * HIF_DEVICE_DEBUG_BUS_STATE
218 * input : none
219 * output : none
220 * note: This configure option triggers the HIF interface to dump as much bus interface state. This
221 * configuration request is optional (No-OP on some HIF implementations)
222 *
223 */
224
225struct hif_mbox_properties {
226 u32 ExtendedAddress; /* extended address for larger writes */
227 u32 ExtendedSize;
228};
229
230#define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */
231
232typedef enum _MBOX_BUF_IF_TYPE {
233 MBOX_BUS_IF_SDIO = 0,
234 MBOX_BUS_IF_SPI = 1,
235} MBOX_BUF_IF_TYPE;
236
237struct hif_device_mbox_info {
238 u32 MboxAddresses[4]; /* must be first element for legacy HIFs that return the address in
239 and ARRAY of 32-bit words */
240
241 /* the following describe extended mailbox properties */
242 struct hif_mbox_properties MboxProp[4];
243 /* if the HIF supports the GMbox extended address region it can report it
244 * here, some interfaces cannot support the GMBOX address range and not set this */
245 u32 GMboxAddress;
246 u32 GMboxSize;
247 u32 Flags; /* flags to describe mbox behavior or usage */
248 MBOX_BUF_IF_TYPE MboxBusIFType; /* mailbox bus interface type */
249};
250
251typedef enum {
252 HIF_DEVICE_IRQ_SYNC_ONLY, /* for HIF implementations that require the DSR to process all
253 interrupts before returning */
254 HIF_DEVICE_IRQ_ASYNC_SYNC, /* for HIF implementations that allow DSR to process interrupts
255 using ASYNC I/O (that is HIFAckInterrupt can be called at a
256 later time */
257} HIF_DEVICE_IRQ_PROCESSING_MODE;
258
259typedef enum {
260 HIF_DEVICE_POWER_UP, /* HIF layer should power up interface and/or module */
261 HIF_DEVICE_POWER_DOWN, /* HIF layer should initiate bus-specific measures to minimize power */
262 HIF_DEVICE_POWER_CUT /* HIF layer should initiate bus-specific AND/OR platform-specific measures
263 to completely power-off the module and associated hardware (i.e. cut power supplies)
264 */
265} HIF_DEVICE_POWER_CHANGE_TYPE;
266
267struct hif_device_irq_yield_params {
268 int RecvPacketYieldCount; /* max number of packets to force DSR to return */
269};
270
271
272struct hif_scatter_item {
273 u8 *pBuffer; /* CPU accessible address of buffer */
274 int Length; /* length of transfer to/from this buffer */
275 void *pCallerContexts[2]; /* space for caller to insert a context associated with this item */
276};
277
278struct hif_scatter_req;
279typedef void ( *HIF_SCATTER_COMP_CB)(struct hif_scatter_req *);
280
281typedef enum _HIF_SCATTER_METHOD {
282 HIF_SCATTER_NONE = 0,
283 HIF_SCATTER_DMA_REAL, /* Real SG support no restrictions */
284 HIF_SCATTER_DMA_BOUNCE, /* Uses SG DMA but HIF layer uses an internal bounce buffer */
285} HIF_SCATTER_METHOD;
286
287struct hif_scatter_req {
288 struct dl_list ListLink; /* link management */
289 u32 Address; /* address for the read/write operation */
290 u32 Request; /* request flags */
291 u32 TotalLength; /* total length of entire transfer */
292 u32 CallerFlags; /* caller specific flags can be stored here */
293 HIF_SCATTER_COMP_CB CompletionRoutine; /* completion routine set by caller */
294 int CompletionStatus; /* status of completion */
295 void *Context; /* caller context for this request */
296 int ValidScatterEntries; /* number of valid entries set by caller */
297 HIF_SCATTER_METHOD ScatterMethod; /* scatter method handled by HIF */
298 void *HIFPrivate[4]; /* HIF private area */
299 u8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */
300 struct hif_scatter_item ScatterList[1]; /* start of scatter list */
301};
302
303typedef struct hif_scatter_req * ( *HIF_ALLOCATE_SCATTER_REQUEST)(struct hif_device *device);
304typedef void ( *HIF_FREE_SCATTER_REQUEST)(struct hif_device *device, struct hif_scatter_req *request);
305typedef int ( *HIF_READWRITE_SCATTER)(struct hif_device *device, struct hif_scatter_req *request);
306
307struct hif_device_scatter_support_info {
308 /* information returned from HIF layer */
309 HIF_ALLOCATE_SCATTER_REQUEST pAllocateReqFunc;
310 HIF_FREE_SCATTER_REQUEST pFreeReqFunc;
311 HIF_READWRITE_SCATTER pReadWriteScatterFunc;
312 int MaxScatterEntries;
313 int MaxTransferSizePerScatterReq;
314};
315
316struct hif_device_os_device_info {
317 void *pOSDevice;
318};
319
320#define HIF_MAX_DEVICES 1
321
322struct htc_callbacks {
323 void *context; /* context to pass to the dsrhandler
324 note : rwCompletionHandler is provided the context passed to HIFReadWrite */
325 int (* rwCompletionHandler)(void *rwContext, int status);
326 int (* dsrHandler)(void *context);
327};
328
329typedef struct osdrv_callbacks {
330 void *context; /* context to pass for all callbacks except deviceRemovedHandler
331 the deviceRemovedHandler is only called if the device is claimed */
332 int (* deviceInsertedHandler)(void *context, void *hif_handle);
333 int (* deviceRemovedHandler)(void *claimedContext, void *hif_handle);
334 int (* deviceSuspendHandler)(void *context);
335 int (* deviceResumeHandler)(void *context);
336 int (* deviceWakeupHandler)(void *context);
337 int (* devicePowerChangeHandler)(void *context, HIF_DEVICE_POWER_CHANGE_TYPE config);
338} OSDRV_CALLBACKS;
339
340#define HIF_OTHER_EVENTS (1 << 0) /* other interrupts (non-Recv) are pending, host
341 needs to read the register table to figure out what */
342#define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */
343
344struct hif_pending_events_info {
345 u32 Events;
346 u32 LookAhead;
347 u32 AvailableRecvBytes;
348#ifdef THREAD_X
349 u32 Polling;
350 u32 INT_CAUSE_REG;
351#endif
352};
353
354 /* function to get pending events , some HIF modules use special mechanisms
355 * to detect packet available and other interrupts */
356typedef int ( *HIF_PENDING_EVENTS_FUNC)(struct hif_device *device,
357 struct hif_pending_events_info *pEvents,
358 void *AsyncContext);
359
360#define HIF_MASK_RECV true
361#define HIF_UNMASK_RECV false
362 /* function to mask recv events */
363typedef int ( *HIF_MASK_UNMASK_RECV_EVENT)(struct hif_device *device,
364 bool Mask,
365 void *AsyncContext);
366
367
368/*
369 * This API is used to perform any global initialization of the HIF layer
370 * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer
371 *
372 */
373int HIFInit(OSDRV_CALLBACKS *callbacks);
374
375/* This API claims the HIF device and provides a context for handling removal.
376 * The device removal callback is only called when the OSDRV layer claims
377 * a device. The claimed context must be non-NULL */
378void HIFClaimDevice(struct hif_device *device, void *claimedContext);
379/* release the claimed device */
380void HIFReleaseDevice(struct hif_device *device);
381
382/* This API allows the HTC layer to attach to the HIF device */
383int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks);
384/* This API detaches the HTC layer from the HIF device */
385void HIFDetachHTC(struct hif_device *device);
386
387/*
388 * This API is used to provide the read/write interface over the specific bus
389 * interface.
390 * address - Starting address in the AR6000's address space. For mailbox
391 * writes, it refers to the start of the mbox boundary. It should
392 * be ensured that the last byte falls on the mailbox's EOM. For
393 * mailbox reads, it refers to the end of the mbox boundary.
394 * buffer - Pointer to the buffer containg the data to be transmitted or
395 * received.
396 * length - Amount of data to be transmitted or received.
397 * request - Characterizes the attributes of the command.
398 */
399int
400HIFReadWrite(struct hif_device *device,
401 u32 address,
402 u8 *buffer,
403 u32 length,
404 u32 request,
405 void *context);
406
407/*
408 * This can be initiated from the unload driver context when the OSDRV layer has no more use for
409 * the device.
410 */
411void HIFShutDownDevice(struct hif_device *device);
412
413/*
414 * This should translate to an acknowledgment to the bus driver indicating that
415 * the previous interrupt request has been serviced and the all the relevant
416 * sources have been cleared. HTC is ready to process more interrupts.
417 * This should prevent the bus driver from raising an interrupt unless the
418 * previous one has been serviced and acknowledged using the previous API.
419 */
420void HIFAckInterrupt(struct hif_device *device);
421
422void HIFMaskInterrupt(struct hif_device *device);
423
424void HIFUnMaskInterrupt(struct hif_device *device);
425
426#ifdef THREAD_X
427/*
428 * This set of functions are to be used by the bus driver to notify
429 * the HIF module about various events.
430 * These are not implemented if the bus driver provides an alternative
431 * way for this notification though callbacks for instance.
432 */
433int HIFInsertEventNotify(void);
434
435int HIFRemoveEventNotify(void);
436
437int HIFIRQEventNotify(void);
438
439int HIFRWCompleteEventNotify(void);
440#endif
441
442int
443HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode,
444 void *config, u32 configLen);
445
446/*
447 * This API wait for the remaining MBOX messages to be drained
448 * This should be moved to HTC AR6K layer
449 */
450int hifWaitForPendingRecv(struct hif_device *device);
451
452#ifdef __cplusplus
453}
454#endif
455
456#endif /* _HIF_H_ */
diff --git a/drivers/staging/ath6kl/include/host_version.h b/drivers/staging/ath6kl/include/host_version.h
new file mode 100644
index 00000000000..74f1982c681
--- /dev/null
+++ b/drivers/staging/ath6kl/include/host_version.h
@@ -0,0 +1,52 @@
1//------------------------------------------------------------------------------
2// <copyright file="host_version.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains version information for the sample host driver for the
22// AR6000 chip
23//
24// Author(s): ="Atheros"
25//==============================================================================
26#ifndef _HOST_VERSION_H_
27#define _HOST_VERSION_H_
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33#include <AR6002/AR6K_version.h>
34
35/*
36 * The version number is made up of major, minor, patch and build
37 * numbers. These are 16 bit numbers. The build and release script will
38 * set the build number using a Perforce counter. Here the build number is
39 * set to 9999 so that builds done without the build-release script are easily
40 * identifiable.
41 */
42
43#define ATH_SW_VER_MAJOR __VER_MAJOR_
44#define ATH_SW_VER_MINOR __VER_MINOR_
45#define ATH_SW_VER_PATCH __VER_PATCH_
46#define ATH_SW_VER_BUILD __BUILD_NUMBER_
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif /* _HOST_VERSION_H_ */
diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h
new file mode 100644
index 00000000000..4fb767559f8
--- /dev/null
+++ b/drivers/staging/ath6kl/include/htc_api.h
@@ -0,0 +1,575 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_api.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _HTC_API_H_
24#define _HTC_API_H_
25
26#include "htc_packet.h"
27#include <htc.h>
28#include <htc_services.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif /* __cplusplus */
33
34/* TODO.. for BMI */
35#define ENDPOINT1 0
36// TODO -remove me, but we have to fix BMI first
37#define HTC_MAILBOX_NUM_MAX 4
38
39/* this is the amount of header room required by users of HTC */
40#define HTC_HEADER_LEN HTC_HDR_LENGTH
41
42typedef void *HTC_HANDLE;
43
44typedef u16 HTC_SERVICE_ID;
45
46struct htc_init_info {
47 void *pContext; /* context for target failure notification */
48 void (*TargetFailure)(void *Instance, int Status);
49};
50
51/* per service connection send completion */
52typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,struct htc_packet *);
53/* per service connection callback when a plurality of packets have been sent
54 * The struct htc_packet_queue is a temporary queue object (e.g. freed on return from the callback)
55 * to hold a list of completed send packets.
56 * If the handler cannot fully traverse the packet queue before returning, it should
57 * transfer the items of the queue into the caller's private queue using:
58 * HTC_PACKET_ENQUEUE() */
59typedef void (*HTC_EP_SEND_PKT_COMP_MULTIPLE)(void *,struct htc_packet_queue *);
60/* per service connection pkt received */
61typedef void (*HTC_EP_RECV_PKT)(void *,struct htc_packet *);
62/* per service connection callback when a plurality of packets are received
63 * The struct htc_packet_queue is a temporary queue object (e.g. freed on return from the callback)
64 * to hold a list of recv packets.
65 * If the handler cannot fully traverse the packet queue before returning, it should
66 * transfer the items of the queue into the caller's private queue using:
67 * HTC_PACKET_ENQUEUE() */
68typedef void (*HTC_EP_RECV_PKT_MULTIPLE)(void *,struct htc_packet_queue *);
69
70/* Optional per service connection receive buffer re-fill callback,
71 * On some OSes (like Linux) packets are allocated from a global pool and indicated up
72 * to the network stack. The driver never gets the packets back from the OS. For these OSes
73 * a refill callback can be used to allocate and re-queue buffers into HTC.
74 *
75 * On other OSes, the network stack can call into the driver's OS-specifc "return_packet" handler and
76 * the driver can re-queue these buffers into HTC. In this regard a refill callback is
77 * unnecessary */
78typedef void (*HTC_EP_RECV_REFILL)(void *, HTC_ENDPOINT_ID Endpoint);
79
80/* Optional per service connection receive buffer allocation callback.
81 * On some systems packet buffers are an extremely limited resource. Rather than
82 * queue largest-possible-sized buffers to HTC, some systems would rather
83 * allocate a specific size as the packet is received. The trade off is
84 * slightly more processing (callback invoked for each RX packet)
85 * for the benefit of committing fewer buffer resources into HTC.
86 *
87 * The callback is provided the length of the pending packet to fetch. This includes the
88 * HTC header length plus the length of payload. The callback can return a pointer to
89 * the allocated HTC packet for immediate use.
90 *
91 * Alternatively a variant of this handler can be used to allocate large receive packets as needed.
92 * For example an application can use the refill mechanism for normal packets and the recv-alloc mechanism to
93 * handle the case where a large packet buffer is required. This can significantly reduce the
94 * amount of "committed" memory used to receive packets.
95 *
96 * */
97typedef struct htc_packet *(*HTC_EP_RECV_ALLOC)(void *, HTC_ENDPOINT_ID Endpoint, int Length);
98
99typedef enum _HTC_SEND_FULL_ACTION {
100 HTC_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */
101 HTC_SEND_FULL_DROP = 1, /* packet that overflowed should be dropped */
102} HTC_SEND_FULL_ACTION;
103
104/* Optional per service connection callback when a send queue is full. This can occur if the
105 * host continues queueing up TX packets faster than credits can arrive
106 * To prevent the host (on some Oses like Linux) from continuously queueing packets
107 * and consuming resources, this callback is provided so that that the host
108 * can disable TX in the subsystem (i.e. network stack).
109 * This callback is invoked for each packet that "overflows" the HTC queue. The callback can
110 * determine whether the new packet that overflowed the queue can be kept (HTC_SEND_FULL_KEEP) or
111 * dropped (HTC_SEND_FULL_DROP). If a packet is dropped, the EpTxComplete handler will be called
112 * and the packet's status field will be set to A_NO_RESOURCE.
113 * Other OSes require a "per-packet" indication for each completed TX packet, this
114 * closed loop mechanism will prevent the network stack from overunning the NIC
115 * The packet to keep or drop is passed for inspection to the registered handler the handler
116 * must ONLY inspect the packet, it may not free or reclaim the packet. */
117typedef HTC_SEND_FULL_ACTION (*HTC_EP_SEND_QUEUE_FULL)(void *, struct htc_packet *pPacket);
118
119struct htc_ep_callbacks {
120 void *pContext; /* context for each callback */
121 HTC_EP_SEND_PKT_COMPLETE EpTxComplete; /* tx completion callback for connected endpoint */
122 HTC_EP_RECV_PKT EpRecv; /* receive callback for connected endpoint */
123 HTC_EP_RECV_REFILL EpRecvRefill; /* OPTIONAL receive re-fill callback for connected endpoint */
124 HTC_EP_SEND_QUEUE_FULL EpSendFull; /* OPTIONAL send full callback */
125 HTC_EP_RECV_ALLOC EpRecvAlloc; /* OPTIONAL recv allocation callback */
126 HTC_EP_RECV_ALLOC EpRecvAllocThresh; /* OPTIONAL recv allocation callback based on a threshold */
127 HTC_EP_SEND_PKT_COMP_MULTIPLE EpTxCompleteMultiple; /* OPTIONAL completion handler for multiple complete
128 indications (EpTxComplete must be NULL) */
129 HTC_EP_RECV_PKT_MULTIPLE EpRecvPktMultiple; /* OPTIONAL completion handler for multiple
130 recv packet indications (EpRecv must be NULL) */
131 int RecvAllocThreshold; /* if EpRecvAllocThresh is non-NULL, HTC will compare the
132 threshold value to the current recv packet length and invoke
133 the EpRecvAllocThresh callback to acquire a packet buffer */
134 int RecvRefillWaterMark; /* if a EpRecvRefill handler is provided, this value
135 can be used to set a trigger refill callback
136 when the recv queue drops below this value
137 if set to 0, the refill is only called when packets
138 are empty */
139};
140
141/* service connection information */
142struct htc_service_connect_req {
143 HTC_SERVICE_ID ServiceID; /* service ID to connect to */
144 u16 ConnectionFlags; /* connection flags, see htc protocol definition */
145 u8 *pMetaData; /* ptr to optional service-specific meta-data */
146 u8 MetaDataLength; /* optional meta data length */
147 struct htc_ep_callbacks EpCallbacks; /* endpoint callbacks */
148 int MaxSendQueueDepth; /* maximum depth of any send queue */
149 u32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */
150 unsigned int MaxSendMsgSize; /* override max message size in send direction */
151};
152
153#define HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING (1 << 0) /* enable send bundle padding for this endpoint */
154
155/* service connection response information */
156struct htc_service_connect_resp {
157 u8 *pMetaData; /* caller supplied buffer to optional meta-data */
158 u8 BufferLength; /* length of caller supplied buffer */
159 u8 ActualLength; /* actual length of meta data */
160 HTC_ENDPOINT_ID Endpoint; /* endpoint to communicate over */
161 unsigned int MaxMsgLength; /* max length of all messages over this endpoint */
162 u8 ConnectRespCode; /* connect response code from target */
163};
164
165/* endpoint distribution structure */
166struct htc_endpoint_credit_dist {
167 struct htc_endpoint_credit_dist *pNext;
168 struct htc_endpoint_credit_dist *pPrev;
169 HTC_SERVICE_ID ServiceID; /* Service ID (set by HTC) */
170 HTC_ENDPOINT_ID Endpoint; /* endpoint for this distribution struct (set by HTC) */
171 u32 DistFlags; /* distribution flags, distribution function can
172 set default activity using SET_EP_ACTIVE() macro */
173 int TxCreditsNorm; /* credits for normal operation, anything above this
174 indicates the endpoint is over-subscribed, this field
175 is only relevant to the credit distribution function */
176 int TxCreditsMin; /* floor for credit distribution, this field is
177 only relevant to the credit distribution function */
178 int TxCreditsAssigned; /* number of credits assigned to this EP, this field
179 is only relevant to the credit dist function */
180 int TxCredits; /* current credits available, this field is used by
181 HTC to determine whether a message can be sent or
182 must be queued */
183 int TxCreditsToDist; /* pending credits to distribute on this endpoint, this
184 is set by HTC when credit reports arrive.
185 The credit distribution functions sets this to zero
186 when it distributes the credits */
187 int TxCreditsSeek; /* this is the number of credits that the current pending TX
188 packet needs to transmit. This is set by HTC when
189 and endpoint needs credits in order to transmit */
190 int TxCreditSize; /* size in bytes of each credit (set by HTC) */
191 int TxCreditsPerMaxMsg; /* credits required for a maximum sized messages (set by HTC) */
192 void *pHTCReserved; /* reserved for HTC use */
193 int TxQueueDepth; /* current depth of TX queue , i.e. messages waiting for credits
194 This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE
195 or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint
196 that has non-zero credits to recover
197 */
198};
199
200#define HTC_EP_ACTIVE ((u32) (1u << 31))
201
202/* macro to check if an endpoint has gone active, useful for credit
203 * distributions */
204#define IS_EP_ACTIVE(epDist) ((epDist)->DistFlags & HTC_EP_ACTIVE)
205#define SET_EP_ACTIVE(epDist) (epDist)->DistFlags |= HTC_EP_ACTIVE
206
207 /* credit distibution code that is passed into the distrbution function,
208 * there are mandatory and optional codes that must be handled */
209typedef enum _HTC_CREDIT_DIST_REASON {
210 HTC_CREDIT_DIST_SEND_COMPLETE = 0, /* credits available as a result of completed
211 send operations (MANDATORY) resulting in credit reports */
212 HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1, /* a change in endpoint activity occurred (OPTIONAL) */
213 HTC_CREDIT_DIST_SEEK_CREDITS, /* an endpoint needs to "seek" credits (OPTIONAL) */
214 HTC_DUMP_CREDIT_STATE /* for debugging, dump any state information that is kept by
215 the distribution function */
216} HTC_CREDIT_DIST_REASON;
217
218typedef void (*HTC_CREDIT_DIST_CALLBACK)(void *Context,
219 struct htc_endpoint_credit_dist *pEPList,
220 HTC_CREDIT_DIST_REASON Reason);
221
222typedef void (*HTC_CREDIT_INIT_CALLBACK)(void *Context,
223 struct htc_endpoint_credit_dist *pEPList,
224 int TotalCredits);
225
226 /* endpoint statistics action */
227typedef enum _HTC_ENDPOINT_STAT_ACTION {
228 HTC_EP_STAT_SAMPLE = 0, /* only read statistics */
229 HTC_EP_STAT_SAMPLE_AND_CLEAR = 1, /* sample and immediately clear statistics */
230 HTC_EP_STAT_CLEAR /* clear only */
231} HTC_ENDPOINT_STAT_ACTION;
232
233 /* endpoint statistics */
234struct htc_endpoint_stats {
235 u32 TxCreditLowIndications; /* number of times the host set the credit-low flag in a send message on
236 this endpoint */
237 u32 TxIssued; /* running count of total TX packets issued */
238 u32 TxPacketsBundled; /* running count of TX packets that were issued in bundles */
239 u32 TxBundles; /* running count of TX bundles that were issued */
240 u32 TxDropped; /* tx packets that were dropped */
241 u32 TxCreditRpts; /* running count of total credit reports received for this endpoint */
242 u32 TxCreditRptsFromRx; /* credit reports received from this endpoint's RX packets */
243 u32 TxCreditRptsFromOther; /* credit reports received from RX packets of other endpoints */
244 u32 TxCreditRptsFromEp0; /* credit reports received from endpoint 0 RX packets */
245 u32 TxCreditsFromRx; /* count of credits received via Rx packets on this endpoint */
246 u32 TxCreditsFromOther; /* count of credits received via another endpoint */
247 u32 TxCreditsFromEp0; /* count of credits received via another endpoint */
248 u32 TxCreditsConsummed; /* count of consummed credits */
249 u32 TxCreditsReturned; /* count of credits returned */
250 u32 RxReceived; /* count of RX packets received */
251 u32 RxLookAheads; /* count of lookahead records
252 found in messages received on this endpoint */
253 u32 RxPacketsBundled; /* count of recv packets received in a bundle */
254 u32 RxBundleLookAheads; /* count of number of bundled lookaheads */
255 u32 RxBundleIndFromHdr; /* count of the number of bundle indications from the HTC header */
256 u32 RxAllocThreshHit; /* count of the number of times the recv allocation threshold was hit */
257 u32 RxAllocThreshBytes; /* total number of bytes */
258};
259
260/* ------ Function Prototypes ------ */
261/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
262 @desc: Create an instance of HTC over the underlying HIF device
263 @function name: HTCCreate
264 @input: HifDevice - hif device handle,
265 pInfo - initialization information
266 @output:
267 @return: HTC_HANDLE on success, NULL on failure
268 @notes:
269 @example:
270 @see also: HTCDestroy
271+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
272HTC_HANDLE HTCCreate(void *HifDevice, struct htc_init_info *pInfo);
273/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
274 @desc: Get the underlying HIF device handle
275 @function name: HTCGetHifDevice
276 @input: HTCHandle - handle passed into the AddInstance callback
277 @output:
278 @return: opaque HIF device handle usable in HIF API calls.
279 @notes:
280 @example:
281 @see also:
282+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
283void *HTCGetHifDevice(HTC_HANDLE HTCHandle);
284/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
285 @desc: Set credit distribution parameters
286 @function name: HTCSetCreditDistribution
287 @input: HTCHandle - HTC handle
288 pCreditDistCont - caller supplied context to pass into distribution functions
289 CreditDistFunc - Distribution function callback
290 CreditDistInit - Credit Distribution initialization callback
291 ServicePriorityOrder - Array containing list of service IDs, lowest index is highest
292 priority
293 ListLength - number of elements in ServicePriorityOrder
294 @output:
295 @return:
296 @notes: The user can set a custom credit distribution function to handle special requirements
297 for each endpoint. A default credit distribution routine can be used by setting
298 CreditInitFunc to NULL. The default credit distribution is only provided for simple
299 "fair" credit distribution without regard to any prioritization.
300
301 @example:
302 @see also:
303+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
304void HTCSetCreditDistribution(HTC_HANDLE HTCHandle,
305 void *pCreditDistContext,
306 HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
307 HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
308 HTC_SERVICE_ID ServicePriorityOrder[],
309 int ListLength);
310/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
311 @desc: Wait for the target to indicate the HTC layer is ready
312 @function name: HTCWaitTarget
313 @input: HTCHandle - HTC handle
314 @output:
315 @return:
316 @notes: This API blocks until the target responds with an HTC ready message.
317 The caller should not connect services until the target has indicated it is
318 ready.
319 @example:
320 @see also: HTCConnectService
321+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
322int HTCWaitTarget(HTC_HANDLE HTCHandle);
323/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
324 @desc: Start target service communications
325 @function name: HTCStart
326 @input: HTCHandle - HTC handle
327 @output:
328 @return:
329 @notes: This API indicates to the target that the service connection phase is complete
330 and the target can freely start all connected services. This API should only be
331 called AFTER all service connections have been made. TCStart will issue a
332 SETUP_COMPLETE message to the target to indicate that all service connections
333 have been made and the target can start communicating over the endpoints.
334 @example:
335 @see also: HTCConnectService
336+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
337int HTCStart(HTC_HANDLE HTCHandle);
338/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
339 @desc: Add receive packet to HTC
340 @function name: HTCAddReceivePkt
341 @input: HTCHandle - HTC handle
342 pPacket - HTC receive packet to add
343 @output:
344 @return: 0 on success
345 @notes: user must supply HTC packets for capturing incomming HTC frames. The caller
346 must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
347 macro.
348 @example:
349 @see also:
350+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
351int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket);
352/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
353 @desc: Connect to an HTC service
354 @function name: HTCConnectService
355 @input: HTCHandle - HTC handle
356 pReq - connection details
357 @output: pResp - connection response
358 @return:
359 @notes: Service connections must be performed before HTCStart. User provides callback handlers
360 for various endpoint events.
361 @example:
362 @see also: HTCStart
363+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
364int HTCConnectService(HTC_HANDLE HTCHandle,
365 struct htc_service_connect_req *pReq,
366 struct htc_service_connect_resp *pResp);
367/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
368 @desc: Send an HTC packet
369 @function name: HTCSendPkt
370 @input: HTCHandle - HTC handle
371 pPacket - packet to send
372 @output:
373 @return: 0
374 @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() macro.
375 This interface is fully asynchronous. On error, HTC SendPkt will
376 call the registered Endpoint callback to cleanup the packet.
377 @example:
378 @see also: HTCFlushEndpoint
379+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
380int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket);
381/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
382 @desc: Stop HTC service communications
383 @function name: HTCStop
384 @input: HTCHandle - HTC handle
385 @output:
386 @return:
387 @notes: HTC communications is halted. All receive and pending TX packets will
388 be flushed.
389 @example:
390 @see also:
391+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
392void HTCStop(HTC_HANDLE HTCHandle);
393/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
394 @desc: Destroy HTC service
395 @function name: HTCDestroy
396 @input: HTCHandle
397 @output:
398 @return:
399 @notes: This cleans up all resources allocated by HTCCreate().
400 @example:
401 @see also: HTCCreate
402+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
403void HTCDestroy(HTC_HANDLE HTCHandle);
404/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
405 @desc: Flush pending TX packets
406 @function name: HTCFlushEndpoint
407 @input: HTCHandle - HTC handle
408 Endpoint - Endpoint to flush
409 Tag - flush tag
410 @output:
411 @return:
412 @notes: The Tag parameter is used to selectively flush packets with matching tags.
413 The value of 0 forces all packets to be flush regardless of tag.
414 @example:
415 @see also: HTCSendPkt
416+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
417void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag);
418/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
419 @desc: Dump credit distribution state
420 @function name: HTCDumpCreditStates
421 @input: HTCHandle - HTC handle
422 @output:
423 @return:
424 @notes: This dumps all credit distribution information to the debugger
425 @example:
426 @see also:
427+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
428void HTCDumpCreditStates(HTC_HANDLE HTCHandle);
429/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
430 @desc: Indicate a traffic activity change on an endpoint
431 @function name: HTCIndicateActivityChange
432 @input: HTCHandle - HTC handle
433 Endpoint - endpoint in which activity has changed
434 Active - true if active, false if it has become inactive
435 @output:
436 @return:
437 @notes: This triggers the registered credit distribution function to
438 re-adjust credits for active/inactive endpoints.
439 @example:
440 @see also:
441+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
442void HTCIndicateActivityChange(HTC_HANDLE HTCHandle,
443 HTC_ENDPOINT_ID Endpoint,
444 bool Active);
445
446/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
447 @desc: Get endpoint statistics
448 @function name: HTCGetEndpointStatistics
449 @input: HTCHandle - HTC handle
450 Endpoint - Endpoint identifier
451 Action - action to take with statistics
452 @output:
453 pStats - statistics that were sampled (can be NULL if Action is HTC_EP_STAT_CLEAR)
454
455 @return: true if statistics profiling is enabled, otherwise false.
456
457 @notes: Statistics is a compile-time option and this function may return false
458 if HTC is not compiled with profiling.
459
460 The caller can specify the statistic "action" to take when sampling
461 the statistics. This includes:
462
463 HTC_EP_STAT_SAMPLE: The pStats structure is filled with the current values.
464 HTC_EP_STAT_SAMPLE_AND_CLEAR: The structure is filled and the current statistics
465 are cleared.
466 HTC_EP_STAT_CLEA : the statistics are cleared, the called can pass a NULL value for
467 pStats
468
469 @example:
470 @see also:
471+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
472bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle,
473 HTC_ENDPOINT_ID Endpoint,
474 HTC_ENDPOINT_STAT_ACTION Action,
475 struct htc_endpoint_stats *pStats);
476
477/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
478 @desc: Unblock HTC message reception
479 @function name: HTCUnblockRecv
480 @input: HTCHandle - HTC handle
481 @output:
482 @return:
483 @notes:
484 HTC will block the receiver if the EpRecvAlloc callback fails to provide a packet.
485 The caller can use this API to indicate to HTC when resources (buffers) are available
486 such that the receiver can be unblocked and HTC may re-attempt fetching the pending message.
487
488 This API is not required if the user uses the EpRecvRefill callback or uses the HTCAddReceivePacket()
489 API to recycle or provide receive packets to HTC.
490
491 @example:
492 @see also:
493+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
494void HTCUnblockRecv(HTC_HANDLE HTCHandle);
495
496/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
497 @desc: send a series of HTC packets
498 @function name: HTCSendPktsMultiple
499 @input: HTCHandle - HTC handle
500 pPktQueue - local queue holding packets to send
501 @output:
502 @return: 0
503 @notes: Caller must initialize each packet using SET_HTC_PACKET_INFO_TX() macro.
504 The queue must only contain packets directed at the same endpoint.
505 Caller supplies a pointer to an struct htc_packet_queue structure holding the TX packets in FIFO order.
506 This API will remove the packets from the pkt queue and place them into the HTC Tx Queue
507 and bundle messages where possible.
508 The caller may allocate the pkt queue on the stack to hold the packets.
509 This interface is fully asynchronous. On error, HTCSendPkts will
510 call the registered Endpoint callback to cleanup the packet.
511 @example:
512 @see also: HTCFlushEndpoint
513+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
514int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue);
515
516/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
517 @desc: Add multiple receive packets to HTC
518 @function name: HTCAddReceivePktMultiple
519 @input: HTCHandle - HTC handle
520 pPktQueue - HTC receive packet queue holding packets to add
521 @output:
522 @return: 0 on success
523 @notes: user must supply HTC packets for capturing incomming HTC frames. The caller
524 must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
525 macro. The queue must only contain recv packets for the same endpoint.
526 Caller supplies a pointer to an struct htc_packet_queue structure holding the recv packet.
527 This API will remove the packets from the pkt queue and place them into internal
528 recv packet list.
529 The caller may allocate the pkt queue on the stack to hold the packets.
530 @example:
531 @see also:
532+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
533int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue);
534
535/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
536 @desc: Check if an endpoint is marked active
537 @function name: HTCIsEndpointActive
538 @input: HTCHandle - HTC handle
539 Endpoint - endpoint to check for active state
540 @output:
541 @return: returns true if Endpoint is Active
542 @notes:
543 @example:
544 @see also:
545+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
546bool HTCIsEndpointActive(HTC_HANDLE HTCHandle,
547 HTC_ENDPOINT_ID Endpoint);
548
549
550/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
551 @desc: Get the number of recv buffers currently queued into an HTC endpoint
552 @function name: HTCGetNumRecvBuffers
553 @input: HTCHandle - HTC handle
554 Endpoint - endpoint to check
555 @output:
556 @return: returns number of buffers in queue
557 @notes:
558 @example:
559 @see also:
560+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
561int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle,
562 HTC_ENDPOINT_ID Endpoint);
563
564/* internally used functions for testing... */
565void HTCEnableRecv(HTC_HANDLE HTCHandle);
566void HTCDisableRecv(HTC_HANDLE HTCHandle);
567int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle,
568 u32 TimeoutInMs,
569 bool *pbIsRecvPending);
570
571#ifdef __cplusplus
572}
573#endif
574
575#endif /* _HTC_API_H_ */
diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h
new file mode 100644
index 00000000000..ba65c34ebc9
--- /dev/null
+++ b/drivers/staging/ath6kl/include/htc_packet.h
@@ -0,0 +1,227 @@
1//------------------------------------------------------------------------------
2// <copyright file="htc_packet.h" company="Atheros">
3// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef HTC_PACKET_H_
24#define HTC_PACKET_H_
25
26
27#include "dl_list.h"
28
29/* ------ Endpoint IDS ------ */
30typedef enum
31{
32 ENDPOINT_UNUSED = -1,
33 ENDPOINT_0 = 0,
34 ENDPOINT_1 = 1,
35 ENDPOINT_2 = 2,
36 ENDPOINT_3,
37 ENDPOINT_4,
38 ENDPOINT_5,
39 ENDPOINT_6,
40 ENDPOINT_7,
41 ENDPOINT_8,
42 ENDPOINT_MAX,
43} HTC_ENDPOINT_ID;
44
45struct htc_packet;
46
47typedef void (* HTC_PACKET_COMPLETION)(void *,struct htc_packet *);
48
49typedef u16 HTC_TX_TAG;
50
51struct htc_tx_packet_info {
52 HTC_TX_TAG Tag; /* tag used to selective flush packets */
53 int CreditsUsed; /* number of credits used for this TX packet (HTC internal) */
54 u8 SendFlags; /* send flags (HTC internal) */
55 int SeqNo; /* internal seq no for debugging (HTC internal) */
56};
57
58#define HTC_TX_PACKET_TAG_ALL 0 /* a tag of zero is reserved and used to flush ALL packets */
59#define HTC_TX_PACKET_TAG_INTERNAL 1 /* internal tags start here */
60#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_TX_PACKET_TAG_INTERNAL + 9) /* user-defined tags start here */
61
62struct htc_rx_packet_info {
63 u32 ExpectedHdr; /* HTC internal use */
64 u32 HTCRxFlags; /* HTC internal use */
65 u32 IndicationFlags; /* indication flags set on each RX packet indication */
66};
67
68#define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) /* more packets on this endpoint are being fetched */
69
70/* wrapper around endpoint-specific packets */
71struct htc_packet {
72 struct dl_list ListLink; /* double link */
73 void *pPktContext; /* caller's per packet specific context */
74
75 u8 *pBufferStart; /* the true buffer start , the caller can
76 store the real buffer start here. In
77 receive callbacks, the HTC layer sets pBuffer
78 to the start of the payload past the header. This
79 field allows the caller to reset pBuffer when it
80 recycles receive packets back to HTC */
81 /*
82 * Pointer to the start of the buffer. In the transmit
83 * direction this points to the start of the payload. In the
84 * receive direction, however, the buffer when queued up
85 * points to the start of the HTC header but when returned
86 * to the caller points to the start of the payload
87 */
88 u8 *pBuffer; /* payload start (RX/TX) */
89 u32 BufferLength; /* length of buffer */
90 u32 ActualLength; /* actual length of payload */
91 HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */
92 int Status; /* completion status */
93 union {
94 struct htc_tx_packet_info AsTx; /* Tx Packet specific info */
95 struct htc_rx_packet_info AsRx; /* Rx Packet specific info */
96 } PktInfo;
97
98 /* the following fields are for internal HTC use */
99 HTC_PACKET_COMPLETION Completion; /* completion */
100 void *pContext; /* HTC private completion context */
101};
102
103
104
105#define COMPLETE_HTC_PACKET(p,status) \
106{ \
107 (p)->Status = (status); \
108 (p)->Completion((p)->pContext,(p)); \
109}
110
111#define INIT_HTC_PACKET_INFO(p,b,len) \
112{ \
113 (p)->pBufferStart = (b); \
114 (p)->BufferLength = (len); \
115}
116
117/* macro to set an initial RX packet for refilling HTC */
118#define SET_HTC_PACKET_INFO_RX_REFILL(p,c,b,len,ep) \
119{ \
120 (p)->pPktContext = (c); \
121 (p)->pBuffer = (b); \
122 (p)->pBufferStart = (b); \
123 (p)->BufferLength = (len); \
124 (p)->Endpoint = (ep); \
125}
126
127/* fast macro to recycle an RX packet that will be re-queued to HTC */
128#define HTC_PACKET_RESET_RX(p) \
129 { (p)->pBuffer = (p)->pBufferStart; (p)->ActualLength = 0; }
130
131/* macro to set packet parameters for TX */
132#define SET_HTC_PACKET_INFO_TX(p,c,b,len,ep,tag) \
133{ \
134 (p)->pPktContext = (c); \
135 (p)->pBuffer = (b); \
136 (p)->ActualLength = (len); \
137 (p)->Endpoint = (ep); \
138 (p)->PktInfo.AsTx.Tag = (tag); \
139}
140
141/* HTC Packet Queueing Macros */
142struct htc_packet_queue {
143 struct dl_list QueueHead;
144 int Depth;
145};
146
147/* initialize queue */
148#define INIT_HTC_PACKET_QUEUE(pQ) \
149{ \
150 DL_LIST_INIT(&(pQ)->QueueHead); \
151 (pQ)->Depth = 0; \
152}
153
154/* enqueue HTC packet to the tail of the queue */
155#define HTC_PACKET_ENQUEUE(pQ,p) \
156{ DL_ListInsertTail(&(pQ)->QueueHead,&(p)->ListLink); \
157 (pQ)->Depth++; \
158}
159
160/* enqueue HTC packet to the tail of the queue */
161#define HTC_PACKET_ENQUEUE_TO_HEAD(pQ,p) \
162{ DL_ListInsertHead(&(pQ)->QueueHead,&(p)->ListLink); \
163 (pQ)->Depth++; \
164}
165/* test if a queue is empty */
166#define HTC_QUEUE_EMPTY(pQ) ((pQ)->Depth == 0)
167/* get packet at head without removing it */
168static INLINE struct htc_packet *HTC_GET_PKT_AT_HEAD(struct htc_packet_queue *queue) {
169 if (queue->Depth == 0) {
170 return NULL;
171 }
172 return A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(&queue->QueueHead)),struct htc_packet,ListLink);
173}
174/* remove a packet from a queue, where-ever it is in the queue */
175#define HTC_PACKET_REMOVE(pQ,p) \
176{ \
177 DL_ListRemove(&(p)->ListLink); \
178 (pQ)->Depth--; \
179}
180
181/* dequeue an HTC packet from the head of the queue */
182static INLINE struct htc_packet *HTC_PACKET_DEQUEUE(struct htc_packet_queue *queue) {
183 struct dl_list *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead);
184 if (pItem != NULL) {
185 queue->Depth--;
186 return A_CONTAINING_STRUCT(pItem, struct htc_packet, ListLink);
187 }
188 return NULL;
189}
190
191/* dequeue an HTC packet from the tail of the queue */
192static INLINE struct htc_packet *HTC_PACKET_DEQUEUE_TAIL(struct htc_packet_queue *queue) {
193 struct dl_list *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead);
194 if (pItem != NULL) {
195 queue->Depth--;
196 return A_CONTAINING_STRUCT(pItem, struct htc_packet, ListLink);
197 }
198 return NULL;
199}
200
201#define HTC_PACKET_QUEUE_DEPTH(pQ) (pQ)->Depth
202
203
204#define HTC_GET_ENDPOINT_FROM_PKT(p) (p)->Endpoint
205#define HTC_GET_TAG_FROM_PKT(p) (p)->PktInfo.AsTx.Tag
206
207 /* transfer the packets from one queue to the tail of another queue */
208#define HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(pQDest,pQSrc) \
209{ \
210 DL_ListTransferItemsToTail(&(pQDest)->QueueHead,&(pQSrc)->QueueHead); \
211 (pQDest)->Depth += (pQSrc)->Depth; \
212 (pQSrc)->Depth = 0; \
213}
214
215 /* fast version to init and add a single packet to a queue */
216#define INIT_HTC_PACKET_QUEUE_AND_ADD(pQ,pP) \
217{ \
218 DL_LIST_INIT_AND_ADD(&(pQ)->QueueHead,&(pP)->ListLink) \
219 (pQ)->Depth = 1; \
220}
221
222#define HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pQ, pPTemp) \
223 ITERATE_OVER_LIST_ALLOW_REMOVE(&(pQ)->QueueHead,(pPTemp), struct htc_packet, ListLink)
224
225#define HTC_PACKET_QUEUE_ITERATE_END ITERATE_END
226
227#endif /*HTC_PACKET_H_*/
diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h
new file mode 100644
index 00000000000..9eea5875dd3
--- /dev/null
+++ b/drivers/staging/ath6kl/include/wlan_api.h
@@ -0,0 +1,128 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// This file contains the API for the host wlan module
21//
22// Author(s): ="Atheros"
23//==============================================================================
24#ifndef _HOST_WLAN_API_H_
25#define _HOST_WLAN_API_H_
26
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#include <a_osapi.h>
33
34struct ieee80211_node_table;
35struct ieee80211_frame;
36
37struct ieee80211_common_ie {
38 u16 ie_chan;
39 u8 *ie_tstamp;
40 u8 *ie_ssid;
41 u8 *ie_rates;
42 u8 *ie_xrates;
43 u8 *ie_country;
44 u8 *ie_wpa;
45 u8 *ie_rsn;
46 u8 *ie_wmm;
47 u8 *ie_ath;
48 u16 ie_capInfo;
49 u16 ie_beaconInt;
50 u8 *ie_tim;
51 u8 *ie_chswitch;
52 u8 ie_erp;
53 u8 *ie_wsc;
54 u8 *ie_htcap;
55 u8 *ie_htop;
56#ifdef WAPI_ENABLE
57 u8 *ie_wapi;
58#endif
59};
60
61typedef struct bss {
62 u8 ni_macaddr[6];
63 u8 ni_snr;
64 s16 ni_rssi;
65 struct bss *ni_list_next;
66 struct bss *ni_list_prev;
67 struct bss *ni_hash_next;
68 struct bss *ni_hash_prev;
69 struct ieee80211_common_ie ni_cie;
70 u8 *ni_buf;
71 u16 ni_framelen;
72 struct ieee80211_node_table *ni_table;
73 u32 ni_refcnt;
74 int ni_scangen;
75
76 u32 ni_tstamp;
77 u32 ni_actcnt;
78#ifdef OS_ROAM_MANAGEMENT
79 u32 ni_si_gen;
80#endif
81} bss_t;
82
83typedef void wlan_node_iter_func(void *arg, bss_t *);
84
85bss_t *wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size);
86void wlan_node_free(bss_t *ni);
87void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
88 const u8 *macaddr);
89bss_t *wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr);
90void wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni);
91void wlan_free_allnodes(struct ieee80211_node_table *nt);
92void wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
93 void *arg);
94
95void wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt);
96void wlan_node_table_reset(struct ieee80211_node_table *nt);
97void wlan_node_table_cleanup(struct ieee80211_node_table *nt);
98
99int wlan_parse_beacon(u8 *buf, int framelen,
100 struct ieee80211_common_ie *cie);
101
102u16 wlan_ieee2freq(int chan);
103u32 wlan_freq2ieee(u16 freq);
104
105void wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge);
106
107void
108wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt);
109
110bss_t *
111wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
112 u32 ssidLength, bool bIsWPA2, bool bMatchSSID);
113
114void
115wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni);
116
117bss_t *wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid);
118
119bss_t *
120wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
121 u32 ssidLength, u32 dot11AuthMode, u32 authMode,
122 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp);
123
124#ifdef __cplusplus
125}
126#endif
127
128#endif /* _HOST_WLAN_API_H_ */
diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h
new file mode 100644
index 00000000000..c8583e0c4a9
--- /dev/null
+++ b/drivers/staging/ath6kl/include/wmi_api.h
@@ -0,0 +1,441 @@
1//------------------------------------------------------------------------------
2// <copyright file="wmi_api.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains the definitions for the Wireless Module Interface (WMI).
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _WMI_API_H_
26#define _WMI_API_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32 /* WMI converts a dix frame with an ethernet payload (up to 1500 bytes)
33 * to an 802.3 frame (adds SNAP header) and adds on a WMI data header */
34#define WMI_MAX_TX_DATA_FRAME_LENGTH (1500 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
35
36 /* A normal WMI data frame */
37#define WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH (1500 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
38
39 /* An AMSDU frame */ /* The MAX AMSDU length of AR6003 is 3839 */
40#define WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH (3840 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
41
42/*
43 * IP QoS Field definitions according to 802.1p
44 */
45#define BEST_EFFORT_PRI 0
46#define BACKGROUND_PRI 1
47#define EXCELLENT_EFFORT_PRI 3
48#define CONTROLLED_LOAD_PRI 4
49#define VIDEO_PRI 5
50#define VOICE_PRI 6
51#define NETWORK_CONTROL_PRI 7
52#define MAX_NUM_PRI 8
53
54#define UNDEFINED_PRI (0xff)
55
56#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 /* 5 seconds */
57
58#define A_ROUND_UP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
59
60typedef enum {
61 ATHEROS_COMPLIANCE = 0x1,
62}TSPEC_PARAM_COMPLIANCE;
63
64struct wmi_t;
65
66void *wmi_init(void *devt);
67
68void wmi_qos_state_init(struct wmi_t *wmip);
69void wmi_shutdown(struct wmi_t *wmip);
70HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t * wmip);
71void wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid);
72u16 wmi_get_mapped_qos_queue(struct wmi_t *, u8 );
73int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf);
74int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS);
75int wmi_dot3_2_dix(void *osbuf);
76
77int wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf);
78int wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode);
79
80int wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf);
81int wmi_syncpoint(struct wmi_t *wmip);
82int wmi_syncpoint_reset(struct wmi_t *wmip);
83u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled);
84
85u8 wmi_determine_userPriority (u8 *pkt, u32 layer2Pri);
86
87int wmi_control_rx(struct wmi_t *wmip, void *osbuf);
88void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg);
89void wmi_free_allnodes(struct wmi_t *wmip);
90bss_t *wmi_find_node(struct wmi_t *wmip, const u8 *macaddr);
91void wmi_free_node(struct wmi_t *wmip, const u8 *macaddr);
92
93
94typedef enum {
95 NO_SYNC_WMIFLAG = 0,
96 SYNC_BEFORE_WMIFLAG, /* transmit all queued data before cmd */
97 SYNC_AFTER_WMIFLAG, /* any new data waits until cmd execs */
98 SYNC_BOTH_WMIFLAG,
99 END_WMIFLAG /* end marker */
100} WMI_SYNC_FLAG;
101
102int wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
103 WMI_SYNC_FLAG flag);
104
105int wmi_connect_cmd(struct wmi_t *wmip,
106 NETWORK_TYPE netType,
107 DOT11_AUTH_MODE dot11AuthMode,
108 AUTH_MODE authMode,
109 CRYPTO_TYPE pairwiseCrypto,
110 u8 pairwiseCryptoLen,
111 CRYPTO_TYPE groupCrypto,
112 u8 groupCryptoLen,
113 int ssidLength,
114 u8 *ssid,
115 u8 *bssid,
116 u16 channel,
117 u32 ctrl_flags);
118
119int wmi_reconnect_cmd(struct wmi_t *wmip,
120 u8 *bssid,
121 u16 channel);
122int wmi_disconnect_cmd(struct wmi_t *wmip);
123int wmi_getrev_cmd(struct wmi_t *wmip);
124int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
125 u32 forceFgScan, u32 isLegacy,
126 u32 homeDwellTime, u32 forceScanInterval,
127 s8 numChan, u16 *channelList);
128int wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec,
129 u16 fg_end_sec, u16 bg_sec,
130 u16 minact_chdw_msec,
131 u16 maxact_chdw_msec, u16 pas_chdw_msec,
132 u8 shScanRatio, u8 scanCtrlFlags,
133 u32 max_dfsch_act_time,
134 u16 maxact_scan_per_ssid);
135int wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask);
136int wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag,
137 u8 ssidLength, u8 *ssid);
138int wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons);
139int wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmisstime, u16 bmissbeacons);
140int wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType,
141 u8 ieLen, u8 *ieInfo);
142int wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode);
143int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl,
144 u16 atim_windows, u16 timeout_value);
145int wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time,
146 u32 ps_period, u8 sleep_period);
147int wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod,
148 u16 psPollNum, u16 dtimPolicy,
149 u16 wakup_tx_policy, u16 num_tx_to_wakeup,
150 u16 ps_fail_event_policy);
151int wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout);
152int wmi_sync_cmd(struct wmi_t *wmip, u8 syncNumber);
153int wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream);
154int wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 streamID);
155int wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask);
156int wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate);
157int wmi_get_bitrate_cmd(struct wmi_t *wmip);
158s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx);
159int wmi_get_regDomain_cmd(struct wmi_t *wmip);
160int wmi_get_channelList_cmd(struct wmi_t *wmip);
161int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam,
162 WMI_PHY_MODE mode, s8 numChan,
163 u16 *channelList);
164
165int wmi_set_snr_threshold_params(struct wmi_t *wmip,
166 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
167int wmi_set_rssi_threshold_params(struct wmi_t *wmip,
168 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
169int wmi_clr_rssi_snr(struct wmi_t *wmip);
170int wmi_set_lq_threshold_params(struct wmi_t *wmip,
171 WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd);
172int wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold);
173int wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy);
174
175int wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 bitmask);
176
177int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie,
178 u32 source);
179
180int wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask,
181 u16 tsr, bool rep, u16 size,
182 u32 valid);
183
184int wmi_get_stats_cmd(struct wmi_t *wmip);
185
186int wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex,
187 CRYPTO_TYPE keyType, u8 keyUsage,
188 u8 keyLength,u8 *keyRSC,
189 u8 *keyMaterial, u8 key_op_ctrl, u8 *mac,
190 WMI_SYNC_FLAG sync_flag);
191int wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk);
192int wmi_delete_krk_cmd(struct wmi_t *wmip);
193int wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex);
194int wmi_set_akmp_params_cmd(struct wmi_t *wmip,
195 WMI_SET_AKMP_PARAMS_CMD *akmpParams);
196int wmi_get_pmkid_list_cmd(struct wmi_t *wmip);
197int wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
198 WMI_SET_PMKID_LIST_CMD *pmkInfo);
199int wmi_abort_scan_cmd(struct wmi_t *wmip);
200int wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM);
201int wmi_get_txPwr_cmd(struct wmi_t *wmip);
202int wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid);
203int wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex);
204int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en);
205int wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId,
206 bool set);
207int wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop,
208 u8 eCWmin, u8 eCWmax,
209 u8 aifsn);
210int wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType,
211 u8 trafficClass, u8 maxRetries,
212 u8 enableNotify);
213
214void wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid);
215
216int wmi_get_roam_tbl_cmd(struct wmi_t *wmip);
217int wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType);
218int wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
219 u8 size);
220int wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
221 WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
222 u8 size);
223
224int wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode);
225int wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
226 u8 frmType,
227 u8 *dstMacAddr,
228 u8 *bssid,
229 u16 optIEDataLen,
230 u8 *optIEData);
231
232int wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl);
233int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize);
234int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSpLen);
235u8 convert_userPriority_to_trafficClass(u8 userPriority);
236u8 wmi_get_power_mode_cmd(struct wmi_t *wmip);
237int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance);
238
239#ifdef CONFIG_HOST_TCMD_SUPPORT
240int wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len);
241#endif
242
243int wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status);
244int wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd);
245
246int wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd);
247
248int wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
249 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd);
250
251int wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
252 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *cmd);
253
254int wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
255 WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd);
256
257int wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
258 WMI_SET_BTCOEX_A2DP_CONFIG_CMD* cmd);
259
260
261int wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD* cmd);
262
263int wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd);
264
265int wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
266 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd);
267
268int wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd);
269
270int wmi_get_btcoex_stats_cmd(struct wmi_t * wmip);
271
272int wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold);
273
274/*
275 * This function is used to configure the fix rates mask to the target.
276 */
277int wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask);
278int wmi_get_ratemask_cmd(struct wmi_t *wmip);
279
280int wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode);
281
282int wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode);
283
284int wmi_set_qos_supp_cmd(struct wmi_t *wmip,u8 status);
285int wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status);
286int wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable);
287int wmi_set_country(struct wmi_t *wmip, u8 *countryCode);
288
289int wmi_get_keepalive_configured(struct wmi_t *wmip);
290u8 wmi_get_keepalive_cmd(struct wmi_t *wmip);
291int wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval);
292
293int wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType,
294 u8 ieLen,u8 *ieInfo);
295
296int wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen);
297
298s32 wmi_get_rate(s8 rateindex);
299
300int wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd);
301
302/*Wake on Wireless WMI commands*/
303int wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *cmd);
304int wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd);
305int wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd);
306int wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
307 WMI_ADD_WOW_PATTERN_CMD *cmd, u8 *pattern, u8 *mask, u8 pattern_size);
308int wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
309 WMI_DEL_WOW_PATTERN_CMD *cmd);
310int wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status);
311
312int
313wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer);
314
315int
316wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4);
317
318int
319wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4);
320
321int
322wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable);
323
324bss_t *
325wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
326 u32 ssidLength, bool bIsWPA2, bool bMatchSSID);
327
328
329void
330wmi_node_return (struct wmi_t *wmip, bss_t *bss);
331
332void
333wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge);
334
335#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
336int wmi_prof_cfg_cmd(struct wmi_t *wmip, u32 period, u32 nbins);
337int wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr);
338int wmi_prof_start_cmd(struct wmi_t *wmip);
339int wmi_prof_stop_cmd(struct wmi_t *wmip);
340int wmi_prof_count_get_cmd(struct wmi_t *wmip);
341#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
342#ifdef OS_ROAM_MANAGEMENT
343void wmi_scan_indication (struct wmi_t *wmip);
344#endif
345
346int
347wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd);
348
349bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id);
350int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss);
351
352
353/*
354 * AP mode
355 */
356int
357wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p);
358
359int
360wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid);
361
362int
363wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta);
364
365int
366wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy);
367
368int
369wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *a);
370
371u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl);
372
373int
374wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason);
375
376int
377wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag);
378
379int
380wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period);
381
382int
383wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell);
384
385int
386wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim);
387
388int
389wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset);
390
391int
392wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd);
393
394int
395wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width);
396
397int
398wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz);
399
400int
401wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray);
402
403int
404wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid);
405
406int
407wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink);
408
409int
410wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask);
411
412int
413wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion, bool rxDot11Hdr, bool defragOnHost);
414
415int
416wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode);
417
418int
419wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence);
420
421int
422wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk);
423
424int
425wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd);
426
427u16 wmi_ieee2freq (int chan);
428
429u32 wmi_freq2ieee (u16 freq);
430
431bss_t *
432wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
433 u32 ssidLength,
434 u32 dot11AuthMode, u32 authMode,
435 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp);
436
437#ifdef __cplusplus
438}
439#endif
440
441#endif /* _WMI_API_H_ */
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c
new file mode 100644
index 00000000000..e0ea2183019
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c
@@ -0,0 +1,565 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// AR3K configuration implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#include "a_config.h"
26#include "athdefs.h"
27#include "a_osapi.h"
28#define ATH_MODULE_NAME misc
29#include "a_debug.h"
30#include "common_drv.h"
31#ifdef EXPORT_HCI_BRIDGE_INTERFACE
32#include "export_hci_transport.h"
33#else
34#include "hci_transport_api.h"
35#endif
36#include "ar3kconfig.h"
37#include "tlpm.h"
38
39#define BAUD_CHANGE_COMMAND_STATUS_OFFSET 5
40#define HCI_EVENT_RESP_TIMEOUTMS 3000
41#define HCI_CMD_OPCODE_BYTE_LOW_OFFSET 0
42#define HCI_CMD_OPCODE_BYTE_HI_OFFSET 1
43#define HCI_EVENT_OPCODE_BYTE_LOW 3
44#define HCI_EVENT_OPCODE_BYTE_HI 4
45#define HCI_CMD_COMPLETE_EVENT_CODE 0xE
46#define HCI_MAX_EVT_RECV_LENGTH 257
47#define EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET 5
48
49int AthPSInitialize(struct ar3k_config_info *hdev);
50
51static int SendHCICommand(struct ar3k_config_info *pConfig,
52 u8 *pBuffer,
53 int Length)
54{
55 struct htc_packet *pPacket = NULL;
56 int status = 0;
57
58 do {
59
60 pPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet));
61 if (NULL == pPacket) {
62 status = A_NO_MEMORY;
63 break;
64 }
65
66 A_MEMZERO(pPacket,sizeof(struct htc_packet));
67 SET_HTC_PACKET_INFO_TX(pPacket,
68 NULL,
69 pBuffer,
70 Length,
71 HCI_COMMAND_TYPE,
72 AR6K_CONTROL_PKT_TAG);
73
74 /* issue synchronously */
75 status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,true);
76
77 } while (false);
78
79 if (pPacket != NULL) {
80 kfree(pPacket);
81 }
82
83 return status;
84}
85
86static int RecvHCIEvent(struct ar3k_config_info *pConfig,
87 u8 *pBuffer,
88 int *pLength)
89{
90 int status = 0;
91 struct htc_packet *pRecvPacket = NULL;
92
93 do {
94
95 pRecvPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet));
96 if (NULL == pRecvPacket) {
97 status = A_NO_MEMORY;
98 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
99 break;
100 }
101
102 A_MEMZERO(pRecvPacket,sizeof(struct htc_packet));
103
104 SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE);
105
106 status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev,
107 pRecvPacket,
108 HCI_EVENT_RESP_TIMEOUTMS);
109 if (status) {
110 break;
111 }
112
113 *pLength = pRecvPacket->ActualLength;
114
115 } while (false);
116
117 if (pRecvPacket != NULL) {
118 kfree(pRecvPacket);
119 }
120
121 return status;
122}
123
124int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
125 u8 *pHCICommand,
126 int CmdLength,
127 u8 **ppEventBuffer,
128 u8 **ppBufferToFree)
129{
130 int status = 0;
131 u8 *pBuffer = NULL;
132 u8 *pTemp;
133 int length;
134 bool commandComplete = false;
135 u8 opCodeBytes[2];
136
137 do {
138
139 length = max(HCI_MAX_EVT_RECV_LENGTH,CmdLength);
140 length += pConfig->pHCIProps->HeadRoom + pConfig->pHCIProps->TailRoom;
141 length += pConfig->pHCIProps->IOBlockPad;
142
143 pBuffer = (u8 *)A_MALLOC(length);
144 if (NULL == pBuffer) {
145 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to allocate bt buffer \n"));
146 status = A_NO_MEMORY;
147 break;
148 }
149
150 /* get the opcodes to check the command complete event */
151 opCodeBytes[0] = pHCICommand[HCI_CMD_OPCODE_BYTE_LOW_OFFSET];
152 opCodeBytes[1] = pHCICommand[HCI_CMD_OPCODE_BYTE_HI_OFFSET];
153
154 /* copy HCI command */
155 memcpy(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength);
156 /* send command */
157 status = SendHCICommand(pConfig,
158 pBuffer + pConfig->pHCIProps->HeadRoom,
159 CmdLength);
160 if (status) {
161 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to send HCI Command (%d) \n", status));
162 AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
163 break;
164 }
165
166 /* reuse buffer to capture command complete event */
167 A_MEMZERO(pBuffer,length);
168 status = RecvHCIEvent(pConfig,pBuffer,&length);
169 if (status) {
170 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI event recv failed \n"));
171 AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
172 break;
173 }
174
175 pTemp = pBuffer + pConfig->pHCIProps->HeadRoom;
176 if (pTemp[0] == HCI_CMD_COMPLETE_EVENT_CODE) {
177 if ((pTemp[HCI_EVENT_OPCODE_BYTE_LOW] == opCodeBytes[0]) &&
178 (pTemp[HCI_EVENT_OPCODE_BYTE_HI] == opCodeBytes[1])) {
179 commandComplete = true;
180 }
181 }
182
183 if (!commandComplete) {
184 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Unexpected HCI event : %d \n",pTemp[0]));
185 AR_DEBUG_PRINTBUF(pTemp,pTemp[1],"Unexpected HCI event");
186 status = A_ECOMM;
187 break;
188 }
189
190 if (ppEventBuffer != NULL) {
191 /* caller wants to look at the event */
192 *ppEventBuffer = pTemp;
193 if (ppBufferToFree == NULL) {
194 status = A_EINVAL;
195 break;
196 }
197 /* caller must free the buffer */
198 *ppBufferToFree = pBuffer;
199 pBuffer = NULL;
200 }
201
202 } while (false);
203
204 if (pBuffer != NULL) {
205 kfree(pBuffer);
206 }
207
208 return status;
209}
210
211static int AR3KConfigureHCIBaud(struct ar3k_config_info *pConfig)
212{
213 int status = 0;
214 u8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0};
215 u16 baudVal;
216 u8 *pEvent = NULL;
217 u8 *pBufferToFree = NULL;
218
219 do {
220
221 if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR3K_BAUD) {
222 baudVal = (u16)(pConfig->AR3KBaudRate / 100);
223 hciBaudChangeCommand[3] = (u8)baudVal;
224 hciBaudChangeCommand[4] = (u8)(baudVal >> 8);
225
226 status = SendHCICommandWaitCommandComplete(pConfig,
227 hciBaudChangeCommand,
228 sizeof(hciBaudChangeCommand),
229 &pEvent,
230 &pBufferToFree);
231 if (status) {
232 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Baud rate change failed! \n"));
233 break;
234 }
235
236 if (pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET] != 0) {
237 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
238 ("AR3K Config: Baud change command event status failed: %d \n",
239 pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET]));
240 status = A_ECOMM;
241 break;
242 }
243
244 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
245 ("AR3K Config: Baud Changed to %d \n",pConfig->AR3KBaudRate));
246 }
247
248 if (pConfig->Flags & AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY) {
249 /* some versions of AR3K do not switch baud immediately, up to 300MS */
250 A_MDELAY(325);
251 }
252
253 if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP) {
254 /* Tell target to change UART baud rate for AR6K */
255 status = HCI_TransportSetBaudRate(pConfig->pHCIDev, pConfig->AR3KBaudRate);
256
257 if (status) {
258 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
259 ("AR3K Config: failed to set scale and step values: %d \n", status));
260 break;
261 }
262
263 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
264 ("AR3K Config: Baud changed to %d for AR6K\n", pConfig->AR3KBaudRate));
265 }
266
267 } while (false);
268
269 if (pBufferToFree != NULL) {
270 kfree(pBufferToFree);
271 }
272
273 return status;
274}
275
276static int AR3KExitMinBoot(struct ar3k_config_info *pConfig)
277{
278 int status;
279 char exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
280 0x00,0x00,0x00,0x00,0x00};
281 u8 *pEvent = NULL;
282 u8 *pBufferToFree = NULL;
283
284 status = SendHCICommandWaitCommandComplete(pConfig,
285 exitMinBootCmd,
286 sizeof(exitMinBootCmd),
287 &pEvent,
288 &pBufferToFree);
289
290 if (!status) {
291 if (pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET] != 0) {
292 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
293 ("AR3K Config: MinBoot exit command event status failed: %d \n",
294 pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET]));
295 status = A_ECOMM;
296 } else {
297 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
298 ("AR3K Config: MinBoot Exit Command Complete (Success) \n"));
299 A_MDELAY(1);
300 }
301 } else {
302 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: MinBoot Exit Failed! \n"));
303 }
304
305 if (pBufferToFree != NULL) {
306 kfree(pBufferToFree);
307 }
308
309 return status;
310}
311
312static int AR3KConfigureSendHCIReset(struct ar3k_config_info *pConfig)
313{
314 int status = 0;
315 u8 hciResetCommand[] = {0x03,0x0c,0x0};
316 u8 *pEvent = NULL;
317 u8 *pBufferToFree = NULL;
318
319 status = SendHCICommandWaitCommandComplete( pConfig,
320 hciResetCommand,
321 sizeof(hciResetCommand),
322 &pEvent,
323 &pBufferToFree );
324
325 if (status) {
326 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI reset failed! \n"));
327 }
328
329 if (pBufferToFree != NULL) {
330 kfree(pBufferToFree);
331 }
332
333 return status;
334}
335
336static int AR3KEnableTLPM(struct ar3k_config_info *pConfig)
337{
338 int status;
339 /* AR3K vendor specific command for Host Wakeup Config */
340 char hostWakeupConfig[] = {0x31,0xFC,0x18,
341 0x02,0x00,0x00,0x00,
342 0x01,0x00,0x00,0x00,
343 TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00, //idle timeout in ms
344 0x00,0x00,0x00,0x00,
345 TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00, //wakeup timeout in ms
346 0x00,0x00,0x00,0x00};
347 /* AR3K vendor specific command for Target Wakeup Config */
348 char targetWakeupConfig[] = {0x31,0xFC,0x18,
349 0x04,0x00,0x00,0x00,
350 0x01,0x00,0x00,0x00,
351 TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00, //idle timeout in ms
352 0x00,0x00,0x00,0x00,
353 TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00, //wakeup timeout in ms
354 0x00,0x00,0x00,0x00};
355 /* AR3K vendor specific command for Host Wakeup Enable */
356 char hostWakeupEnable[] = {0x31,0xFC,0x4,
357 0x01,0x00,0x00,0x00};
358 /* AR3K vendor specific command for Target Wakeup Enable */
359 char targetWakeupEnable[] = {0x31,0xFC,0x4,
360 0x06,0x00,0x00,0x00};
361 /* AR3K vendor specific command for Sleep Enable */
362 char sleepEnable[] = {0x4,0xFC,0x1,
363 0x1};
364 u8 *pEvent = NULL;
365 u8 *pBufferToFree = NULL;
366
367 if (0 != pConfig->IdleTimeout) {
368 u8 idle_lsb = pConfig->IdleTimeout & 0xFF;
369 u8 idle_msb = (pConfig->IdleTimeout & 0xFF00) >> 8;
370 hostWakeupConfig[11] = targetWakeupConfig[11] = idle_lsb;
371 hostWakeupConfig[12] = targetWakeupConfig[12] = idle_msb;
372 }
373
374 if (0 != pConfig->WakeupTimeout) {
375 hostWakeupConfig[19] = targetWakeupConfig[19] = (pConfig->WakeupTimeout & 0xFF);
376 }
377
378 status = SendHCICommandWaitCommandComplete(pConfig,
379 hostWakeupConfig,
380 sizeof(hostWakeupConfig),
381 &pEvent,
382 &pBufferToFree);
383 if (pBufferToFree != NULL) {
384 kfree(pBufferToFree);
385 }
386 if (status) {
387 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Config Failed! \n"));
388 return status;
389 }
390
391 pEvent = NULL;
392 pBufferToFree = NULL;
393 status = SendHCICommandWaitCommandComplete(pConfig,
394 targetWakeupConfig,
395 sizeof(targetWakeupConfig),
396 &pEvent,
397 &pBufferToFree);
398 if (pBufferToFree != NULL) {
399 kfree(pBufferToFree);
400 }
401 if (status) {
402 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Config Failed! \n"));
403 return status;
404 }
405
406 pEvent = NULL;
407 pBufferToFree = NULL;
408 status = SendHCICommandWaitCommandComplete(pConfig,
409 hostWakeupEnable,
410 sizeof(hostWakeupEnable),
411 &pEvent,
412 &pBufferToFree);
413 if (pBufferToFree != NULL) {
414 kfree(pBufferToFree);
415 }
416 if (status) {
417 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Enable Failed! \n"));
418 return status;
419 }
420
421 pEvent = NULL;
422 pBufferToFree = NULL;
423 status = SendHCICommandWaitCommandComplete(pConfig,
424 targetWakeupEnable,
425 sizeof(targetWakeupEnable),
426 &pEvent,
427 &pBufferToFree);
428 if (pBufferToFree != NULL) {
429 kfree(pBufferToFree);
430 }
431 if (status) {
432 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Enable Failed! \n"));
433 return status;
434 }
435
436 pEvent = NULL;
437 pBufferToFree = NULL;
438 status = SendHCICommandWaitCommandComplete(pConfig,
439 sleepEnable,
440 sizeof(sleepEnable),
441 &pEvent,
442 &pBufferToFree);
443 if (pBufferToFree != NULL) {
444 kfree(pBufferToFree);
445 }
446 if (status) {
447 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Sleep Enable Failed! \n"));
448 }
449
450 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Enable TLPM Completed (status = %d) \n",status));
451
452 return status;
453}
454
455int AR3KConfigure(struct ar3k_config_info *pConfig)
456{
457 int status = 0;
458
459 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuring AR3K ...\n"));
460
461 do {
462
463 if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) {
464 status = A_EINVAL;
465 break;
466 }
467
468 /* disable asynchronous recv while we issue commands and receive events synchronously */
469 status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false);
470 if (status) {
471 break;
472 }
473
474 if (pConfig->Flags & AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT) {
475 status = AR3KExitMinBoot(pConfig);
476 if (status) {
477 break;
478 }
479 }
480
481
482 /* Load patching and PST file if available*/
483 if (0 != AthPSInitialize(pConfig)) {
484 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch Download Failed!\n"));
485 }
486
487 /* Send HCI reset to make PS tags take effect*/
488 AR3KConfigureSendHCIReset(pConfig);
489
490 if (pConfig->Flags &
491 (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
492 status = AR3KConfigureHCIBaud(pConfig);
493 if (status) {
494 break;
495 }
496 }
497
498
499
500 if (pConfig->PwrMgmtEnabled) {
501 /* the delay is required after the previous HCI reset before further
502 * HCI commands can be issued
503 */
504 A_MDELAY(200);
505 AR3KEnableTLPM(pConfig);
506 }
507
508 /* re-enable asynchronous recv */
509 status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true);
510 if (status) {
511 break;
512 }
513
514
515 } while (false);
516
517
518 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuration Complete (status = %d) \n",status));
519
520 return status;
521}
522
523int AR3KConfigureExit(void *config)
524{
525 int status = 0;
526 struct ar3k_config_info *pConfig = (struct ar3k_config_info *)config;
527
528 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleaning up AR3K ...\n"));
529
530 do {
531
532 if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) {
533 status = A_EINVAL;
534 break;
535 }
536
537 /* disable asynchronous recv while we issue commands and receive events synchronously */
538 status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false);
539 if (status) {
540 break;
541 }
542
543 if (pConfig->Flags &
544 (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
545 status = AR3KConfigureHCIBaud(pConfig);
546 if (status) {
547 break;
548 }
549 }
550
551 /* re-enable asynchronous recv */
552 status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true);
553 if (status) {
554 break;
555 }
556
557
558 } while (false);
559
560
561 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleanup Complete (status = %d) \n",status));
562
563 return status;
564}
565
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c
new file mode 100644
index 00000000000..282ceac597b
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c
@@ -0,0 +1,572 @@
1/*
2 * Copyright (c) 2004-2010 Atheros Communications Inc.
3 * All rights reserved.
4 *
5 * This file implements the Atheros PS and patch downloaded for HCI UART Transport driver.
6 * This file can be used for HCI SDIO transport implementation for AR6002 with HCI_TRANSPORT_SDIO
7 * defined.
8 *
9 *
10 * ar3kcpsconfig.c
11 *
12 *
13 *
14 * The software source and binaries included in this development package are
15 * licensed, not sold. You, or your company, received the package under one
16 * or more license agreements. The rights granted to you are specifically
17 * listed in these license agreement(s). All other rights remain with Atheros
18 * Communications, Inc., its subsidiaries, or the respective owner including
19 * those listed on the included copyright notices.. Distribution of any
20 * portion of this package must be in strict compliance with the license
21 * agreement(s) terms.
22 *
23 *
24 *
25 */
26
27
28
29#include "ar3kpsconfig.h"
30#ifndef HCI_TRANSPORT_SDIO
31#include "hci_ath.h"
32#include "hci_uart.h"
33#endif /* #ifndef HCI_TRANSPORT_SDIO */
34
35#define MAX_FW_PATH_LEN 50
36#define MAX_BDADDR_FORMAT_LENGTH 30
37
38/*
39 * Structure used to send HCI packet, hci packet length and device info
40 * together as parameter to PSThread.
41 */
42typedef struct {
43
44 struct ps_cmd_packet *HciCmdList;
45 u32 num_packets;
46 struct ar3k_config_info *dev;
47}HciCommandListParam;
48
49int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
50 u8 *pHCICommand,
51 int CmdLength,
52 u8 **ppEventBuffer,
53 u8 **ppBufferToFree);
54
55u32 Rom_Version;
56u32 Build_Version;
57extern bool BDADDR;
58
59int getDeviceType(struct ar3k_config_info *pConfig, u32 *code);
60int ReadVersionInfo(struct ar3k_config_info *pConfig);
61#ifndef HCI_TRANSPORT_SDIO
62
63DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent);
64DECLARE_WAIT_QUEUE_HEAD(HciEvent);
65u8 *HciEventpacket;
66rwlock_t syncLock;
67wait_queue_t Eventwait;
68
69int PSHciWritepacket(struct hci_dev*,u8* Data, u32 len);
70extern char *bdaddr;
71#endif /* HCI_TRANSPORT_SDIO */
72
73int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type);
74
75int PSSendOps(void *arg);
76
77#ifdef BT_PS_DEBUG
78void Hci_log(u8 * log_string,u8 *data,u32 len)
79{
80 int i;
81 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s : ",log_string));
82 for (i = 0; i < len; i++) {
83 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("0x%02x ", data[i]));
84 }
85 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n...................................\n"));
86}
87#else
88#define Hci_log(string,data,len)
89#endif /* BT_PS_DEBUG */
90
91
92
93
94int AthPSInitialize(struct ar3k_config_info *hdev)
95{
96 int status = 0;
97 if(hdev == NULL) {
98 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Device handle received\n"));
99 return A_ERROR;
100 }
101
102#ifndef HCI_TRANSPORT_SDIO
103 DECLARE_WAITQUEUE(wait, current);
104#endif /* HCI_TRANSPORT_SDIO */
105
106
107#ifdef HCI_TRANSPORT_SDIO
108 status = PSSendOps((void*)hdev);
109#else
110 if(InitPSState(hdev) == -1) {
111 return A_ERROR;
112 }
113 allow_signal(SIGKILL);
114 add_wait_queue(&PsCompleteEvent,&wait);
115 set_current_state(TASK_INTERRUPTIBLE);
116 if(!kernel_thread(PSSendOps,(void*)hdev,CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD)) {
117 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Kthread Failed\n"));
118 remove_wait_queue(&PsCompleteEvent,&wait);
119 return A_ERROR;
120 }
121 wait_event_interruptible(PsCompleteEvent,(PSTagMode == false));
122 set_current_state(TASK_RUNNING);
123 remove_wait_queue(&PsCompleteEvent,&wait);
124
125#endif /* HCI_TRANSPORT_SDIO */
126
127
128 return status;
129
130}
131
132int PSSendOps(void *arg)
133{
134 int i;
135 int status = 0;
136 struct ps_cmd_packet *HciCmdList; /* List storing the commands */
137 const struct firmware* firmware;
138 u32 numCmds;
139 u8 *event;
140 u8 *bufferToFree;
141 struct hci_dev *device;
142 u8 *buffer;
143 u32 len;
144 u32 DevType;
145 u8 *PsFileName;
146 u8 *patchFileName;
147 u8 *path = NULL;
148 u8 *config_path = NULL;
149 u8 config_bdaddr[MAX_BDADDR_FORMAT_LENGTH];
150 struct ar3k_config_info *hdev = (struct ar3k_config_info*)arg;
151 struct device *firmwareDev = NULL;
152 status = 0;
153 HciCmdList = NULL;
154#ifdef HCI_TRANSPORT_SDIO
155 device = hdev->pBtStackHCIDev;
156 firmwareDev = device->parent;
157#else
158 device = hdev;
159 firmwareDev = &device->dev;
160 AthEnableSyncCommandOp(true);
161#endif /* HCI_TRANSPORT_SDIO */
162 /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different.
163 */
164
165 path =(u8 *)A_MALLOC(MAX_FW_PATH_LEN);
166 if(path == NULL) {
167 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN));
168 goto complete;
169 }
170 config_path = (u8 *) A_MALLOC(MAX_FW_PATH_LEN);
171 if(config_path == NULL) {
172 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN));
173 goto complete;
174 }
175
176 if(A_ERROR == getDeviceType(hdev,&DevType)) {
177 status = 1;
178 goto complete;
179 }
180 if(A_ERROR == ReadVersionInfo(hdev)) {
181 status = 1;
182 goto complete;
183 }
184
185 patchFileName = PATCH_FILE;
186 snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version);
187 if(DevType){
188 if(DevType == 0xdeadc0de){
189 PsFileName = PS_ASIC_FILE;
190 } else{
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x \n",Rom_Version,Build_Version));
192 if((Rom_Version == 0x99999999) && (Build_Version == 1)){
193
194 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n"));
195 patchFileName = NULL;
196 }
197 PsFileName = PS_FPGA_FILE;
198 }
199 }
200 else{
201 PsFileName = PS_ASIC_FILE;
202 }
203
204 snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName);
205 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path));
206 /* Read the PS file to a dynamically allocated buffer */
207 if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
208 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
209 status = 1;
210 goto complete;
211
212 }
213 if(NULL == firmware || firmware->size == 0) {
214 status = 1;
215 goto complete;
216 }
217 buffer = (u8 *)A_MALLOC(firmware->size);
218 if(buffer != NULL) {
219 /* Copy the read file to a local Dynamic buffer */
220 memcpy(buffer,firmware->data,firmware->size);
221 len = firmware->size;
222 A_RELEASE_FIRMWARE(firmware);
223 /* Parse the PS buffer to a global variable */
224 status = AthDoParsePS(buffer,len);
225 kfree(buffer);
226 } else {
227 A_RELEASE_FIRMWARE(firmware);
228 }
229
230
231 /* Read the patch file to a dynamically allocated buffer */
232 if(patchFileName != NULL)
233 snprintf(config_path,
234 MAX_FW_PATH_LEN, "%s%s",path,patchFileName);
235 else {
236 status = 0;
237 }
238 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
239 if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) {
240 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
241 /*
242 * It is not necessary that Patch file be available, continue with PS Operations if.
243 * failed.
244 */
245 status = 0;
246
247 } else {
248 if(NULL == firmware || firmware->size == 0) {
249 status = 0;
250 } else {
251 buffer = (u8 *)A_MALLOC(firmware->size);
252 if(buffer != NULL) {
253 /* Copy the read file to a local Dynamic buffer */
254 memcpy(buffer,firmware->data,firmware->size);
255 len = firmware->size;
256 A_RELEASE_FIRMWARE(firmware);
257 /* parse and store the Patch file contents to a global variables */
258 status = AthDoParsePatch(buffer,len);
259 kfree(buffer);
260 } else {
261 A_RELEASE_FIRMWARE(firmware);
262 }
263 }
264 }
265
266 /* Create an HCI command list from the parsed PS and patch information */
267 AthCreateCommandList(&HciCmdList,&numCmds);
268
269 /* Form the parameter for PSSendOps() API */
270
271
272 /*
273 * First Send the CRC packet,
274 * We have to continue with the PS operations only if the CRC packet has been replied with
275 * a Command complete event with status Error.
276 */
277
278 if(SendHCICommandWaitCommandComplete
279 (hdev,
280 HciCmdList[0].Hcipacket,
281 HciCmdList[0].packetLen,
282 &event,
283 &bufferToFree) == 0) {
284 if(ReadPSEvent(event) == 0) { /* Exit if the status is success */
285 if(bufferToFree != NULL) {
286 kfree(bufferToFree);
287 }
288
289#ifndef HCI_TRANSPORT_SDIO
290 if(bdaddr && bdaddr[0] !='\0') {
291 write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
292 }
293#endif
294 status = 1;
295 goto complete;
296 }
297 if(bufferToFree != NULL) {
298 kfree(bufferToFree);
299 }
300 } else {
301 status = 0;
302 goto complete;
303 }
304
305 for(i = 1; i <numCmds; i++) {
306
307 if(SendHCICommandWaitCommandComplete
308 (hdev,
309 HciCmdList[i].Hcipacket,
310 HciCmdList[i].packetLen,
311 &event,
312 &bufferToFree) == 0) {
313 if(ReadPSEvent(event) != 0) { /* Exit if the status is success */
314 if(bufferToFree != NULL) {
315 kfree(bufferToFree);
316 }
317 status = 1;
318 goto complete;
319 }
320 if(bufferToFree != NULL) {
321 kfree(bufferToFree);
322 }
323 } else {
324 status = 0;
325 goto complete;
326 }
327 }
328#ifdef HCI_TRANSPORT_SDIO
329 if(BDADDR == false)
330 if(hdev->bdaddr[0] !=0x00 ||
331 hdev->bdaddr[1] !=0x00 ||
332 hdev->bdaddr[2] !=0x00 ||
333 hdev->bdaddr[3] !=0x00 ||
334 hdev->bdaddr[4] !=0x00 ||
335 hdev->bdaddr[5] !=0x00)
336 write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX);
337
338#ifndef HCI_TRANSPORT_SDIO
339
340 if(bdaddr && bdaddr[0] != '\0') {
341 write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
342 } else
343#endif /* HCI_TRANSPORT_SDIO */
344 /* Write BDADDR Read from OTP here */
345
346
347
348#endif
349
350 {
351 /* Read Contents of BDADDR file if user has not provided any option */
352 snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE);
353 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
354 if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
355 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
356 status = 1;
357 goto complete;
358 }
359 if(NULL == firmware || firmware->size == 0) {
360 status = 1;
361 goto complete;
362 }
363 len = min_t(size_t, firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1);
364 memcpy(config_bdaddr, firmware->data, len);
365 config_bdaddr[len] = '\0';
366 write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING);
367 A_RELEASE_FIRMWARE(firmware);
368 }
369complete:
370#ifndef HCI_TRANSPORT_SDIO
371 AthEnableSyncCommandOp(false);
372 PSTagMode = false;
373 wake_up_interruptible(&PsCompleteEvent);
374#endif /* HCI_TRANSPORT_SDIO */
375 if(NULL != HciCmdList) {
376 AthFreeCommandList(&HciCmdList,numCmds);
377 }
378 if(path) {
379 kfree(path);
380 }
381 if(config_path) {
382 kfree(config_path);
383 }
384 return status;
385}
386#ifndef HCI_TRANSPORT_SDIO
387/*
388 * This API is used to send the HCI command to controller and return
389 * with a HCI Command Complete event.
390 * For HCI SDIO transport, this will be internally defined.
391 */
392int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
393 u8 *pHCICommand,
394 int CmdLength,
395 u8 **ppEventBuffer,
396 u8 **ppBufferToFree)
397{
398 if(CmdLength == 0) {
399 return A_ERROR;
400 }
401 Hci_log("COM Write -->",pHCICommand,CmdLength);
402 PSAcked = false;
403 if(PSHciWritepacket(pConfig,pHCICommand,CmdLength) == 0) {
404 /* If the controller is not available, return Error */
405 return A_ERROR;
406 }
407 //add_timer(&psCmdTimer);
408 wait_event_interruptible(HciEvent,(PSAcked == true));
409 if(NULL != HciEventpacket) {
410 *ppEventBuffer = HciEventpacket;
411 *ppBufferToFree = HciEventpacket;
412 } else {
413 /* Did not get an event from controller. return error */
414 *ppBufferToFree = NULL;
415 return A_ERROR;
416 }
417
418 return 0;
419}
420#endif /* HCI_TRANSPORT_SDIO */
421
422int ReadPSEvent(u8* Data){
423 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" PS Event %x %x %x\n",Data[4],Data[5],Data[3]));
424
425 if(Data[4] == 0xFC && Data[5] == 0x00)
426 {
427 switch(Data[3]){
428 case 0x0B:
429 return 0;
430 break;
431 case 0x0C:
432 /* Change Baudrate */
433 return 0;
434 break;
435 case 0x04:
436 return 0;
437 break;
438 case 0x1E:
439 Rom_Version = Data[9];
440 Rom_Version = ((Rom_Version << 8) |Data[8]);
441 Rom_Version = ((Rom_Version << 8) |Data[7]);
442 Rom_Version = ((Rom_Version << 8) |Data[6]);
443
444 Build_Version = Data[13];
445 Build_Version = ((Build_Version << 8) |Data[12]);
446 Build_Version = ((Build_Version << 8) |Data[11]);
447 Build_Version = ((Build_Version << 8) |Data[10]);
448 return 0;
449 break;
450
451
452 }
453 }
454
455 return A_ERROR;
456}
457int str2ba(unsigned char *str_bdaddr,unsigned char *bdaddr)
458{
459 unsigned char bdbyte[3];
460 unsigned char *str_byte = str_bdaddr;
461 int i,j;
462 unsigned char colon_present = 0;
463
464 if(NULL != strstr(str_bdaddr,":")) {
465 colon_present = 1;
466 }
467
468
469 bdbyte[2] = '\0';
470
471 for( i = 0,j = 5; i < 6; i++, j--) {
472 bdbyte[0] = str_byte[0];
473 bdbyte[1] = str_byte[1];
474 bdaddr[j] = A_STRTOL(bdbyte,NULL,16);
475 if(colon_present == 1) {
476 str_byte+=3;
477 } else {
478 str_byte+=2;
479 }
480 }
481 return 0;
482}
483
484int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type)
485{
486 u8 bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01,
487 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
488
489 u8 *event;
490 u8 *bufferToFree = NULL;
491 int result = A_ERROR;
492 int inc,outc;
493
494 if (type == BDADDR_TYPE_STRING)
495 str2ba(bdaddr,&bdaddr_cmd[7]);
496 else {
497 /* Bdaddr has to be sent as LAP first */
498 for(inc = 5 ,outc = 7; inc >=0; inc--, outc++)
499 bdaddr_cmd[outc] = bdaddr[inc];
500 }
501
502 if(0 == SendHCICommandWaitCommandComplete(pConfig,bdaddr_cmd,
503 sizeof(bdaddr_cmd),
504 &event,&bufferToFree)) {
505
506 if(event[4] == 0xFC && event[5] == 0x00){
507 if(event[3] == 0x0B){
508 result = 0;
509 }
510 }
511
512 }
513 if(bufferToFree != NULL) {
514 kfree(bufferToFree);
515 }
516 return result;
517
518}
519int ReadVersionInfo(struct ar3k_config_info *pConfig)
520{
521 u8 hciCommand[] = {0x1E,0xfc,0x00};
522 u8 *event;
523 u8 *bufferToFree = NULL;
524 int result = A_ERROR;
525 if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
526 result = ReadPSEvent(event);
527
528 }
529 if(bufferToFree != NULL) {
530 kfree(bufferToFree);
531 }
532 return result;
533}
534int getDeviceType(struct ar3k_config_info *pConfig, u32 *code)
535{
536 u8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04};
537 u8 *event;
538 u8 *bufferToFree = NULL;
539 u32 reg;
540 int result = A_ERROR;
541 *code = 0;
542 hciCommand[3] = (u8)(FPGA_REGISTER & 0xFF);
543 hciCommand[4] = (u8)((FPGA_REGISTER >> 8) & 0xFF);
544 hciCommand[5] = (u8)((FPGA_REGISTER >> 16) & 0xFF);
545 hciCommand[6] = (u8)((FPGA_REGISTER >> 24) & 0xFF);
546 if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
547
548 if(event[4] == 0xFC && event[5] == 0x00){
549 switch(event[3]){
550 case 0x05:
551 reg = event[9];
552 reg = ((reg << 8) |event[8]);
553 reg = ((reg << 8) |event[7]);
554 reg = ((reg << 8) |event[6]);
555 *code = reg;
556 result = 0;
557
558 break;
559 case 0x06:
560 //Sleep(500);
561 break;
562 }
563 }
564
565 }
566 if(bufferToFree != NULL) {
567 kfree(bufferToFree);
568 }
569 return result;
570}
571
572
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h
new file mode 100644
index 00000000000..d4435130780
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h
@@ -0,0 +1,75 @@
1/*
2 * Copyright (c) 2004-2010 Atheros Communications Inc.
3 * All rights reserved.
4 *
5 * This file defines the symbols exported by Atheros PS and patch download module.
6 * define the constant HCI_TRANSPORT_SDIO if the module is being used for HCI SDIO transport.
7 * defined.
8 *
9 *
10 * ar3kcpsconfig.h
11 *
12 *
13 *
14 * The software source and binaries included in this development package are
15 * licensed, not sold. You, or your company, received the package under one
16 * or more license agreements. The rights granted to you are specifically
17 * listed in these license agreement(s). All other rights remain with Atheros
18 * Communications, Inc., its subsidiaries, or the respective owner including
19 * those listed on the included copyright notices.. Distribution of any
20 * portion of this package must be in strict compliance with the license
21 * agreement(s) terms.
22 *
23 *
24 *
25 */
26
27
28
29#ifndef __AR3KPSCONFIG_H
30#define __AR3KPSCONFIG_H
31
32/*
33 * Define the flag HCI_TRANSPORT_SDIO and undefine HCI_TRANSPORT_UART if the transport being used is SDIO.
34 */
35#undef HCI_TRANSPORT_UART
36
37#include <linux/fs.h>
38#include <linux/errno.h>
39#include <linux/signal.h>
40
41
42#include <linux/ioctl.h>
43#include <linux/firmware.h>
44
45
46#include <net/bluetooth/bluetooth.h>
47#include <net/bluetooth/hci_core.h>
48
49#include "ar3kpsparser.h"
50
51#define FPGA_REGISTER 0x4FFC
52#define BDADDR_TYPE_STRING 0
53#define BDADDR_TYPE_HEX 1
54#define CONFIG_PATH "ar3k"
55
56#define PS_ASIC_FILE "PS_ASIC.pst"
57#define PS_FPGA_FILE "PS_FPGA.pst"
58
59#define PATCH_FILE "RamPatch.txt"
60#define BDADDR_FILE "ar3kbdaddr.pst"
61
62#define ROM_VER_AR3001_3_1_0 30000
63#define ROM_VER_AR3001_3_1_1 30101
64
65
66#ifndef HCI_TRANSPORT_SDIO
67#define struct ar3k_config_info struct hci_dev
68extern wait_queue_head_t HciEvent;
69extern wait_queue_t Eventwait;
70extern u8 *HciEventpacket;
71#endif /* #ifndef HCI_TRANSPORT_SDIO */
72
73int AthPSInitialize(struct ar3k_config_info *hdev);
74int ReadPSEvent(u8* Data);
75#endif /* __AR3KPSCONFIG_H */
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
new file mode 100644
index 00000000000..b99a11a9dd6
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
@@ -0,0 +1,969 @@
1/*
2 * Copyright (c) 2004-2010 Atheros Communications Inc.
3 * All rights reserved.
4 *
5 * This file implements the Atheros PS and patch parser.
6 * It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands.
7 *
8 *
9 *
10 * ar3kpsparser.c
11 *
12 *
13 *
14 * The software source and binaries included in this development package are
15 * licensed, not sold. You, or your company, received the package under one
16 * or more license agreements. The rights granted to you are specifically
17 * listed in these license agreement(s). All other rights remain with Atheros
18 * Communications, Inc., its subsidiaries, or the respective owner including
19 * those listed on the included copyright notices.. Distribution of any
20 * portion of this package must be in strict compliance with the license
21 * agreement(s) terms.
22 *
23 *
24 *
25 */
26
27
28#include "ar3kpsparser.h"
29
30#include <linux/ctype.h>
31#include <linux/kernel.h>
32
33#define BD_ADDR_SIZE 6
34#define WRITE_PATCH 8
35#define ENABLE_PATCH 11
36#define PS_RESET 2
37#define PS_WRITE 1
38#define PS_VERIFY_CRC 9
39#define CHANGE_BDADDR 15
40
41#define HCI_COMMAND_HEADER 7
42
43#define HCI_EVENT_SIZE 7
44
45#define WRITE_PATCH_COMMAND_STATUS_OFFSET 5
46
47#define PS_RAM_SIZE 2048
48
49#define RAM_PS_REGION (1<<0)
50#define RAM_PATCH_REGION (1<<1)
51#define RAMPS_MAX_PS_DATA_PER_TAG 20000
52#define MAX_RADIO_CFG_TABLE_SIZE 244
53#define RAMPS_MAX_PS_TAGS_PER_FILE 50
54
55#define PS_MAX_LEN 500
56#define LINE_SIZE_MAX (PS_MAX_LEN *2)
57
58/* Constant values used by parser */
59#define BYTES_OF_PS_DATA_PER_LINE 16
60#define RAMPS_MAX_PS_DATA_PER_TAG 20000
61
62
63/* Number pf PS/Patch entries in an HCI packet */
64#define MAX_BYTE_LENGTH 244
65
66#define SKIP_BLANKS(str) while (*str == ' ') str++
67
68enum MinBootFileFormatE
69{
70 MB_FILEFORMAT_RADIOTBL,
71 MB_FILEFORMAT_PATCH,
72 MB_FILEFORMAT_COEXCONFIG
73};
74
75enum RamPsSection
76{
77 RAM_PS_SECTION,
78 RAM_PATCH_SECTION,
79 RAM_DYN_MEM_SECTION
80};
81
82enum eType {
83 eHex,
84 edecimal
85};
86
87
88typedef struct tPsTagEntry
89{
90 u32 TagId;
91 u32 TagLen;
92 u8 *TagData;
93} tPsTagEntry, *tpPsTagEntry;
94
95typedef struct tRamPatch
96{
97 u16 Len;
98 u8 *Data;
99} tRamPatch, *ptRamPatch;
100
101
102
103struct st_ps_data_format {
104 enum eType eDataType;
105 bool bIsArray;
106};
107
108struct st_read_status {
109 unsigned uTagID;
110 unsigned uSection;
111 unsigned uLineCount;
112 unsigned uCharCount;
113 unsigned uByteCount;
114};
115
116
117/* Stores the number of PS Tags */
118static u32 Tag_Count = 0;
119
120/* Stores the number of patch commands */
121static u32 Patch_Count = 0;
122static u32 Total_tag_lenght = 0;
123bool BDADDR = false;
124u32 StartTagId;
125
126tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE];
127tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY];
128
129
130int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat);
131char AthReadChar(u8 *buffer, u32 len,u32 *pos);
132char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos);
133static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,struct ps_cmd_packet *PSPatchPacket,u32 *index);
134
135/* Function to reads the next character from the input buffer */
136char AthReadChar(u8 *buffer, u32 len,u32 *pos)
137{
138 char Ch;
139 if(buffer == NULL || *pos >=len )
140 {
141 return '\0';
142 } else {
143 Ch = buffer[*pos];
144 (*pos)++;
145 return Ch;
146 }
147}
148/* PS parser helper function */
149unsigned int uGetInputDataFormat(char *pCharLine, struct st_ps_data_format *pstFormat)
150{
151 if(pCharLine[0] != '[') {
152 pstFormat->eDataType = eHex;
153 pstFormat->bIsArray = true;
154 return 0;
155 }
156 switch(pCharLine[1]) {
157 case 'H':
158 case 'h':
159 if(pCharLine[2]==':') {
160 if((pCharLine[3]== 'a') || (pCharLine[3]== 'A')) {
161 if(pCharLine[4] == ']') {
162 pstFormat->eDataType = eHex;
163 pstFormat->bIsArray = true;
164 pCharLine += 5;
165 return 0;
166 }
167 else {
168 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A
169 return 1;
170 }
171 }
172 if((pCharLine[3]== 'S') || (pCharLine[3]== 's')) {
173 if(pCharLine[4] == ']') {
174 pstFormat->eDataType = eHex;
175 pstFormat->bIsArray = false;
176 pCharLine += 5;
177 return 0;
178 }
179 else {
180 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A
181 return 1;
182 }
183 }
184 else if(pCharLine[3] == ']') { //[H:]
185 pstFormat->eDataType = eHex;
186 pstFormat->bIsArray = true;
187 pCharLine += 4;
188 return 0;
189 }
190 else { //[H:
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n"));
192 return 1;
193 }
194 }
195 else if(pCharLine[2]==']') { //[H]
196 pstFormat->eDataType = eHex;
197 pstFormat->bIsArray = true;
198 pCharLine += 3;
199 return 0;
200 }
201 else { //[H
202 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n"));
203 return 1;
204 }
205 break;
206
207 case 'A':
208 case 'a':
209 if(pCharLine[2]==':') {
210 if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) {
211 if(pCharLine[4] == ']') {
212 pstFormat->eDataType = eHex;
213 pstFormat->bIsArray = true;
214 pCharLine += 5;
215 return 0;
216 }
217 else {
218 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 1\n")); //[A:H
219 return 1;
220 }
221 }
222 else if(pCharLine[3]== ']') { //[A:]
223 pstFormat->eDataType = eHex;
224 pstFormat->bIsArray = true;
225 pCharLine += 4;
226 return 0;
227 }
228 else { //[A:
229 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 2\n"));
230 return 1;
231 }
232 }
233 else if(pCharLine[2]==']') { //[H]
234 pstFormat->eDataType = eHex;
235 pstFormat->bIsArray = true;
236 pCharLine += 3;
237 return 0;
238 }
239 else { //[H
240 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 3\n"));
241 return 1;
242 }
243 break;
244
245 case 'S':
246 case 's':
247 if(pCharLine[2]==':') {
248 if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) {
249 if(pCharLine[4] == ']') {
250 pstFormat->eDataType = eHex;
251 pstFormat->bIsArray = true;
252 pCharLine += 5;
253 return 0;
254 }
255 else {
256 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 5\n")); //[A:H
257 return 1;
258 }
259 }
260 else if(pCharLine[3]== ']') { //[A:]
261 pstFormat->eDataType = eHex;
262 pstFormat->bIsArray = true;
263 pCharLine += 4;
264 return 0;
265 }
266 else { //[A:
267 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 6\n"));
268 return 1;
269 }
270 }
271 else if(pCharLine[2]==']') { //[H]
272 pstFormat->eDataType = eHex;
273 pstFormat->bIsArray = true;
274 pCharLine += 3;
275 return 0;
276 }
277 else { //[H
278 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 7\n"));
279 return 1;
280 }
281 break;
282
283 default:
284 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 8\n"));
285 return 1;
286 }
287}
288
289unsigned int uReadDataInSection(char *pCharLine, struct st_ps_data_format stPS_DataFormat)
290{
291 char *pTokenPtr = pCharLine;
292
293 if(pTokenPtr[0] == '[') {
294 while(pTokenPtr[0] != ']' && pTokenPtr[0] != '\0') {
295 pTokenPtr++;
296 }
297 if(pTokenPtr[0] == '\0') {
298 return (0x0FFF);
299 }
300 pTokenPtr++;
301
302
303 }
304 if(stPS_DataFormat.eDataType == eHex) {
305 if(stPS_DataFormat.bIsArray == true) {
306 //Not implemented
307 return (0x0FFF);
308 }
309 else {
310 return (A_STRTOL(pTokenPtr, NULL, 16));
311 }
312 }
313 else {
314 //Not implemented
315 return (0x0FFF);
316 }
317}
318int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat)
319{
320 char *Buffer;
321 char *pCharLine;
322 u8 TagCount;
323 u16 ByteCount;
324 u8 ParseSection=RAM_PS_SECTION;
325 u32 pos;
326
327
328
329 int uReadCount;
330 struct st_ps_data_format stPS_DataFormat;
331 struct st_read_status stReadStatus = {0, 0, 0,0};
332 pos = 0;
333 Buffer = NULL;
334
335 if (srcbuffer == NULL || srclen == 0)
336 {
337 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Could not open .\n"));
338 return A_ERROR;
339 }
340 TagCount = 0;
341 ByteCount = 0;
342 Buffer = A_MALLOC(LINE_SIZE_MAX + 1);
343 if(NULL == Buffer) {
344 return A_ERROR;
345 }
346 if (FileFormat == MB_FILEFORMAT_PATCH)
347 {
348 int LineRead = 0;
349 while((pCharLine = AthGetLine(Buffer, LINE_SIZE_MAX, srcbuffer,srclen,&pos)) != NULL)
350 {
351
352 SKIP_BLANKS(pCharLine);
353
354 // Comment line or empty line
355 if ((pCharLine[0] == '/') && (pCharLine[1] == '/'))
356 {
357 continue;
358 }
359
360 if ((pCharLine[0] == '#')) {
361 if (stReadStatus.uSection != 0)
362 {
363 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("error\n"));
364 if(Buffer != NULL) {
365 kfree(Buffer);
366 }
367 return A_ERROR;
368 }
369 else {
370 stReadStatus.uSection = 1;
371 continue;
372 }
373 }
374 if ((pCharLine[0] == '/') && (pCharLine[1] == '*'))
375 {
376 pCharLine+=2;
377 SKIP_BLANKS(pCharLine);
378
379 if(!strncmp(pCharLine,"PA",2)||!strncmp(pCharLine,"Pa",2)||!strncmp(pCharLine,"pa",2))
380 ParseSection=RAM_PATCH_SECTION;
381
382 if(!strncmp(pCharLine,"DY",2)||!strncmp(pCharLine,"Dy",2)||!strncmp(pCharLine,"dy",2))
383 ParseSection=RAM_DYN_MEM_SECTION;
384
385 if(!strncmp(pCharLine,"PS",2)||!strncmp(pCharLine,"Ps",2)||!strncmp(pCharLine,"ps",2))
386 ParseSection=RAM_PS_SECTION;
387
388 LineRead = 0;
389 stReadStatus.uSection = 0;
390
391 continue;
392 }
393
394 switch(ParseSection)
395 {
396 case RAM_PS_SECTION:
397 {
398 if (stReadStatus.uSection == 1) //TagID
399 {
400 SKIP_BLANKS(pCharLine);
401 if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
402 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail\n"));
403 if(Buffer != NULL) {
404 kfree(Buffer);
405 }
406 return A_ERROR;
407 }
408 //pCharLine +=5;
409 PsTagEntry[TagCount].TagId = uReadDataInSection(pCharLine, stPS_DataFormat);
410 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG ID %d \n",PsTagEntry[TagCount].TagId));
411
412 //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag # %x\n", PsTagEntry[TagCount].TagId);
413 if (TagCount == 0)
414 {
415 StartTagId = PsTagEntry[TagCount].TagId;
416 }
417 stReadStatus.uSection = 2;
418 }
419 else if (stReadStatus.uSection == 2) //TagLength
420 {
421
422 if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
423 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail \n"));
424 if(Buffer != NULL) {
425 kfree(Buffer);
426 }
427 return A_ERROR;
428 }
429 //pCharLine +=5;
430 ByteCount = uReadDataInSection(pCharLine, stPS_DataFormat);
431
432 //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag length %x\n", ByteCount));
433 if (ByteCount > LINE_SIZE_MAX/2)
434 {
435 if(Buffer != NULL) {
436 kfree(Buffer);
437 }
438 return A_ERROR;
439 }
440 PsTagEntry[TagCount].TagLen = ByteCount;
441 PsTagEntry[TagCount].TagData = (u8 *)A_MALLOC(ByteCount);
442 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG Length %d Tag Index %d \n",PsTagEntry[TagCount].TagLen,TagCount));
443 stReadStatus.uSection = 3;
444 stReadStatus.uLineCount = 0;
445 }
446 else if( stReadStatus.uSection == 3) { //Data
447
448 if(stReadStatus.uLineCount == 0) {
449 if(uGetInputDataFormat(pCharLine,&stPS_DataFormat)) {
450 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat Fail\n"));
451 if(Buffer != NULL) {
452 kfree(Buffer);
453 }
454 return A_ERROR;
455 }
456 //pCharLine +=5;
457 }
458 SKIP_BLANKS(pCharLine);
459 stReadStatus.uCharCount = 0;
460 if(pCharLine[stReadStatus.uCharCount] == '[') {
461 while(pCharLine[stReadStatus.uCharCount] != ']' && pCharLine[stReadStatus.uCharCount] != '\0' ) {
462 stReadStatus.uCharCount++;
463 }
464 if(pCharLine[stReadStatus.uCharCount] == ']' ) {
465 stReadStatus.uCharCount++;
466 } else {
467 stReadStatus.uCharCount = 0;
468 }
469 }
470 uReadCount = (ByteCount > BYTES_OF_PS_DATA_PER_LINE)? BYTES_OF_PS_DATA_PER_LINE: ByteCount;
471 //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" "));
472 if((stPS_DataFormat.eDataType == eHex) && stPS_DataFormat.bIsArray == true) {
473 while(uReadCount > 0) {
474 PsTagEntry[TagCount].TagData[stReadStatus.uByteCount] =
475 (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount]) << 4)
476 | (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 1]));
477
478 PsTagEntry[TagCount].TagData[stReadStatus.uByteCount+1] =
479 (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 3]) << 4)
480 | (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 4]));
481
482 stReadStatus.uCharCount += 6; // read two bytes, plus a space;
483 stReadStatus.uByteCount += 2;
484 uReadCount -= 2;
485 }
486 if(ByteCount > BYTES_OF_PS_DATA_PER_LINE) {
487 ByteCount -= BYTES_OF_PS_DATA_PER_LINE;
488 }
489 else {
490 ByteCount = 0;
491 }
492 }
493 else {
494 //to be implemented
495 }
496
497 stReadStatus.uLineCount++;
498
499 if(ByteCount == 0) {
500 stReadStatus.uSection = 0;
501 stReadStatus.uCharCount = 0;
502 stReadStatus.uLineCount = 0;
503 stReadStatus.uByteCount = 0;
504 }
505 else {
506 stReadStatus.uCharCount = 0;
507 }
508
509 if((stReadStatus.uSection == 0)&&(++TagCount == RAMPS_MAX_PS_TAGS_PER_FILE))
510 {
511 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n Buffer over flow PS File too big!!!"));
512 if(Buffer != NULL) {
513 kfree(Buffer);
514 }
515 return A_ERROR;
516 //Sleep (3000);
517 //exit(1);
518 }
519
520 }
521 }
522
523 break;
524 default:
525 {
526 if(Buffer != NULL) {
527 kfree(Buffer);
528 }
529 return A_ERROR;
530 }
531 break;
532 }
533 LineRead++;
534 }
535 Tag_Count = TagCount;
536 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Number of Tags %d\n", Tag_Count));
537 }
538
539
540 if (TagCount > RAMPS_MAX_PS_TAGS_PER_FILE)
541 {
542
543 if(Buffer != NULL) {
544 kfree(Buffer);
545 }
546 return A_ERROR;
547 }
548
549 if(Buffer != NULL) {
550 kfree(Buffer);
551 }
552 return 0;
553
554}
555
556
557
558/********************/
559
560
561int GetNextTwoChar(u8 *srcbuffer,u32 len, u32 *pos, char *buffer)
562{
563 unsigned char ch;
564
565 ch = AthReadChar(srcbuffer,len,pos);
566 if(ch != '\0' && isxdigit(ch)) {
567 buffer[0] = ch;
568 } else
569 {
570 return A_ERROR;
571 }
572 ch = AthReadChar(srcbuffer,len,pos);
573 if(ch != '\0' && isxdigit(ch)) {
574 buffer[1] = ch;
575 } else
576 {
577 return A_ERROR;
578 }
579 return 0;
580}
581
582int AthDoParsePatch(u8 *patchbuffer, u32 patchlen)
583{
584
585 char Byte[3];
586 char Line[MAX_BYTE_LENGTH + 1];
587 int ByteCount,ByteCount_Org;
588 int count;
589 int i,j,k;
590 int data;
591 u32 filepos;
592 Byte[2] = '\0';
593 j = 0;
594 filepos = 0;
595 Patch_Count = 0;
596
597 while(NULL != AthGetLine(Line,MAX_BYTE_LENGTH,patchbuffer,patchlen,&filepos)) {
598 if(strlen(Line) <= 1 || !isxdigit(Line[0])) {
599 continue;
600 } else {
601 break;
602 }
603 }
604 ByteCount = A_STRTOL(Line, NULL, 16);
605 ByteCount_Org = ByteCount;
606
607 while(ByteCount > MAX_BYTE_LENGTH){
608
609 /* Handle case when the number of patch buffer is more than the 20K */
610 if(MAX_NUM_PATCH_ENTRY == Patch_Count) {
611 for(i = 0; i < Patch_Count; i++) {
612 kfree(RamPatch[i].Data);
613 }
614 return A_ERROR;
615 }
616 RamPatch[Patch_Count].Len= MAX_BYTE_LENGTH;
617 RamPatch[Patch_Count].Data = (u8 *)A_MALLOC(MAX_BYTE_LENGTH);
618 Patch_Count ++;
619
620
621 ByteCount= ByteCount - MAX_BYTE_LENGTH;
622 }
623
624 RamPatch[Patch_Count].Len= (ByteCount & 0xFF);
625 if(ByteCount != 0) {
626 RamPatch[Patch_Count].Data = (u8 *)A_MALLOC(ByteCount);
627 Patch_Count ++;
628 }
629 count = 0;
630 while(ByteCount_Org > MAX_BYTE_LENGTH){
631 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j));
632 for (i = 0,k=0; i < MAX_BYTE_LENGTH*2; i += 2,k++,count +=2) {
633 if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) {
634 return A_ERROR;
635 }
636 data = A_STRTOUL(&Byte[0], NULL, 16);
637 RamPatch[j].Data[k] = (data & 0xFF);
638
639
640 }
641 j++;
642 ByteCount_Org = ByteCount_Org - MAX_BYTE_LENGTH;
643 }
644 if(j == 0){
645 j++;
646 }
647 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j));
648 for (k=0; k < ByteCount_Org; i += 2,k++,count+=2) {
649 if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) {
650 return A_ERROR;
651 }
652 data = A_STRTOUL(Byte, NULL, 16);
653 RamPatch[j].Data[k] = (data & 0xFF);
654
655
656 }
657 return 0;
658}
659
660
661/********************/
662int AthDoParsePS(u8 *srcbuffer, u32 srclen)
663{
664 int status;
665 int i;
666 bool BDADDR_Present = false;
667
668 Tag_Count = 0;
669
670 Total_tag_lenght = 0;
671 BDADDR = false;
672
673
674 status = A_ERROR;
675
676 if(NULL != srcbuffer && srclen != 0)
677 {
678 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("File Open Operation Successful\n"));
679
680 status = AthParseFilesUnified(srcbuffer,srclen,MB_FILEFORMAT_PATCH);
681 }
682
683
684
685 if(Tag_Count == 0){
686 Total_tag_lenght = 10;
687
688 }
689 else{
690 for(i=0; i<Tag_Count; i++){
691 if(PsTagEntry[i].TagId == 1){
692 BDADDR_Present = true;
693 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is present in Patch File \r\n"));
694
695 }
696 if(PsTagEntry[i].TagLen % 2 == 1){
697 Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen + 1;
698 }
699 else{
700 Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen;
701 }
702
703 }
704 }
705
706 if(Tag_Count > 0 && !BDADDR_Present){
707 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is not present adding 10 extra bytes \r\n"));
708 Total_tag_lenght=Total_tag_lenght + 10;
709 }
710 Total_tag_lenght = Total_tag_lenght+ 10 + (Tag_Count*4);
711 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Total Length %d\n",Total_tag_lenght));
712
713
714 return status;
715}
716char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos)
717{
718
719 int count;
720 static short flag;
721 char CharRead;
722 count = 0;
723 flag = A_ERROR;
724
725 do
726 {
727 CharRead = AthReadChar(srcbuffer,len,pos);
728 if( CharRead == '\0' ) {
729 buffer[count+1] = '\0';
730 if(count == 0) {
731 return NULL;
732 }
733 else {
734 return buffer;
735 }
736 }
737
738 if(CharRead == 13) {
739 } else if(CharRead == 10) {
740 buffer[count] ='\0';
741 flag = A_ERROR;
742 return buffer;
743 }else {
744 buffer[count++] = CharRead;
745 }
746
747 }
748 while(count < maxlen-1 && CharRead != '\0');
749 buffer[count] = '\0';
750
751 return buffer;
752}
753
754static void LoadHeader(u8 *HCI_PS_Command,u8 opcode,int length,int index){
755
756 HCI_PS_Command[0]= 0x0B;
757 HCI_PS_Command[1]= 0xFC;
758 HCI_PS_Command[2]= length + 4;
759 HCI_PS_Command[3]= opcode;
760 HCI_PS_Command[4]= (index & 0xFF);
761 HCI_PS_Command[5]= ((index>>8) & 0xFF);
762 HCI_PS_Command[6]= length;
763}
764
765/////////////////////////
766//
767int AthCreateCommandList(struct ps_cmd_packet **HciPacketList, u32 *numPackets)
768{
769
770 u8 count;
771 u32 NumcmdEntry = 0;
772
773 u32 Crc = 0;
774 *numPackets = 0;
775
776
777 if(Patch_Count > 0)
778 Crc |= RAM_PATCH_REGION;
779 if(Tag_Count > 0)
780 Crc |= RAM_PS_REGION;
781 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("PS Thread Started CRC %x Patch Count %d Tag Count %d \n",Crc,Patch_Count,Tag_Count));
782
783 if(Patch_Count || Tag_Count ){
784 NumcmdEntry+=(2 + Patch_Count + Tag_Count); /* CRC Packet + PS Reset Packet + Patch List + PS List*/
785 if(Patch_Count > 0) {
786 NumcmdEntry++; /* Patch Enable Command */
787 }
788 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Num Cmd Entries %d Size %d \r\n",NumcmdEntry,(u32)sizeof(struct ps_cmd_packet) * NumcmdEntry));
789 (*HciPacketList) = A_MALLOC(sizeof(struct ps_cmd_packet) * NumcmdEntry);
790 if(NULL == *HciPacketList) {
791 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("memory allocation failed \r\n"));
792 }
793 AthPSCreateHCICommand(PS_VERIFY_CRC,Crc,*HciPacketList,numPackets);
794 if(Patch_Count > 0){
795 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Write Patch**** \r\n"));
796 AthPSCreateHCICommand(WRITE_PATCH,Patch_Count,*HciPacketList,numPackets);
797 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Enable Patch**** \r\n"));
798 AthPSCreateHCICommand(ENABLE_PATCH,0,*HciPacketList,numPackets);
799 }
800
801 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Reset**** %d[0x%x] \r\n",PS_RAM_SIZE,PS_RAM_SIZE));
802 AthPSCreateHCICommand(PS_RESET,PS_RAM_SIZE,*HciPacketList,numPackets);
803 if(Tag_Count > 0){
804 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Write**** \r\n"));
805 AthPSCreateHCICommand(PS_WRITE,Tag_Count,*HciPacketList,numPackets);
806 }
807 }
808 if(!BDADDR){
809 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR not present \r\n"));
810
811 }
812 for(count = 0; count < Patch_Count; count++) {
813
814 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing Patch Buffer %d \r\n",count));
815 kfree(RamPatch[count].Data);
816 }
817
818 for(count = 0; count < Tag_Count; count++) {
819
820 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing PS Buffer %d \r\n",count));
821 kfree(PsTagEntry[count].TagData);
822 }
823
824/*
825 * SDIO Transport uses synchronous mode of data transfer
826 * So, AthPSOperations() call returns only after receiving the
827 * command complete event.
828 */
829 return *numPackets;
830}
831
832
833////////////////////////
834
835/////////////
836static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,struct ps_cmd_packet *PSPatchPacket,u32 *index)
837{
838 u8 *HCI_PS_Command;
839 u32 Length;
840 int i,j;
841
842 switch(Opcode)
843 {
844 case WRITE_PATCH:
845
846
847 for(i=0;i< Param1;i++){
848
849 HCI_PS_Command = (u8 *) A_MALLOC(RamPatch[i].Len+HCI_COMMAND_HEADER);
850 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Allocated Buffer Size %d\n",RamPatch[i].Len+HCI_COMMAND_HEADER));
851 if(HCI_PS_Command == NULL){
852 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
853 return A_ERROR;
854 }
855 memset (HCI_PS_Command, 0, RamPatch[i].Len+HCI_COMMAND_HEADER);
856 LoadHeader(HCI_PS_Command,Opcode,RamPatch[i].Len,i);
857 for(j=0;j<RamPatch[i].Len;j++){
858 HCI_PS_Command[HCI_COMMAND_HEADER+j]=RamPatch[i].Data[j];
859 }
860 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
861 PSPatchPacket[*index].packetLen = RamPatch[i].Len+HCI_COMMAND_HEADER;
862 (*index)++;
863
864
865 }
866
867 break;
868
869 case ENABLE_PATCH:
870
871
872 Length = 0;
873 i= 0;
874 HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER);
875 if(HCI_PS_Command == NULL){
876 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
877 return A_ERROR;
878 }
879
880 memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
881 LoadHeader(HCI_PS_Command,Opcode,Length,i);
882 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
883 PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
884 (*index)++;
885
886 break;
887
888 case PS_RESET:
889 Length = 0x06;
890 i=0;
891 HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER);
892 if(HCI_PS_Command == NULL){
893 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
894 return A_ERROR;
895 }
896 memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
897 LoadHeader(HCI_PS_Command,Opcode,Length,i);
898 HCI_PS_Command[7]= 0x00;
899 HCI_PS_Command[Length+HCI_COMMAND_HEADER -2]= (Param1 & 0xFF);
900 HCI_PS_Command[Length+HCI_COMMAND_HEADER -1]= ((Param1 >> 8) & 0xFF);
901 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
902 PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
903 (*index)++;
904
905 break;
906
907 case PS_WRITE:
908 for(i=0;i< Param1;i++){
909 if(PsTagEntry[i].TagId ==1)
910 BDADDR = true;
911
912 HCI_PS_Command = (u8 *) A_MALLOC(PsTagEntry[i].TagLen+HCI_COMMAND_HEADER);
913 if(HCI_PS_Command == NULL){
914 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
915 return A_ERROR;
916 }
917
918 memset (HCI_PS_Command, 0, PsTagEntry[i].TagLen+HCI_COMMAND_HEADER);
919 LoadHeader(HCI_PS_Command,Opcode,PsTagEntry[i].TagLen,PsTagEntry[i].TagId);
920
921 for(j=0;j<PsTagEntry[i].TagLen;j++){
922 HCI_PS_Command[HCI_COMMAND_HEADER+j]=PsTagEntry[i].TagData[j];
923 }
924
925 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
926 PSPatchPacket[*index].packetLen = PsTagEntry[i].TagLen+HCI_COMMAND_HEADER;
927 (*index)++;
928
929 }
930
931 break;
932
933
934 case PS_VERIFY_CRC:
935 Length = 0x0;
936
937 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("VALUE of CRC:%d At index %d\r\n",Param1,*index));
938
939 HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER);
940 if(HCI_PS_Command == NULL){
941 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
942 return A_ERROR;
943 }
944 memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
945 LoadHeader(HCI_PS_Command,Opcode,Length,Param1);
946
947 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
948 PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
949 (*index)++;
950
951 break;
952
953 case CHANGE_BDADDR:
954 break;
955 }
956 return 0;
957}
958int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets)
959{
960 int i;
961 if(*HciPacketList == NULL) {
962 return A_ERROR;
963 }
964 for(i = 0; i < numPackets;i++) {
965 kfree((*HciPacketList)[i].Hcipacket);
966 }
967 kfree(*HciPacketList);
968 return 0;
969}
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h
new file mode 100644
index 00000000000..4e0f2f713a4
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h
@@ -0,0 +1,113 @@
1//------------------------------------------------------------------------------
2//
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//
21// This file is the include file for Atheros PS and patch parser.
22// It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands.
23//
24
25#ifndef __AR3KPSPARSER_H
26#define __AR3KPSPARSER_H
27
28
29
30
31#include <linux/fs.h>
32#include <linux/slab.h>
33#include "athdefs.h"
34#ifdef HCI_TRANSPORT_SDIO
35#include "a_config.h"
36#include "a_osapi.h"
37#define ATH_MODULE_NAME misc
38#include "a_debug.h"
39#include "common_drv.h"
40#include "hci_transport_api.h"
41#include "ar3kconfig.h"
42#else
43#ifndef A_PRINTF
44#define A_PRINTF(args...) printk(KERN_ALERT args)
45#endif /* A_PRINTF */
46#include "debug_linux.h"
47
48/* Helper data type declaration */
49
50#define ATH_DEBUG_ERR (1 << 0)
51#define ATH_DEBUG_WARN (1 << 1)
52#define ATH_DEBUG_INFO (1 << 2)
53
54
55
56#define false 0
57#define true 1
58
59#ifndef A_MALLOC
60#define A_MALLOC(size) kmalloc((size),GFP_KERNEL)
61#endif /* A_MALLOC */
62#endif /* HCI_TRANSPORT_UART */
63
64/* String manipulation APIs */
65#ifndef A_STRTOUL
66#define A_STRTOUL simple_strtoul
67#endif /* A_STRTOL */
68
69#ifndef A_STRTOL
70#define A_STRTOL simple_strtol
71#endif /* A_STRTOL */
72
73
74/* The maximum number of bytes possible in a patch entry */
75#define MAX_PATCH_SIZE 20000
76
77/* Maximum HCI packets that will be formed from the Patch file */
78#define MAX_NUM_PATCH_ENTRY (MAX_PATCH_SIZE/MAX_BYTE_LENGTH) + 1
79
80
81
82
83
84
85
86struct ps_cmd_packet
87{
88 u8 *Hcipacket;
89 int packetLen;
90};
91
92/* Parses a Patch information buffer and store it in global structure */
93int AthDoParsePatch(u8 *, u32 );
94
95/* parses a PS information buffer and stores it in a global structure */
96int AthDoParsePS(u8 *, u32 );
97
98/*
99 * Uses the output of Both AthDoParsePS and AthDoParsePatch APIs to form HCI command array with
100 * all the PS and patch commands.
101 * The list will have the below mentioned commands in order.
102 * CRC command packet
103 * Download patch command(s)
104 * Enable patch Command
105 * PS Reset Command
106 * PS Tag Command(s)
107 *
108 */
109int AthCreateCommandList(struct ps_cmd_packet **, u32 *);
110
111/* Cleanup the dynamically allicated HCI command list */
112int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets);
113#endif /* __AR3KPSPARSER_H */
diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c
new file mode 100644
index 00000000000..1ce539aa019
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/common_drv.c
@@ -0,0 +1,910 @@
1//------------------------------------------------------------------------------
2// <copyright file="common_drv.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#include "a_config.h"
25#include "athdefs.h"
26
27#include "hw/mbox_host_reg.h"
28#include "gpio_reg.h"
29#include "hw/rtc_reg.h"
30#include "hw/mbox_reg.h"
31#include "hw/apb_map.h"
32
33#include "a_osapi.h"
34#include "targaddrs.h"
35#include "hif.h"
36#include "htc_api.h"
37#include "wmi.h"
38#include "bmi.h"
39#include "bmi_msg.h"
40#include "common_drv.h"
41#define ATH_MODULE_NAME misc
42#include "a_debug.h"
43#include "ar6000_diag.h"
44
45static ATH_DEBUG_MODULE_DBG_INFO *g_pModuleInfoHead = NULL;
46static A_MUTEX_T g_ModuleListLock;
47static bool g_ModuleDebugInit = false;
48
49#ifdef ATH_DEBUG_MODULE
50
51ATH_DEBUG_INSTANTIATE_MODULE_VAR(misc,
52 "misc",
53 "Common and misc APIs",
54 ATH_DEBUG_MASK_DEFAULTS,
55 0,
56 NULL);
57
58#endif
59
60#define HOST_INTEREST_ITEM_ADDRESS(target, item) \
61 ((((target) == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
62 (((target) == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0)))
63
64
65#define AR6001_LOCAL_COUNT_ADDRESS 0x0c014080
66#define AR6002_LOCAL_COUNT_ADDRESS 0x00018080
67#define AR6003_LOCAL_COUNT_ADDRESS 0x00018080
68#define CPU_DBG_SEL_ADDRESS 0x00000483
69#define CPU_DBG_ADDRESS 0x00000484
70
71static u8 custDataAR6002[AR6002_CUST_DATA_SIZE];
72static u8 custDataAR6003[AR6003_CUST_DATA_SIZE];
73
74/* Compile the 4BYTE version of the window register setup routine,
75 * This mitigates host interconnect issues with non-4byte aligned bus requests, some
76 * interconnects use bus adapters that impose strict limitations.
77 * Since diag window access is not intended for performance critical operations, the 4byte mode should
78 * be satisfactory even though it generates 4X the bus activity. */
79
80#ifdef USE_4BYTE_REGISTER_ACCESS
81
82 /* set the window address register (using 4-byte register access ). */
83int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address)
84{
85 int status;
86 u8 addrValue[4];
87 s32 i;
88
89 /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
90 * last to initiate the access cycle */
91
92 for (i = 1; i <= 3; i++) {
93 /* fill the buffer with the address byte value we want to hit 4 times*/
94 addrValue[0] = ((u8 *)&Address)[i];
95 addrValue[1] = addrValue[0];
96 addrValue[2] = addrValue[0];
97 addrValue[3] = addrValue[0];
98
99 /* hit each byte of the register address with a 4-byte write operation to the same address,
100 * this is a harmless operation */
101 status = HIFReadWrite(hifDevice,
102 RegisterAddr+i,
103 addrValue,
104 4,
105 HIF_WR_SYNC_BYTE_FIX,
106 NULL);
107 if (status) {
108 break;
109 }
110 }
111
112 if (status) {
113 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
114 Address, RegisterAddr));
115 return status;
116 }
117
118 /* write the address register again, this time write the whole 4-byte value.
119 * The effect here is that the LSB write causes the cycle to start, the extra
120 * 3 byte write to bytes 1,2,3 has no effect since we are writing the same values again */
121 status = HIFReadWrite(hifDevice,
122 RegisterAddr,
123 (u8 *)(&Address),
124 4,
125 HIF_WR_SYNC_BYTE_INC,
126 NULL);
127
128 if (status) {
129 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
130 Address, RegisterAddr));
131 return status;
132 }
133
134 return 0;
135
136
137
138}
139
140
141#else
142
143 /* set the window address register */
144int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address)
145{
146 int status;
147
148 /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
149 * last to initiate the access cycle */
150 status = HIFReadWrite(hifDevice,
151 RegisterAddr+1, /* write upper 3 bytes */
152 ((u8 *)(&Address))+1,
153 sizeof(u32)-1,
154 HIF_WR_SYNC_BYTE_INC,
155 NULL);
156
157 if (status) {
158 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
159 RegisterAddr, Address));
160 return status;
161 }
162
163 /* write the LSB of the register, this initiates the operation */
164 status = HIFReadWrite(hifDevice,
165 RegisterAddr,
166 (u8 *)(&Address),
167 sizeof(u8),
168 HIF_WR_SYNC_BYTE_INC,
169 NULL);
170
171 if (status) {
172 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
173 RegisterAddr, Address));
174 return status;
175 }
176
177 return 0;
178}
179
180#endif
181
182/*
183 * Read from the AR6000 through its diagnostic window.
184 * No cooperation from the Target is required for this.
185 */
186int
187ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data)
188{
189 int status;
190
191 /* set window register to start read cycle */
192 status = ar6000_SetAddressWindowRegister(hifDevice,
193 WINDOW_READ_ADDR_ADDRESS,
194 *address);
195
196 if (status) {
197 return status;
198 }
199
200 /* read the data */
201 status = HIFReadWrite(hifDevice,
202 WINDOW_DATA_ADDRESS,
203 (u8 *)data,
204 sizeof(u32),
205 HIF_RD_SYNC_BYTE_INC,
206 NULL);
207 if (status) {
208 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n"));
209 return status;
210 }
211
212 return status;
213}
214
215
216/*
217 * Write to the AR6000 through its diagnostic window.
218 * No cooperation from the Target is required for this.
219 */
220int
221ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data)
222{
223 int status;
224
225 /* set write data */
226 status = HIFReadWrite(hifDevice,
227 WINDOW_DATA_ADDRESS,
228 (u8 *)data,
229 sizeof(u32),
230 HIF_WR_SYNC_BYTE_INC,
231 NULL);
232 if (status) {
233 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data));
234 return status;
235 }
236
237 /* set window register, which starts the write cycle */
238 return ar6000_SetAddressWindowRegister(hifDevice,
239 WINDOW_WRITE_ADDR_ADDRESS,
240 *address);
241 }
242
243int
244ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address,
245 u8 *data, u32 length)
246{
247 u32 count;
248 int status = 0;
249
250 for (count = 0; count < length; count += 4, address += 4) {
251 if ((status = ar6000_ReadRegDiag(hifDevice, &address,
252 (u32 *)&data[count])) != 0)
253 {
254 break;
255 }
256 }
257
258 return status;
259}
260
261int
262ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address,
263 u8 *data, u32 length)
264{
265 u32 count;
266 int status = 0;
267
268 for (count = 0; count < length; count += 4, address += 4) {
269 if ((status = ar6000_WriteRegDiag(hifDevice, &address,
270 (u32 *)&data[count])) != 0)
271 {
272 break;
273 }
274 }
275
276 return status;
277}
278
279int
280ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval)
281{
282 int status;
283 u8 vals[4];
284 u8 register_selection[4];
285
286 register_selection[0] = register_selection[1] = register_selection[2] = register_selection[3] = (regsel & 0xff);
287 status = HIFReadWrite(hifDevice,
288 CPU_DBG_SEL_ADDRESS,
289 register_selection,
290 4,
291 HIF_WR_SYNC_BYTE_FIX,
292 NULL);
293
294 if (status) {
295 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write CPU_DBG_SEL (%d)\n", regsel));
296 return status;
297 }
298
299 status = HIFReadWrite(hifDevice,
300 CPU_DBG_ADDRESS,
301 (u8 *)vals,
302 sizeof(vals),
303 HIF_RD_SYNC_BYTE_INC,
304 NULL);
305 if (status) {
306 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from CPU_DBG_ADDRESS\n"));
307 return status;
308 }
309
310 *regval = vals[0]<<0 | vals[1]<<8 | vals[2]<<16 | vals[3]<<24;
311
312 return status;
313}
314
315void
316ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs)
317{
318 int i;
319 u32 val;
320
321 for (i=0; i<AR6003_FETCH_TARG_REGS_COUNT; i++) {
322 val=0xffffffff;
323 (void)ar6k_ReadTargetRegister(hifDevice, i, &val);
324 targregs[i] = val;
325 }
326}
327
328#if 0
329static int
330_do_write_diag(struct hif_device *hifDevice, u32 addr, u32 value)
331{
332 int status;
333
334 status = ar6000_WriteRegDiag(hifDevice, &addr, &value);
335 if (status)
336 {
337 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot force Target to execute ROM!\n"));
338 }
339
340 return status;
341}
342#endif
343
344
345/*
346 * Delay up to wait_msecs millisecs to allow Target to enter BMI phase,
347 * which is a good sign that it's alive and well. This is used after
348 * explicitly forcing the Target to reset.
349 *
350 * The wait_msecs time should be sufficiently long to cover any reasonable
351 * boot-time delay. For instance, AR6001 firmware allow one second for a
352 * low frequency crystal to settle before it calibrates the refclk frequency.
353 *
354 * TBD: Might want to add special handling for AR6K_OPTION_BMI_DISABLE.
355 */
356#if 0
357static int
358_delay_until_target_alive(struct hif_device *hifDevice, s32 wait_msecs, u32 TargetType)
359{
360 s32 actual_wait;
361 s32 i;
362 u32 address;
363
364 actual_wait = 0;
365
366 /* Hardcode the address of LOCAL_COUNT_ADDRESS based on the target type */
367 if (TargetType == TARGET_TYPE_AR6002) {
368 address = AR6002_LOCAL_COUNT_ADDRESS;
369 } else if (TargetType == TARGET_TYPE_AR6003) {
370 address = AR6003_LOCAL_COUNT_ADDRESS;
371 } else {
372 A_ASSERT(0);
373 }
374 address += 0x10;
375 for (i=0; actual_wait < wait_msecs; i++) {
376 u32 data;
377
378 A_MDELAY(100);
379 actual_wait += 100;
380
381 data = 0;
382 if (ar6000_ReadRegDiag(hifDevice, &address, &data) != 0) {
383 return A_ERROR;
384 }
385
386 if (data != 0) {
387 /* No need to wait longer -- we have a BMI credit */
388 return 0;
389 }
390 }
391 return A_ERROR; /* timed out */
392}
393#endif
394
395#define AR6001_RESET_CONTROL_ADDRESS 0x0C000000
396#define AR6002_RESET_CONTROL_ADDRESS 0x00004000
397#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
398/* reset device */
399int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset)
400{
401 int status = 0;
402 u32 address;
403 u32 data;
404
405 do {
406// Workaround BEGIN
407 // address = RESET_CONTROL_ADDRESS;
408
409 if (coldReset) {
410 data = RESET_CONTROL_COLD_RST_MASK;
411 }
412 else {
413 data = RESET_CONTROL_MBOX_RST_MASK;
414 }
415
416 /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */
417 if (TargetType == TARGET_TYPE_AR6002) {
418 address = AR6002_RESET_CONTROL_ADDRESS;
419 } else if (TargetType == TARGET_TYPE_AR6003) {
420 address = AR6003_RESET_CONTROL_ADDRESS;
421 } else {
422 A_ASSERT(0);
423 }
424
425
426 status = ar6000_WriteRegDiag(hifDevice, &address, &data);
427
428 if (status) {
429 break;
430 }
431
432 if (!waitForCompletion) {
433 break;
434 }
435
436#if 0
437 /* Up to 2 second delay to allow things to settle down */
438 (void)_delay_until_target_alive(hifDevice, 2000, TargetType);
439
440 /*
441 * Read back the RESET CAUSE register to ensure that the cold reset
442 * went through.
443 */
444
445 // address = RESET_CAUSE_ADDRESS;
446 /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */
447 if (TargetType == TARGET_TYPE_AR6002) {
448 address = 0x000040C0;
449 } else if (TargetType == TARGET_TYPE_AR6003) {
450 address = 0x000040C0;
451 } else {
452 A_ASSERT(0);
453 }
454
455 data = 0;
456 status = ar6000_ReadRegDiag(hifDevice, &address, &data);
457
458 if (status) {
459 break;
460 }
461
462 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data));
463 data &= RESET_CAUSE_LAST_MASK;
464 if (data != 2) {
465 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n"));
466 }
467#endif
468// Workaroud END
469
470 } while (false);
471
472 if (status) {
473 AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n"));
474 }
475
476 return 0;
477}
478
479/* This should be called in BMI phase after firmware is downloaded */
480void
481ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType)
482{
483 u32 eepHeaderAddr;
484 u8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4];
485 s32 i;
486
487 if (BMIReadMemory(hifDevice,
488 HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data),
489 (u8 *)&eepHeaderAddr,
490 4)!= 0)
491 {
492 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n"));
493 return;
494 }
495
496 if (TargetType == TARGET_TYPE_AR6003) {
497 eepHeaderAddr += 36; /* AR6003 customer data section offset is 37 */
498
499 for (i=0; i<AR6003_CUST_DATA_SIZE+4; i+=4){
500 if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (u32 *)&AR6003CustDataShadow[i])!= 0) {
501 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
502 return ;
503 }
504 eepHeaderAddr +=4;
505 }
506
507 memcpy(custDataAR6003, AR6003CustDataShadow+1, AR6003_CUST_DATA_SIZE);
508 }
509
510 if (TargetType == TARGET_TYPE_AR6002) {
511 eepHeaderAddr += 64; /* AR6002 customer data sectioin offset is 64 */
512
513 for (i=0; i<AR6002_CUST_DATA_SIZE; i+=4){
514 if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (u32 *)&custDataAR6002[i])!= 0) {
515 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
516 return ;
517 }
518 eepHeaderAddr +=4;
519 }
520 }
521
522 return;
523}
524
525/* This is the function to call when need to use the cust data */
526u8 *ar6000_get_cust_data_buffer(u32 TargetType)
527{
528 if (TargetType == TARGET_TYPE_AR6003)
529 return custDataAR6003;
530
531 if (TargetType == TARGET_TYPE_AR6002)
532 return custDataAR6002;
533
534 return NULL;
535}
536
537#define REG_DUMP_COUNT_AR6001 38 /* WORDs, derived from AR600x_regdump.h */
538#define REG_DUMP_COUNT_AR6002 60
539#define REG_DUMP_COUNT_AR6003 60
540#define REGISTER_DUMP_LEN_MAX 60
541#if REG_DUMP_COUNT_AR6001 > REGISTER_DUMP_LEN_MAX
542#error "REG_DUMP_COUNT_AR6001 too large"
543#endif
544#if REG_DUMP_COUNT_AR6002 > REGISTER_DUMP_LEN_MAX
545#error "REG_DUMP_COUNT_AR6002 too large"
546#endif
547#if REG_DUMP_COUNT_AR6003 > REGISTER_DUMP_LEN_MAX
548#error "REG_DUMP_COUNT_AR6003 too large"
549#endif
550
551
552void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType)
553{
554 u32 address;
555 u32 regDumpArea = 0;
556 int status;
557 u32 regDumpValues[REGISTER_DUMP_LEN_MAX];
558 u32 regDumpCount = 0;
559 u32 i;
560
561 do {
562
563 /* the reg dump pointer is copied to the host interest area */
564 address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state);
565 address = TARG_VTOP(TargetType, address);
566
567 if (TargetType == TARGET_TYPE_AR6002) {
568 regDumpCount = REG_DUMP_COUNT_AR6002;
569 } else if (TargetType == TARGET_TYPE_AR6003) {
570 regDumpCount = REG_DUMP_COUNT_AR6003;
571 } else {
572 A_ASSERT(0);
573 }
574
575 /* read RAM location through diagnostic window */
576 status = ar6000_ReadRegDiag(hifDevice, &address, &regDumpArea);
577
578 if (status) {
579 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n"));
580 break;
581 }
582
583 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea));
584
585 if (regDumpArea == 0) {
586 /* no reg dump */
587 break;
588 }
589
590 regDumpArea = TARG_VTOP(TargetType, regDumpArea);
591
592 /* fetch register dump data */
593 status = ar6000_ReadDataDiag(hifDevice,
594 regDumpArea,
595 (u8 *)&regDumpValues[0],
596 regDumpCount * (sizeof(u32)));
597
598 if (status) {
599 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n"));
600 break;
601 }
602 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n"));
603
604 for (i = 0; i < regDumpCount; i++) {
605 //ATHR_DISPLAY_MSG (_T(" %d : 0x%8.8X \n"), i, regDumpValues[i]);
606 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d : 0x%8.8X \n",i, regDumpValues[i]));
607
608#ifdef UNDER_CE
609 /*
610 * For Every logPrintf() Open the File so that in case of Crashes
611 * We will have until the Last Message Flushed on to the File
612 * So use logPrintf Sparingly..!!
613 */
614 tgtassertPrintf (ATH_DEBUG_TRC," %d: 0x%8.8X \n",i, regDumpValues[i]);
615#endif
616 }
617
618 } while (false);
619
620}
621
622/* set HTC/Mbox operational parameters, this can only be called when the target is in the
623 * BMI phase */
624int ar6000_set_htc_params(struct hif_device *hifDevice,
625 u32 TargetType,
626 u32 MboxIsrYieldValue,
627 u8 HtcControlBuffers)
628{
629 int status;
630 u32 blocksizes[HTC_MAILBOX_NUM_MAX];
631
632 do {
633 /* get the block sizes */
634 status = HIFConfigureDevice(hifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
635 blocksizes, sizeof(blocksizes));
636
637 if (status) {
638 AR_DEBUG_PRINTF(ATH_LOG_ERR,("Failed to get block size info from HIF layer...\n"));
639 break;
640 }
641 /* note: we actually get the block size for mailbox 1, for SDIO the block
642 * size on mailbox 0 is artificially set to 1 */
643 /* must be a power of 2 */
644 A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0);
645
646 if (HtcControlBuffers != 0) {
647 /* set override for number of control buffers to use */
648 blocksizes[1] |= ((u32)HtcControlBuffers) << 16;
649 }
650
651 /* set the host interest area for the block size */
652 status = BMIWriteMemory(hifDevice,
653 HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz),
654 (u8 *)&blocksizes[1],
655 4);
656
657 if (status) {
658 AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for IO block size failed \n"));
659 break;
660 }
661
662 AR_DEBUG_PRINTF(ATH_LOG_INF,("Block Size Set: %d (target address:0x%X)\n",
663 blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz)));
664
665 if (MboxIsrYieldValue != 0) {
666 /* set the host interest area for the mbox ISR yield limit */
667 status = BMIWriteMemory(hifDevice,
668 HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_isr_yield_limit),
669 (u8 *)&MboxIsrYieldValue,
670 4);
671
672 if (status) {
673 AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for yield limit failed \n"));
674 break;
675 }
676 }
677
678 } while (false);
679
680 return status;
681}
682
683void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription)
684{
685 char stream[60];
686 char byteOffsetStr[10];
687 u32 i;
688 u16 offset, count, byteOffset;
689
690 A_PRINTF("<---------Dumping %d Bytes : %s ------>\n", length, pDescription);
691
692 count = 0;
693 offset = 0;
694 byteOffset = 0;
695 for(i = 0; i < length; i++) {
696 A_SPRINTF(stream + offset, "%2.2X ", buffer[i]);
697 count ++;
698 offset += 3;
699
700 if(count == 16) {
701 count = 0;
702 offset = 0;
703 A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset);
704 A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
705 A_MEMZERO(stream, 60);
706 byteOffset += 16;
707 }
708 }
709
710 if(offset != 0) {
711 A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset);
712 A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
713 }
714
715 A_PRINTF("<------------------------------------------------->\n");
716}
717
718void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
719{
720 int i;
721 struct ath_debug_mask_description *pDesc;
722
723 if (pInfo == NULL) {
724 return;
725 }
726
727 pDesc = pInfo->pMaskDescriptions;
728
729 A_PRINTF("========================================================\n\n");
730 A_PRINTF("Module Debug Info => Name : %s \n", pInfo->ModuleName);
731 A_PRINTF(" => Descr. : %s \n", pInfo->ModuleDescription);
732 A_PRINTF("\n Current mask => 0x%8.8X \n", pInfo->CurrentMask);
733 A_PRINTF("\n Avail. Debug Masks :\n\n");
734
735 for (i = 0; i < pInfo->MaxDescriptions; i++,pDesc++) {
736 A_PRINTF(" => 0x%8.8X -- %s \n", pDesc->Mask, pDesc->Description);
737 }
738
739 if (0 == i) {
740 A_PRINTF(" => * none defined * \n");
741 }
742
743 A_PRINTF("\n Standard Debug Masks :\n\n");
744 /* print standard masks */
745 A_PRINTF(" => 0x%8.8X -- Errors \n", ATH_DEBUG_ERR);
746 A_PRINTF(" => 0x%8.8X -- Warnings \n", ATH_DEBUG_WARN);
747 A_PRINTF(" => 0x%8.8X -- Informational \n", ATH_DEBUG_INFO);
748 A_PRINTF(" => 0x%8.8X -- Tracing \n", ATH_DEBUG_TRC);
749 A_PRINTF("\n========================================================\n");
750
751}
752
753
754static ATH_DEBUG_MODULE_DBG_INFO *FindModule(char *module_name)
755{
756 ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
757
758 if (!g_ModuleDebugInit) {
759 return NULL;
760 }
761
762 while (pInfo != NULL) {
763 /* TODO: need to use something other than strlen */
764 if (memcmp(pInfo->ModuleName,module_name,strlen(module_name)) == 0) {
765 break;
766 }
767 pInfo = pInfo->pNext;
768 }
769
770 return pInfo;
771}
772
773
774void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
775{
776 if (!g_ModuleDebugInit) {
777 return;
778 }
779
780 A_MUTEX_LOCK(&g_ModuleListLock);
781
782 if (!(pInfo->Flags & ATH_DEBUG_INFO_FLAGS_REGISTERED)) {
783 if (g_pModuleInfoHead == NULL) {
784 g_pModuleInfoHead = pInfo;
785 } else {
786 pInfo->pNext = g_pModuleInfoHead;
787 g_pModuleInfoHead = pInfo;
788 }
789 pInfo->Flags |= ATH_DEBUG_INFO_FLAGS_REGISTERED;
790 }
791
792 A_MUTEX_UNLOCK(&g_ModuleListLock);
793}
794
795void a_dump_module_debug_info_by_name(char *module_name)
796{
797 ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
798
799 if (!g_ModuleDebugInit) {
800 return;
801 }
802
803 if (memcmp(module_name,"all",3) == 0) {
804 /* dump all */
805 while (pInfo != NULL) {
806 a_dump_module_debug_info(pInfo);
807 pInfo = pInfo->pNext;
808 }
809 return;
810 }
811
812 pInfo = FindModule(module_name);
813
814 if (pInfo != NULL) {
815 a_dump_module_debug_info(pInfo);
816 }
817
818}
819
820int a_get_module_mask(char *module_name, u32 *pMask)
821{
822 ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
823
824 if (NULL == pInfo) {
825 return A_ERROR;
826 }
827
828 *pMask = pInfo->CurrentMask;
829 return 0;
830}
831
832int a_set_module_mask(char *module_name, u32 Mask)
833{
834 ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
835
836 if (NULL == pInfo) {
837 return A_ERROR;
838 }
839
840 pInfo->CurrentMask = Mask;
841 A_PRINTF("Module %s, new mask: 0x%8.8X \n",module_name,pInfo->CurrentMask);
842 return 0;
843}
844
845
846void a_module_debug_support_init(void)
847{
848 if (g_ModuleDebugInit) {
849 return;
850 }
851 A_MUTEX_INIT(&g_ModuleListLock);
852 g_pModuleInfoHead = NULL;
853 g_ModuleDebugInit = true;
854 A_REGISTER_MODULE_DEBUG_INFO(misc);
855}
856
857void a_module_debug_support_cleanup(void)
858{
859 ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
860 ATH_DEBUG_MODULE_DBG_INFO *pCur;
861
862 if (!g_ModuleDebugInit) {
863 return;
864 }
865
866 g_ModuleDebugInit = false;
867
868 A_MUTEX_LOCK(&g_ModuleListLock);
869
870 while (pInfo != NULL) {
871 pCur = pInfo;
872 pInfo = pInfo->pNext;
873 pCur->pNext = NULL;
874 /* clear registered flag */
875 pCur->Flags &= ~ATH_DEBUG_INFO_FLAGS_REGISTERED;
876 }
877
878 A_MUTEX_UNLOCK(&g_ModuleListLock);
879
880 A_MUTEX_DELETE(&g_ModuleListLock);
881 g_pModuleInfoHead = NULL;
882}
883
884 /* can only be called during bmi init stage */
885int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice,
886 u32 TargetType,
887 u32 Flags)
888{
889 int status = 0;
890
891 do {
892
893 if (TargetType != TARGET_TYPE_AR6003) {
894 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Target Type:%d, does not support HCI bridging! \n",
895 TargetType));
896 break;
897 }
898
899 /* set hci bridge flags */
900 status = BMIWriteMemory(hifDevice,
901 HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_hci_bridge_flags),
902 (u8 *)&Flags,
903 4);
904
905
906 } while (false);
907
908 return status;
909}
910
diff --git a/drivers/staging/ath6kl/miscdrv/credit_dist.c b/drivers/staging/ath6kl/miscdrv/credit_dist.c
new file mode 100644
index 00000000000..c777e98a756
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/credit_dist.c
@@ -0,0 +1,417 @@
1//------------------------------------------------------------------------------
2// <copyright file="credit_dist.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23
24#include "a_config.h"
25#include "athdefs.h"
26#include "a_osapi.h"
27#define ATH_MODULE_NAME misc
28#include "a_debug.h"
29#include "htc_api.h"
30#include "common_drv.h"
31
32/********* CREDIT DISTRIBUTION FUNCTIONS ******************************************/
33
34#define NO_VO_SERVICE 1 /* currently WMI only uses 3 data streams, so we leave VO service inactive */
35#define CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS 1
36
37#ifdef NO_VO_SERVICE
38#define DATA_SVCS_USED 3
39#else
40#define DATA_SVCS_USED 4
41#endif
42
43static void RedistributeCredits(struct common_credit_state_info *pCredInfo,
44 struct htc_endpoint_credit_dist *pEPDistList);
45
46static void SeekCredits(struct common_credit_state_info *pCredInfo,
47 struct htc_endpoint_credit_dist *pEPDistList);
48
49/* reduce an ep's credits back to a set limit */
50static INLINE void ReduceCredits(struct common_credit_state_info *pCredInfo,
51 struct htc_endpoint_credit_dist *pEpDist,
52 int Limit)
53{
54 int credits;
55
56 /* set the new limit */
57 pEpDist->TxCreditsAssigned = Limit;
58
59 if (pEpDist->TxCredits <= Limit) {
60 return;
61 }
62
63 /* figure out how much to take away */
64 credits = pEpDist->TxCredits - Limit;
65 /* take them away */
66 pEpDist->TxCredits -= credits;
67 pCredInfo->CurrentFreeCredits += credits;
68}
69
70/* give an endpoint some credits from the free credit pool */
71#define GiveCredits(pCredInfo,pEpDist,credits) \
72{ \
73 (pEpDist)->TxCredits += (credits); \
74 (pEpDist)->TxCreditsAssigned += (credits); \
75 (pCredInfo)->CurrentFreeCredits -= (credits); \
76}
77
78
79/* default credit init callback.
80 * This function is called in the context of HTCStart() to setup initial (application-specific)
81 * credit distributions */
82static void ar6000_credit_init(void *Context,
83 struct htc_endpoint_credit_dist *pEPList,
84 int TotalCredits)
85{
86 struct htc_endpoint_credit_dist *pCurEpDist;
87 int count;
88 struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context;
89
90 pCredInfo->CurrentFreeCredits = TotalCredits;
91 pCredInfo->TotalAvailableCredits = TotalCredits;
92
93 pCurEpDist = pEPList;
94
95 /* run through the list and initialize */
96 while (pCurEpDist != NULL) {
97
98 /* set minimums for each endpoint */
99 pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg;
100
101#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
102
103 if (TotalCredits > 4)
104 {
105 if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC) || (pCurEpDist->ServiceID == WMI_DATA_BE_SVC)){
106 /* assign at least min credits to lower than VO priority services */
107 GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin);
108 /* force active */
109 SET_EP_ACTIVE(pCurEpDist);
110 }
111 }
112
113#endif
114
115 if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) {
116 /* give control service some credits */
117 GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin);
118 /* control service is always marked active, it never goes inactive EVER */
119 SET_EP_ACTIVE(pCurEpDist);
120 } else if (pCurEpDist->ServiceID == WMI_DATA_BK_SVC) {
121 /* this is the lowest priority data endpoint, save this off for easy access */
122 pCredInfo->pLowestPriEpDist = pCurEpDist;
123 }
124
125 /* Streams have to be created (explicit | implicit)for all kinds
126 * of traffic. BE endpoints are also inactive in the beginning.
127 * When BE traffic starts it creates implicit streams that
128 * redistributes credits.
129 */
130
131 /* note, all other endpoints have minimums set but are initially given NO credits.
132 * Credits will be distributed as traffic activity demands */
133 pCurEpDist = pCurEpDist->pNext;
134 }
135
136 if (pCredInfo->CurrentFreeCredits <= 0) {
137 AR_DEBUG_PRINTF(ATH_LOG_INF, ("Not enough credits (%d) to do credit distributions \n", TotalCredits));
138 A_ASSERT(false);
139 return;
140 }
141
142 /* reset list */
143 pCurEpDist = pEPList;
144 /* now run through the list and set max operating credit limits for everyone */
145 while (pCurEpDist != NULL) {
146 if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) {
147 /* control service max is just 1 max message */
148 pCurEpDist->TxCreditsNorm = pCurEpDist->TxCreditsPerMaxMsg;
149 } else {
150 /* for the remaining data endpoints, we assume that each TxCreditsPerMaxMsg are
151 * the same.
152 * We use a simple calculation here, we take the remaining credits and
153 * determine how many max messages this can cover and then set each endpoint's
154 * normal value equal to 3/4 this amount.
155 * */
156 count = (pCredInfo->CurrentFreeCredits/pCurEpDist->TxCreditsPerMaxMsg) * pCurEpDist->TxCreditsPerMaxMsg;
157 count = (count * 3) >> 2;
158 count = max(count,pCurEpDist->TxCreditsPerMaxMsg);
159 /* set normal */
160 pCurEpDist->TxCreditsNorm = count;
161
162 }
163 pCurEpDist = pCurEpDist->pNext;
164 }
165
166}
167
168
169/* default credit distribution callback
170 * This callback is invoked whenever endpoints require credit distributions.
171 * A lock is held while this function is invoked, this function shall NOT block.
172 * The pEPDistList is a list of distribution structures in prioritized order as
173 * defined by the call to the HTCSetCreditDistribution() api.
174 *
175 */
176static void ar6000_credit_distribute(void *Context,
177 struct htc_endpoint_credit_dist *pEPDistList,
178 HTC_CREDIT_DIST_REASON Reason)
179{
180 struct htc_endpoint_credit_dist *pCurEpDist;
181 struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context;
182
183 switch (Reason) {
184 case HTC_CREDIT_DIST_SEND_COMPLETE :
185 pCurEpDist = pEPDistList;
186 /* we are given the start of the endpoint distribution list.
187 * There may be one or more endpoints to service.
188 * Run through the list and distribute credits */
189 while (pCurEpDist != NULL) {
190
191 if (pCurEpDist->TxCreditsToDist > 0) {
192 /* return the credits back to the endpoint */
193 pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist;
194 /* always zero out when we are done */
195 pCurEpDist->TxCreditsToDist = 0;
196
197 if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsAssigned) {
198 /* reduce to the assigned limit, previous credit reductions
199 * could have caused the limit to change */
200 ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsAssigned);
201 }
202
203 if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsNorm) {
204 /* oversubscribed endpoints need to reduce back to normal */
205 ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsNorm);
206 }
207
208 if (!IS_EP_ACTIVE(pCurEpDist)) {
209 /* endpoint is inactive, now check for messages waiting for credits */
210 if (pCurEpDist->TxQueueDepth == 0) {
211 /* EP is inactive and there are no pending messages,
212 * reduce credits back to zero to recover credits */
213 ReduceCredits(pCredInfo, pCurEpDist, 0);
214 }
215 }
216 }
217
218 pCurEpDist = pCurEpDist->pNext;
219 }
220
221 break;
222
223 case HTC_CREDIT_DIST_ACTIVITY_CHANGE :
224 RedistributeCredits(pCredInfo,pEPDistList);
225 break;
226 case HTC_CREDIT_DIST_SEEK_CREDITS :
227 SeekCredits(pCredInfo,pEPDistList);
228 break;
229 case HTC_DUMP_CREDIT_STATE :
230 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Credit Distribution, total : %d, free : %d\n",
231 pCredInfo->TotalAvailableCredits, pCredInfo->CurrentFreeCredits));
232 break;
233 default:
234 break;
235
236 }
237
238 /* sanity checks done after each distribution action */
239 A_ASSERT(pCredInfo->CurrentFreeCredits <= pCredInfo->TotalAvailableCredits);
240 A_ASSERT(pCredInfo->CurrentFreeCredits >= 0);
241
242}
243
244/* redistribute credits based on activity change */
245static void RedistributeCredits(struct common_credit_state_info *pCredInfo,
246 struct htc_endpoint_credit_dist *pEPDistList)
247{
248 struct htc_endpoint_credit_dist *pCurEpDist = pEPDistList;
249
250 /* walk through the list and remove credits from inactive endpoints */
251 while (pCurEpDist != NULL) {
252
253#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
254
255 if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC) || (pCurEpDist->ServiceID == WMI_DATA_BE_SVC)) {
256 /* force low priority streams to always be active to retain their minimum credit distribution */
257 SET_EP_ACTIVE(pCurEpDist);
258 }
259#endif
260
261 if (pCurEpDist->ServiceID != WMI_CONTROL_SVC) {
262 if (!IS_EP_ACTIVE(pCurEpDist)) {
263 if (pCurEpDist->TxQueueDepth == 0) {
264 /* EP is inactive and there are no pending messages, reduce credits back to zero */
265 ReduceCredits(pCredInfo, pCurEpDist, 0);
266 } else {
267 /* we cannot zero the credits assigned to this EP, but to keep
268 * the credits available for these leftover packets, reduce to
269 * a minimum */
270 ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsMin);
271 }
272 }
273 }
274
275 /* NOTE in the active case, we do not need to do anything further,
276 * when an EP goes active and needs credits, HTC will call into
277 * our distribution function using a reason code of HTC_CREDIT_DIST_SEEK_CREDITS */
278
279 pCurEpDist = pCurEpDist->pNext;
280 }
281
282}
283
284/* HTC has an endpoint that needs credits, pEPDist is the endpoint in question */
285static void SeekCredits(struct common_credit_state_info *pCredInfo,
286 struct htc_endpoint_credit_dist *pEPDist)
287{
288 struct htc_endpoint_credit_dist *pCurEpDist;
289 int credits = 0;
290 int need;
291
292 do {
293
294 if (pEPDist->ServiceID == WMI_CONTROL_SVC) {
295 /* we never oversubscribe on the control service, this is not
296 * a high performance path and the target never holds onto control
297 * credits for too long */
298 break;
299 }
300
301#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
302 if (pEPDist->ServiceID == WMI_DATA_VI_SVC) {
303 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) {
304 /* limit VI service from oversubscribing */
305 break;
306 }
307 }
308
309 if (pEPDist->ServiceID == WMI_DATA_VO_SVC) {
310 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) {
311 /* limit VO service from oversubscribing */
312 break;
313 }
314 }
315#else
316 if (pEPDist->ServiceID == WMI_DATA_VI_SVC) {
317 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) ||
318 (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg)) {
319 /* limit VI service from oversubscribing */
320 /* at least one free credit will not be used by VI */
321 break;
322 }
323 }
324
325 if (pEPDist->ServiceID == WMI_DATA_VO_SVC) {
326 if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) ||
327 (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg)) {
328 /* limit VO service from oversubscribing */
329 /* at least one free credit will not be used by VO */
330 break;
331 }
332 }
333#endif
334
335 /* for all other services, we follow a simple algorithm of
336 * 1. checking the free pool for credits
337 * 2. checking lower priority endpoints for credits to take */
338
339 /* give what we can */
340 credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek);
341
342 if (credits >= pEPDist->TxCreditsSeek) {
343 /* we found some to fulfill the seek request */
344 break;
345 }
346
347 /* we don't have enough in the free pool, try taking away from lower priority services
348 *
349 * The rule for taking away credits:
350 * 1. Only take from lower priority endpoints
351 * 2. Only take what is allocated above the minimum (never starve an endpoint completely)
352 * 3. Only take what you need.
353 *
354 * */
355
356 /* starting at the lowest priority */
357 pCurEpDist = pCredInfo->pLowestPriEpDist;
358
359 /* work backwards until we hit the endpoint again */
360 while (pCurEpDist != pEPDist) {
361 /* calculate how many we need so far */
362 need = pEPDist->TxCreditsSeek - pCredInfo->CurrentFreeCredits;
363
364 if ((pCurEpDist->TxCreditsAssigned - need) >= pCurEpDist->TxCreditsMin) {
365 /* the current one has been allocated more than it's minimum and it
366 * has enough credits assigned above it's minimum to fulfill our need
367 * try to take away just enough to fulfill our need */
368 ReduceCredits(pCredInfo,
369 pCurEpDist,
370 pCurEpDist->TxCreditsAssigned - need);
371
372 if (pCredInfo->CurrentFreeCredits >= pEPDist->TxCreditsSeek) {
373 /* we have enough */
374 break;
375 }
376 }
377
378 pCurEpDist = pCurEpDist->pPrev;
379 }
380
381 /* return what we can get */
382 credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek);
383
384 } while (false);
385
386 /* did we find some credits? */
387 if (credits) {
388 /* give what we can */
389 GiveCredits(pCredInfo, pEPDist, credits);
390 }
391
392}
393
394/* initialize and setup credit distribution */
395int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo)
396{
397 HTC_SERVICE_ID servicepriority[5];
398
399 A_MEMZERO(pCredInfo,sizeof(struct common_credit_state_info));
400
401 servicepriority[0] = WMI_CONTROL_SVC; /* highest */
402 servicepriority[1] = WMI_DATA_VO_SVC;
403 servicepriority[2] = WMI_DATA_VI_SVC;
404 servicepriority[3] = WMI_DATA_BE_SVC;
405 servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
406
407 /* set callbacks and priority list */
408 HTCSetCreditDistribution(HTCHandle,
409 pCredInfo,
410 ar6000_credit_distribute,
411 ar6000_credit_init,
412 servicepriority,
413 5);
414
415 return 0;
416}
417
diff --git a/drivers/staging/ath6kl/miscdrv/miscdrv.h b/drivers/staging/ath6kl/miscdrv/miscdrv.h
new file mode 100644
index 00000000000..41be5670db4
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/miscdrv.h
@@ -0,0 +1,42 @@
1//------------------------------------------------------------------------------
2// <copyright file="miscdrv.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _MISCDRV_H
24#define _MISCDRV_H
25
26
27#define HOST_INTEREST_ITEM_ADDRESS(target, item) \
28 AR6002_HOST_INTEREST_ITEM_ADDRESS(item)
29
30u32 ar6kRev2Array[][128] = {
31 {0xFFFF, 0xFFFF}, // No Patches
32 };
33
34#define CFG_REV2_ITEMS 0 // no patches so far
35#define AR6K_RESET_ADDR 0x4000
36#define AR6K_RESET_VAL 0x100
37
38#define EEPROM_SZ 768
39#define EEPROM_WAIT_LIMIT 4
40
41#endif
42
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c
new file mode 100644
index 00000000000..32ee39ad00d
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c
@@ -0,0 +1,6267 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24/*
25 * This driver is a pseudo ethernet driver to access the Atheros AR6000
26 * WLAN Device
27 */
28
29#include "ar6000_drv.h"
30#include "cfg80211.h"
31#include "htc.h"
32#include "wmi_filter_linux.h"
33#include "epping_test.h"
34#include "wlan_config.h"
35#include "ar3kconfig.h"
36#include "ar6k_pal.h"
37#include "AR6002/addrs.h"
38
39
40/* LINUX_HACK_FUDGE_FACTOR -- this is used to provide a workaround for linux behavior. When
41 * the meta data was added to the header it was found that linux did not correctly provide
42 * enough headroom. However when more headroom was requested beyond what was truly needed
43 * Linux gave the requested headroom. Therefore to get the necessary headroom from Linux
44 * the driver requests more than is needed by the amount = LINUX_HACK_FUDGE_FACTOR */
45#define LINUX_HACK_FUDGE_FACTOR 16
46#define BDATA_BDADDR_OFFSET 28
47
48u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
49u8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
50
51#ifdef DEBUG
52
53#define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0)
54#define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1)
55#define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2)
56#define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3)
57#define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4)
58#define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5)
59#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
60
61static struct ath_debug_mask_description driver_debug_desc[] = {
62 { ATH_DEBUG_DBG_LOG , "Target Debug Logs"},
63 { ATH_DEBUG_WLAN_CONNECT , "WLAN connect"},
64 { ATH_DEBUG_WLAN_SCAN , "WLAN scan"},
65 { ATH_DEBUG_WLAN_TX , "WLAN Tx"},
66 { ATH_DEBUG_WLAN_RX , "WLAN Rx"},
67 { ATH_DEBUG_HTC_RAW , "HTC Raw IF tracing"},
68 { ATH_DEBUG_HCI_BRIDGE , "HCI Bridge Setup"},
69 { ATH_DEBUG_HCI_RECV , "HCI Recv tracing"},
70 { ATH_DEBUG_HCI_DUMP , "HCI Packet dumps"},
71};
72
73ATH_DEBUG_INSTANTIATE_MODULE_VAR(driver,
74 "driver",
75 "Linux Driver Interface",
76 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_WLAN_SCAN |
77 ATH_DEBUG_HCI_BRIDGE,
78 ATH_DEBUG_DESCRIPTION_COUNT(driver_debug_desc),
79 driver_debug_desc);
80
81#endif
82
83
84#define IS_MAC_NULL(mac) (mac[0]==0 && mac[1]==0 && mac[2]==0 && mac[3]==0 && mac[4]==0 && mac[5]==0)
85#define IS_MAC_BCAST(mac) (*mac==0xff)
86
87#define DESCRIPTION "Driver to access the Atheros AR600x Device, version " __stringify(__VER_MAJOR_) "." __stringify(__VER_MINOR_) "." __stringify(__VER_PATCH_) "." __stringify(__BUILD_NUMBER_)
88
89MODULE_AUTHOR("Atheros Communications, Inc.");
90MODULE_DESCRIPTION(DESCRIPTION);
91MODULE_LICENSE("Dual BSD/GPL");
92
93#ifndef REORG_APTC_HEURISTICS
94#undef ADAPTIVE_POWER_THROUGHPUT_CONTROL
95#endif /* REORG_APTC_HEURISTICS */
96
97#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
98#define APTC_TRAFFIC_SAMPLING_INTERVAL 100 /* msec */
99#define APTC_UPPER_THROUGHPUT_THRESHOLD 3000 /* Kbps */
100#define APTC_LOWER_THROUGHPUT_THRESHOLD 2000 /* Kbps */
101
102typedef struct aptc_traffic_record {
103 bool timerScheduled;
104 struct timeval samplingTS;
105 unsigned long bytesReceived;
106 unsigned long bytesTransmitted;
107} APTC_TRAFFIC_RECORD;
108
109A_TIMER aptcTimer;
110APTC_TRAFFIC_RECORD aptcTR;
111#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
112
113#ifdef EXPORT_HCI_BRIDGE_INTERFACE
114// callbacks registered by HCI transport driver
115struct hci_transport_callbacks ar6kHciTransCallbacks = { NULL };
116#endif
117
118unsigned int processDot11Hdr = 0;
119
120char ifname[IFNAMSIZ] = {0,};
121
122int wlaninitmode = WLAN_INIT_MODE_DEFAULT;
123static bool bypasswmi;
124unsigned int debuglevel = 0;
125int tspecCompliance = ATHEROS_COMPLIANCE;
126unsigned int busspeedlow = 0;
127unsigned int onebitmode = 0;
128unsigned int skipflash = 0;
129unsigned int wmitimeout = 2;
130unsigned int wlanNodeCaching = 1;
131unsigned int enableuartprint = ENABLEUARTPRINT_DEFAULT;
132unsigned int logWmiRawMsgs = 0;
133unsigned int enabletimerwar = 0;
134unsigned int num_device = 1;
135unsigned int regscanmode;
136unsigned int fwmode = 1;
137unsigned int mbox_yield_limit = 99;
138unsigned int enablerssicompensation = 0;
139int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF;
140int allow_trace_signal = 0;
141#ifdef CONFIG_HOST_TCMD_SUPPORT
142unsigned int testmode =0;
143#endif
144
145unsigned int irqprocmode = HIF_DEVICE_IRQ_SYNC_ONLY;//HIF_DEVICE_IRQ_ASYNC_SYNC;
146unsigned int panic_on_assert = 1;
147unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT;
148
149unsigned int setuphci = SETUPHCI_DEFAULT;
150unsigned int loghci = 0;
151unsigned int setupbtdev = SETUPBTDEV_DEFAULT;
152#ifndef EXPORT_HCI_BRIDGE_INTERFACE
153unsigned int ar3khcibaud = AR3KHCIBAUD_DEFAULT;
154unsigned int hciuartscale = HCIUARTSCALE_DEFAULT;
155unsigned int hciuartstep = HCIUARTSTEP_DEFAULT;
156#endif
157unsigned int csumOffload=0;
158unsigned int csumOffloadTest=0;
159unsigned int eppingtest=0;
160unsigned int mac_addr_method;
161unsigned int firmware_bridge;
162
163module_param_string(ifname, ifname, sizeof(ifname), 0644);
164module_param(wlaninitmode, int, 0644);
165module_param(bypasswmi, bool, 0644);
166module_param(debuglevel, uint, 0644);
167module_param(tspecCompliance, int, 0644);
168module_param(onebitmode, uint, 0644);
169module_param(busspeedlow, uint, 0644);
170module_param(skipflash, uint, 0644);
171module_param(wmitimeout, uint, 0644);
172module_param(wlanNodeCaching, uint, 0644);
173module_param(logWmiRawMsgs, uint, 0644);
174module_param(enableuartprint, uint, 0644);
175module_param(enabletimerwar, uint, 0644);
176module_param(fwmode, uint, 0644);
177module_param(mbox_yield_limit, uint, 0644);
178module_param(reduce_credit_dribble, int, 0644);
179module_param(allow_trace_signal, int, 0644);
180module_param(enablerssicompensation, uint, 0644);
181module_param(processDot11Hdr, uint, 0644);
182module_param(csumOffload, uint, 0644);
183#ifdef CONFIG_HOST_TCMD_SUPPORT
184module_param(testmode, uint, 0644);
185#endif
186module_param(irqprocmode, uint, 0644);
187module_param(nohifscattersupport, uint, 0644);
188module_param(panic_on_assert, uint, 0644);
189module_param(setuphci, uint, 0644);
190module_param(loghci, uint, 0644);
191module_param(setupbtdev, uint, 0644);
192#ifndef EXPORT_HCI_BRIDGE_INTERFACE
193module_param(ar3khcibaud, uint, 0644);
194module_param(hciuartscale, uint, 0644);
195module_param(hciuartstep, uint, 0644);
196#endif
197module_param(eppingtest, uint, 0644);
198
199/* in 2.6.10 and later this is now a pointer to a uint */
200unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX;
201#define mboxnum &_mboxnum
202
203#ifdef DEBUG
204u32 g_dbg_flags = DBG_DEFAULTS;
205unsigned int debugflags = 0;
206int debugdriver = 0;
207unsigned int debughtc = 0;
208unsigned int debugbmi = 0;
209unsigned int debughif = 0;
210unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0};
211unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0};
212unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0};
213unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0};
214module_param(debugflags, uint, 0644);
215module_param(debugdriver, int, 0644);
216module_param(debughtc, uint, 0644);
217module_param(debugbmi, uint, 0644);
218module_param(debughif, uint, 0644);
219module_param_array(txcreditsavailable, uint, mboxnum, 0644);
220module_param_array(txcreditsconsumed, uint, mboxnum, 0644);
221module_param_array(txcreditintrenable, uint, mboxnum, 0644);
222module_param_array(txcreditintrenableaggregate, uint, mboxnum, 0644);
223
224#endif /* DEBUG */
225
226unsigned int resetok = 1;
227unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0};
228unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0};
229unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0};
230unsigned int hifBusRequestNumMax = 40;
231unsigned int war23838_disabled = 0;
232#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
233unsigned int enableAPTCHeuristics = 1;
234#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
235module_param_array(tx_attempt, uint, mboxnum, 0644);
236module_param_array(tx_post, uint, mboxnum, 0644);
237module_param_array(tx_complete, uint, mboxnum, 0644);
238module_param(hifBusRequestNumMax, uint, 0644);
239module_param(war23838_disabled, uint, 0644);
240module_param(resetok, uint, 0644);
241#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
242module_param(enableAPTCHeuristics, uint, 0644);
243#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
244
245#ifdef BLOCK_TX_PATH_FLAG
246int blocktx = 0;
247module_param(blocktx, int, 0644);
248#endif /* BLOCK_TX_PATH_FLAG */
249
250typedef struct user_rssi_compensation_t {
251 u16 customerID;
252 union {
253 u16 a_enable;
254 u16 bg_enable;
255 u16 enable;
256 };
257 s16 bg_param_a;
258 s16 bg_param_b;
259 s16 a_param_a;
260 s16 a_param_b;
261 u32 reserved;
262} USER_RSSI_CPENSATION;
263
264static USER_RSSI_CPENSATION rssi_compensation_param;
265
266static s16 rssi_compensation_table[96];
267
268int reconnect_flag = 0;
269static ar6k_pal_config_t ar6k_pal_config_g;
270
271/* Function declarations */
272static int ar6000_init_module(void);
273static void ar6000_cleanup_module(void);
274
275int ar6000_init(struct net_device *dev);
276static int ar6000_open(struct net_device *dev);
277static int ar6000_close(struct net_device *dev);
278static void ar6000_init_control_info(struct ar6_softc *ar);
279static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev);
280
281void ar6000_destroy(struct net_device *dev, unsigned int unregister);
282static void ar6000_detect_error(unsigned long ptr);
283static void ar6000_set_multicast_list(struct net_device *dev);
284static struct net_device_stats *ar6000_get_stats(struct net_device *dev);
285
286static void disconnect_timer_handler(unsigned long ptr);
287
288void read_rssi_compensation_param(struct ar6_softc *ar);
289
290/*
291 * HTC service connection handlers
292 */
293static int ar6000_avail_ev(void *context, void *hif_handle);
294
295static int ar6000_unavail_ev(void *context, void *hif_handle);
296
297int ar6000_configure_target(struct ar6_softc *ar);
298
299static void ar6000_target_failure(void *Instance, int Status);
300
301static void ar6000_rx(void *Context, struct htc_packet *pPacket);
302
303static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint);
304
305static void ar6000_tx_complete(void *Context, struct htc_packet_queue *pPackets);
306
307static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket);
308
309static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num);
310static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf);
311//static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf);
312
313static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length);
314
315static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count);
316
317static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar);
318
319static ssize_t
320ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
321 struct bin_attribute *bin_attr,
322 char *buf, loff_t pos, size_t count);
323
324static ssize_t
325ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
326 struct bin_attribute *bin_attr,
327 char *buf, loff_t pos, size_t count);
328
329static int
330ar6000_sysfs_bmi_init(struct ar6_softc *ar);
331
332void ar6k_cleanup_hci_pal(struct ar6_softc *ar);
333
334static void
335ar6000_sysfs_bmi_deinit(struct ar6_softc *ar);
336
337int
338ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode);
339
340/*
341 * Static variables
342 */
343
344struct net_device *ar6000_devices[MAX_AR6000];
345static int is_netdev_registered;
346DECLARE_WAIT_QUEUE_HEAD(arEvent);
347static void ar6000_cookie_init(struct ar6_softc *ar);
348static void ar6000_cookie_cleanup(struct ar6_softc *ar);
349static void ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie);
350static struct ar_cookie *ar6000_alloc_cookie(struct ar6_softc *ar);
351
352static int ar6000_reinstall_keys(struct ar6_softc *ar,u8 key_op_ctrl);
353
354#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
355struct net_device *arApNetDev;
356#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
357
358static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM];
359
360#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
361 (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
362 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
363
364
365static struct net_device_ops ar6000_netdev_ops = {
366 .ndo_init = NULL,
367 .ndo_open = ar6000_open,
368 .ndo_stop = ar6000_close,
369 .ndo_get_stats = ar6000_get_stats,
370 .ndo_start_xmit = ar6000_data_tx,
371 .ndo_set_multicast_list = ar6000_set_multicast_list,
372};
373
374/* Debug log support */
375
376/*
377 * Flag to govern whether the debug logs should be parsed in the kernel
378 * or reported to the application.
379 */
380#define REPORT_DEBUG_LOGS_TO_APP
381
382int
383ar6000_set_host_app_area(struct ar6_softc *ar)
384{
385 u32 address, data;
386 struct host_app_area_s host_app_area;
387
388 /* Fetch the address of the host_app_area_s instance in the host interest area */
389 address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest));
390 if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != 0) {
391 return A_ERROR;
392 }
393 address = TARG_VTOP(ar->arTargetType, data);
394 host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
395 if (ar6000_WriteDataDiag(ar->arHifDevice, address,
396 (u8 *)&host_app_area,
397 sizeof(struct host_app_area_s)) != 0)
398 {
399 return A_ERROR;
400 }
401
402 return 0;
403}
404
405u32 dbglog_get_debug_hdr_ptr(struct ar6_softc *ar)
406{
407 u32 param;
408 u32 address;
409 int status;
410
411 address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr));
412 if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address,
413 (u8 *)&param, 4)) != 0)
414 {
415 param = 0;
416 }
417
418 return param;
419}
420
421/*
422 * The dbglog module has been initialized. Its ok to access the relevant
423 * data stuctures over the diagnostic window.
424 */
425void
426ar6000_dbglog_init_done(struct ar6_softc *ar)
427{
428 ar->dbglog_init_done = true;
429}
430
431u32 dbglog_get_debug_fragment(s8 *datap, u32 len, u32 limit)
432{
433 s32 *buffer;
434 u32 count;
435 u32 numargs;
436 u32 length;
437 u32 fraglen;
438
439 count = fraglen = 0;
440 buffer = (s32 *)datap;
441 length = (limit >> 2);
442
443 if (len <= limit) {
444 fraglen = len;
445 } else {
446 while (count < length) {
447 numargs = DBGLOG_GET_NUMARGS(buffer[count]);
448 fraglen = (count << 2);
449 count += numargs + 1;
450 }
451 }
452
453 return fraglen;
454}
455
456void
457dbglog_parse_debug_logs(s8 *datap, u32 len)
458{
459 s32 *buffer;
460 u32 count;
461 u32 timestamp;
462 u32 debugid;
463 u32 moduleid;
464 u32 numargs;
465 u32 length;
466
467 count = 0;
468 buffer = (s32 *)datap;
469 length = (len >> 2);
470 while (count < length) {
471 debugid = DBGLOG_GET_DBGID(buffer[count]);
472 moduleid = DBGLOG_GET_MODULEID(buffer[count]);
473 numargs = DBGLOG_GET_NUMARGS(buffer[count]);
474 timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]);
475 switch (numargs) {
476 case 0:
477 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d)\n", moduleid, debugid, timestamp));
478 break;
479
480 case 1:
481 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x\n", moduleid, debugid,
482 timestamp, buffer[count+1]));
483 break;
484
485 case 2:
486 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x, 0x%x\n", moduleid, debugid,
487 timestamp, buffer[count+1], buffer[count+2]));
488 break;
489
490 default:
491 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid args: %d\n", numargs));
492 }
493 count += numargs + 1;
494 }
495}
496
497int
498ar6000_dbglog_get_debug_logs(struct ar6_softc *ar)
499{
500 u32 data[8]; /* Should be able to accommodate struct dbglog_buf_s */
501 u32 address;
502 u32 length;
503 u32 dropped;
504 u32 firstbuf;
505 u32 debug_hdr_ptr;
506
507 if (!ar->dbglog_init_done) return A_ERROR;
508
509
510 AR6000_SPIN_LOCK(&ar->arLock, 0);
511
512 if (ar->dbgLogFetchInProgress) {
513 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
514 return A_EBUSY;
515 }
516
517 /* block out others */
518 ar->dbgLogFetchInProgress = true;
519
520 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
521
522 debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar);
523 printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr);
524
525 /* Get the contents of the ring buffer */
526 if (debug_hdr_ptr) {
527 address = TARG_VTOP(ar->arTargetType, debug_hdr_ptr);
528 length = 4 /* sizeof(dbuf) */ + 4 /* sizeof(dropped) */;
529 A_MEMZERO(data, sizeof(data));
530 ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)data, length);
531 address = TARG_VTOP(ar->arTargetType, data[0] /* dbuf */);
532 firstbuf = address;
533 dropped = data[1]; /* dropped */
534 length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
535 A_MEMZERO(data, sizeof(data));
536 ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)&data, length);
537
538 do {
539 address = TARG_VTOP(ar->arTargetType, data[1] /* buffer*/);
540 length = data[3]; /* length */
541 if ((length) && (length <= data[2] /* bufsize*/)) {
542 /* Rewind the index if it is about to overrun the buffer */
543 if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) {
544 ar->log_cnt = 0;
545 }
546 if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address,
547 (u8 *)&ar->log_buffer[ar->log_cnt], length))
548 {
549 break;
550 }
551 ar6000_dbglog_event(ar, dropped, (s8 *)&ar->log_buffer[ar->log_cnt], length);
552 ar->log_cnt += length;
553 } else {
554 AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("Length: %d (Total size: %d)\n",
555 data[3], data[2]));
556 }
557
558 address = TARG_VTOP(ar->arTargetType, data[0] /* next */);
559 length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
560 A_MEMZERO(data, sizeof(data));
561 if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address,
562 (u8 *)&data, length))
563 {
564 break;
565 }
566
567 } while (address != firstbuf);
568 }
569
570 ar->dbgLogFetchInProgress = false;
571
572 return 0;
573}
574
575void
576ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped,
577 s8 *buffer, u32 length)
578{
579#ifdef REPORT_DEBUG_LOGS_TO_APP
580 #define MAX_WIRELESS_EVENT_SIZE 252
581 /*
582 * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.
583 * There seems to be a limitation on the length of message that could be
584 * transmitted to the user app via this mechanism.
585 */
586 u32 send, sent;
587
588 sent = 0;
589 send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
590 MAX_WIRELESS_EVENT_SIZE);
591 while (send) {
592 sent += send;
593 send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
594 MAX_WIRELESS_EVENT_SIZE);
595 }
596#else
597 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Dropped logs: 0x%x\nDebug info length: %d\n",
598 dropped, length));
599
600 /* Interpret the debug logs */
601 dbglog_parse_debug_logs((s8 *)buffer, length);
602#endif /* REPORT_DEBUG_LOGS_TO_APP */
603}
604
605
606static int __init
607ar6000_init_module(void)
608{
609 static int probed = 0;
610 int r;
611 OSDRV_CALLBACKS osdrvCallbacks;
612
613 a_module_debug_support_init();
614
615#ifdef DEBUG
616 /* check for debug mask overrides */
617 if (debughtc != 0) {
618 ATH_DEBUG_SET_DEBUG_MASK(htc,debughtc);
619 }
620 if (debugbmi != 0) {
621 ATH_DEBUG_SET_DEBUG_MASK(bmi,debugbmi);
622 }
623 if (debughif != 0) {
624 ATH_DEBUG_SET_DEBUG_MASK(hif,debughif);
625 }
626 if (debugdriver != 0) {
627 ATH_DEBUG_SET_DEBUG_MASK(driver,debugdriver);
628 }
629
630#endif
631
632 A_REGISTER_MODULE_DEBUG_INFO(driver);
633
634 A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks));
635 osdrvCallbacks.deviceInsertedHandler = ar6000_avail_ev;
636 osdrvCallbacks.deviceRemovedHandler = ar6000_unavail_ev;
637#ifdef CONFIG_PM
638 osdrvCallbacks.deviceSuspendHandler = ar6000_suspend_ev;
639 osdrvCallbacks.deviceResumeHandler = ar6000_resume_ev;
640 osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev;
641#endif
642
643#ifdef DEBUG
644 /* Set the debug flags if specified at load time */
645 if(debugflags != 0)
646 {
647 g_dbg_flags = debugflags;
648 }
649#endif
650
651 if (probed) {
652 return -ENODEV;
653 }
654 probed++;
655
656#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
657 memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD));
658#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
659
660 r = HIFInit(&osdrvCallbacks);
661 if (r)
662 return r;
663
664 return 0;
665}
666
667static void __exit
668ar6000_cleanup_module(void)
669{
670 int i = 0;
671 struct net_device *ar6000_netdev;
672
673#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
674 /* Delete the Adaptive Power Control timer */
675 if (timer_pending(&aptcTimer)) {
676 del_timer_sync(&aptcTimer);
677 }
678#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
679
680 for (i=0; i < MAX_AR6000; i++) {
681 if (ar6000_devices[i] != NULL) {
682 ar6000_netdev = ar6000_devices[i];
683 ar6000_devices[i] = NULL;
684 ar6000_destroy(ar6000_netdev, 1);
685 }
686 }
687
688 HIFShutDownDevice(NULL);
689
690 a_module_debug_support_cleanup();
691
692 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n"));
693}
694
695#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
696void
697aptcTimerHandler(unsigned long arg)
698{
699 u32 numbytes;
700 u32 throughput;
701 struct ar6_softc *ar;
702 int status;
703
704 ar = (struct ar6_softc *)arg;
705 A_ASSERT(ar != NULL);
706 A_ASSERT(!timer_pending(&aptcTimer));
707
708 AR6000_SPIN_LOCK(&ar->arLock, 0);
709
710 /* Get the number of bytes transferred */
711 numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
712 aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
713
714 /* Calculate and decide based on throughput thresholds */
715 throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */
716 if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) {
717 /* Enable Sleep and delete the timer */
718 A_ASSERT(ar->arWmiReady == true);
719 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
720 status = wmi_powermode_cmd(ar->arWmi, REC_POWER);
721 AR6000_SPIN_LOCK(&ar->arLock, 0);
722 A_ASSERT(status == 0);
723 aptcTR.timerScheduled = false;
724 } else {
725 A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
726 }
727
728 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
729}
730#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
731
732static void
733ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num)
734{
735 void * osbuf;
736
737 while(num) {
738 if((osbuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE))) {
739 A_NETBUF_ENQUEUE(q, osbuf);
740 } else {
741 break;
742 }
743 num--;
744 }
745
746 if(num) {
747 A_PRINTF("%s(), allocation of netbuf failed", __func__);
748 }
749}
750
751static struct bin_attribute bmi_attr = {
752 .attr = {.name = "bmi", .mode = 0600},
753 .read = ar6000_sysfs_bmi_read,
754 .write = ar6000_sysfs_bmi_write,
755};
756
757static ssize_t
758ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
759 struct bin_attribute *bin_attr,
760 char *buf, loff_t pos, size_t count)
761{
762 int index;
763 struct ar6_softc *ar;
764 struct hif_device_os_device_info *osDevInfo;
765
766 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (u32)count));
767 for (index=0; index < MAX_AR6000; index++) {
768 ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]);
769 osDevInfo = &ar->osDevInfo;
770 if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
771 break;
772 }
773 }
774
775 if (index == MAX_AR6000) return 0;
776
777 if ((BMIRawRead(ar->arHifDevice, (u8*)buf, count, true)) != 0) {
778 return 0;
779 }
780
781 return count;
782}
783
784static ssize_t
785ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
786 struct bin_attribute *bin_attr,
787 char *buf, loff_t pos, size_t count)
788{
789 int index;
790 struct ar6_softc *ar;
791 struct hif_device_os_device_info *osDevInfo;
792
793 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (u32)count));
794 for (index=0; index < MAX_AR6000; index++) {
795 ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]);
796 osDevInfo = &ar->osDevInfo;
797 if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
798 break;
799 }
800 }
801
802 if (index == MAX_AR6000) return 0;
803
804 if ((BMIRawWrite(ar->arHifDevice, (u8*)buf, count)) != 0) {
805 return 0;
806 }
807
808 return count;
809}
810
811static int
812ar6000_sysfs_bmi_init(struct ar6_softc *ar)
813{
814 int status;
815
816 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Creating sysfs entry\n"));
817 A_MEMZERO(&ar->osDevInfo, sizeof(struct hif_device_os_device_info));
818
819 /* Get the underlying OS device */
820 status = HIFConfigureDevice(ar->arHifDevice,
821 HIF_DEVICE_GET_OS_DEVICE,
822 &ar->osDevInfo,
823 sizeof(struct hif_device_os_device_info));
824
825 if (status) {
826 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failed to get OS device info from HIF\n"));
827 return A_ERROR;
828 }
829
830 /* Create a bmi entry in the sysfs filesystem */
831 if ((sysfs_create_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr)) < 0)
832 {
833 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to create entry for bmi in sysfs filesystem\n"));
834 return A_ERROR;
835 }
836
837 return 0;
838}
839
840static void
841ar6000_sysfs_bmi_deinit(struct ar6_softc *ar)
842{
843 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Deleting sysfs entry\n"));
844
845 sysfs_remove_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr);
846}
847
848#define bmifn(fn) do { \
849 if ((fn) < 0) { \
850 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); \
851 return A_ERROR; \
852 } \
853} while(0)
854
855#ifdef SOFTMAC_FILE_USED
856#define AR6002_MAC_ADDRESS_OFFSET 0x0A
857#define AR6003_MAC_ADDRESS_OFFSET 0x16
858static
859void calculate_crc(u32 TargetType, u8 *eeprom_data)
860{
861 u16 *ptr_crc;
862 u16 *ptr16_eeprom;
863 u16 checksum;
864 u32 i;
865 u32 eeprom_size;
866
867 if (TargetType == TARGET_TYPE_AR6001)
868 {
869 eeprom_size = 512;
870 ptr_crc = (u16 *)eeprom_data;
871 }
872 else if (TargetType == TARGET_TYPE_AR6003)
873 {
874 eeprom_size = 1024;
875 ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04);
876 }
877 else
878 {
879 eeprom_size = 768;
880 ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04);
881 }
882
883
884 // Clear the crc
885 *ptr_crc = 0;
886
887 // Recalculate new CRC
888 checksum = 0;
889 ptr16_eeprom = (u16 *)eeprom_data;
890 for (i = 0;i < eeprom_size; i += 2)
891 {
892 checksum = checksum ^ (*ptr16_eeprom);
893 ptr16_eeprom++;
894 }
895 checksum = 0xFFFF ^ checksum;
896 *ptr_crc = checksum;
897}
898
899static void
900ar6000_softmac_update(struct ar6_softc *ar, u8 *eeprom_data, size_t size)
901{
902 const char *source = "random generated";
903 const struct firmware *softmac_entry;
904 u8 *ptr_mac;
905 switch (ar->arTargetType) {
906 case TARGET_TYPE_AR6002:
907 ptr_mac = (u8 *)((u8 *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET);
908 break;
909 case TARGET_TYPE_AR6003:
910 ptr_mac = (u8 *)((u8 *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET);
911 break;
912 default:
913 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Target Type\n"));
914 return;
915 }
916 printk(KERN_DEBUG "MAC from EEPROM %pM\n", ptr_mac);
917
918 /* create a random MAC in case we cannot read file from system */
919 ptr_mac[0] = 0;
920 ptr_mac[1] = 0x03;
921 ptr_mac[2] = 0x7F;
922 ptr_mac[3] = random32() & 0xff;
923 ptr_mac[4] = random32() & 0xff;
924 ptr_mac[5] = random32() & 0xff;
925 if ((A_REQUEST_FIRMWARE(&softmac_entry, "softmac", ((struct device *)ar->osDevInfo.pOSDevice))) == 0)
926 {
927 char *macbuf = A_MALLOC_NOWAIT(softmac_entry->size+1);
928 if (macbuf) {
929 unsigned int softmac[6];
930 memcpy(macbuf, softmac_entry->data, softmac_entry->size);
931 macbuf[softmac_entry->size] = '\0';
932 if (sscanf(macbuf, "%02x:%02x:%02x:%02x:%02x:%02x",
933 &softmac[0], &softmac[1], &softmac[2],
934 &softmac[3], &softmac[4], &softmac[5])==6) {
935 int i;
936 for (i=0; i<6; ++i) {
937 ptr_mac[i] = softmac[i] & 0xff;
938 }
939 source = "softmac file";
940 }
941 kfree(macbuf);
942 }
943 A_RELEASE_FIRMWARE(softmac_entry);
944 }
945 printk(KERN_DEBUG "MAC from %s %pM\n", source, ptr_mac);
946 calculate_crc(ar->arTargetType, eeprom_data);
947}
948#endif /* SOFTMAC_FILE_USED */
949
950static int
951ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, bool compressed)
952{
953 int status;
954 const char *filename;
955 const struct firmware *fw_entry;
956 u32 fw_entry_size;
957 u8 **buf;
958 size_t *buf_len;
959
960 switch (file) {
961 case AR6K_OTP_FILE:
962 buf = &ar->fw_otp;
963 buf_len = &ar->fw_otp_len;
964 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
965 filename = AR6003_REV1_OTP_FILE;
966 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
967 filename = AR6003_REV2_OTP_FILE;
968 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
969 filename = AR6003_REV3_OTP_FILE;
970 } else {
971 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
972 return A_ERROR;
973 }
974 break;
975
976 case AR6K_FIRMWARE_FILE:
977 buf = &ar->fw;
978 buf_len = &ar->fw_len;
979 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
980 filename = AR6003_REV1_FIRMWARE_FILE;
981 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
982 filename = AR6003_REV2_FIRMWARE_FILE;
983 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
984 filename = AR6003_REV3_FIRMWARE_FILE;
985 } else {
986 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
987 return A_ERROR;
988 }
989
990 if (eppingtest) {
991 bypasswmi = true;
992 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
993 filename = AR6003_REV1_EPPING_FIRMWARE_FILE;
994 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
995 filename = AR6003_REV2_EPPING_FIRMWARE_FILE;
996 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
997 filename = AR6003_REV3_EPPING_FIRMWARE_FILE;
998 } else {
999 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("eppingtest : unsupported firmware revision: %d\n",
1000 ar->arVersion.target_ver));
1001 return A_ERROR;
1002 }
1003 compressed = false;
1004 }
1005
1006#ifdef CONFIG_HOST_TCMD_SUPPORT
1007 if(testmode) {
1008 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1009 filename = AR6003_REV1_TCMD_FIRMWARE_FILE;
1010 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1011 filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
1012 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
1013 filename = AR6003_REV3_TCMD_FIRMWARE_FILE;
1014 } else {
1015 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1016 return A_ERROR;
1017 }
1018 compressed = false;
1019 }
1020#endif
1021#ifdef HTC_RAW_INTERFACE
1022 if (!eppingtest && bypasswmi) {
1023 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1024 filename = AR6003_REV1_ART_FIRMWARE_FILE;
1025 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1026 filename = AR6003_REV2_ART_FIRMWARE_FILE;
1027 } else {
1028 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1029 return A_ERROR;
1030 }
1031 compressed = false;
1032 }
1033#endif
1034 break;
1035
1036 case AR6K_PATCH_FILE:
1037 buf = &ar->fw_patch;
1038 buf_len = &ar->fw_patch_len;
1039 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1040 filename = AR6003_REV1_PATCH_FILE;
1041 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1042 filename = AR6003_REV2_PATCH_FILE;
1043 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
1044 filename = AR6003_REV3_PATCH_FILE;
1045 } else {
1046 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1047 return A_ERROR;
1048 }
1049 break;
1050
1051 case AR6K_BOARD_DATA_FILE:
1052 buf = &ar->fw_data;
1053 buf_len = &ar->fw_data_len;
1054 if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
1055 filename = AR6003_REV1_BOARD_DATA_FILE;
1056 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1057 filename = AR6003_REV2_BOARD_DATA_FILE;
1058 } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
1059 filename = AR6003_REV3_BOARD_DATA_FILE;
1060 } else {
1061 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
1062 return A_ERROR;
1063 }
1064 break;
1065
1066 default:
1067 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file));
1068 return A_ERROR;
1069 }
1070
1071 if (*buf == NULL) {
1072 if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) {
1073 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename));
1074 return A_ENOENT;
1075 }
1076
1077 *buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
1078 *buf_len = fw_entry->size;
1079 A_RELEASE_FIRMWARE(fw_entry);
1080 }
1081
1082#ifdef SOFTMAC_FILE_USED
1083 if (file==AR6K_BOARD_DATA_FILE && *buf_len) {
1084 ar6000_softmac_update(ar, *buf, *buf_len);
1085 }
1086#endif
1087
1088
1089 fw_entry_size = *buf_len;
1090
1091 /* Load extended board data for AR6003 */
1092 if ((file==AR6K_BOARD_DATA_FILE) && *buf) {
1093 u32 board_ext_address;
1094 u32 board_ext_data_size;
1095 u32 board_data_size;
1096
1097 board_ext_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_EXT_DATA_SZ : \
1098 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_EXT_DATA_SZ : 0));
1099
1100 board_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_DATA_SZ : \
1101 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_DATA_SZ : 0));
1102
1103 /* Determine where in Target RAM to write Board Data */
1104 bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (u8 *)&board_ext_address, 4));
1105 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address));
1106
1107 /* check whether the target has allocated memory for extended board data and file contains extended board data */
1108 if ((board_ext_address) && (*buf_len == (board_data_size + board_ext_data_size))) {
1109 u32 param;
1110
1111 status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(*buf + board_data_size), board_ext_data_size);
1112
1113 if (status) {
1114 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
1115 return A_ERROR;
1116 }
1117
1118 /* Record the fact that extended board Data IS initialized */
1119 param = (board_ext_data_size << 16) | 1;
1120 bmifn(BMIWriteMemory(ar->arHifDevice,
1121 HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_config),
1122 (unsigned char *)&param, 4));
1123 }
1124 fw_entry_size = board_data_size;
1125 }
1126
1127 if (compressed) {
1128 status = BMIFastDownload(ar->arHifDevice, address, *buf, fw_entry_size);
1129 } else {
1130 status = BMIWriteMemory(ar->arHifDevice, address, *buf, fw_entry_size);
1131 }
1132
1133 if (status) {
1134 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
1135 return A_ERROR;
1136 }
1137
1138 return 0;
1139}
1140
1141int
1142ar6000_update_bdaddr(struct ar6_softc *ar)
1143{
1144
1145 if (setupbtdev != 0) {
1146 u32 address;
1147
1148 if (BMIReadMemory(ar->arHifDevice,
1149 HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4) != 0)
1150 {
1151 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for hi_board_data failed\n"));
1152 return A_ERROR;
1153 }
1154
1155 if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (u8 *)ar->bdaddr, 6) != 0)
1156 {
1157 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for BD address failed\n"));
1158 return A_ERROR;
1159 }
1160 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BDADDR 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", ar->bdaddr[0],
1161 ar->bdaddr[1], ar->bdaddr[2], ar->bdaddr[3],
1162 ar->bdaddr[4], ar->bdaddr[5]));
1163 }
1164
1165return 0;
1166}
1167
1168int
1169ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode)
1170{
1171 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n"));
1172
1173 if (mode == WLAN_INIT_MODE_UDEV) {
1174 char version[16];
1175 const struct firmware *fw_entry;
1176
1177 /* Get config using udev through a script in user space */
1178 sprintf(version, "%2.2x", ar->arVersion.target_ver);
1179 if ((A_REQUEST_FIRMWARE(&fw_entry, version, ((struct device *)ar->osDevInfo.pOSDevice))) != 0)
1180 {
1181 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get configuration for target version: %s\n", version));
1182 return A_ERROR;
1183 }
1184
1185 A_RELEASE_FIRMWARE(fw_entry);
1186 } else {
1187 /* The config is contained within the driver itself */
1188 int status;
1189 u32 param, options, sleep, address;
1190
1191 /* Temporarily disable system sleep */
1192 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1193 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1194 options = param;
1195 param |= AR6K_OPTION_SLEEP_DISABLE;
1196 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1197
1198 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1199 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1200 sleep = param;
1201 param |= WLAN_SYSTEM_SLEEP_DISABLE_SET(1);
1202 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1203 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("old options: %d, old sleep: %d\n", options, sleep));
1204
1205 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1206 /* Program analog PLL register */
1207 bmifn(BMIWriteSOCRegister(ar->arHifDevice, ANALOG_INTF_BASE_ADDRESS + 0x284, 0xF9104001));
1208 /* Run at 80/88MHz by default */
1209 param = CPU_CLOCK_STANDARD_SET(1);
1210 } else {
1211 /* Run at 40/44MHz by default */
1212 param = CPU_CLOCK_STANDARD_SET(0);
1213 }
1214 address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
1215 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1216
1217 param = 0;
1218 if (ar->arTargetType == TARGET_TYPE_AR6002) {
1219 bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)&param, 4));
1220 }
1221
1222 /* LPO_CAL.ENABLE = 1 if no external clk is detected */
1223 if (param != 1) {
1224 address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
1225 param = LPO_CAL_ENABLE_SET(1);
1226 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1227 }
1228
1229 /* Venus2.0: Lower SDIO pad drive strength,
1230 * temporary WAR to avoid SDIO CRC error */
1231 if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1232 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6K: Temporary WAR to avoid SDIO CRC error\n"));
1233 param = 0x20;
1234 address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
1235 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1236
1237 address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
1238 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1239
1240 address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
1241 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1242
1243 address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
1244 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1245 }
1246
1247#ifdef FORCE_INTERNAL_CLOCK
1248 /* Ignore external clock, if any, and force use of internal clock */
1249 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1250 /* hi_ext_clk_detected = 0 */
1251 param = 0;
1252 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)&param, 4));
1253
1254 /* CLOCK_CONTROL &= ~LF_CLK32 */
1255 address = RTC_BASE_ADDRESS + CLOCK_CONTROL_ADDRESS;
1256 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1257 param &= (~CLOCK_CONTROL_LF_CLK32_SET(1));
1258 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1259 }
1260#endif /* FORCE_INTERNAL_CLOCK */
1261
1262 /* Transfer Board Data from Target EEPROM to Target RAM */
1263 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1264 /* Determine where in Target RAM to write Board Data */
1265 bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4));
1266 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", address));
1267
1268 /* Write EEPROM data to Target RAM */
1269 if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, false)) != 0) {
1270 return A_ERROR;
1271 }
1272
1273 /* Record the fact that Board Data IS initialized */
1274 param = 1;
1275 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), (u8 *)&param, 4));
1276
1277 /* Transfer One time Programmable data */
1278 AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver);
1279 if (ar->arVersion.target_ver == AR6003_REV3_VERSION)
1280 address = 0x1234;
1281 status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, true);
1282 if (status == 0) {
1283 /* Execute the OTP code */
1284 param = 0;
1285 AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
1286 bmifn(BMIExecute(ar->arHifDevice, address, &param));
1287 } else if (status != A_ENOENT) {
1288 return A_ERROR;
1289 }
1290 } else {
1291 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Programming of board data for chip %d not supported\n", ar->arTargetType));
1292 return A_ERROR;
1293 }
1294
1295 /* Download Target firmware */
1296 AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver);
1297 if (ar->arVersion.target_ver == AR6003_REV3_VERSION)
1298 address = 0x1234;
1299 if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, true)) != 0) {
1300 return A_ERROR;
1301 }
1302
1303 /* Set starting address for firmware */
1304 AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
1305 bmifn(BMISetAppStart(ar->arHifDevice, address));
1306
1307 if(ar->arTargetType == TARGET_TYPE_AR6003) {
1308 AR6K_DATASET_PATCH_ADDRESS(address, ar->arVersion.target_ver);
1309 if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE,
1310 address, false)) != 0)
1311 return A_ERROR;
1312 param = address;
1313 bmifn(BMIWriteMemory(ar->arHifDevice,
1314 HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head),
1315 (unsigned char *)&param, 4));
1316 }
1317
1318 /* Restore system sleep */
1319 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1320 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, sleep));
1321
1322 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1323 param = options | 0x20;
1324 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1325
1326 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1327 /* Configure GPIO AR6003 UART */
1328#ifndef CONFIG_AR600x_DEBUG_UART_TX_PIN
1329#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
1330#endif
1331 param = CONFIG_AR600x_DEBUG_UART_TX_PIN;
1332 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbg_uart_txpin), (u8 *)&param, 4));
1333
1334#if (CONFIG_AR600x_DEBUG_UART_TX_PIN == 23)
1335 {
1336 address = GPIO_BASE_ADDRESS + CLOCK_GPIO_ADDRESS;
1337 bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
1338 param |= CLOCK_GPIO_BT_CLK_OUT_EN_SET(1);
1339 bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
1340 }
1341#endif
1342
1343 /* Configure GPIO for BT Reset */
1344#ifdef ATH6KL_CONFIG_GPIO_BT_RESET
1345#define CONFIG_AR600x_BT_RESET_PIN 0x16
1346 param = CONFIG_AR600x_BT_RESET_PIN;
1347 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_support_pins), (u8 *)&param, 4));
1348#endif /* ATH6KL_CONFIG_GPIO_BT_RESET */
1349
1350 /* Configure UART flow control polarity */
1351#ifndef CONFIG_ATH6KL_BT_UART_FC_POLARITY
1352#define CONFIG_ATH6KL_BT_UART_FC_POLARITY 0
1353#endif
1354
1355#if (CONFIG_ATH6KL_BT_UART_FC_POLARITY == 1)
1356 if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1357 param = ((CONFIG_ATH6KL_BT_UART_FC_POLARITY << 1) & 0x2);
1358 bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_pwr_mgmt_params), (u8 *)&param, 4));
1359 }
1360#endif /* CONFIG_ATH6KL_BT_UART_FC_POLARITY */
1361 }
1362
1363#ifdef HTC_RAW_INTERFACE
1364 if (!eppingtest && bypasswmi) {
1365 /* Don't run BMIDone for ART mode and force resetok=0 */
1366 resetok = 0;
1367 msleep(1000);
1368 }
1369#endif /* HTC_RAW_INTERFACE */
1370 }
1371
1372 return 0;
1373}
1374
1375int
1376ar6000_configure_target(struct ar6_softc *ar)
1377{
1378 u32 param;
1379 if (enableuartprint) {
1380 param = 1;
1381 if (BMIWriteMemory(ar->arHifDevice,
1382 HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable),
1383 (u8 *)&param,
1384 4)!= 0)
1385 {
1386 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enableuartprint failed \n"));
1387 return A_ERROR;
1388 }
1389 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Serial console prints enabled\n"));
1390 }
1391
1392 /* Tell target which HTC version it is used*/
1393 param = HTC_PROTOCOL_VERSION;
1394 if (BMIWriteMemory(ar->arHifDevice,
1395 HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest),
1396 (u8 *)&param,
1397 4)!= 0)
1398 {
1399 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for htc version failed \n"));
1400 return A_ERROR;
1401 }
1402
1403#ifdef CONFIG_HOST_TCMD_SUPPORT
1404 if(testmode) {
1405 ar->arTargetMode = AR6000_TCMD_MODE;
1406 }else {
1407 ar->arTargetMode = AR6000_WLAN_MODE;
1408 }
1409#endif
1410 if (enabletimerwar) {
1411 u32 param;
1412
1413 if (BMIReadMemory(ar->arHifDevice,
1414 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1415 (u8 *)&param,
1416 4)!= 0)
1417 {
1418 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for enabletimerwar failed \n"));
1419 return A_ERROR;
1420 }
1421
1422 param |= HI_OPTION_TIMER_WAR;
1423
1424 if (BMIWriteMemory(ar->arHifDevice,
1425 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1426 (u8 *)&param,
1427 4) != 0)
1428 {
1429 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enabletimerwar failed \n"));
1430 return A_ERROR;
1431 }
1432 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Timer WAR enabled\n"));
1433 }
1434
1435 /* set the firmware mode to STA/IBSS/AP */
1436 {
1437 u32 param;
1438
1439 if (BMIReadMemory(ar->arHifDevice,
1440 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1441 (u8 *)&param,
1442 4)!= 0)
1443 {
1444 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for setting fwmode failed \n"));
1445 return A_ERROR;
1446 }
1447
1448 param |= (num_device << HI_OPTION_NUM_DEV_SHIFT);
1449 param |= (fwmode << HI_OPTION_FW_MODE_SHIFT);
1450 param |= (mac_addr_method << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
1451 param |= (firmware_bridge << HI_OPTION_FW_BRIDGE_SHIFT);
1452
1453
1454 if (BMIWriteMemory(ar->arHifDevice,
1455 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1456 (u8 *)&param,
1457 4) != 0)
1458 {
1459 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for setting fwmode failed \n"));
1460 return A_ERROR;
1461 }
1462 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
1463 }
1464
1465#ifdef ATH6KL_DISABLE_TARGET_DBGLOGS
1466 {
1467 u32 param;
1468
1469 if (BMIReadMemory(ar->arHifDevice,
1470 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1471 (u8 *)&param,
1472 4)!= 0)
1473 {
1474 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for disabling debug logs failed\n"));
1475 return A_ERROR;
1476 }
1477
1478 param |= HI_OPTION_DISABLE_DBGLOG;
1479
1480 if (BMIWriteMemory(ar->arHifDevice,
1481 HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
1482 (u8 *)&param,
1483 4) != 0)
1484 {
1485 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for HI_OPTION_DISABLE_DBGLOG\n"));
1486 return A_ERROR;
1487 }
1488 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
1489 }
1490#endif /* ATH6KL_DISABLE_TARGET_DBGLOGS */
1491
1492 /*
1493 * Hardcode the address use for the extended board data
1494 * Ideally this should be pre-allocate by the OS at boot time
1495 * But since it is a new feature and board data is loaded
1496 * at init time, we have to workaround this from host.
1497 * It is difficult to patch the firmware boot code,
1498 * but possible in theory.
1499 */
1500
1501 if (ar->arTargetType == TARGET_TYPE_AR6003) {
1502 u32 ramReservedSz;
1503 if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
1504 param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
1505 ramReservedSz = AR6003_REV2_RAM_RESERVE_SIZE;
1506 } else {
1507 param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
1508 ramReservedSz = AR6003_REV3_RAM_RESERVE_SIZE;
1509 }
1510 if (BMIWriteMemory(ar->arHifDevice,
1511 HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data),
1512 (u8 *)&param, 4) != 0) {
1513 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1514 ("BMIWriteMemory for "
1515 "hi_board_ext_data failed\n"));
1516 return A_ERROR;
1517 }
1518 if (BMIWriteMemory(ar->arHifDevice,
1519 HOST_INTEREST_ITEM_ADDRESS(ar,
1520 hi_end_RAM_reserve_sz),
1521 (u8 *)&ramReservedSz, 4) != 0) {
1522 AR_DEBUG_PRINTF(ATH_DEBUG_ERR ,
1523 ("BMIWriteMemory for "
1524 "hi_end_RAM_reserve_sz failed\n"));
1525 return A_ERROR;
1526 }
1527 }
1528
1529 /* since BMIInit is called in the driver layer, we have to set the block
1530 * size here for the target */
1531
1532 if (ar6000_set_htc_params(ar->arHifDevice, ar->arTargetType,
1533 mbox_yield_limit, 0)) {
1534 /* use default number of control buffers */
1535 return A_ERROR;
1536 }
1537
1538 if (setupbtdev != 0) {
1539 if (ar6000_set_hci_bridge_flags(ar->arHifDevice,
1540 ar->arTargetType,
1541 setupbtdev)) {
1542 return A_ERROR;
1543 }
1544 }
1545 return 0;
1546}
1547
1548static void
1549init_netdev(struct net_device *dev, char *name)
1550{
1551 dev->netdev_ops = &ar6000_netdev_ops;
1552 dev->watchdog_timeo = AR6000_TX_TIMEOUT;
1553
1554 /*
1555 * We need the OS to provide us with more headroom in order to
1556 * perform dix to 802.3, WMI header encap, and the HTC header
1557 */
1558 if (processDot11Hdr) {
1559 dev->hard_header_len = sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
1560 } else {
1561 dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) +
1562 sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
1563 }
1564
1565 if (name[0])
1566 {
1567 strcpy(dev->name, name);
1568 }
1569
1570#ifdef CONFIG_CHECKSUM_OFFLOAD
1571 if(csumOffload){
1572 dev->features |= NETIF_F_IP_CSUM; /*advertise kernel capability to do TCP/UDP CSUM offload for IPV4*/
1573 }
1574#endif
1575
1576 return;
1577}
1578
1579static int __ath6kl_init_netdev(struct net_device *dev)
1580{
1581 int r;
1582
1583 rtnl_lock();
1584 r = ar6000_init(dev);
1585 rtnl_unlock();
1586
1587 if (r) {
1588 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n"));
1589 return r;
1590 }
1591
1592 return 0;
1593}
1594
1595#ifdef HTC_RAW_INTERFACE
1596static int ath6kl_init_netdev_wmi(struct net_device *dev)
1597{
1598 if (!eppingtest && bypasswmi)
1599 return 0;
1600
1601 return __ath6kl_init_netdev(dev);
1602}
1603#else
1604static int ath6kl_init_netdev_wmi(struct net_device *dev)
1605{
1606 return __ath6kl_init_netdev(dev);
1607}
1608#endif
1609
1610static int ath6kl_init_netdev(struct ar6_softc *ar)
1611{
1612 int r;
1613
1614 r = ar6000_sysfs_bmi_get_config(ar, wlaninitmode);
1615 if (r) {
1616 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1617 ("ar6000_avail: "
1618 "ar6000_sysfs_bmi_get_config failed\n"));
1619 return r;
1620 }
1621
1622 return ath6kl_init_netdev_wmi(ar->arNetDev);
1623}
1624
1625/*
1626 * HTC Event handlers
1627 */
1628static int
1629ar6000_avail_ev(void *context, void *hif_handle)
1630{
1631 int i;
1632 struct net_device *dev;
1633 void *ar_netif;
1634 struct ar6_softc *ar;
1635 int device_index = 0;
1636 struct htc_init_info htcInfo;
1637 struct wireless_dev *wdev;
1638 int r = 0;
1639 struct hif_device_os_device_info osDevInfo;
1640
1641 memset(&osDevInfo, 0, sizeof(osDevInfo));
1642 if (HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE,
1643 &osDevInfo, sizeof(osDevInfo))) {
1644 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Failed to get OS device instance\n", __func__));
1645 return A_ERROR;
1646 }
1647
1648 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n"));
1649
1650 for (i=0; i < MAX_AR6000; i++) {
1651 if (ar6000_devices[i] == NULL) {
1652 break;
1653 }
1654 }
1655
1656 if (i == MAX_AR6000) {
1657 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: max devices reached\n"));
1658 return A_ERROR;
1659 }
1660
1661 /* Save this. It gives a bit better readability especially since */
1662 /* we use another local "i" variable below. */
1663 device_index = i;
1664
1665 wdev = ar6k_cfg80211_init(osDevInfo.pOSDevice);
1666 if (IS_ERR(wdev)) {
1667 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __func__));
1668 return A_ERROR;
1669 }
1670 ar_netif = wdev_priv(wdev);
1671
1672 if (ar_netif == NULL) {
1673 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Can't allocate ar6k priv memory\n", __func__));
1674 return A_ERROR;
1675 }
1676
1677 A_MEMZERO(ar_netif, sizeof(struct ar6_softc));
1678 ar = (struct ar6_softc *)ar_netif;
1679
1680 ar->wdev = wdev;
1681 wdev->iftype = NL80211_IFTYPE_STATION;
1682
1683 dev = alloc_netdev_mq(0, "wlan%d", ether_setup, 1);
1684 if (!dev) {
1685 printk(KERN_CRIT "AR6K: no memory for network device instance\n");
1686 ar6k_cfg80211_deinit(ar);
1687 return A_ERROR;
1688 }
1689
1690 dev->ieee80211_ptr = wdev;
1691 SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
1692 wdev->netdev = dev;
1693 ar->arNetworkType = INFRA_NETWORK;
1694 ar->smeState = SME_DISCONNECTED;
1695 ar->arAutoAuthStage = AUTH_IDLE;
1696
1697 init_netdev(dev, ifname);
1698
1699
1700 ar->arNetDev = dev;
1701 ar->arHifDevice = hif_handle;
1702 ar->arWlanState = WLAN_ENABLED;
1703 ar->arDeviceIndex = device_index;
1704
1705 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
1706 ar->arWlanOff = false; /* We are in ON state */
1707#ifdef CONFIG_PM
1708 ar->arWowState = WLAN_WOW_STATE_NONE;
1709 ar->arBTOff = true; /* BT chip assumed to be OFF */
1710 ar->arBTSharing = WLAN_CONFIG_BT_SHARING;
1711 ar->arWlanOffConfig = WLAN_CONFIG_WLAN_OFF;
1712 ar->arSuspendConfig = WLAN_CONFIG_PM_SUSPEND;
1713 ar->arWow2Config = WLAN_CONFIG_PM_WOW2;
1714#endif /* CONFIG_PM */
1715
1716 A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev);
1717 ar->arHBChallengeResp.seqNum = 0;
1718 ar->arHBChallengeResp.outstanding = false;
1719 ar->arHBChallengeResp.missCnt = 0;
1720 ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT;
1721 ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT;
1722
1723 ar6000_init_control_info(ar);
1724 init_waitqueue_head(&arEvent);
1725 sema_init(&ar->arSem, 1);
1726 ar->bIsDestroyProgress = false;
1727
1728 INIT_HTC_PACKET_QUEUE(&ar->amsdu_rx_buffer_queue);
1729
1730#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
1731 A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar);
1732#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
1733
1734 A_INIT_TIMER(&ar->disconnect_timer, disconnect_timer_handler, dev);
1735
1736 BMIInit();
1737
1738 ar6000_sysfs_bmi_init(ar);
1739
1740 {
1741 struct bmi_target_info targ_info;
1742
1743 r = BMIGetTargetInfo(ar->arHifDevice, &targ_info);
1744 if (r)
1745 goto avail_ev_failed;
1746
1747 ar->arVersion.target_ver = targ_info.target_ver;
1748 ar->arTargetType = targ_info.target_type;
1749 wdev->wiphy->hw_version = targ_info.target_ver;
1750 }
1751
1752 r = ar6000_configure_target(ar);
1753 if (r)
1754 goto avail_ev_failed;
1755
1756 A_MEMZERO(&htcInfo,sizeof(htcInfo));
1757 htcInfo.pContext = ar;
1758 htcInfo.TargetFailure = ar6000_target_failure;
1759
1760 ar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo);
1761
1762 if (!ar->arHtcTarget) {
1763 r = -ENOMEM;
1764 goto avail_ev_failed;
1765 }
1766
1767 spin_lock_init(&ar->arLock);
1768
1769#ifdef WAPI_ENABLE
1770 ar->arWapiEnable = 0;
1771#endif
1772
1773
1774 if(csumOffload){
1775 /*if external frame work is also needed, change and use an extended rxMetaVerion*/
1776 ar->rxMetaVersion=WMI_META_VERSION_2;
1777 }
1778
1779 ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs);
1780 if (!ar->aggr_cntxt) {
1781 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__));
1782 r = -ENOMEM;
1783 goto avail_ev_failed;
1784 }
1785
1786 aggr_register_rx_dispatcher(ar->aggr_cntxt, (void *)dev, ar6000_deliver_frames_to_nw_stack);
1787
1788 HIFClaimDevice(ar->arHifDevice, ar);
1789
1790 /* We only register the device in the global list if we succeed. */
1791 /* If the device is in the global list, it will be destroyed */
1792 /* when the module is unloaded. */
1793 ar6000_devices[device_index] = dev;
1794
1795 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode));
1796 if ((wlaninitmode == WLAN_INIT_MODE_UDEV) ||
1797 (wlaninitmode == WLAN_INIT_MODE_DRV)) {
1798 r = ath6kl_init_netdev(ar);
1799 if (r)
1800 goto avail_ev_failed;
1801 }
1802
1803 /* This runs the init function if registered */
1804 r = register_netdev(dev);
1805 if (r) {
1806 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: register_netdev failed\n"));
1807 ar6000_destroy(dev, 0);
1808 return r;
1809 }
1810
1811 is_netdev_registered = 1;
1812
1813#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
1814 arApNetDev = NULL;
1815#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
1816 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_avail: name=%s hifdevice=0x%lx, dev=0x%lx (%d), ar=0x%lx\n",
1817 dev->name, (unsigned long)ar->arHifDevice, (unsigned long)dev, device_index,
1818 (unsigned long)ar));
1819
1820avail_ev_failed :
1821 if (r)
1822 ar6000_sysfs_bmi_deinit(ar);
1823
1824 return r;
1825}
1826
1827static void ar6000_target_failure(void *Instance, int Status)
1828{
1829 struct ar6_softc *ar = (struct ar6_softc *)Instance;
1830 WMI_TARGET_ERROR_REPORT_EVENT errEvent;
1831 static bool sip = false;
1832
1833 if (Status != 0) {
1834
1835 printk(KERN_ERR "ar6000_target_failure: target asserted \n");
1836
1837 if (timer_pending(&ar->arHBChallengeResp.timer)) {
1838 A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
1839 }
1840
1841 /* try dumping target assertion information (if any) */
1842 ar6000_dump_target_assert_info(ar->arHifDevice,ar->arTargetType);
1843
1844 /*
1845 * Fetch the logs from the target via the diagnostic
1846 * window.
1847 */
1848 ar6000_dbglog_get_debug_logs(ar);
1849
1850 /* Report the error only once */
1851 if (!sip) {
1852 sip = true;
1853 errEvent.errorVal = WMI_TARGET_COM_ERR |
1854 WMI_TARGET_FATAL_ERR;
1855 }
1856 }
1857}
1858
1859static int
1860ar6000_unavail_ev(void *context, void *hif_handle)
1861{
1862 struct ar6_softc *ar = (struct ar6_softc *)context;
1863 /* NULL out it's entry in the global list */
1864 ar6000_devices[ar->arDeviceIndex] = NULL;
1865 ar6000_destroy(ar->arNetDev, 1);
1866
1867 return 0;
1868}
1869
1870void
1871ar6000_restart_endpoint(struct net_device *dev)
1872{
1873 int status = 0;
1874 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1875
1876 BMIInit();
1877 do {
1878 if ( (status=ar6000_configure_target(ar))!= 0)
1879 break;
1880 if ( (status=ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0)
1881 {
1882 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n"));
1883 break;
1884 }
1885 rtnl_lock();
1886 status = (ar6000_init(dev)==0) ? 0 : A_ERROR;
1887 rtnl_unlock();
1888
1889 if (status) {
1890 break;
1891 }
1892 if (ar->arSsidLen && ar->arWlanState == WLAN_ENABLED) {
1893 ar6000_connect_to_ap(ar);
1894 }
1895 } while (0);
1896
1897 if (status== 0) {
1898 return;
1899 }
1900
1901 ar6000_devices[ar->arDeviceIndex] = NULL;
1902 ar6000_destroy(ar->arNetDev, 1);
1903}
1904
1905void
1906ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs)
1907{
1908 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1909
1910 /* Stop the transmit queues */
1911 netif_stop_queue(dev);
1912
1913 /* Disable the target and the interrupts associated with it */
1914 if (ar->arWmiReady == true)
1915 {
1916 if (!bypasswmi)
1917 {
1918 bool disconnectIssued;
1919
1920 disconnectIssued = (ar->arConnected) || (ar->arConnectPending);
1921 ar6000_disconnect(ar);
1922 if (!keepprofile) {
1923 ar6000_init_profile_info(ar);
1924 }
1925
1926 A_UNTIMEOUT(&ar->disconnect_timer);
1927
1928 if (getdbglogs) {
1929 ar6000_dbglog_get_debug_logs(ar);
1930 }
1931
1932 ar->arWmiReady = false;
1933 wmi_shutdown(ar->arWmi);
1934 ar->arWmiEnabled = false;
1935 ar->arWmi = NULL;
1936 /*
1937 * After wmi_shudown all WMI events will be dropped.
1938 * We need to cleanup the buffers allocated in AP mode
1939 * and give disconnect notification to stack, which usually
1940 * happens in the disconnect_event.
1941 * Simulate the disconnect_event by calling the function directly.
1942 * Sometimes disconnect_event will be received when the debug logs
1943 * are collected.
1944 */
1945 if (disconnectIssued) {
1946 if(ar->arNetworkType & AP_NETWORK) {
1947 ar6000_disconnect_event(ar, DISCONNECT_CMD, bcast_mac, 0, NULL, 0);
1948 } else {
1949 ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0);
1950 }
1951 }
1952 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
1953 ar->user_key_ctrl = 0;
1954 }
1955
1956 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI stopped\n", __func__));
1957 }
1958 else
1959 {
1960 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI not ready 0x%lx 0x%lx\n",
1961 __func__, (unsigned long) ar, (unsigned long) ar->arWmi));
1962
1963 /* Shut down WMI if we have started it */
1964 if(ar->arWmiEnabled == true)
1965 {
1966 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Shut down WMI\n", __func__));
1967 wmi_shutdown(ar->arWmi);
1968 ar->arWmiEnabled = false;
1969 ar->arWmi = NULL;
1970 }
1971 }
1972
1973 if (ar->arHtcTarget != NULL) {
1974#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1975 if (NULL != ar6kHciTransCallbacks.cleanupTransport) {
1976 ar6kHciTransCallbacks.cleanupTransport(NULL);
1977 }
1978#else
1979 // FIXME: workaround to reset BT's UART baud rate to default
1980 if (NULL != ar->exitCallback) {
1981 struct ar3k_config_info ar3kconfig;
1982 int status;
1983
1984 A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
1985 ar6000_set_default_ar3kconfig(ar, (void *)&ar3kconfig);
1986 status = ar->exitCallback(&ar3kconfig);
1987 if (0 != status) {
1988 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to reset AR3K baud rate! \n"));
1989 }
1990 }
1991 // END workaround
1992 if (setuphci)
1993 ar6000_cleanup_hci(ar);
1994#endif
1995 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n"));
1996 /* stop HTC */
1997 HTCStop(ar->arHtcTarget);
1998 }
1999
2000 if (resetok) {
2001 /* try to reset the device if we can
2002 * The driver may have been configure NOT to reset the target during
2003 * a debug session */
2004 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Attempting to reset target on instance destroy.... \n"));
2005 if (ar->arHifDevice != NULL) {
2006 bool coldReset = (ar->arTargetType == TARGET_TYPE_AR6003) ? true: false;
2007 ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, coldReset);
2008 }
2009 } else {
2010 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Host does not want target reset. \n"));
2011 }
2012 /* Done with cookies */
2013 ar6000_cookie_cleanup(ar);
2014
2015 /* cleanup any allocated AMSDU buffers */
2016 ar6000_cleanup_amsdu_rxbufs(ar);
2017}
2018/*
2019 * We need to differentiate between the surprise and planned removal of the
2020 * device because of the following consideration:
2021 * - In case of surprise removal, the hcd already frees up the pending
2022 * for the device and hence there is no need to unregister the function
2023 * driver inorder to get these requests. For planned removal, the function
2024 * driver has to explicitly unregister itself to have the hcd return all the
2025 * pending requests before the data structures for the devices are freed up.
2026 * Note that as per the current implementation, the function driver will
2027 * end up releasing all the devices since there is no API to selectively
2028 * release a particular device.
2029 * - Certain commands issued to the target can be skipped for surprise
2030 * removal since they will anyway not go through.
2031 */
2032void
2033ar6000_destroy(struct net_device *dev, unsigned int unregister)
2034{
2035 struct ar6_softc *ar;
2036
2037 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("+ar6000_destroy \n"));
2038
2039 if((dev == NULL) || ((ar = ar6k_priv(dev)) == NULL))
2040 {
2041 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): Failed to get device structure.\n", __func__));
2042 return;
2043 }
2044
2045 ar->bIsDestroyProgress = true;
2046
2047 if (down_interruptible(&ar->arSem)) {
2048 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): down_interruptible failed \n", __func__));
2049 return;
2050 }
2051
2052 if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
2053 /* only stop endpoint if we are not stop it in suspend_ev */
2054 ar6000_stop_endpoint(dev, false, true);
2055 }
2056
2057 ar->arWlanState = WLAN_DISABLED;
2058 if (ar->arHtcTarget != NULL) {
2059 /* destroy HTC */
2060 HTCDestroy(ar->arHtcTarget);
2061 }
2062 if (ar->arHifDevice != NULL) {
2063 /*release the device so we do not get called back on remove incase we
2064 * we're explicity destroyed by module unload */
2065 HIFReleaseDevice(ar->arHifDevice);
2066 HIFShutDownDevice(ar->arHifDevice);
2067 }
2068 aggr_module_destroy(ar->aggr_cntxt);
2069
2070 /* Done with cookies */
2071 ar6000_cookie_cleanup(ar);
2072
2073 /* cleanup any allocated AMSDU buffers */
2074 ar6000_cleanup_amsdu_rxbufs(ar);
2075
2076 ar6000_sysfs_bmi_deinit(ar);
2077
2078 /* Cleanup BMI */
2079 BMICleanup();
2080
2081 /* Clear the tx counters */
2082 memset(tx_attempt, 0, sizeof(tx_attempt));
2083 memset(tx_post, 0, sizeof(tx_post));
2084 memset(tx_complete, 0, sizeof(tx_complete));
2085
2086#ifdef HTC_RAW_INTERFACE
2087 if (ar->arRawHtc) {
2088 kfree(ar->arRawHtc);
2089 ar->arRawHtc = NULL;
2090 }
2091#endif
2092 /* Free up the device data structure */
2093 if (unregister && is_netdev_registered) {
2094 unregister_netdev(dev);
2095 is_netdev_registered = 0;
2096 }
2097 free_netdev(dev);
2098
2099 ar6k_cfg80211_deinit(ar);
2100
2101#ifdef CONFIG_AP_VIRTUL_ADAPTER_SUPPORT
2102 ar6000_remove_ap_interface();
2103#endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
2104
2105 kfree(ar->fw_otp);
2106 kfree(ar->fw);
2107 kfree(ar->fw_patch);
2108 kfree(ar->fw_data);
2109
2110 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n"));
2111}
2112
2113static void disconnect_timer_handler(unsigned long ptr)
2114{
2115 struct net_device *dev = (struct net_device *)ptr;
2116 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2117
2118 A_UNTIMEOUT(&ar->disconnect_timer);
2119
2120 ar6000_init_profile_info(ar);
2121 ar6000_disconnect(ar);
2122}
2123
2124static void ar6000_detect_error(unsigned long ptr)
2125{
2126 struct net_device *dev = (struct net_device *)ptr;
2127 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2128 WMI_TARGET_ERROR_REPORT_EVENT errEvent;
2129
2130 AR6000_SPIN_LOCK(&ar->arLock, 0);
2131
2132 if (ar->arHBChallengeResp.outstanding) {
2133 ar->arHBChallengeResp.missCnt++;
2134 } else {
2135 ar->arHBChallengeResp.missCnt = 0;
2136 }
2137
2138 if (ar->arHBChallengeResp.missCnt > ar->arHBChallengeResp.missThres) {
2139 /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */
2140 ar->arHBChallengeResp.missCnt = 0;
2141 ar->arHBChallengeResp.seqNum = 0;
2142 errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR;
2143 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2144 return;
2145 }
2146
2147 /* Generate the sequence number for the next challenge */
2148 ar->arHBChallengeResp.seqNum++;
2149 ar->arHBChallengeResp.outstanding = true;
2150
2151 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2152
2153 /* Send the challenge on the control channel */
2154 if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != 0) {
2155 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to send heart beat challenge\n"));
2156 }
2157
2158
2159 /* Reschedule the timer for the next challenge */
2160 A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
2161}
2162
2163void ar6000_init_profile_info(struct ar6_softc *ar)
2164{
2165 ar->arSsidLen = 0;
2166 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2167
2168 switch(fwmode) {
2169 case HI_OPTION_FW_MODE_IBSS:
2170 ar->arNetworkType = ar->arNextMode = ADHOC_NETWORK;
2171 break;
2172 case HI_OPTION_FW_MODE_BSS_STA:
2173 ar->arNetworkType = ar->arNextMode = INFRA_NETWORK;
2174 break;
2175 case HI_OPTION_FW_MODE_AP:
2176 ar->arNetworkType = ar->arNextMode = AP_NETWORK;
2177 break;
2178 }
2179
2180 ar->arDot11AuthMode = OPEN_AUTH;
2181 ar->arAuthMode = NONE_AUTH;
2182 ar->arPairwiseCrypto = NONE_CRYPT;
2183 ar->arPairwiseCryptoLen = 0;
2184 ar->arGroupCrypto = NONE_CRYPT;
2185 ar->arGroupCryptoLen = 0;
2186 A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
2187 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
2188 A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
2189 ar->arBssChannel = 0;
2190}
2191
2192static void
2193ar6000_init_control_info(struct ar6_softc *ar)
2194{
2195 ar->arWmiEnabled = false;
2196 ar6000_init_profile_info(ar);
2197 ar->arDefTxKeyIndex = 0;
2198 A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
2199 ar->arChannelHint = 0;
2200 ar->arListenIntervalT = A_DEFAULT_LISTEN_INTERVAL;
2201 ar->arListenIntervalB = 0;
2202 ar->arVersion.host_ver = AR6K_SW_VERSION;
2203 ar->arRssi = 0;
2204 ar->arTxPwr = 0;
2205 ar->arTxPwrSet = false;
2206 ar->arSkipScan = 0;
2207 ar->arBeaconInterval = 0;
2208 ar->arBitRate = 0;
2209 ar->arMaxRetries = 0;
2210 ar->arWmmEnabled = true;
2211 ar->intra_bss = 1;
2212 ar->scan_triggered = 0;
2213 A_MEMZERO(&ar->scParams, sizeof(ar->scParams));
2214 ar->scParams.shortScanRatio = WMI_SHORTSCANRATIO_DEFAULT;
2215 ar->scParams.scanCtrlFlags = DEFAULT_SCAN_CTRL_FLAGS;
2216
2217 /* Initialize the AP mode state info */
2218 {
2219 u8 ctr;
2220 A_MEMZERO((u8 *)ar->sta_list, AP_MAX_NUM_STA * sizeof(sta_t));
2221
2222 /* init the Mutexes */
2223 A_MUTEX_INIT(&ar->mcastpsqLock);
2224
2225 /* Init the PS queues */
2226 for (ctr=0; ctr < AP_MAX_NUM_STA ; ctr++) {
2227 A_MUTEX_INIT(&ar->sta_list[ctr].psqLock);
2228 A_NETBUF_QUEUE_INIT(&ar->sta_list[ctr].psq);
2229 }
2230
2231 ar->ap_profile_flag = 0;
2232 A_NETBUF_QUEUE_INIT(&ar->mcastpsq);
2233
2234 memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
2235 ar->ap_wmode = DEF_AP_WMODE_G;
2236 ar->ap_dtim_period = DEF_AP_DTIM;
2237 ar->ap_beacon_interval = DEF_BEACON_INTERVAL;
2238 }
2239}
2240
2241static int
2242ar6000_open(struct net_device *dev)
2243{
2244 unsigned long flags;
2245 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2246
2247 spin_lock_irqsave(&ar->arLock, flags);
2248
2249 if(ar->arWlanState == WLAN_DISABLED) {
2250 ar->arWlanState = WLAN_ENABLED;
2251 }
2252
2253 if( ar->arConnected || bypasswmi) {
2254 netif_carrier_on(dev);
2255 /* Wake up the queues */
2256 netif_wake_queue(dev);
2257 }
2258 else
2259 netif_carrier_off(dev);
2260
2261 spin_unlock_irqrestore(&ar->arLock, flags);
2262 return 0;
2263}
2264
2265static int
2266ar6000_close(struct net_device *dev)
2267{
2268 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2269 netif_stop_queue(dev);
2270
2271 ar6000_disconnect(ar);
2272
2273 if(ar->arWmiReady == true) {
2274 if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0,
2275 0, 0, 0, 0, 0, 0, 0, 0) != 0) {
2276 return -EIO;
2277 }
2278 ar->arWlanState = WLAN_DISABLED;
2279 }
2280 ar6k_cfg80211_scanComplete_event(ar, A_ECANCELED);
2281
2282 return 0;
2283}
2284
2285/* connect to a service */
2286static int ar6000_connectservice(struct ar6_softc *ar,
2287 struct htc_service_connect_req *pConnect,
2288 char *pDesc)
2289{
2290 int status;
2291 struct htc_service_connect_resp response;
2292
2293 do {
2294
2295 A_MEMZERO(&response,sizeof(response));
2296
2297 status = HTCConnectService(ar->arHtcTarget,
2298 pConnect,
2299 &response);
2300
2301 if (status) {
2302 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Failed to connect to %s service status:%d \n",
2303 pDesc, status));
2304 break;
2305 }
2306 switch (pConnect->ServiceID) {
2307 case WMI_CONTROL_SVC :
2308 if (ar->arWmiEnabled) {
2309 /* set control endpoint for WMI use */
2310 wmi_set_control_ep(ar->arWmi, response.Endpoint);
2311 }
2312 /* save EP for fast lookup */
2313 ar->arControlEp = response.Endpoint;
2314 break;
2315 case WMI_DATA_BE_SVC :
2316 arSetAc2EndpointIDMap(ar, WMM_AC_BE, response.Endpoint);
2317 break;
2318 case WMI_DATA_BK_SVC :
2319 arSetAc2EndpointIDMap(ar, WMM_AC_BK, response.Endpoint);
2320 break;
2321 case WMI_DATA_VI_SVC :
2322 arSetAc2EndpointIDMap(ar, WMM_AC_VI, response.Endpoint);
2323 break;
2324 case WMI_DATA_VO_SVC :
2325 arSetAc2EndpointIDMap(ar, WMM_AC_VO, response.Endpoint);
2326 break;
2327 default:
2328 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ServiceID not mapped %d\n", pConnect->ServiceID));
2329 status = A_EINVAL;
2330 break;
2331 }
2332
2333 } while (false);
2334
2335 return status;
2336}
2337
2338void ar6000_TxDataCleanup(struct ar6_softc *ar)
2339{
2340 /* flush all the data (non-control) streams
2341 * we only flush packets that are tagged as data, we leave any control packets that
2342 * were in the TX queues alone */
2343 HTCFlushEndpoint(ar->arHtcTarget,
2344 arAc2EndpointID(ar, WMM_AC_BE),
2345 AR6K_DATA_PKT_TAG);
2346 HTCFlushEndpoint(ar->arHtcTarget,
2347 arAc2EndpointID(ar, WMM_AC_BK),
2348 AR6K_DATA_PKT_TAG);
2349 HTCFlushEndpoint(ar->arHtcTarget,
2350 arAc2EndpointID(ar, WMM_AC_VI),
2351 AR6K_DATA_PKT_TAG);
2352 HTCFlushEndpoint(ar->arHtcTarget,
2353 arAc2EndpointID(ar, WMM_AC_VO),
2354 AR6K_DATA_PKT_TAG);
2355}
2356
2357HTC_ENDPOINT_ID
2358ar6000_ac2_endpoint_id ( void * devt, u8 ac)
2359{
2360 struct ar6_softc *ar = (struct ar6_softc *) devt;
2361 return(arAc2EndpointID(ar, ac));
2362}
2363
2364u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep )
2365{
2366 struct ar6_softc *ar = (struct ar6_softc *) devt;
2367 return(arEndpoint2Ac(ar, ep ));
2368}
2369
2370#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE)
2371static int ath6kl_config_btcoex_params(struct ar6_softc *ar)
2372{
2373 int r;
2374 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd;
2375 WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd;
2376
2377 /* Configure the type of BT collocated with WLAN */
2378 memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
2379 sbcb_cmd.btcoexCoLocatedBTdev = ATH6KL_BT_DEV;
2380
2381 r = wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd);
2382
2383 if (r) {
2384 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2385 ("Unable to set collocated BT type\n"));
2386 return r;
2387 }
2388
2389 /* Configure the type of BT collocated with WLAN */
2390 memset(&sbfa_cmd, 0, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
2391
2392 sbfa_cmd.btcoexFeAntType = ATH6KL_BT_ANTENNA;
2393
2394 r = wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd);
2395 if (r) {
2396 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2397 ("Unable to set fornt end antenna configuration\n"));
2398 return r;
2399 }
2400
2401 return 0;
2402}
2403#else
2404static int ath6kl_config_btcoex_params(struct ar6_softc *ar)
2405{
2406 return 0;
2407}
2408#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */
2409
2410/*
2411 * This function applies WLAN specific configuration defined in wlan_config.h
2412 */
2413int ar6000_target_config_wlan_params(struct ar6_softc *ar)
2414{
2415 int status = 0;
2416
2417#ifdef CONFIG_HOST_TCMD_SUPPORT
2418 if (ar->arTargetMode != AR6000_WLAN_MODE) {
2419 return 0;
2420 }
2421#endif /* CONFIG_HOST_TCMD_SUPPORT */
2422
2423 /*
2424 * configure the device for rx dot11 header rules 0,0 are the default values
2425 * therefore this command can be skipped if the inputs are 0,FALSE,FALSE.Required
2426 * if checksum offload is needed. Set RxMetaVersion to 2
2427 */
2428 if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != 0) {
2429 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n"));
2430 status = A_ERROR;
2431 }
2432
2433 status = ath6kl_config_btcoex_params(ar);
2434 if (status)
2435 return status;
2436
2437#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
2438 if ((wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
2439 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power save fail event policy\n"));
2440 status = A_ERROR;
2441 }
2442#endif
2443
2444#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP
2445 if ((wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
2446 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set barker preamble policy\n"));
2447 status = A_ERROR;
2448 }
2449#endif
2450
2451 if ((wmi_set_keepalive_cmd(ar->arWmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) != 0) {
2452 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set keep alive interval\n"));
2453 status = A_ERROR;
2454 }
2455
2456#if WLAN_CONFIG_DISABLE_11N
2457 {
2458 WMI_SET_HT_CAP_CMD htCap;
2459
2460 memset(&htCap, 0, sizeof(WMI_SET_HT_CAP_CMD));
2461 htCap.band = 0;
2462 if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) {
2463 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n"));
2464 status = A_ERROR;
2465 }
2466
2467 htCap.band = 1;
2468 if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) {
2469 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n"));
2470 status = A_ERROR;
2471 }
2472 }
2473#endif /* WLAN_CONFIG_DISABLE_11N */
2474
2475#ifdef ATH6K_CONFIG_OTA_MODE
2476 if ((wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER)) != 0) {
2477 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power mode \n"));
2478 status = A_ERROR;
2479 }
2480#endif
2481
2482 if ((wmi_disctimeout_cmd(ar->arWmi, WLAN_CONFIG_DISCONNECT_TIMEOUT)) != 0) {
2483 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set disconnect timeout \n"));
2484 status = A_ERROR;
2485 }
2486
2487#if WLAN_CONFIG_DISABLE_TX_BURSTING
2488 if ((wmi_set_wmm_txop(ar->arWmi, WMI_TXOP_DISABLED)) != 0) {
2489 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set txop bursting \n"));
2490 status = A_ERROR;
2491 }
2492#endif
2493
2494 return status;
2495}
2496
2497/* This function does one time initialization for the lifetime of the device */
2498int ar6000_init(struct net_device *dev)
2499{
2500 struct ar6_softc *ar;
2501 int status;
2502 s32 timeleft;
2503 s16 i;
2504 int ret = 0;
2505
2506 if((ar = ar6k_priv(dev)) == NULL)
2507 {
2508 return -EIO;
2509 }
2510
2511 if (wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) {
2512
2513 ar6000_update_bdaddr(ar);
2514
2515 if (enablerssicompensation) {
2516 ar6000_copy_cust_data_from_target(ar->arHifDevice, ar->arTargetType);
2517 read_rssi_compensation_param(ar);
2518 for (i=-95; i<=0; i++) {
2519 rssi_compensation_table[0-i] = rssi_compensation_calc(ar,i);
2520 }
2521 }
2522 }
2523
2524 dev_hold(dev);
2525 rtnl_unlock();
2526
2527 /* Do we need to finish the BMI phase */
2528 if ((wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) &&
2529 (BMIDone(ar->arHifDevice) != 0))
2530 {
2531 ret = -EIO;
2532 goto ar6000_init_done;
2533 }
2534
2535 if (!bypasswmi)
2536 {
2537#if 0 /* TBDXXX */
2538 if (ar->arVersion.host_ver != ar->arVersion.target_ver) {
2539 A_PRINTF("WARNING: Host version 0x%x does not match Target "
2540 " version 0x%x!\n",
2541 ar->arVersion.host_ver, ar->arVersion.target_ver);
2542 }
2543#endif
2544
2545 /* Indicate that WMI is enabled (although not ready yet) */
2546 ar->arWmiEnabled = true;
2547 if ((ar->arWmi = wmi_init((void *) ar)) == NULL)
2548 {
2549 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize WMI.\n", __func__));
2550 ret = -EIO;
2551 goto ar6000_init_done;
2552 }
2553
2554 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Got WMI @ 0x%lx.\n", __func__,
2555 (unsigned long) ar->arWmi));
2556 }
2557
2558 do {
2559 struct htc_service_connect_req connect;
2560
2561 /* the reason we have to wait for the target here is that the driver layer
2562 * has to init BMI in order to set the host block size,
2563 */
2564 status = HTCWaitTarget(ar->arHtcTarget);
2565
2566 if (status) {
2567 break;
2568 }
2569
2570 A_MEMZERO(&connect,sizeof(connect));
2571 /* meta data is unused for now */
2572 connect.pMetaData = NULL;
2573 connect.MetaDataLength = 0;
2574 /* these fields are the same for all service endpoints */
2575 connect.EpCallbacks.pContext = ar;
2576 connect.EpCallbacks.EpTxCompleteMultiple = ar6000_tx_complete;
2577 connect.EpCallbacks.EpRecv = ar6000_rx;
2578 connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill;
2579 connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full;
2580 /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
2581 * Linux has the peculiarity of not providing flow control between the
2582 * NIC and the network stack. There is no API to indicate that a TX packet
2583 * was sent which could provide some back pressure to the network stack.
2584 * Under linux you would have to wait till the network stack consumed all sk_buffs
2585 * before any back-flow kicked in. Which isn't very friendly.
2586 * So we have to manage this ourselves */
2587 connect.MaxSendQueueDepth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
2588 connect.EpCallbacks.RecvRefillWaterMark = AR6000_MAX_RX_BUFFERS / 4; /* set to 25 % */
2589 if (0 == connect.EpCallbacks.RecvRefillWaterMark) {
2590 connect.EpCallbacks.RecvRefillWaterMark++;
2591 }
2592 /* connect to control service */
2593 connect.ServiceID = WMI_CONTROL_SVC;
2594 status = ar6000_connectservice(ar,
2595 &connect,
2596 "WMI CONTROL");
2597 if (status) {
2598 break;
2599 }
2600
2601 connect.LocalConnectionFlags |= HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING;
2602 /* limit the HTC message size on the send path, although we can receive A-MSDU frames of
2603 * 4K, we will only send ethernet-sized (802.3) frames on the send path. */
2604 connect.MaxSendMsgSize = WMI_MAX_TX_DATA_FRAME_LENGTH;
2605
2606 /* to reduce the amount of committed memory for larger A_MSDU frames, use the recv-alloc threshold
2607 * mechanism for larger packets */
2608 connect.EpCallbacks.RecvAllocThreshold = AR6000_BUFFER_SIZE;
2609 connect.EpCallbacks.EpRecvAllocThresh = ar6000_alloc_amsdu_rxbuf;
2610
2611 /* for the remaining data services set the connection flag to reduce dribbling,
2612 * if configured to do so */
2613 if (reduce_credit_dribble) {
2614 connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE;
2615 /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value
2616 * of 0-3 */
2617 connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
2618 connect.ConnectionFlags |=
2619 ((u16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
2620 }
2621 /* connect to best-effort service */
2622 connect.ServiceID = WMI_DATA_BE_SVC;
2623
2624 status = ar6000_connectservice(ar,
2625 &connect,
2626 "WMI DATA BE");
2627 if (status) {
2628 break;
2629 }
2630
2631 /* connect to back-ground
2632 * map this to WMI LOW_PRI */
2633 connect.ServiceID = WMI_DATA_BK_SVC;
2634 status = ar6000_connectservice(ar,
2635 &connect,
2636 "WMI DATA BK");
2637 if (status) {
2638 break;
2639 }
2640
2641 /* connect to Video service, map this to
2642 * to HI PRI */
2643 connect.ServiceID = WMI_DATA_VI_SVC;
2644 status = ar6000_connectservice(ar,
2645 &connect,
2646 "WMI DATA VI");
2647 if (status) {
2648 break;
2649 }
2650
2651 /* connect to VO service, this is currently not
2652 * mapped to a WMI priority stream due to historical reasons.
2653 * WMI originally defined 3 priorities over 3 mailboxes
2654 * We can change this when WMI is reworked so that priorities are not
2655 * dependent on mailboxes */
2656 connect.ServiceID = WMI_DATA_VO_SVC;
2657 status = ar6000_connectservice(ar,
2658 &connect,
2659 "WMI DATA VO");
2660 if (status) {
2661 break;
2662 }
2663
2664 A_ASSERT(arAc2EndpointID(ar,WMM_AC_BE) != 0);
2665 A_ASSERT(arAc2EndpointID(ar,WMM_AC_BK) != 0);
2666 A_ASSERT(arAc2EndpointID(ar,WMM_AC_VI) != 0);
2667 A_ASSERT(arAc2EndpointID(ar,WMM_AC_VO) != 0);
2668
2669 /* setup access class priority mappings */
2670 ar->arAcStreamPriMap[WMM_AC_BK] = 0; /* lowest */
2671 ar->arAcStreamPriMap[WMM_AC_BE] = 1; /* */
2672 ar->arAcStreamPriMap[WMM_AC_VI] = 2; /* */
2673 ar->arAcStreamPriMap[WMM_AC_VO] = 3; /* highest */
2674
2675#ifdef EXPORT_HCI_BRIDGE_INTERFACE
2676 if (setuphci && (NULL != ar6kHciTransCallbacks.setupTransport)) {
2677 struct hci_transport_misc_handles hciHandles;
2678
2679 hciHandles.netDevice = ar->arNetDev;
2680 hciHandles.hifDevice = ar->arHifDevice;
2681 hciHandles.htcHandle = ar->arHtcTarget;
2682 status = (int)(ar6kHciTransCallbacks.setupTransport(&hciHandles));
2683 }
2684#else
2685 if (setuphci) {
2686 /* setup HCI */
2687 status = ar6000_setup_hci(ar);
2688 }
2689#endif
2690
2691 } while (false);
2692
2693 if (status) {
2694 ret = -EIO;
2695 goto ar6000_init_done;
2696 }
2697
2698 if (regscanmode) {
2699 u32 param;
2700
2701 if (BMIReadMemory(ar->arHifDevice,
2702 HOST_INTEREST_ITEM_ADDRESS(ar,
2703 hi_option_flag),
2704 (u8 *)&param,
2705 4) != 0) {
2706 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2707 ("BMIReadMemory forsetting "
2708 "regscanmode failed\n"));
2709 return A_ERROR;
2710 }
2711
2712 if (regscanmode == 1)
2713 param |= HI_OPTION_SKIP_REG_SCAN;
2714 else if (regscanmode == 2)
2715 param |= HI_OPTION_INIT_REG_SCAN;
2716
2717 if (BMIWriteMemory(ar->arHifDevice,
2718 HOST_INTEREST_ITEM_ADDRESS(ar,
2719 hi_option_flag),
2720 (u8 *)&param,
2721 4) != 0) {
2722 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
2723 ("BMIWriteMemory forsetting "
2724 "regscanmode failed\n"));
2725 return A_ERROR;
2726 }
2727 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Regulatory scan mode set\n"));
2728 }
2729
2730 /*
2731 * give our connected endpoints some buffers
2732 */
2733
2734 ar6000_rx_refill(ar, ar->arControlEp);
2735 ar6000_rx_refill(ar, arAc2EndpointID(ar,WMM_AC_BE));
2736
2737 /*
2738 * We will post the receive buffers only for SPE or endpoint ping testing so we are
2739 * making it conditional on the 'bypasswmi' flag.
2740 */
2741 if (bypasswmi) {
2742 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_BK));
2743 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VI));
2744 ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VO));
2745 }
2746
2747 /* allocate some buffers that handle larger AMSDU frames */
2748 ar6000_refill_amsdu_rxbufs(ar,AR6000_MAX_AMSDU_RX_BUFFERS);
2749
2750 /* setup credit distribution */
2751 ar6000_setup_credit_dist(ar->arHtcTarget, &ar->arCreditStateInfo);
2752
2753 /* Since cookies are used for HTC transports, they should be */
2754 /* initialized prior to enabling HTC. */
2755 ar6000_cookie_init(ar);
2756
2757 /* start HTC */
2758 status = HTCStart(ar->arHtcTarget);
2759
2760 if (status) {
2761 if (ar->arWmiEnabled == true) {
2762 wmi_shutdown(ar->arWmi);
2763 ar->arWmiEnabled = false;
2764 ar->arWmi = NULL;
2765 }
2766 ar6000_cookie_cleanup(ar);
2767 ret = -EIO;
2768 goto ar6000_init_done;
2769 }
2770
2771 if (!bypasswmi) {
2772 /* Wait for Wmi event to be ready */
2773 timeleft = wait_event_interruptible_timeout(arEvent,
2774 (ar->arWmiReady == true), wmitimeout * HZ);
2775
2776 if (ar->arVersion.abi_ver != AR6K_ABI_VERSION) {
2777 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ABI Version mismatch: Host(0x%x), Target(0x%x)\n", AR6K_ABI_VERSION, ar->arVersion.abi_ver));
2778#ifndef ATH6K_SKIP_ABI_VERSION_CHECK
2779 ret = -EIO;
2780 goto ar6000_init_done;
2781#endif /* ATH6K_SKIP_ABI_VERSION_CHECK */
2782 }
2783
2784 if(!timeleft || signal_pending(current))
2785 {
2786 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI is not ready or wait was interrupted\n"));
2787 ret = -EIO;
2788 goto ar6000_init_done;
2789 }
2790
2791 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() WMI is ready\n", __func__));
2792
2793 /* Communicate the wmi protocol verision to the target */
2794 if ((ar6000_set_host_app_area(ar)) != 0) {
2795 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the host app area\n"));
2796 }
2797 ar6000_target_config_wlan_params(ar);
2798 }
2799
2800 ar->arNumDataEndPts = 1;
2801
2802 if (bypasswmi) {
2803 /* for tests like endpoint ping, the MAC address needs to be non-zero otherwise
2804 * the data path through a raw socket is disabled */
2805 dev->dev_addr[0] = 0x00;
2806 dev->dev_addr[1] = 0x01;
2807 dev->dev_addr[2] = 0x02;
2808 dev->dev_addr[3] = 0xAA;
2809 dev->dev_addr[4] = 0xBB;
2810 dev->dev_addr[5] = 0xCC;
2811 }
2812
2813ar6000_init_done:
2814 rtnl_lock();
2815 dev_put(dev);
2816
2817 return ret;
2818}
2819
2820
2821void
2822ar6000_bitrate_rx(void *devt, s32 rateKbps)
2823{
2824 struct ar6_softc *ar = (struct ar6_softc *)devt;
2825
2826 ar->arBitRate = rateKbps;
2827 wake_up(&arEvent);
2828}
2829
2830void
2831ar6000_ratemask_rx(void *devt, u32 ratemask)
2832{
2833 struct ar6_softc *ar = (struct ar6_softc *)devt;
2834
2835 ar->arRateMask = ratemask;
2836 wake_up(&arEvent);
2837}
2838
2839void
2840ar6000_txPwr_rx(void *devt, u8 txPwr)
2841{
2842 struct ar6_softc *ar = (struct ar6_softc *)devt;
2843
2844 ar->arTxPwr = txPwr;
2845 wake_up(&arEvent);
2846}
2847
2848
2849void
2850ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList)
2851{
2852 struct ar6_softc *ar = (struct ar6_softc *)devt;
2853
2854 memcpy(ar->arChannelList, chanList, numChan * sizeof (u16));
2855 ar->arNumChannels = numChan;
2856
2857 wake_up(&arEvent);
2858}
2859
2860u8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *mapNo)
2861{
2862 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2863 u8 *datap;
2864 ATH_MAC_HDR *macHdr;
2865 u32 i, eptMap;
2866
2867 (*mapNo) = 0;
2868 datap = A_NETBUF_DATA(skb);
2869 macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR));
2870 if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) {
2871 return ENDPOINT_2;
2872 }
2873
2874 eptMap = -1;
2875 for (i = 0; i < ar->arNodeNum; i ++) {
2876 if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) {
2877 (*mapNo) = i + 1;
2878 ar->arNodeMap[i].txPending ++;
2879 return ar->arNodeMap[i].epId;
2880 }
2881
2882 if ((eptMap == -1) && !ar->arNodeMap[i].txPending) {
2883 eptMap = i;
2884 }
2885 }
2886
2887 if (eptMap == -1) {
2888 eptMap = ar->arNodeNum;
2889 ar->arNodeNum ++;
2890 A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM);
2891 }
2892
2893 memcpy(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN);
2894
2895 for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) {
2896 if (!ar->arTxPending[i]) {
2897 ar->arNodeMap[eptMap].epId = i;
2898 break;
2899 }
2900 // No free endpoint is available, start redistribution on the inuse endpoints.
2901 if (i == ENDPOINT_5) {
2902 ar->arNodeMap[eptMap].epId = ar->arNexEpId;
2903 ar->arNexEpId ++;
2904 if (ar->arNexEpId > ENDPOINT_5) {
2905 ar->arNexEpId = ENDPOINT_2;
2906 }
2907 }
2908 }
2909
2910 (*mapNo) = eptMap + 1;
2911 ar->arNodeMap[eptMap].txPending ++;
2912
2913 return ar->arNodeMap[eptMap].epId;
2914}
2915
2916#ifdef DEBUG
2917static void ar6000_dump_skb(struct sk_buff *skb)
2918{
2919 u_char *ch;
2920 for (ch = A_NETBUF_DATA(skb);
2921 (unsigned long)ch < ((unsigned long)A_NETBUF_DATA(skb) +
2922 A_NETBUF_LEN(skb)); ch++)
2923 {
2924 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("%2.2x ", *ch));
2925 }
2926 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("\n"));
2927}
2928#endif
2929
2930#ifdef HTC_TEST_SEND_PKTS
2931static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *skb);
2932#endif
2933
2934static int
2935ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
2936{
2937#define AC_NOT_MAPPED 99
2938 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
2939 u8 ac = AC_NOT_MAPPED;
2940 HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
2941 u32 mapNo = 0;
2942 int len;
2943 struct ar_cookie *cookie;
2944 bool checkAdHocPsMapping = false,bMoreData = false;
2945 HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
2946 u8 dot11Hdr = processDot11Hdr;
2947#ifdef CONFIG_PM
2948 if (ar->arWowState != WLAN_WOW_STATE_NONE) {
2949 A_NETBUF_FREE(skb);
2950 return 0;
2951 }
2952#endif /* CONFIG_PM */
2953
2954 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_data_tx start - skb=0x%lx, data=0x%lx, len=0x%x\n",
2955 (unsigned long)skb, (unsigned long)A_NETBUF_DATA(skb),
2956 A_NETBUF_LEN(skb)));
2957
2958 /* If target is not associated */
2959 if( (!ar->arConnected && !bypasswmi)
2960#ifdef CONFIG_HOST_TCMD_SUPPORT
2961 /* TCMD doesn't support any data, free the buf and return */
2962 || (ar->arTargetMode == AR6000_TCMD_MODE)
2963#endif
2964 ) {
2965 A_NETBUF_FREE(skb);
2966 return 0;
2967 }
2968
2969 do {
2970
2971 if (ar->arWmiReady == false && bypasswmi == 0) {
2972 break;
2973 }
2974
2975#ifdef BLOCK_TX_PATH_FLAG
2976 if (blocktx) {
2977 break;
2978 }
2979#endif /* BLOCK_TX_PATH_FLAG */
2980
2981 /* AP mode Power save processing */
2982 /* If the dst STA is in sleep state, queue the pkt in its PS queue */
2983
2984 if (ar->arNetworkType == AP_NETWORK) {
2985 ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
2986 sta_t *conn = NULL;
2987
2988 /* If the dstMac is a Multicast address & atleast one of the
2989 * associated STA is in PS mode, then queue the pkt to the
2990 * mcastq
2991 */
2992 if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
2993 u8 ctr=0;
2994 bool qMcast=false;
2995
2996
2997 for (ctr=0; ctr<AP_MAX_NUM_STA; ctr++) {
2998 if (STA_IS_PWR_SLEEP((&ar->sta_list[ctr]))) {
2999 qMcast = true;
3000 }
3001 }
3002 if(qMcast) {
3003
3004 /* If this transmit is not because of a Dtim Expiry q it */
3005 if (ar->DTIMExpired == false) {
3006 bool isMcastqEmpty = false;
3007
3008 A_MUTEX_LOCK(&ar->mcastpsqLock);
3009 isMcastqEmpty = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
3010 A_NETBUF_ENQUEUE(&ar->mcastpsq, skb);
3011 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
3012
3013 /* If this is the first Mcast pkt getting queued
3014 * indicate to the target to set the BitmapControl LSB
3015 * of the TIM IE.
3016 */
3017 if (isMcastqEmpty) {
3018 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 1);
3019 }
3020 return 0;
3021 } else {
3022 /* This transmit is because of Dtim expiry. Determine if
3023 * MoreData bit has to be set.
3024 */
3025 A_MUTEX_LOCK(&ar->mcastpsqLock);
3026 if(!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
3027 bMoreData = true;
3028 }
3029 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
3030 }
3031 }
3032 } else {
3033 conn = ieee80211_find_conn(ar, datap->dstMac);
3034 if (conn) {
3035 if (STA_IS_PWR_SLEEP(conn)) {
3036 /* If this transmit is not because of a PsPoll q it*/
3037 if (!STA_IS_PS_POLLED(conn)) {
3038 bool isPsqEmpty = false;
3039 /* Queue the frames if the STA is sleeping */
3040 A_MUTEX_LOCK(&conn->psqLock);
3041 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
3042 A_NETBUF_ENQUEUE(&conn->psq, skb);
3043 A_MUTEX_UNLOCK(&conn->psqLock);
3044
3045 /* If this is the first pkt getting queued
3046 * for this STA, update the PVB for this STA
3047 */
3048 if (isPsqEmpty) {
3049 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 1);
3050 }
3051
3052 return 0;
3053 } else {
3054 /* This tx is because of a PsPoll. Determine if
3055 * MoreData bit has to be set
3056 */
3057 A_MUTEX_LOCK(&conn->psqLock);
3058 if (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
3059 bMoreData = true;
3060 }
3061 A_MUTEX_UNLOCK(&conn->psqLock);
3062 }
3063 }
3064 } else {
3065
3066 /* non existent STA. drop the frame */
3067 A_NETBUF_FREE(skb);
3068 return 0;
3069 }
3070 }
3071 }
3072
3073 if (ar->arWmiEnabled) {
3074 u8 csumStart=0;
3075 u8 csumDest=0;
3076 u8 csum=skb->ip_summed;
3077 if(csumOffload && (csum==CHECKSUM_PARTIAL)){
3078 csumStart = (skb->head + skb->csum_start - skb_network_header(skb) +
3079 sizeof(ATH_LLC_SNAP_HDR));
3080 csumDest=skb->csum_offset+csumStart;
3081 }
3082 if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len - LINUX_HACK_FUDGE_FACTOR) {
3083 struct sk_buff *newbuf;
3084
3085 /*
3086 * We really should have gotten enough headroom but sometimes
3087 * we still get packets with not enough headroom. Copy the packet.
3088 */
3089 len = A_NETBUF_LEN(skb);
3090 newbuf = A_NETBUF_ALLOC(len);
3091 if (newbuf == NULL) {
3092 break;
3093 }
3094 A_NETBUF_PUT(newbuf, len);
3095 memcpy(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len);
3096 A_NETBUF_FREE(skb);
3097 skb = newbuf;
3098 /* fall through and assemble header */
3099 }
3100
3101 if (dot11Hdr) {
3102 if (wmi_dot11_hdr_add(ar->arWmi,skb,ar->arNetworkType) != 0) {
3103 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx-wmi_dot11_hdr_add failed\n"));
3104 break;
3105 }
3106 } else {
3107 if (wmi_dix_2_dot3(ar->arWmi, skb) != 0) {
3108 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_dix_2_dot3 failed\n"));
3109 break;
3110 }
3111 }
3112 if(csumOffload && (csum ==CHECKSUM_PARTIAL)){
3113 WMI_TX_META_V2 metaV2;
3114 metaV2.csumStart =csumStart;
3115 metaV2.csumDest = csumDest;
3116 metaV2.csumFlags = 0x1;/*instruct target to calculate checksum*/
3117 if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,
3118 WMI_META_VERSION_2,&metaV2) != 0) {
3119 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
3120 break;
3121 }
3122
3123 }
3124 else
3125 {
3126 if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != 0) {
3127 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
3128 break;
3129 }
3130 }
3131
3132
3133 if ((ar->arNetworkType == ADHOC_NETWORK) &&
3134 ar->arIbssPsEnable && ar->arConnected) {
3135 /* flag to check adhoc mapping once we take the lock below: */
3136 checkAdHocPsMapping = true;
3137
3138 } else {
3139 /* get the stream mapping */
3140 ac = wmi_implicit_create_pstream(ar->arWmi, skb, 0, ar->arWmmEnabled);
3141 }
3142
3143 } else {
3144 EPPING_HEADER *eppingHdr;
3145
3146 eppingHdr = A_NETBUF_DATA(skb);
3147
3148 if (IS_EPPING_PACKET(eppingHdr)) {
3149 /* the stream ID is mapped to an access class */
3150 ac = eppingHdr->StreamNo_h;
3151 /* some EPPING packets cannot be dropped no matter what access class it was
3152 * sent on. We can change the packet tag to guarantee it will not get dropped */
3153 if (IS_EPING_PACKET_NO_DROP(eppingHdr)) {
3154 htc_tag = AR6K_CONTROL_PKT_TAG;
3155 }
3156
3157 if (ac == HCI_TRANSPORT_STREAM_NUM) {
3158 /* pass this to HCI */
3159#ifndef EXPORT_HCI_BRIDGE_INTERFACE
3160 if (!hci_test_send(ar,skb)) {
3161 return 0;
3162 }
3163#endif
3164 /* set AC to discard this skb */
3165 ac = AC_NOT_MAPPED;
3166 } else {
3167 /* a quirk of linux, the payload of the frame is 32-bit aligned and thus the addition
3168 * of the HTC header will mis-align the start of the HTC frame, so we add some
3169 * padding which will be stripped off in the target */
3170 if (EPPING_ALIGNMENT_PAD > 0) {
3171 A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD);
3172 }
3173 }
3174
3175 } else {
3176 /* not a ping packet, drop it */
3177 ac = AC_NOT_MAPPED;
3178 }
3179 }
3180
3181 } while (false);
3182
3183 /* did we succeed ? */
3184 if ((ac == AC_NOT_MAPPED) && !checkAdHocPsMapping) {
3185 /* cleanup and exit */
3186 A_NETBUF_FREE(skb);
3187 AR6000_STAT_INC(ar, tx_dropped);
3188 AR6000_STAT_INC(ar, tx_aborted_errors);
3189 return 0;
3190 }
3191
3192 cookie = NULL;
3193
3194 /* take the lock to protect driver data */
3195 AR6000_SPIN_LOCK(&ar->arLock, 0);
3196
3197 do {
3198
3199 if (checkAdHocPsMapping) {
3200 eid = ar6000_ibss_map_epid(skb, dev, &mapNo);
3201 }else {
3202 eid = arAc2EndpointID (ar, ac);
3203 }
3204 /* validate that the endpoint is connected */
3205 if (eid == 0 || eid == ENDPOINT_UNUSED ) {
3206 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" eid %d is NOT mapped!\n", eid));
3207 break;
3208 }
3209 /* allocate resource for this packet */
3210 cookie = ar6000_alloc_cookie(ar);
3211
3212 if (cookie != NULL) {
3213 /* update counts while the lock is held */
3214 ar->arTxPending[eid]++;
3215 ar->arTotalTxDataPending++;
3216 }
3217
3218 } while (false);
3219
3220 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3221
3222 if (cookie != NULL) {
3223 cookie->arc_bp[0] = (unsigned long)skb;
3224 cookie->arc_bp[1] = mapNo;
3225 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
3226 cookie,
3227 A_NETBUF_DATA(skb),
3228 A_NETBUF_LEN(skb),
3229 eid,
3230 htc_tag);
3231
3232#ifdef DEBUG
3233 if (debugdriver >= 3) {
3234 ar6000_dump_skb(skb);
3235 }
3236#endif
3237#ifdef HTC_TEST_SEND_PKTS
3238 DoHTCSendPktsTest(ar,mapNo,eid,skb);
3239#endif
3240 /* HTC interface is asynchronous, if this fails, cleanup will happen in
3241 * the ar6000_tx_complete callback */
3242 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
3243 } else {
3244 /* no packet to send, cleanup */
3245 A_NETBUF_FREE(skb);
3246 AR6000_STAT_INC(ar, tx_dropped);
3247 AR6000_STAT_INC(ar, tx_aborted_errors);
3248 }
3249
3250 return 0;
3251}
3252
3253int
3254ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev)
3255{
3256 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
3257 struct ar_cookie *cookie;
3258 HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
3259
3260 cookie = NULL;
3261 AR6000_SPIN_LOCK(&ar->arLock, 0);
3262
3263 /* For now we send ACL on BE endpoint: We can also have a dedicated EP */
3264 eid = arAc2EndpointID (ar, 0);
3265 /* allocate resource for this packet */
3266 cookie = ar6000_alloc_cookie(ar);
3267
3268 if (cookie != NULL) {
3269 /* update counts while the lock is held */
3270 ar->arTxPending[eid]++;
3271 ar->arTotalTxDataPending++;
3272 }
3273
3274
3275 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3276
3277 if (cookie != NULL) {
3278 cookie->arc_bp[0] = (unsigned long)skb;
3279 cookie->arc_bp[1] = 0;
3280 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
3281 cookie,
3282 A_NETBUF_DATA(skb),
3283 A_NETBUF_LEN(skb),
3284 eid,
3285 AR6K_DATA_PKT_TAG);
3286
3287 /* HTC interface is asynchronous, if this fails, cleanup will happen in
3288 * the ar6000_tx_complete callback */
3289 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
3290 } else {
3291 /* no packet to send, cleanup */
3292 A_NETBUF_FREE(skb);
3293 AR6000_STAT_INC(ar, tx_dropped);
3294 AR6000_STAT_INC(ar, tx_aborted_errors);
3295 }
3296 return 0;
3297}
3298
3299
3300#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3301static void
3302tvsub(register struct timeval *out, register struct timeval *in)
3303{
3304 if((out->tv_usec -= in->tv_usec) < 0) {
3305 out->tv_sec--;
3306 out->tv_usec += 1000000;
3307 }
3308 out->tv_sec -= in->tv_sec;
3309}
3310
3311void
3312applyAPTCHeuristics(struct ar6_softc *ar)
3313{
3314 u32 duration;
3315 u32 numbytes;
3316 u32 throughput;
3317 struct timeval ts;
3318 int status;
3319
3320 AR6000_SPIN_LOCK(&ar->arLock, 0);
3321
3322 if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) {
3323 do_gettimeofday(&ts);
3324 tvsub(&ts, &aptcTR.samplingTS);
3325 duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */
3326 numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
3327
3328 if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) {
3329 /* Initialize the time stamp and byte count */
3330 aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
3331 do_gettimeofday(&aptcTR.samplingTS);
3332
3333 /* Calculate and decide based on throughput thresholds */
3334 throughput = ((numbytes * 8) / duration);
3335 if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) {
3336 /* Disable Sleep and schedule a timer */
3337 A_ASSERT(ar->arWmiReady == true);
3338 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3339 status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);
3340 AR6000_SPIN_LOCK(&ar->arLock, 0);
3341 A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
3342 aptcTR.timerScheduled = true;
3343 }
3344 }
3345 }
3346
3347 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3348}
3349#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3350
3351static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket)
3352{
3353 struct ar6_softc *ar = (struct ar6_softc *)Context;
3354 HTC_SEND_FULL_ACTION action = HTC_SEND_FULL_KEEP;
3355 bool stopNet = false;
3356 HTC_ENDPOINT_ID Endpoint = HTC_GET_ENDPOINT_FROM_PKT(pPacket);
3357
3358 do {
3359
3360 if (bypasswmi) {
3361 int accessClass;
3362
3363 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
3364 /* don't drop special control packets */
3365 break;
3366 }
3367
3368 accessClass = arEndpoint2Ac(ar,Endpoint);
3369 /* for endpoint ping testing drop Best Effort and Background */
3370 if ((accessClass == WMM_AC_BE) || (accessClass == WMM_AC_BK)) {
3371 action = HTC_SEND_FULL_DROP;
3372 stopNet = false;
3373 } else {
3374 /* keep but stop the netqueues */
3375 stopNet = true;
3376 }
3377 break;
3378 }
3379
3380 if (Endpoint == ar->arControlEp) {
3381 /* under normal WMI if this is getting full, then something is running rampant
3382 * the host should not be exhausting the WMI queue with too many commands
3383 * the only exception to this is during testing using endpointping */
3384 AR6000_SPIN_LOCK(&ar->arLock, 0);
3385 /* set flag to handle subsequent messages */
3386 ar->arWMIControlEpFull = true;
3387 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3388 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI Control Endpoint is FULL!!! \n"));
3389 /* no need to stop the network */
3390 stopNet = false;
3391 break;
3392 }
3393
3394 /* if we get here, we are dealing with data endpoints getting full */
3395
3396 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
3397 /* don't drop control packets issued on ANY data endpoint */
3398 break;
3399 }
3400
3401 if (ar->arNetworkType == ADHOC_NETWORK) {
3402 /* in adhoc mode, we cannot differentiate traffic priorities so there is no need to
3403 * continue, however we should stop the network */
3404 stopNet = true;
3405 break;
3406 }
3407 /* the last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for the highest
3408 * active stream */
3409 if (ar->arAcStreamPriMap[arEndpoint2Ac(ar,Endpoint)] < ar->arHiAcStreamActivePri &&
3410 ar->arCookieCount <= MAX_HI_COOKIE_NUM) {
3411 /* this stream's priority is less than the highest active priority, we
3412 * give preference to the highest priority stream by directing
3413 * HTC to drop the packet that overflowed */
3414 action = HTC_SEND_FULL_DROP;
3415 /* since we are dropping packets, no need to stop the network */
3416 stopNet = false;
3417 break;
3418 }
3419
3420 } while (false);
3421
3422 if (stopNet) {
3423 AR6000_SPIN_LOCK(&ar->arLock, 0);
3424 ar->arNetQueueStopped = true;
3425 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3426 /* one of the data endpoints queues is getting full..need to stop network stack
3427 * the queue will resume in ar6000_tx_complete() */
3428 netif_stop_queue(ar->arNetDev);
3429 }
3430
3431 return action;
3432}
3433
3434
3435static void
3436ar6000_tx_complete(void *Context, struct htc_packet_queue *pPacketQueue)
3437{
3438 struct ar6_softc *ar = (struct ar6_softc *)Context;
3439 u32 mapNo = 0;
3440 int status;
3441 struct ar_cookie * ar_cookie;
3442 HTC_ENDPOINT_ID eid;
3443 bool wakeEvent = false;
3444 struct sk_buff_head skb_queue;
3445 struct htc_packet *pPacket;
3446 struct sk_buff *pktSkb;
3447 bool flushing = false;
3448
3449 skb_queue_head_init(&skb_queue);
3450
3451 /* lock the driver as we update internal state */
3452 AR6000_SPIN_LOCK(&ar->arLock, 0);
3453
3454 /* reap completed packets */
3455 while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
3456
3457 pPacket = HTC_PACKET_DEQUEUE(pPacketQueue);
3458
3459 ar_cookie = (struct ar_cookie *)pPacket->pPktContext;
3460 A_ASSERT(ar_cookie);
3461
3462 status = pPacket->Status;
3463 pktSkb = (struct sk_buff *)ar_cookie->arc_bp[0];
3464 eid = pPacket->Endpoint;
3465 mapNo = ar_cookie->arc_bp[1];
3466
3467 A_ASSERT(pktSkb);
3468 A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(pktSkb));
3469
3470 /* add this to the list, use faster non-lock API */
3471 __skb_queue_tail(&skb_queue,pktSkb);
3472
3473 if (!status) {
3474 A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(pktSkb));
3475 }
3476
3477 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_tx_complete skb=0x%lx data=0x%lx len=0x%x eid=%d ",
3478 (unsigned long)pktSkb, (unsigned long)pPacket->pBuffer,
3479 pPacket->ActualLength,
3480 eid));
3481
3482 ar->arTxPending[eid]--;
3483
3484 if ((eid != ar->arControlEp) || bypasswmi) {
3485 ar->arTotalTxDataPending--;
3486 }
3487
3488 if (eid == ar->arControlEp)
3489 {
3490 if (ar->arWMIControlEpFull) {
3491 /* since this packet completed, the WMI EP is no longer full */
3492 ar->arWMIControlEpFull = false;
3493 }
3494
3495 if (ar->arTxPending[eid] == 0) {
3496 wakeEvent = true;
3497 }
3498 }
3499
3500 if (status) {
3501 if (status == A_ECANCELED) {
3502 /* a packet was flushed */
3503 flushing = true;
3504 }
3505 AR6000_STAT_INC(ar, tx_errors);
3506 if (status != A_NO_RESOURCE) {
3507 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() -TX ERROR, status: 0x%x\n", __func__,
3508 status));
3509 }
3510 } else {
3511 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("OK\n"));
3512 flushing = false;
3513 AR6000_STAT_INC(ar, tx_packets);
3514 ar->arNetStats.tx_bytes += A_NETBUF_LEN(pktSkb);
3515#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3516 aptcTR.bytesTransmitted += a_netbuf_to_len(pktSkb);
3517 applyAPTCHeuristics(ar);
3518#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3519 }
3520
3521 // TODO this needs to be looked at
3522 if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable
3523 && (eid != ar->arControlEp) && mapNo)
3524 {
3525 mapNo --;
3526 ar->arNodeMap[mapNo].txPending --;
3527
3528 if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) {
3529 u32 i;
3530 for (i = ar->arNodeNum; i > 0; i --) {
3531 if (!ar->arNodeMap[i - 1].txPending) {
3532 A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping));
3533 ar->arNodeNum --;
3534 } else {
3535 break;
3536 }
3537 }
3538 }
3539 }
3540
3541 ar6000_free_cookie(ar, ar_cookie);
3542
3543 if (ar->arNetQueueStopped) {
3544 ar->arNetQueueStopped = false;
3545 }
3546 }
3547
3548 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3549
3550 /* lock is released, we can freely call other kernel APIs */
3551
3552 /* free all skbs in our local list */
3553 while (!skb_queue_empty(&skb_queue)) {
3554 /* use non-lock version */
3555 pktSkb = __skb_dequeue(&skb_queue);
3556 A_NETBUF_FREE(pktSkb);
3557 }
3558
3559 if ((ar->arConnected == true) || bypasswmi) {
3560 if (!flushing) {
3561 /* don't wake the queue if we are flushing, other wise it will just
3562 * keep queueing packets, which will keep failing */
3563 netif_wake_queue(ar->arNetDev);
3564 }
3565 }
3566
3567 if (wakeEvent) {
3568 wake_up(&arEvent);
3569 }
3570
3571}
3572
3573sta_t *
3574ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr)
3575{
3576 sta_t *conn = NULL;
3577 u8 i, max_conn;
3578
3579 switch(ar->arNetworkType) {
3580 case AP_NETWORK:
3581 max_conn = AP_MAX_NUM_STA;
3582 break;
3583 default:
3584 max_conn=0;
3585 break;
3586 }
3587
3588 for (i = 0; i < max_conn; i++) {
3589 if (IEEE80211_ADDR_EQ(node_addr, ar->sta_list[i].mac)) {
3590 conn = &ar->sta_list[i];
3591 break;
3592 }
3593 }
3594
3595 return conn;
3596}
3597
3598sta_t *ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid)
3599{
3600 sta_t *conn = NULL;
3601 u8 ctr;
3602
3603 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
3604 if (ar->sta_list[ctr].aid == aid) {
3605 conn = &ar->sta_list[ctr];
3606 break;
3607 }
3608 }
3609 return conn;
3610}
3611
3612/*
3613 * Receive event handler. This is called by HTC when a packet is received
3614 */
3615int pktcount;
3616static void
3617ar6000_rx(void *Context, struct htc_packet *pPacket)
3618{
3619 struct ar6_softc *ar = (struct ar6_softc *)Context;
3620 struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext;
3621 int minHdrLen;
3622 u8 containsDot11Hdr = 0;
3623 int status = pPacket->Status;
3624 HTC_ENDPOINT_ID ept = pPacket->Endpoint;
3625
3626 A_ASSERT((status) ||
3627 (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN)));
3628
3629 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%lx eid=%d, skb=0x%lx, data=0x%lx, len=0x%x status:%d",
3630 (unsigned long)ar, ept, (unsigned long)skb, (unsigned long)pPacket->pBuffer,
3631 pPacket->ActualLength, status));
3632 if (status) {
3633 if (status != A_ECANCELED) {
3634 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("RX ERR (%d) \n",status));
3635 }
3636 }
3637
3638 /* take lock to protect buffer counts
3639 * and adaptive power throughput state */
3640 AR6000_SPIN_LOCK(&ar->arLock, 0);
3641
3642 if (!status) {
3643 AR6000_STAT_INC(ar, rx_packets);
3644 ar->arNetStats.rx_bytes += pPacket->ActualLength;
3645#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
3646 aptcTR.bytesReceived += a_netbuf_to_len(skb);
3647 applyAPTCHeuristics(ar);
3648#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
3649
3650 A_NETBUF_PUT(skb, pPacket->ActualLength + HTC_HEADER_LEN);
3651 A_NETBUF_PULL(skb, HTC_HEADER_LEN);
3652
3653#ifdef DEBUG
3654 if (debugdriver >= 2) {
3655 ar6000_dump_skb(skb);
3656 }
3657#endif /* DEBUG */
3658 }
3659
3660 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3661
3662 skb->dev = ar->arNetDev;
3663 if (status) {
3664 AR6000_STAT_INC(ar, rx_errors);
3665 A_NETBUF_FREE(skb);
3666 } else if (ar->arWmiEnabled == true) {
3667 if (ept == ar->arControlEp) {
3668 /*
3669 * this is a wmi control msg
3670 */
3671#ifdef CONFIG_PM
3672 ar6000_check_wow_status(ar, skb, true);
3673#endif /* CONFIG_PM */
3674 wmi_control_rx(ar->arWmi, skb);
3675 } else {
3676 WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb);
3677 bool is_amsdu;
3678 u8 tid;
3679
3680 /*
3681 * This check can be removed if after a while we do not
3682 * see the warning. For now we leave it to ensure
3683 * we drop these frames accordingly in case the
3684 * target generates them for some reason. These
3685 * were used for an internal PAL but that's not
3686 * used or supported anymore. These frames should
3687 * not come up from the target.
3688 */
3689 if (WARN_ON(WMI_DATA_HDR_GET_DATA_TYPE(dhdr) ==
3690 WMI_DATA_HDR_DATA_TYPE_ACL)) {
3691 AR6000_STAT_INC(ar, rx_errors);
3692 A_NETBUF_FREE(skb);
3693 return;
3694 }
3695
3696#ifdef CONFIG_PM
3697 ar6000_check_wow_status(ar, NULL, false);
3698#endif /* CONFIG_PM */
3699 /*
3700 * this is a wmi data packet
3701 */
3702 // NWF
3703
3704 if (processDot11Hdr) {
3705 minHdrLen = sizeof(WMI_DATA_HDR) + sizeof(struct ieee80211_frame) + sizeof(ATH_LLC_SNAP_HDR);
3706 } else {
3707 minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) +
3708 sizeof(ATH_LLC_SNAP_HDR);
3709 }
3710
3711 /* In the case of AP mode we may receive NULL data frames
3712 * that do not have LLC hdr. They are 16 bytes in size.
3713 * Allow these frames in the AP mode.
3714 * ACL data frames don't follow ethernet frame bounds for
3715 * min length
3716 */
3717 if (ar->arNetworkType != AP_NETWORK &&
3718 ((pPacket->ActualLength < minHdrLen) ||
3719 (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)))
3720 {
3721 /*
3722 * packet is too short or too long
3723 */
3724 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("TOO SHORT or TOO LONG\n"));
3725 AR6000_STAT_INC(ar, rx_errors);
3726 AR6000_STAT_INC(ar, rx_length_errors);
3727 A_NETBUF_FREE(skb);
3728 } else {
3729 u16 seq_no;
3730 u8 meta_type;
3731
3732#if 0
3733 /* Access RSSI values here */
3734 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("RSSI %d\n",
3735 ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi));
3736#endif
3737 /* Get the Power save state of the STA */
3738 if (ar->arNetworkType == AP_NETWORK) {
3739 sta_t *conn = NULL;
3740 u8 psState=0,prevPsState;
3741 ATH_MAC_HDR *datap=NULL;
3742 u16 offset;
3743
3744 meta_type = WMI_DATA_HDR_GET_META(dhdr);
3745
3746 psState = (((WMI_DATA_HDR *)A_NETBUF_DATA(skb))->info
3747 >> WMI_DATA_HDR_PS_SHIFT) & WMI_DATA_HDR_PS_MASK;
3748
3749 offset = sizeof(WMI_DATA_HDR);
3750
3751 switch (meta_type) {
3752 case 0:
3753 break;
3754 case WMI_META_VERSION_1:
3755 offset += sizeof(WMI_RX_META_V1);
3756 break;
3757 case WMI_META_VERSION_2:
3758 offset += sizeof(WMI_RX_META_V2);
3759 break;
3760 default:
3761 break;
3762 }
3763
3764 datap = (ATH_MAC_HDR *)(A_NETBUF_DATA(skb)+offset);
3765 conn = ieee80211_find_conn(ar, datap->srcMac);
3766
3767 if (conn) {
3768 /* if there is a change in PS state of the STA,
3769 * take appropriate steps.
3770 * 1. If Sleep-->Awake, flush the psq for the STA
3771 * Clear the PVB for the STA.
3772 * 2. If Awake-->Sleep, Starting queueing frames
3773 * the STA.
3774 */
3775 prevPsState = STA_IS_PWR_SLEEP(conn);
3776 if (psState) {
3777 STA_SET_PWR_SLEEP(conn);
3778 } else {
3779 STA_CLR_PWR_SLEEP(conn);
3780 }
3781
3782 if (prevPsState ^ STA_IS_PWR_SLEEP(conn)) {
3783
3784 if (!STA_IS_PWR_SLEEP(conn)) {
3785
3786 A_MUTEX_LOCK(&conn->psqLock);
3787 while (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
3788 struct sk_buff *skb=NULL;
3789
3790 skb = A_NETBUF_DEQUEUE(&conn->psq);
3791 A_MUTEX_UNLOCK(&conn->psqLock);
3792 ar6000_data_tx(skb,ar->arNetDev);
3793 A_MUTEX_LOCK(&conn->psqLock);
3794 }
3795 A_MUTEX_UNLOCK(&conn->psqLock);
3796 /* Clear the PVB for this STA */
3797 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
3798 }
3799 }
3800 } else {
3801 /* This frame is from a STA that is not associated*/
3802 A_ASSERT(false);
3803 }
3804
3805 /* Drop NULL data frames here */
3806 if((pPacket->ActualLength < minHdrLen) ||
3807 (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)) {
3808 A_NETBUF_FREE(skb);
3809 goto rx_done;
3810 }
3811 }
3812
3813 is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr) ? true : false;
3814 tid = WMI_DATA_HDR_GET_UP(dhdr);
3815 seq_no = WMI_DATA_HDR_GET_SEQNO(dhdr);
3816 meta_type = WMI_DATA_HDR_GET_META(dhdr);
3817 containsDot11Hdr = WMI_DATA_HDR_GET_DOT11(dhdr);
3818
3819 wmi_data_hdr_remove(ar->arWmi, skb);
3820
3821 switch (meta_type) {
3822 case WMI_META_VERSION_1:
3823 {
3824 WMI_RX_META_V1 *pMeta = (WMI_RX_META_V1 *)A_NETBUF_DATA(skb);
3825 A_PRINTF("META %d %d %d %d %x\n", pMeta->status, pMeta->rix, pMeta->rssi, pMeta->channel, pMeta->flags);
3826 A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V1));
3827 break;
3828 }
3829 case WMI_META_VERSION_2:
3830 {
3831 WMI_RX_META_V2 *pMeta = (WMI_RX_META_V2 *)A_NETBUF_DATA(skb);
3832 if(pMeta->csumFlags & 0x1){
3833 skb->ip_summed=CHECKSUM_COMPLETE;
3834 skb->csum=(pMeta->csum);
3835 }
3836 A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V2));
3837 break;
3838 }
3839 default:
3840 break;
3841 }
3842
3843 A_ASSERT(status == 0);
3844
3845 /* NWF: print the 802.11 hdr bytes */
3846 if(containsDot11Hdr) {
3847 status = wmi_dot11_hdr_remove(ar->arWmi,skb);
3848 } else if(!is_amsdu) {
3849 status = wmi_dot3_2_dix(skb);
3850 }
3851
3852 if (status) {
3853 /* Drop frames that could not be processed (lack of memory, etc.) */
3854 A_NETBUF_FREE(skb);
3855 goto rx_done;
3856 }
3857
3858 if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) {
3859 if (ar->arNetworkType == AP_NETWORK) {
3860 struct sk_buff *skb1 = NULL;
3861 ATH_MAC_HDR *datap;
3862
3863 datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
3864 if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
3865 /* Bcast/Mcast frames should be sent to the OS
3866 * stack as well as on the air.
3867 */
3868 skb1 = skb_copy(skb,GFP_ATOMIC);
3869 } else {
3870 /* Search for a connected STA with dstMac as
3871 * the Mac address. If found send the frame to
3872 * it on the air else send the frame up the
3873 * stack
3874 */
3875 sta_t *conn = NULL;
3876 conn = ieee80211_find_conn(ar, datap->dstMac);
3877
3878 if (conn && ar->intra_bss) {
3879 skb1 = skb;
3880 skb = NULL;
3881 } else if(conn && !ar->intra_bss) {
3882 A_NETBUF_FREE(skb);
3883 skb = NULL;
3884 }
3885 }
3886 if (skb1) {
3887 ar6000_data_tx(skb1, ar->arNetDev);
3888 }
3889 }
3890 }
3891 aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, (void **)&skb);
3892 ar6000_deliver_frames_to_nw_stack((void *) ar->arNetDev, (void *)skb);
3893 }
3894 }
3895 } else {
3896 if (EPPING_ALIGNMENT_PAD > 0) {
3897 A_NETBUF_PULL(skb, EPPING_ALIGNMENT_PAD);
3898 }
3899 ar6000_deliver_frames_to_nw_stack((void *)ar->arNetDev, (void *)skb);
3900 }
3901
3902rx_done:
3903
3904 return;
3905}
3906
3907static void
3908ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf)
3909{
3910 struct sk_buff *skb = (struct sk_buff *)osbuf;
3911
3912 if(skb) {
3913 skb->dev = dev;
3914 if ((skb->dev->flags & IFF_UP) == IFF_UP) {
3915#ifdef CONFIG_PM
3916 ar6000_check_wow_status((struct ar6_softc *)ar6k_priv(dev), skb, false);
3917#endif /* CONFIG_PM */
3918 skb->protocol = eth_type_trans(skb, skb->dev);
3919 /*
3920 * If this routine is called on a ISR (Hard IRQ) or DSR (Soft IRQ)
3921 * or tasklet use the netif_rx to deliver the packet to the stack
3922 * netif_rx will queue the packet onto the receive queue and mark
3923 * the softirq thread has a pending action to complete. Kernel will
3924 * schedule the softIrq kernel thread after processing the DSR.
3925 *
3926 * If this routine is called on a process context, use netif_rx_ni
3927 * which will schedle the softIrq kernel thread after queuing the packet.
3928 */
3929 if (in_interrupt()) {
3930 netif_rx(skb);
3931 } else {
3932 netif_rx_ni(skb);
3933 }
3934 } else {
3935 A_NETBUF_FREE(skb);
3936 }
3937 }
3938}
3939
3940#if 0
3941static void
3942ar6000_deliver_frames_to_bt_stack(void *dev, void *osbuf)
3943{
3944 struct sk_buff *skb = (struct sk_buff *)osbuf;
3945
3946 if(skb) {
3947 skb->dev = dev;
3948 if ((skb->dev->flags & IFF_UP) == IFF_UP) {
3949 skb->protocol = htons(ETH_P_CONTROL);
3950 netif_rx(skb);
3951 } else {
3952 A_NETBUF_FREE(skb);
3953 }
3954 }
3955}
3956#endif
3957
3958static void
3959ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint)
3960{
3961 struct ar6_softc *ar = (struct ar6_softc *)Context;
3962 void *osBuf;
3963 int RxBuffers;
3964 int buffersToRefill;
3965 struct htc_packet *pPacket;
3966 struct htc_packet_queue queue;
3967
3968 buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
3969 HTCGetNumRecvBuffers(ar->arHtcTarget, Endpoint);
3970
3971 if (buffersToRefill <= 0) {
3972 /* fast return, nothing to fill */
3973 return;
3974 }
3975
3976 INIT_HTC_PACKET_QUEUE(&queue);
3977
3978 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
3979 buffersToRefill, Endpoint));
3980
3981 for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
3982 osBuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE);
3983 if (NULL == osBuf) {
3984 break;
3985 }
3986 /* the HTC packet wrapper is at the head of the reserved area
3987 * in the skb */
3988 pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf));
3989 /* set re-fill info */
3990 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_BUFFER_SIZE,Endpoint);
3991 /* add to queue */
3992 HTC_PACKET_ENQUEUE(&queue,pPacket);
3993 }
3994
3995 if (!HTC_QUEUE_EMPTY(&queue)) {
3996 /* add packets */
3997 HTCAddReceivePktMultiple(ar->arHtcTarget, &queue);
3998 }
3999
4000}
4001
4002 /* clean up our amsdu buffer list */
4003static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar)
4004{
4005 struct htc_packet *pPacket;
4006 void *osBuf;
4007
4008 /* empty AMSDU buffer queue and free OS bufs */
4009 while (true) {
4010
4011 AR6000_SPIN_LOCK(&ar->arLock, 0);
4012 pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
4013 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4014
4015 if (NULL == pPacket) {
4016 break;
4017 }
4018
4019 osBuf = pPacket->pPktContext;
4020 if (NULL == osBuf) {
4021 A_ASSERT(false);
4022 break;
4023 }
4024
4025 A_NETBUF_FREE(osBuf);
4026 }
4027
4028}
4029
4030
4031 /* refill the amsdu buffer list */
4032static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count)
4033{
4034 struct htc_packet *pPacket;
4035 void *osBuf;
4036
4037 while (Count > 0) {
4038 osBuf = A_NETBUF_ALLOC(AR6000_AMSDU_BUFFER_SIZE);
4039 if (NULL == osBuf) {
4040 break;
4041 }
4042 /* the HTC packet wrapper is at the head of the reserved area
4043 * in the skb */
4044 pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf));
4045 /* set re-fill info */
4046 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_AMSDU_BUFFER_SIZE,0);
4047
4048 AR6000_SPIN_LOCK(&ar->arLock, 0);
4049 /* put it in the list */
4050 HTC_PACKET_ENQUEUE(&ar->amsdu_rx_buffer_queue,pPacket);
4051 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4052 Count--;
4053 }
4054
4055}
4056
4057 /* callback to allocate a large receive buffer for a pending packet. This function is called when
4058 * an HTC packet arrives whose length exceeds a threshold value
4059 *
4060 * We use a pre-allocated list of buffers of maximum AMSDU size (4K). Under linux it is more optimal to
4061 * keep the allocation size the same to optimize cached-slab allocations.
4062 *
4063 * */
4064static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length)
4065{
4066 struct htc_packet *pPacket = NULL;
4067 struct ar6_softc *ar = (struct ar6_softc *)Context;
4068 int refillCount = 0;
4069
4070 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_alloc_amsdu_rxbuf: eid=%d, Length:%d\n",Endpoint,Length));
4071
4072 do {
4073
4074 if (Length <= AR6000_BUFFER_SIZE) {
4075 /* shouldn't be getting called on normal sized packets */
4076 A_ASSERT(false);
4077 break;
4078 }
4079
4080 if (Length > AR6000_AMSDU_BUFFER_SIZE) {
4081 A_ASSERT(false);
4082 break;
4083 }
4084
4085 AR6000_SPIN_LOCK(&ar->arLock, 0);
4086 /* allocate a packet from the list */
4087 pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
4088 /* see if we need to refill again */
4089 refillCount = AR6000_MAX_AMSDU_RX_BUFFERS - HTC_PACKET_QUEUE_DEPTH(&ar->amsdu_rx_buffer_queue);
4090 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
4091
4092 if (NULL == pPacket) {
4093 break;
4094 }
4095 /* set actual endpoint ID */
4096 pPacket->Endpoint = Endpoint;
4097
4098 } while (false);
4099
4100 if (refillCount >= AR6000_AMSDU_REFILL_THRESHOLD) {
4101 ar6000_refill_amsdu_rxbufs(ar,refillCount);
4102 }
4103
4104 return pPacket;
4105}
4106
4107static void
4108ar6000_set_multicast_list(struct net_device *dev)
4109{
4110 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: Multicast filter not supported\n"));
4111}
4112
4113static struct net_device_stats *
4114ar6000_get_stats(struct net_device *dev)
4115{
4116 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
4117 return &ar->arNetStats;
4118}
4119
4120void
4121ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver)
4122{
4123 struct ar6_softc *ar = (struct ar6_softc *)devt;
4124 struct net_device *dev = ar->arNetDev;
4125
4126 memcpy(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN);
4127 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
4128 dev->dev_addr[0], dev->dev_addr[1],
4129 dev->dev_addr[2], dev->dev_addr[3],
4130 dev->dev_addr[4], dev->dev_addr[5]));
4131
4132 ar->arPhyCapability = phyCap;
4133 ar->arVersion.wlan_ver = sw_ver;
4134 ar->arVersion.abi_ver = abi_ver;
4135
4136 snprintf(ar->wdev->wiphy->fw_version, sizeof(ar->wdev->wiphy->fw_version),
4137 "%u:%u:%u:%u",
4138 (ar->arVersion.wlan_ver & 0xf0000000) >> 28,
4139 (ar->arVersion.wlan_ver & 0x0f000000) >> 24,
4140 (ar->arVersion.wlan_ver & 0x00ff0000) >> 16,
4141 (ar->arVersion.wlan_ver & 0x0000ffff));
4142
4143 /* Indicate to the waiting thread that the ready event was received */
4144 ar->arWmiReady = true;
4145 wake_up(&arEvent);
4146}
4147
4148void ar6000_install_static_wep_keys(struct ar6_softc *ar)
4149{
4150 u8 index;
4151 u8 keyUsage;
4152
4153 for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
4154 if (ar->arWepKeyList[index].arKeyLen) {
4155 keyUsage = GROUP_USAGE;
4156 if (index == ar->arDefTxKeyIndex) {
4157 keyUsage |= TX_USAGE;
4158 }
4159 wmi_addKey_cmd(ar->arWmi,
4160 index,
4161 WEP_CRYPT,
4162 keyUsage,
4163 ar->arWepKeyList[index].arKeyLen,
4164 NULL,
4165 ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
4166 NO_SYNC_WMIFLAG);
4167 }
4168 }
4169}
4170
4171void
4172add_new_sta(struct ar6_softc *ar, u8 *mac, u16 aid, u8 *wpaie,
4173 u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
4174{
4175 u8 free_slot=aid-1;
4176
4177 memcpy(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN);
4178 memcpy(ar->sta_list[free_slot].wpa_ie, wpaie, ielen);
4179 ar->sta_list[free_slot].aid = aid;
4180 ar->sta_list[free_slot].keymgmt = keymgmt;
4181 ar->sta_list[free_slot].ucipher = ucipher;
4182 ar->sta_list[free_slot].auth = auth;
4183 ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
4184 ar->arAPStats.sta[free_slot].aid = aid;
4185}
4186
4187void
4188ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid,
4189 u16 listenInterval, u16 beaconInterval,
4190 NETWORK_TYPE networkType, u8 beaconIeLen,
4191 u8 assocReqLen, u8 assocRespLen,
4192 u8 *assocInfo)
4193{
4194 union iwreq_data wrqu;
4195 int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos;
4196 static const char *tag1 = "ASSOCINFO(ReqIEs=";
4197 static const char *tag2 = "ASSOCRESPIE=";
4198 static const char *beaconIetag = "BEACONIE=";
4199 char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + strlen(tag1) + 1];
4200 char *pos;
4201 u8 key_op_ctrl;
4202 unsigned long flags;
4203 struct ieee80211req_key *ik;
4204 CRYPTO_TYPE keyType = NONE_CRYPT;
4205
4206 if(ar->arNetworkType & AP_NETWORK) {
4207 struct net_device *dev = ar->arNetDev;
4208 if(memcmp(dev->dev_addr, bssid, ATH_MAC_LEN)==0) {
4209 ar->arACS = channel;
4210 ik = &ar->ap_mode_bkey;
4211
4212 switch(ar->arAuthMode) {
4213 case NONE_AUTH:
4214 if(ar->arPairwiseCrypto == WEP_CRYPT) {
4215 ar6000_install_static_wep_keys(ar);
4216 }
4217#ifdef WAPI_ENABLE
4218 else if(ar->arPairwiseCrypto == WAPI_CRYPT) {
4219 ap_set_wapi_key(ar, ik);
4220 }
4221#endif
4222 break;
4223 case WPA_PSK_AUTH:
4224 case WPA2_PSK_AUTH:
4225 case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
4226 switch (ik->ik_type) {
4227 case IEEE80211_CIPHER_TKIP:
4228 keyType = TKIP_CRYPT;
4229 break;
4230 case IEEE80211_CIPHER_AES_CCM:
4231 keyType = AES_CRYPT;
4232 break;
4233 default:
4234 goto skip_key;
4235 }
4236 wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, GROUP_USAGE,
4237 ik->ik_keylen, (u8 *)&ik->ik_keyrsc,
4238 ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
4239 SYNC_BOTH_WMIFLAG);
4240
4241 break;
4242 }
4243skip_key:
4244 ar->arConnected = true;
4245 return;
4246 }
4247
4248 A_PRINTF("NEW STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n "
4249 " AID=%d \n", bssid[0], bssid[1], bssid[2],
4250 bssid[3], bssid[4], bssid[5], channel);
4251 switch ((listenInterval>>8)&0xFF) {
4252 case OPEN_AUTH:
4253 A_PRINTF("AUTH: OPEN\n");
4254 break;
4255 case SHARED_AUTH:
4256 A_PRINTF("AUTH: SHARED\n");
4257 break;
4258 default:
4259 A_PRINTF("AUTH: Unknown\n");
4260 break;
4261 }
4262 switch (listenInterval&0xFF) {
4263 case WPA_PSK_AUTH:
4264 A_PRINTF("KeyMgmt: WPA-PSK\n");
4265 break;
4266 case WPA2_PSK_AUTH:
4267 A_PRINTF("KeyMgmt: WPA2-PSK\n");
4268 break;
4269 default:
4270 A_PRINTF("KeyMgmt: NONE\n");
4271 break;
4272 }
4273 switch (beaconInterval) {
4274 case AES_CRYPT:
4275 A_PRINTF("Cipher: AES\n");
4276 break;
4277 case TKIP_CRYPT:
4278 A_PRINTF("Cipher: TKIP\n");
4279 break;
4280 case WEP_CRYPT:
4281 A_PRINTF("Cipher: WEP\n");
4282 break;
4283#ifdef WAPI_ENABLE
4284 case WAPI_CRYPT:
4285 A_PRINTF("Cipher: WAPI\n");
4286 break;
4287#endif
4288 default:
4289 A_PRINTF("Cipher: NONE\n");
4290 break;
4291 }
4292
4293 add_new_sta(ar, bssid, channel /*aid*/,
4294 assocInfo /* WPA IE */, assocRespLen /* IE len */,
4295 listenInterval&0xFF /* Keymgmt */, beaconInterval /* cipher */,
4296 (listenInterval>>8)&0xFF /* auth alg */);
4297
4298 /* Send event to application */
4299 A_MEMZERO(&wrqu, sizeof(wrqu));
4300 memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
4301 wireless_send_event(ar->arNetDev, IWEVREGISTERED, &wrqu, NULL);
4302 /* In case the queue is stopped when we switch modes, this will
4303 * wake it up
4304 */
4305 netif_wake_queue(ar->arNetDev);
4306 return;
4307 }
4308
4309 ar6k_cfg80211_connect_event(ar, channel, bssid,
4310 listenInterval, beaconInterval,
4311 networkType, beaconIeLen,
4312 assocReqLen, assocRespLen,
4313 assocInfo);
4314
4315 memcpy(ar->arBssid, bssid, sizeof(ar->arBssid));
4316 ar->arBssChannel = channel;
4317
4318 A_PRINTF("AR6000 connected event on freq %d ", channel);
4319 A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
4320 " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d"
4321 " assocRespLen =%d\n",
4322 bssid[0], bssid[1], bssid[2],
4323 bssid[3], bssid[4], bssid[5],
4324 listenInterval, beaconInterval,
4325 beaconIeLen, assocReqLen, assocRespLen);
4326 if (networkType & ADHOC_NETWORK) {
4327 if (networkType & ADHOC_CREATOR) {
4328 A_PRINTF("Network: Adhoc (Creator)\n");
4329 } else {
4330 A_PRINTF("Network: Adhoc (Joiner)\n");
4331 }
4332 } else {
4333 A_PRINTF("Network: Infrastructure\n");
4334 }
4335
4336 if ((ar->arNetworkType == INFRA_NETWORK)) {
4337 wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
4338 }
4339
4340 if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) {
4341 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nBeaconIEs= "));
4342
4343 beacon_ie_pos = 0;
4344 A_MEMZERO(buf, sizeof(buf));
4345 sprintf(buf, "%s", beaconIetag);
4346 pos = buf + 9;
4347 for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) {
4348 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4349 sprintf(pos, "%2.2x", assocInfo[i]);
4350 pos += 2;
4351 }
4352 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4353
4354 A_MEMZERO(&wrqu, sizeof(wrqu));
4355 wrqu.data.length = strlen(buf);
4356 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4357 }
4358
4359 if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2))))
4360 {
4361 assoc_resp_ie_pos = beaconIeLen + assocReqLen +
4362 sizeof(u16) + /* capinfo*/
4363 sizeof(u16) + /* status Code */
4364 sizeof(u16) ; /* associd */
4365 A_MEMZERO(buf, sizeof(buf));
4366 sprintf(buf, "%s", tag2);
4367 pos = buf + 12;
4368 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocRespIEs= "));
4369 /*
4370 * The Association Response Frame w.o. the WLAN header is delivered to
4371 * the host, so skip over to the IEs
4372 */
4373 for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen - 6; i++)
4374 {
4375 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4376 sprintf(pos, "%2.2x", assocInfo[i]);
4377 pos += 2;
4378 }
4379 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4380
4381 A_MEMZERO(&wrqu, sizeof(wrqu));
4382 wrqu.data.length = strlen(buf);
4383 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4384 }
4385
4386 if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) {
4387 /*
4388 * assoc Request includes capability and listen interval. Skip these.
4389 */
4390 assoc_req_ie_pos = beaconIeLen +
4391 sizeof(u16) + /* capinfo*/
4392 sizeof(u16); /* listen interval */
4393
4394 A_MEMZERO(buf, sizeof(buf));
4395 sprintf(buf, "%s", tag1);
4396 pos = buf + 17;
4397 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AssocReqIEs= "));
4398 for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
4399 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4400 sprintf(pos, "%2.2x", assocInfo[i]);
4401 pos += 2;
4402 }
4403 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4404
4405 A_MEMZERO(&wrqu, sizeof(wrqu));
4406 wrqu.data.length = strlen(buf);
4407 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4408 }
4409
4410 if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN &&
4411 ar->user_saved_keys.keyOk == true)
4412 {
4413 key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC;
4414
4415 if (ar->user_key_ctrl & AR6000_USER_SETKEYS_RSC_UNCHANGED) {
4416 key_op_ctrl &= ~KEY_OP_INIT_RSC;
4417 } else {
4418 key_op_ctrl |= KEY_OP_INIT_RSC;
4419 }
4420 ar6000_reinstall_keys(ar, key_op_ctrl);
4421 }
4422
4423 netif_wake_queue(ar->arNetDev);
4424
4425 /* Update connect & link status atomically */
4426 spin_lock_irqsave(&ar->arLock, flags);
4427 ar->arConnected = true;
4428 ar->arConnectPending = false;
4429 netif_carrier_on(ar->arNetDev);
4430 spin_unlock_irqrestore(&ar->arLock, flags);
4431 /* reset the rx aggr state */
4432 aggr_reset_state(ar->aggr_cntxt);
4433 reconnect_flag = 0;
4434
4435 A_MEMZERO(&wrqu, sizeof(wrqu));
4436 memcpy(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN);
4437 wrqu.addr.sa_family = ARPHRD_ETHER;
4438 wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
4439 if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) {
4440 A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap));
4441 ar->arNodeNum = 0;
4442 ar->arNexEpId = ENDPOINT_2;
4443 }
4444 if (!ar->arUserBssFilter) {
4445 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4446 }
4447
4448}
4449
4450void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num)
4451{
4452 A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1));
4453 ar->arNumDataEndPts = num;
4454}
4455
4456void
4457sta_cleanup(struct ar6_softc *ar, u8 i)
4458{
4459 struct sk_buff *skb;
4460
4461 /* empty the queued pkts in the PS queue if any */
4462 A_MUTEX_LOCK(&ar->sta_list[i].psqLock);
4463 while (!A_NETBUF_QUEUE_EMPTY(&ar->sta_list[i].psq)) {
4464 skb = A_NETBUF_DEQUEUE(&ar->sta_list[i].psq);
4465 A_NETBUF_FREE(skb);
4466 }
4467 A_MUTEX_UNLOCK(&ar->sta_list[i].psqLock);
4468
4469 /* Zero out the state fields */
4470 A_MEMZERO(&ar->arAPStats.sta[ar->sta_list[i].aid-1], sizeof(WMI_PER_STA_STAT));
4471 A_MEMZERO(&ar->sta_list[i].mac, ATH_MAC_LEN);
4472 A_MEMZERO(&ar->sta_list[i].wpa_ie, IEEE80211_MAX_IE);
4473 ar->sta_list[i].aid = 0;
4474 ar->sta_list[i].flags = 0;
4475
4476 ar->sta_list_index = ar->sta_list_index & ~(1 << i);
4477
4478}
4479
4480u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason)
4481{
4482 u8 i, removed=0;
4483
4484 if(IS_MAC_NULL(mac)) {
4485 return removed;
4486 }
4487
4488 if(IS_MAC_BCAST(mac)) {
4489 A_PRINTF("DEL ALL STA\n");
4490 for(i=0; i < AP_MAX_NUM_STA; i++) {
4491 if(!IS_MAC_NULL(ar->sta_list[i].mac)) {
4492 sta_cleanup(ar, i);
4493 removed = 1;
4494 }
4495 }
4496 } else {
4497 for(i=0; i < AP_MAX_NUM_STA; i++) {
4498 if(memcmp(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) {
4499 A_PRINTF("DEL STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
4500 " aid=%d REASON=%d\n", mac[0], mac[1], mac[2],
4501 mac[3], mac[4], mac[5], ar->sta_list[i].aid, reason);
4502
4503 sta_cleanup(ar, i);
4504 removed = 1;
4505 break;
4506 }
4507 }
4508 }
4509 return removed;
4510}
4511
4512void
4513ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid,
4514 u8 assocRespLen, u8 *assocInfo, u16 protocolReasonStatus)
4515{
4516 u8 i;
4517 unsigned long flags;
4518 union iwreq_data wrqu;
4519
4520 if(ar->arNetworkType & AP_NETWORK) {
4521 union iwreq_data wrqu;
4522 struct sk_buff *skb;
4523
4524 if(!remove_sta(ar, bssid, protocolReasonStatus)) {
4525 return;
4526 }
4527
4528 /* If there are no more associated STAs, empty the mcast PS q */
4529 if (ar->sta_list_index == 0) {
4530 A_MUTEX_LOCK(&ar->mcastpsqLock);
4531 while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
4532 skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
4533 A_NETBUF_FREE(skb);
4534 }
4535 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
4536
4537 /* Clear the LSB of the BitMapCtl field of the TIM IE */
4538 if (ar->arWmiReady) {
4539 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
4540 }
4541 }
4542
4543 if(!IS_MAC_BCAST(bssid)) {
4544 /* Send event to application */
4545 A_MEMZERO(&wrqu, sizeof(wrqu));
4546 memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
4547 wireless_send_event(ar->arNetDev, IWEVEXPIRED, &wrqu, NULL);
4548 }
4549
4550 ar->arConnected = false;
4551 return;
4552 }
4553
4554 ar6k_cfg80211_disconnect_event(ar, reason, bssid,
4555 assocRespLen, assocInfo,
4556 protocolReasonStatus);
4557
4558 /* Send disconnect event to supplicant */
4559 A_MEMZERO(&wrqu, sizeof(wrqu));
4560 wrqu.addr.sa_family = ARPHRD_ETHER;
4561 wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
4562
4563 /* it is necessary to clear the host-side rx aggregation state */
4564 aggr_reset_state(ar->aggr_cntxt);
4565
4566 A_UNTIMEOUT(&ar->disconnect_timer);
4567
4568 A_PRINTF("AR6000 disconnected");
4569 if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) {
4570 A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
4571 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
4572 }
4573
4574 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nDisconnect Reason is %d", reason));
4575 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nProtocol Reason/Status Code is %d", protocolReasonStatus));
4576 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocResp Frame = %s",
4577 assocRespLen ? " " : "NULL"));
4578 for (i = 0; i < assocRespLen; i++) {
4579 if (!(i % 0x10)) {
4580 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4581 }
4582 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
4583 }
4584 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
4585 /*
4586 * If the event is due to disconnect cmd from the host, only they the target
4587 * would stop trying to connect. Under any other condition, target would
4588 * keep trying to connect.
4589 *
4590 */
4591 if( reason == DISCONNECT_CMD)
4592 {
4593 if ((!ar->arUserBssFilter) && (ar->arWmiReady)) {
4594 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4595 }
4596 } else {
4597 ar->arConnectPending = true;
4598 if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) ||
4599 ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (reconnect_flag == 1))) {
4600 ar->arConnected = true;
4601 return;
4602 }
4603 }
4604
4605 if ((reason == NO_NETWORK_AVAIL) && (ar->arWmiReady))
4606 {
4607 bss_t *pWmiSsidnode = NULL;
4608
4609 /* remove the current associated bssid node */
4610 wmi_free_node (ar->arWmi, bssid);
4611
4612 /*
4613 * In case any other same SSID nodes are present
4614 * remove it, since those nodes also not available now
4615 */
4616 do
4617 {
4618 /*
4619 * Find the nodes based on SSID and remove it
4620 * NOTE :: This case will not work out for Hidden-SSID
4621 */
4622 pWmiSsidnode = wmi_find_Ssidnode (ar->arWmi, ar->arSsid, ar->arSsidLen, false, true);
4623
4624 if (pWmiSsidnode)
4625 {
4626 wmi_free_node (ar->arWmi, pWmiSsidnode->ni_macaddr);
4627 }
4628
4629 } while (pWmiSsidnode);
4630 }
4631
4632 /* Update connect & link status atomically */
4633 spin_lock_irqsave(&ar->arLock, flags);
4634 ar->arConnected = false;
4635 netif_carrier_off(ar->arNetDev);
4636 spin_unlock_irqrestore(&ar->arLock, flags);
4637
4638 if( (reason != CSERV_DISCONNECT) || (reconnect_flag != 1) ) {
4639 reconnect_flag = 0;
4640 }
4641
4642 if (reason != CSERV_DISCONNECT)
4643 {
4644 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
4645 ar->user_key_ctrl = 0;
4646 }
4647
4648 netif_stop_queue(ar->arNetDev);
4649 A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
4650 ar->arBssChannel = 0;
4651 ar->arBeaconInterval = 0;
4652
4653 ar6000_TxDataCleanup(ar);
4654}
4655
4656void
4657ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode)
4658{
4659 A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode);
4660 ar->arRegCode = regCode;
4661}
4662
4663void
4664ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *evt)
4665{
4666 if(evt->status == 0) {
4667 aggr_recv_addba_req_evt(ar->aggr_cntxt, evt->tid, evt->st_seq_no, evt->win_sz);
4668 }
4669}
4670
4671void
4672ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *evt)
4673{
4674 A_PRINTF("ADDBA RESP. tid %d status %d, sz %d\n", evt->tid, evt->status, evt->amsdu_sz);
4675 if(evt->status == 0) {
4676 }
4677}
4678
4679void
4680ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *evt)
4681{
4682 aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid);
4683}
4684
4685void register_pal_cb(ar6k_pal_config_t *palConfig_p)
4686{
4687 ar6k_pal_config_g = *palConfig_p;
4688}
4689
4690void
4691ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd)
4692{
4693 void *osbuf = NULL;
4694 s8 i;
4695 u8 size, *buf;
4696 int ret = 0;
4697
4698 size = cmd->evt_buf_sz + 4;
4699 osbuf = A_NETBUF_ALLOC(size);
4700 if (osbuf == NULL) {
4701 ret = A_NO_MEMORY;
4702 A_PRINTF("Error in allocating netbuf \n");
4703 return;
4704 }
4705
4706 A_NETBUF_PUT(osbuf, size);
4707 buf = (u8 *)A_NETBUF_DATA(osbuf);
4708 /* First 2-bytes carry HCI event/ACL data type
4709 * the next 2 are free
4710 */
4711 *((short *)buf) = WMI_HCI_EVENT_EVENTID;
4712 buf += sizeof(int);
4713 memcpy(buf, cmd->buf, cmd->evt_buf_sz);
4714
4715 ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf);
4716 if(loghci) {
4717 A_PRINTF_LOG("HCI Event From PAL <-- \n");
4718 for(i = 0; i < cmd->evt_buf_sz; i++) {
4719 A_PRINTF_LOG("0x%02x ", cmd->buf[i]);
4720 if((i % 10) == 0) {
4721 A_PRINTF_LOG("\n");
4722 }
4723 }
4724 A_PRINTF_LOG("\n");
4725 A_PRINTF_LOG("==================================\n");
4726 }
4727}
4728
4729void
4730ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, WMI_NEIGHBOR_INFO *info)
4731{
4732#if WIRELESS_EXT >= 18
4733 struct iw_pmkid_cand *pmkcand;
4734#else /* WIRELESS_EXT >= 18 */
4735 static const char *tag = "PRE-AUTH";
4736 char buf[128];
4737#endif /* WIRELESS_EXT >= 18 */
4738
4739 union iwreq_data wrqu;
4740 int i;
4741
4742 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("AR6000 Neighbor Report Event\n"));
4743 for (i=0; i < numAps; info++, i++) {
4744 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
4745 info->bssid[0], info->bssid[1], info->bssid[2],
4746 info->bssid[3], info->bssid[4], info->bssid[5]));
4747 if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) {
4748 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("preauth-cap"));
4749 }
4750 if (info->bssFlags & WMI_PMKID_VALID_BSS) {
4751 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,(" pmkid-valid\n"));
4752 continue; /* we skip bss if the pmkid is already valid */
4753 }
4754 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("\n"));
4755 A_MEMZERO(&wrqu, sizeof(wrqu));
4756#if WIRELESS_EXT >= 18
4757 pmkcand = A_MALLOC_NOWAIT(sizeof(struct iw_pmkid_cand));
4758 A_MEMZERO(pmkcand, sizeof(struct iw_pmkid_cand));
4759 pmkcand->index = i;
4760 pmkcand->flags = info->bssFlags;
4761 memcpy(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN);
4762 wrqu.data.length = sizeof(struct iw_pmkid_cand);
4763 wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand);
4764 kfree(pmkcand);
4765#else /* WIRELESS_EXT >= 18 */
4766 snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
4767 tag,
4768 info->bssid[0], info->bssid[1], info->bssid[2],
4769 info->bssid[3], info->bssid[4], info->bssid[5],
4770 i, info->bssFlags);
4771 wrqu.data.length = strlen(buf);
4772 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4773#endif /* WIRELESS_EXT >= 18 */
4774 }
4775}
4776
4777void
4778ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
4779{
4780 static const char *tag = "MLME-MICHAELMICFAILURE.indication";
4781 char buf[128];
4782 union iwreq_data wrqu;
4783
4784 /*
4785 * For AP case, keyid will have aid of STA which sent pkt with
4786 * MIC error. Use this aid to get MAC & send it to hostapd.
4787 */
4788 if (ar->arNetworkType == AP_NETWORK) {
4789 sta_t *s = ieee80211_find_conn_for_aid(ar, (keyid >> 2));
4790 if(!s){
4791 A_PRINTF("AP TKIP MIC error received from Invalid aid / STA not found =%d\n", keyid);
4792 return;
4793 }
4794 A_PRINTF("AP TKIP MIC error received from aid=%d\n", keyid);
4795 snprintf(buf,sizeof(buf), "%s addr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
4796 tag, s->mac[0],s->mac[1],s->mac[2],s->mac[3],s->mac[4],s->mac[5]);
4797 } else {
4798
4799 ar6k_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
4800
4801 A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
4802 keyid & 0x3, ismcast ? "multi": "uni");
4803 snprintf(buf, sizeof(buf), "%s(keyid=%d %sicast)", tag, keyid & 0x3,
4804 ismcast ? "mult" : "un");
4805 }
4806
4807 memset(&wrqu, 0, sizeof(wrqu));
4808 wrqu.data.length = strlen(buf);
4809 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
4810}
4811
4812void
4813ar6000_scanComplete_event(struct ar6_softc *ar, int status)
4814{
4815
4816 ar6k_cfg80211_scanComplete_event(ar, status);
4817
4818 if (!ar->arUserBssFilter) {
4819 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
4820 }
4821 if (ar->scan_triggered) {
4822 if (status== 0) {
4823 union iwreq_data wrqu;
4824 A_MEMZERO(&wrqu, sizeof(wrqu));
4825 wireless_send_event(ar->arNetDev, SIOCGIWSCAN, &wrqu, NULL);
4826 }
4827 ar->scan_triggered = 0;
4828 }
4829
4830 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,( "AR6000 scan complete: %d\n", status));
4831}
4832
4833void
4834ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len)
4835{
4836 u8 ac;
4837
4838 if(ar->arNetworkType == AP_NETWORK) {
4839 WMI_AP_MODE_STAT *p = (WMI_AP_MODE_STAT *)ptr;
4840 WMI_AP_MODE_STAT *ap = &ar->arAPStats;
4841
4842 if (len < sizeof(*p)) {
4843 return;
4844 }
4845
4846 for(ac=0;ac<AP_MAX_NUM_STA;ac++) {
4847 ap->sta[ac].tx_bytes += p->sta[ac].tx_bytes;
4848 ap->sta[ac].tx_pkts += p->sta[ac].tx_pkts;
4849 ap->sta[ac].tx_error += p->sta[ac].tx_error;
4850 ap->sta[ac].tx_discard += p->sta[ac].tx_discard;
4851 ap->sta[ac].rx_bytes += p->sta[ac].rx_bytes;
4852 ap->sta[ac].rx_pkts += p->sta[ac].rx_pkts;
4853 ap->sta[ac].rx_error += p->sta[ac].rx_error;
4854 ap->sta[ac].rx_discard += p->sta[ac].rx_discard;
4855 }
4856
4857 } else {
4858 WMI_TARGET_STATS *pTarget = (WMI_TARGET_STATS *)ptr;
4859 TARGET_STATS *pStats = &ar->arTargetStats;
4860
4861 if (len < sizeof(*pTarget)) {
4862 return;
4863 }
4864
4865 // Update the RSSI of the connected bss.
4866 if (ar->arConnected) {
4867 bss_t *pConnBss = NULL;
4868
4869 pConnBss = wmi_find_node(ar->arWmi,ar->arBssid);
4870 if (pConnBss)
4871 {
4872 pConnBss->ni_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
4873 pConnBss->ni_snr = pTarget->cservStats.cs_aveBeacon_snr;
4874 wmi_node_return(ar->arWmi, pConnBss);
4875 }
4876 }
4877
4878 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 updating target stats\n"));
4879 pStats->tx_packets += pTarget->txrxStats.tx_stats.tx_packets;
4880 pStats->tx_bytes += pTarget->txrxStats.tx_stats.tx_bytes;
4881 pStats->tx_unicast_pkts += pTarget->txrxStats.tx_stats.tx_unicast_pkts;
4882 pStats->tx_unicast_bytes += pTarget->txrxStats.tx_stats.tx_unicast_bytes;
4883 pStats->tx_multicast_pkts += pTarget->txrxStats.tx_stats.tx_multicast_pkts;
4884 pStats->tx_multicast_bytes += pTarget->txrxStats.tx_stats.tx_multicast_bytes;
4885 pStats->tx_broadcast_pkts += pTarget->txrxStats.tx_stats.tx_broadcast_pkts;
4886 pStats->tx_broadcast_bytes += pTarget->txrxStats.tx_stats.tx_broadcast_bytes;
4887 pStats->tx_rts_success_cnt += pTarget->txrxStats.tx_stats.tx_rts_success_cnt;
4888 for(ac = 0; ac < WMM_NUM_AC; ac++)
4889 pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packet_per_ac[ac];
4890 pStats->tx_errors += pTarget->txrxStats.tx_stats.tx_errors;
4891 pStats->tx_failed_cnt += pTarget->txrxStats.tx_stats.tx_failed_cnt;
4892 pStats->tx_retry_cnt += pTarget->txrxStats.tx_stats.tx_retry_cnt;
4893 pStats->tx_mult_retry_cnt += pTarget->txrxStats.tx_stats.tx_mult_retry_cnt;
4894 pStats->tx_rts_fail_cnt += pTarget->txrxStats.tx_stats.tx_rts_fail_cnt;
4895 pStats->tx_unicast_rate = wmi_get_rate(pTarget->txrxStats.tx_stats.tx_unicast_rate);
4896
4897 pStats->rx_packets += pTarget->txrxStats.rx_stats.rx_packets;
4898 pStats->rx_bytes += pTarget->txrxStats.rx_stats.rx_bytes;
4899 pStats->rx_unicast_pkts += pTarget->txrxStats.rx_stats.rx_unicast_pkts;
4900 pStats->rx_unicast_bytes += pTarget->txrxStats.rx_stats.rx_unicast_bytes;
4901 pStats->rx_multicast_pkts += pTarget->txrxStats.rx_stats.rx_multicast_pkts;
4902 pStats->rx_multicast_bytes += pTarget->txrxStats.rx_stats.rx_multicast_bytes;
4903 pStats->rx_broadcast_pkts += pTarget->txrxStats.rx_stats.rx_broadcast_pkts;
4904 pStats->rx_broadcast_bytes += pTarget->txrxStats.rx_stats.rx_broadcast_bytes;
4905 pStats->rx_fragment_pkt += pTarget->txrxStats.rx_stats.rx_fragment_pkt;
4906 pStats->rx_errors += pTarget->txrxStats.rx_stats.rx_errors;
4907 pStats->rx_crcerr += pTarget->txrxStats.rx_stats.rx_crcerr;
4908 pStats->rx_key_cache_miss += pTarget->txrxStats.rx_stats.rx_key_cache_miss;
4909 pStats->rx_decrypt_err += pTarget->txrxStats.rx_stats.rx_decrypt_err;
4910 pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_frames;
4911 pStats->rx_unicast_rate = wmi_get_rate(pTarget->txrxStats.rx_stats.rx_unicast_rate);
4912
4913
4914 pStats->tkip_local_mic_failure
4915 += pTarget->txrxStats.tkipCcmpStats.tkip_local_mic_failure;
4916 pStats->tkip_counter_measures_invoked
4917 += pTarget->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked;
4918 pStats->tkip_replays += pTarget->txrxStats.tkipCcmpStats.tkip_replays;
4919 pStats->tkip_format_errors += pTarget->txrxStats.tkipCcmpStats.tkip_format_errors;
4920 pStats->ccmp_format_errors += pTarget->txrxStats.tkipCcmpStats.ccmp_format_errors;
4921 pStats->ccmp_replays += pTarget->txrxStats.tkipCcmpStats.ccmp_replays;
4922
4923 pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cnt;
4924 pStats->noise_floor_calibation = pTarget->noise_floor_calibation;
4925
4926 pStats->cs_bmiss_cnt += pTarget->cservStats.cs_bmiss_cnt;
4927 pStats->cs_lowRssi_cnt += pTarget->cservStats.cs_lowRssi_cnt;
4928 pStats->cs_connect_cnt += pTarget->cservStats.cs_connect_cnt;
4929 pStats->cs_disconnect_cnt += pTarget->cservStats.cs_disconnect_cnt;
4930 pStats->cs_aveBeacon_snr = pTarget->cservStats.cs_aveBeacon_snr;
4931 pStats->cs_aveBeacon_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
4932
4933 if (enablerssicompensation) {
4934 pStats->cs_aveBeacon_rssi =
4935 rssi_compensation_calc(ar, pStats->cs_aveBeacon_rssi);
4936 }
4937 pStats->cs_lastRoam_msec = pTarget->cservStats.cs_lastRoam_msec;
4938 pStats->cs_snr = pTarget->cservStats.cs_snr;
4939 pStats->cs_rssi = pTarget->cservStats.cs_rssi;
4940
4941 pStats->lq_val = pTarget->lqVal;
4942
4943 pStats->wow_num_pkts_dropped += pTarget->wowStats.wow_num_pkts_dropped;
4944 pStats->wow_num_host_pkt_wakeups += pTarget->wowStats.wow_num_host_pkt_wakeups;
4945 pStats->wow_num_host_event_wakeups += pTarget->wowStats.wow_num_host_event_wakeups;
4946 pStats->wow_num_events_discarded += pTarget->wowStats.wow_num_events_discarded;
4947 pStats->arp_received += pTarget->arpStats.arp_received;
4948 pStats->arp_matched += pTarget->arpStats.arp_matched;
4949 pStats->arp_replied += pTarget->arpStats.arp_replied;
4950
4951 if (ar->statsUpdatePending) {
4952 ar->statsUpdatePending = false;
4953 wake_up(&arEvent);
4954 }
4955 }
4956}
4957
4958void
4959ar6000_rssiThreshold_event(struct ar6_softc *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, s16 rssi)
4960{
4961 USER_RSSI_THOLD userRssiThold;
4962
4963 rssi = rssi + SIGNAL_QUALITY_NOISE_FLOOR;
4964
4965 if (enablerssicompensation) {
4966 rssi = rssi_compensation_calc(ar, rssi);
4967 }
4968
4969 /* Send an event to the app */
4970 userRssiThold.tag = ar->rssi_map[newThreshold].tag;
4971 userRssiThold.rssi = rssi;
4972 A_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold,
4973 userRssiThold.tag, userRssiThold.rssi);
4974}
4975
4976
4977void
4978ar6000_hbChallengeResp_event(struct ar6_softc *ar, u32 cookie, u32 source)
4979{
4980 if (source != APP_HB_CHALLENGE) {
4981 /* This would ignore the replys that come in after their due time */
4982 if (cookie == ar->arHBChallengeResp.seqNum) {
4983 ar->arHBChallengeResp.outstanding = false;
4984 }
4985 }
4986}
4987
4988
4989void
4990ar6000_reportError_event(struct ar6_softc *ar, WMI_TARGET_ERROR_VAL errorVal)
4991{
4992 static const char * const errString[] = {
4993 [WMI_TARGET_PM_ERR_FAIL] "WMI_TARGET_PM_ERR_FAIL",
4994 [WMI_TARGET_KEY_NOT_FOUND] "WMI_TARGET_KEY_NOT_FOUND",
4995 [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR",
4996 [WMI_TARGET_BMISS] "WMI_TARGET_BMISS",
4997 [WMI_PSDISABLE_NODE_JOIN] "WMI_PSDISABLE_NODE_JOIN"
4998 };
4999
5000 A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal);
5001
5002 /* One error is reported at a time, and errorval is a bitmask */
5003 if(errorVal & (errorVal - 1))
5004 return;
5005
5006 A_PRINTF("AR6000 Error type = ");
5007 switch(errorVal)
5008 {
5009 case WMI_TARGET_PM_ERR_FAIL:
5010 case WMI_TARGET_KEY_NOT_FOUND:
5011 case WMI_TARGET_DECRYPTION_ERR:
5012 case WMI_TARGET_BMISS:
5013 case WMI_PSDISABLE_NODE_JOIN:
5014 A_PRINTF("%s\n", errString[errorVal]);
5015 break;
5016 default:
5017 A_PRINTF("INVALID\n");
5018 break;
5019 }
5020
5021}
5022
5023
5024void
5025ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cacIndication,
5026 u8 statusCode, u8 *tspecSuggestion)
5027{
5028 WMM_TSPEC_IE *tspecIe;
5029
5030 /*
5031 * This is the TSPEC IE suggestion from AP.
5032 * Suggestion provided by AP under some error
5033 * cases, could be helpful for the host app.
5034 * Check documentation.
5035 */
5036 tspecIe = (WMM_TSPEC_IE *)tspecSuggestion;
5037
5038 /*
5039 * What do we do, if we get TSPEC rejection? One thought
5040 * that comes to mind is implictly delete the pstream...
5041 */
5042 A_PRINTF("AR6000 CAC notification. "
5043 "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
5044 ac, cacIndication, statusCode);
5045}
5046
5047void
5048ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel,
5049 u16 newChannel)
5050{
5051 A_PRINTF("Channel Change notification\nOld Channel: %d, New Channel: %d\n",
5052 oldChannel, newChannel);
5053}
5054
5055#define AR6000_PRINT_BSSID(_pBss) do { \
5056 A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
5057 (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
5058 (_pBss)[4],(_pBss)[5]); \
5059} while(0)
5060
5061void
5062ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl)
5063{
5064 u8 i;
5065
5066 A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
5067 pTbl->numEntries, pTbl->roamMode);
5068 for (i= 0; i < pTbl->numEntries; i++) {
5069 A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i,
5070 pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1],
5071 pTbl->bssRoamInfo[i].bssid[2],
5072 pTbl->bssRoamInfo[i].bssid[3],
5073 pTbl->bssRoamInfo[i].bssid[4],
5074 pTbl->bssRoamInfo[i].bssid[5]);
5075 A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
5076 " BIAS %d\n",
5077 pTbl->bssRoamInfo[i].rssi,
5078 pTbl->bssRoamInfo[i].rssidt,
5079 pTbl->bssRoamInfo[i].last_rssi,
5080 pTbl->bssRoamInfo[i].util,
5081 pTbl->bssRoamInfo[i].roam_util,
5082 pTbl->bssRoamInfo[i].bias);
5083 }
5084}
5085
5086void
5087ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply)
5088{
5089 u8 i,j;
5090
5091 /*Each event now contains exactly one filter, see bug 26613*/
5092 A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num, wow_reply->num_filters);
5093 A_PRINTF("wow mode = %s host mode = %s\n",
5094 (wow_reply->wow_mode == 0? "disabled":"enabled"),
5095 (wow_reply->host_mode == 1 ? "awake":"asleep"));
5096
5097
5098 /*If there are no patterns, the reply will only contain generic
5099 WoW information. Pattern information will exist only if there are
5100 patterns present. Bug 26716*/
5101
5102 /* If this event contains pattern information, display it*/
5103 if (wow_reply->this_filter_num) {
5104 i=0;
5105 A_PRINTF("id=%d size=%d offset=%d\n",
5106 wow_reply->wow_filters[i].wow_filter_id,
5107 wow_reply->wow_filters[i].wow_filter_size,
5108 wow_reply->wow_filters[i].wow_filter_offset);
5109 A_PRINTF("wow pattern = ");
5110 for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
5111 A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_pattern[j]);
5112 }
5113
5114 A_PRINTF("\nwow mask = ");
5115 for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
5116 A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_mask[j]);
5117 }
5118 A_PRINTF("\n");
5119 }
5120}
5121
5122/*
5123 * Report the Roaming related data collected on the target
5124 */
5125void
5126ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p)
5127{
5128 A_PRINTF("Disconnect Data : BSSID: ");
5129 AR6000_PRINT_BSSID(p->disassoc_bssid);
5130 A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
5131 p->disassoc_bss_rssi,p->disassoc_time,
5132 p->no_txrx_time);
5133 A_PRINTF("Connect Data: BSSID: ");
5134 AR6000_PRINT_BSSID(p->assoc_bssid);
5135 A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
5136 p->assoc_bss_rssi,p->assoc_time,
5137 p->allow_txrx_time);
5138}
5139
5140void
5141ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p)
5142{
5143 switch (p->roamDataType) {
5144 case ROAM_DATA_TIME:
5145 ar6000_display_roam_time(&p->u.roamTime);
5146 break;
5147 default:
5148 break;
5149 }
5150}
5151
5152void
5153ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *datap, int len)
5154{
5155 struct sk_buff *skb;
5156 WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap;
5157
5158
5159 if (!ar->arMgmtFilter) {
5160 return;
5161 }
5162 if (((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_BEACON) &&
5163 (bih->frameType != BEACON_FTYPE)) ||
5164 ((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_PROBE_RESP) &&
5165 (bih->frameType != PROBERESP_FTYPE)))
5166 {
5167 return;
5168 }
5169
5170 if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) {
5171
5172 A_NETBUF_PUT(skb, len);
5173 memcpy(A_NETBUF_DATA(skb), datap, len);
5174 skb->dev = ar->arNetDev;
5175 memcpy(skb_mac_header(skb), A_NETBUF_DATA(skb), 6);
5176 skb->ip_summed = CHECKSUM_NONE;
5177 skb->pkt_type = PACKET_OTHERHOST;
5178 skb->protocol = __constant_htons(0x0019);
5179 netif_rx(skb);
5180 }
5181}
5182
5183u32 wmiSendCmdNum;
5184
5185int
5186ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid)
5187{
5188 struct ar6_softc *ar = (struct ar6_softc *)devt;
5189 int status = 0;
5190 struct ar_cookie *cookie = NULL;
5191 int i;
5192#ifdef CONFIG_PM
5193 if (ar->arWowState != WLAN_WOW_STATE_NONE) {
5194 A_NETBUF_FREE(osbuf);
5195 return A_EACCES;
5196 }
5197#endif /* CONFIG_PM */
5198 /* take lock to protect ar6000_alloc_cookie() */
5199 AR6000_SPIN_LOCK(&ar->arLock, 0);
5200
5201 do {
5202
5203 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar_contrstatus = ol_tx: skb=0x%lx, len=0x%x eid =%d\n",
5204 (unsigned long)osbuf, A_NETBUF_LEN(osbuf), eid));
5205
5206 if (ar->arWMIControlEpFull && (eid == ar->arControlEp)) {
5207 /* control endpoint is full, don't allocate resources, we
5208 * are just going to drop this packet */
5209 cookie = NULL;
5210 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" WMI Control EP full, dropping packet : 0x%lX, len:%d \n",
5211 (unsigned long)osbuf, A_NETBUF_LEN(osbuf)));
5212 } else {
5213 cookie = ar6000_alloc_cookie(ar);
5214 }
5215
5216 if (cookie == NULL) {
5217 status = A_NO_MEMORY;
5218 break;
5219 }
5220
5221 if(logWmiRawMsgs) {
5222 A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum);
5223 for(i = 0; i < a_netbuf_to_len(osbuf); i++)
5224 A_PRINTF("%x ", ((u8 *)a_netbuf_to_data(osbuf))[i]);
5225 A_PRINTF("\n");
5226 }
5227
5228 wmiSendCmdNum++;
5229
5230 } while (false);
5231
5232 if (cookie != NULL) {
5233 /* got a structure to send it out on */
5234 ar->arTxPending[eid]++;
5235
5236 if (eid != ar->arControlEp) {
5237 ar->arTotalTxDataPending++;
5238 }
5239 }
5240
5241 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
5242
5243 if (cookie != NULL) {
5244 cookie->arc_bp[0] = (unsigned long)osbuf;
5245 cookie->arc_bp[1] = 0;
5246 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
5247 cookie,
5248 A_NETBUF_DATA(osbuf),
5249 A_NETBUF_LEN(osbuf),
5250 eid,
5251 AR6K_CONTROL_PKT_TAG);
5252 /* this interface is asynchronous, if there is an error, cleanup will happen in the
5253 * TX completion callback */
5254 HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
5255 status = 0;
5256 }
5257
5258 if (status) {
5259 A_NETBUF_FREE(osbuf);
5260 }
5261 return status;
5262}
5263
5264/* indicate tx activity or inactivity on a WMI stream */
5265void ar6000_indicate_tx_activity(void *devt, u8 TrafficClass, bool Active)
5266{
5267 struct ar6_softc *ar = (struct ar6_softc *)devt;
5268 HTC_ENDPOINT_ID eid ;
5269 int i;
5270
5271 if (ar->arWmiEnabled) {
5272 eid = arAc2EndpointID(ar, TrafficClass);
5273
5274 AR6000_SPIN_LOCK(&ar->arLock, 0);
5275
5276 ar->arAcStreamActive[TrafficClass] = Active;
5277
5278 if (Active) {
5279 /* when a stream goes active, keep track of the active stream with the highest priority */
5280
5281 if (ar->arAcStreamPriMap[TrafficClass] > ar->arHiAcStreamActivePri) {
5282 /* set the new highest active priority */
5283 ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[TrafficClass];
5284 }
5285
5286 } else {
5287 /* when a stream goes inactive, we may have to search for the next active stream
5288 * that is the highest priority */
5289
5290 if (ar->arHiAcStreamActivePri == ar->arAcStreamPriMap[TrafficClass]) {
5291
5292 /* the highest priority stream just went inactive */
5293
5294 /* reset and search for the "next" highest "active" priority stream */
5295 ar->arHiAcStreamActivePri = 0;
5296 for (i = 0; i < WMM_NUM_AC; i++) {
5297 if (ar->arAcStreamActive[i]) {
5298 if (ar->arAcStreamPriMap[i] > ar->arHiAcStreamActivePri) {
5299 /* set the new highest active priority */
5300 ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[i];
5301 }
5302 }
5303 }
5304 }
5305 }
5306
5307 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
5308
5309 } else {
5310 /* for mbox ping testing, the traffic class is mapped directly as a stream ID,
5311 * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c
5312 * convert the stream ID to a endpoint */
5313 eid = arAc2EndpointID(ar, TrafficClass);
5314 }
5315
5316 /* notify HTC, this may cause credit distribution changes */
5317
5318 HTCIndicateActivityChange(ar->arHtcTarget,
5319 eid,
5320 Active);
5321
5322}
5323
5324void
5325ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len)
5326{
5327
5328 WMI_BTCOEX_CONFIG_EVENT *pBtcoexConfig = (WMI_BTCOEX_CONFIG_EVENT *)ptr;
5329 WMI_BTCOEX_CONFIG_EVENT *pArbtcoexConfig =&ar->arBtcoexConfig;
5330
5331 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
5332
5333 A_PRINTF("received config event\n");
5334 pArbtcoexConfig->btProfileType = pBtcoexConfig->btProfileType;
5335 pArbtcoexConfig->linkId = pBtcoexConfig->linkId;
5336
5337 switch (pBtcoexConfig->btProfileType) {
5338 case WMI_BTCOEX_BT_PROFILE_SCO:
5339 memcpy(&pArbtcoexConfig->info.scoConfigCmd, &pBtcoexConfig->info.scoConfigCmd,
5340 sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
5341 break;
5342 case WMI_BTCOEX_BT_PROFILE_A2DP:
5343 memcpy(&pArbtcoexConfig->info.a2dpConfigCmd, &pBtcoexConfig->info.a2dpConfigCmd,
5344 sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
5345 break;
5346 case WMI_BTCOEX_BT_PROFILE_ACLCOEX:
5347 memcpy(&pArbtcoexConfig->info.aclcoexConfig, &pBtcoexConfig->info.aclcoexConfig,
5348 sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5349 break;
5350 case WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE:
5351 memcpy(&pArbtcoexConfig->info.btinquiryPageConfigCmd, &pBtcoexConfig->info.btinquiryPageConfigCmd,
5352 sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5353 break;
5354 }
5355 if (ar->statsUpdatePending) {
5356 ar->statsUpdatePending = false;
5357 wake_up(&arEvent);
5358 }
5359}
5360
5361void
5362ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len)
5363{
5364 WMI_BTCOEX_STATS_EVENT *pBtcoexStats = (WMI_BTCOEX_STATS_EVENT *)ptr;
5365
5366 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
5367
5368 memcpy(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT));
5369
5370 if (ar->statsUpdatePending) {
5371 ar->statsUpdatePending = false;
5372 wake_up(&arEvent);
5373 }
5374
5375}
5376module_init(ar6000_init_module);
5377module_exit(ar6000_cleanup_module);
5378
5379/* Init cookie queue */
5380static void
5381ar6000_cookie_init(struct ar6_softc *ar)
5382{
5383 u32 i;
5384
5385 ar->arCookieList = NULL;
5386 ar->arCookieCount = 0;
5387
5388 A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem));
5389
5390 for (i = 0; i < MAX_COOKIE_NUM; i++) {
5391 ar6000_free_cookie(ar, &s_ar_cookie_mem[i]);
5392 }
5393}
5394
5395/* cleanup cookie queue */
5396static void
5397ar6000_cookie_cleanup(struct ar6_softc *ar)
5398{
5399 /* It is gone .... */
5400 ar->arCookieList = NULL;
5401 ar->arCookieCount = 0;
5402}
5403
5404/* Init cookie queue */
5405static void
5406ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie)
5407{
5408 /* Insert first */
5409 A_ASSERT(ar != NULL);
5410 A_ASSERT(cookie != NULL);
5411
5412 cookie->arc_list_next = ar->arCookieList;
5413 ar->arCookieList = cookie;
5414 ar->arCookieCount++;
5415}
5416
5417/* cleanup cookie queue */
5418static struct ar_cookie *
5419ar6000_alloc_cookie(struct ar6_softc *ar)
5420{
5421 struct ar_cookie *cookie;
5422
5423 cookie = ar->arCookieList;
5424 if(cookie != NULL)
5425 {
5426 ar->arCookieList = cookie->arc_list_next;
5427 ar->arCookieCount--;
5428 }
5429
5430 return cookie;
5431}
5432
5433void
5434ar6000_tx_retry_err_event(void *devt)
5435{
5436 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Tx retries reach maximum!\n"));
5437}
5438
5439void
5440ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, u8 snr)
5441{
5442 WMI_SNR_THRESHOLD_EVENT event;
5443
5444 event.range = newThreshold;
5445 event.snr = snr;
5446}
5447
5448void
5449ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, u8 lq)
5450{
5451 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("lq threshold range %d, lq %d\n", newThreshold, lq));
5452}
5453
5454
5455
5456u32 a_copy_to_user(void *to, const void *from, u32 n)
5457{
5458 return(copy_to_user(to, from, n));
5459}
5460
5461u32 a_copy_from_user(void *to, const void *from, u32 n)
5462{
5463 return(copy_from_user(to, from, n));
5464}
5465
5466
5467int
5468ar6000_get_driver_cfg(struct net_device *dev,
5469 u16 cfgParam,
5470 void *result)
5471{
5472
5473 int ret = 0;
5474
5475 switch(cfgParam)
5476 {
5477 case AR6000_DRIVER_CFG_GET_WLANNODECACHING:
5478 *((u32 *)result) = wlanNodeCaching;
5479 break;
5480 case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS:
5481 *((u32 *)result) = logWmiRawMsgs;
5482 break;
5483 default:
5484 ret = EINVAL;
5485 break;
5486 }
5487
5488 return ret;
5489}
5490
5491void
5492ar6000_keepalive_rx(void *devt, u8 configured)
5493{
5494 struct ar6_softc *ar = (struct ar6_softc *)devt;
5495
5496 ar->arKeepaliveConfigured = configured;
5497 wake_up(&arEvent);
5498}
5499
5500void
5501ar6000_pmkid_list_event(void *devt, u8 numPMKID, WMI_PMKID *pmkidList,
5502 u8 *bssidList)
5503{
5504 u8 i, j;
5505
5506 A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID);
5507
5508 for (i = 0; i < numPMKID; i++) {
5509 A_PRINTF("\nBSSID %d ", i);
5510 for (j = 0; j < ATH_MAC_LEN; j++) {
5511 A_PRINTF("%2.2x", bssidList[j]);
5512 }
5513 bssidList += (ATH_MAC_LEN + WMI_PMKID_LEN);
5514 A_PRINTF("\nPMKID %d ", i);
5515 for (j = 0; j < WMI_PMKID_LEN; j++) {
5516 A_PRINTF("%2.2x", pmkidList->pmkid[j]);
5517 }
5518 pmkidList = (WMI_PMKID *)((u8 *)pmkidList + ATH_MAC_LEN +
5519 WMI_PMKID_LEN);
5520 }
5521}
5522
5523void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid)
5524{
5525 sta_t *conn=NULL;
5526 bool isPsqEmpty = false;
5527
5528 conn = ieee80211_find_conn_for_aid(ar, aid);
5529
5530 /* If the PS q for this STA is not empty, dequeue and send a pkt from
5531 * the head of the q. Also update the More data bit in the WMI_DATA_HDR
5532 * if there are more pkts for this STA in the PS q. If there are no more
5533 * pkts for this STA, update the PVB for this STA.
5534 */
5535 A_MUTEX_LOCK(&conn->psqLock);
5536 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
5537 A_MUTEX_UNLOCK(&conn->psqLock);
5538
5539 if (isPsqEmpty) {
5540 /* TODO:No buffered pkts for this STA. Send out a NULL data frame */
5541 } else {
5542 struct sk_buff *skb = NULL;
5543
5544 A_MUTEX_LOCK(&conn->psqLock);
5545 skb = A_NETBUF_DEQUEUE(&conn->psq);
5546 A_MUTEX_UNLOCK(&conn->psqLock);
5547 /* Set the STA flag to PSPolled, so that the frame will go out */
5548 STA_SET_PS_POLLED(conn);
5549 ar6000_data_tx(skb, ar->arNetDev);
5550 STA_CLR_PS_POLLED(conn);
5551
5552 /* Clear the PVB for this STA if the queue has become empty */
5553 A_MUTEX_LOCK(&conn->psqLock);
5554 isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
5555 A_MUTEX_UNLOCK(&conn->psqLock);
5556
5557 if (isPsqEmpty) {
5558 wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
5559 }
5560 }
5561}
5562
5563void ar6000_dtimexpiry_event(struct ar6_softc *ar)
5564{
5565 bool isMcastQueued = false;
5566 struct sk_buff *skb = NULL;
5567
5568 /* If there are no associated STAs, ignore the DTIM expiry event.
5569 * There can be potential race conditions where the last associated
5570 * STA may disconnect & before the host could clear the 'Indicate DTIM'
5571 * request to the firmware, the firmware would have just indicated a DTIM
5572 * expiry event. The race is between 'clear DTIM expiry cmd' going
5573 * from the host to the firmware & the DTIM expiry event happening from
5574 * the firmware to the host.
5575 */
5576 if (ar->sta_list_index == 0) {
5577 return;
5578 }
5579
5580 A_MUTEX_LOCK(&ar->mcastpsqLock);
5581 isMcastQueued = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
5582 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5583
5584 A_ASSERT(isMcastQueued == false);
5585
5586 /* Flush the mcast psq to the target */
5587 /* Set the STA flag to DTIMExpired, so that the frame will go out */
5588 ar->DTIMExpired = true;
5589
5590 A_MUTEX_LOCK(&ar->mcastpsqLock);
5591 while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
5592 skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
5593 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5594
5595 ar6000_data_tx(skb, ar->arNetDev);
5596
5597 A_MUTEX_LOCK(&ar->mcastpsqLock);
5598 }
5599 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
5600
5601 /* Reset the DTIMExpired flag back to 0 */
5602 ar->DTIMExpired = false;
5603
5604 /* Clear the LSB of the BitMapCtl field of the TIM IE */
5605 wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
5606}
5607
5608void
5609read_rssi_compensation_param(struct ar6_softc *ar)
5610{
5611 u8 *cust_data_ptr;
5612
5613//#define RSSICOMPENSATION_PRINT
5614
5615#ifdef RSSICOMPENSATION_PRINT
5616 s16 i;
5617 cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
5618 for (i=0; i<16; i++) {
5619 A_PRINTF("cust_data_%d = %x \n", i, *(u8 *)cust_data_ptr);
5620 cust_data_ptr += 1;
5621 }
5622#endif
5623
5624 cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
5625
5626 rssi_compensation_param.customerID = *(u16 *)cust_data_ptr & 0xffff;
5627 rssi_compensation_param.enable = *(u16 *)(cust_data_ptr+2) & 0xffff;
5628 rssi_compensation_param.bg_param_a = *(u16 *)(cust_data_ptr+4) & 0xffff;
5629 rssi_compensation_param.bg_param_b = *(u16 *)(cust_data_ptr+6) & 0xffff;
5630 rssi_compensation_param.a_param_a = *(u16 *)(cust_data_ptr+8) & 0xffff;
5631 rssi_compensation_param.a_param_b = *(u16 *)(cust_data_ptr+10) &0xffff;
5632 rssi_compensation_param.reserved = *(u32 *)(cust_data_ptr+12);
5633
5634#ifdef RSSICOMPENSATION_PRINT
5635 A_PRINTF("customerID = 0x%x \n", rssi_compensation_param.customerID);
5636 A_PRINTF("enable = 0x%x \n", rssi_compensation_param.enable);
5637 A_PRINTF("bg_param_a = 0x%x and %d \n", rssi_compensation_param.bg_param_a, rssi_compensation_param.bg_param_a);
5638 A_PRINTF("bg_param_b = 0x%x and %d \n", rssi_compensation_param.bg_param_b, rssi_compensation_param.bg_param_b);
5639 A_PRINTF("a_param_a = 0x%x and %d \n", rssi_compensation_param.a_param_a, rssi_compensation_param.a_param_a);
5640 A_PRINTF("a_param_b = 0x%x and %d \n", rssi_compensation_param.a_param_b, rssi_compensation_param.a_param_b);
5641 A_PRINTF("Last 4 bytes = 0x%x \n", rssi_compensation_param.reserved);
5642#endif
5643
5644 if (rssi_compensation_param.enable != 0x1) {
5645 rssi_compensation_param.enable = 0;
5646 }
5647
5648 return;
5649}
5650
5651s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt)
5652{
5653
5654 if (freq > 5000)
5655 {
5656 if (rssi_compensation_param.enable)
5657 {
5658 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5659 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, totalPkt = %d\n", rssi,totalPkt));
5660 rssi = rssi * rssi_compensation_param.a_param_a + totalPkt * rssi_compensation_param.a_param_b;
5661 rssi = (rssi-50) /100;
5662 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5663 }
5664 }
5665 else
5666 {
5667 if (rssi_compensation_param.enable)
5668 {
5669 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5670 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, totalPkt = %d\n", rssi,totalPkt));
5671 rssi = rssi * rssi_compensation_param.bg_param_a + totalPkt * rssi_compensation_param.bg_param_b;
5672 rssi = (rssi-50) /100;
5673 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5674 }
5675 }
5676
5677 return rssi;
5678}
5679
5680s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi)
5681{
5682 if (ar->arBssChannel > 5000)
5683 {
5684 if (rssi_compensation_param.enable)
5685 {
5686 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5687 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi));
5688 rssi = rssi * rssi_compensation_param.a_param_a + rssi_compensation_param.a_param_b;
5689 rssi = (rssi-50) /100;
5690 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5691 }
5692 }
5693 else
5694 {
5695 if (rssi_compensation_param.enable)
5696 {
5697 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5698 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi));
5699 rssi = rssi * rssi_compensation_param.bg_param_a + rssi_compensation_param.bg_param_b;
5700 rssi = (rssi-50) /100;
5701 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
5702 }
5703 }
5704
5705 return rssi;
5706}
5707
5708s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above)
5709{
5710 s16 i;
5711
5712 if (ar->arBssChannel > 5000)
5713 {
5714 if (rssi_compensation_param.enable)
5715 {
5716 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
5717 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d\n", rssi));
5718 rssi = rssi * 100;
5719 rssi = (rssi - rssi_compensation_param.a_param_b) / rssi_compensation_param.a_param_a;
5720 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
5721 }
5722 }
5723 else
5724 {
5725 if (rssi_compensation_param.enable)
5726 {
5727 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
5728 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d\n", rssi));
5729
5730 if (Above) {
5731 for (i=95; i>=0; i--) {
5732 if (rssi <= rssi_compensation_table[i]) {
5733 rssi = 0 - i;
5734 break;
5735 }
5736 }
5737 } else {
5738 for (i=0; i<=95; i++) {
5739 if (rssi >= rssi_compensation_table[i]) {
5740 rssi = 0 - i;
5741 break;
5742 }
5743 }
5744 }
5745 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
5746 }
5747 }
5748
5749 return rssi;
5750}
5751
5752#ifdef WAPI_ENABLE
5753void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac)
5754{
5755 union iwreq_data wrqu;
5756 char buf[20];
5757
5758 A_MEMZERO(buf, sizeof(buf));
5759
5760 strcpy(buf, "WAPI_REKEY");
5761 buf[10] = type;
5762 memcpy(&buf[11], mac, ATH_MAC_LEN);
5763
5764 A_MEMZERO(&wrqu, sizeof(wrqu));
5765 wrqu.data.length = 10+1+ATH_MAC_LEN;
5766 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
5767
5768 A_PRINTF("WAPI REKEY - %d - %02x:%02x\n", type, mac[4], mac[5]);
5769}
5770#endif
5771
5772static int
5773ar6000_reinstall_keys(struct ar6_softc *ar, u8 key_op_ctrl)
5774{
5775 int status = 0;
5776 struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik;
5777 struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik;
5778 CRYPTO_TYPE keyType = ar->user_saved_keys.keyType;
5779
5780 if (IEEE80211_CIPHER_CCKM_KRK != uik->ik_type) {
5781 if (NONE_CRYPT == keyType) {
5782 goto _reinstall_keys_out;
5783 }
5784
5785 if (uik->ik_keylen) {
5786 status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix,
5787 ar->user_saved_keys.keyType, PAIRWISE_USAGE,
5788 uik->ik_keylen, (u8 *)&uik->ik_keyrsc,
5789 uik->ik_keydata, key_op_ctrl, uik->ik_macaddr, SYNC_BEFORE_WMIFLAG);
5790 }
5791
5792 } else {
5793 status = wmi_add_krk_cmd(ar->arWmi, uik->ik_keydata);
5794 }
5795
5796 if (IEEE80211_CIPHER_CCKM_KRK != bik->ik_type) {
5797 if (NONE_CRYPT == keyType) {
5798 goto _reinstall_keys_out;
5799 }
5800
5801 if (bik->ik_keylen) {
5802 status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix,
5803 ar->user_saved_keys.keyType, GROUP_USAGE,
5804 bik->ik_keylen, (u8 *)&bik->ik_keyrsc,
5805 bik->ik_keydata, key_op_ctrl, bik->ik_macaddr, NO_SYNC_WMIFLAG);
5806 }
5807 } else {
5808 status = wmi_add_krk_cmd(ar->arWmi, bik->ik_keydata);
5809 }
5810
5811_reinstall_keys_out:
5812 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
5813 ar->user_key_ctrl = 0;
5814
5815 return status;
5816}
5817
5818
5819void
5820ar6000_dset_open_req(
5821 void *context,
5822 u32 id,
5823 u32 targHandle,
5824 u32 targReplyFn,
5825 u32 targReplyArg)
5826{
5827}
5828
5829void
5830ar6000_dset_close(
5831 void *context,
5832 u32 access_cookie)
5833{
5834 return;
5835}
5836
5837void
5838ar6000_dset_data_req(
5839 void *context,
5840 u32 accessCookie,
5841 u32 offset,
5842 u32 length,
5843 u32 targBuf,
5844 u32 targReplyFn,
5845 u32 targReplyArg)
5846{
5847}
5848
5849int
5850ar6000_ap_mode_profile_commit(struct ar6_softc *ar)
5851{
5852 WMI_CONNECT_CMD p;
5853 unsigned long flags;
5854
5855 /* No change in AP's profile configuration */
5856 if(ar->ap_profile_flag==0) {
5857 A_PRINTF("COMMIT: No change in profile!!!\n");
5858 return -ENODATA;
5859 }
5860
5861 if(!ar->arSsidLen) {
5862 A_PRINTF("SSID not set!!!\n");
5863 return -ECHRNG;
5864 }
5865
5866 switch(ar->arAuthMode) {
5867 case NONE_AUTH:
5868 if((ar->arPairwiseCrypto != NONE_CRYPT) &&
5869#ifdef WAPI_ENABLE
5870 (ar->arPairwiseCrypto != WAPI_CRYPT) &&
5871#endif
5872 (ar->arPairwiseCrypto != WEP_CRYPT)) {
5873 A_PRINTF("Cipher not supported in AP mode Open auth\n");
5874 return -EOPNOTSUPP;
5875 }
5876 break;
5877 case WPA_PSK_AUTH:
5878 case WPA2_PSK_AUTH:
5879 case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
5880 break;
5881 default:
5882 A_PRINTF("This key mgmt type not supported in AP mode\n");
5883 return -EOPNOTSUPP;
5884 }
5885
5886 /* Update the arNetworkType */
5887 ar->arNetworkType = ar->arNextMode;
5888
5889 A_MEMZERO(&p,sizeof(p));
5890 p.ssidLength = ar->arSsidLen;
5891 memcpy(p.ssid,ar->arSsid,p.ssidLength);
5892 p.channel = ar->arChannelHint;
5893 p.networkType = ar->arNetworkType;
5894
5895 p.dot11AuthMode = ar->arDot11AuthMode;
5896 p.authMode = ar->arAuthMode;
5897 p.pairwiseCryptoType = ar->arPairwiseCrypto;
5898 p.pairwiseCryptoLen = ar->arPairwiseCryptoLen;
5899 p.groupCryptoType = ar->arGroupCrypto;
5900 p.groupCryptoLen = ar->arGroupCryptoLen;
5901 p.ctrl_flags = ar->arConnectCtrlFlags;
5902
5903 wmi_ap_profile_commit(ar->arWmi, &p);
5904 spin_lock_irqsave(&ar->arLock, flags);
5905 ar->arConnected = true;
5906 netif_carrier_on(ar->arNetDev);
5907 spin_unlock_irqrestore(&ar->arLock, flags);
5908 ar->ap_profile_flag = 0;
5909 return 0;
5910}
5911
5912int
5913ar6000_connect_to_ap(struct ar6_softc *ar)
5914{
5915 /* The ssid length check prevents second "essid off" from the user,
5916 to be treated as a connect cmd. The second "essid off" is ignored.
5917 */
5918 if((ar->arWmiReady == true) && (ar->arSsidLen > 0) && ar->arNetworkType!=AP_NETWORK)
5919 {
5920 int status;
5921 if((ADHOC_NETWORK != ar->arNetworkType) &&
5922 (NONE_AUTH==ar->arAuthMode) &&
5923 (WEP_CRYPT==ar->arPairwiseCrypto)) {
5924 ar6000_install_static_wep_keys(ar);
5925 }
5926
5927 if (!ar->arUserBssFilter) {
5928 if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) {
5929 return -EIO;
5930 }
5931 }
5932#ifdef WAPI_ENABLE
5933 if (ar->arWapiEnable) {
5934 ar->arPairwiseCrypto = WAPI_CRYPT;
5935 ar->arPairwiseCryptoLen = 0;
5936 ar->arGroupCrypto = WAPI_CRYPT;
5937 ar->arGroupCryptoLen = 0;
5938 ar->arAuthMode = NONE_AUTH;
5939 ar->arConnectCtrlFlags |= CONNECT_IGNORE_WPAx_GROUP_CIPHER;
5940 }
5941#endif
5942 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Connect called with authmode %d dot11 auth %d"\
5943 " PW crypto %d PW crypto Len %d GRP crypto %d"\
5944 " GRP crypto Len %d\n",
5945 ar->arAuthMode, ar->arDot11AuthMode,
5946 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
5947 ar->arGroupCrypto, ar->arGroupCryptoLen));
5948 reconnect_flag = 0;
5949 /* Set the listen interval into 1000TUs or more. This value will be indicated to Ap in the conn.
5950 later set it back locally at the STA to 100/1000 TUs depending on the power mode */
5951 if ((ar->arNetworkType == INFRA_NETWORK)) {
5952 wmi_listeninterval_cmd(ar->arWmi, max(ar->arListenIntervalT, (u16)A_MAX_WOW_LISTEN_INTERVAL), 0);
5953 }
5954 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
5955 ar->arDot11AuthMode, ar->arAuthMode,
5956 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
5957 ar->arGroupCrypto,ar->arGroupCryptoLen,
5958 ar->arSsidLen, ar->arSsid,
5959 ar->arReqBssid, ar->arChannelHint,
5960 ar->arConnectCtrlFlags);
5961 if (status) {
5962 wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
5963 if (!ar->arUserBssFilter) {
5964 wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
5965 }
5966 return status;
5967 }
5968
5969 if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
5970 ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
5971 {
5972 A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
5973 }
5974
5975 ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
5976
5977 ar->arConnectPending = true;
5978 return status;
5979 }
5980 return A_ERROR;
5981}
5982
5983int
5984ar6000_disconnect(struct ar6_softc *ar)
5985{
5986 if ((ar->arConnected == true) || (ar->arConnectPending == true)) {
5987 wmi_disconnect_cmd(ar->arWmi);
5988 /*
5989 * Disconnect cmd is issued, clear connectPending.
5990 * arConnected will be cleard in disconnect_event notification.
5991 */
5992 ar->arConnectPending = false;
5993 }
5994
5995 return 0;
5996}
5997
5998int
5999ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie)
6000{
6001 sta_t *conn = NULL;
6002 conn = ieee80211_find_conn(ar, wpaie->wpa_macaddr);
6003
6004 A_MEMZERO(wpaie->wpa_ie, IEEE80211_MAX_IE);
6005 A_MEMZERO(wpaie->rsn_ie, IEEE80211_MAX_IE);
6006
6007 if(conn) {
6008 memcpy(wpaie->wpa_ie, conn->wpa_ie, IEEE80211_MAX_IE);
6009 }
6010
6011 return 0;
6012}
6013
6014int
6015is_iwioctl_allowed(u8 mode, u16 cmd)
6016{
6017 if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) {
6018 cmd -= SIOCSIWCOMMIT;
6019 if(sioctl_filter[cmd] == 0xFF) return 0;
6020 if(sioctl_filter[cmd] & mode) return 0;
6021 } else if(cmd >= SIOCIWFIRSTPRIV && cmd <= (SIOCIWFIRSTPRIV+30)) {
6022 cmd -= SIOCIWFIRSTPRIV;
6023 if(pioctl_filter[cmd] == 0xFF) return 0;
6024 if(pioctl_filter[cmd] & mode) return 0;
6025 } else {
6026 return A_ERROR;
6027 }
6028 return A_ENOTSUP;
6029}
6030
6031int
6032is_xioctl_allowed(u8 mode, int cmd)
6033{
6034 if(sizeof(xioctl_filter)-1 < cmd) {
6035 A_PRINTF("Filter for this cmd=%d not defined\n",cmd);
6036 return 0;
6037 }
6038 if(xioctl_filter[cmd] == 0xFF) return 0;
6039 if(xioctl_filter[cmd] & mode) return 0;
6040 return A_ERROR;
6041}
6042
6043#ifdef WAPI_ENABLE
6044int
6045ap_set_wapi_key(struct ar6_softc *ar, void *ikey)
6046{
6047 struct ieee80211req_key *ik = (struct ieee80211req_key *)ikey;
6048 KEY_USAGE keyUsage = 0;
6049 int status;
6050
6051 if (memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) {
6052 keyUsage = GROUP_USAGE;
6053 } else {
6054 keyUsage = PAIRWISE_USAGE;
6055 }
6056 A_PRINTF("WAPI_KEY: Type:%d ix:%d mac:%02x:%02x len:%d\n",
6057 keyUsage, ik->ik_keyix, ik->ik_macaddr[4], ik->ik_macaddr[5],
6058 ik->ik_keylen);
6059
6060 status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, WAPI_CRYPT, keyUsage,
6061 ik->ik_keylen, (u8 *)&ik->ik_keyrsc,
6062 ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
6063 SYNC_BOTH_WMIFLAG);
6064
6065 if (0 != status) {
6066 return -EIO;
6067 }
6068 return 0;
6069}
6070#endif
6071
6072void ar6000_peer_event(
6073 void *context,
6074 u8 eventCode,
6075 u8 *macAddr)
6076{
6077 u8 pos;
6078
6079 for (pos=0;pos<6;pos++)
6080 printk("%02x: ",*(macAddr+pos));
6081 printk("\n");
6082}
6083
6084#ifdef HTC_TEST_SEND_PKTS
6085#define HTC_TEST_DUPLICATE 8
6086static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *dupskb)
6087{
6088 struct ar_cookie *cookie;
6089 struct ar_cookie *cookieArray[HTC_TEST_DUPLICATE];
6090 struct sk_buff *new_skb;
6091 int i;
6092 int pkts = 0;
6093 struct htc_packet_queue pktQueue;
6094 EPPING_HEADER *eppingHdr;
6095
6096 eppingHdr = A_NETBUF_DATA(dupskb);
6097
6098 if (eppingHdr->Cmd_h == EPPING_CMD_NO_ECHO) {
6099 /* skip test if this is already a tx perf test */
6100 return;
6101 }
6102
6103 for (i = 0; i < HTC_TEST_DUPLICATE; i++,pkts++) {
6104 AR6000_SPIN_LOCK(&ar->arLock, 0);
6105 cookie = ar6000_alloc_cookie(ar);
6106 if (cookie != NULL) {
6107 ar->arTxPending[eid]++;
6108 ar->arTotalTxDataPending++;
6109 }
6110
6111 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
6112
6113 if (NULL == cookie) {
6114 break;
6115 }
6116
6117 new_skb = A_NETBUF_ALLOC(A_NETBUF_LEN(dupskb));
6118
6119 if (new_skb == NULL) {
6120 AR6000_SPIN_LOCK(&ar->arLock, 0);
6121 ar6000_free_cookie(ar,cookie);
6122 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
6123 break;
6124 }
6125
6126 A_NETBUF_PUT_DATA(new_skb, A_NETBUF_DATA(dupskb), A_NETBUF_LEN(dupskb));
6127 cookie->arc_bp[0] = (unsigned long)new_skb;
6128 cookie->arc_bp[1] = MapNo;
6129 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
6130 cookie,
6131 A_NETBUF_DATA(new_skb),
6132 A_NETBUF_LEN(new_skb),
6133 eid,
6134 AR6K_DATA_PKT_TAG);
6135
6136 cookieArray[i] = cookie;
6137
6138 {
6139 EPPING_HEADER *pHdr = (EPPING_HEADER *)A_NETBUF_DATA(new_skb);
6140 pHdr->Cmd_h = EPPING_CMD_NO_ECHO; /* do not echo the packet */
6141 }
6142 }
6143
6144 if (pkts == 0) {
6145 return;
6146 }
6147
6148 INIT_HTC_PACKET_QUEUE(&pktQueue);
6149
6150 for (i = 0; i < pkts; i++) {
6151 HTC_PACKET_ENQUEUE(&pktQueue,&cookieArray[i]->HtcPkt);
6152 }
6153
6154 HTCSendPktsMultiple(ar->arHtcTarget, &pktQueue);
6155
6156}
6157#endif
6158
6159#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
6160/*
6161 * Add support for adding and removing a virtual adapter for soft AP.
6162 * Some OS requires different adapters names for station and soft AP mode.
6163 * To support these requirement, create and destroy a netdevice instance
6164 * when the AP mode is operational. A full fledged support for virual device
6165 * is not implemented. Rather a virtual interface is created and is linked
6166 * with the existing physical device instance during the operation of the
6167 * AP mode.
6168 */
6169
6170int ar6000_start_ap_interface(struct ar6_softc *ar)
6171{
6172 struct ar_virtual_interface *arApDev;
6173
6174 /* Change net_device to point to AP instance */
6175 arApDev = (struct ar_virtual_interface *)ar->arApDev;
6176 ar->arNetDev = arApDev->arNetDev;
6177
6178 return 0;
6179}
6180
6181int ar6000_stop_ap_interface(struct ar6_softc *ar)
6182{
6183 struct ar_virtual_interface *arApDev;
6184
6185 /* Change net_device to point to sta instance */
6186 arApDev = (struct ar_virtual_interface *)ar->arApDev;
6187 if (arApDev) {
6188 ar->arNetDev = arApDev->arStaNetDev;
6189 }
6190
6191 return 0;
6192}
6193
6194
6195int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname)
6196{
6197 struct net_device *dev;
6198 struct ar_virtual_interface *arApDev;
6199
6200 dev = alloc_etherdev(sizeof(struct ar_virtual_interface));
6201 if (dev == NULL) {
6202 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: can't alloc etherdev\n"));
6203 return A_ERROR;
6204 }
6205
6206 ether_setup(dev);
6207 init_netdev(dev, ap_ifname);
6208 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
6209
6210 if (register_netdev(dev)) {
6211 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n"));
6212 return A_ERROR;
6213 }
6214
6215 arApDev = netdev_priv(dev);
6216 arApDev->arDev = ar;
6217 arApDev->arNetDev = dev;
6218 arApDev->arStaNetDev = ar->arNetDev;
6219
6220 ar->arApDev = arApDev;
6221 arApNetDev = dev;
6222
6223 /* Copy the MAC address */
6224 memcpy(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN);
6225
6226 return 0;
6227}
6228
6229int ar6000_add_ap_interface(struct ar6_softc *ar, char *ap_ifname)
6230{
6231 /* Interface already added, need not proceed further */
6232 if (ar->arApDev != NULL) {
6233 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_add_ap_interface: interface already present \n"));
6234 return 0;
6235 }
6236
6237 if (ar6000_create_ap_interface(ar, ap_ifname) != 0) {
6238 return A_ERROR;
6239 }
6240
6241 A_PRINTF("Add AP interface %s \n",ap_ifname);
6242
6243 return ar6000_start_ap_interface(ar);
6244}
6245
6246int ar6000_remove_ap_interface(struct ar6_softc *ar)
6247{
6248 if (arApNetDev) {
6249 ar6000_stop_ap_interface(ar);
6250
6251 unregister_netdev(arApNetDev);
6252 free_netdev(apApNetDev);
6253
6254 A_PRINTF("Remove AP interface\n");
6255 }
6256 ar->arApDev = NULL;
6257 arApNetDev = NULL;
6258
6259
6260 return 0;
6261}
6262#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
6263
6264
6265#ifdef EXPORT_HCI_BRIDGE_INTERFACE
6266EXPORT_SYMBOL(setupbtdev);
6267#endif
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c
new file mode 100644
index 00000000000..1e0ace8b6d1
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c
@@ -0,0 +1,626 @@
1/*
2 *
3 * Copyright (c) 2004-2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7//
8// Permission to use, copy, modify, and/or distribute this software for any
9// purpose with or without fee is hereby granted, provided that the above
10// copyright notice and this permission notice appear in all copies.
11//
12// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19//
20//
21 *
22 */
23
24/*
25 * Implementation of system power management
26 */
27
28#include "ar6000_drv.h"
29#include <linux/inetdevice.h>
30#include <linux/platform_device.h>
31#include "wlan_config.h"
32
33#define WOW_ENABLE_MAX_INTERVAL 0
34#define WOW_SET_SCAN_PARAMS 0
35
36extern unsigned int wmitimeout;
37extern wait_queue_head_t arEvent;
38
39#undef ATH_MODULE_NAME
40#define ATH_MODULE_NAME pm
41#define ATH_DEBUG_PM ATH_DEBUG_MAKE_MODULE_MASK(0)
42
43#ifdef DEBUG
44static struct ath_debug_mask_description pm_debug_desc[] = {
45 { ATH_DEBUG_PM , "System power management"},
46};
47
48ATH_DEBUG_INSTANTIATE_MODULE_VAR(pm,
49 "pm",
50 "System Power Management",
51 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_PM,
52 ATH_DEBUG_DESCRIPTION_COUNT(pm_debug_desc),
53 pm_debug_desc);
54
55#endif /* DEBUG */
56
57int ar6000_exit_cut_power_state(struct ar6_softc *ar);
58
59#ifdef CONFIG_PM
60static void ar6k_send_asleep_event_to_app(struct ar6_softc *ar, bool asleep)
61{
62 char buf[128];
63 union iwreq_data wrqu;
64
65 snprintf(buf, sizeof(buf), "HOST_ASLEEP=%s", asleep ? "asleep" : "awake");
66 A_MEMZERO(&wrqu, sizeof(wrqu));
67 wrqu.data.length = strlen(buf);
68 wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
69}
70
71static void ar6000_wow_resume(struct ar6_softc *ar)
72{
73 if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
74 u16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
75 u16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period;
76 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {true, false};
77 ar->arWowState = WLAN_WOW_STATE_NONE;
78 if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!= 0) {
79 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n"));
80 }
81#if WOW_SET_SCAN_PARAMS
82 wmi_scanparams_cmd(ar->arWmi, fg_start_period,
83 ar->scParams.fg_end_period,
84 bg_period,
85 ar->scParams.minact_chdwell_time,
86 ar->scParams.maxact_chdwell_time,
87 ar->scParams.pas_chdwell_time,
88 ar->scParams.shortScanRatio,
89 ar->scParams.scanCtrlFlags,
90 ar->scParams.max_dfsch_act_time,
91 ar->scParams.maxact_scan_per_ssid);
92#else
93 (void)fg_start_period;
94 (void)bg_period;
95#endif
96
97
98#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
99 if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == 0) {
100 }
101#endif
102 ar6k_send_asleep_event_to_app(ar, false);
103 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Resume WoW successfully\n"));
104 } else {
105 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WoW does not invoked. skip resume"));
106 }
107 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
108}
109
110static void ar6000_wow_suspend(struct ar6_softc *ar)
111{
112#define WOW_LIST_ID 1
113 if (ar->arNetworkType != AP_NETWORK) {
114 /* Setup WoW for unicast & Arp request for our own IP
115 disable background scan. Set listen interval into 1000 TUs
116 Enable keepliave for 110 seconds
117 */
118 struct in_ifaddr **ifap = NULL;
119 struct in_ifaddr *ifa = NULL;
120 struct in_device *in_dev;
121 u8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
122 int status;
123 WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } };
124 WMI_DEL_WOW_PATTERN_CMD delWowCmd;
125 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {false, true};
126 WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = true,
127 .hostReqDelay = 500 };/*500 ms delay*/
128
129 if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
130 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("System already go into wow mode!\n"));
131 return;
132 }
133
134 ar6000_TxDataCleanup(ar); /* IMPORTANT, otherwise there will be 11mA after listen interval as 1000*/
135
136#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
137 if (wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0) == 0) {
138 }
139#endif
140
141#if WOW_SET_SCAN_PARAMS
142 status = wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0xFFFF, 0, 0, 0, 0, 0, 0, 0);
143#endif
144 /* clear up our WoW pattern first */
145 delWowCmd.filter_list_id = WOW_LIST_ID;
146 delWowCmd.filter_id = 0;
147 wmi_del_wow_pattern_cmd(ar->arWmi, &delWowCmd);
148
149 /* setup unicast packet pattern for WoW */
150 if (ar->arNetDev->dev_addr[1]) {
151 addWowCmd.filter_list_id = WOW_LIST_ID;
152 addWowCmd.filter_size = 6; /* MAC address */
153 addWowCmd.filter_offset = 0;
154 status = wmi_add_wow_pattern_cmd(ar->arWmi, &addWowCmd, ar->arNetDev->dev_addr, macMask, addWowCmd.filter_size);
155 if (status) {
156 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to add WoW pattern\n"));
157 }
158 }
159 /* setup ARP request for our own IP */
160 if ((in_dev = __in_dev_get_rtnl(ar->arNetDev)) != NULL) {
161 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) {
162 if (!strcmp(ar->arNetDev->name, ifa->ifa_label)) {
163 break; /* found */
164 }
165 }
166 }
167 if (ifa && ifa->ifa_local) {
168 WMI_SET_IP_CMD ipCmd;
169 memset(&ipCmd, 0, sizeof(ipCmd));
170 ipCmd.ips[0] = ifa->ifa_local;
171 status = wmi_set_ip_cmd(ar->arWmi, &ipCmd);
172 if (status) {
173 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup IP for ARP agent\n"));
174 }
175 }
176
177#ifndef ATH6K_CONFIG_OTA_MODE
178 wmi_powermode_cmd(ar->arWmi, REC_POWER);
179#endif
180
181 status = wmi_set_wow_mode_cmd(ar->arWmi, &wowMode);
182 if (status) {
183 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enable wow mode\n"));
184 }
185 ar6k_send_asleep_event_to_app(ar, true);
186
187 status = wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode);
188 if (status) {
189 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to set host asleep\n"));
190 }
191
192 ar->arWowState = WLAN_WOW_STATE_SUSPENDING;
193 if (ar->arTxPending[ar->arControlEp]) {
194 u32 timeleft = wait_event_interruptible_timeout(arEvent,
195 ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
196 if (!timeleft || signal_pending(current)) {
197 /* what can I do? wow resume at once */
198 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WoW. Pending wmi control data %d\n", ar->arTxPending[ar->arControlEp]));
199 }
200 }
201
202 status = hifWaitForPendingRecv(ar->arHifDevice);
203
204 ar->arWowState = WLAN_WOW_STATE_SUSPENDED;
205 ar->arWlanPowerState = WLAN_POWER_STATE_WOW;
206 } else {
207 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Not allowed to go to WOW at this moment.\n"));
208 }
209}
210
211int ar6000_suspend_ev(void *context)
212{
213 int status = 0;
214 struct ar6_softc *ar = (struct ar6_softc *)context;
215 s16 pmmode = ar->arSuspendConfig;
216wow_not_connected:
217 switch (pmmode) {
218 case WLAN_SUSPEND_WOW:
219 if (ar->arWmiReady && ar->arWlanState==WLAN_ENABLED && ar->arConnected) {
220 ar6000_wow_suspend(ar);
221 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for wow mode %d\n", __func__, ar->arWlanPowerState));
222 } else {
223 pmmode = ar->arWow2Config;
224 goto wow_not_connected;
225 }
226 break;
227 case WLAN_SUSPEND_CUT_PWR:
228 /* fall through */
229 case WLAN_SUSPEND_CUT_PWR_IF_BT_OFF:
230 /* fall through */
231 case WLAN_SUSPEND_DEEP_SLEEP:
232 /* fall through */
233 default:
234 status = ar6000_update_wlan_pwr_state(ar, WLAN_DISABLED, true);
235 if (ar->arWlanPowerState==WLAN_POWER_STATE_ON ||
236 ar->arWlanPowerState==WLAN_POWER_STATE_WOW) {
237 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Strange suspend state for not wow mode %d", ar->arWlanPowerState));
238 }
239 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for %d mode pwr %d status %d\n", __func__, pmmode, ar->arWlanPowerState, status));
240 status = (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) ? 0 : A_EBUSY;
241 break;
242 }
243
244 ar->scan_triggered = 0;
245 return status;
246}
247
248int ar6000_resume_ev(void *context)
249{
250 struct ar6_softc *ar = (struct ar6_softc *)context;
251 u16 powerState = ar->arWlanPowerState;
252
253 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: enter previous state %d wowState %d\n", __func__, powerState, ar->arWowState));
254 switch (powerState) {
255 case WLAN_POWER_STATE_WOW:
256 ar6000_wow_resume(ar);
257 break;
258 case WLAN_POWER_STATE_CUT_PWR:
259 /* fall through */
260 case WLAN_POWER_STATE_DEEP_SLEEP:
261 ar6000_update_wlan_pwr_state(ar, WLAN_ENABLED, true);
262 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Resume for %d mode pwr %d\n", __func__, powerState, ar->arWlanPowerState));
263 break;
264 case WLAN_POWER_STATE_ON:
265 break;
266 default:
267 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange SDIO bus power mode!!\n"));
268 break;
269 }
270 return 0;
271}
272
273void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent)
274{
275 if (ar->arWowState!=WLAN_WOW_STATE_NONE) {
276 if (ar->arWowState==WLAN_WOW_STATE_SUSPENDING) {
277 AR_DEBUG_PRINTF(ATH_DEBUG_PM,("\n%s: Received IRQ while we are wow suspending!!!\n\n", __func__));
278 return;
279 }
280 /* Wow resume from irq interrupt */
281 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: WoW resume from irq thread status %d\n", __func__, ar->arWlanPowerState));
282 ar6000_wow_resume(ar);
283 }
284}
285
286int ar6000_power_change_ev(void *context, u32 config)
287{
288 struct ar6_softc *ar = (struct ar6_softc *)context;
289 int status = 0;
290
291 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: power change event callback %d \n", __func__, config));
292 switch (config) {
293 case HIF_DEVICE_POWER_UP:
294 ar6000_restart_endpoint(ar->arNetDev);
295 status = 0;
296 break;
297 case HIF_DEVICE_POWER_DOWN:
298 case HIF_DEVICE_POWER_CUT:
299 status = 0;
300 break;
301 }
302 return status;
303}
304
305#endif /* CONFIG_PM */
306
307int
308ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
309{
310 int status = 0;
311 HIF_DEVICE_POWER_CHANGE_TYPE config;
312
313 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Cut power %d %d \n", __func__,state, ar->arWlanPowerState));
314#ifdef CONFIG_PM
315 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
316#endif
317 do {
318 if (state == WLAN_ENABLED) {
319 /* Not in cut power state.. exit */
320 if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
321 break;
322 }
323
324 /* Change the state to ON */
325 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
326
327
328 /* Indicate POWER_UP to HIF */
329 config = HIF_DEVICE_POWER_UP;
330 status = HIFConfigureDevice(ar->arHifDevice,
331 HIF_DEVICE_POWER_STATE_CHANGE,
332 &config,
333 sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
334
335 if (status == A_PENDING) {
336 } else if (status == 0) {
337 ar6000_restart_endpoint(ar->arNetDev);
338 status = 0;
339 }
340 } else if (state == WLAN_DISABLED) {
341
342
343 /* Already in cut power state.. exit */
344 if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
345 break;
346 }
347 ar6000_stop_endpoint(ar->arNetDev, true, false);
348
349 config = HIF_DEVICE_POWER_CUT;
350 status = HIFConfigureDevice(ar->arHifDevice,
351 HIF_DEVICE_POWER_STATE_CHANGE,
352 &config,
353 sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
354
355 ar->arWlanPowerState = WLAN_POWER_STATE_CUT_PWR;
356 }
357 } while (0);
358
359 return status;
360}
361
362int
363ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
364{
365 int status = 0;
366
367 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Deep sleep %d %d \n", __func__,state, ar->arWlanPowerState));
368#ifdef CONFIG_PM
369 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
370#endif
371 do {
372 WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode;
373
374 if (state == WLAN_ENABLED) {
375 u16 fg_start_period;
376
377 /* Not in deep sleep state.. exit */
378 if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
379 if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
380 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we resume from deep sleep %d\n", ar->arWlanPowerState));
381 }
382 break;
383 }
384
385 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
386 hostSleepMode.awake = true;
387 hostSleepMode.asleep = false;
388
389 if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != 0) {
390 break;
391 }
392
393 /* Change the state to ON */
394 ar->arWlanPowerState = WLAN_POWER_STATE_ON;
395
396 /* Enable foreground scanning */
397 if ((status=wmi_scanparams_cmd(ar->arWmi, fg_start_period,
398 ar->scParams.fg_end_period,
399 ar->scParams.bg_period,
400 ar->scParams.minact_chdwell_time,
401 ar->scParams.maxact_chdwell_time,
402 ar->scParams.pas_chdwell_time,
403 ar->scParams.shortScanRatio,
404 ar->scParams.scanCtrlFlags,
405 ar->scParams.max_dfsch_act_time,
406 ar->scParams.maxact_scan_per_ssid)) != 0)
407 {
408 break;
409 }
410
411 if (ar->arNetworkType != AP_NETWORK)
412 {
413 if (ar->arSsidLen) {
414 if (ar6000_connect_to_ap(ar) != 0) {
415 /* no need to report error if connection failed */
416 break;
417 }
418 }
419 }
420 } else if (state == WLAN_DISABLED){
421 WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = false };
422
423 /* Already in deep sleep state.. exit */
424 if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
425 if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
426 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we suspend for deep sleep %d\n", ar->arWlanPowerState));
427 }
428 break;
429 }
430
431 if (ar->arNetworkType != AP_NETWORK)
432 {
433 /* Disconnect from the AP and disable foreground scanning */
434 AR6000_SPIN_LOCK(&ar->arLock, 0);
435 if (ar->arConnected == true || ar->arConnectPending == true) {
436 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
437 wmi_disconnect_cmd(ar->arWmi);
438 } else {
439 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
440 }
441 }
442
443 ar->scan_triggered = 0;
444
445 if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != 0) {
446 break;
447 }
448
449 /* make sure we disable wow for deep sleep */
450 if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!= 0)
451 {
452 break;
453 }
454
455 ar6000_TxDataCleanup(ar);
456#ifndef ATH6K_CONFIG_OTA_MODE
457 wmi_powermode_cmd(ar->arWmi, REC_POWER);
458#endif
459
460 hostSleepMode.awake = false;
461 hostSleepMode.asleep = true;
462 if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!= 0) {
463 break;
464 }
465 if (ar->arTxPending[ar->arControlEp]) {
466 u32 timeleft = wait_event_interruptible_timeout(arEvent,
467 ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
468 if (!timeleft || signal_pending(current)) {
469 status = A_ERROR;
470 break;
471 }
472 }
473 status = hifWaitForPendingRecv(ar->arHifDevice);
474
475 ar->arWlanPowerState = WLAN_POWER_STATE_DEEP_SLEEP;
476 }
477 } while (0);
478
479 if (status) {
480 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enter/exit deep sleep %d\n", state));
481 }
482
483 return status;
484}
485
486int
487ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool pmEvent)
488{
489 int status = 0;
490 u16 powerState, oldPowerState;
491 AR6000_WLAN_STATE oldstate = ar->arWlanState;
492 bool wlanOff = ar->arWlanOff;
493#ifdef CONFIG_PM
494 bool btOff = ar->arBTOff;
495#endif /* CONFIG_PM */
496
497 if ((state!=WLAN_DISABLED && state!=WLAN_ENABLED)) {
498 return A_ERROR;
499 }
500
501 if (ar->bIsDestroyProgress) {
502 return A_EBUSY;
503 }
504
505 if (down_interruptible(&ar->arSem)) {
506 return A_ERROR;
507 }
508
509 if (ar->bIsDestroyProgress) {
510 up(&ar->arSem);
511 return A_EBUSY;
512 }
513
514 ar->arWlanState = wlanOff ? WLAN_DISABLED : state;
515 oldPowerState = ar->arWlanPowerState;
516 if (state == WLAN_ENABLED) {
517 powerState = ar->arWlanPowerState;
518 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to ENABLE^^\n"));
519 if (!wlanOff) {
520 if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
521 status = ar6000_setup_deep_sleep_state(ar, WLAN_ENABLED);
522 } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
523 status = ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
524 }
525 }
526#ifdef CONFIG_PM
527 else if (pmEvent && wlanOff) {
528 bool allowCutPwr = ((!ar->arBTSharing) || btOff);
529 if ((powerState==WLAN_POWER_STATE_CUT_PWR) && (!allowCutPwr)) {
530 /* Come out of cut power */
531 ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
532 status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
533 }
534 }
535#endif /* CONFIG_PM */
536 } else if (state == WLAN_DISABLED) {
537 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to DISABLED~\n"));
538 powerState = WLAN_POWER_STATE_DEEP_SLEEP;
539#ifdef CONFIG_PM
540 if (pmEvent) { /* disable due to suspend */
541 bool suspendCutPwr = (ar->arSuspendConfig == WLAN_SUSPEND_CUT_PWR ||
542 (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
543 ar->arWow2Config==WLAN_SUSPEND_CUT_PWR));
544 bool suspendCutIfBtOff = ((ar->arSuspendConfig ==
545 WLAN_SUSPEND_CUT_PWR_IF_BT_OFF ||
546 (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
547 ar->arWow2Config==WLAN_SUSPEND_CUT_PWR_IF_BT_OFF)) &&
548 (!ar->arBTSharing || btOff));
549 if ((suspendCutPwr) ||
550 (suspendCutIfBtOff) ||
551 (ar->arWlanState==WLAN_POWER_STATE_CUT_PWR))
552 {
553 powerState = WLAN_POWER_STATE_CUT_PWR;
554 }
555 } else {
556 if ((wlanOff) &&
557 (ar->arWlanOffConfig == WLAN_OFF_CUT_PWR) &&
558 (!ar->arBTSharing || btOff))
559 {
560 /* For BT clock sharing designs, CUT_POWER depend on BT state */
561 powerState = WLAN_POWER_STATE_CUT_PWR;
562 }
563 }
564#endif /* CONFIG_PM */
565
566 if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
567 if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
568 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Load firmware before set to deep sleep\n"));
569 ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
570 }
571 status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
572 } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
573 status = ar6000_setup_cut_power_state(ar, WLAN_DISABLED);
574 }
575
576 }
577
578 if (status) {
579 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WLAN state %d\n", ar->arWlanState));
580 ar->arWlanState = oldstate;
581 } else if (status == 0) {
582 WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent, *pSleepEvent = NULL;
583 if ((ar->arWlanPowerState == WLAN_POWER_STATE_ON) && (oldPowerState != WLAN_POWER_STATE_ON)) {
584 wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE;
585 pSleepEvent = &wmiSleepEvent;
586 } else if ((ar->arWlanPowerState != WLAN_POWER_STATE_ON) && (oldPowerState == WLAN_POWER_STATE_ON)) {
587 wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP;
588 pSleepEvent = &wmiSleepEvent;
589 }
590 if (pSleepEvent) {
591 AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("SENT WLAN Sleep Event %d\n", wmiSleepEvent.sleepState));
592 }
593 }
594 up(&ar->arSem);
595 return status;
596}
597
598int
599ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 enable)
600{
601#ifdef CONFIG_PM
602 bool off = (enable == 0);
603 int status;
604 if (ar->arBTOff == off) {
605 return 0;
606 }
607 ar->arBTOff = off;
608 status = ar6000_update_wlan_pwr_state(ar, ar->arWlanOff ? WLAN_DISABLED : WLAN_ENABLED, false);
609 return status;
610#else
611 return 0;
612#endif
613}
614
615int
616ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
617{
618 int status;
619 bool off = (state == WLAN_DISABLED);
620 if (ar->arWlanOff == off) {
621 return 0;
622 }
623 ar->arWlanOff = off;
624 status = ar6000_update_wlan_pwr_state(ar, state, false);
625 return status;
626}
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c
new file mode 100644
index 00000000000..ae7c1dd96d8
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c
@@ -0,0 +1,455 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#include "ar6000_drv.h"
25
26#ifdef HTC_RAW_INTERFACE
27
28static void
29ar6000_htc_raw_read_cb(void *Context, struct htc_packet *pPacket)
30{
31 struct ar6_softc *ar = (struct ar6_softc *)Context;
32 raw_htc_buffer *busy;
33 HTC_RAW_STREAM_ID streamID;
34 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
35
36 busy = (raw_htc_buffer *)pPacket->pPktContext;
37 A_ASSERT(busy != NULL);
38
39 if (pPacket->Status == A_ECANCELED) {
40 /*
41 * HTC provides A_ECANCELED status when it doesn't want to be refilled
42 * (probably due to a shutdown)
43 */
44 return;
45 }
46
47 streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
48 A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
49
50#ifdef CF
51 if (down_trylock(&arRaw->raw_htc_read_sem[streamID])) {
52#else
53 if (down_interruptible(&arRaw->raw_htc_read_sem[streamID])) {
54#endif /* CF */
55 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
56 }
57
58 A_ASSERT((pPacket->Status != 0) ||
59 (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN)));
60
61 busy->length = pPacket->ActualLength + HTC_HEADER_LEN;
62 busy->currPtr = HTC_HEADER_LEN;
63 arRaw->read_buffer_available[streamID] = true;
64 //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb: 0x%X 0x%X \n", busy->currPtr,busy->length);
65 up(&arRaw->raw_htc_read_sem[streamID]);
66
67 /* Signal the waiting process */
68 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) read process\n", streamID));
69 wake_up_interruptible(&arRaw->raw_htc_read_queue[streamID]);
70}
71
72static void
73ar6000_htc_raw_write_cb(void *Context, struct htc_packet *pPacket)
74{
75 struct ar6_softc *ar = (struct ar6_softc *)Context;
76 raw_htc_buffer *free;
77 HTC_RAW_STREAM_ID streamID;
78 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
79
80 free = (raw_htc_buffer *)pPacket->pPktContext;
81 A_ASSERT(free != NULL);
82
83 if (pPacket->Status == A_ECANCELED) {
84 /*
85 * HTC provides A_ECANCELED status when it doesn't want to be refilled
86 * (probably due to a shutdown)
87 */
88 return;
89 }
90
91 streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
92 A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
93
94#ifdef CF
95 if (down_trylock(&arRaw->raw_htc_write_sem[streamID])) {
96#else
97 if (down_interruptible(&arRaw->raw_htc_write_sem[streamID])) {
98#endif
99 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
100 }
101
102 A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN));
103
104 free->length = 0;
105 arRaw->write_buffer_available[streamID] = true;
106 up(&arRaw->raw_htc_write_sem[streamID]);
107
108 /* Signal the waiting process */
109 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) write process\n", streamID));
110 wake_up_interruptible(&arRaw->raw_htc_write_queue[streamID]);
111}
112
113/* connect to a service */
114static int ar6000_connect_raw_service(struct ar6_softc *ar,
115 HTC_RAW_STREAM_ID StreamID)
116{
117 int status;
118 struct htc_service_connect_resp response;
119 u8 streamNo;
120 struct htc_service_connect_req connect;
121
122 do {
123
124 A_MEMZERO(&connect,sizeof(connect));
125 /* pass the stream ID as meta data to the RAW streams service */
126 streamNo = (u8)StreamID;
127 connect.pMetaData = &streamNo;
128 connect.MetaDataLength = sizeof(u8);
129 /* these fields are the same for all endpoints */
130 connect.EpCallbacks.pContext = ar;
131 connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb;
132 connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb;
133 /* simple interface, we don't need these optional callbacks */
134 connect.EpCallbacks.EpRecvRefill = NULL;
135 connect.EpCallbacks.EpSendFull = NULL;
136 connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM;
137
138 /* connect to the raw streams service, we may be able to get 1 or more
139 * connections, depending on WHAT is running on the target */
140 connect.ServiceID = HTC_RAW_STREAMS_SVC;
141
142 A_MEMZERO(&response,sizeof(response));
143
144 /* try to connect to the raw stream, it is okay if this fails with
145 * status HTC_SERVICE_NO_MORE_EP */
146 status = HTCConnectService(ar->arHtcTarget,
147 &connect,
148 &response);
149
150 if (status) {
151 if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) {
152 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n"));
153 status = 0;
154 }
155 break;
156 }
157
158 /* set endpoint mapping for the RAW HTC streams */
159 arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint);
160
161 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n",
162 StreamID, arRawStream2EndpointID(ar,StreamID)));
163
164 } while (false);
165
166 return status;
167}
168
169int ar6000_htc_raw_open(struct ar6_softc *ar)
170{
171 int status;
172 int streamID, endPt, count2;
173 raw_htc_buffer *buffer;
174 HTC_SERVICE_ID servicepriority;
175 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
176 if (!arRaw) {
177 arRaw = ar->arRawHtc = A_MALLOC(sizeof(AR_RAW_HTC_T));
178 if (arRaw) {
179 A_MEMZERO(arRaw, sizeof(AR_RAW_HTC_T));
180 }
181 }
182 A_ASSERT(ar->arHtcTarget != NULL);
183 if (!arRaw) {
184 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Faile to allocate memory for HTC RAW interface\n"));
185 return -ENOMEM;
186 }
187 /* wait for target */
188 status = HTCWaitTarget(ar->arHtcTarget);
189
190 if (status) {
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status));
192 return -ENODEV;
193 }
194
195 for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) {
196 arRaw->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED;
197 }
198
199 for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) {
200 /* Initialize the data structures */
201 sema_init(&arRaw->raw_htc_read_sem[streamID], 1);
202 sema_init(&arRaw->raw_htc_write_sem[streamID], 1);
203 init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]);
204 init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]);
205
206 /* try to connect to the raw service */
207 status = ar6000_connect_raw_service(ar,streamID);
208
209 if (status) {
210 break;
211 }
212
213 if (arRawStream2EndpointID(ar,streamID) == 0) {
214 break;
215 }
216
217 for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) {
218 /* Initialize the receive buffers */
219 buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
220 memset(buffer, 0, sizeof(raw_htc_buffer));
221 buffer = &arRaw->raw_htc_read_buffer[streamID][count2];
222 memset(buffer, 0, sizeof(raw_htc_buffer));
223
224 SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket,
225 buffer,
226 buffer->data,
227 HTC_RAW_BUFFER_SIZE,
228 arRawStream2EndpointID(ar,streamID));
229
230 /* Queue buffers to HTC for receive */
231 if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != 0)
232 {
233 BMIInit();
234 return -EIO;
235 }
236 }
237
238 for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) {
239 /* Initialize the receive buffers */
240 buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
241 memset(buffer, 0, sizeof(raw_htc_buffer));
242 }
243
244 arRaw->read_buffer_available[streamID] = false;
245 arRaw->write_buffer_available[streamID] = true;
246 }
247
248 if (status) {
249 return -EIO;
250 }
251
252 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HTC RAW, number of streams the target supports: %d \n", streamID));
253
254 servicepriority = HTC_RAW_STREAMS_SVC; /* only 1 */
255
256 /* set callbacks and priority list */
257 HTCSetCreditDistribution(ar->arHtcTarget,
258 ar,
259 NULL, /* use default */
260 NULL, /* use default */
261 &servicepriority,
262 1);
263
264 /* Start the HTC component */
265 if ((status = HTCStart(ar->arHtcTarget)) != 0) {
266 BMIInit();
267 return -EIO;
268 }
269
270 (ar)->arRawIfInit = true;
271
272 return 0;
273}
274
275int ar6000_htc_raw_close(struct ar6_softc *ar)
276{
277 A_PRINTF("ar6000_htc_raw_close called \n");
278 HTCStop(ar->arHtcTarget);
279
280 /* reset the device */
281 ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, false);
282 /* Initialize the BMI component */
283 BMIInit();
284
285 return 0;
286}
287
288raw_htc_buffer *
289get_filled_buffer(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID)
290{
291 int count;
292 raw_htc_buffer *busy;
293 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
294
295 /* Check for data */
296 for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) {
297 busy = &arRaw->raw_htc_read_buffer[StreamID][count];
298 if (busy->length) {
299 break;
300 }
301 }
302 if (busy->length) {
303 arRaw->read_buffer_available[StreamID] = true;
304 } else {
305 arRaw->read_buffer_available[StreamID] = false;
306 }
307
308 return busy;
309}
310
311ssize_t ar6000_htc_raw_read(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID,
312 char __user *buffer, size_t length)
313{
314 int readPtr;
315 raw_htc_buffer *busy;
316 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
317
318 if (arRawStream2EndpointID(ar,StreamID) == 0) {
319 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
320 return -EFAULT;
321 }
322
323 if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
324 return -ERESTARTSYS;
325 }
326
327 busy = get_filled_buffer(ar,StreamID);
328 while (!arRaw->read_buffer_available[StreamID]) {
329 up(&arRaw->raw_htc_read_sem[StreamID]);
330
331 /* Wait for the data */
332 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) read process\n", StreamID));
333 if (wait_event_interruptible(arRaw->raw_htc_read_queue[StreamID],
334 arRaw->read_buffer_available[StreamID]))
335 {
336 return -EINTR;
337 }
338 if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
339 return -ERESTARTSYS;
340 }
341 busy = get_filled_buffer(ar,StreamID);
342 }
343
344 /* Read the data */
345 readPtr = busy->currPtr;
346 if (length > busy->length - HTC_HEADER_LEN) {
347 length = busy->length - HTC_HEADER_LEN;
348 }
349 if (copy_to_user(buffer, &busy->data[readPtr], length)) {
350 up(&arRaw->raw_htc_read_sem[StreamID]);
351 return -EFAULT;
352 }
353
354 busy->currPtr += length;
355
356 if (busy->currPtr == busy->length)
357 {
358 busy->currPtr = 0;
359 busy->length = 0;
360 HTC_PACKET_RESET_RX(&busy->HTCPacket);
361 //AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("raw read ioctl: ep for packet:%d \n", busy->HTCPacket.Endpoint));
362 HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket);
363 }
364 arRaw->read_buffer_available[StreamID] = false;
365 up(&arRaw->raw_htc_read_sem[StreamID]);
366
367 return length;
368}
369
370static raw_htc_buffer *
371get_free_buffer(struct ar6_softc *ar, HTC_ENDPOINT_ID StreamID)
372{
373 int count;
374 raw_htc_buffer *free;
375 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
376
377 free = NULL;
378 for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) {
379 free = &arRaw->raw_htc_write_buffer[StreamID][count];
380 if (free->length == 0) {
381 break;
382 }
383 }
384 if (!free->length) {
385 arRaw->write_buffer_available[StreamID] = true;
386 } else {
387 arRaw->write_buffer_available[StreamID] = false;
388 }
389
390 return free;
391}
392
393ssize_t ar6000_htc_raw_write(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID,
394 char __user *buffer, size_t length)
395{
396 int writePtr;
397 raw_htc_buffer *free;
398 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
399 if (arRawStream2EndpointID(ar,StreamID) == 0) {
400 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
401 return -EFAULT;
402 }
403
404 if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
405 return -ERESTARTSYS;
406 }
407
408 /* Search for a free buffer */
409 free = get_free_buffer(ar,StreamID);
410
411 /* Check if there is space to write else wait */
412 while (!arRaw->write_buffer_available[StreamID]) {
413 up(&arRaw->raw_htc_write_sem[StreamID]);
414
415 /* Wait for buffer to become free */
416 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) write process\n", StreamID));
417 if (wait_event_interruptible(arRaw->raw_htc_write_queue[StreamID],
418 arRaw->write_buffer_available[StreamID]))
419 {
420 return -EINTR;
421 }
422 if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
423 return -ERESTARTSYS;
424 }
425 free = get_free_buffer(ar,StreamID);
426 }
427
428 /* Send the data */
429 writePtr = HTC_HEADER_LEN;
430 if (length > (HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN)) {
431 length = HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN;
432 }
433
434 if (copy_from_user(&free->data[writePtr], buffer, length)) {
435 up(&arRaw->raw_htc_read_sem[StreamID]);
436 return -EFAULT;
437 }
438
439 free->length = length;
440
441 SET_HTC_PACKET_INFO_TX(&free->HTCPacket,
442 free,
443 &free->data[writePtr],
444 length,
445 arRawStream2EndpointID(ar,StreamID),
446 AR6K_DATA_PKT_TAG);
447
448 HTCSendPkt(ar->arHtcTarget,&free->HTCPacket);
449
450 arRaw->write_buffer_available[StreamID] = false;
451 up(&arRaw->raw_htc_write_sem[StreamID]);
452
453 return length;
454}
455#endif /* HTC_RAW_INTERFACE */
diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c
new file mode 100644
index 00000000000..5fdda4aa2fe
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/cfg80211.c
@@ -0,0 +1,1892 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#include <linux/wireless.h>
25#include <linux/ieee80211.h>
26#include <net/cfg80211.h>
27#include <net/netlink.h>
28
29#include "ar6000_drv.h"
30
31
32extern A_WAITQUEUE_HEAD arEvent;
33extern unsigned int wmitimeout;
34extern int reconnect_flag;
35
36
37#define RATETAB_ENT(_rate, _rateid, _flags) { \
38 .bitrate = (_rate), \
39 .flags = (_flags), \
40 .hw_value = (_rateid), \
41}
42
43#define CHAN2G(_channel, _freq, _flags) { \
44 .band = IEEE80211_BAND_2GHZ, \
45 .hw_value = (_channel), \
46 .center_freq = (_freq), \
47 .flags = (_flags), \
48 .max_antenna_gain = 0, \
49 .max_power = 30, \
50}
51
52#define CHAN5G(_channel, _flags) { \
53 .band = IEEE80211_BAND_5GHZ, \
54 .hw_value = (_channel), \
55 .center_freq = 5000 + (5 * (_channel)), \
56 .flags = (_flags), \
57 .max_antenna_gain = 0, \
58 .max_power = 30, \
59}
60
61static struct
62ieee80211_rate ar6k_rates[] = {
63 RATETAB_ENT(10, 0x1, 0),
64 RATETAB_ENT(20, 0x2, 0),
65 RATETAB_ENT(55, 0x4, 0),
66 RATETAB_ENT(110, 0x8, 0),
67 RATETAB_ENT(60, 0x10, 0),
68 RATETAB_ENT(90, 0x20, 0),
69 RATETAB_ENT(120, 0x40, 0),
70 RATETAB_ENT(180, 0x80, 0),
71 RATETAB_ENT(240, 0x100, 0),
72 RATETAB_ENT(360, 0x200, 0),
73 RATETAB_ENT(480, 0x400, 0),
74 RATETAB_ENT(540, 0x800, 0),
75};
76
77#define ar6k_a_rates (ar6k_rates + 4)
78#define ar6k_a_rates_size 8
79#define ar6k_g_rates (ar6k_rates + 0)
80#define ar6k_g_rates_size 12
81
82static struct
83ieee80211_channel ar6k_2ghz_channels[] = {
84 CHAN2G(1, 2412, 0),
85 CHAN2G(2, 2417, 0),
86 CHAN2G(3, 2422, 0),
87 CHAN2G(4, 2427, 0),
88 CHAN2G(5, 2432, 0),
89 CHAN2G(6, 2437, 0),
90 CHAN2G(7, 2442, 0),
91 CHAN2G(8, 2447, 0),
92 CHAN2G(9, 2452, 0),
93 CHAN2G(10, 2457, 0),
94 CHAN2G(11, 2462, 0),
95 CHAN2G(12, 2467, 0),
96 CHAN2G(13, 2472, 0),
97 CHAN2G(14, 2484, 0),
98};
99
100static struct
101ieee80211_channel ar6k_5ghz_a_channels[] = {
102 CHAN5G(34, 0), CHAN5G(36, 0),
103 CHAN5G(38, 0), CHAN5G(40, 0),
104 CHAN5G(42, 0), CHAN5G(44, 0),
105 CHAN5G(46, 0), CHAN5G(48, 0),
106 CHAN5G(52, 0), CHAN5G(56, 0),
107 CHAN5G(60, 0), CHAN5G(64, 0),
108 CHAN5G(100, 0), CHAN5G(104, 0),
109 CHAN5G(108, 0), CHAN5G(112, 0),
110 CHAN5G(116, 0), CHAN5G(120, 0),
111 CHAN5G(124, 0), CHAN5G(128, 0),
112 CHAN5G(132, 0), CHAN5G(136, 0),
113 CHAN5G(140, 0), CHAN5G(149, 0),
114 CHAN5G(153, 0), CHAN5G(157, 0),
115 CHAN5G(161, 0), CHAN5G(165, 0),
116 CHAN5G(184, 0), CHAN5G(188, 0),
117 CHAN5G(192, 0), CHAN5G(196, 0),
118 CHAN5G(200, 0), CHAN5G(204, 0),
119 CHAN5G(208, 0), CHAN5G(212, 0),
120 CHAN5G(216, 0),
121};
122
123static struct
124ieee80211_supported_band ar6k_band_2ghz = {
125 .n_channels = ARRAY_SIZE(ar6k_2ghz_channels),
126 .channels = ar6k_2ghz_channels,
127 .n_bitrates = ar6k_g_rates_size,
128 .bitrates = ar6k_g_rates,
129};
130
131static struct
132ieee80211_supported_band ar6k_band_5ghz = {
133 .n_channels = ARRAY_SIZE(ar6k_5ghz_a_channels),
134 .channels = ar6k_5ghz_a_channels,
135 .n_bitrates = ar6k_a_rates_size,
136 .bitrates = ar6k_a_rates,
137};
138
139static int
140ar6k_set_wpa_version(struct ar6_softc *ar, enum nl80211_wpa_versions wpa_version)
141{
142
143 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: %u\n", __func__, wpa_version));
144
145 if (!wpa_version) {
146 ar->arAuthMode = NONE_AUTH;
147 } else if (wpa_version & NL80211_WPA_VERSION_1) {
148 ar->arAuthMode = WPA_AUTH;
149 } else if (wpa_version & NL80211_WPA_VERSION_2) {
150 ar->arAuthMode = WPA2_AUTH;
151 } else {
152 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
153 ("%s: %u not spported\n", __func__, wpa_version));
154 return -ENOTSUPP;
155 }
156
157 return 0;
158}
159
160static int
161ar6k_set_auth_type(struct ar6_softc *ar, enum nl80211_auth_type auth_type)
162{
163
164 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, auth_type));
165
166 switch (auth_type) {
167 case NL80211_AUTHTYPE_OPEN_SYSTEM:
168 ar->arDot11AuthMode = OPEN_AUTH;
169 break;
170 case NL80211_AUTHTYPE_SHARED_KEY:
171 ar->arDot11AuthMode = SHARED_AUTH;
172 break;
173 case NL80211_AUTHTYPE_NETWORK_EAP:
174 ar->arDot11AuthMode = LEAP_AUTH;
175 break;
176
177 case NL80211_AUTHTYPE_AUTOMATIC:
178 ar->arDot11AuthMode = OPEN_AUTH;
179 ar->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS;
180 break;
181
182 default:
183 ar->arDot11AuthMode = OPEN_AUTH;
184 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
185 ("%s: 0x%x not spported\n", __func__, auth_type));
186 return -ENOTSUPP;
187 }
188
189 return 0;
190}
191
192static int
193ar6k_set_cipher(struct ar6_softc *ar, u32 cipher, bool ucast)
194{
195 u8 *ar_cipher = ucast ? &ar->arPairwiseCrypto :
196 &ar->arGroupCrypto;
197 u8 *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen :
198 &ar->arGroupCryptoLen;
199
200 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
201 ("%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast));
202
203 switch (cipher) {
204 case 0:
205 case IW_AUTH_CIPHER_NONE:
206 *ar_cipher = NONE_CRYPT;
207 *ar_cipher_len = 0;
208 break;
209 case WLAN_CIPHER_SUITE_WEP40:
210 *ar_cipher = WEP_CRYPT;
211 *ar_cipher_len = 5;
212 break;
213 case WLAN_CIPHER_SUITE_WEP104:
214 *ar_cipher = WEP_CRYPT;
215 *ar_cipher_len = 13;
216 break;
217 case WLAN_CIPHER_SUITE_TKIP:
218 *ar_cipher = TKIP_CRYPT;
219 *ar_cipher_len = 0;
220 break;
221 case WLAN_CIPHER_SUITE_CCMP:
222 *ar_cipher = AES_CRYPT;
223 *ar_cipher_len = 0;
224 break;
225 default:
226 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
227 ("%s: cipher 0x%x not supported\n", __func__, cipher));
228 return -ENOTSUPP;
229 }
230
231 return 0;
232}
233
234static void
235ar6k_set_key_mgmt(struct ar6_softc *ar, u32 key_mgmt)
236{
237 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt));
238
239 if (WLAN_AKM_SUITE_PSK == key_mgmt) {
240 if (WPA_AUTH == ar->arAuthMode) {
241 ar->arAuthMode = WPA_PSK_AUTH;
242 } else if (WPA2_AUTH == ar->arAuthMode) {
243 ar->arAuthMode = WPA2_PSK_AUTH;
244 }
245 } else if (WLAN_AKM_SUITE_8021X != key_mgmt) {
246 ar->arAuthMode = NONE_AUTH;
247 }
248}
249
250static int
251ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
252 struct cfg80211_connect_params *sme)
253{
254 struct ar6_softc *ar = ar6k_priv(dev);
255 int status;
256
257 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
258 ar->smeState = SME_CONNECTING;
259
260 if(ar->arWmiReady == false) {
261 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
262 return -EIO;
263 }
264
265 if(ar->arWlanState == WLAN_DISABLED) {
266 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
267 return -EIO;
268 }
269
270 if(ar->bIsDestroyProgress) {
271 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: destroy in progress\n", __func__));
272 return -EBUSY;
273 }
274
275 if(!sme->ssid_len || IEEE80211_MAX_SSID_LEN < sme->ssid_len) {
276 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
277 return -EINVAL;
278 }
279
280 if(ar->arSkipScan == true &&
281 ((sme->channel && sme->channel->center_freq == 0) ||
282 (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] &&
283 !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5])))
284 {
285 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:SkipScan: channel or bssid invalid\n", __func__));
286 return -EINVAL;
287 }
288
289 if(down_interruptible(&ar->arSem)) {
290 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
291 return -ERESTARTSYS;
292 }
293
294 if(ar->bIsDestroyProgress) {
295 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
296 up(&ar->arSem);
297 return -EBUSY;
298 }
299
300 if(ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
301 /*
302 * sleep until the command queue drains
303 */
304 wait_event_interruptible_timeout(arEvent,
305 ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
306 if (signal_pending(current)) {
307 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: cmd queue drain timeout\n", __func__));
308 up(&ar->arSem);
309 return -EINTR;
310 }
311 }
312
313 if(ar->arConnected == true &&
314 ar->arSsidLen == sme->ssid_len &&
315 !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) {
316 reconnect_flag = true;
317 status = wmi_reconnect_cmd(ar->arWmi,
318 ar->arReqBssid,
319 ar->arChannelHint);
320
321 up(&ar->arSem);
322 if (status) {
323 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__));
324 return -EIO;
325 }
326 return 0;
327 } else if(ar->arSsidLen == sme->ssid_len &&
328 !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) {
329 ar6000_disconnect(ar);
330 }
331
332 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
333 ar->arSsidLen = sme->ssid_len;
334 memcpy(ar->arSsid, sme->ssid, sme->ssid_len);
335
336 if(sme->channel){
337 ar->arChannelHint = sme->channel->center_freq;
338 }
339
340 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
341 if(sme->bssid){
342 if(memcmp(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
343 memcpy(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid));
344 }
345 }
346
347 ar6k_set_wpa_version(ar, sme->crypto.wpa_versions);
348 ar6k_set_auth_type(ar, sme->auth_type);
349
350 if(sme->crypto.n_ciphers_pairwise) {
351 ar6k_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
352 } else {
353 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
354 }
355 ar6k_set_cipher(ar, sme->crypto.cipher_group, false);
356
357 if(sme->crypto.n_akm_suites) {
358 ar6k_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
359 }
360
361 if((sme->key_len) &&
362 (NONE_AUTH == ar->arAuthMode) &&
363 (WEP_CRYPT == ar->arPairwiseCrypto)) {
364 struct ar_key *key = NULL;
365
366 if(sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) {
367 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
368 ("%s: key index %d out of bounds\n", __func__, sme->key_idx));
369 up(&ar->arSem);
370 return -ENOENT;
371 }
372
373 key = &ar->keys[sme->key_idx];
374 key->key_len = sme->key_len;
375 memcpy(key->key, sme->key, key->key_len);
376 key->cipher = ar->arPairwiseCrypto;
377 ar->arDefTxKeyIndex = sme->key_idx;
378
379 wmi_addKey_cmd(ar->arWmi, sme->key_idx,
380 ar->arPairwiseCrypto,
381 GROUP_USAGE | TX_USAGE,
382 key->key_len,
383 NULL,
384 key->key, KEY_OP_INIT_VAL, NULL,
385 NO_SYNC_WMIFLAG);
386 }
387
388 if (!ar->arUserBssFilter) {
389 if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) {
390 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
391 up(&ar->arSem);
392 return -EIO;
393 }
394 }
395
396 ar->arNetworkType = ar->arNextMode;
397
398 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
399 " PW crypto %d PW crypto Len %d GRP crypto %d"\
400 " GRP crypto Len %d channel hint %u\n",
401 __func__, ar->arAuthMode, ar->arDot11AuthMode,
402 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
403 ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
404
405 reconnect_flag = 0;
406 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
407 ar->arDot11AuthMode, ar->arAuthMode,
408 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
409 ar->arGroupCrypto,ar->arGroupCryptoLen,
410 ar->arSsidLen, ar->arSsid,
411 ar->arReqBssid, ar->arChannelHint,
412 ar->arConnectCtrlFlags);
413
414 up(&ar->arSem);
415
416 if (A_EINVAL == status) {
417 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
418 ar->arSsidLen = 0;
419 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__));
420 return -ENOENT;
421 } else if (status) {
422 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__));
423 return -EIO;
424 }
425
426 if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
427 ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
428 {
429 A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
430 }
431
432 ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
433 ar->arConnectPending = true;
434
435 return 0;
436}
437
438void
439ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
440 u8 *bssid, u16 listenInterval,
441 u16 beaconInterval,NETWORK_TYPE networkType,
442 u8 beaconIeLen, u8 assocReqLen,
443 u8 assocRespLen, u8 *assocInfo)
444{
445 u16 size = 0;
446 u16 capability = 0;
447 struct cfg80211_bss *bss = NULL;
448 struct ieee80211_mgmt *mgmt = NULL;
449 struct ieee80211_channel *ibss_channel = NULL;
450 s32 signal = 50 * 100;
451 u8 ie_buf_len = 0;
452 unsigned char ie_buf[256];
453 unsigned char *ptr_ie_buf = ie_buf;
454 unsigned char *ieeemgmtbuf = NULL;
455 u8 source_mac[ATH_MAC_LEN];
456
457 u8 assocReqIeOffset = sizeof(u16) + /* capinfo*/
458 sizeof(u16); /* listen interval */
459 u8 assocRespIeOffset = sizeof(u16) + /* capinfo*/
460 sizeof(u16) + /* status Code */
461 sizeof(u16); /* associd */
462 u8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset;
463 u8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset;
464
465 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
466
467 assocReqLen -= assocReqIeOffset;
468 assocRespLen -= assocRespIeOffset;
469
470 ar->arAutoAuthStage = AUTH_IDLE;
471
472 if((ADHOC_NETWORK & networkType)) {
473 if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
474 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
475 ("%s: ath6k not in ibss mode\n", __func__));
476 return;
477 }
478 }
479
480 if((INFRA_NETWORK & networkType)) {
481 if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
482 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
483 ("%s: ath6k not in station mode\n", __func__));
484 return;
485 }
486 }
487
488 /* Before informing the join/connect event, make sure that
489 * bss entry is present in scan list, if it not present
490 * construct and insert into scan list, otherwise that
491 * event will be dropped on the way by cfg80211, due to
492 * this keys will not be plumbed in case of WEP and
493 * application will not be aware of join/connect status. */
494 bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
495 ar->wdev->ssid, ar->wdev->ssid_len,
496 ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
497 ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
498
499 /*
500 * Earlier we were updating the cfg about bss by making a beacon frame
501 * only if the entry for bss is not there. This can have some issue if
502 * ROAM event is generated and a heavy traffic is ongoing. The ROAM
503 * event is handled through a work queue and by the time it really gets
504 * handled, BSS would have been aged out. So it is better to update the
505 * cfg about BSS irrespective of its entry being present right now or
506 * not.
507 */
508
509 if (ADHOC_NETWORK & networkType) {
510 /* construct 802.11 mgmt beacon */
511 if(ptr_ie_buf) {
512 *ptr_ie_buf++ = WLAN_EID_SSID;
513 *ptr_ie_buf++ = ar->arSsidLen;
514 memcpy(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
515 ptr_ie_buf +=ar->arSsidLen;
516
517 *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
518 *ptr_ie_buf++ = 2; /* length */
519 *ptr_ie_buf++ = 0; /* ATIM window */
520 *ptr_ie_buf++ = 0; /* ATIM window */
521
522 /* TODO: update ibss params and include supported rates,
523 * DS param set, extened support rates, wmm. */
524
525 ie_buf_len = ptr_ie_buf - ie_buf;
526 }
527
528 capability |= IEEE80211_CAPINFO_IBSS;
529 if(WEP_CRYPT == ar->arPairwiseCrypto) {
530 capability |= IEEE80211_CAPINFO_PRIVACY;
531 }
532 memcpy(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN);
533 ptr_ie_buf = ie_buf;
534 } else {
535 capability = *(u16 *)(&assocInfo[beaconIeLen]);
536 memcpy(source_mac, bssid, ATH_MAC_LEN);
537 ptr_ie_buf = assocReqIe;
538 ie_buf_len = assocReqLen;
539 }
540
541 size = offsetof(struct ieee80211_mgmt, u)
542 + sizeof(mgmt->u.beacon)
543 + ie_buf_len;
544
545 ieeemgmtbuf = A_MALLOC_NOWAIT(size);
546 if(!ieeemgmtbuf) {
547 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
548 ("%s: ieeeMgmtbuf alloc error\n", __func__));
549 cfg80211_put_bss(bss);
550 return;
551 }
552
553 A_MEMZERO(ieeemgmtbuf, size);
554 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
555 mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
556 memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
557 memcpy(mgmt->sa, source_mac, ATH_MAC_LEN);
558 memcpy(mgmt->bssid, bssid, ATH_MAC_LEN);
559 mgmt->u.beacon.beacon_int = beaconInterval;
560 mgmt->u.beacon.capab_info = capability;
561 memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
562
563 ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
564
565 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
566 ("%s: inform bss with bssid %pM channel %d beaconInterval %d "
567 "capability 0x%x\n", __func__, mgmt->bssid,
568 ibss_channel->hw_value, beaconInterval, capability));
569
570 bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
571 ibss_channel, mgmt,
572 le16_to_cpu(size),
573 signal, GFP_KERNEL);
574 kfree(ieeemgmtbuf);
575 cfg80211_put_bss(bss);
576
577 if((ADHOC_NETWORK & networkType)) {
578 cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
579 return;
580 }
581
582 if (false == ar->arConnected) {
583 /* inform connect result to cfg80211 */
584 ar->smeState = SME_DISCONNECTED;
585 cfg80211_connect_result(ar->arNetDev, bssid,
586 assocReqIe, assocReqLen,
587 assocRespIe, assocRespLen,
588 WLAN_STATUS_SUCCESS, GFP_KERNEL);
589 } else {
590 /* inform roam event to cfg80211 */
591 cfg80211_roamed(ar->arNetDev, ibss_channel, bssid,
592 assocReqIe, assocReqLen,
593 assocRespIe, assocRespLen,
594 GFP_KERNEL);
595 }
596}
597
598static int
599ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
600 u16 reason_code)
601{
602 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
603
604 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code));
605
606 if(ar->arWmiReady == false) {
607 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
608 return -EIO;
609 }
610
611 if(ar->arWlanState == WLAN_DISABLED) {
612 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
613 return -EIO;
614 }
615
616 if(ar->bIsDestroyProgress) {
617 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
618 return -EBUSY;
619 }
620
621 if(down_interruptible(&ar->arSem)) {
622 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
623 return -ERESTARTSYS;
624 }
625
626 reconnect_flag = 0;
627 ar6000_disconnect(ar);
628 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
629 ar->arSsidLen = 0;
630
631 if (ar->arSkipScan == false) {
632 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
633 }
634
635 up(&ar->arSem);
636
637 return 0;
638}
639
640void
641ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
642 u8 *bssid, u8 assocRespLen,
643 u8 *assocInfo, u16 protocolReasonStatus)
644{
645
646 u16 status;
647
648 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
649
650 if (ar->scan_request) {
651 cfg80211_scan_done(ar->scan_request, true);
652 ar->scan_request = NULL;
653 }
654 if((ADHOC_NETWORK & ar->arNetworkType)) {
655 if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
656 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
657 ("%s: ath6k not in ibss mode\n", __func__));
658 return;
659 }
660 A_MEMZERO(bssid, ETH_ALEN);
661 cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
662 return;
663 }
664
665 if((INFRA_NETWORK & ar->arNetworkType)) {
666 if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
667 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
668 ("%s: ath6k not in station mode\n", __func__));
669 return;
670 }
671 }
672
673 if(true == ar->arConnectPending) {
674 if(NO_NETWORK_AVAIL == reason) {
675 /* connect cmd failed */
676 wmi_disconnect_cmd(ar->arWmi);
677 } else if (reason == DISCONNECT_CMD) {
678 if (ar->arAutoAuthStage) {
679 /*
680 * If the current auth algorithm is open try shared
681 * and make autoAuthStage idle. We do not make it
682 * leap for now being.
683 */
684 if (ar->arDot11AuthMode == OPEN_AUTH) {
685 struct ar_key *key = NULL;
686 key = &ar->keys[ar->arDefTxKeyIndex];
687 if (down_interruptible(&ar->arSem)) {
688 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
689 return;
690 }
691
692
693 ar->arDot11AuthMode = SHARED_AUTH;
694 ar->arAutoAuthStage = AUTH_IDLE;
695
696 wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
697 ar->arPairwiseCrypto,
698 GROUP_USAGE | TX_USAGE,
699 key->key_len,
700 NULL,
701 key->key, KEY_OP_INIT_VAL, NULL,
702 NO_SYNC_WMIFLAG);
703
704 status = wmi_connect_cmd(ar->arWmi,
705 ar->arNetworkType,
706 ar->arDot11AuthMode,
707 ar->arAuthMode,
708 ar->arPairwiseCrypto,
709 ar->arPairwiseCryptoLen,
710 ar->arGroupCrypto,
711 ar->arGroupCryptoLen,
712 ar->arSsidLen,
713 ar->arSsid,
714 ar->arReqBssid,
715 ar->arChannelHint,
716 ar->arConnectCtrlFlags);
717 up(&ar->arSem);
718
719 } else if (ar->arDot11AuthMode == SHARED_AUTH) {
720 /* should not reach here */
721 }
722 } else {
723 ar->arConnectPending = false;
724 if (ar->smeState == SME_CONNECTING) {
725 cfg80211_connect_result(ar->arNetDev, bssid,
726 NULL, 0,
727 NULL, 0,
728 WLAN_STATUS_UNSPECIFIED_FAILURE,
729 GFP_KERNEL);
730 } else {
731 cfg80211_disconnected(ar->arNetDev,
732 reason,
733 NULL, 0,
734 GFP_KERNEL);
735 }
736 ar->smeState = SME_DISCONNECTED;
737 }
738 }
739 } else {
740 if (reason != DISCONNECT_CMD)
741 wmi_disconnect_cmd(ar->arWmi);
742 }
743}
744
745void
746ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
747{
748 struct wiphy *wiphy = (struct wiphy *)arg;
749 u16 size;
750 unsigned char *ieeemgmtbuf = NULL;
751 struct ieee80211_mgmt *mgmt;
752 struct ieee80211_channel *channel;
753 struct ieee80211_supported_band *band;
754 struct ieee80211_common_ie *cie;
755 s32 signal;
756 int freq;
757
758 cie = &ni->ni_cie;
759
760#define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484)))
761 if(CHAN_IS_11A(cie->ie_chan)) {
762 /* 11a */
763 band = wiphy->bands[IEEE80211_BAND_5GHZ];
764 } else if((cie->ie_erp) || (cie->ie_xrates)) {
765 /* 11g */
766 band = wiphy->bands[IEEE80211_BAND_2GHZ];
767 } else {
768 /* 11b */
769 band = wiphy->bands[IEEE80211_BAND_2GHZ];
770 }
771
772 size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
773 ieeemgmtbuf = A_MALLOC_NOWAIT(size);
774 if(!ieeemgmtbuf)
775 {
776 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
777 return;
778 }
779
780 /* Note:
781 TODO: Update target to include 802.11 mac header while sending bss info.
782 Target removes 802.11 mac header while sending the bss info to host,
783 cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
784 */
785 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
786 memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
787 memcpy(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
788 memcpy(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
789 memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
790 ni->ni_buf, ni->ni_framelen);
791
792 freq = cie->ie_chan;
793 channel = ieee80211_get_channel(wiphy, freq);
794 signal = ni->ni_snr * 100;
795
796 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
797 ("%s: bssid %pM channel %d freq %d size %d\n", __func__,
798 mgmt->bssid, channel->hw_value, freq, size));
799 cfg80211_inform_bss_frame(wiphy, channel, mgmt,
800 le16_to_cpu(size),
801 signal, GFP_KERNEL);
802
803 kfree (ieeemgmtbuf);
804}
805
806static int
807ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
808 struct cfg80211_scan_request *request)
809{
810 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
811 int ret = 0;
812 u32 forceFgScan = 0;
813
814 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
815
816 if(ar->arWmiReady == false) {
817 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
818 return -EIO;
819 }
820
821 if(ar->arWlanState == WLAN_DISABLED) {
822 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
823 return -EIO;
824 }
825
826 if (!ar->arUserBssFilter) {
827 if (wmi_bssfilter_cmd(ar->arWmi,
828 (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
829 0) != 0) {
830 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
831 return -EIO;
832 }
833 }
834
835 if(request->n_ssids &&
836 request->ssids[0].ssid_len) {
837 u8 i;
838
839 if(request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) {
840 request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
841 }
842
843 for (i = 0; i < request->n_ssids; i++) {
844 wmi_probedSsid_cmd(ar->arWmi, i+1, SPECIFIC_SSID_FLAG,
845 request->ssids[i].ssid_len,
846 request->ssids[i].ssid);
847 }
848 }
849
850 if(ar->arConnected) {
851 forceFgScan = 1;
852 }
853
854 if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, false, \
855 0, 0, 0, NULL) != 0) {
856 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
857 ret = -EIO;
858 }
859
860 ar->scan_request = request;
861
862 return ret;
863}
864
865void
866ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status)
867{
868
869 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
870
871 if (!ar->scan_request)
872 return;
873
874 if ((status == A_ECANCELED) || (status == A_EBUSY)) {
875 cfg80211_scan_done(ar->scan_request, true);
876 goto out;
877 }
878
879 /* Translate data to cfg80211 mgmt format */
880 wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
881
882 cfg80211_scan_done(ar->scan_request, false);
883
884 if(ar->scan_request->n_ssids &&
885 ar->scan_request->ssids[0].ssid_len) {
886 u8 i;
887
888 for (i = 0; i < ar->scan_request->n_ssids; i++) {
889 wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG,
890 0, NULL);
891 }
892 }
893
894out:
895 ar->scan_request = NULL;
896}
897
898static int
899ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
900 u8 key_index, bool pairwise, const u8 *mac_addr,
901 struct key_params *params)
902{
903 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
904 struct ar_key *key = NULL;
905 u8 key_usage;
906 u8 key_type;
907 int status = 0;
908
909 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
910
911 if(ar->arWmiReady == false) {
912 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
913 return -EIO;
914 }
915
916 if(ar->arWlanState == WLAN_DISABLED) {
917 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
918 return -EIO;
919 }
920
921 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
922 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
923 ("%s: key index %d out of bounds\n", __func__, key_index));
924 return -ENOENT;
925 }
926
927 key = &ar->keys[key_index];
928 A_MEMZERO(key, sizeof(struct ar_key));
929
930 if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
931 key_usage = GROUP_USAGE;
932 } else {
933 key_usage = PAIRWISE_USAGE;
934 }
935
936 if(params) {
937 if(params->key_len > WLAN_MAX_KEY_LEN ||
938 params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
939 return -EINVAL;
940
941 key->key_len = params->key_len;
942 memcpy(key->key, params->key, key->key_len);
943 key->seq_len = params->seq_len;
944 memcpy(key->seq, params->seq, key->seq_len);
945 key->cipher = params->cipher;
946 }
947
948 switch (key->cipher) {
949 case WLAN_CIPHER_SUITE_WEP40:
950 case WLAN_CIPHER_SUITE_WEP104:
951 key_type = WEP_CRYPT;
952 break;
953
954 case WLAN_CIPHER_SUITE_TKIP:
955 key_type = TKIP_CRYPT;
956 break;
957
958 case WLAN_CIPHER_SUITE_CCMP:
959 key_type = AES_CRYPT;
960 break;
961
962 default:
963 return -ENOTSUPP;
964 }
965
966 if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
967 (GROUP_USAGE & key_usage))
968 {
969 A_UNTIMEOUT(&ar->disconnect_timer);
970 }
971
972 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
973 ("%s: index %d, key_len %d, key_type 0x%x,"\
974 " key_usage 0x%x, seq_len %d\n",
975 __func__, key_index, key->key_len, key_type,
976 key_usage, key->seq_len));
977
978 ar->arDefTxKeyIndex = key_index;
979 status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
980 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
981 (u8 *)mac_addr, SYNC_BOTH_WMIFLAG);
982
983
984 if (status) {
985 return -EIO;
986 }
987
988 return 0;
989}
990
991static int
992ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
993 u8 key_index, bool pairwise, const u8 *mac_addr)
994{
995 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
996
997 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
998
999 if(ar->arWmiReady == false) {
1000 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1001 return -EIO;
1002 }
1003
1004 if(ar->arWlanState == WLAN_DISABLED) {
1005 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1006 return -EIO;
1007 }
1008
1009 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1010 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1011 ("%s: key index %d out of bounds\n", __func__, key_index));
1012 return -ENOENT;
1013 }
1014
1015 if(!ar->keys[key_index].key_len) {
1016 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
1017 return 0;
1018 }
1019
1020 ar->keys[key_index].key_len = 0;
1021
1022 return wmi_deleteKey_cmd(ar->arWmi, key_index);
1023}
1024
1025
1026static int
1027ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1028 u8 key_index, bool pairwise, const u8 *mac_addr,
1029 void *cookie,
1030 void (*callback)(void *cookie, struct key_params*))
1031{
1032 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1033 struct ar_key *key = NULL;
1034 struct key_params params;
1035
1036 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1037
1038 if(ar->arWmiReady == false) {
1039 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1040 return -EIO;
1041 }
1042
1043 if(ar->arWlanState == WLAN_DISABLED) {
1044 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1045 return -EIO;
1046 }
1047
1048 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1049 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1050 ("%s: key index %d out of bounds\n", __func__, key_index));
1051 return -ENOENT;
1052 }
1053
1054 key = &ar->keys[key_index];
1055 A_MEMZERO(&params, sizeof(params));
1056 params.cipher = key->cipher;
1057 params.key_len = key->key_len;
1058 params.seq_len = key->seq_len;
1059 params.seq = key->seq;
1060 params.key = key->key;
1061
1062 callback(cookie, &params);
1063
1064 return key->key_len ? 0 : -ENOENT;
1065}
1066
1067
1068static int
1069ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
1070 u8 key_index, bool unicast, bool multicast)
1071{
1072 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1073 struct ar_key *key = NULL;
1074 int status = 0;
1075 u8 key_usage;
1076
1077 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1078
1079 if(ar->arWmiReady == false) {
1080 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1081 return -EIO;
1082 }
1083
1084 if(ar->arWlanState == WLAN_DISABLED) {
1085 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1086 return -EIO;
1087 }
1088
1089 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1090 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1091 ("%s: key index %d out of bounds\n",
1092 __func__, key_index));
1093 return -ENOENT;
1094 }
1095
1096 if(!ar->keys[key_index].key_len) {
1097 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
1098 __func__, key_index));
1099 return -EINVAL;
1100 }
1101
1102 ar->arDefTxKeyIndex = key_index;
1103 key = &ar->keys[ar->arDefTxKeyIndex];
1104 key_usage = GROUP_USAGE;
1105 if (WEP_CRYPT == ar->arPairwiseCrypto) {
1106 key_usage |= TX_USAGE;
1107 }
1108
1109 status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
1110 ar->arPairwiseCrypto, key_usage,
1111 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
1112 NULL, SYNC_BOTH_WMIFLAG);
1113 if (status) {
1114 return -EIO;
1115 }
1116
1117 return 0;
1118}
1119
1120static int
1121ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
1122 u8 key_index)
1123{
1124 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1125
1126 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1127
1128 if(ar->arWmiReady == false) {
1129 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1130 return -EIO;
1131 }
1132
1133 if(ar->arWlanState == WLAN_DISABLED) {
1134 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1135 return -EIO;
1136 }
1137
1138 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1139 return -ENOTSUPP;
1140}
1141
1142void
1143ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
1144{
1145 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1146 ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
1147
1148 cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
1149 (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
1150 keyid, NULL, GFP_KERNEL);
1151}
1152
1153static int
1154ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1155{
1156 struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1157
1158 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
1159
1160 if(ar->arWmiReady == false) {
1161 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1162 return -EIO;
1163 }
1164
1165 if(ar->arWlanState == WLAN_DISABLED) {
1166 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1167 return -EIO;
1168 }
1169
1170 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1171 if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != 0){
1172 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
1173 return -EIO;
1174 }
1175 }
1176
1177 return 0;
1178}
1179
1180static int
1181ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1182 const u8 *peer,
1183 const struct cfg80211_bitrate_mask *mask)
1184{
1185 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
1186 return -EIO;
1187}
1188
1189/* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
1190static int
1191ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
1192{
1193 struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1194 u8 ar_dbm;
1195
1196 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
1197
1198 if(ar->arWmiReady == false) {
1199 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1200 return -EIO;
1201 }
1202
1203 if(ar->arWlanState == WLAN_DISABLED) {
1204 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1205 return -EIO;
1206 }
1207
1208 ar->arTxPwrSet = false;
1209 switch(type) {
1210 case NL80211_TX_POWER_AUTOMATIC:
1211 return 0;
1212 case NL80211_TX_POWER_LIMITED:
1213 ar->arTxPwr = ar_dbm = dbm;
1214 ar->arTxPwrSet = true;
1215 break;
1216 default:
1217 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
1218 return -EOPNOTSUPP;
1219 }
1220
1221 wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
1222
1223 return 0;
1224}
1225
1226static int
1227ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1228{
1229 struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1230
1231 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1232
1233 if(ar->arWmiReady == false) {
1234 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1235 return -EIO;
1236 }
1237
1238 if(ar->arWlanState == WLAN_DISABLED) {
1239 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1240 return -EIO;
1241 }
1242
1243 if((ar->arConnected == true)) {
1244 ar->arTxPwr = 0;
1245
1246 if(wmi_get_txPwr_cmd(ar->arWmi) != 0) {
1247 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
1248 return -EIO;
1249 }
1250
1251 wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
1252
1253 if(signal_pending(current)) {
1254 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
1255 return -EINTR;
1256 }
1257 }
1258
1259 *dbm = ar->arTxPwr;
1260 return 0;
1261}
1262
1263static int
1264ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1265 struct net_device *dev,
1266 bool pmgmt, int timeout)
1267{
1268 struct ar6_softc *ar = ar6k_priv(dev);
1269 WMI_POWER_MODE_CMD pwrMode;
1270
1271 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
1272
1273 if(ar->arWmiReady == false) {
1274 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1275 return -EIO;
1276 }
1277
1278 if(ar->arWlanState == WLAN_DISABLED) {
1279 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1280 return -EIO;
1281 }
1282
1283 if(pmgmt) {
1284 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
1285 pwrMode.powerMode = REC_POWER;
1286 } else {
1287 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
1288 pwrMode.powerMode = MAX_PERF_POWER;
1289 }
1290
1291 if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != 0) {
1292 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
1293 return -EIO;
1294 }
1295
1296 return 0;
1297}
1298
1299static struct net_device *
1300ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
1301 enum nl80211_iftype type, u32 *flags,
1302 struct vif_params *params)
1303{
1304
1305 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1306
1307 /* Multiple virtual interface is not supported.
1308 * The default interface supports STA and IBSS type
1309 */
1310 return ERR_PTR(-EOPNOTSUPP);
1311}
1312
1313static int
1314ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1315{
1316
1317 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1318
1319 /* Multiple virtual interface is not supported.
1320 * The default interface supports STA and IBSS type
1321 */
1322 return -EOPNOTSUPP;
1323}
1324
1325static int
1326ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1327 enum nl80211_iftype type, u32 *flags,
1328 struct vif_params *params)
1329{
1330 struct ar6_softc *ar = ar6k_priv(ndev);
1331 struct wireless_dev *wdev = ar->wdev;
1332
1333 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
1334
1335 if(ar->arWmiReady == false) {
1336 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1337 return -EIO;
1338 }
1339
1340 if(ar->arWlanState == WLAN_DISABLED) {
1341 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1342 return -EIO;
1343 }
1344
1345 switch (type) {
1346 case NL80211_IFTYPE_STATION:
1347 ar->arNextMode = INFRA_NETWORK;
1348 break;
1349 case NL80211_IFTYPE_ADHOC:
1350 ar->arNextMode = ADHOC_NETWORK;
1351 break;
1352 default:
1353 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
1354 return -EOPNOTSUPP;
1355 }
1356
1357 wdev->iftype = type;
1358
1359 return 0;
1360}
1361
1362static int
1363ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1364 struct cfg80211_ibss_params *ibss_param)
1365{
1366 struct ar6_softc *ar = ar6k_priv(dev);
1367 int status;
1368
1369 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1370
1371 if(ar->arWmiReady == false) {
1372 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1373 return -EIO;
1374 }
1375
1376 if(ar->arWlanState == WLAN_DISABLED) {
1377 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1378 return -EIO;
1379 }
1380
1381 if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
1382 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
1383 return -EINVAL;
1384 }
1385
1386 ar->arSsidLen = ibss_param->ssid_len;
1387 memcpy(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
1388
1389 if(ibss_param->channel) {
1390 ar->arChannelHint = ibss_param->channel->center_freq;
1391 }
1392
1393 if(ibss_param->channel_fixed) {
1394 /* TODO: channel_fixed: The channel should be fixed, do not search for
1395 * IBSSs to join on other channels. Target firmware does not support this
1396 * feature, needs to be updated.*/
1397 }
1398
1399 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1400 if(ibss_param->bssid) {
1401 if(memcmp(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
1402 memcpy(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
1403 }
1404 }
1405
1406 ar6k_set_wpa_version(ar, 0);
1407 ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1408
1409 if(ibss_param->privacy) {
1410 ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1411 ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1412 } else {
1413 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
1414 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
1415 }
1416
1417 ar->arNetworkType = ar->arNextMode;
1418
1419 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
1420 " PW crypto %d PW crypto Len %d GRP crypto %d"\
1421 " GRP crypto Len %d channel hint %u\n",
1422 __func__, ar->arAuthMode, ar->arDot11AuthMode,
1423 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1424 ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
1425
1426 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
1427 ar->arDot11AuthMode, ar->arAuthMode,
1428 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1429 ar->arGroupCrypto,ar->arGroupCryptoLen,
1430 ar->arSsidLen, ar->arSsid,
1431 ar->arReqBssid, ar->arChannelHint,
1432 ar->arConnectCtrlFlags);
1433 ar->arConnectPending = true;
1434
1435 return 0;
1436}
1437
1438static int
1439ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1440{
1441 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1442
1443 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1444
1445 if(ar->arWmiReady == false) {
1446 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1447 return -EIO;
1448 }
1449
1450 if(ar->arWlanState == WLAN_DISABLED) {
1451 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1452 return -EIO;
1453 }
1454
1455 ar6000_disconnect(ar);
1456 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1457 ar->arSsidLen = 0;
1458
1459 return 0;
1460}
1461
1462#ifdef CONFIG_NL80211_TESTMODE
1463enum ar6k_testmode_attr {
1464 __AR6K_TM_ATTR_INVALID = 0,
1465 AR6K_TM_ATTR_CMD = 1,
1466 AR6K_TM_ATTR_DATA = 2,
1467
1468 /* keep last */
1469 __AR6K_TM_ATTR_AFTER_LAST,
1470 AR6K_TM_ATTR_MAX = __AR6K_TM_ATTR_AFTER_LAST - 1
1471};
1472
1473enum ar6k_testmode_cmd {
1474 AR6K_TM_CMD_TCMD = 0,
1475 AR6K_TM_CMD_RX_REPORT = 1,
1476};
1477
1478#define AR6K_TM_DATA_MAX_LEN 5000
1479
1480static const struct nla_policy ar6k_testmode_policy[AR6K_TM_ATTR_MAX + 1] = {
1481 [AR6K_TM_ATTR_CMD] = { .type = NLA_U32 },
1482 [AR6K_TM_ATTR_DATA] = { .type = NLA_BINARY,
1483 .len = AR6K_TM_DATA_MAX_LEN },
1484};
1485
1486void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf,
1487 int buf_len)
1488{
1489 if (down_interruptible(&ar->arSem))
1490 return;
1491
1492 kfree(ar->tcmd_rx_report);
1493
1494 ar->tcmd_rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
1495 ar->tcmd_rx_report_len = buf_len;
1496
1497 up(&ar->arSem);
1498
1499 wake_up(&arEvent);
1500}
1501
1502static int ar6000_testmode_rx_report(struct ar6_softc *ar, void *buf,
1503 int buf_len, struct sk_buff *skb)
1504{
1505 int ret = 0;
1506 long left;
1507
1508 if (down_interruptible(&ar->arSem))
1509 return -ERESTARTSYS;
1510
1511 if (ar->arWmiReady == false) {
1512 ret = -EIO;
1513 goto out;
1514 }
1515
1516 if (ar->bIsDestroyProgress) {
1517 ret = -EBUSY;
1518 goto out;
1519 }
1520
1521 WARN_ON(ar->tcmd_rx_report != NULL);
1522 WARN_ON(ar->tcmd_rx_report_len > 0);
1523
1524 if (wmi_test_cmd(ar->arWmi, buf, buf_len) < 0) {
1525 up(&ar->arSem);
1526 return -EIO;
1527 }
1528
1529 left = wait_event_interruptible_timeout(arEvent,
1530 ar->tcmd_rx_report != NULL,
1531 wmitimeout * HZ);
1532
1533 if (left == 0) {
1534 ret = -ETIMEDOUT;
1535 goto out;
1536 } else if (left < 0) {
1537 ret = left;
1538 goto out;
1539 }
1540
1541 if (ar->tcmd_rx_report == NULL || ar->tcmd_rx_report_len == 0) {
1542 ret = -EINVAL;
1543 goto out;
1544 }
1545
1546 NLA_PUT(skb, AR6K_TM_ATTR_DATA, ar->tcmd_rx_report_len,
1547 ar->tcmd_rx_report);
1548
1549 kfree(ar->tcmd_rx_report);
1550 ar->tcmd_rx_report = NULL;
1551
1552out:
1553 up(&ar->arSem);
1554
1555 return ret;
1556
1557nla_put_failure:
1558 ret = -ENOBUFS;
1559 goto out;
1560}
1561
1562static int ar6k_testmode_cmd(struct wiphy *wiphy, void *data, int len)
1563{
1564 struct ar6_softc *ar = wiphy_priv(wiphy);
1565 struct nlattr *tb[AR6K_TM_ATTR_MAX + 1];
1566 int err, buf_len, reply_len;
1567 struct sk_buff *skb;
1568 void *buf;
1569
1570 err = nla_parse(tb, AR6K_TM_ATTR_MAX, data, len,
1571 ar6k_testmode_policy);
1572 if (err)
1573 return err;
1574
1575 if (!tb[AR6K_TM_ATTR_CMD])
1576 return -EINVAL;
1577
1578 switch (nla_get_u32(tb[AR6K_TM_ATTR_CMD])) {
1579 case AR6K_TM_CMD_TCMD:
1580 if (!tb[AR6K_TM_ATTR_DATA])
1581 return -EINVAL;
1582
1583 buf = nla_data(tb[AR6K_TM_ATTR_DATA]);
1584 buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]);
1585
1586 wmi_test_cmd(ar->arWmi, buf, buf_len);
1587
1588 return 0;
1589
1590 break;
1591 case AR6K_TM_CMD_RX_REPORT:
1592 if (!tb[AR6K_TM_ATTR_DATA])
1593 return -EINVAL;
1594
1595 buf = nla_data(tb[AR6K_TM_ATTR_DATA]);
1596 buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]);
1597
1598 reply_len = nla_total_size(AR6K_TM_DATA_MAX_LEN);
1599 skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
1600 if (!skb)
1601 return -ENOMEM;
1602
1603 err = ar6000_testmode_rx_report(ar, buf, buf_len, skb);
1604 if (err < 0) {
1605 kfree_skb(skb);
1606 return err;
1607 }
1608
1609 return cfg80211_testmode_reply(skb);
1610 default:
1611 return -EOPNOTSUPP;
1612 }
1613}
1614#endif
1615
1616static const
1617u32 cipher_suites[] = {
1618 WLAN_CIPHER_SUITE_WEP40,
1619 WLAN_CIPHER_SUITE_WEP104,
1620 WLAN_CIPHER_SUITE_TKIP,
1621 WLAN_CIPHER_SUITE_CCMP,
1622};
1623
1624bool is_rate_legacy(s32 rate)
1625{
1626 static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1627 6000, 9000, 12000, 18000, 24000,
1628 36000, 48000, 54000 };
1629 u8 i;
1630
1631 for (i = 0; i < ARRAY_SIZE(legacy); i++) {
1632 if (rate == legacy[i])
1633 return true;
1634 }
1635
1636 return false;
1637}
1638
1639bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1640{
1641 static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1642 52000, 58500, 65000, 72200 };
1643 u8 i;
1644
1645 for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1646 if (rate == ht20[i]) {
1647 if (i == ARRAY_SIZE(ht20) - 1)
1648 /* last rate uses sgi */
1649 *sgi = true;
1650 else
1651 *sgi = false;
1652
1653 *mcs = i;
1654 return true;
1655 }
1656 }
1657 return false;
1658}
1659
1660bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1661{
1662 static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1663 81000, 108000, 121500, 135000,
1664 150000 };
1665 u8 i;
1666
1667 for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1668 if (rate == ht40[i]) {
1669 if (i == ARRAY_SIZE(ht40) - 1)
1670 /* last rate uses sgi */
1671 *sgi = true;
1672 else
1673 *sgi = false;
1674
1675 *mcs = i;
1676 return true;
1677 }
1678 }
1679
1680 return false;
1681}
1682
1683static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev,
1684 u8 *mac, struct station_info *sinfo)
1685{
1686 struct ar6_softc *ar = ar6k_priv(dev);
1687 long left;
1688 bool sgi;
1689 s32 rate;
1690 int ret;
1691 u8 mcs;
1692
1693 if (memcmp(mac, ar->arBssid, ETH_ALEN) != 0)
1694 return -ENOENT;
1695
1696 if (down_interruptible(&ar->arSem))
1697 return -EBUSY;
1698
1699 ar->statsUpdatePending = true;
1700
1701 ret = wmi_get_stats_cmd(ar->arWmi);
1702
1703 if (ret != 0) {
1704 up(&ar->arSem);
1705 return -EIO;
1706 }
1707
1708 left = wait_event_interruptible_timeout(arEvent,
1709 ar->statsUpdatePending == false,
1710 wmitimeout * HZ);
1711
1712 up(&ar->arSem);
1713
1714 if (left == 0)
1715 return -ETIMEDOUT;
1716 else if (left < 0)
1717 return left;
1718
1719 if (ar->arTargetStats.rx_bytes) {
1720 sinfo->rx_bytes = ar->arTargetStats.rx_bytes;
1721 sinfo->filled |= STATION_INFO_RX_BYTES;
1722 sinfo->rx_packets = ar->arTargetStats.rx_packets;
1723 sinfo->filled |= STATION_INFO_RX_PACKETS;
1724 }
1725
1726 if (ar->arTargetStats.tx_bytes) {
1727 sinfo->tx_bytes = ar->arTargetStats.tx_bytes;
1728 sinfo->filled |= STATION_INFO_TX_BYTES;
1729 sinfo->tx_packets = ar->arTargetStats.tx_packets;
1730 sinfo->filled |= STATION_INFO_TX_PACKETS;
1731 }
1732
1733 sinfo->signal = ar->arTargetStats.cs_rssi;
1734 sinfo->filled |= STATION_INFO_SIGNAL;
1735
1736 rate = ar->arTargetStats.tx_unicast_rate;
1737
1738 if (is_rate_legacy(rate)) {
1739 sinfo->txrate.legacy = rate / 100;
1740 } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1741 if (sgi) {
1742 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1743 sinfo->txrate.mcs = mcs - 1;
1744 } else {
1745 sinfo->txrate.mcs = mcs;
1746 }
1747
1748 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1749 } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1750 if (sgi) {
1751 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1752 sinfo->txrate.mcs = mcs - 1;
1753 } else {
1754 sinfo->txrate.mcs = mcs;
1755 }
1756
1757 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1758 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1759 } else {
1760 WARN(1, "invalid rate: %d", rate);
1761 return 0;
1762 }
1763
1764 sinfo->filled |= STATION_INFO_TX_BITRATE;
1765
1766 return 0;
1767}
1768
1769static int ar6k_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1770 struct cfg80211_pmksa *pmksa)
1771{
1772 struct ar6_softc *ar = ar6k_priv(netdev);
1773 return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, true);
1774}
1775
1776static int ar6k_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1777 struct cfg80211_pmksa *pmksa)
1778{
1779 struct ar6_softc *ar = ar6k_priv(netdev);
1780 return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, false);
1781}
1782
1783static int ar6k_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1784{
1785 struct ar6_softc *ar = ar6k_priv(netdev);
1786 if (ar->arConnected)
1787 return wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, false);
1788 return 0;
1789}
1790
1791static struct
1792cfg80211_ops ar6k_cfg80211_ops = {
1793 .change_virtual_intf = ar6k_cfg80211_change_iface,
1794 .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
1795 .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
1796 .scan = ar6k_cfg80211_scan,
1797 .connect = ar6k_cfg80211_connect,
1798 .disconnect = ar6k_cfg80211_disconnect,
1799 .add_key = ar6k_cfg80211_add_key,
1800 .get_key = ar6k_cfg80211_get_key,
1801 .del_key = ar6k_cfg80211_del_key,
1802 .set_default_key = ar6k_cfg80211_set_default_key,
1803 .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
1804 .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
1805 .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
1806 .set_tx_power = ar6k_cfg80211_set_txpower,
1807 .get_tx_power = ar6k_cfg80211_get_txpower,
1808 .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
1809 .join_ibss = ar6k_cfg80211_join_ibss,
1810 .leave_ibss = ar6k_cfg80211_leave_ibss,
1811 .get_station = ar6k_get_station,
1812 .set_pmksa = ar6k_set_pmksa,
1813 .del_pmksa = ar6k_del_pmksa,
1814 .flush_pmksa = ar6k_flush_pmksa,
1815 CFG80211_TESTMODE_CMD(ar6k_testmode_cmd)
1816};
1817
1818struct wireless_dev *
1819ar6k_cfg80211_init(struct device *dev)
1820{
1821 int ret = 0;
1822 struct wireless_dev *wdev;
1823
1824 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1825
1826 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1827 if(!wdev) {
1828 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1829 ("%s: Couldn't allocate wireless device\n", __func__));
1830 return ERR_PTR(-ENOMEM);
1831 }
1832
1833 /* create a new wiphy for use with cfg80211 */
1834 wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(struct ar6_softc));
1835 if(!wdev->wiphy) {
1836 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1837 ("%s: Couldn't allocate wiphy device\n", __func__));
1838 kfree(wdev);
1839 return ERR_PTR(-ENOMEM);
1840 }
1841
1842 /* set device pointer for wiphy */
1843 set_wiphy_dev(wdev->wiphy, dev);
1844
1845 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1846 BIT(NL80211_IFTYPE_ADHOC);
1847 /* max num of ssids that can be probed during scanning */
1848 wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1849 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
1850 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
1851 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1852
1853 wdev->wiphy->cipher_suites = cipher_suites;
1854 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1855
1856 ret = wiphy_register(wdev->wiphy);
1857 if(ret < 0) {
1858 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1859 ("%s: Couldn't register wiphy device\n", __func__));
1860 wiphy_free(wdev->wiphy);
1861 return ERR_PTR(ret);
1862 }
1863
1864 return wdev;
1865}
1866
1867void
1868ar6k_cfg80211_deinit(struct ar6_softc *ar)
1869{
1870 struct wireless_dev *wdev = ar->wdev;
1871
1872 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1873
1874 if(ar->scan_request) {
1875 cfg80211_scan_done(ar->scan_request, true);
1876 ar->scan_request = NULL;
1877 }
1878
1879 if(!wdev)
1880 return;
1881
1882 wiphy_unregister(wdev->wiphy);
1883 wiphy_free(wdev->wiphy);
1884 kfree(wdev);
1885}
1886
1887
1888
1889
1890
1891
1892
diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c
new file mode 100644
index 00000000000..430998edacc
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c
@@ -0,0 +1,124 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HCI bridge implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24#include <a_config.h>
25#include <athdefs.h>
26#include "a_osapi.h"
27#include "htc_api.h"
28#include "a_drv.h"
29#include "hif.h"
30#include "common_drv.h"
31#include "a_debug.h"
32#include "hci_transport_api.h"
33
34#include "AR6002/hw4.0/hw/apb_athr_wlan_map.h"
35#include "AR6002/hw4.0/hw/uart_reg.h"
36#include "AR6002/hw4.0/hw/rtc_wlan_reg.h"
37
38HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo);
39void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans);
40int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
41int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
42void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans);
43int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans);
44int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
45int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans,
46 struct htc_packet *pPacket,
47 int MaxPollMS);
48int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
49int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
50
51extern struct hci_transport_callbacks ar6kHciTransCallbacks;
52
53int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks)
54{
55 ar6kHciTransCallbacks = *hciTransCallbacks;
56
57 _HCI_TransportAttach = HCI_TransportAttach;
58 _HCI_TransportDetach = HCI_TransportDetach;
59 _HCI_TransportAddReceivePkts = HCI_TransportAddReceivePkts;
60 _HCI_TransportSendPkt = HCI_TransportSendPkt;
61 _HCI_TransportStop = HCI_TransportStop;
62 _HCI_TransportStart = HCI_TransportStart;
63 _HCI_TransportEnableDisableAsyncRecv = HCI_TransportEnableDisableAsyncRecv;
64 _HCI_TransportRecvHCIEventSync = HCI_TransportRecvHCIEventSync;
65 _HCI_TransportSetBaudRate = HCI_TransportSetBaudRate;
66 _HCI_TransportEnablePowerMgmt = HCI_TransportEnablePowerMgmt;
67
68 return 0;
69}
70
71int
72ar6000_get_hif_dev(struct hif_device *device, void *config)
73{
74 int status;
75
76 status = HIFConfigureDevice(device,
77 HIF_DEVICE_GET_OS_DEVICE,
78 (struct hif_device_os_device_info *)config,
79 sizeof(struct hif_device_os_device_info));
80 return status;
81}
82
83int ar6000_set_uart_config(struct hif_device *hifDevice,
84 u32 scale,
85 u32 step)
86{
87 u32 regAddress;
88 u32 regVal;
89 int status;
90
91 regAddress = WLAN_UART_BASE_ADDRESS | UART_CLKDIV_ADDRESS;
92 regVal = ((u32)scale << 16) | step;
93 /* change the HCI UART scale/step values through the diagnostic window */
94 status = ar6000_WriteRegDiag(hifDevice, &regAddress, &regVal);
95
96 return status;
97}
98
99int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data)
100{
101 u32 regAddress;
102 int status;
103
104 regAddress = WLAN_RTC_BASE_ADDRESS | WLAN_CPU_CLOCK_ADDRESS;
105 /* read CPU clock settings*/
106 status = ar6000_ReadRegDiag(hifDevice, &regAddress, data);
107
108 return status;
109}
110
111EXPORT_SYMBOL(ar6000_register_hci_transport);
112EXPORT_SYMBOL(ar6000_get_hif_dev);
113EXPORT_SYMBOL(ar6000_set_uart_config);
114EXPORT_SYMBOL(ar6000_get_core_clock_config);
115EXPORT_SYMBOL(_HCI_TransportAttach);
116EXPORT_SYMBOL(_HCI_TransportDetach);
117EXPORT_SYMBOL(_HCI_TransportAddReceivePkts);
118EXPORT_SYMBOL(_HCI_TransportSendPkt);
119EXPORT_SYMBOL(_HCI_TransportStop);
120EXPORT_SYMBOL(_HCI_TransportStart);
121EXPORT_SYMBOL(_HCI_TransportEnableDisableAsyncRecv);
122EXPORT_SYMBOL(_HCI_TransportRecvHCIEventSync);
123EXPORT_SYMBOL(_HCI_TransportSetBaudRate);
124EXPORT_SYMBOL(_HCI_TransportEnablePowerMgmt);
diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c
new file mode 100644
index 00000000000..6087edcb1d6
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c
@@ -0,0 +1,1141 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HCI bridge implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#ifdef EXPORT_HCI_BRIDGE_INTERFACE
26#include <linux/etherdevice.h>
27#include <a_config.h>
28#include <athdefs.h>
29#include "a_osapi.h"
30#include "htc_api.h"
31#include "wmi.h"
32#include "a_drv.h"
33#include "hif.h"
34#include "common_drv.h"
35#include "a_debug.h"
36#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
37#define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7)
38#define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8)
39#define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9)
40#else
41#include "ar6000_drv.h"
42#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
43
44#ifdef ATH_AR6K_ENABLE_GMBOX
45#ifdef EXPORT_HCI_BRIDGE_INTERFACE
46#include "export_hci_transport.h"
47#else
48#include "hci_transport_api.h"
49#endif
50#include "epping_test.h"
51#include "gmboxif.h"
52#include "ar3kconfig.h"
53#include <net/bluetooth/bluetooth.h>
54#include <net/bluetooth/hci_core.h>
55
56 /* only build on newer kernels which have BT configured */
57#if defined(CONFIG_BT_MODULE) || defined(CONFIG_BT)
58#define CONFIG_BLUEZ_HCI_BRIDGE
59#endif
60
61#ifdef EXPORT_HCI_BRIDGE_INTERFACE
62unsigned int ar3khcibaud = 0;
63unsigned int hciuartscale = 0;
64unsigned int hciuartstep = 0;
65
66module_param(ar3khcibaud, int, 0644);
67module_param(hciuartscale, int, 0644);
68module_param(hciuartstep, int, 0644);
69#else
70extern unsigned int ar3khcibaud;
71extern unsigned int hciuartscale;
72extern unsigned int hciuartstep;
73#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
74
75struct ar6k_hci_bridge_info {
76 void *pHCIDev; /* HCI bridge device */
77 struct hci_transport_properties HCIProps; /* HCI bridge props */
78 struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */
79 bool HciNormalMode; /* Actual HCI mode enabled (non-TEST)*/
80 bool HciRegistered; /* HCI device registered with stack */
81 struct htc_packet_queue HTCPacketStructHead;
82 u8 *pHTCStructAlloc;
83 spinlock_t BridgeLock;
84#ifdef EXPORT_HCI_BRIDGE_INTERFACE
85 struct hci_transport_misc_handles HCITransHdl;
86#else
87 struct ar6_softc *ar;
88#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
89};
90
91#define MAX_ACL_RECV_BUFS 16
92#define MAX_EVT_RECV_BUFS 8
93#define MAX_HCI_WRITE_QUEUE_DEPTH 32
94#define MAX_ACL_RECV_LENGTH 1200
95#define MAX_EVT_RECV_LENGTH 257
96#define TX_PACKET_RSV_OFFSET 32
97#define NUM_HTC_PACKET_STRUCTS ((MAX_ACL_RECV_BUFS + MAX_EVT_RECV_BUFS + MAX_HCI_WRITE_QUEUE_DEPTH) * 2)
98
99#define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0]))
100
101extern unsigned int setupbtdev;
102struct ar3k_config_info ar3kconfig;
103
104#ifdef EXPORT_HCI_BRIDGE_INTERFACE
105struct ar6k_hci_bridge_info *g_pHcidevInfo;
106#endif
107
108static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
109static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
110static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
111static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo,
112 HCI_TRANSPORT_PACKET_TYPE Type,
113 struct sk_buff *skb);
114static struct sk_buff *bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length);
115static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb);
116
117#ifdef EXPORT_HCI_BRIDGE_INTERFACE
118int ar6000_setup_hci(void *ar);
119void ar6000_cleanup_hci(void *ar);
120int hci_test_send(void *ar, struct sk_buff *skb);
121#else
122int ar6000_setup_hci(struct ar6_softc *ar);
123void ar6000_cleanup_hci(struct ar6_softc *ar);
124/* HCI bridge testing */
125int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb);
126#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
127
128#define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock)
129#define UNLOCK_BRIDGE(dev) spin_unlock_bh(&(dev)->BridgeLock)
130
131static inline void FreeBtOsBuf(struct ar6k_hci_bridge_info *pHcidevInfo, void *osbuf)
132{
133 if (pHcidevInfo->HciNormalMode) {
134 bt_free_buffer(pHcidevInfo, (struct sk_buff *)osbuf);
135 } else {
136 /* in test mode, these are just ordinary netbuf allocations */
137 A_NETBUF_FREE(osbuf);
138 }
139}
140
141static void FreeHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo, struct htc_packet *pPacket)
142{
143 LOCK_BRIDGE(pHcidevInfo);
144 HTC_PACKET_ENQUEUE(&pHcidevInfo->HTCPacketStructHead,pPacket);
145 UNLOCK_BRIDGE(pHcidevInfo);
146}
147
148static struct htc_packet * AllocHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo)
149{
150 struct htc_packet *pPacket = NULL;
151 LOCK_BRIDGE(pHcidevInfo);
152 pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead);
153 UNLOCK_BRIDGE(pHcidevInfo);
154 return pPacket;
155}
156
157#define BLOCK_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1))
158
159static void RefillRecvBuffers(struct ar6k_hci_bridge_info *pHcidevInfo,
160 HCI_TRANSPORT_PACKET_TYPE Type,
161 int NumBuffers)
162{
163 int length, i;
164 void *osBuf = NULL;
165 struct htc_packet_queue queue;
166 struct htc_packet *pPacket;
167
168 INIT_HTC_PACKET_QUEUE(&queue);
169
170 if (Type == HCI_ACL_TYPE) {
171 if (pHcidevInfo->HciNormalMode) {
172 length = HCI_MAX_FRAME_SIZE;
173 } else {
174 length = MAX_ACL_RECV_LENGTH;
175 }
176 } else {
177 length = MAX_EVT_RECV_LENGTH;
178 }
179
180 /* add on transport head and tail room */
181 length += pHcidevInfo->HCIProps.HeadRoom + pHcidevInfo->HCIProps.TailRoom;
182 /* round up to the required I/O padding */
183 length = BLOCK_ROUND_UP_PWR2(length,pHcidevInfo->HCIProps.IOBlockPad);
184
185 for (i = 0; i < NumBuffers; i++) {
186
187 if (pHcidevInfo->HciNormalMode) {
188 osBuf = bt_alloc_buffer(pHcidevInfo,length);
189 } else {
190 osBuf = A_NETBUF_ALLOC(length);
191 }
192
193 if (NULL == osBuf) {
194 break;
195 }
196
197 pPacket = AllocHTCStruct(pHcidevInfo);
198 if (NULL == pPacket) {
199 FreeBtOsBuf(pHcidevInfo,osBuf);
200 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
201 break;
202 }
203
204 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),length,Type);
205 /* add to queue */
206 HTC_PACKET_ENQUEUE(&queue,pPacket);
207 }
208
209 if (i > 0) {
210 HCI_TransportAddReceivePkts(pHcidevInfo->pHCIDev, &queue);
211 }
212}
213
214#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
215 (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
216 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
217static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle,
218 struct hci_transport_properties *pProps,
219 void *pContext)
220{
221 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
222 int status;
223 u32 address, hci_uart_pwr_mgmt_params;
224// struct ar3k_config_info ar3kconfig;
225
226 pHcidevInfo->pHCIDev = HCIHandle;
227
228 memcpy(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps));
229
230 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n",
231 (unsigned long)HCIHandle,
232 pHcidevInfo->HCIProps.HeadRoom,
233 pHcidevInfo->HCIProps.TailRoom,
234 pHcidevInfo->HCIProps.IOBlockPad));
235
236#ifdef EXPORT_HCI_BRIDGE_INTERFACE
237 A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len);
238#else
239 A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev->hard_header_len);
240#endif
241
242 /* provide buffers */
243 RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS);
244 RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS);
245
246 do {
247 /* start transport */
248 status = HCI_TransportStart(pHcidevInfo->pHCIDev);
249
250 if (status) {
251 break;
252 }
253
254 if (!pHcidevInfo->HciNormalMode) {
255 /* in test mode, no need to go any further */
256 break;
257 }
258
259 // The delay is required when AR6K is driving the BT reset line
260 // where time is needed after the BT chip is out of reset (HCI_TransportStart)
261 // and before the first HCI command is issued (AR3KConfigure)
262 // FIXME
263 // The delay should be configurable and be only applied when AR6K driving the BT
264 // reset line. This could be done by some module parameter or based on some HW config
265 // info. For now apply 100ms delay blindly
266 A_MDELAY(100);
267
268 A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
269 ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev;
270 ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps;
271#ifdef EXPORT_HCI_BRIDGE_INTERFACE
272 ar3kconfig.pHIFDevice = (struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice);
273#else
274 ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice;
275#endif
276 ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
277
278 if (ar3khcibaud != 0) {
279 /* user wants ar3k baud rate change */
280 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
281 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY;
282 ar3kconfig.AR3KBaudRate = ar3khcibaud;
283 }
284
285 if ((hciuartscale != 0) || (hciuartstep != 0)) {
286 /* user wants to tune HCI bridge UART scale/step values */
287 ar3kconfig.AR6KScale = (u16)hciuartscale;
288 ar3kconfig.AR6KStep = (u16)hciuartstep;
289 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP;
290 }
291
292 /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */
293 address = TARG_VTOP(pHcidevInfo->ar->arTargetType,
294 HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar, hi_hci_uart_pwr_mgmt_params));
295 status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params);
296 if (0 == status) {
297 ar3kconfig.PwrMgmtEnabled = (hci_uart_pwr_mgmt_params & 0x1);
298 ar3kconfig.IdleTimeout = (hci_uart_pwr_mgmt_params & 0xFFFF0000) >> 16;
299 ar3kconfig.WakeupTimeout = (hci_uart_pwr_mgmt_params & 0xFF00) >> 8;
300 } else {
301 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to read hci_uart_pwr_mgmt_params! \n"));
302 }
303 /* configure the AR3K device */
304 memcpy(ar3kconfig.bdaddr,pHcidevInfo->ar->bdaddr,6);
305 status = AR3KConfigure(&ar3kconfig);
306 if (status) {
307 break;
308 }
309
310 /* Make sure both AR6K and AR3K have power management enabled */
311 if (ar3kconfig.PwrMgmtEnabled) {
312 status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, true);
313 if (status) {
314 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n"));
315 }
316 }
317
318 status = bt_register_hci(pHcidevInfo);
319
320 } while (false);
321
322 return status;
323}
324
325static void ar6000_hci_transport_failure(void *pContext, int Status)
326{
327 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
328
329 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: transport failure! \n"));
330
331 if (pHcidevInfo->HciNormalMode) {
332 /* TODO .. */
333 }
334}
335
336static void ar6000_hci_transport_removed(void *pContext)
337{
338 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
339
340 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: transport removed. \n"));
341
342 A_ASSERT(pHcidevInfo->pHCIDev != NULL);
343
344 HCI_TransportDetach(pHcidevInfo->pHCIDev);
345 bt_cleanup_hci(pHcidevInfo);
346 pHcidevInfo->pHCIDev = NULL;
347}
348
349static void ar6000_hci_send_complete(void *pContext, struct htc_packet *pPacket)
350{
351 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
352 void *osbuf = pPacket->pPktContext;
353 A_ASSERT(osbuf != NULL);
354 A_ASSERT(pHcidevInfo != NULL);
355
356 if (pPacket->Status) {
357 if ((pPacket->Status != A_ECANCELED) && (pPacket->Status != A_NO_RESOURCE)) {
358 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: Send Packet Failed: %d \n",pPacket->Status));
359 }
360 }
361
362 FreeHTCStruct(pHcidevInfo,pPacket);
363 FreeBtOsBuf(pHcidevInfo,osbuf);
364
365}
366
367static void ar6000_hci_pkt_recv(void *pContext, struct htc_packet *pPacket)
368{
369 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
370 struct sk_buff *skb;
371
372 A_ASSERT(pHcidevInfo != NULL);
373 skb = (struct sk_buff *)pPacket->pPktContext;
374 A_ASSERT(skb != NULL);
375
376 do {
377
378 if (pPacket->Status) {
379 break;
380 }
381
382 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
383 ("HCI Bridge, packet received type : %d len:%d \n",
384 HCI_GET_PACKET_TYPE(pPacket),pPacket->ActualLength));
385
386 /* set the actual buffer position in the os buffer, HTC recv buffers posted to HCI are set
387 * to fill the front of the buffer */
388 A_NETBUF_PUT(skb,pPacket->ActualLength + pHcidevInfo->HCIProps.HeadRoom);
389 A_NETBUF_PULL(skb,pHcidevInfo->HCIProps.HeadRoom);
390
391 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
392 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("<<< Recv HCI %s packet len:%d \n",
393 (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) ? "EVENT" : "ACL",
394 skb->len));
395 AR_DEBUG_PRINTBUF(skb->data, skb->len,"BT HCI RECV Packet Dump");
396 }
397
398 if (pHcidevInfo->HciNormalMode) {
399 /* indicate the packet */
400 if (bt_indicate_recv(pHcidevInfo,HCI_GET_PACKET_TYPE(pPacket),skb)) {
401 /* bt stack accepted the packet */
402 skb = NULL;
403 }
404 break;
405 }
406
407 /* for testing, indicate packet to the network stack */
408#ifdef EXPORT_HCI_BRIDGE_INTERFACE
409 skb->dev = (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice);
410 if ((((struct net_device *)pHcidevInfo->HCITransHdl.netDevice)->flags & IFF_UP) == IFF_UP) {
411 skb->protocol = eth_type_trans(skb, (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice));
412#else
413 skb->dev = pHcidevInfo->ar->arNetDev;
414 if ((pHcidevInfo->ar->arNetDev->flags & IFF_UP) == IFF_UP) {
415 skb->protocol = eth_type_trans(skb, pHcidevInfo->ar->arNetDev);
416#endif
417 netif_rx(skb);
418 skb = NULL;
419 }
420
421 } while (false);
422
423 FreeHTCStruct(pHcidevInfo,pPacket);
424
425 if (skb != NULL) {
426 /* packet was not accepted, free it */
427 FreeBtOsBuf(pHcidevInfo,skb);
428 }
429
430}
431
432static void ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable)
433{
434 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
435 int refillCount;
436
437 if (Type == HCI_ACL_TYPE) {
438 refillCount = MAX_ACL_RECV_BUFS - BuffersAvailable;
439 } else {
440 refillCount = MAX_EVT_RECV_BUFS - BuffersAvailable;
441 }
442
443 if (refillCount > 0) {
444 RefillRecvBuffers(pHcidevInfo,Type,refillCount);
445 }
446
447}
448
449static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, struct htc_packet *pPacket)
450{
451 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
452 HCI_SEND_FULL_ACTION action = HCI_SEND_FULL_KEEP;
453
454 if (!pHcidevInfo->HciNormalMode) {
455 /* for epping testing, check packet tag, some epping packets are
456 * special and cannot be dropped */
457 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_DATA_PKT_TAG) {
458 action = HCI_SEND_FULL_DROP;
459 }
460 }
461
462 return action;
463}
464
465#ifdef EXPORT_HCI_BRIDGE_INTERFACE
466int ar6000_setup_hci(void *ar)
467#else
468int ar6000_setup_hci(struct ar6_softc *ar)
469#endif
470{
471 struct hci_transport_config_info config;
472 int status = 0;
473 int i;
474 struct htc_packet *pPacket;
475 struct ar6k_hci_bridge_info *pHcidevInfo;
476
477
478 do {
479
480 pHcidevInfo = (struct ar6k_hci_bridge_info *)A_MALLOC(sizeof(struct ar6k_hci_bridge_info));
481
482 if (NULL == pHcidevInfo) {
483 status = A_NO_MEMORY;
484 break;
485 }
486
487 A_MEMZERO(pHcidevInfo, sizeof(struct ar6k_hci_bridge_info));
488#ifdef EXPORT_HCI_BRIDGE_INTERFACE
489 g_pHcidevInfo = pHcidevInfo;
490 pHcidevInfo->HCITransHdl = *(struct hci_transport_misc_handles *)ar;
491#else
492 ar->hcidev_info = pHcidevInfo;
493 pHcidevInfo->ar = ar;
494#endif
495 spin_lock_init(&pHcidevInfo->BridgeLock);
496 INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead);
497
498 ar->exitCallback = AR3KConfigureExit;
499
500 status = bt_setup_hci(pHcidevInfo);
501 if (status) {
502 break;
503 }
504
505 if (pHcidevInfo->HciNormalMode) {
506 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in normal mode... \n"));
507 } else {
508 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n"));
509 }
510
511 pHcidevInfo->pHTCStructAlloc = (u8 *)A_MALLOC((sizeof(struct htc_packet)) * NUM_HTC_PACKET_STRUCTS);
512
513 if (NULL == pHcidevInfo->pHTCStructAlloc) {
514 status = A_NO_MEMORY;
515 break;
516 }
517
518 pPacket = (struct htc_packet *)pHcidevInfo->pHTCStructAlloc;
519 for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) {
520 FreeHTCStruct(pHcidevInfo,pPacket);
521 }
522
523 A_MEMZERO(&config,sizeof(struct hci_transport_config_info));
524 config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2;
525 config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2;
526 config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH;
527 config.pContext = pHcidevInfo;
528 config.TransportFailure = ar6000_hci_transport_failure;
529 config.TransportReady = ar6000_hci_transport_ready;
530 config.TransportRemoved = ar6000_hci_transport_removed;
531 config.pHCISendComplete = ar6000_hci_send_complete;
532 config.pHCIPktRecv = ar6000_hci_pkt_recv;
533 config.pHCIPktRecvRefill = ar6000_hci_pkt_refill;
534 config.pHCISendFull = ar6000_hci_pkt_send_full;
535
536#ifdef EXPORT_HCI_BRIDGE_INTERFACE
537 pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcHandle, &config);
538#else
539 pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config);
540#endif
541
542 if (NULL == pHcidevInfo->pHCIDev) {
543 status = A_ERROR;
544 }
545
546 } while (false);
547
548 if (status) {
549 if (pHcidevInfo != NULL) {
550 if (NULL == pHcidevInfo->pHCIDev) {
551 /* GMBOX may not be present in older chips */
552 /* just return success */
553 status = 0;
554 }
555 }
556 ar6000_cleanup_hci(ar);
557 }
558
559 return status;
560}
561
562#ifdef EXPORT_HCI_BRIDGE_INTERFACE
563void ar6000_cleanup_hci(void *ar)
564#else
565void ar6000_cleanup_hci(struct ar6_softc *ar)
566#endif
567{
568#ifdef EXPORT_HCI_BRIDGE_INTERFACE
569 struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo;
570#else
571 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
572#endif
573
574 if (pHcidevInfo != NULL) {
575 bt_cleanup_hci(pHcidevInfo);
576
577 if (pHcidevInfo->pHCIDev != NULL) {
578 HCI_TransportStop(pHcidevInfo->pHCIDev);
579 HCI_TransportDetach(pHcidevInfo->pHCIDev);
580 pHcidevInfo->pHCIDev = NULL;
581 }
582
583 if (pHcidevInfo->pHTCStructAlloc != NULL) {
584 kfree(pHcidevInfo->pHTCStructAlloc);
585 pHcidevInfo->pHTCStructAlloc = NULL;
586 }
587
588 kfree(pHcidevInfo);
589#ifndef EXPORT_HCI_BRIDGE_INTERFACE
590 ar->hcidev_info = NULL;
591#endif
592 }
593
594
595}
596
597#ifdef EXPORT_HCI_BRIDGE_INTERFACE
598int hci_test_send(void *ar, struct sk_buff *skb)
599#else
600int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb)
601#endif
602{
603 int status = 0;
604 int length;
605 EPPING_HEADER *pHeader;
606 struct htc_packet *pPacket;
607 HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
608#ifdef EXPORT_HCI_BRIDGE_INTERFACE
609 struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo;
610#else
611 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
612#endif
613
614 do {
615
616 if (NULL == pHcidevInfo) {
617 status = A_ERROR;
618 break;
619 }
620
621 if (NULL == pHcidevInfo->pHCIDev) {
622 status = A_ERROR;
623 break;
624 }
625
626 if (pHcidevInfo->HciNormalMode) {
627 /* this interface cannot run when normal WMI is running */
628 status = A_ERROR;
629 break;
630 }
631
632 pHeader = (EPPING_HEADER *)A_NETBUF_DATA(skb);
633
634 if (!IS_EPPING_PACKET(pHeader)) {
635 status = A_EINVAL;
636 break;
637 }
638
639 if (IS_EPING_PACKET_NO_DROP(pHeader)) {
640 htc_tag = AR6K_CONTROL_PKT_TAG;
641 }
642
643 length = sizeof(EPPING_HEADER) + pHeader->DataLength;
644
645 pPacket = AllocHTCStruct(pHcidevInfo);
646 if (NULL == pPacket) {
647 status = A_NO_MEMORY;
648 break;
649 }
650
651 SET_HTC_PACKET_INFO_TX(pPacket,
652 skb,
653 A_NETBUF_DATA(skb),
654 length,
655 HCI_ACL_TYPE, /* send every thing out as ACL */
656 htc_tag);
657
658 HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false);
659 pPacket = NULL;
660
661 } while (false);
662
663 return status;
664}
665
666void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig)
667{
668 struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
669 struct ar3k_config_info *config = (struct ar3k_config_info *)ar3kconfig;
670
671 config->pHCIDev = pHcidevInfo->pHCIDev;
672 config->pHCIProps = &pHcidevInfo->HCIProps;
673 config->pHIFDevice = ar->arHifDevice;
674 config->pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
675 config->Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
676 config->AR3KBaudRate = 115200;
677}
678
679#ifdef CONFIG_BLUEZ_HCI_BRIDGE
680/*** BT Stack Entrypoints *******/
681
682/*
683 * bt_open - open a handle to the device
684*/
685static int bt_open(struct hci_dev *hdev)
686{
687
688 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_open - enter - x\n"));
689 set_bit(HCI_RUNNING, &hdev->flags);
690 set_bit(HCI_UP, &hdev->flags);
691 set_bit(HCI_INIT, &hdev->flags);
692 return 0;
693}
694
695/*
696 * bt_close - close handle to the device
697*/
698static int bt_close(struct hci_dev *hdev)
699{
700 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_close - enter\n"));
701 clear_bit(HCI_RUNNING, &hdev->flags);
702 return 0;
703}
704
705/*
706 * bt_send_frame - send data frames
707*/
708static int bt_send_frame(struct sk_buff *skb)
709{
710 struct hci_dev *hdev = (struct hci_dev *)skb->dev;
711 HCI_TRANSPORT_PACKET_TYPE type;
712 struct ar6k_hci_bridge_info *pHcidevInfo;
713 struct htc_packet *pPacket;
714 int status = 0;
715 struct sk_buff *txSkb = NULL;
716
717 if (!hdev) {
718 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_send_frame - no device\n"));
719 return -ENODEV;
720 }
721
722 if (!test_bit(HCI_RUNNING, &hdev->flags)) {
723 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_send_frame - not open\n"));
724 return -EBUSY;
725 }
726
727 pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data;
728 A_ASSERT(pHcidevInfo != NULL);
729
730 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb)->pkt_type));
731 type = HCI_COMMAND_TYPE;
732
733 switch (bt_cb(skb)->pkt_type) {
734 case HCI_COMMAND_PKT:
735 type = HCI_COMMAND_TYPE;
736 hdev->stat.cmd_tx++;
737 break;
738
739 case HCI_ACLDATA_PKT:
740 type = HCI_ACL_TYPE;
741 hdev->stat.acl_tx++;
742 break;
743
744 case HCI_SCODATA_PKT:
745 /* we don't support SCO over the bridge */
746 kfree_skb(skb);
747 return 0;
748 default:
749 A_ASSERT(false);
750 kfree_skb(skb);
751 return 0;
752 }
753
754 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
755 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(">>> Send HCI %s packet len: %d\n",
756 (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL",
757 skb->len));
758 if (type == HCI_COMMAND_TYPE) {
759 u16 opcode = HCI_GET_OP_CODE(skb->data);
760 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" HCI Command: OGF:0x%X OCF:0x%X \r\n",
761 opcode >> 10, opcode & 0x3FF));
762 }
763 AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump");
764 }
765
766 do {
767
768 txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom +
769 pHcidevInfo->HCIProps.TailRoom + skb->len,
770 GFP_ATOMIC);
771
772 if (txSkb == NULL) {
773 status = A_NO_MEMORY;
774 break;
775 }
776
777 bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type;
778 txSkb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
779 skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom);
780 memcpy(txSkb->data, skb->data, skb->len);
781 skb_put(txSkb,skb->len);
782
783 pPacket = AllocHTCStruct(pHcidevInfo);
784 if (NULL == pPacket) {
785 status = A_NO_MEMORY;
786 break;
787 }
788
789 /* HCI packet length here doesn't include the 1-byte transport header which
790 * will be handled by the HCI transport layer. Enough headroom has already
791 * been reserved above for the transport header
792 */
793 SET_HTC_PACKET_INFO_TX(pPacket,
794 txSkb,
795 txSkb->data,
796 txSkb->len,
797 type,
798 AR6K_CONTROL_PKT_TAG); /* HCI packets cannot be dropped */
799
800 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: bt_send_frame skb:0x%lX \n",(unsigned long)txSkb));
801 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: type:%d, Total Length:%d Bytes \n",
802 type, txSkb->len));
803
804 status = HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false);
805 pPacket = NULL;
806 txSkb = NULL;
807
808 } while (false);
809
810 if (txSkb != NULL) {
811 kfree_skb(txSkb);
812 }
813
814 kfree_skb(skb);
815
816 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("-bt_send_frame \n"));
817 return 0;
818}
819
820/*
821 * bt_ioctl - ioctl processing
822*/
823static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
824{
825 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_ioctl - enter\n"));
826 return -ENOIOCTLCMD;
827}
828
829/*
830 * bt_flush - flush outstandingbpackets
831*/
832static int bt_flush(struct hci_dev *hdev)
833{
834 struct ar6k_hci_bridge_info *pHcidevInfo;
835
836 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_flush - enter\n"));
837
838 pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data;
839
840 /* TODO??? */
841
842 return 0;
843}
844
845
846/*
847 * bt_destruct -
848*/
849static void bt_destruct(struct hci_dev *hdev)
850{
851 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_destruct - enter\n"));
852 /* nothing to do here */
853}
854
855static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
856{
857 int status = 0;
858 struct hci_dev *pHciDev = NULL;
859 struct hif_device_os_device_info osDevInfo;
860
861 if (!setupbtdev) {
862 return 0;
863 }
864
865 do {
866
867 A_MEMZERO(&osDevInfo,sizeof(osDevInfo));
868 /* get the underlying OS device */
869#ifdef EXPORT_HCI_BRIDGE_INTERFACE
870 status = ar6000_get_hif_dev((struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice),
871 &osDevInfo);
872#else
873 status = HIFConfigureDevice(pHcidevInfo->ar->arHifDevice,
874 HIF_DEVICE_GET_OS_DEVICE,
875 &osDevInfo,
876 sizeof(osDevInfo));
877#endif
878
879 if (status) {
880 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to OS device info from HIF\n"));
881 break;
882 }
883
884 /* allocate a BT HCI struct for this device */
885 pHciDev = hci_alloc_dev();
886 if (NULL == pHciDev) {
887 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge - failed to allocate bt struct \n"));
888 status = A_NO_MEMORY;
889 break;
890 }
891 /* save the device, we'll register this later */
892 pHcidevInfo->pBtStackHCIDev = pHciDev;
893 SET_HCIDEV_DEV(pHciDev,osDevInfo.pOSDevice);
894 SET_HCI_BUS_TYPE(pHciDev, HCI_VIRTUAL, HCI_BREDR);
895 pHciDev->driver_data = pHcidevInfo;
896 pHciDev->open = bt_open;
897 pHciDev->close = bt_close;
898 pHciDev->send = bt_send_frame;
899 pHciDev->ioctl = bt_ioctl;
900 pHciDev->flush = bt_flush;
901 pHciDev->destruct = bt_destruct;
902 pHciDev->owner = THIS_MODULE;
903 /* driver is running in normal BT mode */
904 pHcidevInfo->HciNormalMode = true;
905
906 } while (false);
907
908 if (status) {
909 bt_cleanup_hci(pHcidevInfo);
910 }
911
912 return status;
913}
914
915static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
916{
917 int err;
918
919 if (pHcidevInfo->HciRegistered) {
920 pHcidevInfo->HciRegistered = false;
921 clear_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags);
922 clear_bit(HCI_UP, &pHcidevInfo->pBtStackHCIDev->flags);
923 clear_bit(HCI_INIT, &pHcidevInfo->pBtStackHCIDev->flags);
924 A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
925 /* unregister */
926 if ((err = hci_unregister_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
927 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to unregister with bluetooth %d\n",err));
928 }
929 }
930
931 kfree(pHcidevInfo->pBtStackHCIDev);
932 pHcidevInfo->pBtStackHCIDev = NULL;
933}
934
935static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
936{
937 int err;
938 int status = 0;
939
940 do {
941 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: registering HCI... \n"));
942 A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
943 /* mark that we are registered */
944 pHcidevInfo->HciRegistered = true;
945 if ((err = hci_register_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
946 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to register with bluetooth %d\n",err));
947 pHcidevInfo->HciRegistered = false;
948 status = A_ERROR;
949 break;
950 }
951
952 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: HCI registered \n"));
953
954 } while (false);
955
956 return status;
957}
958
959static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo,
960 HCI_TRANSPORT_PACKET_TYPE Type,
961 struct sk_buff *skb)
962{
963 u8 btType;
964 int len;
965 bool success = false;
966 BT_HCI_EVENT_HEADER *pEvent;
967
968 do {
969
970 if (!test_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags)) {
971 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_indicate_recv - not running\n"));
972 break;
973 }
974
975 switch (Type) {
976 case HCI_ACL_TYPE:
977 btType = HCI_ACLDATA_PKT;
978 break;
979 case HCI_EVENT_TYPE:
980 btType = HCI_EVENT_PKT;
981 break;
982 default:
983 btType = 0;
984 A_ASSERT(false);
985 break;
986 }
987
988 if (0 == btType) {
989 break;
990 }
991
992 /* set the final type */
993 bt_cb(skb)->pkt_type = btType;
994 /* set dev */
995 skb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
996 len = skb->len;
997
998 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_RECV)) {
999 if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
1000 pEvent = (BT_HCI_EVENT_HEADER *)skb->data;
1001 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, ("BT HCI EventCode: %d, len:%d \n",
1002 pEvent->EventCode, pEvent->ParamLength));
1003 }
1004 }
1005
1006 /* pass receive packet up the stack */
1007 if (hci_recv_frame(skb) != 0) {
1008 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: hci_recv_frame failed \n"));
1009 break;
1010 } else {
1011 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
1012 ("HCI Bridge: Indicated RCV of type:%d, Length:%d \n",btType,len));
1013 }
1014
1015 success = true;
1016
1017 } while (false);
1018
1019 return success;
1020}
1021
1022static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length)
1023{
1024 struct sk_buff *skb;
1025 /* in normal HCI mode we need to alloc from the bt core APIs */
1026 skb = bt_skb_alloc(Length, GFP_ATOMIC);
1027 if (NULL == skb) {
1028 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc bt sk_buff \n"));
1029 }
1030 return skb;
1031}
1032
1033static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb)
1034{
1035 kfree_skb(skb);
1036}
1037
1038#else // { CONFIG_BLUEZ_HCI_BRIDGE
1039
1040 /* stubs when we only want to test the HCI bridging Interface without the HT stack */
1041static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
1042{
1043 return 0;
1044}
1045static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
1046{
1047
1048}
1049static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
1050{
1051 A_ASSERT(false);
1052 return A_ERROR;
1053}
1054
1055static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo,
1056 HCI_TRANSPORT_PACKET_TYPE Type,
1057 struct sk_buff *skb)
1058{
1059 A_ASSERT(false);
1060 return false;
1061}
1062
1063static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length)
1064{
1065 A_ASSERT(false);
1066 return NULL;
1067}
1068static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb)
1069{
1070 A_ASSERT(false);
1071}
1072
1073#endif // } CONFIG_BLUEZ_HCI_BRIDGE
1074
1075#else // { ATH_AR6K_ENABLE_GMBOX
1076
1077 /* stubs when GMBOX support is not needed */
1078
1079#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1080int ar6000_setup_hci(void *ar)
1081#else
1082int ar6000_setup_hci(struct ar6_softc *ar)
1083#endif
1084{
1085 return 0;
1086}
1087
1088#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1089void ar6000_cleanup_hci(void *ar)
1090#else
1091void ar6000_cleanup_hci(struct ar6_softc *ar)
1092#endif
1093{
1094 return;
1095}
1096
1097#ifndef EXPORT_HCI_BRIDGE_INTERFACE
1098void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig)
1099{
1100 return;
1101}
1102#endif
1103
1104#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1105int hci_test_send(void *ar, struct sk_buff *skb)
1106#else
1107int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb)
1108#endif
1109{
1110 return -EOPNOTSUPP;
1111}
1112
1113#endif // } ATH_AR6K_ENABLE_GMBOX
1114
1115
1116#ifdef EXPORT_HCI_BRIDGE_INTERFACE
1117static int __init
1118hcibridge_init_module(void)
1119{
1120 int status;
1121 struct hci_transport_callbacks hciTransCallbacks;
1122
1123 hciTransCallbacks.setupTransport = ar6000_setup_hci;
1124 hciTransCallbacks.cleanupTransport = ar6000_cleanup_hci;
1125
1126 status = ar6000_register_hci_transport(&hciTransCallbacks);
1127 if (status)
1128 return -ENODEV;
1129
1130 return 0;
1131}
1132
1133static void __exit
1134hcibridge_cleanup_module(void)
1135{
1136}
1137
1138module_init(hcibridge_init_module);
1139module_exit(hcibridge_cleanup_module);
1140MODULE_LICENSE("Dual BSD/GPL");
1141#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h
new file mode 100644
index 00000000000..80cef77738f
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h
@@ -0,0 +1,776 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _AR6000_H_
25#define _AR6000_H_
26
27#include <linux/init.h>
28#include <linux/sched.h>
29#include <linux/spinlock.h>
30#include <linux/if_ether.h>
31#include <linux/etherdevice.h>
32#include <net/iw_handler.h>
33#include <linux/if_arp.h>
34#include <linux/ip.h>
35#include <linux/wireless.h>
36#include <net/cfg80211.h>
37#include <linux/module.h>
38#include <asm/io.h>
39
40#include <a_config.h>
41#include <athdefs.h>
42#include "a_osapi.h"
43#include "htc_api.h"
44#include "wmi.h"
45#include "a_drv.h"
46#include "bmi.h"
47#include <ieee80211.h>
48#include <ieee80211_ioctl.h>
49#include <wlan_api.h>
50#include <wmi_api.h>
51#include "pkt_log.h"
52#include "aggr_recv_api.h"
53#include <host_version.h>
54#include <linux/rtnetlink.h>
55#include <linux/moduleparam.h>
56#include "ar6000_api.h"
57#ifdef CONFIG_HOST_TCMD_SUPPORT
58#include <testcmd.h>
59#endif
60#include <linux/firmware.h>
61
62#include "targaddrs.h"
63#include "dbglog_api.h"
64#include "ar6000_diag.h"
65#include "common_drv.h"
66#include "roaming.h"
67#include "hci_transport_api.h"
68#define ATH_MODULE_NAME driver
69#include "a_debug.h"
70#include "hw/apb_map.h"
71#include "hw/rtc_reg.h"
72#include "hw/mbox_reg.h"
73#include "gpio_reg.h"
74
75#define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0)
76#define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1)
77#define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2)
78#define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3)
79#define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4)
80#define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5)
81#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
82#define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7)
83#define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8)
84#define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9)
85
86#ifndef __dev_put
87#define __dev_put(dev) dev_put(dev)
88#endif
89
90
91#define USER_SAVEDKEYS_STAT_INIT 0
92#define USER_SAVEDKEYS_STAT_RUN 1
93
94// TODO this needs to move into the AR_SOFTC struct
95struct USER_SAVEDKEYS {
96 struct ieee80211req_key ucast_ik;
97 struct ieee80211req_key bcast_ik;
98 CRYPTO_TYPE keyType;
99 bool keyOk;
100};
101
102#define DBG_INFO 0x00000001
103#define DBG_ERROR 0x00000002
104#define DBG_WARNING 0x00000004
105#define DBG_SDIO 0x00000008
106#define DBG_HIF 0x00000010
107#define DBG_HTC 0x00000020
108#define DBG_WMI 0x00000040
109#define DBG_WMI2 0x00000080
110#define DBG_DRIVER 0x00000100
111
112#define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING)
113
114
115int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
116int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
117
118#ifdef __cplusplus
119extern "C" {
120#endif
121
122#define MAX_AR6000 1
123#define AR6000_MAX_RX_BUFFERS 16
124#define AR6000_BUFFER_SIZE 1664
125#define AR6000_MAX_AMSDU_RX_BUFFERS 4
126#define AR6000_AMSDU_REFILL_THRESHOLD 3
127#define AR6000_AMSDU_BUFFER_SIZE (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128)
128#define AR6000_MAX_RX_MESSAGE_SIZE (max(WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH,WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))
129
130#define AR6000_TX_TIMEOUT 10
131#define AR6000_ETH_ADDR_LEN 6
132#define AR6000_MAX_ENDPOINTS 4
133#define MAX_NODE_NUM 15
134/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
135#define MAX_DEF_COOKIE_NUM 180
136#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */
137#define MAX_COOKIE_NUM (MAX_DEF_COOKIE_NUM + MAX_HI_COOKIE_NUM)
138
139/* MAX_DEFAULT_SEND_QUEUE_DEPTH is used to set the default queue depth for the
140 * WMM send queues. If a queue exceeds this depth htc will query back to the
141 * OS specific layer by calling EpSendFull(). This gives the OS layer the
142 * opportunity to drop the packet if desired. Therefore changing
143 * MAX_DEFAULT_SEND_QUEUE_DEPTH does not affect resource utilization but
144 * does impact the threshold used to identify if a packet should be
145 * dropped. */
146#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
147
148#define AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT 1
149#define AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT 1
150#define A_DISCONNECT_TIMER_INTERVAL 10 * 1000
151#define A_DEFAULT_LISTEN_INTERVAL 100
152#define A_MAX_WOW_LISTEN_INTERVAL 1000
153
154enum {
155 DRV_HB_CHALLENGE = 0,
156 APP_HB_CHALLENGE
157};
158
159enum {
160 WLAN_INIT_MODE_NONE = 0,
161 WLAN_INIT_MODE_USR,
162 WLAN_INIT_MODE_UDEV,
163 WLAN_INIT_MODE_DRV
164};
165
166/* Suspend - configuration */
167enum {
168 WLAN_SUSPEND_CUT_PWR = 0,
169 WLAN_SUSPEND_DEEP_SLEEP,
170 WLAN_SUSPEND_WOW,
171 WLAN_SUSPEND_CUT_PWR_IF_BT_OFF
172};
173
174/* WiFi OFF - configuration */
175enum {
176 WLAN_OFF_CUT_PWR = 0,
177 WLAN_OFF_DEEP_SLEEP,
178};
179
180/* WLAN low power state */
181enum {
182 WLAN_POWER_STATE_ON = 0,
183 WLAN_POWER_STATE_CUT_PWR = 1,
184 WLAN_POWER_STATE_DEEP_SLEEP,
185 WLAN_POWER_STATE_WOW
186};
187
188/* WLAN WoW State */
189enum {
190 WLAN_WOW_STATE_NONE = 0,
191 WLAN_WOW_STATE_SUSPENDED,
192 WLAN_WOW_STATE_SUSPENDING
193};
194
195
196typedef enum _AR6K_BIN_FILE {
197 AR6K_OTP_FILE,
198 AR6K_FIRMWARE_FILE,
199 AR6K_PATCH_FILE,
200 AR6K_BOARD_DATA_FILE,
201} AR6K_BIN_FILE;
202
203#ifdef SETUPHCI_ENABLED
204#define SETUPHCI_DEFAULT 1
205#else
206#define SETUPHCI_DEFAULT 0
207#endif /* SETUPHCI_ENABLED */
208
209#ifdef SETUPBTDEV_ENABLED
210#define SETUPBTDEV_DEFAULT 1
211#else
212#define SETUPBTDEV_DEFAULT 0
213#endif /* SETUPBTDEV_ENABLED */
214
215#ifdef ENABLEUARTPRINT_SET
216#define ENABLEUARTPRINT_DEFAULT 1
217#else
218#define ENABLEUARTPRINT_DEFAULT 0
219#endif /* ENABLEARTPRINT_SET */
220
221#ifdef ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER
222#define NOHIFSCATTERSUPPORT_DEFAULT 1
223#else /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */
224#define NOHIFSCATTERSUPPORT_DEFAULT 0
225#endif /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */
226
227
228#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE)
229
230#ifdef CONFIG_AR600x_BT_QCOM
231#define ATH6KL_BT_DEV 1
232#elif defined(CONFIG_AR600x_BT_CSR)
233#define ATH6KL_BT_DEV 2
234#else
235#define ATH6KL_BT_DEV 3
236#endif
237
238#ifdef CONFIG_AR600x_DUAL_ANTENNA
239#define ATH6KL_BT_ANTENNA 2
240#else
241#define ATH6KL_BT_ANTENNA 1
242#endif
243
244#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */
245
246#ifdef AR600x_BT_AR3001
247#define AR3KHCIBAUD_DEFAULT 3000000
248#define HCIUARTSCALE_DEFAULT 1
249#define HCIUARTSTEP_DEFAULT 8937
250#else
251#define AR3KHCIBAUD_DEFAULT 0
252#define HCIUARTSCALE_DEFAULT 0
253#define HCIUARTSTEP_DEFAULT 0
254#endif /* AR600x_BT_AR3001 */
255
256#define WLAN_INIT_MODE_DEFAULT WLAN_INIT_MODE_DRV
257
258#define AR6K_PATCH_DOWNLOAD_ADDRESS(_param, _ver) do { \
259 if ((_ver) == AR6003_REV1_VERSION) { \
260 (_param) = AR6003_REV1_PATCH_DOWNLOAD_ADDRESS; \
261 } else if ((_ver) == AR6003_REV2_VERSION) { \
262 (_param) = AR6003_REV2_PATCH_DOWNLOAD_ADDRESS; \
263 } else { \
264 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
265 A_ASSERT(0); \
266 } \
267} while (0)
268
269#define AR6K_DATA_DOWNLOAD_ADDRESS(_param, _ver) do { \
270 if ((_ver) == AR6003_REV1_VERSION) { \
271 (_param) = AR6003_REV1_DATA_DOWNLOAD_ADDRESS; \
272 } else if ((_ver) == AR6003_REV2_VERSION) { \
273 (_param) = AR6003_REV2_DATA_DOWNLOAD_ADDRESS; \
274 } else { \
275 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
276 A_ASSERT(0); \
277 } \
278} while (0)
279
280#define AR6K_DATASET_PATCH_ADDRESS(_param, _ver) do { \
281 if ((_ver) == AR6003_REV2_VERSION) { \
282 (_param) = AR6003_REV2_DATASET_PATCH_ADDRESS; \
283 } else if ((_ver) == AR6003_REV3_VERSION) { \
284 (_param) = AR6003_REV3_DATASET_PATCH_ADDRESS; \
285 } else { \
286 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
287 A_ASSERT(0); \
288 } \
289} while (0)
290
291#define AR6K_APP_LOAD_ADDRESS(_param, _ver) do { \
292 if ((_ver) == AR6003_REV2_VERSION) { \
293 (_param) = AR6003_REV2_APP_LOAD_ADDRESS; \
294 } else if ((_ver) == AR6003_REV3_VERSION) { \
295 (_param) = AR6003_REV3_APP_LOAD_ADDRESS; \
296 } else { \
297 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
298 A_ASSERT(0); \
299 } \
300} while (0)
301
302#define AR6K_APP_START_OVERRIDE_ADDRESS(_param, _ver) do { \
303 if ((_ver) == AR6003_REV2_VERSION) { \
304 (_param) = AR6003_REV2_APP_START_OVERRIDE; \
305 } else if ((_ver) == AR6003_REV3_VERSION) { \
306 (_param) = AR6003_REV3_APP_START_OVERRIDE; \
307 } else { \
308 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
309 A_ASSERT(0); \
310 } \
311} while (0)
312
313/* AR6003 1.0 definitions */
314#define AR6003_REV1_VERSION 0x300002ba
315#define AR6003_REV1_DATA_DOWNLOAD_ADDRESS AR6003_REV1_OTP_DATA_ADDRESS
316#define AR6003_REV1_PATCH_DOWNLOAD_ADDRESS 0x57ea6c
317#define AR6003_REV1_OTP_FILE "ath6k/AR6003/hw1.0/otp.bin.z77"
318#define AR6003_REV1_FIRMWARE_FILE "ath6k/AR6003/hw1.0/athwlan.bin.z77"
319#define AR6003_REV1_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw1.0/athtcmd_ram.bin"
320#define AR6003_REV1_ART_FIRMWARE_FILE "ath6k/AR6003/hw1.0/device.bin"
321#define AR6003_REV1_PATCH_FILE "ath6k/AR6003/hw1.0/data.patch.bin"
322#define AR6003_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw1.0/endpointping.bin"
323#ifdef CONFIG_AR600x_SD31_XXX
324#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD31.bin"
325#elif defined(CONFIG_AR600x_SD32_XXX)
326#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD32.bin"
327#elif defined(CONFIG_AR600x_WB31_XXX)
328#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.WB31.bin"
329#else
330#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.CUSTOM.bin"
331#endif /* Board Data File */
332
333/* AR6003 2.0 definitions */
334#define AR6003_REV2_VERSION 0x30000384
335#define AR6003_REV2_DATA_DOWNLOAD_ADDRESS AR6003_REV2_OTP_DATA_ADDRESS
336#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910
337#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
338#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
339#define AR6003_REV2_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
340#define AR6003_REV2_ART_FIRMWARE_FILE "ath6k/AR6003/hw2.0/device.bin"
341#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
342#define AR6003_REV2_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.0/endpointping.bin"
343#ifdef CONFIG_AR600x_SD31_XXX
344#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
345#elif defined(CONFIG_AR600x_SD32_XXX)
346#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD32.bin"
347#elif defined(CONFIG_AR600x_WB31_XXX)
348#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.WB31.bin"
349#else
350#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.CUSTOM.bin"
351#endif /* Board Data File */
352
353/* AR6003 3.0 definitions */
354#define AR6003_REV3_VERSION 0x30000582
355#define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin"
356#define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin"
357#define AR6003_REV3_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin"
358#define AR6003_REV3_ART_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/device.bin"
359#define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin"
360#define AR6003_REV3_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/endpointping.bin"
361#ifdef CONFIG_AR600x_SD31_XXX
362#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
363#elif defined(CONFIG_AR600x_SD32_XXX)
364#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.SD32.bin"
365#elif defined(CONFIG_AR600x_WB31_XXX)
366#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.WB31.bin"
367#else
368#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.CUSTOM.bin"
369#endif /* Board Data File */
370
371
372/* Power states */
373enum {
374 WLAN_PWR_CTRL_UP = 0,
375 WLAN_PWR_CTRL_CUT_PWR,
376 WLAN_PWR_CTRL_DEEP_SLEEP,
377 WLAN_PWR_CTRL_WOW,
378 WLAN_PWR_CTRL_DEEP_SLEEP_DISABLED
379};
380
381/* HTC RAW streams */
382typedef enum _HTC_RAW_STREAM_ID {
383 HTC_RAW_STREAM_NOT_MAPPED = -1,
384 HTC_RAW_STREAM_0 = 0,
385 HTC_RAW_STREAM_1 = 1,
386 HTC_RAW_STREAM_2 = 2,
387 HTC_RAW_STREAM_3 = 3,
388 HTC_RAW_STREAM_NUM_MAX
389} HTC_RAW_STREAM_ID;
390
391#define RAW_HTC_READ_BUFFERS_NUM 4
392#define RAW_HTC_WRITE_BUFFERS_NUM 4
393
394#define HTC_RAW_BUFFER_SIZE 1664
395
396typedef struct {
397 int currPtr;
398 int length;
399 unsigned char data[HTC_RAW_BUFFER_SIZE];
400 struct htc_packet HTCPacket;
401} raw_htc_buffer;
402
403#ifdef CONFIG_HOST_TCMD_SUPPORT
404/*
405 * add TCMD_MODE besides wmi and bypasswmi
406 * in TCMD_MODE, only few TCMD releated wmi commands
407 * counld be hanlder
408 */
409enum {
410 AR6000_WMI_MODE = 0,
411 AR6000_BYPASS_MODE,
412 AR6000_TCMD_MODE,
413 AR6000_WLAN_MODE
414};
415#endif /* CONFIG_HOST_TCMD_SUPPORT */
416
417struct ar_wep_key {
418 u8 arKeyIndex;
419 u8 arKeyLen;
420 u8 arKey[64];
421} ;
422
423struct ar_key {
424 u8 key[WLAN_MAX_KEY_LEN];
425 u8 key_len;
426 u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
427 u8 seq_len;
428 u32 cipher;
429};
430
431enum {
432 SME_DISCONNECTED,
433 SME_CONNECTING,
434 SME_CONNECTED
435};
436
437struct ar_node_mapping {
438 u8 macAddress[6];
439 u8 epId;
440 u8 txPending;
441};
442
443struct ar_cookie {
444 unsigned long arc_bp[2]; /* Must be first field */
445 struct htc_packet HtcPkt; /* HTC packet wrapper */
446 struct ar_cookie *arc_list_next;
447};
448
449struct ar_hb_chlng_resp {
450 A_TIMER timer;
451 u32 frequency;
452 u32 seqNum;
453 bool outstanding;
454 u8 missCnt;
455 u8 missThres;
456};
457
458/* Per STA data, used in AP mode */
459/*TODO: All this should move to OS independent dir */
460
461#define STA_PWR_MGMT_MASK 0x1
462#define STA_PWR_MGMT_SHIFT 0x0
463#define STA_PWR_MGMT_AWAKE 0x0
464#define STA_PWR_MGMT_SLEEP 0x1
465
466#define STA_SET_PWR_SLEEP(sta) (sta->flags |= (STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT))
467#define STA_CLR_PWR_SLEEP(sta) (sta->flags &= ~(STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT))
468#define STA_IS_PWR_SLEEP(sta) ((sta->flags >> STA_PWR_MGMT_SHIFT) & STA_PWR_MGMT_MASK)
469
470#define STA_PS_POLLED_MASK 0x1
471#define STA_PS_POLLED_SHIFT 0x1
472#define STA_SET_PS_POLLED(sta) (sta->flags |= (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
473#define STA_CLR_PS_POLLED(sta) (sta->flags &= ~(STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
474#define STA_IS_PS_POLLED(sta) (sta->flags & (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
475
476typedef struct {
477 u16 flags;
478 u8 mac[ATH_MAC_LEN];
479 u8 aid;
480 u8 keymgmt;
481 u8 ucipher;
482 u8 auth;
483 u8 wpa_ie[IEEE80211_MAX_IE];
484 A_NETBUF_QUEUE_T psq; /* power save q */
485 A_MUTEX_T psqLock;
486} sta_t;
487
488typedef struct ar6_raw_htc {
489 HTC_ENDPOINT_ID arRaw2EpMapping[HTC_RAW_STREAM_NUM_MAX];
490 HTC_RAW_STREAM_ID arEp2RawMapping[ENDPOINT_MAX];
491 struct semaphore raw_htc_read_sem[HTC_RAW_STREAM_NUM_MAX];
492 struct semaphore raw_htc_write_sem[HTC_RAW_STREAM_NUM_MAX];
493 wait_queue_head_t raw_htc_read_queue[HTC_RAW_STREAM_NUM_MAX];
494 wait_queue_head_t raw_htc_write_queue[HTC_RAW_STREAM_NUM_MAX];
495 raw_htc_buffer raw_htc_read_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_READ_BUFFERS_NUM];
496 raw_htc_buffer raw_htc_write_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_WRITE_BUFFERS_NUM];
497 bool write_buffer_available[HTC_RAW_STREAM_NUM_MAX];
498 bool read_buffer_available[HTC_RAW_STREAM_NUM_MAX];
499} AR_RAW_HTC_T;
500
501struct ar6_softc {
502 struct net_device *arNetDev; /* net_device pointer */
503 void *arWmi;
504 int arTxPending[ENDPOINT_MAX];
505 int arTotalTxDataPending;
506 u8 arNumDataEndPts;
507 bool arWmiEnabled;
508 bool arWmiReady;
509 bool arConnected;
510 HTC_HANDLE arHtcTarget;
511 void *arHifDevice;
512 spinlock_t arLock;
513 struct semaphore arSem;
514 int arSsidLen;
515 u_char arSsid[32];
516 u8 arNextMode;
517 u8 arNetworkType;
518 u8 arDot11AuthMode;
519 u8 arAuthMode;
520 u8 arPairwiseCrypto;
521 u8 arPairwiseCryptoLen;
522 u8 arGroupCrypto;
523 u8 arGroupCryptoLen;
524 u8 arDefTxKeyIndex;
525 struct ar_wep_key arWepKeyList[WMI_MAX_KEY_INDEX + 1];
526 u8 arBssid[6];
527 u8 arReqBssid[6];
528 u16 arChannelHint;
529 u16 arBssChannel;
530 u16 arListenIntervalB;
531 u16 arListenIntervalT;
532 struct ar6000_version arVersion;
533 u32 arTargetType;
534 s8 arRssi;
535 u8 arTxPwr;
536 bool arTxPwrSet;
537 s32 arBitRate;
538 struct net_device_stats arNetStats;
539 struct iw_statistics arIwStats;
540 s8 arNumChannels;
541 u16 arChannelList[32];
542 u32 arRegCode;
543 bool statsUpdatePending;
544 TARGET_STATS arTargetStats;
545 s8 arMaxRetries;
546 u8 arPhyCapability;
547#ifdef CONFIG_HOST_TCMD_SUPPORT
548 u32 arTargetMode;
549 void *tcmd_rx_report;
550 int tcmd_rx_report_len;
551#endif
552 AR6000_WLAN_STATE arWlanState;
553 struct ar_node_mapping arNodeMap[MAX_NODE_NUM];
554 u8 arIbssPsEnable;
555 u8 arNodeNum;
556 u8 arNexEpId;
557 struct ar_cookie *arCookieList;
558 u32 arCookieCount;
559 u32 arRateMask;
560 u8 arSkipScan;
561 u16 arBeaconInterval;
562 bool arConnectPending;
563 bool arWmmEnabled;
564 struct ar_hb_chlng_resp arHBChallengeResp;
565 u8 arKeepaliveConfigured;
566 u32 arMgmtFilter;
567 HTC_ENDPOINT_ID arAc2EpMapping[WMM_NUM_AC];
568 bool arAcStreamActive[WMM_NUM_AC];
569 u8 arAcStreamPriMap[WMM_NUM_AC];
570 u8 arHiAcStreamActivePri;
571 u8 arEp2AcMapping[ENDPOINT_MAX];
572 HTC_ENDPOINT_ID arControlEp;
573#ifdef HTC_RAW_INTERFACE
574 AR_RAW_HTC_T *arRawHtc;
575#endif
576 bool arNetQueueStopped;
577 bool arRawIfInit;
578 int arDeviceIndex;
579 struct common_credit_state_info arCreditStateInfo;
580 bool arWMIControlEpFull;
581 bool dbgLogFetchInProgress;
582 u8 log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE];
583 u32 log_cnt;
584 u32 dbglog_init_done;
585 u32 arConnectCtrlFlags;
586 s32 user_savedkeys_stat;
587 u32 user_key_ctrl;
588 struct USER_SAVEDKEYS user_saved_keys;
589 USER_RSSI_THOLD rssi_map[12];
590 u8 arUserBssFilter;
591 u16 ap_profile_flag; /* AP mode */
592 WMI_AP_ACL g_acl; /* AP mode */
593 sta_t sta_list[AP_MAX_NUM_STA]; /* AP mode */
594 u8 sta_list_index; /* AP mode */
595 struct ieee80211req_key ap_mode_bkey; /* AP mode */
596 A_NETBUF_QUEUE_T mcastpsq; /* power save q for Mcast frames */
597 A_MUTEX_T mcastpsqLock;
598 bool DTIMExpired; /* flag to indicate DTIM expired */
599 u8 intra_bss; /* enable/disable intra bss data forward */
600 void *aggr_cntxt;
601#ifndef EXPORT_HCI_BRIDGE_INTERFACE
602 void *hcidev_info;
603#endif
604 WMI_AP_MODE_STAT arAPStats;
605 u8 ap_hidden_ssid;
606 u8 ap_country_code[3];
607 u8 ap_wmode;
608 u8 ap_dtim_period;
609 u16 ap_beacon_interval;
610 u16 arRTS;
611 u16 arACS; /* AP mode - Auto Channel Selection */
612 struct htc_packet_queue amsdu_rx_buffer_queue;
613 bool bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */
614 A_TIMER disconnect_timer;
615 u8 rxMetaVersion;
616#ifdef WAPI_ENABLE
617 u8 arWapiEnable;
618#endif
619 WMI_BTCOEX_CONFIG_EVENT arBtcoexConfig;
620 WMI_BTCOEX_STATS_EVENT arBtcoexStats;
621 s32 (*exitCallback)(void *config); /* generic callback at AR6K exit */
622 struct hif_device_os_device_info osDevInfo;
623 struct wireless_dev *wdev;
624 struct cfg80211_scan_request *scan_request;
625 struct ar_key keys[WMI_MAX_KEY_INDEX + 1];
626 u32 smeState;
627 u16 arWlanPowerState;
628 bool arWlanOff;
629#ifdef CONFIG_PM
630 u16 arWowState;
631 bool arBTOff;
632 bool arBTSharing;
633 u16 arSuspendConfig;
634 u16 arWlanOffConfig;
635 u16 arWow2Config;
636#endif
637 u8 scan_triggered;
638 WMI_SCAN_PARAMS_CMD scParams;
639#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
640 u8 mcast_filters[MAC_MAX_FILTERS_PER_LIST][AR_MCAST_FILTER_MAC_ADDR_SIZE];
641 u8 bdaddr[6];
642 bool scanSpecificSsid;
643#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
644 void *arApDev;
645#endif
646 u8 arAutoAuthStage;
647
648 u8 *fw_otp;
649 size_t fw_otp_len;
650 u8 *fw;
651 size_t fw_len;
652 u8 *fw_patch;
653 size_t fw_patch_len;
654 u8 *fw_data;
655 size_t fw_data_len;
656};
657
658#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
659struct ar_virtual_interface {
660 struct net_device *arNetDev; /* net_device pointer */
661 struct ar6_softc *arDev; /* ar device pointer */
662 struct net_device *arStaNetDev; /* net_device pointer */
663};
664#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
665
666static inline void *ar6k_priv(struct net_device *dev)
667{
668 return (wdev_priv(dev->ieee80211_ptr));
669}
670
671#define SET_HCI_BUS_TYPE(pHciDev, __bus, __type) do { \
672 (pHciDev)->bus = (__bus); \
673 (pHciDev)->dev_type = (__type); \
674} while(0)
675
676#define GET_INODE_FROM_FILEP(filp) \
677 (filp)->f_path.dentry->d_inode
678
679#define arAc2EndpointID(ar,ac) (ar)->arAc2EpMapping[(ac)]
680#define arSetAc2EndpointIDMap(ar,ac,ep) \
681{ (ar)->arAc2EpMapping[(ac)] = (ep); \
682 (ar)->arEp2AcMapping[(ep)] = (ac); }
683#define arEndpoint2Ac(ar,ep) (ar)->arEp2AcMapping[(ep)]
684
685#define arRawIfEnabled(ar) (ar)->arRawIfInit
686#define arRawStream2EndpointID(ar,raw) (ar)->arRawHtc->arRaw2EpMapping[(raw)]
687#define arSetRawStream2EndpointIDMap(ar,raw,ep) \
688{ (ar)->arRawHtc->arRaw2EpMapping[(raw)] = (ep); \
689 (ar)->arRawHtc->arEp2RawMapping[(ep)] = (raw); }
690#define arEndpoint2RawStreamID(ar,ep) (ar)->arRawHtc->arEp2RawMapping[(ep)]
691
692struct ar_giwscan_param {
693 char *current_ev;
694 char *end_buf;
695 u32 bytes_needed;
696 struct iw_request_info *info;
697};
698
699#define AR6000_STAT_INC(ar, stat) (ar->arNetStats.stat++)
700
701#define AR6000_SPIN_LOCK(lock, param) do { \
702 if (irqs_disabled()) { \
703 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled:AR6000_LOCK\n")); \
704 } \
705 spin_lock_bh(lock); \
706} while (0)
707
708#define AR6000_SPIN_UNLOCK(lock, param) do { \
709 if (irqs_disabled()) { \
710 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled: AR6000_UNLOCK\n")); \
711 } \
712 spin_unlock_bh(lock); \
713} while (0)
714
715void ar6000_init_profile_info(struct ar6_softc *ar);
716void ar6000_install_static_wep_keys(struct ar6_softc *ar);
717int ar6000_init(struct net_device *dev);
718int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar);
719void ar6000_TxDataCleanup(struct ar6_softc *ar);
720int ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev);
721void ar6000_restart_endpoint(struct net_device *dev);
722void ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs);
723
724#ifdef HTC_RAW_INTERFACE
725
726#ifndef __user
727#define __user
728#endif
729
730int ar6000_htc_raw_open(struct ar6_softc *ar);
731int ar6000_htc_raw_close(struct ar6_softc *ar);
732ssize_t ar6000_htc_raw_read(struct ar6_softc *ar,
733 HTC_RAW_STREAM_ID StreamID,
734 char __user *buffer, size_t count);
735ssize_t ar6000_htc_raw_write(struct ar6_softc *ar,
736 HTC_RAW_STREAM_ID StreamID,
737 char __user *buffer, size_t count);
738
739#endif /* HTC_RAW_INTERFACE */
740
741/* AP mode */
742/*TODO: These routines should be moved to a file that is common across OS */
743sta_t *
744ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr);
745
746sta_t *
747ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid);
748
749u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason);
750
751/* HCI support */
752
753#ifndef EXPORT_HCI_BRIDGE_INTERFACE
754int ar6000_setup_hci(struct ar6_softc *ar);
755void ar6000_cleanup_hci(struct ar6_softc *ar);
756void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig);
757
758/* HCI bridge testing */
759int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb);
760#endif
761
762ATH_DEBUG_DECLARE_EXTERN(htc);
763ATH_DEBUG_DECLARE_EXTERN(wmi);
764ATH_DEBUG_DECLARE_EXTERN(bmi);
765ATH_DEBUG_DECLARE_EXTERN(hif);
766ATH_DEBUG_DECLARE_EXTERN(wlan);
767ATH_DEBUG_DECLARE_EXTERN(misc);
768
769extern u8 bcast_mac[];
770extern u8 null_mac[];
771
772#ifdef __cplusplus
773}
774#endif
775
776#endif /* _AR6000_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h
new file mode 100644
index 00000000000..39e0873aff2
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h
@@ -0,0 +1,36 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4// The software source and binaries included in this development package are
5// licensed, not sold. You, or your company, received the package under one
6// or more license agreements. The rights granted to you are specifically
7// listed in these license agreement(s). All other rights remain with Atheros
8// Communications, Inc., its subsidiaries, or the respective owner including
9// those listed on the included copyright notices. Distribution of any
10// portion of this package must be in strict compliance with the license
11// agreement(s) terms.
12// </copyright>
13//
14// <summary>
15// PAL driver for AR6003
16// </summary>
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// Author(s): ="Atheros"
21//==============================================================================
22#ifndef _AR6K_PAL_H_
23#define _AR6K_PAL_H_
24#define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0]))
25
26/* transmit packet reserve offset */
27#define TX_PACKET_RSV_OFFSET 32
28/* pal specific config structure */
29typedef bool (*ar6k_pal_recv_pkt_t)(void *pHciPalInfo, void *skb);
30typedef struct ar6k_pal_config_s
31{
32 ar6k_pal_recv_pkt_t fpar6k_pal_recv_pkt;
33}ar6k_pal_config_t;
34
35void register_pal_cb(ar6k_pal_config_t *palConfig_p);
36#endif /* _AR6K_PAL_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h
new file mode 100644
index 00000000000..184dbdb5049
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h
@@ -0,0 +1,190 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _AR6XAPI_LINUX_H
25#define _AR6XAPI_LINUX_H
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30struct ar6_softc;
31
32void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap,
33 u32 sw_ver, u32 abi_ver);
34int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid);
35void ar6000_connect_event(struct ar6_softc *ar, u16 channel,
36 u8 *bssid, u16 listenInterval,
37 u16 beaconInterval, NETWORK_TYPE networkType,
38 u8 beaconIeLen, u8 assocReqLen,
39 u8 assocRespLen,u8 *assocInfo);
40void ar6000_disconnect_event(struct ar6_softc *ar, u8 reason,
41 u8 *bssid, u8 assocRespLen,
42 u8 *assocInfo, u16 protocolReasonStatus);
43void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid,
44 bool ismcast);
45void ar6000_bitrate_rx(void *devt, s32 rateKbps);
46void ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList);
47void ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode);
48void ar6000_txPwr_rx(void *devt, u8 txPwr);
49void ar6000_keepalive_rx(void *devt, u8 configured);
50void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps,
51 WMI_NEIGHBOR_INFO *info);
52void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num);
53void ar6000_scanComplete_event(struct ar6_softc *ar, int status);
54void ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len);
55void ar6000_rssiThreshold_event(struct ar6_softc *ar,
56 WMI_RSSI_THRESHOLD_VAL newThreshold,
57 s16 rssi);
58void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal);
59void ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cac_indication,
60 u8 statusCode, u8 *tspecSuggestion);
61void ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel, u16 newChannel);
62void ar6000_hbChallengeResp_event(struct ar6_softc *, u32 cookie, u32 source);
63void
64ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl);
65
66void
67ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p);
68
69void
70ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters,
71 WMI_GET_WOW_LIST_REPLY *wow_reply);
72
73void ar6000_pmkid_list_event(void *devt, u8 numPMKID,
74 WMI_PMKID *pmkidList, u8 *bssidList);
75
76void ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values);
77void ar6000_gpio_data_rx(u32 reg_id, u32 value);
78void ar6000_gpio_ack_rx(void);
79
80s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt);
81s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi);
82s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above);
83
84void ar6000_dbglog_init_done(struct ar6_softc *ar);
85
86#ifdef CONFIG_HOST_TCMD_SUPPORT
87void ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len);
88#endif
89
90void ar6000_tx_retry_err_event(void *devt);
91
92void ar6000_snrThresholdEvent_rx(void *devt,
93 WMI_SNR_THRESHOLD_VAL newThreshold,
94 u8 snr);
95
96void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, u8 lqVal);
97
98
99void ar6000_ratemask_rx(void *devt, u32 ratemask);
100
101int ar6000_get_driver_cfg(struct net_device *dev,
102 u16 cfgParam,
103 void *result);
104void ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *data, int len);
105
106void ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped,
107 s8 *buffer, u32 length);
108
109int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar);
110
111void ar6000_peer_event(void *devt, u8 eventCode, u8 *bssid);
112
113void ar6000_indicate_tx_activity(void *devt, u8 trafficClass, bool Active);
114HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, u8 ac);
115u8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep );
116
117void ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len);
118
119void ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len) ;
120
121void ar6000_dset_open_req(void *devt,
122 u32 id,
123 u32 targ_handle,
124 u32 targ_reply_fn,
125 u32 targ_reply_arg);
126void ar6000_dset_close(void *devt, u32 access_cookie);
127void ar6000_dset_data_req(void *devt,
128 u32 access_cookie,
129 u32 offset,
130 u32 length,
131 u32 targ_buf,
132 u32 targ_reply_fn,
133 u32 targ_reply_arg);
134
135
136#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
137void prof_count_rx(unsigned int addr, unsigned int count);
138#endif
139
140u32 ar6000_getnodeAge (void);
141
142u32 ar6000_getclkfreq (void);
143
144int ar6000_ap_mode_profile_commit(struct ar6_softc *ar);
145
146struct ieee80211req_wpaie;
147int
148ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie);
149
150int is_iwioctl_allowed(u8 mode, u16 cmd);
151
152int is_xioctl_allowed(u8 mode, int cmd);
153
154void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid);
155
156void ar6000_dtimexpiry_event(struct ar6_softc *ar);
157
158void ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *cmd);
159void ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *cmd);
160void ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *cmd);
161void ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd);
162
163#ifdef WAPI_ENABLE
164int ap_set_wapi_key(struct ar6_softc *ar, void *ik);
165void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac);
166#endif
167
168int ar6000_connect_to_ap(struct ar6_softc *ar);
169int ar6000_disconnect(struct ar6_softc *ar);
170int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool suspending);
171int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state);
172int ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 state);
173
174#ifdef CONFIG_PM
175int ar6000_suspend_ev(void *context);
176int ar6000_resume_ev(void *context);
177int ar6000_power_change_ev(void *context, u32 config);
178void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent);
179#endif
180
181#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
182int ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname);
183int ar6000_remove_ap_interface(struct ar6_softc *ar);
184#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
185
186#ifdef __cplusplus
187}
188#endif
189
190#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h
new file mode 100644
index 00000000000..3d5f01da543
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h
@@ -0,0 +1,1217 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _ATHDRV_LINUX_H
25#define _ATHDRV_LINUX_H
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31
32/*
33 * There are two types of ioctl's here: Standard ioctls and
34 * eXtended ioctls. All extended ioctls (XIOCTL) are multiplexed
35 * off of the single ioctl command, AR6000_IOCTL_EXTENDED. The
36 * arguments for every XIOCTL starts with a 32-bit command word
37 * that is used to select which extended ioctl is in use. After
38 * the command word are command-specific arguments.
39 */
40
41/* Linux standard Wireless Extensions, private ioctl interfaces */
42#define IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0)
43#define IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1)
44#define IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2)
45#define IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+3)
46#define IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+4)
47#define IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+5)
48//#define IEEE80211_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+6)
49//#define IEEE80211_IOCTL_SETWMMPARAMS (SIOCIWFIRSTPRIV+7)
50//#define IEEE80211_IOCTL_GETWMMPARAMS (SIOCIWFIRSTPRIV+8)
51//#define IEEE80211_IOCTL_GETOPTIE (SIOCIWFIRSTPRIV+9)
52//#define IEEE80211_IOCTL_SETAUTHALG (SIOCIWFIRSTPRIV+10)
53#define IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+10)
54
55
56
57/* ====WMI Ioctls==== */
58/*
59 *
60 * Many ioctls simply provide WMI services to application code:
61 * an application makes such an ioctl call with a set of arguments
62 * that are packaged into the corresponding WMI message, and sent
63 * to the Target.
64 */
65
66#define AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+11)
67/*
68 * arguments:
69 * ar6000_version *revision
70 */
71
72#define AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+12)
73/*
74 * arguments:
75 * WMI_POWER_MODE_CMD pwrModeCmd (see include/wmi.h)
76 * uses: WMI_SET_POWER_MODE_CMDID
77 */
78
79#define AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+13)
80/*
81 * arguments:
82 * WMI_SCAN_PARAMS_CMD scanParams (see include/wmi.h)
83 * uses: WMI_SET_SCAN_PARAMS_CMDID
84 */
85
86#define AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+14)
87/*
88 * arguments:
89 * UINT32 listenInterval
90 * uses: WMI_SET_LISTEN_INT_CMDID
91 */
92
93#define AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+15)
94/*
95 * arguments:
96 * WMI_BSS_FILTER filter (see include/wmi.h)
97 * uses: WMI_SET_BSS_FILTER_CMDID
98 */
99
100#define AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16)
101/*
102 * arguments:
103 * WMI_CHANNEL_PARAMS_CMD chParams
104 * uses: WMI_SET_CHANNEL_PARAMS_CMDID
105 */
106
107#define AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17)
108/*
109 * arguments:
110 * WMI_PROBED_SSID_CMD probedSsids (see include/wmi.h)
111 * uses: WMI_SETPROBED_SSID_CMDID
112 */
113
114#define AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18)
115/*
116 * arguments:
117 * WMI_POWER_PARAMS_CMD powerParams (see include/wmi.h)
118 * uses: WMI_SET_POWER_PARAMS_CMDID
119 */
120
121#define AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19)
122/*
123 * arguments:
124 * WMI_ADD_BAD_AP_CMD badAPs (see include/wmi.h)
125 * uses: WMI_ADD_BAD_AP_CMDID
126 */
127
128#define AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20)
129/*
130 * arguments:
131 * ar6000_queuereq queueRequest (see below)
132 */
133
134#define AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21)
135/*
136 * arguments:
137 * WMI_CREATE_PSTREAM createPstreamCmd (see include/wmi.h)
138 * uses: WMI_CREATE_PSTREAM_CMDID
139 */
140
141#define AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22)
142/*
143 * arguments:
144 * WMI_DELETE_PSTREAM_CMD deletePstreamCmd (see include/wmi.h)
145 * uses: WMI_DELETE_PSTREAM_CMDID
146 */
147
148#define AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23)
149/*
150 * arguments:
151 * WMI_SNR_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
152 * uses: WMI_SNR_THRESHOLD_PARAMS_CMDID
153 */
154
155#define AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)
156/*
157 * arguments:
158 * WMI_TARGET_ERROR_REPORT_BITMASK errorReportBitMask (see include/wmi.h)
159 * uses: WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
160 */
161
162#define AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25)
163/*
164 * arguments:
165 * TARGET_STATS *targetStats (see below)
166 * uses: WMI_GET_STATISTICS_CMDID
167 */
168
169#define AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26)
170/*
171 * arguments:
172 * WMI_SET_ASSOC_INFO_CMD setAssocInfoCmd
173 * uses: WMI_SET_ASSOC_INFO_CMDID
174 */
175
176#define AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27)
177/*
178 * arguments:
179 * WMI_SET_ACCESS_PARAMS_CMD setAccessParams (see include/wmi.h)
180 * uses: WMI_SET_ACCESS_PARAMS_CMDID
181 */
182
183#define AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28)
184/*
185 * arguments:
186 * UINT32 beaconMissTime
187 * uses: WMI_SET_BMISS_TIME_CMDID
188 */
189
190#define AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29)
191/*
192 * arguments:
193 * WMI_DISC_TIMEOUT_CMD disconnectTimeoutCmd (see include/wmi.h)
194 * uses: WMI_SET_DISC_TIMEOUT_CMDID
195 */
196
197#define AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30)
198/*
199 * arguments:
200 * WMI_IBSS_PM_CAPS_CMD ibssPowerMgmtCapsCmd
201 * uses: WMI_SET_IBSS_PM_CAPS_CMDID
202 */
203
204/*
205 * There is a very small space available for driver-private
206 * wireless ioctls. In order to circumvent this limitation,
207 * we multiplex a bunch of ioctls (XIOCTLs) on top of a
208 * single AR6000_IOCTL_EXTENDED ioctl.
209 */
210#define AR6000_IOCTL_EXTENDED (SIOCIWFIRSTPRIV+31)
211
212
213/* ====BMI Extended Ioctls==== */
214
215#define AR6000_XIOCTL_BMI_DONE 1
216/*
217 * arguments:
218 * UINT32 cmd (AR6000_XIOCTL_BMI_DONE)
219 * uses: BMI_DONE
220 */
221
222#define AR6000_XIOCTL_BMI_READ_MEMORY 2
223/*
224 * arguments:
225 * union {
226 * struct {
227 * UINT32 cmd (AR6000_XIOCTL_BMI_READ_MEMORY)
228 * UINT32 address
229 * UINT32 length
230 * }
231 * char results[length]
232 * }
233 * uses: BMI_READ_MEMORY
234 */
235
236#define AR6000_XIOCTL_BMI_WRITE_MEMORY 3
237/*
238 * arguments:
239 * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_MEMORY)
240 * UINT32 address
241 * UINT32 length
242 * char data[length]
243 * uses: BMI_WRITE_MEMORY
244 */
245
246#define AR6000_XIOCTL_BMI_EXECUTE 4
247/*
248 * arguments:
249 * UINT32 cmd (AR6000_XIOCTL_BMI_EXECUTE)
250 * UINT32 TargetAddress
251 * UINT32 parameter
252 * uses: BMI_EXECUTE
253 */
254
255#define AR6000_XIOCTL_BMI_SET_APP_START 5
256/*
257 * arguments:
258 * UINT32 cmd (AR6000_XIOCTL_BMI_SET_APP_START)
259 * UINT32 TargetAddress
260 * uses: BMI_SET_APP_START
261 */
262
263#define AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6
264/*
265 * arguments:
266 * union {
267 * struct {
268 * UINT32 cmd (AR6000_XIOCTL_BMI_READ_SOC_REGISTER)
269 * UINT32 TargetAddress, 32-bit aligned
270 * }
271 * UINT32 result
272 * }
273 * uses: BMI_READ_SOC_REGISTER
274 */
275
276#define AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7
277/*
278 * arguments:
279 * struct {
280 * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER)
281 * UINT32 TargetAddress, 32-bit aligned
282 * UINT32 newValue
283 * }
284 * uses: BMI_WRITE_SOC_REGISTER
285 */
286
287#define AR6000_XIOCTL_BMI_TEST 8
288/*
289 * arguments:
290 * UINT32 cmd (AR6000_XIOCTL_BMI_TEST)
291 * UINT32 address
292 * UINT32 length
293 * UINT32 count
294 */
295
296
297
298/* Historical Host-side DataSet support */
299#define AR6000_XIOCTL_UNUSED9 9
300#define AR6000_XIOCTL_UNUSED10 10
301#define AR6000_XIOCTL_UNUSED11 11
302
303/* ====Misc Extended Ioctls==== */
304
305#define AR6000_XIOCTL_FORCE_TARGET_RESET 12
306/*
307 * arguments:
308 * UINT32 cmd (AR6000_XIOCTL_FORCE_TARGET_RESET)
309 */
310
311
312#ifdef HTC_RAW_INTERFACE
313/* HTC Raw Interface Ioctls */
314#define AR6000_XIOCTL_HTC_RAW_OPEN 13
315/*
316 * arguments:
317 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_OPEN)
318 */
319
320#define AR6000_XIOCTL_HTC_RAW_CLOSE 14
321/*
322 * arguments:
323 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_CLOSE)
324 */
325
326#define AR6000_XIOCTL_HTC_RAW_READ 15
327/*
328 * arguments:
329 * union {
330 * struct {
331 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_READ)
332 * UINT32 mailboxID
333 * UINT32 length
334 * }
335 * results[length]
336 * }
337 */
338
339#define AR6000_XIOCTL_HTC_RAW_WRITE 16
340/*
341 * arguments:
342 * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_WRITE)
343 * UINT32 mailboxID
344 * UINT32 length
345 * char buffer[length]
346 */
347#endif /* HTC_RAW_INTERFACE */
348
349#define AR6000_XIOCTL_CHECK_TARGET_READY 17
350/*
351 * arguments:
352 * UINT32 cmd (AR6000_XIOCTL_CHECK_TARGET_READY)
353 */
354
355
356
357/* ====GPIO (General Purpose I/O) Extended Ioctls==== */
358
359#define AR6000_XIOCTL_GPIO_OUTPUT_SET 18
360/*
361 * arguments:
362 * UINT32 cmd (AR6000_XIOCTL_GPIO_OUTPUT_SET)
363 * ar6000_gpio_output_set_cmd_s (see below)
364 * uses: WMIX_GPIO_OUTPUT_SET_CMDID
365 */
366
367#define AR6000_XIOCTL_GPIO_INPUT_GET 19
368/*
369 * arguments:
370 * UINT32 cmd (AR6000_XIOCTL_GPIO_INPUT_GET)
371 * uses: WMIX_GPIO_INPUT_GET_CMDID
372 */
373
374#define AR6000_XIOCTL_GPIO_REGISTER_SET 20
375/*
376 * arguments:
377 * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_SET)
378 * ar6000_gpio_register_cmd_s (see below)
379 * uses: WMIX_GPIO_REGISTER_SET_CMDID
380 */
381
382#define AR6000_XIOCTL_GPIO_REGISTER_GET 21
383/*
384 * arguments:
385 * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_GET)
386 * ar6000_gpio_register_cmd_s (see below)
387 * uses: WMIX_GPIO_REGISTER_GET_CMDID
388 */
389
390#define AR6000_XIOCTL_GPIO_INTR_ACK 22
391/*
392 * arguments:
393 * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_ACK)
394 * ar6000_cpio_intr_ack_cmd_s (see below)
395 * uses: WMIX_GPIO_INTR_ACK_CMDID
396 */
397
398#define AR6000_XIOCTL_GPIO_INTR_WAIT 23
399/*
400 * arguments:
401 * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_WAIT)
402 */
403
404
405
406/* ====more wireless commands==== */
407
408#define AR6000_XIOCTL_SET_ADHOC_BSSID 24
409/*
410 * arguments:
411 * UINT32 cmd (AR6000_XIOCTL_SET_ADHOC_BSSID)
412 * WMI_SET_ADHOC_BSSID_CMD setAdHocBssidCmd (see include/wmi.h)
413 */
414
415#define AR6000_XIOCTL_SET_OPT_MODE 25
416/*
417 * arguments:
418 * UINT32 cmd (AR6000_XIOCTL_SET_OPT_MODE)
419 * WMI_SET_OPT_MODE_CMD setOptModeCmd (see include/wmi.h)
420 * uses: WMI_SET_OPT_MODE_CMDID
421 */
422
423#define AR6000_XIOCTL_OPT_SEND_FRAME 26
424/*
425 * arguments:
426 * UINT32 cmd (AR6000_XIOCTL_OPT_SEND_FRAME)
427 * WMI_OPT_TX_FRAME_CMD optTxFrameCmd (see include/wmi.h)
428 * uses: WMI_OPT_TX_FRAME_CMDID
429 */
430
431#define AR6000_XIOCTL_SET_BEACON_INTVAL 27
432/*
433 * arguments:
434 * UINT32 cmd (AR6000_XIOCTL_SET_BEACON_INTVAL)
435 * WMI_BEACON_INT_CMD beaconIntCmd (see include/wmi.h)
436 * uses: WMI_SET_BEACON_INT_CMDID
437 */
438
439
440#define IEEE80211_IOCTL_SETAUTHALG 28
441
442
443#define AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29
444/*
445 * arguments:
446 * UINT32 cmd (AR6000_XIOCTL_SET_VOICE_PKT_SIZE)
447 * WMI_SET_VOICE_PKT_SIZE_CMD setVoicePktSizeCmd (see include/wmi.h)
448 * uses: WMI_SET_VOICE_PKT_SIZE_CMDID
449 */
450
451
452#define AR6000_XIOCTL_SET_MAX_SP 30
453/*
454 * arguments:
455 * UINT32 cmd (AR6000_XIOCTL_SET_MAX_SP)
456 * WMI_SET_MAX_SP_LEN_CMD maxSPLen(see include/wmi.h)
457 * uses: WMI_SET_MAX_SP_LEN_CMDID
458 */
459
460#define AR6000_XIOCTL_WMI_GET_ROAM_TBL 31
461
462#define AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32
463
464#define AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33
465
466
467/*
468 * arguments:
469 * UINT32 cmd (AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS)
470 * WMI_SET_POWERSAVE_TIMERS_CMD powerSaveTimers(see include/wmi.h)
471 * WMI_SET_POWERSAVE_TIMERS_CMDID
472 */
473
474#define AR6000_XIOCTRL_WMI_GET_POWER_MODE 34
475/*
476 * arguments:
477 * UINT32 cmd (AR6000_XIOCTRL_WMI_GET_POWER_MODE)
478 */
479
480#define AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35
481typedef enum {
482 WLAN_DISABLED,
483 WLAN_ENABLED
484} AR6000_WLAN_STATE;
485/*
486 * arguments:
487 * enable/disable
488 */
489
490#define AR6000_XIOCTL_WMI_GET_ROAM_DATA 36
491
492#define AR6000_XIOCTL_WMI_SETRETRYLIMITS 37
493/*
494 * arguments:
495 * WMI_SET_RETRY_LIMITS_CMD ibssSetRetryLimitsCmd
496 * uses: WMI_SET_RETRY_LIMITS_CMDID
497 */
498
499#ifdef CONFIG_HOST_TCMD_SUPPORT
500/* ====extended commands for radio test ==== */
501
502#define AR6000_XIOCTL_TCMD_CONT_TX 38
503/*
504 * arguments:
505 * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_TX)
506 * WMI_TCMD_CONT_TX_CMD contTxCmd (see include/wmi.h)
507 * uses: WMI_TCMD_CONT_TX_CMDID
508 */
509
510#define AR6000_XIOCTL_TCMD_CONT_RX 39
511/*
512 * arguments:
513 * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_RX)
514 * WMI_TCMD_CONT_RX_CMD rxCmd (see include/wmi.h)
515 * uses: WMI_TCMD_CONT_RX_CMDID
516 */
517
518#define AR6000_XIOCTL_TCMD_PM 40
519/*
520 * arguments:
521 * UINT32 cmd (AR6000_XIOCTL_TCMD_PM)
522 * WMI_TCMD_PM_CMD pmCmd (see include/wmi.h)
523 * uses: WMI_TCMD_PM_CMDID
524 */
525
526#endif /* CONFIG_HOST_TCMD_SUPPORT */
527
528#define AR6000_XIOCTL_WMI_STARTSCAN 41
529/*
530 * arguments:
531 * UINT32 cmd (AR6000_XIOCTL_WMI_STARTSCAN)
532 * UINT8 scanType
533 * UINT8 scanConnected
534 * u32 forceFgScan
535 * uses: WMI_START_SCAN_CMDID
536 */
537
538#define AR6000_XIOCTL_WMI_SETFIXRATES 42
539
540#define AR6000_XIOCTL_WMI_GETFIXRATES 43
541
542
543#define AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44
544/*
545 * arguments:
546 * WMI_RSSI_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
547 * uses: WMI_RSSI_THRESHOLD_PARAMS_CMDID
548 */
549
550#define AR6000_XIOCTL_WMI_CLR_RSSISNR 45
551/*
552 * arguments:
553 * WMI_CLR_RSSISNR_CMD thresholdParams (see include/wmi.h)
554 * uses: WMI_CLR_RSSISNR_CMDID
555 */
556
557#define AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46
558/*
559 * arguments:
560 * WMI_LQ_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
561 * uses: WMI_LQ_THRESHOLD_PARAMS_CMDID
562 */
563
564#define AR6000_XIOCTL_WMI_SET_RTS 47
565/*
566 * arguments:
567 * WMI_SET_RTS_MODE_CMD (see include/wmi.h)
568 * uses: WMI_SET_RTS_MODE_CMDID
569 */
570
571#define AR6000_XIOCTL_WMI_SET_LPREAMBLE 48
572
573#define AR6000_XIOCTL_WMI_SET_AUTHMODE 49
574/*
575 * arguments:
576 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_AUTHMODE)
577 * UINT8 mode
578 * uses: WMI_SET_RECONNECT_AUTH_MODE_CMDID
579 */
580
581#define AR6000_XIOCTL_WMI_SET_REASSOCMODE 50
582
583/*
584 * arguments:
585 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_WMM)
586 * UINT8 mode
587 * uses: WMI_SET_WMM_CMDID
588 */
589#define AR6000_XIOCTL_WMI_SET_WMM 51
590
591/*
592 * arguments:
593 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS)
594 * UINT32 frequency
595 * UINT8 threshold
596 */
597#define AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52
598
599/*
600 * arguments:
601 * UINT32 cmd (AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP)
602 * UINT32 cookie
603 */
604#define AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53
605
606/*
607 * arguments:
608 * UINT32 cmd (AR6000_XIOCTL_WMI_GET_RD)
609 * UINT32 regDomain
610 */
611#define AR6000_XIOCTL_WMI_GET_RD 54
612
613#define AR6000_XIOCTL_DIAG_READ 55
614
615#define AR6000_XIOCTL_DIAG_WRITE 56
616
617/*
618 * arguments cmd (AR6000_XIOCTL_SET_TXOP)
619 * WMI_TXOP_CFG txopEnable
620 */
621#define AR6000_XIOCTL_WMI_SET_TXOP 57
622
623/*
624 * arguments:
625 * UINT32 cmd (AR6000_XIOCTL_USER_SETKEYS)
626 * UINT32 keyOpCtrl
627 * uses struct ar6000_user_setkeys_info
628 */
629#define AR6000_XIOCTL_USER_SETKEYS 58
630
631#define AR6000_XIOCTL_WMI_SET_KEEPALIVE 59
632/*
633 * arguments:
634 * UINT8 cmd (AR6000_XIOCTL_WMI_SET_KEEPALIVE)
635 * UINT8 keepaliveInterval
636 * uses: WMI_SET_KEEPALIVE_CMDID
637 */
638
639#define AR6000_XIOCTL_WMI_GET_KEEPALIVE 60
640/*
641 * arguments:
642 * UINT8 cmd (AR6000_XIOCTL_WMI_GET_KEEPALIVE)
643 * UINT8 keepaliveInterval
644 * u32 configured
645 * uses: WMI_GET_KEEPALIVE_CMDID
646 */
647
648/* ====ROM Patching Extended Ioctls==== */
649
650#define AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61
651/*
652 * arguments:
653 * union {
654 * struct {
655 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_INSTALL)
656 * UINT32 ROM Address
657 * UINT32 RAM Address
658 * UINT32 number of bytes
659 * UINT32 activate? (0 or 1)
660 * }
661 * u32 resulting rompatch ID
662 * }
663 * uses: BMI_ROMPATCH_INSTALL
664 */
665
666#define AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62
667/*
668 * arguments:
669 * struct {
670 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL)
671 * UINT32 rompatch ID
672 * }
673 * uses: BMI_ROMPATCH_UNINSTALL
674 */
675
676#define AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63
677/*
678 * arguments:
679 * struct {
680 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE)
681 * UINT32 rompatch count
682 * UINT32 rompatch IDs[rompatch count]
683 * }
684 * uses: BMI_ROMPATCH_ACTIVATE
685 */
686
687#define AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64
688/*
689 * arguments:
690 * struct {
691 * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE)
692 * UINT32 rompatch count
693 * UINT32 rompatch IDs[rompatch count]
694 * }
695 * uses: BMI_ROMPATCH_DEACTIVATE
696 */
697
698#define AR6000_XIOCTL_WMI_SET_APPIE 65
699/*
700 * arguments:
701 * struct {
702 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_APPIE)
703 * UINT32 app_frmtype;
704 * UINT32 app_buflen;
705 * UINT8 app_buf[];
706 * }
707 */
708#define AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66
709/*
710 * arguments:
711 * u32 filter_type;
712 */
713
714#define AR6000_XIOCTL_DBGLOG_CFG_MODULE 67
715
716#define AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68
717
718#define AR6000_XIOCTL_WMI_SET_WSC_STATUS 70
719/*
720 * arguments:
721 * u32 wsc_status;
722 * (WSC_REG_INACTIVE or WSC_REG_ACTIVE)
723 */
724
725/*
726 * arguments:
727 * struct {
728 * u8 streamType;
729 * u8 status;
730 * }
731 * uses: WMI_SET_BT_STATUS_CMDID
732 */
733#define AR6000_XIOCTL_WMI_SET_BT_STATUS 71
734
735/*
736 * arguments:
737 * struct {
738 * u8 paramType;
739 * union {
740 * u8 noSCOPkts;
741 * BT_PARAMS_A2DP a2dpParams;
742 * BT_COEX_REGS regs;
743 * };
744 * }
745 * uses: WMI_SET_BT_PARAM_CMDID
746 */
747#define AR6000_XIOCTL_WMI_SET_BT_PARAMS 72
748
749#define AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73
750#define AR6000_XIOCTL_WMI_SET_WOW_MODE 74
751#define AR6000_XIOCTL_WMI_GET_WOW_LIST 75
752#define AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76
753#define AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77
754
755
756
757#define AR6000_XIOCTL_TARGET_INFO 78
758/*
759 * arguments:
760 * UINT32 cmd (AR6000_XIOCTL_TARGET_INFO)
761 * u32 TargetVersion (returned)
762 * u32 TargetType (returned)
763 * (See also bmi_msg.h target_ver and target_type)
764 */
765
766#define AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79
767/*
768 * arguments:
769 * none
770 */
771
772#define AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80
773/*
774 * This ioctl is used to emulate traffic activity
775 * timeouts. Activity/inactivity will trigger the driver
776 * to re-balance credits.
777 *
778 * arguments:
779 * ar6000_traffic_activity_change
780 */
781
782#define AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81
783/*
784 * This ioctl is used to set the connect control flags
785 *
786 * arguments:
787 * u32 connectCtrlFlags
788 */
789
790#define AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82
791/*
792 * This IOCTL sets any Authentication,Key Management and Protection
793 * related parameters. This is used along with the information set in
794 * Connect Command.
795 * Currently this enables Multiple PMKIDs to an AP.
796 *
797 * arguments:
798 * struct {
799 * u32 akmpInfo;
800 * }
801 * uses: WMI_SET_AKMP_PARAMS_CMD
802 */
803
804#define AR6000_XIOCTL_WMI_GET_PMKID_LIST 83
805
806#define AR6000_XIOCTL_WMI_SET_PMKID_LIST 84
807/*
808 * This IOCTL is used to set a list of PMKIDs. This list of
809 * PMKIDs is used in the [Re]AssocReq Frame. This list is used
810 * only if the MultiPMKID option is enabled via the
811 * AR6000_XIOCTL_WMI_SET_AKMP_PARAMS IOCTL.
812 *
813 * arguments:
814 * struct {
815 * u32 numPMKID;
816 * WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE];
817 * }
818 * uses: WMI_SET_PMKIDLIST_CMD
819 */
820
821#define AR6000_XIOCTL_WMI_SET_PARAMS 85
822#define AR6000_XIOCTL_WMI_SET_MCAST_FILTER 86
823#define AR6000_XIOCTL_WMI_DEL_MCAST_FILTER 87
824
825
826/* Historical DSETPATCH support for INI patches */
827#define AR6000_XIOCTL_UNUSED90 90
828
829
830/* Support LZ-compressed firmware download */
831#define AR6000_XIOCTL_BMI_LZ_STREAM_START 91
832/*
833 * arguments:
834 * UINT32 cmd (AR6000_XIOCTL_BMI_LZ_STREAM_START)
835 * UINT32 address
836 * uses: BMI_LZ_STREAM_START
837 */
838
839#define AR6000_XIOCTL_BMI_LZ_DATA 92
840/*
841 * arguments:
842 * UINT32 cmd (AR6000_XIOCTL_BMI_LZ_DATA)
843 * UINT32 length
844 * char data[length]
845 * uses: BMI_LZ_DATA
846 */
847
848#define AR6000_XIOCTL_PROF_CFG 93
849/*
850 * arguments:
851 * u32 period
852 * u32 nbins
853 */
854
855#define AR6000_XIOCTL_PROF_ADDR_SET 94
856/*
857 * arguments:
858 * u32 Target address
859 */
860
861#define AR6000_XIOCTL_PROF_START 95
862
863#define AR6000_XIOCTL_PROF_STOP 96
864
865#define AR6000_XIOCTL_PROF_COUNT_GET 97
866
867#define AR6000_XIOCTL_WMI_ABORT_SCAN 98
868
869/*
870 * AP mode
871 */
872#define AR6000_XIOCTL_AP_GET_STA_LIST 99
873
874#define AR6000_XIOCTL_AP_HIDDEN_SSID 100
875
876#define AR6000_XIOCTL_AP_SET_NUM_STA 101
877
878#define AR6000_XIOCTL_AP_SET_ACL_MAC 102
879
880#define AR6000_XIOCTL_AP_GET_ACL_LIST 103
881
882#define AR6000_XIOCTL_AP_COMMIT_CONFIG 104
883
884#define IEEE80211_IOCTL_GETWPAIE 105
885
886#define AR6000_XIOCTL_AP_CONN_INACT_TIME 106
887
888#define AR6000_XIOCTL_AP_PROT_SCAN_TIME 107
889
890#define AR6000_XIOCTL_AP_SET_COUNTRY 108
891
892#define AR6000_XIOCTL_AP_SET_DTIM 109
893
894
895
896
897#define AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT 110
898
899#define AR6000_XIOCTL_SET_IP 111
900
901#define AR6000_XIOCTL_AP_SET_ACL_POLICY 112
902
903#define AR6000_XIOCTL_AP_INTRA_BSS_COMM 113
904
905#define AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO 114
906
907#define AR6000_XIOCTL_MODULE_DEBUG_SET_MASK 115
908
909#define AR6000_XIOCTL_MODULE_DEBUG_GET_MASK 116
910
911#define AR6000_XIOCTL_DUMP_RCV_AGGR_STATS 117
912
913#define AR6000_XIOCTL_SET_HT_CAP 118
914
915#define AR6000_XIOCTL_SET_HT_OP 119
916
917#define AR6000_XIOCTL_AP_GET_STAT 120
918
919#define AR6000_XIOCTL_SET_TX_SELECT_RATES 121
920
921#define AR6000_XIOCTL_SETUP_AGGR 122
922
923#define AR6000_XIOCTL_ALLOW_AGGR 123
924
925#define AR6000_XIOCTL_AP_GET_HIDDEN_SSID 124
926
927#define AR6000_XIOCTL_AP_GET_COUNTRY 125
928
929#define AR6000_XIOCTL_AP_GET_WMODE 126
930
931#define AR6000_XIOCTL_AP_GET_DTIM 127
932
933#define AR6000_XIOCTL_AP_GET_BINTVL 128
934
935#define AR6000_XIOCTL_AP_GET_RTS 129
936
937#define AR6000_XIOCTL_DELE_AGGR 130
938
939#define AR6000_XIOCTL_FETCH_TARGET_REGS 131
940
941#define AR6000_XIOCTL_HCI_CMD 132
942
943#define AR6000_XIOCTL_ACL_DATA 133 /* used to be used for PAL */
944
945#define AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134
946
947#define AR6000_XIOCTL_AP_SET_11BG_RATESET 135
948
949/*
950 * arguments:
951 * WMI_AP_PS_CMD apPsCmd
952 * uses: WMI_AP_PS_CMDID
953 */
954
955#define AR6000_XIOCTL_WMI_SET_AP_PS 136
956
957#define AR6000_XIOCTL_WMI_MCAST_FILTER 137
958
959#define AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT 138
960
961#define AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV 139
962
963#define AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG 140
964
965#define AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG 141
966
967#define AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG 142
968
969#define AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG 143
970
971#define AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG 144
972
973#define AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS 145
974
975#define AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG 146
976
977#define AR6000_XIOCTL_WMI_GET_BTCOEX_STATS 147
978/*
979 * arguments:
980 * UINT32 cmd (AR6000_XIOCTL_WMI_SET_QOS_SUPP)
981 * UINT8 mode
982 * uses: WMI_SET_QOS_SUPP_CMDID
983 */
984#define AR6000_XIOCTL_WMI_SET_QOS_SUPP 148
985
986#define AR6000_XIOCTL_GET_WLAN_SLEEP_STATE 149
987
988#define AR6000_XIOCTL_SET_BT_HW_POWER_STATE 150
989
990#define AR6000_XIOCTL_GET_BT_HW_POWER_STATE 151
991
992#define AR6000_XIOCTL_ADD_AP_INTERFACE 152
993
994#define AR6000_XIOCTL_REMOVE_AP_INTERFACE 153
995
996#define AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154
997
998#define AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES 161
999
1000/* used by AR6000_IOCTL_WMI_GETREV */
1001struct ar6000_version {
1002 u32 host_ver;
1003 u32 target_ver;
1004 u32 wlan_ver;
1005 u32 abi_ver;
1006};
1007
1008/* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */
1009struct ar6000_queuereq {
1010 u8 trafficClass;
1011 u16 activeTsids;
1012};
1013
1014/* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */
1015typedef struct targetStats_t {
1016 u64 tx_packets;
1017 u64 tx_bytes;
1018 u64 tx_unicast_pkts;
1019 u64 tx_unicast_bytes;
1020 u64 tx_multicast_pkts;
1021 u64 tx_multicast_bytes;
1022 u64 tx_broadcast_pkts;
1023 u64 tx_broadcast_bytes;
1024 u64 tx_rts_success_cnt;
1025 u64 tx_packet_per_ac[4];
1026
1027 u64 tx_errors;
1028 u64 tx_failed_cnt;
1029 u64 tx_retry_cnt;
1030 u64 tx_mult_retry_cnt;
1031 u64 tx_rts_fail_cnt;
1032
1033 u64 rx_packets;
1034 u64 rx_bytes;
1035 u64 rx_unicast_pkts;
1036 u64 rx_unicast_bytes;
1037 u64 rx_multicast_pkts;
1038 u64 rx_multicast_bytes;
1039 u64 rx_broadcast_pkts;
1040 u64 rx_broadcast_bytes;
1041 u64 rx_fragment_pkt;
1042
1043 u64 rx_errors;
1044 u64 rx_crcerr;
1045 u64 rx_key_cache_miss;
1046 u64 rx_decrypt_err;
1047 u64 rx_duplicate_frames;
1048
1049 u64 tkip_local_mic_failure;
1050 u64 tkip_counter_measures_invoked;
1051 u64 tkip_replays;
1052 u64 tkip_format_errors;
1053 u64 ccmp_format_errors;
1054 u64 ccmp_replays;
1055
1056 u64 power_save_failure_cnt;
1057
1058 u64 cs_bmiss_cnt;
1059 u64 cs_lowRssi_cnt;
1060 u64 cs_connect_cnt;
1061 u64 cs_disconnect_cnt;
1062
1063 s32 tx_unicast_rate;
1064 s32 rx_unicast_rate;
1065
1066 u32 lq_val;
1067
1068 u32 wow_num_pkts_dropped;
1069 u16 wow_num_events_discarded;
1070
1071 s16 noise_floor_calibation;
1072 s16 cs_rssi;
1073 s16 cs_aveBeacon_rssi;
1074 u8 cs_aveBeacon_snr;
1075 u8 cs_lastRoam_msec;
1076 u8 cs_snr;
1077
1078 u8 wow_num_host_pkt_wakeups;
1079 u8 wow_num_host_event_wakeups;
1080
1081 u32 arp_received;
1082 u32 arp_matched;
1083 u32 arp_replied;
1084}TARGET_STATS;
1085
1086typedef struct targetStats_cmd_t {
1087 TARGET_STATS targetStats;
1088 int clearStats;
1089} TARGET_STATS_CMD;
1090
1091/* used by AR6000_XIOCTL_USER_SETKEYS */
1092
1093/*
1094 * Setting this bit to 1 doesnot initialize the RSC on the firmware
1095 */
1096#define AR6000_XIOCTL_USER_SETKEYS_RSC_CTRL 1
1097#define AR6000_USER_SETKEYS_RSC_UNCHANGED 0x00000002
1098
1099struct ar6000_user_setkeys_info {
1100 u32 keyOpCtrl; /* Bit Map of Key Mgmt Ctrl Flags */
1101}; /* XXX: unused !? */
1102
1103/* used by AR6000_XIOCTL_GPIO_OUTPUT_SET */
1104struct ar6000_gpio_output_set_cmd_s {
1105 u32 set_mask;
1106 u32 clear_mask;
1107 u32 enable_mask;
1108 u32 disable_mask;
1109};
1110
1111/*
1112 * used by AR6000_XIOCTL_GPIO_REGISTER_GET and AR6000_XIOCTL_GPIO_REGISTER_SET
1113 */
1114struct ar6000_gpio_register_cmd_s {
1115 u32 gpioreg_id;
1116 u32 value;
1117};
1118
1119/* used by AR6000_XIOCTL_GPIO_INTR_ACK */
1120struct ar6000_gpio_intr_ack_cmd_s {
1121 u32 ack_mask;
1122};
1123
1124/* used by AR6000_XIOCTL_GPIO_INTR_WAIT */
1125struct ar6000_gpio_intr_wait_cmd_s {
1126 u32 intr_mask;
1127 u32 input_values;
1128};
1129
1130/* used by the AR6000_XIOCTL_DBGLOG_CFG_MODULE */
1131typedef struct ar6000_dbglog_module_config_s {
1132 u32 valid;
1133 u16 mmask;
1134 u16 tsr;
1135 u32 rep;
1136 u16 size;
1137} DBGLOG_MODULE_CONFIG;
1138
1139typedef struct user_rssi_thold_t {
1140 s16 tag;
1141 s16 rssi;
1142} USER_RSSI_THOLD;
1143
1144typedef struct user_rssi_params_t {
1145 u8 weight;
1146 u32 pollTime;
1147 USER_RSSI_THOLD tholds[12];
1148} USER_RSSI_PARAMS;
1149
1150typedef struct ar6000_get_btcoex_config_cmd_t{
1151 u32 btProfileType;
1152 u32 linkId;
1153 }AR6000_GET_BTCOEX_CONFIG_CMD;
1154
1155typedef struct ar6000_btcoex_config_t {
1156 AR6000_GET_BTCOEX_CONFIG_CMD configCmd;
1157 u32 *configEvent;
1158} AR6000_BTCOEX_CONFIG;
1159
1160typedef struct ar6000_btcoex_stats_t {
1161 u32 *statsEvent;
1162 }AR6000_BTCOEX_STATS;
1163/*
1164 * Host driver may have some config parameters. Typically, these
1165 * config params are one time config parameters. These could
1166 * correspond to any of the underlying modules. Host driver exposes
1167 * an api for the underlying modules to get this config.
1168 */
1169#define AR6000_DRIVER_CFG_BASE 0x8000
1170
1171/* Should driver perform wlan node caching? */
1172#define AR6000_DRIVER_CFG_GET_WLANNODECACHING 0x8001
1173/*Should we log raw WMI msgs */
1174#define AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS 0x8002
1175
1176/* used by AR6000_XIOCTL_DIAG_READ & AR6000_XIOCTL_DIAG_WRITE */
1177struct ar6000_diag_window_cmd_s {
1178 unsigned int addr;
1179 unsigned int value;
1180};
1181
1182
1183struct ar6000_traffic_activity_change {
1184 u32 StreamID; /* stream ID to indicate activity change */
1185 u32 Active; /* active (1) or inactive (0) */
1186};
1187
1188/* Used with AR6000_XIOCTL_PROF_COUNT_GET */
1189struct prof_count_s {
1190 u32 addr; /* bin start address */
1191 u32 count; /* hit count */
1192};
1193
1194
1195/* used by AR6000_XIOCTL_MODULE_DEBUG_SET_MASK */
1196/* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK */
1197/* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO */
1198struct drv_debug_module_s {
1199 char modulename[128]; /* name of module */
1200 u32 mask; /* new mask to set .. or .. current mask */
1201};
1202
1203
1204/* All HCI related rx events are sent up to the host app
1205 * via a wmi event id. It can contain ACL data or HCI event,
1206 * based on which it will be de-multiplexed.
1207 */
1208typedef enum {
1209 PAL_HCI_EVENT = 0,
1210 PAL_HCI_RX_DATA,
1211} WMI_PAL_EVENT_INFO;
1212
1213
1214#ifdef __cplusplus
1215}
1216#endif
1217#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h
new file mode 100644
index 00000000000..d5253207b19
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/cfg80211.h
@@ -0,0 +1,61 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _AR6K_CFG80211_H_
25#define _AR6K_CFG80211_H_
26
27struct wireless_dev *ar6k_cfg80211_init(struct device *dev);
28void ar6k_cfg80211_deinit(struct ar6_softc *ar);
29
30void ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status);
31
32void ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
33 u8 *bssid, u16 listenInterval,
34 u16 beaconInterval,NETWORK_TYPE networkType,
35 u8 beaconIeLen, u8 assocReqLen,
36 u8 assocRespLen, u8 *assocInfo);
37
38void ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
39 u8 *bssid, u8 assocRespLen,
40 u8 *assocInfo, u16 protocolReasonStatus);
41
42void ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast);
43
44#ifdef CONFIG_NL80211_TESTMODE
45void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf,
46 int buf_len);
47#else
48static inline void ar6000_testmode_rx_report_event(struct ar6_softc *ar,
49 void *buf, int buf_len)
50{
51}
52#endif
53
54
55#endif /* _AR6K_CFG80211_H_ */
56
57
58
59
60
61
diff --git a/drivers/staging/ath6kl/os/linux/include/config_linux.h b/drivers/staging/ath6kl/os/linux/include/config_linux.h
new file mode 100644
index 00000000000..dbbe1a00b92
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/config_linux.h
@@ -0,0 +1,51 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _CONFIG_LINUX_H_
25#define _CONFIG_LINUX_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/*
32 * Host side Test Command support
33 */
34#define CONFIG_HOST_TCMD_SUPPORT
35
36#define USE_4BYTE_REGISTER_ACCESS
37
38/* Host-side support for Target-side profiling */
39#undef CONFIG_TARGET_PROFILE_SUPPORT
40
41/* IP/TCP checksum offload */
42/* Checksum offload is currently not supported for 64 bit platforms */
43#ifndef __LP64__
44#define CONFIG_CHECKSUM_OFFLOAD
45#endif /* __LP64__ */
46
47#ifdef __cplusplus
48}
49#endif
50
51#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/debug_linux.h b/drivers/staging/ath6kl/os/linux/include/debug_linux.h
new file mode 100644
index 00000000000..b8dba52badc
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/debug_linux.h
@@ -0,0 +1,50 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _DEBUG_LINUX_H_
25#define _DEBUG_LINUX_H_
26
27 /* macro to remove parens */
28#define ATH_PRINTX_ARG(arg...) arg
29
30#ifdef DEBUG
31 /* NOTE: the AR_DEBUG_PRINTF macro is defined here to handle special handling of variable arg macros
32 * which may be compiler dependent. */
33#define AR_DEBUG_PRINTF(mask, args) do { \
34 if (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (mask)) { \
35 A_LOGGER(mask, ATH_MODULE_NAME, ATH_PRINTX_ARG args); \
36 } \
37} while (0)
38#else
39 /* on non-debug builds, keep in error and warning messages in the driver, all other
40 * message tracing will get compiled out */
41#define AR_DEBUG_PRINTF(mask, args) \
42 if ((mask) & (ATH_DEBUG_ERR | ATH_DEBUG_WARN)) { A_PRINTF(ATH_PRINTX_ARG args); }
43
44#endif
45
46 /* compile specific macro to get the function name string */
47#define _A_FUNCNAME_ __func__
48
49
50#endif /* _DEBUG_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h
new file mode 100644
index 00000000000..74f98618334
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h
@@ -0,0 +1,76 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// HCI bridge implementation
21//
22// Author(s): ="Atheros"
23//==============================================================================
24
25#include "hci_transport_api.h"
26#include "common_drv.h"
27
28extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo);
29extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans);
30extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
31extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
32extern void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans);
33extern int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans);
34extern int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
35extern int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans,
36 struct htc_packet *pPacket,
37 int MaxPollMS);
38extern int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
39extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
40
41
42#define HCI_TransportAttach(HTCHandle, pInfo) \
43 _HCI_TransportAttach((HTCHandle), (pInfo))
44#define HCI_TransportDetach(HciTrans) \
45 _HCI_TransportDetach(HciTrans)
46#define HCI_TransportAddReceivePkts(HciTrans, pQueue) \
47 _HCI_TransportAddReceivePkts((HciTrans), (pQueue))
48#define HCI_TransportSendPkt(HciTrans, pPacket, Synchronous) \
49 _HCI_TransportSendPkt((HciTrans), (pPacket), (Synchronous))
50#define HCI_TransportStop(HciTrans) \
51 _HCI_TransportStop((HciTrans))
52#define HCI_TransportStart(HciTrans) \
53 _HCI_TransportStart((HciTrans))
54#define HCI_TransportEnableDisableAsyncRecv(HciTrans, Enable) \
55 _HCI_TransportEnableDisableAsyncRecv((HciTrans), (Enable))
56#define HCI_TransportRecvHCIEventSync(HciTrans, pPacket, MaxPollMS) \
57 _HCI_TransportRecvHCIEventSync((HciTrans), (pPacket), (MaxPollMS))
58#define HCI_TransportSetBaudRate(HciTrans, Baud) \
59 _HCI_TransportSetBaudRate((HciTrans), (Baud))
60#define HCI_TransportEnablePowerMgmt(HciTrans, Enable) \
61 _HCI_TransportEnablePowerMgmt((HciTrans), (Enable))
62
63
64extern int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks);
65
66extern int ar6000_get_hif_dev(struct hif_device *device, void *config);
67
68extern int ar6000_set_uart_config(struct hif_device *hifDevice, u32 scale, u32 step);
69
70/* get core clock register settings
71 * data: 0 - 40/44MHz
72 * 1 - 80/88MHz
73 * where (5G band/2.4G band)
74 * assume 2.4G band for now
75 */
76extern int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data);
diff --git a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h
new file mode 100644
index 00000000000..e6e96de3fc6
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h
@@ -0,0 +1,177 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _IEEE80211_IOCTL_H_
25#define _IEEE80211_IOCTL_H_
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/*
32 * Extracted from the MADWIFI net80211/ieee80211_ioctl.h
33 */
34
35/*
36 * WPA/RSN get/set key request. Specify the key/cipher
37 * type and whether the key is to be used for sending and/or
38 * receiving. The key index should be set only when working
39 * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
40 * Otherwise a unicast/pairwise key is specified by the bssid
41 * (on a station) or mac address (on an ap). They key length
42 * must include any MIC key data; otherwise it should be no
43 more than IEEE80211_KEYBUF_SIZE.
44 */
45struct ieee80211req_key {
46 u_int8_t ik_type; /* key/cipher type */
47 u_int8_t ik_pad;
48 u_int16_t ik_keyix; /* key index */
49 u_int8_t ik_keylen; /* key length in bytes */
50 u_int8_t ik_flags;
51#define IEEE80211_KEY_XMIT 0x01
52#define IEEE80211_KEY_RECV 0x02
53#define IEEE80211_KEY_DEFAULT 0x80 /* default xmit key */
54 u_int8_t ik_macaddr[IEEE80211_ADDR_LEN];
55 u_int64_t ik_keyrsc; /* key receive sequence counter */
56 u_int64_t ik_keytsc; /* key transmit sequence counter */
57 u_int8_t ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
58};
59/*
60 * Delete a key either by index or address. Set the index
61 * to IEEE80211_KEYIX_NONE when deleting a unicast key.
62 */
63struct ieee80211req_del_key {
64 u_int8_t idk_keyix; /* key index */
65 u_int8_t idk_macaddr[IEEE80211_ADDR_LEN];
66};
67/*
68 * MLME state manipulation request. IEEE80211_MLME_ASSOC
69 * only makes sense when operating as a station. The other
70 * requests can be used when operating as a station or an
71 * ap (to effect a station).
72 */
73struct ieee80211req_mlme {
74 u_int8_t im_op; /* operation to perform */
75#define IEEE80211_MLME_ASSOC 1 /* associate station */
76#define IEEE80211_MLME_DISASSOC 2 /* disassociate station */
77#define IEEE80211_MLME_DEAUTH 3 /* deauthenticate station */
78#define IEEE80211_MLME_AUTHORIZE 4 /* authorize station */
79#define IEEE80211_MLME_UNAUTHORIZE 5 /* unauthorize station */
80 u_int16_t im_reason; /* 802.11 reason code */
81 u_int8_t im_macaddr[IEEE80211_ADDR_LEN];
82};
83
84struct ieee80211req_addpmkid {
85 u_int8_t pi_bssid[IEEE80211_ADDR_LEN];
86 u_int8_t pi_enable;
87 u_int8_t pi_pmkid[16];
88};
89
90#define AUTH_ALG_OPEN_SYSTEM 0x01
91#define AUTH_ALG_SHARED_KEY 0x02
92#define AUTH_ALG_LEAP 0x04
93
94struct ieee80211req_authalg {
95 u_int8_t auth_alg;
96};
97
98/*
99 * Request to add an IE to a Management Frame
100 */
101enum{
102 IEEE80211_APPIE_FRAME_BEACON = 0,
103 IEEE80211_APPIE_FRAME_PROBE_REQ = 1,
104 IEEE80211_APPIE_FRAME_PROBE_RESP = 2,
105 IEEE80211_APPIE_FRAME_ASSOC_REQ = 3,
106 IEEE80211_APPIE_FRAME_ASSOC_RESP = 4,
107 IEEE80211_APPIE_NUM_OF_FRAME = 5
108};
109
110/*
111 * The Maximum length of the IE that can be added to a Management frame
112 */
113#define IEEE80211_APPIE_FRAME_MAX_LEN 200
114
115struct ieee80211req_getset_appiebuf {
116 u_int32_t app_frmtype; /* management frame type for which buffer is added */
117 u_int32_t app_buflen; /*application supplied buffer length */
118 u_int8_t app_buf[];
119};
120
121/*
122 * The following definitions are used by an application to set filter
123 * for receiving management frames
124 */
125enum {
126 IEEE80211_FILTER_TYPE_BEACON = 0x1,
127 IEEE80211_FILTER_TYPE_PROBE_REQ = 0x2,
128 IEEE80211_FILTER_TYPE_PROBE_RESP = 0x4,
129 IEEE80211_FILTER_TYPE_ASSOC_REQ = 0x8,
130 IEEE80211_FILTER_TYPE_ASSOC_RESP = 0x10,
131 IEEE80211_FILTER_TYPE_AUTH = 0x20,
132 IEEE80211_FILTER_TYPE_DEAUTH = 0x40,
133 IEEE80211_FILTER_TYPE_DISASSOC = 0x80,
134 IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */
135};
136
137struct ieee80211req_set_filter {
138 u_int32_t app_filterype; /* management frame filter type */
139};
140
141enum {
142 IEEE80211_PARAM_AUTHMODE = 3, /* Authentication Mode */
143 IEEE80211_PARAM_MCASTCIPHER = 5,
144 IEEE80211_PARAM_MCASTKEYLEN = 6, /* multicast key length */
145 IEEE80211_PARAM_UCASTCIPHER = 8,
146 IEEE80211_PARAM_UCASTKEYLEN = 9, /* unicast key length */
147 IEEE80211_PARAM_WPA = 10, /* WPA mode (0,1,2) */
148 IEEE80211_PARAM_ROAMING = 12, /* roaming mode */
149 IEEE80211_PARAM_PRIVACY = 13, /* privacy invoked */
150 IEEE80211_PARAM_COUNTERMEASURES = 14, /* WPA/TKIP countermeasures */
151 IEEE80211_PARAM_DROPUNENCRYPTED = 15, /* discard unencrypted frames */
152 IEEE80211_PARAM_WAPI = 16, /* WAPI policy from wapid */
153};
154
155/*
156 * Values for IEEE80211_PARAM_WPA
157 */
158#define WPA_MODE_WPA1 1
159#define WPA_MODE_WPA2 2
160#define WPA_MODE_AUTO 3
161#define WPA_MODE_NONE 4
162
163struct ieee80211req_wpaie {
164 u_int8_t wpa_macaddr[IEEE80211_ADDR_LEN];
165 u_int8_t wpa_ie[IEEE80211_MAX_IE];
166 u_int8_t rsn_ie[IEEE80211_MAX_IE];
167};
168
169#ifndef IW_ENCODE_ALG_PMK
170#define IW_ENCODE_ALG_PMK 4
171#endif
172
173#ifdef __cplusplus
174}
175#endif
176
177#endif /* _IEEE80211_IOCTL_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h
new file mode 100644
index 00000000000..41f43730772
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h
@@ -0,0 +1,339 @@
1//------------------------------------------------------------------------------
2// This file contains the definitions of the basic atheros data types.
3// It is used to map the data types in atheros files to a platform specific
4// type.
5// Copyright (c) 2004-2010 Atheros Communications Inc.
6// All rights reserved.
7//
8//
9//
10// Permission to use, copy, modify, and/or distribute this software for any
11// purpose with or without fee is hereby granted, provided that the above
12// copyright notice and this permission notice appear in all copies.
13//
14// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21//
22//
23//
24// Author(s): ="Atheros"
25//------------------------------------------------------------------------------
26
27#ifndef _OSAPI_LINUX_H_
28#define _OSAPI_LINUX_H_
29
30#ifdef __KERNEL__
31
32#include <linux/types.h>
33#include <linux/kernel.h>
34#include <linux/string.h>
35#include <linux/skbuff.h>
36#include <linux/netdevice.h>
37#include <linux/jiffies.h>
38#include <linux/timer.h>
39#include <linux/delay.h>
40#include <linux/wait.h>
41#include <linux/semaphore.h>
42#include <linux/cache.h>
43
44#ifdef __GNUC__
45#define __ATTRIB_PACK __attribute__ ((packed))
46#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2)))
47#define __ATTRIB_NORETURN __attribute__ ((noreturn))
48#ifndef INLINE
49#define INLINE __inline__
50#endif
51#else /* Not GCC */
52#define __ATTRIB_PACK
53#define __ATTRIB_PRINTF
54#define __ATTRIB_NORETURN
55#ifndef INLINE
56#define INLINE __inline
57#endif
58#endif /* End __GNUC__ */
59
60#define PREPACK
61#define POSTPACK __ATTRIB_PACK
62
63/*
64 * Endianes macros
65 */
66#define A_BE2CPU8(x) ntohb(x)
67#define A_BE2CPU16(x) ntohs(x)
68#define A_BE2CPU32(x) ntohl(x)
69
70#define A_LE2CPU8(x) (x)
71#define A_LE2CPU16(x) (x)
72#define A_LE2CPU32(x) (x)
73
74#define A_CPU2BE8(x) htonb(x)
75#define A_CPU2BE16(x) htons(x)
76#define A_CPU2BE32(x) htonl(x)
77
78#define A_MEMZERO(addr, len) memset(addr, 0, len)
79#define A_MALLOC(size) kmalloc((size), GFP_KERNEL)
80#define A_MALLOC_NOWAIT(size) kmalloc((size), GFP_ATOMIC)
81
82#define A_LOGGER(mask, mod, args...) printk(KERN_ALERT args)
83#define A_PRINTF(args...) printk(KERN_ALERT args)
84
85#define A_PRINTF_LOG(args...) printk(args)
86#define A_SPRINTF(buf, args...) sprintf (buf, args)
87
88/* Mutual Exclusion */
89typedef spinlock_t A_MUTEX_T;
90#define A_MUTEX_INIT(mutex) spin_lock_init(mutex)
91#define A_MUTEX_LOCK(mutex) spin_lock_bh(mutex)
92#define A_MUTEX_UNLOCK(mutex) spin_unlock_bh(mutex)
93#define A_IS_MUTEX_VALID(mutex) true /* okay to return true, since A_MUTEX_DELETE does nothing */
94#define A_MUTEX_DELETE(mutex) /* spin locks are not kernel resources so nothing to free.. */
95
96/* Get current time in ms adding a constant offset (in ms) */
97#define A_GET_MS(offset) \
98 (((jiffies / HZ) * 1000) + (offset))
99
100/*
101 * Timer Functions
102 */
103#define A_MDELAY(msecs) mdelay(msecs)
104typedef struct timer_list A_TIMER;
105
106#define A_INIT_TIMER(pTimer, pFunction, pArg) do { \
107 init_timer(pTimer); \
108 (pTimer)->function = (pFunction); \
109 (pTimer)->data = (unsigned long)(pArg); \
110} while (0)
111
112/*
113 * Start a Timer that elapses after 'periodMSec' milli-seconds
114 * Support is provided for a one-shot timer. The 'repeatFlag' is
115 * ignored.
116 */
117#define A_TIMEOUT_MS(pTimer, periodMSec, repeatFlag) do { \
118 if (repeatFlag) { \
119 printk("\n" __FILE__ ":%d: Timer Repeat requested\n",__LINE__); \
120 panic("Timer Repeat"); \
121 } \
122 mod_timer((pTimer), jiffies + HZ * (periodMSec) / 1000); \
123} while (0)
124
125/*
126 * Cancel the Timer.
127 */
128#define A_UNTIMEOUT(pTimer) do { \
129 del_timer((pTimer)); \
130} while (0)
131
132#define A_DELETE_TIMER(pTimer) do { \
133} while (0)
134
135/*
136 * Wait Queue related functions
137 */
138typedef wait_queue_head_t A_WAITQUEUE_HEAD;
139#define A_INIT_WAITQUEUE_HEAD(head) init_waitqueue_head(head)
140#ifndef wait_event_interruptible_timeout
141#define __wait_event_interruptible_timeout(wq, condition, ret) \
142do { \
143 wait_queue_t __wait; \
144 init_waitqueue_entry(&__wait, current); \
145 \
146 add_wait_queue(&wq, &__wait); \
147 for (;;) { \
148 set_current_state(TASK_INTERRUPTIBLE); \
149 if (condition) \
150 break; \
151 if (!signal_pending(current)) { \
152 ret = schedule_timeout(ret); \
153 if (!ret) \
154 break; \
155 continue; \
156 } \
157 ret = -ERESTARTSYS; \
158 break; \
159 } \
160 current->state = TASK_RUNNING; \
161 remove_wait_queue(&wq, &__wait); \
162} while (0)
163
164#define wait_event_interruptible_timeout(wq, condition, timeout) \
165({ \
166 long __ret = timeout; \
167 if (!(condition)) \
168 __wait_event_interruptible_timeout(wq, condition, __ret); \
169 __ret; \
170})
171#endif /* wait_event_interruptible_timeout */
172
173#define A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(head, condition, timeout) do { \
174 wait_event_interruptible_timeout(head, condition, timeout); \
175} while (0)
176
177#define A_WAKE_UP(head) wake_up(head)
178
179#ifdef DEBUG
180extern unsigned int panic_on_assert;
181#define A_ASSERT(expr) \
182 if (!(expr)) { \
183 printk(KERN_ALERT"Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#expr); \
184 if (panic_on_assert) panic(#expr); \
185 }
186#else
187#define A_ASSERT(expr)
188#endif /* DEBUG */
189
190#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) request_firmware(_ppf, _pfile, _dev)
191#define A_RELEASE_FIRMWARE(_pf) release_firmware(_pf)
192
193/*
194 * Initialization of the network buffer subsystem
195 */
196#define A_NETBUF_INIT()
197
198/*
199 * Network buffer queue support
200 */
201typedef struct sk_buff_head A_NETBUF_QUEUE_T;
202
203#define A_NETBUF_QUEUE_INIT(q) \
204 a_netbuf_queue_init(q)
205
206#define A_NETBUF_ENQUEUE(q, pkt) \
207 a_netbuf_enqueue((q), (pkt))
208#define A_NETBUF_PREQUEUE(q, pkt) \
209 a_netbuf_prequeue((q), (pkt))
210#define A_NETBUF_DEQUEUE(q) \
211 (a_netbuf_dequeue(q))
212#define A_NETBUF_QUEUE_SIZE(q) \
213 a_netbuf_queue_size(q)
214#define A_NETBUF_QUEUE_EMPTY(q) \
215 (a_netbuf_queue_empty(q) ? true : false)
216
217/*
218 * Network buffer support
219 */
220#define A_NETBUF_ALLOC(size) \
221 a_netbuf_alloc(size)
222#define A_NETBUF_ALLOC_RAW(size) \
223 a_netbuf_alloc_raw(size)
224#define A_NETBUF_FREE(bufPtr) \
225 a_netbuf_free(bufPtr)
226#define A_NETBUF_DATA(bufPtr) \
227 a_netbuf_to_data(bufPtr)
228#define A_NETBUF_LEN(bufPtr) \
229 a_netbuf_to_len(bufPtr)
230#define A_NETBUF_PUSH(bufPtr, len) \
231 a_netbuf_push(bufPtr, len)
232#define A_NETBUF_PUT(bufPtr, len) \
233 a_netbuf_put(bufPtr, len)
234#define A_NETBUF_TRIM(bufPtr,len) \
235 a_netbuf_trim(bufPtr, len)
236#define A_NETBUF_PULL(bufPtr, len) \
237 a_netbuf_pull(bufPtr, len)
238#define A_NETBUF_HEADROOM(bufPtr)\
239 a_netbuf_headroom(bufPtr)
240#define A_NETBUF_SETLEN(bufPtr,len) \
241 a_netbuf_setlen(bufPtr, len)
242
243/* Add data to end of a buffer */
244#define A_NETBUF_PUT_DATA(bufPtr, srcPtr, len) \
245 a_netbuf_put_data(bufPtr, srcPtr, len)
246
247/* Add data to start of the buffer */
248#define A_NETBUF_PUSH_DATA(bufPtr, srcPtr, len) \
249 a_netbuf_push_data(bufPtr, srcPtr, len)
250
251/* Remove data at start of the buffer */
252#define A_NETBUF_PULL_DATA(bufPtr, dstPtr, len) \
253 a_netbuf_pull_data(bufPtr, dstPtr, len)
254
255/* Remove data from the end of the buffer */
256#define A_NETBUF_TRIM_DATA(bufPtr, dstPtr, len) \
257 a_netbuf_trim_data(bufPtr, dstPtr, len)
258
259/* View data as "size" contiguous bytes of type "t" */
260#define A_NETBUF_VIEW_DATA(bufPtr, t, size) \
261 (t )( ((struct skbuf *)(bufPtr))->data)
262
263/* return the beginning of the headroom for the buffer */
264#define A_NETBUF_HEAD(bufPtr) \
265 ((((struct sk_buff *)(bufPtr))->head))
266
267/*
268 * OS specific network buffer access routines
269 */
270void *a_netbuf_alloc(int size);
271void *a_netbuf_alloc_raw(int size);
272void a_netbuf_free(void *bufPtr);
273void *a_netbuf_to_data(void *bufPtr);
274u32 a_netbuf_to_len(void *bufPtr);
275int a_netbuf_push(void *bufPtr, s32 len);
276int a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len);
277int a_netbuf_put(void *bufPtr, s32 len);
278int a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len);
279int a_netbuf_pull(void *bufPtr, s32 len);
280int a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len);
281int a_netbuf_trim(void *bufPtr, s32 len);
282int a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len);
283int a_netbuf_setlen(void *bufPtr, s32 len);
284s32 a_netbuf_headroom(void *bufPtr);
285void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt);
286void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt);
287void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q);
288int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q);
289int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
290int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
291void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q);
292
293/*
294 * Kernel v.s User space functions
295 */
296u32 a_copy_to_user(void *to, const void *from, u32 n);
297u32 a_copy_from_user(void *to, const void *from, u32 n);
298
299/* In linux, WLAN Rx and Tx run in different contexts, so no need to check
300 * for any commands/data queued for WLAN */
301#define A_CHECK_DRV_TX()
302
303#define A_GET_CACHE_LINE_BYTES() L1_CACHE_BYTES
304
305#define A_CACHE_LINE_PAD 128
306
307static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) {
308 return (void *)L1_CACHE_ALIGN((unsigned long)ptr);
309}
310
311#else /* __KERNEL__ */
312
313#ifdef __GNUC__
314#define __ATTRIB_PACK __attribute__ ((packed))
315#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2)))
316#define __ATTRIB_NORETURN __attribute__ ((noreturn))
317#ifndef INLINE
318#define INLINE __inline__
319#endif
320#else /* Not GCC */
321#define __ATTRIB_PACK
322#define __ATTRIB_PRINTF
323#define __ATTRIB_NORETURN
324#ifndef INLINE
325#define INLINE __inline
326#endif
327#endif /* End __GNUC__ */
328
329#define PREPACK
330#define POSTPACK __ATTRIB_PACK
331
332#define A_MEMZERO(addr, len) memset((addr), 0, (len))
333#define A_MALLOC(size) malloc(size)
334
335#include <err.h>
336
337#endif /* __KERNEL__ */
338
339#endif /* _OSAPI_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/wlan_config.h b/drivers/staging/ath6kl/os/linux/include/wlan_config.h
new file mode 100644
index 00000000000..c1fe0c6e4fa
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/wlan_config.h
@@ -0,0 +1,108 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// This file contains the tunable configuration items for the WLAN module
21//
22// Author(s): ="Atheros"
23//==============================================================================
24#ifndef _HOST_WLAN_CONFIG_H_
25#define _HOST_WLAN_CONFIG_H_
26
27/* Include definitions here that can be used to tune the WLAN module behavior.
28 * Different customers can tune the behavior as per their needs, here.
29 */
30
31/* This configuration item when defined will consider the barker preamble
32 * mentioned in the ERP IE of the beacons from the AP to determine the short
33 * preamble support sent in the (Re)Assoc request frames.
34 */
35#define WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP 0
36
37/* This config item when defined will not send the power module state transition
38 * failure events that happen during scan, to the host.
39 */
40#define WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN 0
41
42/*
43 * This configuration item enable/disable keepalive support.
44 * Keepalive support: In the absence of any data traffic to AP, null
45 * frames will be sent to the AP at periodic interval, to keep the association
46 * active. This configuration item defines the periodic interval.
47 * Use value of zero to disable keepalive support
48 * Default: 60 seconds
49 */
50#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
51
52/*
53 * This configuration item sets the value of disconnect timeout
54 * Firmware delays sending the disconnec event to the host for this
55 * timeout after is gets disconnected from the current AP.
56 * If the firmware successly roams within the disconnect timeout
57 * it sends a new connect event
58 */
59#define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
60
61/*
62 * This configuration item disables 11n support.
63 * 0 - Enable
64 * 1 - Disable
65 */
66#define WLAN_CONFIG_DISABLE_11N 0
67
68/*
69 * This configuration item enable BT clock sharing support
70 * 1 - Enable
71 * 0 - Disable (Default)
72 */
73#define WLAN_CONFIG_BT_SHARING 0
74
75/*
76 * This configuration item sets WIFI OFF policy
77 * 0 - CUT_POWER
78 * 1 - DEEP_SLEEP (Default)
79 */
80#define WLAN_CONFIG_WLAN_OFF 1
81
82/*
83 * This configuration item sets suspend policy
84 * 0 - CUT_POWER (Default)
85 * 1 - DEEP_SLEEP
86 * 2 - WoW
87 * 3 - CUT_POWER if BT OFF (clock sharing designs only)
88 */
89#define WLAN_CONFIG_PM_SUSPEND 0
90
91/*
92 * This configuration item sets suspend policy to use if PM_SUSPEND is
93 * set to WoW and device is not connected at the time of suspend
94 * 0 - CUT_POWER (Default)
95 * 1 - DEEP_SLEEP
96 * 2 - WoW
97 * 3 - CUT_POWER if BT OFF (clock sharing designs only)
98 */
99#define WLAN_CONFIG_PM_WOW2 0
100
101/*
102 * This configuration item enables/disables transmit bursting
103 * 0 - Enable tx Bursting (default)
104 * 1 - Disable tx bursting
105 */
106#define WLAN_CONFIG_DISABLE_TX_BURSTING 0
107
108#endif /* _HOST_WLAN_CONFIG_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h
new file mode 100644
index 00000000000..1eb6f822d64
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h
@@ -0,0 +1,300 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
24#ifndef _WMI_FILTER_LINUX_H_
25#define _WMI_FILTER_LINUX_H_
26
27/*
28 * sioctl_filter - Standard ioctl
29 * pioctl_filter - Priv ioctl
30 * xioctl_filter - eXtended ioctl
31 *
32 * ---- Possible values for the WMI filter ---------------
33 * (0) - Block this cmd always (or) not implemented
34 * (INFRA_NETWORK) - Allow this cmd only in STA mode
35 * (ADHOC_NETWORK) - Allow this cmd only in IBSS mode
36 * (AP_NETWORK) - Allow this cmd only in AP mode
37 * (INFRA_NETWORK | ADHOC_NETWORK) - Block this cmd in AP mode
38 * (ADHOC_NETWORK | AP_NETWORK) - Block this cmd in STA mode
39 * (INFRA_NETWORK | AP_NETWORK) - Block this cmd in IBSS mode
40 * (INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK)- allow only when mode is set
41 * (0xFF) - Allow this cmd always irrespective of mode
42 */
43
44u8 sioctl_filter[] = {
45(AP_NETWORK), /* SIOCSIWCOMMIT 0x8B00 */
46(0xFF), /* SIOCGIWNAME 0x8B01 */
47(0), /* SIOCSIWNWID 0x8B02 */
48(0), /* SIOCGIWNWID 0x8B03 */
49(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWFREQ 0x8B04 */
50(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWFREQ 0x8B05 */
51(0xFF), /* SIOCSIWMODE 0x8B06 */
52(0xFF), /* SIOCGIWMODE 0x8B07 */
53(0), /* SIOCSIWSENS 0x8B08 */
54(0), /* SIOCGIWSENS 0x8B09 */
55(0), /* SIOCSIWRANGE 0x8B0A */
56(0xFF), /* SIOCGIWRANGE 0x8B0B */
57(0), /* SIOCSIWPRIV 0x8B0C */
58(0), /* SIOCGIWPRIV 0x8B0D */
59(0), /* SIOCSIWSTATS 0x8B0E */
60(0), /* SIOCGIWSTATS 0x8B0F */
61(0), /* SIOCSIWSPY 0x8B10 */
62(0), /* SIOCGIWSPY 0x8B11 */
63(0), /* SIOCSIWTHRSPY 0x8B12 */
64(0), /* SIOCGIWTHRSPY 0x8B13 */
65(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWAP 0x8B14 */
66(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWAP 0x8B15 */
67#if (WIRELESS_EXT >= 18)
68(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWMLME 0X8B16 */
69#else
70(0), /* Dummy 0 */
71#endif /* WIRELESS_EXT */
72(0), /* SIOCGIWAPLIST 0x8B17 */
73(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWSCAN 0x8B18 */
74(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCGIWSCAN 0x8B19 */
75(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWESSID 0x8B1A */
76(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWESSID 0x8B1B */
77(0), /* SIOCSIWNICKN 0x8B1C */
78(0), /* SIOCGIWNICKN 0x8B1D */
79(0), /* Dummy 0 */
80(0), /* Dummy 0 */
81(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWRATE 0x8B20 */
82(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWRATE 0x8B21 */
83(0), /* SIOCSIWRTS 0x8B22 */
84(0), /* SIOCGIWRTS 0x8B23 */
85(0), /* SIOCSIWFRAG 0x8B24 */
86(0), /* SIOCGIWFRAG 0x8B25 */
87(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWTXPOW 0x8B26 */
88(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWTXPOW 0x8B27 */
89(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWRETRY 0x8B28 */
90(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCGIWRETRY 0x8B29 */
91(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWENCODE 0x8B2A */
92(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWENCODE 0x8B2B */
93(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWPOWER 0x8B2C */
94(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWPOWER 0x8B2D */
95};
96
97
98
99u8 pioctl_filter[] = {
100(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) */
101(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1) */
102(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2) */
103(AP_NETWORK), /* IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+3) */
104(INFRA_NETWORK), /* IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+4) */
105(0), /* IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+5) */
106(0), /* (SIOCIWFIRSTPRIV+6) */
107(0), /* (SIOCIWFIRSTPRIV+7) */
108(0), /* (SIOCIWFIRSTPRIV+8) */
109(0), /* (SIOCIWFIRSTPRIV+9) */
110(0), /* IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+10) */
111(0xFF), /* AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+11) */
112(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+12) */
113(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+13) */
114(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+14) */
115(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+15) */
116(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16) */
117(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17) */
118(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18) */
119(INFRA_NETWORK), /* AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19) */
120(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20) */
121(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21) */
122(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22) */
123(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23) */
124(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)*/
125(0xFF), /* AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25) */
126(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26) */
127(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27) */
128(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28) */
129(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29) */
130(ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30) */
131};
132
133
134
135u8 xioctl_filter[] = {
136(0xFF), /* Dummy 0 */
137(0xFF), /* AR6000_XIOCTL_BMI_DONE 1 */
138(0xFF), /* AR6000_XIOCTL_BMI_READ_MEMORY 2 */
139(0xFF), /* AR6000_XIOCTL_BMI_WRITE_MEMORY 3 */
140(0xFF), /* AR6000_XIOCTL_BMI_EXECUTE 4 */
141(0xFF), /* AR6000_XIOCTL_BMI_SET_APP_START 5 */
142(0xFF), /* AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6 */
143(0xFF), /* AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7 */
144(0xFF), /* AR6000_XIOCTL_BMI_TEST 8 */
145(0xFF), /* AR6000_XIOCTL_UNUSED9 9 */
146(0xFF), /* AR6000_XIOCTL_UNUSED10 10 */
147(0xFF), /* AR6000_XIOCTL_UNUSED11 11 */
148(0xFF), /* AR6000_XIOCTL_FORCE_TARGET_RESET 12 */
149(0xFF), /* AR6000_XIOCTL_HTC_RAW_OPEN 13 */
150(0xFF), /* AR6000_XIOCTL_HTC_RAW_CLOSE 14 */
151(0xFF), /* AR6000_XIOCTL_HTC_RAW_READ 15 */
152(0xFF), /* AR6000_XIOCTL_HTC_RAW_WRITE 16 */
153(0xFF), /* AR6000_XIOCTL_CHECK_TARGET_READY 17 */
154(0xFF), /* AR6000_XIOCTL_GPIO_OUTPUT_SET 18 */
155(0xFF), /* AR6000_XIOCTL_GPIO_INPUT_GET 19 */
156(0xFF), /* AR6000_XIOCTL_GPIO_REGISTER_SET 20 */
157(0xFF), /* AR6000_XIOCTL_GPIO_REGISTER_GET 21 */
158(0xFF), /* AR6000_XIOCTL_GPIO_INTR_ACK 22 */
159(0xFF), /* AR6000_XIOCTL_GPIO_INTR_WAIT 23 */
160(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_ADHOC_BSSID 24 */
161(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_OPT_MODE 25 */
162(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_OPT_SEND_FRAME 26 */
163(ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_SET_BEACON_INTVAL 27 */
164(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETAUTHALG 28 */
165(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29 */
166(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_MAX_SP 30 */
167(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_ROAM_TBL 31 */
168(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32 */
169(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33 */
170(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTRL_WMI_GET_POWER_MODE 34 */
171(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35 */
172(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_ROAM_DATA 36 */
173(0xFF), /* AR6000_XIOCTL_WMI_SETRETRYLIMITS 37 */
174(0xFF), /* AR6000_XIOCTL_TCMD_CONT_TX 38 */
175(0xFF), /* AR6000_XIOCTL_TCMD_CONT_RX 39 */
176(0xFF), /* AR6000_XIOCTL_TCMD_PM 40 */
177(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_STARTSCAN 41 */
178(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SETFIXRATES 42 */
179(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_GETFIXRATES 43 */
180(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44 */
181(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_CLR_RSSISNR 45 */
182(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46 */
183(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_RTS 47 */
184(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_LPREAMBLE 48 */
185(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_AUTHMODE 49 */
186(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_REASSOCMODE 50 */
187(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WMM 51 */
188(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52 */
189(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53 */
190(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_GET_RD 54 */
191(0xFF), /* AR6000_XIOCTL_DIAG_READ 55 */
192(0xFF), /* AR6000_XIOCTL_DIAG_WRITE 56 */
193(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_TXOP 57 */
194(INFRA_NETWORK), /* AR6000_XIOCTL_USER_SETKEYS 58 */
195(INFRA_NETWORK), /* AR6000_XIOCTL_WMI_SET_KEEPALIVE 59 */
196(INFRA_NETWORK), /* AR6000_XIOCTL_WMI_GET_KEEPALIVE 60 */
197(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61 */
198(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62 */
199(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63 */
200(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64 */
201(0xFF), /* AR6000_XIOCTL_WMI_SET_APPIE 65 */
202(0xFF), /* AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66 */
203(0xFF), /* AR6000_XIOCTL_DBGLOG_CFG_MODULE 67 */
204(0xFF), /* AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68 */
205(0xFF), /* Dummy 69 */
206(0xFF), /* AR6000_XIOCTL_WMI_SET_WSC_STATUS 70 */
207(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_STATUS 71 */
208(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_PARAMS 72 */
209(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73 */
210(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WOW_MODE 74 */
211(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_WOW_LIST 75 */
212(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76 */
213(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77 */
214(0xFF), /* AR6000_XIOCTL_TARGET_INFO 78 */
215(0xFF), /* AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79 */
216(0xFF), /* AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80 */
217(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81 */
218(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82 */
219(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_PMKID_LIST 83 */
220(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_PMKID_LIST 84 */
221(0xFF), /* Dummy 85 */
222(0xFF), /* Dummy 86 */
223(0xFF), /* Dummy 87 */
224(0xFF), /* Dummy 88 */
225(0xFF), /* Dummy 89 */
226(0xFF), /* AR6000_XIOCTL_UNUSED90 90 */
227(0xFF), /* AR6000_XIOCTL_BMI_LZ_STREAM_START 91 */
228(0xFF), /* AR6000_XIOCTL_BMI_LZ_DATA 92 */
229(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_CFG 93 */
230(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_ADDR_SET 94 */
231(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_START 95 */
232(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_STOP 96 */
233(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_COUNT_GET 97 */
234(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_ABORT_SCAN 98 */
235(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_STA_LIST 99 */
236(AP_NETWORK), /* AR6000_XIOCTL_AP_HIDDEN_SSID 100 */
237(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_NUM_STA 101 */
238(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_ACL_MAC 102 */
239(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_ACL_LIST 103 */
240(AP_NETWORK), /* AR6000_XIOCTL_AP_COMMIT_CONFIG 104 */
241(AP_NETWORK), /* IEEE80211_IOCTL_GETWPAIE 105 */
242(AP_NETWORK), /* AR6000_XIOCTL_AP_CONN_INACT_TIME 106 */
243(AP_NETWORK), /* AR6000_XIOCTL_AP_PROT_SCAN_TIME 107 */
244(AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_COUNTRY 108 */
245(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_DTIM 109 */
246(0xFF), /* AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT 110 */
247(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_IP 111 */
248(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_ACL_POLICY 112 */
249(AP_NETWORK), /* AR6000_XIOCTL_AP_INTRA_BSS_COMM 113 */
250(0xFF), /* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO 114 */
251(0xFF), /* AR6000_XIOCTL_MODULE_DEBUG_SET_MASK 115 */
252(0xFF), /* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK 116 */
253(0xFF), /* AR6000_XIOCTL_DUMP_RCV_AGGR_STATS 117 */
254(0xFF), /* AR6000_XIOCTL_SET_HT_CAP 118 */
255(0xFF), /* AR6000_XIOCTL_SET_HT_OP 119 */
256(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_STAT 120 */
257(0xFF), /* AR6000_XIOCTL_SET_TX_SELECT_RATES 121 */
258(0xFF), /* AR6000_XIOCTL_SETUP_AGGR 122 */
259(0xFF), /* AR6000_XIOCTL_ALLOW_AGGR 123 */
260(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_HIDDEN_SSID 124 */
261(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_COUNTRY 125 */
262(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_WMODE 126 */
263(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_DTIM 127 */
264(AP_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_AP_GET_BINTVL 128 */
265(0xFF), /* AR6000_XIOCTL_AP_GET_RTS 129 */
266(0xFF), /* AR6000_XIOCTL_DELE_AGGR 130 */
267(0xFF), /* AR6000_XIOCTL_FETCH_TARGET_REGS 131 */
268(0xFF), /* AR6000_XIOCTL_HCI_CMD 132 */
269(0xFF), /* AR6000_XIOCTL_ACL_DATA(used to be used for PAL) 133 */
270(0xFF), /* AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134 */
271(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_11BG_RATESET 135 */
272(0xFF),
273(0xFF),
274(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT 138 */
275(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV 139 */
276(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG 140 */
277(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG 141 */
278(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG 142 */
279(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG 143 */
280(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG 144 */
281(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS 145 */
282(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG 146 */
283(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_BTCOEX_GET_STATS 147 */
284(0xFF), /* AR6000_XIOCTL_WMI_SET_QOS_SUPP 148 */
285(0xFF), /* AR6000_XIOCTL_GET_WLAN_SLEEP_STATE 149 */
286(0xFF), /* AR6000_XIOCTL_SET_BT_HW_POWER_STATE 150 */
287(0xFF), /* AR6000_XIOCTL_GET_BT_HW_POWER_STATE 151 */
288(0xFF), /* AR6000_XIOCTL_ADD_AP_INTERFACE 152 */
289(0xFF), /* AR6000_XIOCTL_REMOVE_AP_INTERFACE 153 */
290(0xFF), /* AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154 */
291(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WPA_OFFLOAD_STATE 155 */
292(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_PASSPHRASE 156 */
293(0xFF),
294(0xFF),
295(0xFF),
296(0xFF),
297(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES 161 */
298};
299
300#endif /*_WMI_FILTER_LINUX_H_*/
diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c
new file mode 100644
index 00000000000..963a2fb76a9
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/netbuf.c
@@ -0,0 +1,231 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23#include <a_config.h>
24#include "athdefs.h"
25#include "a_osapi.h"
26#include "htc_packet.h"
27
28#define AR6000_DATA_OFFSET 64
29
30void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt)
31{
32 skb_queue_tail((struct sk_buff_head *) q, (struct sk_buff *) pkt);
33}
34
35void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt)
36{
37 skb_queue_head((struct sk_buff_head *) q, (struct sk_buff *) pkt);
38}
39
40void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q)
41{
42 return((void *) skb_dequeue((struct sk_buff_head *) q));
43}
44
45int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q)
46{
47 return(skb_queue_len((struct sk_buff_head *) q));
48}
49
50int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q)
51{
52 return(skb_queue_empty((struct sk_buff_head *) q));
53}
54
55void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q)
56{
57 skb_queue_head_init((struct sk_buff_head *) q);
58}
59
60void *
61a_netbuf_alloc(int size)
62{
63 struct sk_buff *skb;
64 size += 2 * (A_GET_CACHE_LINE_BYTES()); /* add some cacheline space at front and back of buffer */
65 skb = dev_alloc_skb(AR6000_DATA_OFFSET + sizeof(struct htc_packet) + size);
66 skb_reserve(skb, AR6000_DATA_OFFSET + sizeof(struct htc_packet) + A_GET_CACHE_LINE_BYTES());
67 return ((void *)skb);
68}
69
70/*
71 * Allocate an SKB w.o. any encapsulation requirement.
72 */
73void *
74a_netbuf_alloc_raw(int size)
75{
76 struct sk_buff *skb;
77
78 skb = dev_alloc_skb(size);
79
80 return ((void *)skb);
81}
82
83void
84a_netbuf_free(void *bufPtr)
85{
86 struct sk_buff *skb = (struct sk_buff *)bufPtr;
87
88 dev_kfree_skb(skb);
89}
90
91u32 a_netbuf_to_len(void *bufPtr)
92{
93 return (((struct sk_buff *)bufPtr)->len);
94}
95
96void *
97a_netbuf_to_data(void *bufPtr)
98{
99 return (((struct sk_buff *)bufPtr)->data);
100}
101
102/*
103 * Add len # of bytes to the beginning of the network buffer
104 * pointed to by bufPtr
105 */
106int
107a_netbuf_push(void *bufPtr, s32 len)
108{
109 skb_push((struct sk_buff *)bufPtr, len);
110
111 return 0;
112}
113
114/*
115 * Add len # of bytes to the beginning of the network buffer
116 * pointed to by bufPtr and also fill with data
117 */
118int
119a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len)
120{
121 skb_push((struct sk_buff *) bufPtr, len);
122 memcpy(((struct sk_buff *)bufPtr)->data, srcPtr, len);
123
124 return 0;
125}
126
127/*
128 * Add len # of bytes to the end of the network buffer
129 * pointed to by bufPtr
130 */
131int
132a_netbuf_put(void *bufPtr, s32 len)
133{
134 skb_put((struct sk_buff *)bufPtr, len);
135
136 return 0;
137}
138
139/*
140 * Add len # of bytes to the end of the network buffer
141 * pointed to by bufPtr and also fill with data
142 */
143int
144a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len)
145{
146 char *start = (char*)(((struct sk_buff *)bufPtr)->data +
147 ((struct sk_buff *)bufPtr)->len);
148 skb_put((struct sk_buff *)bufPtr, len);
149 memcpy(start, srcPtr, len);
150
151 return 0;
152}
153
154
155/*
156 * Trim the network buffer pointed to by bufPtr to len # of bytes
157 */
158int
159a_netbuf_setlen(void *bufPtr, s32 len)
160{
161 skb_trim((struct sk_buff *)bufPtr, len);
162
163 return 0;
164}
165
166/*
167 * Chop of len # of bytes from the end of the buffer.
168 */
169int
170a_netbuf_trim(void *bufPtr, s32 len)
171{
172 skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len);
173
174 return 0;
175}
176
177/*
178 * Chop of len # of bytes from the end of the buffer and return the data.
179 */
180int
181a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len)
182{
183 char *start = (char*)(((struct sk_buff *)bufPtr)->data +
184 (((struct sk_buff *)bufPtr)->len - len));
185
186 memcpy(dstPtr, start, len);
187 skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len);
188
189 return 0;
190}
191
192
193/*
194 * Returns the number of bytes available to a a_netbuf_push()
195 */
196s32 a_netbuf_headroom(void *bufPtr)
197{
198 return (skb_headroom((struct sk_buff *)bufPtr));
199}
200
201/*
202 * Removes specified number of bytes from the beginning of the buffer
203 */
204int
205a_netbuf_pull(void *bufPtr, s32 len)
206{
207 skb_pull((struct sk_buff *)bufPtr, len);
208
209 return 0;
210}
211
212/*
213 * Removes specified number of bytes from the beginning of the buffer
214 * and return the data
215 */
216int
217a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len)
218{
219 memcpy(dstPtr, ((struct sk_buff *)bufPtr)->data, len);
220 skb_pull((struct sk_buff *)bufPtr, len);
221
222 return 0;
223}
224
225#ifdef EXPORT_HCI_BRIDGE_INTERFACE
226EXPORT_SYMBOL(a_netbuf_to_data);
227EXPORT_SYMBOL(a_netbuf_put);
228EXPORT_SYMBOL(a_netbuf_pull);
229EXPORT_SYMBOL(a_netbuf_alloc);
230EXPORT_SYMBOL(a_netbuf_free);
231#endif
diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h
new file mode 100644
index 00000000000..11125967d53
--- /dev/null
+++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h
@@ -0,0 +1,117 @@
1/*
2 *
3 * Copyright (c) 2004-2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7//
8// Permission to use, copy, modify, and/or distribute this software for any
9// purpose with or without fee is hereby granted, provided that the above
10// copyright notice and this permission notice appear in all copies.
11//
12// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19//
20//
21 *
22 */
23
24#ifndef __AGGR_RX_INTERNAL_H__
25#define __AGGR_RX_INTERNAL_H__
26
27#include "a_osapi.h"
28#include "aggr_recv_api.h"
29
30#define AGGR_WIN_IDX(x, y) ((x) % (y))
31#define AGGR_INCR_IDX(x, y) AGGR_WIN_IDX(((x)+1), (y))
32#define AGGR_DCRM_IDX(x, y) AGGR_WIN_IDX(((x)-1), (y))
33#define IEEE80211_MAX_SEQ_NO 0xFFF
34#define IEEE80211_NEXT_SEQ_NO(x) (((x) + 1) & IEEE80211_MAX_SEQ_NO)
35
36
37#define NUM_OF_TIDS 8
38#define AGGR_SZ_DEFAULT 8
39
40#define AGGR_WIN_SZ_MIN 2
41#define AGGR_WIN_SZ_MAX 8
42/* TID Window sz is double of what is negotiated. Derive TID_WINDOW_SZ from win_sz, per tid */
43#define TID_WINDOW_SZ(_x) ((_x) << 1)
44
45#define AGGR_NUM_OF_FREE_NETBUFS 16
46
47#define AGGR_GET_RXTID_STATS(_p, _x) (&(_p->stat[(_x)]))
48#define AGGR_GET_RXTID(_p, _x) (&(_p->RxTid[(_x)]))
49
50/* Hold q is a function of win_sz, which is negotiated per tid */
51#define HOLD_Q_SZ(_x) (TID_WINDOW_SZ((_x))*sizeof(struct osbuf_hold_q))
52/* AGGR_RX_TIMEOUT value is important as a (too) small value can cause frames to be
53 * delivered out of order and a (too) large value can cause undesirable latency in
54 * certain situations. */
55#define AGGR_RX_TIMEOUT 400 /* Timeout(in ms) for delivery of frames, if they are stuck */
56
57typedef enum {
58 ALL_SEQNO = 0,
59 CONTIGUOUS_SEQNO = 1,
60}DELIVERY_ORDER;
61
62struct osbuf_hold_q {
63 void *osbuf;
64 bool is_amsdu;
65 u16 seq_no;
66};
67
68
69#if 0
70/* XXX: unused ? */
71struct window_snapshot {
72 u16 seqno_st;
73 u16 seqno_end;
74};
75#endif
76
77struct rxtid {
78 bool aggr; /* is it ON or OFF */
79 bool progress; /* true when frames have arrived after a timer start */
80 bool timerMon; /* true if the timer started for the sake of this TID */
81 u16 win_sz; /* negotiated window size */
82 u16 seq_next; /* Next seq no, in current window */
83 u32 hold_q_sz; /* Num of frames that can be held in hold q */
84 struct osbuf_hold_q *hold_q; /* Hold q for re-order */
85#if 0
86 struct window_snapshot old_win; /* Sliding window snapshot - for timeout */
87#endif
88 A_NETBUF_QUEUE_T q; /* q head for enqueuing frames for dispatch */
89 A_MUTEX_T lock;
90};
91
92struct rxtid_stats {
93 u32 num_into_aggr; /* hitting at the input of this module */
94 u32 num_dups; /* duplicate */
95 u32 num_oow; /* out of window */
96 u32 num_mpdu; /* single payload 802.3/802.11 frame */
97 u32 num_amsdu; /* AMSDU */
98 u32 num_delivered; /* frames delivered to IP stack */
99 u32 num_timeouts; /* num of timeouts, during which frames delivered */
100 u32 num_hole; /* frame not present, when window moved over */
101 u32 num_bar; /* num of resets of seq_num, via BAR */
102};
103
104struct aggr_info {
105 u8 aggr_sz; /* config value of aggregation size */
106 u8 timerScheduled;
107 A_TIMER timer; /* timer for returning held up pkts in re-order que */
108 void *dev; /* dev handle */
109 RX_CALLBACK rx_fn; /* callback function to return frames; to upper layer */
110 struct rxtid RxTid[NUM_OF_TIDS]; /* Per tid window */
111 ALLOC_NETBUFS netbuf_allocator; /* OS netbuf alloc fn */
112 A_NETBUF_QUEUE_T freeQ; /* pre-allocated buffers - for A_MSDU slicing */
113 struct rxtid_stats stat[NUM_OF_TIDS]; /* Tid based statistics */
114 PACKET_LOG pkt_log; /* Log info of the packets */
115};
116
117#endif /* __AGGR_RX_INTERNAL_H__ */
diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c
new file mode 100644
index 00000000000..9b1509ec5a7
--- /dev/null
+++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c
@@ -0,0 +1,661 @@
1/*
2 *
3 * Copyright (c) 2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7//
8// Permission to use, copy, modify, and/or distribute this software for any
9// purpose with or without fee is hereby granted, provided that the above
10// copyright notice and this permission notice appear in all copies.
11//
12// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19//
20//
21 *
22 */
23
24#include <a_config.h>
25#include <athdefs.h>
26#include <a_osapi.h>
27#include <a_debug.h>
28#include "pkt_log.h"
29#include "aggr_recv_api.h"
30#include "aggr_rx_internal.h"
31#include "wmi.h"
32
33extern int
34wmi_dot3_2_dix(void *osbuf);
35
36static void
37aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf);
38
39static void
40aggr_timeout(unsigned long arg);
41
42static void
43aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order);
44
45static void
46aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q);
47
48static void *
49aggr_get_osbuf(struct aggr_info *p_aggr);
50
51void *
52aggr_init(ALLOC_NETBUFS netbuf_allocator)
53{
54 struct aggr_info *p_aggr = NULL;
55 struct rxtid *rxtid;
56 u8 i;
57 int status = 0;
58
59 A_PRINTF("In aggr_init..\n");
60
61 do {
62 p_aggr = A_MALLOC(sizeof(struct aggr_info));
63 if(!p_aggr) {
64 A_PRINTF("Failed to allocate memory for aggr_node\n");
65 status = A_ERROR;
66 break;
67 }
68
69 /* Init timer and data structures */
70 A_MEMZERO(p_aggr, sizeof(struct aggr_info));
71 p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
72 A_INIT_TIMER(&p_aggr->timer, aggr_timeout, p_aggr);
73 p_aggr->timerScheduled = false;
74 A_NETBUF_QUEUE_INIT(&p_aggr->freeQ);
75
76 p_aggr->netbuf_allocator = netbuf_allocator;
77 p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
78
79 for(i = 0; i < NUM_OF_TIDS; i++) {
80 rxtid = AGGR_GET_RXTID(p_aggr, i);
81 rxtid->aggr = false;
82 rxtid->progress = false;
83 rxtid->timerMon = false;
84 A_NETBUF_QUEUE_INIT(&rxtid->q);
85 A_MUTEX_INIT(&rxtid->lock);
86 }
87 }while(false);
88
89 A_PRINTF("going out of aggr_init..status %s\n",
90 (status == 0) ? "OK":"Error");
91
92 if (status) {
93 /* Cleanup */
94 aggr_module_destroy(p_aggr);
95 }
96 return ((status == 0) ? p_aggr : NULL);
97}
98
99/* utility function to clear rx hold_q for a tid */
100static void
101aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
102{
103 struct rxtid *rxtid;
104 struct rxtid_stats *stats;
105
106 A_ASSERT(tid < NUM_OF_TIDS && p_aggr);
107
108 rxtid = AGGR_GET_RXTID(p_aggr, tid);
109 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
110
111 if(rxtid->aggr) {
112 aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
113 }
114
115 rxtid->aggr = false;
116 rxtid->progress = false;
117 rxtid->timerMon = false;
118 rxtid->win_sz = 0;
119 rxtid->seq_next = 0;
120 rxtid->hold_q_sz = 0;
121
122 if(rxtid->hold_q) {
123 kfree(rxtid->hold_q);
124 rxtid->hold_q = NULL;
125 }
126
127 A_MEMZERO(stats, sizeof(struct rxtid_stats));
128}
129
130void
131aggr_module_destroy(void *cntxt)
132{
133 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
134 struct rxtid *rxtid;
135 u8 i, k;
136 A_PRINTF("%s(): aggr = %p\n",_A_FUNCNAME_, p_aggr);
137 A_ASSERT(p_aggr);
138
139 if(p_aggr) {
140 if(p_aggr->timerScheduled) {
141 A_UNTIMEOUT(&p_aggr->timer);
142 p_aggr->timerScheduled = false;
143 }
144
145 for(i = 0; i < NUM_OF_TIDS; i++) {
146 rxtid = AGGR_GET_RXTID(p_aggr, i);
147 /* Free the hold q contents and hold_q*/
148 if(rxtid->hold_q) {
149 for(k = 0; k< rxtid->hold_q_sz; k++) {
150 if(rxtid->hold_q[k].osbuf) {
151 A_NETBUF_FREE(rxtid->hold_q[k].osbuf);
152 }
153 }
154 kfree(rxtid->hold_q);
155 }
156 /* Free the dispatch q contents*/
157 while(A_NETBUF_QUEUE_SIZE(&rxtid->q)) {
158 A_NETBUF_FREE(A_NETBUF_DEQUEUE(&rxtid->q));
159 }
160 if (A_IS_MUTEX_VALID(&rxtid->lock)) {
161 A_MUTEX_DELETE(&rxtid->lock);
162 }
163 }
164 /* free the freeQ and its contents*/
165 while(A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
166 A_NETBUF_FREE(A_NETBUF_DEQUEUE(&p_aggr->freeQ));
167 }
168 kfree(p_aggr);
169 }
170 A_PRINTF("out aggr_module_destroy\n");
171}
172
173
174void
175aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn)
176{
177 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
178
179 A_ASSERT(p_aggr && fn && dev);
180
181 p_aggr->rx_fn = fn;
182 p_aggr->dev = dev;
183}
184
185
186void
187aggr_process_bar(void *cntxt, u8 tid, u16 seq_no)
188{
189 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
190 struct rxtid_stats *stats;
191
192 A_ASSERT(p_aggr);
193 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
194 stats->num_bar++;
195
196 aggr_deque_frms(p_aggr, tid, seq_no, ALL_SEQNO);
197}
198
199
200void
201aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz)
202{
203 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
204 struct rxtid *rxtid;
205 struct rxtid_stats *stats;
206
207 A_ASSERT(p_aggr);
208 rxtid = AGGR_GET_RXTID(p_aggr, tid);
209 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
210
211 A_PRINTF("%s(): win_sz = %d aggr %d\n", _A_FUNCNAME_, win_sz, rxtid->aggr);
212 if(win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) {
213 A_PRINTF("win_sz %d, tid %d\n", win_sz, tid);
214 }
215
216 if(rxtid->aggr) {
217 /* Just go and deliver all the frames up from this
218 * queue, as if we got DELBA and re-initialize the queue
219 */
220 aggr_delete_tid_state(p_aggr, tid);
221 }
222
223 rxtid->seq_next = seq_no;
224 /* create these queues, only upon receiving of ADDBA for a
225 * tid, reducing memory requirement
226 */
227 rxtid->hold_q = A_MALLOC(HOLD_Q_SZ(win_sz));
228 if((rxtid->hold_q == NULL)) {
229 A_PRINTF("Failed to allocate memory, tid = %d\n", tid);
230 A_ASSERT(0);
231 }
232 A_MEMZERO(rxtid->hold_q, HOLD_Q_SZ(win_sz));
233
234 /* Update rxtid for the window sz */
235 rxtid->win_sz = win_sz;
236 /* hold_q_sz inicates the depth of holding q - which is
237 * a factor of win_sz. Compute once, as it will be used often
238 */
239 rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz);
240 /* There should be no frames on q - even when second ADDBA comes in.
241 * If aggr was previously ON on this tid, we would have cleaned up
242 * the q
243 */
244 if(A_NETBUF_QUEUE_SIZE(&rxtid->q) != 0) {
245 A_PRINTF("ERROR: Frames still on queue ?\n");
246 A_ASSERT(0);
247 }
248
249 rxtid->aggr = true;
250}
251
252void
253aggr_recv_delba_req_evt(void *cntxt, u8 tid)
254{
255 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
256 struct rxtid *rxtid;
257
258 A_ASSERT(p_aggr);
259 A_PRINTF("%s(): tid %d\n", _A_FUNCNAME_, tid);
260
261 rxtid = AGGR_GET_RXTID(p_aggr, tid);
262
263 if(rxtid->aggr) {
264 aggr_delete_tid_state(p_aggr, tid);
265 }
266}
267
268static void
269aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order)
270{
271 struct rxtid *rxtid;
272 struct osbuf_hold_q *node;
273 u16 idx, idx_end, seq_end;
274 struct rxtid_stats *stats;
275
276 A_ASSERT(p_aggr);
277 rxtid = AGGR_GET_RXTID(p_aggr, tid);
278 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
279
280 /* idx is absolute location for first frame */
281 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
282
283 /* idx_end is typically the last possible frame in the window,
284 * but changes to 'the' seq_no, when BAR comes. If seq_no
285 * is non-zero, we will go up to that and stop.
286 * Note: last seq no in current window will occupy the same
287 * index position as index that is just previous to start.
288 * An imp point : if win_sz is 7, for seq_no space of 4095,
289 * then, there would be holes when sequence wrap around occurs.
290 * Target should judiciously choose the win_sz, based on
291 * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz
292 * 2, 4, 8, 16 win_sz works fine).
293 * We must deque from "idx" to "idx_end", including both.
294 */
295 seq_end = (seq_no) ? seq_no : rxtid->seq_next;
296 idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
297
298 /* Critical section begins */
299 A_MUTEX_LOCK(&rxtid->lock);
300 do {
301
302 node = &rxtid->hold_q[idx];
303
304 if((order == CONTIGUOUS_SEQNO) && (!node->osbuf))
305 break;
306
307 /* chain frames and deliver frames bcos:
308 * 1. either the frames are in order and window is contiguous, OR
309 * 2. we need to deque frames, irrespective of holes
310 */
311 if(node->osbuf) {
312 if(node->is_amsdu) {
313 aggr_slice_amsdu(p_aggr, rxtid, &node->osbuf);
314 } else {
315 A_NETBUF_ENQUEUE(&rxtid->q, node->osbuf);
316 }
317 node->osbuf = NULL;
318 } else {
319 stats->num_hole++;
320 }
321
322 /* window is moving */
323 rxtid->seq_next = IEEE80211_NEXT_SEQ_NO(rxtid->seq_next);
324 idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
325 } while(idx != idx_end);
326 /* Critical section ends */
327 A_MUTEX_UNLOCK(&rxtid->lock);
328
329 stats->num_delivered += A_NETBUF_QUEUE_SIZE(&rxtid->q);
330 aggr_dispatch_frames(p_aggr, &rxtid->q);
331}
332
333static void *
334aggr_get_osbuf(struct aggr_info *p_aggr)
335{
336 void *buf = NULL;
337
338 /* Starving for buffers? get more from OS
339 * check for low netbuffers( < 1/4 AGGR_NUM_OF_FREE_NETBUFS) :
340 * re-allocate bufs if so
341 * allocate a free buf from freeQ
342 */
343 if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) {
344 p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
345 }
346
347 if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
348 buf = A_NETBUF_DEQUEUE(&p_aggr->freeQ);
349 }
350
351 return buf;
352}
353
354
355static void
356aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf)
357{
358 void *new_buf;
359 u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
360 u8 *framep;
361
362 /* Frame format at this point:
363 * [DIX hdr | 802.3 | 802.3 | ... | 802.3]
364 *
365 * Strip the DIX header.
366 * Iterate through the osbuf and do:
367 * grab a free netbuf from freeQ
368 * find the start and end of a frame
369 * copy it to netbuf(Vista can do better here)
370 * convert all msdu's(802.3) frames to upper layer format - os routine
371 * -for now lets convert from 802.3 to dix
372 * enque this to dispatch q of tid
373 * repeat
374 * free the osbuf - to OS. It's been sliced.
375 */
376
377 mac_hdr_len = sizeof(ATH_MAC_HDR);
378 framep = A_NETBUF_DATA(*osbuf) + mac_hdr_len;
379 amsdu_len = A_NETBUF_LEN(*osbuf) - mac_hdr_len;
380
381 while(amsdu_len > mac_hdr_len) {
382 /* Begin of a 802.3 frame */
383 payload_8023_len = A_BE2CPU16(((ATH_MAC_HDR *)framep)->typeOrLen);
384#define MAX_MSDU_SUBFRAME_PAYLOAD_LEN 1508
385#define MIN_MSDU_SUBFRAME_PAYLOAD_LEN 46
386 if(payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN || payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) {
387 A_PRINTF("802.3 AMSDU frame bound check failed. len %d\n", payload_8023_len);
388 break;
389 }
390 frame_8023_len = payload_8023_len + mac_hdr_len;
391 new_buf = aggr_get_osbuf(p_aggr);
392 if(new_buf == NULL) {
393 A_PRINTF("No buffer available \n");
394 break;
395 }
396
397 memcpy(A_NETBUF_DATA(new_buf), framep, frame_8023_len);
398 A_NETBUF_PUT(new_buf, frame_8023_len);
399 if (wmi_dot3_2_dix(new_buf) != 0) {
400 A_PRINTF("dot3_2_dix err..\n");
401 A_NETBUF_FREE(new_buf);
402 break;
403 }
404
405 A_NETBUF_ENQUEUE(&rxtid->q, new_buf);
406
407 /* Is this the last subframe within this aggregate ? */
408 if ((amsdu_len - frame_8023_len) == 0) {
409 break;
410 }
411
412 /* Add the length of A-MSDU subframe padding bytes -
413 * Round to nearest word.
414 */
415 frame_8023_len = ((frame_8023_len + 3) & ~3);
416
417 framep += frame_8023_len;
418 amsdu_len -= frame_8023_len;
419 }
420
421 A_NETBUF_FREE(*osbuf);
422 *osbuf = NULL;
423}
424
425void
426aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf)
427{
428 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
429 struct rxtid *rxtid;
430 struct rxtid_stats *stats;
431 u16 idx, st, cur, end;
432 u16 *log_idx;
433 struct osbuf_hold_q *node;
434 PACKET_LOG *log;
435
436 A_ASSERT(p_aggr);
437 A_ASSERT(tid < NUM_OF_TIDS);
438
439 rxtid = AGGR_GET_RXTID(p_aggr, tid);
440 stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
441
442 stats->num_into_aggr++;
443
444 if(!rxtid->aggr) {
445 if(is_amsdu) {
446 aggr_slice_amsdu(p_aggr, rxtid, osbuf);
447 stats->num_amsdu++;
448 aggr_dispatch_frames(p_aggr, &rxtid->q);
449 }
450 return;
451 }
452
453 /* Check the incoming sequence no, if it's in the window */
454 st = rxtid->seq_next;
455 cur = seq_no;
456 end = (st + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
457 /* Log the pkt info for future analysis */
458 log = &p_aggr->pkt_log;
459 log_idx = &log->last_idx;
460 log->info[*log_idx].cur = cur;
461 log->info[*log_idx].st = st;
462 log->info[*log_idx].end = end;
463 *log_idx = IEEE80211_NEXT_SEQ_NO(*log_idx);
464
465 if(((st < end) && (cur < st || cur > end)) ||
466 ((st > end) && (cur > end) && (cur < st))) {
467 /* the cur frame is outside the window. Since we know
468 * our target would not do this without reason it must
469 * be assumed that the window has moved for some valid reason.
470 * Therefore, we dequeue all frames and start fresh.
471 */
472 u16 extended_end;
473
474 extended_end = (end + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
475
476 if(((end < extended_end) && (cur < end || cur > extended_end)) ||
477 ((end > extended_end) && (cur > extended_end) && (cur < end))) {
478 // dequeue all frames in queue and shift window to new frame
479 aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
480 //set window start so that new frame is last frame in window
481 if(cur >= rxtid->hold_q_sz-1) {
482 rxtid->seq_next = cur - (rxtid->hold_q_sz-1);
483 }else{
484 rxtid->seq_next = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
485 }
486 } else {
487 // dequeue only those frames that are outside the new shifted window
488 if(cur >= rxtid->hold_q_sz-1) {
489 st = cur - (rxtid->hold_q_sz-1);
490 }else{
491 st = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
492 }
493
494 aggr_deque_frms(p_aggr, tid, st, ALL_SEQNO);
495 }
496
497 stats->num_oow++;
498 }
499
500 idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz);
501
502 /*enque the frame, in hold_q */
503 node = &rxtid->hold_q[idx];
504
505 A_MUTEX_LOCK(&rxtid->lock);
506 if(node->osbuf) {
507 /* Is the cur frame duplicate or something beyond our
508 * window(hold_q -> which is 2x, already)?
509 * 1. Duplicate is easy - drop incoming frame.
510 * 2. Not falling in current sliding window.
511 * 2a. is the frame_seq_no preceding current tid_seq_no?
512 * -> drop the frame. perhaps sender did not get our ACK.
513 * this is taken care of above.
514 * 2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ);
515 * -> Taken care of it above, by moving window forward.
516 *
517 */
518 A_NETBUF_FREE(node->osbuf);
519 stats->num_dups++;
520 }
521
522 node->osbuf = *osbuf;
523 node->is_amsdu = is_amsdu;
524 node->seq_no = seq_no;
525 if(node->is_amsdu) {
526 stats->num_amsdu++;
527 } else {
528 stats->num_mpdu++;
529 }
530 A_MUTEX_UNLOCK(&rxtid->lock);
531
532 *osbuf = NULL;
533 aggr_deque_frms(p_aggr, tid, 0, CONTIGUOUS_SEQNO);
534
535 if(p_aggr->timerScheduled) {
536 rxtid->progress = true;
537 }else{
538 for(idx=0 ; idx<rxtid->hold_q_sz ; idx++) {
539 if(rxtid->hold_q[idx].osbuf) {
540 /* there is a frame in the queue and no timer so
541 * start a timer to ensure that the frame doesn't remain
542 * stuck forever. */
543 p_aggr->timerScheduled = true;
544 A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
545 rxtid->progress = false;
546 rxtid->timerMon = true;
547 break;
548 }
549 }
550 }
551}
552
553/*
554 * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate
555 * hold Q state. Examples include when a Connect event or disconnect event is
556 * received.
557 */
558void
559aggr_reset_state(void *cntxt)
560{
561 u8 tid;
562 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
563
564 A_ASSERT(p_aggr);
565
566 for(tid=0 ; tid<NUM_OF_TIDS ; tid++) {
567 aggr_delete_tid_state(p_aggr, tid);
568 }
569}
570
571
572static void
573aggr_timeout(unsigned long arg)
574{
575 u8 i,j;
576 struct aggr_info *p_aggr = (struct aggr_info *)arg;
577 struct rxtid *rxtid;
578 struct rxtid_stats *stats;
579 /*
580 * If the q for which the timer was originally started has
581 * not progressed then it is necessary to dequeue all the
582 * contained frames so that they are not held forever.
583 */
584 for(i = 0; i < NUM_OF_TIDS; i++) {
585 rxtid = AGGR_GET_RXTID(p_aggr, i);
586 stats = AGGR_GET_RXTID_STATS(p_aggr, i);
587
588 if(rxtid->aggr == false ||
589 rxtid->timerMon == false ||
590 rxtid->progress == true) {
591 continue;
592 }
593 // dequeue all frames in for this tid
594 stats->num_timeouts++;
595 A_PRINTF("TO: st %d end %d\n", rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO));
596 aggr_deque_frms(p_aggr, i, 0, ALL_SEQNO);
597 }
598
599 p_aggr->timerScheduled = false;
600 // determine whether a new timer should be started.
601 for(i = 0; i < NUM_OF_TIDS; i++) {
602 rxtid = AGGR_GET_RXTID(p_aggr, i);
603
604 if(rxtid->aggr == true && rxtid->hold_q) {
605 for(j = 0 ; j < rxtid->hold_q_sz ; j++)
606 {
607 if(rxtid->hold_q[j].osbuf)
608 {
609 p_aggr->timerScheduled = true;
610 rxtid->timerMon = true;
611 rxtid->progress = false;
612 break;
613 }
614 }
615
616 if(j >= rxtid->hold_q_sz) {
617 rxtid->timerMon = false;
618 }
619 }
620 }
621
622 if(p_aggr->timerScheduled) {
623 /* Rearm the timer*/
624 A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
625 }
626
627}
628
629static void
630aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q)
631{
632 void *osbuf;
633
634 while((osbuf = A_NETBUF_DEQUEUE(q))) {
635 p_aggr->rx_fn(p_aggr->dev, osbuf);
636 }
637}
638
639void
640aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf)
641{
642 struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
643 struct rxtid *rxtid;
644 struct rxtid_stats *stats;
645 u8 i;
646
647 *log_buf = &p_aggr->pkt_log;
648 A_PRINTF("\n\n================================================\n");
649 A_PRINTF("tid: num_into_aggr, dups, oow, mpdu, amsdu, delivered, timeouts, holes, bar, seq_next\n");
650 for(i = 0; i < NUM_OF_TIDS; i++) {
651 stats = AGGR_GET_RXTID_STATS(p_aggr, i);
652 rxtid = AGGR_GET_RXTID(p_aggr, i);
653 A_PRINTF("%d: %d %d %d %d %d %d %d %d %d : %d\n", i, stats->num_into_aggr, stats->num_dups,
654 stats->num_oow, stats->num_mpdu,
655 stats->num_amsdu, stats->num_delivered, stats->num_timeouts,
656 stats->num_hole, stats->num_bar,
657 rxtid->seq_next);
658 }
659 A_PRINTF("================================================\n\n");
660
661}
diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h
new file mode 100644
index 00000000000..cf47d0657e7
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/include/ieee80211.h
@@ -0,0 +1,397 @@
1//------------------------------------------------------------------------------
2// <copyright file="ieee80211.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _NET80211_IEEE80211_H_
24#define _NET80211_IEEE80211_H_
25
26/*
27 * 802.11 protocol definitions.
28 */
29#define IEEE80211_WEP_KEYLEN 5 /* 40bit */
30#define IEEE80211_WEP_IVLEN 3 /* 24bit */
31#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */
32#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */
33#define IEEE80211_WEP_NKID 4 /* number of key ids */
34
35/*
36 * 802.11i defines an extended IV for use with non-WEP ciphers.
37 * When the EXTIV bit is set in the key id byte an additional
38 * 4 bytes immediately follow the IV for TKIP. For CCMP the
39 * EXTIV bit is likewise set but the 8 bytes represent the
40 * CCMP header rather than IV+extended-IV.
41 */
42#define IEEE80211_WEP_EXTIV 0x20
43#define IEEE80211_WEP_EXTIVLEN 4 /* extended IV length */
44#define IEEE80211_WEP_MICLEN 8 /* trailing MIC */
45
46#define IEEE80211_CRC_LEN 4
47
48#ifdef WAPI_ENABLE
49#define IEEE80211_WAPI_EXTIVLEN 10 /* extended IV length */
50#endif /* WAPI ENABLE */
51
52
53#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */
54/* is 802.11 address multicast/broadcast? */
55#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01)
56#define IEEE80211_IS_BROADCAST(_a) (*(_a) == 0xFF)
57#define WEP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN)
58#define WEP_TRAILER IEEE80211_WEP_CRCLEN
59#define CCMP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \
60 IEEE80211_WEP_EXTIVLEN)
61#define CCMP_TRAILER IEEE80211_WEP_MICLEN
62#define TKIP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \
63 IEEE80211_WEP_EXTIVLEN)
64#define TKIP_TRAILER IEEE80211_WEP_CRCLEN
65#define TKIP_MICLEN IEEE80211_WEP_MICLEN
66
67
68#define IEEE80211_ADDR_EQ(addr1, addr2) \
69 (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) == 0)
70
71#define IEEE80211_ADDR_COPY(dst,src) memcpy(dst,src,IEEE80211_ADDR_LEN)
72
73#define IEEE80211_KEYBUF_SIZE 16
74#define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx and rx */
75
76/*
77 * NB: these values are ordered carefully; there are lots of
78 * of implications in any reordering. In particular beware
79 * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
80 */
81#define IEEE80211_CIPHER_WEP 0
82#define IEEE80211_CIPHER_TKIP 1
83#define IEEE80211_CIPHER_AES_OCB 2
84#define IEEE80211_CIPHER_AES_CCM 3
85#define IEEE80211_CIPHER_CKIP 5
86#define IEEE80211_CIPHER_CCKM_KRK 6
87#define IEEE80211_CIPHER_NONE 7 /* pseudo value */
88
89#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1)
90
91#define IEEE80211_IS_VALID_WEP_CIPHER_LEN(len) \
92 (((len) == 5) || ((len) == 13) || ((len) == 16))
93
94
95
96/*
97 * generic definitions for IEEE 802.11 frames
98 */
99PREPACK struct ieee80211_frame {
100 u8 i_fc[2];
101 u8 i_dur[2];
102 u8 i_addr1[IEEE80211_ADDR_LEN];
103 u8 i_addr2[IEEE80211_ADDR_LEN];
104 u8 i_addr3[IEEE80211_ADDR_LEN];
105 u8 i_seq[2];
106 /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
107 /* see below */
108} POSTPACK;
109
110PREPACK struct ieee80211_qosframe {
111 u8 i_fc[2];
112 u8 i_dur[2];
113 u8 i_addr1[IEEE80211_ADDR_LEN];
114 u8 i_addr2[IEEE80211_ADDR_LEN];
115 u8 i_addr3[IEEE80211_ADDR_LEN];
116 u8 i_seq[2];
117 u8 i_qos[2];
118} POSTPACK;
119
120#define IEEE80211_FC0_VERSION_MASK 0x03
121#define IEEE80211_FC0_VERSION_SHIFT 0
122#define IEEE80211_FC0_VERSION_0 0x00
123#define IEEE80211_FC0_TYPE_MASK 0x0c
124#define IEEE80211_FC0_TYPE_SHIFT 2
125#define IEEE80211_FC0_TYPE_MGT 0x00
126#define IEEE80211_FC0_TYPE_CTL 0x04
127#define IEEE80211_FC0_TYPE_DATA 0x08
128
129#define IEEE80211_FC0_SUBTYPE_MASK 0xf0
130#define IEEE80211_FC0_SUBTYPE_SHIFT 4
131/* for TYPE_MGT */
132#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00
133#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10
134#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20
135#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30
136#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40
137#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50
138#define IEEE80211_FC0_SUBTYPE_BEACON 0x80
139#define IEEE80211_FC0_SUBTYPE_ATIM 0x90
140#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0
141#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0
142#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0
143/* for TYPE_CTL */
144#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0
145#define IEEE80211_FC0_SUBTYPE_RTS 0xb0
146#define IEEE80211_FC0_SUBTYPE_CTS 0xc0
147#define IEEE80211_FC0_SUBTYPE_ACK 0xd0
148#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0
149#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0
150/* for TYPE_DATA (bit combination) */
151#define IEEE80211_FC0_SUBTYPE_DATA 0x00
152#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10
153#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20
154#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30
155#define IEEE80211_FC0_SUBTYPE_NODATA 0x40
156#define IEEE80211_FC0_SUBTYPE_CFACK 0x50
157#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60
158#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70
159#define IEEE80211_FC0_SUBTYPE_QOS 0x80
160#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0
161
162#define IEEE80211_FC1_DIR_MASK 0x03
163#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */
164#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */
165#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */
166#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */
167
168#define IEEE80211_FC1_MORE_FRAG 0x04
169#define IEEE80211_FC1_RETRY 0x08
170#define IEEE80211_FC1_PWR_MGT 0x10
171#define IEEE80211_FC1_MORE_DATA 0x20
172#define IEEE80211_FC1_WEP 0x40
173#define IEEE80211_FC1_ORDER 0x80
174
175#define IEEE80211_SEQ_FRAG_MASK 0x000f
176#define IEEE80211_SEQ_FRAG_SHIFT 0
177#define IEEE80211_SEQ_SEQ_MASK 0xfff0
178#define IEEE80211_SEQ_SEQ_SHIFT 4
179
180#define IEEE80211_NWID_LEN 32
181
182/*
183 * 802.11 rate set.
184 */
185#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */
186#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */
187
188#define WMM_NUM_AC 4 /* 4 AC categories */
189
190#define WMM_PARAM_ACI_M 0x60 /* Mask for ACI field */
191#define WMM_PARAM_ACI_S 5 /* Shift for ACI field */
192#define WMM_PARAM_ACM_M 0x10 /* Mask for ACM bit */
193#define WMM_PARAM_ACM_S 4 /* Shift for ACM bit */
194#define WMM_PARAM_AIFSN_M 0x0f /* Mask for aifsn field */
195#define WMM_PARAM_LOGCWMIN_M 0x0f /* Mask for CwMin field (in log) */
196#define WMM_PARAM_LOGCWMAX_M 0xf0 /* Mask for CwMax field (in log) */
197#define WMM_PARAM_LOGCWMAX_S 4 /* Shift for CwMax field */
198
199#define WMM_AC_TO_TID(_ac) ( \
200 ((_ac) == WMM_AC_VO) ? 6 : \
201 ((_ac) == WMM_AC_VI) ? 5 : \
202 ((_ac) == WMM_AC_BK) ? 1 : \
203 0)
204
205#define TID_TO_WMM_AC(_tid) ( \
206 ((_tid) < 1) ? WMM_AC_BE : \
207 ((_tid) < 3) ? WMM_AC_BK : \
208 ((_tid) < 6) ? WMM_AC_VI : \
209 WMM_AC_VO)
210/*
211 * Management information element payloads.
212 */
213
214enum {
215 IEEE80211_ELEMID_SSID = 0,
216 IEEE80211_ELEMID_RATES = 1,
217 IEEE80211_ELEMID_FHPARMS = 2,
218 IEEE80211_ELEMID_DSPARMS = 3,
219 IEEE80211_ELEMID_CFPARMS = 4,
220 IEEE80211_ELEMID_TIM = 5,
221 IEEE80211_ELEMID_IBSSPARMS = 6,
222 IEEE80211_ELEMID_COUNTRY = 7,
223 IEEE80211_ELEMID_CHALLENGE = 16,
224 /* 17-31 reserved for challenge text extension */
225 IEEE80211_ELEMID_PWRCNSTR = 32,
226 IEEE80211_ELEMID_PWRCAP = 33,
227 IEEE80211_ELEMID_TPCREQ = 34,
228 IEEE80211_ELEMID_TPCREP = 35,
229 IEEE80211_ELEMID_SUPPCHAN = 36,
230 IEEE80211_ELEMID_CHANSWITCH = 37,
231 IEEE80211_ELEMID_MEASREQ = 38,
232 IEEE80211_ELEMID_MEASREP = 39,
233 IEEE80211_ELEMID_QUIET = 40,
234 IEEE80211_ELEMID_IBSSDFS = 41,
235 IEEE80211_ELEMID_ERP = 42,
236 IEEE80211_ELEMID_HTCAP_ANA = 45, /* Address ANA, and non-ANA story, for interop. CL#171733 */
237 IEEE80211_ELEMID_RSN = 48,
238 IEEE80211_ELEMID_XRATES = 50,
239 IEEE80211_ELEMID_HTINFO_ANA = 61,
240#ifdef WAPI_ENABLE
241 IEEE80211_ELEMID_WAPI = 68,
242#endif
243 IEEE80211_ELEMID_TPC = 150,
244 IEEE80211_ELEMID_CCKM = 156,
245 IEEE80211_ELEMID_VENDOR = 221, /* vendor private */
246};
247
248#define ATH_OUI 0x7f0300 /* Atheros OUI */
249#define ATH_OUI_TYPE 0x01
250#define ATH_OUI_SUBTYPE 0x01
251#define ATH_OUI_VERSION 0x00
252
253#define WPA_OUI 0xf25000
254#define WPA_OUI_TYPE 0x01
255#define WPA_VERSION 1 /* current supported version */
256
257#define WPA_CSE_NULL 0x00
258#define WPA_CSE_WEP40 0x01
259#define WPA_CSE_TKIP 0x02
260#define WPA_CSE_CCMP 0x04
261#define WPA_CSE_WEP104 0x05
262
263#define WPA_ASE_NONE 0x00
264#define WPA_ASE_8021X_UNSPEC 0x01
265#define WPA_ASE_8021X_PSK 0x02
266
267#define RSN_OUI 0xac0f00
268#define RSN_VERSION 1 /* current supported version */
269
270#define RSN_CSE_NULL 0x00
271#define RSN_CSE_WEP40 0x01
272#define RSN_CSE_TKIP 0x02
273#define RSN_CSE_WRAP 0x03
274#define RSN_CSE_CCMP 0x04
275#define RSN_CSE_WEP104 0x05
276
277#define RSN_ASE_NONE 0x00
278#define RSN_ASE_8021X_UNSPEC 0x01
279#define RSN_ASE_8021X_PSK 0x02
280
281#define RSN_CAP_PREAUTH 0x01
282
283#define WMM_OUI 0xf25000
284#define WMM_OUI_TYPE 0x02
285#define WMM_INFO_OUI_SUBTYPE 0x00
286#define WMM_PARAM_OUI_SUBTYPE 0x01
287#define WMM_VERSION 1
288
289/* WMM stream classes */
290#define WMM_NUM_AC 4
291#define WMM_AC_BE 0 /* best effort */
292#define WMM_AC_BK 1 /* background */
293#define WMM_AC_VI 2 /* video */
294#define WMM_AC_VO 3 /* voice */
295
296/* TSPEC related */
297#define ACTION_CATEGORY_CODE_TSPEC 17
298#define ACTION_CODE_TSPEC_ADDTS 0
299#define ACTION_CODE_TSPEC_ADDTS_RESP 1
300#define ACTION_CODE_TSPEC_DELTS 2
301
302typedef enum {
303 TSPEC_STATUS_CODE_ADMISSION_ACCEPTED = 0,
304 TSPEC_STATUS_CODE_ADDTS_INVALID_PARAMS = 0x1,
305 TSPEC_STATUS_CODE_ADDTS_REQUEST_REFUSED = 0x3,
306 TSPEC_STATUS_CODE_UNSPECIFIED_QOS_RELATED_FAILURE = 0xC8,
307 TSPEC_STATUS_CODE_REQUESTED_REFUSED_POLICY_CONFIGURATION = 0xC9,
308 TSPEC_STATUS_CODE_INSUFFCIENT_BANDWIDTH = 0xCA,
309 TSPEC_STATUS_CODE_INVALID_PARAMS = 0xCB,
310 TSPEC_STATUS_CODE_DELTS_SENT = 0x30,
311 TSPEC_STATUS_CODE_DELTS_RECV = 0x31,
312} TSPEC_STATUS_CODE;
313
314#define TSPEC_TSID_MASK 0xF
315#define TSPEC_TSID_S 1
316
317/*
318 * WMM/802.11e Tspec Element
319 */
320typedef PREPACK struct wmm_tspec_ie_t {
321 u8 elementId;
322 u8 len;
323 u8 oui[3];
324 u8 ouiType;
325 u8 ouiSubType;
326 u8 version;
327 u16 tsInfo_info;
328 u8 tsInfo_reserved;
329 u16 nominalMSDU;
330 u16 maxMSDU;
331 u32 minServiceInt;
332 u32 maxServiceInt;
333 u32 inactivityInt;
334 u32 suspensionInt;
335 u32 serviceStartTime;
336 u32 minDataRate;
337 u32 meanDataRate;
338 u32 peakDataRate;
339 u32 maxBurstSize;
340 u32 delayBound;
341 u32 minPhyRate;
342 u16 sba;
343 u16 mediumTime;
344} POSTPACK WMM_TSPEC_IE;
345
346
347/*
348 * BEACON management packets
349 *
350 * octet timestamp[8]
351 * octet beacon interval[2]
352 * octet capability information[2]
353 * information element
354 * octet elemid
355 * octet length
356 * octet information[length]
357 */
358
359#define IEEE80211_BEACON_INTERVAL(beacon) \
360 ((beacon)[8] | ((beacon)[9] << 8))
361#define IEEE80211_BEACON_CAPABILITY(beacon) \
362 ((beacon)[10] | ((beacon)[11] << 8))
363
364#define IEEE80211_CAPINFO_ESS 0x0001
365#define IEEE80211_CAPINFO_IBSS 0x0002
366#define IEEE80211_CAPINFO_CF_POLLABLE 0x0004
367#define IEEE80211_CAPINFO_CF_POLLREQ 0x0008
368#define IEEE80211_CAPINFO_PRIVACY 0x0010
369#define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020
370#define IEEE80211_CAPINFO_PBCC 0x0040
371#define IEEE80211_CAPINFO_CHNL_AGILITY 0x0080
372/* bits 8-9 are reserved */
373#define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400
374#define IEEE80211_CAPINFO_APSD 0x0800
375/* bit 12 is reserved */
376#define IEEE80211_CAPINFO_DSSSOFDM 0x2000
377/* bits 14-15 are reserved */
378
379/*
380 * Authentication Modes
381 */
382
383enum ieee80211_authmode {
384 IEEE80211_AUTH_NONE = 0,
385 IEEE80211_AUTH_OPEN = 1,
386 IEEE80211_AUTH_SHARED = 2,
387 IEEE80211_AUTH_8021X = 3,
388 IEEE80211_AUTH_AUTO = 4, /* auto-select/accept */
389 /* NB: these are used only for ioctls */
390 IEEE80211_AUTH_WPA = 5, /* WPA/RSN w/ 802.1x */
391 IEEE80211_AUTH_WPA_PSK = 6, /* WPA/RSN w/ PSK */
392 IEEE80211_AUTH_WPA_CCKM = 7, /* WPA/RSN IE w/ CCKM */
393};
394
395#define IEEE80211_PS_MAX_QUEUE 50 /*Maximum no of buffers that can be queues for PS*/
396
397#endif /* _NET80211_IEEE80211_H_ */
diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h
new file mode 100644
index 00000000000..1cb01671c0d
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h
@@ -0,0 +1,93 @@
1//------------------------------------------------------------------------------
2// <copyright file="ieee80211_node.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// Author(s): ="Atheros"
22//==============================================================================
23#ifndef _IEEE80211_NODE_H_
24#define _IEEE80211_NODE_H_
25
26/*
27 * Node locking definitions.
28 */
29#define IEEE80211_NODE_LOCK_INIT(_nt) A_MUTEX_INIT(&(_nt)->nt_nodelock)
30#define IEEE80211_NODE_LOCK_DESTROY(_nt) if (A_IS_MUTEX_VALID(&(_nt)->nt_nodelock)) { \
31 A_MUTEX_DELETE(&(_nt)->nt_nodelock); }
32
33#define IEEE80211_NODE_LOCK(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock)
34#define IEEE80211_NODE_UNLOCK(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
35#define IEEE80211_NODE_LOCK_BH(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock)
36#define IEEE80211_NODE_UNLOCK_BH(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
37#define IEEE80211_NODE_LOCK_ASSERT(_nt)
38
39/*
40 * Node reference counting definitions.
41 *
42 * ieee80211_node_initref initialize the reference count to 1
43 * ieee80211_node_incref add a reference
44 * ieee80211_node_decref remove a reference
45 * ieee80211_node_dectestref remove a reference and return 1 if this
46 * is the last reference, otherwise 0
47 * ieee80211_node_refcnt reference count for printing (only)
48 */
49#define ieee80211_node_initref(_ni) ((_ni)->ni_refcnt = 1)
50#define ieee80211_node_incref(_ni) ((_ni)->ni_refcnt++)
51#define ieee80211_node_decref(_ni) ((_ni)->ni_refcnt--)
52#define ieee80211_node_dectestref(_ni) (((_ni)->ni_refcnt--) == 1)
53#define ieee80211_node_refcnt(_ni) ((_ni)->ni_refcnt)
54
55#define IEEE80211_NODE_HASHSIZE 32
56/* simple hash is enough for variation of macaddr */
57#define IEEE80211_NODE_HASH(addr) \
58 (((const u8 *)(addr))[IEEE80211_ADDR_LEN - 1] % \
59 IEEE80211_NODE_HASHSIZE)
60
61/*
62 * Table of ieee80211_node instances. Each ieee80211com
63 * has at least one for holding the scan candidates.
64 * When operating as an access point or in ibss mode there
65 * is a second table for associated stations or neighbors.
66 */
67struct ieee80211_node_table {
68 void *nt_wmip; /* back reference */
69 A_MUTEX_T nt_nodelock; /* on node table */
70 struct bss *nt_node_first; /* information of all nodes */
71 struct bss *nt_node_last; /* information of all nodes */
72 struct bss *nt_hash[IEEE80211_NODE_HASHSIZE];
73 const char *nt_name; /* for debugging */
74 u32 nt_scangen; /* gen# for timeout scan */
75#ifdef THREAD_X
76 A_TIMER nt_inact_timer;
77 u8 isTimerArmed; /* is the node timer armed */
78#endif
79 u32 nt_nodeAge; /* node aging time */
80#ifdef OS_ROAM_MANAGEMENT
81 u32 nt_si_gen; /* gen# for scan indication*/
82#endif
83};
84
85#ifdef THREAD_X
86#define WLAN_NODE_INACT_TIMEOUT_MSEC 20000
87#else
88#define WLAN_NODE_INACT_TIMEOUT_MSEC 120000
89#endif
90
91#define WLAN_NODE_INACT_CNT 4
92
93#endif /* _IEEE80211_NODE_H_ */
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c
new file mode 100644
index 00000000000..0fe5f4b1346
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c
@@ -0,0 +1,636 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_node.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// IEEE 802.11 node handling support.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include <a_config.h>
26#include <athdefs.h>
27#include <a_osapi.h>
28#define ATH_MODULE_NAME wlan
29#include <a_debug.h>
30#include "htc.h"
31#include "htc_api.h"
32#include <wmi.h>
33#include <ieee80211.h>
34#include <wlan_api.h>
35#include <wmi_api.h>
36#include <ieee80211_node.h>
37
38#define ATH_DEBUG_WLAN ATH_DEBUG_MAKE_MODULE_MASK(0)
39
40#ifdef ATH_DEBUG_MODULE
41
42static struct ath_debug_mask_description wlan_debug_desc[] = {
43 { ATH_DEBUG_WLAN , "General WLAN Node Tracing"},
44};
45
46ATH_DEBUG_INSTANTIATE_MODULE_VAR(wlan,
47 "wlan",
48 "WLAN Node Management",
49 ATH_DEBUG_MASK_DEFAULTS,
50 ATH_DEBUG_DESCRIPTION_COUNT(wlan_debug_desc),
51 wlan_debug_desc);
52
53#endif
54
55#ifdef THREAD_X
56static void wlan_node_timeout(unsigned long arg);
57#endif
58
59static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt,
60 const u8 *macaddr);
61
62bss_t *
63wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size)
64{
65 bss_t *ni;
66
67 ni = A_MALLOC_NOWAIT(sizeof(bss_t));
68
69 if (ni != NULL) {
70 if (wh_size)
71 {
72 ni->ni_buf = A_MALLOC_NOWAIT(wh_size);
73 if (ni->ni_buf == NULL) {
74 kfree(ni);
75 ni = NULL;
76 return ni;
77 }
78 }
79 } else {
80 return ni;
81 }
82
83 /* Make sure our lists are clean */
84 ni->ni_list_next = NULL;
85 ni->ni_list_prev = NULL;
86 ni->ni_hash_next = NULL;
87 ni->ni_hash_prev = NULL;
88
89 //
90 // ni_scangen never initialized before and during suspend/resume of winmobile,
91 // that some junk has been stored in this, due to this scan list didn't properly updated
92 //
93 ni->ni_scangen = 0;
94
95#ifdef OS_ROAM_MANAGEMENT
96 ni->ni_si_gen = 0;
97#endif
98
99 return ni;
100}
101
102void
103wlan_node_free(bss_t *ni)
104{
105 if (ni->ni_buf != NULL) {
106 kfree(ni->ni_buf);
107 }
108 kfree(ni);
109}
110
111void
112wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
113 const u8 *macaddr)
114{
115 int hash;
116 u32 timeoutValue = 0;
117
118 memcpy(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN);
119 hash = IEEE80211_NODE_HASH (macaddr);
120 ieee80211_node_initref (ni); /* mark referenced */
121
122 timeoutValue = nt->nt_nodeAge;
123
124 ni->ni_tstamp = A_GET_MS (0);
125 ni->ni_actcnt = WLAN_NODE_INACT_CNT;
126
127 IEEE80211_NODE_LOCK_BH(nt);
128
129 /* Insert at the end of the node list */
130 ni->ni_list_next = NULL;
131 ni->ni_list_prev = nt->nt_node_last;
132 if(nt->nt_node_last != NULL)
133 {
134 nt->nt_node_last->ni_list_next = ni;
135 }
136 nt->nt_node_last = ni;
137 if(nt->nt_node_first == NULL)
138 {
139 nt->nt_node_first = ni;
140 }
141
142 /* Insert into the hash list i.e. the bucket */
143 if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL)
144 {
145 nt->nt_hash[hash]->ni_hash_prev = ni;
146 }
147 ni->ni_hash_prev = NULL;
148 nt->nt_hash[hash] = ni;
149
150#ifdef THREAD_X
151 if (!nt->isTimerArmed) {
152 A_TIMEOUT_MS(&nt->nt_inact_timer, timeoutValue, 0);
153 nt->isTimerArmed = true;
154 }
155#endif
156
157 IEEE80211_NODE_UNLOCK_BH(nt);
158}
159
160static bss_t *
161_ieee80211_find_node(struct ieee80211_node_table *nt,
162 const u8 *macaddr)
163{
164 bss_t *ni;
165 int hash;
166
167 IEEE80211_NODE_LOCK_ASSERT(nt);
168
169 hash = IEEE80211_NODE_HASH(macaddr);
170 for(ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
171 if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
172 ieee80211_node_incref(ni); /* mark referenced */
173 return ni;
174 }
175 }
176 return NULL;
177}
178
179bss_t *
180wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr)
181{
182 bss_t *ni;
183
184 IEEE80211_NODE_LOCK(nt);
185 ni = _ieee80211_find_node(nt, macaddr);
186 IEEE80211_NODE_UNLOCK(nt);
187 return ni;
188}
189
190/*
191 * Reclaim a node. If this is the last reference count then
192 * do the normal free work. Otherwise remove it from the node
193 * table and mark it gone by clearing the back-reference.
194 */
195void
196wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni)
197{
198 IEEE80211_NODE_LOCK(nt);
199
200 if(ni->ni_list_prev == NULL)
201 {
202 /* First in list so fix the list head */
203 nt->nt_node_first = ni->ni_list_next;
204 }
205 else
206 {
207 ni->ni_list_prev->ni_list_next = ni->ni_list_next;
208 }
209
210 if(ni->ni_list_next == NULL)
211 {
212 /* Last in list so fix list tail */
213 nt->nt_node_last = ni->ni_list_prev;
214 }
215 else
216 {
217 ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
218 }
219
220 if(ni->ni_hash_prev == NULL)
221 {
222 /* First in list so fix the list head */
223 int hash;
224 hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
225 nt->nt_hash[hash] = ni->ni_hash_next;
226 }
227 else
228 {
229 ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
230 }
231
232 if(ni->ni_hash_next != NULL)
233 {
234 ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
235 }
236 wlan_node_free(ni);
237
238 IEEE80211_NODE_UNLOCK(nt);
239}
240
241static void
242wlan_node_dec_free(bss_t *ni)
243{
244 if (ieee80211_node_dectestref(ni)) {
245 wlan_node_free(ni);
246 }
247}
248
249void
250wlan_free_allnodes(struct ieee80211_node_table *nt)
251{
252 bss_t *ni;
253
254 while ((ni = nt->nt_node_first) != NULL) {
255 wlan_node_reclaim(nt, ni);
256 }
257}
258
259void
260wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
261 void *arg)
262{
263 bss_t *ni;
264 u32 gen;
265
266 gen = ++nt->nt_scangen;
267
268 IEEE80211_NODE_LOCK(nt);
269 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
270 if (ni->ni_scangen != gen) {
271 ni->ni_scangen = gen;
272 (void) ieee80211_node_incref(ni);
273 (*f)(arg, ni);
274 wlan_node_dec_free(ni);
275 }
276 }
277 IEEE80211_NODE_UNLOCK(nt);
278}
279
280/*
281 * Node table support.
282 */
283void
284wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt)
285{
286 int i;
287
288 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN, ("node table = 0x%lx\n", (unsigned long)nt));
289 IEEE80211_NODE_LOCK_INIT(nt);
290
291 A_REGISTER_MODULE_DEBUG_INFO(wlan);
292
293 nt->nt_node_first = nt->nt_node_last = NULL;
294 for(i = 0; i < IEEE80211_NODE_HASHSIZE; i++)
295 {
296 nt->nt_hash[i] = NULL;
297 }
298
299#ifdef THREAD_X
300 A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt);
301 nt->isTimerArmed = false;
302#endif
303 nt->nt_wmip = wmip;
304 nt->nt_nodeAge = WLAN_NODE_INACT_TIMEOUT_MSEC;
305
306 //
307 // nt_scangen never initialized before and during suspend/resume of winmobile,
308 // that some junk has been stored in this, due to this scan list didn't properly updated
309 //
310 nt->nt_scangen = 0;
311
312#ifdef OS_ROAM_MANAGEMENT
313 nt->nt_si_gen = 0;
314#endif
315}
316
317void
318wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge)
319{
320 nt->nt_nodeAge = nodeAge;
321 return;
322}
323void
324wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt)
325{
326#ifdef THREAD_X
327 bss_t *bss, *nextBss;
328 u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false;
329
330 wmi_get_current_bssid(nt->nt_wmip, myBssid);
331
332 bss = nt->nt_node_first;
333 while (bss != NULL)
334 {
335 nextBss = bss->ni_list_next;
336 if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
337 {
338 /*
339 * free up all but the current bss - if set
340 */
341 wlan_node_reclaim(nt, bss);
342
343 }
344 bss = nextBss;
345 }
346#else
347 bss_t *bss, *nextBss;
348 u8 myBssid[IEEE80211_ADDR_LEN];
349 u32 timeoutValue = 0;
350 u32 now = A_GET_MS(0);
351 timeoutValue = nt->nt_nodeAge;
352
353 wmi_get_current_bssid(nt->nt_wmip, myBssid);
354
355 bss = nt->nt_node_first;
356 while (bss != NULL)
357 {
358 nextBss = bss->ni_list_next;
359 if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
360 {
361
362 if (((now - bss->ni_tstamp) > timeoutValue) || --bss->ni_actcnt == 0)
363 {
364 /*
365 * free up all but the current bss - if set
366 */
367 wlan_node_reclaim(nt, bss);
368 }
369 }
370 bss = nextBss;
371 }
372#endif
373}
374
375#ifdef THREAD_X
376static void
377wlan_node_timeout (unsigned long arg)
378{
379 struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg;
380 bss_t *bss, *nextBss;
381 u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false;
382 u32 timeoutValue = 0;
383 u32 now = A_GET_MS(0);
384
385 timeoutValue = nt->nt_nodeAge;
386
387 wmi_get_current_bssid(nt->nt_wmip, myBssid);
388
389 bss = nt->nt_node_first;
390 while (bss != NULL)
391 {
392 nextBss = bss->ni_list_next;
393 if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
394 {
395
396 if ((now - bss->ni_tstamp) > timeoutValue)
397 {
398 /*
399 * free up all but the current bss - if set
400 */
401 wlan_node_reclaim(nt, bss);
402 }
403 else
404 {
405 /*
406 * Re-arm timer, only when we have a bss other than
407 * current bss AND it is not aged-out.
408 */
409 reArmTimer = true;
410 }
411 }
412 bss = nextBss;
413 }
414
415 if (reArmTimer)
416 A_TIMEOUT_MS (&nt->nt_inact_timer, timeoutValue, 0);
417
418 nt->isTimerArmed = reArmTimer;
419}
420#endif
421
422void
423wlan_node_table_cleanup(struct ieee80211_node_table *nt)
424{
425#ifdef THREAD_X
426 A_UNTIMEOUT(&nt->nt_inact_timer);
427 A_DELETE_TIMER(&nt->nt_inact_timer);
428#endif
429 wlan_free_allnodes(nt);
430 IEEE80211_NODE_LOCK_DESTROY(nt);
431}
432
433bss_t *
434wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
435 u32 ssidLength, bool bIsWPA2, bool bMatchSSID)
436{
437 bss_t *ni = NULL;
438 u8 *pIESsid = NULL;
439
440 IEEE80211_NODE_LOCK (nt);
441
442 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
443 pIESsid = ni->ni_cie.ie_ssid;
444 if (pIESsid[1] <= 32) {
445
446 // Step 1 : Check SSID
447 if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
448
449 //
450 // Step 2.1 : Check MatchSSID is true, if so, return Matched SSID
451 // Profile, otherwise check whether WPA2 or WPA
452 //
453 if (true == bMatchSSID) {
454 ieee80211_node_incref (ni); /* mark referenced */
455 IEEE80211_NODE_UNLOCK (nt);
456 return ni;
457 }
458
459 // Step 2 : if SSID matches, check WPA or WPA2
460 if (true == bIsWPA2 && NULL != ni->ni_cie.ie_rsn) {
461 ieee80211_node_incref (ni); /* mark referenced */
462 IEEE80211_NODE_UNLOCK (nt);
463 return ni;
464 }
465 if (false == bIsWPA2 && NULL != ni->ni_cie.ie_wpa) {
466 ieee80211_node_incref(ni); /* mark referenced */
467 IEEE80211_NODE_UNLOCK (nt);
468 return ni;
469 }
470 }
471 }
472 }
473
474 IEEE80211_NODE_UNLOCK (nt);
475
476 return NULL;
477}
478
479void
480wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni)
481{
482 IEEE80211_NODE_LOCK (nt);
483 wlan_node_dec_free (ni);
484 IEEE80211_NODE_UNLOCK (nt);
485}
486
487void
488wlan_node_remove_core (struct ieee80211_node_table *nt, bss_t *ni)
489{
490 if(ni->ni_list_prev == NULL)
491 {
492 /* First in list so fix the list head */
493 nt->nt_node_first = ni->ni_list_next;
494 }
495 else
496 {
497 ni->ni_list_prev->ni_list_next = ni->ni_list_next;
498 }
499
500 if(ni->ni_list_next == NULL)
501 {
502 /* Last in list so fix list tail */
503 nt->nt_node_last = ni->ni_list_prev;
504 }
505 else
506 {
507 ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
508 }
509
510 if(ni->ni_hash_prev == NULL)
511 {
512 /* First in list so fix the list head */
513 int hash;
514 hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
515 nt->nt_hash[hash] = ni->ni_hash_next;
516 }
517 else
518 {
519 ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
520 }
521
522 if(ni->ni_hash_next != NULL)
523 {
524 ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
525 }
526}
527
528bss_t *
529wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid)
530{
531 bss_t *bss, *nextBss;
532
533 IEEE80211_NODE_LOCK(nt);
534
535 bss = nt->nt_node_first;
536
537 while (bss != NULL)
538 {
539 nextBss = bss->ni_list_next;
540
541 if (memcmp(bssid, bss->ni_macaddr, 6) == 0)
542 {
543 wlan_node_remove_core (nt, bss);
544 IEEE80211_NODE_UNLOCK(nt);
545 return bss;
546 }
547
548 bss = nextBss;
549 }
550
551 IEEE80211_NODE_UNLOCK(nt);
552 return NULL;
553}
554
555bss_t *
556wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
557 u32 ssidLength, u32 dot11AuthMode, u32 authMode,
558 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp)
559{
560 bss_t *ni = NULL;
561 bss_t *best_ni = NULL;
562 u8 *pIESsid = NULL;
563
564 IEEE80211_NODE_LOCK (nt);
565
566 for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
567 pIESsid = ni->ni_cie.ie_ssid;
568 if (pIESsid[1] <= 32) {
569
570 // Step 1 : Check SSID
571 if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
572
573 if (ni->ni_cie.ie_capInfo & 0x10)
574 {
575
576 if ((NULL != ni->ni_cie.ie_rsn) && (WPA2_PSK_AUTH == authMode))
577 {
578 /* WPA2 */
579 if (NULL == best_ni)
580 {
581 best_ni = ni;
582 }
583 else if (ni->ni_rssi > best_ni->ni_rssi)
584 {
585 best_ni = ni;
586 }
587 }
588 else if ((NULL != ni->ni_cie.ie_wpa) && (WPA_PSK_AUTH == authMode))
589 {
590 /* WPA */
591 if (NULL == best_ni)
592 {
593 best_ni = ni;
594 }
595 else if (ni->ni_rssi > best_ni->ni_rssi)
596 {
597 best_ni = ni;
598 }
599 }
600 else if (WEP_CRYPT == pairwiseCryptoType)
601 {
602 /* WEP */
603 if (NULL == best_ni)
604 {
605 best_ni = ni;
606 }
607 else if (ni->ni_rssi > best_ni->ni_rssi)
608 {
609 best_ni = ni;
610 }
611 }
612 }
613 else
614 {
615 /* open AP */
616 if ((OPEN_AUTH == authMode) && (NONE_CRYPT == pairwiseCryptoType))
617 {
618 if (NULL == best_ni)
619 {
620 best_ni = ni;
621 }
622 else if (ni->ni_rssi > best_ni->ni_rssi)
623 {
624 best_ni = ni;
625 }
626 }
627 }
628 }
629 }
630 }
631
632 IEEE80211_NODE_UNLOCK (nt);
633
634 return best_ni;
635}
636
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c
new file mode 100644
index 00000000000..07b8313b16e
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c
@@ -0,0 +1,199 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_recv_beacon.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// IEEE 802.11 input handling.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25
26#include "a_config.h"
27#include "athdefs.h"
28#include "a_osapi.h"
29#include <wmi.h>
30#include <ieee80211.h>
31#include <wlan_api.h>
32
33#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
34 if ((_len) < (_minlen)) { \
35 return A_EINVAL; \
36 } \
37} while (0)
38
39#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
40 if ((__elem) == NULL) { \
41 return A_EINVAL; \
42 } \
43 if ((__elem)[1] > (__maxlen)) { \
44 return A_EINVAL; \
45 } \
46} while (0)
47
48
49/* unaligned little endian access */
50#define LE_READ_2(p) \
51 ((u16) \
52 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8)))
53
54#define LE_READ_4(p) \
55 ((u32) \
56 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \
57 (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24)))
58
59
60static int __inline
61iswpaoui(const u8 *frm)
62{
63 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
64}
65
66static int __inline
67iswmmoui(const u8 *frm)
68{
69 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
70}
71
72/* unused functions for now */
73#if 0
74static int __inline
75iswmmparam(const u8 *frm)
76{
77 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
78}
79
80static int __inline
81iswmminfo(const u8 *frm)
82{
83 return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE;
84}
85#endif
86
87static int __inline
88isatherosoui(const u8 *frm)
89{
90 return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
91}
92
93static int __inline
94iswscoui(const u8 *frm)
95{
96 return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI);
97}
98
99int
100wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie)
101{
102 u8 *frm, *efrm;
103 u8 elemid_ssid = false;
104
105 frm = buf;
106 efrm = (u8 *) (frm + framelen);
107
108 /*
109 * beacon/probe response frame format
110 * [8] time stamp
111 * [2] beacon interval
112 * [2] capability information
113 * [tlv] ssid
114 * [tlv] supported rates
115 * [tlv] country information
116 * [tlv] parameter set (FH/DS)
117 * [tlv] erp information
118 * [tlv] extended supported rates
119 * [tlv] WMM
120 * [tlv] WPA or RSN
121 * [tlv] Atheros Advanced Capabilities
122 */
123 IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
124 A_MEMZERO(cie, sizeof(*cie));
125
126 cie->ie_tstamp = frm; frm += 8;
127 cie->ie_beaconInt = A_LE2CPU16(*(u16 *)frm); frm += 2;
128 cie->ie_capInfo = A_LE2CPU16(*(u16 *)frm); frm += 2;
129 cie->ie_chan = 0;
130
131 while (frm < efrm) {
132 switch (*frm) {
133 case IEEE80211_ELEMID_SSID:
134 if (!elemid_ssid) {
135 cie->ie_ssid = frm;
136 elemid_ssid = true;
137 }
138 break;
139 case IEEE80211_ELEMID_RATES:
140 cie->ie_rates = frm;
141 break;
142 case IEEE80211_ELEMID_COUNTRY:
143 cie->ie_country = frm;
144 break;
145 case IEEE80211_ELEMID_FHPARMS:
146 break;
147 case IEEE80211_ELEMID_DSPARMS:
148 cie->ie_chan = frm[2];
149 break;
150 case IEEE80211_ELEMID_TIM:
151 cie->ie_tim = frm;
152 break;
153 case IEEE80211_ELEMID_IBSSPARMS:
154 break;
155 case IEEE80211_ELEMID_XRATES:
156 cie->ie_xrates = frm;
157 break;
158 case IEEE80211_ELEMID_ERP:
159 if (frm[1] != 1) {
160 //A_PRINTF("Discarding ERP Element - Bad Len\n");
161 return A_EINVAL;
162 }
163 cie->ie_erp = frm[2];
164 break;
165 case IEEE80211_ELEMID_RSN:
166 cie->ie_rsn = frm;
167 break;
168 case IEEE80211_ELEMID_HTCAP_ANA:
169 cie->ie_htcap = frm;
170 break;
171 case IEEE80211_ELEMID_HTINFO_ANA:
172 cie->ie_htop = frm;
173 break;
174#ifdef WAPI_ENABLE
175 case IEEE80211_ELEMID_WAPI:
176 cie->ie_wapi = frm;
177 break;
178#endif
179 case IEEE80211_ELEMID_VENDOR:
180 if (iswpaoui(frm)) {
181 cie->ie_wpa = frm;
182 } else if (iswmmoui(frm)) {
183 cie->ie_wmm = frm;
184 } else if (isatherosoui(frm)) {
185 cie->ie_ath = frm;
186 } else if(iswscoui(frm)) {
187 cie->ie_wsc = frm;
188 }
189 break;
190 default:
191 break;
192 }
193 frm += frm[1] + 2;
194 }
195 IEEE80211_VERIFY_ELEMENT(cie->ie_rates, IEEE80211_RATE_MAXSIZE);
196 IEEE80211_VERIFY_ELEMENT(cie->ie_ssid, IEEE80211_NWID_LEN);
197
198 return 0;
199}
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_utils.c b/drivers/staging/ath6kl/wlan/src/wlan_utils.c
new file mode 100644
index 00000000000..bc91599d9bf
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/src/wlan_utils.c
@@ -0,0 +1,58 @@
1//------------------------------------------------------------------------------
2// <copyright file="wlan_utils.c" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This module implements frequently used wlan utilies
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#include <a_config.h>
26#include <athdefs.h>
27#include <a_osapi.h>
28
29/*
30 * converts ieee channel number to frequency
31 */
32u16 wlan_ieee2freq(int chan)
33{
34 if (chan == 14) {
35 return 2484;
36 }
37 if (chan < 14) { /* 0-13 */
38 return (2407 + (chan*5));
39 }
40 if (chan < 27) { /* 15-26 */
41 return (2512 + ((chan-15)*20));
42 }
43 return (5000 + (chan*5));
44}
45
46/*
47 * Converts MHz frequency to IEEE channel number.
48 */
49u32 wlan_freq2ieee(u16 freq)
50{
51 if (freq == 2484)
52 return 14;
53 if (freq < 2484)
54 return (freq - 2407) / 5;
55 if (freq < 5000)
56 return 15 + ((freq - 2512) / 20);
57 return (freq - 5000) / 5;
58}
diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c
new file mode 100644
index 00000000000..c7b5e5cf9df
--- /dev/null
+++ b/drivers/staging/ath6kl/wmi/wmi.c
@@ -0,0 +1,6444 @@
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3//
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17//
18//------------------------------------------------------------------------------
19//==============================================================================
20// This module implements the hardware independent layer of the
21// Wireless Module Interface (WMI) protocol.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25
26#include <a_config.h>
27#include <athdefs.h>
28#include <a_osapi.h>
29#include "htc.h"
30#include "htc_api.h"
31#include "wmi.h"
32#include <wlan_api.h>
33#include <wmi_api.h>
34#include <ieee80211.h>
35#include <ieee80211_node.h>
36#include "dset_api.h"
37#include "wmi_host.h"
38#include "a_drv.h"
39#include "a_drv_api.h"
40#define ATH_MODULE_NAME wmi
41#include "a_debug.h"
42#include "dbglog_api.h"
43#include "roaming.h"
44#include "cfg80211.h"
45
46#define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0)
47
48#ifdef ATH_DEBUG_MODULE
49
50static struct ath_debug_mask_description wmi_debug_desc[] = {
51 { ATH_DEBUG_WMI , "General WMI Tracing"},
52};
53
54ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi,
55 "wmi",
56 "Wireless Module Interface",
57 ATH_DEBUG_MASK_DEFAULTS,
58 ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc),
59 wmi_debug_desc);
60
61#endif
62
63#ifndef REXOS
64#define DBGARG _A_FUNCNAME_
65#define DBGFMT "%s() : "
66#define DBG_WMI ATH_DEBUG_WMI
67#define DBG_ERROR ATH_DEBUG_ERR
68#define DBG_WMI2 ATH_DEBUG_WMI
69#define A_DPRINTF AR_DEBUG_PRINTF
70#endif
71
72static int wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len);
73
74static int wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap,
75 int len);
76static int wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap,
77 int len);
78
79static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap,
80 int len);
81static int wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap,
82 int len);
83static int wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap,
84 int len);
85static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap,
86 int len);
87static int wmi_sync_point(struct wmi_t *wmip);
88
89static int wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap,
90 int len);
91static int wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap,
92 int len);
93static int wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap,
94 int len);
95static int wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap,
96 int len);
97static int wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
98static int wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap,
99 int len);
100
101static int wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap,
102 int len);
103#ifdef CONFIG_HOST_DSET_SUPPORT
104static int wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len);
105static int wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap,
106 int len);
107#endif /* CONFIG_HOST_DSET_SUPPORT */
108
109
110static int wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap,
111 int len);
112static int wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
113static int wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
114static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
115static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len);
116static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
117static int wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len);
118static int wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len);
119static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap,
120 int len);
121static int wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap,
122 int len);
123static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap,
124 int len);
125static int
126wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
127
128static int
129wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
130
131
132#ifdef CONFIG_HOST_TCMD_SUPPORT
133static int
134wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len);
135#endif
136
137static int
138wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
139
140static int
141wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
142
143static int
144wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
145
146static bool
147wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex);
148
149static int
150wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
151
152static int
153wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len);
154
155static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
156
157int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
158 WMI_SYNC_FLAG syncflag);
159
160u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
161u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
162
163void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
164void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
165static int wmi_send_rssi_threshold_params(struct wmi_t *wmip,
166 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
167static int wmi_send_snr_threshold_params(struct wmi_t *wmip,
168 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
169#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
170static int
171wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len);
172#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
173
174static int wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap,
175 int len);
176static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,
177 int len);
178
179static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap,
180 int len);
181static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int);
182static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int);
183static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int);
184static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len);
185static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len);
186static int wmi_hci_event_rx(struct wmi_t *, u8 *, int);
187
188#ifdef WAPI_ENABLE
189static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,
190 int len);
191#endif
192
193#if defined(UNDER_CE)
194#if defined(NDIS51_MINIPORT)
195unsigned int processDot11Hdr = 0;
196#else
197unsigned int processDot11Hdr = 1;
198#endif
199#else
200extern unsigned int processDot11Hdr;
201#endif
202
203int wps_enable;
204static const s32 wmi_rateTable[][2] = {
205 //{W/O SGI, with SGI}
206 {1000, 1000},
207 {2000, 2000},
208 {5500, 5500},
209 {11000, 11000},
210 {6000, 6000},
211 {9000, 9000},
212 {12000, 12000},
213 {18000, 18000},
214 {24000, 24000},
215 {36000, 36000},
216 {48000, 48000},
217 {54000, 54000},
218 {6500, 7200},
219 {13000, 14400},
220 {19500, 21700},
221 {26000, 28900},
222 {39000, 43300},
223 {52000, 57800},
224 {58500, 65000},
225 {65000, 72200},
226 {13500, 15000},
227 {27000, 30000},
228 {40500, 45000},
229 {54000, 60000},
230 {81000, 90000},
231 {108000, 120000},
232 {121500, 135000},
233 {135000, 150000},
234 {0, 0}};
235
236#define MODE_A_SUPPORT_RATE_START ((s32) 4)
237#define MODE_A_SUPPORT_RATE_STOP ((s32) 11)
238
239#define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START
240#define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP
241
242#define MODE_B_SUPPORT_RATE_START ((s32) 0)
243#define MODE_B_SUPPORT_RATE_STOP ((s32) 3)
244
245#define MODE_G_SUPPORT_RATE_START ((s32) 0)
246#define MODE_G_SUPPORT_RATE_STOP ((s32) 11)
247
248#define MODE_GHT20_SUPPORT_RATE_START ((s32) 0)
249#define MODE_GHT20_SUPPORT_RATE_STOP ((s32) 19)
250
251#define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1)
252
253/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
254const u8 up_to_ac[]= {
255 WMM_AC_BE,
256 WMM_AC_BK,
257 WMM_AC_BK,
258 WMM_AC_BE,
259 WMM_AC_VI,
260 WMM_AC_VI,
261 WMM_AC_VO,
262 WMM_AC_VO,
263 };
264
265/* This stuff is used when we want a simple layer-3 visibility */
266typedef PREPACK struct _iphdr {
267 u8 ip_ver_hdrlen; /* version and hdr length */
268 u8 ip_tos; /* type of service */
269 u16 ip_len; /* total length */
270 u16 ip_id; /* identification */
271 s16 ip_off; /* fragment offset field */
272#define IP_DF 0x4000 /* dont fragment flag */
273#define IP_MF 0x2000 /* more fragments flag */
274#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
275 u8 ip_ttl; /* time to live */
276 u8 ip_p; /* protocol */
277 u16 ip_sum; /* checksum */
278 u8 ip_src[4]; /* source and dest address */
279 u8 ip_dst[4];
280} POSTPACK iphdr;
281
282static s16 rssi_event_value = 0;
283static s16 snr_event_value = 0;
284
285bool is_probe_ssid = false;
286
287void *
288wmi_init(void *devt)
289{
290 struct wmi_t *wmip;
291
292 A_REGISTER_MODULE_DEBUG_INFO(wmi);
293
294 wmip = A_MALLOC (sizeof(struct wmi_t));
295 if (wmip == NULL) {
296 return (NULL);
297 }
298 A_MEMZERO(wmip, sizeof(struct wmi_t ));
299#ifdef THREAD_X
300 INIT_WMI_LOCK(wmip);
301#else
302 A_MUTEX_INIT(&wmip->wmi_lock);
303#endif
304 wmip->wmi_devt = devt;
305 wlan_node_table_init(wmip, &wmip->wmi_scan_table);
306 wmi_qos_state_init(wmip);
307
308 wmip->wmi_powerMode = REC_POWER;
309 wmip->wmi_phyMode = WMI_11G_MODE;
310
311 wmip->wmi_pair_crypto_type = NONE_CRYPT;
312 wmip->wmi_grp_crypto_type = NONE_CRYPT;
313
314 wmip->wmi_ht_allowed[A_BAND_24GHZ] = 1;
315 wmip->wmi_ht_allowed[A_BAND_5GHZ] = 1;
316
317 return (wmip);
318}
319
320void
321wmi_qos_state_init(struct wmi_t *wmip)
322{
323 u8 i;
324
325 if (wmip == NULL) {
326 return;
327 }
328 LOCK_WMI(wmip);
329
330 /* Initialize QoS States */
331 wmip->wmi_numQoSStream = 0;
332
333 wmip->wmi_fatPipeExists = 0;
334
335 for (i=0; i < WMM_NUM_AC; i++) {
336 wmip->wmi_streamExistsForAC[i]=0;
337 }
338
339 UNLOCK_WMI(wmip);
340
341 A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1);
342}
343
344void
345wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid)
346{
347 A_ASSERT( eid != ENDPOINT_UNUSED);
348 wmip->wmi_endpoint_id = eid;
349}
350
351HTC_ENDPOINT_ID
352wmi_get_control_ep(struct wmi_t * wmip)
353{
354 return(wmip->wmi_endpoint_id);
355}
356
357void
358wmi_shutdown(struct wmi_t *wmip)
359{
360 if (wmip != NULL) {
361 wlan_node_table_cleanup(&wmip->wmi_scan_table);
362 if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) {
363#ifdef THREAD_X
364 DELETE_WMI_LOCK(&wmip);
365#else
366 A_MUTEX_DELETE(&wmip->wmi_lock);
367#endif
368 }
369 kfree(wmip);
370 }
371}
372
373/*
374 * performs DIX to 802.3 encapsulation for transmit packets.
375 * uses passed in buffer. Returns buffer or NULL if failed.
376 * Assumes the entire DIX header is contigous and that there is
377 * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
378 */
379int
380wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf)
381{
382 u8 *datap;
383 u16 typeorlen;
384 ATH_MAC_HDR macHdr;
385 ATH_LLC_SNAP_HDR *llcHdr;
386
387 A_ASSERT(osbuf != NULL);
388
389 if (A_NETBUF_HEADROOM(osbuf) <
390 (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
391 {
392 return A_NO_MEMORY;
393 }
394
395 datap = A_NETBUF_DATA(osbuf);
396
397 typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
398
399 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
400 /*
401 * packet is already in 802.3 format - return success
402 */
403 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
404 return (0);
405 }
406
407 /*
408 * Save mac fields and length to be inserted later
409 */
410 memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
411 memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
412 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
413 sizeof(ATH_LLC_SNAP_HDR));
414
415 /*
416 * Make room for LLC+SNAP headers
417 */
418 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
419 return A_NO_MEMORY;
420 }
421 datap = A_NETBUF_DATA(osbuf);
422
423 memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
424
425 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
426 llcHdr->dsap = 0xAA;
427 llcHdr->ssap = 0xAA;
428 llcHdr->cntl = 0x03;
429 llcHdr->orgCode[0] = 0x0;
430 llcHdr->orgCode[1] = 0x0;
431 llcHdr->orgCode[2] = 0x0;
432 llcHdr->etherType = typeorlen;
433
434 return (0);
435}
436
437int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS)
438{
439 switch(*pVersion){
440 case 0:
441 return (0);
442 case WMI_META_VERSION_1:
443 {
444 WMI_TX_META_V1 *pV1= NULL;
445 A_ASSERT(osbuf != NULL);
446 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
447 return A_NO_MEMORY;
448 }
449
450 pV1 = (WMI_TX_META_V1 *)A_NETBUF_DATA(osbuf);
451 /* the pktID is used in conjunction with txComplete messages
452 * allowing the target to notify which tx requests have been
453 * completed and how. */
454 pV1->pktID = 0;
455 /* the ratePolicyID allows the host to specify which rate policy
456 * to use for transmitting this packet. 0 means use default behavior. */
457 pV1->ratePolicyID = 0;
458 A_ASSERT(pVersion != NULL);
459 /* the version must be used to populate the meta field of the WMI_DATA_HDR */
460 *pVersion = WMI_META_VERSION_1;
461 return (0);
462 }
463 case WMI_META_VERSION_2:
464 {
465 WMI_TX_META_V2 *pV2 ;
466 A_ASSERT(osbuf != NULL);
467 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
468 return A_NO_MEMORY;
469 }
470 pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf);
471 memcpy(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2));
472 return (0);
473 }
474 default:
475 return (0);
476 }
477}
478
479/* Adds a WMI data header */
480int
481wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData,
482 WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS)
483{
484 WMI_DATA_HDR *dtHdr;
485// u8 metaVersion = 0;
486 int status;
487
488 A_ASSERT(osbuf != NULL);
489
490 /* adds the meta data field after the wmi data hdr. If metaVersion
491 * is returns 0 then no meta field was added. */
492 if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != 0) {
493 return status;
494 }
495
496 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
497 return A_NO_MEMORY;
498 }
499
500 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
501 A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR));
502
503 WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType);
504 WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type);
505
506 if (bMoreData) {
507 WMI_DATA_HDR_SET_MORE_BIT(dtHdr);
508 }
509
510 WMI_DATA_HDR_SET_META(dtHdr, metaVersion);
511
512 dtHdr->info3 = 0;
513
514 return (0);
515}
516
517
518u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled)
519{
520 u8 *datap;
521 u8 trafficClass = WMM_AC_BE;
522 u16 ipType = IP_ETHERTYPE;
523 WMI_DATA_HDR *dtHdr;
524 u8 streamExists = 0;
525 u8 userPriority;
526 u32 hdrsize, metasize;
527 ATH_LLC_SNAP_HDR *llcHdr;
528
529 WMI_CREATE_PSTREAM_CMD cmd;
530
531 A_ASSERT(osbuf != NULL);
532
533 //
534 // Initialize header size
535 //
536 hdrsize = 0;
537
538 datap = A_NETBUF_DATA(osbuf);
539 dtHdr = (WMI_DATA_HDR *)datap;
540 metasize = (WMI_DATA_HDR_GET_META(dtHdr))? WMI_MAX_TX_META_SZ : 0;
541
542 if (!wmmEnabled)
543 {
544 /* If WMM is disabled all traffic goes as BE traffic */
545 userPriority = 0;
546 }
547 else
548 {
549 if (processDot11Hdr)
550 {
551 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
552 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
553 hdrsize);
554
555
556 }
557 else
558 {
559 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
560 sizeof(ATH_MAC_HDR));
561 }
562
563 if (llcHdr->etherType == A_CPU2BE16(ipType))
564 {
565 /* Extract the endpoint info from the TOS field in the IP header */
566
567 userPriority = wmi_determine_userPriority (((u8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority);
568 }
569 else
570 {
571 userPriority = layer2Priority & 0x7;
572 }
573 }
574
575
576 /* workaround for WMM S5 */
577 if ((WMM_AC_VI == wmip->wmi_traffic_class) && ((5 == userPriority) || (4 == userPriority)))
578 {
579 userPriority = 1;
580 }
581
582 trafficClass = convert_userPriority_to_trafficClass(userPriority);
583
584 WMI_DATA_HDR_SET_UP(dtHdr, userPriority);
585 /* lower 3-bits are 802.1d priority */
586 //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;
587
588 LOCK_WMI(wmip);
589 streamExists = wmip->wmi_fatPipeExists;
590 UNLOCK_WMI(wmip);
591
592 if (!(streamExists & (1 << trafficClass)))
593 {
594
595 A_MEMZERO(&cmd, sizeof(cmd));
596 cmd.trafficClass = trafficClass;
597 cmd.userPriority = userPriority;
598 cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT;
599 /* Implicit streams are created with TSID 0xFF */
600
601 cmd.tsid = WMI_IMPLICIT_PSTREAM;
602 wmi_create_pstream_cmd(wmip, &cmd);
603 }
604
605 return trafficClass;
606}
607
608int
609wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode)
610{
611 u8 *datap;
612 u16 typeorlen;
613 ATH_MAC_HDR macHdr;
614 ATH_LLC_SNAP_HDR *llcHdr;
615 struct ieee80211_frame *wh;
616 u32 hdrsize;
617
618 A_ASSERT(osbuf != NULL);
619
620 if (A_NETBUF_HEADROOM(osbuf) <
621 (sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
622 {
623 return A_NO_MEMORY;
624 }
625
626 datap = A_NETBUF_DATA(osbuf);
627
628 typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
629
630 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
631/*
632 * packet is already in 802.3 format - return success
633 */
634 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
635 goto AddDot11Hdr;
636 }
637
638 /*
639 * Save mac fields and length to be inserted later
640 */
641 memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
642 memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
643 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
644 sizeof(ATH_LLC_SNAP_HDR));
645
646 // Remove the Ethernet hdr
647 A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR));
648 /*
649 * Make room for LLC+SNAP headers
650 */
651 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
652 return A_NO_MEMORY;
653 }
654 datap = A_NETBUF_DATA(osbuf);
655
656 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
657 llcHdr->dsap = 0xAA;
658 llcHdr->ssap = 0xAA;
659 llcHdr->cntl = 0x03;
660 llcHdr->orgCode[0] = 0x0;
661 llcHdr->orgCode[1] = 0x0;
662 llcHdr->orgCode[2] = 0x0;
663 llcHdr->etherType = typeorlen;
664
665AddDot11Hdr:
666 /* Make room for 802.11 hdr */
667 if (wmip->wmi_is_wmm_enabled)
668 {
669 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
670 if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
671 {
672 return A_NO_MEMORY;
673 }
674 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
675 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_QOS;
676 }
677 else
678 {
679 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(u32));
680 if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
681 {
682 return A_NO_MEMORY;
683 }
684 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
685 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_DATA;
686 }
687 /* Setup the SA & DA */
688 IEEE80211_ADDR_COPY(wh->i_addr2, macHdr.srcMac);
689
690 if (mode == INFRA_NETWORK) {
691 IEEE80211_ADDR_COPY(wh->i_addr3, macHdr.dstMac);
692 }
693 else if (mode == ADHOC_NETWORK) {
694 IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac);
695 }
696
697 return (0);
698}
699
700int
701wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf)
702{
703 u8 *datap;
704 struct ieee80211_frame *pwh,wh;
705 u8 type,subtype;
706 ATH_LLC_SNAP_HDR *llcHdr;
707 ATH_MAC_HDR macHdr;
708 u32 hdrsize;
709
710 A_ASSERT(osbuf != NULL);
711 datap = A_NETBUF_DATA(osbuf);
712
713 pwh = (struct ieee80211_frame *)datap;
714 type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
715 subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
716
717 memcpy((u8 *)&wh, datap, sizeof(struct ieee80211_frame));
718
719 /* strip off the 802.11 hdr*/
720 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
721 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
722 A_NETBUF_PULL(osbuf, hdrsize);
723 } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) {
724 A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame));
725 }
726
727 datap = A_NETBUF_DATA(osbuf);
728 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
729
730 macHdr.typeOrLen = llcHdr->etherType;
731 A_MEMZERO(macHdr.dstMac, sizeof(macHdr.dstMac));
732 A_MEMZERO(macHdr.srcMac, sizeof(macHdr.srcMac));
733
734 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
735 case IEEE80211_FC1_DIR_NODS:
736 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
737 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
738 break;
739 case IEEE80211_FC1_DIR_TODS:
740 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr3);
741 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
742 break;
743 case IEEE80211_FC1_DIR_FROMDS:
744 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
745 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr3);
746 break;
747 case IEEE80211_FC1_DIR_DSTODS:
748 break;
749 }
750
751 // Remove the LLC Hdr.
752 A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR));
753
754 // Insert the ATH MAC hdr.
755
756 A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR));
757 datap = A_NETBUF_DATA(osbuf);
758
759 memcpy (datap, &macHdr, sizeof(ATH_MAC_HDR));
760
761 return 0;
762}
763
764/*
765 * performs 802.3 to DIX encapsulation for received packets.
766 * Assumes the entire 802.3 header is contigous.
767 */
768int
769wmi_dot3_2_dix(void *osbuf)
770{
771 u8 *datap;
772 ATH_MAC_HDR macHdr;
773 ATH_LLC_SNAP_HDR *llcHdr;
774
775 A_ASSERT(osbuf != NULL);
776 datap = A_NETBUF_DATA(osbuf);
777
778 memcpy(&macHdr, datap, sizeof(ATH_MAC_HDR));
779 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
780 macHdr.typeOrLen = llcHdr->etherType;
781
782 if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
783 return A_NO_MEMORY;
784 }
785
786 datap = A_NETBUF_DATA(osbuf);
787
788 memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
789
790 return (0);
791}
792
793/*
794 * Removes a WMI data header
795 */
796int
797wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf)
798{
799 A_ASSERT(osbuf != NULL);
800
801 return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR)));
802}
803
804void
805wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg)
806{
807 wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg);
808}
809
810/*
811 * WMI Extended Event received from Target.
812 */
813int
814wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf)
815{
816 WMIX_CMD_HDR *cmd;
817 u16 id;
818 u8 *datap;
819 u32 len;
820 int status = 0;
821
822 if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) {
823 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
824 wmip->wmi_stats.cmd_len_err++;
825 return A_ERROR;
826 }
827
828 cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
829 id = cmd->commandId;
830
831 if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
832 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
833 wmip->wmi_stats.cmd_len_err++;
834 return A_ERROR;
835 }
836
837 datap = A_NETBUF_DATA(osbuf);
838 len = A_NETBUF_LEN(osbuf);
839
840 switch (id) {
841 case (WMIX_DSETOPENREQ_EVENTID):
842 status = wmi_dset_open_req_rx(wmip, datap, len);
843 break;
844#ifdef CONFIG_HOST_DSET_SUPPORT
845 case (WMIX_DSETCLOSE_EVENTID):
846 status = wmi_dset_close_rx(wmip, datap, len);
847 break;
848 case (WMIX_DSETDATAREQ_EVENTID):
849 status = wmi_dset_data_req_rx(wmip, datap, len);
850 break;
851#endif /* CONFIG_HOST_DSET_SUPPORT */
852 case (WMIX_HB_CHALLENGE_RESP_EVENTID):
853 wmi_hbChallengeResp_rx(wmip, datap, len);
854 break;
855 case (WMIX_DBGLOG_EVENTID):
856 wmi_dbglog_event_rx(wmip, datap, len);
857 break;
858#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
859 case (WMIX_PROF_COUNT_EVENTID):
860 wmi_prof_count_rx(wmip, datap, len);
861 break;
862#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
863 default:
864 A_DPRINTF(DBG_WMI|DBG_ERROR,
865 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
866 wmip->wmi_stats.cmd_id_err++;
867 status = A_ERROR;
868 break;
869 }
870
871 return status;
872}
873
874/*
875 * Control Path
876 */
877u32 cmdRecvNum;
878
879int
880wmi_control_rx(struct wmi_t *wmip, void *osbuf)
881{
882 WMI_CMD_HDR *cmd;
883 u16 id;
884 u8 *datap;
885 u32 len, i, loggingReq;
886 int status = 0;
887
888 A_ASSERT(osbuf != NULL);
889 if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) {
890 A_NETBUF_FREE(osbuf);
891 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
892 wmip->wmi_stats.cmd_len_err++;
893 return A_ERROR;
894 }
895
896 cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
897 id = cmd->commandId;
898
899 if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
900 A_NETBUF_FREE(osbuf);
901 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
902 wmip->wmi_stats.cmd_len_err++;
903 return A_ERROR;
904 }
905
906 datap = A_NETBUF_DATA(osbuf);
907 len = A_NETBUF_LEN(osbuf);
908
909 loggingReq = 0;
910
911 ar6000_get_driver_cfg(wmip->wmi_devt,
912 AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS,
913 &loggingReq);
914
915 if(loggingReq) {
916 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id));
917 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum));
918 for(i = 0; i < len; i++)
919 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i]));
920 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n"));
921 }
922
923 LOCK_WMI(wmip);
924 cmdRecvNum++;
925 UNLOCK_WMI(wmip);
926
927 switch (id) {
928 case (WMI_GET_BITRATE_CMDID):
929 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG));
930 status = wmi_bitrate_reply_rx(wmip, datap, len);
931 break;
932 case (WMI_GET_CHANNEL_LIST_CMDID):
933 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG));
934 status = wmi_channelList_reply_rx(wmip, datap, len);
935 break;
936 case (WMI_GET_TX_PWR_CMDID):
937 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG));
938 status = wmi_txPwr_reply_rx(wmip, datap, len);
939 break;
940 case (WMI_READY_EVENTID):
941 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG));
942 status = wmi_ready_event_rx(wmip, datap, len);
943 A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt);
944 break;
945 case (WMI_CONNECT_EVENTID):
946 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG));
947 status = wmi_connect_event_rx(wmip, datap, len);
948 break;
949 case (WMI_DISCONNECT_EVENTID):
950 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG));
951 status = wmi_disconnect_event_rx(wmip, datap, len);
952 break;
953 case (WMI_PEER_NODE_EVENTID):
954 A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG));
955 status = wmi_peer_node_event_rx(wmip, datap, len);
956 break;
957 case (WMI_TKIP_MICERR_EVENTID):
958 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG));
959 status = wmi_tkip_micerr_event_rx(wmip, datap, len);
960 break;
961 case (WMI_BSSINFO_EVENTID):
962 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG));
963 {
964 /*
965 * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR
966 * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer
967 * and reconstruct the WMI_BSS_INFO_HDR in its place
968 */
969 WMI_BSS_INFO_HDR2 bih2;
970 WMI_BSS_INFO_HDR *bih;
971 memcpy(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2));
972
973 A_NETBUF_PUSH(osbuf, 4);
974 datap = A_NETBUF_DATA(osbuf);
975 len = A_NETBUF_LEN(osbuf);
976 bih = (WMI_BSS_INFO_HDR *)datap;
977
978 bih->channel = bih2.channel;
979 bih->frameType = bih2.frameType;
980 bih->snr = bih2.snr;
981 bih->rssi = bih2.snr - 95;
982 bih->ieMask = bih2.ieMask;
983 memcpy(bih->bssid, bih2.bssid, ATH_MAC_LEN);
984
985 status = wmi_bssInfo_event_rx(wmip, datap, len);
986 }
987 break;
988 case (WMI_REGDOMAIN_EVENTID):
989 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG));
990 status = wmi_regDomain_event_rx(wmip, datap, len);
991 break;
992 case (WMI_PSTREAM_TIMEOUT_EVENTID):
993 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG));
994 status = wmi_pstream_timeout_event_rx(wmip, datap, len);
995 break;
996 case (WMI_NEIGHBOR_REPORT_EVENTID):
997 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG));
998 status = wmi_neighborReport_event_rx(wmip, datap, len);
999 break;
1000 case (WMI_SCAN_COMPLETE_EVENTID):
1001 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG));
1002 status = wmi_scanComplete_rx(wmip, datap, len);
1003 break;
1004 case (WMI_CMDERROR_EVENTID):
1005 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG));
1006 status = wmi_errorEvent_rx(wmip, datap, len);
1007 break;
1008 case (WMI_REPORT_STATISTICS_EVENTID):
1009 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG));
1010 status = wmi_statsEvent_rx(wmip, datap, len);
1011 break;
1012 case (WMI_RSSI_THRESHOLD_EVENTID):
1013 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG));
1014 status = wmi_rssiThresholdEvent_rx(wmip, datap, len);
1015 break;
1016 case (WMI_ERROR_REPORT_EVENTID):
1017 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG));
1018 status = wmi_reportErrorEvent_rx(wmip, datap, len);
1019 break;
1020 case (WMI_OPT_RX_FRAME_EVENTID):
1021 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG));
1022 status = wmi_opt_frame_event_rx(wmip, datap, len);
1023 break;
1024 case (WMI_REPORT_ROAM_TBL_EVENTID):
1025 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG));
1026 status = wmi_roam_tbl_event_rx(wmip, datap, len);
1027 break;
1028 case (WMI_EXTENSION_EVENTID):
1029 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG));
1030 status = wmi_control_rx_xtnd(wmip, osbuf);
1031 break;
1032 case (WMI_CAC_EVENTID):
1033 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG));
1034 status = wmi_cac_event_rx(wmip, datap, len);
1035 break;
1036 case (WMI_CHANNEL_CHANGE_EVENTID):
1037 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CHANNEL_CHANGE_EVENTID\n", DBGARG));
1038 status = wmi_channel_change_event_rx(wmip, datap, len);
1039 break;
1040 case (WMI_REPORT_ROAM_DATA_EVENTID):
1041 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG));
1042 status = wmi_roam_data_event_rx(wmip, datap, len);
1043 break;
1044#ifdef CONFIG_HOST_TCMD_SUPPORT
1045 case (WMI_TEST_EVENTID):
1046 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG));
1047 status = wmi_tcmd_test_report_rx(wmip, datap, len);
1048 break;
1049#endif
1050 case (WMI_GET_FIXRATES_CMDID):
1051 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG));
1052 status = wmi_ratemask_reply_rx(wmip, datap, len);
1053 break;
1054 case (WMI_TX_RETRY_ERR_EVENTID):
1055 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG));
1056 status = wmi_txRetryErrEvent_rx(wmip, datap, len);
1057 break;
1058 case (WMI_SNR_THRESHOLD_EVENTID):
1059 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG));
1060 status = wmi_snrThresholdEvent_rx(wmip, datap, len);
1061 break;
1062 case (WMI_LQ_THRESHOLD_EVENTID):
1063 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG));
1064 status = wmi_lqThresholdEvent_rx(wmip, datap, len);
1065 break;
1066 case (WMI_APLIST_EVENTID):
1067 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n"));
1068 status = wmi_aplistEvent_rx(wmip, datap, len);
1069 break;
1070 case (WMI_GET_KEEPALIVE_CMDID):
1071 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG));
1072 status = wmi_keepalive_reply_rx(wmip, datap, len);
1073 break;
1074 case (WMI_GET_WOW_LIST_EVENTID):
1075 status = wmi_get_wow_list_event_rx(wmip, datap, len);
1076 break;
1077 case (WMI_GET_PMKID_LIST_EVENTID):
1078 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG));
1079 status = wmi_get_pmkid_list_event_rx(wmip, datap, len);
1080 break;
1081 case (WMI_PSPOLL_EVENTID):
1082 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSPOLL_EVENT\n", DBGARG));
1083 status = wmi_pspoll_event_rx(wmip, datap, len);
1084 break;
1085 case (WMI_DTIMEXPIRY_EVENTID):
1086 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DTIMEXPIRY_EVENT\n", DBGARG));
1087 status = wmi_dtimexpiry_event_rx(wmip, datap, len);
1088 break;
1089 case (WMI_SET_PARAMS_REPLY_EVENTID):
1090 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
1091 status = wmi_set_params_event_rx(wmip, datap, len);
1092 break;
1093 case (WMI_ADDBA_REQ_EVENTID):
1094 status = wmi_addba_req_event_rx(wmip, datap, len);
1095 break;
1096 case (WMI_ADDBA_RESP_EVENTID):
1097 status = wmi_addba_resp_event_rx(wmip, datap, len);
1098 break;
1099 case (WMI_DELBA_REQ_EVENTID):
1100 status = wmi_delba_req_event_rx(wmip, datap, len);
1101 break;
1102 case (WMI_REPORT_BTCOEX_CONFIG_EVENTID):
1103 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_CONFIG_EVENTID", DBGARG));
1104 status = wmi_btcoex_config_event_rx(wmip, datap, len);
1105 break;
1106 case (WMI_REPORT_BTCOEX_STATS_EVENTID):
1107 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG));
1108 status = wmi_btcoex_stats_event_rx(wmip, datap, len);
1109 break;
1110 case (WMI_TX_COMPLETE_EVENTID):
1111 {
1112 int index;
1113 TX_COMPLETE_MSG_V1 *pV1;
1114 WMI_TX_COMPLETE_EVENT *pEv = (WMI_TX_COMPLETE_EVENT *)datap;
1115 A_PRINTF("comp: %d %d %d\n", pEv->numMessages, pEv->msgLen, pEv->msgType);
1116
1117 for(index = 0 ; index < pEv->numMessages ; index++) {
1118 pV1 = (TX_COMPLETE_MSG_V1 *)(datap + sizeof(WMI_TX_COMPLETE_EVENT) + index*sizeof(TX_COMPLETE_MSG_V1));
1119 A_PRINTF("msg: %d %d %d %d\n", pV1->status, pV1->pktID, pV1->rateIdx, pV1->ackFailures);
1120 }
1121 }
1122 break;
1123 case (WMI_HCI_EVENT_EVENTID):
1124 status = wmi_hci_event_rx(wmip, datap, len);
1125 break;
1126#ifdef WAPI_ENABLE
1127 case (WMI_WAPI_REKEY_EVENTID):
1128 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_WAPI_REKEY_EVENTID", DBGARG));
1129 status = wmi_wapi_rekey_event_rx(wmip, datap, len);
1130 break;
1131#endif
1132 default:
1133 A_DPRINTF(DBG_WMI|DBG_ERROR,
1134 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
1135 wmip->wmi_stats.cmd_id_err++;
1136 status = A_ERROR;
1137 break;
1138 }
1139
1140 A_NETBUF_FREE(osbuf);
1141
1142 return status;
1143}
1144
1145/* Send a "simple" wmi command -- one with no arguments */
1146static int
1147wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid)
1148{
1149 void *osbuf;
1150
1151 osbuf = A_NETBUF_ALLOC(0);
1152 if (osbuf == NULL) {
1153 return A_NO_MEMORY;
1154 }
1155
1156 return (wmi_cmd_send(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1157}
1158
1159/* Send a "simple" extended wmi command -- one with no arguments.
1160 Enabling this command only if GPIO or profiling support is enabled.
1161 This is to suppress warnings on some platforms */
1162#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
1163static int
1164wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid)
1165{
1166 void *osbuf;
1167
1168 osbuf = A_NETBUF_ALLOC(0);
1169 if (osbuf == NULL) {
1170 return A_NO_MEMORY;
1171 }
1172
1173 return (wmi_cmd_send_xtnd(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1174}
1175#endif
1176
1177static int
1178wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1179{
1180 WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
1181
1182 if (len < sizeof(WMI_READY_EVENT)) {
1183 return A_EINVAL;
1184 }
1185 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1186 wmip->wmi_ready = true;
1187 A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability,
1188 ev->sw_version, ev->abi_version);
1189
1190 return 0;
1191}
1192
1193#define LE_READ_4(p) \
1194 ((u32) \
1195 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \
1196 (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24)))
1197
1198static int __inline
1199iswmmoui(const u8 *frm)
1200{
1201 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
1202}
1203
1204static int __inline
1205iswmmparam(const u8 *frm)
1206{
1207 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
1208}
1209
1210
1211static int
1212wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1213{
1214 WMI_CONNECT_EVENT *ev;
1215 u8 *pie,*peie;
1216
1217 if (len < sizeof(WMI_CONNECT_EVENT))
1218 {
1219 return A_EINVAL;
1220 }
1221 ev = (WMI_CONNECT_EVENT *)datap;
1222
1223 A_DPRINTF(DBG_WMI,
1224 (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
1225 DBGARG, ev->channel,
1226 ev->bssid[0], ev->bssid[1], ev->bssid[2],
1227 ev->bssid[3], ev->bssid[4], ev->bssid[5]));
1228
1229 memcpy(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);
1230
1231 /* initialize pointer to start of assoc rsp IEs */
1232 pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen +
1233 sizeof(u16) + /* capinfo*/
1234 sizeof(u16) + /* status Code */
1235 sizeof(u16) ; /* associd */
1236
1237 /* initialize pointer to end of assoc rsp IEs */
1238 peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen;
1239
1240 while (pie < peie)
1241 {
1242 switch (*pie)
1243 {
1244 case IEEE80211_ELEMID_VENDOR:
1245 if (iswmmoui(pie))
1246 {
1247 if(iswmmparam (pie))
1248 {
1249 wmip->wmi_is_wmm_enabled = true;
1250 }
1251 }
1252 break;
1253 }
1254
1255 if (wmip->wmi_is_wmm_enabled)
1256 {
1257 break;
1258 }
1259 pie += pie[1] + 2;
1260 }
1261
1262 A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid,
1263 ev->listenInterval, ev->beaconInterval,
1264 (NETWORK_TYPE) ev->networkType, ev->beaconIeLen,
1265 ev->assocReqLen, ev->assocRespLen,
1266 ev->assocInfo);
1267
1268 return 0;
1269}
1270
1271static int
1272wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1273{
1274 WMI_REG_DOMAIN_EVENT *ev;
1275
1276 if (len < sizeof(*ev)) {
1277 return A_EINVAL;
1278 }
1279 ev = (WMI_REG_DOMAIN_EVENT *)datap;
1280
1281 A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain);
1282
1283 return 0;
1284}
1285
1286static int
1287wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1288{
1289 WMI_NEIGHBOR_REPORT_EVENT *ev;
1290 int numAps;
1291
1292 if (len < sizeof(*ev)) {
1293 return A_EINVAL;
1294 }
1295 ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;
1296 numAps = ev->numberOfAps;
1297
1298 if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {
1299 return A_EINVAL;
1300 }
1301
1302 A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor);
1303
1304 return 0;
1305}
1306
1307static int
1308wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1309{
1310 WMI_DISCONNECT_EVENT *ev;
1311 wmip->wmi_traffic_class = 100;
1312
1313 if (len < sizeof(WMI_DISCONNECT_EVENT)) {
1314 return A_EINVAL;
1315 }
1316 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1317
1318 ev = (WMI_DISCONNECT_EVENT *)datap;
1319
1320 A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));
1321
1322 wmip->wmi_is_wmm_enabled = false;
1323 wmip->wmi_pair_crypto_type = NONE_CRYPT;
1324 wmip->wmi_grp_crypto_type = NONE_CRYPT;
1325
1326 A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid,
1327 ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus);
1328
1329 return 0;
1330}
1331
1332static int
1333wmi_peer_node_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1334{
1335 WMI_PEER_NODE_EVENT *ev;
1336
1337 if (len < sizeof(WMI_PEER_NODE_EVENT)) {
1338 return A_EINVAL;
1339 }
1340 ev = (WMI_PEER_NODE_EVENT *)datap;
1341 if (ev->eventCode == PEER_NODE_JOIN_EVENT) {
1342 A_DPRINTF (DBG_WMI, (DBGFMT "Joined node with Macaddr: ", DBGARG));
1343 } else if(ev->eventCode == PEER_NODE_LEAVE_EVENT) {
1344 A_DPRINTF (DBG_WMI, (DBGFMT "left node with Macaddr: ", DBGARG));
1345 }
1346
1347 A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr);
1348
1349 return 0;
1350}
1351
1352static int
1353wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1354{
1355 WMI_TKIP_MICERR_EVENT *ev;
1356
1357 if (len < sizeof(*ev)) {
1358 return A_EINVAL;
1359 }
1360 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1361
1362 ev = (WMI_TKIP_MICERR_EVENT *)datap;
1363 A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast);
1364
1365 return 0;
1366}
1367
1368static int
1369wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1370{
1371 bss_t *bss = NULL;
1372 WMI_BSS_INFO_HDR *bih;
1373 u8 *buf;
1374 u32 nodeCachingAllowed = 1;
1375 u8 cached_ssid_len = 0;
1376 u8 cached_ssid_buf[IEEE80211_NWID_LEN] = {0};
1377 u8 beacon_ssid_len = 0;
1378
1379 if (len <= sizeof(WMI_BSS_INFO_HDR)) {
1380 return A_EINVAL;
1381 }
1382
1383 bih = (WMI_BSS_INFO_HDR *)datap;
1384 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1385
1386 if (bih->rssi > 0) {
1387 if (NULL == bss)
1388 return 0; //no node found in the table, just drop the node with incorrect RSSI
1389 else
1390 bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used in A_WMI_BSSINFO_EVENT_RX
1391 }
1392
1393 A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len);
1394 /* What is driver config for wlan node caching? */
1395 if(ar6000_get_driver_cfg(wmip->wmi_devt,
1396 AR6000_DRIVER_CFG_GET_WLANNODECACHING,
1397 &nodeCachingAllowed) != 0) {
1398 wmi_node_return(wmip, bss);
1399 return A_EINVAL;
1400 }
1401
1402 if(!nodeCachingAllowed) {
1403 wmi_node_return(wmip, bss);
1404 return 0;
1405 }
1406
1407 buf = datap + sizeof(WMI_BSS_INFO_HDR);
1408 len -= sizeof(WMI_BSS_INFO_HDR);
1409
1410 A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
1411 "bssid \"%pM\"\n", DBGARG, bih->channel,
1412 (unsigned char) bih->rssi, bih->bssid));
1413
1414 if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
1415 wmi_node_return(wmip, bss);
1416 return 0;
1417 }
1418
1419 if (bss != NULL) {
1420 /*
1421 * Free up the node. Not the most efficient process given
1422 * we are about to allocate a new node but it is simple and should be
1423 * adequate.
1424 */
1425
1426 /* In case of hidden AP, beacon will not have ssid,
1427 * but a directed probe response will have it,
1428 * so cache the probe-resp-ssid if already present. */
1429 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType))
1430 {
1431 u8 *ie_ssid;
1432
1433 ie_ssid = bss->ni_cie.ie_ssid;
1434 if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0))
1435 {
1436 cached_ssid_len = ie_ssid[1];
1437 memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len);
1438 }
1439 }
1440
1441 /*
1442 * Use the current average rssi of associated AP base on assumpiton
1443 * 1. Most os with GUI will update RSSI by wmi_get_stats_cmd() periodically
1444 * 2. wmi_get_stats_cmd(..) will be called when calling wmi_startscan_cmd(...)
1445 * The average value of RSSI give end-user better feeling for instance value of scan result
1446 * It also sync up RSSI info in GUI between scan result and RSSI signal icon
1447 */
1448 if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
1449 bih->rssi = bss->ni_rssi;
1450 bih->snr = bss->ni_snr;
1451 }
1452
1453 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1454 }
1455
1456 /* beacon/probe response frame format
1457 * [8] time stamp
1458 * [2] beacon interval
1459 * [2] capability information
1460 * [tlv] ssid */
1461 beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
1462
1463 /* If ssid is cached for this hidden AP, then change buffer len accordingly. */
1464 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1465 (0 != cached_ssid_len) &&
1466 (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1467 {
1468 len += (cached_ssid_len - beacon_ssid_len);
1469 }
1470
1471 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1472 if (bss == NULL) {
1473 return A_NO_MEMORY;
1474 }
1475
1476 bss->ni_snr = bih->snr;
1477 bss->ni_rssi = bih->rssi;
1478 A_ASSERT(bss->ni_buf != NULL);
1479
1480 /* In case of hidden AP, beacon will not have ssid,
1481 * but a directed probe response will have it,
1482 * so place the cached-ssid(probe-resp) in the bssinfo. */
1483 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1484 (0 != cached_ssid_len) &&
1485 (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1486 {
1487 u8 *ni_buf = bss->ni_buf;
1488 int buf_len = len;
1489
1490 /* copy the first 14 bytes such as
1491 * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(1). */
1492 memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
1493
1494 ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
1495 ni_buf += (SSID_IE_LEN_INDEX + 1);
1496
1497 buf += (SSID_IE_LEN_INDEX + 1);
1498 buf_len -= (SSID_IE_LEN_INDEX + 1);
1499
1500 /* copy the cached ssid */
1501 memcpy(ni_buf, cached_ssid_buf, cached_ssid_len);
1502 ni_buf += cached_ssid_len;
1503
1504 buf += beacon_ssid_len;
1505 buf_len -= beacon_ssid_len;
1506
1507 if (cached_ssid_len > beacon_ssid_len)
1508 buf_len -= (cached_ssid_len - beacon_ssid_len);
1509
1510 /* now copy the rest of bytes */
1511 memcpy(ni_buf, buf, buf_len);
1512 }
1513 else
1514 memcpy(bss->ni_buf, buf, len);
1515
1516 bss->ni_framelen = len;
1517 if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != 0) {
1518 wlan_node_free(bss);
1519 return A_EINVAL;
1520 }
1521
1522 /*
1523 * Update the frequency in ie_chan, overwriting of channel number
1524 * which is done in wlan_parse_beacon
1525 */
1526 bss->ni_cie.ie_chan = bih->channel;
1527 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1528
1529 return 0;
1530}
1531
1532static int
1533wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1534{
1535 bss_t *bss;
1536 WMI_OPT_RX_INFO_HDR *bih;
1537 u8 *buf;
1538
1539 if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
1540 return A_EINVAL;
1541 }
1542
1543 bih = (WMI_OPT_RX_INFO_HDR *)datap;
1544 buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
1545 len -= sizeof(WMI_OPT_RX_INFO_HDR);
1546
1547 A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG,
1548 bih->bssid[4], bih->bssid[5]));
1549
1550 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1551 if (bss != NULL) {
1552 /*
1553 * Free up the node. Not the most efficient process given
1554 * we are about to allocate a new node but it is simple and should be
1555 * adequate.
1556 */
1557 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1558 }
1559
1560 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1561 if (bss == NULL) {
1562 return A_NO_MEMORY;
1563 }
1564
1565 bss->ni_snr = bih->snr;
1566 bss->ni_cie.ie_chan = bih->channel;
1567 A_ASSERT(bss->ni_buf != NULL);
1568 memcpy(bss->ni_buf, buf, len);
1569 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1570
1571 return 0;
1572}
1573
1574 /* This event indicates inactivity timeout of a fatpipe(pstream)
1575 * at the target
1576 */
1577static int
1578wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1579{
1580 WMI_PSTREAM_TIMEOUT_EVENT *ev;
1581
1582 if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
1583 return A_EINVAL;
1584 }
1585
1586 A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG));
1587
1588 ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
1589
1590 /* When the pstream (fat pipe == AC) timesout, it means there were no
1591 * thinStreams within this pstream & it got implicitly created due to
1592 * data flow on this AC. We start the inactivity timer only for
1593 * implicitly created pstream. Just reset the host state.
1594 */
1595 /* Set the activeTsids for this AC to 0 */
1596 LOCK_WMI(wmip);
1597 wmip->wmi_streamExistsForAC[ev->trafficClass]=0;
1598 wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass);
1599 UNLOCK_WMI(wmip);
1600
1601 /*Indicate inactivity to driver layer for this fatpipe (pstream)*/
1602 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass);
1603
1604 return 0;
1605}
1606
1607static int
1608wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1609{
1610 WMI_BIT_RATE_REPLY *reply;
1611 s32 rate;
1612 u32 sgi,index;
1613 /* 54149:
1614 * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY.
1615 * since there is difference in the length and to avoid returning
1616 * error value.
1617 */
1618 if (len < sizeof(WMI_BIT_RATE_REPLY)) {
1619 return A_EINVAL;
1620 }
1621 reply = (WMI_BIT_RATE_REPLY *)datap;
1622 A_DPRINTF(DBG_WMI,
1623 (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex));
1624
1625 if (reply->rateIndex == (s8) RATE_AUTO) {
1626 rate = RATE_AUTO;
1627 } else {
1628 // the SGI state is stored as the MSb of the rateIndex
1629 index = reply->rateIndex & 0x7f;
1630 sgi = (reply->rateIndex & 0x80)? 1:0;
1631 rate = wmi_rateTable[index][sgi];
1632 }
1633
1634 A_WMI_BITRATE_RX(wmip->wmi_devt, rate);
1635 return 0;
1636}
1637
1638static int
1639wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1640{
1641 WMI_FIX_RATES_REPLY *reply;
1642
1643 if (len < sizeof(WMI_FIX_RATES_REPLY)) {
1644 return A_EINVAL;
1645 }
1646 reply = (WMI_FIX_RATES_REPLY *)datap;
1647 A_DPRINTF(DBG_WMI,
1648 (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask));
1649
1650 A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask);
1651
1652 return 0;
1653}
1654
1655static int
1656wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1657{
1658 WMI_CHANNEL_LIST_REPLY *reply;
1659
1660 if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
1661 return A_EINVAL;
1662 }
1663 reply = (WMI_CHANNEL_LIST_REPLY *)datap;
1664 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1665
1666 A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels,
1667 reply->channelList);
1668
1669 return 0;
1670}
1671
1672static int
1673wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1674{
1675 WMI_TX_PWR_REPLY *reply;
1676
1677 if (len < sizeof(*reply)) {
1678 return A_EINVAL;
1679 }
1680 reply = (WMI_TX_PWR_REPLY *)datap;
1681 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1682
1683 A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM);
1684
1685 return 0;
1686}
1687static int
1688wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1689{
1690 WMI_GET_KEEPALIVE_CMD *reply;
1691
1692 if (len < sizeof(*reply)) {
1693 return A_EINVAL;
1694 }
1695 reply = (WMI_GET_KEEPALIVE_CMD *)datap;
1696 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1697
1698 A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured);
1699
1700 return 0;
1701}
1702
1703
1704static int
1705wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, int len)
1706{
1707 WMIX_DSETOPENREQ_EVENT *dsetopenreq;
1708
1709 if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
1710 return A_EINVAL;
1711 }
1712 dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
1713 A_DPRINTF(DBG_WMI,
1714 (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id));
1715 A_WMI_DSET_OPEN_REQ(wmip->wmi_devt,
1716 dsetopenreq->dset_id,
1717 dsetopenreq->targ_dset_handle,
1718 dsetopenreq->targ_reply_fn,
1719 dsetopenreq->targ_reply_arg);
1720
1721 return 0;
1722}
1723
1724#ifdef CONFIG_HOST_DSET_SUPPORT
1725static int
1726wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len)
1727{
1728 WMIX_DSETCLOSE_EVENT *dsetclose;
1729
1730 if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
1731 return A_EINVAL;
1732 }
1733 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1734
1735 dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
1736 A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie);
1737
1738 return 0;
1739}
1740
1741static int
1742wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, int len)
1743{
1744 WMIX_DSETDATAREQ_EVENT *dsetdatareq;
1745
1746 if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
1747 return A_EINVAL;
1748 }
1749 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1750
1751 dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
1752 A_WMI_DSET_DATA_REQ(wmip->wmi_devt,
1753 dsetdatareq->access_cookie,
1754 dsetdatareq->offset,
1755 dsetdatareq->length,
1756 dsetdatareq->targ_buf,
1757 dsetdatareq->targ_reply_fn,
1758 dsetdatareq->targ_reply_arg);
1759
1760 return 0;
1761}
1762#endif /* CONFIG_HOST_DSET_SUPPORT */
1763
1764static int
1765wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, int len)
1766{
1767 WMI_SCAN_COMPLETE_EVENT *ev;
1768
1769 ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
1770 if ((int)ev->status == 0) {
1771 wlan_refresh_inactive_nodes(&wmip->wmi_scan_table);
1772 }
1773 A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (int) ev->status);
1774 is_probe_ssid = false;
1775
1776 return 0;
1777}
1778
1779/*
1780 * Target is reporting a programming error. This is for
1781 * developer aid only. Target only checks a few common violations
1782 * and it is responsibility of host to do all error checking.
1783 * Behavior of target after wmi error event is undefined.
1784 * A reset is recommended.
1785 */
1786static int
1787wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1788{
1789 WMI_CMD_ERROR_EVENT *ev;
1790
1791 ev = (WMI_CMD_ERROR_EVENT *)datap;
1792 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId));
1793 switch (ev->errorCode) {
1794 case (INVALID_PARAM):
1795 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n"));
1796 break;
1797 case (ILLEGAL_STATE):
1798 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n"));
1799 break;
1800 case (INTERNAL_ERROR):
1801 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n"));
1802 break;
1803 }
1804
1805 return 0;
1806}
1807
1808
1809static int
1810wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1811{
1812 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1813
1814 A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len);
1815
1816 return 0;
1817}
1818
1819static int
1820wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1821{
1822 WMI_RSSI_THRESHOLD_EVENT *reply;
1823 WMI_RSSI_THRESHOLD_VAL newThreshold;
1824 WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
1825 SQ_THRESHOLD_PARAMS *sq_thresh =
1826 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
1827 u8 upper_rssi_threshold, lower_rssi_threshold;
1828 s16 rssi;
1829
1830 if (len < sizeof(*reply)) {
1831 return A_EINVAL;
1832 }
1833 reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
1834 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1835 newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range;
1836 rssi = reply->rssi;
1837
1838 /*
1839 * Identify the threshold breached and communicate that to the app. After
1840 * that install a new set of thresholds based on the signal quality
1841 * reported by the target
1842 */
1843 if (newThreshold) {
1844 /* Upper threshold breached */
1845 if (rssi < sq_thresh->upper_threshold[0]) {
1846 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: "
1847 " %d\n", DBGARG, rssi));
1848 } else if ((rssi < sq_thresh->upper_threshold[1]) &&
1849 (rssi >= sq_thresh->upper_threshold[0]))
1850 {
1851 newThreshold = WMI_RSSI_THRESHOLD1_ABOVE;
1852 } else if ((rssi < sq_thresh->upper_threshold[2]) &&
1853 (rssi >= sq_thresh->upper_threshold[1]))
1854 {
1855 newThreshold = WMI_RSSI_THRESHOLD2_ABOVE;
1856 } else if ((rssi < sq_thresh->upper_threshold[3]) &&
1857 (rssi >= sq_thresh->upper_threshold[2]))
1858 {
1859 newThreshold = WMI_RSSI_THRESHOLD3_ABOVE;
1860 } else if ((rssi < sq_thresh->upper_threshold[4]) &&
1861 (rssi >= sq_thresh->upper_threshold[3]))
1862 {
1863 newThreshold = WMI_RSSI_THRESHOLD4_ABOVE;
1864 } else if ((rssi < sq_thresh->upper_threshold[5]) &&
1865 (rssi >= sq_thresh->upper_threshold[4]))
1866 {
1867 newThreshold = WMI_RSSI_THRESHOLD5_ABOVE;
1868 } else if (rssi >= sq_thresh->upper_threshold[5]) {
1869 newThreshold = WMI_RSSI_THRESHOLD6_ABOVE;
1870 }
1871 } else {
1872 /* Lower threshold breached */
1873 if (rssi > sq_thresh->lower_threshold[0]) {
1874 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: "
1875 "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0]));
1876 } else if ((rssi > sq_thresh->lower_threshold[1]) &&
1877 (rssi <= sq_thresh->lower_threshold[0]))
1878 {
1879 newThreshold = WMI_RSSI_THRESHOLD6_BELOW;
1880 } else if ((rssi > sq_thresh->lower_threshold[2]) &&
1881 (rssi <= sq_thresh->lower_threshold[1]))
1882 {
1883 newThreshold = WMI_RSSI_THRESHOLD5_BELOW;
1884 } else if ((rssi > sq_thresh->lower_threshold[3]) &&
1885 (rssi <= sq_thresh->lower_threshold[2]))
1886 {
1887 newThreshold = WMI_RSSI_THRESHOLD4_BELOW;
1888 } else if ((rssi > sq_thresh->lower_threshold[4]) &&
1889 (rssi <= sq_thresh->lower_threshold[3]))
1890 {
1891 newThreshold = WMI_RSSI_THRESHOLD3_BELOW;
1892 } else if ((rssi > sq_thresh->lower_threshold[5]) &&
1893 (rssi <= sq_thresh->lower_threshold[4]))
1894 {
1895 newThreshold = WMI_RSSI_THRESHOLD2_BELOW;
1896 } else if (rssi <= sq_thresh->lower_threshold[5]) {
1897 newThreshold = WMI_RSSI_THRESHOLD1_BELOW;
1898 }
1899 }
1900 /* Calculate and install the next set of thresholds */
1901 lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh,
1902 sq_thresh->lower_threshold_valid_count);
1903 upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh,
1904 sq_thresh->upper_threshold_valid_count);
1905 /* Issue a wmi command to install the thresholds */
1906 cmd.thresholdAbove1_Val = upper_rssi_threshold;
1907 cmd.thresholdBelow1_Val = lower_rssi_threshold;
1908 cmd.weight = sq_thresh->weight;
1909 cmd.pollTime = sq_thresh->polling_interval;
1910
1911 rssi_event_value = rssi;
1912
1913 if (wmi_send_rssi_threshold_params(wmip, &cmd) != 0) {
1914 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n",
1915 DBGARG));
1916 }
1917
1918 A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi);
1919
1920 return 0;
1921}
1922
1923
1924static int
1925wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1926{
1927 WMI_TARGET_ERROR_REPORT_EVENT *reply;
1928
1929 if (len < sizeof(*reply)) {
1930 return A_EINVAL;
1931 }
1932 reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
1933 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1934
1935 A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal);
1936
1937 return 0;
1938}
1939
1940static int
1941wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1942{
1943 WMI_CAC_EVENT *reply;
1944 WMM_TSPEC_IE *tspec_ie;
1945 u16 activeTsids;
1946
1947 if (len < sizeof(*reply)) {
1948 return A_EINVAL;
1949 }
1950 reply = (WMI_CAC_EVENT *)datap;
1951
1952 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1953
1954 if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
1955 (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) {
1956 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
1957
1958 wmi_delete_pstream_cmd(wmip, reply->ac,
1959 (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
1960 }
1961 else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
1962 u8 i;
1963
1964 /* following assumes that there is only one outstanding ADDTS request
1965 when this event is received */
1966 LOCK_WMI(wmip);
1967 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
1968 UNLOCK_WMI(wmip);
1969
1970 for (i = 0; i < sizeof(activeTsids) * 8; i++) {
1971 if ((activeTsids >> i) & 1) {
1972 break;
1973 }
1974 }
1975 if (i < (sizeof(activeTsids) * 8)) {
1976 wmi_delete_pstream_cmd(wmip, reply->ac, i);
1977 }
1978 }
1979 /*
1980 * Ev#72990: Clear active tsids and Add missing handling
1981 * for delete qos stream from AP
1982 */
1983 else if (reply->cac_indication == CAC_INDICATION_DELETE) {
1984 u8 tsid = 0;
1985
1986 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
1987 tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
1988 LOCK_WMI(wmip);
1989 wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid);
1990 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
1991 UNLOCK_WMI(wmip);
1992
1993
1994 /* Indicate stream inactivity to driver layer only if all tsids
1995 * within this AC are deleted.
1996 */
1997 if (!activeTsids) {
1998 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac);
1999 wmip->wmi_fatPipeExists &= ~(1 << reply->ac);
2000 }
2001 }
2002
2003 A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
2004 reply->cac_indication, reply->statusCode,
2005 reply->tspecSuggestion);
2006
2007 return 0;
2008}
2009
2010static int
2011wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2012{
2013 WMI_CHANNEL_CHANGE_EVENT *reply;
2014
2015 if (len < sizeof(*reply)) {
2016 return A_EINVAL;
2017 }
2018 reply = (WMI_CHANNEL_CHANGE_EVENT *)datap;
2019 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2020
2021 A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel,
2022 reply->newChannel);
2023
2024 return 0;
2025}
2026
2027static int
2028wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len)
2029{
2030 WMIX_HB_CHALLENGE_RESP_EVENT *reply;
2031
2032 if (len < sizeof(*reply)) {
2033 return A_EINVAL;
2034 }
2035 reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap;
2036 A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG));
2037
2038 A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source);
2039
2040 return 0;
2041}
2042
2043static int
2044wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2045{
2046 WMI_TARGET_ROAM_TBL *reply;
2047
2048 if (len < sizeof(*reply)) {
2049 return A_EINVAL;
2050 }
2051 reply = (WMI_TARGET_ROAM_TBL *)datap;
2052 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2053
2054 A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply);
2055
2056 return 0;
2057}
2058
2059static int
2060wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2061{
2062 WMI_TARGET_ROAM_DATA *reply;
2063
2064 if (len < sizeof(*reply)) {
2065 return A_EINVAL;
2066 }
2067 reply = (WMI_TARGET_ROAM_DATA *)datap;
2068 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2069
2070 A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply);
2071
2072 return 0;
2073}
2074
2075static int
2076wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2077{
2078 if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) {
2079 return A_EINVAL;
2080 }
2081 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2082
2083 A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt);
2084
2085 return 0;
2086}
2087
2088static int
2089wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2090{
2091 WMI_SNR_THRESHOLD_EVENT *reply;
2092 SQ_THRESHOLD_PARAMS *sq_thresh =
2093 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
2094 WMI_SNR_THRESHOLD_VAL newThreshold;
2095 WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
2096 u8 upper_snr_threshold, lower_snr_threshold;
2097 s16 snr;
2098
2099 if (len < sizeof(*reply)) {
2100 return A_EINVAL;
2101 }
2102 reply = (WMI_SNR_THRESHOLD_EVENT *)datap;
2103 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2104
2105 newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range;
2106 snr = reply->snr;
2107 /*
2108 * Identify the threshold breached and communicate that to the app. After
2109 * that install a new set of thresholds based on the signal quality
2110 * reported by the target
2111 */
2112 if (newThreshold) {
2113 /* Upper threshold breached */
2114 if (snr < sq_thresh->upper_threshold[0]) {
2115 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: "
2116 "%d\n", DBGARG, snr));
2117 } else if ((snr < sq_thresh->upper_threshold[1]) &&
2118 (snr >= sq_thresh->upper_threshold[0]))
2119 {
2120 newThreshold = WMI_SNR_THRESHOLD1_ABOVE;
2121 } else if ((snr < sq_thresh->upper_threshold[2]) &&
2122 (snr >= sq_thresh->upper_threshold[1]))
2123 {
2124 newThreshold = WMI_SNR_THRESHOLD2_ABOVE;
2125 } else if ((snr < sq_thresh->upper_threshold[3]) &&
2126 (snr >= sq_thresh->upper_threshold[2]))
2127 {
2128 newThreshold = WMI_SNR_THRESHOLD3_ABOVE;
2129 } else if (snr >= sq_thresh->upper_threshold[3]) {
2130 newThreshold = WMI_SNR_THRESHOLD4_ABOVE;
2131 }
2132 } else {
2133 /* Lower threshold breached */
2134 if (snr > sq_thresh->lower_threshold[0]) {
2135 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: "
2136 "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0]));
2137 } else if ((snr > sq_thresh->lower_threshold[1]) &&
2138 (snr <= sq_thresh->lower_threshold[0]))
2139 {
2140 newThreshold = WMI_SNR_THRESHOLD4_BELOW;
2141 } else if ((snr > sq_thresh->lower_threshold[2]) &&
2142 (snr <= sq_thresh->lower_threshold[1]))
2143 {
2144 newThreshold = WMI_SNR_THRESHOLD3_BELOW;
2145 } else if ((snr > sq_thresh->lower_threshold[3]) &&
2146 (snr <= sq_thresh->lower_threshold[2]))
2147 {
2148 newThreshold = WMI_SNR_THRESHOLD2_BELOW;
2149 } else if (snr <= sq_thresh->lower_threshold[3]) {
2150 newThreshold = WMI_SNR_THRESHOLD1_BELOW;
2151 }
2152 }
2153
2154 /* Calculate and install the next set of thresholds */
2155 lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh,
2156 sq_thresh->lower_threshold_valid_count);
2157 upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh,
2158 sq_thresh->upper_threshold_valid_count);
2159
2160 /* Issue a wmi command to install the thresholds */
2161 cmd.thresholdAbove1_Val = upper_snr_threshold;
2162 cmd.thresholdBelow1_Val = lower_snr_threshold;
2163 cmd.weight = sq_thresh->weight;
2164 cmd.pollTime = sq_thresh->polling_interval;
2165
2166 A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n"
2167 ,DBGARG, snr, newThreshold, lower_snr_threshold,
2168 upper_snr_threshold));
2169
2170 snr_event_value = snr;
2171
2172 if (wmi_send_snr_threshold_params(wmip, &cmd) != 0) {
2173 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n",
2174 DBGARG));
2175 }
2176 A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr);
2177
2178 return 0;
2179}
2180
2181static int
2182wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2183{
2184 WMI_LQ_THRESHOLD_EVENT *reply;
2185
2186 if (len < sizeof(*reply)) {
2187 return A_EINVAL;
2188 }
2189 reply = (WMI_LQ_THRESHOLD_EVENT *)datap;
2190 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2191
2192 A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt,
2193 (WMI_LQ_THRESHOLD_VAL) reply->range,
2194 reply->lq);
2195
2196 return 0;
2197}
2198
2199static int
2200wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2201{
2202 u16 ap_info_entry_size;
2203 WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap;
2204 WMI_AP_INFO_V1 *ap_info_v1;
2205 u8 i;
2206
2207 if (len < sizeof(WMI_APLIST_EVENT)) {
2208 return A_EINVAL;
2209 }
2210
2211 if (ev->apListVer == APLIST_VER1) {
2212 ap_info_entry_size = sizeof(WMI_AP_INFO_V1);
2213 ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList;
2214 } else {
2215 return A_EINVAL;
2216 }
2217
2218 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP));
2219 if (len < (int)(sizeof(WMI_APLIST_EVENT) +
2220 (ev->numAP - 1) * ap_info_entry_size))
2221 {
2222 return A_EINVAL;
2223 }
2224
2225 /*
2226 * AP List Ver1 Contents
2227 */
2228 for (i = 0; i < ev->numAP; i++) {
2229 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\
2230 "Channel %d\n", i,
2231 ap_info_v1->bssid[0], ap_info_v1->bssid[1],
2232 ap_info_v1->bssid[2], ap_info_v1->bssid[3],
2233 ap_info_v1->bssid[4], ap_info_v1->bssid[5],
2234 ap_info_v1->channel));
2235 ap_info_v1++;
2236 }
2237 return 0;
2238}
2239
2240static int
2241wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2242{
2243 u32 dropped;
2244
2245 dropped = *((u32 *)datap);
2246 datap += sizeof(dropped);
2247 len -= sizeof(dropped);
2248 A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (s8 *)datap, len);
2249 return 0;
2250}
2251
2252/*
2253 * Called to send a wmi command. Command specific data is already built
2254 * on osbuf and current osbuf->data points to it.
2255 */
2256int
2257wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
2258 WMI_SYNC_FLAG syncflag)
2259{
2260 int status;
2261#define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID))
2262 WMI_CMD_HDR *cHdr;
2263 HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id;
2264
2265 A_ASSERT(osbuf != NULL);
2266
2267 if (syncflag >= END_WMIFLAG) {
2268 A_NETBUF_FREE(osbuf);
2269 return A_EINVAL;
2270 }
2271
2272 if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2273 /*
2274 * We want to make sure all data currently queued is transmitted before
2275 * the cmd execution. Establish a new sync point.
2276 */
2277 wmi_sync_point(wmip);
2278 }
2279
2280 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
2281 A_NETBUF_FREE(osbuf);
2282 return A_NO_MEMORY;
2283 }
2284
2285 cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
2286 cHdr->commandId = (u16) cmdId;
2287 cHdr->info1 = 0; // added for virtual interface
2288
2289 /*
2290 * Only for OPT_TX_CMD, use BE endpoint.
2291 */
2292 if (IS_OPT_TX_CMD(cmdId)) {
2293 if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, false, false,0,NULL)) != 0) {
2294 A_NETBUF_FREE(osbuf);
2295 return status;
2296 }
2297 eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE);
2298 }
2299 A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid);
2300
2301 if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2302 /*
2303 * We want to make sure all new data queued waits for the command to
2304 * execute. Establish a new sync point.
2305 */
2306 wmi_sync_point(wmip);
2307 }
2308 return (0);
2309#undef IS_OPT_TX_CMD
2310}
2311
2312int
2313wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
2314 WMI_SYNC_FLAG syncflag)
2315{
2316 WMIX_CMD_HDR *cHdr;
2317
2318 if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
2319 A_NETBUF_FREE(osbuf);
2320 return A_NO_MEMORY;
2321 }
2322
2323 cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
2324 cHdr->commandId = (u32) cmdId;
2325
2326 return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
2327}
2328
2329int
2330wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
2331 DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
2332 CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen,
2333 CRYPTO_TYPE groupCrypto, u8 groupCryptoLen,
2334 int ssidLength, u8 *ssid,
2335 u8 *bssid, u16 channel, u32 ctrl_flags)
2336{
2337 void *osbuf;
2338 WMI_CONNECT_CMD *cc;
2339 wmip->wmi_traffic_class = 100;
2340
2341 if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
2342 return A_EINVAL;
2343 }
2344 if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
2345 return A_EINVAL;
2346 }
2347
2348 osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD));
2349 if (osbuf == NULL) {
2350 return A_NO_MEMORY;
2351 }
2352
2353 A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD));
2354
2355 cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2356 A_MEMZERO(cc, sizeof(*cc));
2357
2358 if (ssidLength)
2359 {
2360 memcpy(cc->ssid, ssid, ssidLength);
2361 }
2362
2363 cc->ssidLength = ssidLength;
2364 cc->networkType = netType;
2365 cc->dot11AuthMode = dot11AuthMode;
2366 cc->authMode = authMode;
2367 cc->pairwiseCryptoType = pairwiseCrypto;
2368 cc->pairwiseCryptoLen = pairwiseCryptoLen;
2369 cc->groupCryptoType = groupCrypto;
2370 cc->groupCryptoLen = groupCryptoLen;
2371 cc->channel = channel;
2372 cc->ctrl_flags = ctrl_flags;
2373
2374 if (bssid != NULL) {
2375 memcpy(cc->bssid, bssid, ATH_MAC_LEN);
2376 }
2377
2378 wmip->wmi_pair_crypto_type = pairwiseCrypto;
2379 wmip->wmi_grp_crypto_type = groupCrypto;
2380
2381 return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
2382}
2383
2384int
2385wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, u16 channel)
2386{
2387 void *osbuf;
2388 WMI_RECONNECT_CMD *cc;
2389 wmip->wmi_traffic_class = 100;
2390
2391 osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
2392 if (osbuf == NULL) {
2393 return A_NO_MEMORY;
2394 }
2395
2396 A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD));
2397
2398 cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2399 A_MEMZERO(cc, sizeof(*cc));
2400
2401 cc->channel = channel;
2402
2403 if (bssid != NULL) {
2404 memcpy(cc->bssid, bssid, ATH_MAC_LEN);
2405 }
2406
2407 return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
2408}
2409
2410int
2411wmi_disconnect_cmd(struct wmi_t *wmip)
2412{
2413 int status;
2414 wmip->wmi_traffic_class = 100;
2415
2416 /* Bug fix for 24817(elevator bug) - the disconnect command does not
2417 need to do a SYNC before.*/
2418 status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID);
2419
2420 return status;
2421}
2422
2423int
2424wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
2425 u32 forceFgScan, u32 isLegacy,
2426 u32 homeDwellTime, u32 forceScanInterval,
2427 s8 numChan, u16 *channelList)
2428{
2429 void *osbuf;
2430 WMI_START_SCAN_CMD *sc;
2431 s8 size;
2432
2433 size = sizeof (*sc);
2434
2435 if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
2436 return A_EINVAL;
2437 }
2438
2439 if (numChan) {
2440 if (numChan > WMI_MAX_CHANNELS) {
2441 return A_EINVAL;
2442 }
2443 size += sizeof(u16) * (numChan - 1);
2444 }
2445
2446 osbuf = A_NETBUF_ALLOC(size);
2447 if (osbuf == NULL) {
2448 return A_NO_MEMORY;
2449 }
2450
2451 A_NETBUF_PUT(osbuf, size);
2452
2453 sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf));
2454 sc->scanType = scanType;
2455 sc->forceFgScan = forceFgScan;
2456 sc->isLegacy = isLegacy;
2457 sc->homeDwellTime = homeDwellTime;
2458 sc->forceScanInterval = forceScanInterval;
2459 sc->numChannels = numChan;
2460 if (numChan) {
2461 memcpy(sc->channelList, channelList, numChan * sizeof(u16));
2462 }
2463
2464 return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
2465}
2466
2467int
2468wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec,
2469 u16 fg_end_sec, u16 bg_sec,
2470 u16 minact_chdw_msec, u16 maxact_chdw_msec,
2471 u16 pas_chdw_msec,
2472 u8 shScanRatio, u8 scanCtrlFlags,
2473 u32 max_dfsch_act_time, u16 maxact_scan_per_ssid)
2474{
2475 void *osbuf;
2476 WMI_SCAN_PARAMS_CMD *sc;
2477
2478 osbuf = A_NETBUF_ALLOC(sizeof(*sc));
2479 if (osbuf == NULL) {
2480 return A_NO_MEMORY;
2481 }
2482
2483 A_NETBUF_PUT(osbuf, sizeof(*sc));
2484
2485 sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2486 A_MEMZERO(sc, sizeof(*sc));
2487 sc->fg_start_period = fg_start_sec;
2488 sc->fg_end_period = fg_end_sec;
2489 sc->bg_period = bg_sec;
2490 sc->minact_chdwell_time = minact_chdw_msec;
2491 sc->maxact_chdwell_time = maxact_chdw_msec;
2492 sc->pas_chdwell_time = pas_chdw_msec;
2493 sc->shortScanRatio = shScanRatio;
2494 sc->scanCtrlFlags = scanCtrlFlags;
2495 sc->max_dfsch_act_time = max_dfsch_act_time;
2496 sc->maxact_scan_per_ssid = maxact_scan_per_ssid;
2497
2498 return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
2499 NO_SYNC_WMIFLAG));
2500}
2501
2502int
2503wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask)
2504{
2505 void *osbuf;
2506 WMI_BSS_FILTER_CMD *cmd;
2507
2508 if (filter >= LAST_BSS_FILTER) {
2509 return A_EINVAL;
2510 }
2511
2512 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2513 if (osbuf == NULL) {
2514 return A_NO_MEMORY;
2515 }
2516
2517 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2518
2519 cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
2520 A_MEMZERO(cmd, sizeof(*cmd));
2521 cmd->bssFilter = filter;
2522 cmd->ieMask = ieMask;
2523
2524 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
2525 NO_SYNC_WMIFLAG));
2526}
2527
2528int
2529wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag,
2530 u8 ssidLength, u8 *ssid)
2531{
2532 void *osbuf;
2533 WMI_PROBED_SSID_CMD *cmd;
2534
2535 if (index > MAX_PROBED_SSID_INDEX) {
2536 return A_EINVAL;
2537 }
2538 if (ssidLength > sizeof(cmd->ssid)) {
2539 return A_EINVAL;
2540 }
2541 if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
2542 return A_EINVAL;
2543 }
2544 if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
2545 return A_EINVAL;
2546 }
2547
2548 if (flag & SPECIFIC_SSID_FLAG) {
2549 is_probe_ssid = true;
2550 }
2551
2552 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2553 if (osbuf == NULL) {
2554 return A_NO_MEMORY;
2555 }
2556
2557 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2558
2559 cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf));
2560 A_MEMZERO(cmd, sizeof(*cmd));
2561 cmd->entryIndex = index;
2562 cmd->flag = flag;
2563 cmd->ssidLength = ssidLength;
2564 memcpy(cmd->ssid, ssid, ssidLength);
2565
2566 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
2567 NO_SYNC_WMIFLAG));
2568}
2569
2570int
2571wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons)
2572{
2573 void *osbuf;
2574 WMI_LISTEN_INT_CMD *cmd;
2575
2576 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2577 if (osbuf == NULL) {
2578 return A_NO_MEMORY;
2579 }
2580
2581 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2582
2583 cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf));
2584 A_MEMZERO(cmd, sizeof(*cmd));
2585 cmd->listenInterval = listenInterval;
2586 cmd->numBeacons = listenBeacons;
2587
2588 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
2589 NO_SYNC_WMIFLAG));
2590}
2591
2592int
2593wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmissTime, u16 bmissBeacons)
2594{
2595 void *osbuf;
2596 WMI_BMISS_TIME_CMD *cmd;
2597
2598 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2599 if (osbuf == NULL) {
2600 return A_NO_MEMORY;
2601 }
2602
2603 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2604
2605 cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf));
2606 A_MEMZERO(cmd, sizeof(*cmd));
2607 cmd->bmissTime = bmissTime;
2608 cmd->numBeacons = bmissBeacons;
2609
2610 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
2611 NO_SYNC_WMIFLAG));
2612}
2613
2614int
2615wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType,
2616 u8 ieLen, u8 *ieInfo)
2617{
2618 void *osbuf;
2619 WMI_SET_ASSOC_INFO_CMD *cmd;
2620 u16 cmdLen;
2621
2622 cmdLen = sizeof(*cmd) + ieLen - 1;
2623 osbuf = A_NETBUF_ALLOC(cmdLen);
2624 if (osbuf == NULL) {
2625 return A_NO_MEMORY;
2626 }
2627
2628 A_NETBUF_PUT(osbuf, cmdLen);
2629
2630 cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf));
2631 A_MEMZERO(cmd, cmdLen);
2632 cmd->ieType = ieType;
2633 cmd->bufferSize = ieLen;
2634 memcpy(cmd->assocInfo, ieInfo, ieLen);
2635
2636 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
2637 NO_SYNC_WMIFLAG));
2638}
2639
2640int
2641wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode)
2642{
2643 void *osbuf;
2644 WMI_POWER_MODE_CMD *cmd;
2645
2646 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2647 if (osbuf == NULL) {
2648 return A_NO_MEMORY;
2649 }
2650
2651 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2652
2653 cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf));
2654 A_MEMZERO(cmd, sizeof(*cmd));
2655 cmd->powerMode = powerMode;
2656 wmip->wmi_powerMode = powerMode;
2657
2658 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
2659 NO_SYNC_WMIFLAG));
2660}
2661
2662int
2663wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl,
2664 u16 atim_windows, u16 timeout_value)
2665{
2666 void *osbuf;
2667 WMI_IBSS_PM_CAPS_CMD *cmd;
2668
2669 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2670 if (osbuf == NULL) {
2671 return A_NO_MEMORY;
2672 }
2673
2674 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2675
2676 cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf));
2677 A_MEMZERO(cmd, sizeof(*cmd));
2678 cmd->power_saving = pmEnable;
2679 cmd->ttl = ttl;
2680 cmd->atim_windows = atim_windows;
2681 cmd->timeout_value = timeout_value;
2682
2683 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
2684 NO_SYNC_WMIFLAG));
2685}
2686
2687int
2688wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time,
2689 u32 ps_period, u8 sleep_period)
2690{
2691 void *osbuf;
2692 WMI_AP_PS_CMD *cmd;
2693
2694 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2695 if (osbuf == NULL) {
2696 return A_NO_MEMORY;
2697 }
2698
2699 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2700
2701 cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf));
2702 A_MEMZERO(cmd, sizeof(*cmd));
2703 cmd->psType = psType;
2704 cmd->idle_time = idle_time;
2705 cmd->ps_period = ps_period;
2706 cmd->sleep_period = sleep_period;
2707
2708 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID,
2709 NO_SYNC_WMIFLAG));
2710}
2711
2712int
2713wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod,
2714 u16 psPollNum, u16 dtimPolicy,
2715 u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
2716 u16 ps_fail_event_policy)
2717{
2718 void *osbuf;
2719 WMI_POWER_PARAMS_CMD *pm;
2720
2721 osbuf = A_NETBUF_ALLOC(sizeof(*pm));
2722 if (osbuf == NULL) {
2723 return A_NO_MEMORY;
2724 }
2725
2726 A_NETBUF_PUT(osbuf, sizeof(*pm));
2727
2728 pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2729 A_MEMZERO(pm, sizeof(*pm));
2730 pm->idle_period = idlePeriod;
2731 pm->pspoll_number = psPollNum;
2732 pm->dtim_policy = dtimPolicy;
2733 pm->tx_wakeup_policy = tx_wakeup_policy;
2734 pm->num_tx_to_wakeup = num_tx_to_wakeup;
2735 pm->ps_fail_event_policy = ps_fail_event_policy;
2736
2737 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
2738 NO_SYNC_WMIFLAG));
2739}
2740
2741int
2742wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout)
2743{
2744 void *osbuf;
2745 WMI_DISC_TIMEOUT_CMD *cmd;
2746
2747 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2748 if (osbuf == NULL) {
2749 return A_NO_MEMORY;
2750 }
2751
2752 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2753
2754 cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf));
2755 A_MEMZERO(cmd, sizeof(*cmd));
2756 cmd->disconnectTimeout = timeout;
2757
2758 return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
2759 NO_SYNC_WMIFLAG));
2760}
2761
2762int
2763wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, CRYPTO_TYPE keyType,
2764 u8 keyUsage, u8 keyLength, u8 *keyRSC,
2765 u8 *keyMaterial, u8 key_op_ctrl, u8 *macAddr,
2766 WMI_SYNC_FLAG sync_flag)
2767{
2768 void *osbuf;
2769 WMI_ADD_CIPHER_KEY_CMD *cmd;
2770
2771 if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
2772 (keyMaterial == NULL))
2773 {
2774 return A_EINVAL;
2775 }
2776
2777 if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
2778 return A_EINVAL;
2779 }
2780
2781 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2782 if (osbuf == NULL) {
2783 return A_NO_MEMORY;
2784 }
2785
2786 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2787
2788 cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2789 A_MEMZERO(cmd, sizeof(*cmd));
2790 cmd->keyIndex = keyIndex;
2791 cmd->keyType = keyType;
2792 cmd->keyUsage = keyUsage;
2793 cmd->keyLength = keyLength;
2794 memcpy(cmd->key, keyMaterial, keyLength);
2795#ifdef WAPI_ENABLE
2796 if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) {
2797#else
2798 if (NULL != keyRSC) {
2799#endif // WAPI_ENABLE
2800 memcpy(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
2801 }
2802 cmd->key_op_ctrl = key_op_ctrl;
2803
2804 if(macAddr) {
2805 memcpy(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN);
2806 }
2807
2808 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
2809}
2810
2811int
2812wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk)
2813{
2814 void *osbuf;
2815 WMI_ADD_KRK_CMD *cmd;
2816
2817 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2818 if (osbuf == NULL) {
2819 return A_NO_MEMORY;
2820 }
2821
2822 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2823
2824 cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf));
2825 A_MEMZERO(cmd, sizeof(*cmd));
2826 memcpy(cmd->krk, krk, WMI_KRK_LEN);
2827
2828 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
2829}
2830
2831int
2832wmi_delete_krk_cmd(struct wmi_t *wmip)
2833{
2834 return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID);
2835}
2836
2837int
2838wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex)
2839{
2840 void *osbuf;
2841 WMI_DELETE_CIPHER_KEY_CMD *cmd;
2842
2843 if (keyIndex > WMI_MAX_KEY_INDEX) {
2844 return A_EINVAL;
2845 }
2846
2847 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2848 if (osbuf == NULL) {
2849 return A_NO_MEMORY;
2850 }
2851
2852 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2853
2854 cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2855 A_MEMZERO(cmd, sizeof(*cmd));
2856 cmd->keyIndex = keyIndex;
2857
2858 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
2859 NO_SYNC_WMIFLAG));
2860}
2861
2862int
2863wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId,
2864 bool set)
2865{
2866 void *osbuf;
2867 WMI_SET_PMKID_CMD *cmd;
2868
2869 if (bssid == NULL) {
2870 return A_EINVAL;
2871 }
2872
2873 if ((set == true) && (pmkId == NULL)) {
2874 return A_EINVAL;
2875 }
2876
2877 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2878 if (osbuf == NULL) {
2879 return A_NO_MEMORY;
2880 }
2881
2882 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2883
2884 cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf));
2885 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
2886 if (set == true) {
2887 memcpy(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
2888 cmd->enable = PMKID_ENABLE;
2889 } else {
2890 A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
2891 cmd->enable = PMKID_DISABLE;
2892 }
2893
2894 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
2895}
2896
2897int
2898wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en)
2899{
2900 void *osbuf;
2901 WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
2902
2903 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2904 if (osbuf == NULL) {
2905 return A_NO_MEMORY;
2906 }
2907
2908 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2909
2910 cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf));
2911 cmd->cm_en = (en == true)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
2912
2913 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
2914 NO_SYNC_WMIFLAG));
2915}
2916
2917int
2918wmi_set_akmp_params_cmd(struct wmi_t *wmip,
2919 WMI_SET_AKMP_PARAMS_CMD *akmpParams)
2920{
2921 void *osbuf;
2922 WMI_SET_AKMP_PARAMS_CMD *cmd;
2923
2924 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2925 if (osbuf == NULL) {
2926 return A_NO_MEMORY;
2927 }
2928
2929 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2930 cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2931 cmd->akmpInfo = akmpParams->akmpInfo;
2932
2933 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID,
2934 NO_SYNC_WMIFLAG));
2935}
2936
2937int
2938wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
2939 WMI_SET_PMKID_LIST_CMD *pmkInfo)
2940{
2941 void *osbuf;
2942 WMI_SET_PMKID_LIST_CMD *cmd;
2943 u16 cmdLen;
2944 u8 i;
2945
2946 cmdLen = sizeof(pmkInfo->numPMKID) +
2947 pmkInfo->numPMKID * sizeof(WMI_PMKID);
2948
2949 osbuf = A_NETBUF_ALLOC(cmdLen);
2950 if (osbuf == NULL) {
2951 return A_NO_MEMORY;
2952 }
2953
2954 A_NETBUF_PUT(osbuf, cmdLen);
2955 cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf));
2956 cmd->numPMKID = pmkInfo->numPMKID;
2957
2958 for (i = 0; i < cmd->numPMKID; i++) {
2959 memcpy(&cmd->pmkidList[i], &pmkInfo->pmkidList[i],
2960 WMI_PMKID_LEN);
2961 }
2962
2963 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID,
2964 NO_SYNC_WMIFLAG));
2965}
2966
2967int
2968wmi_get_pmkid_list_cmd(struct wmi_t *wmip)
2969{
2970 return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID);
2971}
2972
2973int
2974wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid)
2975{
2976 WMI_DATA_HDR *dtHdr;
2977
2978 A_ASSERT( eid != wmip->wmi_endpoint_id);
2979 A_ASSERT(osbuf != NULL);
2980
2981 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
2982 return A_NO_MEMORY;
2983 }
2984
2985 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
2986 dtHdr->info =
2987 (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
2988
2989 dtHdr->info3 = 0;
2990 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid));
2991
2992 return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid));
2993}
2994
2995typedef struct _WMI_DATA_SYNC_BUFS {
2996 u8 trafficClass;
2997 void *osbuf;
2998}WMI_DATA_SYNC_BUFS;
2999
3000static int
3001wmi_sync_point(struct wmi_t *wmip)
3002{
3003 void *cmd_osbuf;
3004 WMI_SYNC_CMD *cmd;
3005 WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
3006 u8 i,numPriStreams=0;
3007 int status = 0;
3008
3009 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
3010
3011 memset(dataSyncBufs,0,sizeof(dataSyncBufs));
3012
3013 /* lock out while we walk through the priority list and assemble our local array */
3014 LOCK_WMI(wmip);
3015
3016 for (i=0; i < WMM_NUM_AC ; i++) {
3017 if (wmip->wmi_fatPipeExists & (1 << i)) {
3018 numPriStreams++;
3019 dataSyncBufs[numPriStreams-1].trafficClass = i;
3020 }
3021 }
3022
3023 UNLOCK_WMI(wmip);
3024
3025 /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */
3026
3027 do {
3028 /*
3029 * We allocate all network buffers needed so we will be able to
3030 * send all required frames.
3031 */
3032 cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3033 if (cmd_osbuf == NULL) {
3034 status = A_NO_MEMORY;
3035 break;
3036 }
3037
3038 A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd));
3039
3040 cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf));
3041 A_MEMZERO(cmd, sizeof(*cmd));
3042
3043 /* In the SYNC cmd sent on the control Ep, send a bitmap of the data
3044 * eps on which the Data Sync will be sent
3045 */
3046 cmd->dataSyncMap = wmip->wmi_fatPipeExists;
3047
3048 for (i=0; i < numPriStreams ; i++) {
3049 dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0);
3050 if (dataSyncBufs[i].osbuf == NULL) {
3051 status = A_NO_MEMORY;
3052 break;
3053 }
3054 } //end for
3055
3056 /* if Buffer allocation for any of the dataSync fails, then do not
3057 * send the Synchronize cmd on the control ep
3058 */
3059 if (status) {
3060 break;
3061 }
3062
3063 /*
3064 * Send sync cmd followed by sync data messages on all endpoints being
3065 * used
3066 */
3067 status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
3068 NO_SYNC_WMIFLAG);
3069
3070 if (status) {
3071 break;
3072 }
3073 /* cmd buffer sent, we no longer own it */
3074 cmd_osbuf = NULL;
3075
3076 for(i=0; i < numPriStreams; i++) {
3077 A_ASSERT(dataSyncBufs[i].osbuf != NULL);
3078 status = wmi_dataSync_send(wmip,
3079 dataSyncBufs[i].osbuf,
3080 A_WMI_Ac2EndpointID(wmip->wmi_devt,
3081 dataSyncBufs[i].
3082 trafficClass)
3083 );
3084
3085 if (status) {
3086 break;
3087 }
3088 /* we don't own this buffer anymore, NULL it out of the array so it
3089 * won't get cleaned up */
3090 dataSyncBufs[i].osbuf = NULL;
3091 } //end for
3092
3093 } while(false);
3094
3095 /* free up any resources left over (possibly due to an error) */
3096
3097 if (cmd_osbuf != NULL) {
3098 A_NETBUF_FREE(cmd_osbuf);
3099 }
3100
3101 for (i = 0; i < numPriStreams; i++) {
3102 if (dataSyncBufs[i].osbuf != NULL) {
3103 A_NETBUF_FREE(dataSyncBufs[i].osbuf);
3104 }
3105 }
3106
3107 return (status);
3108}
3109
3110int
3111wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
3112{
3113 void *osbuf;
3114 WMI_CREATE_PSTREAM_CMD *cmd;
3115 u8 fatPipeExistsForAC=0;
3116 s32 minimalPHY = 0;
3117 s32 nominalPHY = 0;
3118
3119 /* Validate all the parameters. */
3120 if( !((params->userPriority < 8) &&
3121 (params->userPriority <= 0x7) &&
3122 (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass) &&
3123 (params->trafficDirection == UPLINK_TRAFFIC ||
3124 params->trafficDirection == DNLINK_TRAFFIC ||
3125 params->trafficDirection == BIDIR_TRAFFIC) &&
3126 (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
3127 params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
3128 (params->voicePSCapability == DISABLE_FOR_THIS_AC ||
3129 params->voicePSCapability == ENABLE_FOR_THIS_AC ||
3130 params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
3131 (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) )
3132 {
3133 return A_EINVAL;
3134 }
3135
3136 //
3137 // check nominal PHY rate is >= minimalPHY, so that DUT
3138 // can allow TSRS IE
3139 //
3140
3141 // get the physical rate
3142 minimalPHY = ((params->minPhyRate / 1000)/1000); // unit of bps
3143
3144 // check minimal phy < nominal phy rate
3145 //
3146 if (params->nominalPHY >= minimalPHY)
3147 {
3148 nominalPHY = (params->nominalPHY * 1000)/500; // unit of 500 kbps
3149 A_DPRINTF(DBG_WMI,
3150 (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DBGARG,
3151 minimalPHY, nominalPHY));
3152
3153 params->nominalPHY = nominalPHY;
3154 }
3155 else
3156 {
3157 params->nominalPHY = 0;
3158 }
3159
3160 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3161 if (osbuf == NULL) {
3162 return A_NO_MEMORY;
3163 }
3164
3165 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3166
3167 A_DPRINTF(DBG_WMI,
3168 (DBGFMT "Sending create_pstream_cmd: ac=%d tsid:%d\n", DBGARG,
3169 params->trafficClass, params->tsid));
3170
3171 cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3172 A_MEMZERO(cmd, sizeof(*cmd));
3173 memcpy(cmd, params, sizeof(*cmd));
3174
3175 /* this is an implicitly created Fat pipe */
3176 if ((u32)params->tsid == (u32)WMI_IMPLICIT_PSTREAM) {
3177 LOCK_WMI(wmip);
3178 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3179 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3180 UNLOCK_WMI(wmip);
3181 } else {
3182 /* this is an explicitly created thin stream within a fat pipe */
3183 LOCK_WMI(wmip);
3184 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3185 wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid);
3186 /* if a thinstream becomes active, the fat pipe automatically
3187 * becomes active
3188 */
3189 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3190 UNLOCK_WMI(wmip);
3191 }
3192
3193 /* Indicate activty change to driver layer only if this is the
3194 * first TSID to get created in this AC explicitly or an implicit
3195 * fat pipe is getting created.
3196 */
3197 if (!fatPipeExistsForAC) {
3198 A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass);
3199 }
3200
3201 /* mike: should be SYNC_BEFORE_WMIFLAG */
3202 return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
3203 NO_SYNC_WMIFLAG));
3204}
3205
3206int
3207wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 tsid)
3208{
3209 void *osbuf;
3210 WMI_DELETE_PSTREAM_CMD *cmd;
3211 int status;
3212 u16 activeTsids=0;
3213
3214 /* validate the parameters */
3215 if (trafficClass > 3) {
3216 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, trafficClass));
3217 return A_EINVAL;
3218 }
3219
3220 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3221 if (osbuf == NULL) {
3222 return A_NO_MEMORY;
3223 }
3224
3225 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3226
3227 cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3228 A_MEMZERO(cmd, sizeof(*cmd));
3229
3230 cmd->trafficClass = trafficClass;
3231 cmd->tsid = tsid;
3232
3233 LOCK_WMI(wmip);
3234 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3235 UNLOCK_WMI(wmip);
3236
3237 /* Check if the tsid was created & exists */
3238 if (!(activeTsids & (1<<tsid))) {
3239
3240 A_NETBUF_FREE(osbuf);
3241 A_DPRINTF(DBG_WMI,
3242 (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass));
3243 /* TODO: return a more appropriate err code */
3244 return A_ERROR;
3245 }
3246
3247 A_DPRINTF(DBG_WMI,
3248 (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid));
3249
3250 status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
3251 SYNC_BEFORE_WMIFLAG));
3252
3253 LOCK_WMI(wmip);
3254 wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid);
3255 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3256 UNLOCK_WMI(wmip);
3257
3258
3259 /* Indicate stream inactivity to driver layer only if all tsids
3260 * within this AC are deleted.
3261 */
3262 if(!activeTsids) {
3263 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass);
3264 wmip->wmi_fatPipeExists &= ~(1<<trafficClass);
3265 }
3266
3267 return status;
3268}
3269
3270int
3271wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask)
3272{
3273 void *osbuf;
3274 WMI_FRAME_RATES_CMD *cmd;
3275 u8 frameType;
3276
3277 A_DPRINTF(DBG_WMI,
3278 (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask));
3279
3280 if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) ||
3281 (subType > 15)){
3282
3283 return A_EINVAL;
3284 }
3285
3286 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3287 if (osbuf == NULL) {
3288 return A_NO_MEMORY;
3289 }
3290
3291 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3292
3293 cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3294 A_MEMZERO(cmd, sizeof(*cmd));
3295
3296 frameType = (u8)((subType << 4) | type);
3297
3298 cmd->bEnableMask = bEnable;
3299 cmd->frameType = frameType;
3300 cmd->frameRateMask = rateMask;
3301
3302 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG));
3303}
3304
3305/*
3306 * used to set the bit rate. rate is in Kbps. If rate == -1
3307 * then auto selection is used.
3308 */
3309int
3310wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate)
3311{
3312 void *osbuf;
3313 WMI_BIT_RATE_CMD *cmd;
3314 s8 drix, mrix, crix, ret_val;
3315
3316 if (dataRate != -1) {
3317 ret_val = wmi_validate_bitrate(wmip, dataRate, &drix);
3318 if(ret_val == A_EINVAL){
3319 return A_EINVAL;
3320 }
3321 } else {
3322 drix = -1;
3323 }
3324
3325 if (mgmtRate != -1) {
3326 ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix);
3327 if(ret_val == A_EINVAL){
3328 return A_EINVAL;
3329 }
3330 } else {
3331 mrix = -1;
3332 }
3333 if (ctlRate != -1) {
3334 ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix);
3335 if(ret_val == A_EINVAL){
3336 return A_EINVAL;
3337 }
3338 } else {
3339 crix = -1;
3340 }
3341 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3342 if (osbuf == NULL) {
3343 return A_NO_MEMORY;
3344 }
3345
3346 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3347
3348 cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf));
3349 A_MEMZERO(cmd, sizeof(*cmd));
3350
3351 cmd->rateIndex = drix;
3352 cmd->mgmtRateIndex = mrix;
3353 cmd->ctlRateIndex = crix;
3354
3355
3356 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
3357}
3358
3359int
3360wmi_get_bitrate_cmd(struct wmi_t *wmip)
3361{
3362 return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID);
3363}
3364
3365/*
3366 * Returns true iff the given rate index is legal in the current PHY mode.
3367 */
3368bool
3369wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex)
3370{
3371 WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode;
3372 bool isValid = true;
3373 switch(phyMode) {
3374 case WMI_11A_MODE:
3375 if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){
3376 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3377 isValid = false;
3378 }
3379 } else {
3380 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) {
3381 isValid = false;
3382 }
3383 }
3384 break;
3385
3386 case WMI_11B_MODE:
3387 if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) {
3388 isValid = false;
3389 }
3390 break;
3391
3392 case WMI_11GONLY_MODE:
3393 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3394 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3395 isValid = false;
3396 }
3397 } else {
3398 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) {
3399 isValid = false;
3400 }
3401 }
3402 break;
3403
3404 case WMI_11G_MODE:
3405 case WMI_11AG_MODE:
3406 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3407 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3408 isValid = false;
3409 }
3410 } else {
3411 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) {
3412 isValid = false;
3413 }
3414 }
3415 break;
3416 default:
3417 A_ASSERT(false);
3418 break;
3419 }
3420
3421 return isValid;
3422}
3423
3424s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx)
3425{
3426 s8 i;
3427
3428 for (i=0;;i++)
3429 {
3430 if (wmi_rateTable[(u32) i][0] == 0) {
3431 return A_EINVAL;
3432 }
3433 if (wmi_rateTable[(u32) i][0] == rate) {
3434 break;
3435 }
3436 }
3437
3438 if(wmi_is_bitrate_index_valid(wmip, (s32) i) != true) {
3439 return A_EINVAL;
3440 }
3441
3442 *rate_idx = i;
3443 return 0;
3444}
3445
3446int
3447wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask)
3448{
3449 void *osbuf;
3450 WMI_FIX_RATES_CMD *cmd;
3451#if 0
3452 s32 rateIndex;
3453/* This check does not work for AR6003 as the HT modes are enabled only when
3454 * the STA is connected to a HT_BSS and is not based only on channel. It is
3455 * safe to skip this check however because rate control will only use rates
3456 * that are permitted by the valid rate mask and the fix rate mask. Meaning
3457 * the fix rate mask is not sufficient by itself to cause an invalid rate
3458 * to be used. */
3459 /* Make sure all rates in the mask are valid in the current PHY mode */
3460 for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
3461 if((1 << rateIndex) & (u32)fixRatesMask) {
3462 if(wmi_is_bitrate_index_valid(wmip, rateIndex) != true) {
3463 A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
3464 return A_EINVAL;
3465 }
3466 }
3467 }
3468#endif
3469
3470
3471 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3472 if (osbuf == NULL) {
3473 return A_NO_MEMORY;
3474 }
3475
3476 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3477
3478 cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3479 A_MEMZERO(cmd, sizeof(*cmd));
3480
3481 cmd->fixRateMask = fixRatesMask;
3482
3483 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
3484}
3485
3486int
3487wmi_get_ratemask_cmd(struct wmi_t *wmip)
3488{
3489 return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID);
3490}
3491
3492int
3493wmi_get_channelList_cmd(struct wmi_t *wmip)
3494{
3495 return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID);
3496}
3497
3498/*
3499 * used to generate a wmi sey channel Parameters cmd.
3500 * mode should always be specified and corresponds to the phy mode of the
3501 * wlan.
3502 * numChan should alway sbe specified. If zero indicates that all available
3503 * channels should be used.
3504 * channelList is an array of channel frequencies (in Mhz) which the radio
3505 * should limit its operation to. It should be NULL if numChan == 0. Size of
3506 * array should correspond to numChan entries.
3507 */
3508int
3509wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam,
3510 WMI_PHY_MODE mode, s8 numChan,
3511 u16 *channelList)
3512{
3513 void *osbuf;
3514 WMI_CHANNEL_PARAMS_CMD *cmd;
3515 s8 size;
3516
3517 size = sizeof (*cmd);
3518
3519 if (numChan) {
3520 if (numChan > WMI_MAX_CHANNELS) {
3521 return A_EINVAL;
3522 }
3523 size += sizeof(u16) * (numChan - 1);
3524 }
3525
3526 osbuf = A_NETBUF_ALLOC(size);
3527 if (osbuf == NULL) {
3528 return A_NO_MEMORY;
3529 }
3530
3531 A_NETBUF_PUT(osbuf, size);
3532
3533 cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3534 A_MEMZERO(cmd, size);
3535
3536 wmip->wmi_phyMode = mode;
3537 cmd->scanParam = scanParam;
3538 cmd->phyMode = mode;
3539 cmd->numChannels = numChan;
3540 memcpy(cmd->channelList, channelList, numChan * sizeof(u16));
3541
3542 return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
3543 NO_SYNC_WMIFLAG));
3544}
3545
3546void
3547wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3548{
3549 SQ_THRESHOLD_PARAMS *sq_thresh =
3550 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
3551 /*
3552 * Parse the command and store the threshold values here. The checks
3553 * for valid values can be put here
3554 */
3555 sq_thresh->weight = rssiCmd->weight;
3556 sq_thresh->polling_interval = rssiCmd->pollTime;
3557
3558 sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3559 sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3560 sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3561 sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3562 sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3563 sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3564 sq_thresh->upper_threshold_valid_count = 6;
3565
3566 /* List sorted in descending order */
3567 sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3568 sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3569 sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3570 sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3571 sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3572 sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3573 sq_thresh->lower_threshold_valid_count = 6;
3574
3575 if (!rssi_event_value) {
3576 /*
3577 * Configuring the thresholds to their extremes allows the host to get an
3578 * event from the target which is used for the configuring the correct
3579 * thresholds
3580 */
3581 rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0];
3582 rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0];
3583 } else {
3584 /*
3585 * In case the user issues multiple times of rssi_threshold_setting,
3586 * we should not use the extreames anymore, the target does not expect that.
3587 */
3588 rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh,
3589 sq_thresh->upper_threshold_valid_count);
3590 rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh,
3591 sq_thresh->lower_threshold_valid_count);
3592}
3593}
3594
3595int
3596wmi_set_rssi_threshold_params(struct wmi_t *wmip,
3597 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3598{
3599
3600 /* Check these values are in ascending order */
3601 if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
3602 rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
3603 rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
3604 rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
3605 rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
3606 rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
3607 rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
3608 rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
3609 rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
3610 rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val)
3611 {
3612 return A_EINVAL;
3613 }
3614
3615 wmi_cache_configure_rssithreshold(wmip, rssiCmd);
3616
3617 return (wmi_send_rssi_threshold_params(wmip, rssiCmd));
3618}
3619
3620int
3621wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd)
3622{
3623 void *osbuf;
3624 WMI_SET_IP_CMD *cmd;
3625
3626 /* Multicast address are not valid */
3627 if((*((u8 *)&ipCmd->ips[0]) >= 0xE0) ||
3628 (*((u8 *)&ipCmd->ips[1]) >= 0xE0)) {
3629 return A_EINVAL;
3630 }
3631
3632 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD));
3633 if (osbuf == NULL) {
3634 return A_NO_MEMORY;
3635 }
3636
3637 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD));
3638 cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf));
3639 memcpy(cmd, ipCmd, sizeof(WMI_SET_IP_CMD));
3640
3641 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID,
3642 NO_SYNC_WMIFLAG));
3643}
3644
3645int
3646wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
3647 WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
3648{
3649 void *osbuf;
3650 s8 size;
3651 WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
3652 u16 activeTsids=0;
3653 u8 streamExists=0;
3654 u8 i;
3655
3656 if( hostModeCmd->awake == hostModeCmd->asleep) {
3657 return A_EINVAL;
3658 }
3659
3660 size = sizeof (*cmd);
3661
3662 osbuf = A_NETBUF_ALLOC(size);
3663 if (osbuf == NULL) {
3664 return A_NO_MEMORY;
3665 }
3666
3667 A_NETBUF_PUT(osbuf, size);
3668
3669 cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3670 A_MEMZERO(cmd, size);
3671 memcpy(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
3672
3673 if(hostModeCmd->asleep) {
3674 /*
3675 * Relinquish credits from all implicitly created pstreams since when we
3676 * go to sleep. If user created explicit thinstreams exists with in a
3677 * fatpipe leave them intact for the user to delete
3678 */
3679 LOCK_WMI(wmip);
3680 streamExists = wmip->wmi_fatPipeExists;
3681 UNLOCK_WMI(wmip);
3682
3683 for(i=0;i< WMM_NUM_AC;i++) {
3684 if (streamExists & (1<<i)) {
3685 LOCK_WMI(wmip);
3686 activeTsids = wmip->wmi_streamExistsForAC[i];
3687 UNLOCK_WMI(wmip);
3688 /* If there are no user created thin streams delete the fatpipe */
3689 if(!activeTsids) {
3690 streamExists &= ~(1<<i);
3691 /*Indicate inactivity to drv layer for this fatpipe(pstream)*/
3692 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i);
3693 }
3694 }
3695 }
3696
3697 /* Update the fatpipes that exists*/
3698 LOCK_WMI(wmip);
3699 wmip->wmi_fatPipeExists = streamExists;
3700 UNLOCK_WMI(wmip);
3701 }
3702
3703 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
3704 NO_SYNC_WMIFLAG));
3705}
3706
3707int
3708wmi_set_wow_mode_cmd(struct wmi_t *wmip,
3709 WMI_SET_WOW_MODE_CMD *wowModeCmd)
3710{
3711 void *osbuf;
3712 s8 size;
3713 WMI_SET_WOW_MODE_CMD *cmd;
3714
3715 size = sizeof (*cmd);
3716
3717 osbuf = A_NETBUF_ALLOC(size);
3718 if (osbuf == NULL) {
3719 return A_NO_MEMORY;
3720 }
3721
3722 A_NETBUF_PUT(osbuf, size);
3723
3724 cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3725 A_MEMZERO(cmd, size);
3726 memcpy(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
3727
3728 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
3729 NO_SYNC_WMIFLAG));
3730
3731}
3732
3733int
3734wmi_get_wow_list_cmd(struct wmi_t *wmip,
3735 WMI_GET_WOW_LIST_CMD *wowListCmd)
3736{
3737 void *osbuf;
3738 s8 size;
3739 WMI_GET_WOW_LIST_CMD *cmd;
3740
3741 size = sizeof (*cmd);
3742
3743 osbuf = A_NETBUF_ALLOC(size);
3744 if (osbuf == NULL) {
3745 return A_NO_MEMORY;
3746 }
3747
3748 A_NETBUF_PUT(osbuf, size);
3749
3750 cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3751 A_MEMZERO(cmd, size);
3752 memcpy(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
3753
3754 return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
3755 NO_SYNC_WMIFLAG));
3756
3757}
3758
3759static int
3760wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len)
3761{
3762 WMI_GET_WOW_LIST_REPLY *reply;
3763
3764 if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
3765 return A_EINVAL;
3766 }
3767 reply = (WMI_GET_WOW_LIST_REPLY *)datap;
3768
3769 A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
3770 reply);
3771
3772 return 0;
3773}
3774
3775int wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
3776 WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
3777 u8 *pattern, u8 *mask,
3778 u8 pattern_size)
3779{
3780 void *osbuf;
3781 s8 size;
3782 WMI_ADD_WOW_PATTERN_CMD *cmd;
3783 u8 *filter_mask = NULL;
3784
3785 size = sizeof (*cmd);
3786
3787 size += ((2 * addWowCmd->filter_size)* sizeof(u8));
3788 osbuf = A_NETBUF_ALLOC(size);
3789 if (osbuf == NULL) {
3790 return A_NO_MEMORY;
3791 }
3792
3793 A_NETBUF_PUT(osbuf, size);
3794
3795 cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3796 cmd->filter_list_id = addWowCmd->filter_list_id;
3797 cmd->filter_offset = addWowCmd->filter_offset;
3798 cmd->filter_size = addWowCmd->filter_size;
3799
3800 memcpy(cmd->filter, pattern, addWowCmd->filter_size);
3801
3802 filter_mask = (u8 *)(cmd->filter + cmd->filter_size);
3803 memcpy(filter_mask, mask, addWowCmd->filter_size);
3804
3805
3806 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
3807 NO_SYNC_WMIFLAG));
3808}
3809
3810int
3811wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
3812 WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
3813{
3814 void *osbuf;
3815 s8 size;
3816 WMI_DEL_WOW_PATTERN_CMD *cmd;
3817
3818 size = sizeof (*cmd);
3819
3820 osbuf = A_NETBUF_ALLOC(size);
3821 if (osbuf == NULL) {
3822 return A_NO_MEMORY;
3823 }
3824
3825 A_NETBUF_PUT(osbuf, size);
3826
3827 cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3828 A_MEMZERO(cmd, size);
3829 memcpy(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
3830
3831 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
3832 NO_SYNC_WMIFLAG));
3833
3834}
3835
3836void
3837wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3838{
3839 SQ_THRESHOLD_PARAMS *sq_thresh =
3840 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
3841 /*
3842 * Parse the command and store the threshold values here. The checks
3843 * for valid values can be put here
3844 */
3845 sq_thresh->weight = snrCmd->weight;
3846 sq_thresh->polling_interval = snrCmd->pollTime;
3847
3848 sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val;
3849 sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val;
3850 sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val;
3851 sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val;
3852 sq_thresh->upper_threshold_valid_count = 4;
3853
3854 /* List sorted in descending order */
3855 sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val;
3856 sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val;
3857 sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val;
3858 sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val;
3859 sq_thresh->lower_threshold_valid_count = 4;
3860
3861 if (!snr_event_value) {
3862 /*
3863 * Configuring the thresholds to their extremes allows the host to get an
3864 * event from the target which is used for the configuring the correct
3865 * thresholds
3866 */
3867 snrCmd->thresholdAbove1_Val = (u8)sq_thresh->upper_threshold[0];
3868 snrCmd->thresholdBelow1_Val = (u8)sq_thresh->lower_threshold[0];
3869 } else {
3870 /*
3871 * In case the user issues multiple times of snr_threshold_setting,
3872 * we should not use the extreames anymore, the target does not expect that.
3873 */
3874 snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh,
3875 sq_thresh->upper_threshold_valid_count);
3876 snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh,
3877 sq_thresh->lower_threshold_valid_count);
3878 }
3879
3880}
3881int
3882wmi_set_snr_threshold_params(struct wmi_t *wmip,
3883 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3884{
3885 if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
3886 snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
3887 snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
3888 snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
3889 snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
3890 snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val)
3891 {
3892 return A_EINVAL;
3893 }
3894 wmi_cache_configure_snrthreshold(wmip, snrCmd);
3895 return (wmi_send_snr_threshold_params(wmip, snrCmd));
3896}
3897
3898int
3899wmi_clr_rssi_snr(struct wmi_t *wmip)
3900{
3901 void *osbuf;
3902
3903 osbuf = A_NETBUF_ALLOC(sizeof(int));
3904 if (osbuf == NULL) {
3905 return A_NO_MEMORY;
3906 }
3907
3908 return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
3909 NO_SYNC_WMIFLAG));
3910}
3911
3912int
3913wmi_set_lq_threshold_params(struct wmi_t *wmip,
3914 WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
3915{
3916 void *osbuf;
3917 s8 size;
3918 WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
3919 /* These values are in ascending order */
3920 if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
3921 lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
3922 lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
3923 lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
3924 lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
3925 lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
3926
3927 return A_EINVAL;
3928 }
3929
3930 size = sizeof (*cmd);
3931
3932 osbuf = A_NETBUF_ALLOC(size);
3933 if (osbuf == NULL) {
3934 return A_NO_MEMORY;
3935 }
3936
3937 A_NETBUF_PUT(osbuf, size);
3938
3939 cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3940 A_MEMZERO(cmd, size);
3941 memcpy(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
3942
3943 return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
3944 NO_SYNC_WMIFLAG));
3945}
3946
3947int
3948wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 mask)
3949{
3950 void *osbuf;
3951 s8 size;
3952 WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
3953
3954 size = sizeof (*cmd);
3955
3956 osbuf = A_NETBUF_ALLOC(size);
3957 if (osbuf == NULL) {
3958 return A_NO_MEMORY;
3959 }
3960
3961 A_NETBUF_PUT(osbuf, size);
3962
3963 cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
3964 A_MEMZERO(cmd, size);
3965
3966 cmd->bitmask = mask;
3967
3968 return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
3969 NO_SYNC_WMIFLAG));
3970}
3971
3972int
3973wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, u32 source)
3974{
3975 void *osbuf;
3976 WMIX_HB_CHALLENGE_RESP_CMD *cmd;
3977
3978 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3979 if (osbuf == NULL) {
3980 return A_NO_MEMORY;
3981 }
3982
3983 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3984
3985 cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
3986 cmd->cookie = cookie;
3987 cmd->source = source;
3988
3989 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
3990 NO_SYNC_WMIFLAG));
3991}
3992
3993int
3994wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask,
3995 u16 tsr, bool rep, u16 size,
3996 u32 valid)
3997{
3998 void *osbuf;
3999 WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
4000
4001 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4002 if (osbuf == NULL) {
4003 return A_NO_MEMORY;
4004 }
4005
4006 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4007
4008 cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
4009 cmd->config.cfgmmask = mmask;
4010 cmd->config.cfgtsr = tsr;
4011 cmd->config.cfgrep = rep;
4012 cmd->config.cfgsize = size;
4013 cmd->config.cfgvalid = valid;
4014
4015 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
4016 NO_SYNC_WMIFLAG));
4017}
4018
4019int
4020wmi_get_stats_cmd(struct wmi_t *wmip)
4021{
4022 return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID);
4023}
4024
4025int
4026wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid)
4027{
4028 void *osbuf;
4029 WMI_ADD_BAD_AP_CMD *cmd;
4030
4031 if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
4032 return A_EINVAL;
4033 }
4034
4035 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4036 if (osbuf == NULL) {
4037 return A_NO_MEMORY;
4038 }
4039
4040 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4041
4042 cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4043 cmd->badApIndex = apIndex;
4044 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
4045
4046 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG));
4047}
4048
4049int
4050wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex)
4051{
4052 void *osbuf;
4053 WMI_DELETE_BAD_AP_CMD *cmd;
4054
4055 if (apIndex > WMI_MAX_BAD_AP_INDEX) {
4056 return A_EINVAL;
4057 }
4058
4059 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4060 if (osbuf == NULL) {
4061 return A_NO_MEMORY;
4062 }
4063
4064 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4065
4066 cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4067 cmd->badApIndex = apIndex;
4068
4069 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
4070 NO_SYNC_WMIFLAG));
4071}
4072
4073int
4074wmi_abort_scan_cmd(struct wmi_t *wmip)
4075{
4076 return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID);
4077}
4078
4079int
4080wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM)
4081{
4082 void *osbuf;
4083 WMI_SET_TX_PWR_CMD *cmd;
4084
4085 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4086 if (osbuf == NULL) {
4087 return A_NO_MEMORY;
4088 }
4089
4090 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4091
4092 cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
4093 cmd->dbM = dbM;
4094
4095 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
4096}
4097
4098int
4099wmi_get_txPwr_cmd(struct wmi_t *wmip)
4100{
4101 return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID);
4102}
4103
4104u16 wmi_get_mapped_qos_queue(struct wmi_t *wmip, u8 trafficClass)
4105{
4106 u16 activeTsids=0;
4107
4108 LOCK_WMI(wmip);
4109 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
4110 UNLOCK_WMI(wmip);
4111
4112 return activeTsids;
4113}
4114
4115int
4116wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
4117{
4118 return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID);
4119}
4120
4121int
4122wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType)
4123{
4124 void *osbuf;
4125 u32 size = sizeof(u8);
4126 WMI_TARGET_ROAM_DATA *cmd;
4127
4128 osbuf = A_NETBUF_ALLOC(size); /* no payload */
4129 if (osbuf == NULL) {
4130 return A_NO_MEMORY;
4131 }
4132
4133 A_NETBUF_PUT(osbuf, size);
4134
4135 cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
4136 cmd->roamDataType = roamDataType;
4137
4138 return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
4139 NO_SYNC_WMIFLAG));
4140}
4141
4142int
4143wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
4144 u8 size)
4145{
4146 void *osbuf;
4147 WMI_SET_ROAM_CTRL_CMD *cmd;
4148
4149 osbuf = A_NETBUF_ALLOC(size);
4150 if (osbuf == NULL) {
4151 return A_NO_MEMORY;
4152 }
4153
4154 A_NETBUF_PUT(osbuf, size);
4155
4156 cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
4157 A_MEMZERO(cmd, size);
4158
4159 memcpy(cmd, p, size);
4160
4161 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
4162 NO_SYNC_WMIFLAG));
4163}
4164
4165int
4166wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
4167 WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
4168 u8 size)
4169{
4170 void *osbuf;
4171 WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
4172
4173 /* These timers can't be zero */
4174 if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
4175 !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
4176 pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
4177 !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
4178 pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
4179 return A_EINVAL;
4180
4181 osbuf = A_NETBUF_ALLOC(size);
4182 if (osbuf == NULL) {
4183 return A_NO_MEMORY;
4184 }
4185
4186 A_NETBUF_PUT(osbuf, size);
4187
4188 cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
4189 A_MEMZERO(cmd, size);
4190
4191 memcpy(cmd, pCmd, size);
4192
4193 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
4194 NO_SYNC_WMIFLAG));
4195}
4196
4197int
4198wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, u8 eCWmin,
4199 u8 eCWmax, u8 aifsn)
4200{
4201 void *osbuf;
4202 WMI_SET_ACCESS_PARAMS_CMD *cmd;
4203
4204 if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
4205 (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC))
4206 {
4207 return A_EINVAL;
4208 }
4209
4210 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4211 if (osbuf == NULL) {
4212 return A_NO_MEMORY;
4213 }
4214
4215 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4216
4217 cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4218 cmd->txop = txop;
4219 cmd->eCWmin = eCWmin;
4220 cmd->eCWmax = eCWmax;
4221 cmd->aifsn = aifsn;
4222 cmd->ac = ac;
4223
4224 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
4225 NO_SYNC_WMIFLAG));
4226}
4227
4228int
4229wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType,
4230 u8 trafficClass, u8 maxRetries,
4231 u8 enableNotify)
4232{
4233 void *osbuf;
4234 WMI_SET_RETRY_LIMITS_CMD *cmd;
4235
4236 if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
4237 (frameType != DATA_FRAMETYPE))
4238 {
4239 return A_EINVAL;
4240 }
4241
4242 if (maxRetries > WMI_MAX_RETRIES) {
4243 return A_EINVAL;
4244 }
4245
4246 if (frameType != DATA_FRAMETYPE) {
4247 trafficClass = 0;
4248 }
4249
4250 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4251 if (osbuf == NULL) {
4252 return A_NO_MEMORY;
4253 }
4254
4255 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4256
4257 cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
4258 cmd->frameType = frameType;
4259 cmd->trafficClass = trafficClass;
4260 cmd->maxRetries = maxRetries;
4261 cmd->enableNotify = enableNotify;
4262
4263 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
4264 NO_SYNC_WMIFLAG));
4265}
4266
4267void
4268wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid)
4269{
4270 if (bssid != NULL) {
4271 memcpy(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
4272 }
4273}
4274
4275int
4276wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode)
4277{
4278 void *osbuf;
4279 WMI_SET_OPT_MODE_CMD *cmd;
4280
4281 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4282 if (osbuf == NULL) {
4283 return A_NO_MEMORY;
4284 }
4285
4286 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4287
4288 cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4289 A_MEMZERO(cmd, sizeof(*cmd));
4290 cmd->optMode = optMode;
4291
4292 return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
4293 SYNC_BOTH_WMIFLAG));
4294}
4295
4296int
4297wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
4298 u8 frmType,
4299 u8 *dstMacAddr,
4300 u8 *bssid,
4301 u16 optIEDataLen,
4302 u8 *optIEData)
4303{
4304 void *osbuf;
4305 WMI_OPT_TX_FRAME_CMD *cmd;
4306 osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
4307 if (osbuf == NULL) {
4308 return A_NO_MEMORY;
4309 }
4310
4311 A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
4312
4313 cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
4314 A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
4315
4316 cmd->frmType = frmType;
4317 cmd->optIEDataLen = optIEDataLen;
4318 //cmd->optIEData = (u8 *)((int)cmd + sizeof(*cmd));
4319 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
4320 memcpy(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
4321 memcpy(&cmd->optIEData[0], optIEData, optIEDataLen);
4322
4323 return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
4324 NO_SYNC_WMIFLAG));
4325}
4326
4327int
4328wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl)
4329{
4330 void *osbuf;
4331 WMI_BEACON_INT_CMD *cmd;
4332
4333 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4334 if (osbuf == NULL) {
4335 return A_NO_MEMORY;
4336 }
4337
4338 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4339
4340 cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
4341 A_MEMZERO(cmd, sizeof(*cmd));
4342 cmd->beaconInterval = intvl;
4343
4344 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
4345 NO_SYNC_WMIFLAG));
4346}
4347
4348
4349int
4350wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize)
4351{
4352 void *osbuf;
4353 WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
4354
4355 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4356 if (osbuf == NULL) {
4357 return A_NO_MEMORY;
4358 }
4359
4360 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4361
4362 cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
4363 A_MEMZERO(cmd, sizeof(*cmd));
4364 cmd->voicePktSize = voicePktSize;
4365
4366 return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
4367 NO_SYNC_WMIFLAG));
4368}
4369
4370
4371int
4372wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSPLen)
4373{
4374 void *osbuf;
4375 WMI_SET_MAX_SP_LEN_CMD *cmd;
4376
4377 /* maxSPLen is a two-bit value. If user trys to set anything
4378 * other than this, then its invalid
4379 */
4380 if(maxSPLen & ~0x03)
4381 return A_EINVAL;
4382
4383 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4384 if (osbuf == NULL) {
4385 return A_NO_MEMORY;
4386 }
4387
4388 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4389
4390 cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
4391 A_MEMZERO(cmd, sizeof(*cmd));
4392 cmd->maxSPLen = maxSPLen;
4393
4394 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
4395 NO_SYNC_WMIFLAG));
4396}
4397
4398u8 wmi_determine_userPriority(
4399 u8 *pkt,
4400 u32 layer2Pri)
4401{
4402 u8 ipPri;
4403 iphdr *ipHdr = (iphdr *)pkt;
4404
4405 /* Determine IPTOS priority */
4406 /*
4407 * IP Tos format :
4408 * (Refer Pg 57 WMM-test-plan-v1.2)
4409 * IP-TOS - 8bits
4410 * : DSCP(6-bits) ECN(2-bits)
4411 * : DSCP - P2 P1 P0 X X X
4412 * where (P2 P1 P0) form 802.1D
4413 */
4414 ipPri = ipHdr->ip_tos >> 5;
4415 ipPri &= 0x7;
4416
4417 if ((layer2Pri & 0x7) > ipPri)
4418 return ((u8)layer2Pri & 0x7);
4419 else
4420 return ipPri;
4421}
4422
4423u8 convert_userPriority_to_trafficClass(u8 userPriority)
4424{
4425 return (up_to_ac[userPriority & 0x7]);
4426}
4427
4428u8 wmi_get_power_mode_cmd(struct wmi_t *wmip)
4429{
4430 return wmip->wmi_powerMode;
4431}
4432
4433int
4434wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance)
4435{
4436 int ret = 0;
4437
4438#define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0)
4439#define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0
4440#define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF 0
4441#define TSPEC_DELAY_BOUND_ATHEROS_DEF 0
4442#define TSPEC_MEDIUM_TIME_ATHEROS_DEF 0
4443#define TSPEC_SBA_ATHEROS_DEF 0x2000 /* factor is 1 */
4444
4445 /* Verify TSPEC params for ATHEROS compliance */
4446 if(tspecCompliance == ATHEROS_COMPLIANCE) {
4447 if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) ||
4448 (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) ||
4449 (pCmd->minDataRate != pCmd->meanDataRate) ||
4450 (pCmd->minDataRate != pCmd->peakDataRate) ||
4451 (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) ||
4452 (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) ||
4453 (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) ||
4454 (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) {
4455
4456 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG));
4457 //A_PRINTF("%s: Invalid TSPEC params\n", __func__);
4458 ret = A_EINVAL;
4459 }
4460 }
4461
4462 return ret;
4463}
4464
4465#ifdef CONFIG_HOST_TCMD_SUPPORT
4466static int
4467wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len)
4468{
4469 ar6000_testmode_rx_report_event(wmip->wmi_devt, datap, len);
4470
4471 return 0;
4472}
4473
4474#endif /* CONFIG_HOST_TCMD_SUPPORT*/
4475
4476int
4477wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode)
4478{
4479 void *osbuf;
4480 WMI_SET_AUTH_MODE_CMD *cmd;
4481
4482 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4483 if (osbuf == NULL) {
4484 return A_NO_MEMORY;
4485 }
4486
4487 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4488
4489 cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4490 A_MEMZERO(cmd, sizeof(*cmd));
4491 cmd->mode = mode;
4492
4493 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
4494 NO_SYNC_WMIFLAG));
4495}
4496
4497int
4498wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode)
4499{
4500 void *osbuf;
4501 WMI_SET_REASSOC_MODE_CMD *cmd;
4502
4503 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4504 if (osbuf == NULL) {
4505 return A_NO_MEMORY;
4506 }
4507
4508 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4509
4510 cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4511 A_MEMZERO(cmd, sizeof(*cmd));
4512 cmd->mode = mode;
4513
4514 return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
4515 NO_SYNC_WMIFLAG));
4516}
4517
4518int
4519wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy)
4520{
4521 void *osbuf;
4522 WMI_SET_LPREAMBLE_CMD *cmd;
4523
4524 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4525 if (osbuf == NULL) {
4526 return A_NO_MEMORY;
4527 }
4528
4529 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4530
4531 cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf));
4532 A_MEMZERO(cmd, sizeof(*cmd));
4533 cmd->status = status;
4534 cmd->preamblePolicy = preamblePolicy;
4535
4536 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID,
4537 NO_SYNC_WMIFLAG));
4538}
4539
4540int
4541wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold)
4542{
4543 void *osbuf;
4544 WMI_SET_RTS_CMD *cmd;
4545
4546 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4547 if (osbuf == NULL) {
4548 return A_NO_MEMORY;
4549 }
4550
4551 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4552
4553 cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf));
4554 A_MEMZERO(cmd, sizeof(*cmd));
4555 cmd->threshold = threshold;
4556
4557 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID,
4558 NO_SYNC_WMIFLAG));
4559}
4560
4561int
4562wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
4563{
4564 void *osbuf;
4565 WMI_SET_WMM_CMD *cmd;
4566
4567 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4568 if (osbuf == NULL) {
4569 return A_NO_MEMORY;
4570 }
4571
4572 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4573
4574 cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf));
4575 A_MEMZERO(cmd, sizeof(*cmd));
4576 cmd->status = status;
4577
4578 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID,
4579 NO_SYNC_WMIFLAG));
4580
4581}
4582
4583int
4584wmi_set_qos_supp_cmd(struct wmi_t *wmip, u8 status)
4585{
4586 void *osbuf;
4587 WMI_SET_QOS_SUPP_CMD *cmd;
4588
4589 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4590 if (osbuf == NULL) {
4591 return A_NO_MEMORY;
4592 }
4593
4594 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4595
4596 cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf));
4597 A_MEMZERO(cmd, sizeof(*cmd));
4598 cmd->status = status;
4599 return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID,
4600 NO_SYNC_WMIFLAG));
4601}
4602
4603
4604int
4605wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
4606{
4607 void *osbuf;
4608 WMI_SET_WMM_TXOP_CMD *cmd;
4609
4610 if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
4611 return A_EINVAL;
4612
4613 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4614 if (osbuf == NULL) {
4615 return A_NO_MEMORY;
4616 }
4617
4618 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4619
4620 cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf));
4621 A_MEMZERO(cmd, sizeof(*cmd));
4622 cmd->txopEnable = cfg;
4623
4624 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID,
4625 NO_SYNC_WMIFLAG));
4626
4627}
4628
4629int
4630wmi_set_country(struct wmi_t *wmip, u8 *countryCode)
4631{
4632 void *osbuf;
4633 WMI_AP_SET_COUNTRY_CMD *cmd;
4634
4635 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4636 if (osbuf == NULL) {
4637 return A_NO_MEMORY;
4638 }
4639
4640 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4641
4642 cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf));
4643 A_MEMZERO(cmd, sizeof(*cmd));
4644 memcpy(cmd->countryCode,countryCode,3);
4645
4646 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID,
4647 NO_SYNC_WMIFLAG));
4648}
4649
4650#ifdef CONFIG_HOST_TCMD_SUPPORT
4651/* WMI layer doesn't need to know the data type of the test cmd.
4652 This would be beneficial for customers like Qualcomm, who might
4653 have different test command requirements from different manufacturers
4654 */
4655int
4656wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len)
4657{
4658 void *osbuf;
4659 char *data;
4660
4661 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4662
4663 osbuf= A_NETBUF_ALLOC(len);
4664 if(osbuf == NULL)
4665 {
4666 return A_NO_MEMORY;
4667 }
4668 A_NETBUF_PUT(osbuf, len);
4669 data = A_NETBUF_DATA(osbuf);
4670 memcpy(data, buf, len);
4671
4672 return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID,
4673 NO_SYNC_WMIFLAG));
4674}
4675
4676#endif
4677
4678int
4679wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status)
4680{
4681 void *osbuf;
4682 WMI_SET_BT_STATUS_CMD *cmd;
4683
4684 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", streamType, status));
4685
4686 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4687 if (osbuf == NULL) {
4688 return A_NO_MEMORY;
4689 }
4690
4691 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4692
4693 cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
4694 A_MEMZERO(cmd, sizeof(*cmd));
4695 cmd->streamType = streamType;
4696 cmd->status = status;
4697
4698 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID,
4699 NO_SYNC_WMIFLAG));
4700}
4701
4702int
4703wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
4704{
4705 void *osbuf;
4706 WMI_SET_BT_PARAMS_CMD* alloc_cmd;
4707
4708 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType));
4709
4710 if (cmd->paramType == BT_PARAM_SCO) {
4711 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("sco params %d %d %d %d %d %d %d %d %d %d %d %d\n", cmd->info.scoParams.numScoCyclesForceTrigger,
4712 cmd->info.scoParams.dataResponseTimeout,
4713 cmd->info.scoParams.stompScoRules,
4714 cmd->info.scoParams.scoOptFlags,
4715 cmd->info.scoParams.stompDutyCyleVal,
4716 cmd->info.scoParams.stompDutyCyleMaxVal,
4717 cmd->info.scoParams.psPollLatencyFraction,
4718 cmd->info.scoParams.noSCOSlots,
4719 cmd->info.scoParams.noIdleSlots,
4720 cmd->info.scoParams.scoOptOffRssi,
4721 cmd->info.scoParams.scoOptOnRssi,
4722 cmd->info.scoParams.scoOptRtsCount));
4723 }
4724 else if (cmd->paramType == BT_PARAM_A2DP) {
4725 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n", cmd->info.a2dpParams.a2dpWlanUsageLimit,
4726 cmd->info.a2dpParams.a2dpBurstCntMin,
4727 cmd->info.a2dpParams.a2dpDataRespTimeout,
4728 cmd->info.a2dpParams.a2dpOptFlags,
4729 cmd->info.a2dpParams.isCoLocatedBtRoleMaster,
4730 cmd->info.a2dpParams.a2dpOptOffRssi,
4731 cmd->info.a2dpParams.a2dpOptOnRssi,
4732 cmd->info.a2dpParams.a2dpOptRtsCount));
4733 }
4734 else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) {
4735 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType));
4736 }
4737 else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) {
4738 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocatedBtDev));
4739 }
4740 else if (cmd->paramType == BT_PARAM_ACLCOEX) {
4741 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoexParams.aclWlanMediumUsageTime,
4742 cmd->info.aclCoexParams.aclBtMediumUsageTime,
4743 cmd->info.aclCoexParams.aclDataRespTimeout));
4744 }
4745 else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) {
4746 A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG));
4747 }
4748
4749 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4750 if (osbuf == NULL) {
4751 return A_NO_MEMORY;
4752 }
4753
4754 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4755
4756 alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4757 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4758 memcpy(alloc_cmd, cmd, sizeof(*cmd));
4759
4760 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID,
4761 NO_SYNC_WMIFLAG));
4762}
4763
4764int
4765wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd)
4766{
4767 void *osbuf;
4768 WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd;
4769
4770 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4771 if (osbuf == NULL) {
4772 return A_NO_MEMORY;
4773 }
4774 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4775 alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf));
4776 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4777 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
4778 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID,
4779 NO_SYNC_WMIFLAG));
4780
4781}
4782
4783
4784int
4785wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
4786 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd)
4787{
4788 void *osbuf;
4789 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd;
4790
4791 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4792 if (osbuf == NULL) {
4793 return A_NO_MEMORY;
4794 }
4795 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4796 alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf));
4797 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4798 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
4799 A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev);
4800 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
4801 NO_SYNC_WMIFLAG));
4802
4803}
4804
4805int
4806wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
4807 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd)
4808{
4809 void *osbuf;
4810 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd;
4811
4812 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4813 if (osbuf == NULL) {
4814 return A_NO_MEMORY;
4815 }
4816 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4817 alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4818 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4819 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD));
4820 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
4821 NO_SYNC_WMIFLAG));
4822
4823}
4824
4825int
4826wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
4827 WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd)
4828{
4829 void *osbuf;
4830 WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd;
4831
4832 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4833 if (osbuf == NULL) {
4834 return A_NO_MEMORY;
4835 }
4836 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4837 alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4838 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4839 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
4840 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID ,
4841 NO_SYNC_WMIFLAG));
4842
4843}
4844
4845int
4846wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
4847 WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd)
4848{
4849 void *osbuf;
4850 WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd;
4851
4852 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4853 if (osbuf == NULL) {
4854 return A_NO_MEMORY;
4855 }
4856 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4857 alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4858 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4859 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
4860 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID ,
4861 NO_SYNC_WMIFLAG));
4862
4863}
4864
4865int
4866wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip,
4867 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd)
4868{
4869 void *osbuf;
4870 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd;
4871
4872 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4873 if (osbuf == NULL) {
4874 return A_NO_MEMORY;
4875 }
4876 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4877 alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4878 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4879 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
4880 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID ,
4881 NO_SYNC_WMIFLAG));
4882
4883}
4884
4885int
4886wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd)
4887{
4888 void *osbuf;
4889 WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd;
4890
4891 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4892 if (osbuf == NULL) {
4893 return A_NO_MEMORY;
4894 }
4895 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4896 alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf));
4897 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4898 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD));
4899 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID ,
4900 NO_SYNC_WMIFLAG));
4901
4902}
4903
4904int
4905wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
4906 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd)
4907{
4908 void *osbuf;
4909 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd;
4910
4911 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4912 if (osbuf == NULL) {
4913 return A_NO_MEMORY;
4914 }
4915 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4916 alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
4917 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4918 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD));
4919 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ,
4920 NO_SYNC_WMIFLAG));
4921
4922}
4923
4924int
4925wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd)
4926{
4927 void *osbuf;
4928 WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd;
4929
4930 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4931 if (osbuf == NULL) {
4932 return A_NO_MEMORY;
4933 }
4934 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4935 alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4936 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4937 memcpy(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD));
4938 return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID ,
4939 NO_SYNC_WMIFLAG));
4940
4941}
4942
4943int
4944wmi_get_btcoex_stats_cmd(struct wmi_t *wmip)
4945{
4946
4947 return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID);
4948
4949}
4950
4951int
4952wmi_get_keepalive_configured(struct wmi_t *wmip)
4953{
4954 void *osbuf;
4955 WMI_GET_KEEPALIVE_CMD *cmd;
4956 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4957 if (osbuf == NULL) {
4958 return A_NO_MEMORY;
4959 }
4960 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4961 cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
4962 A_MEMZERO(cmd, sizeof(*cmd));
4963 return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID,
4964 NO_SYNC_WMIFLAG));
4965}
4966
4967u8 wmi_get_keepalive_cmd(struct wmi_t *wmip)
4968{
4969 return wmip->wmi_keepaliveInterval;
4970}
4971
4972int
4973wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval)
4974{
4975 void *osbuf;
4976 WMI_SET_KEEPALIVE_CMD *cmd;
4977
4978 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4979 if (osbuf == NULL) {
4980 return A_NO_MEMORY;
4981 }
4982
4983 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4984
4985 cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
4986 A_MEMZERO(cmd, sizeof(*cmd));
4987 cmd->keepaliveInterval = keepaliveInterval;
4988 wmip->wmi_keepaliveInterval = keepaliveInterval;
4989
4990 return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID,
4991 NO_SYNC_WMIFLAG));
4992}
4993
4994int
4995wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer)
4996{
4997 void *osbuf;
4998 WMI_SET_PARAMS_CMD *cmd;
4999
5000 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length);
5001 if (osbuf == NULL) {
5002 return A_NO_MEMORY;
5003 }
5004
5005 A_NETBUF_PUT(osbuf, sizeof(*cmd) + length);
5006
5007 cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5008 A_MEMZERO(cmd, sizeof(*cmd));
5009 cmd->opcode = opcode;
5010 cmd->length = length;
5011 memcpy(cmd->buffer, buffer, length);
5012
5013 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID,
5014 NO_SYNC_WMIFLAG));
5015}
5016
5017
5018int
5019wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
5020{
5021 void *osbuf;
5022 WMI_SET_MCAST_FILTER_CMD *cmd;
5023
5024 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5025 if (osbuf == NULL) {
5026 return A_NO_MEMORY;
5027 }
5028
5029 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5030
5031 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5032 cmd->multicast_mac[0] = 0x01;
5033 cmd->multicast_mac[1] = 0x00;
5034 cmd->multicast_mac[2] = 0x5e;
5035 cmd->multicast_mac[3] = dot2&0x7F;
5036 cmd->multicast_mac[4] = dot3;
5037 cmd->multicast_mac[5] = dot4;
5038
5039 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID,
5040 NO_SYNC_WMIFLAG));
5041}
5042
5043
5044int
5045wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
5046{
5047 void *osbuf;
5048 WMI_SET_MCAST_FILTER_CMD *cmd;
5049
5050 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5051 if (osbuf == NULL) {
5052 return A_NO_MEMORY;
5053 }
5054
5055 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5056
5057 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5058 cmd->multicast_mac[0] = 0x01;
5059 cmd->multicast_mac[1] = 0x00;
5060 cmd->multicast_mac[2] = 0x5e;
5061 cmd->multicast_mac[3] = dot2&0x7F;
5062 cmd->multicast_mac[4] = dot3;
5063 cmd->multicast_mac[5] = dot4;
5064
5065 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID,
5066 NO_SYNC_WMIFLAG));
5067}
5068
5069int
5070wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable)
5071{
5072 void *osbuf;
5073 WMI_MCAST_FILTER_CMD *cmd;
5074
5075 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5076 if (osbuf == NULL) {
5077 return A_NO_MEMORY;
5078 }
5079
5080 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5081
5082 cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5083 cmd->enable = enable;
5084
5085 return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID,
5086 NO_SYNC_WMIFLAG));
5087}
5088
5089int
5090wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen,
5091 u8 *ieInfo)
5092{
5093 void *osbuf;
5094 WMI_SET_APPIE_CMD *cmd;
5095 u16 cmdLen;
5096
5097 cmdLen = sizeof(*cmd) + ieLen - 1;
5098 osbuf = A_NETBUF_ALLOC(cmdLen);
5099 if (osbuf == NULL) {
5100 return A_NO_MEMORY;
5101 }
5102
5103 A_NETBUF_PUT(osbuf, cmdLen);
5104
5105 cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf));
5106 A_MEMZERO(cmd, cmdLen);
5107
5108 cmd->mgmtFrmType = mgmtFrmType;
5109 cmd->ieLen = ieLen;
5110 memcpy(cmd->ieInfo, ieInfo, ieLen);
5111
5112 return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG));
5113}
5114
5115int
5116wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen)
5117{
5118 void *osbuf;
5119 u8 *data;
5120
5121 osbuf = A_NETBUF_ALLOC(dataLen);
5122 if (osbuf == NULL) {
5123 return A_NO_MEMORY;
5124 }
5125
5126 A_NETBUF_PUT(osbuf, dataLen);
5127
5128 data = A_NETBUF_DATA(osbuf);
5129
5130 memcpy(data, cmd, dataLen);
5131
5132 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG));
5133}
5134
5135s32 wmi_get_rate(s8 rateindex)
5136{
5137 if (rateindex == RATE_AUTO) {
5138 return 0;
5139 } else {
5140 return(wmi_rateTable[(u32) rateindex][0]);
5141 }
5142}
5143
5144void
5145wmi_node_return (struct wmi_t *wmip, bss_t *bss)
5146{
5147 if (NULL != bss)
5148 {
5149 wlan_node_return (&wmip->wmi_scan_table, bss);
5150 }
5151}
5152
5153void
5154wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge)
5155{
5156 wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge);
5157}
5158
5159bss_t *
5160wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
5161 u32 ssidLength, bool bIsWPA2, bool bMatchSSID)
5162{
5163 bss_t *node = NULL;
5164 node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
5165 ssidLength, bIsWPA2, bMatchSSID);
5166 return node;
5167}
5168
5169
5170#ifdef THREAD_X
5171void
5172wmi_refresh_scan_table (struct wmi_t *wmip)
5173{
5174 wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
5175}
5176#endif
5177
5178void
5179wmi_free_allnodes(struct wmi_t *wmip)
5180{
5181 wlan_free_allnodes(&wmip->wmi_scan_table);
5182}
5183
5184bss_t *
5185wmi_find_node(struct wmi_t *wmip, const u8 *macaddr)
5186{
5187 bss_t *ni=NULL;
5188 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5189 return ni;
5190}
5191
5192void
5193wmi_free_node(struct wmi_t *wmip, const u8 *macaddr)
5194{
5195 bss_t *ni=NULL;
5196
5197 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5198 if (ni != NULL) {
5199 wlan_node_reclaim(&wmip->wmi_scan_table, ni);
5200 }
5201
5202 return;
5203}
5204
5205int
5206wmi_dset_open_reply(struct wmi_t *wmip,
5207 u32 status,
5208 u32 access_cookie,
5209 u32 dset_size,
5210 u32 dset_version,
5211 u32 targ_handle,
5212 u32 targ_reply_fn,
5213 u32 targ_reply_arg)
5214{
5215 void *osbuf;
5216 WMIX_DSETOPEN_REPLY_CMD *open_reply;
5217
5218 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip));
5219
5220 osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
5221 if (osbuf == NULL) {
5222 return A_NO_MEMORY;
5223 }
5224
5225 A_NETBUF_PUT(osbuf, sizeof(*open_reply));
5226 open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5227
5228 open_reply->status = status;
5229 open_reply->targ_dset_handle = targ_handle;
5230 open_reply->targ_reply_fn = targ_reply_fn;
5231 open_reply->targ_reply_arg = targ_reply_arg;
5232 open_reply->access_cookie = access_cookie;
5233 open_reply->size = dset_size;
5234 open_reply->version = dset_version;
5235
5236 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
5237 NO_SYNC_WMIFLAG));
5238}
5239
5240static int
5241wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
5242{
5243 WMI_PMKID_LIST_REPLY *reply;
5244 u32 expected_len;
5245
5246 if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
5247 return A_EINVAL;
5248 }
5249 reply = (WMI_PMKID_LIST_REPLY *)datap;
5250 expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
5251
5252 if (len < expected_len) {
5253 return A_EINVAL;
5254 }
5255
5256 A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
5257 reply->pmkidList, reply->bssidList[0]);
5258
5259 return 0;
5260}
5261
5262
5263static int
5264wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
5265{
5266 WMI_SET_PARAMS_REPLY *reply;
5267
5268 if (len < sizeof(WMI_SET_PARAMS_REPLY)) {
5269 return A_EINVAL;
5270 }
5271 reply = (WMI_SET_PARAMS_REPLY *)datap;
5272
5273 if (0 == reply->status)
5274 {
5275
5276 }
5277 else
5278 {
5279
5280 }
5281
5282 return 0;
5283}
5284
5285
5286#ifdef CONFIG_HOST_DSET_SUPPORT
5287int
5288wmi_dset_data_reply(struct wmi_t *wmip,
5289 u32 status,
5290 u8 *user_buf,
5291 u32 length,
5292 u32 targ_buf,
5293 u32 targ_reply_fn,
5294 u32 targ_reply_arg)
5295{
5296 void *osbuf;
5297 WMIX_DSETDATA_REPLY_CMD *data_reply;
5298 u32 size;
5299
5300 size = sizeof(*data_reply) + length;
5301
5302 if (size <= length) {
5303 return A_ERROR;
5304 }
5305
5306 A_DPRINTF(DBG_WMI,
5307 (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
5308
5309 osbuf = A_NETBUF_ALLOC(size);
5310 if (osbuf == NULL) {
5311 return A_NO_MEMORY;
5312 }
5313 A_NETBUF_PUT(osbuf, size);
5314 data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5315
5316 data_reply->status = status;
5317 data_reply->targ_buf = targ_buf;
5318 data_reply->targ_reply_fn = targ_reply_fn;
5319 data_reply->targ_reply_arg = targ_reply_arg;
5320 data_reply->length = length;
5321
5322 if (status == 0) {
5323 if (a_copy_from_user(data_reply->buf, user_buf, length)) {
5324 A_NETBUF_FREE(osbuf);
5325 return A_ERROR;
5326 }
5327 }
5328
5329 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
5330 NO_SYNC_WMIFLAG));
5331}
5332#endif /* CONFIG_HOST_DSET_SUPPORT */
5333
5334int
5335wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status)
5336{
5337 void *osbuf;
5338 char *cmd;
5339
5340 wps_enable = status;
5341
5342 osbuf = a_netbuf_alloc(sizeof(1));
5343 if (osbuf == NULL) {
5344 return A_NO_MEMORY;
5345 }
5346
5347 a_netbuf_put(osbuf, sizeof(1));
5348
5349 cmd = (char *)(a_netbuf_to_data(osbuf));
5350
5351 A_MEMZERO(cmd, sizeof(*cmd));
5352 cmd[0] = (status?1:0);
5353 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID,
5354 NO_SYNC_WMIFLAG));
5355}
5356
5357#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
5358int
5359wmi_prof_cfg_cmd(struct wmi_t *wmip,
5360 u32 period,
5361 u32 nbins)
5362{
5363 void *osbuf;
5364 WMIX_PROF_CFG_CMD *cmd;
5365
5366 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5367 if (osbuf == NULL) {
5368 return A_NO_MEMORY;
5369 }
5370
5371 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5372
5373 cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf));
5374 A_MEMZERO(cmd, sizeof(*cmd));
5375 cmd->period = period;
5376 cmd->nbins = nbins;
5377
5378 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG));
5379}
5380
5381int
5382wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr)
5383{
5384 void *osbuf;
5385 WMIX_PROF_ADDR_SET_CMD *cmd;
5386
5387 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5388 if (osbuf == NULL) {
5389 return A_NO_MEMORY;
5390 }
5391
5392 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5393
5394 cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf));
5395 A_MEMZERO(cmd, sizeof(*cmd));
5396 cmd->addr = addr;
5397
5398 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG));
5399}
5400
5401int
5402wmi_prof_start_cmd(struct wmi_t *wmip)
5403{
5404 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID);
5405}
5406
5407int
5408wmi_prof_stop_cmd(struct wmi_t *wmip)
5409{
5410 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID);
5411}
5412
5413int
5414wmi_prof_count_get_cmd(struct wmi_t *wmip)
5415{
5416 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID);
5417}
5418
5419/* Called to handle WMIX_PROF_CONT_EVENTID */
5420static int
5421wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len)
5422{
5423 WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap;
5424
5425 A_DPRINTF(DBG_WMI,
5426 (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG,
5427 prof_data->addr, prof_data->count));
5428
5429 A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count);
5430
5431 return 0;
5432}
5433#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
5434
5435#ifdef OS_ROAM_MANAGEMENT
5436
5437#define ETHERNET_MAC_ADDRESS_LENGTH 6
5438
5439void
5440wmi_scan_indication (struct wmi_t *wmip)
5441{
5442 struct ieee80211_node_table *nt;
5443 u32 gen;
5444 u32 size;
5445 u32 bsssize;
5446 bss_t *bss;
5447 u32 numbss;
5448 PNDIS_802_11_BSSID_SCAN_INFO psi;
5449 PBYTE pie;
5450 NDIS_802_11_FIXED_IEs *pFixed;
5451 NDIS_802_11_VARIABLE_IEs *pVar;
5452 u32 RateSize;
5453
5454 struct ar6kScanIndication
5455 {
5456 NDIS_802_11_STATUS_INDICATION ind;
5457 NDIS_802_11_BSSID_SCAN_INFO_LIST slist;
5458 } *pAr6kScanIndEvent;
5459
5460 nt = &wmip->wmi_scan_table;
5461
5462 ++nt->nt_si_gen;
5463
5464
5465 gen = nt->nt_si_gen;
5466
5467 size = offsetof(struct ar6kScanIndication, slist) +
5468 offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo);
5469
5470 numbss = 0;
5471
5472 IEEE80211_NODE_LOCK(nt);
5473
5474 //calc size
5475 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5476 if (bss->ni_si_gen != gen) {
5477 bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(NDIS_WLAN_BSSID_EX, IEs);
5478 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5479
5480#ifdef SUPPORT_WPA2
5481 if (bss->ni_cie.ie_rsn) {
5482 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5483 }
5484#endif
5485 if (bss->ni_cie.ie_wpa) {
5486 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5487 }
5488
5489 // bsssize must be a multiple of 4 to maintain alignment.
5490 bsssize = (bsssize + 3) & ~3;
5491
5492 size += bsssize;
5493
5494 numbss++;
5495 }
5496 }
5497
5498 if (0 == numbss)
5499 {
5500// RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n"));
5501 ar6000_scan_indication (wmip->wmi_devt, NULL, 0);
5502 IEEE80211_NODE_UNLOCK (nt);
5503 return;
5504 }
5505
5506 pAr6kScanIndEvent = A_MALLOC(size);
5507
5508 if (NULL == pAr6kScanIndEvent)
5509 {
5510 IEEE80211_NODE_UNLOCK(nt);
5511 return;
5512 }
5513
5514 A_MEMZERO(pAr6kScanIndEvent, size);
5515
5516 //copy data
5517 pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList;
5518 pAr6kScanIndEvent->slist.Version = 1;
5519 pAr6kScanIndEvent->slist.NumItems = numbss;
5520
5521 psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0];
5522
5523 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5524 if (bss->ni_si_gen != gen) {
5525
5526 bss->ni_si_gen = gen;
5527
5528 //Set scan time
5529 psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC;
5530
5531 // Copy data to bssid_ex
5532 bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs);
5533 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5534
5535#ifdef SUPPORT_WPA2
5536 if (bss->ni_cie.ie_rsn) {
5537 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5538 }
5539#endif
5540 if (bss->ni_cie.ie_wpa) {
5541 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5542 }
5543
5544 // bsssize must be a multiple of 4 to maintain alignment.
5545 bsssize = (bsssize + 3) & ~3;
5546
5547 psi->Bssid.Length = bsssize;
5548
5549 memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS_LENGTH);
5550
5551
5552//if (((bss->ni_macaddr[3] == 0xCE) && (bss->ni_macaddr[4] == 0xF0) && (bss->ni_macaddr[5] == 0xE7)) ||
5553// ((bss->ni_macaddr[3] == 0x03) && (bss->ni_macaddr[4] == 0xE2) && (bss->ni_macaddr[5] == 0x70)))
5554// RETAILMSG (1, (L"%x\n",bss->ni_macaddr[5]));
5555
5556 psi->Bssid.Ssid.SsidLength = 0;
5557 pie = bss->ni_cie.ie_ssid;
5558
5559 if (pie) {
5560 // Format of SSID IE is:
5561 // Type (1 octet)
5562 // Length (1 octet)
5563 // SSID (Length octets)
5564 //
5565 // Validation of the IE should have occurred within WMI.
5566 //
5567 if (pie[1] <= 32) {
5568 psi->Bssid.Ssid.SsidLength = pie[1];
5569 memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLength);
5570 }
5571 }
5572 psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0;
5573
5574 //Post the RSSI value relative to the Standard Noise floor value.
5575 psi->Bssid.Rssi = bss->ni_rssi;
5576
5577 if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) {
5578
5579 if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) {
5580 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24;
5581 }
5582 else {
5583 psi->Bssid.NetworkTypeInUse = Ndis802_11DS;
5584 }
5585 }
5586 else {
5587 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5;
5588 }
5589
5590 psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration);
5591 psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt; // Units are Kmicroseconds (1024 us)
5592 psi->Bssid.Configuration.ATIMWindow = 0;
5593 psi->Bssid.Configuration.DSConfig = bss->ni_cie.ie_chan * 1000;
5594 psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) == 0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS;
5595
5596 RateSize = 0;
5597 pie = bss->ni_cie.ie_rates;
5598 if (pie) {
5599 RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDIS_802_11_LENGTH_RATES_EX;
5600 memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize);
5601 }
5602 pie = bss->ni_cie.ie_xrates;
5603 if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) {
5604 memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2],
5605 (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize));
5606 }
5607
5608 // Copy the fixed IEs
5609 psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs);
5610
5611 pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs;
5612 memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Timestamp));
5613 pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt;
5614 pFixed->Capabilities = bss->ni_cie.ie_capInfo;
5615
5616 // Copy selected variable IEs
5617
5618 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_11_FIXED_IEs));
5619
5620#ifdef SUPPORT_WPA2
5621 // Copy the WPAv2 IE
5622 if (bss->ni_cie.ie_rsn) {
5623 pie = bss->ni_cie.ie_rsn;
5624 psi->Bssid.IELength += pie[1] + 2;
5625 memcpy(pVar, pie, pie[1] + 2);
5626 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5627 }
5628#endif
5629 // Copy the WPAv1 IE
5630 if (bss->ni_cie.ie_wpa) {
5631 pie = bss->ni_cie.ie_wpa;
5632 psi->Bssid.IELength += pie[1] + 2;
5633 memcpy(pVar, pie, pie[1] + 2);
5634 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5635 }
5636
5637 // Advance buffer pointer
5638 psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OFFSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid));
5639 }
5640 }
5641
5642 IEEE80211_NODE_UNLOCK(nt);
5643
5644// wmi_free_allnodes(wmip);
5645
5646// RETAILMSG(1, (L"AR6K: scan indication: %u bss\n", numbss));
5647
5648 ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size);
5649
5650 kfree(pAr6kScanIndEvent);
5651}
5652#endif
5653
5654u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5655 u32 size)
5656{
5657 u32 index;
5658 u8 threshold = (u8)sq_thresh->upper_threshold[size - 1];
5659
5660 /* The list is already in sorted order. Get the next lower value */
5661 for (index = 0; index < size; index ++) {
5662 if (rssi < sq_thresh->upper_threshold[index]) {
5663 threshold = (u8)sq_thresh->upper_threshold[index];
5664 break;
5665 }
5666 }
5667
5668 return threshold;
5669}
5670
5671u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5672 u32 size)
5673{
5674 u32 index;
5675 u8 threshold = (u8)sq_thresh->lower_threshold[size - 1];
5676
5677 /* The list is already in sorted order. Get the next lower value */
5678 for (index = 0; index < size; index ++) {
5679 if (rssi > sq_thresh->lower_threshold[index]) {
5680 threshold = (u8)sq_thresh->lower_threshold[index];
5681 break;
5682 }
5683 }
5684
5685 return threshold;
5686}
5687static int
5688wmi_send_rssi_threshold_params(struct wmi_t *wmip,
5689 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
5690{
5691 void *osbuf;
5692 s8 size;
5693 WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
5694
5695 size = sizeof (*cmd);
5696
5697 osbuf = A_NETBUF_ALLOC(size);
5698 if (osbuf == NULL) {
5699 return A_NO_MEMORY;
5700 }
5701
5702 A_NETBUF_PUT(osbuf, size);
5703
5704 cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5705 A_MEMZERO(cmd, size);
5706 memcpy(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD));
5707
5708 return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
5709 NO_SYNC_WMIFLAG));
5710}
5711static int
5712wmi_send_snr_threshold_params(struct wmi_t *wmip,
5713 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
5714{
5715 void *osbuf;
5716 s8 size;
5717 WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
5718
5719 size = sizeof (*cmd);
5720
5721 osbuf = A_NETBUF_ALLOC(size);
5722 if (osbuf == NULL) {
5723 return A_NO_MEMORY;
5724 }
5725
5726 A_NETBUF_PUT(osbuf, size);
5727 cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5728 A_MEMZERO(cmd, size);
5729 memcpy(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD));
5730
5731 return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID,
5732 NO_SYNC_WMIFLAG));
5733}
5734
5735int
5736wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd)
5737{
5738 void *osbuf;
5739 WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd;
5740
5741 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5742 if (osbuf == NULL) {
5743 return A_NO_MEMORY;
5744 }
5745
5746 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5747
5748 alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf));
5749 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5750 memcpy(alloc_cmd, cmd, sizeof(*cmd));
5751
5752 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID,
5753 NO_SYNC_WMIFLAG));
5754}
5755
5756bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id)
5757{
5758 wmi_get_current_bssid (wmip, id);
5759 return wlan_node_remove (&wmip->wmi_scan_table, id);
5760}
5761
5762int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss)
5763{
5764 wlan_setup_node (&wmip->wmi_scan_table, bss, id);
5765 return 0;
5766}
5767
5768static int
5769wmi_addba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5770{
5771 WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap;
5772
5773 A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd);
5774
5775 return 0;
5776}
5777
5778
5779static int
5780wmi_addba_resp_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5781{
5782 WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap;
5783
5784 A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd);
5785
5786 return 0;
5787}
5788
5789static int
5790wmi_delba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5791{
5792 WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap;
5793
5794 A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd);
5795
5796 return 0;
5797}
5798
5799int
5800wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5801{
5802 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
5803
5804 A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len);
5805
5806 return 0;
5807}
5808
5809
5810int
5811wmi_btcoex_stats_event_rx(struct wmi_t * wmip,u8 *datap,int len)
5812{
5813 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
5814
5815 A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len);
5816
5817 return 0;
5818
5819}
5820
5821static int
5822wmi_hci_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5823{
5824 WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap;
5825 A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd);
5826
5827 return 0;
5828}
5829
5830////////////////////////////////////////////////////////////////////////////////
5831//// ////
5832//// AP mode functions ////
5833//// ////
5834////////////////////////////////////////////////////////////////////////////////
5835/*
5836 * IOCTL: AR6000_XIOCTL_AP_COMMIT_CONFIG
5837 *
5838 * When AR6K in AP mode, This command will be called after
5839 * changing ssid, channel etc. It will pass the profile to
5840 * target with a flag which will indicate which parameter changed,
5841 * also if this flag is 0, there was no change in parametes, so
5842 * commit cmd will not be sent to target. Without calling this IOCTL
5843 * the changes will not take effect.
5844 */
5845int
5846wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p)
5847{
5848 void *osbuf;
5849 WMI_CONNECT_CMD *cm;
5850
5851 osbuf = A_NETBUF_ALLOC(sizeof(*cm));
5852 if (osbuf == NULL) {
5853 return A_NO_MEMORY;
5854 }
5855
5856 A_NETBUF_PUT(osbuf, sizeof(*cm));
5857 cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
5858 A_MEMZERO(cm, sizeof(*cm));
5859
5860 memcpy(cm,p,sizeof(*cm));
5861
5862 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG));
5863}
5864
5865/*
5866 * IOCTL: AR6000_XIOCTL_AP_HIDDEN_SSID
5867 *
5868 * This command will be used to enable/disable hidden ssid functioanlity of
5869 * beacon. If it is enabled, ssid will be NULL in beacon.
5870 */
5871int
5872wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid)
5873{
5874 void *osbuf;
5875 WMI_AP_HIDDEN_SSID_CMD *hs;
5876
5877 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD));
5878 if (osbuf == NULL) {
5879 return A_NO_MEMORY;
5880 }
5881
5882 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD));
5883 hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf));
5884 A_MEMZERO(hs, sizeof(*hs));
5885
5886 hs->hidden_ssid = hidden_ssid;
5887
5888 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hidden_ssid));
5889 return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG));
5890}
5891
5892/*
5893 * IOCTL: AR6000_XIOCTL_AP_SET_MAX_NUM_STA
5894 *
5895 * This command is used to limit max num of STA that can connect
5896 * with this AP. This value should not exceed AP_MAX_NUM_STA (this
5897 * is max num of STA supported by AP). Value was already validated
5898 * in ioctl.c
5899 */
5900int
5901wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta)
5902{
5903 void *osbuf;
5904 WMI_AP_SET_NUM_STA_CMD *ns;
5905
5906 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD));
5907 if (osbuf == NULL) {
5908 return A_NO_MEMORY;
5909 }
5910
5911 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD));
5912 ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf));
5913 A_MEMZERO(ns, sizeof(*ns));
5914
5915 ns->num_sta = num_sta;
5916
5917 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG , num_sta));
5918 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG));
5919}
5920
5921/*
5922 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_MAC
5923 *
5924 * This command is used to send list of mac of STAs which will
5925 * be allowed to connect with this AP. When this list is empty
5926 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
5927 */
5928int
5929wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl)
5930{
5931 void *osbuf;
5932 WMI_AP_ACL_MAC_CMD *a;
5933
5934 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD));
5935 if (osbuf == NULL) {
5936 return A_NO_MEMORY;
5937 }
5938
5939 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD));
5940 a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf));
5941 A_MEMZERO(a, sizeof(*a));
5942 memcpy(a,acl,sizeof(*acl));
5943
5944 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG));
5945}
5946
5947/*
5948 * IOCTL: AR6000_XIOCTL_AP_SET_MLME
5949 *
5950 * This command is used to send list of mac of STAs which will
5951 * be allowed to connect with this AP. When this list is empty
5952 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
5953 */
5954int
5955wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason)
5956{
5957 void *osbuf;
5958 WMI_AP_SET_MLME_CMD *mlme;
5959
5960 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD));
5961 if (osbuf == NULL) {
5962 return A_NO_MEMORY;
5963 }
5964
5965 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD));
5966 mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf));
5967 A_MEMZERO(mlme, sizeof(*mlme));
5968
5969 mlme->cmd = cmd;
5970 memcpy(mlme->mac, mac, ATH_MAC_LEN);
5971 mlme->reason = reason;
5972
5973 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG));
5974}
5975
5976static int
5977wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5978{
5979 WMI_PSPOLL_EVENT *ev;
5980
5981 if (len < sizeof(WMI_PSPOLL_EVENT)) {
5982 return A_EINVAL;
5983 }
5984 ev = (WMI_PSPOLL_EVENT *)datap;
5985
5986 A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid);
5987 return 0;
5988}
5989
5990static int
5991wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,int len)
5992{
5993 A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt);
5994 return 0;
5995}
5996
5997#ifdef WAPI_ENABLE
5998static int
5999wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,int len)
6000{
6001 u8 *ev;
6002
6003 if (len < 7) {
6004 return A_EINVAL;
6005 }
6006 ev = (u8 *)datap;
6007
6008 A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]);
6009 return 0;
6010}
6011#endif
6012
6013int
6014wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag)
6015{
6016 WMI_AP_SET_PVB_CMD *cmd;
6017 void *osbuf = NULL;
6018
6019 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD));
6020 if (osbuf == NULL) {
6021 return A_NO_MEMORY;
6022 }
6023
6024 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD));
6025 cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf));
6026 A_MEMZERO(cmd, sizeof(*cmd));
6027
6028 cmd->aid = aid;
6029 cmd->flag = flag;
6030
6031 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG));
6032}
6033
6034int
6035wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period)
6036{
6037 WMI_AP_CONN_INACT_CMD *cmd;
6038 void *osbuf = NULL;
6039
6040 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD));
6041 if (osbuf == NULL) {
6042 return A_NO_MEMORY;
6043 }
6044
6045 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD));
6046 cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf));
6047 A_MEMZERO(cmd, sizeof(*cmd));
6048
6049 cmd->period = period;
6050
6051 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG));
6052}
6053
6054int
6055wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell)
6056{
6057 WMI_AP_PROT_SCAN_TIME_CMD *cmd;
6058 void *osbuf = NULL;
6059
6060 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6061 if (osbuf == NULL) {
6062 return A_NO_MEMORY;
6063 }
6064
6065 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6066 cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf));
6067 A_MEMZERO(cmd, sizeof(*cmd));
6068
6069 cmd->period_min = period;
6070 cmd->dwell_ms = dwell;
6071
6072 return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG));
6073}
6074
6075int
6076wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim)
6077{
6078 WMI_AP_SET_DTIM_CMD *cmd;
6079 void *osbuf = NULL;
6080
6081 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD));
6082 if (osbuf == NULL) {
6083 return A_NO_MEMORY;
6084 }
6085
6086 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD));
6087 cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf));
6088 A_MEMZERO(cmd, sizeof(*cmd));
6089
6090 cmd->dtim = dtim;
6091
6092 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG));
6093}
6094
6095/*
6096 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_POLICY
6097 *
6098 * This command is used to set ACL policay. While changing policy, if you
6099 * want to retain the existing MAC addresses in the ACL list, policy should be
6100 * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared.
6101 * If there is no chage in policy, the list will be intact.
6102 */
6103int
6104wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy)
6105{
6106 void *osbuf;
6107 WMI_AP_ACL_POLICY_CMD *po;
6108
6109 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD));
6110 if (osbuf == NULL) {
6111 return A_NO_MEMORY;
6112}
6113
6114 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD));
6115 po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
6116 A_MEMZERO(po, sizeof(*po));
6117
6118 po->policy = policy;
6119
6120 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG));
6121}
6122
6123int
6124wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset)
6125{
6126 void *osbuf;
6127 WMI_AP_SET_11BG_RATESET_CMD *rs;
6128
6129 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6130 if (osbuf == NULL) {
6131 return A_NO_MEMORY;
6132 }
6133
6134 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6135 rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf));
6136 A_MEMZERO(rs, sizeof(*rs));
6137
6138 rs->rateset = rateset;
6139
6140 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG));
6141}
6142
6143int
6144wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
6145{
6146 void *osbuf;
6147 WMI_SET_HT_CAP_CMD *htCap;
6148 u8 band;
6149
6150 osbuf = A_NETBUF_ALLOC(sizeof(*htCap));
6151 if (osbuf == NULL) {
6152 return A_NO_MEMORY;
6153 }
6154
6155 A_NETBUF_PUT(osbuf, sizeof(*htCap));
6156
6157 band = (cmd->band)? A_BAND_5GHZ : A_BAND_24GHZ;
6158 wmip->wmi_ht_allowed[band] = (cmd->enable)? 1:0;
6159
6160 htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf));
6161 A_MEMZERO(htCap, sizeof(*htCap));
6162 memcpy(htCap, cmd, sizeof(*htCap));
6163
6164 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID,
6165 NO_SYNC_WMIFLAG));
6166}
6167
6168int
6169wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width)
6170{
6171 void *osbuf;
6172 WMI_SET_HT_OP_CMD *htInfo;
6173
6174 osbuf = A_NETBUF_ALLOC(sizeof(*htInfo));
6175 if (osbuf == NULL) {
6176 return A_NO_MEMORY;
6177 }
6178
6179 A_NETBUF_PUT(osbuf, sizeof(*htInfo));
6180
6181 htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf));
6182 A_MEMZERO(htInfo, sizeof(*htInfo));
6183 htInfo->sta_chan_width = sta_chan_width;
6184
6185 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID,
6186 NO_SYNC_WMIFLAG));
6187}
6188
6189int
6190wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray)
6191{
6192 void *osbuf;
6193 WMI_SET_TX_SELECT_RATES_CMD *pData;
6194
6195 osbuf = A_NETBUF_ALLOC(sizeof(*pData));
6196 if (osbuf == NULL) {
6197 return A_NO_MEMORY;
6198 }
6199
6200 A_NETBUF_PUT(osbuf, sizeof(*pData));
6201
6202 pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf));
6203 memcpy(pData, pMaskArray, sizeof(*pData));
6204
6205 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID,
6206 NO_SYNC_WMIFLAG));
6207}
6208
6209
6210int
6211wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz)
6212{
6213 void *osbuf;
6214 WMI_HCI_CMD *cmd;
6215
6216 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz);
6217 if (osbuf == NULL) {
6218 return A_NO_MEMORY;
6219 }
6220
6221 A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz);
6222 cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf));
6223
6224 cmd->cmd_buf_sz = sz;
6225 memcpy(cmd->buf, buf, sz);
6226 return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG));
6227}
6228
6229int
6230wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask)
6231{
6232 void *osbuf;
6233 WMI_ALLOW_AGGR_CMD *cmd;
6234
6235 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6236 if (osbuf == NULL) {
6237 return A_NO_MEMORY;
6238 }
6239
6240 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6241
6242 cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf));
6243 cmd->tx_allow_aggr = tx_tidmask;
6244 cmd->rx_allow_aggr = rx_tidmask;
6245
6246 return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG));
6247}
6248
6249int
6250wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid)
6251{
6252 void *osbuf;
6253 WMI_ADDBA_REQ_CMD *cmd;
6254
6255 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6256 if (osbuf == NULL) {
6257 return A_NO_MEMORY;
6258 }
6259
6260 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6261
6262 cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6263 cmd->tid = tid;
6264
6265 return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6266}
6267
6268int
6269wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink)
6270{
6271 void *osbuf;
6272 WMI_DELBA_REQ_CMD *cmd;
6273
6274 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6275 if (osbuf == NULL) {
6276 return A_NO_MEMORY;
6277 }
6278
6279 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6280
6281 cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6282 cmd->tid = tid;
6283 cmd->is_sender_initiator = uplink; /* uplink =1 - uplink direction, 0=downlink direction */
6284
6285 /* Delete the local aggr state, on host */
6286 return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6287}
6288
6289int
6290wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion,
6291 bool rxDot11Hdr, bool defragOnHost)
6292{
6293 void *osbuf;
6294 WMI_RX_FRAME_FORMAT_CMD *cmd;
6295
6296 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6297 if (osbuf == NULL) {
6298 return A_NO_MEMORY;
6299 }
6300
6301 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6302
6303 cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf));
6304 cmd->dot11Hdr = (rxDot11Hdr==true)? 1:0;
6305 cmd->defragOnHost = (defragOnHost==true)? 1:0;
6306 cmd->metaVersion = rxMetaVersion; /* */
6307
6308 /* Delete the local aggr state, on host */
6309 return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG));
6310}
6311
6312
6313int
6314wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode)
6315{
6316 void *osbuf;
6317 WMI_SET_THIN_MODE_CMD *cmd;
6318
6319 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6320 if (osbuf == NULL) {
6321 return A_NO_MEMORY;
6322 }
6323
6324 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6325
6326 cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf));
6327 cmd->enable = (bThinMode==true)? 1:0;
6328
6329 /* Delete the local aggr state, on host */
6330 return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG));
6331}
6332
6333
6334int
6335wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence)
6336{
6337 void *osbuf;
6338 WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd;
6339
6340 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6341 if (osbuf == NULL) {
6342 return A_NO_MEMORY;
6343 }
6344
6345 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6346
6347 cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf));
6348 A_MEMZERO(cmd, sizeof(*cmd));
6349 cmd->precedence = precedence;
6350
6351 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
6352 NO_SYNC_WMIFLAG));
6353}
6354
6355int
6356wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk)
6357{
6358 void *osbuf;
6359 WMI_SET_PMK_CMD *p;
6360
6361 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD));
6362 if (osbuf == NULL) {
6363 return A_NO_MEMORY;
6364 }
6365
6366 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD));
6367
6368 p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf));
6369 A_MEMZERO(p, sizeof(*p));
6370
6371 memcpy(p->pmk, pmk, WMI_PMK_LEN);
6372
6373 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG));
6374}
6375
6376int
6377wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd)
6378{
6379 void *osbuf;
6380 WMI_SET_EXCESS_TX_RETRY_THRES_CMD *p;
6381
6382 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD));
6383 if (osbuf == NULL) {
6384 return A_NO_MEMORY;
6385 }
6386
6387 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD));
6388
6389 p = (WMI_SET_EXCESS_TX_RETRY_THRES_CMD *)(A_NETBUF_DATA(osbuf));
6390 memset(p, 0, sizeof(*p));
6391
6392 p->threshold = cmd->threshold;
6393
6394 return (wmi_cmd_send(wmip, osbuf, WMI_SET_EXCESS_TX_RETRY_THRES_CMDID, NO_SYNC_WMIFLAG));
6395}
6396
6397int
6398wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold)
6399{
6400 void *osbuf;
6401 WMI_SET_TX_SGI_PARAM_CMD *cmd;
6402
6403 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6404 if (osbuf == NULL) {
6405 return A_NO_MEMORY ;
6406 }
6407
6408 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6409
6410 cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf));
6411 A_MEMZERO(cmd, sizeof(*cmd));
6412 cmd->sgiMask = sgiMask;
6413 cmd->sgiPERThreshold = sgiPERThreshold;
6414 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID,
6415 NO_SYNC_WMIFLAG));
6416}
6417
6418bss_t *
6419wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
6420 u32 ssidLength,
6421 u32 dot11AuthMode, u32 authMode,
6422 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp)
6423{
6424 bss_t *node = NULL;
6425 node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid,
6426 ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp);
6427
6428 return node;
6429}
6430
6431u16 wmi_ieee2freq (int chan)
6432{
6433 u16 freq = 0;
6434 freq = wlan_ieee2freq (chan);
6435 return freq;
6436
6437}
6438
6439u32 wmi_freq2ieee (u16 freq)
6440{
6441 u16 chan = 0;
6442 chan = wlan_freq2ieee (freq);
6443 return chan;
6444}
diff --git a/drivers/staging/ath6kl/wmi/wmi_host.h b/drivers/staging/ath6kl/wmi/wmi_host.h
new file mode 100644
index 00000000000..53e4f085dfe
--- /dev/null
+++ b/drivers/staging/ath6kl/wmi/wmi_host.h
@@ -0,0 +1,102 @@
1//------------------------------------------------------------------------------
2// <copyright file="wmi_host.h" company="Atheros">
3// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4//
5//
6// Permission to use, copy, modify, and/or distribute this software for any
7// purpose with or without fee is hereby granted, provided that the above
8// copyright notice and this permission notice appear in all copies.
9//
10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17//
18//
19//------------------------------------------------------------------------------
20//==============================================================================
21// This file contains local definitios for the wmi host module.
22//
23// Author(s): ="Atheros"
24//==============================================================================
25#ifndef _WMI_HOST_H_
26#define _WMI_HOST_H_
27
28#include "roaming.h"
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33struct wmi_stats {
34 u32 cmd_len_err;
35 u32 cmd_id_err;
36};
37
38#define SSID_IE_LEN_INDEX 13
39
40/* Host side link management data structures */
41#define SIGNAL_QUALITY_THRESHOLD_LEVELS 6
42#define SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS
43#define SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS
44typedef struct sq_threshold_params_s {
45 s16 upper_threshold[SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS];
46 s16 lower_threshold[SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS];
47 u32 upper_threshold_valid_count;
48 u32 lower_threshold_valid_count;
49 u32 polling_interval;
50 u8 weight;
51 u8 last_rssi; //normally you would expect this to be bss specific but we keep only one instance because its only valid when the device is in a connected state. Not sure if it belongs to host or target.
52 u8 last_rssi_poll_event; //Not sure if it belongs to host or target
53} SQ_THRESHOLD_PARAMS;
54
55/*
56 * These constants are used with A_WLAN_BAND_SET.
57 */
58#define A_BAND_24GHZ 0
59#define A_BAND_5GHZ 1
60#define A_NUM_BANDS 2
61
62struct wmi_t {
63 bool wmi_ready;
64 bool wmi_numQoSStream;
65 u16 wmi_streamExistsForAC[WMM_NUM_AC];
66 u8 wmi_fatPipeExists;
67 void *wmi_devt;
68 struct wmi_stats wmi_stats;
69 struct ieee80211_node_table wmi_scan_table;
70 u8 wmi_bssid[ATH_MAC_LEN];
71 u8 wmi_powerMode;
72 u8 wmi_phyMode;
73 u8 wmi_keepaliveInterval;
74#ifdef THREAD_X
75 A_CSECT_T wmi_lock;
76#else
77 A_MUTEX_T wmi_lock;
78#endif
79 HTC_ENDPOINT_ID wmi_endpoint_id;
80 SQ_THRESHOLD_PARAMS wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_NUM_MAX];
81 CRYPTO_TYPE wmi_pair_crypto_type;
82 CRYPTO_TYPE wmi_grp_crypto_type;
83 bool wmi_is_wmm_enabled;
84 u8 wmi_ht_allowed[A_NUM_BANDS];
85 u8 wmi_traffic_class;
86};
87
88#ifdef THREAD_X
89#define INIT_WMI_LOCK(w) A_CSECT_INIT(&(w)->wmi_lock)
90#define LOCK_WMI(w) A_CSECT_ENTER(&(w)->wmi_lock);
91#define UNLOCK_WMI(w) A_CSECT_LEAVE(&(w)->wmi_lock);
92#define DELETE_WMI_LOCK(w) A_CSECT_DELETE(&(w)->wmi_lock);
93#else
94#define LOCK_WMI(w) A_MUTEX_LOCK(&(w)->wmi_lock);
95#define UNLOCK_WMI(w) A_MUTEX_UNLOCK(&(w)->wmi_lock);
96#endif
97
98#ifdef __cplusplus
99}
100#endif
101
102#endif /* _WMI_HOST_H_ */