diff options
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_ */ | ||
