├── .gitignore ├── Kconfig ├── LICENSE ├── Makefile ├── Makefile.old ├── README.md ├── dts-4.6 ├── sun8i-a33-aoson-m751s.dtb └── sun8i-a33-aoson-m751s.dts ├── esp_ctrl.c ├── esp_ctrl.h ├── esp_debug.c ├── esp_debug.h ├── esp_ext.c ├── esp_ext.h ├── esp_file.c ├── esp_file.h ├── esp_init_data.h ├── esp_io.c ├── esp_mac80211.c ├── esp_mac80211.h ├── esp_main.c ├── esp_path.h ├── esp_pub.h ├── esp_sif.h ├── esp_sip.c ├── esp_sip.h ├── esp_utils.c ├── esp_utils.h ├── esp_version.h ├── esp_wl.h ├── esp_wmac.h ├── firmware ├── LICENSE-2.0.txt ├── eagle_fw_ate_config_v19.bin ├── eagle_fw_first_init_v19.bin └── eagle_fw_second_init_v19.bin ├── sdio_sif_esp.c ├── sip2_common.h └── slc_host_register.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.cmd 2 | *.o 3 | Module.symvers 4 | modules.order 5 | .tmp_versions 6 | *.ko 7 | *.mod.c 8 | -------------------------------------------------------------------------------- /Kconfig: -------------------------------------------------------------------------------- 1 | config ESP8089 2 | tristate "Espressif ESP8089 SDIO WiFi" 3 | depends on MAC80211 4 | ---help--- 5 | ESP8089 is a low-budget 2.4GHz WiFi chip by Espressif, used in many 6 | cheap tablets with Allwinner or Rockchip SoC 7 | 8 | config ESP8089_DEBUG_FS 9 | bool "Enable DebugFS support for ESP8089" 10 | depends on ESP8089 11 | default y 12 | ---help--- 13 | DebugFS support for ESP8089 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MODULE_NAME = esp8089 2 | 3 | $(MODULE_NAME)-y := esp_debug.o sdio_sif_esp.o esp_io.o \ 4 | esp_file.o esp_main.o esp_sip.o esp_ext.o esp_ctrl.o \ 5 | esp_mac80211.o esp_debug.o esp_utils.o 6 | 7 | obj-$(CONFIG_ESP8089) := esp8089.o 8 | -------------------------------------------------------------------------------- /Makefile.old: -------------------------------------------------------------------------------- 1 | MODNAME = esp8089 2 | 3 | # By default, we try to compile the modules for the currently running 4 | # kernel. But it's the first approximation, as we will re-read the 5 | # version from the kernel sources. 6 | KVERS_UNAME ?= $(shell uname -r) 7 | 8 | # KBUILD is the path to the Linux kernel build tree. It is usually the 9 | # same as the kernel source tree, except when the kernel was compiled in 10 | # a separate directory. 11 | KBUILD ?= $(shell readlink -f /lib/modules/$(KVERS_UNAME)/build) 12 | 13 | ifeq (,$(KBUILD)) 14 | $(error Kernel build tree not found - please set KBUILD to configured kernel) 15 | endif 16 | 17 | KCONFIG := $(KBUILD)/.config 18 | ifeq (,$(wildcard $(KCONFIG))) 19 | $(error No .config found in $(KBUILD), please set KBUILD to configured kernel) 20 | endif 21 | 22 | ifneq (,$(wildcard $(KBUILD)/include/linux/version.h)) 23 | ifneq (,$(wildcard $(KBUILD)/include/generated/uapi/linux/version.h)) 24 | $(error Multiple copies of version.h found, please clean your build tree) 25 | endif 26 | endif 27 | 28 | # Kernel Makefile doesn't always know the exact kernel version, so we 29 | # get it from the kernel headers instead and pass it to make. 30 | VERSION_H := $(KBUILD)/include/generated/utsrelease.h 31 | ifeq (,$(wildcard $(VERSION_H))) 32 | VERSION_H := $(KBUILD)/include/linux/utsrelease.h 33 | endif 34 | ifeq (,$(wildcard $(VERSION_H))) 35 | VERSION_H := $(KBUILD)/include/linux/version.h 36 | endif 37 | ifeq (,$(wildcard $(VERSION_H))) 38 | $(error Please run 'make modules_prepare' in $(KBUILD)) 39 | endif 40 | 41 | KVERS := $(shell sed -ne 's/"//g;s/^\#define UTS_RELEASE //p' $(VERSION_H)) 42 | 43 | ifeq (,$(KVERS)) 44 | $(error Cannot find UTS_RELEASE in $(VERSION_H), please report) 45 | endif 46 | 47 | INST_DIR = /lib/modules/$(KVERS)/misc 48 | 49 | SRC_DIR=$(shell pwd) 50 | 51 | include $(KCONFIG) 52 | 53 | EXTRA_CFLAGS += -DCONFIG_ESP8089_DEBUG_FS 54 | 55 | OBJS = esp_debug.o sdio_sif_esp.o esp_io.o \ 56 | esp_file.o esp_main.o esp_sip.o esp_ext.o esp_ctrl.o \ 57 | esp_mac80211.o esp_debug.o esp_utils.o esp_pm.o 58 | 59 | all: config_check modules 60 | 61 | MODULE := $(MODNAME).ko 62 | obj-m := $(MODNAME).o 63 | 64 | $(MODNAME)-objs := $(OBJS) 65 | 66 | config_check: 67 | @if [ -z "$(CONFIG_WIRELESS_EXT)$(CONFIG_NET_RADIO)" ]; then \ 68 | echo; echo; \ 69 | echo "*** WARNING: This kernel lacks wireless extensions."; \ 70 | echo "Wireless drivers will not work properly."; \ 71 | echo; echo; \ 72 | fi 73 | 74 | modules: 75 | $(MAKE) -C $(KBUILD) M=$(SRC_DIR) 76 | 77 | $(MODULE): 78 | $(MAKE) modules 79 | 80 | clean: 81 | rm -f *.o *.ko .*.cmd *.mod.c *.symvers modules.order 82 | rm -rf .tmp_versions 83 | 84 | install: config_check $(MODULE) 85 | @/sbin/modinfo $(MODULE) | grep -q "^vermagic: *$(KVERS) " || \ 86 | { echo "$(MODULE)" is not for Linux $(KVERS); exit 1; } 87 | mkdir -p -m 755 $(DESTDIR)$(INST_DIR) 88 | install -m 0644 $(MODULE) $(DESTDIR)$(INST_DIR) 89 | ifndef DESTDIR 90 | -/sbin/depmod -a $(KVERS) 91 | endif 92 | 93 | uninstall: 94 | rm -f $(DESTDIR)$(INST_DIR)/$(MODULE) 95 | ifndef DESTDIR 96 | -/sbin/depmod -a $(KVERS) 97 | endif 98 | 99 | .PHONY: all modules clean install config_check 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | esp8089 2 | ====== 3 | 4 | ESP8089 Linux driver 5 | 6 | v1.9 imported from the Rockchip Linux kernel github repo 7 | 8 | Modified to build as a standalone module for SDIO devices. 9 | 10 | 11 | 12 | 13 | Building: 14 | 15 | make 16 | 17 | Using: 18 | 19 | Must load mac80211.ko first if not baked in. 20 | 21 | sudo modprobe esp8089.ko 22 | 23 | If you get a wlan interface, but scanning shows no networks try using: 24 | 25 | sudo modprobe esp8089.ko config=crystal_26M_en=1 26 | 27 | or: 28 | 29 | sudo modprobe esp8089.ko config=crystal_26M_en=2 30 | 31 | To load the module. 32 | -------------------------------------------------------------------------------- /dts-4.6/sun8i-a33-aoson-m751s.dtb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lichee-Pi/esp8089/72782740c063676eaec2965c26f275907933b85d/dts-4.6/sun8i-a33-aoson-m751s.dtb -------------------------------------------------------------------------------- /dts-4.6/sun8i-a33-aoson-m751s.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Hans de Goede 3 | * 4 | * This file is dual-licensed: you can use it either under the terms 5 | * of the GPL or the X11 license, at your option. Note that this dual 6 | * licensing only applies to this file, and not this project as a 7 | * whole. 8 | * 9 | * a) This file is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU General Public License as 11 | * published by the Free Software Foundation; either version 2 of the 12 | * License, or (at your option) any later version. 13 | * 14 | * This file is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Or, alternatively, 20 | * 21 | * b) Permission is hereby granted, free of charge, to any person 22 | * obtaining a copy of this software and associated documentation 23 | * files (the "Software"), to deal in the Software without 24 | * restriction, including without limitation the rights to use, 25 | * copy, modify, merge, publish, distribute, sublicense, and/or 26 | * sell copies of the Software, and to permit persons to whom the 27 | * Software is furnished to do so, subject to the following 28 | * conditions: 29 | * 30 | * The above copyright notice and this permission notice shall be 31 | * included in all copies or substantial portions of the Software. 32 | * 33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 | * OTHER DEALINGS IN THE SOFTWARE. 41 | */ 42 | 43 | /dts-v1/; 44 | #include "sun8i-a33.dtsi" 45 | #include "sun8i-q8-common.dtsi" 46 | 47 | / { 48 | model = "Aoson M751s Q8 A33 Tablet"; 49 | compatible = "allwinner,q8-a33", "allwinner,sun8i-a33"; 50 | 51 | /* 52 | * This is actually an active-low reset line for the WLAN 53 | * part of the WiFi CHIP. 54 | * 55 | * Just like for DLDO1 and DLDO2, we cannot tie it to the DT 56 | * node of the SDIO device for now, as there is no bindings 57 | * for it, so we need to have this hack. 58 | */ 59 | wifi_reg_on: wifi_reg_on { 60 | compatible = "regulator-fixed"; 61 | pinctrl-names = "default"; 62 | pinctrl-0 = <&m751s_wifi_reg_on_pin>; 63 | 64 | regulator-name = "wifi-reg-on"; 65 | regulator-min-microvolt = <3300000>; 66 | regulator-max-microvolt = <3300000>; 67 | regulator-always-on; 68 | gpio = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ 69 | enable-active-high; 70 | }; 71 | 72 | mmc1_pwrseq: mmc1_pwrseq { 73 | compatible = "mmc-pwrseq-simple"; 74 | pinctrl-names = "default"; 75 | pinctrl-0 = <&m751s_wifi_reset_pin>; 76 | reset-gpios = <&r_pio 0 11 GPIO_ACTIVE_LOW>; /* PH9 WIFI_EN */ 77 | }; 78 | 79 | /* 80 | * Both DLDO1 and DLDO2 are used in parallel to power up the 81 | * WiFi Chip. 82 | * 83 | * If those are not enabled, the SDIO part will not enumerate, 84 | * and since there's no way currently to pass DT infos to an 85 | * SDIO device, we cannot really do better than this ugly hack 86 | * for now. 87 | */ 88 | 89 | vcc_wifi: wifi_reg { 90 | compatible = "coupled-voltage-regulator"; 91 | regulator-name = "vcc-wifi"; 92 | vin0-supply = <&vcc_wifi_1>; 93 | vin1-supply = <&vcc_wifi_2>; 94 | }; 95 | }; 96 | 97 | &axp22x { 98 | regulators { 99 | vcc_wifi_1: dldo1 { 100 | regulator-min-microvolt = <3300000>; 101 | regulator-max-microvolt = <3300000>; 102 | regulator-name = "vcc-wifi-1"; 103 | }; 104 | 105 | vcc_wifi_2: dldo2 { 106 | regulator-min-microvolt = <3300000>; 107 | regulator-max-microvolt = <3300000>; 108 | regulator-name = "vcc-wifi-2"; 109 | regulator-always-on; 110 | }; 111 | }; 112 | }; 113 | 114 | &mmc1 { 115 | pinctrl-names = "default"; 116 | pinctrl-0 = <&mmc1_pins_a>; 117 | vmmc-supply = <&vcc_wifi_1>; 118 | mmc-pwrseq = <&mmc1_pwrseq>; 119 | bus-width = <4>; 120 | //non-removable; 121 | broken-cd; 122 | status = "okay"; 123 | }; 124 | 125 | &mmc1_pins_a { 126 | allwinner,pull = ; 127 | }; 128 | 129 | &r_pio { 130 | m751s_wifi_reg_on_pin: m751s_wifi_reg_on_pin@0 { 131 | allwinner,pins = "PL6"; 132 | allwinner,function = "gpio_out"; 133 | allwinner,drive = ; 134 | allwinner,pull = ; 135 | }; 136 | m751s_wifi_reset_pin: m751s_wifi_reset_pin@0 { 137 | allwinner,pins = "PL11"; 138 | allwinner,function = "gpio_out"; 139 | allwinner,drive = ; 140 | allwinner,pull = ; 141 | }; 142 | }; 143 | 144 | /* 145 | * FIXME for now we only support host mode and rely on u-boot to have 146 | * turned on Vbus which is controlled by the axp223 pmic on the board. 147 | * 148 | * Once we have axp223 support we should switch to fully supporting otg. 149 | */ 150 | &usb_otg { 151 | dr_mode = "host"; 152 | status = "okay"; 153 | }; 154 | 155 | &usbphy { 156 | status = "okay"; 157 | }; 158 | -------------------------------------------------------------------------------- /esp_ctrl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 - 2014 Espressif System. 3 | * 4 | * SIP ctrl packet parse and pack 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "esp_pub.h" 24 | #include "esp_sip.h" 25 | #include "esp_ctrl.h" 26 | #include "esp_sif.h" 27 | #include "esp_debug.h" 28 | #include "esp_wmac.h" 29 | #include "esp_utils.h" 30 | #include "esp_wl.h" 31 | #include "esp_file.h" 32 | #include "esp_path.h" 33 | #ifdef TEST_MODE 34 | #include "testmode.h" 35 | #endif /* TEST_MODE */ 36 | #include "esp_version.h" 37 | 38 | extern struct completion *gl_bootup_cplx; 39 | 40 | static void esp_tx_ba_session_op(struct esp_sip *sip, 41 | struct esp_node *node, 42 | trc_ampdu_state_t state, u8 tid) 43 | { 44 | struct esp_tx_tid *txtid; 45 | 46 | txtid = &node->tid[tid]; 47 | if (state == TRC_TX_AMPDU_STOPPED) { 48 | if (txtid->state == ESP_TID_STATE_OPERATIONAL) { 49 | esp_dbg(ESP_DBG_TXAMPDU, 50 | "%s tid %d TXAMPDU GOT STOP EVT\n", 51 | __func__, tid); 52 | 53 | spin_lock_bh(&sip->epub->tx_ampdu_lock); 54 | txtid->state = ESP_TID_STATE_WAIT_STOP; 55 | spin_unlock_bh(&sip->epub->tx_ampdu_lock); 56 | ieee80211_stop_tx_ba_session(node->sta, (u16) tid); 57 | } else { 58 | esp_dbg(ESP_DBG_TXAMPDU, 59 | "%s tid %d TXAMPDU GOT STOP EVT IN WRONG STATE %d\n", 60 | __func__, tid, txtid->state); 61 | } 62 | } else if (state == TRC_TX_AMPDU_OPERATIONAL) { 63 | if (txtid->state == ESP_TID_STATE_STOP) { 64 | esp_dbg(ESP_DBG_TXAMPDU, 65 | "%s tid %d TXAMPDU GOT OPERATIONAL\n", 66 | __func__, tid); 67 | 68 | spin_lock_bh(&sip->epub->tx_ampdu_lock); 69 | txtid->state = ESP_TID_STATE_TRIGGER; 70 | spin_unlock_bh(&sip->epub->tx_ampdu_lock); 71 | ieee80211_start_tx_ba_session(node->sta, (u16) tid, 72 | 0); 73 | 74 | } else if (txtid->state == ESP_TID_STATE_OPERATIONAL) { 75 | sip_send_ampdu_action(sip->epub, 76 | SIP_AMPDU_TX_OPERATIONAL, 77 | node->sta->addr, tid, 78 | node->ifidx, 0); 79 | } else { 80 | esp_dbg(ESP_DBG_TXAMPDU, 81 | "%s tid %d TXAMPDU GOT OPERATIONAL EVT IN WRONG STATE %d\n", 82 | __func__, tid, txtid->state); 83 | } 84 | } 85 | } 86 | 87 | int sip_parse_events(struct esp_sip *sip, u8 * buf) 88 | { 89 | struct sip_hdr *hdr = (struct sip_hdr *) buf; 90 | 91 | switch (hdr->c_evtid) { 92 | case SIP_EVT_TARGET_ON:{ 93 | /* use rx work queue to send... */ 94 | if (atomic_read(&sip->state) == SIP_PREPARE_BOOT 95 | || atomic_read(&sip->state) == SIP_BOOT) { 96 | atomic_set(&sip->state, SIP_SEND_INIT); 97 | queue_work(sip->epub->esp_wkq, 98 | &sip->rx_process_work); 99 | } else { 100 | esp_dbg(ESP_DBG_ERROR, 101 | "%s boot during wrong state %d\n", 102 | __func__, 103 | atomic_read(&sip->state)); 104 | } 105 | break; 106 | } 107 | 108 | case SIP_EVT_BOOTUP:{ 109 | struct sip_evt_bootup2 *bootup_evt = 110 | (struct sip_evt_bootup2 *) (buf + 111 | SIP_CTRL_HDR_LEN); 112 | if (sip->rawbuf) 113 | kfree(sip->rawbuf); 114 | 115 | sip_post_init(sip, bootup_evt); 116 | 117 | if (gl_bootup_cplx) 118 | complete(gl_bootup_cplx); 119 | 120 | break; 121 | } 122 | case SIP_EVT_RESETTING:{ 123 | sip->epub->wait_reset = 1; 124 | if (gl_bootup_cplx) 125 | complete(gl_bootup_cplx); 126 | break; 127 | } 128 | case SIP_EVT_SLEEP:{ 129 | //atomic_set(&sip->epub->ps.state, ESP_PM_ON); 130 | break; 131 | } 132 | case SIP_EVT_TXIDLE:{ 133 | //struct sip_evt_txidle *txidle = (struct sip_evt_txidle *)(buf + SIP_CTRL_HDR_LEN); 134 | //sip_txdone_clear(sip, txidle->last_seq); 135 | break; 136 | } 137 | 138 | case SIP_EVT_SCAN_RESULT:{ 139 | struct sip_evt_scan_report *report = 140 | (struct sip_evt_scan_report *) (buf + 141 | SIP_CTRL_HDR_LEN); 142 | if (atomic_read(&sip->epub->wl.off)) { 143 | esp_dbg(ESP_DBG_ERROR, 144 | "%s scan result while wlan off\n", 145 | __func__); 146 | return 0; 147 | } 148 | sip_scandone_process(sip, report); 149 | 150 | break; 151 | } 152 | 153 | case SIP_EVT_ROC:{ 154 | struct sip_evt_roc *report = 155 | (struct sip_evt_roc *) (buf + 156 | SIP_CTRL_HDR_LEN); 157 | esp_rocdone_process(sip->epub->hw, report); 158 | break; 159 | } 160 | 161 | 162 | #ifdef ESP_RX_COPYBACK_TEST 163 | 164 | case SIP_EVT_COPYBACK:{ 165 | u32 len = hdr->len - SIP_CTRL_HDR_LEN; 166 | 167 | esp_dbg(ESP_DBG_TRACE, 168 | "%s copyback len %d seq %u\n", __func__, 169 | len, hdr->seq); 170 | 171 | memcpy(copyback_buf + copyback_offset, 172 | pkt->buf + SIP_CTRL_HDR_LEN, len); 173 | copyback_offset += len; 174 | 175 | //show_buf(pkt->buf, 256); 176 | 177 | //how about totlen % 256 == 0?? 178 | if (hdr->hdr.len < 256) { 179 | kfree(copyback_buf); 180 | } 181 | } 182 | break; 183 | #endif /* ESP_RX_COPYBACK_TEST */ 184 | case SIP_EVT_CREDIT_RPT: 185 | break; 186 | 187 | #ifdef TEST_MODE 188 | case SIP_EVT_WAKEUP:{ 189 | u8 check_str[12]; 190 | struct sip_evt_wakeup *wakeup_evt = 191 | (struct sip_evt_wakeup *) (buf + 192 | SIP_CTRL_HDR_LEN); 193 | sprintf((char *) &check_str, "%d", 194 | wakeup_evt->check_data); 195 | esp_test_cmd_event(TEST_CMD_WAKEUP, 196 | (char *) &check_str); 197 | break; 198 | } 199 | 200 | case SIP_EVT_DEBUG:{ 201 | u8 check_str[640]; 202 | sip_parse_event_debug(sip->epub, buf, check_str); 203 | esp_dbg(ESP_DBG_TRACE, "%s", check_str); 204 | esp_test_cmd_event(TEST_CMD_DEBUG, 205 | (char *) &check_str); 206 | break; 207 | } 208 | 209 | case SIP_EVT_LOOPBACK:{ 210 | u8 check_str[12]; 211 | struct sip_evt_loopback *loopback_evt = 212 | (struct sip_evt_loopback *) (buf + 213 | SIP_CTRL_HDR_LEN); 214 | esp_dbg(ESP_DBG_LOG, "%s loopback len %d seq %u\n", 215 | __func__, hdr->len, hdr->seq); 216 | 217 | if (loopback_evt->pack_id != get_loopback_id()) { 218 | sprintf((char *) &check_str, 219 | "seq id error %d, expect %d", 220 | loopback_evt->pack_id, 221 | get_loopback_id()); 222 | esp_test_cmd_event(TEST_CMD_LOOPBACK, 223 | (char *) &check_str); 224 | } 225 | 226 | if ((loopback_evt->pack_id + 1) < 227 | get_loopback_num()) { 228 | inc_loopback_id(); 229 | sip_send_loopback_mblk(sip, 230 | loopback_evt->txlen, 231 | loopback_evt->rxlen, 232 | get_loopback_id()); 233 | } else { 234 | sprintf((char *) &check_str, "test over!"); 235 | esp_test_cmd_event(TEST_CMD_LOOPBACK, 236 | (char *) &check_str); 237 | } 238 | break; 239 | } 240 | #endif /*TEST_MODE */ 241 | 242 | case SIP_EVT_SNPRINTF_TO_HOST:{ 243 | u8 *p = 244 | (buf + sizeof(struct sip_hdr) + sizeof(u16)); 245 | u16 *len = (u16 *) (buf + sizeof(struct sip_hdr)); 246 | char test_res_str[560]; 247 | sprintf(test_res_str, 248 | "esp_host:%llx\nesp_target: %.*s", 249 | DRIVER_VER, *len, p); 250 | 251 | esp_dbg(ESP_DBG_TRACE, "%s\n", test_res_str); 252 | if (*len 253 | && sip->epub->sdio_state == 254 | ESP_SDIO_STATE_FIRST_INIT) { 255 | char filename[256]; 256 | if (mod_eagle_path_get() == NULL) 257 | sprintf(filename, "%s/%s", FWPATH, 258 | "test_results"); 259 | else 260 | sprintf(filename, "%s/%s", 261 | mod_eagle_path_get(), 262 | "test_results"); 263 | esp_dbg(ESP_DBG_TRACE, 264 | "SNPRINTF TO HOST: %s\n", 265 | test_res_str); 266 | } 267 | break; 268 | } 269 | case SIP_EVT_TRC_AMPDU:{ 270 | struct sip_evt_trc_ampdu *ep = 271 | (struct sip_evt_trc_ampdu *) (buf + 272 | SIP_CTRL_HDR_LEN); 273 | struct esp_node *node = NULL; 274 | int i = 0; 275 | 276 | if (atomic_read(&sip->epub->wl.off)) { 277 | esp_dbg(ESP_DBG_ERROR, 278 | "%s scan result while wlan off\n", 279 | __func__); 280 | return 0; 281 | } 282 | 283 | node = esp_get_node_by_addr(sip->epub, ep->addr); 284 | if (node == NULL) 285 | break; 286 | for (i = 0; i < 8; i++) { 287 | if (ep->tid & (1 << i)) { 288 | esp_tx_ba_session_op(sip, node, 289 | ep->state, i); 290 | } 291 | } 292 | break; 293 | } 294 | 295 | #ifdef TEST_MODE 296 | case SIP_EVT_EP:{ 297 | char *ep = (char *) (buf + SIP_CTRL_HDR_LEN); 298 | static int counter = 0; 299 | 300 | esp_dbg(ESP_ATE, "%s EVT_EP \n\n", __func__); 301 | if (counter++ < 2) { 302 | esp_dbg(ESP_ATE, "ATE: %s \n", ep); 303 | } 304 | 305 | esp_test_ate_done_cb(ep); 306 | 307 | break; 308 | } 309 | #endif /*TEST_MODE */ 310 | 311 | case SIP_EVT_INIT_EP:{ 312 | char *ep = (char *) (buf + SIP_CTRL_HDR_LEN); 313 | esp_dbg(ESP_ATE, "Phy Init: %s \n", ep); 314 | break; 315 | } 316 | 317 | case SIP_EVT_NOISEFLOOR:{ 318 | struct sip_evt_noisefloor *ep = 319 | (struct sip_evt_noisefloor *) (buf + 320 | SIP_CTRL_HDR_LEN); 321 | atomic_set(&sip->noise_floor, ep->noise_floor); 322 | break; 323 | } 324 | default: 325 | break; 326 | } 327 | 328 | return 0; 329 | } 330 | 331 | #include "esp_init_data.h" 332 | 333 | void sip_send_chip_init(struct esp_sip *sip) 334 | { 335 | size_t size = 0; 336 | size = sizeof(esp_init_data); 337 | 338 | fix_init_data(esp_init_data, size); 339 | 340 | atomic_sub(1, &sip->tx_credits); 341 | 342 | sip_send_cmd(sip, SIP_CMD_INIT, size, (void *) esp_init_data); 343 | 344 | } 345 | 346 | int sip_send_config(struct esp_pub *epub, struct ieee80211_conf *conf) 347 | { 348 | struct sk_buff *skb = NULL; 349 | struct sip_cmd_config *configcmd; 350 | 351 | skb = 352 | sip_alloc_ctrl_skbuf(epub->sip, 353 | sizeof(struct sip_cmd_config) + 354 | sizeof(struct sip_hdr), SIP_CMD_CONFIG); 355 | if (!skb) 356 | return -EINVAL; 357 | esp_dbg(ESP_DBG_TRACE, "%s config center freq %d\n", __func__, 358 | conf->chandef.chan->center_freq); 359 | configcmd = 360 | (struct sip_cmd_config *) (skb->data + sizeof(struct sip_hdr)); 361 | configcmd->center_freq = conf->chandef.chan->center_freq; 362 | configcmd->duration = 0; 363 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 364 | } 365 | 366 | int sip_send_bss_info_update(struct esp_pub *epub, struct esp_vif *evif, 367 | u8 * bssid, int assoc) 368 | { 369 | struct sk_buff *skb = NULL; 370 | struct sip_cmd_bss_info_update *bsscmd; 371 | 372 | skb = 373 | sip_alloc_ctrl_skbuf(epub->sip, 374 | sizeof(struct sip_cmd_bss_info_update) + 375 | sizeof(struct sip_hdr), 376 | SIP_CMD_BSS_INFO_UPDATE); 377 | if (!skb) 378 | return -EINVAL; 379 | 380 | bsscmd = 381 | (struct sip_cmd_bss_info_update *) (skb->data + 382 | sizeof(struct sip_hdr)); 383 | if (assoc == 2) { //hack for softAP mode 384 | bsscmd->beacon_int = evif->beacon_interval; 385 | } else if (assoc == 1) { 386 | set_bit(ESP_WL_FLAG_CONNECT, &epub->wl.flags); 387 | } else { 388 | clear_bit(ESP_WL_FLAG_CONNECT, &epub->wl.flags); 389 | } 390 | bsscmd->bssid_no = evif->index; 391 | bsscmd->isassoc = assoc; 392 | bsscmd->beacon_int = evif->beacon_interval; 393 | memcpy(bsscmd->bssid, bssid, ETH_ALEN); 394 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 395 | } 396 | 397 | int sip_send_wmm_params(struct esp_pub *epub, u8 aci, 398 | const struct ieee80211_tx_queue_params *params) 399 | { 400 | struct sk_buff *skb = NULL; 401 | struct sip_cmd_set_wmm_params *bsscmd; 402 | skb = 403 | sip_alloc_ctrl_skbuf(epub->sip, 404 | sizeof(struct sip_cmd_set_wmm_params) + 405 | sizeof(struct sip_hdr), 406 | SIP_CMD_SET_WMM_PARAM); 407 | if (!skb) 408 | return -EINVAL; 409 | 410 | bsscmd = 411 | (struct sip_cmd_set_wmm_params *) (skb->data + 412 | sizeof(struct sip_hdr)); 413 | bsscmd->aci = aci; 414 | bsscmd->aifs = params->aifs; 415 | bsscmd->txop_us = params->txop * 32; 416 | 417 | bsscmd->ecw_min = 32 - __builtin_clz(params->cw_min); 418 | bsscmd->ecw_max = 32 - __builtin_clz(params->cw_max); 419 | 420 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 421 | } 422 | 423 | int sip_send_ampdu_action(struct esp_pub *epub, u8 action_num, 424 | const u8 * addr, u16 tid, u16 ssn, u8 buf_size) 425 | { 426 | int index = 0; 427 | struct sk_buff *skb = NULL; 428 | struct sip_cmd_ampdu_action *action; 429 | if (action_num == SIP_AMPDU_RX_START) { 430 | index = esp_get_empty_rxampdu(epub, addr, tid); 431 | } else if (action_num == SIP_AMPDU_RX_STOP) { 432 | index = esp_get_exist_rxampdu(epub, addr, tid); 433 | } 434 | if (index < 0) 435 | return -EACCES; 436 | skb = 437 | sip_alloc_ctrl_skbuf(epub->sip, 438 | sizeof(struct sip_cmd_ampdu_action) + 439 | sizeof(struct sip_hdr), 440 | SIP_CMD_AMPDU_ACTION); 441 | if (!skb) 442 | return -EINVAL; 443 | 444 | action = 445 | (struct sip_cmd_ampdu_action *) (skb->data + 446 | sizeof(struct sip_hdr)); 447 | action->action = action_num; 448 | //for TX, it means interface index 449 | action->index = ssn; 450 | 451 | switch (action_num) { 452 | case SIP_AMPDU_RX_START: 453 | action->ssn = ssn; 454 | case SIP_AMPDU_RX_STOP: 455 | action->index = index; 456 | case SIP_AMPDU_TX_OPERATIONAL: 457 | case SIP_AMPDU_TX_STOP: 458 | action->win_size = buf_size; 459 | action->tid = tid; 460 | memcpy(action->addr, addr, ETH_ALEN); 461 | break; 462 | } 463 | 464 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 465 | } 466 | 467 | #ifdef HW_SCAN 468 | /*send cmd to target, if aborted is true, inform target stop scan, report scan complete imediately 469 | return 1: complete over, 0: success, still have next scan, -1: hardware failure 470 | */ 471 | int sip_send_scan(struct esp_pub *epub) 472 | { 473 | struct cfg80211_scan_request *scan_req = epub->wl.scan_req; 474 | struct sk_buff *skb = NULL; 475 | struct sip_cmd_scan *scancmd; 476 | u8 *ptr = NULL; 477 | int i; 478 | u8 append_len, ssid_len; 479 | 480 | ESSERT(scan_req != NULL); 481 | ssid_len = scan_req->n_ssids == 0 ? 0 : 482 | (scan_req->n_ssids == 483 | 1 ? scan_req->ssids->ssid_len : scan_req->ssids->ssid_len + 484 | (scan_req->ssids + 1)->ssid_len); 485 | append_len = ssid_len + scan_req->n_channels + scan_req->ie_len; 486 | 487 | skb = 488 | sip_alloc_ctrl_skbuf(epub->sip, 489 | sizeof(struct sip_cmd_scan) + 490 | sizeof(struct sip_hdr) + append_len, 491 | SIP_CMD_SCAN); 492 | 493 | if (!skb) 494 | return -EINVAL; 495 | 496 | ptr = skb->data; 497 | scancmd = (struct sip_cmd_scan *) (ptr + sizeof(struct sip_hdr)); 498 | ptr += sizeof(struct sip_hdr); 499 | 500 | scancmd->aborted = false; 501 | 502 | if (scancmd->aborted == false) { 503 | ptr += sizeof(struct sip_cmd_scan); 504 | if (scan_req->n_ssids <= 0 505 | || (scan_req->n_ssids == 1 && ssid_len == 0)) { 506 | scancmd->ssid_len = 0; 507 | } else { 508 | scancmd->ssid_len = ssid_len; 509 | if (scan_req->ssids->ssid_len == ssid_len) 510 | memcpy(ptr, scan_req->ssids->ssid, 511 | scancmd->ssid_len); 512 | else 513 | memcpy(ptr, (scan_req->ssids + 1)->ssid, 514 | scancmd->ssid_len); 515 | } 516 | 517 | ptr += scancmd->ssid_len; 518 | scancmd->n_channels = scan_req->n_channels; 519 | for (i = 0; i < scan_req->n_channels; i++) 520 | ptr[i] = scan_req->channels[i]->hw_value; 521 | 522 | ptr += scancmd->n_channels; 523 | if (scan_req->ie_len && scan_req->ie != NULL) { 524 | scancmd->ie_len = scan_req->ie_len; 525 | memcpy(ptr, scan_req->ie, scan_req->ie_len); 526 | } else { 527 | scancmd->ie_len = 0; 528 | } 529 | //add a flag that support two ssids, 530 | if (scan_req->n_ssids > 1) 531 | scancmd->ssid_len |= 0x80; 532 | 533 | } 534 | 535 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 536 | } 537 | #endif 538 | 539 | int sip_send_suspend_config(struct esp_pub *epub, u8 suspend) 540 | { 541 | struct sip_cmd_suspend *cmd = NULL; 542 | struct sk_buff *skb = NULL; 543 | 544 | skb = 545 | sip_alloc_ctrl_skbuf(epub->sip, 546 | sizeof(struct sip_cmd_suspend) + 547 | sizeof(struct sip_hdr), SIP_CMD_SUSPEND); 548 | 549 | if (!skb) 550 | return -EINVAL; 551 | 552 | cmd = 553 | (struct sip_cmd_suspend *) (skb->data + 554 | sizeof(struct sip_hdr)); 555 | cmd->suspend = suspend; 556 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 557 | } 558 | 559 | int sip_send_ps_config(struct esp_pub *epub, struct esp_ps *ps) 560 | { 561 | struct sip_cmd_ps *pscmd = NULL; 562 | struct sk_buff *skb = NULL; 563 | struct sip_hdr *shdr = NULL; 564 | 565 | skb = 566 | sip_alloc_ctrl_skbuf(epub->sip, 567 | sizeof(struct sip_cmd_ps) + 568 | sizeof(struct sip_hdr), SIP_CMD_PS); 569 | 570 | if (!skb) 571 | return -EINVAL; 572 | 573 | 574 | shdr = (struct sip_hdr *) skb->data; 575 | pscmd = (struct sip_cmd_ps *) (skb->data + sizeof(struct sip_hdr)); 576 | 577 | pscmd->dtim_period = ps->dtim_period; 578 | pscmd->max_sleep_period = ps->max_sleep_period; 579 | 580 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 581 | } 582 | 583 | void sip_scandone_process(struct esp_sip *sip, 584 | struct sip_evt_scan_report *scan_report) 585 | { 586 | struct esp_pub *epub = sip->epub; 587 | 588 | esp_dbg(ESP_DBG_TRACE, "eagle hw scan report\n"); 589 | 590 | if (epub->wl.scan_req) { 591 | hw_scan_done(epub, scan_report->aborted); 592 | epub->wl.scan_req = NULL; 593 | } 594 | } 595 | 596 | int sip_send_setkey(struct esp_pub *epub, u8 bssid_no, u8 * peer_addr, 597 | struct ieee80211_key_conf *key, u8 isvalid) 598 | { 599 | struct sip_cmd_setkey *setkeycmd; 600 | struct sk_buff *skb = NULL; 601 | 602 | skb = 603 | sip_alloc_ctrl_skbuf(epub->sip, 604 | sizeof(struct sip_cmd_setkey) + 605 | sizeof(struct sip_hdr), SIP_CMD_SETKEY); 606 | 607 | if (!skb) 608 | return -EINVAL; 609 | 610 | setkeycmd = 611 | (struct sip_cmd_setkey *) (skb->data + sizeof(struct sip_hdr)); 612 | 613 | if (peer_addr) { 614 | memcpy(setkeycmd->addr, peer_addr, ETH_ALEN); 615 | } else { 616 | memset(setkeycmd->addr, 0, ETH_ALEN); 617 | } 618 | 619 | setkeycmd->bssid_no = bssid_no; 620 | setkeycmd->hw_key_idx = key->hw_key_idx; 621 | 622 | if (isvalid) { 623 | setkeycmd->alg = esp_cipher2alg(key->cipher); 624 | setkeycmd->keyidx = key->keyidx; 625 | setkeycmd->keylen = key->keylen; 626 | if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { 627 | memcpy(setkeycmd->key, key->key, 16); 628 | memcpy(setkeycmd->key + 16, key->key + 24, 8); 629 | memcpy(setkeycmd->key + 24, key->key + 16, 8); 630 | } else { 631 | memcpy(setkeycmd->key, key->key, key->keylen); 632 | } 633 | 634 | setkeycmd->flags = 1; 635 | } else { 636 | setkeycmd->flags = 0; 637 | } 638 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 639 | } 640 | 641 | #ifdef FPGA_LOOPBACK 642 | #define LOOPBACK_PKT_LEN 200 643 | int sip_send_loopback_cmd_mblk(struct esp_sip *sip) 644 | { 645 | int cnt, ret; 646 | 647 | for (cnt = 0; cnt < 4; cnt++) { 648 | if (0 != 649 | (ret = 650 | sip_send_loopback_mblk(sip, LOOPBACK_PKT_LEN, 651 | LOOPBACK_PKT_LEN, 0))) 652 | return ret; 653 | } 654 | return 0; 655 | } 656 | #endif /* FPGA_LOOPBACK */ 657 | 658 | int sip_send_loopback_mblk(struct esp_sip *sip, int txpacket_len, 659 | int rxpacket_len, int packet_id) 660 | { 661 | struct sk_buff *skb = NULL; 662 | struct sip_cmd_loopback *cmd; 663 | u8 *ptr = NULL; 664 | int i, ret; 665 | 666 | //send 100 loopback pkt 667 | if (txpacket_len) 668 | skb = 669 | sip_alloc_ctrl_skbuf(sip, 670 | sizeof(struct sip_cmd_loopback) + 671 | sizeof(struct sip_hdr) + 672 | txpacket_len, SIP_CMD_LOOPBACK); 673 | else 674 | skb = 675 | sip_alloc_ctrl_skbuf(sip, 676 | sizeof(struct sip_cmd_loopback) + 677 | sizeof(struct sip_hdr), 678 | SIP_CMD_LOOPBACK); 679 | 680 | if (!skb) 681 | return -ENOMEM; 682 | 683 | ptr = skb->data; 684 | cmd = (struct sip_cmd_loopback *) (ptr + sizeof(struct sip_hdr)); 685 | ptr += sizeof(struct sip_hdr); 686 | cmd->txlen = txpacket_len; 687 | cmd->rxlen = rxpacket_len; 688 | cmd->pack_id = packet_id; 689 | 690 | if (txpacket_len) { 691 | ptr += sizeof(struct sip_cmd_loopback); 692 | /* fill up pkt payload */ 693 | for (i = 0; i < txpacket_len; i++) { 694 | ptr[i] = i; 695 | } 696 | } 697 | 698 | ret = sip_cmd_enqueue(sip, skb, ENQUEUE_PRIOR_TAIL); 699 | if (ret < 0) 700 | return ret; 701 | 702 | return 0; 703 | } 704 | 705 | //remain_on_channel 706 | int sip_send_roc(struct esp_pub *epub, u16 center_freq, u16 duration) 707 | { 708 | struct sk_buff *skb = NULL; 709 | struct sip_cmd_config *configcmd; 710 | 711 | skb = 712 | sip_alloc_ctrl_skbuf(epub->sip, 713 | sizeof(struct sip_cmd_config) + 714 | sizeof(struct sip_hdr), SIP_CMD_CONFIG); 715 | if (!skb) 716 | return -EINVAL; 717 | 718 | configcmd = 719 | (struct sip_cmd_config *) (skb->data + sizeof(struct sip_hdr)); 720 | configcmd->center_freq = center_freq; 721 | configcmd->duration = duration; 722 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 723 | } 724 | 725 | int sip_send_set_sta(struct esp_pub *epub, u8 ifidx, u8 set, 726 | struct ieee80211_sta *sta, struct ieee80211_vif *vif, 727 | u8 index) 728 | { 729 | struct sk_buff *skb = NULL; 730 | struct sip_cmd_setsta *setstacmd; 731 | skb = 732 | sip_alloc_ctrl_skbuf(epub->sip, 733 | sizeof(struct sip_cmd_setsta) + 734 | sizeof(struct sip_hdr), SIP_CMD_SETSTA); 735 | if (!skb) 736 | return -EINVAL; 737 | 738 | setstacmd = 739 | (struct sip_cmd_setsta *) (skb->data + sizeof(struct sip_hdr)); 740 | setstacmd->ifidx = ifidx; 741 | setstacmd->index = index; 742 | setstacmd->set = set; 743 | if (sta->aid == 0) 744 | setstacmd->aid = vif->bss_conf.aid; 745 | else 746 | setstacmd->aid = sta->aid; 747 | memcpy(setstacmd->mac, sta->addr, ETH_ALEN); 748 | if (set) { 749 | if (sta->ht_cap.ht_supported) { 750 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) 751 | setstacmd->phymode = 752 | ESP_IEEE80211_T_HT20_S; 753 | else 754 | setstacmd->phymode = 755 | ESP_IEEE80211_T_HT20_L; 756 | setstacmd->ampdu_factor = sta->ht_cap.ampdu_factor; 757 | setstacmd->ampdu_density = 758 | sta->ht_cap.ampdu_density; 759 | } else { 760 | if (sta-> 761 | supp_rates[NL80211_BAND_2GHZ] & (~(u32) 762 | CONF_HW_BIT_RATE_11B_MASK)) 763 | { 764 | setstacmd->phymode = ESP_IEEE80211_T_OFDM; 765 | } else { 766 | setstacmd->phymode = ESP_IEEE80211_T_CCK; 767 | } 768 | } 769 | } 770 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 771 | } 772 | 773 | int sip_send_recalc_credit(struct esp_pub *epub) 774 | { 775 | struct sk_buff *skb = NULL; 776 | 777 | skb = 778 | sip_alloc_ctrl_skbuf(epub->sip, 0 + sizeof(struct sip_hdr), 779 | SIP_CMD_RECALC_CREDIT); 780 | if (!skb) 781 | return -ENOMEM; 782 | 783 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_HEAD); 784 | } 785 | 786 | int sip_cmd(struct esp_pub *epub, enum sip_cmd_id cmd_id, u8 * cmd_buf, 787 | u8 cmd_len) 788 | { 789 | struct sk_buff *skb = NULL; 790 | 791 | skb = 792 | sip_alloc_ctrl_skbuf(epub->sip, 793 | cmd_len + sizeof(struct sip_hdr), cmd_id); 794 | if (!skb) 795 | return -ENOMEM; 796 | 797 | memcpy(skb->data + sizeof(struct sip_hdr), cmd_buf, cmd_len); 798 | 799 | return sip_cmd_enqueue(epub->sip, skb, ENQUEUE_PRIOR_TAIL); 800 | } 801 | -------------------------------------------------------------------------------- /esp_ctrl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009- 2014 Espressif System. 3 | * 4 | * SIP ctrl packet parse and pack 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | */ 16 | #ifndef _ESP_CTRL_H_ 17 | #define _ESP_CTRL_H_ 18 | 19 | int sip_send_loopback_mblk(struct esp_sip *sip, int txpacket_len, 20 | int rxpacket_len, int packet_id); 21 | 22 | int sip_send_config(struct esp_pub *epub, struct ieee80211_conf *conf); 23 | 24 | int sip_send_setkey(struct esp_pub *epub, u8 bssid_no, u8 * peer_addr, 25 | struct ieee80211_key_conf *key, u8 isvalid); 26 | 27 | int sip_send_scan(struct esp_pub *epub); 28 | 29 | void sip_scandone_process(struct esp_sip *sip, 30 | struct sip_evt_scan_report *scan_report); 31 | 32 | int sip_send_bss_info_update(struct esp_pub *epub, struct esp_vif *evif, 33 | u8 * bssid, int assoc); 34 | 35 | int sip_send_wmm_params(struct esp_pub *epub, u8 aci, 36 | const struct ieee80211_tx_queue_params *params); 37 | 38 | int sip_send_ampdu_action(struct esp_pub *epub, u8 action_num, 39 | const u8 * addr, u16 tid, u16 ssn, u8 buf_size); 40 | 41 | int sip_send_roc(struct esp_pub *epub, u16 center_freq, u16 duration); 42 | 43 | int sip_send_set_sta(struct esp_pub *epub, u8 ifidx, u8 set, 44 | struct ieee80211_sta *sta, struct ieee80211_vif *vif, 45 | u8 index); 46 | 47 | int sip_send_suspend_config(struct esp_pub *epub, u8 suspend); 48 | 49 | int sip_send_ps_config(struct esp_pub *epub, struct esp_ps *ps); 50 | 51 | int sip_parse_events(struct esp_sip *sip, u8 * buf); 52 | 53 | int sip_send_recalc_credit(struct esp_pub *epub); 54 | 55 | int sip_cmd(struct esp_pub *epub, enum sip_cmd_id cmd_id, u8 * cmd_buf, 56 | u8 cmd_len); 57 | 58 | #endif /* _ESP_CTRL_H_ */ 59 | -------------------------------------------------------------------------------- /esp_debug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2014 Espressif System. 3 | * 4 | * esp debug interface 5 | * - debugfs 6 | * - debug level control 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include "sip2_common.h" 24 | 25 | #include "esp_debug.h" 26 | 27 | #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_ESP8089_DEBUG_FS) 28 | 29 | static struct dentry *esp_debugfs_root = NULL; 30 | 31 | static int esp_debugfs_open(struct inode *inode, struct file *filp) 32 | { 33 | filp->private_data = inode->i_private; 34 | return 0; 35 | } 36 | 37 | static ssize_t esp_debugfs_read(struct file *filp, char __user * buffer, 38 | size_t count, loff_t * ppos) 39 | { 40 | if (*ppos >= 32) 41 | return 0; 42 | if (*ppos + count > 32) 43 | count = 32 - *ppos; 44 | 45 | if (copy_to_user(buffer, filp->private_data + *ppos, count)) 46 | return -EFAULT; 47 | 48 | *ppos += count; 49 | 50 | return count; 51 | } 52 | 53 | static ssize_t esp_debugfs_write(struct file *filp, 54 | const char __user * buffer, size_t count, 55 | loff_t * ppos) 56 | { 57 | if (*ppos >= 32) 58 | return 0; 59 | if (*ppos + count > 32) 60 | count = 32 - *ppos; 61 | 62 | if (copy_from_user(filp->private_data + *ppos, buffer, count)) 63 | return -EFAULT; 64 | 65 | *ppos += count; 66 | 67 | return count; 68 | } 69 | 70 | struct file_operations esp_debugfs_fops = { 71 | .owner = THIS_MODULE, 72 | .open = esp_debugfs_open, 73 | .read = esp_debugfs_read, 74 | .write = esp_debugfs_write, 75 | }; 76 | 77 | 78 | struct dentry *esp_dump_var(const char *name, struct dentry *parent, 79 | void *value, esp_type type) 80 | { 81 | struct dentry *rc = NULL; 82 | umode_t mode = 0644; 83 | 84 | if (!esp_debugfs_root) 85 | return NULL; 86 | 87 | if (!parent) 88 | parent = esp_debugfs_root; 89 | 90 | switch (type) { 91 | case ESP_U8: 92 | rc = debugfs_create_u8(name, mode, parent, (u8 *) value); 93 | break; 94 | case ESP_U16: 95 | rc = debugfs_create_u16(name, mode, parent, (u16 *) value); 96 | break; 97 | case ESP_U32: 98 | rc = debugfs_create_u32(name, mode, parent, (u32 *) value); 99 | break; 100 | case ESP_U64: 101 | rc = debugfs_create_u64(name, mode, parent, (u64 *) value); 102 | break; 103 | case ESP_BOOL: 104 | rc = debugfs_create_bool(name, mode, parent, 105 | (bool *) value); 106 | break; 107 | default: //32 108 | rc = debugfs_create_u32(name, mode, parent, (u32 *) value); 109 | } 110 | 111 | if (!rc) 112 | goto Fail; 113 | else 114 | return rc; 115 | Fail: 116 | debugfs_remove_recursive(esp_debugfs_root); 117 | esp_debugfs_root = NULL; 118 | esp_dbg(ESP_DBG_ERROR, 119 | "%s failed, debugfs root removed; var name: %s\n", 120 | __FUNCTION__, name); 121 | return NULL; 122 | } 123 | 124 | struct dentry *esp_dump_array(const char *name, struct dentry *parent, 125 | struct debugfs_blob_wrapper *blob) 126 | { 127 | struct dentry *rc = NULL; 128 | umode_t mode = 0644; 129 | 130 | if (!esp_debugfs_root) 131 | return NULL; 132 | 133 | if (!parent) 134 | parent = esp_debugfs_root; 135 | 136 | rc = debugfs_create_blob(name, mode, parent, blob); 137 | 138 | if (!rc) 139 | goto Fail; 140 | else 141 | return rc; 142 | 143 | Fail: 144 | debugfs_remove_recursive(esp_debugfs_root); 145 | esp_debugfs_root = NULL; 146 | esp_dbg(ESP_DBG_ERROR, 147 | "%s failed, debugfs root removed; var name: %s\n", 148 | __FUNCTION__, name); 149 | return NULL; 150 | } 151 | 152 | struct dentry *esp_dump(const char *name, struct dentry *parent, 153 | void *data, int size) 154 | { 155 | struct dentry *rc; 156 | umode_t mode = 0644; 157 | 158 | if (!esp_debugfs_root) 159 | return NULL; 160 | 161 | if (!parent) 162 | parent = esp_debugfs_root; 163 | 164 | rc = debugfs_create_file(name, mode, parent, data, 165 | &esp_debugfs_fops); 166 | 167 | if (!rc) 168 | goto Fail; 169 | else 170 | return rc; 171 | 172 | Fail: 173 | debugfs_remove_recursive(esp_debugfs_root); 174 | esp_debugfs_root = NULL; 175 | esp_dbg(ESP_DBG_ERROR, 176 | "%s failed, debugfs root removed; var name: %s\n", 177 | __FUNCTION__, name); 178 | return NULL; 179 | } 180 | 181 | struct dentry *esp_debugfs_add_sub_dir(const char *name) 182 | { 183 | struct dentry *sub_dir = NULL; 184 | 185 | sub_dir = debugfs_create_dir(name, esp_debugfs_root); 186 | 187 | if (!sub_dir) 188 | goto Fail; 189 | 190 | return sub_dir; 191 | 192 | Fail: 193 | debugfs_remove_recursive(esp_debugfs_root); 194 | esp_debugfs_root = NULL; 195 | esp_dbg(ESP_DBG_ERROR, 196 | "%s failed, debugfs root removed; dir name: %s\n", 197 | __FUNCTION__, name); 198 | return NULL; 199 | 200 | } 201 | 202 | int esp_debugfs_init(void) 203 | { 204 | esp_dbg(ESP_DBG, "esp debugfs init\n"); 205 | esp_debugfs_root = debugfs_create_dir("esp_debug", NULL); 206 | 207 | if (!esp_debugfs_root || IS_ERR_OR_NULL(esp_debugfs_root)) { 208 | return -ENOENT; 209 | } 210 | 211 | return 0; 212 | } 213 | 214 | void esp_debugfs_exit(void) 215 | { 216 | esp_dbg(ESP_DBG, "esp debugfs exit"); 217 | 218 | debugfs_remove_recursive(esp_debugfs_root); 219 | 220 | return; 221 | } 222 | 223 | #else 224 | 225 | inline struct dentry *esp_dump_var(const char *name, struct dentry *parent, 226 | void *value, esp_type type) 227 | { 228 | return NULL; 229 | } 230 | 231 | inline struct dentry *esp_dump_array(const char *name, 232 | struct dentry *parent, 233 | struct debugfs_blob_wrapper *blob) 234 | { 235 | return NULL; 236 | } 237 | 238 | inline struct dentry *esp_dump(const char *name, struct dentry *parent, 239 | void *data, int size) 240 | { 241 | return NULL; 242 | } 243 | 244 | struct dentry *esp_debugfs_add_sub_dir(const char *name) 245 | { 246 | return NULL; 247 | } 248 | 249 | inline int esp_debugfs_init(void) 250 | { 251 | return -EPERM; 252 | } 253 | 254 | inline void esp_debugfs_exit(void) 255 | { 256 | 257 | } 258 | 259 | #endif 260 | 261 | 262 | void show_buf(u8 * buf, u32 len) 263 | { 264 | // print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, buf, len, true); 265 | #if 1 266 | int i = 0, j; 267 | 268 | printk(KERN_INFO "\n++++++++++++++++show rbuf+++++++++++++++\n"); 269 | for (i = 0; i < (len / 16); i++) { 270 | j = i * 16; 271 | printk(KERN_INFO 272 | "0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x \n", 273 | buf[j], buf[j + 1], buf[j + 2], buf[j + 3], 274 | buf[j + 4], buf[j + 5], buf[j + 6], buf[j + 7], 275 | buf[j + 8], buf[j + 9], buf[j + 10], buf[j + 11], 276 | buf[j + 12], buf[j + 13], buf[j + 14], buf[j + 15]); 277 | } 278 | printk(KERN_INFO "\n++++++++++++++++++++++++++++++++++++++++\n"); 279 | #endif //0000 280 | } 281 | 282 | #ifdef HOST_RC 283 | static u8 get_cnt(u32 cnt_store, int idx) 284 | { 285 | int shift = idx << 2; 286 | 287 | return (u8) ((cnt_store >> shift) & 0xf); 288 | } 289 | 290 | void esp_show_rcstatus(struct sip_rc_status *rcstatus) 291 | { 292 | int i; 293 | char msg[82]; 294 | char rcstr[16]; 295 | u32 cnt_store = rcstatus->rc_cnt_store; 296 | 297 | memset(msg, 0, sizeof(msg)); 298 | memset(rcstr, 0, sizeof(rcstr)); 299 | 300 | printk(KERN_INFO "rcstatus map 0x%08x cntStore 0x%08x\n", 301 | rcstatus->rc_map, rcstatus->rc_cnt_store); 302 | 303 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 304 | if (rcstatus->rc_map & BIT(i)) { 305 | sprintf(rcstr, "rcIdx %d, cnt %d ", i, 306 | get_cnt(cnt_store, i)); 307 | strcat(msg, rcstr); 308 | } 309 | } 310 | printk(KERN_INFO "%s \n", msg); 311 | } 312 | 313 | void esp_show_tx_rates(struct ieee80211_tx_rate *rates) 314 | { 315 | int i; 316 | char msg[128]; 317 | char rcstr[32]; 318 | 319 | memset(msg, 0, sizeof(msg)); 320 | memset(rcstr, 0, sizeof(rcstr)); 321 | 322 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 323 | if (rates->idx != -1) { 324 | sprintf(rcstr, "Idx %d, cnt %d, flag %02x ", 325 | rates->idx, rates->count, rates->flags); 326 | strcat(msg, rcstr); 327 | } 328 | rates++; 329 | } 330 | strcat(msg, "\n"); 331 | printk(KERN_INFO "%s \n", msg); 332 | } 333 | #endif /* HOST_RC */ 334 | -------------------------------------------------------------------------------- /esp_debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2014 Espressif System. 3 | * 4 | * esp debug 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | */ 16 | 17 | #ifndef _DEBUG_H_ 18 | 19 | #ifdef ASSERT_PANIC 20 | #define ESSERT(v) BUG_ON(!(v)) 21 | #else 22 | #define ESSERT(v) if(!(v)) printk("ESSERT:%s %d\n", __FILE__, __LINE__) 23 | #endif 24 | 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | typedef enum esp_type { 31 | ESP_BOOL, 32 | ESP_U8, 33 | ESP_U16, 34 | ESP_U32, 35 | ESP_U64 36 | } esp_type; 37 | 38 | struct dentry *esp_dump_var(const char *name, struct dentry *parent, 39 | void *value, esp_type type); 40 | 41 | struct dentry *esp_dump_array(const char *name, struct dentry *parent, 42 | struct debugfs_blob_wrapper *blob); 43 | 44 | struct dentry *esp_dump(const char *name, struct dentry *parent, 45 | void *data, int size); 46 | 47 | struct dentry *esp_debugfs_add_sub_dir(const char *name); 48 | 49 | int esp_debugfs_init(void); 50 | 51 | void esp_debugfs_exit(void); 52 | 53 | enum { 54 | ESP_DBG_ERROR = BIT(0), 55 | ESP_DBG_TRACE = BIT(1), 56 | ESP_DBG_LOG = BIT(2), 57 | ESP_DBG = BIT(3), 58 | ESP_SHOW = BIT(4), 59 | ESP_DBG_TXAMPDU = BIT(5), 60 | ESP_DBG_OP = BIT(6), 61 | ESP_DBG_PS = BIT(7), 62 | ESP_ATE = BIT(8), 63 | ESP_DBG_ALL = 0xffffffff 64 | }; 65 | 66 | extern unsigned int esp_msg_level; 67 | 68 | #ifdef ESP_ANDROID_LOGGER 69 | extern bool log_off; 70 | #endif /* ESP_ANDROID_LOGGER */ 71 | 72 | #ifdef ESP_ANDROID_LOGGER 73 | #include "esp_file.h" 74 | #define esp_dbg(mask, fmt, args...) do { \ 75 | if (esp_msg_level & mask) \ 76 | { \ 77 | if (log_off) \ 78 | printk(fmt, ##args); \ 79 | else \ 80 | logger_write(4, "esp_wifi", fmt, ##args); \ 81 | } \ 82 | } while (0) 83 | #else 84 | #define esp_dbg(mask, fmt, args...) do { \ 85 | if (esp_msg_level & mask) \ 86 | printk(fmt, ##args); \ 87 | } while (0) 88 | #endif /* ESP_ANDROID_LOGGER */ 89 | 90 | void show_buf(u8 * buf, u32 len); 91 | 92 | #ifdef HOST_RC 93 | struct sip_rc_status; 94 | struct ieee80211_tx_rate; 95 | 96 | void esp_show_rcstatus(struct sip_rc_status *rcstatus); 97 | 98 | void esp_show_tx_rates(struct ieee80211_tx_rate *rates); 99 | #endif /* HOST_RC */ 100 | 101 | #endif /* _DEBUG_H_ */ 102 | -------------------------------------------------------------------------------- /esp_ext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 -2013 Espressif System. 3 | * 4 | * extended gpio 5 | * - interface for other driver or kernel 6 | * - gpio control 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | */ 18 | 19 | #ifdef USE_EXT_GPIO 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "esp_ext.h" 35 | #include "esp_debug.h" 36 | #include "esp_sip.h" 37 | #include "esp_sif.h" 38 | 39 | #ifdef EXT_GPIO_OPS 40 | extern void register_ext_gpio_ops(struct esp_ext_gpio_ops *ops); 41 | extern void unregister_ext_gpio_ops(void); 42 | 43 | static struct esp_ext_gpio_ops ext_gpio_ops = { 44 | .gpio_request = ext_gpio_request, /* gpio_request gpio_no from 0x0 to 0xf */ 45 | .gpio_release = ext_gpio_release, /* gpio_release */ 46 | .gpio_set_mode = ext_gpio_set_mode, /* gpio_set_mode, data is irq_func of irq_mode , default level of output_mode */ 47 | .gpio_get_mode = ext_gpio_get_mode, /* gpio_get_mode, current mode */ 48 | .gpio_set_state = ext_gpio_set_output_state, /* only output state, high level or low level */ 49 | .gpio_get_state = ext_gpio_get_state, /* current state */ 50 | .irq_ack = ext_irq_ack, /* ack interrupt */ 51 | }; 52 | 53 | 54 | #endif 55 | 56 | static struct esp_pub *ext_epub = NULL; 57 | 58 | static u16 intr_mask_reg = 0x0000; 59 | struct workqueue_struct *ext_irq_wkq = NULL; 60 | struct work_struct ext_irq_work; 61 | static struct mutex ext_mutex_lock; 62 | 63 | static struct ext_gpio_info gpio_list[EXT_GPIO_MAX_NUM] = { 64 | {0, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 65 | {1, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 66 | {2, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 67 | {3, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 68 | {4, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 69 | {5, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 70 | {6, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 71 | {7, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 72 | {8, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 73 | {9, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 74 | {10, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 75 | {11, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 76 | {12, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 77 | {13, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 78 | {14, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 79 | {15, EXT_GPIO_MODE_DISABLE, EXT_GPIO_STATE_IDLE, NULL}, 80 | }; 81 | 82 | static struct pending_intr_list_info esp_pending_intr_list = { 83 | .start_pos = 0, 84 | .end_pos = 0, 85 | .curr_num = 0, 86 | }; 87 | 88 | u16 ext_gpio_get_int_mask_reg(void) 89 | { 90 | return intr_mask_reg; 91 | } 92 | 93 | int ext_gpio_request(int gpio_no) 94 | { 95 | if (ext_epub == NULL || ext_epub->sip == NULL || 96 | atomic_read(&ext_epub->sip->state) != SIP_RUN) { 97 | esp_dbg(ESP_DBG_ERROR, "%s esp state is not ok\n", 98 | __func__); 99 | return -ENOTRECOVERABLE; 100 | } 101 | 102 | mutex_lock(&ext_mutex_lock); 103 | 104 | if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { 105 | mutex_unlock(&ext_mutex_lock); 106 | esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); 107 | return -ERANGE; 108 | } 109 | 110 | if (gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_DISABLE) { 111 | mutex_unlock(&ext_mutex_lock); 112 | esp_dbg(ESP_DBG_ERROR, 113 | "%s gpio is already in used by other\n", __func__); 114 | return -EPERM; 115 | } else { 116 | gpio_list[gpio_no].gpio_mode = EXT_GPIO_MODE_MAX; 117 | mutex_unlock(&ext_mutex_lock); 118 | return 0; 119 | } 120 | } 121 | 122 | EXPORT_SYMBOL(ext_gpio_request); 123 | 124 | int ext_gpio_release(int gpio_no) 125 | { 126 | int ret; 127 | 128 | if (ext_epub == NULL || ext_epub->sip == NULL || 129 | atomic_read(&ext_epub->sip->state) != SIP_RUN) { 130 | esp_dbg(ESP_DBG_ERROR, "%s esp state is not ok\n", 131 | __func__); 132 | return -ENOTRECOVERABLE; 133 | } 134 | 135 | mutex_lock(&ext_mutex_lock); 136 | 137 | if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { 138 | mutex_unlock(&ext_mutex_lock); 139 | esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); 140 | return -ERANGE; 141 | } 142 | sif_lock_bus(ext_epub); 143 | ret = 144 | sif_config_gpio_mode(ext_epub, (u8) gpio_no, 145 | EXT_GPIO_MODE_DISABLE); 146 | sif_unlock_bus(ext_epub); 147 | if (ret) { 148 | esp_dbg(ESP_DBG_ERROR, "%s gpio release error\n", 149 | __func__); 150 | mutex_unlock(&ext_mutex_lock); 151 | return ret; 152 | } 153 | 154 | gpio_list[gpio_no].gpio_mode = EXT_GPIO_MODE_DISABLE; 155 | gpio_list[gpio_no].gpio_state = EXT_GPIO_STATE_IDLE; 156 | gpio_list[gpio_no].irq_handler = NULL; 157 | intr_mask_reg &= ~(1 << gpio_no); 158 | 159 | mutex_unlock(&ext_mutex_lock); 160 | 161 | return 0; 162 | } 163 | 164 | EXPORT_SYMBOL(ext_gpio_release); 165 | 166 | int ext_gpio_set_mode(int gpio_no, int mode, void *data) 167 | { 168 | u8 gpio_mode; 169 | int ret; 170 | struct ext_gpio_info backup_info; 171 | 172 | if (ext_epub == NULL || ext_epub->sip == NULL || 173 | atomic_read(&ext_epub->sip->state) != SIP_RUN) { 174 | esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__); 175 | return -ENOTRECOVERABLE; 176 | } 177 | 178 | mutex_lock(&ext_mutex_lock); 179 | 180 | if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { 181 | mutex_unlock(&ext_mutex_lock); 182 | esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); 183 | return -ERANGE; 184 | } 185 | 186 | if (gpio_list[gpio_no].gpio_mode == EXT_GPIO_MODE_DISABLE) { 187 | mutex_unlock(&ext_mutex_lock); 188 | esp_dbg(ESP_DBG_ERROR, 189 | "%s gpio is not in occupy, please request gpio\n", 190 | __func__); 191 | return -ENOTRECOVERABLE; 192 | } 193 | 194 | if (mode <= EXT_GPIO_MODE_OOB || mode >= EXT_GPIO_MODE_MAX) { 195 | mutex_unlock(&ext_mutex_lock); 196 | esp_dbg(ESP_DBG_ERROR, "%s gpio mode unknown\n", __func__); 197 | return -EOPNOTSUPP; 198 | } 199 | 200 | memcpy(&backup_info, &gpio_list[gpio_no], 201 | sizeof(struct ext_gpio_info)); 202 | 203 | gpio_list[gpio_no].gpio_mode = mode; 204 | gpio_mode = (u8) mode; 205 | 206 | switch (mode) { 207 | case EXT_GPIO_MODE_INTR_POSEDGE: 208 | case EXT_GPIO_MODE_INTR_NEGEDGE: 209 | case EXT_GPIO_MODE_INTR_LOLEVEL: 210 | case EXT_GPIO_MODE_INTR_HILEVEL: 211 | if (!data) { 212 | memcpy(&gpio_list[gpio_no], &backup_info, 213 | sizeof(struct ext_gpio_info)); 214 | esp_dbg(ESP_DBG_ERROR, "%s irq_handler is NULL\n", 215 | __func__); 216 | mutex_unlock(&ext_mutex_lock); 217 | return -EINVAL; 218 | } 219 | gpio_list[gpio_no].irq_handler = (ext_irq_handler_t) data; 220 | intr_mask_reg |= (1 << gpio_no); 221 | break; 222 | case EXT_GPIO_MODE_OUTPUT: 223 | if (!data) { 224 | memcpy(&gpio_list[gpio_no], &backup_info, 225 | sizeof(struct ext_gpio_info)); 226 | esp_dbg(ESP_DBG_ERROR, 227 | "%s output default value is NULL\n", 228 | __func__); 229 | mutex_unlock(&ext_mutex_lock); 230 | return -EINVAL; 231 | } 232 | *(int *) data = (*(int *) data == 0 ? 0 : 1); 233 | gpio_mode = (u8) (((*(int *) data) << 4) | gpio_mode); 234 | default: 235 | gpio_list[gpio_no].irq_handler = NULL; 236 | intr_mask_reg &= ~(1 << gpio_no); 237 | break; 238 | } 239 | 240 | sif_lock_bus(ext_epub); 241 | ret = sif_config_gpio_mode(ext_epub, (u8) gpio_no, gpio_mode); 242 | sif_unlock_bus(ext_epub); 243 | if (ret) { 244 | memcpy(&gpio_list[gpio_no], &backup_info, 245 | sizeof(struct ext_gpio_info)); 246 | esp_dbg(ESP_DBG_ERROR, "%s gpio set error\n", __func__); 247 | mutex_unlock(&ext_mutex_lock); 248 | return ret; 249 | } 250 | 251 | mutex_unlock(&ext_mutex_lock); 252 | return 0; 253 | } 254 | 255 | EXPORT_SYMBOL(ext_gpio_set_mode); 256 | 257 | int ext_gpio_get_mode(int gpio_no) 258 | { 259 | int gpio_mode; 260 | 261 | if (ext_epub == NULL || ext_epub->sip == NULL || 262 | atomic_read(&ext_epub->sip->state) != SIP_RUN) { 263 | esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__); 264 | return -ENOTRECOVERABLE; 265 | } 266 | 267 | mutex_lock(&ext_mutex_lock); 268 | 269 | if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { 270 | esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); 271 | mutex_unlock(&ext_mutex_lock); 272 | return -ERANGE; 273 | } 274 | 275 | gpio_mode = gpio_list[gpio_no].gpio_mode; 276 | 277 | mutex_unlock(&ext_mutex_lock); 278 | 279 | return gpio_mode; 280 | } 281 | 282 | EXPORT_SYMBOL(ext_gpio_get_mode); 283 | 284 | 285 | int ext_gpio_set_output_state(int gpio_no, int state) 286 | { 287 | int ret; 288 | 289 | if (ext_epub == NULL || ext_epub->sip == NULL || 290 | atomic_read(&ext_epub->sip->state) != SIP_RUN) { 291 | esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__); 292 | return -ENOTRECOVERABLE; 293 | } 294 | 295 | mutex_lock(&ext_mutex_lock); 296 | 297 | if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { 298 | mutex_unlock(&ext_mutex_lock); 299 | esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); 300 | return -ERANGE; 301 | } 302 | 303 | if (gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_OUTPUT) { 304 | mutex_unlock(&ext_mutex_lock); 305 | esp_dbg(ESP_DBG_ERROR, 306 | "%s gpio is not in output state, please request gpio or set output state\n", 307 | __func__); 308 | return -EOPNOTSUPP; 309 | } 310 | 311 | if (state != EXT_GPIO_STATE_LOW && state != EXT_GPIO_STATE_HIGH) { 312 | mutex_unlock(&ext_mutex_lock); 313 | esp_dbg(ESP_DBG_ERROR, "%s gpio state unknown\n", 314 | __func__); 315 | return -ENOTRECOVERABLE; 316 | } 317 | 318 | sif_lock_bus(ext_epub); 319 | ret = 320 | sif_set_gpio_output(ext_epub, 1 << gpio_no, state << gpio_no); 321 | sif_unlock_bus(ext_epub); 322 | if (ret) { 323 | esp_dbg(ESP_DBG_ERROR, "%s gpio state set error\n", 324 | __func__); 325 | mutex_unlock(&ext_mutex_lock); 326 | return ret; 327 | } 328 | gpio_list[gpio_no].gpio_state = state; 329 | 330 | mutex_unlock(&ext_mutex_lock); 331 | 332 | return 0; 333 | } 334 | 335 | EXPORT_SYMBOL(ext_gpio_set_output_state); 336 | 337 | int ext_gpio_get_state(int gpio_no) 338 | { 339 | int ret; 340 | u16 state; 341 | u16 mask; 342 | 343 | if (ext_epub == NULL || ext_epub->sip == NULL || 344 | atomic_read(&ext_epub->sip->state) != SIP_RUN) { 345 | esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__); 346 | return -ENOTRECOVERABLE; 347 | } 348 | 349 | mutex_lock(&ext_mutex_lock); 350 | 351 | if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { 352 | esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); 353 | mutex_unlock(&ext_mutex_lock); 354 | return -ERANGE; 355 | } 356 | 357 | if (gpio_list[gpio_no].gpio_mode == EXT_GPIO_MODE_OUTPUT) { 358 | state = gpio_list[gpio_no].gpio_state; 359 | } else if (gpio_list[gpio_no].gpio_mode == EXT_GPIO_MODE_INPUT) { 360 | sif_lock_bus(ext_epub); 361 | ret = sif_get_gpio_input(ext_epub, &mask, &state); 362 | sif_unlock_bus(ext_epub); 363 | if (ret) { 364 | esp_dbg(ESP_DBG_ERROR, 365 | "%s get gpio_input state error\n", 366 | __func__); 367 | mutex_unlock(&ext_mutex_lock); 368 | return ret; 369 | } 370 | } else { 371 | esp_dbg(ESP_DBG_ERROR, 372 | "%s gpio_state is not input or output\n", 373 | __func__); 374 | mutex_unlock(&ext_mutex_lock); 375 | return -EOPNOTSUPP; 376 | } 377 | mutex_unlock(&ext_mutex_lock); 378 | 379 | return (state & (1 << gpio_no)) ? 1 : 0; 380 | } 381 | 382 | EXPORT_SYMBOL(ext_gpio_get_state); 383 | 384 | int ext_irq_ack(int gpio_no) 385 | { 386 | int ret; 387 | 388 | if (ext_epub == NULL || ext_epub->sip == NULL || 389 | atomic_read(&ext_epub->sip->state) != SIP_RUN) { 390 | esp_dbg(ESP_DBG_LOG, "%s esp state is not ok\n", __func__); 391 | return -ENOTRECOVERABLE; 392 | } 393 | 394 | mutex_lock(&ext_mutex_lock); 395 | if (gpio_no >= EXT_GPIO_MAX_NUM || gpio_no < 0) { 396 | esp_dbg(ESP_DBG_ERROR, "%s unkown gpio num\n", __func__); 397 | mutex_unlock(&ext_mutex_lock); 398 | return -ERANGE; 399 | } 400 | 401 | if (gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_INTR_POSEDGE 402 | && gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_INTR_NEGEDGE 403 | && gpio_list[gpio_no].gpio_mode != EXT_GPIO_MODE_INTR_LOLEVEL 404 | && gpio_list[gpio_no].gpio_mode != 405 | EXT_GPIO_MODE_INTR_HILEVEL) { 406 | esp_dbg(ESP_DBG_ERROR, "%s gpio mode is not intr mode\n", 407 | __func__); 408 | mutex_unlock(&ext_mutex_lock); 409 | return -ENOTRECOVERABLE; 410 | } 411 | 412 | sif_lock_bus(ext_epub); 413 | ret = sif_set_gpio_output(ext_epub, 0x00, 1 << gpio_no); 414 | sif_unlock_bus(ext_epub); 415 | if (ret) { 416 | esp_dbg(ESP_DBG_ERROR, "%s gpio intr ack error\n", 417 | __func__); 418 | mutex_unlock(&ext_mutex_lock); 419 | return ret; 420 | } 421 | 422 | mutex_unlock(&ext_mutex_lock); 423 | return 0; 424 | } 425 | 426 | EXPORT_SYMBOL(ext_irq_ack); 427 | 428 | void show_status(void) 429 | { 430 | int i = 0; 431 | for (i = 0; i < MAX_PENDING_INTR_LIST; i++) 432 | esp_dbg(ESP_DBG_ERROR, "status[%d] = [0x%04x]\n", i, 433 | esp_pending_intr_list.pending_intr_list[i]); 434 | 435 | esp_dbg(ESP_DBG_ERROR, "start_pos[%d]\n", 436 | esp_pending_intr_list.start_pos); 437 | esp_dbg(ESP_DBG_ERROR, "end_pos[%d]\n", 438 | esp_pending_intr_list.end_pos); 439 | esp_dbg(ESP_DBG_ERROR, "curr_num[%d]\n", 440 | esp_pending_intr_list.curr_num); 441 | 442 | } 443 | void esp_tx_work(struct work_struct *work) 444 | { 445 | int i; 446 | u16 tmp_intr_status_reg; 447 | 448 | esp_dbg(ESP_DBG_TRACE, "%s enter\n", __func__); 449 | 450 | spin_lock(&esp_pending_intr_list.spin_lock); 451 | 452 | tmp_intr_status_reg = 453 | esp_pending_intr_list.pending_intr_list[esp_pending_intr_list. 454 | start_pos]; 455 | 456 | esp_pending_intr_list.pending_intr_list[esp_pending_intr_list. 457 | start_pos] = 0x0000; 458 | esp_pending_intr_list.start_pos = 459 | (esp_pending_intr_list.start_pos + 1) % MAX_PENDING_INTR_LIST; 460 | esp_pending_intr_list.curr_num--; 461 | 462 | spin_unlock(&esp_pending_intr_list.spin_lock); 463 | 464 | for (i = 0; i < EXT_GPIO_MAX_NUM; i++) { 465 | if (tmp_intr_status_reg & (1 << i) 466 | && (gpio_list[i].irq_handler)) 467 | gpio_list[i].irq_handler(); 468 | } 469 | 470 | spin_lock(&esp_pending_intr_list.spin_lock); 471 | if (esp_pending_intr_list.curr_num > 0) 472 | queue_work(ext_irq_wkq, &ext_irq_work); 473 | spin_unlock(&esp_pending_intr_list.spin_lock); 474 | } 475 | 476 | void ext_gpio_int_process(u16 value) 477 | { 478 | if (value == 0x00) 479 | return; 480 | 481 | esp_dbg(ESP_DBG_TRACE, "%s enter\n", __func__); 482 | 483 | /* intr cycle queue is full, wait */ 484 | while (esp_pending_intr_list.curr_num >= MAX_PENDING_INTR_LIST) { 485 | udelay(1); 486 | } 487 | 488 | spin_lock(&esp_pending_intr_list.spin_lock); 489 | 490 | esp_pending_intr_list.pending_intr_list[esp_pending_intr_list. 491 | end_pos] = value; 492 | esp_pending_intr_list.end_pos = 493 | (esp_pending_intr_list.end_pos + 1) % MAX_PENDING_INTR_LIST; 494 | esp_pending_intr_list.curr_num++; 495 | 496 | queue_work(ext_irq_wkq, &ext_irq_work); 497 | 498 | spin_unlock(&esp_pending_intr_list.spin_lock); 499 | } 500 | 501 | int ext_gpio_init(struct esp_pub *epub) 502 | { 503 | esp_dbg(ESP_DBG_ERROR, "%s enter\n", __func__); 504 | 505 | ext_irq_wkq = create_singlethread_workqueue("esp_ext_irq_wkq"); 506 | if (ext_irq_wkq == NULL) { 507 | esp_dbg(ESP_DBG_ERROR, "%s create workqueue error\n", 508 | __func__); 509 | return -EACCES; 510 | } 511 | 512 | INIT_WORK(&ext_irq_work, esp_tx_work); 513 | mutex_init(&ext_mutex_lock); 514 | 515 | ext_epub = epub; 516 | 517 | if (ext_epub == NULL) 518 | return -EINVAL; 519 | 520 | #ifdef EXT_GPIO_OPS 521 | register_ext_gpio_ops(&ext_gpio_ops); 522 | #endif 523 | 524 | return 0; 525 | } 526 | 527 | void ext_gpio_deinit(void) 528 | { 529 | esp_dbg(ESP_DBG_ERROR, "%s enter\n", __func__); 530 | 531 | #ifdef EXT_GPIO_OPS 532 | unregister_ext_gpio_ops(); 533 | #endif 534 | ext_epub = NULL; 535 | cancel_work_sync(&ext_irq_work); 536 | 537 | if (ext_irq_wkq) 538 | destroy_workqueue(ext_irq_wkq); 539 | 540 | } 541 | 542 | #endif /* USE_EXT_GPIO */ 543 | -------------------------------------------------------------------------------- /esp_ext.h: -------------------------------------------------------------------------------- 1 | #ifdef USE_EXT_GPIO 2 | 3 | #ifndef _ESP_EXT_H_ 4 | #define _ESP_EXT_H_ 5 | 6 | #include 7 | #include 8 | #include "esp_sip.h" 9 | 10 | #define MAX_PENDING_INTR_LIST 16 11 | 12 | #ifdef EXT_GPIO_OPS 13 | typedef struct esp_ext_gpio_ops { 14 | int (*gpio_request) (int gpio_no); /* gpio_request gpio_no from 0x0 to 0xf */ 15 | int (*gpio_release) (int gpio_no); /* gpio_release */ 16 | int (*gpio_set_mode) (int gpio_no, int mode, void *data); /* gpio_set_mode, data is irq_func of irq_mode , default level of output_mode */ 17 | int (*gpio_get_mode) (int gpio_no); /* gpio_get_mode, current mode */ 18 | int (*gpio_set_state) (int gpio_no, int state); /* only output state, high level or low level */ 19 | int (*gpio_get_state) (int gpio_no); /* current state */ 20 | int (*irq_ack) (int gpio_no); /* ack interrupt */ 21 | } esp_ext_gpio_ops_t; 22 | #endif 23 | 24 | typedef enum EXT_GPIO_NO { 25 | EXT_GPIO_GPIO0 = 0, 26 | EXT_GPIO_U0TXD, 27 | EXT_GPIO_GPIO2, 28 | EXT_GPIO_U0RXD, 29 | EXT_GPIO_GPIO4, 30 | EXT_GPIO_GPIO5, 31 | EXT_GPIO_SD_CLK, 32 | EXT_GPIO_SD_DATA0, 33 | EXT_GPIO_SD_DATA1, 34 | EXT_GPIO_SD_DATA2, 35 | EXT_GPIO_SD_DATA3, 36 | EXT_GPIO_SD_CMD, 37 | EXT_GPIO_MTDI, 38 | EXT_GPIO_MTCK, 39 | EXT_GPIO_MTMS, 40 | EXT_GPIO_MTDO, 41 | EXT_GPIO_MAX_NUM 42 | } EXT_GPIO_NO_T; 43 | 44 | typedef enum EXT_GPIO_MODE { //dir def pullup mode wake 45 | EXT_GPIO_MODE_OOB = 0, //output 1 0 n/a n/a 46 | EXT_GPIO_MODE_OUTPUT, //output / 0 n/a n/a 47 | EXT_GPIO_MODE_DISABLE, //input n/a 0 DIS n/a 48 | EXT_GPIO_MODE_INTR_POSEDGE, //input n/a 0 POS 1 49 | EXT_GPIO_MODE_INTR_NEGEDGE, //input n/a 1 NEG 1 50 | EXT_GPIO_MODE_INPUT, //input n/a 0 ANY 1 51 | EXT_GPIO_MODE_INTR_LOLEVEL, //input n/a 1 LOW 1 52 | EXT_GPIO_MODE_INTR_HILEVEL, //input n/a 0 HIGH 1 53 | EXT_GPIO_MODE_MAX, 54 | } EXT_GPIO_MODE_T; 55 | 56 | typedef enum EXT_GPIO_STATE { 57 | EXT_GPIO_STATE_LOW, 58 | EXT_GPIO_STATE_HIGH, 59 | EXT_GPIO_STATE_IDLE 60 | } EXT_GPIO_STATE_T; 61 | 62 | typedef irqreturn_t(*ext_irq_handler_t) (void); 63 | 64 | struct ext_gpio_info { 65 | int gpio_no; 66 | int gpio_mode; 67 | int gpio_state; 68 | ext_irq_handler_t irq_handler; 69 | }; 70 | 71 | struct pending_intr_list_info { 72 | u16 pending_intr_list[MAX_PENDING_INTR_LIST]; 73 | int start_pos; 74 | int end_pos; 75 | int curr_num; 76 | spinlock_t spin_lock; 77 | }; 78 | 79 | u16 ext_gpio_get_int_mask_reg(void); 80 | 81 | /* for extern user start */ 82 | int ext_gpio_request(int gpio_no); 83 | int ext_gpio_release(int gpio_no); 84 | 85 | int ext_gpio_set_mode(int gpio_no, int mode, void *data); 86 | int ext_gpio_get_mode(int gpio_no); 87 | 88 | int ext_gpio_set_output_state(int gpio_no, int state); 89 | int ext_gpio_get_state(int gpio_no); 90 | 91 | int ext_irq_ack(int gpio_no); 92 | /* for extern user end */ 93 | 94 | void ext_gpio_int_process(u16 value); 95 | 96 | int ext_gpio_init(struct esp_pub *epub); 97 | void ext_gpio_deinit(void); 98 | #endif /* _ESP_EXT_H_ */ 99 | 100 | #endif /* USE_EXT_GPIO */ 101 | -------------------------------------------------------------------------------- /esp_file.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 -2014 Espressif System. 3 | * 4 | * file operation in kernel space 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "esp_file.h" 28 | #include "esp_debug.h" 29 | #include "esp_sif.h" 30 | 31 | static char *modparam_init_data_conf; 32 | module_param_named(config, modparam_init_data_conf, charp, 0444); 33 | MODULE_PARM_DESC(config, "Firmware init config string (format: key=value;)"); 34 | 35 | struct esp_init_table_elem esp_init_table[MAX_ATTR_NUM] = { 36 | /* 37 | * Crystal type: 38 | * 0: 40MHz (default) 39 | * 1: 26MHz (ESP8266 ESP-12F) 40 | */ 41 | {"crystal_26M_en", 48, 0}, 42 | /* 43 | * Output crystal clock to pin: 44 | * 0: None 45 | * 1: GPIO1 46 | * 2: URXD0 47 | */ 48 | {"test_xtal", 49, 0}, 49 | /* 50 | * Host SDIO mode: 51 | * 0: Auto by pin strapping 52 | * 1: SDIO data output on negative edges (SDIO v1.1) 53 | * 2: SDIO data output on positive edges (SDIO v2.0) 54 | */ 55 | {"sdio_configure", 50, 2}, 56 | /* 57 | * WiFi/Bluetooth co-existence with BK3515A BT chip 58 | * 0: None 59 | * 1: GPIO0->WLAN_ACTIVE, MTMS->BT_ACTIVE, MTDI->BT_PRIORITY, 60 | * U0TXD->ANT_SEL_BT, U0RXD->ANT_SEL_WIFI 61 | */ 62 | {"bt_configure", 51, 0}, 63 | /* 64 | * Antenna selection: 65 | * 0: Antenna is for WiFi 66 | * 1: Antenna is for Bluetooth 67 | */ 68 | {"bt_protocol", 52, 0}, 69 | /* 70 | * Dual antenna configuration mode: 71 | * 0: None 72 | * 1: U0RXD + XPD_DCDC 73 | * 2: U0RXD + GPIO0 74 | * 3: U0RXD + U0TXD 75 | */ 76 | {"dual_ant_configure", 53, 0}, 77 | /* 78 | * Firmware debugging output pin: 79 | * 0: None 80 | * 1: UART TX on GPIO2 81 | * 2: UART TX on U0TXD 82 | */ 83 | {"test_uart_configure", 54, 2}, 84 | /* 85 | * Whether to share crystal clock with BT (in sleep mode): 86 | * 0: no 87 | * 1: always on 88 | * 2: automatically on according to XPD_DCDC 89 | */ 90 | {"share_xtal", 55, 0}, 91 | /* 92 | * Allow chip to be woken up during sleep on pin: 93 | * 0: None 94 | * 1: XPD_DCDC 95 | * 2: GPIO0 96 | * 3: Both XPD_DCDC and GPIO0 97 | */ 98 | {"gpio_wake", 56, 0}, 99 | {"no_auto_sleep", 57, 0}, 100 | {"speed_suspend", 58, 0}, 101 | {"attr11", -1, -1}, 102 | {"attr12", -1, -1}, 103 | {"attr13", -1, -1}, 104 | {"attr14", -1, -1}, 105 | {"attr15", -1, -1}, 106 | //attr that is not send to target 107 | /* 108 | * Allow chip to be reset by GPIO pin: 109 | * 0: no 110 | * 1: yes 111 | */ 112 | {"ext_rst", -1, 0}, 113 | {"wakeup_gpio", -1, 12}, 114 | {"ate_test", -1, 0}, 115 | {"attr19", -1, -1}, 116 | {"attr20", -1, -1}, 117 | {"attr21", -1, -1}, 118 | {"attr22", -1, -1}, 119 | {"attr23", -1, -1}, 120 | }; 121 | 122 | /* update init config table */ 123 | static int set_init_config_attr(const char *attr, int attr_len, short value) 124 | { 125 | int i; 126 | 127 | for (i = 0; i < MAX_ATTR_NUM; i++) { 128 | if (!memcmp(esp_init_table[i].attr, attr, attr_len)) { 129 | if (value < 0 || value > 255) { 130 | esp_dbg(ESP_DBG_ERROR, "%s: attribute value for %s is out of range", 131 | __func__, esp_init_table[i].attr); 132 | return -1; 133 | } 134 | esp_init_table[i].value = value; 135 | return 0; 136 | } 137 | } 138 | 139 | return -1; 140 | } 141 | 142 | static int update_init_config_attr(const char *attr, int attr_len, 143 | const char *val, int val_len) 144 | { 145 | char digits[4]; 146 | short value; 147 | int i; 148 | 149 | for (i = 0; i < sizeof(digits) - 1 && i < val_len; i++) 150 | digits[i] = val[i]; 151 | digits[i] = 0; 152 | 153 | if (kstrtou16(digits, 10, &value) < 0) { 154 | esp_dbg(ESP_DBG_ERROR, "%s: invalid attribute value: %s", 155 | __func__, digits); 156 | return -1; 157 | } 158 | 159 | return set_init_config_attr(attr, attr_len, value); 160 | } 161 | 162 | /* export config table settings to SDIO driver */ 163 | static void record_init_config(void) 164 | { 165 | int i; 166 | 167 | for (i = 0; i < MAX_ATTR_NUM; i++) { 168 | if (esp_init_table[i].value < 0) 169 | continue; 170 | 171 | if (!strcmp(esp_init_table[i].attr, "share_xtal")) 172 | sif_record_bt_config(esp_init_table[i].value); 173 | else if (!strcmp(esp_init_table[i].attr, "ext_rst")) 174 | sif_record_rst_config(esp_init_table[i].value); 175 | else if (!strcmp(esp_init_table[i].attr, "wakeup_gpio")) 176 | sif_record_wakeup_gpio_config(esp_init_table[i].value); 177 | else if (!strcmp(esp_init_table[i].attr, "ate_test")) 178 | sif_record_ate_config(esp_init_table[i].value); 179 | } 180 | } 181 | 182 | int request_init_conf(struct device *dev) 183 | { 184 | char *attr, *str, *p; 185 | int attr_len, str_len; 186 | int ret = 0; 187 | u32 val; 188 | 189 | /* Check for any parameters passed through devicetree (or acpi) */ 190 | if (device_property_read_u32(dev, "esp,crystal-26M-en", &val) == 0) 191 | set_init_config_attr("crystal_26M_en", strlen("crystal_26M_en"), 192 | val); 193 | 194 | /* parse optional parameter in the form of key1=value,key2=value,.. */ 195 | attr = NULL; 196 | attr_len = str_len = 0; 197 | for (p = str = modparam_init_data_conf; p && *p; p++) { 198 | if (*p == '=') { 199 | attr = str; 200 | attr_len = str_len; 201 | 202 | str = p + 1; 203 | str_len = 0; 204 | } else if (*p == ',' || *p == ';') { 205 | if (attr_len) 206 | ret |= update_init_config_attr(attr, attr_len, 207 | str, str_len); 208 | 209 | str = p + 1; 210 | attr_len = str_len = 0; 211 | } else 212 | str_len++; 213 | } 214 | 215 | if (attr_len && str != attr) 216 | ret |= update_init_config_attr(attr, attr_len, str, str_len); 217 | 218 | record_init_config(); 219 | 220 | return ret; 221 | } 222 | 223 | void fix_init_data(u8 * init_data_buf, int buf_size) 224 | { 225 | int i; 226 | 227 | for (i = 0; i < MAX_FIX_ATTR_NUM; i++) { 228 | if (esp_init_table[i].offset > -1 229 | && esp_init_table[i].offset < buf_size 230 | && esp_init_table[i].value > -1) { 231 | *(u8 *) (init_data_buf + 232 | esp_init_table[i].offset) = 233 | esp_init_table[i].value; 234 | } else if (esp_init_table[i].offset > buf_size) { 235 | esp_dbg(ESP_DBG_ERROR, 236 | "%s: offset[%d] longer than init_data_buf len[%d] Ignore\n", 237 | __FUNCTION__, esp_init_table[i].offset, 238 | buf_size); 239 | } 240 | } 241 | 242 | } 243 | -------------------------------------------------------------------------------- /esp_file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 -2014 Espressif System. 3 | * 4 | * file operation in kernel space 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | */ 16 | 17 | #ifndef _ESP_FILE_H_ 18 | #define _ESP_FILE_H_ 19 | 20 | #include 21 | #include 22 | 23 | #define E_ROUND_UP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) 24 | 25 | #define CONF_ATTR_LEN 24 26 | #define CONF_VAL_LEN 3 27 | #define MAX_ATTR_NUM 24 28 | #define MAX_FIX_ATTR_NUM 16 29 | #define MAX_BUF_LEN ((CONF_ATTR_LEN + CONF_VAL_LEN + 2) * MAX_ATTR_NUM + 2) 30 | 31 | struct esp_init_table_elem { 32 | char attr[CONF_ATTR_LEN]; 33 | int offset; 34 | short value; 35 | }; 36 | 37 | int request_init_conf(struct device *dev); 38 | void fix_init_data(u8 * init_data_buf, int buf_size); 39 | 40 | #endif /* _ESP_FILE_H_ */ 41 | -------------------------------------------------------------------------------- /esp_init_data.h: -------------------------------------------------------------------------------- 1 | static char esp_init_data[] = 2 | { 0x5, 0x0, 4, 2, 5, 5, 5, 2, 5, 0, 4, 5, 5, 4, 5, 5, 4, -2, -3, -1, 3 | -16, -16, -16, -32, -32, -32, 204, 1, 0xff, 0xff, 0, 0, 0, 0, 82, 78, 74, 68, 64, 56, 0, 4 | 0, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 10, 0x0, 0x0, 5 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 | 0 }; 8 | -------------------------------------------------------------------------------- /esp_io.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 - 2014 Espressif System. 3 | * IO interface 4 | * - sdio/spi common i/f driver 5 | * - target sdio hal 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | */ 17 | 18 | #include 19 | #include "esp_sif.h" 20 | #include "slc_host_register.h" 21 | #include "esp_debug.h" 22 | 23 | #ifdef SIF_DEBUG_DSR_DUMP_REG 24 | static void dump_slc_regs(struct slc_host_regs *regs); 25 | #endif /* SIF_DEBUG_DSR_DUMP_REG */ 26 | 27 | int esp_common_read(struct esp_pub *epub, u8 * buf, u32 len, int sync, 28 | bool noround) 29 | { 30 | if (sync) { 31 | return sif_lldesc_read_sync(epub, buf, len); 32 | } else { 33 | return sif_lldesc_read_raw(epub, buf, len, noround); 34 | } 35 | } 36 | 37 | 38 | int esp_common_write(struct esp_pub *epub, u8 * buf, u32 len, int sync) 39 | { 40 | if (sync) { 41 | return sif_lldesc_write_sync(epub, buf, len); 42 | } else { 43 | return sif_lldesc_write_raw(epub, buf, len); 44 | } 45 | } 46 | 47 | 48 | int esp_common_read_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, 49 | u32 len, int sync) 50 | { 51 | if (sync) { 52 | return sif_io_sync(epub, addr, buf, len, 53 | SIF_FROM_DEVICE | SIF_SYNC | 54 | SIF_BYTE_BASIS | SIF_INC_ADDR); 55 | } else { 56 | return sif_io_raw(epub, addr, buf, len, 57 | SIF_FROM_DEVICE | SIF_BYTE_BASIS | 58 | SIF_INC_ADDR); 59 | } 60 | 61 | } 62 | 63 | 64 | int esp_common_write_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, 65 | u32 len, int sync) 66 | { 67 | if (sync) { 68 | return sif_io_sync(epub, addr, buf, len, 69 | SIF_TO_DEVICE | SIF_SYNC | 70 | SIF_BYTE_BASIS | SIF_INC_ADDR); 71 | } else { 72 | return sif_io_raw(epub, addr, buf, len, 73 | SIF_TO_DEVICE | SIF_BYTE_BASIS | 74 | SIF_INC_ADDR); 75 | } 76 | } 77 | 78 | int esp_common_readbyte_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, 79 | int sync) 80 | { 81 | if (sync) { 82 | int res; 83 | sif_lock_bus(epub); 84 | *buf = sdio_io_readb(epub, addr, &res); 85 | sif_unlock_bus(epub); 86 | return res; 87 | } else { 88 | int res; 89 | *buf = sdio_io_readb(epub, addr, &res); 90 | return res; 91 | } 92 | 93 | } 94 | 95 | 96 | 97 | int esp_common_writebyte_with_addr(struct esp_pub *epub, u32 addr, u8 buf, 98 | int sync) 99 | { 100 | if (sync) { 101 | int res; 102 | sif_lock_bus(epub); 103 | sdio_io_writeb(epub, buf, addr, &res); 104 | sif_unlock_bus(epub); 105 | return res; 106 | } else { 107 | int res; 108 | sdio_io_writeb(epub, buf, addr, &res); 109 | return res; 110 | } 111 | } 112 | 113 | int sif_read_reg_window(struct esp_pub *epub, unsigned int reg_addr, 114 | u8 * value) 115 | { 116 | u8 *p_tbuf = NULL; 117 | int ret = 0; 118 | int retry = 20; 119 | 120 | reg_addr >>= 2; 121 | if (reg_addr > 0x1f) 122 | return -1; 123 | 124 | p_tbuf = kzalloc(4, GFP_KERNEL); 125 | if (p_tbuf == NULL) 126 | return -ENOMEM; 127 | 128 | p_tbuf[0] = 0x80 | (reg_addr & 0x1f); 129 | 130 | ret = 131 | esp_common_write_with_addr(epub, SLC_HOST_WIN_CMD, p_tbuf, 1, 132 | ESP_SIF_NOSYNC); 133 | 134 | if (ret == 0) { 135 | do { 136 | if (retry < 20) 137 | mdelay(10); 138 | retry--; 139 | ret = 140 | esp_common_read_with_addr(epub, 141 | SLC_HOST_STATE_W0, 142 | p_tbuf, 4, 143 | ESP_SIF_NOSYNC); 144 | } while (retry > 0 && ret != 0); 145 | } 146 | 147 | if (ret == 0) 148 | memcpy(value, p_tbuf, 4); 149 | 150 | kfree(p_tbuf); 151 | return ret; 152 | } 153 | 154 | int sif_write_reg_window(struct esp_pub *epub, unsigned int reg_addr, 155 | u8 * value) 156 | { 157 | u8 *p_tbuf = NULL; 158 | int ret = 0; 159 | 160 | reg_addr >>= 2; 161 | if (reg_addr > 0x1f) 162 | return -1; 163 | 164 | p_tbuf = kzalloc(8, GFP_KERNEL); 165 | if (p_tbuf == NULL) 166 | return -ENOMEM; 167 | memcpy(p_tbuf, value, 4); 168 | p_tbuf[4] = 0xc0 | (reg_addr & 0x1f); 169 | 170 | ret = 171 | esp_common_write_with_addr(epub, SLC_HOST_CONF_W5, p_tbuf, 5, 172 | ESP_SIF_NOSYNC); 173 | 174 | kfree(p_tbuf); 175 | return ret; 176 | } 177 | 178 | int sif_ack_target_read_err(struct esp_pub *epub) 179 | { 180 | u32 value[1]; 181 | int ret; 182 | 183 | ret = sif_read_reg_window(epub, SLC_RX_LINK, (u8 *) value); 184 | if (ret) 185 | return ret; 186 | value[0] |= SLC_RXLINK_START; 187 | ret = sif_write_reg_window(epub, SLC_RX_LINK, (u8 *) value); 188 | return ret; 189 | } 190 | 191 | int sif_had_io_enable(struct esp_pub *epub) 192 | { 193 | u32 *p_tbuf = NULL; 194 | int ret; 195 | 196 | p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL); 197 | if (p_tbuf == NULL) 198 | return -ENOMEM; 199 | 200 | *p_tbuf = 201 | SLC_TXEOF_ENA | (0x4 << SLC_FIFO_MAP_ENA_S) | SLC_TX_DUMMY_MODE 202 | | SLC_HDA_MAP_128K | (0xFE << SLC_TX_PUSH_IDLE_NUM_S); 203 | ret = sif_write_reg_window(epub, SLC_BRIDGE_CONF, (u8 *) p_tbuf); 204 | 205 | if (ret) 206 | goto _err; 207 | 208 | *p_tbuf = 0x30; 209 | ret = 210 | esp_common_write_with_addr((epub), SLC_HOST_CONF_W4 + 1, 211 | (u8 *) p_tbuf, 1, ESP_SIF_NOSYNC); 212 | 213 | if (ret) 214 | goto _err; 215 | //set w3 0 216 | *p_tbuf = 0x1; 217 | ret = 218 | esp_common_write_with_addr((epub), SLC_HOST_CONF_W3, 219 | (u8 *) p_tbuf, 1, ESP_SIF_NOSYNC); 220 | 221 | _err: 222 | kfree(p_tbuf); 223 | return ret; 224 | } 225 | 226 | typedef enum _SDIO_INTR_MODE { 227 | SDIO_INTR_IB = 0, 228 | SDIO_INTR_OOB_TOGGLE, 229 | SDIO_INTR_OOB_HIGH_LEVEL, 230 | SDIO_INTR_OOB_LOW_LEVEL, 231 | } SDIO_INTR_MODE; 232 | 233 | #define GEN_GPIO_SEL(_gpio_num, _sel_func, _intr_mode, _offset) (((_offset)<< 9 ) |((_intr_mode) << 7)|((_sel_func) << 4)|(_gpio_num)) 234 | //bit[3:0] = gpio num, 2 235 | //bit[6:4] = gpio sel func, 0 236 | //bit[8:7] = gpio intr mode, SDIO_INTR_OOB_TOGGLE 237 | //bit[15:9] = register offset, 0x38 238 | 239 | u16 gpio_sel_sets[17] = { 240 | GEN_GPIO_SEL(0, 0, SDIO_INTR_OOB_TOGGLE, 0x34), //GPIO0 241 | GEN_GPIO_SEL(1, 3, SDIO_INTR_OOB_TOGGLE, 0x18), //U0TXD 242 | GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_TOGGLE, 0x38), //GPIO2 243 | GEN_GPIO_SEL(3, 3, SDIO_INTR_OOB_TOGGLE, 0x14), //U0RXD 244 | GEN_GPIO_SEL(4, 0, SDIO_INTR_OOB_TOGGLE, 0x3C), //GPIO4 245 | GEN_GPIO_SEL(5, 0, SDIO_INTR_OOB_TOGGLE, 0x40), //GPIO5 246 | GEN_GPIO_SEL(6, 3, SDIO_INTR_OOB_TOGGLE, 0x1C), //SD_CLK 247 | GEN_GPIO_SEL(7, 3, SDIO_INTR_OOB_TOGGLE, 0x20), //SD_DATA0 248 | GEN_GPIO_SEL(8, 3, SDIO_INTR_OOB_TOGGLE, 0x24), //SD_DATA1 249 | GEN_GPIO_SEL(9, 3, SDIO_INTR_OOB_TOGGLE, 0x28), //SD_DATA2 250 | GEN_GPIO_SEL(10, 3, SDIO_INTR_OOB_TOGGLE, 0x2C), //SD_DATA3 251 | GEN_GPIO_SEL(11, 3, SDIO_INTR_OOB_TOGGLE, 0x30), //SD_CMD 252 | GEN_GPIO_SEL(12, 3, SDIO_INTR_OOB_TOGGLE, 0x04), //MTDI 253 | GEN_GPIO_SEL(13, 3, SDIO_INTR_OOB_TOGGLE, 0x08), //MTCK 254 | GEN_GPIO_SEL(14, 3, SDIO_INTR_OOB_TOGGLE, 0x0C), //MTMS 255 | GEN_GPIO_SEL(15, 3, SDIO_INTR_OOB_TOGGLE, 0x10), //MTDO 256 | //pls do not change sel before, if you want to change intr mode,change the one blow 257 | //GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_TOGGLE, 0x38) 258 | GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_LOW_LEVEL, 0x38) 259 | }; 260 | 261 | #if defined(USE_EXT_GPIO) 262 | u16 gpio_forbidden = 0; 263 | #endif 264 | 265 | int sif_interrupt_target(struct esp_pub *epub, u8 index) 266 | { 267 | u8 low_byte = BIT(index); 268 | return esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W4 + 2, 269 | low_byte, ESP_SIF_NOSYNC); 270 | 271 | } 272 | 273 | #ifdef USE_EXT_GPIO 274 | int sif_config_gpio_mode(struct esp_pub *epub, u8 gpio_num, u8 gpio_mode) 275 | { 276 | u32 *p_tbuf = NULL; 277 | int err; 278 | 279 | if ((BIT(gpio_num) & gpio_forbidden) || gpio_num > 15) 280 | return -EINVAL; 281 | 282 | p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL); 283 | if (p_tbuf == NULL) 284 | return -ENOMEM; 285 | *p_tbuf = (gpio_mode << 16) | gpio_sel_sets[gpio_num]; 286 | err = 287 | esp_common_write_with_addr(epub, SLC_HOST_CONF_W1, 288 | (u8 *) p_tbuf, sizeof(u32), 289 | ESP_SIF_NOSYNC); 290 | kfree(p_tbuf); 291 | if (err) 292 | return err; 293 | 294 | return sif_interrupt_target(epub, 4); 295 | } 296 | 297 | int sif_set_gpio_output(struct esp_pub *epub, u16 mask, u16 value) 298 | { 299 | u32 *p_tbuf = NULL; 300 | int err; 301 | 302 | mask &= ~gpio_forbidden; 303 | p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL); 304 | if (p_tbuf == NULL) 305 | return -ENOMEM; 306 | *p_tbuf = (mask << 16) | value; 307 | err = 308 | esp_common_write_with_addr(epub, SLC_HOST_CONF_W2, 309 | (u8 *) p_tbuf, sizeof(u32), 310 | ESP_SIF_NOSYNC); 311 | kfree(p_tbuf); 312 | if (err) 313 | return err; 314 | 315 | return sif_interrupt_target(epub, 5); 316 | } 317 | 318 | int sif_get_gpio_intr(struct esp_pub *epub, u16 intr_mask, u16 * value) 319 | { 320 | u32 *p_tbuf = NULL; 321 | int err; 322 | 323 | p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL); 324 | if (p_tbuf == NULL) 325 | return -ENOMEM; 326 | *p_tbuf = 0; 327 | err = 328 | esp_common_read_with_addr(epub, SLC_HOST_CONF_W3, 329 | (u8 *) p_tbuf, sizeof(u32), 330 | ESP_SIF_NOSYNC); 331 | if (err) { 332 | kfree(p_tbuf); 333 | return err; 334 | } 335 | 336 | *value = *p_tbuf & intr_mask; 337 | kfree(p_tbuf); 338 | if (*value == 0) 339 | return 0; 340 | return sif_interrupt_target(epub, 6); 341 | } 342 | 343 | int sif_get_gpio_input(struct esp_pub *epub, u16 * mask, u16 * value) 344 | { 345 | u32 *p_tbuf = NULL; 346 | int err; 347 | 348 | err = sif_interrupt_target(epub, 3); 349 | if (err) 350 | return err; 351 | 352 | udelay(20); 353 | p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL); 354 | if (p_tbuf == NULL) 355 | return -ENOMEM; 356 | *p_tbuf = 0; 357 | err = 358 | esp_common_read_with_addr(epub, SLC_HOST_CONF_W3, 359 | (u8 *) p_tbuf, sizeof(u32), 360 | ESP_SIF_NOSYNC); 361 | if (err) { 362 | kfree(p_tbuf); 363 | return err; 364 | } 365 | 366 | *mask = *p_tbuf >> 16; 367 | *value = *p_tbuf & *mask; 368 | kfree(p_tbuf); 369 | 370 | return 0; 371 | } 372 | #endif 373 | 374 | void check_target_id(struct esp_pub *epub) 375 | { 376 | u32 date; 377 | int err = 0; 378 | int i; 379 | 380 | EPUB_CTRL_CHECK(epub, _err); 381 | 382 | sif_lock_bus(epub); 383 | 384 | for (i = 0; i < 4; i++) { 385 | err = 386 | esp_common_readbyte_with_addr(epub, SLC_HOST_DATE + i, 387 | (u8 *) & date + i, 388 | ESP_SIF_NOSYNC); 389 | err = 390 | esp_common_readbyte_with_addr(epub, SLC_HOST_ID + i, 391 | (u8 *) & 392 | EPUB_TO_CTRL(epub)-> 393 | target_id + i, 394 | ESP_SIF_NOSYNC); 395 | } 396 | 397 | sif_unlock_bus(epub); 398 | 399 | esp_dbg(ESP_DBG_LOG, "\n\n \t\t SLC data 0x%08x, ID 0x%08x\n\n", 400 | date, EPUB_TO_CTRL(epub)->target_id); 401 | 402 | switch (EPUB_TO_CTRL(epub)->target_id) { 403 | case 0x100: 404 | EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000; 405 | break; 406 | case 0x600: 407 | EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000 - 0x800; 408 | 409 | do { 410 | u16 gpio_sel; 411 | u8 low_byte = 0; 412 | u8 high_byte = 0; 413 | u8 byte2 = 0; 414 | u8 byte3 = 0; 415 | #ifdef USE_OOB_INTR 416 | gpio_sel = gpio_sel_sets[16]; 417 | low_byte = gpio_sel; 418 | high_byte = gpio_sel >> 8; 419 | #ifdef USE_EXT_GPIO 420 | gpio_forbidden |= BIT(gpio_sel & 0xf); 421 | #endif /* USE_EXT_GPIO */ 422 | #endif /* USE_OOB_INTR */ 423 | 424 | if (sif_get_bt_config() == 1 425 | && sif_get_rst_config() != 1) { 426 | u8 gpio_num = sif_get_wakeup_gpio_config(); 427 | gpio_sel = gpio_sel_sets[gpio_num]; 428 | byte2 = gpio_sel; 429 | byte3 = gpio_sel >> 8; 430 | #ifdef USE_EXT_GPIO 431 | gpio_forbidden |= BIT(gpio_num); 432 | #endif 433 | } 434 | sif_lock_bus(epub); 435 | err = 436 | esp_common_writebyte_with_addr(epub, 437 | SLC_HOST_CONF_W1, 438 | low_byte, 439 | ESP_SIF_NOSYNC); 440 | err = 441 | esp_common_writebyte_with_addr(epub, 442 | SLC_HOST_CONF_W1 443 | + 1, high_byte, 444 | ESP_SIF_NOSYNC); 445 | err = 446 | esp_common_writebyte_with_addr(epub, 447 | SLC_HOST_CONF_W1 448 | + 2, byte2, 449 | ESP_SIF_NOSYNC); 450 | err = 451 | esp_common_writebyte_with_addr(epub, 452 | SLC_HOST_CONF_W1 453 | + 3, byte3, 454 | ESP_SIF_NOSYNC); 455 | sif_unlock_bus(epub); 456 | } while (0); 457 | break; 458 | default: 459 | EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000; 460 | break; 461 | } 462 | _err: 463 | return; 464 | } 465 | 466 | u32 sif_get_blksz(struct esp_pub * epub) 467 | { 468 | EPUB_CTRL_CHECK(epub, _err); 469 | 470 | return EPUB_TO_CTRL(epub)->slc_blk_sz; 471 | _err: 472 | return 512; 473 | } 474 | 475 | u32 sif_get_target_id(struct esp_pub * epub) 476 | { 477 | EPUB_CTRL_CHECK(epub, _err); 478 | 479 | return EPUB_TO_CTRL(epub)->target_id; 480 | _err: 481 | return 0x600; 482 | } 483 | 484 | void sif_dsr(struct sdio_func *func) 485 | { 486 | struct esp_sdio_ctrl *sctrl = sdio_get_drvdata(func); 487 | static int dsr_cnt = 0, real_intr_cnt = 0, bogus_intr_cnt = 0; 488 | struct slc_host_regs *regs = &(sctrl->slc_regs); 489 | esp_dbg(ESP_DBG_TRACE, " %s enter %d \n", __func__, dsr_cnt++); 490 | 491 | sdio_release_host(sctrl->func); 492 | 493 | 494 | sif_lock_bus(sctrl->epub); 495 | 496 | 497 | do { 498 | int ret = 0; 499 | 500 | memset(regs, 0x0, sizeof(struct slc_host_regs)); 501 | 502 | ret = 503 | esp_common_read_with_addr(sctrl->epub, 504 | REG_SLC_HOST_BASE + 8, 505 | (u8 *) regs, 506 | sizeof(struct slc_host_regs), 507 | ESP_SIF_NOSYNC); 508 | 509 | if ((regs->intr_raw & SLC_HOST_RX_ST) && (ret == 0)) { 510 | esp_dbg(ESP_DBG_TRACE, "%s eal intr cnt: %d", 511 | __func__, ++real_intr_cnt); 512 | 513 | esp_dsr(sctrl->epub); 514 | 515 | } else { 516 | sif_unlock_bus(sctrl->epub); 517 | 518 | esp_dbg(ESP_DBG_TRACE, "%s bogus_intr_cnt %d\n", 519 | __func__, ++bogus_intr_cnt); 520 | } 521 | 522 | #ifdef SIF_DEBUG_DSR_DUMP_REG 523 | dump_slc_regs(regs); 524 | #endif /* SIF_DEBUG_DUMP_DSR */ 525 | 526 | } while (0); 527 | 528 | sdio_claim_host(func); 529 | 530 | atomic_set(&sctrl->irq_handling, 0); 531 | } 532 | 533 | 534 | struct slc_host_regs *sif_get_regs(struct esp_pub *epub) 535 | { 536 | EPUB_CTRL_CHECK(epub, _err); 537 | 538 | return &EPUB_TO_CTRL(epub)->slc_regs; 539 | _err: 540 | return NULL; 541 | } 542 | 543 | void sif_disable_target_interrupt(struct esp_pub *epub) 544 | { 545 | EPUB_FUNC_CHECK(epub, _exit); 546 | sif_lock_bus(epub); 547 | #ifdef HOST_RESET_BUG 548 | mdelay(10); 549 | #endif 550 | memset(EPUB_TO_CTRL(epub)->dma_buffer, 0x00, sizeof(u32)); 551 | esp_common_write_with_addr(epub, SLC_HOST_INT_ENA, 552 | EPUB_TO_CTRL(epub)->dma_buffer, 553 | sizeof(u32), ESP_SIF_NOSYNC); 554 | #ifdef HOST_RESET_BUG 555 | mdelay(10); 556 | #endif 557 | 558 | sif_unlock_bus(epub); 559 | 560 | mdelay(1); 561 | 562 | sif_lock_bus(epub); 563 | sif_interrupt_target(epub, 7); 564 | sif_unlock_bus(epub); 565 | _exit: 566 | return; 567 | } 568 | 569 | #ifdef SIF_DEBUG_DSR_DUMP_REG 570 | static void dump_slc_regs(struct slc_host_regs *regs) 571 | { 572 | esp_dbg(ESP_DBG_TRACE, "\n\n ------- %s --------------\n", 573 | __func__); 574 | 575 | esp_dbg(ESP_DBG_TRACE, " \ 576 | intr_raw 0x%08X \t \n \ 577 | state_w0 0x%08X \t state_w1 0x%08X \n \ 578 | config_w0 0x%08X \t config_w1 0x%08X \n \ 579 | intr_status 0x%08X \t config_w2 0x%08X \n \ 580 | config_w3 0x%08X \t config_w4 0x%08X \n \ 581 | token_wdata 0x%08X \t intr_clear 0x%08X \n \ 582 | intr_enable 0x%08X \n\n", regs->intr_raw, regs->state_w0, regs->state_w1, regs->config_w0, regs->config_w1, regs->intr_status, regs->config_w2, regs->config_w3, regs->config_w4, regs->token_wdata, regs->intr_clear, regs->intr_enable); 583 | } 584 | #endif /* SIF_DEBUG_DSR_DUMP_REG */ 585 | 586 | static int bt_config = 0; 587 | void sif_record_bt_config(int value) 588 | { 589 | bt_config = value; 590 | } 591 | 592 | int sif_get_bt_config(void) 593 | { 594 | return bt_config; 595 | } 596 | 597 | static int rst_config = 0; 598 | void sif_record_rst_config(int value) 599 | { 600 | rst_config = value; 601 | } 602 | 603 | int sif_get_rst_config(void) 604 | { 605 | return rst_config; 606 | } 607 | 608 | static int ate_test = 0; 609 | void sif_record_ate_config(int value) 610 | { 611 | ate_test = value; 612 | } 613 | 614 | int sif_get_ate_config(void) 615 | { 616 | return ate_test; 617 | } 618 | 619 | static int retry_reset = 0; 620 | void sif_record_retry_config(void) 621 | { 622 | retry_reset = 1; 623 | } 624 | 625 | int sif_get_retry_config(void) 626 | { 627 | return retry_reset; 628 | } 629 | 630 | static int wakeup_gpio = 12; 631 | void sif_record_wakeup_gpio_config(int value) 632 | { 633 | wakeup_gpio = value; 634 | } 635 | 636 | int sif_get_wakeup_gpio_config(void) 637 | { 638 | return wakeup_gpio; 639 | } 640 | -------------------------------------------------------------------------------- /esp_mac80211.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2014 Espressif System. 3 | * 4 | * MAC80211 support module 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | */ 16 | #ifndef _ESP_MAC80211_H_ 17 | #define _ESP_MAC80211_H_ 18 | 19 | struct esp_80211_wmm_ac_param { 20 | u8 aci_aifsn; /* AIFSN, ACM, ACI */ 21 | u8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */ 22 | u16 txop_limit; 23 | }; 24 | 25 | struct esp_80211_wmm_param_element { 26 | /* Element ID: 221 (0xdd); length: 24 */ 27 | /* required fields for WMM version 1 */ 28 | u8 oui[3]; /* 00:50:f2 */ 29 | u8 oui_type; /* 2 */ 30 | u8 oui_subtype; /* 1 */ 31 | u8 version; /* 1 for WMM version 1.0 */ 32 | u8 qos_info; /* AP/STA specif QoS info */ 33 | u8 reserved; /* 0 */ 34 | struct esp_80211_wmm_ac_param ac[4]; /* AC_BE, AC_BK, AC_VI, AC_VO */ 35 | }; 36 | 37 | 38 | #endif /* _ESP_MAC80211_H_ */ 39 | -------------------------------------------------------------------------------- /esp_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 - 2014 Espressif System. 3 | * 4 | * main routine 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "esp_pub.h" 29 | #include "esp_sip.h" 30 | #include "esp_sif.h" 31 | #include "esp_debug.h" 32 | #include "esp_file.h" 33 | #include "esp_wl.h" 34 | 35 | struct completion *gl_bootup_cplx = NULL; 36 | 37 | #ifndef FPGA_DEBUG 38 | static int esp_download_fw(struct esp_pub *epub); 39 | #endif /* !FGPA_DEBUG */ 40 | 41 | static int modparam_no_txampdu = 0; 42 | static int modparam_no_rxampdu = 0; 43 | module_param_named(no_txampdu, modparam_no_txampdu, int, 0444); 44 | MODULE_PARM_DESC(no_txampdu, "Disable tx ampdu."); 45 | module_param_named(no_rxampdu, modparam_no_rxampdu, int, 0444); 46 | MODULE_PARM_DESC(no_rxampdu, "Disable rx ampdu."); 47 | 48 | static char *modparam_eagle_path = "/lib/firmware"; 49 | module_param_named(eagle_path, modparam_eagle_path, charp, 0444); 50 | MODULE_PARM_DESC(eagle_path, "eagle path"); 51 | 52 | bool mod_support_no_txampdu() 53 | { 54 | return modparam_no_txampdu; 55 | } 56 | 57 | bool mod_support_no_rxampdu() 58 | { 59 | return modparam_no_rxampdu; 60 | } 61 | 62 | void mod_support_no_txampdu_set(bool value) 63 | { 64 | modparam_no_txampdu = value; 65 | } 66 | 67 | char *mod_eagle_path_get(void) 68 | { 69 | if (modparam_eagle_path[0] == '\0') 70 | return NULL; 71 | 72 | return modparam_eagle_path; 73 | } 74 | 75 | int esp_pub_init_all(struct esp_pub *epub) 76 | { 77 | int ret = 0; 78 | 79 | /* completion for bootup event poll */ 80 | DECLARE_COMPLETION_ONSTACK(complete); 81 | atomic_set(&epub->ps.state, ESP_PM_OFF); 82 | if (epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) { 83 | epub->sip = sip_attach(epub); 84 | if (epub->sip == NULL) { 85 | printk(KERN_ERR "%s sip alloc failed\n", __func__); 86 | return -ENOMEM; 87 | } 88 | 89 | esp_dump_var("esp_msg_level", NULL, &esp_msg_level, 90 | ESP_U32); 91 | 92 | #ifdef ESP_ANDROID_LOGGER 93 | esp_dump_var("log_off", NULL, &log_off, ESP_U32); 94 | #endif /* ESP_ANDROID_LOGGER */ 95 | } else { 96 | atomic_set(&epub->sip->state, SIP_PREPARE_BOOT); 97 | atomic_set(&epub->sip->tx_credits, 0); 98 | } 99 | 100 | epub->sip->to_host_seq = 0; 101 | 102 | #ifdef TEST_MODE 103 | if (sif_get_ate_config() != 0 && sif_get_ate_config() != 1 104 | && sif_get_ate_config() != 6) { 105 | esp_test_init(epub); 106 | return -1; 107 | } 108 | #endif 109 | 110 | #ifndef FPGA_DEBUG 111 | ret = esp_download_fw(epub); 112 | #ifdef TEST_MODE 113 | if (sif_get_ate_config() == 6) { 114 | sif_enable_irq(epub); 115 | mdelay(500); 116 | sif_disable_irq(epub); 117 | mdelay(1000); 118 | esp_test_init(epub); 119 | return -1; 120 | } 121 | #endif 122 | if (ret) { 123 | esp_dbg(ESP_DBG_ERROR, "download firmware failed\n"); 124 | return ret; 125 | } 126 | 127 | esp_dbg(ESP_DBG_TRACE, "download firmware OK \n"); 128 | #else 129 | sip_send_bootup(epub->sip); 130 | #endif /* FPGA_DEBUG */ 131 | 132 | gl_bootup_cplx = &complete; 133 | epub->wait_reset = 0; 134 | sif_enable_irq(epub); 135 | 136 | if (epub->sdio_state == ESP_SDIO_STATE_SECOND_INIT 137 | || sif_get_ate_config() == 1) { 138 | ret = sip_poll_bootup_event(epub->sip); 139 | } else { 140 | ret = sip_poll_resetting_event(epub->sip); 141 | if (ret == 0) { 142 | sif_lock_bus(epub); 143 | sif_interrupt_target(epub, 7); 144 | sif_unlock_bus(epub); 145 | } 146 | 147 | } 148 | 149 | gl_bootup_cplx = NULL; 150 | 151 | if (sif_get_ate_config() == 1) 152 | ret = -EOPNOTSUPP; 153 | 154 | return ret; 155 | } 156 | 157 | void esp_dsr(struct esp_pub *epub) 158 | { 159 | sip_rx(epub); 160 | } 161 | 162 | 163 | struct esp_fw_hdr { 164 | u8 magic; 165 | u8 blocks; 166 | u8 pad[2]; 167 | u32 entry_addr; 168 | } __packed; 169 | 170 | struct esp_fw_blk_hdr { 171 | u32 load_addr; 172 | u32 data_len; 173 | } __packed; 174 | 175 | #define ESP_FW_NAME1 "eagle_fw_ate_config_v19.bin" 176 | #define ESP_FW_NAME2 "eagle_fw_first_init_v19.bin" 177 | #define ESP_FW_NAME3 "eagle_fw_second_init_v19.bin" 178 | 179 | #ifndef FPGA_DEBUG 180 | static int esp_download_fw(struct esp_pub *epub) 181 | { 182 | const struct firmware *fw_entry; 183 | u8 *fw_buf = NULL; 184 | u32 offset = 0; 185 | int ret = 0; 186 | u8 blocks; 187 | struct esp_fw_hdr *fhdr; 188 | struct esp_fw_blk_hdr *bhdr = NULL; 189 | struct sip_cmd_bootup bootcmd; 190 | char *esp_fw_name; 191 | 192 | if (sif_get_ate_config() == 1) { 193 | esp_fw_name = ESP_FW_NAME3; 194 | } else { 195 | esp_fw_name = 196 | epub->sdio_state == 197 | ESP_SDIO_STATE_FIRST_INIT ? ESP_FW_NAME1 : 198 | ESP_FW_NAME2; 199 | } 200 | ret = request_firmware(&fw_entry, esp_fw_name, epub->dev); 201 | 202 | if (ret) 203 | return ret; 204 | 205 | fw_buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); 206 | 207 | release_firmware(fw_entry); 208 | 209 | if (fw_buf == NULL) { 210 | return -ENOMEM; 211 | } 212 | 213 | fhdr = (struct esp_fw_hdr *) fw_buf; 214 | 215 | if (fhdr->magic != 0xE9) { 216 | esp_dbg(ESP_DBG_ERROR, "%s wrong magic! \n", __func__); 217 | goto _err; 218 | } 219 | 220 | blocks = fhdr->blocks; 221 | offset += sizeof(struct esp_fw_hdr); 222 | 223 | while (blocks) { 224 | 225 | bhdr = (struct esp_fw_blk_hdr *) (&fw_buf[offset]); 226 | offset += sizeof(struct esp_fw_blk_hdr); 227 | 228 | ret = 229 | sip_write_memory(epub->sip, bhdr->load_addr, 230 | &fw_buf[offset], bhdr->data_len); 231 | 232 | if (ret) { 233 | esp_dbg(ESP_DBG_ERROR, 234 | "%s Failed to write fw, err: %d\n", 235 | __func__, ret); 236 | goto _err; 237 | } 238 | 239 | blocks--; 240 | offset += bhdr->data_len; 241 | } 242 | 243 | /* TODO: last byte should be the checksum and skip checksum for now */ 244 | 245 | bootcmd.boot_addr = fhdr->entry_addr; 246 | ret = 247 | sip_send_cmd(epub->sip, SIP_CMD_BOOTUP, 248 | sizeof(struct sip_cmd_bootup), &bootcmd); 249 | 250 | if (ret) 251 | goto _err; 252 | 253 | _err: 254 | kfree(fw_buf); 255 | 256 | return ret; 257 | 258 | } 259 | 260 | MODULE_FIRMWARE(ESP_FW_NAME1); 261 | MODULE_FIRMWARE(ESP_FW_NAME2); 262 | MODULE_FIRMWARE(ESP_FW_NAME3); 263 | #endif /* !FPGA_DEBUG */ 264 | -------------------------------------------------------------------------------- /esp_path.h: -------------------------------------------------------------------------------- 1 | #ifndef _ESP_PATH_H_ 2 | #define _ESP_PATH_H_ 3 | #define FWPATH "/lib/firmware" 4 | //module_param_string(fwpath, fwpath, sizeof(fwpath), 0644); 5 | 6 | #endif /* _ESP_PATH_H_ */ 7 | -------------------------------------------------------------------------------- /esp_pub.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2014 Espressif System. 3 | * 4 | * wlan device header file 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | */ 16 | 17 | #ifndef _ESP_PUB_H_ 18 | #define _ESP_PUB_H_ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "sip2_common.h" 28 | 29 | enum esp_sdio_state { 30 | ESP_SDIO_STATE_FIRST_INIT, 31 | ESP_SDIO_STATE_FIRST_NORMAL_EXIT, 32 | ESP_SDIO_STATE_FIRST_ERROR_EXIT, 33 | ESP_SDIO_STATE_SECOND_INIT, 34 | ESP_SDIO_STATE_SECOND_ERROR_EXIT, 35 | }; 36 | 37 | enum esp_tid_state { 38 | ESP_TID_STATE_INIT, 39 | ESP_TID_STATE_TRIGGER, 40 | ESP_TID_STATE_PROGRESS, 41 | ESP_TID_STATE_OPERATIONAL, 42 | ESP_TID_STATE_WAIT_STOP, 43 | ESP_TID_STATE_STOP, 44 | }; 45 | 46 | struct esp_tx_tid { 47 | u8 state; 48 | u8 cnt; 49 | u16 ssn; 50 | }; 51 | 52 | #define WME_NUM_TID 16 53 | struct esp_node { 54 | struct esp_tx_tid tid[WME_NUM_TID]; 55 | struct ieee80211_sta *sta; 56 | u8 ifidx; 57 | u8 index; 58 | }; 59 | 60 | #define WME_AC_BE 2 61 | #define WME_AC_BK 3 62 | #define WME_AC_VI 1 63 | #define WME_AC_VO 0 64 | 65 | struct llc_snap_hdr { 66 | u8 dsap; 67 | u8 ssap; 68 | u8 cntl; 69 | u8 org_code[3]; 70 | __be16 eth_type; 71 | } __packed; 72 | 73 | struct esp_vif { 74 | struct esp_pub *epub; 75 | u8 index; 76 | u32 beacon_interval; 77 | bool ap_up; 78 | struct timer_list beacon_timer; 79 | }; 80 | 81 | /* WLAN related, mostly... */ 82 | /*struct hw_scan_timeout { 83 | struct delayed_work w; 84 | struct ieee80211_hw *hw; 85 | };*/ 86 | 87 | typedef struct esp_wl { 88 | u8 bssid[ETH_ALEN]; 89 | u8 req_bssid[ETH_ALEN]; 90 | 91 | //struct hw_scan_timeout *hsd; 92 | struct cfg80211_scan_request *scan_req; 93 | atomic_t ptk_cnt; 94 | atomic_t gtk_cnt; 95 | atomic_t tkip_key_set; 96 | 97 | /* so far only 2G band */ 98 | struct ieee80211_supported_band sbands[NUM_NL80211_BANDS]; 99 | 100 | unsigned long flags; 101 | atomic_t off; 102 | } esp_wl_t; 103 | 104 | typedef struct esp_hw_idx_map { 105 | u8 mac[ETH_ALEN]; 106 | u8 flag; 107 | } esp_hw_idx_map_t; 108 | 109 | #define ESP_WL_FLAG_RFKILL BIT(0) 110 | #define ESP_WL_FLAG_HW_REGISTERED BIT(1) 111 | #define ESP_WL_FLAG_CONNECT BIT(2) 112 | #define ESP_WL_FLAG_STOP_TXQ BIT(3) 113 | 114 | #define ESP_PUB_MAX_VIF 2 115 | #define ESP_PUB_MAX_STA 4 //for one interface 116 | #define ESP_PUB_MAX_RXAMPDU 8 //for all interfaces 117 | 118 | enum { 119 | ESP_PM_OFF = 0, 120 | ESP_PM_TURNING_ON, 121 | ESP_PM_ON, 122 | ESP_PM_TURNING_OFF, /* Do NOT change the order */ 123 | }; 124 | 125 | struct esp_ps { 126 | u32 dtim_period; 127 | u32 max_sleep_period; 128 | unsigned long last_config_time; 129 | atomic_t state; 130 | bool nulldata_pm_on; 131 | }; 132 | 133 | struct esp_mac_prefix { 134 | u8 mac_index; 135 | u8 mac_addr_prefix[3]; 136 | }; 137 | 138 | struct esp_pub { 139 | struct device *dev; 140 | #ifdef ESP_NO_MAC80211 141 | struct net_device *net_dev; 142 | struct wireless_dev *wdev; 143 | struct net_device_stats *net_stats; 144 | #else 145 | struct ieee80211_hw *hw; 146 | struct ieee80211_vif *vif; 147 | u8 vif_slot; 148 | #endif /* ESP_MAC80211 */ 149 | 150 | void *sif; /* serial interface control block, e.g. sdio */ 151 | enum esp_sdio_state sdio_state; 152 | struct esp_sip *sip; 153 | struct esp_wl wl; 154 | struct esp_hw_idx_map hi_map[19]; 155 | struct esp_hw_idx_map low_map[ESP_PUB_MAX_VIF][2]; 156 | //u32 flags; //flags to represent rfkill switch,start 157 | u8 roc_flags; //0: not in remain on channel state, 1: in roc state 158 | 159 | struct work_struct tx_work; /* attach to ieee80211 workqueue */ 160 | /* latest mac80211 has multiple tx queue, but we stick with single queue now */ 161 | spinlock_t rx_lock; 162 | spinlock_t tx_ampdu_lock; 163 | spinlock_t rx_ampdu_lock; 164 | spinlock_t tx_lock; 165 | struct mutex tx_mtx; 166 | struct sk_buff_head txq; 167 | atomic_t txq_stopped; 168 | 169 | struct work_struct sendup_work; /* attach to ieee80211 workqueue */ 170 | struct sk_buff_head txdoneq; 171 | struct sk_buff_head rxq; 172 | 173 | struct workqueue_struct *esp_wkq; 174 | 175 | //u8 bssid[ETH_ALEN]; 176 | u8 mac_addr[ETH_ALEN]; 177 | 178 | u32 rx_filter; 179 | unsigned long scan_permit; 180 | bool scan_permit_valid; 181 | struct delayed_work scan_timeout_work; 182 | u32 enodes_map; 183 | u8 rxampdu_map; 184 | u32 enodes_maps[ESP_PUB_MAX_VIF]; 185 | struct esp_node *enodes[ESP_PUB_MAX_STA + 1]; 186 | struct esp_node *rxampdu_node[ESP_PUB_MAX_RXAMPDU]; 187 | u8 rxampdu_tid[ESP_PUB_MAX_RXAMPDU]; 188 | struct esp_ps ps; 189 | int enable_int; 190 | int wait_reset; 191 | }; 192 | 193 | typedef struct esp_pub esp_pub_t; 194 | 195 | struct esp_pub *esp_pub_alloc_mac80211(struct device *dev); 196 | int esp_pub_dealloc_mac80211(struct esp_pub *epub); 197 | int esp_register_mac80211(struct esp_pub *epub); 198 | 199 | int esp_pub_init_all(struct esp_pub *epub); 200 | 201 | char *mod_eagle_path_get(void); 202 | 203 | void esp_dsr(struct esp_pub *epub); 204 | void hw_scan_done(struct esp_pub *epub, bool aborted); 205 | void esp_rocdone_process(struct ieee80211_hw *hw, 206 | struct sip_evt_roc *report); 207 | 208 | void esp_ps_config(struct esp_pub *epub, struct esp_ps *ps, bool on); 209 | 210 | struct esp_node *esp_get_node_by_addr(struct esp_pub *epub, 211 | const u8 * addr); 212 | struct esp_node *esp_get_node_by_index(struct esp_pub *epub, u8 index); 213 | int esp_get_empty_rxampdu(struct esp_pub *epub, const u8 * addr, u8 tid); 214 | int esp_get_exist_rxampdu(struct esp_pub *epub, const u8 * addr, u8 tid); 215 | 216 | #ifdef TEST_MODE 217 | int test_init_netlink(struct esp_sip *sip); 218 | void test_exit_netlink(void); 219 | void esp_test_cmd_event(u32 cmd_type, char *reply_info); 220 | void esp_test_init(struct esp_pub *epub); 221 | #endif 222 | #endif /* _ESP_PUB_H_ */ 223 | -------------------------------------------------------------------------------- /esp_sif.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 - 2014 Espressif System. 3 | * 4 | * Serial I/F wrapper layer for eagle WLAN device, 5 | * abstraction of buses like SDIO/SIP, and provides 6 | * flow control for tx/rx layer 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | */ 18 | 19 | #ifndef _ESP_SIF_H_ 20 | #define _ESP_SIF_H_ 21 | 22 | #include "esp_pub.h" 23 | #include 24 | #include 25 | 26 | /* 27 | * H/W SLC module definitions 28 | */ 29 | 30 | #define SIF_SLC_BLOCK_SIZE 512 31 | 32 | 33 | /* S/W struct mapping to slc registers */ 34 | typedef struct slc_host_regs { 35 | /* do NOT read token_rdata 36 | * 37 | u32 pf_data; 38 | u32 token_rdata; 39 | */ 40 | u32 intr_raw; 41 | u32 state_w0; 42 | u32 state_w1; 43 | u32 config_w0; 44 | u32 config_w1; 45 | u32 intr_status; 46 | u32 config_w2; 47 | u32 config_w3; 48 | u32 config_w4; 49 | u32 token_wdata; 50 | u32 intr_clear; 51 | u32 intr_enable; 52 | } sif_slc_reg_t; 53 | 54 | 55 | enum io_sync_type { 56 | ESP_SIF_NOSYNC = 0, 57 | ESP_SIF_SYNC, 58 | }; 59 | 60 | typedef struct esp_sdio_ctrl { 61 | struct sdio_func *func; 62 | struct esp_pub *epub; 63 | 64 | 65 | struct list_head free_req; 66 | 67 | u8 *dma_buffer; 68 | 69 | spinlock_t scat_lock; 70 | struct list_head scat_req; 71 | 72 | bool off; 73 | atomic_t irq_handling; 74 | const struct sdio_device_id *id; 75 | u32 slc_blk_sz; 76 | u32 target_id; 77 | u32 slc_window_end_addr; 78 | 79 | struct slc_host_regs slc_regs; 80 | atomic_t irq_installed; 81 | 82 | } esp_sdio_ctrl_t; 83 | 84 | #define SIF_TO_DEVICE 0x1 85 | #define SIF_FROM_DEVICE 0x2 86 | 87 | #define SIF_SYNC 0x00000010 88 | #define SIF_ASYNC 0x00000020 89 | 90 | #define SIF_BYTE_BASIS 0x00000040 91 | #define SIF_BLOCK_BASIS 0x00000080 92 | 93 | #define SIF_FIXED_ADDR 0x00000100 94 | #define SIF_INC_ADDR 0x00000200 95 | 96 | #define EPUB_CTRL_CHECK(_epub, _go_err) do{\ 97 | if (_epub == NULL) {\ 98 | ESSERT(0);\ 99 | goto _go_err;\ 100 | }\ 101 | if ((_epub)->sif == NULL) {\ 102 | ESSERT(0);\ 103 | goto _go_err;\ 104 | }\ 105 | }while(0) 106 | 107 | #define EPUB_FUNC_CHECK(_epub, _go_err) do{\ 108 | if (_epub == NULL) {\ 109 | ESSERT(0);\ 110 | goto _go_err;\ 111 | }\ 112 | if ((_epub)->sif == NULL) {\ 113 | ESSERT(0);\ 114 | goto _go_err;\ 115 | }\ 116 | if (((struct esp_sdio_ctrl *)(_epub)->sif)->func == NULL) {\ 117 | ESSERT(0);\ 118 | goto _go_err;\ 119 | }\ 120 | }while(0) 121 | 122 | #define EPUB_TO_CTRL(_epub) (((struct esp_sdio_ctrl *)(_epub)->sif)) 123 | 124 | #define EPUB_TO_FUNC(_epub) (((struct esp_sdio_ctrl *)(_epub)->sif)->func) 125 | 126 | void sdio_io_writeb(struct esp_pub *epub, u8 value, int addr, int *res); 127 | u8 sdio_io_readb(struct esp_pub *epub, int addr, int *res); 128 | 129 | 130 | void sif_enable_irq(struct esp_pub *epub); 131 | void sif_disable_irq(struct esp_pub *epub); 132 | void sif_disable_target_interrupt(struct esp_pub *epub); 133 | 134 | u32 sif_get_blksz(struct esp_pub *epub); 135 | u32 sif_get_target_id(struct esp_pub *epub); 136 | 137 | void sif_dsr(struct sdio_func *func); 138 | int sif_io_raw(struct esp_pub *epub, u32 addr, u8 * buf, u32 len, 139 | u32 flag); 140 | int sif_io_sync(struct esp_pub *epub, u32 addr, u8 * buf, u32 len, 141 | u32 flag); 142 | int sif_io_async(struct esp_pub *epub, u32 addr, u8 * buf, u32 len, 143 | u32 flag, void *context); 144 | int sif_lldesc_read_sync(struct esp_pub *epub, u8 * buf, u32 len); 145 | int sif_lldesc_write_sync(struct esp_pub *epub, u8 * buf, u32 len); 146 | int sif_lldesc_read_raw(struct esp_pub *epub, u8 * buf, u32 len, 147 | bool noround); 148 | int sif_lldesc_write_raw(struct esp_pub *epub, u8 * buf, u32 len); 149 | 150 | int sif_platform_get_irq_no(void); 151 | int sif_platform_is_irq_occur(void); 152 | void sif_platform_irq_clear(void); 153 | void sif_platform_irq_mask(int enable_mask); 154 | int sif_platform_irq_init(void); 155 | void sif_platform_irq_deinit(void); 156 | 157 | int esp_common_read(struct esp_pub *epub, u8 * buf, u32 len, int sync, 158 | bool noround); 159 | int esp_common_write(struct esp_pub *epub, u8 * buf, u32 len, int sync); 160 | int esp_common_read_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, 161 | u32 len, int sync); 162 | int esp_common_write_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, 163 | u32 len, int sync); 164 | 165 | int esp_common_readbyte_with_addr(struct esp_pub *epub, u32 addr, u8 * buf, 166 | int sync); 167 | int esp_common_writebyte_with_addr(struct esp_pub *epub, u32 addr, u8 buf, 168 | int sync); 169 | 170 | int sif_read_reg_window(struct esp_pub *epub, unsigned int reg_addr, 171 | unsigned char *value); 172 | int sif_write_reg_window(struct esp_pub *epub, unsigned int reg_addr, 173 | unsigned char *value); 174 | int sif_ack_target_read_err(struct esp_pub *epub); 175 | int sif_had_io_enable(struct esp_pub *epub); 176 | 177 | struct slc_host_regs *sif_get_regs(struct esp_pub *epub); 178 | 179 | void sif_lock_bus(struct esp_pub *epub); 180 | void sif_unlock_bus(struct esp_pub *epub); 181 | 182 | int sif_interrupt_target(struct esp_pub *epub, u8 index); 183 | #ifdef USE_EXT_GPIO 184 | int sif_config_gpio_mode(struct esp_pub *epub, u8 gpio_num, u8 gpio_mode); 185 | int sif_set_gpio_output(struct esp_pub *epub, u16 mask, u16 value); 186 | int sif_get_gpio_intr(struct esp_pub *epub, u16 intr_mask, u16 * value); 187 | int sif_get_gpio_input(struct esp_pub *epub, u16 * mask, u16 * value); 188 | #endif 189 | 190 | void check_target_id(struct esp_pub *epub); 191 | 192 | void sif_record_bt_config(int value); 193 | int sif_get_bt_config(void); 194 | void sif_record_rst_config(int value); 195 | int sif_get_rst_config(void); 196 | void sif_record_ate_config(int value); 197 | int sif_get_ate_config(void); 198 | void sif_record_retry_config(void); 199 | int sif_get_retry_config(void); 200 | void sif_record_wakeup_gpio_config(int value); 201 | int sif_get_wakeup_gpio_config(void); 202 | 203 | #define sif_reg_read_sync(epub, addr, buf, len) sif_io_sync((epub), (addr), (buf), (len), SIF_FROM_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR) 204 | 205 | #define sif_reg_write_sync(epub, addr, buf, len) sif_io_sync((epub), (addr), (buf), (len), SIF_TO_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR) 206 | 207 | #endif /* _ESP_SIF_H_ */ 208 | -------------------------------------------------------------------------------- /esp_sip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009- 2014 Espressif System. 3 | * 4 | * Serial Interconnctor Protocol 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | */ 16 | 17 | #ifndef _ESP_SIP_H 18 | #define _ESP_SIP_H 19 | 20 | #include "sip2_common.h" 21 | 22 | #define SIP_CTRL_CREDIT_RESERVE 2 23 | 24 | #define SIP_PKT_MAX_LEN (1024*16) 25 | 26 | /* 16KB on normal X86 system, should check before porting to orhters */ 27 | 28 | #define SIP_TX_AGGR_BUF_SIZE (4 * PAGE_SIZE) 29 | #define SIP_RX_AGGR_BUF_SIZE (4 * PAGE_SIZE) 30 | 31 | struct sk_buff; 32 | 33 | struct sip_pkt { 34 | struct list_head list; 35 | 36 | u8 *buf_begin; 37 | u32 buf_len; 38 | u8 *buf; 39 | }; 40 | 41 | typedef enum RECALC_CREDIT_STATE { 42 | RECALC_CREDIT_DISABLE = 0, 43 | RECALC_CREDIT_ENABLE = 1, 44 | } RECALC_CREDIT_STATE; 45 | 46 | typedef enum ENQUEUE_PRIOR { 47 | ENQUEUE_PRIOR_TAIL = 0, 48 | ENQUEUE_PRIOR_HEAD, 49 | } ENQUEUE_PRIOR; 50 | 51 | typedef enum SIP_STATE { 52 | SIP_INIT = 0, 53 | SIP_PREPARE_BOOT, 54 | SIP_BOOT, 55 | SIP_SEND_INIT, 56 | SIP_WAIT_BOOTUP, 57 | SIP_RUN, 58 | SIP_SUSPEND, 59 | SIP_STOP 60 | } SIP_STATE; 61 | 62 | enum sip_notifier { 63 | SIP_TX_DONE = 1, 64 | SIP_RX_DONE = 2, 65 | }; 66 | 67 | #define SIP_CREDITS_LOW_THRESHOLD 64 //i.e. 4k 68 | 69 | struct esp_sip { 70 | struct list_head free_ctrl_txbuf; 71 | struct list_head free_ctrl_rxbuf; 72 | 73 | u32 rxseq; /* sip pkt seq, should match target side */ 74 | u32 txseq; 75 | u32 txdataseq; 76 | 77 | u8 to_host_seq; 78 | 79 | atomic_t state; 80 | spinlock_t lock; 81 | atomic_t tx_credits; 82 | 83 | atomic_t tx_ask_credit_update; 84 | 85 | u8 *rawbuf; /* used in boot stage, free once chip is fully up */ 86 | u8 *tx_aggr_buf; 87 | u8 *tx_aggr_write_ptr; /* update after insertion of each pkt */ 88 | u8 *tx_aggr_lastpkt_ptr; 89 | 90 | struct mutex rx_mtx; 91 | struct sk_buff_head rxq; 92 | struct work_struct rx_process_work; 93 | 94 | u16 tx_blksz; 95 | u16 rx_blksz; 96 | 97 | bool dump_rpbm_err; 98 | bool sendup_rpbm_pkt; 99 | bool rxabort_fixed; 100 | bool support_bgscan; 101 | u8 credit_to_reserve; 102 | 103 | atomic_t credit_status; 104 | struct timer_list credit_timer; 105 | 106 | atomic_t noise_floor; 107 | 108 | u32 tx_tot_len; /* total len for one transaction */ 109 | u32 rx_tot_len; 110 | 111 | atomic_t rx_handling; 112 | atomic_t tx_data_pkt_queued; 113 | 114 | atomic_t data_tx_stopped; 115 | atomic_t tx_stopped; 116 | 117 | struct esp_pub *epub; 118 | }; 119 | 120 | int sip_rx(struct esp_pub *epub); 121 | //int sip_download_fw(struct esp_sip *sip, u32 load_addr, u32 boot_addr); 122 | 123 | 124 | int sip_write_memory(struct esp_sip *, u32 addr, u8 * buf, u16 len); 125 | 126 | void sip_credit_process(struct esp_pub *, u8 credits); 127 | 128 | int sip_send_cmd(struct esp_sip *sip, int cid, u32 cmdlen, void *cmd); 129 | 130 | struct esp_sip *sip_attach(struct esp_pub *); 131 | 132 | int sip_post_init(struct esp_sip *sip, struct sip_evt_bootup2 *bevt); 133 | 134 | void sip_detach(struct esp_sip *sip); 135 | 136 | void sip_txq_process(struct esp_pub *epub); 137 | 138 | struct sk_buff *sip_alloc_ctrl_skbuf(struct esp_sip *sip, u16 len, 139 | u32 cid); 140 | 141 | void sip_free_ctrl_skbuff(struct esp_sip *sip, struct sk_buff *skb); 142 | 143 | bool sip_queue_need_stop(struct esp_sip *sip); 144 | bool sip_queue_may_resume(struct esp_sip *sip); 145 | bool sip_tx_data_need_stop(struct esp_sip *sip); 146 | bool sip_tx_data_may_resume(struct esp_sip *sip); 147 | 148 | void sip_tx_data_pkt_enqueue(struct esp_pub *epub, struct sk_buff *skb); 149 | void sip_rx_data_pkt_enqueue(struct esp_pub *epub, struct sk_buff *skb); 150 | 151 | int sip_cmd_enqueue(struct esp_sip *sip, struct sk_buff *skb, int prior); 152 | 153 | int sip_poll_bootup_event(struct esp_sip *sip); 154 | 155 | int sip_poll_resetting_event(struct esp_sip *sip); 156 | 157 | void sip_trigger_txq_process(struct esp_sip *sip); 158 | 159 | void sip_send_chip_init(struct esp_sip *sip); 160 | 161 | bool mod_support_no_txampdu(void); 162 | 163 | bool mod_support_no_rxampdu(void); 164 | 165 | void mod_support_no_txampdu_set(bool value); 166 | 167 | #ifdef FPGA_DEBUG 168 | int sip_send_bootup(struct esp_sip *sip); 169 | #endif /* FPGA_DEBUG */ 170 | void sip_debug_show(struct esp_sip *sip); 171 | #endif 172 | -------------------------------------------------------------------------------- /esp_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 - 2014 Espressif System. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | */ 14 | 15 | #include "linux/types.h" 16 | #include "linux/kernel.h" 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "esp_pub.h" 26 | #include "esp_utils.h" 27 | #include "esp_wmac.h" 28 | #include "esp_debug.h" 29 | 30 | /* 31 | * Convert IEEE channel number to MHz frequency. 32 | */ 33 | u32 esp_ieee2mhz(u8 chan) 34 | { 35 | if (chan == 14) 36 | return 2484; 37 | 38 | if (chan < 14) 39 | return 2407 + chan * 5; 40 | else 41 | return 2512 + ((chan - 15) * 20); 42 | //TODO, add 5GHz 43 | } 44 | 45 | enum { 46 | ESP_RATE_1_LONG = 0x0, 47 | ESP_RATE_2_LONG = 0x1, 48 | ESP_RATE_2_SHORT = 0x5, 49 | ESP_RATE_5_SHORT = 0x6, 50 | ESP_RATE_5_LONG = 0x2, 51 | ESP_RATE_11_SHORT = 0x7, 52 | ESP_RATE_11_LONG = 0x3, 53 | ESP_RATE_6 = 0xb, 54 | ESP_RATE_9 = 0xf, 55 | ESP_RATE_12 = 0xa, 56 | ESP_RATE_18 = 0xe, 57 | ESP_RATE_24 = 0x9, 58 | ESP_RATE_36 = 0xd, 59 | ESP_RATE_48 = 0x8, 60 | ESP_RATE_54 = 0xc, 61 | /* ESP_RATE_MCS0 =0x10, 62 | ESP_RATE_MCS1 =0x11, 63 | ESP_RATE_MCS2 =0x12, 64 | ESP_RATE_MCS3 =0x13, 65 | ESP_RATE_MCS4 =0x14, 66 | ESP_RATE_MCS5 =0x15, 67 | ESP_RATE_MCS6 =0x16, 68 | ESP_RATE_MCS7 =0x17, 69 | */ 70 | }; 71 | 72 | static u8 esp_rate_table[20] = { 73 | ESP_RATE_1_LONG, 74 | ESP_RATE_2_SHORT, 75 | ESP_RATE_5_SHORT, 76 | ESP_RATE_11_SHORT, 77 | ESP_RATE_6, 78 | ESP_RATE_9, 79 | ESP_RATE_12, 80 | ESP_RATE_18, 81 | ESP_RATE_24, 82 | ESP_RATE_36, 83 | ESP_RATE_48, 84 | ESP_RATE_54, 85 | /* ESP_RATE_MCS0, 86 | ESP_RATE_MCS1, 87 | ESP_RATE_MCS2, 88 | ESP_RATE_MCS3, 89 | ESP_RATE_MCS4, 90 | ESP_RATE_MCS5, 91 | ESP_RATE_MCS6, 92 | ESP_RATE_MCS7, 93 | */ 94 | }; 95 | 96 | s8 esp_wmac_rate2idx(u8 rate) 97 | { 98 | int i; 99 | 100 | if (rate == ESP_RATE_2_LONG) 101 | return 1; 102 | if (rate == ESP_RATE_5_LONG) 103 | return 2; 104 | if (rate == ESP_RATE_11_LONG) 105 | return 3; 106 | 107 | for (i = 0; i < 20; i++) { 108 | if (rate == esp_rate_table[i]) 109 | return i; 110 | } 111 | 112 | esp_dbg(ESP_DBG_ERROR, "%s unknown rate 0x%02x \n", __func__, 113 | rate); 114 | 115 | return 0; 116 | } 117 | 118 | bool esp_wmac_rxsec_error(u8 error) 119 | { 120 | return (error >= RX_SECOV_ERR && error <= RX_SECFIFO_TIMEOUT) 121 | || (error >= RX_WEPICV_ERR && error <= RX_WAPIMIC_ERR); 122 | } 123 | 124 | int esp_cipher2alg(int cipher) 125 | { 126 | if (cipher == WLAN_CIPHER_SUITE_TKIP) 127 | return ALG_TKIP; 128 | 129 | if (cipher == WLAN_CIPHER_SUITE_CCMP) 130 | return ALG_CCMP; 131 | 132 | if (cipher == WLAN_CIPHER_SUITE_WEP40 133 | || cipher == WLAN_CIPHER_SUITE_WEP104) 134 | return ALG_WEP; 135 | 136 | if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) 137 | return ALG_AES_CMAC; 138 | 139 | //printk("%s wrong cipher 0x%x!\n",__func__,cipher); 140 | 141 | return -1; 142 | } 143 | 144 | #ifdef RX_CHECKSUM_TEST 145 | atomic_t g_iv_len; 146 | void esp_rx_checksum_test(struct sk_buff *skb) 147 | { 148 | static u32 ip_err = 0; 149 | static u32 tcp_err = 0; 150 | struct ieee80211_hdr *pwh = (struct ieee80211_hdr *) skb->data; 151 | int hdrlen = ieee80211_hdrlen(pwh->frame_control); 152 | 153 | if (ieee80211_has_protected(pwh->frame_control)) 154 | hdrlen += atomic_read(&g_iv_len); 155 | 156 | if (ieee80211_is_data(pwh->frame_control)) { 157 | struct llc_snap_hdr *llc = 158 | (struct llc_snap_hdr *) (skb->data + hdrlen); 159 | if (ntohs(llc->eth_type) == ETH_P_IP) { 160 | int llclen = sizeof(struct llc_snap_hdr); 161 | struct iphdr *iph = 162 | (struct iphdr *) (skb->data + hdrlen + llclen); 163 | __sum16 csum_bak = iph->check; 164 | 165 | iph->check = 0; 166 | iph->check = ip_fast_csum(iph, iph->ihl); 167 | if (iph->check != csum_bak) { 168 | esp_dbg(ESP_DBG_ERROR, 169 | "total ip checksum error %d\n", 170 | ++ip_err); 171 | } 172 | iph->check = csum_bak; 173 | 174 | if (iph->protocol == 0x06) { 175 | struct tcphdr *tcph = 176 | (struct tcphdr *) (skb->data + hdrlen + 177 | llclen + 178 | iph->ihl * 4); 179 | int datalen = 180 | skb->len - (hdrlen + llclen + 181 | iph->ihl * 4); 182 | csum_bak = tcph->check; 183 | 184 | tcph->check = 0; 185 | tcph->check = 186 | tcp_v4_check(datalen, iph->saddr, 187 | iph->daddr, 188 | csum_partial((char *) 189 | tcph, 190 | datalen, 0)); 191 | if (tcph->check != csum_bak) { 192 | esp_dbg(ESP_DBG_ERROR, 193 | "total tcp checksum error %d\n", 194 | ++tcp_err); 195 | } 196 | tcph->check = csum_bak; 197 | } 198 | } 199 | } 200 | } 201 | 202 | #endif 203 | 204 | #ifdef GEN_ERR_CHECKSUM 205 | 206 | void esp_gen_err_checksum(struct sk_buff *skb) 207 | { 208 | static u32 tx_seq = 0; 209 | if ((tx_seq++ % 16) == 0) { 210 | struct ieee80211_hdr *hdr = 211 | (struct ieee80211_hdr *) skb->data; 212 | int hdrlen = ieee80211_hdrlen(hdr->frame_control); 213 | 214 | if (ieee80211_has_protected(pwh->frame_control)) 215 | hdrlen += 216 | IEEE80211_SKB_CB(skb)->control.hw_key->iv_len; 217 | 218 | struct llc_snap_hdr *llc = 219 | (struct llc_snap_hdr *) (skb->data + hdrlen); 220 | if (ntohs(llc->eth_type) == ETH_P_IP) { 221 | int llclen = sizeof(struct llc_snap_hdr); 222 | struct iphdr *iph = 223 | (struct iphdr *) (skb->data + hdrlen + llclen); 224 | 225 | iph->check = ~iph->check; 226 | 227 | if (iph->protocol == 0x06) { 228 | struct tcphdr *tcph = 229 | (struct tcphdr *) (skb->data + hdrlen + 230 | llclen + 231 | iph->ihl * 4); 232 | tcph->check = ~tcph->check; 233 | } 234 | } 235 | } 236 | } 237 | #endif 238 | 239 | bool esp_is_ip_pkt(struct sk_buff *skb) 240 | { 241 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 242 | int hdrlen; 243 | struct llc_snap_hdr *llc; 244 | 245 | if (!ieee80211_is_data(hdr->frame_control)) 246 | return false; 247 | 248 | hdrlen = ieee80211_hdrlen(hdr->frame_control); 249 | if (ieee80211_has_protected(hdr->frame_control)) 250 | hdrlen += IEEE80211_SKB_CB(skb)->control.hw_key->iv_len; 251 | #ifdef RX_CHECKSUM_TEST 252 | atomic_set(&g_iv_len, 253 | IEEE80211_SKB_CB(skb)->control.hw_key->iv_len); 254 | #endif 255 | if (skb->len < hdrlen + sizeof(struct llc_snap_hdr)) 256 | return false; 257 | llc = (struct llc_snap_hdr *) (skb->data + hdrlen); 258 | if (ntohs(llc->eth_type) != ETH_P_IP) 259 | return false; 260 | else 261 | return true; 262 | } 263 | -------------------------------------------------------------------------------- /esp_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2012 Espressif System. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | */ 14 | 15 | #ifndef _ESP_UTILS_H_ 16 | #define _ESP_UTILS_H_ 17 | 18 | #include "linux/types.h" 19 | #include 20 | 21 | #ifndef BIT 22 | #define BIT(x) (0x1 << (x)) 23 | #endif 24 | 25 | u32 esp_ieee2mhz(u8 chan); 26 | 27 | enum ieee80211_key_alg { 28 | ALG_WEP, 29 | ALG_TKIP, 30 | ALG_CCMP, 31 | ALG_AES_CMAC 32 | }; 33 | 34 | int esp_cipher2alg(int cipher); 35 | 36 | void esp_rx_checksum_test(struct sk_buff *skb); 37 | void esp_gen_err_checksum(struct sk_buff *skb); 38 | 39 | bool esp_is_ip_pkt(struct sk_buff *skb); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /esp_version.h: -------------------------------------------------------------------------------- 1 | #define DRIVER_VER 0xbdf5087c3debll 2 | -------------------------------------------------------------------------------- /esp_wl.h: -------------------------------------------------------------------------------- 1 | #ifndef _ESP_WL_H_ 2 | #define _ESP_WL_H_ 3 | 4 | //#define MAX_PROBED_SSID_INDEX 9 5 | 6 | 7 | enum { 8 | CONF_HW_BIT_RATE_1MBPS = BIT(0), 9 | CONF_HW_BIT_RATE_2MBPS = BIT(1), 10 | CONF_HW_BIT_RATE_5_5MBPS = BIT(2), 11 | CONF_HW_BIT_RATE_11MBPS = BIT(3), 12 | CONF_HW_BIT_RATE_6MBPS = BIT(4), 13 | CONF_HW_BIT_RATE_9MBPS = BIT(5), 14 | CONF_HW_BIT_RATE_12MBPS = BIT(6), 15 | CONF_HW_BIT_RATE_18MBPS = BIT(7), 16 | CONF_HW_BIT_RATE_22MBPS = BIT(8), 17 | CONF_HW_BIT_RATE_24MBPS = BIT(9), 18 | CONF_HW_BIT_RATE_36MBPS = BIT(10), 19 | CONF_HW_BIT_RATE_48MBPS = BIT(11), 20 | CONF_HW_BIT_RATE_54MBPS = BIT(12), 21 | CONF_HW_BIT_RATE_11B_MASK = 22 | (CONF_HW_BIT_RATE_1MBPS | CONF_HW_BIT_RATE_2MBPS | 23 | CONF_HW_BIT_RATE_5_5MBPS | CONF_HW_BIT_RATE_11MBPS), 24 | }; 25 | 26 | #if 0 27 | enum { 28 | CONF_HW_RATE_INDEX_1MBPS = 0, 29 | CONF_HW_RATE_INDEX_2MBPS = 1, 30 | CONF_HW_RATE_INDEX_5_5MBPS = 2, 31 | CONF_HW_RATE_INDEX_6MBPS = 3, 32 | CONF_HW_RATE_INDEX_9MBPS = 4, 33 | CONF_HW_RATE_INDEX_11MBPS = 5, 34 | CONF_HW_RATE_INDEX_12MBPS = 6, 35 | CONF_HW_RATE_INDEX_18MBPS = 7, 36 | CONF_HW_RATE_INDEX_22MBPS = 8, 37 | CONF_HW_RATE_INDEX_24MBPS = 9, 38 | CONF_HW_RATE_INDEX_36MBPS = 10, 39 | CONF_HW_RATE_INDEX_48MBPS = 11, 40 | CONF_HW_RATE_INDEX_54MBPS = 12, 41 | CONF_HW_RATE_INDEX_MAX, 42 | }; 43 | 44 | enum { 45 | CONF_HW_RXTX_RATE_54 = 0, 46 | CONF_HW_RXTX_RATE_48, 47 | CONF_HW_RXTX_RATE_36, 48 | CONF_HW_RXTX_RATE_24, 49 | CONF_HW_RXTX_RATE_22, 50 | CONF_HW_RXTX_RATE_18, 51 | CONF_HW_RXTX_RATE_12, 52 | CONF_HW_RXTX_RATE_11, 53 | CONF_HW_RXTX_RATE_9, 54 | CONF_HW_RXTX_RATE_6, 55 | CONF_HW_RXTX_RATE_5_5, 56 | CONF_HW_RXTX_RATE_2, 57 | CONF_HW_RXTX_RATE_1, 58 | CONF_HW_RXTX_RATE_MAX, 59 | CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff 60 | }; 61 | #endif 62 | 63 | #endif /* _ESP_WL_H_ */ 64 | -------------------------------------------------------------------------------- /esp_wmac.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2012 Espressif System. 3 | * 4 | * MAC header 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | */ 16 | 17 | #ifndef _ESP_WMAC_H_ 18 | #define _ESP_WMAC_H_ 19 | 20 | struct esp_mac_rx_ctrl { 21 | signed rssi:8; 22 | unsigned rate:4; 23 | unsigned is_group:1; 24 | unsigned:1; 25 | unsigned sig_mode:2; 26 | unsigned legacy_length:12; 27 | unsigned damatch0:1; 28 | unsigned damatch1:1; 29 | unsigned bssidmatch0:1; 30 | unsigned bssidmatch1:1; 31 | unsigned MCS:7; 32 | unsigned CWB:1; 33 | unsigned HT_length:16; 34 | unsigned Smoothing:1; 35 | unsigned Not_Sounding:1; 36 | unsigned:1; 37 | unsigned Aggregation:1; 38 | unsigned STBC:2; 39 | unsigned FEC_CODING:1; 40 | unsigned SGI:1; 41 | unsigned rxend_state:8; 42 | unsigned ampdu_cnt:8; 43 | unsigned channel:4; 44 | unsigned:4; 45 | signed noise_floor:8; 46 | }; 47 | 48 | struct esp_rx_ampdu_len { 49 | unsigned substate:8; 50 | unsigned sublen:12; 51 | unsigned:12; 52 | }; 53 | 54 | struct esp_tx_ampdu_entry { 55 | u32 sub_len:12, dili_num:7,:1, null_byte:2, data:1, enc:1, seq:8; 56 | }; 57 | 58 | //rxend_state flags 59 | #define RX_PYH_ERR_MIN 0x42 60 | #define RX_AGC_ERR_MIN 0x42 61 | #define RX_AGC_ERR_MAX 0x47 62 | #define RX_OFDM_ERR_MIN 0x50 63 | #define RX_OFDM_ERR_MAX 0x58 64 | #define RX_CCK_ERR_MIN 0x59 65 | #define RX_CCK_ERR_MAX 0x5F 66 | #define RX_ABORT 0x80 67 | #define RX_SF_ERR 0x40 68 | #define RX_FCS_ERR 0x41 69 | #define RX_AHBOV_ERR 0xC0 70 | #define RX_BUFOV_ERR 0xC1 71 | #define RX_BUFINV_ERR 0xC2 72 | #define RX_AMPDUSF_ERR 0xC3 73 | #define RX_AMPDUBUFOV_ERR 0xC4 74 | #define RX_MACBBFIFOOV_ERR 0xC5 75 | #define RX_RPBM_ERR 0xC6 76 | #define RX_BTFORCE_ERR 0xC7 77 | #define RX_SECOV_ERR 0xE1 78 | #define RX_SECPROT_ERR0 0xE2 79 | #define RX_SECPROT_ERR1 0xE3 80 | #define RX_SECKEY_ERR 0xE4 81 | #define RX_SECCRLEN_ERR 0xE5 82 | #define RX_SECFIFO_TIMEOUT 0xE6 83 | #define RX_WEPICV_ERR 0xF0 84 | #define RX_TKIPICV_ERR 0xF4 85 | #define RX_TKIPMIC_ERR 0xF5 86 | #define RX_CCMPMIC_ERR 0xF8 87 | #define RX_WAPIMIC_ERR 0xFC 88 | 89 | s8 esp_wmac_rate2idx(u8 rate); 90 | bool esp_wmac_rxsec_error(u8 error); 91 | 92 | #endif /* _ESP_WMAC_H_ */ 93 | -------------------------------------------------------------------------------- /firmware/LICENSE-2.0.txt: -------------------------------------------------------------------------------- 1 | The esp8089 firmware files are licensed under the Apache License, Version 2.0: 2 | 3 | Apache License 4 | Version 2.0, January 2004 5 | http://www.apache.org/licenses/ 6 | 7 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 8 | 9 | 1. Definitions. 10 | 11 | "License" shall mean the terms and conditions for use, reproduction, 12 | and distribution as defined by Sections 1 through 9 of this document. 13 | 14 | "Licensor" shall mean the copyright owner or entity authorized by 15 | the copyright owner that is granting the License. 16 | 17 | "Legal Entity" shall mean the union of the acting entity and all 18 | other entities that control, are controlled by, or are under common 19 | control with that entity. For the purposes of this definition, 20 | "control" means (i) the power, direct or indirect, to cause the 21 | direction or management of such entity, whether by contract or 22 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 23 | outstanding shares, or (iii) beneficial ownership of such entity. 24 | 25 | "You" (or "Your") shall mean an individual or Legal Entity 26 | exercising permissions granted by this License. 27 | 28 | "Source" form shall mean the preferred form for making modifications, 29 | including but not limited to software source code, documentation 30 | source, and configuration files. 31 | 32 | "Object" form shall mean any form resulting from mechanical 33 | transformation or translation of a Source form, including but 34 | not limited to compiled object code, generated documentation, 35 | and conversions to other media types. 36 | 37 | "Work" shall mean the work of authorship, whether in Source or 38 | Object form, made available under the License, as indicated by a 39 | copyright notice that is included in or attached to the work 40 | (an example is provided in the Appendix below). 41 | 42 | "Derivative Works" shall mean any work, whether in Source or Object 43 | form, that is based on (or derived from) the Work and for which the 44 | editorial revisions, annotations, elaborations, or other modifications 45 | represent, as a whole, an original work of authorship. For the purposes 46 | of this License, Derivative Works shall not include works that remain 47 | separable from, or merely link (or bind by name) to the interfaces of, 48 | the Work and Derivative Works thereof. 49 | 50 | "Contribution" shall mean any work of authorship, including 51 | the original version of the Work and any modifications or additions 52 | to that Work or Derivative Works thereof, that is intentionally 53 | submitted to Licensor for inclusion in the Work by the copyright owner 54 | or by an individual or Legal Entity authorized to submit on behalf of 55 | the copyright owner. For the purposes of this definition, "submitted" 56 | means any form of electronic, verbal, or written communication sent 57 | to the Licensor or its representatives, including but not limited to 58 | communication on electronic mailing lists, source code control systems, 59 | and issue tracking systems that are managed by, or on behalf of, the 60 | Licensor for the purpose of discussing and improving the Work, but 61 | excluding communication that is conspicuously marked or otherwise 62 | designated in writing by the copyright owner as "Not a Contribution." 63 | 64 | "Contributor" shall mean Licensor and any individual or Legal Entity 65 | on behalf of whom a Contribution has been received by Licensor and 66 | subsequently incorporated within the Work. 67 | 68 | 2. Grant of Copyright License. Subject to the terms and conditions of 69 | this License, each Contributor hereby grants to You a perpetual, 70 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 71 | copyright license to reproduce, prepare Derivative Works of, 72 | publicly display, publicly perform, sublicense, and distribute the 73 | Work and such Derivative Works in Source or Object form. 74 | 75 | 3. Grant of Patent License. Subject to the terms and conditions of 76 | this License, each Contributor hereby grants to You a perpetual, 77 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 78 | (except as stated in this section) patent license to make, have made, 79 | use, offer to sell, sell, import, and otherwise transfer the Work, 80 | where such license applies only to those patent claims licensable 81 | by such Contributor that are necessarily infringed by their 82 | Contribution(s) alone or by combination of their Contribution(s) 83 | with the Work to which such Contribution(s) was submitted. If You 84 | institute patent litigation against any entity (including a 85 | cross-claim or counterclaim in a lawsuit) alleging that the Work 86 | or a Contribution incorporated within the Work constitutes direct 87 | or contributory patent infringement, then any patent licenses 88 | granted to You under this License for that Work shall terminate 89 | as of the date such litigation is filed. 90 | 91 | 4. Redistribution. You may reproduce and distribute copies of the 92 | Work or Derivative Works thereof in any medium, with or without 93 | modifications, and in Source or Object form, provided that You 94 | meet the following conditions: 95 | 96 | (a) You must give any other recipients of the Work or 97 | Derivative Works a copy of this License; and 98 | 99 | (b) You must cause any modified files to carry prominent notices 100 | stating that You changed the files; and 101 | 102 | (c) You must retain, in the Source form of any Derivative Works 103 | that You distribute, all copyright, patent, trademark, and 104 | attribution notices from the Source form of the Work, 105 | excluding those notices that do not pertain to any part of 106 | the Derivative Works; and 107 | 108 | (d) If the Work includes a "NOTICE" text file as part of its 109 | distribution, then any Derivative Works that You distribute must 110 | include a readable copy of the attribution notices contained 111 | within such NOTICE file, excluding those notices that do not 112 | pertain to any part of the Derivative Works, in at least one 113 | of the following places: within a NOTICE text file distributed 114 | as part of the Derivative Works; within the Source form or 115 | documentation, if provided along with the Derivative Works; or, 116 | within a display generated by the Derivative Works, if and 117 | wherever such third-party notices normally appear. The contents 118 | of the NOTICE file are for informational purposes only and 119 | do not modify the License. You may add Your own attribution 120 | notices within Derivative Works that You distribute, alongside 121 | or as an addendum to the NOTICE text from the Work, provided 122 | that such additional attribution notices cannot be construed 123 | as modifying the License. 124 | 125 | You may add Your own copyright statement to Your modifications and 126 | may provide additional or different license terms and conditions 127 | for use, reproduction, or distribution of Your modifications, or 128 | for any such Derivative Works as a whole, provided Your use, 129 | reproduction, and distribution of the Work otherwise complies with 130 | the conditions stated in this License. 131 | 132 | 5. Submission of Contributions. Unless You explicitly state otherwise, 133 | any Contribution intentionally submitted for inclusion in the Work 134 | by You to the Licensor shall be under the terms and conditions of 135 | this License, without any additional terms or conditions. 136 | Notwithstanding the above, nothing herein shall supersede or modify 137 | the terms of any separate license agreement you may have executed 138 | with Licensor regarding such Contributions. 139 | 140 | 6. Trademarks. This License does not grant permission to use the trade 141 | names, trademarks, service marks, or product names of the Licensor, 142 | except as required for reasonable and customary use in describing the 143 | origin of the Work and reproducing the content of the NOTICE file. 144 | 145 | 7. Disclaimer of Warranty. Unless required by applicable law or 146 | agreed to in writing, Licensor provides the Work (and each 147 | Contributor provides its Contributions) on an "AS IS" BASIS, 148 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 149 | implied, including, without limitation, any warranties or conditions 150 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 151 | PARTICULAR PURPOSE. You are solely responsible for determining the 152 | appropriateness of using or redistributing the Work and assume any 153 | risks associated with Your exercise of permissions under this License. 154 | 155 | 8. Limitation of Liability. In no event and under no legal theory, 156 | whether in tort (including negligence), contract, or otherwise, 157 | unless required by applicable law (such as deliberate and grossly 158 | negligent acts) or agreed to in writing, shall any Contributor be 159 | liable to You for damages, including any direct, indirect, special, 160 | incidental, or consequential damages of any character arising as a 161 | result of this License or out of the use or inability to use the 162 | Work (including but not limited to damages for loss of goodwill, 163 | work stoppage, computer failure or malfunction, or any and all 164 | other commercial damages or losses), even if such Contributor 165 | has been advised of the possibility of such damages. 166 | 167 | 9. Accepting Warranty or Additional Liability. While redistributing 168 | the Work or Derivative Works thereof, You may choose to offer, 169 | and charge a fee for, acceptance of support, warranty, indemnity, 170 | or other liability obligations and/or rights consistent with this 171 | License. However, in accepting such obligations, You may act only 172 | on Your own behalf and on Your sole responsibility, not on behalf 173 | of any other Contributor, and only if You agree to indemnify, 174 | defend, and hold each Contributor harmless for any liability 175 | incurred by, or claims asserted against, such Contributor by reason 176 | of your accepting any such warranty or additional liability. 177 | 178 | END OF TERMS AND CONDITIONS 179 | 180 | APPENDIX: How to apply the Apache License to your work. 181 | 182 | To apply the Apache License to your work, attach the following 183 | boilerplate notice, with the fields enclosed by brackets "[]" 184 | replaced with your own identifying information. (Don't include 185 | the brackets!) The text should be enclosed in the appropriate 186 | comment syntax for the file format. We also recommend that a 187 | file or class name and description of purpose be included on the 188 | same "printed page" as the copyright notice for easier 189 | identification within third-party archives. 190 | 191 | Copyright [yyyy] [name of copyright owner] 192 | 193 | Licensed under the Apache License, Version 2.0 (the "License"); 194 | you may not use this file except in compliance with the License. 195 | You may obtain a copy of the License at 196 | 197 | http://www.apache.org/licenses/LICENSE-2.0 198 | 199 | Unless required by applicable law or agreed to in writing, software 200 | distributed under the License is distributed on an "AS IS" BASIS, 201 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 202 | See the License for the specific language governing permissions and 203 | limitations under the License. 204 | -------------------------------------------------------------------------------- /firmware/eagle_fw_ate_config_v19.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lichee-Pi/esp8089/72782740c063676eaec2965c26f275907933b85d/firmware/eagle_fw_ate_config_v19.bin -------------------------------------------------------------------------------- /firmware/eagle_fw_first_init_v19.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lichee-Pi/esp8089/72782740c063676eaec2965c26f275907933b85d/firmware/eagle_fw_first_init_v19.bin -------------------------------------------------------------------------------- /firmware/eagle_fw_second_init_v19.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lichee-Pi/esp8089/72782740c063676eaec2965c26f275907933b85d/firmware/eagle_fw_second_init_v19.bin -------------------------------------------------------------------------------- /sdio_sif_esp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 -2013 Espressif System. 3 | * 4 | * sdio serial i/f driver 5 | * - sdio device control routines 6 | * - sync/async DMA/PIO read/write 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "esp_pub.h" 32 | #include "esp_sif.h" 33 | #include "esp_sip.h" 34 | #include "esp_debug.h" 35 | #include "slc_host_register.h" 36 | #include "esp_version.h" 37 | #include "esp_ctrl.h" 38 | #include "esp_file.h" 39 | #ifdef USE_EXT_GPIO 40 | #include "esp_ext.h" 41 | #endif /* USE_EXT_GPIO */ 42 | 43 | /* 44 | * HdG: Note: 45 | * 1) MMC_HAS_FORCE_DETECT_CHANGE is a hack which is set by my sunxi-wip 46 | * tree. FIXME replace with a version check once mmc_force_detect_change() 47 | * is added to the mainline kernel. 48 | * 2) This version does NOT implement keep_power, the dts must mark the 49 | * regulators as regulator-always-on and not use mmc-pwrseq for this stub 50 | * to work. 51 | */ 52 | #ifndef MMC_HAS_FORCE_DETECT_CHANGE 53 | void mmc_force_detect_change(struct mmc_host *host, unsigned long delay, 54 | bool keep_power) 55 | { 56 | host->caps &= ~MMC_CAP_NONREMOVABLE; 57 | host->caps |= MMC_CAP_NEEDS_POLL; 58 | mmc_detect_change(host, delay); 59 | } 60 | #endif 61 | 62 | static int /*__init*/ esp_sdio_init(void); 63 | static void /*__exit*/ esp_sdio_exit(void); 64 | 65 | 66 | #define ESP_DMA_IBUFSZ 2048 67 | 68 | //unsigned int esp_msg_level = 0; 69 | unsigned int esp_msg_level = ESP_DBG_ERROR | ESP_SHOW; 70 | 71 | struct esp_sdio_ctrl *sif_sctrl = NULL; 72 | 73 | #ifdef ESP_ANDROID_LOGGER 74 | bool log_off = false; 75 | #endif /* ESP_ANDROID_LOGGER */ 76 | 77 | static int esdio_power_off(struct esp_sdio_ctrl *sctrl); 78 | static int esdio_power_on(struct esp_sdio_ctrl *sctrl); 79 | 80 | void sif_set_clock(struct sdio_func *func, int clk); 81 | 82 | void sif_lock_bus(struct esp_pub *epub) 83 | { 84 | EPUB_FUNC_CHECK(epub, _exit); 85 | 86 | sdio_claim_host(EPUB_TO_FUNC(epub)); 87 | _exit: 88 | return; 89 | } 90 | 91 | void sif_unlock_bus(struct esp_pub *epub) 92 | { 93 | EPUB_FUNC_CHECK(epub, _exit); 94 | 95 | sdio_release_host(EPUB_TO_FUNC(epub)); 96 | _exit: 97 | return; 98 | } 99 | 100 | static inline bool bad_buf(u8 * buf) 101 | { 102 | return ((unsigned long) buf & 0x3) || !virt_addr_valid(buf); 103 | } 104 | 105 | u8 sdio_io_readb(struct esp_pub *epub, int addr, int *res) 106 | { 107 | struct esp_sdio_ctrl *sctrl = NULL; 108 | struct sdio_func *func = NULL; 109 | sctrl = (struct esp_sdio_ctrl *) epub->sif; 110 | func = sctrl->func; 111 | 112 | if (func->num == 0) 113 | return sdio_f0_readb(func, addr, res); 114 | else 115 | return sdio_readb(func, addr, res); 116 | } 117 | 118 | void sdio_io_writeb(struct esp_pub *epub, u8 value, int addr, int *res) 119 | { 120 | struct esp_sdio_ctrl *sctrl = NULL; 121 | struct sdio_func *func = NULL; 122 | sctrl = (struct esp_sdio_ctrl *) epub->sif; 123 | func = sctrl->func; 124 | 125 | if (func->num == 0) 126 | sdio_f0_writeb(func, value, addr, res); 127 | else 128 | sdio_writeb(func, value, addr, res); 129 | } 130 | 131 | int sif_io_raw(struct esp_pub *epub, u32 addr, u8 * buf, u32 len, u32 flag) 132 | { 133 | int err = 0; 134 | u8 *ibuf = NULL; 135 | bool need_ibuf = false; 136 | struct esp_sdio_ctrl *sctrl = NULL; 137 | struct sdio_func *func = NULL; 138 | 139 | if (epub == NULL || buf == NULL) { 140 | ESSERT(0); 141 | err = -EINVAL; 142 | goto _exit; 143 | } 144 | 145 | sctrl = (struct esp_sdio_ctrl *) epub->sif; 146 | func = sctrl->func; 147 | if (func == NULL) { 148 | ESSERT(0); 149 | err = -EINVAL; 150 | goto _exit; 151 | } 152 | 153 | if (bad_buf(buf)) { 154 | esp_dbg(ESP_DBG_TRACE, "%s dst 0x%08x, len %d badbuf\n", 155 | __func__, addr, len); 156 | need_ibuf = true; 157 | ibuf = sctrl->dma_buffer; 158 | } else { 159 | ibuf = buf; 160 | } 161 | 162 | if (flag & SIF_BLOCK_BASIS) { 163 | /* round up for block data transcation */ 164 | } 165 | 166 | if (flag & SIF_TO_DEVICE) { 167 | 168 | if (need_ibuf) 169 | memcpy(ibuf, buf, len); 170 | 171 | if (flag & SIF_FIXED_ADDR) 172 | err = sdio_writesb(func, addr, ibuf, len); 173 | else if (flag & SIF_INC_ADDR) { 174 | err = sdio_memcpy_toio(func, addr, ibuf, len); 175 | } 176 | } else if (flag & SIF_FROM_DEVICE) { 177 | 178 | if (flag & SIF_FIXED_ADDR) 179 | err = sdio_readsb(func, ibuf, addr, len); 180 | else if (flag & SIF_INC_ADDR) { 181 | err = sdio_memcpy_fromio(func, ibuf, addr, len); 182 | } 183 | 184 | 185 | if (!err && need_ibuf) 186 | memcpy(buf, ibuf, len); 187 | } 188 | 189 | _exit: 190 | return err; 191 | } 192 | 193 | int sif_io_sync(struct esp_pub *epub, u32 addr, u8 * buf, u32 len, 194 | u32 flag) 195 | { 196 | int err = 0; 197 | u8 *ibuf = NULL; 198 | bool need_ibuf = false; 199 | struct esp_sdio_ctrl *sctrl = NULL; 200 | struct sdio_func *func = NULL; 201 | 202 | if (epub == NULL || buf == NULL) { 203 | ESSERT(0); 204 | err = -EINVAL; 205 | goto _exit; 206 | } 207 | 208 | sctrl = (struct esp_sdio_ctrl *) epub->sif; 209 | func = sctrl->func; 210 | if (func == NULL) { 211 | ESSERT(0); 212 | err = -EINVAL; 213 | goto _exit; 214 | } 215 | 216 | if (bad_buf(buf)) { 217 | esp_dbg(ESP_DBG_TRACE, "%s dst 0x%08x, len %d badbuf\n", 218 | __func__, addr, len); 219 | need_ibuf = true; 220 | ibuf = sctrl->dma_buffer; 221 | } else { 222 | ibuf = buf; 223 | } 224 | 225 | if (flag & SIF_BLOCK_BASIS) { 226 | /* round up for block data transcation */ 227 | } 228 | 229 | if (flag & SIF_TO_DEVICE) { 230 | 231 | esp_dbg(ESP_DBG_TRACE, "%s to addr 0x%08x, len %d \n", 232 | __func__, addr, len); 233 | if (need_ibuf) 234 | memcpy(ibuf, buf, len); 235 | 236 | sdio_claim_host(func); 237 | 238 | if (flag & SIF_FIXED_ADDR) 239 | err = sdio_writesb(func, addr, ibuf, len); 240 | else if (flag & SIF_INC_ADDR) { 241 | err = sdio_memcpy_toio(func, addr, ibuf, len); 242 | } 243 | sdio_release_host(func); 244 | } else if (flag & SIF_FROM_DEVICE) { 245 | 246 | esp_dbg(ESP_DBG_TRACE, "%s from addr 0x%08x, len %d \n", 247 | __func__, addr, len); 248 | 249 | sdio_claim_host(func); 250 | 251 | if (flag & SIF_FIXED_ADDR) 252 | err = sdio_readsb(func, ibuf, addr, len); 253 | else if (flag & SIF_INC_ADDR) { 254 | err = sdio_memcpy_fromio(func, ibuf, addr, len); 255 | } 256 | 257 | sdio_release_host(func); 258 | 259 | if (!err && need_ibuf) 260 | memcpy(buf, ibuf, len); 261 | } 262 | 263 | _exit: 264 | return err; 265 | } 266 | 267 | int sif_lldesc_read_sync(struct esp_pub *epub, u8 * buf, u32 len) 268 | { 269 | struct esp_sdio_ctrl *sctrl = NULL; 270 | u32 read_len; 271 | 272 | if (epub == NULL || buf == NULL) { 273 | ESSERT(0); 274 | return -EINVAL; 275 | } 276 | 277 | sctrl = (struct esp_sdio_ctrl *) epub->sif; 278 | 279 | switch (sctrl->target_id) { 280 | case 0x100: 281 | read_len = len; 282 | break; 283 | case 0x600: 284 | read_len = roundup(len, sctrl->slc_blk_sz); 285 | break; 286 | default: 287 | read_len = len; 288 | break; 289 | } 290 | 291 | return sif_io_sync((epub), 292 | (sctrl->slc_window_end_addr - 2 - (len)), (buf), 293 | (read_len), 294 | SIF_FROM_DEVICE | SIF_BYTE_BASIS | 295 | SIF_INC_ADDR); 296 | } 297 | 298 | int sif_lldesc_write_sync(struct esp_pub *epub, u8 * buf, u32 len) 299 | { 300 | struct esp_sdio_ctrl *sctrl = NULL; 301 | u32 write_len; 302 | 303 | if (epub == NULL || buf == NULL) { 304 | ESSERT(0); 305 | return -EINVAL; 306 | } 307 | 308 | sctrl = (struct esp_sdio_ctrl *) epub->sif; 309 | 310 | switch (sctrl->target_id) { 311 | case 0x100: 312 | write_len = len; 313 | break; 314 | case 0x600: 315 | write_len = roundup(len, sctrl->slc_blk_sz); 316 | break; 317 | default: 318 | write_len = len; 319 | break; 320 | } 321 | 322 | return sif_io_sync((epub), (sctrl->slc_window_end_addr - (len)), 323 | (buf), (write_len), 324 | SIF_TO_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR); 325 | } 326 | 327 | int sif_lldesc_read_raw(struct esp_pub *epub, u8 * buf, u32 len, 328 | bool noround) 329 | { 330 | struct esp_sdio_ctrl *sctrl = NULL; 331 | u32 read_len; 332 | 333 | if (epub == NULL || buf == NULL) { 334 | ESSERT(0); 335 | return -EINVAL; 336 | } 337 | 338 | sctrl = (struct esp_sdio_ctrl *) epub->sif; 339 | 340 | switch (sctrl->target_id) { 341 | case 0x100: 342 | read_len = len; 343 | break; 344 | case 0x600: 345 | if (!noround) 346 | read_len = roundup(len, sctrl->slc_blk_sz); 347 | else 348 | read_len = len; 349 | break; 350 | default: 351 | read_len = len; 352 | break; 353 | } 354 | 355 | return sif_io_raw((epub), (sctrl->slc_window_end_addr - 2 - (len)), 356 | (buf), (read_len), 357 | SIF_FROM_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR); 358 | } 359 | 360 | int sif_lldesc_write_raw(struct esp_pub *epub, u8 * buf, u32 len) 361 | { 362 | struct esp_sdio_ctrl *sctrl = NULL; 363 | u32 write_len; 364 | 365 | if (epub == NULL || buf == NULL) { 366 | ESSERT(0); 367 | return -EINVAL; 368 | } 369 | 370 | sctrl = (struct esp_sdio_ctrl *) epub->sif; 371 | 372 | switch (sctrl->target_id) { 373 | case 0x100: 374 | write_len = len; 375 | break; 376 | case 0x600: 377 | write_len = roundup(len, sctrl->slc_blk_sz); 378 | break; 379 | default: 380 | write_len = len; 381 | break; 382 | } 383 | return sif_io_raw((epub), (sctrl->slc_window_end_addr - (len)), 384 | (buf), (write_len), 385 | SIF_TO_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR); 386 | 387 | } 388 | 389 | #define MANUFACTURER_ID_EAGLE_BASE 0x1110 390 | #define MANUFACTURER_ID_EAGLE_BASE_MASK 0xFF00 391 | #define MANUFACTURER_CODE 0x6666 392 | 393 | static const struct sdio_device_id esp_sdio_devices[] = { 394 | {SDIO_DEVICE 395 | (MANUFACTURER_CODE, (MANUFACTURER_ID_EAGLE_BASE | 0x1))}, 396 | {}, 397 | }; 398 | 399 | static int esdio_power_on(struct esp_sdio_ctrl *sctrl) 400 | { 401 | int err = 0; 402 | 403 | if (sctrl->off == false) 404 | return err; 405 | 406 | sdio_claim_host(sctrl->func); 407 | err = sdio_enable_func(sctrl->func); 408 | 409 | if (err) { 410 | esp_dbg(ESP_DBG_ERROR, "Unable to enable sdio func: %d\n", 411 | err); 412 | sdio_release_host(sctrl->func); 413 | return err; 414 | } 415 | 416 | sdio_release_host(sctrl->func); 417 | 418 | /* ensure device is up */ 419 | msleep(5); 420 | 421 | sctrl->off = false; 422 | 423 | return err; 424 | } 425 | 426 | static int esdio_power_off(struct esp_sdio_ctrl *sctrl) 427 | { 428 | int err; 429 | 430 | if (sctrl->off) 431 | return 0; 432 | 433 | sdio_claim_host(sctrl->func); 434 | err = sdio_disable_func(sctrl->func); 435 | sdio_release_host(sctrl->func); 436 | 437 | if (err) 438 | return err; 439 | 440 | sctrl->off = true; 441 | 442 | return err; 443 | } 444 | 445 | void sif_enable_irq(struct esp_pub *epub) 446 | { 447 | int err; 448 | struct esp_sdio_ctrl *sctrl = NULL; 449 | 450 | sctrl = (struct esp_sdio_ctrl *) epub->sif; 451 | 452 | sdio_claim_host(sctrl->func); 453 | 454 | err = sdio_claim_irq(sctrl->func, sif_dsr); 455 | 456 | if (err) 457 | esp_dbg(ESP_DBG_ERROR, "sif %s failed\n", __func__); 458 | 459 | atomic_set(&epub->sip->state, SIP_BOOT); 460 | 461 | atomic_set(&sctrl->irq_installed, 1); 462 | 463 | sdio_release_host(sctrl->func); 464 | } 465 | 466 | void sif_disable_irq(struct esp_pub *epub) 467 | { 468 | struct esp_sdio_ctrl *sctrl = (struct esp_sdio_ctrl *) epub->sif; 469 | int i = 0; 470 | 471 | if (atomic_read(&sctrl->irq_installed) == 0) 472 | return; 473 | 474 | sdio_claim_host(sctrl->func); 475 | 476 | while (atomic_read(&sctrl->irq_handling)) { 477 | sdio_release_host(sctrl->func); 478 | schedule_timeout(HZ / 100); 479 | sdio_claim_host(sctrl->func); 480 | if (i++ >= 400) { 481 | esp_dbg(ESP_DBG_ERROR, "%s force to stop irq\n", 482 | __func__); 483 | break; 484 | } 485 | } 486 | 487 | /* Ignore errors, we don't always use an irq. */ 488 | sdio_release_irq(sctrl->func); 489 | 490 | atomic_set(&sctrl->irq_installed, 0); 491 | 492 | sdio_release_host(sctrl->func); 493 | 494 | } 495 | 496 | void sif_set_clock(struct sdio_func *func, int clk) 497 | { 498 | struct mmc_host *host = NULL; 499 | struct mmc_card *card = NULL; 500 | 501 | card = func->card; 502 | host = card->host; 503 | 504 | sdio_claim_host(func); 505 | 506 | //currently only set clock 507 | host->ios.clock = clk * 1000000; 508 | 509 | esp_dbg(ESP_SHOW, "%s clock is %u\n", __func__, host->ios.clock); 510 | if (host->ios.clock > host->f_max) { 511 | host->ios.clock = host->f_max; 512 | } 513 | host->ops->set_ios(host, &host->ios); 514 | 515 | mdelay(2); 516 | 517 | sdio_release_host(func); 518 | } 519 | 520 | static int esp_sdio_probe(struct sdio_func *func, 521 | const struct sdio_device_id *id); 522 | static void esp_sdio_remove(struct sdio_func *func); 523 | 524 | static int esp_sdio_probe(struct sdio_func *func, 525 | const struct sdio_device_id *id) 526 | { 527 | int err = 0; 528 | struct esp_pub *epub = NULL; 529 | struct esp_sdio_ctrl *sctrl; 530 | struct mmc_host *host = func->card->host; 531 | 532 | esp_dbg(ESP_DBG_TRACE, 533 | "sdio_func_num: 0x%X, vendor id: 0x%X, dev id: 0x%X, block size: 0x%X/0x%X\n", 534 | func->num, func->vendor, func->device, func->max_blksize, 535 | func->cur_blksize); 536 | if (sif_sctrl == NULL) { 537 | request_init_conf(&func->dev); 538 | 539 | sctrl = kzalloc(sizeof(struct esp_sdio_ctrl), GFP_KERNEL); 540 | 541 | if (sctrl == NULL) { 542 | return -ENOMEM; 543 | } 544 | 545 | /* temp buffer reserved for un-dma-able request */ 546 | sctrl->dma_buffer = kzalloc(ESP_DMA_IBUFSZ, GFP_KERNEL); 547 | 548 | if (sctrl->dma_buffer == NULL) { 549 | err = -ENOMEM; 550 | goto _err_last; 551 | } 552 | sif_sctrl = sctrl; 553 | sctrl->slc_blk_sz = SIF_SLC_BLOCK_SIZE; 554 | 555 | epub = esp_pub_alloc_mac80211(&func->dev); 556 | 557 | if (epub == NULL) { 558 | esp_dbg(ESP_DBG_ERROR, "no mem for epub \n"); 559 | err = -ENOMEM; 560 | goto _err_dma; 561 | } 562 | epub->sif = (void *) sctrl; 563 | epub->sdio_state = ESP_SDIO_STATE_FIRST_INIT; 564 | sctrl->epub = epub; 565 | 566 | #ifdef USE_EXT_GPIO 567 | if (sif_get_ate_config() == 0) { 568 | err = ext_gpio_init(epub); 569 | if (err) { 570 | esp_dbg(ESP_DBG_ERROR, 571 | "ext_irq_work_init failed %d\n", 572 | err); 573 | goto _err_epub; 574 | } 575 | } 576 | #endif 577 | 578 | } else { 579 | sctrl = sif_sctrl; 580 | sif_sctrl = NULL; 581 | epub = sctrl->epub; 582 | epub->sdio_state = ESP_SDIO_STATE_SECOND_INIT; 583 | SET_IEEE80211_DEV(epub->hw, &func->dev); 584 | epub->dev = &func->dev; 585 | } 586 | 587 | sctrl->func = func; 588 | sdio_set_drvdata(func, sctrl); 589 | 590 | sctrl->id = id; 591 | sctrl->off = true; 592 | 593 | /* give us some time to enable, in ms */ 594 | func->enable_timeout = 100; 595 | 596 | err = esdio_power_on(sctrl); 597 | esp_dbg(ESP_DBG_TRACE, " %s >> power_on err %d \n", __func__, err); 598 | 599 | if (err) { 600 | if (epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) 601 | goto _err_ext_gpio; 602 | else 603 | goto _err_second_init; 604 | } 605 | check_target_id(epub); 606 | 607 | sdio_claim_host(func); 608 | 609 | err = sdio_set_block_size(func, sctrl->slc_blk_sz); 610 | 611 | if (err) { 612 | esp_dbg(ESP_DBG_ERROR, 613 | "Set sdio block size %d failed: %d)\n", 614 | sctrl->slc_blk_sz, err); 615 | sdio_release_host(func); 616 | if (epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) 617 | goto _err_off; 618 | else 619 | goto _err_second_init; 620 | } 621 | 622 | sdio_release_host(func); 623 | 624 | #ifdef LOWER_CLK 625 | /* fix clock for dongle */ 626 | sif_set_clock(func, 23); 627 | #endif //LOWER_CLK 628 | 629 | err = esp_pub_init_all(epub); 630 | 631 | if (err) { 632 | esp_dbg(ESP_DBG_ERROR, "esp_init_all failed: %d\n", err); 633 | if (epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) { 634 | err = 0; 635 | goto _err_first_init; 636 | } 637 | if (epub->sdio_state == ESP_SDIO_STATE_SECOND_INIT) 638 | goto _err_second_init; 639 | } 640 | 641 | esp_dbg(ESP_DBG_TRACE, " %s return %d\n", __func__, err); 642 | if (epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) { 643 | esp_dbg(ESP_DBG_TRACE, "first normal exit\n"); 644 | epub->sdio_state = ESP_SDIO_STATE_FIRST_NORMAL_EXIT; 645 | /* Rescan the esp8089 after loading the initial firmware */ 646 | mmc_force_detect_change(host, msecs_to_jiffies(100), true); 647 | } 648 | 649 | return err; 650 | 651 | _err_off: 652 | esdio_power_off(sctrl); 653 | _err_ext_gpio: 654 | #ifdef USE_EXT_GPIO 655 | if (sif_get_ate_config() == 0) 656 | ext_gpio_deinit(); 657 | _err_epub: 658 | #endif 659 | esp_pub_dealloc_mac80211(epub); 660 | _err_dma: 661 | kfree(sctrl->dma_buffer); 662 | _err_last: 663 | kfree(sctrl); 664 | _err_first_init: 665 | if (epub && epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT) { 666 | esp_dbg(ESP_DBG_ERROR, "first error exit\n"); 667 | epub->sdio_state = ESP_SDIO_STATE_FIRST_ERROR_EXIT; 668 | } 669 | return err; 670 | _err_second_init: 671 | epub->sdio_state = ESP_SDIO_STATE_SECOND_ERROR_EXIT; 672 | esp_sdio_remove(func); 673 | return err; 674 | } 675 | 676 | static void esp_sdio_remove(struct sdio_func *func) 677 | { 678 | struct esp_sdio_ctrl *sctrl = NULL; 679 | struct esp_pub *epub = NULL; 680 | 681 | esp_dbg(ESP_DBG_TRACE, "%s enter\n", __func__); 682 | 683 | sctrl = sdio_get_drvdata(func); 684 | 685 | if (sctrl == NULL) { 686 | esp_dbg(ESP_DBG_ERROR, "%s no sctrl\n", __func__); 687 | return; 688 | } 689 | 690 | do { 691 | epub = sctrl->epub; 692 | if (epub == NULL) { 693 | esp_dbg(ESP_DBG_ERROR, "%s epub null\n", __func__); 694 | break; 695 | } 696 | if (epub->sdio_state != ESP_SDIO_STATE_FIRST_NORMAL_EXIT) { 697 | if (epub->sip) { 698 | sip_detach(epub->sip); 699 | epub->sip = NULL; 700 | esp_dbg(ESP_DBG_TRACE, 701 | "%s sip detached \n", __func__); 702 | } 703 | #ifdef USE_EXT_GPIO 704 | if (sif_get_ate_config() == 0) 705 | ext_gpio_deinit(); 706 | #endif 707 | } else { 708 | //sif_disable_target_interrupt(epub); 709 | atomic_set(&epub->sip->state, SIP_STOP); 710 | sif_disable_irq(epub); 711 | } 712 | 713 | if (epub->sdio_state != ESP_SDIO_STATE_FIRST_NORMAL_EXIT) { 714 | esp_pub_dealloc_mac80211(epub); 715 | esp_dbg(ESP_DBG_TRACE, "%s dealloc mac80211 \n", 716 | __func__); 717 | 718 | if (sctrl->dma_buffer) { 719 | kfree(sctrl->dma_buffer); 720 | sctrl->dma_buffer = NULL; 721 | esp_dbg(ESP_DBG_TRACE, 722 | "%s free dma_buffer \n", __func__); 723 | } 724 | 725 | kfree(sctrl); 726 | } 727 | 728 | } while (0); 729 | 730 | sdio_set_drvdata(func, NULL); 731 | 732 | esp_dbg(ESP_DBG_TRACE, "eagle sdio remove complete\n"); 733 | } 734 | 735 | MODULE_DEVICE_TABLE(sdio, esp_sdio_devices); 736 | 737 | static int esp_sdio_suspend(struct device *dev) 738 | { 739 | struct sdio_func *func = dev_to_sdio_func(dev); 740 | struct esp_sdio_ctrl *sctrl = sdio_get_drvdata(func); 741 | struct esp_pub *epub = sctrl->epub; 742 | 743 | printk("%s", __func__); 744 | atomic_set(&epub->ps.state, ESP_PM_ON); 745 | 746 | do { 747 | u32 sdio_flags = 0; 748 | int ret = 0; 749 | sdio_flags = sdio_get_host_pm_caps(func); 750 | 751 | if (!(sdio_flags & MMC_PM_KEEP_POWER)) { 752 | printk 753 | ("%s can't keep power while host is suspended\n", 754 | __func__); 755 | } 756 | 757 | /* keep power while host suspended */ 758 | ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); 759 | if (ret) { 760 | printk("%s error while trying to keep power\n", 761 | __func__); 762 | } 763 | } while (0); 764 | 765 | 766 | return 0; 767 | 768 | } 769 | 770 | static int esp_sdio_resume(struct device *dev) 771 | { 772 | esp_dbg(ESP_DBG_ERROR, "%s", __func__); 773 | 774 | return 0; 775 | } 776 | 777 | static const struct dev_pm_ops esp_sdio_pm_ops = { 778 | .suspend = esp_sdio_suspend, 779 | .resume = esp_sdio_resume, 780 | }; 781 | 782 | static struct sdio_driver esp_sdio_driver = { 783 | .name = "eagle_sdio", 784 | .id_table = esp_sdio_devices, 785 | .probe = esp_sdio_probe, 786 | .remove = esp_sdio_remove, 787 | .drv = {.pm = &esp_sdio_pm_ops,}, 788 | }; 789 | 790 | static int /*__init*/ esp_sdio_init(void) 791 | { 792 | esp_debugfs_init(); 793 | 794 | sdio_register_driver(&esp_sdio_driver); 795 | return 0; 796 | } 797 | 798 | static void /*__exit*/ esp_sdio_exit(void) 799 | { 800 | sdio_unregister_driver(&esp_sdio_driver); 801 | esp_debugfs_exit(); 802 | } 803 | 804 | MODULE_AUTHOR("Espressif System"); 805 | MODULE_DESCRIPTION 806 | ("Driver for SDIO interconnected eagle low-power WLAN devices"); 807 | MODULE_LICENSE("GPL"); 808 | 809 | module_init(esp_sdio_init); 810 | module_exit(esp_sdio_exit); 811 | -------------------------------------------------------------------------------- /sip2_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 - 2014 Espressif System. 3 | * 4 | * Common definitions of Serial Interconnctor Protocol 5 | * 6 | * little endian 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | */ 18 | 19 | #ifndef _SIP2_COMMON_H 20 | #define _SIP2_COMMON_H 21 | 22 | #ifdef __ets__ 23 | #include "utils.h" 24 | #endif /*__ets__*/ 25 | 26 | /* max 16 types */ 27 | typedef enum { 28 | SIP_CTRL = 0, 29 | SIP_DATA, 30 | SIP_DATA_AMPDU 31 | } SIP_TYPE; 32 | 33 | typedef enum { 34 | SIP_TX_CTRL_BUF = 0, /* from host */ 35 | SIP_RX_CTRL_BUF, /* to host */ 36 | SIP_TX_DATA_BUF, /* from host */ 37 | SIP_RX_DATA_BUF /* to host */ 38 | } SIP_BUF_TYPE; 39 | 40 | enum sip_cmd_id { 41 | SIP_CMD_GET_VER = 0, 42 | SIP_CMD_WRITE_MEMORY, //1 ROM code 43 | SIP_CMD_READ_MEMORY, //2 44 | SIP_CMD_WRITE_REG, //3 ROM code 45 | SIP_CMD_READ_REG, //4 46 | SIP_CMD_BOOTUP, //5 ROM code 47 | SIP_CMD_COPYBACK, //6 48 | SIP_CMD_INIT, //7 49 | SIP_CMD_SCAN, //8 50 | SIP_CMD_SETKEY, //9 51 | SIP_CMD_CONFIG, //10 52 | SIP_CMD_BSS_INFO_UPDATE, //11 53 | SIP_CMD_LOOPBACK, //12 ROM code 54 | //do not add cmd before this line 55 | SIP_CMD_SET_WMM_PARAM, 56 | SIP_CMD_AMPDU_ACTION, 57 | SIP_CMD_HB_REQ, //15 58 | SIP_CMD_RESET_MAC, //16 59 | SIP_CMD_PRE_DOWN, //17 60 | SIP_CMD_SLEEP, /* for sleep testing */ 61 | SIP_CMD_WAKEUP, /* for sleep testing */ 62 | SIP_CMD_DEBUG, /* for general testing */ 63 | SIP_CMD_GET_FW_VER, /* get fw rev. */ 64 | SIP_CMD_SETVIF, 65 | SIP_CMD_SETSTA, 66 | SIP_CMD_PS, 67 | SIP_CMD_ATE, 68 | SIP_CMD_SUSPEND, 69 | SIP_CMD_RECALC_CREDIT, 70 | SIP_CMD_MAX, 71 | }; 72 | 73 | enum { 74 | SIP_EVT_TARGET_ON = 0, // 75 | SIP_EVT_BOOTUP, //1 in ROM code 76 | SIP_EVT_COPYBACK, //2 77 | SIP_EVT_SCAN_RESULT, //3 78 | SIP_EVT_TX_STATUS, //4 79 | SIP_EVT_CREDIT_RPT, //5, in ROM code 80 | SIP_EVT_ERROR, //6 81 | SIP_EVT_LOOPBACK, //7, in ROM code 82 | SIP_EVT_SNPRINTF_TO_HOST, //8 in ROM code 83 | //do not add evt before this line 84 | SIP_EVT_HB_ACK, //9 85 | SIP_EVT_RESET_MAC_ACK, //10 86 | SIP_EVT_WAKEUP, //11 /* for sleep testing */ 87 | SIP_EVT_DEBUG, //12 /* for general testing */ 88 | SIP_EVT_PRINT_TO_HOST, //13 89 | SIP_EVT_TRC_AMPDU, //14 90 | SIP_EVT_ROC, //15 91 | SIP_EVT_RESETTING, 92 | SIP_EVT_ATE, 93 | SIP_EVT_EP, 94 | SIP_EVT_INIT_EP, 95 | SIP_EVT_SLEEP, 96 | SIP_EVT_TXIDLE, 97 | SIP_EVT_NOISEFLOOR, 98 | SIP_EVT_MAX 99 | }; 100 | 101 | #define SIP_IFIDX_MASK 0xf0 102 | #define SIP_IFIDX_S 4 103 | #define SIP_TYPE_MASK 0x0f 104 | #define SIP_TYPE_S 0 105 | 106 | #define SIP_HDR_GET_IFIDX(fc0) (((fc0) & SIP_IFIDX_MASK) >> SIP_IFIDX_S) 107 | #define SIP_HDR_SET_IFIDX(fc0, ifidx) ( (fc0) = ((fc0) & ~SIP_IFIDX_MASK) | ((ifidx) << SIP_IFIDX_S & SIP_IFIDX_MASK) ) 108 | #define SIP_HDR_GET_TYPE(fc0) ((fc0) & SIP_TYPE_MASK ) 109 | /* assume type field is cleared */ 110 | #define SIP_HDR_SET_TYPE(fc0, type) ((fc0) = ((fc0) & ~ SIP_TYPE_MASK) | ((type) & SIP_TYPE_MASK)) 111 | 112 | /* sip 2.0, not hybrid header so far */ 113 | #define SIP_HDR_IS_CTRL(hdr) (SIP_HDR_GET_TYPE((hdr)->fc[0]) == SIP_CTRL) 114 | #define SIP_HDR_IS_DATA(hdr) (SIP_HDR_GET_TYPE((hdr)->fc[0]) == SIP_DATA) 115 | #define SIP_HDR_IS_AMPDU(hdr) (SIP_HDR_GET_TYPE((hdr)->fc[0]) == SIP_DATA_AMPDU) 116 | 117 | /* fc[1] flags, only for data pkt. Ctrl pkts use fc[1] as eventID */ 118 | #define SIP_HDR_SET_FLAGS(hdr, flags) ((hdr)->fc[1] |= (flags)) 119 | #define SIP_HDR_F_MORE_PKT 0x1 120 | #define SIP_HDR_F_NEED_CRDT_RPT 0x2 121 | #define SIP_HDR_F_SYNC 0x4 122 | #define SIP_HDR_F_SYNC_RESET 0x8 123 | #define SIP_HDR_F_PM_TURNING_ON 0x10 124 | #define SIP_HDR_F_PM_TURNING_OFF 0x20 125 | 126 | #define SIP_HDR_NEED_CREDIT_UPDATE(hdr) ((hdr)->fc[1] & SIP_HDR_F_NEED_CRDT_RPT) 127 | #define SIP_HDR_IS_MORE_PKT(hdr) ((hdr)->fc[1] & SIP_HDR_F_MORE_PKT) 128 | #define SIP_HDR_IS_CRDT_RPT(hdr) ((hdr)->fc[1] & SIP_HDR_F_CRDT_RPT) 129 | #define SIP_HDR_IS_SYNC(hdr) ((hdr)->fc[1] & SIP_HDR_F_SYNC) 130 | #define SIP_HDR_IS_SYNC_RESET(hdr) ((hdr)->fc[1] & SIP_HDR_F_SYNC_RESET) 131 | #define SIP_HDR_IS_SYNC_PKT(hdr) (SIP_HDR_IS_SYNC(hdr) | SIP_HDR_IS_SYNC_RESET(hdr)) 132 | #define SIP_HDR_SET_SYNC(hdr) SIP_HDR_SET_FLAGS((hdr), SIP_HDR_F_SYNC) 133 | #define SIP_HDR_SET_SYNC_RESET(hdr) SIP_HDR_SET_FLAGS((hdr), SIP_HDR_F_SYNC_RESET) 134 | #define SIP_HDR_SET_MORE_PKT(hdr) SIP_HDR_SET_FLAGS((hdr), SIP_HDR_F_MORE_PKT) 135 | #define SIP_HDR_SET_PM_TURNING_ON(hdr) SIP_HDR_SET_FLAGS((hdr), SIP_HDR_F_PM_TURNING_ON) 136 | #define SIP_HDR_IS_PM_TURNING_ON(hdr) ((hdr)->fc[1] & SIP_HDR_F_PM_TURNING_ON) 137 | #define SIP_HDR_SET_PM_TURNING_OFF(hdr) SIP_HDR_SET_FLAGS((hdr), SIP_HDR_F_PM_TURNING_OFF) 138 | #define SIP_HDR_IS_PM_TURNING_OFF(hdr) ((hdr)->fc[1] & SIP_HDR_F_PM_TURNING_OFF) 139 | 140 | /* 141 | * fc[0]: first 4bit: ifidx; last 4bit: type 142 | * fc[1]: flags 143 | * 144 | * Don't touch the header definitons 145 | */ 146 | struct sip_hdr_min { 147 | u8 fc[2]; 148 | __le16 len; 149 | } __packed; 150 | 151 | /* not more than 4byte long */ 152 | struct sip_tx_data_info { 153 | u8 tid; 154 | u8 ac; 155 | u8 p2p:1, enc_flag:7; 156 | u8 hw_kid; 157 | } __packed; 158 | 159 | /* NB: this structure should be not more than 4byte !! */ 160 | struct sip_tx_info { 161 | union { 162 | u32 cmdid; 163 | struct sip_tx_data_info dinfo; 164 | } u; 165 | } __packed; 166 | 167 | struct sip_hdr { 168 | u8 fc[2]; //fc[0]: type and ifidx ; fc[1] is eventID if the first ctrl pkt in the chain. data pkt still can use fc[1] to set flag 169 | __le16 len; 170 | union { 171 | volatile u32 recycled_credits; /* last 12bits is credits, first 20 bits is actual length of the first pkt in the chain */ 172 | struct sip_tx_info tx_info; 173 | } u; 174 | u32 seq; 175 | } __packed; 176 | 177 | #define h_credits u.recycled_credits 178 | #define c_evtid fc[1] 179 | #define c_cmdid u.tx_info.u.cmdid 180 | #define d_ac u.tx_info.u.dinfo.ac 181 | #define d_tid u.tx_info.u.dinfo.tid 182 | #define d_p2p u.tx_info.u.dinfo.p2p 183 | #define d_enc_flag u.tx_info.u.dinfo.enc_flag 184 | #define d_hw_kid u.tx_info.u.dinfo.hw_kid 185 | 186 | #define SIP_CREDITS_MASK 0xfff /* last 12 bits */ 187 | 188 | #ifdef HOST_RC 189 | 190 | #define RC_CNT_MASK 0xf 191 | 192 | struct sip_rc_status { 193 | u32 rc_map; 194 | union { 195 | u32 rc_cnt1:4, rc_cnt2:4, rc_cnt3:4, rc_cnt4:4, rc_cnt5:4; 196 | 197 | u32 rc_cnt_store; 198 | }; 199 | }; 200 | 201 | /* copy from mac80211.h */ 202 | struct sip_tx_rc { 203 | struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES]; 204 | s8 rts_cts_rate_idx; 205 | }; 206 | #endif /* HOST_RC */ 207 | 208 | #define SIP_HDR_MIN_LEN 4 209 | #define SIP_HDR_LEN sizeof(struct sip_hdr) 210 | #define SIP_CTRL_HDR_LEN SIP_HDR_LEN /* same as sip_hdr in sip2 design */ 211 | #define SIP_BOOT_BUF_SIZE 256 212 | #define SIP_CTRL_BUF_SZ 256 /* too much?? */ 213 | #define SIP_CTRL_BUF_N 6 214 | #define SIP_CTRL_TXBUF_N 2 215 | #define SIP_CTRL_RXBUF_N 4 216 | 217 | /* WAR for mblk */ 218 | #define SIP_RX_ADDR_PREFIX_MASK 0xfc000000 219 | #define SIP_RX_ADDR_SHIFT 6 /* [31:5], shift 6 bits */ 220 | 221 | struct sip_cmd_write_memory { 222 | u32 addr; 223 | u32 len; 224 | } __packed; 225 | 226 | struct sip_cmd_read_memory { 227 | u32 addr; 228 | u32 len; 229 | } __packed; 230 | 231 | struct sip_cmd_write_reg { 232 | u32 addr; 233 | u32 val; 234 | } __packed; 235 | 236 | struct sip_cmd_bootup { 237 | u32 boot_addr; 238 | } __packed; 239 | 240 | struct sip_cmd_loopback { 241 | u32 txlen; //host to target packet len, 0 means no txpacket 242 | u32 rxlen; //target to host packet len, 0 means no rxpacket 243 | u32 pack_id; //sequence of packet 244 | } __packed; 245 | 246 | struct sip_evt_loopback { 247 | u32 txlen; //host to target packet len, 0 means no txpacket 248 | u32 rxlen; //target to host packet len, 0 means no rxpacket 249 | u32 pack_id; //sequence of packet 250 | } __packed; 251 | 252 | struct sip_cmd_copyback { 253 | u32 addr; 254 | u32 len; 255 | } __packed; 256 | 257 | struct sip_cmd_scan { 258 | // u8 ssid[32]; 259 | u8 ssid_len; 260 | // u8 hw_channel[14]; 261 | u8 n_channels; 262 | u8 ie_len; 263 | u8 aborted; 264 | } __packed; // ie[] append at the end 265 | 266 | 267 | #ifndef ETH_ALEN 268 | #define ETH_ALEN 6 269 | #endif /* ETH_ALEN */ 270 | 271 | struct sip_cmd_setkey { 272 | u8 bssid_no; 273 | u8 addr[ETH_ALEN]; 274 | u8 alg; 275 | u8 keyidx; 276 | u8 hw_key_idx; 277 | u8 flags; 278 | u8 keylen; 279 | u8 key[32]; 280 | } __packed; 281 | 282 | struct sip_cmd_config { 283 | u16 center_freq; 284 | u16 duration; 285 | } __packed; 286 | 287 | struct sip_cmd_bss_info_update { 288 | u8 bssid[ETH_ALEN]; 289 | u16 isassoc; 290 | u32 beacon_int; 291 | u8 bssid_no; 292 | } __packed; 293 | 294 | struct sip_evt_bootup { 295 | u16 tx_blksz; 296 | u8 mac_addr[ETH_ALEN]; 297 | /* anything else ? */ 298 | } __packed; 299 | 300 | struct sip_cmd_setvif { 301 | u8 index; 302 | u8 mac[ETH_ALEN]; 303 | u8 set; 304 | u8 op_mode; 305 | u8 is_p2p; 306 | } __packed; 307 | 308 | enum esp_ieee80211_phytype { 309 | ESP_IEEE80211_T_CCK = 0, 310 | ESP_IEEE80211_T_OFDM = 1, 311 | ESP_IEEE80211_T_HT20_L = 2, 312 | ESP_IEEE80211_T_HT20_S = 3, 313 | }; 314 | 315 | struct sip_cmd_setsta { 316 | u8 ifidx; 317 | u8 index; 318 | u8 set; 319 | u8 phymode; 320 | u8 mac[ETH_ALEN]; 321 | u16 aid; 322 | u8 ampdu_factor; 323 | u8 ampdu_density; 324 | u16 resv; 325 | } __packed; 326 | 327 | struct sip_cmd_ps { 328 | u8 dtim_period; 329 | u8 max_sleep_period; 330 | u8 on; 331 | u8 resv; 332 | } __packed; 333 | 334 | struct sip_cmd_suspend { 335 | u8 suspend; 336 | u8 resv[3]; 337 | } __packed; 338 | 339 | #define SIP_DUMP_RPBM_ERR BIT(0) 340 | #define SIP_RXABORT_FIXED BIT(1) 341 | #define SIP_SUPPORT_BGSCAN BIT(2) 342 | struct sip_evt_bootup2 { 343 | u16 tx_blksz; 344 | u8 mac_addr[ETH_ALEN]; 345 | u16 rx_blksz; 346 | u8 credit_to_reserve; 347 | u8 options; 348 | s16 noise_floor; 349 | u8 resv[2]; 350 | /* anything else ? */ 351 | } __packed; 352 | 353 | typedef enum { 354 | TRC_TX_AMPDU_STOPPED = 1, 355 | TRC_TX_AMPDU_OPERATIONAL, 356 | TRC_TX_AMPDU_WAIT_STOP, 357 | TRC_TX_AMPDU_WAIT_OPERATIONAL, 358 | TRC_TX_AMPDU_START, 359 | } trc_ampdu_state_t; 360 | 361 | struct sip_evt_trc_ampdu { 362 | u8 state; 363 | u8 tid; 364 | u8 addr[ETH_ALEN]; 365 | } __packed; 366 | 367 | struct sip_cmd_set_wmm_params { 368 | u8 aci; 369 | u8 aifs; 370 | u8 ecw_min; 371 | u8 ecw_max; 372 | u16 txop_us; 373 | } __packed; 374 | 375 | #define SIP_AMPDU_RX_START 0 376 | #define SIP_AMPDU_RX_STOP 1 377 | #define SIP_AMPDU_TX_OPERATIONAL 2 378 | #define SIP_AMPDU_TX_STOP 3 379 | struct sip_cmd_ampdu_action { 380 | u8 action; 381 | u8 index; 382 | u8 tid; 383 | u8 win_size; 384 | u16 ssn; 385 | u8 addr[ETH_ALEN]; 386 | } __packed; 387 | 388 | #define SIP_TX_ST_OK 0 389 | #define SIP_TX_ST_NOEB 1 390 | #define SIP_TX_ST_ACKTO 2 391 | #define SIP_TX_ST_ENCERR 3 392 | 393 | //NB: sip_tx_status must be 4 bytes aligned 394 | struct sip_tx_status { 395 | u32 sip_seq; 396 | #ifdef HOST_RC 397 | struct sip_rc_status rcstatus; 398 | #endif /* HOST_RC */ 399 | u8 errno; /* success or failure code */ 400 | u8 rate_index; 401 | char ack_signal; 402 | u8 pad; 403 | } __packed; 404 | 405 | struct sip_evt_tx_report { 406 | u32 pkts; 407 | struct sip_tx_status status[0]; 408 | } __packed; 409 | 410 | struct sip_evt_tx_mblk { 411 | u32 mblk_map; 412 | } __packed; 413 | 414 | struct sip_evt_scan_report { 415 | u16 scan_id; 416 | u16 aborted; 417 | } __packed; 418 | 419 | struct sip_evt_roc { 420 | u16 state; //start:1, end :0 421 | u16 is_ok; 422 | } __packed; 423 | 424 | struct sip_evt_txidle { 425 | u32 last_seq; 426 | } __packed; 427 | 428 | struct sip_evt_noisefloor { 429 | s16 noise_floor; 430 | u16 pad; 431 | } __packed; 432 | /* 433 | * for mblk direct memory access, no need for sip_hdr. tx: first 2k for contrl msg, 434 | * rest of 14k for data. rx, same. 435 | */ 436 | #ifdef TEST_MODE 437 | 438 | struct sip_cmd_sleep { 439 | u32 sleep_mode; 440 | u32 sleep_tm_ms; 441 | u32 wakeup_tm_ms; //zero: after receive bcn, then sleep, nozero: delay nozero ms to sleep 442 | u32 sleep_times; //zero: always sleep, nozero: after nozero number sleep/wakeup, then end up sleep 443 | } __packed; 444 | 445 | struct sip_cmd_wakeup { 446 | u32 check_data; //0:copy to event 447 | } __packed; 448 | 449 | struct sip_evt_wakeup { 450 | u32 check_data; 451 | } __packed; 452 | 453 | //general debug command 454 | struct sip_cmd_debug { 455 | u32 cmd_type; 456 | u32 para_num; 457 | u32 para[10]; 458 | } __packed; 459 | 460 | struct sip_evt_debug { 461 | u16 len; 462 | u32 results[12]; 463 | u16 pad; 464 | } __packed; 465 | 466 | struct sip_cmd_ate { 467 | //u8 len; 468 | u8 cmdstr[0]; 469 | } __packed; 470 | 471 | 472 | 473 | #endif //ifdef TEST_MODE 474 | 475 | #endif /* _SIP_COMMON_H_ */ 476 | -------------------------------------------------------------------------------- /slc_host_register.h: -------------------------------------------------------------------------------- 1 | //Generated at 2012-10-23 20:11:08 2 | /* 3 | * Copyright (c) 2011 Espressif System 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | */ 15 | 16 | #ifndef SLC_HOST_REGISTER_H_INCLUDED 17 | #define SLC_HOST_REGISTER_H_INCLUDED 18 | 19 | /* #define REG_SLC_HOST_BASE 0x00000000 */ 20 | /* skip the token1, since reading it will clean the credit */ 21 | #define REG_SLC_HOST_BASE 0x00000000 22 | #define REG_SLC_BASE 0x00000000 23 | 24 | 25 | #define SLC_HOST_PF (REG_SLC_HOST_BASE + 0x0) 26 | #define SLC_HOST_TOKEN_RDATA (REG_SLC_HOST_BASE + 0x4) 27 | #define SLC_HOST_RX_PF_EOF 0x0000000F 28 | #define SLC_HOST_RX_PF_EOF_S 28 29 | #define SLC_HOST_TOKEN1 0x00000FFF 30 | #define SLC_HOST_TOKEN1_S 16 31 | #define SLC_HOST_RX_PF_VALID (BIT(15)) 32 | #define SLC_HOST_TOKEN0 0x00000FFF 33 | #define SLC_HOST_TOKEN0_S 0 34 | 35 | #define SLC_HOST_TOKEN0_MASK SLC_HOST_TOKEN0 36 | 37 | #define SLC_HOST_INT_RAW (REG_SLC_HOST_BASE + 0x8) 38 | #define SLC_HOST_EXT_BIT3_INT_RAW (BIT(22)) 39 | #define SLC_HOST_EXT_BIT2_INT_RAW (BIT(21)) 40 | #define SLC_HOST_EXT_BIT1_INT_RAW (BIT(20)) 41 | #define SLC_HOST_RXFIFO_NOT_EMPTY_INT_RAW (BIT(19)) 42 | #define SLC_HOST_RX_PF_VALID_INT_RAW (BIT(18)) 43 | #define SLC_HOST_TX_OVF_INT_RAW (BIT(17)) 44 | #define SLC_HOST_RX_UDF_INT_RAW (BIT(16)) 45 | #define SLC_HOST_TX_START_INT_RAW (BIT(15)) 46 | #define SLC_HOST_RX_START_INT_RAW (BIT(14)) 47 | #define SLC_HOST_RX_EOF_INT_RAW (BIT(13)) 48 | #define SLC_HOST_RX_SOF_INT_RAW (BIT(12)) 49 | #define SLC_HOST_TOKEN1_0TO1_INT_RAW (BIT(11)) 50 | #define SLC_HOST_TOKEN0_0TO1_INT_RAW (BIT(10)) 51 | #define SLC_HOST_TOKEN1_1TO0_INT_RAW (BIT(9)) 52 | #define SLC_HOST_TOKEN0_1TO0_INT_RAW (BIT(8)) 53 | #define SLC_HOST_TOHOST_BIT7_INT_RAW (BIT(7)) 54 | #define SLC_HOST_TOHOST_BIT6_INT_RAW (BIT(6)) 55 | #define SLC_HOST_TOHOST_BIT5_INT_RAW (BIT(5)) 56 | #define SLC_HOST_TOHOST_BIT4_INT_RAW (BIT(4)) 57 | #define SLC_HOST_TOHOST_BIT3_INT_RAW (BIT(3)) 58 | #define SLC_HOST_TOHOST_BIT2_INT_RAW (BIT(2)) 59 | #define SLC_HOST_TOHOST_BIT1_INT_RAW (BIT(1)) 60 | #define SLC_HOST_TOHOST_BIT0_INT_RAW (BIT(0)) 61 | 62 | #define SLC_HOST_STATE_W0 (REG_SLC_HOST_BASE + 0xC) 63 | #define SLC_HOST_STATE3 0x000000FF 64 | #define SLC_HOST_STATE3_S 24 65 | #define SLC_HOST_STATE2 0x000000FF 66 | #define SLC_HOST_STATE2_S 16 67 | #define SLC_HOST_STATE1 0x000000FF 68 | #define SLC_HOST_STATE1_S 8 69 | #define SLC_HOST_STATE0 0x000000FF 70 | #define SLC_HOST_STATE0_S 0 71 | 72 | #define SLC_HOST_STATE_W1 (REG_SLC_HOST_BASE + 0x10) 73 | #define SLC_HOST_STATE7 0x000000FF 74 | #define SLC_HOST_STATE7_S 24 75 | #define SLC_HOST_STATE6 0x000000FF 76 | #define SLC_HOST_STATE6_S 16 77 | #define SLC_HOST_STATE5 0x000000FF 78 | #define SLC_HOST_STATE5_S 8 79 | #define SLC_HOST_STATE4 0x000000FF 80 | #define SLC_HOST_STATE4_S 0 81 | 82 | #define SLC_HOST_CONF_W0 (REG_SLC_HOST_BASE + 0x14) 83 | #define SLC_HOST_CONF3 0x000000FF 84 | #define SLC_HOST_CONF3_S 24 85 | #define SLC_HOST_CONF2 0x000000FF 86 | #define SLC_HOST_CONF2_S 16 87 | #define SLC_HOST_CONF1 0x000000FF 88 | #define SLC_HOST_CONF1_S 8 89 | #define SLC_HOST_CONF0 0x000000FF 90 | #define SLC_HOST_CONF0_S 0 91 | 92 | #define SLC_HOST_CONF_W1 (REG_SLC_HOST_BASE + 0x18) 93 | #define SLC_HOST_CONF7 0x000000FF 94 | #define SLC_HOST_CONF7_S 24 95 | #define SLC_HOST_CONF6 0x000000FF 96 | #define SLC_HOST_CONF6_S 16 97 | #define SLC_HOST_CONF5 0x000000FF 98 | #define SLC_HOST_CONF5_S 8 99 | #define SLC_HOST_CONF4 0x000000FF 100 | #define SLC_HOST_CONF4_S 0 101 | 102 | #define SLC_HOST_INT_ST (REG_SLC_HOST_BASE + 0x1C) 103 | #define SLC_HOST_RX_ST (BIT(23)) 104 | #define SLC_HOST_EXT_BIT3_INT_ST (BIT(22)) 105 | #define SLC_HOST_EXT_BIT2_INT_ST (BIT(21)) 106 | #define SLC_HOST_EXT_BIT1_INT_ST (BIT(20)) 107 | #define SLC_HOST_RXFIFO_NOT_EMPTY_INT_ST (BIT(19)) 108 | #define SLC_HOST_RX_PF_VALID_INT_ST (BIT(18)) 109 | #define SLC_HOST_TX_OVF_INT_ST (BIT(17)) 110 | #define SLC_HOST_RX_UDF_INT_ST (BIT(16)) 111 | #define SLC_HOST_TX_START_INT_ST (BIT(15)) 112 | #define SLC_HOST_RX_START_INT_ST (BIT(14)) 113 | #define SLC_HOST_RX_EOF_INT_ST (BIT(13)) 114 | #define SLC_HOST_RX_SOF_INT_ST (BIT(12)) 115 | #define SLC_HOST_TOKEN1_0TO1_INT_ST (BIT(11)) 116 | #define SLC_HOST_TOKEN0_0TO1_INT_ST (BIT(10)) 117 | #define SLC_HOST_TOKEN1_1TO0_INT_ST (BIT(9)) 118 | #define SLC_HOST_TOKEN0_1TO0_INT_ST (BIT(8)) 119 | #define SLC_HOST_TOHOST_BIT7_INT_ST (BIT(7)) 120 | #define SLC_HOST_TOHOST_BIT6_INT_ST (BIT(6)) 121 | #define SLC_HOST_TOHOST_BIT5_INT_ST (BIT(5)) 122 | #define SLC_HOST_TOHOST_BIT4_INT_ST (BIT(4)) 123 | #define SLC_HOST_TOHOST_BIT3_INT_ST (BIT(3)) 124 | #define SLC_HOST_TOHOST_BIT2_INT_ST (BIT(2)) 125 | #define SLC_HOST_TOHOST_BIT1_INT_ST (BIT(1)) 126 | #define SLC_HOST_TOHOST_BIT0_INT_ST (BIT(0)) 127 | 128 | #define SLC_HOST_CONF_W2 (REG_SLC_HOST_BASE + 0x20) 129 | #define SLC_HOST_CONF11 0x000000FF 130 | #define SLC_HOST_CONF11_S 24 131 | #define SLC_HOST_CONF10 0x000000FF 132 | #define SLC_HOST_CONF10_S 16 133 | #define SLC_HOST_CONF9 0x000000FF 134 | #define SLC_HOST_CONF9_S 8 135 | #define SLC_HOST_CONF8 0x000000FF 136 | #define SLC_HOST_CONF8_S 0 137 | 138 | #define SLC_HOST_CONF_W3 (REG_SLC_HOST_BASE + 0x24) 139 | #define SLC_HOST_CONF15 0x000000FF 140 | #define SLC_HOST_CONF15_S 24 141 | #define SLC_HOST_CONF14 0x000000FF 142 | #define SLC_HOST_CONF14_S 16 143 | #define SLC_HOST_CONF13 0x000000FF 144 | #define SLC_HOST_CONF13_S 8 145 | #define SLC_HOST_CONF12 0x000000FF 146 | #define SLC_HOST_CONF12_S 0 147 | 148 | #define SLC_HOST_GEN_TXDONE_INT BIT(16) 149 | #define SLC_HOST_GEN_RXDONE_INT BIT(17) 150 | 151 | #define SLC_HOST_CONF_W4 (REG_SLC_HOST_BASE + 0x28) 152 | #define SLC_HOST_CONF19 0x000000FF 153 | #define SLC_HOST_CONF19_S 24 154 | #define SLC_HOST_CONF18 0x000000FF 155 | #define SLC_HOST_CONF18_S 16 156 | #define SLC_HOST_CONF17 0x000000FF 157 | #define SLC_HOST_CONF17_S 8 158 | #define SLC_HOST_CONF16 0x000000FF 159 | #define SLC_HOST_CONF16_S 0 160 | 161 | #define SLC_HOST_TOKEN_WDATA (REG_SLC_HOST_BASE + 0x2C) 162 | #define SLC_HOST_TOKEN1_WD 0x00000FFF 163 | #define SLC_HOST_TOKEN1_WD_S 16 164 | #define SLC_HOST_TOKEN0_WD 0x00000FFF 165 | #define SLC_HOST_TOKEN0_WD_S 0 166 | 167 | #define SLC_HOST_INT_CLR (REG_SLC_HOST_BASE + 0x30) 168 | #define SLC_HOST_TOKEN1_WR (BIT(31)) 169 | #define SLC_HOST_TOKEN0_WR (BIT(30)) 170 | #define SLC_HOST_TOKEN1_DEC (BIT(29)) 171 | #define SLC_HOST_TOKEN0_DEC (BIT(28)) 172 | #define SLC_HOST_EXT_BIT3_INT_CLR (BIT(22)) 173 | #define SLC_HOST_EXT_BIT2_INT_CLR (BIT(21)) 174 | #define SLC_HOST_EXT_BIT1_INT_CLR (BIT(20)) 175 | #define SLC_HOST_EXT_BIT0_INT_CLR (BIT(19)) 176 | #define SLC_HOST_RX_PF_VALID_INT_CLR (BIT(18)) 177 | #define SLC_HOST_TX_OVF_INT_CLR (BIT(17)) 178 | #define SLC_HOST_RX_UDF_INT_CLR (BIT(16)) 179 | #define SLC_HOST_TX_START_INT_CLR (BIT(15)) 180 | #define SLC_HOST_RX_START_INT_CLR (BIT(14)) 181 | #define SLC_HOST_RX_EOF_INT_CLR (BIT(13)) 182 | #define SLC_HOST_RX_SOF_INT_CLR (BIT(12)) 183 | #define SLC_HOST_TOKEN1_0TO1_INT_CLR (BIT(11)) 184 | #define SLC_HOST_TOKEN0_0TO1_INT_CLR (BIT(10)) 185 | #define SLC_HOST_TOKEN1_1TO0_INT_CLR (BIT(9)) 186 | #define SLC_HOST_TOKEN0_1TO0_INT_CLR (BIT(8)) 187 | #define SLC_HOST_TOHOST_BIT7_INT_CLR (BIT(7)) 188 | #define SLC_HOST_TOHOST_BIT6_INT_CLR (BIT(6)) 189 | #define SLC_HOST_TOHOST_BIT5_INT_CLR (BIT(5)) 190 | #define SLC_HOST_TOHOST_BIT4_INT_CLR (BIT(4)) 191 | #define SLC_HOST_TOHOST_BIT3_INT_CLR (BIT(3)) 192 | #define SLC_HOST_TOHOST_BIT2_INT_CLR (BIT(2)) 193 | #define SLC_HOST_TOHOST_BIT1_INT_CLR (BIT(1)) 194 | #define SLC_HOST_TOHOST_BIT0_INT_CLR (BIT(0)) 195 | 196 | #define SLC_HOST_INT_ENA (REG_SLC_HOST_BASE + 0x34) 197 | #define SLC_HOST_EXT_BIT3_INT_ENA (BIT(22)) 198 | #define SLC_HOST_EXT_BIT2_INT_ENA (BIT(21)) 199 | #define SLC_HOST_EXT_BIT1_INT_ENA (BIT(20)) 200 | #define SLC_HOST_EXT_BIT0_INT_ENA (BIT(19)) 201 | #define SLC_HOST_RX_PF_VALID_INT_ENA (BIT(18)) 202 | #define SLC_HOST_TX_OVF_INT_ENA (BIT(17)) 203 | #define SLC_HOST_RX_UDF_INT_ENA (BIT(16)) 204 | #define SLC_HOST_TX_START_INT_ENA (BIT(15)) 205 | #define SLC_HOST_RX_START_INT_ENA (BIT(14)) 206 | #define SLC_HOST_RX_EOF_INT_ENA (BIT(13)) 207 | #define SLC_HOST_RX_SOF_INT_ENA (BIT(12)) 208 | #define SLC_HOST_TOKEN1_0TO1_INT_ENA (BIT(11)) 209 | #define SLC_HOST_TOKEN0_0TO1_INT_ENA (BIT(10)) 210 | #define SLC_HOST_TOKEN1_1TO0_INT_ENA (BIT(9)) 211 | #define SLC_HOST_TOKEN0_1TO0_INT_ENA (BIT(8)) 212 | #define SLC_HOST_TOHOST_BIT7_INT_ENA (BIT(7)) 213 | #define SLC_HOST_TOHOST_BIT6_INT_ENA (BIT(6)) 214 | #define SLC_HOST_TOHOST_BIT5_INT_ENA (BIT(5)) 215 | #define SLC_HOST_TOHOST_BIT4_INT_ENA (BIT(4)) 216 | #define SLC_HOST_TOHOST_BIT3_INT_ENA (BIT(3)) 217 | #define SLC_HOST_TOHOST_BIT2_INT_ENA (BIT(2)) 218 | #define SLC_HOST_TOHOST_BIT1_INT_ENA (BIT(1)) 219 | #define SLC_HOST_TOHOST_BIT0_INT_ENA (BIT(0)) 220 | 221 | #define SLC_HOST_CONF_W5 (REG_SLC_HOST_BASE + 0x3C) 222 | #define SLC_HOST_CONF23 0x000000FF 223 | #define SLC_HOST_CONF23_S 24 224 | #define SLC_HOST_CONF22 0x000000FF 225 | #define SLC_HOST_CONF22_S 16 226 | #define SLC_HOST_CONF21 0x000000FF 227 | #define SLC_HOST_CONF21_S 8 228 | #define SLC_HOST_CONF20 0x000000FF 229 | #define SLC_HOST_CONF20_S 0 230 | 231 | #define SLC_HOST_WIN_CMD (REG_SLC_HOST_BASE + 0x40) 232 | 233 | 234 | #define SLC_HOST_DATE (REG_SLC_HOST_BASE + 0x78) 235 | #define SLC_HOST_ID (REG_SLC_HOST_BASE + 0x7C) 236 | 237 | #define SLC_ADDR_WINDOW_CLEAR_MASK (~(0xf<<12)) 238 | #define SLC_FROM_HOST_ADDR_WINDOW (0x1<<12) 239 | #define SLC_TO_HOST_ADDR_WINDOW (0x3<<12) 240 | 241 | #define SLC_SET_FROM_HOST_ADDR_WINDOW(v) do { \ 242 | (v) &= 0xffff; \ 243 | (v) &= SLC_ADDR_WINDOW_CLEAR_MASK; \ 244 | (v) |= SLC_FROM_HOST_ADDR_WINDOW; \ 245 | } while (0); 246 | 247 | #define SLC_SET_TO_HOST_ADDR_WINDOW(v) do { \ 248 | (v) &= 0xffff; \ 249 | (v) &= SLC_ADDR_WINDOW_CLEAR_MASK; \ 250 | (v) |= SLC_TO_HOST_ADDR_WINDOW; \ 251 | } while (0); 252 | 253 | #define SLC_INT_ENA (REG_SLC_BASE + 0xC) 254 | #define SLC_RX_EOF_INT_ENA BIT(17) 255 | #define SLC_FRHOST_BIT2_INT_ENA BIT(2) 256 | 257 | #define SLC_RX_LINK (REG_SLC_BASE + 0x24) 258 | #define SLC_RXLINK_START BIT(29) 259 | 260 | #define SLC_BRIDGE_CONF (REG_SLC_BASE + 0x44) 261 | #define SLC_TX_PUSH_IDLE_NUM 0xFFFF 262 | #define SLC_TX_PUSH_IDLE_NUM_S 16 263 | #define SLC_HDA_MAP_128K BIT(13) 264 | #define SLC_TX_DUMMY_MODE BIT(12) 265 | #define SLC_FIFO_MAP_ENA 0x0000000F 266 | #define SLC_FIFO_MAP_ENA_S 8 267 | #define SLC_TXEOF_ENA 0x0000003F 268 | #define SLC_TXEOF_ENA_S 269 | 270 | 271 | #endif // SLC_HOST_REGISTER_H_INCLUDED 272 | --------------------------------------------------------------------------------