├── .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 |
--------------------------------------------------------------------------------