├── .gitignore ├── CMakeLists.txt ├── COPYRIGHT ├── GPL ├── Kconfig ├── README.md ├── autogen.sh ├── carlfw ├── CMakeLists.txt ├── Kconfig ├── carl9170.lds ├── include │ ├── cam.h │ ├── carl9170.h │ ├── cmd.h │ ├── config.h │ ├── dma.h │ ├── fwdsc.h │ ├── gpio.h │ ├── hostif.h │ ├── io.h │ ├── printf.h │ ├── rf.h │ ├── rom.h │ ├── timer.h │ ├── uart.h │ ├── usb.h │ ├── usb_fifo.h │ ├── wl.h │ └── wol.h ├── src │ ├── cam.c │ ├── dma.c │ ├── fw.c │ ├── gpio.c │ ├── hostif.c │ ├── main.c │ ├── memcpy.S │ ├── memset.S │ ├── printf.c │ ├── reboot.S │ ├── rf.c │ ├── timer.c │ ├── uart.c │ ├── udivsi3_i4i-Os.S │ ├── wlan.c │ ├── wlanrx.c │ ├── wlantx.c │ └── wol.c └── usb │ ├── Kconfig │ ├── fifo.c │ ├── main.c │ └── usb.c ├── com.qualcomm.qca.carl9170.firmware.metainfo.xml ├── config ├── .gitignore ├── CMakeLists.txt ├── array_size.h ├── conf.c ├── confdata.c ├── expr.c ├── expr.h ├── hash.h ├── hashtable.h ├── internal.h ├── lexer.l ├── list.h ├── list_types.h ├── lkc.h ├── lkc_proto.h ├── menu.c ├── parser.y ├── preprocess.c ├── preprocess.h ├── symbol.c ├── util.c └── xalloc.h ├── extra ├── FindPackageHandleStandardArgs.cmake ├── FindUSB-1.0.cmake ├── libusb-zeropacket.diff └── sh-elf-linux.cmake ├── genapi.sh ├── include ├── linux │ ├── byteorder_generic.h │ ├── ch9.h │ ├── compiler.h │ ├── ieee80211.h │ ├── little_endian.h │ ├── packed_struct.h │ ├── swab.h │ ├── types.h │ └── unaligned.h └── shared │ ├── eeprom.h │ ├── fwcmd.h │ ├── fwdesc.h │ ├── hw.h │ ├── phy.h │ ├── version.h │ └── wlan.h ├── minifw ├── CMakeLists.txt ├── Kconfig ├── miniboot.S └── miniboot.lds ├── toolchain ├── Makefile └── SHA256SUMS └── tools ├── .gitignore ├── CMakeLists.txt ├── Kconfig ├── include ├── frame.h └── list.h ├── lib ├── CMakeLists.txt ├── carlfw.c └── carlfw.h └── src ├── CMakeLists.txt ├── checksum.c ├── eeprom_fix ├── fwinfo.c ├── miniboot.c └── wol.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.orig 4 | *.fw 5 | *.dsc 6 | *.elf 7 | *.bin 8 | *.a 9 | fw.map 10 | *~ 11 | *.dis 12 | a.out 13 | *.cmake 14 | *.conf 15 | *.conf.cmd 16 | *old 17 | .config 18 | CMakeCache.txt 19 | include/generated 20 | CMakeFiles/ 21 | toolchain 22 | toolchain/src 23 | toolchain/build 24 | toolchain/inst 25 | Makefile 26 | include/autoconf.h 27 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(carl9170) 4 | 5 | #if you don't want the full compiler output, remove the following line 6 | #set(CMAKE_VERBOSE_MAKEFILE ON) 7 | 8 | include("config.cmake") 9 | 10 | add_subdirectory(carlfw) 11 | 12 | if (CONFIG_CARL9170FW_BUILD_MINIBOOT) 13 | add_subdirectory(minifw) 14 | endif (CONFIG_CARL9170FW_BUILD_MINIBOOT) 15 | 16 | if (CONFIG_CARL9170FW_BUILD_TOOLS) 17 | add_subdirectory(tools) 18 | endif (CONFIG_CARL9170FW_BUILD_TOOLS) 19 | 20 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Atheros carl9170 firmware - used by the ar9170 wireless device 2 | 3 | Copyright (c) 2000-2005 ZyDAS Technology Corporation 4 | Copyright (c) 2007-2009 Atheros Communications, Inc. 5 | Copyright (c) 2009-2011 Christian Lamparter 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 | You should have received a copy of the GNU General Public License along 18 | with this program; If not, see . 19 | -------------------------------------------------------------------------------- /Kconfig: -------------------------------------------------------------------------------- 1 | mainmenu "CARL9170 Firmware Configuration" 2 | 3 | source "carlfw/Kconfig" 4 | source "minifw/Kconfig" 5 | source "tools/Kconfig" 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Community AR9170 Linux firmware 2 | 3 | ## Introduction 4 | 5 | This is the firmware for the Atheros ar9170 802.11n devices. 6 | The firmware, carl9170.fw, can be used with the carl9170 Linux 7 | driver or the tools supplied in the repository. 8 | 9 | ## Build 10 | 11 | ### Build Toolchain 12 | 13 | To build the firmware you will need an SH-2 toolchain. 14 | You can use the makefile in this repository to build 15 | your own toolchain: 16 | 17 | `# make -C toolchain` 18 | 19 | but be aware that this will take some time and requires 20 | about 3-5 GiB disk space. 21 | 22 | ### Build Firmware Image 23 | 24 | The firmware configuration and build process requires the following 25 | tools and libraries: 26 | 27 | * gcc 6.0+ (including library and header dependencies) 28 | 29 | * bison/flex 30 | 31 | * cmake 3.8+ 32 | 33 | to start the configuration, run: 34 | 35 | `# autogen.sh` 36 | 37 | The configuration is based on the Linux's KConfig utility CLI. 38 | For each configurable option, a prompt will appear. To choose 39 | the default/previous option simply hit ``-key on your 40 | keyboard. 41 | 42 | ### Install Firmware 43 | 44 | if you want to "install" your own firmware, you can either 45 | do this manually, or by executing: 46 | 47 | `# autogen.sh install` 48 | 49 | This will place a copy with the right filename [adds API rev] 50 | into /lib/firmware/[the default path on most Distributions]. 51 | 52 | ## Contact 53 | 54 | If you have any patches, you should write 55 | to and 56 | include "carl9170" in the subject line. 57 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | case "$1" in 6 | config) 7 | echo "Configuring..." 8 | pushd config 9 | cmake . 10 | make 11 | popd 12 | shift 1 13 | config/conf Kconfig "$@" 14 | cmake . 15 | ;; 16 | 17 | compile) 18 | echo "Compile time..." 19 | make 20 | ;; 21 | 22 | install) 23 | if [ ! -e .config ]; then 24 | exit 1 25 | fi 26 | 27 | # shellcheck source=/dev/null 28 | . ./.config 29 | make 30 | 31 | echo -n "Installing firmware..." 32 | if [ "$CONFIG_CARL9170FW_BUILD_TOOLS" = "y" ]; then 33 | if [ "$CONFIG_CARL9170FW_BUILD_MINIBOOT" = "y" ]; then 34 | echo -n "Apply miniboot..." 35 | # also adds checksum 36 | tools/src/miniboot a carlfw/carl9170.fw minifw/miniboot.fw 37 | else 38 | echo -n "Add checksum..." 39 | tools/src/checksum carlfw/carl9170.fw 40 | fi 41 | fi 42 | 43 | install -m 644 carlfw/carl9170.fw \ 44 | ../carl9170-"$CONFIG_CARL9170FW_RELEASE_VERSION".fw 45 | echo "done." 46 | ;; 47 | 48 | *) 49 | $0 config "$@" 50 | $0 compile 51 | ;; 52 | 53 | 54 | esac 55 | -------------------------------------------------------------------------------- /carlfw/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(carl9170.fw) 4 | 5 | include("../extra/sh-elf-linux.cmake") 6 | include("../config.cmake") 7 | 8 | set(CARL9170_FW_ELF carl9170.elf) 9 | set(CARLFW_CFLAGS_WARNING "-W -Wall -Wextra -Wunreachable-code -Winline -Wlogical-op -Wno-packed-bitfield-compat -Winit-self -Wshadow -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wformat=2 -Wcast-align -Wmissing-format-attribute -Wmissing-prototypes -Wtype-limits -Wmissing-declarations -Wmissing-noreturn -Wredundant-decls -Wnested-externs -Wdisabled-optimization -Wpointer-arith -Wvolatile-register-var -Waddress -Wbad-function-cast -Wunsafe-loop-optimizations") 10 | set(CARLFW_CFLAGS_EXTRA "-mbitops -ffunction-sections -Wframe-larger-than=128 -Werror") 11 | set(CARLFW_CFLAGS_DEF "-D__CARL9170FW__") 12 | if (CONFIG_CARL9170FW_AGGRESSIVE_CFLAGS) 13 | set(CARLFW_CFLAGS_AGGRESSIVE "-fomit-frame-pointer -fsee -frename-registers -ftree-vectorize -flto -fstrict-volatile-bitfields -fmodulo-sched -fwhole-program") 14 | endif (CONFIG_CARL9170FW_AGGRESSIVE_CFLAGS) 15 | set(CARLFW_CFLAGS "${CARLFW_CFLAGS_DEF} ${CARLFW_CFLAGS_EXTRA} ${CARLFW_CFLAGS_AGGRESSIVE} ${CARLFW_CFLAGS_WARNING}") 16 | 17 | include_directories (../include/linux ../include/shared ../include include) 18 | 19 | set(carl9170_main_src src/main.c src/wlan.c src/wlanrx.c src/wlantx.c 20 | src/fw.c src/gpio.c src/timer.c 21 | src/uart.c src/dma.c src/hostif.c src/reboot.S 22 | src/printf.c src/rf.c src/cam.c src/wol.c) 23 | 24 | set(carl9170_lib_src src/memcpy.S src/memset.S src/udivsi3_i4i-Os.S) 25 | set(carl9170_usb_src usb/main.c usb/usb.c usb/fifo.c) 26 | 27 | set(carl9170_src ${carl9170_main_src} ${carl9170_lib_src} ${carl9170_usb_src}) 28 | 29 | #set_source_files_properties(src/ashlsi3.S PROPERTIES LANGUAGE C) 30 | set_source_files_properties(src/memcpy.S PROPERTIES LANGUAGE C) 31 | set_source_files_properties(src/memset.S PROPERTIES LANGUAGE C) 32 | set_source_files_properties(src/reboot.S PROPERTIES LANGUAGE C) 33 | set_source_files_properties(src/udivsi3_i4i-Os.S PROPERTIES LANGUAGE C) 34 | 35 | add_executable(carl9170.elf ${carl9170_src}) 36 | 37 | set_target_properties(carl9170.elf PROPERTIES LINKER_LANGUAGE C) 38 | 39 | set_target_properties(carl9170.elf PROPERTIES COMPILE_FLAGS "${CARLFW_CFLAGS}") 40 | set_target_properties(carl9170.elf PROPERTIES LINK_FLAGS "${CARLFW_CFLAGS} -Wl,-Tcarl9170.lds") 41 | 42 | add_custom_target(firmware ALL DEPENDS carl9170.elf) 43 | 44 | add_custom_command( 45 | POST_BUILD 46 | DEPENDS carl9170.elf 47 | COMMAND ${OBJCOPY} 48 | ARGS --strip-unneeded -O binary -R .sram -R .eeprom -R .fwdsc carl9170.elf carl9170.bin 49 | TARGET firmware 50 | BYPRODUCTS carl9170.bin 51 | OUTPUTS carl9170.bin) 52 | 53 | add_custom_command( 54 | POST_BUILD 55 | DEPENDS carl9170.elf 56 | COMMAND ${OBJCOPY} 57 | ARGS --strip-unneeded -O binary -j .fwdsc carl9170.elf carl9170.dsc 58 | TARGET firmware 59 | BYPRODUCTS carl9170.dsc 60 | OUTPUTS carl9170.dsc) 61 | 62 | add_custom_command( 63 | POST_BUILD 64 | DEPENDS firmware 65 | TARGET firmware 66 | COMMAND cat 67 | ARGS "carl9170.bin" "carl9170.dsc" > "carl9170.fw" 68 | DEPENDS carl9170.elf carl9170.bin carl9170.dsc 69 | OUTPUTS carl9170.fw) 70 | 71 | SET_DIRECTORY_PROPERTIES( 72 | PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "carl9170.fw") 73 | -------------------------------------------------------------------------------- /carlfw/Kconfig: -------------------------------------------------------------------------------- 1 | menu "General" 2 | 3 | config CARL9170FW_RELEASE_VERSION 4 | int 5 | default 1 6 | 7 | menu "Selectable Hardware Options" 8 | 9 | choice 10 | prompt "Receiver Max. Frame Length" 11 | default CARL9170FW_RX_FRAME_LEN_8192 12 | 13 | config CARL9170FW_RX_FRAME_LEN_4096 14 | bool "4096" 15 | 16 | config CARL9170FW_RX_FRAME_LEN_8192 17 | bool "8192" 18 | 19 | config CARL9170FW_RX_FRAME_LEN_16384 20 | bool "16384" 21 | 22 | config CARL9170FW_RX_FRAME_LEN_32768 23 | bool "32768" 24 | 25 | endchoice 26 | 27 | config CARL9170FW_RX_FRAME_LEN 28 | int 29 | default 4096 if CARL9170FW_RX_FRAME_LEN_4096 30 | default 8192 if CARL9170FW_RX_FRAME_LEN_8192 31 | default 16384 if CARL9170FW_RX_FRAME_LEN_16384 32 | default 32768 if CARL9170FW_RX_FRAME_LEN_32768 33 | 34 | config CARL9170FW_GPIO_INTERRUPT 35 | def_bool y 36 | prompt "GPIO Software Interrupt" 37 | help 38 | When this option is enabled, the firmware will poll the GPIO 39 | registers and reports to the driver whenever the GPIO state 40 | has changed from a previous state. 41 | 42 | Note: This feature is necessary to monitor the WPS button, 43 | if you have one on your device, then say Y. 44 | 45 | config CARL9170FW_SECURITY_ENGINE 46 | def_bool y 47 | prompt "Support Hardware Crypto Engine" 48 | help 49 | This options controls if the firmware will allow the driver 50 | to program the security engine / CAM through a firmware 51 | interface. 52 | 53 | Say Y. Unless you want to do the en- and decryption for 54 | CCMP(AES), TKIP/WEP(RC4) in the application anyway. 55 | 56 | config CARL9170FW_RADIO_FUNCTIONS 57 | def_bool y 58 | prompt "Enable Firmware-supported Radio/RF functions" 59 | help 60 | Some PHY/RF functions (e.g.: AGC and Noise calibration) need 61 | to be done in the firmware. 62 | 63 | Say Y, unless you really don't need the Radio/RF for 64 | your project. 65 | 66 | endmenu 67 | 68 | source "carlfw/usb/Kconfig" 69 | 70 | menu "Experimental, Unstable & Testing Extensions" 71 | 72 | config CARL9170FW_PRINTF 73 | def_bool y 74 | prompt "Advanced printf" 75 | depends on CARL9170FW_DEBUG_UART || CARL9170FW_DEBUG_USB 76 | help 77 | Advanced printf (very useful for debugging purposes) 78 | The formats supported by this implementation are: 79 | 'd' 'u' 'c' 's' 'x' 'X' 'p'. 80 | 81 | Note: If this option is disabled, the firmware will be only 82 | capable of reported _preformated_ string. 83 | 84 | config CARL9170FW_EXPERIMENTAL 85 | def_bool y 86 | prompt "Experimental Features" 87 | 88 | config CARL9170FW_WOL_OPTION 89 | def_bool n 90 | prompt "Wakeup on WLAN" 91 | depends on CARL9170FW_EXPERIMENTAL 92 | help 93 | With this option enabled, the firmware can wake-up 94 | suspended hosts... As long as they fully support 95 | USB remote wakeup. 96 | 97 | config CARL9170FW_WOL 98 | def_bool n 99 | depends on CARL9170FW_WOL_OPTION 100 | 101 | config CARL9170FW_WOL_NL80211_TRIGGERS 102 | def_bool n 103 | prompt "Standard NL80211 wakeup triggers" 104 | depends on CARL9170FW_WOL_OPTION 105 | select CARL9170FW_WOL 106 | help 107 | Available triggers: 108 | * Magic Packet(tm) pattern 109 | * disconnect event 110 | 111 | config CARL9170FW_WOL_PROBE_REQUEST 112 | def_bool n 113 | prompt "Probe Request" 114 | depends on CARL9170FW_WOL_OPTION 115 | select CARL9170FW_WOL 116 | help 117 | Scan probe requests for a given SSID. 118 | 119 | config CARL9170FW_WOL_PROBE_REQUEST_SSID 120 | string 121 | prompt "Wakeup on WLAN SSID" 122 | default "CARL9170_WAKEUP" 123 | depends on CARL9170FW_WOL_PROBE_REQUEST 124 | 125 | config CARL9170FW_VIFS_NUM 126 | default 1 127 | int 128 | prompt "Number of additional pseudo virtual interfaces" 129 | depends on CARL9170FW_EXPERIMENTAL 130 | 131 | config CARL9170FW_FW_MAC_RESET 132 | def_bool y 133 | prompt "Firmware MAC Chip recovery" 134 | depends on CARL9170FW_EXPERIMENTAL 135 | 136 | config CARL9170FW_NOISY_MAC_RESET 137 | def_bool n 138 | prompt "Notify MAC RESET events" 139 | depends on CARL9170FW_FW_MAC_RESET 140 | 141 | config CARL9170FW_80MHZ_CLOCK 142 | def_bool n 143 | prompt "Allow 80/88MHz clock for HT40" 144 | depends on CARL9170FW_EXPERIMENTAL 145 | help 146 | The SoC can run up to 80/88MHz in HT40 mode. This improves 147 | throughput and timing accuracy over the 40/44MHz clock. 148 | However some devices don't have heat shields and they with 149 | this option enabled, they become unstable under load. 150 | 151 | config CARL9170FW_BROKEN_FEATURES 152 | def_bool n 153 | prompt "Broken Features" 154 | 155 | config CARL9170FW_DEBUG 156 | def_bool n 157 | depends on CARL9170FW_BROKEN_FEATURES && CARL9170FW_PRINTF 158 | prompt "Enable verbose debugging messages" 159 | 160 | config CARL9170FW_DEBUG_LED_HEARTBEAT 161 | def_bool n 162 | prompt "LED Heartbeat" 163 | depends on CARL9170FW_BROKEN_FEATURES 164 | help 165 | This option conflicts with the application's LED code. 166 | Also, it assumes that you have two LEDs, which is not 167 | necessarily true. 168 | 169 | config CARL9170FW_DEBUG_UART 170 | def_bool n 171 | prompt "Pass debug messages through Highspeed UART" 172 | depends on CARL9170FW_BROKEN_FEATURES 173 | help 174 | This option allows the firmware to send BUG/ERR/INFO/DBG and 175 | hexdumps through the UART _as well_. However, first: you must 176 | connect a working logger. 177 | 178 | config CARL9170FW_WATCHDOG_BUTTON 179 | def_bool n 180 | depends on CARL9170FW_BROKEN && CARL9170FW_GPIO_INTERRUPT 181 | prompt "Trigger Watchdog by pressing the WPS button" 182 | 183 | choice 184 | prompt "UART Clock" 185 | depends on CARL9170FW_DEBUG_UART 186 | default CARL9170FW_UART_CLOCK_40M 187 | 188 | config CARL9170FW_UART_CLOCK_25M 189 | bool "25" 190 | 191 | config CARL9170FW_UART_CLOCK_40M 192 | bool "40" 193 | 194 | endchoice 195 | 196 | config CARL9170FW_UNUSABLE 197 | def_bool y 198 | depends on CARL9170FW_BROKEN || CARL9170FW_DEBUG 199 | 200 | config CARL9170FW_USB_MODESWITCH 201 | def_bool n 202 | prompt "USB 1.1 / 2.0 switching support" 203 | depends on CARL9170FW_BROKEN_FEATURES && CARL9170FW_USB_STANDARD_CMDS 204 | help 205 | Mostly implemented, but untested and some serious 206 | doubts remain. 207 | 208 | config CARL9170FW_DMA_QUEUE_BUMP 209 | def_bool n 210 | prompt "Bump a stuck TX queue before doing a MAC reset" 211 | depends on CARL9170FW_BROKEN_FEATURES 212 | 213 | menu "Build Options" 214 | config CARL9170FW_AGGRESSIVE_CFLAGS 215 | def_bool y 216 | prompt "Enable aggressive size optimization" 217 | help 218 | This option adds several more optimization compiler flags, 219 | which can greatly reduce the firmware size... at the expense 220 | of machine-code readability. 221 | 222 | Say Y. Else the firmware might not fit onto the device! 223 | 224 | endmenu 225 | 226 | endmenu 227 | 228 | endmenu 229 | -------------------------------------------------------------------------------- /carlfw/carl9170.lds: -------------------------------------------------------------------------------- 1 | /* 2 | * The carl9170 firwmare gets copied into the device's 3 | * Program RAM (pram), which has a size of 16K, but 4 | * also has to accomodate the stack the device uses, 5 | * which starts at the top of the 16k, so we pretend 6 | * that we just have 16256 (16k - 128) of pram. 7 | * 8 | * This section documents some of the other areas 9 | * mapped into the firmware processor's address space 10 | * as well. 11 | */ 12 | 13 | ENTRY(_start); 14 | 15 | MEMORY 16 | { 17 | eeprom : ORIGIN = 0x000000, LENGTH = 1024k 18 | sram : ORIGIN = 0x100000, LENGTH = 96k 19 | uart : ORIGIN = 0x1c0000, LENGTH = 4k 20 | timer : ORIGIN = 0x1c1000, LENGTH = 4k 21 | vflash : ORIGIN = 0x1c2000, LENGTH = 4k 22 | wlan : ORIGIN = 0x1c3000, LENGTH = 4k 23 | pci2ahb : ORIGIN = 0x1c4000, LENGTH = 4k 24 | security : ORIGIN = 0x1c5000, LENGTH = 4k 25 | gpio : ORIGIN = 0x1d0000, LENGTH = 4k 26 | memctl : ORIGIN = 0x1d1000, LENGTH = 4k 27 | irqctl : ORIGIN = 0x1d2000, LENGTH = 4k 28 | usb : ORIGIN = 0x1e1000, LENGTH = 4k 29 | pta : ORIGIN = 0x1e2000, LENGTH = 4k 30 | pram : ORIGIN = 0x200000, LENGTH = 16256 31 | bogus : ORIGIN = 0x300000, LENGTH = 8k 32 | } 33 | 34 | SECTIONS 35 | { 36 | .eeprom : { *(.eeprom*) } > eeprom 37 | .sram : { *(.sram*) } > sram 38 | 39 | /* 40 | * The ar9170 boot code will execute the code 41 | * at address 0x04 from the loaded firmware as 42 | * such we must ensure our starting routine 43 | * is kept at that address. 44 | */ 45 | .padding : { 46 | /* NOP NOP just in case */ 47 | LONG(0x00090009) 48 | } > pram 49 | 50 | .boot : { *(.boot) } > pram 51 | /* anything else can be anywhere */ 52 | 53 | .text : { *(.text*) } > pram 54 | .rodata : { *(.rodata*) } > pram 55 | .bss : { *(.bss) } > pram 56 | .data : { *(.data*) } > pram 57 | 58 | .fwdsc : { KEEP(*(.fwdsc)) } > bogus 59 | } 60 | -------------------------------------------------------------------------------- /carlfw/include/cam.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * CAM (Security Engine) definitions 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #ifndef __CARL9170FW_CAM_H 26 | #define __CARL9170FW_CAM_H 27 | 28 | #include "config.h" 29 | #include "cmd.h" 30 | 31 | #ifdef CONFIG_CARL9170FW_SECURITY_ENGINE 32 | 33 | #define ENCRY_TYPE_START_ADDR 24 34 | #define DEFAULT_ENCRY_TYPE 26 35 | #define KEY_START_ADDR 27 36 | #define STA_KEY_START_ADDR 155 37 | #define COUNTER_START_ADDR 163 38 | #define STA_COUNTER_START_ADDR 165 39 | 40 | /* CAM */ 41 | #define MIC_FINISH 0x1 42 | 43 | void set_key(const struct carl9170_set_key_cmd *key); 44 | void disable_key(const struct carl9170_disable_key_cmd *key); 45 | 46 | #endif /* CONFIG_CARL9170FW_SECURITY_ENGINE */ 47 | 48 | #endif /* __CARL9170FW_CAM_H */ 49 | -------------------------------------------------------------------------------- /carlfw/include/carl9170.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * Firmware context definition 5 | * 6 | * Copyright 2009-2011 Christian Lamparter 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 | * You should have received a copy of the GNU General Public License along 19 | * with this program; If not, see . 20 | */ 21 | 22 | #ifndef __CARL9170FW_CARL9170_H 23 | #define __CARL9170FW_CARL9170_H 24 | 25 | #include "generated/autoconf.h" 26 | #include "version.h" 27 | #include "config.h" 28 | #include "types.h" 29 | #include "compiler.h" 30 | #include "unaligned.h" 31 | #include "fwcmd.h" 32 | #include "hw.h" 33 | #include "dma.h" 34 | #include "usb.h" 35 | #include "cmd.h" 36 | 37 | struct carl9170_bar_ctx { 38 | uint8_t ta[6]; 39 | uint8_t ra[6]; 40 | __le16 start_seq_num; 41 | __le16 control; 42 | }; 43 | 44 | enum carl9170_cab_trigger { 45 | CARL9170_CAB_TRIGGER_EMPTY = 0, 46 | CARL9170_CAB_TRIGGER_ARMED = BIT(0), 47 | CARL9170_CAB_TRIGGER_DEFER = BIT(1), 48 | }; 49 | 50 | enum carl9170_ep0_action { 51 | CARL9170_EP0_NO_ACTION = 0, 52 | CARL9170_EP0_STALL = BIT(0), 53 | CARL9170_EP0_TRIGGER = BIT(1), 54 | }; 55 | 56 | enum carl9170_mac_reset_state { 57 | CARL9170_MAC_RESET_OFF = 0, 58 | CARL9170_MAC_RESET_ARMED, 59 | CARL9170_MAC_RESET_RESET, 60 | CARL9170_MAC_RESET_FORCE, 61 | }; 62 | 63 | enum carl9170_suspend_mode { 64 | CARL9170_HOST_AWAKE = 0, 65 | CARL9170_HOST_SUSPENDED, 66 | CARL9170_AWAKE_HOST, 67 | }; 68 | 69 | enum carl9170_phy_state { 70 | CARL9170_PHY_OFF = 0, 71 | CARL9170_PHY_ON 72 | }; 73 | 74 | typedef void (*fw_desc_callback_t)(void *, const bool); 75 | 76 | /* 77 | * This platform - being an odd 32-bit architecture - prefers to 78 | * have 32-Bit variables. 79 | */ 80 | 81 | struct firmware_context_struct { 82 | /* timer / clocks */ 83 | unsigned int ticks_per_usec; 84 | unsigned int counter; /* main() cycles */ 85 | 86 | /* misc */ 87 | unsigned int watchdog_enable; 88 | unsigned int reboot; 89 | unsigned int suspend_mode; 90 | 91 | struct { 92 | /* Host Interface DMA queues */ 93 | struct dma_queue up_queue; /* used to send frames to the host */ 94 | struct dma_queue down_queue; /* stores incoming frames from the host */ 95 | } pta; 96 | 97 | struct { 98 | /* Hardware DMA queues */ 99 | struct dma_queue tx_queue[__AR9170_NUM_TX_QUEUES]; /* wlan tx queue */ 100 | struct dma_queue tx_retry; 101 | struct dma_queue rx_queue; /* wlan rx queue */ 102 | 103 | /* tx aggregate scheduling */ 104 | struct carl9170_tx_superframe *ampdu_prev[__AR9170_NUM_TX_QUEUES]; 105 | 106 | /* Hardware DMA queue unstuck/fix detection */ 107 | unsigned int last_super_num[__AR9170_NUM_TX_QUEUES]; 108 | struct carl9170_tx_superframe *last_super[__AR9170_NUM_TX_QUEUES]; 109 | unsigned int mac_reset; 110 | unsigned int soft_int; 111 | 112 | /* rx filter */ 113 | unsigned int rx_filter; 114 | 115 | /* tx sequence control counters */ 116 | unsigned int sequence[CARL9170_INTF_NUM]; 117 | 118 | /* CAB */ 119 | struct dma_queue cab_queue[CARL9170_INTF_NUM]; 120 | unsigned int cab_queue_len[CARL9170_INTF_NUM]; 121 | unsigned int cab_flush_time; 122 | enum carl9170_cab_trigger cab_flush_trigger[CARL9170_INTF_NUM]; 123 | 124 | /* tx status */ 125 | unsigned int tx_status_pending, 126 | tx_status_head_idx, 127 | tx_status_tail_idx; 128 | struct carl9170_tx_status tx_status_cache[CARL9170_TX_STATUS_NUM]; 129 | 130 | /* internal descriptor for use within the service routines */ 131 | struct dma_desc *fw_desc; 132 | unsigned int fw_desc_available; 133 | void *fw_desc_data; 134 | fw_desc_callback_t fw_desc_callback; 135 | 136 | /* BA(R) Request Handler */ 137 | struct carl9170_bar_ctx ba_cache[CONFIG_CARL9170FW_BACK_REQS_NUM]; 138 | unsigned int ba_tail_idx, 139 | ba_head_idx, 140 | queued_ba; 141 | 142 | unsigned int queued_bar; 143 | } wlan; 144 | 145 | struct { 146 | unsigned int config, 147 | interface_setting, 148 | alternate_interface_setting, 149 | device_feature; 150 | enum carl9170_ep0_action ep0_action; 151 | 152 | void *ep0_txrx_buffer; 153 | unsigned int ep0_txrx_len, 154 | ep0_txrx_pos; 155 | 156 | struct ar9170_usb_config *cfg_desc; 157 | struct ar9170_usb_config *os_cfg_desc; 158 | 159 | /* 160 | * special buffers for command & response handling 161 | * 162 | * the firmware uses a sort of ring-buffer to communicate 163 | * to the host. 164 | */ 165 | unsigned int int_pending, 166 | int_desc_available, 167 | int_head_index, 168 | int_tail_index; 169 | struct dma_desc *int_desc; 170 | struct carl9170_rsp int_buf[CARL9170_INT_RQ_CACHES]; 171 | 172 | #ifdef CONFIG_CARL9170FW_DEBUG_USB 173 | /* USB printf */ 174 | unsigned int put_index; 175 | uint8_t put_buffer[CARL9170_MAX_CMD_PAYLOAD_LEN]; 176 | #endif /* CONFIG_CARL9170FW_DEBUG_USB */ 177 | 178 | } usb; 179 | 180 | struct { 181 | #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS 182 | /* (cached) ar9170_rf_init */ 183 | 184 | /* PHY/RF state */ 185 | unsigned int frequency; 186 | unsigned int ht_settings; 187 | 188 | enum carl9170_phy_state state; 189 | struct carl9170_psm psm; 190 | #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ 191 | } phy; 192 | 193 | unsigned int tally_clock; 194 | struct carl9170_tally_rsp tally; 195 | unsigned int tx_time; 196 | 197 | #ifdef CONFIG_CARL9170FW_WOL 198 | struct { 199 | struct carl9170_wol_cmd cmd; 200 | unsigned int last_beacon; 201 | unsigned int lost_null; 202 | unsigned int last_null; 203 | bool wake_up; 204 | } wol; 205 | #endif /* CONFIG_CARL9170FW_WOL */ 206 | 207 | #ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT 208 | struct carl9170_gpio cached_gpio_state; 209 | #endif /*CONFIG_CARL9170FW_GPIO_INTERRUPT */ 210 | }; 211 | 212 | /* 213 | * global firmware context struct. 214 | * 215 | * NOTE: This struct will zeroed out in start() 216 | */ 217 | extern struct firmware_context_struct fw; 218 | #endif /* __CARL9170FW_CARL9170_H */ 219 | -------------------------------------------------------------------------------- /carlfw/include/cmd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * Firmware command interface definition 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #ifndef __CARL9170FW_CMD_H 26 | #define __CARL9170FW_CMD_H 27 | 28 | #include "config.h" 29 | #include "compiler.h" 30 | #include "types.h" 31 | 32 | #include "fwcmd.h" 33 | 34 | static inline void __check(void) 35 | { 36 | BUILD_BUG_ON(sizeof(struct carl9170_cmd) != CARL9170_MAX_CMD_LEN); 37 | BUILD_BUG_ON(sizeof(struct carl9170_rsp) != CARL9170_MAX_CMD_LEN); 38 | BUILD_BUG_ON(sizeof(struct carl9170_set_key_cmd) != CARL9170_SET_KEY_CMD_SIZE); 39 | BUILD_BUG_ON(sizeof(struct carl9170_disable_key_cmd) != CARL9170_DISABLE_KEY_CMD_SIZE); 40 | BUILD_BUG_ON(sizeof(struct carl9170_rf_init) != CARL9170_RF_INIT_SIZE); 41 | BUILD_BUG_ON(sizeof(struct carl9170_rf_init_result) != CARL9170_RF_INIT_RESULT_SIZE); 42 | BUILD_BUG_ON(sizeof(struct carl9170_psm) != CARL9170_PSM_SIZE); 43 | BUILD_BUG_ON(sizeof(struct carl9170_tsf_rsp) != CARL9170_TSF_RSP_SIZE); 44 | BUILD_BUG_ON(sizeof(struct carl9170_bcn_ctrl_cmd) != CARL9170_BCN_CTRL_CMD_SIZE); 45 | BUILD_BUG_ON(sizeof(struct carl9170_tx_status) != CARL9170_TX_STATUS_SIZE); 46 | BUILD_BUG_ON(sizeof(struct _carl9170_tx_status) != CARL9170_TX_STATUS_SIZE); 47 | BUILD_BUG_ON(sizeof(struct carl9170_gpio) != CARL9170_GPIO_SIZE); 48 | BUILD_BUG_ON(sizeof(struct carl9170_rx_filter_cmd) != CARL9170_RX_FILTER_CMD_SIZE); 49 | BUILD_BUG_ON(sizeof(struct carl9170_wol_cmd) != CARL9170_WOL_CMD_SIZE); 50 | } 51 | 52 | void handle_cmd(struct carl9170_rsp *resp); 53 | 54 | #endif /* __CARL9170FW_CMD_H */ 55 | -------------------------------------------------------------------------------- /carlfw/include/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License along 13 | * with this program; If not, see . 14 | */ 15 | 16 | #include "generated/autoconf.h" 17 | #include "version.h" 18 | #include "types.h" 19 | #include "compiler.h" 20 | #include "fwcmd.h" 21 | #include "hw.h" 22 | 23 | #ifndef __CARL9170FW_CONFIG_H 24 | #define __CARL9170FW_CONFIG_H 25 | 26 | #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 27 | 28 | #if GCC_VERSION < 40400 29 | # error "This firmware will not work if it is compiled with gcc versions < 4.4" 30 | # error "See: http://gcc.gnu.org/gcc-4.4/changes.html / Caveats No. 4" 31 | #endif 32 | 33 | #if ((defined CONFIG_CARL9170FW_PRINTF) && \ 34 | (!defined CONFIG_CARL9170FW_DEBUG_USB) && \ 35 | (!defined CONFIG_CARL9170FW_DEBUG_UART)) 36 | # warning "You have disabled all debug message transports." 37 | # warning "However CONFIG_CARL9170FW_PRINTF is still set..." 38 | # warning "Which is a waste of firmware space, if you ask me." 39 | #endif 40 | 41 | #define CARL9170_TX_STATUS_NUM (CARL9170_RSP_TX_STATUS_NUM) 42 | #define CARL9170_INT_RQ_CACHES 16 43 | #define AR9170_INT_MAGIC_HEADER_SIZE 12 44 | #define CARL9170_TBTT_DELTA (CARL9170_PRETBTT_KUS + 1) 45 | 46 | #define CARL9170_GPIO_MASK (AR9170_GPIO_PORT_WPS_BUTTON_PRESSED) 47 | 48 | #ifdef CONFIG_CARL9170FW_VIFS_NUM 49 | #define CARL9170_INTF_NUM (1 + CONFIG_CARL9170FW_VIFS_NUM) 50 | #else 51 | #define CARL9170_INTF_NUM (1) 52 | #endif /* CONFIG_CARL9170FW_VIFS_NUM */ 53 | 54 | #define CONFIG_CARL9170FW_BACK_REQS_NUM 4 55 | 56 | static inline void __config_check(void) 57 | { 58 | BUILD_BUG_ON(!CARL9170_TX_STATUS_NUM); 59 | BUILD_BUG_ON(CARL9170_INTF_NUM < 1); 60 | BUILD_BUG_ON(CARL9170_INTF_NUM >= AR9170_MAX_VIRTUAL_MAC); 61 | } 62 | 63 | #endif /* __CARL9170FW_CONFIG_H */ 64 | -------------------------------------------------------------------------------- /carlfw/include/fwdsc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * Firmware definition 5 | * 6 | * Copyright 2009-2011 Christian Lamparter 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 | * You should have received a copy of the GNU General Public License along 19 | * with this program; If not, see . 20 | */ 21 | 22 | #ifndef __CARL9170FW_FWDSC_H 23 | #define __CARL9170FW_FWDSC_H 24 | 25 | #include "config.h" 26 | #include "compiler.h" 27 | #include "types.h" 28 | #include "fwdesc.h" 29 | 30 | struct carl9170_firmware_descriptor { 31 | struct carl9170fw_otus_desc otus; 32 | struct carl9170fw_txsq_desc txsq; 33 | #ifdef CONFIG_CARL9170FW_WOL 34 | struct carl9170fw_wol_desc wol; 35 | #endif /* CONFIG_CARL9170FW_WOL */ 36 | struct carl9170fw_motd_desc motd; 37 | struct carl9170fw_dbg_desc dbg; 38 | struct carl9170fw_last_desc last; 39 | } __packed; 40 | 41 | extern const struct carl9170_firmware_descriptor carl9170fw_desc; 42 | 43 | static inline void __check_fw(void) 44 | { 45 | BUILD_BUG_ON(sizeof(carl9170fw_desc) & 0x3); 46 | BUILD_BUG_ON(sizeof(carl9170fw_desc) > CARL9170FW_DESC_MAX_LENGTH); 47 | } 48 | 49 | #endif /* __CARL9170FW_FWDSC_H */ 50 | -------------------------------------------------------------------------------- /carlfw/include/gpio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * GPIO definitions 5 | * 6 | * Copyright 2009-2011 Christian Lamparter 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 | * You should have received a copy of the GNU General Public License along 19 | * with this program; If not, see . 20 | */ 21 | 22 | #ifndef __CARL9170FW_GPIO_H 23 | #define __CARL9170FW_GPIO_H 24 | 25 | #include "config.h" 26 | #include "hw.h" 27 | #include "io.h" 28 | 29 | static inline __inline void led_init(void) 30 | { 31 | set(AR9170_GPIO_REG_PORT_TYPE, 3); 32 | } 33 | 34 | static inline __inline void led_set(const unsigned int ledstate) 35 | { 36 | set(AR9170_GPIO_REG_PORT_DATA, ledstate); 37 | } 38 | 39 | static inline __inline u16 get_random_u16(void) 40 | { 41 | return getw(AR9170_RAND_REG_NUM); 42 | } 43 | 44 | #ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT 45 | 46 | void gpio_timer(void); 47 | 48 | #endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ 49 | #endif /* __CARL9170FW_GPIO_H */ 50 | -------------------------------------------------------------------------------- /carlfw/include/hostif.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * HostIF definition 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #ifndef __CARL9170FW_HOSTIF_H 26 | #define __CARL9170FW_HOSTIF_H 27 | 28 | #include "config.h" 29 | #include "compiler.h" 30 | #include "types.h" 31 | #include "hw.h" 32 | #include "io.h" 33 | 34 | static inline __inline void down_trigger(void) 35 | { 36 | set(AR9170_PTA_REG_DN_DMA_TRIGGER, 1); 37 | } 38 | 39 | static inline __inline void up_trigger(void) 40 | { 41 | set(AR9170_PTA_REG_UP_DMA_TRIGGER, 1); 42 | } 43 | 44 | void handle_host_interface(void); 45 | 46 | #endif /* __CARL9170FW_HOSTIF_H */ 47 | -------------------------------------------------------------------------------- /carlfw/include/io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License along 13 | * with this program; If not, see . 14 | */ 15 | 16 | #ifndef __CARL9170FW_IO_H 17 | #define __CARL9170FW_IO_H 18 | 19 | #include "config.h" 20 | #include "types.h" 21 | #include "compiler.h" 22 | 23 | static inline __inline uint8_t readb(const volatile void *addr) 24 | { 25 | return *(const volatile uint8_t *) addr; 26 | } 27 | 28 | static inline __inline uint16_t readw(const volatile void *addr) 29 | { 30 | return *(const volatile uint16_t *) addr; 31 | } 32 | 33 | static inline __inline volatile void *readp(const volatile void *addr) 34 | { 35 | return *(volatile void **) addr; 36 | } 37 | 38 | static inline __inline uint32_t readl(const volatile void *addr) 39 | { 40 | return *(const volatile unsigned int *) addr; 41 | } 42 | 43 | static inline __inline void writeb(volatile void *addr, const volatile uint8_t val) 44 | { 45 | *(volatile uint8_t *) addr = val; 46 | } 47 | 48 | static inline __inline void writew(volatile void *addr, const volatile uint16_t val) 49 | { 50 | *(volatile uint16_t *) addr = val; 51 | } 52 | 53 | static inline __inline void writel(volatile void *addr, const volatile uint32_t val) 54 | { 55 | *(volatile uint32_t *) addr = val; 56 | } 57 | 58 | static inline __inline void __orl(volatile void *addr, const volatile uint32_t val) 59 | { 60 | *(volatile uint32_t *) addr |= val; 61 | } 62 | 63 | static inline __inline void __andl(volatile void *addr, const volatile uint32_t val) 64 | { 65 | *(volatile uint32_t *) addr &= val; 66 | } 67 | 68 | static inline __inline void __xorl(volatile void *addr, const volatile uint32_t val) 69 | { 70 | *(volatile uint32_t *) addr ^= val; 71 | } 72 | 73 | static inline __inline void __incl(volatile void *addr) 74 | { 75 | (*(volatile uint32_t *)addr)++; 76 | } 77 | 78 | static inline __inline uint32_t readl_async(const volatile void *addr) 79 | { 80 | uint32_t i = 0, read, tmp; 81 | 82 | read = readl(addr); 83 | do { 84 | tmp = read; 85 | tmp = readl(addr); 86 | i++; 87 | } while (tmp != read && i <= 10); 88 | 89 | return read; 90 | } 91 | 92 | static inline __inline void set(const volatile uint32_t addr, const volatile uint32_t val) 93 | { 94 | writel((volatile void *) addr, val); 95 | } 96 | 97 | static inline __inline void orl(volatile uint32_t addr, const volatile uint32_t val) 98 | { 99 | __orl((volatile void *) addr, val); 100 | } 101 | 102 | static inline __inline void xorl(const volatile uint32_t addr, const volatile uint32_t val) 103 | { 104 | __xorl((volatile void *) addr, val); 105 | } 106 | 107 | static inline __inline void andl(const volatile uint32_t addr, const volatile uint32_t val) 108 | { 109 | __andl((volatile void *) addr, val); 110 | } 111 | 112 | static inline __inline void incl(const volatile uint32_t addr) 113 | { 114 | __incl((volatile void *) addr); 115 | } 116 | 117 | static inline __inline uint32_t get(const volatile uint32_t addr) 118 | { 119 | return readl((volatile void *) addr); 120 | } 121 | 122 | static inline __inline volatile void *getp(const volatile uint32_t addr) 123 | { 124 | return readp((const volatile void *) addr); 125 | } 126 | 127 | static inline __inline uint32_t get_async(const volatile uint32_t addr) 128 | { 129 | return readl_async((const volatile void *) addr); 130 | } 131 | 132 | static inline __inline void setb(const volatile uint32_t addr, const volatile uint8_t val) 133 | { 134 | writeb((volatile void *) addr, val); 135 | } 136 | 137 | static inline __inline uint8_t getb(const volatile uint32_t addr) 138 | { 139 | return readb((const volatile void *) addr); 140 | } 141 | 142 | static inline __inline void andb(const volatile uint32_t addr, const volatile uint8_t val) 143 | { 144 | setb(addr, getb(addr) & val); 145 | } 146 | 147 | static inline __inline void orb(const volatile uint32_t addr, const volatile uint32_t val) 148 | { 149 | setb(addr, getb(addr) | val); 150 | } 151 | 152 | static inline __inline uint16_t getw(const volatile uint32_t addr) 153 | { 154 | return readw((const volatile void *) addr); 155 | } 156 | 157 | #endif /* __CARL9170FW_IO_H */ 158 | -------------------------------------------------------------------------------- /carlfw/include/printf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * printf and his friends... 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #ifndef __CARL9170FW_PRINTF_H 26 | #define __CARL9170FW_PRINTF_H 27 | 28 | #include 29 | #include 30 | #include "config.h" 31 | #include "carl9170.h" 32 | #include "uart.h" 33 | #include "fwcmd.h" 34 | 35 | #ifdef CONFIG_CARL9170FW_PRINTF 36 | void __attribute__((format (printf, 1, 2))) tfp_printf(const char *fmt, ...); 37 | 38 | #define printf tfp_printf 39 | 40 | #else 41 | void __attribute__((format (printf, 1, 2))) min_printf(const char *fmt, ...); 42 | 43 | #define printf min_printf 44 | #endif /* CONFIG_CARL9170FW_PRINTF */ 45 | 46 | #define PRINT(fmt, args...) \ 47 | do { \ 48 | printf(fmt, ## args); \ 49 | } while (0) 50 | 51 | #define INFO(fmt, args...) PRINT(fmt, ## args) 52 | 53 | #define ERR(fmt, args...) PRINT(CARL9170_ERR_MAGIC fmt, ## args) 54 | 55 | #ifdef CONFIG_CARL9170FW_DEBUG 56 | #define DBG(fmt, args...) PRINT(fmt, ## args) 57 | #else 58 | #define DBG(...) do { } while (0); 59 | #endif 60 | 61 | /* 62 | * NB: even though the MACRO is called "stall". It isn't supposed 63 | * to stall since this will render the device unresponsive, until 64 | * someone pulls the plug. 65 | */ 66 | #define STALL() 67 | 68 | #define BUG(fmt, args...) \ 69 | do { \ 70 | PRINT(CARL9170_BUG_MAGIC" %s()@%d \"" fmt "\"" , \ 71 | __func__, __LINE__, ## args); \ 72 | STALL() \ 73 | } while (0); 74 | 75 | #define BUG_ON(condition) \ 76 | ({ \ 77 | int __ret = !!(condition); \ 78 | if (unlikely(!!(__ret))) \ 79 | BUG(#condition); \ 80 | (__ret); \ 81 | }) 82 | 83 | static inline __inline void putcharacter(const char c __unused) 84 | { 85 | #ifdef CONFIG_CARL9170FW_DEBUG_USB 86 | usb_putc(c); 87 | #endif /* CONFIG_CARL9170FW_DEBUG_USB */ 88 | 89 | #ifdef CONFIG_CARL9170FW_DEBUG_UART 90 | uart_putc(c); 91 | #endif /* CONFIG_CARL9170FW_DEBUG_UART */ 92 | } 93 | 94 | static inline __inline void print_hex_dump(const void *buf __unused, int len __unused) 95 | { 96 | #ifdef CONFIG_CARL9170FW_DEBUG_USB 97 | usb_print_hex_dump(buf, len); 98 | #endif /* CONFIG_CARL9170FW_DEBUG_USB */ 99 | 100 | #ifdef CONFIG_CARL9170FW_DEBUG_UART 101 | uart_print_hex_dump(buf, len); 102 | #endif /* CONFIG_CARL9170FW_DEBUG_UART */ 103 | } 104 | 105 | #endif /* __CARL9170FW_PRINTF_H */ 106 | 107 | -------------------------------------------------------------------------------- /carlfw/include/rf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * RF routine definitions 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #ifndef __CARL9170FW_RF_H 26 | #define __CARL9170FW_RF_H 27 | 28 | #include "config.h" 29 | 30 | #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS 31 | void rf_notify_set_channel(void); 32 | void rf_cmd(const struct carl9170_cmd *cmd, struct carl9170_rsp *resp); 33 | void rf_psm(void); 34 | #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ 35 | 36 | #endif /* __CARL9170FW_RF_H */ 37 | -------------------------------------------------------------------------------- /carlfw/include/rom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * ROM layout 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #ifndef __CARL9170FW_ROM_H 26 | #define __CARL9170FW_ROM_H 27 | 28 | #include "types.h" 29 | #include "config.h" 30 | #include "compiler.h" 31 | #include "usb.h" 32 | #include "eeprom.h" 33 | 34 | struct ar9170_hwtype { 35 | /* 0x00001370 */ 36 | uint8_t data[4]; 37 | 38 | /* 0x00001374 */ 39 | struct ar9170_led_mode led_mode[AR9170_NUM_LEDS]; 40 | 41 | /* 0x00001378 */ 42 | uint8_t nulldata[2]; 43 | 44 | struct { 45 | /* 0x0000137a */ 46 | struct usb_device_descriptor device_desc; 47 | 48 | /* 0x0000138c */ 49 | uint8_t string0_desc[4]; 50 | 51 | /* 0x00001390 */ 52 | uint8_t string1_desc[32]; 53 | 54 | /* 0x000013b0 */ 55 | uint8_t string2_desc[48]; 56 | 57 | /* 0x000013e0 */ 58 | uint8_t string3_desc[32]; 59 | } usb; 60 | } __packed; 61 | 62 | struct ar9170_rom { 63 | /* 0x00000000 */ 64 | uint32_t *irq_table[2]; 65 | 66 | /* 0x00000008 */ 67 | uint8_t bootcode[4968]; 68 | 69 | /* 0x00001370 */ 70 | struct ar9170_hwtype hw; 71 | 72 | /* 0x00001400 */ 73 | uint8_t data[512]; 74 | 75 | /* eeprom */ 76 | struct ar9170_eeprom sys; 77 | } __packed; 78 | 79 | static const struct ar9170_rom rom __in_section(eeprom); 80 | 81 | #endif /* __CARL9170FW_ROM_H */ 82 | -------------------------------------------------------------------------------- /carlfw/include/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * Clock, Timer & Timing 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #ifndef __CARL9170FW_TIMER_H 26 | #define __CARL9170FW_TIMER_H 27 | 28 | #include "config.h" 29 | 30 | enum cpu_clock_t { 31 | AHB_40MHZ_OSC = 0, 32 | AHB_20_22MHZ = 1, 33 | AHB_40_44MHZ = 2, 34 | AHB_80_88MHZ = 3 35 | }; 36 | 37 | static inline __inline uint32_t get_clock_counter(void) 38 | { 39 | return (get(AR9170_TIMER_REG_CLOCK_HIGH) << 16) | get(AR9170_TIMER_REG_CLOCK_LOW); 40 | } 41 | 42 | /* 43 | * works only up to 97 secs [44 MHz] or 107 secs for 40 MHz 44 | * Also, the delay wait will be affected by 2.4GHz<->5GHz 45 | * band changes. 46 | */ 47 | static inline __inline bool is_after_msecs(const uint32_t t0, const uint32_t msecs) 48 | { 49 | return ((get_clock_counter() - t0) / 1000) > (msecs * fw.ticks_per_usec); 50 | } 51 | 52 | /* 53 | * Note: Be careful with [u]delay. They won't service the 54 | * hardware watchdog timer. It might trigger if you 55 | * wait long enough. Also they don't terminate if sec is 56 | * above 97 sec [44MHz] or more than 107 sec [40MHz]. 57 | */ 58 | static inline __inline void delay(const uint32_t msec) 59 | { 60 | uint32_t t1, t2, dt, wt; 61 | 62 | wt = msec * fw.ticks_per_usec; 63 | 64 | t1 = get_clock_counter(); 65 | while (1) { 66 | t2 = get_clock_counter(); 67 | dt = (t2 - t1) / 1000; 68 | if (dt >= wt) 69 | break; 70 | } 71 | } 72 | 73 | static inline __inline void udelay(const uint32_t usec) 74 | { 75 | uint32_t t1, t2, dt; 76 | 77 | t1 = get_clock_counter(); 78 | while (1) { 79 | t2 = get_clock_counter(); 80 | dt = (t2 - t1); 81 | if (dt >= (usec * fw.ticks_per_usec)) 82 | break; 83 | } 84 | } 85 | 86 | void clock_set(enum cpu_clock_t _clock, bool on); 87 | void handle_timer(void); 88 | void timer_init(const unsigned int timer, const unsigned int interval); 89 | 90 | #endif /* __CARL9170FW_TIMER_H */ 91 | -------------------------------------------------------------------------------- /carlfw/include/uart.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * UART functions definition 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #ifndef __CARL9170FW_UART_H 26 | #define __CARL9170FW_UART_H 27 | 28 | #include "config.h" 29 | 30 | #ifdef CONFIG_CARL9170FW_DEBUG_UART 31 | void uart_putc(const char c); 32 | void uart_print_hex_dump(const void *buf, const int len); 33 | void uart_init(void); 34 | #endif /* CONFIG_CARL9170FW_DEBUG_UART */ 35 | 36 | #endif /* __CARL9170FW_UART_H */ 37 | -------------------------------------------------------------------------------- /carlfw/include/usb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * USB definitions 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #ifndef __CARL9170FW_USB_H 26 | #define __CARL9170FW_USB_H 27 | 28 | #include "config.h" 29 | #include "types.h" 30 | #include "io.h" 31 | #include "hw.h" 32 | #include "ch9.h" 33 | 34 | struct ar9170_usb_config { 35 | struct usb_config_descriptor cfg; 36 | struct usb_interface_descriptor intf; 37 | struct usb_endpoint_descriptor ep[AR9170_USB_NUM_EXTRA_EP]; 38 | } __packed; 39 | 40 | static inline __inline bool usb_detect_highspeed(void) 41 | { 42 | return !!(getb(AR9170_USB_REG_MAIN_CTRL) & 43 | AR9170_USB_MAIN_CTRL_HIGHSPEED); 44 | } 45 | 46 | static inline __inline bool usb_configured(void) 47 | { 48 | return !!(getb(AR9170_USB_REG_DEVICE_ADDRESS) & 49 | AR9170_USB_DEVICE_ADDRESS_CONFIGURE); 50 | } 51 | 52 | static inline __inline void usb_enable_remote_wakeup(void) 53 | { 54 | orb(AR9170_USB_REG_MAIN_CTRL, AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP); 55 | } 56 | 57 | static inline __inline void usb_disable_remote_wakeup(void) 58 | { 59 | andb(AR9170_USB_REG_MAIN_CTRL, ~AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP); 60 | } 61 | 62 | static inline __inline void usb_enable_global_int(void) 63 | { 64 | orb(AR9170_USB_REG_MAIN_CTRL, AR9170_USB_MAIN_CTRL_ENABLE_GLOBAL_INT); 65 | } 66 | 67 | static inline __inline void usb_trigger_out(void) 68 | { 69 | andb(AR9170_USB_REG_INTR_MASK_BYTE_4, 70 | (uint8_t) ~AR9170_USB_INTR_DISABLE_OUT_INT); 71 | } 72 | 73 | static inline __inline void usb_reset_out(void) 74 | { 75 | orb(AR9170_USB_REG_INTR_MASK_BYTE_4, AR9170_USB_INTR_DISABLE_OUT_INT); 76 | } 77 | 78 | static inline __inline void usb_trigger_in(void) 79 | { 80 | andb(AR9170_USB_REG_INTR_MASK_BYTE_6, ~AR9170_USB_INTR_DISABLE_IN_INT); 81 | } 82 | 83 | static inline __inline void usb_reset_in(void) 84 | { 85 | orb(AR9170_USB_REG_INTR_MASK_BYTE_6, AR9170_USB_INTR_DISABLE_IN_INT); 86 | } 87 | 88 | static inline __inline void usb_ep3_xfer_done(void) 89 | { 90 | orb(AR9170_USB_REG_EP3_BYTE_COUNT_HIGH, 0x08); 91 | } 92 | 93 | static inline __inline void usb_suspend_ack(void) 94 | { 95 | /* 96 | * uP must do-over everything it should handle 97 | * and do before into the suspend mode 98 | */ 99 | andb(AR9170_USB_REG_INTR_SOURCE_7, ~BIT(2)); 100 | } 101 | 102 | static inline __inline void usb_resume_ack(void) 103 | { 104 | /* 105 | * uP must do-over everything it should handle 106 | * and do before into the suspend mode 107 | */ 108 | 109 | andb(AR9170_USB_REG_INTR_SOURCE_7, ~BIT(3)); 110 | } 111 | 112 | static inline __inline void usb_reset_ack(void) 113 | { 114 | andb(AR9170_USB_REG_INTR_SOURCE_7, ~BIT(1)); 115 | } 116 | 117 | static inline __inline void usb_data_out0Byte(void) 118 | { 119 | andb(AR9170_USB_REG_INTR_SOURCE_7, (uint8_t) ~BIT(7)); 120 | } 121 | 122 | static inline __inline void usb_data_in0Byte(void) 123 | { 124 | andb(AR9170_USB_REG_INTR_SOURCE_7, ~BIT(6)); 125 | } 126 | 127 | static inline __inline void usb_stop_down_queue(void) 128 | { 129 | andl(AR9170_USB_REG_DMA_CTL, ~AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE); 130 | } 131 | 132 | static inline __inline void usb_start_down_queue(void) 133 | { 134 | orl(AR9170_USB_REG_DMA_CTL, AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE); 135 | } 136 | 137 | static inline __inline void usb_clear_input_ep_toggle(unsigned int ep) 138 | { 139 | andl(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (ep << 1), 140 | ~AR9170_USB_EP_IN_TOGGLE); 141 | } 142 | 143 | static inline __inline void usb_clear_input_ep_stall(unsigned int ep) 144 | { 145 | andl(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (ep << 1), 146 | ~AR9170_USB_EP_IN_STALL); 147 | } 148 | 149 | static inline __inline void usb_set_input_ep_toggle(unsigned int ep) 150 | { 151 | orl(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (ep << 1), 152 | AR9170_USB_EP_IN_TOGGLE); 153 | } 154 | 155 | static inline __inline void usb_clear_output_ep_toggle(unsigned int ep) 156 | { 157 | andl(AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH + (ep << 1), 158 | ~AR9170_USB_EP_OUT_TOGGLE); 159 | } 160 | 161 | static inline __inline void usb_set_output_ep_toggle(unsigned int ep) 162 | { 163 | orl(AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH + (ep << 1), 164 | AR9170_USB_EP_OUT_TOGGLE); 165 | } 166 | 167 | static inline __inline void usb_clear_output_ep_stall(unsigned int ep) 168 | { 169 | andl(AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH + (ep << 1), 170 | ~AR9170_USB_EP_OUT_STALL); 171 | } 172 | 173 | static inline void usb_structure_check(void) 174 | { 175 | BUILD_BUG_ON(sizeof(struct usb_config_descriptor) != USB_DT_CONFIG_SIZE); 176 | BUILD_BUG_ON(sizeof(struct usb_device_descriptor) != USB_DT_DEVICE_SIZE); 177 | BUILD_BUG_ON(sizeof(struct usb_endpoint_descriptor) != USB_DT_ENDPOINT_SIZE); 178 | BUILD_BUG_ON(sizeof(struct usb_interface_descriptor) != USB_DT_INTERFACE_SIZE); 179 | } 180 | 181 | void __noreturn jump_to_bootcode(void); 182 | 183 | void send_cmd_to_host(const uint8_t len, const uint8_t type, 184 | const uint8_t ext, const uint8_t *body); 185 | 186 | void usb_reset_eps(void); 187 | void usb_init(void); 188 | void usb_ep0rx(void); 189 | void usb_ep0tx(void); 190 | void usb_ep0setup(void); 191 | void handle_usb(void); 192 | 193 | void usb_timer(void); 194 | void usb_putc(const char c); 195 | void usb_print_hex_dump(const void *buf, int len); 196 | 197 | void usb_init_highspeed_fifo_cfg(void); 198 | void usb_init_fullspeed_fifo_cfg(void); 199 | 200 | void __noreturn start(void); 201 | void __noreturn reboot(void); 202 | 203 | #endif /* __CARL9170FW_USB_H */ 204 | -------------------------------------------------------------------------------- /carlfw/include/wol.h: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * WakeUp on WLAN definitions 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #ifndef __CARL9170FW_WOL_H 26 | #define __CARL9170FW_WOL_H 27 | 28 | #include "config.h" 29 | #include "compiler.h" 30 | #include "types.h" 31 | 32 | #include "fwcmd.h" 33 | 34 | #ifdef CONFIG_CARL9170FW_WOL 35 | 36 | struct ieee80211_hdr; 37 | 38 | void wol_prepare(void); 39 | void wol_janitor(void); 40 | void wol_rx(const unsigned int rx_filter __unused, 41 | const struct ieee80211_hdr *hdr __unused, 42 | const unsigned int len __unused); 43 | void wol_cmd(const struct carl9170_wol_cmd *cmd); 44 | 45 | #else 46 | 47 | static inline void wol_cmd(const struct carl9170_wol_cmd *cmd __unused) 48 | { 49 | } 50 | 51 | static inline void wol_prepare(void) 52 | { 53 | } 54 | 55 | static inline void wol_janitor(void) 56 | { 57 | } 58 | 59 | static inline void wol_rx(const unsigned int rx_filter __unused, 60 | const struct ieee80211_hdr *hdr __unused, 61 | const unsigned int len __unused) 62 | { 63 | } 64 | #endif /* CONFIG_CARL9170FW_WOL */ 65 | 66 | #endif /* __CARL9170FW_CMD_H */ 67 | -------------------------------------------------------------------------------- /carlfw/src/cam.c: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * Security Engine 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #include "carl9170.h" 26 | #include "cam.h" 27 | 28 | #ifdef CONFIG_CARL9170FW_SECURITY_ENGINE 29 | static void disable_cam_user(const uint16_t userId) 30 | { 31 | if (userId <= 31) 32 | andl(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L, (~((uint32_t) 1 << userId))); 33 | else if (userId <= 63) 34 | andl(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H, (~((uint32_t) 1 << (userId - 32)))); 35 | } 36 | 37 | static void enable_cam_user(const uint16_t userId) 38 | { 39 | if (userId <= 31) 40 | orl(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L, (((uint32_t) 1) << userId)); 41 | else if (userId <= 63) 42 | orl(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H, (((uint32_t) 1) << (userId - 32))); 43 | } 44 | 45 | static void wait_for_cam_read_ready(void) 46 | { 47 | while ((get(AR9170_MAC_REG_CAM_STATE) & AR9170_MAC_CAM_STATE_READ_PENDING) == 0) { 48 | /* 49 | * wait 50 | */ 51 | } 52 | } 53 | 54 | static void wait_for_cam_write_ready(void) 55 | { 56 | while ((get(AR9170_MAC_REG_CAM_STATE) & AR9170_MAC_CAM_STATE_WRITE_PENDING) == 0) { 57 | /* 58 | * wait some more 59 | */ 60 | } 61 | } 62 | 63 | static void HW_CAM_Avail(void) 64 | { 65 | uint32_t tmpValue; 66 | 67 | do { 68 | tmpValue = get(AR9170_MAC_REG_CAM_MODE); 69 | } while (tmpValue & AR9170_MAC_CAM_HOST_PENDING); 70 | } 71 | 72 | static void HW_CAM_Write128(const uint32_t address, const uint32_t *data) 73 | { 74 | HW_CAM_Avail(); 75 | 76 | set(AR9170_MAC_REG_CAM_DATA0, data[0]); 77 | set(AR9170_MAC_REG_CAM_DATA1, data[1]); 78 | set(AR9170_MAC_REG_CAM_DATA2, data[2]); 79 | set(AR9170_MAC_REG_CAM_DATA3, data[3]); 80 | 81 | set(AR9170_MAC_REG_CAM_ADDR, address | AR9170_MAC_CAM_ADDR_WRITE); 82 | 83 | wait_for_cam_write_ready(); 84 | } 85 | 86 | static void HW_CAM_Read128(const uint32_t address, uint32_t *data) 87 | { 88 | 89 | HW_CAM_Avail(); 90 | set(AR9170_MAC_REG_CAM_ADDR, address); 91 | 92 | wait_for_cam_read_ready(); 93 | HW_CAM_Avail(); 94 | data[0] = get(AR9170_MAC_REG_CAM_DATA0); 95 | data[1] = get(AR9170_MAC_REG_CAM_DATA1); 96 | data[2] = get(AR9170_MAC_REG_CAM_DATA2); 97 | data[3] = get(AR9170_MAC_REG_CAM_DATA3); 98 | } 99 | 100 | void set_key(const struct carl9170_set_key_cmd *key) 101 | { 102 | uint32_t data[4]; 103 | uint16_t row, wordId, nibbleId, i; 104 | 105 | if (key->user > (AR9170_CAM_MAX_USER + 3)) 106 | return ; 107 | 108 | if (key->keyId > 1) 109 | return ; 110 | 111 | /* Disable Key */ 112 | disable_cam_user(key->user); 113 | 114 | /* Set encrypt type */ 115 | if (key->user >= AR9170_CAM_MAX_USER) { 116 | /* default */ 117 | row = DEFAULT_ENCRY_TYPE; 118 | wordId = 0; 119 | nibbleId = (key->user - AR9170_CAM_MAX_USER) & 0x7; 120 | } else { 121 | row = ENCRY_TYPE_START_ADDR + (key->user >> 5); 122 | wordId = (key->user >> 3) & 0x3; 123 | nibbleId = key->user & 0x7; 124 | } 125 | 126 | HW_CAM_Read128(row, data); 127 | data[wordId] &= (~(0xf << ((uint32_t) nibbleId * 4))); 128 | data[wordId] |= (key->type << ((uint32_t) nibbleId * 4)); 129 | HW_CAM_Write128(row, data); 130 | 131 | /* Set MAC address */ 132 | if (key->user < AR9170_CAM_MAX_USER) { 133 | uint16_t byteId; 134 | wordId = (key->user >> 2) & 0x3; 135 | byteId = key->user & 0x3; 136 | row = (key->user >> 4) * 6; 137 | 138 | for (i = 0; i < 6; i++) { 139 | HW_CAM_Read128(row + i, data); 140 | data[wordId] &= (~(0xff << ((uint32_t) byteId * 8))); 141 | data[wordId] |= (key->macAddr[i] << ((uint32_t) byteId * 8)); 142 | HW_CAM_Write128(row + i, data); 143 | } 144 | } 145 | 146 | /* Set key */ 147 | row = KEY_START_ADDR + (key->user * 2) + key->keyId; 148 | 149 | HW_CAM_Write128(row, key->key); 150 | 151 | /* Enable Key */ 152 | enable_cam_user(key->user); 153 | } 154 | 155 | void disable_key(const struct carl9170_disable_key_cmd *key) 156 | { 157 | disable_cam_user(key->user); 158 | } 159 | 160 | #endif /* CONFIG_CARL9170FW_SECURITY_ENGINE */ 161 | -------------------------------------------------------------------------------- /carlfw/src/dma.c: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * DMA descriptor handling functions 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #include "carl9170.h" 26 | #include "wl.h" 27 | #include "printf.h" 28 | 29 | struct ar9170_dma_memory dma_mem __in_section(sram); 30 | 31 | static void copy_dma_desc(struct dma_desc *dst, 32 | struct dma_desc *src) 33 | { 34 | memcpy(dst, src, sizeof(struct dma_desc)); 35 | } 36 | 37 | static void clear_descriptor(struct dma_desc *d) 38 | { 39 | d->status = AR9170_OWN_BITS_SW; 40 | d->ctrl = 0; 41 | d->dataSize = 0; 42 | d->totalLen = 0; 43 | d->lastAddr = d; 44 | d->dataAddr = NULL; 45 | d->nextAddr = d; 46 | } 47 | 48 | static void fill_descriptor(struct dma_desc *d, uint16_t size, uint8_t *data) 49 | { 50 | d->status = AR9170_OWN_BITS_SW; 51 | d->ctrl = 0; 52 | d->dataSize = size; 53 | d->totalLen = 0; 54 | d->lastAddr = d; 55 | d->dataAddr = data; 56 | d->nextAddr = NULL; 57 | } 58 | 59 | static void init_queue(struct dma_queue *q, struct dma_desc *d) 60 | { 61 | q->head = q->terminator = d; 62 | } 63 | 64 | /* 65 | * - Init up_queue, down_queue, tx_queue[5], rx_queue. 66 | * - Setup descriptors and data buffer address. 67 | * - Ring descriptors rx_queue and down_queue by dma_reclaim(). 68 | * 69 | * NOTE: LastAddr tempary point (same) to nextAddr after initialize. 70 | * Because LastAddr is don't care in function dma_reclaim(). 71 | */ 72 | void dma_init_descriptors(void) 73 | { 74 | unsigned int i, j; 75 | 76 | for (i = 0; i < ARRAY_SIZE(dma_mem.terminator); i++) 77 | clear_descriptor(&dma_mem.terminator[i]); 78 | 79 | /* Assign terminators to DMA queues */ 80 | i = 0; 81 | init_queue(&fw.pta.up_queue, &dma_mem.terminator[i++]); 82 | init_queue(&fw.pta.down_queue, &dma_mem.terminator[i++]); 83 | for (j = 0; j < __AR9170_NUM_TX_QUEUES; j++) 84 | init_queue(&fw.wlan.tx_queue[j], &dma_mem.terminator[i++]); 85 | init_queue(&fw.wlan.tx_retry, &dma_mem.terminator[i++]); 86 | init_queue(&fw.wlan.rx_queue, &dma_mem.terminator[i++]); 87 | fw.usb.int_desc = &dma_mem.terminator[i++]; 88 | fw.wlan.fw_desc = &dma_mem.terminator[i++]; 89 | 90 | for (j = 0; j < CARL9170_INTF_NUM; j++) 91 | init_queue(&fw.wlan.cab_queue[j], &dma_mem.terminator[i++]); 92 | 93 | BUG_ON(AR9170_TERMINATOR_NUMBER != i); 94 | 95 | DBG("Blocks:%d [tx:%d, rx:%d] Terminators:%d/%d\n", 96 | AR9170_BLOCK_NUMBER, AR9170_TX_BLOCK_NUMBER, 97 | AR9170_RX_BLOCK_NUMBER, AR9170_TERMINATOR_NUMBER, i); 98 | 99 | /* Init descriptors and memory blocks */ 100 | for (i = 0; i < AR9170_BLOCK_NUMBER; i++) { 101 | fill_descriptor(&dma_mem.block[i], AR9170_BLOCK_SIZE, dma_mem.data[i].data); 102 | 103 | if (i < AR9170_TX_BLOCK_NUMBER) 104 | dma_reclaim(&fw.pta.down_queue, &dma_mem.block[i]); 105 | else 106 | dma_reclaim(&fw.wlan.rx_queue, &dma_mem.block[i]); 107 | } 108 | 109 | /* Set DMA address registers */ 110 | set(AR9170_PTA_REG_DN_DMA_ADDRH, (uint32_t) fw.pta.down_queue.head >> 16); 111 | set(AR9170_PTA_REG_DN_DMA_ADDRL, (uint32_t) fw.pta.down_queue.head & 0xffff); 112 | set(AR9170_PTA_REG_UP_DMA_ADDRH, (uint32_t) fw.pta.up_queue.head >> 16); 113 | set(AR9170_PTA_REG_UP_DMA_ADDRL, (uint32_t) fw.pta.up_queue.head & 0xffff); 114 | 115 | for (i = 0; i < __AR9170_NUM_TX_QUEUES; i++) 116 | set_wlan_txq_dma_addr(i, (uint32_t) fw.wlan.tx_queue[i].head); 117 | 118 | set(AR9170_MAC_REG_DMA_RXQ_ADDR, (uint32_t) fw.wlan.rx_queue.head); 119 | fw.usb.int_desc->dataSize = AR9170_BLOCK_SIZE; 120 | fw.usb.int_desc->dataAddr = (void *) &dma_mem.reserved.rsp; 121 | 122 | memset(DESC_PAYLOAD(fw.usb.int_desc), 0xff, 123 | AR9170_INT_MAGIC_HEADER_SIZE); 124 | memset(DESC_PAYLOAD_OFF(fw.usb.int_desc, AR9170_INT_MAGIC_HEADER_SIZE), 125 | 0, AR9170_BLOCK_SIZE - AR9170_INT_MAGIC_HEADER_SIZE); 126 | 127 | /* rsp is now available for use */ 128 | fw.usb.int_desc_available = 1; 129 | 130 | memset(DESC_PAYLOAD(fw.wlan.fw_desc), 0, 128); 131 | fw.wlan.fw_desc_available = 1; 132 | } 133 | 134 | /* 135 | * Free descriptor. 136 | * 137 | * Exchange the terminator and the first descriptor of the packet 138 | * for hardware ascy... 139 | */ 140 | void dma_reclaim(struct dma_queue *q, struct dma_desc *desc) 141 | { 142 | struct dma_desc *tmpDesc, *last; 143 | struct dma_desc tdesc; 144 | 145 | /* 1. Set OWN bit to HW for all TDs to be added, clear ctrl and size */ 146 | tmpDesc = desc; 147 | last = desc->lastAddr; 148 | 149 | while (1) { 150 | tmpDesc->status = AR9170_OWN_BITS_HW; 151 | tmpDesc->ctrl = 0; 152 | tmpDesc->totalLen = 0; 153 | tmpDesc->dataSize = AR9170_BLOCK_SIZE; 154 | 155 | /* TODO : Exception handle */ 156 | 157 | tmpDesc->lastAddr = tmpDesc; 158 | 159 | if (tmpDesc == last) 160 | break; 161 | 162 | tmpDesc = tmpDesc->nextAddr; 163 | } 164 | 165 | /* 2. Next address of Last TD to be added = first TD */ 166 | tmpDesc->nextAddr = desc; 167 | 168 | /* Link first TD to self */ 169 | desc->lastAddr = q->terminator; 170 | 171 | /* 3. Copy first TD to be added to TTD */ 172 | copy_dma_desc(&tdesc, desc); 173 | 174 | /* 4. Initialize new terminator */ 175 | clear_descriptor(desc); 176 | 177 | /* 5. Copy TTD to last TD */ 178 | tdesc.status = 0; 179 | copy_dma_desc((void *)q->terminator, (void *)&tdesc); 180 | q->terminator->status |= AR9170_OWN_BITS_HW; 181 | 182 | /* Update terminator pointer */ 183 | q->terminator = desc; 184 | } 185 | 186 | /* 187 | * Put a complete packet into the tail of the Queue q. 188 | * Exchange the terminator and the first descriptor of the packet 189 | * for hardware ascy... 190 | */ 191 | void dma_put(struct dma_queue *q, struct dma_desc *desc) 192 | { 193 | struct dma_desc *tmpDesc; 194 | struct dma_desc tdesc; 195 | 196 | tmpDesc = desc; 197 | 198 | while (1) { 199 | /* update totalLen */ 200 | tmpDesc->totalLen = desc->totalLen; 201 | 202 | /* 1. Set OWN bit to HW for all TDs to be added */ 203 | tmpDesc->status = AR9170_OWN_BITS_HW; 204 | /* TODO : Exception handle */ 205 | 206 | tmpDesc->lastAddr = desc->lastAddr; 207 | 208 | if (desc->lastAddr == tmpDesc) 209 | break; 210 | 211 | tmpDesc = tmpDesc->nextAddr; 212 | } 213 | 214 | /* 2. Next address of Last TD to be added = first TD */ 215 | desc->lastAddr->nextAddr = desc; 216 | 217 | /* If there is only one descriptor, update pointer of last descriptor */ 218 | if (desc->lastAddr == desc) 219 | desc->lastAddr = q->terminator; 220 | 221 | /* 3. Copy first TD to be added to TTD */ 222 | copy_dma_desc(&tdesc, desc); 223 | 224 | /* 4. Initialize new terminator */ 225 | clear_descriptor(desc); 226 | 227 | /* 5. Copy TTD to last TD */ 228 | tdesc.status &= (~AR9170_OWN_BITS); 229 | copy_dma_desc((void *)q->terminator, (void *)&tdesc); 230 | q->terminator->status |= AR9170_OWN_BITS_HW; 231 | 232 | /* Update terminator pointer */ 233 | q->terminator = desc; 234 | } 235 | 236 | struct dma_desc *dma_unlink_head(struct dma_queue *queue) 237 | { 238 | struct dma_desc *desc; 239 | 240 | if (queue_empty(queue)) 241 | return NULL; 242 | 243 | desc = queue->head; 244 | 245 | queue->head = desc->lastAddr->nextAddr; 246 | 247 | /* poison nextAddr address */ 248 | desc->lastAddr->nextAddr = desc->lastAddr; 249 | desc->lastAddr->lastAddr = desc->lastAddr; 250 | 251 | return desc; 252 | } 253 | -------------------------------------------------------------------------------- /carlfw/src/fw.c: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * Firmware descriptor 5 | * 6 | * Copyright 2009-2011 Christian Lamparter 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 | * You should have received a copy of the GNU General Public License along 19 | * with this program; If not, see . 20 | */ 21 | #include "carl9170.h" 22 | #include "fwdsc.h" 23 | 24 | #define FILL(small, big, more...) \ 25 | .small = { \ 26 | CARL9170FW_FILL_DESC(big##_MAGIC, \ 27 | sizeof(struct carl9170fw_## small##_desc), \ 28 | CARL9170FW_## big##_DESC_MIN_VER, \ 29 | CARL9170FW_## big##_DESC_CUR_VER), \ 30 | more \ 31 | } 32 | 33 | const struct carl9170_firmware_descriptor __in_section(fwdsc) __visible carl9170fw_desc = { 34 | FILL(otus, OTUS, 35 | .feature_set = cpu_to_le32(BIT(CARL9170FW_DUMMY_FEATURE) | 36 | BIT(CARL9170FW_USB_RESP_EP2) | 37 | BIT(CARL9170FW_HANDLE_BACK_REQ) | 38 | BIT(CARL9170FW_RX_FILTER) | 39 | BIT(CARL9170FW_HW_COUNTERS) | 40 | BIT(CARL9170FW_RX_BA_FILTER) | 41 | BIT(CARL9170FW_USB_INIT_FIRMWARE) | 42 | BIT(CARL9170FW_HAS_WREGB_CMD) | 43 | #ifdef CONFIG_CARL9170FW_USB_UP_STREAM 44 | BIT(CARL9170FW_USB_UP_STREAM) | 45 | #endif /* CONFIG_CARL9170FW_USB_UP_STREAM */ 46 | #ifdef CONFIG_CARL9170FW_USB_DOWN_STREAM 47 | BIT(CARL9170FW_USB_DOWN_STREAM) | 48 | #endif /* CONFIG_CARL9170FW_USB_DOWN_STREAM */ 49 | #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS 50 | BIT(CARL9170FW_COMMAND_PHY) | 51 | BIT(CARL9170FW_PSM) | 52 | BIT(CARL9170FW_FIXED_5GHZ_PSM) | 53 | #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ 54 | #ifdef CONFIG_CARL9170FW_SECURITY_ENGINE 55 | BIT(CARL9170FW_COMMAND_CAM) | 56 | #endif /* CONFIG_CARL9170FW_SECURITY_ENGINE */ 57 | BIT(CARL9170FW_WLANTX_CAB) | 58 | #ifdef CONFIG_CARL9170FW_UNUSABLE 59 | BIT(CARL9170FW_UNUSABLE) | 60 | #endif /* CONFIG_CARL9170FW_UNUSABLE */ 61 | #ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT 62 | BIT(CARL9170FW_GPIO_INTERRUPT) | 63 | #endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ 64 | #ifdef CONFIG_CARL9170FW_WOL 65 | BIT(CARL9170FW_WOL) | 66 | #endif /* CONFIG_CARL9170FW_WOL */ 67 | (0)), 68 | 69 | .miniboot_size = cpu_to_le16(0), 70 | .tx_descs = AR9170_TX_BLOCK_NUMBER, 71 | .cmd_bufs = CARL9170_INT_RQ_CACHES, 72 | .rx_max_frame_len = cpu_to_le16(CONFIG_CARL9170FW_RX_FRAME_LEN), 73 | .tx_frag_len = cpu_to_le16(AR9170_BLOCK_SIZE), 74 | .fw_address = cpu_to_le32(AR9170_PRAM_OFFSET), 75 | .bcn_addr = (__le32) cpu_to_le32(&dma_mem.reserved.bcn), 76 | .bcn_len = (__le16) cpu_to_le16(sizeof(dma_mem.reserved.bcn)), 77 | .vif_num = CARL9170_INTF_NUM, 78 | .api_ver = CONFIG_CARL9170FW_RELEASE_VERSION, 79 | ), 80 | 81 | FILL(txsq, TXSQ, 82 | .seq_table_addr = cpu_to_le32(&fw.wlan.sequence), 83 | ), 84 | 85 | #ifdef CONFIG_CARL9170FW_WOL 86 | FILL(wol, WOL, 87 | .supported_triggers = BIT(CARL9170_WOL_DISCONNECT) | 88 | BIT(CARL9170_WOL_MAGIC_PKT), 89 | ), 90 | #endif /* CONFIG_CARL9170FW_WOL */ 91 | 92 | 93 | FILL(motd, MOTD, 94 | .fw_year_month_day = cpu_to_le32( 95 | CARL9170FW_SET_DAY(CARL9170FW_VERSION_DAY) + 96 | CARL9170FW_SET_MONTH(CARL9170FW_VERSION_MONTH) + 97 | CARL9170FW_SET_YEAR(CARL9170FW_VERSION_YEAR)), 98 | .desc = "Community AR9170 Linux", 99 | .release = CARL9170FW_VERSION_GIT), 100 | 101 | FILL(dbg, DBG, 102 | .bogoclock_addr = cpu_to_le32(0), 103 | .counter_addr = cpu_to_le32(&fw.counter), 104 | .rx_total_addr = cpu_to_le32(0), 105 | .rx_overrun_addr = cpu_to_le32(0), 106 | .rx_filter = cpu_to_le32(&fw.wlan.rx_filter), 107 | ), 108 | 109 | FILL(last, LAST), 110 | }; 111 | 112 | #undef FILL 113 | 114 | struct firmware_context_struct fw; 115 | -------------------------------------------------------------------------------- /carlfw/src/gpio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * GPIO interrupt service 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #include "carl9170.h" 26 | #include "gpio.h" 27 | 28 | #ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT 29 | void gpio_timer(void) 30 | { 31 | uint32_t cur; 32 | 33 | cur = get(AR9170_GPIO_REG_PORT_DATA) & CARL9170_GPIO_MASK; 34 | 35 | if (cur != fw.cached_gpio_state.gpio) { 36 | fw.cached_gpio_state.gpio = cur; 37 | 38 | send_cmd_to_host(sizeof(struct carl9170_gpio), 39 | CARL9170_RSP_GPIO, 0x00, 40 | (uint8_t *)&fw.cached_gpio_state); 41 | 42 | # ifdef CONFIG_CARL9170FW_WATCHDOG_BUTTON 43 | for (;;) { 44 | /* 45 | * Loop forever... Until the watchdog triggers. 46 | */ 47 | } 48 | # endif /* CONFIG_CARL9170FW_WATCHDOG_BUTTON */ 49 | } 50 | } 51 | #endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ 52 | -------------------------------------------------------------------------------- /carlfw/src/hostif.c: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * Host interface routines 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2012 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #include "carl9170.h" 26 | #include "hostif.h" 27 | #include "printf.h" 28 | #include "wl.h" 29 | #include "io.h" 30 | #include "cam.h" 31 | #include "rf.h" 32 | #include "timer.h" 33 | #include "wol.h" 34 | 35 | static bool length_check(struct dma_desc *desc) 36 | { 37 | volatile struct carl9170_tx_superframe *super = __get_super(desc); 38 | 39 | if (unlikely(desc->totalLen < sizeof(struct carl9170_tx_superdesc))) 40 | return false; 41 | 42 | /* 43 | * check if the DMA is complete, or clipped. 44 | * 45 | * NB: The hardware aligns the descriptor length to 46 | * a 4 byte boundary. This makes the direct comparison 47 | * difficult, or unnecessary complex for a hot-path. 48 | */ 49 | if (unlikely(super->s.len > desc->totalLen)) 50 | return false; 51 | 52 | return true; 53 | } 54 | 55 | static void handle_download(void) 56 | { 57 | struct dma_desc *desc; 58 | 59 | /* 60 | * Under normal conditions, all completed descs should have 61 | * the AR9170_OWN_BITS_SE status flag set. 62 | * However there seems to be a undocumented case where the flag 63 | * is _SW ( handle_download_exception ) 64 | */ 65 | 66 | for_each_desc_not_bits(desc, &fw.pta.down_queue, AR9170_OWN_BITS_HW) { 67 | if (unlikely((length_check(desc) == false))) { 68 | /* 69 | * There is no easy way of telling what was lost. 70 | * 71 | * Therefore we just reclaim the data. 72 | * The driver has to have some sort frame 73 | * timeout mechanism. 74 | */ 75 | 76 | wlan_tx_complete(__get_super(desc), false); 77 | dma_reclaim(&fw.pta.down_queue, desc); 78 | down_trigger(); 79 | } else { 80 | wlan_tx(desc); 81 | } 82 | } 83 | 84 | #ifdef CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT 85 | xorl(AR9170_GPIO_REG_PORT_DATA, 2); 86 | #endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */ 87 | } 88 | 89 | static void handle_upload(void) 90 | { 91 | struct dma_desc *desc; 92 | 93 | for_each_desc_not_bits(desc, &fw.pta.up_queue, AR9170_OWN_BITS_HW) { 94 | /* 95 | * BIG FAT NOTE: 96 | * 97 | * DO NOT compare the descriptor addresses. 98 | */ 99 | if (DESC_PAYLOAD(desc) == (void *) &dma_mem.reserved.rsp) { 100 | fw.usb.int_desc = desc; 101 | fw.usb.int_desc_available = 1; 102 | } else { 103 | dma_reclaim(&fw.wlan.rx_queue, desc); 104 | wlan_trigger(AR9170_DMA_TRIGGER_RXQ); 105 | } 106 | } 107 | 108 | #ifdef CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT 109 | xorl(AR9170_GPIO_REG_PORT_DATA, 2); 110 | #endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */ 111 | } 112 | 113 | static void handle_download_exception(void) 114 | { 115 | struct dma_desc *desc, *target; 116 | 117 | /* actually, the queue should be stopped by now? */ 118 | usb_stop_down_queue(); 119 | 120 | target = (void *)((get(AR9170_PTA_REG_DN_CURR_ADDRH) << 16) | 121 | get(AR9170_PTA_REG_DN_CURR_ADDRL)); 122 | 123 | /* 124 | * Put "forgotten" packets from the head of the queue, back 125 | * to the current position 126 | */ 127 | __while_desc_bits(desc, &fw.pta.down_queue, AR9170_OWN_BITS_HW) { 128 | if (desc == target) 129 | break; 130 | 131 | dma_reclaim(&fw.pta.down_queue, 132 | dma_unlink_head(&fw.pta.down_queue)); 133 | } 134 | 135 | __for_each_desc_continue(desc, &fw.pta.down_queue) { 136 | if ((desc->status & AR9170_OWN_BITS) == AR9170_OWN_BITS_SW) 137 | dma_fix_downqueue(desc); 138 | } 139 | 140 | 141 | usb_start_down_queue(); 142 | 143 | down_trigger(); 144 | } 145 | 146 | /* handle interrupts from DMA chip */ 147 | void handle_host_interface(void) 148 | { 149 | uint32_t pta_int; 150 | 151 | pta_int = get(AR9170_PTA_REG_INT_FLAG); 152 | 153 | #define HANDLER(intr, flag, func) \ 154 | do { \ 155 | if ((intr & flag) != 0) { \ 156 | func(); \ 157 | } \ 158 | } while (0) 159 | 160 | HANDLER(pta_int, AR9170_PTA_INT_FLAG_DN, handle_download); 161 | 162 | HANDLER(pta_int, AR9170_PTA_INT_FLAG_UP, handle_upload); 163 | 164 | /* This is just guesswork and MAGIC */ 165 | pta_int = get(AR9170_PTA_REG_DMA_STATUS); 166 | HANDLER(pta_int, 0x1, handle_download_exception); 167 | 168 | #undef HANDLER 169 | } 170 | 171 | void handle_cmd(struct carl9170_rsp *resp) 172 | { 173 | struct carl9170_cmd *cmd = &dma_mem.reserved.cmd.cmd; 174 | unsigned int i; 175 | 176 | /* copies cmd, len and extra fields */ 177 | resp->hdr.len = cmd->hdr.len; 178 | resp->hdr.cmd = cmd->hdr.cmd; 179 | resp->hdr.ext = cmd->hdr.ext; 180 | resp->hdr.seq |= cmd->hdr.seq; 181 | 182 | switch (cmd->hdr.cmd & ~CARL9170_CMD_ASYNC_FLAG) { 183 | case CARL9170_CMD_RREG: 184 | for (i = 0; i < (cmd->hdr.len / 4); i++) 185 | resp->rreg_res.vals[i] = get(cmd->rreg.regs[i]); 186 | break; 187 | 188 | case CARL9170_CMD_WREG: 189 | resp->hdr.len = 0; 190 | for (i = 0; i < (cmd->hdr.len / 8); i++) 191 | set(cmd->wreg.regs[i].addr, cmd->wreg.regs[i].val); 192 | break; 193 | 194 | case CARL9170_CMD_ECHO: 195 | memcpy(resp->echo.vals, cmd->echo.vals, cmd->hdr.len); 196 | break; 197 | 198 | case CARL9170_CMD_SWRST: 199 | #ifdef CONFIG_CARL9170FW_FW_MAC_RESET 200 | /* 201 | * Command has no payload, so the response 202 | * has no payload either. 203 | * resp->hdr.len = 0; 204 | */ 205 | fw.wlan.mac_reset = CARL9170_MAC_RESET_FORCE; 206 | #endif /* CONFIG_CARL9170FW_FW_MAC_RESET */ 207 | break; 208 | 209 | case CARL9170_CMD_REBOOT: 210 | /* 211 | * resp->len = 0; 212 | */ 213 | fw.reboot = 1; 214 | break; 215 | 216 | case CARL9170_CMD_READ_TSF: { 217 | uint32_t tmptsf[2]; 218 | 219 | read_tsf(tmptsf); 220 | resp->hdr.len = 8; 221 | memcpy(resp->tsf.tsf, tmptsf, sizeof(tmptsf)); 222 | break; 223 | } 224 | 225 | case CARL9170_CMD_RX_FILTER: 226 | resp->hdr.len = 0; 227 | fw.wlan.rx_filter = cmd->rx_filter.rx_filter; 228 | break; 229 | 230 | case CARL9170_CMD_WOL: 231 | wol_cmd(&cmd->wol); 232 | break; 233 | 234 | case CARL9170_CMD_TALLY: 235 | resp->hdr.len = sizeof(struct carl9170_tally_rsp); 236 | memcpy(&resp->tally, &fw.tally, sizeof(struct carl9170_tally_rsp)); 237 | resp->tally.tick = fw.ticks_per_usec; 238 | memset(&fw.tally, 0, sizeof(struct carl9170_tally_rsp)); 239 | break; 240 | 241 | case CARL9170_CMD_WREGB: 242 | resp->hdr.len = 0; 243 | for (i = 0; i < MIN(cmd->wregb.count, cmd->hdr.len - 8); i++) 244 | setb(cmd->wregb.addr + i, cmd->wregb.val[i]); 245 | break; 246 | 247 | case CARL9170_CMD_BCN_CTRL: 248 | resp->hdr.len = 0; 249 | 250 | if (cmd->bcn_ctrl.mode & CARL9170_BCN_CTRL_CAB_TRIGGER) { 251 | wlan_modify_beacon(cmd->bcn_ctrl.vif_id, 252 | cmd->bcn_ctrl.bcn_addr, cmd->bcn_ctrl.bcn_len); 253 | set(AR9170_MAC_REG_BCN_ADDR, cmd->bcn_ctrl.bcn_addr); 254 | set(AR9170_MAC_REG_BCN_LENGTH, cmd->bcn_ctrl.bcn_len); 255 | set(AR9170_MAC_REG_BCN_CTRL, AR9170_BCN_CTRL_READY); 256 | } else { 257 | wlan_cab_flush_queue(cmd->bcn_ctrl.vif_id); 258 | fw.wlan.cab_flush_trigger[cmd->bcn_ctrl.vif_id] = CARL9170_CAB_TRIGGER_EMPTY; 259 | } 260 | break; 261 | 262 | #ifdef CONFIG_CARL9170FW_SECURITY_ENGINE 263 | case CARL9170_CMD_EKEY: 264 | resp->hdr.len = 0; 265 | set_key(&cmd->setkey); 266 | break; 267 | 268 | case CARL9170_CMD_DKEY: 269 | resp->hdr.len = 0; 270 | disable_key(&cmd->disablekey); 271 | break; 272 | #endif /* CONFIG_CARL9170FW_SECURITY_ENGINE */ 273 | 274 | #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS 275 | case CARL9170_CMD_FREQUENCY: 276 | case CARL9170_CMD_RF_INIT: 277 | rf_cmd(cmd, resp); 278 | break; 279 | 280 | case CARL9170_CMD_FREQ_START: 281 | /* 282 | * resp->hdr.len = 0; 283 | */ 284 | rf_notify_set_channel(); 285 | break; 286 | 287 | case CARL9170_CMD_PSM: 288 | resp->hdr.len = 0; 289 | fw.phy.psm.state = le32_to_cpu(cmd->psm.state); 290 | rf_psm(); 291 | break; 292 | #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ 293 | 294 | default: 295 | BUG("Unknown command %x\n", cmd->hdr.cmd); 296 | break; 297 | } 298 | } 299 | -------------------------------------------------------------------------------- /carlfw/src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * initialization and main() loop 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #include "carl9170.h" 26 | #include "timer.h" 27 | #include "hostif.h" 28 | #include "printf.h" 29 | #include "gpio.h" 30 | #include "wl.h" 31 | #include "rf.h" 32 | #include "usb.h" 33 | 34 | #define AR9170_WATCH_DOG_TIMER 0x100 35 | 36 | static void init(void) 37 | { 38 | led_init(); 39 | 40 | #ifdef CONFIG_CARL9170FW_DEBUG_UART 41 | uart_init(); 42 | #endif /* CONFIG_CARL9170FW_DEBUG_UART */ 43 | 44 | /* 25/50/100ms timer (depends on cpu clock) */ 45 | timer_init(0, 50000); 46 | 47 | /* USB init */ 48 | usb_init(); 49 | 50 | /* initialize DMA memory */ 51 | memset(&dma_mem, 0, sizeof(dma_mem)); 52 | 53 | /* fill DMA rings */ 54 | dma_init_descriptors(); 55 | 56 | /* clear all interrupt */ 57 | set(AR9170_MAC_REG_INT_CTRL, 0xffff); 58 | 59 | orl(AR9170_MAC_REG_AFTER_PNP, 1); 60 | 61 | /* Init watch dog control flag */ 62 | fw.watchdog_enable = 1; 63 | 64 | set(AR9170_TIMER_REG_WATCH_DOG, AR9170_WATCH_DOG_TIMER); 65 | 66 | #ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT 67 | fw.cached_gpio_state.gpio = get(AR9170_GPIO_REG_PORT_DATA) & 68 | CARL9170_GPIO_MASK; 69 | #endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ 70 | 71 | /* this will get the downqueue moving. */ 72 | down_trigger(); 73 | } 74 | 75 | static void handle_fw(void) 76 | { 77 | if (fw.watchdog_enable == 1) 78 | set(AR9170_TIMER_REG_WATCH_DOG, AR9170_WATCH_DOG_TIMER); 79 | 80 | if (fw.reboot) 81 | reboot(); 82 | } 83 | 84 | static void tally_update(void) 85 | { 86 | unsigned int time; 87 | 88 | time = get_clock_counter(); 89 | #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS 90 | if (fw.phy.state == CARL9170_PHY_ON) { 91 | unsigned int boff, delta; 92 | 93 | delta = (time - fw.tally_clock); 94 | 95 | fw.tally.active += delta; 96 | 97 | boff = get(AR9170_MAC_REG_BACKOFF_STATUS); 98 | if (boff & AR9170_MAC_BACKOFF_TX_PE) 99 | fw.tally.tx_time += delta; 100 | if (boff & AR9170_MAC_BACKOFF_CCA) 101 | fw.tally.cca += delta; 102 | } 103 | #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ 104 | fw.tally_clock = time; 105 | fw.counter++; 106 | } 107 | 108 | static void __noreturn main_loop(void) 109 | { 110 | /* main loop */ 111 | while (1) { 112 | handle_fw(); 113 | 114 | /* 115 | * Due to frame order persevation, the wlan subroutines 116 | * must be executed before handle_host_interface. 117 | */ 118 | handle_wlan(); 119 | 120 | handle_host_interface(); 121 | 122 | handle_usb(); 123 | 124 | handle_timer(); 125 | 126 | tally_update(); 127 | } 128 | } 129 | 130 | /* 131 | * The bootcode will work with the device driver to load the firmware 132 | * onto the device's Program SRAM. The Program SRAM has a size of 16 KB 133 | * and also contains the stack, which grows down from 0x204000. 134 | * 135 | * The Program SRAM starts at address 0x200000 on the device. 136 | * The firmware entry point (0x200004) is located in boot.S. 137 | * we put _start() there with the linker script carl9170.lds. 138 | */ 139 | 140 | void __in_section(boot) __noreturn __visible start(void) 141 | { 142 | clock_set(AHB_40MHZ_OSC, true); 143 | 144 | /* watchdog magic pattern check */ 145 | if ((get(AR9170_PWR_REG_WATCH_DOG_MAGIC) & 0xffff0000) == 0x12340000) { 146 | /* watch dog warm start */ 147 | incl(AR9170_PWR_REG_WATCH_DOG_MAGIC); 148 | usb_trigger_out(); 149 | } else if ((get(AR9170_PWR_REG_WATCH_DOG_MAGIC) & 0xffff0000) == 0x98760000) { 150 | /* suspend/resume */ 151 | } 152 | 153 | /* write the magic pattern for watch dog */ 154 | andl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0xFFFF); 155 | orl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0x12340000); 156 | 157 | init(); 158 | 159 | #ifdef CONFIG_CARL9170FW_DEBUG 160 | 161 | BUG("TEST BUG"); 162 | BUG_ON(0x2b || !0x2b); 163 | INFO("INFO MESSAGE"); 164 | 165 | /* a set of unique characters to detect transfer data corruptions */ 166 | DBG("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" 167 | " ~`!1@2#3$4%%5^6&7*8(9)0_-+={[}]|\\:;\"'<,>.?/"); 168 | #endif /* CONFIG_CARL9170FW_DEBUG */ 169 | 170 | /* 171 | * Tell the host, that the firmware has booted and is 172 | * now ready to process requests. 173 | */ 174 | send_cmd_to_host(0, CARL9170_RSP_BOOT, 0x00, NULL); 175 | main_loop(); 176 | } 177 | -------------------------------------------------------------------------------- /carlfw/src/memcpy.S: -------------------------------------------------------------------------------- 1 | /* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $ 2 | * 3 | * "memcpy" implementation of SuperH 4 | * 5 | * Copyright (C) 1999 Niibe Yutaka 6 | * 7 | */ 8 | 9 | /* 10 | * void *memcpy(void *dst, const void *src, size_t n); 11 | * No overlap between the memory of DST and of SRC are assumed. 12 | */ 13 | 14 | .globl _memcpy 15 | .align 2 16 | _memcpy: 17 | tst r6,r6 18 | bt/s 9f ! if n=0, do nothing 19 | mov r4,r0 20 | sub r4,r5 ! From here, r5 has the distance to r0 21 | add r6,r0 ! From here, r0 points the end of copying point 22 | mov #12,r1 23 | cmp/gt r6,r1 24 | bt/s 7f ! if it's too small, copy a byte at once 25 | add #-1,r5 26 | add #1,r5 27 | ! From here, r6 is free 28 | ! 29 | ! r4 --> [ ... ] DST [ ... ] SRC 30 | ! [ ... ] [ ... ] 31 | ! : : 32 | ! r0 --> [ ... ] r0+r5 --> [ ... ] 33 | ! 34 | ! 35 | mov r5,r1 36 | mov #3,r2 37 | and r2,r1 38 | shll2 r1 39 | mov r0,r3 ! Save the value on R0 to R3 40 | mova jmptable,r0 41 | add r1,r0 42 | mov.l @r0,r1 43 | jmp @r1 44 | mov r3,r0 ! and back to R0 45 | .balign 4 46 | jmptable: 47 | .long case0 48 | .long case1 49 | .long case2 50 | .long case3 51 | 52 | ! copy a byte at once 53 | 7: mov r4,r2 54 | add #1,r2 55 | 8: 56 | cmp/hi r2,r0 57 | mov.b @(r0,r5),r1 58 | bt/s 8b ! while (r0>r2) 59 | mov.b r1,@-r0 60 | 9: 61 | rts 62 | nop 63 | 64 | case0: 65 | ! 66 | ! GHIJ KLMN OPQR --> GHIJ KLMN OPQR 67 | ! 68 | ! First, align to long word boundary 69 | mov r0,r3 70 | and r2,r3 71 | tst r3,r3 72 | bt/s 2f 73 | add #-4,r5 74 | add #3,r5 75 | 1: dt r3 76 | mov.b @(r0,r5),r1 77 | bf/s 1b 78 | mov.b r1,@-r0 79 | ! 80 | add #-3,r5 81 | 2: ! Second, copy a long word at once 82 | mov r4,r2 83 | add #7,r2 84 | 3: mov.l @(r0,r5),r1 85 | cmp/hi r2,r0 86 | bt/s 3b 87 | mov.l r1,@-r0 88 | ! 89 | ! Third, copy a byte at once, if necessary 90 | cmp/eq r4,r0 91 | bt/s 9b 92 | add #3,r5 93 | bra 8b 94 | add #-6,r2 95 | 96 | case1: 97 | ! 98 | ! GHIJ KLMN OPQR --> ...G HIJK LMNO PQR. 99 | ! 100 | ! First, align to long word boundary 101 | mov r0,r3 102 | and r2,r3 103 | tst r3,r3 104 | bt/s 2f 105 | add #-1,r5 106 | 1: dt r3 107 | mov.b @(r0,r5),r1 108 | bf/s 1b 109 | mov.b r1,@-r0 110 | ! 111 | 2: ! Second, read a long word and write a long word at once 112 | mov.l @(r0,r5),r1 113 | add #-4,r5 114 | mov r4,r2 115 | add #7,r2 116 | ! 117 | #ifdef __LITTLE_ENDIAN__ 118 | 3: mov r1,r3 ! RQPO 119 | shll16 r3 120 | shll8 r3 ! Oxxx 121 | mov.l @(r0,r5),r1 ! NMLK 122 | mov r1,r6 123 | shlr8 r6 ! xNML 124 | or r6,r3 ! ONML 125 | cmp/hi r2,r0 126 | bt/s 3b 127 | mov.l r3,@-r0 128 | #else 129 | 3: mov r1,r3 ! OPQR 130 | shlr16 r3 131 | shlr8 r3 ! xxxO 132 | mov.l @(r0,r5),r1 ! KLMN 133 | mov r1,r6 134 | shll8 r6 ! LMNx 135 | or r6,r3 ! LMNO 136 | cmp/hi r2,r0 137 | bt/s 3b 138 | mov.l r3,@-r0 139 | #endif 140 | ! 141 | ! Third, copy a byte at once, if necessary 142 | cmp/eq r4,r0 143 | bt/s 9b 144 | add #4,r5 145 | bra 8b 146 | add #-6,r2 147 | 148 | case2: 149 | ! 150 | ! GHIJ KLMN OPQR --> ..GH IJKL MNOP QR.. 151 | ! 152 | ! First, align to word boundary 153 | tst #1,r0 154 | bt/s 2f 155 | add #-1,r5 156 | mov.b @(r0,r5),r1 157 | mov.b r1,@-r0 158 | ! 159 | 2: ! Second, read a word and write a word at once 160 | add #-1,r5 161 | mov r4,r2 162 | add #3,r2 163 | ! 164 | 3: mov.w @(r0,r5),r1 165 | cmp/hi r2,r0 166 | bt/s 3b 167 | mov.w r1,@-r0 168 | ! 169 | ! Third, copy a byte at once, if necessary 170 | cmp/eq r4,r0 171 | bt/s 9b 172 | add #1,r5 173 | mov.b @(r0,r5),r1 174 | rts 175 | mov.b r1,@-r0 176 | 177 | case3: 178 | ! 179 | ! GHIJ KLMN OPQR --> .GHI JKLM NOPQ R... 180 | ! 181 | ! First, align to long word boundary 182 | mov r0,r3 183 | and r2,r3 184 | tst r3,r3 185 | bt/s 2f 186 | add #-1,r5 187 | 1: dt r3 188 | mov.b @(r0,r5),r1 189 | bf/s 1b 190 | mov.b r1,@-r0 191 | ! 192 | 2: ! Second, read a long word and write a long word at once 193 | add #-2,r5 194 | mov.l @(r0,r5),r1 195 | add #-4,r5 196 | mov r4,r2 197 | add #7,r2 198 | ! 199 | #ifdef __LITTLE_ENDIAN__ 200 | 3: mov r1,r3 ! RQPO 201 | shll8 r3 ! QPOx 202 | mov.l @(r0,r5),r1 ! NMLK 203 | mov r1,r6 204 | shlr16 r6 205 | shlr8 r6 ! xxxN 206 | or r6,r3 ! QPON 207 | cmp/hi r2,r0 208 | bt/s 3b 209 | mov.l r3,@-r0 210 | #else 211 | 3: mov r1,r3 ! OPQR 212 | shlr8 r3 ! xOPQ 213 | mov.l @(r0,r5),r1 ! KLMN 214 | mov r1,r6 215 | shll16 r6 216 | shll8 r6 ! Nxxx 217 | or r6,r3 ! NOPQ 218 | cmp/hi r2,r0 219 | bt/s 3b 220 | mov.l r3,@-r0 221 | #endif 222 | ! 223 | ! Third, copy a byte at once, if necessary 224 | cmp/eq r4,r0 225 | bt/s 9b 226 | add #6,r5 227 | bra 8b 228 | add #-6,r2 229 | -------------------------------------------------------------------------------- /carlfw/src/memset.S: -------------------------------------------------------------------------------- 1 | /* $Id: memset.S,v 1.1 2000/04/14 16:49:01 mjd Exp $ 2 | * 3 | * "memset" implementation of SuperH 4 | * 5 | * Copyright (C) 1999 Niibe Yutaka 6 | * 7 | */ 8 | 9 | /* 10 | * void *memset(void *s, int c, size_t n); 11 | */ 12 | 13 | .globl _memset 14 | .align 2 15 | _memset: 16 | tst r6,r6 17 | bt/s 5f ! if n=0, do nothing 18 | add r6,r4 19 | mov #12,r0 20 | cmp/gt r6,r0 21 | bt/s 4f ! if it's too small, set a byte at once 22 | mov r4,r0 23 | and #3,r0 24 | cmp/eq #0,r0 25 | bt/s 2f ! It's aligned 26 | sub r0,r6 27 | 1: 28 | dt r0 29 | bf/s 1b 30 | mov.b r5,@-r4 31 | 2: ! make VVVV 32 | extu.b r5,r5 33 | swap.b r5,r0 ! V0 34 | or r0,r5 ! VV 35 | swap.w r5,r0 ! VV00 36 | or r0,r5 ! VVVV 37 | ! 38 | mov r6,r0 39 | shlr2 r0 40 | shlr r0 ! r0 = r6 >> 3 41 | 3: 42 | dt r0 43 | mov.l r5,@-r4 ! set 8-byte at once 44 | bf/s 3b 45 | mov.l r5,@-r4 46 | ! 47 | mov #7,r0 48 | and r0,r6 49 | tst r6,r6 50 | bt 5f 51 | ! fill bytes 52 | 4: 53 | dt r6 54 | bf/s 4b 55 | mov.b r5,@-r4 56 | 5: 57 | rts 58 | mov r4,r0 59 | -------------------------------------------------------------------------------- /carlfw/src/printf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004,2008 Kustaa Nyholm 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * with this program; If not, see . 16 | */ 17 | 18 | #include "carl9170.h" 19 | #include "printf.h" 20 | 21 | #ifdef CONFIG_CARL9170FW_PRINTF 22 | static char *bf; 23 | static char buf[12]; 24 | static unsigned int num; 25 | static char uc; 26 | static char zs; 27 | 28 | static void out(const char c) 29 | { 30 | *bf++ = c; 31 | } 32 | 33 | static void outDgt(const char dgt) 34 | { 35 | out(dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10)); 36 | zs = 1; 37 | } 38 | 39 | static void divOut(const unsigned int d) 40 | { 41 | unsigned char dgt = 0; 42 | 43 | while (num >= d) { 44 | num -= d; 45 | dgt++; 46 | } 47 | 48 | if (zs || dgt > 0) 49 | outDgt(dgt); 50 | } 51 | 52 | void tfp_printf(const char *fmt, ...) 53 | { 54 | va_list va; 55 | char *p; 56 | unsigned int i; 57 | char ch; 58 | 59 | va_start(va, fmt); 60 | 61 | while ((ch = *(fmt++))) { 62 | if (ch != '%') { 63 | putcharacter(ch); 64 | } else { 65 | char lz = 0; 66 | char w = 0; 67 | ch = *(fmt++); 68 | 69 | if (ch == '0') { 70 | ch = *(fmt++); 71 | lz = 1; 72 | } 73 | 74 | if (ch >= '0' && ch <= '9') { 75 | w = 0; 76 | while (ch >= '0' && ch <= '9') { 77 | w = (((w << 2) + w) << 1) + ch - '0'; 78 | ch = *fmt++; 79 | } 80 | } 81 | 82 | bf = buf; 83 | p = bf; 84 | zs = 0; 85 | 86 | switch (ch) { 87 | case 0: 88 | goto abort; 89 | 90 | case 'u': 91 | case 'd': 92 | num = va_arg(va, unsigned int); 93 | if (ch == 'd' && (int) num < 0) { 94 | num = -(int)num; 95 | out('-'); 96 | } 97 | 98 | for (i = 100000000; i != 1; i /= 10) 99 | divOut(i); 100 | 101 | outDgt(num); 102 | break; 103 | 104 | case 'p': 105 | case 'x': 106 | case 'X': 107 | uc = ch == 'X'; 108 | num = va_arg(va, unsigned int); 109 | for (i = 0x10000000; i != 0x1; i >>= 4) 110 | divOut(i); 111 | 112 | outDgt(num); 113 | break; 114 | 115 | case 'c': 116 | out((char)(va_arg(va, int))); 117 | break; 118 | 119 | case 's': 120 | p = va_arg(va, char*); 121 | break; 122 | case '%': 123 | out('%'); 124 | break; 125 | 126 | default: 127 | break; 128 | } 129 | 130 | *bf = 0; 131 | bf = p; 132 | while (*bf++ && w > 0) 133 | w--; 134 | 135 | while (w-- > 0) 136 | putcharacter(lz ? '0' : ' '); 137 | 138 | while ((ch = *p++)) 139 | putcharacter(ch); 140 | } 141 | } 142 | 143 | abort: 144 | putcharacter('\0'); 145 | va_end(va); 146 | } 147 | 148 | #else 149 | 150 | void min_printf(const char *fmt, ...) 151 | { 152 | char ch; 153 | 154 | do { 155 | ch = *(fmt++); 156 | putcharacter(ch); 157 | } while (ch); 158 | } 159 | 160 | #endif /* CONFIG_CARL9170FW_PRINTF */ 161 | -------------------------------------------------------------------------------- /carlfw/src/reboot.S: -------------------------------------------------------------------------------- 1 | .globl _jump_to_bootcode 2 | .type _jump_to_bootcode, @function 3 | _jump_to_bootcode: 4 | mov.l stack_start, r0 5 | mov.l @r0, sp 6 | mov.l eeprom_start, r0 7 | mov.l @r0, r0 8 | jmp @r0 9 | .align 4 10 | stack_start: .long 0x00000004 11 | eeprom_start: .long 0x00000000 12 | -------------------------------------------------------------------------------- /carlfw/src/timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * timer code 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2012 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #include "carl9170.h" 26 | #include "timer.h" 27 | #include "gpio.h" 28 | #include "printf.h" 29 | #include "wl.h" 30 | 31 | void timer_init(const unsigned int timer, const unsigned int interval) 32 | { 33 | /* Set timer to periodic mode */ 34 | orl(AR9170_TIMER_REG_CONTROL, BIT(timer)); 35 | 36 | /* Set time interval */ 37 | set(AR9170_TIMER_REG_TIMER0 + (timer << 2), interval - 1); 38 | 39 | /* Clear timer interrupt flag */ 40 | orl(AR9170_TIMER_REG_INTERRUPT, BIT(timer)); 41 | } 42 | 43 | void clock_set(enum cpu_clock_t clock_, bool on) 44 | { 45 | /* 46 | * Word of Warning! 47 | * This setting does more than just mess with the CPU Clock. 48 | * So watch out, if you need _stable_ timer interrupts. 49 | */ 50 | #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS 51 | if (fw.phy.frequency < 3000000) 52 | set(AR9170_PWR_REG_PLL_ADDAC, 0x5163); 53 | else 54 | set(AR9170_PWR_REG_PLL_ADDAC, 0x5143); 55 | #else 56 | set(AR9170_PWR_REG_PLL_ADDAC, 0x5163); 57 | #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ 58 | 59 | fw.ticks_per_usec = GET_VAL(AR9170_PWR_PLL_ADDAC_DIV, 60 | get(AR9170_PWR_REG_PLL_ADDAC)); 61 | 62 | set(AR9170_PWR_REG_CLOCK_SEL, (uint32_t) ((on ? 0x70 : 0x600) | clock_)); 63 | 64 | switch (clock_) { 65 | case AHB_20_22MHZ: 66 | fw.ticks_per_usec >>= 1; 67 | /* fall through */ 68 | case AHB_40MHZ_OSC: 69 | /* fall through */ 70 | case AHB_40_44MHZ: 71 | fw.ticks_per_usec >>= 1; 72 | /* fall through */ 73 | case AHB_80_88MHZ: 74 | break; 75 | } 76 | } 77 | 78 | static void timer0_isr(void) 79 | { 80 | wlan_timer(); 81 | 82 | #ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT 83 | gpio_timer(); 84 | #endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ 85 | 86 | #ifdef CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT 87 | set(AR9170_GPIO_REG_PORT_DATA, get(AR9170_GPIO_REG_PORT_DATA) ^ 1); 88 | #endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */ 89 | } 90 | 91 | void handle_timer(void) 92 | { 93 | uint32_t intr; 94 | 95 | intr = get(AR9170_TIMER_REG_INTERRUPT); 96 | 97 | /* ACK timer interrupt */ 98 | set(AR9170_TIMER_REG_INTERRUPT, intr); 99 | 100 | #define HANDLER(intr, flag, func) \ 101 | do { \ 102 | if ((intr & flag) != 0) { \ 103 | intr &= ~flag; \ 104 | func(); \ 105 | } \ 106 | } while (0) 107 | 108 | HANDLER(intr, BIT(0), timer0_isr); 109 | 110 | if (intr) 111 | DBG("Unhandled Timer Event %x", (unsigned int) intr); 112 | 113 | #undef HANDLER 114 | } 115 | -------------------------------------------------------------------------------- /carlfw/src/uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * UART debug interface functions. 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2011 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #include "carl9170.h" 26 | #include "uart.h" 27 | #include "io.h" 28 | 29 | #ifdef CONFIG_CARL9170FW_DEBUG_UART 30 | void uart_putc(const char c) 31 | { 32 | set(AR9170_UART_REG_TX_HOLDING, c); 33 | 34 | while (get(AR9170_UART_REG_LINE_STATUS) & 35 | AR9170_UART_LINE_STS_TX_FIFO_NEAR_EMPTY) { 36 | /* 37 | * wait until the byte has made it 38 | */ 39 | } 40 | } 41 | 42 | void uart_print_hex_dump(const void *buf, const int len) 43 | { 44 | unsigned int offset = 0; 45 | 46 | uart_putc('H'); 47 | uart_putc('D'); 48 | uart_putc(':'); 49 | 50 | while (len > 0) { 51 | uart_putc(*((uint8_t *) buf + offset)); 52 | offset++; 53 | } 54 | } 55 | 56 | void uart_init(void) 57 | { 58 | unsigned int timeout = 0; 59 | 60 | #ifdef CONFIG_CARL9170FW_UART_CLOCK_25M 61 | set(AR9170_UART_REG_DIVISOR_LSB, 0xc); 62 | #elif CONFIG_CARL9170FW_UART_CLOCK_40M 63 | set(AR9170_UART_REG_DIVISOR_LSB, 0x14); /* 40 MHz */ 64 | set(AR9170_UART_REG_REMAINDER, 0xb38e); 65 | #else 66 | #error "Unsupported UART clock" 67 | #endif /* CARL9170FW_UART_CLOCK_25M */ 68 | 69 | while (get(AR9170_UART_REG_LINE_STATUS) & 70 | AR9170_UART_LINE_STS_TRANSMITTER_EMPTY) { 71 | if (timeout++ >= 10000) 72 | break; 73 | } 74 | } 75 | #endif /* CONFIG_CARL9170FW_DEBUG_UART */ 76 | -------------------------------------------------------------------------------- /carlfw/src/udivsi3_i4i-Os.S: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2006 Free Software Foundation, Inc. 2 | 3 | This file is free software; you can redistribute it and/or modify it 4 | under the terms of the GNU General Public License as published by the 5 | Free Software Foundation; either version 2, or (at your option) any 6 | later version. 7 | 8 | In addition to the permissions in the GNU General Public License, the 9 | Free Software Foundation gives you unlimited permission to link the 10 | compiled version of this file into combinations with other programs, 11 | and to distribute those combinations without any restriction coming 12 | from the use of this file. (The General Public License restrictions 13 | do apply in other respects; for example, they cover modification of 14 | the file, and distribution when not linked into a combine 15 | executable.) 16 | 17 | This file is distributed in the hope that it will be useful, but 18 | WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | General Public License for more details. 21 | 22 | You should have received a copy of the GNU General Public License 23 | along with this program; see the file COPYING. If not, write to 24 | with this program; If not, see . */ 25 | 26 | /* Moderately Space-optimized libgcc routines for the Renesas SH / 27 | STMicroelectronics ST40 CPUs. 28 | Contributed by J"orn Rennecke joern.rennecke@st.com. */ 29 | 30 | /* Size: 186 bytes jointly for udivsi3_i4i and sdivsi3_i4i 31 | sh4-200 run times: 32 | udiv small divisor: 55 cycles 33 | udiv large divisor: 52 cycles 34 | sdiv small divisor, positive result: 59 cycles 35 | sdiv large divisor, positive result: 56 cycles 36 | sdiv small divisor, negative result: 65 cycles (*) 37 | sdiv large divisor, negative result: 62 cycles (*) 38 | (*): r2 is restored in the rts delay slot and has a lingering latency 39 | of two more cycles. */ 40 | .balign 4 41 | .global ___udivsi3_i4i 42 | .global ___udivsi3_i4 43 | .set ___udivsi3_i4, ___udivsi3_i4i 44 | ___udivsi3_i4i: 45 | sts pr,r1 46 | mov.l r4,@-r15 47 | extu.w r5,r0 48 | cmp/eq r5,r0 49 | swap.w r4,r0 50 | shlr16 r4 51 | bf/s large_divisor 52 | div0u 53 | mov.l r5,@-r15 54 | shll16 r5 55 | sdiv_small_divisor: 56 | div1 r5,r4 57 | bsr div6 58 | div1 r5,r4 59 | div1 r5,r4 60 | bsr div6 61 | div1 r5,r4 62 | xtrct r4,r0 63 | xtrct r0,r4 64 | bsr div7 65 | swap.w r4,r4 66 | div1 r5,r4 67 | bsr div7 68 | div1 r5,r4 69 | xtrct r4,r0 70 | mov.l @r15+,r5 71 | swap.w r0,r0 72 | mov.l @r15+,r4 73 | jmp @r1 74 | rotcl r0 75 | div7: 76 | div1 r5,r4 77 | div6: 78 | div1 r5,r4; div1 r5,r4; div1 r5,r4 79 | div1 r5,r4; div1 r5,r4; rts; div1 r5,r4 80 | 81 | divx3: 82 | rotcl r0 83 | div1 r5,r4 84 | rotcl r0 85 | div1 r5,r4 86 | rotcl r0 87 | rts 88 | div1 r5,r4 89 | 90 | large_divisor: 91 | mov.l r5,@-r15 92 | sdiv_large_divisor: 93 | xor r4,r0 94 | .rept 4 95 | rotcl r0 96 | bsr divx3 97 | div1 r5,r4 98 | .endr 99 | mov.l @r15+,r5 100 | mov.l @r15+,r4 101 | jmp @r1 102 | rotcl r0 103 | 104 | .global __sdivsi3_i4i 105 | .global __sdivsi3_i4 106 | .global __sdivsi3 107 | .set __sdivsi3_i4, __sdivsi3_i4i 108 | .set __sdivsi3, __sdivsi3_i4i 109 | __sdivsi3_i4i: 110 | mov.l r4,@-r15 111 | cmp/pz r5 112 | mov.l r5,@-r15 113 | bt/s pos_divisor 114 | cmp/pz r4 115 | neg r5,r5 116 | extu.w r5,r0 117 | bt/s neg_result 118 | cmp/eq r5,r0 119 | neg r4,r4 120 | pos_result: 121 | swap.w r4,r0 122 | bra sdiv_check_divisor 123 | sts pr,r1 124 | pos_divisor: 125 | extu.w r5,r0 126 | bt/s pos_result 127 | cmp/eq r5,r0 128 | neg r4,r4 129 | neg_result: 130 | mova negate_result,r0 131 | ; 132 | mov r0,r1 133 | swap.w r4,r0 134 | lds r2,macl 135 | sts pr,r2 136 | sdiv_check_divisor: 137 | shlr16 r4 138 | bf/s sdiv_large_divisor 139 | div0u 140 | bra sdiv_small_divisor 141 | shll16 r5 142 | .balign 4 143 | negate_result: 144 | neg r0,r0 145 | jmp @r2 146 | sts macl,r2 147 | -------------------------------------------------------------------------------- /carlfw/src/wlanrx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * WLAN receive routines 5 | * 6 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 7 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 8 | * Copyright 2009 Johannes Berg 9 | * Copyright 2009-2012 Christian Lamparter 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; If not, see . 23 | */ 24 | 25 | #include "carl9170.h" 26 | #include "shared/phy.h" 27 | #include "hostif.h" 28 | #include "timer.h" 29 | #include "wl.h" 30 | #include "printf.h" 31 | #include "rf.h" 32 | #include "linux/ieee80211.h" 33 | #include "wol.h" 34 | 35 | static struct carl9170_bar_ctx *wlan_get_bar_cache_buffer(void) 36 | { 37 | struct carl9170_bar_ctx *tmp; 38 | 39 | tmp = &fw.wlan.ba_cache[fw.wlan.ba_tail_idx]; 40 | fw.wlan.ba_tail_idx++; 41 | fw.wlan.ba_tail_idx %= CONFIG_CARL9170FW_BACK_REQS_NUM; 42 | if (fw.wlan.queued_ba < CONFIG_CARL9170FW_BACK_REQS_NUM) 43 | fw.wlan.queued_ba++; 44 | 45 | return tmp; 46 | } 47 | 48 | static void handle_bar(struct dma_desc *desc __unused, struct ieee80211_hdr *hdr, 49 | unsigned int len, unsigned int mac_err) 50 | { 51 | struct ieee80211_bar *bar; 52 | struct carl9170_bar_ctx *ctx; 53 | 54 | if (unlikely(mac_err)) { 55 | /* 56 | * This check does a number of things: 57 | * 1. checks if the frame is in good nick 58 | * 2. checks if the RA (MAC) matches 59 | */ 60 | return ; 61 | } 62 | 63 | if (unlikely(len < (sizeof(struct ieee80211_bar) + FCS_LEN))) { 64 | /* 65 | * Sneaky, corrupted BARs... but not with us! 66 | */ 67 | 68 | return ; 69 | } 70 | 71 | bar = (void *) hdr; 72 | 73 | if ((bar->control & cpu_to_le16(IEEE80211_BAR_CTRL_MULTI_TID)) || 74 | !(bar->control & cpu_to_le16(IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA))) { 75 | /* not implemented yet */ 76 | 77 | return ; 78 | } 79 | 80 | ctx = wlan_get_bar_cache_buffer(); 81 | 82 | memcpy(ctx->ra, bar->ra, 6); 83 | memcpy(ctx->ta, bar->ta, 6); 84 | ctx->control = bar->control; 85 | ctx->start_seq_num = bar->start_seq_num; 86 | } 87 | 88 | static unsigned int wlan_rx_filter(struct dma_desc *desc) 89 | { 90 | struct ieee80211_hdr *hdr; 91 | unsigned int data_len; 92 | unsigned int rx_filter; 93 | unsigned int mac_err; 94 | 95 | data_len = ar9170_get_rx_mpdu_len(desc); 96 | mac_err = ar9170_get_rx_macstatus_error(desc); 97 | 98 | #define AR9170_RX_ERROR_BAD (AR9170_RX_ERROR_FCS | AR9170_RX_ERROR_PLCP) 99 | 100 | if (unlikely(data_len < (4 + 6 + FCS_LEN) || 101 | desc->totalLen > CONFIG_CARL9170FW_RX_FRAME_LEN) || 102 | mac_err & AR9170_RX_ERROR_BAD) { 103 | /* 104 | * This frame is too damaged to do anything 105 | * useful with it. 106 | */ 107 | 108 | return CARL9170_RX_FILTER_BAD; 109 | } 110 | 111 | rx_filter = 0; 112 | if (mac_err & AR9170_RX_ERROR_WRONG_RA) 113 | rx_filter |= CARL9170_RX_FILTER_OTHER_RA; 114 | 115 | if (mac_err & AR9170_RX_ERROR_DECRYPT) 116 | rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL; 117 | 118 | hdr = ar9170_get_rx_i3e(desc); 119 | if (likely(ieee80211_is_data(hdr->frame_control))) { 120 | rx_filter |= CARL9170_RX_FILTER_DATA; 121 | } else if (ieee80211_is_ctl(hdr->frame_control)) { 122 | switch (le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE) { 123 | case IEEE80211_STYPE_BACK_REQ: 124 | handle_bar(desc, hdr, data_len, mac_err); 125 | rx_filter |= CARL9170_RX_FILTER_CTL_BACKR; 126 | break; 127 | case IEEE80211_STYPE_PSPOLL: 128 | rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL; 129 | break; 130 | case IEEE80211_STYPE_BACK: 131 | if (fw.wlan.queued_bar) { 132 | /* 133 | * Don't filter block acks when the application 134 | * has queued BARs. This is because the firmware 135 | * can't do the accouting and the application 136 | * has to sort out if the BA belongs to any BARs. 137 | */ 138 | break; 139 | } 140 | /* fall through */ 141 | default: 142 | rx_filter |= CARL9170_RX_FILTER_CTL_OTHER; 143 | break; 144 | } 145 | } else { 146 | /* ieee80211_is_mgmt */ 147 | rx_filter |= CARL9170_RX_FILTER_MGMT; 148 | } 149 | 150 | if (unlikely(fw.suspend_mode == CARL9170_HOST_SUSPENDED)) { 151 | wol_rx(rx_filter, hdr, min(data_len, 152 | (unsigned int)AR9170_BLOCK_SIZE)); 153 | } 154 | 155 | #undef AR9170_RX_ERROR_BAD 156 | 157 | return rx_filter; 158 | } 159 | 160 | void handle_wlan_rx(void) 161 | { 162 | struct dma_desc *desc; 163 | 164 | for_each_desc_not_bits(desc, &fw.wlan.rx_queue, AR9170_OWN_BITS_HW) { 165 | if (!(wlan_rx_filter(desc) & fw.wlan.rx_filter)) { 166 | dma_put(&fw.pta.up_queue, desc); 167 | up_trigger(); 168 | } else { 169 | dma_reclaim(&fw.wlan.rx_queue, desc); 170 | wlan_trigger(AR9170_DMA_TRIGGER_RXQ); 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /carlfw/usb/Kconfig: -------------------------------------------------------------------------------- 1 | menu "USB Firmware Configuration Settings" 2 | 3 | config CARL9170FW_USB_STANDARD_CMDS 4 | def_bool y 5 | prompt "Basic USB Interface" 6 | help 7 | Allows the device to be queried about Standard USB 2.0 Device 8 | Description Descriptors. 9 | 10 | Say Y, unless you don't care if lsusb -v fails. 11 | 12 | config CARL9170FW_USB_UP_STREAM 13 | def_bool y 14 | prompt "USB Upload Stream" 15 | help 16 | This features allows the USB silicon to combine small, single 17 | frames into bigger transfers. This can help to reduce 18 | some per-transfer overhead in the application. 19 | 20 | Say Y, unless you have experienced strange rx corruptions. 21 | 22 | config CARL9170FW_USB_DN_STREAM 23 | def_bool n 24 | prompt "USB Download Stream" 25 | 26 | config CARL9170FW_DEBUG_USB 27 | def_bool y 28 | prompt "Pass debug messages through USB transport" 29 | help 30 | Report all firmware messages through the USB transport. 31 | But there is a catch: In case of a BUG, the USB transport 32 | needs to be functional, otherwise the application won't 33 | receive anything. 34 | 35 | Say Y. 36 | 37 | endmenu 38 | -------------------------------------------------------------------------------- /carlfw/usb/fifo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * carl9170 firmware - used by the ar9170 wireless device 3 | * 4 | * Copyright (c) 2000-2005 ZyDAS Technology Corporation 5 | * Copyright (c) 2007-2009 Atheros Communications, Inc. 6 | * Copyright 2009 Johannes Berg 7 | * Copyright 2009-2011 Christian Lamparter 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program 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 | * You should have received a copy of the GNU General Public License along 20 | * with this program; If not, see . 21 | */ 22 | 23 | #include "carl9170.h" 24 | #include "printf.h" 25 | #include "rom.h" 26 | #include "usb_fifo.h" 27 | 28 | /* TODO / TOTEST */ 29 | #ifdef CONFIG_CARL9170FW_USB_MODESWITCH 30 | static void usb_ep_map(const uint8_t ep, const uint8_t map) 31 | { 32 | setb(AR9170_USB_REG_EP_MAP + (ep - 1), map); 33 | } 34 | 35 | static void usb_fifo_map(const uint8_t fifo, const uint8_t map) 36 | { 37 | setb(AR9170_USB_REG_FIFO_MAP + (fifo - 1), map); 38 | } 39 | 40 | static void usb_fifo_config(const uint8_t fifo, const uint8_t cfg) 41 | { 42 | setb(AR9170_USB_REG_FIFO_CONFIG + (fifo - 1), cfg); 43 | } 44 | 45 | static void usb_ep_packet_size_hi(const uint8_t ep, const uint8_t dir, 46 | const uint16_t size) 47 | { 48 | setb(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (((dir * 0x20) + ep) << 1), 49 | (size >> 8) & 0xf); 50 | } 51 | 52 | static void usb_ep_packet_size_lo(const uint8_t ep, const uint8_t dir, 53 | const uint16_t size) 54 | { 55 | setb(AR9170_USB_REG_EP_IN_MAX_SIZE_LOW + (((dir * 0x20) + ep) << 1), 56 | size & 0xff); 57 | } 58 | 59 | static void usb_ep_in_highbandset(const uint8_t ep, const uint8_t dir, 60 | const uint16_t size) 61 | { 62 | andb(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (ep << 1), ~(BIT(6) | BIT(5))); 63 | 64 | switch (dir) { 65 | case DIRECTION_IN: 66 | setb(AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH + (ep << 1), 67 | ((size >> 11) + 1) << 5); 68 | break; 69 | case DIRECTION_OUT: 70 | default: 71 | break; 72 | } 73 | } 74 | 75 | /* 76 | * vUsbFIFO_EPxCfg_HS(void) 77 | * Description: 78 | * 1. Configure the FIFO and EPx map 79 | * input: none 80 | * output: none 81 | */ 82 | 83 | void usb_init_highspeed_fifo_cfg(void) 84 | { 85 | int i; 86 | 87 | /* EP 1 */ 88 | usb_ep_map(1, HS_C1_I0_A0_EP1_MAP); 89 | usb_fifo_map(HS_C1_I0_A0_EP1_FIFO_START, HS_C1_I0_A0_EP1_FIFO_MAP); 90 | usb_fifo_config(HS_C1_I0_A0_EP1_FIFO_START, HS_C1_I0_A0_EP1_FIFO_CONFIG); 91 | 92 | for (i = HS_C1_I0_A0_EP1_FIFO_START + 1; 93 | i < HS_C1_I0_A0_EP1_FIFO_START + HS_C1_I0_A0_EP1_FIFO_NO; i++) { 94 | usb_fifo_config(i, (HS_C1_I0_A0_EP1_FIFO_CONFIG & (~BIT(7)))); 95 | } 96 | 97 | usb_ep_packet_size_hi(1, HS_C1_I0_A0_EP1_DIRECTION, (HS_C1_I0_A0_EP1_MAX_PACKET & 0x7ff)); 98 | usb_ep_packet_size_lo(1, HS_C1_I0_A0_EP1_DIRECTION, (HS_C1_I0_A0_EP1_MAX_PACKET & 0x7ff)); 99 | usb_ep_in_highbandset(1, HS_C1_I0_A0_EP1_DIRECTION, HS_C1_I0_A0_EP1_MAX_PACKET); 100 | 101 | /* EP 2 */ 102 | usb_ep_map(2, HS_C1_I0_A0_EP2_MAP); 103 | usb_fifo_map(HS_C1_I0_A0_EP2_FIFO_START, HS_C1_I0_A0_EP2_FIFO_MAP); 104 | usb_fifo_config(HS_C1_I0_A0_EP2_FIFO_START, HS_C1_I0_A0_EP2_FIFO_CONFIG); 105 | 106 | for (i = HS_C1_I0_A0_EP2_FIFO_START + 1; 107 | i < HS_C1_I0_A0_EP2_FIFO_START + HS_C1_I0_A0_EP2_FIFO_NO; i++) { 108 | usb_fifo_config(i, (HS_C1_I0_A0_EP2_FIFO_CONFIG & (~BIT(7)))); 109 | } 110 | 111 | usb_ep_packet_size_hi(2, HS_C1_I0_A0_EP2_DIRECTION, (HS_C1_I0_A0_EP2_MAX_PACKET & 0x7ff)); 112 | usb_ep_packet_size_lo(2, HS_C1_I0_A0_EP2_DIRECTION, (HS_C1_I0_A0_EP2_MAX_PACKET & 0x7ff)); 113 | usb_ep_in_highbandset(2, HS_C1_I0_A0_EP2_DIRECTION, HS_C1_I0_A0_EP2_MAX_PACKET); 114 | 115 | /* EP 3 */ 116 | usb_ep_map(3, HS_C1_I0_A0_EP3_MAP); 117 | usb_fifo_map(HS_C1_I0_A0_EP3_FIFO_START, HS_C1_I0_A0_EP3_FIFO_MAP); 118 | usb_fifo_config(HS_C1_I0_A0_EP3_FIFO_START, HS_C1_I0_A0_EP3_FIFO_CONFIG); 119 | 120 | for (i = HS_C1_I0_A0_EP3_FIFO_START + 1; 121 | i < HS_C1_I0_A0_EP3_FIFO_START + HS_C1_I0_A0_EP3_FIFO_NO; i++) { 122 | usb_fifo_config(i, (HS_C1_I0_A0_EP3_FIFO_CONFIG & (~BIT(7)))); 123 | } 124 | 125 | usb_ep_packet_size_hi(3, HS_C1_I0_A0_EP3_DIRECTION, (HS_C1_I0_A0_EP3_MAX_PACKET & 0x7ff)); 126 | usb_ep_packet_size_lo(3, HS_C1_I0_A0_EP3_DIRECTION, (HS_C1_I0_A0_EP3_MAX_PACKET & 0x7ff)); 127 | usb_ep_in_highbandset(3, HS_C1_I0_A0_EP3_DIRECTION, HS_C1_I0_A0_EP3_MAX_PACKET); 128 | 129 | /* EP 4 */ 130 | usb_ep_map(4, HS_C1_I0_A0_EP4_MAP); 131 | usb_fifo_map(HS_C1_I0_A0_EP4_FIFO_START, HS_C1_I0_A0_EP4_FIFO_MAP); 132 | usb_fifo_config(HS_C1_I0_A0_EP4_FIFO_START, HS_C1_I0_A0_EP4_FIFO_CONFIG); 133 | 134 | for (i = HS_C1_I0_A0_EP4_FIFO_START + 1; 135 | i < HS_C1_I0_A0_EP4_FIFO_START + HS_C1_I0_A0_EP4_FIFO_NO; i++) { 136 | usb_fifo_config(i, (HS_C1_I0_A0_EP4_FIFO_CONFIG & (~BIT(7)))); 137 | } 138 | 139 | usb_ep_packet_size_hi(4, HS_C1_I0_A0_EP4_DIRECTION, (HS_C1_I0_A0_EP4_MAX_PACKET & 0x7ff)); 140 | usb_ep_packet_size_lo(4, HS_C1_I0_A0_EP4_DIRECTION, (HS_C1_I0_A0_EP4_MAX_PACKET & 0x7ff)); 141 | usb_ep_in_highbandset(4, HS_C1_I0_A0_EP4_DIRECTION, HS_C1_I0_A0_EP4_MAX_PACKET); 142 | } 143 | 144 | void usb_init_fullspeed_fifo_cfg(void) 145 | { 146 | int i; 147 | 148 | /* EP 1 */ 149 | usb_ep_map(1, FS_C1_I0_A0_EP1_MAP); 150 | usb_fifo_map(FS_C1_I0_A0_EP1_FIFO_START, FS_C1_I0_A0_EP1_FIFO_MAP); 151 | usb_fifo_config(FS_C1_I0_A0_EP1_FIFO_START, FS_C1_I0_A0_EP1_FIFO_CONFIG); 152 | 153 | for (i = FS_C1_I0_A0_EP1_FIFO_START + 1; 154 | i < FS_C1_I0_A0_EP1_FIFO_START + FS_C1_I0_A0_EP1_FIFO_NO; i++) { 155 | usb_fifo_config(i, (FS_C1_I0_A0_EP1_FIFO_CONFIG & (~BIT(7)))); 156 | } 157 | 158 | usb_ep_packet_size_hi(1, FS_C1_I0_A0_EP1_DIRECTION, (FS_C1_I0_A0_EP1_MAX_PACKET & 0x7ff)); 159 | usb_ep_packet_size_lo(1, FS_C1_I0_A0_EP1_DIRECTION, (FS_C1_I0_A0_EP1_MAX_PACKET & 0x7ff)); 160 | /* ``.JWEI 2003/04/29 */ 161 | usb_ep_in_highbandset(1, FS_C1_I0_A0_EP1_DIRECTION, FS_C1_I0_A0_EP1_MAX_PACKET); 162 | 163 | /* EP 2 */ 164 | usb_ep_map(2, FS_C1_I0_A0_EP2_MAP); 165 | usb_fifo_map(FS_C1_I0_A0_EP2_FIFO_START, FS_C1_I0_A0_EP2_FIFO_MAP); 166 | usb_fifo_config(FS_C1_I0_A0_EP2_FIFO_START, FS_C1_I0_A0_EP2_FIFO_CONFIG); 167 | 168 | for (i = FS_C1_I0_A0_EP2_FIFO_START + 1; 169 | i < FS_C1_I0_A0_EP2_FIFO_START + FS_C1_I0_A0_EP2_FIFO_NO; i++) { 170 | usb_fifo_config(i, (FS_C1_I0_A0_EP2_FIFO_CONFIG & (~BIT(7)))); 171 | } 172 | 173 | usb_ep_packet_size_hi(2, FS_C1_I0_A0_EP2_DIRECTION, (FS_C1_I0_A0_EP2_MAX_PACKET & 0x7ff)); 174 | usb_ep_packet_size_lo(2, FS_C1_I0_A0_EP2_DIRECTION, (FS_C1_I0_A0_EP2_MAX_PACKET & 0x7ff)); 175 | usb_ep_in_highbandset(2, FS_C1_I0_A0_EP2_DIRECTION, FS_C1_I0_A0_EP2_MAX_PACKET); 176 | 177 | /* EP 3 */ 178 | usb_ep_map(3, FS_C1_I0_A0_EP3_MAP); 179 | usb_fifo_map(FS_C1_I0_A0_EP3_FIFO_START, FS_C1_I0_A0_EP3_FIFO_MAP); 180 | usb_fifo_config(FS_C1_I0_A0_EP3_FIFO_START, FS_C1_I0_A0_EP3_FIFO_CONFIG); 181 | 182 | for (i = FS_C1_I0_A0_EP3_FIFO_START + 1; 183 | i < FS_C1_I0_A0_EP3_FIFO_START + FS_C1_I0_A0_EP3_FIFO_NO; i++) { 184 | usb_fifo_config(i, (FS_C1_I0_A0_EP3_FIFO_CONFIG & (~BIT(7)))); 185 | } 186 | 187 | usb_ep_packet_size_hi(3, FS_C1_I0_A0_EP3_DIRECTION, (FS_C1_I0_A0_EP3_MAX_PACKET & 0x7ff)); 188 | usb_ep_packet_size_lo(3, FS_C1_I0_A0_EP3_DIRECTION, (FS_C1_I0_A0_EP3_MAX_PACKET & 0x7ff)); 189 | usb_ep_in_highbandset(3, FS_C1_I0_A0_EP3_DIRECTION, FS_C1_I0_A0_EP3_MAX_PACKET); 190 | 191 | /* EP 4 */ 192 | usb_ep_map(4, FS_C1_I0_A0_EP4_MAP); 193 | usb_fifo_map(FS_C1_I0_A0_EP4_FIFO_START, FS_C1_I0_A0_EP4_FIFO_MAP); 194 | usb_fifo_config(FS_C1_I0_A0_EP4_FIFO_START, FS_C1_I0_A0_EP4_FIFO_CONFIG); 195 | 196 | for (i = FS_C1_I0_A0_EP4_FIFO_START + 1; 197 | i < FS_C1_I0_A0_EP4_FIFO_START + FS_C1_I0_A0_EP4_FIFO_NO; i++) { 198 | usb_fifo_config(i, (FS_C1_I0_A0_EP4_FIFO_CONFIG & (~BIT(7)))); 199 | } 200 | 201 | usb_ep_packet_size_hi(4, FS_C1_I0_A0_EP4_DIRECTION, (FS_C1_I0_A0_EP4_MAX_PACKET & 0x7ff)); 202 | usb_ep_packet_size_lo(4, FS_C1_I0_A0_EP4_DIRECTION, (FS_C1_I0_A0_EP4_MAX_PACKET & 0x7ff)); 203 | usb_ep_in_highbandset(4, FS_C1_I0_A0_EP4_DIRECTION, FS_C1_I0_A0_EP4_MAX_PACKET); 204 | } 205 | #endif /* CONFIG_CARL9170FW_USB_MODESWITCH */ 206 | -------------------------------------------------------------------------------- /com.qualcomm.qca.carl9170.firmware.metainfo.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | com.qualcomm.qca.carl9170.firmware 16 | FSFAP 17 | Community AR9170 Linux firmware 18 | Firmware for the Qualcomm Atheros AR9170 USB 802.11n NICs 19 | 20 | https://github.com/chunkeey/carl9170fw 21 | 22 | carl9170-1.fw 23 | 24 | 25 | usb:v0409p0249d* 26 | usb:v0409p02B4d* 27 | usb:v04BBp093Fd* 28 | usb:v057Cp8401d* 29 | usb:v057Cp8402d* 30 | usb:v0586p3417d* 31 | usb:v07D1p3A09d* 32 | usb:v07D1p3A0Fd* 33 | usb:v07D1p3C10d* 34 | usb:v083ApF522d* 35 | usb:v0846p9001d* 36 | usb:v0846p9010d* 37 | usb:v0846p9040d* 38 | usb:v0ACEp1221d* 39 | usb:v0CDEp0023d* 40 | usb:v0CDEp0026d* 41 | usb:v0CDEp0027d* 42 | usb:v0CF3p1001d* 43 | usb:v0CF3p1002d* 44 | usb:v0CF3p1010d* 45 | usb:v0CF3p1011d* 46 | usb:v0CF3p9170d* 47 | usb:v1435p0326d* 48 | usb:v1435p0804d* 49 | usb:v1668p1200d* 50 | usb:v1B75p9170d* 51 | usb:v2019p5304d* 52 | usb:vCACEp0300d* 53 | 54 | 55 | -------------------------------------------------------------------------------- /config/.gitignore: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only 2 | conf 3 | parser.tab.c 4 | parser.tab.h 5 | lexer.lex.c 6 | -------------------------------------------------------------------------------- /config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(config) 4 | 5 | #set(CMAKE_VERBOSE_MAKEFILE ON) 6 | 7 | find_package(BISON REQUIRED) 8 | find_package(FLEX REQUIRED) 9 | 10 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 11 | 12 | file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../include/generated") 13 | 14 | BISON_TARGET(parser parser.y parser.tab.c COMPILE_FLAGS "-l -b parser -p yy -t") 15 | FLEX_TARGET(lexer lexer.l lexer.lex.c COMPILE_FLAGS "-Pyy -L") 16 | 17 | SET(parser_deps ${FLEX_lexer_OUTPUTS}) 18 | SET_SOURCE_FILES_PROPERTIES(${BISON_parser_OUTPUTS} 19 | PROPERTIES OBJECT_DEPENDS "${parser_deps}") 20 | 21 | set(conf_src conf.c util.c symbol.c confdata.c expr.c preprocess.c menu.c ${BISON_parser_OUTPUTS} ${FLEX_lexer_OUTPUTS}) 22 | 23 | add_executable(conf ${conf_src}) 24 | -------------------------------------------------------------------------------- /config/array_size.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef ARRAY_SIZE_H 3 | #define ARRAY_SIZE_H 4 | 5 | /** 6 | * ARRAY_SIZE - get the number of elements in array @arr 7 | * @arr: array to be sized 8 | */ 9 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 10 | 11 | #endif /* ARRAY_SIZE_H */ 12 | -------------------------------------------------------------------------------- /config/hash.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | #ifndef HASH_H 3 | #define HASH_H 4 | 5 | static inline unsigned int hash_str(const char *s) 6 | { 7 | /* fnv32 hash */ 8 | unsigned int hash = 2166136261U; 9 | 10 | for (; *s; s++) 11 | hash = (hash ^ *s) * 0x01000193; 12 | return hash; 13 | } 14 | 15 | /* simplified version of functions from include/linux/hash.h */ 16 | #define GOLDEN_RATIO_32 0x61C88647 17 | 18 | static inline unsigned int hash_32(unsigned int val) 19 | { 20 | return 0x61C88647 * val; 21 | } 22 | 23 | static inline unsigned int hash_ptr(const void *ptr) 24 | { 25 | return hash_32((unsigned int)(unsigned long)ptr); 26 | } 27 | 28 | #endif /* HASH_H */ 29 | -------------------------------------------------------------------------------- /config/hashtable.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | #ifndef HASHTABLE_H 3 | #define HASHTABLE_H 4 | 5 | #include "array_size.h" 6 | #include "list.h" 7 | 8 | #define HASH_SIZE(name) (ARRAY_SIZE(name)) 9 | 10 | #define HASHTABLE_DECLARE(name, size) struct hlist_head name[size] 11 | 12 | #define HASHTABLE_DEFINE(name, size) \ 13 | HASHTABLE_DECLARE(name, size) = \ 14 | { [0 ... ((size) - 1)] = HLIST_HEAD_INIT } 15 | 16 | #define hash_head(table, key) (&(table)[(key) % HASH_SIZE(table)]) 17 | 18 | static inline void __hash_init(struct hlist_head *ht, unsigned int sz) 19 | { 20 | unsigned int i; 21 | 22 | for (i = 0; i < sz; i++) 23 | INIT_HLIST_HEAD(&ht[i]); 24 | } 25 | 26 | /** 27 | * hash_init - initialize a hash table 28 | * @table: hashtable to be initialized 29 | * 30 | * This has to be a macro since HASH_SIZE() will not work on pointers since 31 | * it calculates the size during preprocessing. 32 | */ 33 | #define hash_init(table) __hash_init(table, HASH_SIZE(table)) 34 | 35 | /** 36 | * hash_add - add an object to a hashtable 37 | * @table: hashtable to add to 38 | * @node: the &struct hlist_node of the object to be added 39 | * @key: the key of the object to be added 40 | */ 41 | #define hash_add(table, node, key) \ 42 | hlist_add_head(node, hash_head(table, key)) 43 | 44 | /** 45 | * hash_del - remove an object from a hashtable 46 | * @node: &struct hlist_node of the object to remove 47 | */ 48 | static inline void hash_del(struct hlist_node *node) 49 | { 50 | hlist_del_init(node); 51 | } 52 | 53 | /** 54 | * hash_for_each - iterate over a hashtable 55 | * @table: hashtable to iterate 56 | * @obj: the type * to use as a loop cursor for each entry 57 | * @member: the name of the hlist_node within the struct 58 | */ 59 | #define hash_for_each(table, obj, member) \ 60 | for (int _bkt = 0; _bkt < HASH_SIZE(table); _bkt++) \ 61 | hlist_for_each_entry(obj, &table[_bkt], member) 62 | 63 | /** 64 | * hash_for_each_safe - iterate over a hashtable safe against removal of 65 | * hash entry 66 | * @table: hashtable to iterate 67 | * @obj: the type * to use as a loop cursor for each entry 68 | * @tmp: a &struct hlist_node used for temporary storage 69 | * @member: the name of the hlist_node within the struct 70 | */ 71 | #define hash_for_each_safe(table, obj, tmp, member) \ 72 | for (int _bkt = 0; _bkt < HASH_SIZE(table); _bkt++) \ 73 | hlist_for_each_entry_safe(obj, tmp, &table[_bkt], member) 74 | 75 | /** 76 | * hash_for_each_possible - iterate over all possible objects hashing to the 77 | * same bucket 78 | * @table: hashtable to iterate 79 | * @obj: the type * to use as a loop cursor for each entry 80 | * @member: the name of the hlist_node within the struct 81 | * @key: the key of the objects to iterate over 82 | */ 83 | #define hash_for_each_possible(table, obj, member, key) \ 84 | hlist_for_each_entry(obj, hash_head(table, key), member) 85 | 86 | /** 87 | * hash_for_each_possible_safe - iterate over all possible objects hashing to the 88 | * same bucket safe against removals 89 | * @table: hashtable to iterate 90 | * @obj: the type * to use as a loop cursor for each entry 91 | * @tmp: a &struct hlist_node used for temporary storage 92 | * @member: the name of the hlist_node within the struct 93 | * @key: the key of the objects to iterate over 94 | */ 95 | #define hash_for_each_possible_safe(table, obj, tmp, member, key) \ 96 | hlist_for_each_entry_safe(obj, tmp, hash_head(table, key), member) 97 | 98 | #endif /* HASHTABLE_H */ 99 | -------------------------------------------------------------------------------- /config/internal.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | #ifndef INTERNAL_H 3 | #define INTERNAL_H 4 | 5 | #include "hashtable.h" 6 | 7 | #define SYMBOL_HASHSIZE (1U << 14) 8 | 9 | extern HASHTABLE_DECLARE(sym_hashtable, SYMBOL_HASHSIZE); 10 | 11 | #define for_all_symbols(sym) \ 12 | hash_for_each(sym_hashtable, sym, node) 13 | 14 | #define EXPR_HASHSIZE (1U << 14) 15 | 16 | extern HASHTABLE_DECLARE(expr_hashtable, EXPR_HASHSIZE); 17 | 18 | void expr_invalidate_all(void); 19 | 20 | struct menu; 21 | 22 | extern struct menu *current_menu, *current_entry; 23 | 24 | extern const char *cur_filename; 25 | extern int cur_lineno; 26 | 27 | #endif /* INTERNAL_H */ 28 | -------------------------------------------------------------------------------- /config/list_types.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef LIST_TYPES_H 3 | #define LIST_TYPES_H 4 | 5 | struct list_head { 6 | struct list_head *next, *prev; 7 | }; 8 | 9 | struct hlist_head { 10 | struct hlist_node *first; 11 | }; 12 | 13 | struct hlist_node { 14 | struct hlist_node *next, **pprev; 15 | }; 16 | 17 | #endif /* LIST_TYPES_H */ 18 | -------------------------------------------------------------------------------- /config/lkc.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | /* 3 | * Copyright (C) 2002 Roman Zippel 4 | */ 5 | 6 | #ifndef LKC_H 7 | #define LKC_H 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "expr.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | #include "lkc_proto.h" 20 | 21 | #define SRCTREE "srctree" 22 | 23 | #ifndef CONFIG_ 24 | #define CONFIG_ "CONFIG_" 25 | #endif 26 | static inline const char *CONFIG_prefix(void) 27 | { 28 | return getenv( "CONFIG_" ) ?: CONFIG_; 29 | } 30 | #undef CONFIG_ 31 | #define CONFIG_ CONFIG_prefix() 32 | 33 | extern int yylineno; 34 | void zconfdump(FILE *out); 35 | void zconf_starthelp(void); 36 | FILE *zconf_fopen(const char *name); 37 | void zconf_initscan(const char *name); 38 | void zconf_nextfile(const char *name); 39 | 40 | /* confdata.c */ 41 | extern struct gstr autoconf_cmd; 42 | const char *conf_get_configname(void); 43 | 44 | /* confdata.c and expr.c */ 45 | static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) 46 | { 47 | assert(len != 0); 48 | 49 | if (fwrite(str, len, count, out) != count) 50 | fprintf(stderr, "Error in writing or end of file.\n"); 51 | } 52 | 53 | /* util.c */ 54 | const char *file_lookup(const char *name); 55 | 56 | /* lexer.l */ 57 | int yylex(void); 58 | 59 | struct gstr { 60 | size_t len; 61 | char *s; 62 | /* 63 | * when max_width is not zero long lines in string s (if any) get 64 | * wrapped not to exceed the max_width value 65 | */ 66 | int max_width; 67 | }; 68 | struct gstr str_new(void); 69 | void str_free(struct gstr *gs); 70 | void str_append(struct gstr *gs, const char *s); 71 | void str_printf(struct gstr *gs, const char *fmt, ...); 72 | char *str_get(const struct gstr *gs); 73 | 74 | /* menu.c */ 75 | struct menu *menu_next(struct menu *menu, struct menu *root); 76 | #define menu_for_each_sub_entry(menu, root) \ 77 | for (menu = menu_next(root, root); menu; menu = menu_next(menu, root)) 78 | #define menu_for_each_entry(menu) \ 79 | menu_for_each_sub_entry(menu, &rootmenu) 80 | void _menu_init(void); 81 | void menu_warn(const struct menu *menu, const char *fmt, ...); 82 | struct menu *menu_add_menu(void); 83 | void menu_end_menu(void); 84 | void menu_add_entry(struct symbol *sym); 85 | void menu_add_dep(struct expr *dep); 86 | void menu_add_visibility(struct expr *dep); 87 | struct property *menu_add_prompt(enum prop_type type, const char *prompt, 88 | struct expr *dep); 89 | void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); 90 | void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); 91 | void menu_finalize(void); 92 | void menu_set_type(int type); 93 | 94 | extern struct menu rootmenu; 95 | 96 | bool menu_is_empty(struct menu *menu); 97 | bool menu_is_visible(struct menu *menu); 98 | bool menu_has_prompt(const struct menu *menu); 99 | const char *menu_get_prompt(const struct menu *menu); 100 | struct menu *menu_get_parent_menu(struct menu *menu); 101 | int get_jump_key_char(void); 102 | struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); 103 | void menu_get_ext_help(struct menu *menu, struct gstr *help); 104 | 105 | /* symbol.c */ 106 | void sym_clear_all_valid(void); 107 | struct symbol *sym_choice_default(struct menu *choice); 108 | struct symbol *sym_calc_choice(struct menu *choice); 109 | struct property *sym_get_range_prop(struct symbol *sym); 110 | const char *sym_get_string_default(struct symbol *sym); 111 | struct symbol *sym_check_deps(struct symbol *sym); 112 | struct symbol *prop_get_symbol(const struct property *prop); 113 | 114 | static inline tristate sym_get_tristate_value(const struct symbol *sym) 115 | { 116 | return sym->curr.tri; 117 | } 118 | 119 | static inline bool sym_is_choice(const struct symbol *sym) 120 | { 121 | /* A choice is a symbol with no name */ 122 | return sym->name == NULL; 123 | } 124 | 125 | bool sym_is_choice_value(const struct symbol *sym); 126 | 127 | static inline bool sym_has_value(const struct symbol *sym) 128 | { 129 | return sym->flags & SYMBOL_DEF_USER ? true : false; 130 | } 131 | 132 | #ifdef __cplusplus 133 | } 134 | #endif 135 | 136 | #endif /* LKC_H */ 137 | -------------------------------------------------------------------------------- /config/lkc_proto.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef LKC_PROTO_H 3 | #define LKC_PROTO_H 4 | 5 | #include 6 | 7 | /* confdata.c */ 8 | void conf_parse(const char *name); 9 | int conf_read(const char *name); 10 | int conf_read_simple(const char *name, int); 11 | int conf_write_defconfig(const char *name); 12 | int conf_write(const char *name); 13 | int conf_write_autoconf(int overwrite); 14 | void conf_set_changed(bool val); 15 | bool conf_get_changed(void); 16 | void conf_set_changed_callback(void (*fn)(bool)); 17 | void conf_set_message_callback(void (*fn)(const char *s)); 18 | bool conf_errors(void); 19 | 20 | /* symbol.c */ 21 | struct symbol * sym_lookup(const char *name, int flags); 22 | struct symbol * sym_find(const char *name); 23 | void print_symbol_for_listconfig(struct symbol *sym); 24 | struct symbol ** sym_re_search(const char *pattern); 25 | const char * sym_type_name(enum symbol_type type); 26 | void sym_calc_value(struct symbol *sym); 27 | bool sym_dep_errors(void); 28 | enum symbol_type sym_get_type(const struct symbol *sym); 29 | bool sym_tristate_within_range(const struct symbol *sym, tristate tri); 30 | bool sym_set_tristate_value(struct symbol *sym,tristate tri); 31 | void choice_set_value(struct menu *choice, struct symbol *sym); 32 | tristate sym_toggle_tristate_value(struct symbol *sym); 33 | bool sym_string_valid(struct symbol *sym, const char *newval); 34 | bool sym_string_within_range(struct symbol *sym, const char *str); 35 | bool sym_set_string_value(struct symbol *sym, const char *newval); 36 | bool sym_is_changeable(const struct symbol *sym); 37 | struct menu *sym_get_prompt_menu(const struct symbol *sym); 38 | struct menu *sym_get_choice_menu(const struct symbol *sym); 39 | const char * sym_get_string_value(struct symbol *sym); 40 | 41 | const char * prop_get_type_name(enum prop_type type); 42 | 43 | /* expr.c */ 44 | void expr_print(const struct expr *e, 45 | void (*fn)(void *, struct symbol *, const char *), 46 | void *data, int prevtoken); 47 | 48 | #endif /* LKC_PROTO_H */ 49 | -------------------------------------------------------------------------------- /config/preprocess.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | #ifndef PREPROCESS_H 3 | #define PREPROCESS_H 4 | 5 | enum variable_flavor { 6 | VAR_SIMPLE, 7 | VAR_RECURSIVE, 8 | VAR_APPEND, 9 | }; 10 | 11 | struct gstr; 12 | void env_write_dep(struct gstr *gs); 13 | void variable_add(const char *name, const char *value, 14 | enum variable_flavor flavor); 15 | void variable_all_del(void); 16 | char *expand_dollar(const char **str); 17 | char *expand_one_token(const char **str); 18 | 19 | #endif /* PREPROCESS_H */ 20 | -------------------------------------------------------------------------------- /config/util.c: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0 2 | /* 3 | * Copyright (C) 2002-2005 Roman Zippel 4 | * Copyright (C) 2002-2005 Sam Ravnborg 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "hash.h" 12 | #include "hashtable.h" 13 | #include "xalloc.h" 14 | #include "lkc.h" 15 | 16 | /* hash table of all parsed Kconfig files */ 17 | static HASHTABLE_DEFINE(file_hashtable, 1U << 11); 18 | 19 | struct file { 20 | struct hlist_node node; 21 | char name[]; 22 | }; 23 | 24 | /* file already present in list? If not add it */ 25 | const char *file_lookup(const char *name) 26 | { 27 | struct file *file; 28 | size_t len; 29 | int hash = hash_str(name); 30 | 31 | hash_for_each_possible(file_hashtable, file, node, hash) 32 | if (!strcmp(name, file->name)) 33 | return file->name; 34 | 35 | len = strlen(name); 36 | file = xmalloc(sizeof(*file) + len + 1); 37 | memset(file, 0, sizeof(*file)); 38 | memcpy(file->name, name, len); 39 | file->name[len] = '\0'; 40 | 41 | hash_add(file_hashtable, &file->node, hash); 42 | 43 | str_printf(&autoconf_cmd, "\t%s \\\n", name); 44 | 45 | return file->name; 46 | } 47 | 48 | /* Allocate initial growable string */ 49 | struct gstr str_new(void) 50 | { 51 | struct gstr gs; 52 | gs.s = xmalloc(sizeof(char) * 64); 53 | gs.len = 64; 54 | gs.max_width = 0; 55 | strcpy(gs.s, "\0"); 56 | return gs; 57 | } 58 | 59 | /* Free storage for growable string */ 60 | void str_free(struct gstr *gs) 61 | { 62 | free(gs->s); 63 | gs->s = NULL; 64 | gs->len = 0; 65 | } 66 | 67 | /* Append to growable string */ 68 | void str_append(struct gstr *gs, const char *s) 69 | { 70 | size_t l; 71 | if (s) { 72 | l = strlen(gs->s) + strlen(s) + 1; 73 | if (l > gs->len) { 74 | gs->s = xrealloc(gs->s, l); 75 | gs->len = l; 76 | } 77 | strcat(gs->s, s); 78 | } 79 | } 80 | 81 | /* Append printf formatted string to growable string */ 82 | void str_printf(struct gstr *gs, const char *fmt, ...) 83 | { 84 | va_list ap; 85 | char s[10000]; /* big enough... */ 86 | va_start(ap, fmt); 87 | vsnprintf(s, sizeof(s), fmt, ap); 88 | str_append(gs, s); 89 | va_end(ap); 90 | } 91 | 92 | /* Retrieve value of growable string */ 93 | char *str_get(const struct gstr *gs) 94 | { 95 | return gs->s; 96 | } 97 | -------------------------------------------------------------------------------- /config/xalloc.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | 3 | #ifndef XALLOC_H 4 | #define XALLOC_H 5 | 6 | #include 7 | #include 8 | 9 | static inline void *xmalloc(size_t size) 10 | { 11 | void *p = malloc(size); 12 | 13 | if (!p) 14 | exit(1); 15 | return p; 16 | } 17 | 18 | static inline void *xcalloc(size_t nmemb, size_t size) 19 | { 20 | void *p = calloc(nmemb, size); 21 | 22 | if (!p) 23 | exit(1); 24 | return p; 25 | } 26 | 27 | static inline void *xrealloc(void *p, size_t size) 28 | { 29 | p = realloc(p, size); 30 | if (!p) 31 | exit(1); 32 | return p; 33 | } 34 | 35 | static inline char *xstrdup(const char *s) 36 | { 37 | char *p = strdup(s); 38 | 39 | if (!p) 40 | exit(1); 41 | return p; 42 | } 43 | 44 | static inline char *xstrndup(const char *s, size_t n) 45 | { 46 | char *p = strndup(s, n); 47 | 48 | if (!p) 49 | exit(1); 50 | return p; 51 | } 52 | 53 | #endif /* XALLOC_H */ 54 | -------------------------------------------------------------------------------- /extra/FindUSB-1.0.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find USB-1.0 2 | # Once done this will define 3 | # 4 | # USB-1.0_FOUND - system has USB-1.0 5 | # USB-1.0_INCLUDE_DIRS - the USB-1.0 include directory 6 | # USB-1.0_LIBRARIES - Link these to use USB-1.0 7 | # USB-1.0_DEFINITIONS - Compiler switches required for using USB-1.0 8 | # 9 | # Copyright (c) 2009 Andreas Schneider 10 | # 11 | # Redistribution and use in source and binary forms, with or without 12 | # modification, are permitted provided that the following conditions 13 | # are met: 14 | # 15 | # 1. Redistributions of source code must retain the copyright 16 | # notice, this list of conditions and the following disclaimer. 17 | # 2. Redistributions in binary form must reproduce the copyright 18 | # notice, this list of conditions and the following disclaimer in the 19 | # documentation and/or other materials provided with the distribution. 20 | # 3. The name of the author may not be used to endorse or promote products 21 | # derived from this software without specific prior written permission. 22 | # 23 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 | # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 | # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 | # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | # 34 | 35 | 36 | if (USB-1.0_LIBRARIES AND USB-1.0_INCLUDE_DIRS) 37 | # in cache already 38 | set(USB-1.0_FOUND TRUE) 39 | else (USB-1.0_LIBRARIES AND USB-1.0_INCLUDE_DIRS) 40 | # use pkg-config to get the directories and then use these values 41 | # in the FIND_PATH() and FIND_LIBRARY() calls 42 | if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) 43 | include(UsePkgConfig) 44 | pkgconfig(libusb-1.0 _USB-1.0_INCLUDEDIR _USB-1.0_LIBDIR _USB-1.0_LDFLAGS _USB-1.0_CFLAGS) 45 | else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) 46 | find_package(PkgConfig) 47 | if (PKG_CONFIG_FOUND) 48 | pkg_check_modules(_USB-1.0 libusb-1.0) 49 | endif (PKG_CONFIG_FOUND) 50 | endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) 51 | 52 | find_path(USB-1.0_INCLUDE_DIR 53 | NAMES 54 | libusb.h 55 | PATHS 56 | ${_USB-1.0_INCLUDEDIR} 57 | /usr/include 58 | /usr/local/include 59 | /opt/local/include 60 | /sw/include 61 | PATH_SUFFIXES 62 | libusb-1.0 63 | ) 64 | mark_as_advanced(USB-1.0_INCLUDE_DIR) 65 | 66 | find_library(USB-1.0_LIBRARY 67 | NAMES 68 | usb-1.0 69 | PATHS 70 | ${_USB-1.0_LIBDIR} 71 | /usr/lib 72 | /usr/local/lib 73 | /opt/local/lib 74 | /sw/lib 75 | ) 76 | mark_as_advanced(USB-1.0_LIBRARY) 77 | 78 | if (USB-1.0_LIBRARY) 79 | set(USB-1.0_FOUND TRUE) 80 | mark_as_advanced(USB-1.0_FOUND) 81 | endif (USB-1.0_LIBRARY) 82 | 83 | set(USB-1.0_INCLUDE_DIRS 84 | ${USB-1.0_INCLUDE_DIR} 85 | ) 86 | 87 | if (USB-1.0_FOUND) 88 | set(USB-1.0_LIBRARIES 89 | ${USB-1.0_LIBRARIES} 90 | ${USB-1.0_LIBRARY} 91 | ) 92 | endif (USB-1.0_FOUND) 93 | 94 | if (USB-1.0_INCLUDE_DIRS AND USB-1.0_LIBRARIES) 95 | set(USB-1.0_FOUND TRUE) 96 | endif (USB-1.0_INCLUDE_DIRS AND USB-1.0_LIBRARIES) 97 | 98 | if (USB-1.0_FOUND) 99 | if (NOT USB-1.0_FIND_QUIETLY) 100 | message(STATUS "Found USB-1.0: ${USB-1.0_LIBRARIES}") 101 | endif (NOT USB-1.0_FIND_QUIETLY) 102 | else (USB-1.0_FOUND) 103 | if (USB-1.0_FIND_REQUIRED) 104 | message(FATAL_ERROR "Could not find USB-1.0") 105 | endif (USB-1.0_FIND_REQUIRED) 106 | endif (USB-1.0_FOUND) 107 | 108 | # show the USB-1.0_INCLUDE_DIRS and USB-1.0_LIBRARIES variables only in the advanced view 109 | mark_as_advanced(USB-1.0_INCLUDE_DIRS USB-1.0_LIBRARIES) 110 | 111 | endif (USB-1.0_LIBRARIES AND USB-1.0_INCLUDE_DIRS) 112 | 113 | -------------------------------------------------------------------------------- /extra/libusb-zeropacket.diff: -------------------------------------------------------------------------------- 1 | diff -Nurp libusb-1.0-1.0.2/libusb/libusb.h libusb-1.0-1.0.2-orig/libusb/libusb.h 2 | --- libusb-1.0-1.0.2/libusb/libusb.h 2009-06-07 23:18:19.000000000 +0200 3 | +++ libusb-1.0-1.0.2-orig/libusb/libusb.h 2009-08-10 22:07:41.000000000 +0200 4 | @@ -673,6 +673,9 @@ enum libusb_transfer_flags { 5 | * from your transfer callback, as this will result in a double-free 6 | * when this flag is acted upon. */ 7 | LIBUSB_TRANSFER_FREE_TRANSFER = 1<<2, 8 | + 9 | + /** Send an extra termination packet, when needed */ 10 | + LIBUSB_TRANSFER_ZERO_PACKET = 1<<3, 11 | }; 12 | 13 | /** \ingroup asyncio 14 | diff -Nurp libusb-1.0-1.0.2/libusb/os/linux_usbfs.c libusb-1.0-1.0.2-orig/libusb/os/linux_usbfs.c 15 | --- libusb-1.0-1.0.2/libusb/os/linux_usbfs.c 2009-06-10 22:41:26.000000000 +0200 16 | +++ libusb-1.0-1.0.2-orig/libusb/os/linux_usbfs.c 2009-08-10 22:10:14.000000000 +0200 17 | @@ -1298,6 +1298,8 @@ static int submit_bulk_transfer(struct u 18 | urb->type = urb_type; 19 | urb->endpoint = transfer->endpoint; 20 | urb->buffer = transfer->buffer + (i * MAX_BULK_BUFFER_LENGTH); 21 | + if (transfer->flags & LIBUSB_TRANSFER_ZERO_PACKET) 22 | + urb->flags = USBFS_URB_ZERO_PACKET; 23 | if (i == num_urbs - 1 && last_urb_partial) 24 | urb->buffer_length = transfer->length % MAX_BULK_BUFFER_LENGTH; 25 | else 26 | diff -Nurp libusb-1.0-1.0.2/libusb/os/linux_usbfs.h libusb-1.0-1.0.2-orig/libusb/os/linux_usbfs.h 27 | --- libusb-1.0-1.0.2/libusb/os/linux_usbfs.h 2008-07-16 16:17:57.000000000 +0200 28 | +++ libusb-1.0-1.0.2-orig/libusb/os/linux_usbfs.h 2009-08-10 22:13:15.000000000 +0200 29 | @@ -63,6 +63,9 @@ struct usbfs_getdriver { 30 | #define USBFS_URB_DISABLE_SPD 1 31 | #define USBFS_URB_ISO_ASAP 2 32 | #define USBFS_URB_QUEUE_BULK 0x10 33 | +#define USBFS_URB_NO_FSBR 0x20 34 | +#define USBFS_URB_ZERO_PACKET 0x40 35 | +#define USBFS_URB_NO_INTERRUPT 0x80 36 | 37 | enum usbfs_urb_type { 38 | USBFS_URB_TYPE_ISO = 0, 39 | -------------------------------------------------------------------------------- /extra/sh-elf-linux.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME "Generic") 2 | set(CMAKE_SYSTEM_PROCESSOR "sh2") 3 | 4 | set_property(DIRECTORY PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) 5 | 6 | set(CMAKE_FIND_ROOT_PATH ${CMAKE_SOURCE_DIR}/toolchain/inst/) 7 | 8 | set(CMAKE_C_FLAGS "-m2 -ml -Os -ffreestanding -nostartfiles") 9 | set(CMAKE_C_LINK_FLAGS "-Wl,-static,-EL,-x,--gc-sections,--no-warn-rwx-segments") 10 | set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") 11 | 12 | set(OBJCOPY ${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-objcopy) 13 | set(CMAKE_C_COMPILER "${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-gcc") 14 | set(CMAKE_AR ${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-ar) 15 | set(CMAKE_ASM_COMPILER ${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-as) 16 | set(CMAKE_ASM-ATT_COMPILER ${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-as) 17 | set(CMAKE_LINKER ${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-ld) 18 | set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_SOURCE_DIR}/toolchain/inst/bin/sh-elf-gcc ${CMAKE_C_FLAGS} -o ") 19 | 20 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 21 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 22 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 23 | -------------------------------------------------------------------------------- /genapi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cat < include/shared/version.h 4 | #ifndef __CARL9170_SHARED_VERSION_H 5 | #define __CARL9170_SHARED_VERSION_H 6 | #define CARL9170FW_VERSION_YEAR $((100$(date +%Y)%100)) 7 | #define CARL9170FW_VERSION_MONTH $((100$(date +%m)%100)) 8 | #define CARL9170FW_VERSION_DAY $((100$(date +%d)%100)) 9 | #define CARL9170FW_VERSION_GIT "$(git describe 2>/dev/null)" 10 | #endif /* __CARL9170_SHARED_VERSION_H */ 11 | EOF 12 | -------------------------------------------------------------------------------- /include/linux/byteorder_generic.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef _LINUX_BYTEORDER_GENERIC_H 3 | #define _LINUX_BYTEORDER_GENERIC_H 4 | 5 | /* 6 | * linux/byteorder/generic.h 7 | * Generic Byte-reordering support 8 | * 9 | * The "... p" macros, like le64_to_cpup, can be used with pointers 10 | * to unaligned data, but there will be a performance penalty on 11 | * some architectures. Use get_unaligned for unaligned data. 12 | * 13 | * Francois-Rene Rideau 19970707 14 | * gathered all the good ideas from all asm-foo/byteorder.h into one file, 15 | * cleaned them up. 16 | * I hope it is compliant with non-GCC compilers. 17 | * I decided to put __BYTEORDER_HAS_U64__ in byteorder.h, 18 | * because I wasn't sure it would be ok to put it in types.h 19 | * Upgraded it to 2.1.43 20 | * Francois-Rene Rideau 19971012 21 | * Upgraded it to 2.1.57 22 | * to please Linus T., replaced huge #ifdef's between little/big endian 23 | * by nestedly #include'd files. 24 | * Francois-Rene Rideau 19971205 25 | * Made it to 2.1.71; now a facelift: 26 | * Put files under include/linux/byteorder/ 27 | * Split swab from generic support. 28 | * 29 | * TODO: 30 | * = Regular kernel maintainers could also replace all these manual 31 | * byteswap macros that remain, disseminated among drivers, 32 | * after some grep or the sources... 33 | * = Linus might want to rename all these macros and files to fit his taste, 34 | * to fit his personal naming scheme. 35 | * = it seems that a few drivers would also appreciate 36 | * nybble swapping support... 37 | * = every architecture could add their byteswap macro in asm/byteorder.h 38 | * see how some architectures already do (i386, alpha, ppc, etc) 39 | * = cpu_to_beXX and beXX_to_cpu might some day need to be well 40 | * distinguished throughout the kernel. This is not the case currently, 41 | * since little endian, big endian, and pdp endian machines needn't it. 42 | * But this might be the case for, say, a port of Linux to 20/21 bit 43 | * architectures (and F21 Linux addict around?). 44 | */ 45 | 46 | /* 47 | * The following macros are to be defined by : 48 | * 49 | * Conversion of long and short int between network and host format 50 | * ntohl(__u32 x) 51 | * ntohs(__u16 x) 52 | * htonl(__u32 x) 53 | * htons(__u16 x) 54 | * It seems that some programs (which? where? or perhaps a standard? POSIX?) 55 | * might like the above to be functions, not macros (why?). 56 | * if that's true, then detect them, and take measures. 57 | * Anyway, the measure is: define only ___ntohl as a macro instead, 58 | * and in a separate file, have 59 | * unsigned long inline ntohl(x){return ___ntohl(x);} 60 | * 61 | * The same for constant arguments 62 | * __constant_ntohl(__u32 x) 63 | * __constant_ntohs(__u16 x) 64 | * __constant_htonl(__u32 x) 65 | * __constant_htons(__u16 x) 66 | * 67 | * Conversion of XX-bit integers (16- 32- or 64-) 68 | * between native CPU format and little/big endian format 69 | * 64-bit stuff only defined for proper architectures 70 | * cpu_to_[bl]eXX(__uXX x) 71 | * [bl]eXX_to_cpu(__uXX x) 72 | * 73 | * The same, but takes a pointer to the value to convert 74 | * cpu_to_[bl]eXXp(__uXX x) 75 | * [bl]eXX_to_cpup(__uXX x) 76 | * 77 | * The same, but change in situ 78 | * cpu_to_[bl]eXXs(__uXX x) 79 | * [bl]eXX_to_cpus(__uXX x) 80 | * 81 | * See asm-foo/byteorder.h for examples of how to provide 82 | * architecture-optimized versions 83 | * 84 | */ 85 | 86 | #define cpu_to_le64 __cpu_to_le64 87 | #define le64_to_cpu __le64_to_cpu 88 | #define cpu_to_le32 __cpu_to_le32 89 | #define le32_to_cpu __le32_to_cpu 90 | #define cpu_to_le16 __cpu_to_le16 91 | #define le16_to_cpu __le16_to_cpu 92 | #define cpu_to_be64 __cpu_to_be64 93 | #define be64_to_cpu __be64_to_cpu 94 | #define cpu_to_be32 __cpu_to_be32 95 | #define be32_to_cpu __be32_to_cpu 96 | #define cpu_to_be16 __cpu_to_be16 97 | #define be16_to_cpu __be16_to_cpu 98 | #define cpu_to_le64p __cpu_to_le64p 99 | #define le64_to_cpup __le64_to_cpup 100 | #define cpu_to_le32p __cpu_to_le32p 101 | #define le32_to_cpup __le32_to_cpup 102 | #define cpu_to_le16p __cpu_to_le16p 103 | #define le16_to_cpup __le16_to_cpup 104 | #define cpu_to_be64p __cpu_to_be64p 105 | #define be64_to_cpup __be64_to_cpup 106 | #define cpu_to_be32p __cpu_to_be32p 107 | #define be32_to_cpup __be32_to_cpup 108 | #define cpu_to_be16p __cpu_to_be16p 109 | #define be16_to_cpup __be16_to_cpup 110 | #define cpu_to_le64s __cpu_to_le64s 111 | #define le64_to_cpus __le64_to_cpus 112 | #define cpu_to_le32s __cpu_to_le32s 113 | #define le32_to_cpus __le32_to_cpus 114 | #define cpu_to_le16s __cpu_to_le16s 115 | #define le16_to_cpus __le16_to_cpus 116 | #define cpu_to_be64s __cpu_to_be64s 117 | #define be64_to_cpus __be64_to_cpus 118 | #define cpu_to_be32s __cpu_to_be32s 119 | #define be32_to_cpus __be32_to_cpus 120 | #define cpu_to_be16s __cpu_to_be16s 121 | #define be16_to_cpus __be16_to_cpus 122 | 123 | /* 124 | * They have to be macros in order to do the constant folding 125 | * correctly - if the argument passed into a inline function 126 | * it is no longer constant according to gcc.. 127 | */ 128 | 129 | #undef ntohl 130 | #undef ntohs 131 | #undef htonl 132 | #undef htons 133 | 134 | #define ___htonl(x) __cpu_to_be32(x) 135 | #define ___htons(x) __cpu_to_be16(x) 136 | #define ___ntohl(x) __be32_to_cpu(x) 137 | #define ___ntohs(x) __be16_to_cpu(x) 138 | 139 | #define htonl(x) ___htonl(x) 140 | #define ntohl(x) ___ntohl(x) 141 | #define htons(x) ___htons(x) 142 | #define ntohs(x) ___ntohs(x) 143 | 144 | static inline void le16_add_cpu(__le16 *var, u16 val) 145 | { 146 | *var = cpu_to_le16(le16_to_cpu(*var) + val); 147 | } 148 | 149 | static inline void le32_add_cpu(__le32 *var, u32 val) 150 | { 151 | *var = cpu_to_le32(le32_to_cpu(*var) + val); 152 | } 153 | 154 | static inline void le64_add_cpu(__le64 *var, u64 val) 155 | { 156 | *var = cpu_to_le64(le64_to_cpu(*var) + val); 157 | } 158 | 159 | /* XXX: this stuff can be optimized */ 160 | static inline void le32_to_cpu_array(u32 *buf, unsigned int words) 161 | { 162 | while (words--) { 163 | __le32_to_cpus(buf); 164 | buf++; 165 | } 166 | } 167 | 168 | static inline void cpu_to_le32_array(u32 *buf, unsigned int words) 169 | { 170 | while (words--) { 171 | __cpu_to_le32s(buf); 172 | buf++; 173 | } 174 | } 175 | 176 | static inline void be16_add_cpu(__be16 *var, u16 val) 177 | { 178 | *var = cpu_to_be16(be16_to_cpu(*var) + val); 179 | } 180 | 181 | static inline void be32_add_cpu(__be32 *var, u32 val) 182 | { 183 | *var = cpu_to_be32(be32_to_cpu(*var) + val); 184 | } 185 | 186 | static inline void be64_add_cpu(__be64 *var, u64 val) 187 | { 188 | *var = cpu_to_be64(be64_to_cpu(*var) + val); 189 | } 190 | 191 | static inline void cpu_to_be32_array(__be32 *dst, const u32 *src, size_t len) 192 | { 193 | size_t i; 194 | 195 | for (i = 0; i < len; i++) 196 | dst[i] = cpu_to_be32(src[i]); 197 | } 198 | 199 | static inline void be32_to_cpu_array(u32 *dst, const __be32 *src, size_t len) 200 | { 201 | size_t i; 202 | 203 | for (i = 0; i < len; i++) 204 | dst[i] = be32_to_cpu(src[i]); 205 | } 206 | 207 | #endif /* _LINUX_BYTEORDER_GENERIC_H */ 208 | -------------------------------------------------------------------------------- /include/linux/little_endian.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 | #ifndef _UAPI_LINUX_BYTEORDER_LITTLE_ENDIAN_H 3 | #define _UAPI_LINUX_BYTEORDER_LITTLE_ENDIAN_H 4 | 5 | #ifndef __LITTLE_ENDIAN 6 | #define __LITTLE_ENDIAN 1234 7 | #endif 8 | #ifndef __LITTLE_ENDIAN_BITFIELD 9 | #define __LITTLE_ENDIAN_BITFIELD 10 | #endif 11 | 12 | #define __constant_htonl(x) ((__force __be32)___constant_swab32((x))) 13 | #define __constant_ntohl(x) ___constant_swab32((__force __be32)(x)) 14 | #define __constant_htons(x) ((__force __be16)___constant_swab16((x))) 15 | #define __constant_ntohs(x) ___constant_swab16((__force __be16)(x)) 16 | #define __constant_cpu_to_le64(x) ((__force __le64)(__u64)(x)) 17 | #define __constant_le64_to_cpu(x) ((__force __u64)(__le64)(x)) 18 | #define __constant_cpu_to_le32(x) ((__force __le32)(__u32)(x)) 19 | #define __constant_le32_to_cpu(x) ((__force __u32)(__le32)(x)) 20 | #define __constant_cpu_to_le16(x) ((__force __le16)(__u16)(x)) 21 | #define __constant_le16_to_cpu(x) ((__force __u16)(__le16)(x)) 22 | #define __constant_cpu_to_be64(x) ((__force __be64)___constant_swab64((x))) 23 | #define __constant_be64_to_cpu(x) ___constant_swab64((__force __u64)(__be64)(x)) 24 | #define __constant_cpu_to_be32(x) ((__force __be32)___constant_swab32((x))) 25 | #define __constant_be32_to_cpu(x) ___constant_swab32((__force __u32)(__be32)(x)) 26 | #define __constant_cpu_to_be16(x) ((__force __be16)___constant_swab16((x))) 27 | #define __constant_be16_to_cpu(x) ___constant_swab16((__force __u16)(__be16)(x)) 28 | #define __cpu_to_le64(x) ((__force __le64)(__u64)(x)) 29 | #define __le64_to_cpu(x) ((__force __u64)(__le64)(x)) 30 | #define __cpu_to_le32(x) ((__force __le32)(__u32)(x)) 31 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) 32 | #define __cpu_to_le16(x) ((__force __le16)(__u16)(x)) 33 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) 34 | #define __cpu_to_be64(x) ((__force __be64)__swab64((x))) 35 | #define __be64_to_cpu(x) __swab64((__force __u64)(__be64)(x)) 36 | #define __cpu_to_be32(x) ((__force __be32)__swab32((x))) 37 | #define __be32_to_cpu(x) __swab32((__force __u32)(__be32)(x)) 38 | #define __cpu_to_be16(x) ((__force __be16)__swab16((x))) 39 | #define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x)) 40 | 41 | static inline __always_inline __le64 __cpu_to_le64p(const __u64 *p) 42 | { 43 | return (__force __le64)*p; 44 | } 45 | static inline __always_inline __u64 __le64_to_cpup(const __le64 *p) 46 | { 47 | return (__force __u64)*p; 48 | } 49 | static inline __always_inline __le32 __cpu_to_le32p(const __u32 *p) 50 | { 51 | return (__force __le32)*p; 52 | } 53 | static inline __always_inline __u32 __le32_to_cpup(const __le32 *p) 54 | { 55 | return (__force __u32)*p; 56 | } 57 | static inline __always_inline __le16 __cpu_to_le16p(const __u16 *p) 58 | { 59 | return (__force __le16)*p; 60 | } 61 | static inline __always_inline __u16 __le16_to_cpup(const __le16 *p) 62 | { 63 | return (__force __u16)*p; 64 | } 65 | static inline __always_inline __be64 __cpu_to_be64p(const __u64 *p) 66 | { 67 | return (__force __be64)__swab64p(p); 68 | } 69 | static inline __always_inline __u64 __be64_to_cpup(const __be64 *p) 70 | { 71 | return __swab64p((__u64 *)p); 72 | } 73 | static inline __always_inline __be32 __cpu_to_be32p(const __u32 *p) 74 | { 75 | return (__force __be32)__swab32p(p); 76 | } 77 | static inline __always_inline __u32 __be32_to_cpup(const __be32 *p) 78 | { 79 | return __swab32p((__u32 *)p); 80 | } 81 | static inline __always_inline __be16 __cpu_to_be16p(const __u16 *p) 82 | { 83 | return (__force __be16)__swab16p(p); 84 | } 85 | static inline __always_inline __u16 __be16_to_cpup(const __be16 *p) 86 | { 87 | return __swab16p((__u16 *)p); 88 | } 89 | #define __cpu_to_le64s(x) do { (void)(x); } while (0) 90 | #define __le64_to_cpus(x) do { (void)(x); } while (0) 91 | #define __cpu_to_le32s(x) do { (void)(x); } while (0) 92 | #define __le32_to_cpus(x) do { (void)(x); } while (0) 93 | #define __cpu_to_le16s(x) do { (void)(x); } while (0) 94 | #define __le16_to_cpus(x) do { (void)(x); } while (0) 95 | #define __cpu_to_be64s(x) __swab64s((x)) 96 | #define __be64_to_cpus(x) __swab64s((x)) 97 | #define __cpu_to_be32s(x) __swab32s((x)) 98 | #define __be32_to_cpus(x) __swab32s((x)) 99 | #define __cpu_to_be16s(x) __swab16s((x)) 100 | #define __be16_to_cpus(x) __swab16s((x)) 101 | 102 | 103 | #endif /* _UAPI_LINUX_BYTEORDER_LITTLE_ENDIAN_H */ 104 | -------------------------------------------------------------------------------- /include/linux/packed_struct.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_UNALIGNED_PACKED_STRUCT_H 2 | #define _LINUX_UNALIGNED_PACKED_STRUCT_H 3 | 4 | struct __una_u16 { u16 x; } __packed; 5 | struct __una_u32 { u32 x; } __packed; 6 | struct __una_u64 { u64 x; } __packed; 7 | 8 | static inline u16 __get_unaligned_cpu16(const void *p) 9 | { 10 | const struct __una_u16 *ptr = (const struct __una_u16 *)p; 11 | return ptr->x; 12 | } 13 | 14 | static inline u32 __get_unaligned_cpu32(const void *p) 15 | { 16 | const struct __una_u32 *ptr = (const struct __una_u32 *)p; 17 | return ptr->x; 18 | } 19 | 20 | static inline u64 __get_unaligned_cpu64(const void *p) 21 | { 22 | const struct __una_u64 *ptr = (const struct __una_u64 *)p; 23 | return ptr->x; 24 | } 25 | 26 | static inline void __put_unaligned_cpu16(u16 val, void *p) 27 | { 28 | struct __una_u16 *ptr = (struct __una_u16 *)p; 29 | ptr->x = val; 30 | } 31 | 32 | static inline void __put_unaligned_cpu32(u32 val, void *p) 33 | { 34 | struct __una_u32 *ptr = (struct __una_u32 *)p; 35 | ptr->x = val; 36 | } 37 | 38 | static inline void __put_unaligned_cpu64(u64 val, void *p) 39 | { 40 | struct __una_u64 *ptr = (struct __una_u64 *)p; 41 | ptr->x = val; 42 | } 43 | 44 | #endif /* _LINUX_UNALIGNED_PACKED_STRUCT_H */ 45 | -------------------------------------------------------------------------------- /include/linux/swab.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 | #ifndef _UAPI_LINUX_SWAB_H 3 | #define _UAPI_LINUX_SWAB_H 4 | 5 | /* 6 | * casts are necessary for constants, because we never know how for sure 7 | * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way. 8 | */ 9 | #define ___constant_swab16(x) ((__u16)( \ 10 | (((__u16)(x) & (__u16)0x00ffU) << 8) | \ 11 | (((__u16)(x) & (__u16)0xff00U) >> 8))) 12 | 13 | #define ___constant_swab32(x) ((__u32)( \ 14 | (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ 15 | (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ 16 | (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ 17 | (((__u32)(x) & (__u32)0xff000000UL) >> 24))) 18 | 19 | #define ___constant_swab64(x) ((__u64)( \ 20 | (((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \ 21 | (((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \ 22 | (((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \ 23 | (((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \ 24 | (((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \ 25 | (((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ 26 | (((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \ 27 | (((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56))) 28 | 29 | #define ___constant_swahw32(x) ((__u32)( \ 30 | (((__u32)(x) & (__u32)0x0000ffffUL) << 16) | \ 31 | (((__u32)(x) & (__u32)0xffff0000UL) >> 16))) 32 | 33 | #define ___constant_swahb32(x) ((__u32)( \ 34 | (((__u32)(x) & (__u32)0x00ff00ffUL) << 8) | \ 35 | (((__u32)(x) & (__u32)0xff00ff00UL) >> 8))) 36 | 37 | /* 38 | * Implement the following as inlines, but define the interface using 39 | * macros to allow constant folding when possible: 40 | * ___swab16, ___swab32, ___swab64, ___swahw32, ___swahb32 41 | */ 42 | 43 | static inline __attribute_const__ __u16 __fswab16(__u16 val) 44 | { 45 | #if defined (__arch_swab16) 46 | return __arch_swab16(val); 47 | #else 48 | return ___constant_swab16(val); 49 | #endif 50 | } 51 | 52 | static inline __attribute_const__ __u32 __fswab32(__u32 val) 53 | { 54 | #if defined(__arch_swab32) 55 | return __arch_swab32(val); 56 | #else 57 | return ___constant_swab32(val); 58 | #endif 59 | } 60 | 61 | static inline __attribute_const__ __u64 __fswab64(__u64 val) 62 | { 63 | #if defined (__arch_swab64) 64 | return __arch_swab64(val); 65 | #elif defined(__SWAB_64_THRU_32__) 66 | __u32 h = val >> 32; 67 | __u32 l = val & ((1ULL << 32) - 1); 68 | return (((__u64)__fswab32(l)) << 32) | ((__u64)(__fswab32(h))); 69 | #else 70 | return ___constant_swab64(val); 71 | #endif 72 | } 73 | 74 | static inline __attribute_const__ __u32 __fswahw32(__u32 val) 75 | { 76 | #ifdef __arch_swahw32 77 | return __arch_swahw32(val); 78 | #else 79 | return ___constant_swahw32(val); 80 | #endif 81 | } 82 | 83 | static inline __attribute_const__ __u32 __fswahb32(__u32 val) 84 | { 85 | #ifdef __arch_swahb32 86 | return __arch_swahb32(val); 87 | #else 88 | return ___constant_swahb32(val); 89 | #endif 90 | } 91 | 92 | /** 93 | * __swab16 - return a byteswapped 16-bit value 94 | * @x: value to byteswap 95 | */ 96 | #ifdef __HAVE_BUILTIN_BSWAP16__ 97 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x)) 98 | #else 99 | #define __swab16(x) \ 100 | (__u16)(__builtin_constant_p(x) ? \ 101 | ___constant_swab16(x) : \ 102 | __fswab16(x)) 103 | #endif 104 | 105 | /** 106 | * __swab32 - return a byteswapped 32-bit value 107 | * @x: value to byteswap 108 | */ 109 | #ifdef __HAVE_BUILTIN_BSWAP32__ 110 | #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x)) 111 | #else 112 | #define __swab32(x) \ 113 | (__u32)(__builtin_constant_p(x) ? \ 114 | ___constant_swab32(x) : \ 115 | __fswab32(x)) 116 | #endif 117 | 118 | /** 119 | * __swab64 - return a byteswapped 64-bit value 120 | * @x: value to byteswap 121 | */ 122 | #ifdef __HAVE_BUILTIN_BSWAP64__ 123 | #define __swab64(x) (__u64)__builtin_bswap64((__u64)(x)) 124 | #else 125 | #define __swab64(x) \ 126 | (__u64)(__builtin_constant_p(x) ? \ 127 | ___constant_swab64(x) : \ 128 | __fswab64(x)) 129 | #endif 130 | 131 | static inline __always_inline unsigned long __swab(const unsigned long y) 132 | { 133 | #if __BITS_PER_LONG == 64 134 | return __swab64(y); 135 | #else /* __BITS_PER_LONG == 32 */ 136 | return __swab32(y); 137 | #endif 138 | } 139 | 140 | /** 141 | * __swahw32 - return a word-swapped 32-bit value 142 | * @x: value to wordswap 143 | * 144 | * __swahw32(0x12340000) is 0x00001234 145 | */ 146 | #define __swahw32(x) \ 147 | (__builtin_constant_p((__u32)(x)) ? \ 148 | ___constant_swahw32(x) : \ 149 | __fswahw32(x)) 150 | 151 | /** 152 | * __swahb32 - return a high and low byte-swapped 32-bit value 153 | * @x: value to byteswap 154 | * 155 | * __swahb32(0x12345678) is 0x34127856 156 | */ 157 | #define __swahb32(x) \ 158 | (__builtin_constant_p((__u32)(x)) ? \ 159 | ___constant_swahb32(x) : \ 160 | __fswahb32(x)) 161 | 162 | /** 163 | * __swab16p - return a byteswapped 16-bit value from a pointer 164 | * @p: pointer to a naturally-aligned 16-bit value 165 | */ 166 | static inline __always_inline __u16 __swab16p(const __u16 *p) 167 | { 168 | #ifdef __arch_swab16p 169 | return __arch_swab16p(p); 170 | #else 171 | return __swab16(*p); 172 | #endif 173 | } 174 | 175 | /** 176 | * __swab32p - return a byteswapped 32-bit value from a pointer 177 | * @p: pointer to a naturally-aligned 32-bit value 178 | */ 179 | static inline __always_inline __u32 __swab32p(const __u32 *p) 180 | { 181 | #ifdef __arch_swab32p 182 | return __arch_swab32p(p); 183 | #else 184 | return __swab32(*p); 185 | #endif 186 | } 187 | 188 | /** 189 | * __swab64p - return a byteswapped 64-bit value from a pointer 190 | * @p: pointer to a naturally-aligned 64-bit value 191 | */ 192 | static inline __always_inline __u64 __swab64p(const __u64 *p) 193 | { 194 | #ifdef __arch_swab64p 195 | return __arch_swab64p(p); 196 | #else 197 | return __swab64(*p); 198 | #endif 199 | } 200 | 201 | /** 202 | * __swahw32p - return a wordswapped 32-bit value from a pointer 203 | * @p: pointer to a naturally-aligned 32-bit value 204 | * 205 | * See __swahw32() for details of wordswapping. 206 | */ 207 | static inline __u32 __swahw32p(const __u32 *p) 208 | { 209 | #ifdef __arch_swahw32p 210 | return __arch_swahw32p(p); 211 | #else 212 | return __swahw32(*p); 213 | #endif 214 | } 215 | 216 | /** 217 | * __swahb32p - return a high and low byteswapped 32-bit value from a pointer 218 | * @p: pointer to a naturally-aligned 32-bit value 219 | * 220 | * See __swahb32() for details of high/low byteswapping. 221 | */ 222 | static inline __u32 __swahb32p(const __u32 *p) 223 | { 224 | #ifdef __arch_swahb32p 225 | return __arch_swahb32p(p); 226 | #else 227 | return __swahb32(*p); 228 | #endif 229 | } 230 | 231 | /** 232 | * __swab16s - byteswap a 16-bit value in-place 233 | * @p: pointer to a naturally-aligned 16-bit value 234 | */ 235 | static inline void __swab16s(__u16 *p) 236 | { 237 | #ifdef __arch_swab16s 238 | __arch_swab16s(p); 239 | #else 240 | *p = __swab16p(p); 241 | #endif 242 | } 243 | /** 244 | * __swab32s - byteswap a 32-bit value in-place 245 | * @p: pointer to a naturally-aligned 32-bit value 246 | */ 247 | static inline __always_inline void __swab32s(__u32 *p) 248 | { 249 | #ifdef __arch_swab32s 250 | __arch_swab32s(p); 251 | #else 252 | *p = __swab32p(p); 253 | #endif 254 | } 255 | 256 | /** 257 | * __swab64s - byteswap a 64-bit value in-place 258 | * @p: pointer to a naturally-aligned 64-bit value 259 | */ 260 | static inline __always_inline void __swab64s(__u64 *p) 261 | { 262 | #ifdef __arch_swab64s 263 | __arch_swab64s(p); 264 | #else 265 | *p = __swab64p(p); 266 | #endif 267 | } 268 | 269 | /** 270 | * __swahw32s - wordswap a 32-bit value in-place 271 | * @p: pointer to a naturally-aligned 32-bit value 272 | * 273 | * See __swahw32() for details of wordswapping 274 | */ 275 | static inline void __swahw32s(__u32 *p) 276 | { 277 | #ifdef __arch_swahw32s 278 | __arch_swahw32s(p); 279 | #else 280 | *p = __swahw32p(p); 281 | #endif 282 | } 283 | 284 | /** 285 | * __swahb32s - high and low byteswap a 32-bit value in-place 286 | * @p: pointer to a naturally-aligned 32-bit value 287 | * 288 | * See __swahb32() for details of high and low byte swapping 289 | */ 290 | static inline void __swahb32s(__u32 *p) 291 | { 292 | #ifdef __arch_swahb32s 293 | __arch_swahb32s(p); 294 | #else 295 | *p = __swahb32p(p); 296 | #endif 297 | } 298 | 299 | 300 | #endif /* _UAPI_LINUX_SWAB_H */ 301 | -------------------------------------------------------------------------------- /include/linux/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License along 13 | * with this program; if not, write to the Free Software Foundation, Inc., 14 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 15 | */ 16 | 17 | #ifndef __LINUX_TYPES_H 18 | #define __LINUX_TYPES_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #if BYTE_ORDER == BIG_ENDIAN 27 | #error "big endian is not supported by target" 28 | #endif 29 | 30 | typedef uint16_t __le16; 31 | typedef uint32_t __le32; 32 | typedef uint64_t __le64; 33 | 34 | typedef uint8_t u8; 35 | typedef uint8_t __u8; 36 | typedef uint16_t u16; 37 | typedef uint16_t __u16; 38 | typedef uint32_t u32; 39 | typedef uint32_t __u32; 40 | typedef uint64_t u64; 41 | typedef uint64_t __u64; 42 | typedef int8_t s8; 43 | typedef int8_t __s8; 44 | typedef int16_t s16; 45 | typedef int16_t __s16; 46 | typedef int32_t s32; 47 | typedef int32_t __s32; 48 | typedef int64_t s64; 49 | typedef int64_t __s64; 50 | 51 | #define cpu_to_le16(x) ((__le16)(uint16_t)(x)) 52 | #define le16_to_cpu(x) ((uint16_t)(__le16)(x)) 53 | #define cpu_to_le32(x) ((__le32)(uint32_t)(x)) 54 | #define le32_to_cpu(x) ((uint32_t)(__le32)(x)) 55 | #define cpu_to_le64(x) ((__le64)(uint64_t)(x)) 56 | #define le64_to_cpu(x) ((uint64_t)(__le64)(x)) 57 | 58 | typedef uint16_t __be16; 59 | typedef uint32_t __be32; 60 | typedef uint64_t __be64; 61 | 62 | #define cpu_to_be64 __cpu_to_be64 63 | #define be64_to_cpu __be64_to_cpu 64 | #define cpu_to_be32 __cpu_to_be32 65 | #define be32_to_cpu __be32_to_cpu 66 | #define cpu_to_be16 __cpu_to_be16 67 | #define be16_to_cpu __be16_to_cpu 68 | #define cpu_to_be64p __cpu_to_be64p 69 | #define be64_to_cpup __be64_to_cpup 70 | #define cpu_to_be32p __cpu_to_be32p 71 | #define be32_to_cpup __be32_to_cpup 72 | #define cpu_to_be16p __cpu_to_be16p 73 | #define cpu_to_be64s __cpu_to_be64s 74 | #define be64_to_cpus __be64_to_cpus 75 | #define cpu_to_be32s __cpu_to_be32s 76 | #define be32_to_cpus __be32_to_cpus 77 | #define cpu_to_be16s __cpu_to_be16s 78 | #define be16_to_cpus __be16_to_cpus 79 | #define be16_to_cpup __be16_to_cpup 80 | 81 | #endif /* __LINUX_TYPES_H */ 82 | -------------------------------------------------------------------------------- /include/linux/unaligned.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | #ifndef __ASM_GENERIC_UNALIGNED_H 3 | #define __ASM_GENERIC_UNALIGNED_H 4 | 5 | /* 6 | * This is the most generic implementation of unaligned accesses 7 | * and should work almost anywhere. 8 | */ 9 | #include "swab.h" 10 | #include "little_endian.h" 11 | #include "packed_struct.h" 12 | 13 | #define __get_unaligned_t(type, ptr) ({ \ 14 | const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \ 15 | __pptr->x; \ 16 | }) 17 | 18 | #define __put_unaligned_t(type, val, ptr) do { \ 19 | struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \ 20 | __pptr->x = (val); \ 21 | } while (0) 22 | 23 | #define get_unaligned(ptr) __get_unaligned_t(typeof(*(ptr)), (ptr)) 24 | #define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr)) 25 | 26 | static inline u16 get_unaligned_le16(const void *p) 27 | { 28 | return le16_to_cpu(__get_unaligned_t(__le16, p)); 29 | } 30 | 31 | static inline u32 get_unaligned_le32(const void *p) 32 | { 33 | return le32_to_cpu(__get_unaligned_t(__le32, p)); 34 | } 35 | 36 | static inline u64 get_unaligned_le64(const void *p) 37 | { 38 | return le64_to_cpu(__get_unaligned_t(__le64, p)); 39 | } 40 | 41 | static inline void put_unaligned_le16(u16 val, void *p) 42 | { 43 | __put_unaligned_t(__le16, cpu_to_le16(val), p); 44 | } 45 | 46 | static inline void put_unaligned_le32(u32 val, void *p) 47 | { 48 | __put_unaligned_t(__le32, cpu_to_le32(val), p); 49 | } 50 | 51 | static inline void put_unaligned_le64(u64 val, void *p) 52 | { 53 | __put_unaligned_t(__le64, cpu_to_le64(val), p); 54 | } 55 | 56 | static inline u16 get_unaligned_be16(const void *p) 57 | { 58 | return be16_to_cpu(__get_unaligned_t(__be16, p)); 59 | } 60 | 61 | static inline u32 get_unaligned_be32(const void *p) 62 | { 63 | return be32_to_cpu(__get_unaligned_t(__be32, p)); 64 | } 65 | 66 | static inline u64 get_unaligned_be64(const void *p) 67 | { 68 | return be64_to_cpu(__get_unaligned_t(__be64, p)); 69 | } 70 | 71 | static inline void put_unaligned_be16(u16 val, void *p) 72 | { 73 | __put_unaligned_t(__be16, cpu_to_be16(val), p); 74 | } 75 | 76 | static inline void put_unaligned_be32(u32 val, void *p) 77 | { 78 | __put_unaligned_t(__be32, cpu_to_be32(val), p); 79 | } 80 | 81 | static inline void put_unaligned_be64(u64 val, void *p) 82 | { 83 | __put_unaligned_t(__be64, cpu_to_be64(val), p); 84 | } 85 | 86 | static inline u32 __get_unaligned_be24(const u8 *p) 87 | { 88 | return p[0] << 16 | p[1] << 8 | p[2]; 89 | } 90 | 91 | static inline u32 get_unaligned_be24(const void *p) 92 | { 93 | return __get_unaligned_be24(p); 94 | } 95 | 96 | static inline u32 __get_unaligned_le24(const u8 *p) 97 | { 98 | return p[0] | p[1] << 8 | p[2] << 16; 99 | } 100 | 101 | static inline u32 get_unaligned_le24(const void *p) 102 | { 103 | return __get_unaligned_le24(p); 104 | } 105 | 106 | static inline void __put_unaligned_be24(const u32 val, u8 *p) 107 | { 108 | *p++ = val >> 16; 109 | *p++ = val >> 8; 110 | *p++ = val; 111 | } 112 | 113 | static inline void put_unaligned_be24(const u32 val, void *p) 114 | { 115 | __put_unaligned_be24(val, p); 116 | } 117 | 118 | static inline void __put_unaligned_le24(const u32 val, u8 *p) 119 | { 120 | *p++ = val; 121 | *p++ = val >> 8; 122 | *p++ = val >> 16; 123 | } 124 | 125 | static inline void put_unaligned_le24(const u32 val, void *p) 126 | { 127 | __put_unaligned_le24(val, p); 128 | } 129 | 130 | static inline void __put_unaligned_be48(const u64 val, u8 *p) 131 | { 132 | *p++ = val >> 40; 133 | *p++ = val >> 32; 134 | *p++ = val >> 24; 135 | *p++ = val >> 16; 136 | *p++ = val >> 8; 137 | *p++ = val; 138 | } 139 | 140 | static inline void put_unaligned_be48(const u64 val, void *p) 141 | { 142 | __put_unaligned_be48(val, p); 143 | } 144 | 145 | static inline u64 __get_unaligned_be48(const u8 *p) 146 | { 147 | return (u64)p[0] << 40 | (u64)p[1] << 32 | (u64)p[2] << 24 | 148 | p[3] << 16 | p[4] << 8 | p[5]; 149 | } 150 | 151 | static inline u64 get_unaligned_be48(const void *p) 152 | { 153 | return __get_unaligned_be48(p); 154 | } 155 | 156 | #endif /* __ASM_GENERIC_UNALIGNED_H */ 157 | -------------------------------------------------------------------------------- /include/shared/eeprom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Shared Atheros AR9170 Header 3 | * 4 | * EEPROM layout 5 | * 6 | * Copyright 2008, Johannes Berg 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 | * You should have received a copy of the GNU General Public License 19 | * along with this program; see the file COPYING. If not, see 20 | * http://www.gnu.org/licenses/. 21 | * 22 | * This file incorporates work covered by the following copyright and 23 | * permission notice: 24 | * Copyright (c) 2007-2008 Atheros Communications, Inc. 25 | * 26 | * Permission to use, copy, modify, and/or distribute this software for any 27 | * purpose with or without fee is hereby granted, provided that the above 28 | * copyright notice and this permission notice appear in all copies. 29 | * 30 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 31 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 32 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 33 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 34 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 37 | */ 38 | #ifndef __CARL9170_SHARED_EEPROM_H 39 | #define __CARL9170_SHARED_EEPROM_H 40 | 41 | #define AR9170_EEPROM_START 0x1600 42 | 43 | #define AR5416_MAX_CHAINS 2 44 | #define AR5416_MODAL_SPURS 5 45 | 46 | struct ar9170_eeprom_modal { 47 | __le32 antCtrlChain[AR5416_MAX_CHAINS]; 48 | __le32 antCtrlCommon; 49 | s8 antennaGainCh[AR5416_MAX_CHAINS]; 50 | u8 switchSettling; 51 | u8 txRxAttenCh[AR5416_MAX_CHAINS]; 52 | u8 rxTxMarginCh[AR5416_MAX_CHAINS]; 53 | s8 adcDesiredSize; 54 | s8 pgaDesiredSize; 55 | u8 xlnaGainCh[AR5416_MAX_CHAINS]; 56 | u8 txEndToXpaOff; 57 | u8 txEndToRxOn; 58 | u8 txFrameToXpaOn; 59 | u8 thresh62; 60 | s8 noiseFloorThreshCh[AR5416_MAX_CHAINS]; 61 | u8 xpdGain; 62 | u8 xpd; 63 | s8 iqCalICh[AR5416_MAX_CHAINS]; 64 | s8 iqCalQCh[AR5416_MAX_CHAINS]; 65 | u8 pdGainOverlap; 66 | u8 ob; 67 | u8 db; 68 | u8 xpaBiasLvl; 69 | u8 pwrDecreaseFor2Chain; 70 | u8 pwrDecreaseFor3Chain; 71 | u8 txFrameToDataStart; 72 | u8 txFrameToPaOn; 73 | u8 ht40PowerIncForPdadc; 74 | u8 bswAtten[AR5416_MAX_CHAINS]; 75 | u8 bswMargin[AR5416_MAX_CHAINS]; 76 | u8 swSettleHt40; 77 | u8 reserved[22]; 78 | struct spur_channel { 79 | __le16 spurChan; 80 | u8 spurRangeLow; 81 | u8 spurRangeHigh; 82 | } __packed spur_channels[AR5416_MODAL_SPURS]; 83 | } __packed; 84 | 85 | #define AR5416_NUM_PD_GAINS 4 86 | #define AR5416_PD_GAIN_ICEPTS 5 87 | 88 | struct ar9170_calibration_data_per_freq { 89 | u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; 90 | u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; 91 | } __packed; 92 | 93 | #define AR5416_NUM_5G_CAL_PIERS 8 94 | #define AR5416_NUM_2G_CAL_PIERS 4 95 | 96 | #define AR5416_NUM_5G_TARGET_PWRS 8 97 | #define AR5416_NUM_2G_CCK_TARGET_PWRS 3 98 | #define AR5416_NUM_2G_OFDM_TARGET_PWRS 4 99 | #define AR5416_MAX_NUM_TGT_PWRS 8 100 | 101 | struct ar9170_calibration_target_power_legacy { 102 | u8 freq; 103 | u8 power[4]; 104 | } __packed; 105 | 106 | struct ar9170_calibration_target_power_ht { 107 | u8 freq; 108 | u8 power[8]; 109 | } __packed; 110 | 111 | #define AR5416_NUM_CTLS 24 112 | 113 | struct ar9170_calctl_edges { 114 | u8 channel; 115 | #define AR9170_CALCTL_EDGE_FLAGS 0xC0 116 | u8 power_flags; 117 | } __packed; 118 | 119 | #define AR5416_NUM_BAND_EDGES 8 120 | 121 | struct ar9170_calctl_data { 122 | struct ar9170_calctl_edges 123 | control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; 124 | } __packed; 125 | 126 | struct ar9170_eeprom { 127 | __le16 length; 128 | __le16 checksum; 129 | __le16 version; 130 | u8 operating_flags; 131 | #define AR9170_OPFLAG_5GHZ 1 132 | #define AR9170_OPFLAG_2GHZ 2 133 | u8 misc; 134 | __le16 reg_domain[2]; 135 | u8 mac_address[6]; 136 | u8 rx_mask; 137 | u8 tx_mask; 138 | __le16 rf_silent; 139 | __le16 bluetooth_options; 140 | __le16 device_capabilities; 141 | __le32 build_number; 142 | u8 deviceType; 143 | u8 reserved[33]; 144 | 145 | u8 customer_data[64]; 146 | 147 | struct ar9170_eeprom_modal 148 | modal_header[2]; 149 | 150 | u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS]; 151 | u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS]; 152 | 153 | struct ar9170_calibration_data_per_freq 154 | cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS], 155 | cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; 156 | 157 | /* power calibration data */ 158 | struct ar9170_calibration_target_power_legacy 159 | cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS]; 160 | struct ar9170_calibration_target_power_ht 161 | cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS], 162 | cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS]; 163 | 164 | struct ar9170_calibration_target_power_legacy 165 | cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS], 166 | cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS]; 167 | struct ar9170_calibration_target_power_ht 168 | cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS], 169 | cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS]; 170 | 171 | /* conformance testing limits */ 172 | u8 ctl_index[AR5416_NUM_CTLS]; 173 | struct ar9170_calctl_data 174 | ctl_data[AR5416_NUM_CTLS]; 175 | 176 | u8 pad; 177 | __le16 subsystem_id; 178 | } __packed; 179 | 180 | #define AR9170_LED_MODE_POWER_ON 0x0001 181 | #define AR9170_LED_MODE_RESERVED 0x0002 182 | #define AR9170_LED_MODE_DISABLE_STATE 0x0004 183 | #define AR9170_LED_MODE_OFF_IN_PSM 0x0008 184 | 185 | /* AR9170_LED_MODE BIT is set */ 186 | #define AR9170_LED_MODE_FREQUENCY_S 4 187 | #define AR9170_LED_MODE_FREQUENCY 0x0030 188 | #define AR9170_LED_MODE_FREQUENCY_1HZ 0x0000 189 | #define AR9170_LED_MODE_FREQUENCY_0_5HZ 0x0010 190 | #define AR9170_LED_MODE_FREQUENCY_0_25HZ 0x0020 191 | #define AR9170_LED_MODE_FREQUENCY_0_125HZ 0x0030 192 | 193 | /* AR9170_LED_MODE BIT is not set */ 194 | #define AR9170_LED_MODE_CONN_STATE_S 4 195 | #define AR9170_LED_MODE_CONN_STATE 0x0030 196 | #define AR9170_LED_MODE_CONN_STATE_FORCE_OFF 0x0000 197 | #define AR9170_LED_MODE_CONN_STATE_FORCE_ON 0x0010 198 | /* Idle off / Active on */ 199 | #define AR9170_LED_MODE_CONN_STATE_IOFF_AON 0x0020 200 | /* Idle on / Active off */ 201 | #define AR9170_LED_MODE_CONN_STATE_ION_AOFF 0x0010 202 | 203 | #define AR9170_LED_MODE_MODE 0x0040 204 | #define AR9170_LED_MODE_RESERVED2 0x0080 205 | 206 | #define AR9170_LED_MODE_TON_SCAN_S 8 207 | #define AR9170_LED_MODE_TON_SCAN 0x0f00 208 | 209 | #define AR9170_LED_MODE_TOFF_SCAN_S 12 210 | #define AR9170_LED_MODE_TOFF_SCAN 0xf000 211 | 212 | struct ar9170_led_mode { 213 | __le16 led; 214 | }; 215 | 216 | #endif /* __CARL9170_SHARED_EEPROM_H */ 217 | -------------------------------------------------------------------------------- /include/shared/fwdesc.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* 3 | * Shared CARL9170 Header 4 | * 5 | * Firmware descriptor format 6 | * 7 | * Copyright 2009-2011 Christian Lamparter 8 | */ 9 | 10 | #ifndef __CARL9170_SHARED_FWDESC_H 11 | #define __CARL9170_SHARED_FWDESC_H 12 | 13 | /* NOTE: Don't mess with the order of the flags! */ 14 | enum carl9170fw_feature_list { 15 | /* Always set */ 16 | CARL9170FW_DUMMY_FEATURE, 17 | 18 | /* 19 | * Indicates that this image has special boot block which prevents 20 | * legacy drivers to drive the firmware. 21 | */ 22 | CARL9170FW_MINIBOOT, 23 | 24 | /* usb registers are initialized by the firmware */ 25 | CARL9170FW_USB_INIT_FIRMWARE, 26 | 27 | /* command traps & notifications are send through EP2 */ 28 | CARL9170FW_USB_RESP_EP2, 29 | 30 | /* usb download (app -> fw) stream */ 31 | CARL9170FW_USB_DOWN_STREAM, 32 | 33 | /* usb upload (fw -> app) stream */ 34 | CARL9170FW_USB_UP_STREAM, 35 | 36 | /* unusable - reserved to flag non-functional debug firmwares */ 37 | CARL9170FW_UNUSABLE, 38 | 39 | /* AR9170_CMD_RF_INIT, AR9170_CMD_FREQ_START, AR9170_CMD_FREQUENCY */ 40 | CARL9170FW_COMMAND_PHY, 41 | 42 | /* AR9170_CMD_EKEY, AR9170_CMD_DKEY */ 43 | CARL9170FW_COMMAND_CAM, 44 | 45 | /* Firmware has a software Content After Beacon Queueing mechanism */ 46 | CARL9170FW_WLANTX_CAB, 47 | 48 | /* The firmware is capable of responding to incoming BAR frames */ 49 | CARL9170FW_HANDLE_BACK_REQ, 50 | 51 | /* GPIO Interrupt | CARL9170_RSP_GPIO */ 52 | CARL9170FW_GPIO_INTERRUPT, 53 | 54 | /* Firmware PSM support | CARL9170_CMD_PSM */ 55 | CARL9170FW_PSM, 56 | 57 | /* Firmware RX filter | CARL9170_CMD_RX_FILTER */ 58 | CARL9170FW_RX_FILTER, 59 | 60 | /* Wake up on WLAN */ 61 | CARL9170FW_WOL, 62 | 63 | /* Firmware supports PSM in the 5GHZ Band */ 64 | CARL9170FW_FIXED_5GHZ_PSM, 65 | 66 | /* HW (ANI, CCA, MIB) tally counters */ 67 | CARL9170FW_HW_COUNTERS, 68 | 69 | /* Firmware will pass BA when BARs are queued */ 70 | CARL9170FW_RX_BA_FILTER, 71 | 72 | /* Firmware has support to write a byte at a time */ 73 | CARL9170FW_HAS_WREGB_CMD, 74 | 75 | /* Pattern generator */ 76 | CARL9170FW_PATTERN_GENERATOR, 77 | 78 | /* KEEP LAST */ 79 | __CARL9170FW_FEATURE_NUM 80 | }; 81 | 82 | #define OTUS_MAGIC "OTAR" 83 | #define MOTD_MAGIC "MOTD" 84 | #define FIX_MAGIC "FIX\0" 85 | #define DBG_MAGIC "DBG\0" 86 | #define CHK_MAGIC "CHK\0" 87 | #define TXSQ_MAGIC "TXSQ" 88 | #define WOL_MAGIC "WOL\0" 89 | #define LAST_MAGIC "LAST" 90 | 91 | #define CARL9170FW_SET_DAY(d) (((d) - 1) % 31) 92 | #define CARL9170FW_SET_MONTH(m) ((((m) - 1) % 12) * 31) 93 | #define CARL9170FW_SET_YEAR(y) (((y) - 10) * 372) 94 | 95 | #define CARL9170FW_GET_DAY(d) (((d) % 31) + 1) 96 | #define CARL9170FW_GET_MONTH(m) ((((m) / 31) % 12) + 1) 97 | #define CARL9170FW_GET_YEAR(y) ((y) / 372 + 10) 98 | 99 | #define CARL9170FW_MAGIC_SIZE 4 100 | 101 | struct carl9170fw_desc_head { 102 | u8 magic[CARL9170FW_MAGIC_SIZE] __attribute__((__nonstring__)); 103 | __le16 length; 104 | u8 min_ver; 105 | u8 cur_ver; 106 | } __packed; 107 | #define CARL9170FW_DESC_HEAD_SIZE \ 108 | (sizeof(struct carl9170fw_desc_head)) 109 | 110 | #define CARL9170FW_OTUS_DESC_MIN_VER 6 111 | #define CARL9170FW_OTUS_DESC_CUR_VER 7 112 | struct carl9170fw_otus_desc { 113 | struct carl9170fw_desc_head head; 114 | __le32 feature_set; 115 | __le32 fw_address; 116 | __le32 bcn_addr; 117 | __le16 bcn_len; 118 | __le16 miniboot_size; 119 | __le16 tx_frag_len; 120 | __le16 rx_max_frame_len; 121 | u8 tx_descs; 122 | u8 cmd_bufs; 123 | u8 api_ver; 124 | u8 vif_num; 125 | } __packed; 126 | #define CARL9170FW_OTUS_DESC_SIZE \ 127 | (sizeof(struct carl9170fw_otus_desc)) 128 | 129 | #define CARL9170FW_MOTD_STRING_LEN 24 130 | #define CARL9170FW_MOTD_RELEASE_LEN 20 131 | #define CARL9170FW_MOTD_DESC_MIN_VER 1 132 | #define CARL9170FW_MOTD_DESC_CUR_VER 2 133 | struct carl9170fw_motd_desc { 134 | struct carl9170fw_desc_head head; 135 | __le32 fw_year_month_day; 136 | char desc[CARL9170FW_MOTD_STRING_LEN]; 137 | char release[CARL9170FW_MOTD_RELEASE_LEN]; 138 | } __packed; 139 | #define CARL9170FW_MOTD_DESC_SIZE \ 140 | (sizeof(struct carl9170fw_motd_desc)) 141 | 142 | #define CARL9170FW_FIX_DESC_MIN_VER 1 143 | #define CARL9170FW_FIX_DESC_CUR_VER 2 144 | struct carl9170fw_fix_entry { 145 | __le32 address; 146 | __le32 mask; 147 | __le32 value; 148 | } __packed; 149 | 150 | struct carl9170fw_fix_desc { 151 | struct carl9170fw_desc_head head; 152 | struct carl9170fw_fix_entry data[]; 153 | } __packed; 154 | #define CARL9170FW_FIX_DESC_SIZE \ 155 | (sizeof(struct carl9170fw_fix_desc)) 156 | 157 | #define CARL9170FW_DBG_DESC_MIN_VER 1 158 | #define CARL9170FW_DBG_DESC_CUR_VER 3 159 | struct carl9170fw_dbg_desc { 160 | struct carl9170fw_desc_head head; 161 | 162 | __le32 bogoclock_addr; 163 | __le32 counter_addr; 164 | __le32 rx_total_addr; 165 | __le32 rx_overrun_addr; 166 | __le32 rx_filter; 167 | 168 | /* Put your debugging definitions here */ 169 | } __packed; 170 | #define CARL9170FW_DBG_DESC_SIZE \ 171 | (sizeof(struct carl9170fw_dbg_desc)) 172 | 173 | #define CARL9170FW_CHK_DESC_MIN_VER 1 174 | #define CARL9170FW_CHK_DESC_CUR_VER 2 175 | struct carl9170fw_chk_desc { 176 | struct carl9170fw_desc_head head; 177 | __le32 fw_crc32; 178 | __le32 hdr_crc32; 179 | } __packed; 180 | #define CARL9170FW_CHK_DESC_SIZE \ 181 | (sizeof(struct carl9170fw_chk_desc)) 182 | 183 | #define CARL9170FW_TXSQ_DESC_MIN_VER 1 184 | #define CARL9170FW_TXSQ_DESC_CUR_VER 1 185 | struct carl9170fw_txsq_desc { 186 | struct carl9170fw_desc_head head; 187 | 188 | __le32 seq_table_addr; 189 | } __packed; 190 | #define CARL9170FW_TXSQ_DESC_SIZE \ 191 | (sizeof(struct carl9170fw_txsq_desc)) 192 | 193 | #define CARL9170FW_WOL_DESC_MIN_VER 1 194 | #define CARL9170FW_WOL_DESC_CUR_VER 1 195 | struct carl9170fw_wol_desc { 196 | struct carl9170fw_desc_head head; 197 | 198 | __le32 supported_triggers; /* CARL9170_WOL_ */ 199 | } __packed; 200 | #define CARL9170FW_WOL_DESC_SIZE \ 201 | (sizeof(struct carl9170fw_wol_desc)) 202 | 203 | #define CARL9170FW_LAST_DESC_MIN_VER 1 204 | #define CARL9170FW_LAST_DESC_CUR_VER 2 205 | struct carl9170fw_last_desc { 206 | struct carl9170fw_desc_head head; 207 | } __packed; 208 | #define CARL9170FW_LAST_DESC_SIZE \ 209 | (sizeof(struct carl9170fw_fix_desc)) 210 | 211 | #define CARL9170FW_DESC_MAX_LENGTH 8192 212 | 213 | #define CARL9170FW_FILL_DESC(_magic, _length, _min_ver, _cur_ver) \ 214 | .head = { \ 215 | .magic = _magic, \ 216 | .length = cpu_to_le16(_length), \ 217 | .min_ver = _min_ver, \ 218 | .cur_ver = _cur_ver, \ 219 | } 220 | 221 | static inline void carl9170fw_fill_desc(struct carl9170fw_desc_head *head, 222 | u8 magic[CARL9170FW_MAGIC_SIZE], 223 | __le16 length, u8 min_ver, u8 cur_ver) 224 | { 225 | head->magic[0] = magic[0]; 226 | head->magic[1] = magic[1]; 227 | head->magic[2] = magic[2]; 228 | head->magic[3] = magic[3]; 229 | 230 | head->length = length; 231 | head->min_ver = min_ver; 232 | head->cur_ver = cur_ver; 233 | } 234 | 235 | #define carl9170fw_for_each_hdr(desc, fw_desc) \ 236 | for (desc = fw_desc; \ 237 | memcmp(desc->magic, LAST_MAGIC, CARL9170FW_MAGIC_SIZE) && \ 238 | le16_to_cpu(desc->length) >= CARL9170FW_DESC_HEAD_SIZE && \ 239 | le16_to_cpu(desc->length) < CARL9170FW_DESC_MAX_LENGTH; \ 240 | desc = (void *)((unsigned long)desc + le16_to_cpu(desc->length))) 241 | 242 | #define CHECK_HDR_VERSION(head, _min_ver) \ 243 | (((head)->cur_ver < _min_ver) || ((head)->min_ver > _min_ver)) \ 244 | 245 | static inline bool carl9170fw_supports(__le32 list, u8 feature) 246 | { 247 | return le32_to_cpu(list) & BIT(feature); 248 | } 249 | 250 | static inline bool carl9170fw_desc_cmp(const struct carl9170fw_desc_head *head, 251 | const u8 descid[CARL9170FW_MAGIC_SIZE], 252 | u16 min_len, u8 compatible_revision) 253 | { 254 | if (descid[0] == head->magic[0] && descid[1] == head->magic[1] && 255 | descid[2] == head->magic[2] && descid[3] == head->magic[3] && 256 | !CHECK_HDR_VERSION(head, compatible_revision) && 257 | (le16_to_cpu(head->length) >= min_len)) 258 | return true; 259 | 260 | return false; 261 | } 262 | 263 | #define CARL9170FW_MIN_SIZE 32 264 | #define CARL9170FW_MAX_SIZE 16384 265 | 266 | static inline bool carl9170fw_size_check(unsigned int len) 267 | { 268 | return (len <= CARL9170FW_MAX_SIZE && len >= CARL9170FW_MIN_SIZE); 269 | } 270 | 271 | #endif /* __CARL9170_SHARED_FWDESC_H */ 272 | -------------------------------------------------------------------------------- /include/shared/version.h: -------------------------------------------------------------------------------- 1 | #ifndef __CARL9170_SHARED_VERSION_H 2 | #define __CARL9170_SHARED_VERSION_H 3 | #define CARL9170FW_VERSION_YEAR 21 4 | #define CARL9170FW_VERSION_MONTH 2 5 | #define CARL9170FW_VERSION_DAY 5 6 | #define CARL9170FW_VERSION_GIT "1.9.9" 7 | #endif /* __CARL9170_SHARED_VERSION_H */ 8 | -------------------------------------------------------------------------------- /minifw/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(miniboot.fw) 4 | 5 | include("../extra/sh-elf-linux.cmake") 6 | include("../config.cmake") 7 | 8 | set(miniboot_src miniboot.S) 9 | set_source_files_properties(miniboot.S PROPERTIES LANGUAGE C) 10 | 11 | add_executable(miniboot.elf miniboot.S) 12 | 13 | set_target_properties(miniboot.elf PROPERTIES LINKER_LANGUAGE C) 14 | 15 | set_target_properties(miniboot.elf PROPERTIES LINK_FLAGS "-Tminiboot.lds") 16 | 17 | add_custom_target( 18 | miniboot.fw ALL 19 | ${OBJCOPY} --strip-unneeded -O binary -R .sram -R .eeprom -R .fwdsc miniboot.elf miniboot.fw 20 | DEPENDS miniboot.elf 21 | BYPRODUCTS miniboot.fw) 22 | -------------------------------------------------------------------------------- /minifw/Kconfig: -------------------------------------------------------------------------------- 1 | config CARL9170FW_BUILD_MINIBOOT 2 | def_bool y 3 | prompt "Build MiniBoot Firmware Header" 4 | -------------------------------------------------------------------------------- /minifw/miniboot.S: -------------------------------------------------------------------------------- 1 | .globl _start 2 | .type _start, @function 3 | .section ".boot", "ax" 4 | _start: 5 | mov.l startcode, r0 6 | jmp @r0 7 | startcode: .long 0x00000008 8 | -------------------------------------------------------------------------------- /minifw/miniboot.lds: -------------------------------------------------------------------------------- 1 | ENTRY(_start); 2 | 3 | MEMORY 4 | { 5 | pram : ORIGIN = 0x200000, LENGTH = 16k 6 | } 7 | 8 | SECTIONS 9 | { 10 | .padding : { 11 | /* NOP NOP just in case */ 12 | LONG(0x00090009) 13 | } > pram 14 | 15 | .boot : { *(.boot) } > pram 16 | .text : { *(.text*) } > pram 17 | .rodata : { *(.rodata*) } > pram 18 | .bss : { *(.bss) } > pram 19 | .data : { *(.data*) } > pram 20 | } 21 | -------------------------------------------------------------------------------- /toolchain/Makefile: -------------------------------------------------------------------------------- 1 | BINUTILS_VER=2.44 2 | BINUTILS_TAR=binutils-$(BINUTILS_VER).tar.xz 3 | BINUTILS_URL="http://mirrors.kernel.org/gnu/binutils/$(BINUTILS_TAR)" 4 | 5 | NEWLIB_VER=4.5.0.20241231 6 | NEWLIB_TAR=newlib-$(NEWLIB_VER).tar.gz 7 | NEWLIB_URL="ftp://sourceware.org/pub/newlib/$(NEWLIB_TAR)" 8 | 9 | GCC_VER=15.1.0 10 | GCC_TAR=gcc-$(GCC_VER).tar.xz 11 | GCC_URL="http://mirrors.kernel.org/gnu/gcc/gcc-$(GCC_VER)/$(GCC_TAR)" 12 | 13 | MPFR_VER=4.2.2 14 | MPFR_TAR=mpfr-$(MPFR_VER).tar.xz 15 | MPFR_URL="http://ftpmirror.gnu.org/gnu/mpfr/$(MPFR_TAR)" 16 | 17 | GMP_VER=6.3.0 18 | GMP_TAR=gmp-$(GMP_VER).tar.xz 19 | GMP_URL="http://ftpmirror.gnu.org/gnu/gmp/$(GMP_TAR)" 20 | 21 | MPC_VER=1.3.1 22 | MPC_TAR=mpc-$(MPC_VER).tar.gz 23 | MPC_URL="http://ftpmirror.gnu.org/gnu/mpc/$(MPC_TAR)" 24 | 25 | JOBS?=$(shell grep -c ^processor /proc/cpuinfo) 26 | 27 | BASEDIR=$(shell pwd) 28 | 29 | define checksum 30 | @if grep -q ' $(subst .,\.,$(1))$$' SHA256SUMS; then \ 31 | grep ' $(subst .,\.,$(1))$$' SHA256SUMS | sha256sum -c || rm $(1); \ 32 | else \ 33 | echo "WARNING: no checksum defined for $(1)"; \ 34 | fi 35 | endef 36 | 37 | all: clean gcc 38 | 39 | src/$(MPFR_TAR): 40 | wget -P "$(BASEDIR)/src" "$(MPFR_URL)" 41 | $(call checksum,$@) 42 | 43 | src/$(GMP_TAR): 44 | wget -P "$(BASEDIR)/src" "$(GMP_URL)" 45 | $(call checksum,$@) 46 | 47 | src/$(MPC_TAR): 48 | wget -P "$(BASEDIR)/src" "$(MPC_URL)" 49 | $(call checksum,$@) 50 | 51 | src/$(BINUTILS_TAR): 52 | wget -P "$(BASEDIR)/src" "$(BINUTILS_URL)" 53 | $(call checksum,$@) 54 | 55 | src/$(NEWLIB_TAR): 56 | wget -P "$(BASEDIR)/src" "$(NEWLIB_URL)" 57 | $(call checksum,$@) 58 | 59 | src/$(GCC_TAR): 60 | wget -P "$(BASEDIR)/src" "$(GCC_URL)" 61 | $(call checksum,$@) 62 | 63 | src/mpfr-$(MPFR_VER): src/$(MPFR_TAR) 64 | tar -C "$(BASEDIR)/src" -xf "$<" 65 | 66 | src/gmp-$(GMP_VER): src/$(GMP_TAR) 67 | tar -C "$(BASEDIR)/src" -xf "$<" 68 | 69 | src/mpc-$(MPC_VER): src/$(MPC_TAR) 70 | tar -C "$(BASEDIR)/src" -xf "$<" 71 | 72 | src/binutils-$(BINUTILS_VER): src/$(BINUTILS_TAR) 73 | tar -C "$(BASEDIR)/src" -xf "$<" 74 | 75 | src/newlib-$(NEWLIB_VER): src/$(NEWLIB_TAR) 76 | tar -C "$(BASEDIR)/src" -xf "$<" 77 | 78 | src/gcc-$(GCC_VER): src/$(GCC_TAR) src/newlib-$(NEWLIB_VER) src/mpc-$(MPC_VER) src/gmp-$(GMP_VER) src/mpfr-$(MPFR_VER) 79 | tar -C "$(BASEDIR)/src" -xf "$<" 80 | ln -s "$(BASEDIR)/src/newlib-$(NEWLIB_VER)/newlib" "$@" 81 | ln -s "$(BASEDIR)/src/newlib-$(NEWLIB_VER)/libgloss" "$@" 82 | ln -s "$(BASEDIR)/src/gmp-$(GMP_VER)" "$@/gmp" 83 | ln -s "$(BASEDIR)/src/mpfr-$(MPFR_VER)" "$@/mpfr" 84 | ln -s "$(BASEDIR)/src/mpc-$(MPC_VER)" "$@/mpc" 85 | 86 | binutils: src/binutils-$(BINUTILS_VER) 87 | mkdir -p "$(BASEDIR)/build/binutils" 88 | cd "$(BASEDIR)/build/binutils"; \ 89 | "$(BASEDIR)"/$ 10 | */ 11 | 12 | #ifndef __LIST_H 13 | #define __LIST_H 14 | 15 | struct list_head { 16 | struct list_head *next; 17 | struct list_head *prev; 18 | }; 19 | 20 | static inline void list_add(struct list_head *obj, 21 | struct list_head *prev, 22 | struct list_head *next) 23 | { 24 | prev->next = obj; 25 | obj->prev = prev; 26 | next->prev = obj; 27 | obj->next = next; 28 | } 29 | 30 | static inline void list_add_tail(struct list_head *obj, 31 | struct list_head *head) 32 | { 33 | list_add(obj, head->prev, head); 34 | } 35 | 36 | static inline void list_add_head(struct list_head *obj, 37 | struct list_head *head) 38 | { 39 | list_add(obj, head, head->next); 40 | } 41 | 42 | static inline void list_del(struct list_head *obj) 43 | { 44 | obj->prev->next = obj->next; 45 | obj->next->prev = obj->prev; 46 | obj->next = obj->prev = obj; 47 | } 48 | 49 | static inline void list_replace(struct list_head *old, 50 | struct list_head *obj) 51 | { 52 | obj->next = old->next; 53 | obj->next->prev = obj; 54 | obj->prev = old->prev; 55 | obj->prev->next = obj; 56 | } 57 | 58 | static inline int list_empty(struct list_head *head) 59 | { 60 | return head->next == head; 61 | } 62 | 63 | #define list_entry(ptr, type, member) \ 64 | container_of(ptr, type, member) 65 | 66 | #define list_first_entry(ptr, type, member) \ 67 | container_of((ptr)->next, type, member) 68 | 69 | #define list_at_tail(pos, head, member) \ 70 | ((pos)->member.next == (head)) 71 | 72 | #define list_at_head(pos, head, member) \ 73 | ((pos)->member.prev == (head)) 74 | 75 | #define LIST_HEAD(name) \ 76 | struct list_head name = { &(name), &(name) } 77 | 78 | #define list_for_each_entry(pos, head, member) \ 79 | for (pos = list_entry((head)->next, typeof(*pos), member); \ 80 | &(pos)->member != (head); \ 81 | (pos) = list_entry((pos)->member.next, typeof(*(pos)), member)) 82 | 83 | #define list_for_each_entry_safe(pos, n, head, member) \ 84 | for (pos = list_entry((head)->next, typeof(*pos), member), \ 85 | n = list_entry(pos->member.next, typeof(*pos), member); \ 86 | &(pos)->member != (head); \ 87 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) 88 | 89 | #define init_list_head(head) \ 90 | do { (head)->next = (head); (head)->prev = (head); } while (0) 91 | 92 | #endif /* __LIST_H */ 93 | -------------------------------------------------------------------------------- /tools/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(libcarlfw) 4 | 5 | set(carlfw_src carlfw.c) 6 | 7 | add_library( carlfw STATIC ${carlfw_src}) 8 | -------------------------------------------------------------------------------- /tools/lib/carlfw.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010-2011 Christian Lamparter 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 version 2 of the License. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef __CARLFW_H 19 | #define __CARLFW_H 20 | 21 | /* These macros are already defined as part of newlib's sys/cdefs.h. 22 | * However they are not part of standard libc which is used to compile 23 | * the host tools. For now, simply add them here. 24 | */ 25 | #define __packed __attribute__((packed)) 26 | #define __unused __attribute__((unused)) 27 | #define __aligned(x) __attribute__((aligned(x))) 28 | 29 | #include 30 | #include "compiler.h" 31 | #include "fwdesc.h" 32 | #include "list.h" 33 | 34 | struct carlfw; 35 | 36 | void carlfw_release(struct carlfw *fw); 37 | struct carlfw *carlfw_load(const char *basename); 38 | int carlfw_store(struct carlfw *fw); 39 | void *carlfw_find_desc(struct carlfw *fw, 40 | const uint8_t descid[4], const unsigned int len, 41 | const uint8_t compatible_revision); 42 | 43 | int carlfw_desc_add_tail(struct carlfw *fw, 44 | const struct carl9170fw_desc_head *desc); 45 | 46 | int carlfw_desc_add(struct carlfw *fw, 47 | const struct carl9170fw_desc_head *desc, 48 | struct carl9170fw_desc_head *prev, 49 | struct carl9170fw_desc_head *next); 50 | 51 | void *carlfw_desc_mod_len(struct carlfw *fw, 52 | struct carl9170fw_desc_head *desc, 53 | size_t len); 54 | 55 | int carlfw_desc_add_before(struct carlfw *fw, 56 | const struct carl9170fw_desc_head *desc, 57 | struct carl9170fw_desc_head *pos); 58 | 59 | void carlfw_desc_unlink(struct carlfw *fw, 60 | struct carl9170fw_desc_head *desc); 61 | 62 | void carlfw_desc_del(struct carlfw *fw, 63 | struct carl9170fw_desc_head *entry); 64 | 65 | void *carlfw_desc_next(struct carlfw *fw, 66 | struct carl9170fw_desc_head *pos); 67 | 68 | void *carlfw_mod_tailroom(struct carlfw *fw, ssize_t len); 69 | void *carlfw_mod_headroom(struct carlfw *fw, ssize_t len); 70 | 71 | void *carlfw_get_fw(struct carlfw *fw, size_t *len); 72 | 73 | unsigned int carlfw_get_descs_num(struct carlfw *fw); 74 | unsigned int carlfw_get_descs_size(struct carlfw *fw); 75 | #endif /* __CARLFW_H */ 76 | -------------------------------------------------------------------------------- /tools/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(tools) 4 | 5 | add_custom_target(wol ALL COMMAND gcc wol.c -o wol) 6 | 7 | set(tools fwinfo miniboot checksum) 8 | 9 | foreach(tool ${tools}) 10 | add_executable( ${tool} ${tool}.c ) 11 | add_definitions("-Wall -Wextra -Wshadow") 12 | target_link_libraries( ${tool} carlfw ) 13 | endforeach() 14 | -------------------------------------------------------------------------------- /tools/src/checksum.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010-2011 Christian Lamparter 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 version 2 of the License. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "carlfw.h" 28 | 29 | #include "compiler.h" 30 | 31 | static void checksum_help(void) 32 | { 33 | fprintf(stderr, "Usage:\n"); 34 | fprintf(stderr, "\tchecksum FW-FILE\n"); 35 | 36 | fprintf(stderr, "\nDescription:\n"); 37 | fprintf(stderr, "\tThis simple utility adds/updates various " 38 | "checksums.\n"); 39 | 40 | fprintf(stderr, "\nParameteres:\n"); 41 | fprintf(stderr, "\t 'FW-FILE' = firmware name\n"); 42 | fprintf(stderr, "\n"); 43 | } 44 | 45 | int main(int argc, char *args[]) 46 | { 47 | struct carlfw *fw = NULL; 48 | int err = 0; 49 | 50 | if (argc != 2) { 51 | err = -EINVAL; 52 | goto out; 53 | } 54 | 55 | fw = carlfw_load(args[1]); 56 | if (IS_ERR_OR_NULL(fw)) { 57 | err = PTR_ERR(fw); 58 | fprintf(stderr, "Failed to open file \"%s\" (%d).\n", 59 | args[1], err); 60 | goto out; 61 | } 62 | 63 | /* 64 | * No magic here, The checksum descriptor is added/update 65 | * automatically in a subroutine of carlfw_store(). 66 | * 67 | * This tools serves as a skeleton/example. 68 | */ 69 | err = carlfw_store(fw); 70 | if (err) { 71 | fprintf(stderr, "Failed to apply checksum (%d).\n", err); 72 | goto out; 73 | } 74 | 75 | out: 76 | switch (err) { 77 | case 0: 78 | fprintf(stdout, "checksum applied.\n"); 79 | break; 80 | case -EINVAL: 81 | checksum_help(); 82 | break; 83 | default: 84 | break; 85 | } 86 | 87 | carlfw_release(fw); 88 | return err ? EXIT_FAILURE : EXIT_SUCCESS; 89 | } 90 | -------------------------------------------------------------------------------- /tools/src/eeprom_fix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunkeey/carl9170fw/455d7633deee32e6837d33cc4a427b6dc1d0be24/tools/src/eeprom_fix -------------------------------------------------------------------------------- /tools/src/miniboot.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010-2011 Christian Lamparter 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 version 2 of the License. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "carlfw.h" 28 | 29 | #include "compiler.h" 30 | 31 | static void mini_help(void) 32 | { 33 | fprintf(stderr, "Usage:\n"); 34 | fprintf(stderr, "\tminiboot ACTION FW-FILE [MB-FILE]\n"); 35 | 36 | fprintf(stderr, "\nDescription:\n"); 37 | fprintf(stderr, "\tFirmware concatenation utility.\n"); 38 | 39 | fprintf(stderr, "\nParameteres:\n"); 40 | fprintf(stderr, "\t'ACTION' = [a|d]\n"); 41 | fprintf(stderr, "\t | 'a' = Add miniboot firmware.\n"); 42 | fprintf(stderr, "\t * 'd' = remove miniboot firmware.\n"); 43 | fprintf(stderr, "\t'FW-FILE' = destination for the package.\n"); 44 | fprintf(stderr, "\t'MB-FILE' = extra firmware image.\n"); 45 | } 46 | 47 | static int add_mini(struct carlfw *fw, const char *mini) 48 | { 49 | struct stat file_stat; 50 | struct carl9170fw_otus_desc *otus_desc = NULL; 51 | FILE *m = NULL; 52 | char *buf = NULL; 53 | size_t extra; 54 | int err; 55 | 56 | m = fopen(mini, "r"); 57 | if (m == NULL) { 58 | fprintf(stderr, "Failed to open file %s (%d).\n", 59 | mini, errno); 60 | err = -errno; 61 | goto fail; 62 | } 63 | 64 | err = fstat(fileno(m), &file_stat); 65 | if (err) { 66 | fprintf(stderr, "Failed to query file infos from " 67 | "\"%s\" (%d).\n", mini, errno); 68 | err = -errno; 69 | goto fail; 70 | } 71 | extra = file_stat.st_size; 72 | 73 | otus_desc = carlfw_find_desc(fw, (uint8_t *) OTUS_MAGIC, 74 | sizeof(*otus_desc), 75 | CARL9170FW_OTUS_DESC_CUR_VER); 76 | if (!otus_desc) { 77 | fprintf(stderr, "No OTUS descriptor found\n"); 78 | goto fail; 79 | } 80 | 81 | if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_MINIBOOT)) { 82 | fprintf(stderr, "Firmware has already a miniboot image.\n"); 83 | goto fail; 84 | } 85 | 86 | otus_desc->feature_set |= cpu_to_le32(BIT(CARL9170FW_MINIBOOT)); 87 | otus_desc->miniboot_size = cpu_to_le16(extra); 88 | 89 | buf = carlfw_mod_headroom(fw, extra); 90 | if (IS_ERR_OR_NULL(buf)) { 91 | fprintf(stderr, "Unable to add miniboot image.\n"); 92 | goto fail; 93 | } 94 | 95 | err = fread(buf, extra, 1, m); 96 | if (err != 1) { 97 | fprintf(stderr, "Unable to load miniboot.\n"); 98 | goto fail; 99 | } 100 | 101 | carlfw_store(fw); 102 | fclose(m); 103 | 104 | return 0; 105 | 106 | fail: 107 | if (m) 108 | fclose(m); 109 | 110 | return err; 111 | } 112 | 113 | static int del_mini(struct carlfw *fw) 114 | { 115 | struct carl9170fw_otus_desc *otus_desc = NULL; 116 | void *buf; 117 | int cut; 118 | 119 | otus_desc = carlfw_find_desc(fw, (uint8_t *) OTUS_MAGIC, 120 | sizeof(*otus_desc), 121 | CARL9170FW_OTUS_DESC_CUR_VER); 122 | if (!otus_desc) { 123 | fprintf(stderr, "Firmware is not for USB devices.\n"); 124 | return -ENODATA; 125 | } 126 | 127 | if (!carl9170fw_supports(otus_desc->feature_set, CARL9170FW_MINIBOOT)) { 128 | fprintf(stderr, "Firmware has no miniboot image.\n"); 129 | return -EINVAL; 130 | } 131 | 132 | cut = le16_to_cpu(otus_desc->miniboot_size); 133 | 134 | buf = carlfw_mod_headroom(fw, -cut); 135 | if (IS_ERR_OR_NULL(buf)) { 136 | fprintf(stderr, "Unable to remove miniboot.\n"); 137 | return PTR_ERR(buf); 138 | } 139 | 140 | otus_desc->feature_set &= cpu_to_le32(~BIT(CARL9170FW_MINIBOOT)); 141 | otus_desc->miniboot_size = cpu_to_le16(0); 142 | 143 | carlfw_store(fw); 144 | return 0; 145 | } 146 | 147 | int main(int argc, char *args[]) 148 | { 149 | struct carlfw *fw = NULL; 150 | int err; 151 | 152 | if (argc < 3 || argc > 4) { 153 | err = -EINVAL; 154 | goto err_param; 155 | } 156 | 157 | switch (args[1][0]) { 158 | case 'a': 159 | if (argc != 4) 160 | goto err_param; 161 | 162 | fw = carlfw_load(args[2]); 163 | if (IS_ERR_OR_NULL(fw)) { 164 | err = PTR_ERR(fw); 165 | goto err_out; 166 | } 167 | 168 | err = add_mini(fw, args[3]); 169 | break; 170 | case 'd': 171 | if (argc != 3) 172 | goto err_param; 173 | 174 | fw = carlfw_load(args[2]); 175 | if (IS_ERR_OR_NULL(fw)) { 176 | err = PTR_ERR(fw); 177 | goto err_out; 178 | } 179 | 180 | err = del_mini(fw); 181 | break; 182 | 183 | default: 184 | goto err_param; 185 | break; 186 | } 187 | 188 | carlfw_release(fw); 189 | return EXIT_SUCCESS; 190 | 191 | err_out: 192 | carlfw_release(fw); 193 | fprintf(stderr, "miniboot action failed (%d).\n", err); 194 | return EXIT_FAILURE; 195 | 196 | err_param: 197 | carlfw_release(fw); 198 | mini_help(); 199 | return EXIT_FAILURE; 200 | } 201 | -------------------------------------------------------------------------------- /tools/src/wol.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, Christian Lamparter 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 version 2 of the License. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | #include /* ETH_P_ALL */ 33 | #include /* sockaddr_ll */ 34 | 35 | static int monitor_init(const char *ifname) 36 | { 37 | struct sockaddr_ll ll; 38 | int monitor_sock; 39 | 40 | memset(&ll, 0, sizeof(ll)); 41 | ll.sll_family = AF_PACKET; 42 | ll.sll_ifindex = if_nametoindex(ifname); 43 | if (ll.sll_ifindex == 0) { 44 | fprintf(stderr, "Monitor interface '%s' does not exist\n", ifname); 45 | return -1; 46 | } 47 | 48 | monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 49 | if (monitor_sock < 0) { 50 | fprintf(stderr, "socket(PF_PACKET,SOCK_RAW): %s\n", strerror(errno)); 51 | return -1; 52 | } 53 | 54 | if (bind(monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) { 55 | fprintf(stderr, "bind(PACKET): %s\n", strerror(errno)); 56 | close(monitor_sock); 57 | return -1; 58 | } 59 | 60 | return monitor_sock; 61 | } 62 | 63 | static int inject_frame(int s, const void *data, size_t len) 64 | { 65 | #define IEEE80211_RADIOTAP_F_FRAG 0x08 66 | unsigned char rtap_hdr[] = { 67 | 0x00, 0x00, /* radiotap version */ 68 | 0x0e, 0x00, /* radiotap length */ 69 | 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */ 70 | IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */ 71 | 0x00, /* padding */ 72 | 0x00, 0x00, /* RX and TX flags to indicate that */ 73 | 0x00, 0x00, /* this is the injected frame directly */ 74 | }; 75 | struct iovec iov[2] = { 76 | { 77 | .iov_base = &rtap_hdr, 78 | .iov_len = sizeof(rtap_hdr), 79 | }, 80 | { 81 | .iov_base = (void *) data, 82 | .iov_len = len, 83 | } 84 | }; 85 | struct msghdr msg = { 86 | .msg_name = NULL, 87 | .msg_namelen = 0, 88 | .msg_iov = iov, 89 | .msg_iovlen = 2, 90 | .msg_control = NULL, 91 | .msg_controllen = 0, 92 | .msg_flags = 0, 93 | }; 94 | int ret; 95 | 96 | ret = sendmsg(s, &msg, 0); 97 | if (ret < 0) 98 | perror("sendmsg"); 99 | return ret; 100 | } 101 | 102 | static unsigned char wol_magic_tmpl[30 + 6 + 16 * 6] = { 103 | 0x08, 0x00, 0x00, 0x00, 104 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* RA */ 105 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* TA */ 106 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* SA */ 107 | 0x00, 0x00, 108 | 109 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 110 | }; 111 | 112 | static void prepare_wol(unsigned char *wol_magic, unsigned char *mac) 113 | { 114 | int i; 115 | 116 | for (i = 0; i < 16; i++) 117 | memcpy(&wol_magic[30 + i * 6], mac, 6); 118 | } 119 | 120 | void usage(void) 121 | { 122 | fprintf(stderr, "Usage:\n"); 123 | fprintf(stderr, "\twol -i monitor_dev -m DE:VI:CE:MA:CW:OL -n #num -v\n"); 124 | 125 | fprintf(stderr, "\nDescription:\n"); 126 | fprintf(stderr, "\tThis utility generates a WOL packet for the" 127 | "given [MAC] address and tries to injects" 128 | "it into [monitor_dev]\n"); 129 | 130 | exit(EXIT_FAILURE); 131 | } 132 | 133 | #define MAC_STR "%2X:%2X:%2X:%2X:%2X:%2X" 134 | 135 | #define M(a, i) ((unsigned int *)&a[i]) 136 | #define MAC_ARG(a) M(a, 0), M(a, 1), M(a, 2), M(a, 3), M(a, 4), M(a, 5) 137 | 138 | #define M2(a, i) (a[i]) 139 | #define MAC_ARG2(a) M2(a, 0), M2(a, 1), M2(a, 2), M2(a, 3), M2(a, 4), M2(a, 5) 140 | 141 | int main(int argc, char **args) 142 | { 143 | int sock, err = 0, opt, num = 10; 144 | unsigned char mac[ETH_ALEN]; 145 | char dev_name[IFNAMSIZ + 1] = { 0 }; 146 | bool has_mac = false, has_dev = false, verbose = false; 147 | 148 | while ((opt = getopt(argc, args, "m:i:n:v")) != -EXIT_FAILURE) { 149 | switch (opt) { 150 | case 'i': 151 | has_dev = true; 152 | strncpy(dev_name, optarg, IFNAMSIZ); 153 | break; 154 | case 'm': 155 | has_mac = true; 156 | err = sscanf(optarg, MAC_STR, MAC_ARG(mac)) != 6; 157 | if (err) 158 | fprintf(stderr, "invalid MAC: \"%s\"\n", optarg); 159 | break; 160 | 161 | case 'n': 162 | err = sscanf(optarg, "%d", &num) != 1; 163 | err |= num < 1 | num > 1000; 164 | if (err) 165 | fprintf(stderr, "invalid tries: \"%s\"\n", optarg); 166 | break; 167 | 168 | case 'v': 169 | verbose = true; 170 | break; 171 | 172 | default: 173 | err = -EINVAL; 174 | break; 175 | } 176 | 177 | if (err) 178 | break; 179 | } 180 | 181 | if (!has_mac || !has_dev || err) 182 | usage(); 183 | 184 | if (verbose) 185 | fprintf(stdout, "Opening monitor injection interface [%s].\n", dev_name); 186 | 187 | sock = monitor_init(dev_name); 188 | if (sock < 0) 189 | return EXIT_FAILURE; 190 | 191 | if (verbose) 192 | fprintf(stdout, "Generating %d WOL packet for ["MAC_STR"].\n", num, MAC_ARG2(mac)); 193 | 194 | prepare_wol(wol_magic_tmpl, mac); 195 | 196 | while (num--) { 197 | err = inject_frame(sock, wol_magic_tmpl, sizeof(wol_magic_tmpl)); 198 | if (err < 0) { 199 | fprintf(stderr, "failed to send WOL packet.\n"); 200 | break; 201 | } else if (verbose) { 202 | fprintf(stdout, "WOL packet sent.\n"); 203 | } 204 | } 205 | 206 | close(sock); 207 | if (err < 0) 208 | return EXIT_FAILURE; 209 | 210 | return 0; 211 | } 212 | --------------------------------------------------------------------------------