diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/staging/ath6kl | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/staging/ath6kl')
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 @@ | |||
1 | config 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 | |||
10 | choice | ||
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 | |||
17 | config AR600x_SD31_XXX | ||
18 | bool "SD31-xxx" | ||
19 | help | ||
20 | Board Data file for a standard SD31 reference design (File: bdata.SD31.bin) | ||
21 | |||
22 | config 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 | |||
27 | config 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 | |||
32 | config 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) | ||
36 | endchoice | ||
37 | |||
38 | config 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 | |||
44 | choice | ||
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 | |||
51 | config AR600x_DUAL_ANTENNA | ||
52 | bool "Dual Antenna" | ||
53 | help | ||
54 | Dual Antenna Design | ||
55 | |||
56 | config AR600x_SINGLE_ANTENNA | ||
57 | bool "Single Antenna" | ||
58 | help | ||
59 | Single Antenna Design | ||
60 | endchoice | ||
61 | |||
62 | choice | ||
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 | |||
69 | config AR600x_BT_QCOM | ||
70 | bool "Qualcomm BTS4020X" | ||
71 | help | ||
72 | Qualcomm BT (3 Wire PTA) | ||
73 | |||
74 | config AR600x_BT_CSR | ||
75 | bool "CSR BC06" | ||
76 | help | ||
77 | CSR BT (3 Wire PTA) | ||
78 | |||
79 | config AR600x_BT_AR3001 | ||
80 | bool "Atheros AR3001" | ||
81 | help | ||
82 | Atheros BT (3 Wire PTA) | ||
83 | endchoice | ||
84 | |||
85 | config 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 | |||
91 | config 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 | |||
97 | config 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 | |||
104 | config 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 | |||
110 | config 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 | |||
116 | config 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 | |||
122 | config 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 | |||
129 | config ATH6KL_DEBUG | ||
130 | bool "Debug support" | ||
131 | depends on ATH6K_LEGACY | ||
132 | help | ||
133 | Enables debug support | ||
134 | |||
135 | config ATH6KL_ENABLE_HOST_DEBUG | ||
136 | bool "Host Debug support" | ||
137 | depends on ATH6KL_DEBUG | ||
138 | help | ||
139 | Enables debug support in the driver | ||
140 | |||
141 | config 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 | |||
147 | config 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 | |||
154 | config 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 | |||
24 | ccflags-y += -I$(obj)/include | ||
25 | ccflags-y += -I$(obj)/include/common | ||
26 | ccflags-y += -I$(obj)/wlan/include | ||
27 | ccflags-y += -I$(obj)/os/linux/include | ||
28 | ccflags-y += -I$(obj)/os | ||
29 | ccflags-y += -I$(obj)/bmi/include | ||
30 | ccflags-y += -I$(obj)/include/common/AR6002/hw4.0 | ||
31 | |||
32 | ifeq ($(CONFIG_AR600x_DUAL_ANTENNA),y) | ||
33 | ccflags-y += -DAR600x_DUAL_ANTENNA | ||
34 | endif | ||
35 | |||
36 | ifeq ($(CONFIG_AR600x_SINGLE_ANTENNA),y) | ||
37 | ccflags-y += -DAR600x_SINGLE_ANTENNA | ||
38 | endif | ||
39 | |||
40 | ifeq ($(CONFIG_AR600x_BT_QCOM),y) | ||
41 | ccflags-y += -DAR600x_BT_QCOM | ||
42 | endif | ||
43 | |||
44 | ifeq ($(CONFIG_AR600x_BT_CSR),y) | ||
45 | ccflags-y += -DAR600x_BT_CSR | ||
46 | endif | ||
47 | |||
48 | ifeq ($(CONFIG_AR600x_BT_AR3001),y) | ||
49 | ccflags-y += -DAR600x_BT_AR3001 | ||
50 | endif | ||
51 | |||
52 | ifeq ($(CONFIG_ATH6KL_HCI_BRIDGE),y) | ||
53 | ccflags-y += -DATH_AR6K_ENABLE_GMBOX | ||
54 | ccflags-y += -DHCI_TRANSPORT_SDIO | ||
55 | ccflags-y += -DSETUPHCI_ENABLED | ||
56 | ccflags-y += -DSETUPBTDEV_ENABLED | ||
57 | ath6kl-y += htc2/AR6000/ar6k_gmbox.o | ||
58 | ath6kl-y += htc2/AR6000/ar6k_gmbox_hciuart.o | ||
59 | ath6kl-y += miscdrv/ar3kconfig.o | ||
60 | ath6kl-y += miscdrv/ar3kps/ar3kpsconfig.o | ||
61 | ath6kl-y += miscdrv/ar3kps/ar3kpsparser.o | ||
62 | endif | ||
63 | |||
64 | ifeq ($(CONFIG_ATH6KL_CONFIG_GPIO_BT_RESET),y) | ||
65 | ccflags-y += -DATH6KL_CONFIG_GPIO_BT_RESET | ||
66 | endif | ||
67 | |||
68 | ifeq ($(CONFIG_ATH6KL_HTC_RAW_INTERFACE),y) | ||
69 | ccflags-y += -DHTC_RAW_INTERFACE | ||
70 | endif | ||
71 | |||
72 | ifeq ($(CONFIG_ATH6KL_ENABLE_HOST_DEBUG),y) | ||
73 | ccflags-y += -DDEBUG | ||
74 | ccflags-y += -DATH_DEBUG_MODULE | ||
75 | endif | ||
76 | |||
77 | ifeq ($(CONFIG_ATH6KL_ENABLE_TARGET_DEBUG_PRINTS),y) | ||
78 | ccflags-y += -DENABLEUARTPRINT_SET | ||
79 | endif | ||
80 | |||
81 | ifeq ($(CONFIG_ATH6KL_DISABLE_TARGET_DBGLOGS),y) | ||
82 | ccflags-y += -DATH6KL_DISABLE_TARGET_DBGLOGS | ||
83 | endif | ||
84 | |||
85 | ifeq ($(CONFIG_ATH6KL_VIRTUAL_SCATTER_GATHER),y) | ||
86 | ccflags-y += -DATH6KL_CONFIG_HIF_VIRTUAL_SCATTER | ||
87 | endif | ||
88 | |||
89 | ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y) | ||
90 | ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK | ||
91 | endif | ||
92 | |||
93 | ccflags-y += -DWAPI_ENABLE | ||
94 | ccflags-y += -DCHECKSUM_OFFLOAD | ||
95 | |||
96 | obj-$(CONFIG_ATH6K_LEGACY) := ath6kl.o | ||
97 | ath6kl-y += htc2/AR6000/ar6k.o | ||
98 | ath6kl-y += htc2/AR6000/ar6k_events.o | ||
99 | ath6kl-y += htc2/htc_send.o | ||
100 | ath6kl-y += htc2/htc_recv.o | ||
101 | ath6kl-y += htc2/htc_services.o | ||
102 | ath6kl-y += htc2/htc.o | ||
103 | ath6kl-y += bmi/src/bmi.o | ||
104 | ath6kl-y += os/linux/cfg80211.o | ||
105 | ath6kl-y += os/linux/ar6000_drv.o | ||
106 | ath6kl-y += os/linux/ar6000_raw_if.o | ||
107 | ath6kl-y += os/linux/ar6000_pm.o | ||
108 | ath6kl-y += os/linux/netbuf.o | ||
109 | ath6kl-y += os/linux/hci_bridge.o | ||
110 | ath6kl-y += miscdrv/common_drv.o | ||
111 | ath6kl-y += miscdrv/credit_dist.o | ||
112 | ath6kl-y += wmi/wmi.o | ||
113 | ath6kl-y += reorder/rcv_aggr.o | ||
114 | ath6kl-y += wlan/src/wlan_node.o | ||
115 | ath6kl-y += wlan/src/wlan_recv_beacon.o | ||
116 | ath6kl-y += wlan/src/wlan_utils.o | ||
117 | |||
118 | # ATH_HIF_TYPE := sdio | ||
119 | ccflags-y += -I$(obj)/hif/sdio/linux_sdio/include | ||
120 | ccflags-y += -DSDIO | ||
121 | ath6kl-y += hif/sdio/linux_sdio/src/hif.o | ||
122 | ath6kl-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 @@ | |||
1 | TODO: | ||
2 | |||
3 | We are working hard on cleaning up the driver. There's sooooooooo much todo | ||
4 | so instead of editing this file please use the wiki: | ||
5 | |||
6 | http://wireless.kernel.org/en/users/Drivers/ath6kl | ||
7 | |||
8 | There's a respective TODO page there. Please also subscribe to the wiki page | ||
9 | to get e-mail updates on changes. | ||
10 | |||
11 | IRC: | ||
12 | |||
13 | We *really* need to coordinate development for ath6kl as the cleanup | ||
14 | patches will break pretty much any other patches. Please use IRC to | ||
15 | help coordinate better: | ||
16 | |||
17 | irc.freenode.net | ||
18 | #ath6kl | ||
19 | |||
20 | Send 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 ------- */ | ||
41 | static bool bmiDone; | ||
42 | |||
43 | int | ||
44 | bmiBufferSend(struct hif_device *device, | ||
45 | u8 *buffer, | ||
46 | u32 length); | ||
47 | |||
48 | int | ||
49 | bmiBufferReceive(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 | ||
36 | static struct ath_debug_mask_description bmi_debug_desc[] = { | ||
37 | { ATH_DEBUG_BMI , "BMI Tracing"}, | ||
38 | }; | ||
39 | |||
40 | ATH_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 | /* | ||
50 | Although we had envisioned BMI to run on top of HTC, this is not how the | ||
51 | final implementation ended up. On the Target side, BMI is a part of the BSP | ||
52 | and does not use the HTC protocol nor even DMA -- it is intentionally kept | ||
53 | very simple. | ||
54 | */ | ||
55 | |||
56 | static bool pendingEventsFuncCheck = false; | ||
57 | static u32 *pBMICmdCredits; | ||
58 | static 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 */ | ||
66 | void | ||
67 | BMIInit(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 | |||
94 | void | ||
95 | BMICleanup(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 | |||
108 | int | ||
109 | BMIDone(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 | |||
144 | int | ||
145 | BMIGetTargetInfo(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 | |||
203 | int | ||
204 | BMIReadMemory(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 | |||
259 | int | ||
260 | BMIWriteMemory(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 | |||
324 | int | ||
325 | BMIExecute(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 | |||
372 | int | ||
373 | BMISetAppStart(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 | |||
409 | int | ||
410 | BMIReadSOCRegister(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 | |||
455 | int | ||
456 | BMIWriteSOCRegister(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]), ¶m, 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 | |||
495 | int | ||
496 | BMIrompatchInstall(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 | |||
551 | int | ||
552 | BMIrompatchUninstall(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 | |||
588 | static 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 | |||
632 | int | ||
633 | BMIrompatchActivate(struct hif_device *device, | ||
634 | u32 rompatch_count, | ||
635 | u32 *rompatch_list) | ||
636 | { | ||
637 | return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1); | ||
638 | } | ||
639 | |||
640 | int | ||
641 | BMIrompatchDeactivate(struct hif_device *device, | ||
642 | u32 rompatch_count, | ||
643 | u32 *rompatch_list) | ||
644 | { | ||
645 | return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0); | ||
646 | } | ||
647 | |||
648 | int | ||
649 | BMILZData(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 | |||
698 | int | ||
699 | BMILZStreamStart(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 */ | ||
736 | int | ||
737 | bmiBufferSend(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 | |||
784 | int | ||
785 | bmiBufferReceive(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 | |||
960 | int | ||
961 | BMIFastDownload(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 | |||
1000 | int | ||
1001 | BMIRawWrite(struct hif_device *device, u8 *buffer, u32 length) | ||
1002 | { | ||
1003 | return bmiBufferSend(device, buffer, length); | ||
1004 | } | ||
1005 | |||
1006 | int | ||
1007 | BMIRawRead(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 */ | ||
61 | static 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 | |||
49 | typedef 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 | |||
62 | struct 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 | |||
90 | BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device); | ||
91 | void hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest); | ||
92 | void 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 | |||
100 | struct 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 | |||
110 | int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo); | ||
111 | void CleanupHIFScatterResources(struct hif_device *device); | ||
112 | int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest); | ||
113 | |||
114 | #else // HIF_LINUX_MMC_SCATTER_SUPPORT | ||
115 | |||
116 | static inline int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo) | ||
117 | { | ||
118 | return A_ENOTSUP; | ||
119 | } | ||
120 | |||
121 | static 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 */ | ||
57 | static void delHifDevice(struct hif_device * device); | ||
58 | static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte); | ||
59 | static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte); | ||
60 | |||
61 | static int hifEnableFunc(struct hif_device *device, struct sdio_func *func); | ||
62 | static int hifDisableFunc(struct hif_device *device, struct sdio_func *func); | ||
63 | OSDRV_CALLBACKS osdrvCallbacks; | ||
64 | |||
65 | int reset_sdio_on_unload = 0; | ||
66 | module_param(reset_sdio_on_unload, int, 0644); | ||
67 | |||
68 | extern u32 nohifscattersupport; | ||
69 | |||
70 | static 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 | |||
86 | static struct hif_device *ath6kl_get_hifdev(struct sdio_func *func) | ||
87 | { | ||
88 | return (struct hif_device *) sdio_get_drvdata(func); | ||
89 | } | ||
90 | |||
91 | static 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 | |||
99 | MODULE_DEVICE_TABLE(sdio, ath6kl_hifdev_ids); | ||
100 | |||
101 | static 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 | |||
143 | static 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) | ||
164 | static 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 | |||
195 | static 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 | |||
213 | static const struct dev_pm_ops ath6kl_hifdev_pmops = { | ||
214 | .suspend = ath6kl_hifdev_suspend, | ||
215 | .resume = ath6kl_hifdev_resume, | ||
216 | }; | ||
217 | #endif /* CONFIG_PM */ | ||
218 | |||
219 | static 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. */ | ||
232 | static int registered = 0; | ||
233 | |||
234 | extern u32 onebitmode; | ||
235 | extern u32 busspeedlow; | ||
236 | extern u32 debughif; | ||
237 | |||
238 | static void ResetAllCards(void); | ||
239 | |||
240 | #ifdef DEBUG | ||
241 | |||
242 | ATH_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 ------ */ | ||
253 | int 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 | |||
273 | static 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 | |||
425 | void 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 */ | ||
450 | int | ||
451 | HIFReadWrite(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 */ | ||
519 | static 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 | |||
586 | static 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 | |||
609 | int 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 | |||
768 | int | ||
769 | PowerStateChangeNotify(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 | |||
811 | int | ||
812 | HIFConfigureDevice(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 | |||
865 | void | ||
866 | HIFShutDownDevice(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 | |||
892 | static void | ||
893 | hifIRQHandler(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*/ | ||
911 | static 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) | ||
925 | static 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 | |||
944 | void | ||
945 | HIFAckInterrupt(struct hif_device *device) | ||
946 | { | ||
947 | AR_DEBUG_ASSERT(device != NULL); | ||
948 | |||
949 | /* Acknowledge our function IRQ */ | ||
950 | } | ||
951 | |||
952 | void | ||
953 | HIFUnMaskInterrupt(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 | |||
969 | void 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 | |||
989 | BUS_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 | |||
1008 | void | ||
1009 | hifFreeBusRequest(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 | |||
1028 | static 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 | |||
1075 | static 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 | */ | ||
1158 | int 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 | |||
1188 | static void | ||
1189 | delHifDevice(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 | |||
1197 | static void ResetAllCards(void) | ||
1198 | { | ||
1199 | } | ||
1200 | |||
1201 | void HIFClaimDevice(struct hif_device *device, void *context) | ||
1202 | { | ||
1203 | device->claimedContext = context; | ||
1204 | } | ||
1205 | |||
1206 | void HIFReleaseDevice(struct hif_device *device) | ||
1207 | { | ||
1208 | device->claimedContext = NULL; | ||
1209 | } | ||
1210 | |||
1211 | int 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 | |||
1221 | void 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 | |||
1240 | static 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 | |||
1254 | static 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 | |||
51 | static 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 | |||
63 | static 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 */ | ||
82 | int 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 */ | ||
202 | static 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 */ | ||
278 | int 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 */ | ||
359 | void 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 | |||
37 | int DevEnableInterrupts(struct ar6k_device *pDev); | ||
38 | int DevDisableInterrupts(struct ar6k_device *pDev); | ||
39 | |||
40 | static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev); | ||
41 | |||
42 | void 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 | |||
49 | struct 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 | |||
60 | void 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 | |||
76 | int 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 | |||
218 | int 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(®s,&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 | ®s.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 | |||
278 | int 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(®s,&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 | ®s.int_status_enable, | ||
297 | AR6K_IRQ_ENABLE_REGS_SIZE, | ||
298 | HIF_WR_SYNC_BYTE_INC, | ||
299 | NULL); | ||
300 | } | ||
301 | |||
302 | /* enable device interrupts */ | ||
303 | int 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 */ | ||
329 | int 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 */ | ||
339 | static 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 */ | ||
357 | static 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 */ | ||
405 | static 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(®s,&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,®s,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 | ®s.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 | |||
472 | int 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 | |||
481 | int 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 | |||
490 | int 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 | |||
538 | void 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 | |||
589 | static 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 | |||
602 | static 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 | |||
610 | int 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 | |||
650 | static 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 | |||
666 | static 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 | |||
736 | static 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 */ | ||
751 | static 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 | |||
812 | int DevCleanupMsgBundling(struct ar6k_device *pDev) | ||
813 | { | ||
814 | if(NULL != pDev) | ||
815 | { | ||
816 | DevCleanupVirtualScatterSupport(pDev); | ||
817 | } | ||
818 | |||
819 | return 0; | ||
820 | } | ||
821 | |||
822 | int 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 | |||
887 | int 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 | |||
1013 | static u8 g_Buffer[TOTAL_BYTES]; | ||
1014 | static u32 g_MailboxAddrs[AR6K_MAILBOXES]; | ||
1015 | static u32 g_BlockSizes[AR6K_MAILBOXES]; | ||
1016 | |||
1017 | #define BUFFER_PROC_LIST_DEPTH 4 | ||
1018 | |||
1019 | struct 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 */ | ||
1034 | static 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 | ||
1051 | static 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 | |||
1067 | static 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 | |||
1093 | static 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 */ | ||
1116 | static 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 */ | ||
1136 | static 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 */ | ||
1180 | static 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 */ | ||
1227 | static 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 | |||
1305 | static 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 */ | ||
1341 | int 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 | |||
45 | PREPACK 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 | |||
60 | PREPACK 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 | |||
67 | PREPACK 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 */ | ||
89 | struct 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 | |||
96 | struct 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 | |||
105 | struct 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 | |||
147 | int DevSetup(struct ar6k_device *pDev); | ||
148 | void DevCleanup(struct ar6k_device *pDev); | ||
149 | int DevUnmaskInterrupts(struct ar6k_device *pDev); | ||
150 | int DevMaskInterrupts(struct ar6k_device *pDev); | ||
151 | int DevPollMboxMsgRecv(struct ar6k_device *pDev, | ||
152 | u32 *pLookAhead, | ||
153 | int TimeoutMS); | ||
154 | int DevRWCompletionHandler(void *context, int status); | ||
155 | int DevDsrHandler(void *context); | ||
156 | int DevCheckPendingRecvMsgsAsync(void *context); | ||
157 | void DevAsyncIrqProcessComplete(struct ar6k_device *pDev); | ||
158 | void 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 | ||
166 | int DevStopRecv(struct ar6k_device *pDev, bool ASyncMode); | ||
167 | int DevEnableRecv(struct ar6k_device *pDev, bool ASyncMode); | ||
168 | int DevEnableInterrupts(struct ar6k_device *pDev); | ||
169 | int DevDisableInterrupts(struct ar6k_device *pDev); | ||
170 | int 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 | |||
176 | static 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 | |||
219 | static 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 | |||
272 | int 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) \ | ||
276 | do { \ | ||
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 */ | ||
287 | static 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 | |||
296 | int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer); | ||
297 | |||
298 | int 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 | ||
315 | int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async); | ||
316 | |||
317 | #ifdef MBOXHW_UNIT_TEST | ||
318 | int DoMboxHWTest(struct ar6k_device *pDev); | ||
319 | #endif | ||
320 | |||
321 | /* completely virtual */ | ||
322 | struct 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 | |||
329 | void DumpAR6KDevState(struct ar6k_device *pDev); | ||
330 | |||
331 | /**************************************************/ | ||
332 | /****** GMBOX functions and definitions | ||
333 | * | ||
334 | * | ||
335 | */ | ||
336 | |||
337 | #ifdef ATH_AR6K_ENABLE_GMBOX | ||
338 | |||
339 | void DevCleanupGMbox(struct ar6k_device *pDev); | ||
340 | int DevSetupGMbox(struct ar6k_device *pDev); | ||
341 | int DevCheckGMboxInterrupts(struct ar6k_device *pDev); | ||
342 | void 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 | |||
351 | static 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 */ | ||
361 | HCI_TRANSPORT_HANDLE GMboxAttachProtocol(struct ar6k_device *pDev, struct hci_transport_config_info *pInfo); | ||
362 | int GMboxProtocolInstall(struct ar6k_device *pDev); | ||
363 | void GMboxProtocolUninstall(struct ar6k_device *pDev); | ||
364 | |||
365 | /* API used by GMBOX protocol modules */ | ||
366 | struct 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 | |||
378 | int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength); | ||
379 | int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength); | ||
380 | |||
381 | #define PROC_IO_ASYNC true | ||
382 | #define PROC_IO_SYNC false | ||
383 | typedef 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 | |||
393 | int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode); | ||
394 | int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits); | ||
395 | int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize); | ||
396 | int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes); | ||
397 | int 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 | |||
35 | extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket); | ||
36 | extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev); | ||
37 | |||
38 | static 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 */ | ||
43 | int 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 */ | ||
61 | int 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 | |||
154 | static 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 | |||
194 | static 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 | |||
247 | static 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 | |||
277 | static 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 */ | ||
302 | static 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 */ | ||
390 | int 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 | |||
462 | void 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 */ | ||
469 | static 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.*/ | ||
683 | int 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 | ||
746 | void 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(®s,&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,®s); | ||
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 */ | ||
56 | extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket); | ||
57 | extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev); | ||
58 | |||
59 | |||
60 | /* callback when our fetch to enable/disable completes */ | ||
61 | static 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 | |||
76 | static 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(®s,&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 | ®s.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 | |||
157 | int 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 | |||
263 | void DevCleanupGMbox(struct ar6k_device *pDev) | ||
264 | { | ||
265 | if (pDev->GMboxEnabled) { | ||
266 | pDev->GMboxEnabled = false; | ||
267 | GMboxProtocolUninstall(pDev); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | int 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 | |||
324 | int 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 | |||
398 | int 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 | |||
435 | int 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 | |||
479 | static 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 */ | ||
518 | static 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 | |||
541 | int 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 | |||
604 | int 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 | |||
628 | void 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 | |||
636 | int 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 | |||
678 | int 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 | |||
58 | struct 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) \ | ||
85 | do { \ | ||
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 | |||
101 | static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous); | ||
102 | |||
103 | static 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 | |||
113 | static 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 | |||
191 | static 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 | |||
276 | static 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 | |||
283 | static 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 | |||
291 | static 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 | |||
306 | static 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 | |||
534 | static 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 | |||
549 | static 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 | |||
581 | static 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 | |||
796 | static 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 | |||
820 | static 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 | |||
848 | int 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 ***/ | ||
891 | void 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 | |||
910 | static 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 | |||
938 | HCI_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 | |||
983 | void 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 | |||
1003 | int 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 | |||
1071 | int 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 | |||
1078 | void 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 | |||
1104 | int 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 | |||
1151 | int 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 | |||
1160 | int 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 | ||
1232 | int 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 | |||
1263 | int 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 | ||
26 | static 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 | |||
34 | ATH_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 | |||
43 | static void HTCReportFailure(void *Context); | ||
44 | static void ResetEndpointStates(struct htc_target *target); | ||
45 | |||
46 | void 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 | |||
53 | struct 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 */ | ||
65 | static 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 */ | ||
93 | HTC_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 | |||
207 | void 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 */ | ||
217 | void *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 */ | ||
225 | int 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 */ | ||
372 | int 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 | |||
439 | static 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 */ | ||
462 | void 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 | ||
495 | void 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) */ | ||
510 | static 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 | |||
522 | bool 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 | |||
570 | struct 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 | ||
32 | extern "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 | |||
66 | struct 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 | |||
93 | struct 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 */ | ||
102 | struct 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 */ | ||
156 | void HTCControlTxComplete(void *Context, struct htc_packet *pPacket); | ||
157 | void HTCControlRecv(void *Context, struct htc_packet *pPacket); | ||
158 | int HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket); | ||
159 | struct htc_packet *HTCAllocControlBuffer(struct htc_target *target, struct htc_packet_queue *pList); | ||
160 | void HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList); | ||
161 | int HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket); | ||
162 | void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket); | ||
163 | int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched); | ||
164 | void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint); | ||
165 | int HTCSendSetupComplete(struct htc_target *target); | ||
166 | void HTCFlushRecvBuffers(struct htc_target *target); | ||
167 | void HTCFlushSendPkts(struct htc_target *target); | ||
168 | |||
169 | #ifdef ATH_DEBUG_MODULE | ||
170 | void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist); | ||
171 | void DumpCreditDistStates(struct htc_target *target); | ||
172 | void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription); | ||
173 | #endif | ||
174 | |||
175 | static 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 | |||
49 | static 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 | |||
82 | static 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 */ | ||
225 | static 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 | |||
384 | static 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 */ | ||
431 | static 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 */ | ||
495 | static 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 */ | ||
514 | void 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. */ | ||
586 | int 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 | |||
685 | static 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 | |||
878 | static 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 | |||
981 | static 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 | |||
1099 | static 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 */ | ||
1114 | int 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 | |||
1382 | int 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 */ | ||
1452 | int 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 | |||
1459 | void 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 | |||
1483 | static 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 | |||
1509 | static 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 | |||
1517 | void 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 | |||
1533 | void 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 | |||
1543 | void 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 | |||
1553 | int 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 | |||
1560 | int 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 | |||
25 | typedef 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 | |||
46 | static 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 */ | ||
80 | static 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 */ | ||
104 | static 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 | |||
116 | int 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 */ | ||
149 | static 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 | |||
267 | static 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 | * */ | ||
312 | static 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 */ | ||
480 | static 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 | |||
671 | int 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 */ | ||
712 | int 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 */ | ||
724 | static 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 */ | ||
756 | void 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 */ | ||
836 | static 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 | |||
877 | void 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 | |||
897 | void 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 */ | ||
915 | void 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*/ | ||
937 | void 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 */ | ||
952 | void 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 | |||
1003 | bool 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 | |||
25 | void 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 */ | ||
33 | void 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 | |||
60 | int 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 | |||
124 | int 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 | |||
310 | static 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 */ | ||
338 | static 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 */ | ||
381 | void 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 | |||
404 | void 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 | ||
27 | extern "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 | |||
59 | void 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 | |||
120 | struct 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 | |||
127 | typedef 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) \ | ||
147 | ATH_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 | ||
151 | extern 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 | |||
165 | void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo); | ||
166 | void 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 | |||
183 | int a_get_module_mask(char *module_name, u32 *pMask); | ||
184 | int a_set_module_mask(char *module_name, u32 Mask); | ||
185 | void a_dump_module_debug_info_by_name(char *module_name); | ||
186 | void a_module_debug_support_init(void); | ||
187 | void 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 | ||
27 | extern "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 | ||
28 | extern "C" { | ||
29 | #endif | ||
30 | |||
31 | typedef void (* RX_CALLBACK)(void * dev, void *osbuf); | ||
32 | |||
33 | typedef 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 | */ | ||
43 | void * | ||
44 | aggr_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 | */ | ||
55 | void | ||
56 | aggr_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 | */ | ||
66 | void | ||
67 | aggr_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 | */ | ||
84 | void | ||
85 | aggr_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 | */ | ||
95 | void | ||
96 | aggr_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 | */ | ||
110 | void | ||
111 | aggr_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 | */ | ||
118 | void | ||
119 | aggr_module_destroy(void *cntxt); | ||
120 | |||
121 | /* | ||
122 | * Dumps the aggregation stats | ||
123 | */ | ||
124 | void | ||
125 | aggr_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 | */ | ||
132 | void | ||
133 | aggr_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 | ||
32 | extern "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 | |||
41 | struct 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 | |||
57 | int AR3KConfigure(struct ar3k_config_info *pConfigInfo); | ||
58 | |||
59 | int 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 | |||
28 | int | ||
29 | ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); | ||
30 | |||
31 | int | ||
32 | ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); | ||
33 | |||
34 | int | ||
35 | ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address, | ||
36 | u8 *data, u32 length); | ||
37 | |||
38 | int | ||
39 | ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address, | ||
40 | u8 *data, u32 length); | ||
41 | |||
42 | int | ||
43 | ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval); | ||
44 | |||
45 | void | ||
46 | ar6k_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 | */ | ||
34 | typedef struct { | ||
35 | u8 mac[ATH_MAC_LEN]; | ||
36 | u8 aid; | ||
37 | u8 keymgmt; | ||
38 | u8 ucipher; | ||
39 | u8 auth; | ||
40 | } station_t; | ||
41 | typedef 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 | |||
30 | typedef enum _ATHBT_HCI_CTRL_TYPE { | ||
31 | ATHBT_HCI_COMMAND = 0, | ||
32 | ATHBT_HCI_EVENT = 1, | ||
33 | } ATHBT_HCI_CTRL_TYPE; | ||
34 | |||
35 | typedef 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 */ | ||
49 | typedef 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 */ | ||
52 | typedef void (*ATHBT_FILTER_DATA_FN)(void *pContext, unsigned char *pBuffer, int Length); | ||
53 | |||
54 | typedef 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 | |||
62 | typedef void (*ATHBT_INDICATE_STATE_FN)(void *pContext, ATHBT_STATE_INDICATION Indication, ATHBT_STATE State, unsigned char LMPVersion); | ||
63 | |||
64 | struct 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 | ||
124 | extern "C" { | ||
125 | #endif | ||
126 | |||
127 | /* API prototypes */ | ||
128 | int AthBtFilter_Attach(ATH_BT_FILTER_INSTANCE *pInstance, unsigned int flags); | ||
129 | void 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 | ||
29 | extern "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 | |||
39 | void | ||
40 | BMIInit(void); | ||
41 | |||
42 | void | ||
43 | BMICleanup(void); | ||
44 | |||
45 | int | ||
46 | BMIDone(struct hif_device *device); | ||
47 | |||
48 | int | ||
49 | BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info); | ||
50 | |||
51 | int | ||
52 | BMIReadMemory(struct hif_device *device, | ||
53 | u32 address, | ||
54 | u8 *buffer, | ||
55 | u32 length); | ||
56 | |||
57 | int | ||
58 | BMIWriteMemory(struct hif_device *device, | ||
59 | u32 address, | ||
60 | u8 *buffer, | ||
61 | u32 length); | ||
62 | |||
63 | int | ||
64 | BMIExecute(struct hif_device *device, | ||
65 | u32 address, | ||
66 | u32 *param); | ||
67 | |||
68 | int | ||
69 | BMISetAppStart(struct hif_device *device, | ||
70 | u32 address); | ||
71 | |||
72 | int | ||
73 | BMIReadSOCRegister(struct hif_device *device, | ||
74 | u32 address, | ||
75 | u32 *param); | ||
76 | |||
77 | int | ||
78 | BMIWriteSOCRegister(struct hif_device *device, | ||
79 | u32 address, | ||
80 | u32 param); | ||
81 | |||
82 | int | ||
83 | BMIrompatchInstall(struct hif_device *device, | ||
84 | u32 ROM_addr, | ||
85 | u32 RAM_addr, | ||
86 | u32 nbytes, | ||
87 | u32 do_activate, | ||
88 | u32 *patch_id); | ||
89 | |||
90 | int | ||
91 | BMIrompatchUninstall(struct hif_device *device, | ||
92 | u32 rompatch_id); | ||
93 | |||
94 | int | ||
95 | BMIrompatchActivate(struct hif_device *device, | ||
96 | u32 rompatch_count, | ||
97 | u32 *rompatch_list); | ||
98 | |||
99 | int | ||
100 | BMIrompatchDeactivate(struct hif_device *device, | ||
101 | u32 rompatch_count, | ||
102 | u32 *rompatch_list); | ||
103 | |||
104 | int | ||
105 | BMILZStreamStart(struct hif_device *device, | ||
106 | u32 address); | ||
107 | |||
108 | int | ||
109 | BMILZData(struct hif_device *device, | ||
110 | u8 *buffer, | ||
111 | u32 length); | ||
112 | |||
113 | int | ||
114 | BMIFastDownload(struct hif_device *device, | ||
115 | u32 address, | ||
116 | u8 *buffer, | ||
117 | u32 length); | ||
118 | |||
119 | int | ||
120 | BMIRawWrite(struct hif_device *device, | ||
121 | u8 *buffer, | ||
122 | u32 length); | ||
123 | |||
124 | int | ||
125 | BMIRawRead(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 | |||
144 | PREPACK 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 | |||
27 | typedef 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 | ||
28 | extern "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 | |||
86 | PREPACK 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 | |||
95 | PREPACK struct dbglog_hdr_s { | ||
96 | struct dbglog_buf_s *dbuf; | ||
97 | u32 dropped; | ||
98 | } POSTPACK; | ||
99 | |||
100 | PREPACK 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 | ||
28 | extern "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 | */ | ||
30 | typedef 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 */ | ||
38 | typedef 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 | |||
61 | typedef enum { | ||
62 | BSS_REPORTING_DEFAULT = 0x0, | ||
63 | EXCLUDE_NON_SCAN_RESULTS = 0x1, /* Exclude results outside of scan */ | ||
64 | } DC_BSS_REPORTING_POLICY; | ||
65 | |||
66 | typedef 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 | |||
39 | typedef 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 */ | ||
95 | typedef 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 */ | ||
39 | typedef PREPACK struct { | ||
40 | u16 Flags_ConnHandle; | ||
41 | u16 Length; | ||
42 | } POSTPACK BT_HCI_ACL_HEADER; | ||
43 | |||
44 | typedef PREPACK struct { | ||
45 | u16 Flags_ConnHandle; | ||
46 | u8 Length; | ||
47 | } POSTPACK BT_HCI_SCO_HEADER; | ||
48 | |||
49 | typedef PREPACK struct { | ||
50 | u16 OpCode; | ||
51 | u8 ParamLength; | ||
52 | } POSTPACK BT_HCI_COMMAND_HEADER; | ||
53 | |||
54 | typedef 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 */ | ||
65 | PREPACK 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 */ | ||
108 | typedef PREPACK struct { | ||
109 | u16 MessageID; | ||
110 | } POSTPACK HTC_UNKNOWN_MSG; | ||
111 | |||
112 | /* HTC ready message | ||
113 | * direction : target-to-host */ | ||
114 | typedef 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 */ | ||
123 | typedef 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 */ | ||
137 | typedef 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 */ | ||
159 | typedef 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 | |||
172 | typedef PREPACK struct { | ||
173 | u16 MessageID; | ||
174 | /* currently, no other fields */ | ||
175 | } POSTPACK HTC_SETUP_COMPLETE_MSG; | ||
176 | |||
177 | /* extended setup completion message */ | ||
178 | typedef 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 | |||
202 | typedef PREPACK struct { | ||
203 | u8 RecordID; /* Record ID */ | ||
204 | u8 Length; /* Length of record */ | ||
205 | } POSTPACK HTC_RECORD_HDR; | ||
206 | |||
207 | typedef 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 | |||
212 | typedef 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 | |||
222 | typedef 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 | |||
29 | typedef 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 | ||
27 | extern "C" { | ||
28 | #endif | ||
29 | |||
30 | |||
31 | /* Pkt log info */ | ||
32 | typedef 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 | ||
35 | typedef 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__) | ||
63 | struct register_dump_s; | ||
64 | struct 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 | */ | ||
77 | PREPACK 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 | ||
290 | valid */ | ||
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 | ||
28 | extern "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 | |||
37 | typedef 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) | ||
51 | dataRate: 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 | ||
64 | antenna: 1 - one antenna | ||
65 | 2 - two antenna | ||
66 | Note : Enable/disable continuous tx test cmd works only when target is awake. | ||
67 | */ | ||
68 | |||
69 | typedef 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 | |||
77 | typedef 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 | |||
84 | typedef 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 | */ | ||
118 | typedef 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 | |||
126 | typedef 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 | */ | ||
158 | typedef enum { | ||
159 | TCMD_PM_WAKEUP = 1, /* be consistent with target */ | ||
160 | TCMD_PM_SLEEP, | ||
161 | TCMD_PM_DEEPSLEEP | ||
162 | } TCMD_PM_MODE; | ||
163 | |||
164 | typedef PREPACK struct { | ||
165 | u32 testCmdId; | ||
166 | u32 mode; | ||
167 | } POSTPACK TCMD_PM; | ||
168 | |||
169 | typedef enum { | ||
170 | TCMD_CONT_TX_ID, | ||
171 | TCMD_CONT_RX_ID, | ||
172 | TCMD_PM_ID | ||
173 | } TCMD_ID; | ||
174 | |||
175 | typedef 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 | |||
31 | typedef 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 | |||
49 | typedef enum { | ||
50 | WLAN_11A_CAPABILITY = 1, | ||
51 | WLAN_11G_CAPABILITY = 2, | ||
52 | WLAN_11AG_CAPABILITY = 3, | ||
53 | }WLAN_CAPABILITY; | ||
54 | |||
55 | #ifdef SUPPORT_11N | ||
56 | typedef unsigned long A_RATEMASK; | ||
57 | #else | ||
58 | typedef 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 | ||
41 | extern "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 | |||
68 | PREPACK struct host_app_area_s { | ||
69 | u32 wmi_protocol_ver; | ||
70 | } POSTPACK; | ||
71 | |||
72 | /* | ||
73 | * Data Path | ||
74 | */ | ||
75 | typedef PREPACK struct { | ||
76 | u8 dstMac[ATH_MAC_LEN]; | ||
77 | u8 srcMac[ATH_MAC_LEN]; | ||
78 | u16 typeOrLen; | ||
79 | } POSTPACK ATH_MAC_HDR; | ||
80 | |||
81 | typedef 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 | |||
89 | typedef 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 | |||
114 | typedef 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 | |||
168 | typedef 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.. */ | ||
198 | typedef PREPACK struct { | ||
199 | /* intentionally empty. Default version is no meta data. */ | ||
200 | } POSTPACK WMI_TX_META_V0; | ||
201 | #endif | ||
202 | |||
203 | typedef 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) | ||
211 | typedef 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.. */ | ||
245 | typedef PREPACK struct { | ||
246 | /* intentionally empty. Default version is no meta data. */ | ||
247 | } POSTPACK WMI_RX_META_VERSION_0; | ||
248 | #endif | ||
249 | |||
250 | typedef 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) | ||
259 | typedef 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 | */ | ||
283 | typedef 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 | */ | ||
298 | typedef 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 | */ | ||
499 | typedef 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 | */ | ||
511 | typedef enum { | ||
512 | INFRA_NETWORK = 0x01, | ||
513 | ADHOC_NETWORK = 0x02, | ||
514 | ADHOC_CREATOR = 0x04, | ||
515 | AP_NETWORK = 0x10, | ||
516 | } NETWORK_TYPE; | ||
517 | |||
518 | typedef enum { | ||
519 | OPEN_AUTH = 0x01, | ||
520 | SHARED_AUTH = 0x02, | ||
521 | LEAP_AUTH = 0x04, /* different from IEEE_AUTH_MODE definitions */ | ||
522 | } DOT11_AUTH_MODE; | ||
523 | |||
524 | enum { | ||
525 | AUTH_IDLE, | ||
526 | AUTH_OPEN_IN_PROGRESS, | ||
527 | }; | ||
528 | |||
529 | typedef 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 | |||
539 | typedef 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 | |||
574 | typedef 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 | |||
587 | typedef 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 | */ | ||
605 | typedef 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 | ||
611 | typedef 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 | */ | ||
618 | typedef PREPACK struct { | ||
619 | u32 threshold; | ||
620 | } POSTPACK WMI_SET_EXCESS_TX_RETRY_THRES_CMD; | ||
621 | |||
622 | /* | ||
623 | * WMI_ADD_CIPHER_KEY_CMDID | ||
624 | */ | ||
625 | typedef 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 | |||
644 | typedef 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 | */ | ||
658 | typedef 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 | */ | ||
666 | typedef PREPACK struct { | ||
667 | u8 krk[WMI_KRK_LEN]; | ||
668 | } POSTPACK WMI_ADD_KRK_CMD; | ||
669 | |||
670 | /* | ||
671 | * WMI_SET_TKIP_COUNTERMEASURES_CMDID | ||
672 | */ | ||
673 | typedef enum { | ||
674 | WMI_TKIP_CM_DISABLE = 0x0, | ||
675 | WMI_TKIP_CM_ENABLE = 0x1, | ||
676 | } WMI_TKIP_CM_CONTROL; | ||
677 | |||
678 | typedef 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 | |||
688 | typedef enum { | ||
689 | PMKID_DISABLE = 0, | ||
690 | PMKID_ENABLE = 1, | ||
691 | } PMKID_ENABLE_FLG; | ||
692 | |||
693 | typedef 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 | */ | ||
702 | typedef enum { | ||
703 | WMI_LONG_SCAN = 0, | ||
704 | WMI_SHORT_SCAN = 1, | ||
705 | } WMI_SCAN_TYPE; | ||
706 | |||
707 | typedef 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 | */ | ||
725 | typedef 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 | |||
748 | typedef 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 | */ | ||
764 | typedef 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 | |||
775 | typedef 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 | |||
787 | typedef 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 | |||
793 | typedef 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 | |||
809 | typedef PREPACK struct { | ||
810 | u16 listenInterval; | ||
811 | u16 numBeacons; | ||
812 | } POSTPACK WMI_LISTEN_INT_CMD; | ||
813 | |||
814 | /* | ||
815 | * WMI_SET_BEACON_INT_CMDID | ||
816 | */ | ||
817 | typedef 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 | |||
831 | typedef PREPACK struct { | ||
832 | u16 bmissTime; | ||
833 | u16 numBeacons; | ||
834 | } POSTPACK WMI_BMISS_TIME_CMD; | ||
835 | |||
836 | /* | ||
837 | * WMI_SET_POWER_MODE_CMDID | ||
838 | */ | ||
839 | typedef enum { | ||
840 | REC_POWER = 0x01, | ||
841 | MAX_PERF_POWER, | ||
842 | } WMI_POWER_MODE; | ||
843 | |||
844 | typedef PREPACK struct { | ||
845 | u8 powerMode; /* WMI_POWER_MODE */ | ||
846 | } POSTPACK WMI_POWER_MODE_CMD; | ||
847 | |||
848 | typedef PREPACK struct { | ||
849 | s8 status; /* WMI_SET_PARAMS_REPLY */ | ||
850 | } POSTPACK WMI_SET_PARAMS_REPLY; | ||
851 | |||
852 | typedef PREPACK struct { | ||
853 | u32 opcode; | ||
854 | u32 length; | ||
855 | char buffer[1]; /* WMI_SET_PARAMS */ | ||
856 | } POSTPACK WMI_SET_PARAMS_CMD; | ||
857 | |||
858 | typedef PREPACK struct { | ||
859 | u8 multicast_mac[ATH_MAC_LEN]; /* WMI_SET_MCAST_FILTER */ | ||
860 | } POSTPACK WMI_SET_MCAST_FILTER_CMD; | ||
861 | |||
862 | typedef PREPACK struct { | ||
863 | u8 enable; /* WMI_MCAST_FILTER */ | ||
864 | } POSTPACK WMI_MCAST_FILTER_CMD; | ||
865 | |||
866 | /* | ||
867 | * WMI_SET_POWER_PARAMS_CMDID | ||
868 | */ | ||
869 | typedef 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 */ | ||
877 | typedef 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 | */ | ||
886 | typedef 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 | |||
891 | typedef 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 */ | ||
901 | typedef 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 | |||
908 | typedef 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 */ | ||
916 | typedef enum { | ||
917 | AP_PS_DISABLE=1, | ||
918 | AP_PS_ATH=2, | ||
919 | } WMI_AP_PS_TYPE; | ||
920 | |||
921 | typedef 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 | */ | ||
931 | typedef 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 | |||
938 | typedef 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 | */ | ||
948 | typedef PREPACK struct { | ||
949 | u16 voicePktSize; | ||
950 | } POSTPACK WMI_SET_VOICE_PKT_SIZE_CMD; | ||
951 | |||
952 | /* | ||
953 | * WMI_SET_MAX_SP_LEN_CMDID | ||
954 | */ | ||
955 | typedef 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 | |||
962 | typedef PREPACK struct { | ||
963 | u8 maxSPLen; | ||
964 | } POSTPACK WMI_SET_MAX_SP_LEN_CMD; | ||
965 | |||
966 | /* | ||
967 | * WMI_SET_DISC_TIMEOUT_CMDID | ||
968 | */ | ||
969 | typedef PREPACK struct { | ||
970 | u8 disconnectTimeout; /* seconds */ | ||
971 | } POSTPACK WMI_DISC_TIMEOUT_CMD; | ||
972 | |||
973 | typedef enum { | ||
974 | UPLINK_TRAFFIC = 0, | ||
975 | DNLINK_TRAFFIC = 1, | ||
976 | BIDIR_TRAFFIC = 2, | ||
977 | } DIR_TYPE; | ||
978 | |||
979 | typedef enum { | ||
980 | DISABLE_FOR_THIS_AC = 0, | ||
981 | ENABLE_FOR_THIS_AC = 1, | ||
982 | ENABLE_FOR_ALL_AC = 2, | ||
983 | } VOICEPS_CAP_TYPE; | ||
984 | |||
985 | typedef enum { | ||
986 | TRAFFIC_TYPE_APERIODIC = 0, | ||
987 | TRAFFIC_TYPE_PERIODIC = 1, | ||
988 | }TRAFFIC_TYPE; | ||
989 | |||
990 | /* | ||
991 | * WMI_SYNCHRONIZE_CMDID | ||
992 | */ | ||
993 | typedef PREPACK struct { | ||
994 | u8 dataSyncMap; | ||
995 | } POSTPACK WMI_SYNC_CMD; | ||
996 | |||
997 | /* | ||
998 | * WMI_CREATE_PSTREAM_CMDID | ||
999 | */ | ||
1000 | typedef 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 | */ | ||
1029 | typedef 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 | */ | ||
1040 | typedef 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 | |||
1050 | typedef 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 | |||
1067 | typedef 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 | |||
1090 | typedef 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 | */ | ||
1107 | typedef 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 | |||
1120 | typedef enum { | ||
1121 | WMI_LPREAMBLE_DISABLED = 0, | ||
1122 | WMI_LPREAMBLE_ENABLED | ||
1123 | } WMI_LPREAMBLE_STATUS; | ||
1124 | |||
1125 | typedef enum { | ||
1126 | WMI_IGNORE_BARKER_IN_ERP = 0, | ||
1127 | WMI_DONOT_IGNORE_BARKER_IN_ERP | ||
1128 | } WMI_PREAMBLE_POLICY; | ||
1129 | |||
1130 | typedef PREPACK struct { | ||
1131 | u8 status; | ||
1132 | u8 preamblePolicy; | ||
1133 | }POSTPACK WMI_SET_LPREAMBLE_CMD; | ||
1134 | |||
1135 | typedef 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 | */ | ||
1145 | typedef PREPACK struct { | ||
1146 | u32 bitmask; | ||
1147 | } POSTPACK WMI_TARGET_ERROR_REPORT_BITMASK; | ||
1148 | |||
1149 | /* | ||
1150 | * WMI_SET_TX_PWR_CMDID | ||
1151 | */ | ||
1152 | typedef 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 | |||
1167 | typedef 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 | |||
1183 | typedef 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 | */ | ||
1191 | typedef 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 | ||
1204 | typedef 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 | ||
1221 | typedef enum { | ||
1222 | MGMT_FRAMETYPE = 0, | ||
1223 | CONTROL_FRAMETYPE = 1, | ||
1224 | DATA_FRAMETYPE = 2 | ||
1225 | } WMI_FRAMETYPE; | ||
1226 | |||
1227 | typedef 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 | |||
1246 | typedef 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 | |||
1260 | typedef 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 | |||
1270 | typedef PREPACK struct { | ||
1271 | u8 bssid[ATH_MAC_LEN]; | ||
1272 | s8 bias; | ||
1273 | } POSTPACK WMI_BSS_BIAS; | ||
1274 | |||
1275 | typedef PREPACK struct { | ||
1276 | u8 numBss; | ||
1277 | WMI_BSS_BIAS bssBias[1]; | ||
1278 | } POSTPACK WMI_BSS_BIAS_INFO; | ||
1279 | |||
1280 | typedef 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 | |||
1288 | typedef 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 | */ | ||
1301 | typedef enum { | ||
1302 | BT_WLAN_CONN_PRECDENCE_WLAN=0, /* Default */ | ||
1303 | BT_WLAN_CONN_PRECDENCE_PAL, | ||
1304 | } BT_WLAN_CONN_PRECEDENCE; | ||
1305 | |||
1306 | typedef PREPACK struct { | ||
1307 | u8 precedence; | ||
1308 | } POSTPACK WMI_SET_BT_WLAN_CONN_PRECEDENCE; | ||
1309 | |||
1310 | /* | ||
1311 | * WMI_ENABLE_RM_CMDID | ||
1312 | */ | ||
1313 | typedef PREPACK struct { | ||
1314 | u32 enable_radio_measurements; | ||
1315 | } POSTPACK WMI_ENABLE_RM_CMD; | ||
1316 | |||
1317 | /* | ||
1318 | * WMI_SET_MAX_OFFHOME_DURATION_CMDID | ||
1319 | */ | ||
1320 | typedef PREPACK struct { | ||
1321 | u8 max_offhome_duration; | ||
1322 | } POSTPACK WMI_SET_MAX_OFFHOME_DURATION_CMD; | ||
1323 | |||
1324 | typedef 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 -------------------------*/ | ||
1330 | typedef 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 | |||
1339 | typedef 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 | |||
1345 | typedef 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 | |||
1351 | typedef enum { | ||
1352 | BT_STATUS_UNDEF = 0, | ||
1353 | BT_STATUS_ON, | ||
1354 | BT_STATUS_OFF, | ||
1355 | BT_STATUS_MAX | ||
1356 | } BT_STREAM_STATUS; | ||
1357 | |||
1358 | typedef PREPACK struct { | ||
1359 | u8 streamType; | ||
1360 | u8 status; | ||
1361 | } POSTPACK WMI_SET_BT_STATUS_CMD; | ||
1362 | |||
1363 | typedef 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 | |||
1371 | typedef 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 | |||
1379 | typedef 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 | |||
1401 | typedef 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 | |||
1449 | typedef 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).*/ | ||
1474 | typedef 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 | |||
1487 | typedef 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 | */ | ||
1512 | typedef 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 | |||
1520 | typedef 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 | */ | ||
1533 | typedef 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 | */ | ||
1550 | typedef 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) | ||
1581 | typedef 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 | |||
1600 | typedef 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 | |||
1621 | typedef 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 | |||
1651 | typedef PREPACK struct { | ||
1652 | u32 scanInterval; | ||
1653 | u32 maxScanStompCnt; | ||
1654 | }POSTPACK BTCOEX_WLANSCAN_SCO_CONFIG; | ||
1655 | |||
1656 | typedef 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 | |||
1680 | typedef 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 | |||
1693 | typedef 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 | |||
1708 | typedef 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 | |||
1732 | typedef 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 | |||
1755 | typedef 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 | |||
1806 | typedef 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*/ | ||
1816 | typedef PREPACK struct { | ||
1817 | u32 aclCoexMinlowRateMbps; | ||
1818 | u32 aclCoexLowRateCnt; | ||
1819 | u32 aclCoexHighPktRatio; | ||
1820 | u32 aclCoexMaxAggrSize; | ||
1821 | u32 aclPktStompCnt; | ||
1822 | }POSTPACK BTCOEX_OPTMODE_ACLCOEX_CONFIG; | ||
1823 | |||
1824 | typedef 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 ------------------*/ | ||
1831 | typedef 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 | |||
1838 | typedef 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 */ | ||
1846 | typedef 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 */ | ||
1857 | typedef 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 | * */ | ||
1869 | typedef 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*/ | ||
1882 | typedef PREPACK struct { | ||
1883 | u32 highRatePktCnt; | ||
1884 | u32 firstBmissCnt; | ||
1885 | u32 psPollFailureCnt; | ||
1886 | u32 nullFrameFailureCnt; | ||
1887 | u32 optModeTransitionCnt; | ||
1888 | }BTCOEX_GENERAL_STATS; | ||
1889 | |||
1890 | typedef PREPACK struct { | ||
1891 | u32 scoStompCntAvg; | ||
1892 | u32 scoStompIn100ms; | ||
1893 | u32 scoMaxContStomp; | ||
1894 | u32 scoAvgNoRetries; | ||
1895 | u32 scoMaxNoRetriesIn100ms; | ||
1896 | }BTCOEX_SCO_STATS; | ||
1897 | |||
1898 | typedef PREPACK struct { | ||
1899 | u32 a2dpBurstCnt; | ||
1900 | u32 a2dpMaxBurstCnt; | ||
1901 | u32 a2dpAvgIdletimeIn100ms; | ||
1902 | u32 a2dpAvgStompCnt; | ||
1903 | }BTCOEX_A2DP_STATS; | ||
1904 | |||
1905 | typedef PREPACK struct { | ||
1906 | u32 aclPktCntInBtTime; | ||
1907 | u32 aclStompCntInWlanTime; | ||
1908 | u32 aclPktCntIn100ms; | ||
1909 | }BTCOEX_ACLCOEX_STATS; | ||
1910 | |||
1911 | typedef 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 -------------------------------------*/ | ||
1920 | typedef PREPACK struct { | ||
1921 | u32 sleepState; | ||
1922 | }WMI_REPORT_SLEEP_STATE_EVENT; | ||
1923 | |||
1924 | typedef enum { | ||
1925 | WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP =0, | ||
1926 | WMI_REPORT_SLEEP_STATUS_IS_AWAKE | ||
1927 | } WMI_REPORT_SLEEP_STATUS; | ||
1928 | typedef enum { | ||
1929 | DISCONN_EVT_IN_RECONN = 0, /* default */ | ||
1930 | NO_DISCONN_EVT_IN_RECONN | ||
1931 | } TARGET_EVENT_REPORT_CONFIG; | ||
1932 | |||
1933 | typedef PREPACK struct { | ||
1934 | u32 evtConfig; | ||
1935 | } POSTPACK WMI_SET_TARGET_EVENT_REPORT_CMD; | ||
1936 | |||
1937 | |||
1938 | typedef 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 | */ | ||
1950 | typedef 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 | |||
1956 | typedef 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 | |||
1965 | typedef 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 | |||
1973 | typedef 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 | */ | ||
1984 | typedef 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 | |||
2072 | typedef 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 | |||
2083 | typedef PREPACK struct { | ||
2084 | u8 macaddr[ATH_MAC_LEN]; | ||
2085 | u8 phyCapability; /* WMI_PHY_CAPABILITY */ | ||
2086 | } POSTPACK WMI_READY_EVENT_1; | ||
2087 | |||
2088 | typedef 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 | */ | ||
2109 | typedef 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 | */ | ||
2124 | typedef 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 | |||
2140 | typedef 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 | */ | ||
2154 | typedef enum { | ||
2155 | BEACON_FTYPE = 0x1, | ||
2156 | PROBERESP_FTYPE, | ||
2157 | ACTION_MGMT_FTYPE, | ||
2158 | PROBEREQ_FTYPE, | ||
2159 | } WMI_BI_FTYPE; | ||
2160 | |||
2161 | enum { | ||
2162 | BSS_ELEMID_CHANSWITCH = 0x01, | ||
2163 | BSS_ELEMID_ATHEROS = 0x02, | ||
2164 | }; | ||
2165 | |||
2166 | typedef 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 | */ | ||
2183 | typedef 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 | */ | ||
2194 | typedef enum { | ||
2195 | INVALID_PARAM = 0x01, | ||
2196 | ILLEGAL_STATE = 0x02, | ||
2197 | INTERNAL_ERROR = 0x03, | ||
2198 | } WMI_ERROR_CODE; | ||
2199 | |||
2200 | typedef PREPACK struct { | ||
2201 | u16 commandId; | ||
2202 | u8 errorCode; | ||
2203 | } POSTPACK WMI_CMD_ERROR_EVENT; | ||
2204 | |||
2205 | /* | ||
2206 | * New Regulatory Domain Event | ||
2207 | */ | ||
2208 | typedef PREPACK struct { | ||
2209 | u32 regDomain; | ||
2210 | } POSTPACK WMI_REG_DOMAIN_EVENT; | ||
2211 | |||
2212 | typedef PREPACK struct { | ||
2213 | u8 txQueueNumber; | ||
2214 | u8 rxQueueNumber; | ||
2215 | u8 trafficDirection; | ||
2216 | u8 trafficClass; | ||
2217 | } POSTPACK WMI_PSTREAM_TIMEOUT_EVENT; | ||
2218 | |||
2219 | typedef 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 | */ | ||
2235 | typedef enum { | ||
2236 | WMI_DEFAULT_BSS_FLAGS = 0x00, | ||
2237 | WMI_PREAUTH_CAPABLE_BSS = 0x01, | ||
2238 | WMI_PMKID_VALID_BSS = 0x02, | ||
2239 | } WMI_BSS_FLAGS; | ||
2240 | |||
2241 | typedef PREPACK struct { | ||
2242 | u8 bssid[ATH_MAC_LEN]; | ||
2243 | u8 bssFlags; /* see WMI_BSS_FLAGS */ | ||
2244 | } POSTPACK WMI_NEIGHBOR_INFO; | ||
2245 | |||
2246 | typedef 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 | */ | ||
2254 | typedef 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 | */ | ||
2262 | typedef 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 | */ | ||
2271 | typedef PREPACK struct { | ||
2272 | u8 bssid[ATH_MAC_LEN]; | ||
2273 | } POSTPACK WMI_SET_ADHOC_BSSID_CMD; | ||
2274 | |||
2275 | /* | ||
2276 | * WMI_SET_OPT_MODE_CMDID | ||
2277 | */ | ||
2278 | typedef enum { | ||
2279 | SPECIAL_OFF, | ||
2280 | SPECIAL_ON, | ||
2281 | } OPT_MODE_TYPE; | ||
2282 | |||
2283 | typedef PREPACK struct { | ||
2284 | u8 optMode; | ||
2285 | } POSTPACK WMI_SET_OPT_MODE_CMD; | ||
2286 | |||
2287 | /* | ||
2288 | * WMI_TX_OPT_FRAME_CMDID | ||
2289 | */ | ||
2290 | typedef 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 | |||
2297 | typedef 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 | */ | ||
2312 | typedef 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 | */ | ||
2323 | typedef 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 | |||
2344 | typedef 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 | |||
2363 | typedef 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 | |||
2372 | typedef 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 | |||
2380 | typedef 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 | |||
2393 | typedef 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 | |||
2399 | typedef PREPACK struct { | ||
2400 | u32 arp_received; | ||
2401 | u32 arp_matched; | ||
2402 | u32 arp_replied; | ||
2403 | } POSTPACK arp_stats_t; | ||
2404 | |||
2405 | typedef 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 | |||
2412 | typedef 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 | */ | ||
2427 | typedef 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 | |||
2442 | typedef PREPACK struct { | ||
2443 | s16 rssi; | ||
2444 | u8 range; | ||
2445 | }POSTPACK WMI_RSSI_THRESHOLD_EVENT; | ||
2446 | |||
2447 | /* | ||
2448 | * WMI_ERROR_REPORT_EVENTID | ||
2449 | */ | ||
2450 | typedef 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 | |||
2460 | typedef PREPACK struct { | ||
2461 | u32 errorVal; | ||
2462 | }POSTPACK WMI_TARGET_ERROR_REPORT_EVENT; | ||
2463 | |||
2464 | typedef PREPACK struct { | ||
2465 | u8 retrys; | ||
2466 | }POSTPACK WMI_TX_RETRY_ERR_EVENT; | ||
2467 | |||
2468 | typedef 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 | |||
2479 | typedef PREPACK struct { | ||
2480 | u8 range; /* WMI_SNR_THRESHOLD_VAL */ | ||
2481 | u8 snr; | ||
2482 | }POSTPACK WMI_SNR_THRESHOLD_EVENT; | ||
2483 | |||
2484 | typedef 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 | |||
2495 | typedef 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 | |||
2504 | typedef 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 | |||
2516 | typedef 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 | */ | ||
2525 | typedef 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 | */ | ||
2533 | typedef 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 | |||
2542 | typedef 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 | |||
2553 | typedef enum { | ||
2554 | APLIST_VER1 = 1, | ||
2555 | } APLIST_VER; | ||
2556 | |||
2557 | typedef PREPACK struct { | ||
2558 | u8 bssid[ATH_MAC_LEN]; | ||
2559 | u16 channel; | ||
2560 | } POSTPACK WMI_AP_INFO_V1; | ||
2561 | |||
2562 | typedef PREPACK union { | ||
2563 | WMI_AP_INFO_V1 apInfoV1; | ||
2564 | } POSTPACK WMI_AP_INFO; | ||
2565 | |||
2566 | typedef 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 | */ | ||
2581 | typedef 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 | |||
2613 | typedef PREPACK struct { | ||
2614 | s8 rateIndex; /* see WMI_BIT_RATE */ | ||
2615 | s8 mgmtRateIndex; | ||
2616 | s8 ctlRateIndex; | ||
2617 | } POSTPACK WMI_BIT_RATE_CMD; | ||
2618 | |||
2619 | |||
2620 | typedef 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 | |||
2659 | typedef PREPACK struct { | ||
2660 | u32 fixRateMask; /* see WMI_BIT_RATE */ | ||
2661 | } POSTPACK WMI_FIX_RATES_CMD, WMI_FIX_RATES_REPLY; | ||
2662 | |||
2663 | typedef 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 | */ | ||
2674 | typedef enum { | ||
2675 | RECONN_DO_AUTH = 0x00, | ||
2676 | RECONN_NOT_AUTH = 0x01 | ||
2677 | } WMI_AUTH_MODE; | ||
2678 | |||
2679 | typedef 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 | */ | ||
2688 | typedef enum { | ||
2689 | REASSOC_DO_DISASSOC = 0x00, | ||
2690 | REASSOC_DONOT_DISASSOC = 0x01 | ||
2691 | } WMI_REASSOC_MODE; | ||
2692 | |||
2693 | typedef PREPACK struct { | ||
2694 | u8 mode; | ||
2695 | }POSTPACK WMI_SET_REASSOC_MODE_CMD; | ||
2696 | |||
2697 | typedef enum { | ||
2698 | ROAM_DATA_TIME = 1, /* Get The Roam Time Data */ | ||
2699 | } ROAM_DATA_TYPE; | ||
2700 | |||
2701 | typedef 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 | |||
2712 | typedef PREPACK struct { | ||
2713 | PREPACK union { | ||
2714 | WMI_TARGET_ROAM_TIME roamTime; | ||
2715 | } POSTPACK u; | ||
2716 | u8 roamDataType ; | ||
2717 | } POSTPACK WMI_TARGET_ROAM_DATA; | ||
2718 | |||
2719 | typedef enum { | ||
2720 | WMI_WMM_DISABLED = 0, | ||
2721 | WMI_WMM_ENABLED | ||
2722 | } WMI_WMM_STATUS; | ||
2723 | |||
2724 | typedef PREPACK struct { | ||
2725 | u8 status; | ||
2726 | }POSTPACK WMI_SET_WMM_CMD; | ||
2727 | |||
2728 | typedef PREPACK struct { | ||
2729 | u8 status; | ||
2730 | }POSTPACK WMI_SET_QOS_SUPP_CMD; | ||
2731 | |||
2732 | typedef enum { | ||
2733 | WMI_TXOP_DISABLED = 0, | ||
2734 | WMI_TXOP_ENABLED | ||
2735 | } WMI_TXOP_CFG; | ||
2736 | |||
2737 | typedef PREPACK struct { | ||
2738 | u8 txopEnable; | ||
2739 | }POSTPACK WMI_SET_WMM_TXOP_CMD; | ||
2740 | |||
2741 | typedef PREPACK struct { | ||
2742 | u8 keepaliveInterval; | ||
2743 | } POSTPACK WMI_SET_KEEPALIVE_CMD; | ||
2744 | |||
2745 | typedef 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 | |||
2755 | typedef 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 */ | ||
2768 | typedef enum { | ||
2769 | WHAL_SETCABTO_CMDID = 1, | ||
2770 | }WHAL_CMDID; | ||
2771 | |||
2772 | typedef PREPACK struct { | ||
2773 | u8 cabTimeOut; | ||
2774 | } POSTPACK WHAL_SETCABTO_PARAM; | ||
2775 | |||
2776 | typedef 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 | |||
2789 | typedef 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 | |||
2799 | typedef 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 | |||
2807 | typedef PREPACK struct { | ||
2808 | u8 valid_filter; | ||
2809 | u8 mac_addr[ATH_MAC_LEN]; | ||
2810 | } POSTPACK MAC_FILTER; | ||
2811 | |||
2812 | |||
2813 | typedef 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 | ||
2820 | typedef PREPACK struct { | ||
2821 | u32 ips[MAX_IP_ADDRS]; /* IP in Network Byte Order */ | ||
2822 | } POSTPACK WMI_SET_IP_CMD; | ||
2823 | |||
2824 | typedef PREPACK struct { | ||
2825 | u32 awake; | ||
2826 | u32 asleep; | ||
2827 | } POSTPACK WMI_SET_HOST_SLEEP_MODE_CMD; | ||
2828 | |||
2829 | typedef enum { | ||
2830 | WOW_FILTER_SSID = 0x1 | ||
2831 | } WMI_WOW_FILTER; | ||
2832 | |||
2833 | typedef PREPACK struct { | ||
2834 | u32 enable_wow; | ||
2835 | WMI_WOW_FILTER filter; | ||
2836 | u16 hostReqDelay; | ||
2837 | } POSTPACK WMI_SET_WOW_MODE_CMD; | ||
2838 | |||
2839 | typedef PREPACK struct { | ||
2840 | u8 filter_list_id; | ||
2841 | } POSTPACK WMI_GET_WOW_LIST_CMD; | ||
2842 | |||
2843 | /* | ||
2844 | * WMI_GET_WOW_LIST_CMD reply | ||
2845 | */ | ||
2846 | typedef 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 | |||
2854 | typedef 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 | |||
2861 | typedef PREPACK struct { | ||
2862 | u16 filter_list_id; | ||
2863 | u16 filter_id; | ||
2864 | } POSTPACK WMI_DEL_WOW_PATTERN_CMD; | ||
2865 | |||
2866 | typedef 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 | |||
2876 | typedef PREPACK struct { | ||
2877 | u32 akmpInfo; | ||
2878 | } POSTPACK WMI_SET_AKMP_PARAMS_CMD; | ||
2879 | |||
2880 | typedef 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 | |||
2889 | typedef 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 | */ | ||
2898 | typedef PREPACK struct { | ||
2899 | u32 numPMKID; | ||
2900 | u8 bssidList[ATH_MAC_LEN][1]; | ||
2901 | WMI_PMKID pmkidList[1]; | ||
2902 | } POSTPACK WMI_PMKID_LIST_REPLY; | ||
2903 | |||
2904 | typedef PREPACK struct { | ||
2905 | u16 oldChannel; | ||
2906 | u32 newChannel; | ||
2907 | } POSTPACK WMI_CHANNEL_CHANGE_EVENT; | ||
2908 | |||
2909 | typedef PREPACK struct { | ||
2910 | u32 version; | ||
2911 | } POSTPACK WMI_WLAN_VERSION_EVENT; | ||
2912 | |||
2913 | |||
2914 | /* WMI_ADDBA_REQ_EVENTID */ | ||
2915 | typedef 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 */ | ||
2923 | typedef 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 | */ | ||
2933 | typedef 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 | ||
2943 | typedef 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 | */ | ||
2954 | typedef 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 | */ | ||
2963 | typedef 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 | */ | ||
2971 | typedef 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 | ||
2981 | typedef 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 | |||
2994 | typedef 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 | |||
3011 | typedef 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 | ||
3053 | typedef 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 | ||
3064 | typedef 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 | ||
3073 | typedef 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 | |||
3080 | typedef 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 | */ | ||
3090 | typedef 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 | */ | ||
3097 | typedef 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 | |||
3108 | typedef PREPACK struct { | ||
3109 | u32 period; | ||
3110 | } POSTPACK WMI_AP_CONN_INACT_CMD; | ||
3111 | |||
3112 | typedef PREPACK struct { | ||
3113 | u32 period_min; | ||
3114 | u32 dwell_ms; | ||
3115 | } POSTPACK WMI_AP_PROT_SCAN_TIME_CMD; | ||
3116 | |||
3117 | typedef PREPACK struct { | ||
3118 | u32 flag; | ||
3119 | u16 aid; | ||
3120 | } POSTPACK WMI_AP_SET_PVB_CMD; | ||
3121 | |||
3122 | #define WMI_DISABLE_REGULATORY_CODE "FF" | ||
3123 | |||
3124 | typedef PREPACK struct { | ||
3125 | u8 countryCode[3]; | ||
3126 | } POSTPACK WMI_AP_SET_COUNTRY_CMD; | ||
3127 | |||
3128 | typedef PREPACK struct { | ||
3129 | u8 dtim; | ||
3130 | } POSTPACK WMI_AP_SET_DTIM_CMD; | ||
3131 | |||
3132 | typedef 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 | |||
3142 | typedef PREPACK struct { | ||
3143 | u8 sta_chan_width; | ||
3144 | } POSTPACK WMI_SET_HT_OP_CMD; | ||
3145 | |||
3146 | typedef PREPACK struct { | ||
3147 | u32 rateMasks[8]; | ||
3148 | } POSTPACK WMI_SET_TX_SELECT_RATES_CMD; | ||
3149 | |||
3150 | typedef 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 | |||
3158 | typedef 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 | |||
3166 | typedef 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 | |||
3174 | typedef 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 */ | ||
3181 | typedef PREPACK struct { | ||
3182 | u16 aid; | ||
3183 | } POSTPACK WMI_PSPOLL_EVENT; | ||
3184 | |||
3185 | typedef 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 | |||
3200 | typedef 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 | ||
3209 | typedef 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 | ||
40 | extern "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 | */ | ||
53 | typedef PREPACK struct { | ||
54 | u32 commandId; | ||
55 | } POSTPACK WMIX_CMD_HDR; | ||
56 | |||
57 | typedef 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 | |||
74 | typedef 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 | */ | ||
94 | typedef 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 | */ | ||
105 | typedef PREPACK struct { | ||
106 | u32 access_cookie; | ||
107 | } POSTPACK WMIX_DSETCLOSE_EVENT; | ||
108 | |||
109 | /* | ||
110 | * WMIX_DSETDATAREQ_EVENTID | ||
111 | * DataSet Data Request Event | ||
112 | */ | ||
113 | typedef 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 | |||
122 | typedef 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 | |||
132 | typedef 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 | */ | ||
157 | typedef 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 | */ | ||
169 | typedef 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. */ | ||
175 | typedef 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 | */ | ||
184 | typedef 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 | */ | ||
194 | typedef 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 | */ | ||
214 | typedef 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 | */ | ||
227 | typedef 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 | |||
238 | typedef PREPACK struct { | ||
239 | struct dbglog_config_s config; | ||
240 | } POSTPACK WMIX_DBGLOG_CFG_MODULE_CMD; | ||
241 | |||
242 | /* | ||
243 | * =============Target Profiling support================= | ||
244 | */ | ||
245 | |||
246 | typedef PREPACK struct { | ||
247 | u32 period; /* Time (in 30.5us ticks) between samples */ | ||
248 | u32 nbins; | ||
249 | } POSTPACK WMIX_PROF_CFG_CMD; | ||
250 | |||
251 | typedef 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 | */ | ||
261 | typedef 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 */ | ||
32 | struct 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 | |||
39 | struct hci_transport_callbacks { | ||
40 | s32 (*setupTransport)(void *ar); | ||
41 | void (*cleanupTransport)(void *ar); | ||
42 | }; | ||
43 | |||
44 | struct 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 | ||
63 | extern "C" { | ||
64 | #endif | ||
65 | |||
66 | /* OS-independent APIs */ | ||
67 | int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo); | ||
68 | |||
69 | int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); | ||
70 | |||
71 | int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); | ||
72 | |||
73 | int ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address, u8 *data, u32 length); | ||
74 | |||
75 | int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset); | ||
76 | |||
77 | void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType); | ||
78 | |||
79 | int ar6000_set_htc_params(struct hif_device *hifDevice, | ||
80 | u32 TargetType, | ||
81 | u32 MboxIsrYieldValue, | ||
82 | u8 HtcControlBuffers); | ||
83 | |||
84 | int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice, | ||
85 | u32 TargetType, | ||
86 | u32 Flags); | ||
87 | |||
88 | void ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType); | ||
89 | |||
90 | u8 *ar6000_get_cust_data_buffer(u32 TargetType); | ||
91 | |||
92 | int ar6000_setBTState(void *context, u8 *pInBuf, u32 InBufSize); | ||
93 | |||
94 | int ar6000_setDevicePowerState(void *context, u8 *pInBuf, u32 InBufSize); | ||
95 | |||
96 | int ar6000_setWowMode(void *context, u8 *pInBuf, u32 InBufSize); | ||
97 | |||
98 | int 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 | ||
29 | extern "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 */ | ||
35 | struct 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 | */ | ||
81 | static 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 | */ | ||
93 | static 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 | */ | ||
106 | static 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 | */ | ||
118 | static 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 | |||
128 | static 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 */ | ||
139 | static 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 | ||
29 | extern "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. */ | ||
42 | int 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. */ | ||
52 | int 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 | ||
29 | extern "C" { | ||
30 | #endif /* __cplusplus */ | ||
31 | |||
32 | typedef void *HCI_TRANSPORT_HANDLE; | ||
33 | |||
34 | typedef 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 */ | ||
46 | typedef void (*HCI_TRANSPORT_SEND_PKT_COMPLETE)(void *, struct htc_packet *); | ||
47 | /* callback when an HCI packet is received */ | ||
48 | typedef 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 | */ | ||
56 | typedef 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 | * */ | ||
71 | typedef struct htc_packet *(*HCI_TRANSPORT_RECV_ALLOC)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int Length); | ||
72 | |||
73 | typedef 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) */ | ||
80 | typedef HCI_SEND_FULL_ACTION (*HCI_TRANSPORT_SEND_FULL)(void *, struct htc_packet *); | ||
81 | |||
82 | struct 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 | |||
88 | struct 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
116 | HCI_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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
129 | void 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
144 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
169 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
183 | void 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
196 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
209 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
225 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
240 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
253 | int 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 | ||
29 | extern "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 | |||
39 | typedef struct htc_callbacks HTC_CALLBACKS; | ||
40 | struct 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 | |||
131 | typedef 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 | |||
225 | struct 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 | |||
232 | typedef enum _MBOX_BUF_IF_TYPE { | ||
233 | MBOX_BUS_IF_SDIO = 0, | ||
234 | MBOX_BUS_IF_SPI = 1, | ||
235 | } MBOX_BUF_IF_TYPE; | ||
236 | |||
237 | struct 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 | |||
251 | typedef 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 | |||
259 | typedef 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 | |||
267 | struct hif_device_irq_yield_params { | ||
268 | int RecvPacketYieldCount; /* max number of packets to force DSR to return */ | ||
269 | }; | ||
270 | |||
271 | |||
272 | struct 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 | |||
278 | struct hif_scatter_req; | ||
279 | typedef void ( *HIF_SCATTER_COMP_CB)(struct hif_scatter_req *); | ||
280 | |||
281 | typedef 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 | |||
287 | struct 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 | |||
303 | typedef struct hif_scatter_req * ( *HIF_ALLOCATE_SCATTER_REQUEST)(struct hif_device *device); | ||
304 | typedef void ( *HIF_FREE_SCATTER_REQUEST)(struct hif_device *device, struct hif_scatter_req *request); | ||
305 | typedef int ( *HIF_READWRITE_SCATTER)(struct hif_device *device, struct hif_scatter_req *request); | ||
306 | |||
307 | struct 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 | |||
316 | struct hif_device_os_device_info { | ||
317 | void *pOSDevice; | ||
318 | }; | ||
319 | |||
320 | #define HIF_MAX_DEVICES 1 | ||
321 | |||
322 | struct 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 | |||
329 | typedef 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 | |||
344 | struct 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 */ | ||
356 | typedef 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 */ | ||
363 | typedef 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 | */ | ||
373 | int 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 */ | ||
378 | void HIFClaimDevice(struct hif_device *device, void *claimedContext); | ||
379 | /* release the claimed device */ | ||
380 | void HIFReleaseDevice(struct hif_device *device); | ||
381 | |||
382 | /* This API allows the HTC layer to attach to the HIF device */ | ||
383 | int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks); | ||
384 | /* This API detaches the HTC layer from the HIF device */ | ||
385 | void 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 | */ | ||
399 | int | ||
400 | HIFReadWrite(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 | */ | ||
411 | void 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 | */ | ||
420 | void HIFAckInterrupt(struct hif_device *device); | ||
421 | |||
422 | void HIFMaskInterrupt(struct hif_device *device); | ||
423 | |||
424 | void 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 | */ | ||
433 | int HIFInsertEventNotify(void); | ||
434 | |||
435 | int HIFRemoveEventNotify(void); | ||
436 | |||
437 | int HIFIRQEventNotify(void); | ||
438 | |||
439 | int HIFRWCompleteEventNotify(void); | ||
440 | #endif | ||
441 | |||
442 | int | ||
443 | HIFConfigureDevice(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 | */ | ||
450 | int 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 | ||
30 | extern "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 | ||
31 | extern "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 | |||
42 | typedef void *HTC_HANDLE; | ||
43 | |||
44 | typedef u16 HTC_SERVICE_ID; | ||
45 | |||
46 | struct 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 */ | ||
52 | typedef 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() */ | ||
59 | typedef void (*HTC_EP_SEND_PKT_COMP_MULTIPLE)(void *,struct htc_packet_queue *); | ||
60 | /* per service connection pkt received */ | ||
61 | typedef 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() */ | ||
68 | typedef 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 */ | ||
78 | typedef 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 | * */ | ||
97 | typedef struct htc_packet *(*HTC_EP_RECV_ALLOC)(void *, HTC_ENDPOINT_ID Endpoint, int Length); | ||
98 | |||
99 | typedef 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. */ | ||
117 | typedef HTC_SEND_FULL_ACTION (*HTC_EP_SEND_QUEUE_FULL)(void *, struct htc_packet *pPacket); | ||
118 | |||
119 | struct 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 */ | ||
142 | struct 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 */ | ||
156 | struct 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 */ | ||
166 | struct 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 */ | ||
209 | typedef 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 | |||
218 | typedef void (*HTC_CREDIT_DIST_CALLBACK)(void *Context, | ||
219 | struct htc_endpoint_credit_dist *pEPList, | ||
220 | HTC_CREDIT_DIST_REASON Reason); | ||
221 | |||
222 | typedef void (*HTC_CREDIT_INIT_CALLBACK)(void *Context, | ||
223 | struct htc_endpoint_credit_dist *pEPList, | ||
224 | int TotalCredits); | ||
225 | |||
226 | /* endpoint statistics action */ | ||
227 | typedef 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 */ | ||
234 | struct 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
272 | HTC_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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
283 | void *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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
304 | void 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
322 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
337 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
351 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
364 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
380 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
392 | void 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
403 | void 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
417 | void 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
428 | void 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
442 | void 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
472 | bool 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
494 | void 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
514 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
533 | int 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
546 | bool 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 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
561 | int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, | ||
562 | HTC_ENDPOINT_ID Endpoint); | ||
563 | |||
564 | /* internally used functions for testing... */ | ||
565 | void HTCEnableRecv(HTC_HANDLE HTCHandle); | ||
566 | void HTCDisableRecv(HTC_HANDLE HTCHandle); | ||
567 | int 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 ------ */ | ||
30 | typedef 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 | |||
45 | struct htc_packet; | ||
46 | |||
47 | typedef void (* HTC_PACKET_COMPLETION)(void *,struct htc_packet *); | ||
48 | |||
49 | typedef u16 HTC_TX_TAG; | ||
50 | |||
51 | struct 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 | |||
62 | struct 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 */ | ||
71 | struct 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 */ | ||
142 | struct 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 */ | ||
168 | static 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 */ | ||
182 | static 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 */ | ||
192 | static 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 | ||
29 | extern "C" { | ||
30 | #endif | ||
31 | |||
32 | #include <a_osapi.h> | ||
33 | |||
34 | struct ieee80211_node_table; | ||
35 | struct ieee80211_frame; | ||
36 | |||
37 | struct 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 | |||
61 | typedef 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 | |||
83 | typedef void wlan_node_iter_func(void *arg, bss_t *); | ||
84 | |||
85 | bss_t *wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size); | ||
86 | void wlan_node_free(bss_t *ni); | ||
87 | void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, | ||
88 | const u8 *macaddr); | ||
89 | bss_t *wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr); | ||
90 | void wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni); | ||
91 | void wlan_free_allnodes(struct ieee80211_node_table *nt); | ||
92 | void wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f, | ||
93 | void *arg); | ||
94 | |||
95 | void wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt); | ||
96 | void wlan_node_table_reset(struct ieee80211_node_table *nt); | ||
97 | void wlan_node_table_cleanup(struct ieee80211_node_table *nt); | ||
98 | |||
99 | int wlan_parse_beacon(u8 *buf, int framelen, | ||
100 | struct ieee80211_common_ie *cie); | ||
101 | |||
102 | u16 wlan_ieee2freq(int chan); | ||
103 | u32 wlan_freq2ieee(u16 freq); | ||
104 | |||
105 | void wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge); | ||
106 | |||
107 | void | ||
108 | wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt); | ||
109 | |||
110 | bss_t * | ||
111 | wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid, | ||
112 | u32 ssidLength, bool bIsWPA2, bool bMatchSSID); | ||
113 | |||
114 | void | ||
115 | wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni); | ||
116 | |||
117 | bss_t *wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid); | ||
118 | |||
119 | bss_t * | ||
120 | wlan_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 | ||
29 | extern "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 | |||
60 | typedef enum { | ||
61 | ATHEROS_COMPLIANCE = 0x1, | ||
62 | }TSPEC_PARAM_COMPLIANCE; | ||
63 | |||
64 | struct wmi_t; | ||
65 | |||
66 | void *wmi_init(void *devt); | ||
67 | |||
68 | void wmi_qos_state_init(struct wmi_t *wmip); | ||
69 | void wmi_shutdown(struct wmi_t *wmip); | ||
70 | HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t * wmip); | ||
71 | void wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid); | ||
72 | u16 wmi_get_mapped_qos_queue(struct wmi_t *, u8 ); | ||
73 | int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf); | ||
74 | int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS); | ||
75 | int wmi_dot3_2_dix(void *osbuf); | ||
76 | |||
77 | int wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf); | ||
78 | int wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode); | ||
79 | |||
80 | int wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf); | ||
81 | int wmi_syncpoint(struct wmi_t *wmip); | ||
82 | int wmi_syncpoint_reset(struct wmi_t *wmip); | ||
83 | u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled); | ||
84 | |||
85 | u8 wmi_determine_userPriority (u8 *pkt, u32 layer2Pri); | ||
86 | |||
87 | int wmi_control_rx(struct wmi_t *wmip, void *osbuf); | ||
88 | void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg); | ||
89 | void wmi_free_allnodes(struct wmi_t *wmip); | ||
90 | bss_t *wmi_find_node(struct wmi_t *wmip, const u8 *macaddr); | ||
91 | void wmi_free_node(struct wmi_t *wmip, const u8 *macaddr); | ||
92 | |||
93 | |||
94 | typedef 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 | |||
102 | int wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, | ||
103 | WMI_SYNC_FLAG flag); | ||
104 | |||
105 | int 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 | |||
119 | int wmi_reconnect_cmd(struct wmi_t *wmip, | ||
120 | u8 *bssid, | ||
121 | u16 channel); | ||
122 | int wmi_disconnect_cmd(struct wmi_t *wmip); | ||
123 | int wmi_getrev_cmd(struct wmi_t *wmip); | ||
124 | int 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); | ||
128 | int 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); | ||
135 | int wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask); | ||
136 | int wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, | ||
137 | u8 ssidLength, u8 *ssid); | ||
138 | int wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons); | ||
139 | int wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmisstime, u16 bmissbeacons); | ||
140 | int wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType, | ||
141 | u8 ieLen, u8 *ieInfo); | ||
142 | int wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode); | ||
143 | int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl, | ||
144 | u16 atim_windows, u16 timeout_value); | ||
145 | int wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time, | ||
146 | u32 ps_period, u8 sleep_period); | ||
147 | int 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); | ||
151 | int wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout); | ||
152 | int wmi_sync_cmd(struct wmi_t *wmip, u8 syncNumber); | ||
153 | int wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream); | ||
154 | int wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 streamID); | ||
155 | int wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask); | ||
156 | int wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate); | ||
157 | int wmi_get_bitrate_cmd(struct wmi_t *wmip); | ||
158 | s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx); | ||
159 | int wmi_get_regDomain_cmd(struct wmi_t *wmip); | ||
160 | int wmi_get_channelList_cmd(struct wmi_t *wmip); | ||
161 | int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, | ||
162 | WMI_PHY_MODE mode, s8 numChan, | ||
163 | u16 *channelList); | ||
164 | |||
165 | int wmi_set_snr_threshold_params(struct wmi_t *wmip, | ||
166 | WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); | ||
167 | int wmi_set_rssi_threshold_params(struct wmi_t *wmip, | ||
168 | WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); | ||
169 | int wmi_clr_rssi_snr(struct wmi_t *wmip); | ||
170 | int wmi_set_lq_threshold_params(struct wmi_t *wmip, | ||
171 | WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd); | ||
172 | int wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold); | ||
173 | int wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy); | ||
174 | |||
175 | int wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 bitmask); | ||
176 | |||
177 | int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, | ||
178 | u32 source); | ||
179 | |||
180 | int wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask, | ||
181 | u16 tsr, bool rep, u16 size, | ||
182 | u32 valid); | ||
183 | |||
184 | int wmi_get_stats_cmd(struct wmi_t *wmip); | ||
185 | |||
186 | int 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); | ||
191 | int wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk); | ||
192 | int wmi_delete_krk_cmd(struct wmi_t *wmip); | ||
193 | int wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex); | ||
194 | int wmi_set_akmp_params_cmd(struct wmi_t *wmip, | ||
195 | WMI_SET_AKMP_PARAMS_CMD *akmpParams); | ||
196 | int wmi_get_pmkid_list_cmd(struct wmi_t *wmip); | ||
197 | int wmi_set_pmkid_list_cmd(struct wmi_t *wmip, | ||
198 | WMI_SET_PMKID_LIST_CMD *pmkInfo); | ||
199 | int wmi_abort_scan_cmd(struct wmi_t *wmip); | ||
200 | int wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM); | ||
201 | int wmi_get_txPwr_cmd(struct wmi_t *wmip); | ||
202 | int wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid); | ||
203 | int wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex); | ||
204 | int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en); | ||
205 | int wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId, | ||
206 | bool set); | ||
207 | int wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, | ||
208 | u8 eCWmin, u8 eCWmax, | ||
209 | u8 aifsn); | ||
210 | int wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType, | ||
211 | u8 trafficClass, u8 maxRetries, | ||
212 | u8 enableNotify); | ||
213 | |||
214 | void wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid); | ||
215 | |||
216 | int wmi_get_roam_tbl_cmd(struct wmi_t *wmip); | ||
217 | int wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType); | ||
218 | int wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, | ||
219 | u8 size); | ||
220 | int wmi_set_powersave_timers_cmd(struct wmi_t *wmip, | ||
221 | WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd, | ||
222 | u8 size); | ||
223 | |||
224 | int wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode); | ||
225 | int 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 | |||
232 | int wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl); | ||
233 | int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize); | ||
234 | int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSpLen); | ||
235 | u8 convert_userPriority_to_trafficClass(u8 userPriority); | ||
236 | u8 wmi_get_power_mode_cmd(struct wmi_t *wmip); | ||
237 | int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance); | ||
238 | |||
239 | #ifdef CONFIG_HOST_TCMD_SUPPORT | ||
240 | int wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len); | ||
241 | #endif | ||
242 | |||
243 | int wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status); | ||
244 | int wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd); | ||
245 | |||
246 | int wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd); | ||
247 | |||
248 | int wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip, | ||
249 | WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd); | ||
250 | |||
251 | int wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip, | ||
252 | WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *cmd); | ||
253 | |||
254 | int wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip, | ||
255 | WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd); | ||
256 | |||
257 | int wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip, | ||
258 | WMI_SET_BTCOEX_A2DP_CONFIG_CMD* cmd); | ||
259 | |||
260 | |||
261 | int wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD* cmd); | ||
262 | |||
263 | int wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd); | ||
264 | |||
265 | int wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip, | ||
266 | WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd); | ||
267 | |||
268 | int wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd); | ||
269 | |||
270 | int wmi_get_btcoex_stats_cmd(struct wmi_t * wmip); | ||
271 | |||
272 | int 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 | */ | ||
277 | int wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask); | ||
278 | int wmi_get_ratemask_cmd(struct wmi_t *wmip); | ||
279 | |||
280 | int wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode); | ||
281 | |||
282 | int wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode); | ||
283 | |||
284 | int wmi_set_qos_supp_cmd(struct wmi_t *wmip,u8 status); | ||
285 | int wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status); | ||
286 | int wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable); | ||
287 | int wmi_set_country(struct wmi_t *wmip, u8 *countryCode); | ||
288 | |||
289 | int wmi_get_keepalive_configured(struct wmi_t *wmip); | ||
290 | u8 wmi_get_keepalive_cmd(struct wmi_t *wmip); | ||
291 | int wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval); | ||
292 | |||
293 | int wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, | ||
294 | u8 ieLen,u8 *ieInfo); | ||
295 | |||
296 | int wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen); | ||
297 | |||
298 | s32 wmi_get_rate(s8 rateindex); | ||
299 | |||
300 | int wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd); | ||
301 | |||
302 | /*Wake on Wireless WMI commands*/ | ||
303 | int wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *cmd); | ||
304 | int wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd); | ||
305 | int wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd); | ||
306 | int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, | ||
307 | WMI_ADD_WOW_PATTERN_CMD *cmd, u8 *pattern, u8 *mask, u8 pattern_size); | ||
308 | int wmi_del_wow_pattern_cmd(struct wmi_t *wmip, | ||
309 | WMI_DEL_WOW_PATTERN_CMD *cmd); | ||
310 | int wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status); | ||
311 | |||
312 | int | ||
313 | wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer); | ||
314 | |||
315 | int | ||
316 | wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4); | ||
317 | |||
318 | int | ||
319 | wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4); | ||
320 | |||
321 | int | ||
322 | wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable); | ||
323 | |||
324 | bss_t * | ||
325 | wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid, | ||
326 | u32 ssidLength, bool bIsWPA2, bool bMatchSSID); | ||
327 | |||
328 | |||
329 | void | ||
330 | wmi_node_return (struct wmi_t *wmip, bss_t *bss); | ||
331 | |||
332 | void | ||
333 | wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge); | ||
334 | |||
335 | #if defined(CONFIG_TARGET_PROFILE_SUPPORT) | ||
336 | int wmi_prof_cfg_cmd(struct wmi_t *wmip, u32 period, u32 nbins); | ||
337 | int wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr); | ||
338 | int wmi_prof_start_cmd(struct wmi_t *wmip); | ||
339 | int wmi_prof_stop_cmd(struct wmi_t *wmip); | ||
340 | int wmi_prof_count_get_cmd(struct wmi_t *wmip); | ||
341 | #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ | ||
342 | #ifdef OS_ROAM_MANAGEMENT | ||
343 | void wmi_scan_indication (struct wmi_t *wmip); | ||
344 | #endif | ||
345 | |||
346 | int | ||
347 | wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd); | ||
348 | |||
349 | bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id); | ||
350 | int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss); | ||
351 | |||
352 | |||
353 | /* | ||
354 | * AP mode | ||
355 | */ | ||
356 | int | ||
357 | wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p); | ||
358 | |||
359 | int | ||
360 | wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid); | ||
361 | |||
362 | int | ||
363 | wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta); | ||
364 | |||
365 | int | ||
366 | wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy); | ||
367 | |||
368 | int | ||
369 | wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *a); | ||
370 | |||
371 | u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl); | ||
372 | |||
373 | int | ||
374 | wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason); | ||
375 | |||
376 | int | ||
377 | wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag); | ||
378 | |||
379 | int | ||
380 | wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period); | ||
381 | |||
382 | int | ||
383 | wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell); | ||
384 | |||
385 | int | ||
386 | wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim); | ||
387 | |||
388 | int | ||
389 | wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset); | ||
390 | |||
391 | int | ||
392 | wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd); | ||
393 | |||
394 | int | ||
395 | wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width); | ||
396 | |||
397 | int | ||
398 | wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz); | ||
399 | |||
400 | int | ||
401 | wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray); | ||
402 | |||
403 | int | ||
404 | wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid); | ||
405 | |||
406 | int | ||
407 | wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink); | ||
408 | |||
409 | int | ||
410 | wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask); | ||
411 | |||
412 | int | ||
413 | wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion, bool rxDot11Hdr, bool defragOnHost); | ||
414 | |||
415 | int | ||
416 | wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode); | ||
417 | |||
418 | int | ||
419 | wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence); | ||
420 | |||
421 | int | ||
422 | wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk); | ||
423 | |||
424 | int | ||
425 | wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd); | ||
426 | |||
427 | u16 wmi_ieee2freq (int chan); | ||
428 | |||
429 | u32 wmi_freq2ieee (u16 freq); | ||
430 | |||
431 | bss_t * | ||
432 | wmi_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 | |||
49 | int AthPSInitialize(struct ar3k_config_info *hdev); | ||
50 | |||
51 | static 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 | |||
86 | static 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 | |||
124 | int 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 | |||
211 | static 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 | |||
276 | static 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 | |||
312 | static 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 | |||
336 | static 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 | |||
455 | int 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 | |||
523 | int 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 | */ | ||
42 | typedef struct { | ||
43 | |||
44 | struct ps_cmd_packet *HciCmdList; | ||
45 | u32 num_packets; | ||
46 | struct ar3k_config_info *dev; | ||
47 | }HciCommandListParam; | ||
48 | |||
49 | int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig, | ||
50 | u8 *pHCICommand, | ||
51 | int CmdLength, | ||
52 | u8 **ppEventBuffer, | ||
53 | u8 **ppBufferToFree); | ||
54 | |||
55 | u32 Rom_Version; | ||
56 | u32 Build_Version; | ||
57 | extern bool BDADDR; | ||
58 | |||
59 | int getDeviceType(struct ar3k_config_info *pConfig, u32 *code); | ||
60 | int ReadVersionInfo(struct ar3k_config_info *pConfig); | ||
61 | #ifndef HCI_TRANSPORT_SDIO | ||
62 | |||
63 | DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent); | ||
64 | DECLARE_WAIT_QUEUE_HEAD(HciEvent); | ||
65 | u8 *HciEventpacket; | ||
66 | rwlock_t syncLock; | ||
67 | wait_queue_t Eventwait; | ||
68 | |||
69 | int PSHciWritepacket(struct hci_dev*,u8* Data, u32 len); | ||
70 | extern char *bdaddr; | ||
71 | #endif /* HCI_TRANSPORT_SDIO */ | ||
72 | |||
73 | int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type); | ||
74 | |||
75 | int PSSendOps(void *arg); | ||
76 | |||
77 | #ifdef BT_PS_DEBUG | ||
78 | void 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 | |||
94 | int 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 | |||
132 | int 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 | } | ||
369 | complete: | ||
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 | */ | ||
392 | int 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 | |||
422 | int 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 | } | ||
457 | int 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 | |||
484 | int 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 | } | ||
519 | int 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 | } | ||
534 | int 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 | ||
68 | extern wait_queue_head_t HciEvent; | ||
69 | extern wait_queue_t Eventwait; | ||
70 | extern u8 *HciEventpacket; | ||
71 | #endif /* #ifndef HCI_TRANSPORT_SDIO */ | ||
72 | |||
73 | int AthPSInitialize(struct ar3k_config_info *hdev); | ||
74 | int 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 | |||
68 | enum MinBootFileFormatE | ||
69 | { | ||
70 | MB_FILEFORMAT_RADIOTBL, | ||
71 | MB_FILEFORMAT_PATCH, | ||
72 | MB_FILEFORMAT_COEXCONFIG | ||
73 | }; | ||
74 | |||
75 | enum RamPsSection | ||
76 | { | ||
77 | RAM_PS_SECTION, | ||
78 | RAM_PATCH_SECTION, | ||
79 | RAM_DYN_MEM_SECTION | ||
80 | }; | ||
81 | |||
82 | enum eType { | ||
83 | eHex, | ||
84 | edecimal | ||
85 | }; | ||
86 | |||
87 | |||
88 | typedef struct tPsTagEntry | ||
89 | { | ||
90 | u32 TagId; | ||
91 | u32 TagLen; | ||
92 | u8 *TagData; | ||
93 | } tPsTagEntry, *tpPsTagEntry; | ||
94 | |||
95 | typedef struct tRamPatch | ||
96 | { | ||
97 | u16 Len; | ||
98 | u8 *Data; | ||
99 | } tRamPatch, *ptRamPatch; | ||
100 | |||
101 | |||
102 | |||
103 | struct st_ps_data_format { | ||
104 | enum eType eDataType; | ||
105 | bool bIsArray; | ||
106 | }; | ||
107 | |||
108 | struct 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 */ | ||
118 | static u32 Tag_Count = 0; | ||
119 | |||
120 | /* Stores the number of patch commands */ | ||
121 | static u32 Patch_Count = 0; | ||
122 | static u32 Total_tag_lenght = 0; | ||
123 | bool BDADDR = false; | ||
124 | u32 StartTagId; | ||
125 | |||
126 | tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE]; | ||
127 | tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY]; | ||
128 | |||
129 | |||
130 | int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat); | ||
131 | char AthReadChar(u8 *buffer, u32 len,u32 *pos); | ||
132 | char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos); | ||
133 | static 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 */ | ||
136 | char 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 */ | ||
149 | unsigned 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 | |||
289 | unsigned 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 | } | ||
318 | int 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 | |||
561 | int 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 | |||
582 | int 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 | /********************/ | ||
662 | int 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 | } | ||
716 | char *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 | |||
754 | static 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 | // | ||
767 | int 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 | ///////////// | ||
836 | static 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 | } | ||
958 | int 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 | |||
86 | struct ps_cmd_packet | ||
87 | { | ||
88 | u8 *Hcipacket; | ||
89 | int packetLen; | ||
90 | }; | ||
91 | |||
92 | /* Parses a Patch information buffer and store it in global structure */ | ||
93 | int AthDoParsePatch(u8 *, u32 ); | ||
94 | |||
95 | /* parses a PS information buffer and stores it in a global structure */ | ||
96 | int 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 | */ | ||
109 | int AthCreateCommandList(struct ps_cmd_packet **, u32 *); | ||
110 | |||
111 | /* Cleanup the dynamically allicated HCI command list */ | ||
112 | int 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 | |||
45 | static ATH_DEBUG_MODULE_DBG_INFO *g_pModuleInfoHead = NULL; | ||
46 | static A_MUTEX_T g_ModuleListLock; | ||
47 | static bool g_ModuleDebugInit = false; | ||
48 | |||
49 | #ifdef ATH_DEBUG_MODULE | ||
50 | |||
51 | ATH_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 | |||
71 | static u8 custDataAR6002[AR6002_CUST_DATA_SIZE]; | ||
72 | static 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 ). */ | ||
83 | int 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 */ | ||
144 | int 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 | */ | ||
186 | int | ||
187 | ar6000_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 | */ | ||
220 | int | ||
221 | ar6000_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 | |||
243 | int | ||
244 | ar6000_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 | |||
261 | int | ||
262 | ar6000_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 | |||
279 | int | ||
280 | ar6k_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 | |||
315 | void | ||
316 | ar6k_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 | ||
329 | static 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 | ||
357 | static 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 */ | ||
399 | int 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 */ | ||
480 | void | ||
481 | ar6000_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 */ | ||
526 | u8 *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 | |||
552 | void 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, ®DumpArea); | ||
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 *)®DumpValues[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 */ | ||
624 | int 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 | |||
683 | void 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 | |||
718 | void 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 | |||
754 | static 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 | |||
774 | void 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 | |||
795 | void 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 | |||
820 | int 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 | |||
832 | int 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 | |||
846 | void 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 | |||
857 | void 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 */ | ||
885 | int 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 | |||
43 | static void RedistributeCredits(struct common_credit_state_info *pCredInfo, | ||
44 | struct htc_endpoint_credit_dist *pEPDistList); | ||
45 | |||
46 | static 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 */ | ||
50 | static 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 */ | ||
82 | static 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 | */ | ||
176 | static 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 */ | ||
245 | static 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 */ | ||
285 | static 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 */ | ||
395 | int 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 | |||
30 | u32 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 | |||
48 | u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
49 | u8 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 | |||
61 | static 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 | |||
73 | ATH_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 | |||
89 | MODULE_AUTHOR("Atheros Communications, Inc."); | ||
90 | MODULE_DESCRIPTION(DESCRIPTION); | ||
91 | MODULE_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 | |||
102 | typedef struct aptc_traffic_record { | ||
103 | bool timerScheduled; | ||
104 | struct timeval samplingTS; | ||
105 | unsigned long bytesReceived; | ||
106 | unsigned long bytesTransmitted; | ||
107 | } APTC_TRAFFIC_RECORD; | ||
108 | |||
109 | A_TIMER aptcTimer; | ||
110 | APTC_TRAFFIC_RECORD aptcTR; | ||
111 | #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ | ||
112 | |||
113 | #ifdef EXPORT_HCI_BRIDGE_INTERFACE | ||
114 | // callbacks registered by HCI transport driver | ||
115 | struct hci_transport_callbacks ar6kHciTransCallbacks = { NULL }; | ||
116 | #endif | ||
117 | |||
118 | unsigned int processDot11Hdr = 0; | ||
119 | |||
120 | char ifname[IFNAMSIZ] = {0,}; | ||
121 | |||
122 | int wlaninitmode = WLAN_INIT_MODE_DEFAULT; | ||
123 | static bool bypasswmi; | ||
124 | unsigned int debuglevel = 0; | ||
125 | int tspecCompliance = ATHEROS_COMPLIANCE; | ||
126 | unsigned int busspeedlow = 0; | ||
127 | unsigned int onebitmode = 0; | ||
128 | unsigned int skipflash = 0; | ||
129 | unsigned int wmitimeout = 2; | ||
130 | unsigned int wlanNodeCaching = 1; | ||
131 | unsigned int enableuartprint = ENABLEUARTPRINT_DEFAULT; | ||
132 | unsigned int logWmiRawMsgs = 0; | ||
133 | unsigned int enabletimerwar = 0; | ||
134 | unsigned int num_device = 1; | ||
135 | unsigned int regscanmode; | ||
136 | unsigned int fwmode = 1; | ||
137 | unsigned int mbox_yield_limit = 99; | ||
138 | unsigned int enablerssicompensation = 0; | ||
139 | int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF; | ||
140 | int allow_trace_signal = 0; | ||
141 | #ifdef CONFIG_HOST_TCMD_SUPPORT | ||
142 | unsigned int testmode =0; | ||
143 | #endif | ||
144 | |||
145 | unsigned int irqprocmode = HIF_DEVICE_IRQ_SYNC_ONLY;//HIF_DEVICE_IRQ_ASYNC_SYNC; | ||
146 | unsigned int panic_on_assert = 1; | ||
147 | unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT; | ||
148 | |||
149 | unsigned int setuphci = SETUPHCI_DEFAULT; | ||
150 | unsigned int loghci = 0; | ||
151 | unsigned int setupbtdev = SETUPBTDEV_DEFAULT; | ||
152 | #ifndef EXPORT_HCI_BRIDGE_INTERFACE | ||
153 | unsigned int ar3khcibaud = AR3KHCIBAUD_DEFAULT; | ||
154 | unsigned int hciuartscale = HCIUARTSCALE_DEFAULT; | ||
155 | unsigned int hciuartstep = HCIUARTSTEP_DEFAULT; | ||
156 | #endif | ||
157 | unsigned int csumOffload=0; | ||
158 | unsigned int csumOffloadTest=0; | ||
159 | unsigned int eppingtest=0; | ||
160 | unsigned int mac_addr_method; | ||
161 | unsigned int firmware_bridge; | ||
162 | |||
163 | module_param_string(ifname, ifname, sizeof(ifname), 0644); | ||
164 | module_param(wlaninitmode, int, 0644); | ||
165 | module_param(bypasswmi, bool, 0644); | ||
166 | module_param(debuglevel, uint, 0644); | ||
167 | module_param(tspecCompliance, int, 0644); | ||
168 | module_param(onebitmode, uint, 0644); | ||
169 | module_param(busspeedlow, uint, 0644); | ||
170 | module_param(skipflash, uint, 0644); | ||
171 | module_param(wmitimeout, uint, 0644); | ||
172 | module_param(wlanNodeCaching, uint, 0644); | ||
173 | module_param(logWmiRawMsgs, uint, 0644); | ||
174 | module_param(enableuartprint, uint, 0644); | ||
175 | module_param(enabletimerwar, uint, 0644); | ||
176 | module_param(fwmode, uint, 0644); | ||
177 | module_param(mbox_yield_limit, uint, 0644); | ||
178 | module_param(reduce_credit_dribble, int, 0644); | ||
179 | module_param(allow_trace_signal, int, 0644); | ||
180 | module_param(enablerssicompensation, uint, 0644); | ||
181 | module_param(processDot11Hdr, uint, 0644); | ||
182 | module_param(csumOffload, uint, 0644); | ||
183 | #ifdef CONFIG_HOST_TCMD_SUPPORT | ||
184 | module_param(testmode, uint, 0644); | ||
185 | #endif | ||
186 | module_param(irqprocmode, uint, 0644); | ||
187 | module_param(nohifscattersupport, uint, 0644); | ||
188 | module_param(panic_on_assert, uint, 0644); | ||
189 | module_param(setuphci, uint, 0644); | ||
190 | module_param(loghci, uint, 0644); | ||
191 | module_param(setupbtdev, uint, 0644); | ||
192 | #ifndef EXPORT_HCI_BRIDGE_INTERFACE | ||
193 | module_param(ar3khcibaud, uint, 0644); | ||
194 | module_param(hciuartscale, uint, 0644); | ||
195 | module_param(hciuartstep, uint, 0644); | ||
196 | #endif | ||
197 | module_param(eppingtest, uint, 0644); | ||
198 | |||
199 | /* in 2.6.10 and later this is now a pointer to a uint */ | ||
200 | unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX; | ||
201 | #define mboxnum &_mboxnum | ||
202 | |||
203 | #ifdef DEBUG | ||
204 | u32 g_dbg_flags = DBG_DEFAULTS; | ||
205 | unsigned int debugflags = 0; | ||
206 | int debugdriver = 0; | ||
207 | unsigned int debughtc = 0; | ||
208 | unsigned int debugbmi = 0; | ||
209 | unsigned int debughif = 0; | ||
210 | unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0}; | ||
211 | unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0}; | ||
212 | unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0}; | ||
213 | unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0}; | ||
214 | module_param(debugflags, uint, 0644); | ||
215 | module_param(debugdriver, int, 0644); | ||
216 | module_param(debughtc, uint, 0644); | ||
217 | module_param(debugbmi, uint, 0644); | ||
218 | module_param(debughif, uint, 0644); | ||
219 | module_param_array(txcreditsavailable, uint, mboxnum, 0644); | ||
220 | module_param_array(txcreditsconsumed, uint, mboxnum, 0644); | ||
221 | module_param_array(txcreditintrenable, uint, mboxnum, 0644); | ||
222 | module_param_array(txcreditintrenableaggregate, uint, mboxnum, 0644); | ||
223 | |||
224 | #endif /* DEBUG */ | ||
225 | |||
226 | unsigned int resetok = 1; | ||
227 | unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0}; | ||
228 | unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0}; | ||
229 | unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0}; | ||
230 | unsigned int hifBusRequestNumMax = 40; | ||
231 | unsigned int war23838_disabled = 0; | ||
232 | #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL | ||
233 | unsigned int enableAPTCHeuristics = 1; | ||
234 | #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ | ||
235 | module_param_array(tx_attempt, uint, mboxnum, 0644); | ||
236 | module_param_array(tx_post, uint, mboxnum, 0644); | ||
237 | module_param_array(tx_complete, uint, mboxnum, 0644); | ||
238 | module_param(hifBusRequestNumMax, uint, 0644); | ||
239 | module_param(war23838_disabled, uint, 0644); | ||
240 | module_param(resetok, uint, 0644); | ||
241 | #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL | ||
242 | module_param(enableAPTCHeuristics, uint, 0644); | ||
243 | #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ | ||
244 | |||
245 | #ifdef BLOCK_TX_PATH_FLAG | ||
246 | int blocktx = 0; | ||
247 | module_param(blocktx, int, 0644); | ||
248 | #endif /* BLOCK_TX_PATH_FLAG */ | ||
249 | |||
250 | typedef 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 | |||
264 | static USER_RSSI_CPENSATION rssi_compensation_param; | ||
265 | |||
266 | static s16 rssi_compensation_table[96]; | ||
267 | |||
268 | int reconnect_flag = 0; | ||
269 | static ar6k_pal_config_t ar6k_pal_config_g; | ||
270 | |||
271 | /* Function declarations */ | ||
272 | static int ar6000_init_module(void); | ||
273 | static void ar6000_cleanup_module(void); | ||
274 | |||
275 | int ar6000_init(struct net_device *dev); | ||
276 | static int ar6000_open(struct net_device *dev); | ||
277 | static int ar6000_close(struct net_device *dev); | ||
278 | static void ar6000_init_control_info(struct ar6_softc *ar); | ||
279 | static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev); | ||
280 | |||
281 | void ar6000_destroy(struct net_device *dev, unsigned int unregister); | ||
282 | static void ar6000_detect_error(unsigned long ptr); | ||
283 | static void ar6000_set_multicast_list(struct net_device *dev); | ||
284 | static struct net_device_stats *ar6000_get_stats(struct net_device *dev); | ||
285 | |||
286 | static void disconnect_timer_handler(unsigned long ptr); | ||
287 | |||
288 | void read_rssi_compensation_param(struct ar6_softc *ar); | ||
289 | |||
290 | /* | ||
291 | * HTC service connection handlers | ||
292 | */ | ||
293 | static int ar6000_avail_ev(void *context, void *hif_handle); | ||
294 | |||
295 | static int ar6000_unavail_ev(void *context, void *hif_handle); | ||
296 | |||
297 | int ar6000_configure_target(struct ar6_softc *ar); | ||
298 | |||
299 | static void ar6000_target_failure(void *Instance, int Status); | ||
300 | |||
301 | static void ar6000_rx(void *Context, struct htc_packet *pPacket); | ||
302 | |||
303 | static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint); | ||
304 | |||
305 | static void ar6000_tx_complete(void *Context, struct htc_packet_queue *pPackets); | ||
306 | |||
307 | static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket); | ||
308 | |||
309 | static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num); | ||
310 | static 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 | |||
313 | static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length); | ||
314 | |||
315 | static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count); | ||
316 | |||
317 | static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar); | ||
318 | |||
319 | static ssize_t | ||
320 | ar6000_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 | |||
324 | static ssize_t | ||
325 | ar6000_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 | |||
329 | static int | ||
330 | ar6000_sysfs_bmi_init(struct ar6_softc *ar); | ||
331 | |||
332 | void ar6k_cleanup_hci_pal(struct ar6_softc *ar); | ||
333 | |||
334 | static void | ||
335 | ar6000_sysfs_bmi_deinit(struct ar6_softc *ar); | ||
336 | |||
337 | int | ||
338 | ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode); | ||
339 | |||
340 | /* | ||
341 | * Static variables | ||
342 | */ | ||
343 | |||
344 | struct net_device *ar6000_devices[MAX_AR6000]; | ||
345 | static int is_netdev_registered; | ||
346 | DECLARE_WAIT_QUEUE_HEAD(arEvent); | ||
347 | static void ar6000_cookie_init(struct ar6_softc *ar); | ||
348 | static void ar6000_cookie_cleanup(struct ar6_softc *ar); | ||
349 | static void ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie); | ||
350 | static struct ar_cookie *ar6000_alloc_cookie(struct ar6_softc *ar); | ||
351 | |||
352 | static int ar6000_reinstall_keys(struct ar6_softc *ar,u8 key_op_ctrl); | ||
353 | |||
354 | #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT | ||
355 | struct net_device *arApNetDev; | ||
356 | #endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ | ||
357 | |||
358 | static 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 | |||
365 | static 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 | |||
382 | int | ||
383 | ar6000_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 | |||
405 | u32 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 *)¶m, 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 | */ | ||
425 | void | ||
426 | ar6000_dbglog_init_done(struct ar6_softc *ar) | ||
427 | { | ||
428 | ar->dbglog_init_done = true; | ||
429 | } | ||
430 | |||
431 | u32 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 | |||
456 | void | ||
457 | dbglog_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 | |||
497 | int | ||
498 | ar6000_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 | |||
575 | void | ||
576 | ar6000_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 | |||
606 | static int __init | ||
607 | ar6000_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 | |||
667 | static void __exit | ||
668 | ar6000_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 | ||
696 | void | ||
697 | aptcTimerHandler(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 | |||
732 | static void | ||
733 | ar6000_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 | |||
751 | static 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 | |||
757 | static ssize_t | ||
758 | ar6000_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 | |||
784 | static ssize_t | ||
785 | ar6000_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 | |||
811 | static int | ||
812 | ar6000_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 | |||
840 | static void | ||
841 | ar6000_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 | ||
858 | static | ||
859 | void 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 | |||
899 | static void | ||
900 | ar6000_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 | |||
950 | static int | ||
951 | ar6000_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 *)¶m, 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 | |||
1141 | int | ||
1142 | ar6000_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 | |||
1165 | return 0; | ||
1166 | } | ||
1167 | |||
1168 | int | ||
1169 | ar6000_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, ¶m)); | ||
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, ¶m)); | ||
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 *)¶m, 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 *)¶m, 4)); | ||
1253 | |||
1254 | /* CLOCK_CONTROL &= ~LF_CLK32 */ | ||
1255 | address = RTC_BASE_ADDRESS + CLOCK_CONTROL_ADDRESS; | ||
1256 | bmifn(BMIReadSOCRegister(ar->arHifDevice, address, ¶m)); | ||
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 *)¶m, 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, ¶m)); | ||
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 *)¶m, 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 *)¶m, 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, ¶m)); | ||
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 *)¶m, 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 *)¶m, 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 | |||
1375 | int | ||
1376 | ar6000_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 *)¶m, | ||
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 *)¶m, | ||
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 *)¶m, | ||
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 *)¶m, | ||
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 *)¶m, | ||
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 *)¶m, | ||
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 *)¶m, | ||
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 *)¶m, | ||
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 *)¶m, 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 | |||
1548 | static void | ||
1549 | init_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 | |||
1579 | static 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 | ||
1596 | static 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 | ||
1604 | static int ath6kl_init_netdev_wmi(struct net_device *dev) | ||
1605 | { | ||
1606 | return __ath6kl_init_netdev(dev); | ||
1607 | } | ||
1608 | #endif | ||
1609 | |||
1610 | static 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 | */ | ||
1628 | static int | ||
1629 | ar6000_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 | |||
1820 | avail_ev_failed : | ||
1821 | if (r) | ||
1822 | ar6000_sysfs_bmi_deinit(ar); | ||
1823 | |||
1824 | return r; | ||
1825 | } | ||
1826 | |||
1827 | static 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 | |||
1859 | static int | ||
1860 | ar6000_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 | |||
1870 | void | ||
1871 | ar6000_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 | |||
1905 | void | ||
1906 | ar6000_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 | */ | ||
2032 | void | ||
2033 | ar6000_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 | |||
2113 | static 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 | |||
2124 | static 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 | |||
2163 | void 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 | |||
2192 | static void | ||
2193 | ar6000_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 | |||
2241 | static int | ||
2242 | ar6000_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 | |||
2265 | static int | ||
2266 | ar6000_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 */ | ||
2286 | static 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 | |||
2338 | void 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 | |||
2357 | HTC_ENDPOINT_ID | ||
2358 | ar6000_ac2_endpoint_id ( void * devt, u8 ac) | ||
2359 | { | ||
2360 | struct ar6_softc *ar = (struct ar6_softc *) devt; | ||
2361 | return(arAc2EndpointID(ar, ac)); | ||
2362 | } | ||
2363 | |||
2364 | u8 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) | ||
2371 | static 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 | ||
2404 | static 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 | */ | ||
2413 | int 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 */ | ||
2498 | int 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 *)¶m, | ||
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 *)¶m, | ||
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 | |||
2813 | ar6000_init_done: | ||
2814 | rtnl_lock(); | ||
2815 | dev_put(dev); | ||
2816 | |||
2817 | return ret; | ||
2818 | } | ||
2819 | |||
2820 | |||
2821 | void | ||
2822 | ar6000_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 | |||
2830 | void | ||
2831 | ar6000_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 | |||
2839 | void | ||
2840 | ar6000_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 | |||
2849 | void | ||
2850 | ar6000_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 | |||
2860 | u8 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 | ||
2917 | static 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 | ||
2931 | static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *skb); | ||
2932 | #endif | ||
2933 | |||
2934 | static int | ||
2935 | ar6000_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 | |||
3253 | int | ||
3254 | ar6000_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 | ||
3301 | static void | ||
3302 | tvsub(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 | |||
3311 | void | ||
3312 | applyAPTCHeuristics(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 | |||
3351 | static 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 | |||
3435 | static void | ||
3436 | ar6000_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 | |||
3573 | sta_t * | ||
3574 | ieee80211_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 | |||
3598 | sta_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 | */ | ||
3615 | int pktcount; | ||
3616 | static void | ||
3617 | ar6000_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 | |||
3902 | rx_done: | ||
3903 | |||
3904 | return; | ||
3905 | } | ||
3906 | |||
3907 | static void | ||
3908 | ar6000_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 | ||
3941 | static void | ||
3942 | ar6000_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 | |||
3958 | static void | ||
3959 | ar6000_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 */ | ||
4003 | static 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 */ | ||
4032 | static 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 | * */ | ||
4064 | static 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 | |||
4107 | static void | ||
4108 | ar6000_set_multicast_list(struct net_device *dev) | ||
4109 | { | ||
4110 | AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: Multicast filter not supported\n")); | ||
4111 | } | ||
4112 | |||
4113 | static struct net_device_stats * | ||
4114 | ar6000_get_stats(struct net_device *dev) | ||
4115 | { | ||
4116 | struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); | ||
4117 | return &ar->arNetStats; | ||
4118 | } | ||
4119 | |||
4120 | void | ||
4121 | ar6000_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 | |||
4148 | void 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 | |||
4171 | void | ||
4172 | add_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 | |||
4187 | void | ||
4188 | ar6000_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 | } | ||
4243 | skip_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 | |||
4450 | void 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 | |||
4456 | void | ||
4457 | sta_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 | |||
4480 | u8 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 | |||
4512 | void | ||
4513 | ar6000_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 | |||
4656 | void | ||
4657 | ar6000_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 | |||
4663 | void | ||
4664 | ar6000_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 | |||
4671 | void | ||
4672 | ar6000_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 | |||
4679 | void | ||
4680 | ar6000_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 | |||
4685 | void register_pal_cb(ar6k_pal_config_t *palConfig_p) | ||
4686 | { | ||
4687 | ar6k_pal_config_g = *palConfig_p; | ||
4688 | } | ||
4689 | |||
4690 | void | ||
4691 | ar6000_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 | |||
4729 | void | ||
4730 | ar6000_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 | |||
4777 | void | ||
4778 | ar6000_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 | |||
4812 | void | ||
4813 | ar6000_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 | |||
4833 | void | ||
4834 | ar6000_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 | |||
4958 | void | ||
4959 | ar6000_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 | |||
4977 | void | ||
4978 | ar6000_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 | |||
4989 | void | ||
4990 | ar6000_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 | |||
5024 | void | ||
5025 | ar6000_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 | |||
5047 | void | ||
5048 | ar6000_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 | |||
5061 | void | ||
5062 | ar6000_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 | |||
5086 | void | ||
5087 | ar6000_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 | */ | ||
5125 | void | ||
5126 | ar6000_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 | |||
5140 | void | ||
5141 | ar6000_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 | |||
5152 | void | ||
5153 | ar6000_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 | |||
5183 | u32 wmiSendCmdNum; | ||
5184 | |||
5185 | int | ||
5186 | ar6000_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 */ | ||
5265 | void 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 | |||
5324 | void | ||
5325 | ar6000_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 | |||
5361 | void | ||
5362 | ar6000_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 | } | ||
5376 | module_init(ar6000_init_module); | ||
5377 | module_exit(ar6000_cleanup_module); | ||
5378 | |||
5379 | /* Init cookie queue */ | ||
5380 | static void | ||
5381 | ar6000_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 */ | ||
5396 | static void | ||
5397 | ar6000_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 */ | ||
5405 | static void | ||
5406 | ar6000_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 */ | ||
5418 | static struct ar_cookie * | ||
5419 | ar6000_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 | |||
5433 | void | ||
5434 | ar6000_tx_retry_err_event(void *devt) | ||
5435 | { | ||
5436 | AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Tx retries reach maximum!\n")); | ||
5437 | } | ||
5438 | |||
5439 | void | ||
5440 | ar6000_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 | |||
5448 | void | ||
5449 | ar6000_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 | |||
5456 | u32 a_copy_to_user(void *to, const void *from, u32 n) | ||
5457 | { | ||
5458 | return(copy_to_user(to, from, n)); | ||
5459 | } | ||
5460 | |||
5461 | u32 a_copy_from_user(void *to, const void *from, u32 n) | ||
5462 | { | ||
5463 | return(copy_from_user(to, from, n)); | ||
5464 | } | ||
5465 | |||
5466 | |||
5467 | int | ||
5468 | ar6000_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 | |||
5491 | void | ||
5492 | ar6000_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 | |||
5500 | void | ||
5501 | ar6000_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 | |||
5523 | void 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 | |||
5563 | void 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 | |||
5608 | void | ||
5609 | read_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 | |||
5651 | s32 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 | |||
5680 | s16 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 | |||
5708 | s16 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 | ||
5753 | void 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 | |||
5772 | static int | ||
5773 | ar6000_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 | |||
5819 | void | ||
5820 | ar6000_dset_open_req( | ||
5821 | void *context, | ||
5822 | u32 id, | ||
5823 | u32 targHandle, | ||
5824 | u32 targReplyFn, | ||
5825 | u32 targReplyArg) | ||
5826 | { | ||
5827 | } | ||
5828 | |||
5829 | void | ||
5830 | ar6000_dset_close( | ||
5831 | void *context, | ||
5832 | u32 access_cookie) | ||
5833 | { | ||
5834 | return; | ||
5835 | } | ||
5836 | |||
5837 | void | ||
5838 | ar6000_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 | |||
5849 | int | ||
5850 | ar6000_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 | |||
5912 | int | ||
5913 | ar6000_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 | |||
5983 | int | ||
5984 | ar6000_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 | |||
5998 | int | ||
5999 | ar6000_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 | |||
6014 | int | ||
6015 | is_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 | |||
6031 | int | ||
6032 | is_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 | ||
6044 | int | ||
6045 | ap_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 | |||
6072 | void 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 | ||
6086 | static 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 | |||
6170 | int 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 | |||
6181 | int 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 | |||
6195 | int 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 | |||
6229 | int 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 | |||
6246 | int 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 | ||
6266 | EXPORT_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 | |||
36 | extern unsigned int wmitimeout; | ||
37 | extern 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 | ||
44 | static struct ath_debug_mask_description pm_debug_desc[] = { | ||
45 | { ATH_DEBUG_PM , "System power management"}, | ||
46 | }; | ||
47 | |||
48 | ATH_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 | |||
57 | int ar6000_exit_cut_power_state(struct ar6_softc *ar); | ||
58 | |||
59 | #ifdef CONFIG_PM | ||
60 | static 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 | |||
71 | static 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 | |||
110 | static 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 | |||
211 | int ar6000_suspend_ev(void *context) | ||
212 | { | ||
213 | int status = 0; | ||
214 | struct ar6_softc *ar = (struct ar6_softc *)context; | ||
215 | s16 pmmode = ar->arSuspendConfig; | ||
216 | wow_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 | |||
248 | int 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 | |||
273 | void 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 | |||
286 | int 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 | |||
307 | int | ||
308 | ar6000_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 | |||
362 | int | ||
363 | ar6000_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 | |||
486 | int | ||
487 | ar6000_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 | |||
598 | int | ||
599 | ar6000_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 | |||
615 | int | ||
616 | ar6000_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 | |||
28 | static void | ||
29 | ar6000_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 | |||
72 | static void | ||
73 | ar6000_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 */ | ||
114 | static 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 | |||
169 | int 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 | |||
275 | int 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 | |||
288 | raw_htc_buffer * | ||
289 | get_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 | |||
311 | ssize_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 | |||
370 | static raw_htc_buffer * | ||
371 | get_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 | |||
393 | ssize_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 | |||
32 | extern A_WAITQUEUE_HEAD arEvent; | ||
33 | extern unsigned int wmitimeout; | ||
34 | extern 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 | |||
61 | static struct | ||
62 | ieee80211_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 | |||
82 | static struct | ||
83 | ieee80211_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 | |||
100 | static struct | ||
101 | ieee80211_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 | |||
123 | static struct | ||
124 | ieee80211_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 | |||
131 | static struct | ||
132 | ieee80211_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 | |||
139 | static int | ||
140 | ar6k_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 | |||
160 | static int | ||
161 | ar6k_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 | |||
192 | static int | ||
193 | ar6k_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 | |||
234 | static void | ||
235 | ar6k_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 | |||
250 | static int | ||
251 | ar6k_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 | |||
438 | void | ||
439 | ar6k_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 | |||
598 | static int | ||
599 | ar6k_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 | |||
640 | void | ||
641 | ar6k_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 | |||
745 | void | ||
746 | ar6k_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 | |||
806 | static int | ||
807 | ar6k_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 | |||
865 | void | ||
866 | ar6k_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 | |||
894 | out: | ||
895 | ar->scan_request = NULL; | ||
896 | } | ||
897 | |||
898 | static int | ||
899 | ar6k_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 | |||
991 | static int | ||
992 | ar6k_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 | |||
1026 | static int | ||
1027 | ar6k_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(¶ms, 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, ¶ms); | ||
1063 | |||
1064 | return key->key_len ? 0 : -ENOENT; | ||
1065 | } | ||
1066 | |||
1067 | |||
1068 | static int | ||
1069 | ar6k_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 | |||
1120 | static int | ||
1121 | ar6k_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 | |||
1142 | void | ||
1143 | ar6k_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 | |||
1153 | static int | ||
1154 | ar6k_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 | |||
1180 | static int | ||
1181 | ar6k_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 */ | ||
1190 | static int | ||
1191 | ar6k_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 | |||
1226 | static int | ||
1227 | ar6k_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 | |||
1263 | static int | ||
1264 | ar6k_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 | |||
1299 | static struct net_device * | ||
1300 | ar6k_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 | |||
1313 | static int | ||
1314 | ar6k_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 | |||
1325 | static int | ||
1326 | ar6k_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 | |||
1362 | static int | ||
1363 | ar6k_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 | |||
1438 | static int | ||
1439 | ar6k_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 | ||
1463 | enum 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 | |||
1473 | enum 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 | |||
1480 | static 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 | |||
1486 | void 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 | |||
1502 | static 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 | |||
1552 | out: | ||
1553 | up(&ar->arSem); | ||
1554 | |||
1555 | return ret; | ||
1556 | |||
1557 | nla_put_failure: | ||
1558 | ret = -ENOBUFS; | ||
1559 | goto out; | ||
1560 | } | ||
1561 | |||
1562 | static 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 | |||
1616 | static const | ||
1617 | u32 cipher_suites[] = { | ||
1618 | WLAN_CIPHER_SUITE_WEP40, | ||
1619 | WLAN_CIPHER_SUITE_WEP104, | ||
1620 | WLAN_CIPHER_SUITE_TKIP, | ||
1621 | WLAN_CIPHER_SUITE_CCMP, | ||
1622 | }; | ||
1623 | |||
1624 | bool 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 | |||
1639 | bool 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 | |||
1660 | bool 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 | |||
1683 | static 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 | |||
1769 | static 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 | |||
1776 | static 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 | |||
1783 | static 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 | |||
1791 | static struct | ||
1792 | cfg80211_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 | |||
1818 | struct wireless_dev * | ||
1819 | ar6k_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 | |||
1867 | void | ||
1868 | ar6k_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 | |||
38 | HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo); | ||
39 | void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); | ||
40 | int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue); | ||
41 | int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous); | ||
42 | void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); | ||
43 | int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); | ||
44 | int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); | ||
45 | int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, | ||
46 | struct htc_packet *pPacket, | ||
47 | int MaxPollMS); | ||
48 | int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); | ||
49 | int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); | ||
50 | |||
51 | extern struct hci_transport_callbacks ar6kHciTransCallbacks; | ||
52 | |||
53 | int 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 | |||
71 | int | ||
72 | ar6000_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 | |||
83 | int 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, ®Address, ®Val); | ||
95 | |||
96 | return status; | ||
97 | } | ||
98 | |||
99 | int 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, ®Address, data); | ||
107 | |||
108 | return status; | ||
109 | } | ||
110 | |||
111 | EXPORT_SYMBOL(ar6000_register_hci_transport); | ||
112 | EXPORT_SYMBOL(ar6000_get_hif_dev); | ||
113 | EXPORT_SYMBOL(ar6000_set_uart_config); | ||
114 | EXPORT_SYMBOL(ar6000_get_core_clock_config); | ||
115 | EXPORT_SYMBOL(_HCI_TransportAttach); | ||
116 | EXPORT_SYMBOL(_HCI_TransportDetach); | ||
117 | EXPORT_SYMBOL(_HCI_TransportAddReceivePkts); | ||
118 | EXPORT_SYMBOL(_HCI_TransportSendPkt); | ||
119 | EXPORT_SYMBOL(_HCI_TransportStop); | ||
120 | EXPORT_SYMBOL(_HCI_TransportStart); | ||
121 | EXPORT_SYMBOL(_HCI_TransportEnableDisableAsyncRecv); | ||
122 | EXPORT_SYMBOL(_HCI_TransportRecvHCIEventSync); | ||
123 | EXPORT_SYMBOL(_HCI_TransportSetBaudRate); | ||
124 | EXPORT_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 | ||
62 | unsigned int ar3khcibaud = 0; | ||
63 | unsigned int hciuartscale = 0; | ||
64 | unsigned int hciuartstep = 0; | ||
65 | |||
66 | module_param(ar3khcibaud, int, 0644); | ||
67 | module_param(hciuartscale, int, 0644); | ||
68 | module_param(hciuartstep, int, 0644); | ||
69 | #else | ||
70 | extern unsigned int ar3khcibaud; | ||
71 | extern unsigned int hciuartscale; | ||
72 | extern unsigned int hciuartstep; | ||
73 | #endif /* EXPORT_HCI_BRIDGE_INTERFACE */ | ||
74 | |||
75 | struct 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 | |||
101 | extern unsigned int setupbtdev; | ||
102 | struct ar3k_config_info ar3kconfig; | ||
103 | |||
104 | #ifdef EXPORT_HCI_BRIDGE_INTERFACE | ||
105 | struct ar6k_hci_bridge_info *g_pHcidevInfo; | ||
106 | #endif | ||
107 | |||
108 | static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo); | ||
109 | static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo); | ||
110 | static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo); | ||
111 | static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo, | ||
112 | HCI_TRANSPORT_PACKET_TYPE Type, | ||
113 | struct sk_buff *skb); | ||
114 | static struct sk_buff *bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length); | ||
115 | static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb); | ||
116 | |||
117 | #ifdef EXPORT_HCI_BRIDGE_INTERFACE | ||
118 | int ar6000_setup_hci(void *ar); | ||
119 | void ar6000_cleanup_hci(void *ar); | ||
120 | int hci_test_send(void *ar, struct sk_buff *skb); | ||
121 | #else | ||
122 | int ar6000_setup_hci(struct ar6_softc *ar); | ||
123 | void ar6000_cleanup_hci(struct ar6_softc *ar); | ||
124 | /* HCI bridge testing */ | ||
125 | int 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 | |||
131 | static 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 | |||
141 | static 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 | |||
148 | static 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 | |||
159 | static 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)) | ||
217 | static 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 | |||
325 | static 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 | |||
336 | static 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 | |||
349 | static 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 | |||
367 | static 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 | |||
432 | static 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 | |||
449 | static 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 | ||
466 | int ar6000_setup_hci(void *ar) | ||
467 | #else | ||
468 | int 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 | ||
563 | void ar6000_cleanup_hci(void *ar) | ||
564 | #else | ||
565 | void 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 | ||
598 | int hci_test_send(void *ar, struct sk_buff *skb) | ||
599 | #else | ||
600 | int 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 | |||
666 | void 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 | */ | ||
685 | static 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 | */ | ||
698 | static 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 | */ | ||
708 | static 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 | */ | ||
823 | static 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 | */ | ||
832 | static 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 | */ | ||
849 | static 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 | |||
855 | static 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 | |||
915 | static 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 | |||
935 | static 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 | |||
959 | static 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 | |||
1022 | static 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 | |||
1033 | static 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 */ | ||
1041 | static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) | ||
1042 | { | ||
1043 | return 0; | ||
1044 | } | ||
1045 | static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) | ||
1046 | { | ||
1047 | |||
1048 | } | ||
1049 | static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo) | ||
1050 | { | ||
1051 | A_ASSERT(false); | ||
1052 | return A_ERROR; | ||
1053 | } | ||
1054 | |||
1055 | static 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 | |||
1063 | static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length) | ||
1064 | { | ||
1065 | A_ASSERT(false); | ||
1066 | return NULL; | ||
1067 | } | ||
1068 | static 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 | ||
1080 | int ar6000_setup_hci(void *ar) | ||
1081 | #else | ||
1082 | int ar6000_setup_hci(struct ar6_softc *ar) | ||
1083 | #endif | ||
1084 | { | ||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | #ifdef EXPORT_HCI_BRIDGE_INTERFACE | ||
1089 | void ar6000_cleanup_hci(void *ar) | ||
1090 | #else | ||
1091 | void ar6000_cleanup_hci(struct ar6_softc *ar) | ||
1092 | #endif | ||
1093 | { | ||
1094 | return; | ||
1095 | } | ||
1096 | |||
1097 | #ifndef EXPORT_HCI_BRIDGE_INTERFACE | ||
1098 | void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig) | ||
1099 | { | ||
1100 | return; | ||
1101 | } | ||
1102 | #endif | ||
1103 | |||
1104 | #ifdef EXPORT_HCI_BRIDGE_INTERFACE | ||
1105 | int hci_test_send(void *ar, struct sk_buff *skb) | ||
1106 | #else | ||
1107 | int 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 | ||
1117 | static int __init | ||
1118 | hcibridge_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 | |||
1133 | static void __exit | ||
1134 | hcibridge_cleanup_module(void) | ||
1135 | { | ||
1136 | } | ||
1137 | |||
1138 | module_init(hcibridge_init_module); | ||
1139 | module_exit(hcibridge_cleanup_module); | ||
1140 | MODULE_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 | ||
95 | struct 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 | |||
115 | int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); | ||
116 | int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); | ||
117 | |||
118 | #ifdef __cplusplus | ||
119 | extern "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 | |||
154 | enum { | ||
155 | DRV_HB_CHALLENGE = 0, | ||
156 | APP_HB_CHALLENGE | ||
157 | }; | ||
158 | |||
159 | enum { | ||
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 */ | ||
167 | enum { | ||
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 */ | ||
175 | enum { | ||
176 | WLAN_OFF_CUT_PWR = 0, | ||
177 | WLAN_OFF_DEEP_SLEEP, | ||
178 | }; | ||
179 | |||
180 | /* WLAN low power state */ | ||
181 | enum { | ||
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 */ | ||
189 | enum { | ||
190 | WLAN_WOW_STATE_NONE = 0, | ||
191 | WLAN_WOW_STATE_SUSPENDED, | ||
192 | WLAN_WOW_STATE_SUSPENDING | ||
193 | }; | ||
194 | |||
195 | |||
196 | typedef 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 */ | ||
373 | enum { | ||
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 */ | ||
382 | typedef 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 | |||
396 | typedef 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 | */ | ||
409 | enum { | ||
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 | |||
417 | struct ar_wep_key { | ||
418 | u8 arKeyIndex; | ||
419 | u8 arKeyLen; | ||
420 | u8 arKey[64]; | ||
421 | } ; | ||
422 | |||
423 | struct 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 | |||
431 | enum { | ||
432 | SME_DISCONNECTED, | ||
433 | SME_CONNECTING, | ||
434 | SME_CONNECTED | ||
435 | }; | ||
436 | |||
437 | struct ar_node_mapping { | ||
438 | u8 macAddress[6]; | ||
439 | u8 epId; | ||
440 | u8 txPending; | ||
441 | }; | ||
442 | |||
443 | struct 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 | |||
449 | struct 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 | |||
476 | typedef 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 | |||
488 | typedef 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 | |||
501 | struct 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 | ||
659 | struct 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 | |||
666 | static 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 | |||
692 | struct 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 | |||
715 | void ar6000_init_profile_info(struct ar6_softc *ar); | ||
716 | void ar6000_install_static_wep_keys(struct ar6_softc *ar); | ||
717 | int ar6000_init(struct net_device *dev); | ||
718 | int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar); | ||
719 | void ar6000_TxDataCleanup(struct ar6_softc *ar); | ||
720 | int ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev); | ||
721 | void ar6000_restart_endpoint(struct net_device *dev); | ||
722 | void 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 | |||
730 | int ar6000_htc_raw_open(struct ar6_softc *ar); | ||
731 | int ar6000_htc_raw_close(struct ar6_softc *ar); | ||
732 | ssize_t ar6000_htc_raw_read(struct ar6_softc *ar, | ||
733 | HTC_RAW_STREAM_ID StreamID, | ||
734 | char __user *buffer, size_t count); | ||
735 | ssize_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 */ | ||
743 | sta_t * | ||
744 | ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr); | ||
745 | |||
746 | sta_t * | ||
747 | ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid); | ||
748 | |||
749 | u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason); | ||
750 | |||
751 | /* HCI support */ | ||
752 | |||
753 | #ifndef EXPORT_HCI_BRIDGE_INTERFACE | ||
754 | int ar6000_setup_hci(struct ar6_softc *ar); | ||
755 | void ar6000_cleanup_hci(struct ar6_softc *ar); | ||
756 | void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig); | ||
757 | |||
758 | /* HCI bridge testing */ | ||
759 | int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb); | ||
760 | #endif | ||
761 | |||
762 | ATH_DEBUG_DECLARE_EXTERN(htc); | ||
763 | ATH_DEBUG_DECLARE_EXTERN(wmi); | ||
764 | ATH_DEBUG_DECLARE_EXTERN(bmi); | ||
765 | ATH_DEBUG_DECLARE_EXTERN(hif); | ||
766 | ATH_DEBUG_DECLARE_EXTERN(wlan); | ||
767 | ATH_DEBUG_DECLARE_EXTERN(misc); | ||
768 | |||
769 | extern u8 bcast_mac[]; | ||
770 | extern 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 */ | ||
29 | typedef bool (*ar6k_pal_recv_pkt_t)(void *pHciPalInfo, void *skb); | ||
30 | typedef struct ar6k_pal_config_s | ||
31 | { | ||
32 | ar6k_pal_recv_pkt_t fpar6k_pal_recv_pkt; | ||
33 | }ar6k_pal_config_t; | ||
34 | |||
35 | void 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 | ||
27 | extern "C" { | ||
28 | #endif | ||
29 | |||
30 | struct ar6_softc; | ||
31 | |||
32 | void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, | ||
33 | u32 sw_ver, u32 abi_ver); | ||
34 | int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid); | ||
35 | void 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); | ||
40 | void ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, | ||
41 | u8 *bssid, u8 assocRespLen, | ||
42 | u8 *assocInfo, u16 protocolReasonStatus); | ||
43 | void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, | ||
44 | bool ismcast); | ||
45 | void ar6000_bitrate_rx(void *devt, s32 rateKbps); | ||
46 | void ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList); | ||
47 | void ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode); | ||
48 | void ar6000_txPwr_rx(void *devt, u8 txPwr); | ||
49 | void ar6000_keepalive_rx(void *devt, u8 configured); | ||
50 | void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, | ||
51 | WMI_NEIGHBOR_INFO *info); | ||
52 | void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num); | ||
53 | void ar6000_scanComplete_event(struct ar6_softc *ar, int status); | ||
54 | void ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len); | ||
55 | void ar6000_rssiThreshold_event(struct ar6_softc *ar, | ||
56 | WMI_RSSI_THRESHOLD_VAL newThreshold, | ||
57 | s16 rssi); | ||
58 | void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal); | ||
59 | void ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cac_indication, | ||
60 | u8 statusCode, u8 *tspecSuggestion); | ||
61 | void ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel, u16 newChannel); | ||
62 | void ar6000_hbChallengeResp_event(struct ar6_softc *, u32 cookie, u32 source); | ||
63 | void | ||
64 | ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl); | ||
65 | |||
66 | void | ||
67 | ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p); | ||
68 | |||
69 | void | ||
70 | ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters, | ||
71 | WMI_GET_WOW_LIST_REPLY *wow_reply); | ||
72 | |||
73 | void ar6000_pmkid_list_event(void *devt, u8 numPMKID, | ||
74 | WMI_PMKID *pmkidList, u8 *bssidList); | ||
75 | |||
76 | void ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values); | ||
77 | void ar6000_gpio_data_rx(u32 reg_id, u32 value); | ||
78 | void ar6000_gpio_ack_rx(void); | ||
79 | |||
80 | s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt); | ||
81 | s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi); | ||
82 | s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above); | ||
83 | |||
84 | void ar6000_dbglog_init_done(struct ar6_softc *ar); | ||
85 | |||
86 | #ifdef CONFIG_HOST_TCMD_SUPPORT | ||
87 | void ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len); | ||
88 | #endif | ||
89 | |||
90 | void ar6000_tx_retry_err_event(void *devt); | ||
91 | |||
92 | void ar6000_snrThresholdEvent_rx(void *devt, | ||
93 | WMI_SNR_THRESHOLD_VAL newThreshold, | ||
94 | u8 snr); | ||
95 | |||
96 | void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, u8 lqVal); | ||
97 | |||
98 | |||
99 | void ar6000_ratemask_rx(void *devt, u32 ratemask); | ||
100 | |||
101 | int ar6000_get_driver_cfg(struct net_device *dev, | ||
102 | u16 cfgParam, | ||
103 | void *result); | ||
104 | void ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *data, int len); | ||
105 | |||
106 | void ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped, | ||
107 | s8 *buffer, u32 length); | ||
108 | |||
109 | int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar); | ||
110 | |||
111 | void ar6000_peer_event(void *devt, u8 eventCode, u8 *bssid); | ||
112 | |||
113 | void ar6000_indicate_tx_activity(void *devt, u8 trafficClass, bool Active); | ||
114 | HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, u8 ac); | ||
115 | u8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep ); | ||
116 | |||
117 | void ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len); | ||
118 | |||
119 | void ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len) ; | ||
120 | |||
121 | void ar6000_dset_open_req(void *devt, | ||
122 | u32 id, | ||
123 | u32 targ_handle, | ||
124 | u32 targ_reply_fn, | ||
125 | u32 targ_reply_arg); | ||
126 | void ar6000_dset_close(void *devt, u32 access_cookie); | ||
127 | void 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) | ||
137 | void prof_count_rx(unsigned int addr, unsigned int count); | ||
138 | #endif | ||
139 | |||
140 | u32 ar6000_getnodeAge (void); | ||
141 | |||
142 | u32 ar6000_getclkfreq (void); | ||
143 | |||
144 | int ar6000_ap_mode_profile_commit(struct ar6_softc *ar); | ||
145 | |||
146 | struct ieee80211req_wpaie; | ||
147 | int | ||
148 | ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie); | ||
149 | |||
150 | int is_iwioctl_allowed(u8 mode, u16 cmd); | ||
151 | |||
152 | int is_xioctl_allowed(u8 mode, int cmd); | ||
153 | |||
154 | void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid); | ||
155 | |||
156 | void ar6000_dtimexpiry_event(struct ar6_softc *ar); | ||
157 | |||
158 | void ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *cmd); | ||
159 | void ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *cmd); | ||
160 | void ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *cmd); | ||
161 | void ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd); | ||
162 | |||
163 | #ifdef WAPI_ENABLE | ||
164 | int ap_set_wapi_key(struct ar6_softc *ar, void *ik); | ||
165 | void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac); | ||
166 | #endif | ||
167 | |||
168 | int ar6000_connect_to_ap(struct ar6_softc *ar); | ||
169 | int ar6000_disconnect(struct ar6_softc *ar); | ||
170 | int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool suspending); | ||
171 | int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state); | ||
172 | int ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 state); | ||
173 | |||
174 | #ifdef CONFIG_PM | ||
175 | int ar6000_suspend_ev(void *context); | ||
176 | int ar6000_resume_ev(void *context); | ||
177 | int ar6000_power_change_ev(void *context, u32 config); | ||
178 | void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent); | ||
179 | #endif | ||
180 | |||
181 | #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT | ||
182 | int ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname); | ||
183 | int 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 | ||
28 | extern "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 | ||
481 | typedef 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 */ | ||
1001 | struct 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 */ | ||
1009 | struct ar6000_queuereq { | ||
1010 | u8 trafficClass; | ||
1011 | u16 activeTsids; | ||
1012 | }; | ||
1013 | |||
1014 | /* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */ | ||
1015 | typedef 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 | |||
1086 | typedef 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 | |||
1099 | struct 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 */ | ||
1104 | struct 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 | */ | ||
1114 | struct ar6000_gpio_register_cmd_s { | ||
1115 | u32 gpioreg_id; | ||
1116 | u32 value; | ||
1117 | }; | ||
1118 | |||
1119 | /* used by AR6000_XIOCTL_GPIO_INTR_ACK */ | ||
1120 | struct ar6000_gpio_intr_ack_cmd_s { | ||
1121 | u32 ack_mask; | ||
1122 | }; | ||
1123 | |||
1124 | /* used by AR6000_XIOCTL_GPIO_INTR_WAIT */ | ||
1125 | struct 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 */ | ||
1131 | typedef 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 | |||
1139 | typedef struct user_rssi_thold_t { | ||
1140 | s16 tag; | ||
1141 | s16 rssi; | ||
1142 | } USER_RSSI_THOLD; | ||
1143 | |||
1144 | typedef struct user_rssi_params_t { | ||
1145 | u8 weight; | ||
1146 | u32 pollTime; | ||
1147 | USER_RSSI_THOLD tholds[12]; | ||
1148 | } USER_RSSI_PARAMS; | ||
1149 | |||
1150 | typedef struct ar6000_get_btcoex_config_cmd_t{ | ||
1151 | u32 btProfileType; | ||
1152 | u32 linkId; | ||
1153 | }AR6000_GET_BTCOEX_CONFIG_CMD; | ||
1154 | |||
1155 | typedef struct ar6000_btcoex_config_t { | ||
1156 | AR6000_GET_BTCOEX_CONFIG_CMD configCmd; | ||
1157 | u32 *configEvent; | ||
1158 | } AR6000_BTCOEX_CONFIG; | ||
1159 | |||
1160 | typedef 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 */ | ||
1177 | struct ar6000_diag_window_cmd_s { | ||
1178 | unsigned int addr; | ||
1179 | unsigned int value; | ||
1180 | }; | ||
1181 | |||
1182 | |||
1183 | struct 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 */ | ||
1189 | struct 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 */ | ||
1198 | struct 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 | */ | ||
1208 | typedef 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 | |||
27 | struct wireless_dev *ar6k_cfg80211_init(struct device *dev); | ||
28 | void ar6k_cfg80211_deinit(struct ar6_softc *ar); | ||
29 | |||
30 | void ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status); | ||
31 | |||
32 | void 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 | |||
38 | void ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason, | ||
39 | u8 *bssid, u8 assocRespLen, | ||
40 | u8 *assocInfo, u16 protocolReasonStatus); | ||
41 | |||
42 | void ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast); | ||
43 | |||
44 | #ifdef CONFIG_NL80211_TESTMODE | ||
45 | void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf, | ||
46 | int buf_len); | ||
47 | #else | ||
48 | static 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 | ||
28 | extern "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 | |||
28 | extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo); | ||
29 | extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); | ||
30 | extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue); | ||
31 | extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous); | ||
32 | extern void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); | ||
33 | extern int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); | ||
34 | extern int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); | ||
35 | extern int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, | ||
36 | struct htc_packet *pPacket, | ||
37 | int MaxPollMS); | ||
38 | extern int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); | ||
39 | extern 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 | |||
64 | extern int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks); | ||
65 | |||
66 | extern int ar6000_get_hif_dev(struct hif_device *device, void *config); | ||
67 | |||
68 | extern 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 | */ | ||
76 | extern int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data); | ||
diff --git a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h 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 | ||
28 | extern "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 | */ | ||
45 | struct 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 | */ | ||
63 | struct 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 | */ | ||
73 | struct 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 | |||
84 | struct 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 | |||
94 | struct ieee80211req_authalg { | ||
95 | u_int8_t auth_alg; | ||
96 | }; | ||
97 | |||
98 | /* | ||
99 | * Request to add an IE to a Management Frame | ||
100 | */ | ||
101 | enum{ | ||
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 | |||
115 | struct 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 | */ | ||
125 | enum { | ||
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 | |||
137 | struct ieee80211req_set_filter { | ||
138 | u_int32_t app_filterype; /* management frame filter type */ | ||
139 | }; | ||
140 | |||
141 | enum { | ||
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 | |||
163 | struct 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 */ | ||
89 | typedef 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) | ||
104 | typedef 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 | */ | ||
138 | typedef 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) \ | ||
142 | do { \ | ||
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 | ||
180 | extern 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 | */ | ||
201 | typedef 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 | */ | ||
270 | void *a_netbuf_alloc(int size); | ||
271 | void *a_netbuf_alloc_raw(int size); | ||
272 | void a_netbuf_free(void *bufPtr); | ||
273 | void *a_netbuf_to_data(void *bufPtr); | ||
274 | u32 a_netbuf_to_len(void *bufPtr); | ||
275 | int a_netbuf_push(void *bufPtr, s32 len); | ||
276 | int a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len); | ||
277 | int a_netbuf_put(void *bufPtr, s32 len); | ||
278 | int a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len); | ||
279 | int a_netbuf_pull(void *bufPtr, s32 len); | ||
280 | int a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len); | ||
281 | int a_netbuf_trim(void *bufPtr, s32 len); | ||
282 | int a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len); | ||
283 | int a_netbuf_setlen(void *bufPtr, s32 len); | ||
284 | s32 a_netbuf_headroom(void *bufPtr); | ||
285 | void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt); | ||
286 | void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt); | ||
287 | void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q); | ||
288 | int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q); | ||
289 | int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q); | ||
290 | int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q); | ||
291 | void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q); | ||
292 | |||
293 | /* | ||
294 | * Kernel v.s User space functions | ||
295 | */ | ||
296 | u32 a_copy_to_user(void *to, const void *from, u32 n); | ||
297 | u32 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 | |||
307 | static 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 | |||
44 | u8 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 | |||
99 | u8 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 | |||
135 | u8 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 | |||
30 | void 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 | |||
35 | void 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 | |||
40 | void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q) | ||
41 | { | ||
42 | return((void *) skb_dequeue((struct sk_buff_head *) q)); | ||
43 | } | ||
44 | |||
45 | int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q) | ||
46 | { | ||
47 | return(skb_queue_len((struct sk_buff_head *) q)); | ||
48 | } | ||
49 | |||
50 | int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q) | ||
51 | { | ||
52 | return(skb_queue_empty((struct sk_buff_head *) q)); | ||
53 | } | ||
54 | |||
55 | void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q) | ||
56 | { | ||
57 | skb_queue_head_init((struct sk_buff_head *) q); | ||
58 | } | ||
59 | |||
60 | void * | ||
61 | a_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 | */ | ||
73 | void * | ||
74 | a_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 | |||
83 | void | ||
84 | a_netbuf_free(void *bufPtr) | ||
85 | { | ||
86 | struct sk_buff *skb = (struct sk_buff *)bufPtr; | ||
87 | |||
88 | dev_kfree_skb(skb); | ||
89 | } | ||
90 | |||
91 | u32 a_netbuf_to_len(void *bufPtr) | ||
92 | { | ||
93 | return (((struct sk_buff *)bufPtr)->len); | ||
94 | } | ||
95 | |||
96 | void * | ||
97 | a_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 | */ | ||
106 | int | ||
107 | a_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 | */ | ||
118 | int | ||
119 | a_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 | */ | ||
131 | int | ||
132 | a_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 | */ | ||
143 | int | ||
144 | a_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 | */ | ||
158 | int | ||
159 | a_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 | */ | ||
169 | int | ||
170 | a_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 | */ | ||
180 | int | ||
181 | a_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 | */ | ||
196 | s32 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 | */ | ||
204 | int | ||
205 | a_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 | */ | ||
216 | int | ||
217 | a_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 | ||
226 | EXPORT_SYMBOL(a_netbuf_to_data); | ||
227 | EXPORT_SYMBOL(a_netbuf_put); | ||
228 | EXPORT_SYMBOL(a_netbuf_pull); | ||
229 | EXPORT_SYMBOL(a_netbuf_alloc); | ||
230 | EXPORT_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 | |||
57 | typedef enum { | ||
58 | ALL_SEQNO = 0, | ||
59 | CONTIGUOUS_SEQNO = 1, | ||
60 | }DELIVERY_ORDER; | ||
61 | |||
62 | struct osbuf_hold_q { | ||
63 | void *osbuf; | ||
64 | bool is_amsdu; | ||
65 | u16 seq_no; | ||
66 | }; | ||
67 | |||
68 | |||
69 | #if 0 | ||
70 | /* XXX: unused ? */ | ||
71 | struct window_snapshot { | ||
72 | u16 seqno_st; | ||
73 | u16 seqno_end; | ||
74 | }; | ||
75 | #endif | ||
76 | |||
77 | struct 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 | |||
92 | struct 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 | |||
104 | struct 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 | |||
33 | extern int | ||
34 | wmi_dot3_2_dix(void *osbuf); | ||
35 | |||
36 | static void | ||
37 | aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf); | ||
38 | |||
39 | static void | ||
40 | aggr_timeout(unsigned long arg); | ||
41 | |||
42 | static void | ||
43 | aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order); | ||
44 | |||
45 | static void | ||
46 | aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q); | ||
47 | |||
48 | static void * | ||
49 | aggr_get_osbuf(struct aggr_info *p_aggr); | ||
50 | |||
51 | void * | ||
52 | aggr_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 */ | ||
100 | static void | ||
101 | aggr_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 | |||
130 | void | ||
131 | aggr_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 | |||
174 | void | ||
175 | aggr_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 | |||
186 | void | ||
187 | aggr_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 | |||
200 | void | ||
201 | aggr_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 | |||
252 | void | ||
253 | aggr_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 | |||
268 | static void | ||
269 | aggr_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 | |||
333 | static void * | ||
334 | aggr_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 | |||
355 | static void | ||
356 | aggr_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 | |||
425 | void | ||
426 | aggr_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 | */ | ||
558 | void | ||
559 | aggr_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 | |||
572 | static void | ||
573 | aggr_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 | |||
629 | static void | ||
630 | aggr_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 | |||
639 | void | ||
640 | aggr_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 | */ | ||
99 | PREPACK 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 | |||
110 | PREPACK 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 | |||
214 | enum { | ||
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 | |||
302 | typedef 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 | */ | ||
320 | typedef 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 | |||
383 | enum 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 | */ | ||
67 | struct 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 | |||
42 | static struct ath_debug_mask_description wlan_debug_desc[] = { | ||
43 | { ATH_DEBUG_WLAN , "General WLAN Node Tracing"}, | ||
44 | }; | ||
45 | |||
46 | ATH_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 | ||
56 | static void wlan_node_timeout(unsigned long arg); | ||
57 | #endif | ||
58 | |||
59 | static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt, | ||
60 | const u8 *macaddr); | ||
61 | |||
62 | bss_t * | ||
63 | wlan_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 | |||
102 | void | ||
103 | wlan_node_free(bss_t *ni) | ||
104 | { | ||
105 | if (ni->ni_buf != NULL) { | ||
106 | kfree(ni->ni_buf); | ||
107 | } | ||
108 | kfree(ni); | ||
109 | } | ||
110 | |||
111 | void | ||
112 | wlan_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 | |||
160 | static 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 | |||
179 | bss_t * | ||
180 | wlan_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 | */ | ||
195 | void | ||
196 | wlan_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 | |||
241 | static void | ||
242 | wlan_node_dec_free(bss_t *ni) | ||
243 | { | ||
244 | if (ieee80211_node_dectestref(ni)) { | ||
245 | wlan_node_free(ni); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | void | ||
250 | wlan_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 | |||
259 | void | ||
260 | wlan_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 | */ | ||
283 | void | ||
284 | wlan_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 | |||
317 | void | ||
318 | wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge) | ||
319 | { | ||
320 | nt->nt_nodeAge = nodeAge; | ||
321 | return; | ||
322 | } | ||
323 | void | ||
324 | wlan_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 | ||
376 | static void | ||
377 | wlan_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 | |||
422 | void | ||
423 | wlan_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 | |||
433 | bss_t * | ||
434 | wlan_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 | |||
479 | void | ||
480 | wlan_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 | |||
487 | void | ||
488 | wlan_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 | |||
528 | bss_t * | ||
529 | wlan_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 | |||
555 | bss_t * | ||
556 | wlan_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 | |||
60 | static int __inline | ||
61 | iswpaoui(const u8 *frm) | ||
62 | { | ||
63 | return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); | ||
64 | } | ||
65 | |||
66 | static int __inline | ||
67 | iswmmoui(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 | ||
74 | static int __inline | ||
75 | iswmmparam(const u8 *frm) | ||
76 | { | ||
77 | return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE; | ||
78 | } | ||
79 | |||
80 | static int __inline | ||
81 | iswmminfo(const u8 *frm) | ||
82 | { | ||
83 | return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE; | ||
84 | } | ||
85 | #endif | ||
86 | |||
87 | static int __inline | ||
88 | isatherosoui(const u8 *frm) | ||
89 | { | ||
90 | return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); | ||
91 | } | ||
92 | |||
93 | static int __inline | ||
94 | iswscoui(const u8 *frm) | ||
95 | { | ||
96 | return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI); | ||
97 | } | ||
98 | |||
99 | int | ||
100 | wlan_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 | */ | ||
32 | u16 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 | */ | ||
49 | u32 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 | |||
50 | static struct ath_debug_mask_description wmi_debug_desc[] = { | ||
51 | { ATH_DEBUG_WMI , "General WMI Tracing"}, | ||
52 | }; | ||
53 | |||
54 | ATH_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 | |||
72 | static int wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
73 | |||
74 | static int wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, | ||
75 | int len); | ||
76 | static int wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, | ||
77 | int len); | ||
78 | |||
79 | static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, | ||
80 | int len); | ||
81 | static int wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, | ||
82 | int len); | ||
83 | static int wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, | ||
84 | int len); | ||
85 | static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, | ||
86 | int len); | ||
87 | static int wmi_sync_point(struct wmi_t *wmip); | ||
88 | |||
89 | static int wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, | ||
90 | int len); | ||
91 | static int wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, | ||
92 | int len); | ||
93 | static int wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, | ||
94 | int len); | ||
95 | static int wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, | ||
96 | int len); | ||
97 | static int wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
98 | static int wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, | ||
99 | int len); | ||
100 | |||
101 | static int wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, | ||
102 | int len); | ||
103 | #ifdef CONFIG_HOST_DSET_SUPPORT | ||
104 | static int wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
105 | static int wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, | ||
106 | int len); | ||
107 | #endif /* CONFIG_HOST_DSET_SUPPORT */ | ||
108 | |||
109 | |||
110 | static int wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, | ||
111 | int len); | ||
112 | static int wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
113 | static int wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
114 | static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
115 | static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
116 | static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
117 | static int wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
118 | static int wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
119 | static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, | ||
120 | int len); | ||
121 | static int wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, | ||
122 | int len); | ||
123 | static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, | ||
124 | int len); | ||
125 | static int | ||
126 | wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len); | ||
127 | |||
128 | static int | ||
129 | wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len); | ||
130 | |||
131 | |||
132 | #ifdef CONFIG_HOST_TCMD_SUPPORT | ||
133 | static int | ||
134 | wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
135 | #endif | ||
136 | |||
137 | static int | ||
138 | wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
139 | |||
140 | static int | ||
141 | wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
142 | |||
143 | static int | ||
144 | wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
145 | |||
146 | static bool | ||
147 | wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex); | ||
148 | |||
149 | static int | ||
150 | wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
151 | |||
152 | static int | ||
153 | wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
154 | |||
155 | static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
156 | |||
157 | int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, | ||
158 | WMI_SYNC_FLAG syncflag); | ||
159 | |||
160 | u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size); | ||
161 | u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size); | ||
162 | |||
163 | void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); | ||
164 | void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); | ||
165 | static int wmi_send_rssi_threshold_params(struct wmi_t *wmip, | ||
166 | WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); | ||
167 | static int wmi_send_snr_threshold_params(struct wmi_t *wmip, | ||
168 | WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); | ||
169 | #if defined(CONFIG_TARGET_PROFILE_SUPPORT) | ||
170 | static int | ||
171 | wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
172 | #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ | ||
173 | |||
174 | static int wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, | ||
175 | int len); | ||
176 | static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap, | ||
177 | int len); | ||
178 | |||
179 | static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap, | ||
180 | int len); | ||
181 | static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int); | ||
182 | static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int); | ||
183 | static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int); | ||
184 | static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
185 | static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len); | ||
186 | static int wmi_hci_event_rx(struct wmi_t *, u8 *, int); | ||
187 | |||
188 | #ifdef WAPI_ENABLE | ||
189 | static 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) | ||
195 | unsigned int processDot11Hdr = 0; | ||
196 | #else | ||
197 | unsigned int processDot11Hdr = 1; | ||
198 | #endif | ||
199 | #else | ||
200 | extern unsigned int processDot11Hdr; | ||
201 | #endif | ||
202 | |||
203 | int wps_enable; | ||
204 | static 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 */ | ||
254 | const 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 */ | ||
266 | typedef 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 | |||
282 | static s16 rssi_event_value = 0; | ||
283 | static s16 snr_event_value = 0; | ||
284 | |||
285 | bool is_probe_ssid = false; | ||
286 | |||
287 | void * | ||
288 | wmi_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 | |||
320 | void | ||
321 | wmi_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 | |||
344 | void | ||
345 | wmi_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 | |||
351 | HTC_ENDPOINT_ID | ||
352 | wmi_get_control_ep(struct wmi_t * wmip) | ||
353 | { | ||
354 | return(wmip->wmi_endpoint_id); | ||
355 | } | ||
356 | |||
357 | void | ||
358 | wmi_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 | */ | ||
379 | int | ||
380 | wmi_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 | |||
437 | int 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 */ | ||
480 | int | ||
481 | wmi_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 | |||
518 | u8 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 | |||
608 | int | ||
609 | wmi_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 | |||
665 | AddDot11Hdr: | ||
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 | |||
700 | int | ||
701 | wmi_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 | */ | ||
768 | int | ||
769 | wmi_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 | */ | ||
796 | int | ||
797 | wmi_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 | |||
804 | void | ||
805 | wmi_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 | */ | ||
813 | int | ||
814 | wmi_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 | */ | ||
877 | u32 cmdRecvNum; | ||
878 | |||
879 | int | ||
880 | wmi_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 */ | ||
1146 | static int | ||
1147 | wmi_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) | ||
1163 | static int | ||
1164 | wmi_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 | |||
1177 | static int | ||
1178 | wmi_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 | |||
1198 | static int __inline | ||
1199 | iswmmoui(const u8 *frm) | ||
1200 | { | ||
1201 | return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI); | ||
1202 | } | ||
1203 | |||
1204 | static int __inline | ||
1205 | iswmmparam(const u8 *frm) | ||
1206 | { | ||
1207 | return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE; | ||
1208 | } | ||
1209 | |||
1210 | |||
1211 | static int | ||
1212 | wmi_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 | |||
1271 | static int | ||
1272 | wmi_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 | |||
1286 | static int | ||
1287 | wmi_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 | |||
1307 | static int | ||
1308 | wmi_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 | |||
1332 | static int | ||
1333 | wmi_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 | |||
1352 | static int | ||
1353 | wmi_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 | |||
1368 | static int | ||
1369 | wmi_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 | |||
1532 | static int | ||
1533 | wmi_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 | */ | ||
1577 | static int | ||
1578 | wmi_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 | |||
1607 | static int | ||
1608 | wmi_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 | |||
1638 | static int | ||
1639 | wmi_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 | |||
1655 | static int | ||
1656 | wmi_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 | |||
1672 | static int | ||
1673 | wmi_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 | } | ||
1687 | static int | ||
1688 | wmi_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 | |||
1704 | static int | ||
1705 | wmi_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 | ||
1725 | static int | ||
1726 | wmi_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 | |||
1741 | static int | ||
1742 | wmi_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 | |||
1764 | static int | ||
1765 | wmi_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 | */ | ||
1786 | static int | ||
1787 | wmi_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 | |||
1809 | static int | ||
1810 | wmi_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 | |||
1819 | static int | ||
1820 | wmi_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 | |||
1924 | static int | ||
1925 | wmi_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 | |||
1940 | static int | ||
1941 | wmi_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 | |||
2010 | static int | ||
2011 | wmi_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 | |||
2027 | static int | ||
2028 | wmi_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 | |||
2043 | static int | ||
2044 | wmi_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 | |||
2059 | static int | ||
2060 | wmi_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 | |||
2075 | static int | ||
2076 | wmi_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 | |||
2088 | static int | ||
2089 | wmi_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 | |||
2181 | static int | ||
2182 | wmi_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 | |||
2199 | static int | ||
2200 | wmi_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 | |||
2240 | static int | ||
2241 | wmi_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 | */ | ||
2256 | int | ||
2257 | wmi_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 | |||
2312 | int | ||
2313 | wmi_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 | |||
2329 | int | ||
2330 | wmi_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 | |||
2384 | int | ||
2385 | wmi_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 | |||
2410 | int | ||
2411 | wmi_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 | |||
2423 | int | ||
2424 | wmi_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 | |||
2467 | int | ||
2468 | wmi_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 | |||
2502 | int | ||
2503 | wmi_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 | |||
2528 | int | ||
2529 | wmi_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 | |||
2570 | int | ||
2571 | wmi_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 | |||
2592 | int | ||
2593 | wmi_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 | |||
2614 | int | ||
2615 | wmi_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 | |||
2640 | int | ||
2641 | wmi_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 | |||
2662 | int | ||
2663 | wmi_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 | |||
2687 | int | ||
2688 | wmi_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 | |||
2712 | int | ||
2713 | wmi_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 | |||
2741 | int | ||
2742 | wmi_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 | |||
2762 | int | ||
2763 | wmi_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 | |||
2811 | int | ||
2812 | wmi_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 | |||
2831 | int | ||
2832 | wmi_delete_krk_cmd(struct wmi_t *wmip) | ||
2833 | { | ||
2834 | return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID); | ||
2835 | } | ||
2836 | |||
2837 | int | ||
2838 | wmi_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 | |||
2862 | int | ||
2863 | wmi_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 | |||
2897 | int | ||
2898 | wmi_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 | |||
2917 | int | ||
2918 | wmi_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 | |||
2937 | int | ||
2938 | wmi_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 | |||
2967 | int | ||
2968 | wmi_get_pmkid_list_cmd(struct wmi_t *wmip) | ||
2969 | { | ||
2970 | return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID); | ||
2971 | } | ||
2972 | |||
2973 | int | ||
2974 | wmi_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 | |||
2995 | typedef struct _WMI_DATA_SYNC_BUFS { | ||
2996 | u8 trafficClass; | ||
2997 | void *osbuf; | ||
2998 | }WMI_DATA_SYNC_BUFS; | ||
2999 | |||
3000 | static int | ||
3001 | wmi_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 | |||
3110 | int | ||
3111 | wmi_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 | |||
3206 | int | ||
3207 | wmi_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 | |||
3270 | int | ||
3271 | wmi_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 | */ | ||
3309 | int | ||
3310 | wmi_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 | |||
3359 | int | ||
3360 | wmi_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 | */ | ||
3368 | bool | ||
3369 | wmi_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 | |||
3424 | s8 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 | |||
3446 | int | ||
3447 | wmi_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 | |||
3486 | int | ||
3487 | wmi_get_ratemask_cmd(struct wmi_t *wmip) | ||
3488 | { | ||
3489 | return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID); | ||
3490 | } | ||
3491 | |||
3492 | int | ||
3493 | wmi_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 | */ | ||
3508 | int | ||
3509 | wmi_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 | |||
3546 | void | ||
3547 | wmi_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 | |||
3595 | int | ||
3596 | wmi_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 | |||
3620 | int | ||
3621 | wmi_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 | |||
3645 | int | ||
3646 | wmi_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 | |||
3707 | int | ||
3708 | wmi_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 | |||
3733 | int | ||
3734 | wmi_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 | |||
3759 | static int | ||
3760 | wmi_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 | |||
3775 | int 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 | |||
3810 | int | ||
3811 | wmi_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 | |||
3836 | void | ||
3837 | wmi_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 | } | ||
3881 | int | ||
3882 | wmi_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 | |||
3898 | int | ||
3899 | wmi_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 | |||
3912 | int | ||
3913 | wmi_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 | |||
3947 | int | ||
3948 | wmi_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 | |||
3972 | int | ||
3973 | wmi_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 | |||
3993 | int | ||
3994 | wmi_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 | |||
4019 | int | ||
4020 | wmi_get_stats_cmd(struct wmi_t *wmip) | ||
4021 | { | ||
4022 | return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID); | ||
4023 | } | ||
4024 | |||
4025 | int | ||
4026 | wmi_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 | |||
4049 | int | ||
4050 | wmi_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 | |||
4073 | int | ||
4074 | wmi_abort_scan_cmd(struct wmi_t *wmip) | ||
4075 | { | ||
4076 | return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID); | ||
4077 | } | ||
4078 | |||
4079 | int | ||
4080 | wmi_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 | |||
4098 | int | ||
4099 | wmi_get_txPwr_cmd(struct wmi_t *wmip) | ||
4100 | { | ||
4101 | return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID); | ||
4102 | } | ||
4103 | |||
4104 | u16 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 | |||
4115 | int | ||
4116 | wmi_get_roam_tbl_cmd(struct wmi_t *wmip) | ||
4117 | { | ||
4118 | return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID); | ||
4119 | } | ||
4120 | |||
4121 | int | ||
4122 | wmi_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 | |||
4142 | int | ||
4143 | wmi_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 | |||
4165 | int | ||
4166 | wmi_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 | |||
4197 | int | ||
4198 | wmi_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 | |||
4228 | int | ||
4229 | wmi_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 | |||
4267 | void | ||
4268 | wmi_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 | |||
4275 | int | ||
4276 | wmi_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 | |||
4296 | int | ||
4297 | wmi_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 | |||
4327 | int | ||
4328 | wmi_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 | |||
4349 | int | ||
4350 | wmi_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 | |||
4371 | int | ||
4372 | wmi_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 | |||
4398 | u8 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 | |||
4423 | u8 convert_userPriority_to_trafficClass(u8 userPriority) | ||
4424 | { | ||
4425 | return (up_to_ac[userPriority & 0x7]); | ||
4426 | } | ||
4427 | |||
4428 | u8 wmi_get_power_mode_cmd(struct wmi_t *wmip) | ||
4429 | { | ||
4430 | return wmip->wmi_powerMode; | ||
4431 | } | ||
4432 | |||
4433 | int | ||
4434 | wmi_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 | ||
4466 | static int | ||
4467 | wmi_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 | |||
4476 | int | ||
4477 | wmi_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 | |||
4497 | int | ||
4498 | wmi_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 | |||
4518 | int | ||
4519 | wmi_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 | |||
4540 | int | ||
4541 | wmi_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 | |||
4561 | int | ||
4562 | wmi_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 | |||
4583 | int | ||
4584 | wmi_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 | |||
4604 | int | ||
4605 | wmi_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 | |||
4629 | int | ||
4630 | wmi_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 | */ | ||
4655 | int | ||
4656 | wmi_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 | |||
4678 | int | ||
4679 | wmi_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 | |||
4702 | int | ||
4703 | wmi_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 | |||
4764 | int | ||
4765 | wmi_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 | |||
4784 | int | ||
4785 | wmi_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 | |||
4805 | int | ||
4806 | wmi_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 | |||
4825 | int | ||
4826 | wmi_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 | |||
4845 | int | ||
4846 | wmi_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 | |||
4865 | int | ||
4866 | wmi_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 | |||
4885 | int | ||
4886 | wmi_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 | |||
4904 | int | ||
4905 | wmi_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 | |||
4924 | int | ||
4925 | wmi_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 | |||
4943 | int | ||
4944 | wmi_get_btcoex_stats_cmd(struct wmi_t *wmip) | ||
4945 | { | ||
4946 | |||
4947 | return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID); | ||
4948 | |||
4949 | } | ||
4950 | |||
4951 | int | ||
4952 | wmi_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 | |||
4967 | u8 wmi_get_keepalive_cmd(struct wmi_t *wmip) | ||
4968 | { | ||
4969 | return wmip->wmi_keepaliveInterval; | ||
4970 | } | ||
4971 | |||
4972 | int | ||
4973 | wmi_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 | |||
4994 | int | ||
4995 | wmi_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 | |||
5018 | int | ||
5019 | wmi_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 | |||
5044 | int | ||
5045 | wmi_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 | |||
5069 | int | ||
5070 | wmi_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 | |||
5089 | int | ||
5090 | wmi_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 | |||
5115 | int | ||
5116 | wmi_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 | |||
5135 | s32 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 | |||
5144 | void | ||
5145 | wmi_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 | |||
5153 | void | ||
5154 | wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge) | ||
5155 | { | ||
5156 | wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge); | ||
5157 | } | ||
5158 | |||
5159 | bss_t * | ||
5160 | wmi_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 | ||
5171 | void | ||
5172 | wmi_refresh_scan_table (struct wmi_t *wmip) | ||
5173 | { | ||
5174 | wlan_refresh_inactive_nodes (&wmip->wmi_scan_table); | ||
5175 | } | ||
5176 | #endif | ||
5177 | |||
5178 | void | ||
5179 | wmi_free_allnodes(struct wmi_t *wmip) | ||
5180 | { | ||
5181 | wlan_free_allnodes(&wmip->wmi_scan_table); | ||
5182 | } | ||
5183 | |||
5184 | bss_t * | ||
5185 | wmi_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 | |||
5192 | void | ||
5193 | wmi_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 | |||
5205 | int | ||
5206 | wmi_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 | |||
5240 | static int | ||
5241 | wmi_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 | |||
5263 | static int | ||
5264 | wmi_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 | ||
5287 | int | ||
5288 | wmi_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 | |||
5334 | int | ||
5335 | wmi_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) | ||
5358 | int | ||
5359 | wmi_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 | |||
5381 | int | ||
5382 | wmi_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 | |||
5401 | int | ||
5402 | wmi_prof_start_cmd(struct wmi_t *wmip) | ||
5403 | { | ||
5404 | return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID); | ||
5405 | } | ||
5406 | |||
5407 | int | ||
5408 | wmi_prof_stop_cmd(struct wmi_t *wmip) | ||
5409 | { | ||
5410 | return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID); | ||
5411 | } | ||
5412 | |||
5413 | int | ||
5414 | wmi_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 */ | ||
5420 | static int | ||
5421 | wmi_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 | |||
5439 | void | ||
5440 | wmi_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 | |||
5654 | u8 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 | |||
5671 | u8 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 | } | ||
5687 | static int | ||
5688 | wmi_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 | } | ||
5711 | static int | ||
5712 | wmi_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 | |||
5735 | int | ||
5736 | wmi_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 | |||
5756 | bss_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 | |||
5762 | int 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 | |||
5768 | static int | ||
5769 | wmi_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 | |||
5779 | static int | ||
5780 | wmi_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 | |||
5789 | static int | ||
5790 | wmi_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 | |||
5799 | int | ||
5800 | wmi_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 | |||
5810 | int | ||
5811 | wmi_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 | |||
5821 | static int | ||
5822 | wmi_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 | */ | ||
5845 | int | ||
5846 | wmi_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 | */ | ||
5871 | int | ||
5872 | wmi_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 | */ | ||
5900 | int | ||
5901 | wmi_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 | */ | ||
5928 | int | ||
5929 | wmi_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 | */ | ||
5954 | int | ||
5955 | wmi_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 | |||
5976 | static int | ||
5977 | wmi_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 | |||
5990 | static int | ||
5991 | wmi_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 | ||
5998 | static int | ||
5999 | wmi_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 | |||
6013 | int | ||
6014 | wmi_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 | |||
6034 | int | ||
6035 | wmi_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 | |||
6054 | int | ||
6055 | wmi_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 | |||
6075 | int | ||
6076 | wmi_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 | */ | ||
6103 | int | ||
6104 | wmi_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 | |||
6123 | int | ||
6124 | wmi_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 | |||
6143 | int | ||
6144 | wmi_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 | |||
6168 | int | ||
6169 | wmi_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 | |||
6189 | int | ||
6190 | wmi_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 | |||
6210 | int | ||
6211 | wmi_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 | |||
6229 | int | ||
6230 | wmi_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 | |||
6249 | int | ||
6250 | wmi_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 | |||
6268 | int | ||
6269 | wmi_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 | |||
6289 | int | ||
6290 | wmi_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 | |||
6313 | int | ||
6314 | wmi_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 | |||
6334 | int | ||
6335 | wmi_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 | |||
6355 | int | ||
6356 | wmi_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 | |||
6376 | int | ||
6377 | wmi_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 | |||
6397 | int | ||
6398 | wmi_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 | |||
6418 | bss_t * | ||
6419 | wmi_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 | |||
6431 | u16 wmi_ieee2freq (int chan) | ||
6432 | { | ||
6433 | u16 freq = 0; | ||
6434 | freq = wlan_ieee2freq (chan); | ||
6435 | return freq; | ||
6436 | |||
6437 | } | ||
6438 | |||
6439 | u32 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 | ||
30 | extern "C" { | ||
31 | #endif | ||
32 | |||
33 | struct 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 | ||
44 | typedef 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 | |||
62 | struct 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_ */ | ||