├── .gitignore ├── LICENSE ├── README ├── tools ├── edump │ ├── Makefile.am │ ├── README │ ├── autogen.sh │ ├── configure.ac │ └── src │ │ ├── Makefile.am │ │ ├── edump.c │ │ ├── edump.h │ │ ├── eep_4k.c │ │ ├── eep_4k.h │ │ ├── eep_9003.c │ │ ├── eep_9003.h │ │ ├── eep_9287.c │ │ ├── eep_9287.h │ │ ├── eep_common.h │ │ ├── eep_def.c │ │ └── eep_def.h ├── halregdump │ ├── Makefile │ ├── ah_regdomain.h │ ├── ah_regdomain_common.h │ └── hal-reg-dump.c ├── initvals │ ├── Makefile │ ├── ar5008_initvals.h │ ├── ar9001_initvals.h │ ├── ar9002_initvals.h │ ├── ar9003_2p2_initvals.h │ ├── ar9330_1p1_initvals.h │ ├── ar9330_1p2_initvals.h │ ├── ar9340_initvals.h │ ├── ar9462_2p0_initvals.h │ ├── ar9462_2p1_initvals.h │ ├── ar9485_initvals.h │ ├── ar955x_1p0_initvals.h │ ├── ar9565_1p0_initvals.h │ ├── ar9580_1p0_initvals.h │ ├── checksums.txt │ ├── initvals.c │ ├── sha1.c │ ├── sha1.h │ └── verify_checksums.sh └── scripts │ ├── ath10k │ ├── ath10k-bdencoder │ ├── ath10k-check │ ├── ath10k-fw-repo │ └── ath10k-fwencoder │ ├── ath11k │ ├── ath11k-bdencoder │ ├── ath11k-check │ ├── ath11k-fw-repo │ └── ath11k-fwencoder │ ├── ath12k │ ├── ath12k-bdencoder │ ├── ath12k-check │ ├── ath12k-fw-repo │ └── ath12k-fwencoder │ └── ath9k │ ├── irq-watch │ └── read-powers └── tracing └── plugins ├── ath10k.py ├── ath10k_pktlog.py └── ath6kl.py /.gitignore: -------------------------------------------------------------------------------- 1 | /tools/initvals/initvals 2 | *.ini 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2011 Atheros Communications Inc. 2 | Copyright (c) 2011-2012 Qualcomm Atheros, Inc. 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any 5 | purpose with or without fee is hereby granted, provided that the above 6 | copyright notice and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | qca-swiss-army-knife 2 | ==================== 3 | 4 | This is the qca-swiss-army-knife, which hosts a set of utilities that we use 5 | to debug / help with our driver development. 6 | 7 | Documentation: 8 | 9 | https://github.com/mcgrof/qca-swiss-army-knife/wiki 10 | -------------------------------------------------------------------------------- /tools/edump/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = src 2 | -------------------------------------------------------------------------------- /tools/edump/README: -------------------------------------------------------------------------------- 1 | This is a tool to dump the eeprom contents of WLAN chips supported by ath9k. 2 | 3 | Requirements 4 | ------------ 5 | 6 | libpcicaccess (http://cgit.freedesktop.org/xorg/lib/libpciaccess/) 7 | 8 | Installation 9 | ------------ 10 | 11 | ./autogen.sh 12 | ./configure 13 | make 14 | make install 15 | 16 | Usage 17 | ----- 18 | 19 | To dump everything: "edump" or "edump -a" 20 | To dump the base header: "edump -b" 21 | To dump the modal header: "edump -m" 22 | 23 | Help 24 | ---- 25 | 26 | "edump --help" 27 | 28 | Bugs 29 | ---- 30 | 31 | Report them to "ath9k-devel@qualcomm.com" 32 | -------------------------------------------------------------------------------- /tools/edump/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Running autoreconf..." 4 | 5 | autoreconf -f -i -v 6 | if [ $? -ne 0 ]; then 7 | echo "autoreconf failed" 8 | fi 9 | -------------------------------------------------------------------------------- /tools/edump/configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT([edump], [1.0], [ath9k-devel@qualcomm.com]) 2 | AM_INIT_AUTOMAKE([-Wall -Werror foreign]) 3 | AC_CONFIG_SRCDIR([src/edump.c]) 4 | AC_CONFIG_HEADER([config.h]) 5 | 6 | # Checks for programs. 7 | AC_PROG_CC 8 | AM_PROG_CC_C_O 9 | AC_PROG_INSTALL 10 | 11 | # Checks for header files. 12 | AC_HEADER_STDC 13 | 14 | # Checks for libraries. 15 | PKG_CHECK_MODULES([pciaccess], 16 | [pciaccess >= 0.10.3], 17 | [], 18 | [AC_MSG_ERROR(libpciaccess-0.10.3 is required)]) 19 | 20 | # Checks for typedefs, structures, and compiler characteristics. 21 | AC_C_CONST 22 | 23 | AC_CONFIG_FILES([Makefile 24 | src/Makefile]) 25 | AC_OUTPUT 26 | -------------------------------------------------------------------------------- /tools/edump/src/Makefile.am: -------------------------------------------------------------------------------- 1 | bin_PROGRAMS = edump 2 | edump_CFLAGS = -Wall $(pciaccess_CFLAGS) 3 | edump_LDADD = $(pciaccess_LIBS) 4 | edump_SOURCES = eep_def.c eep_4k.c eep_9287.c eep_9003.c edump.c 5 | -------------------------------------------------------------------------------- /tools/edump/src/edump.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "edump.h" 18 | 19 | const char *argp_program_version = PACKAGE_VERSION; 20 | const char *argp_program_bug_address = PACKAGE_BUGREPORT; 21 | 22 | int dump; 23 | 24 | static struct argp_option argp_cmd_options[] = { 25 | {"base", 'b', 0, 0, "Dump base header", 0}, 26 | {"modal", 'm', 0, 0, "Dump modal header", 0}, 27 | {"power", 'p', 0, 0, "Dump power calibration info", 0}, 28 | {"all", 'a', 0, 0, "Dump everything", 0}, 29 | { 0 } 30 | }; 31 | 32 | static error_t argp_parser(int key, char *arg, struct argp_state *state) 33 | { 34 | switch(key) { 35 | case 'b': 36 | dump = DUMP_BASE_HEADER; 37 | break; 38 | case 'm': 39 | dump = DUMP_MODAL_HEADER; 40 | break; 41 | case 'p': 42 | dump = DUMP_POWER_INFO; 43 | break; 44 | case 'a': 45 | dump = DUMP_ALL; 46 | break; 47 | default: 48 | return ARGP_ERR_UNKNOWN; 49 | } 50 | 51 | return 0; 52 | } 53 | 54 | static struct argp argp = {argp_cmd_options, argp_parser}; 55 | 56 | static struct pci_id_match pci_id[] = { 57 | {ATHEROS_VENDOR_ID, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY}, 58 | { 0 } 59 | }; 60 | 61 | static struct { 62 | uint32_t version; 63 | const char * name; 64 | } mac_bb_names[] = { 65 | /* Devices with external radios */ 66 | { AR_SREV_VERSION_5416_PCI, "5416" }, 67 | { AR_SREV_VERSION_5416_PCIE, "5418" }, 68 | { AR_SREV_VERSION_9160, "9160" }, 69 | /* Single-chip solutions */ 70 | { AR_SREV_VERSION_9280, "9280" }, 71 | { AR_SREV_VERSION_9285, "9285" }, 72 | { AR_SREV_VERSION_9287, "9287" }, 73 | { AR_SREV_VERSION_9300, "9300" }, 74 | { AR_SREV_VERSION_9330, "9330" }, 75 | { AR_SREV_VERSION_9485, "9485" }, 76 | { AR_SREV_VERSION_9462, "9462" }, 77 | { AR_SREV_VERSION_9565, "9565" }, 78 | { AR_SREV_VERSION_9340, "9340" }, 79 | { AR_SREV_VERSION_9550, "9550" }, 80 | }; 81 | 82 | static const char * 83 | mac_bb_name(uint32_t mac_bb_version) 84 | { 85 | int i; 86 | 87 | for (i = 0; i < ARRAY_SIZE(mac_bb_names); i++) { 88 | if (mac_bb_names[i].version == mac_bb_version) { 89 | return mac_bb_names[i].name; 90 | } 91 | } 92 | 93 | return "????"; 94 | } 95 | 96 | static int is_supported_chipset(struct pci_device *pdev) 97 | { 98 | if (pdev->vendor_id != ATHEROS_VENDOR_ID) 99 | return 0; 100 | 101 | if ((pdev->device_id != AR5416_DEVID_PCI) && 102 | (pdev->device_id != AR5416_DEVID_PCIE) && 103 | (pdev->device_id != AR9160_DEVID_PCI) && 104 | (pdev->device_id != AR9280_DEVID_PCI) && 105 | (pdev->device_id != AR9280_DEVID_PCIE) && 106 | (pdev->device_id != AR9285_DEVID_PCIE) && 107 | (pdev->device_id != AR9287_DEVID_PCI) && 108 | (pdev->device_id != AR9287_DEVID_PCIE) && 109 | (pdev->device_id != AR9300_DEVID_PCIE) && 110 | (pdev->device_id != AR9485_DEVID_PCIE) && 111 | (pdev->device_id != AR9580_DEVID_PCIE) && 112 | (pdev->device_id != AR9462_DEVID_PCIE) && 113 | (pdev->device_id != AR9565_DEVID_PCIE) && 114 | (pdev->device_id != AR1111_DEVID_PCIE)) { 115 | fprintf(stderr, "Device ID: 0x%x not supported\n", pdev->device_id); 116 | return 0; 117 | } 118 | 119 | printf("Found Device ID: 0x%04x\n", pdev->device_id); 120 | return 1; 121 | } 122 | 123 | static struct edump* init_pci_device(struct pci_device *pdev) 124 | { 125 | int err; 126 | struct edump *edump; 127 | 128 | if (!pdev->regions[0].base_addr) { 129 | fprintf(stderr, "Invalid base address\n"); 130 | return NULL; 131 | } 132 | 133 | edump = malloc(sizeof(struct edump)); 134 | if (edump == NULL) { 135 | fprintf(stderr, "Unable to alloc memory for edump\n"); 136 | return NULL; 137 | } 138 | 139 | memset(edump, 0, sizeof(struct edump)); 140 | 141 | edump->pdev = pdev; 142 | edump->base_addr = pdev->regions[0].base_addr; 143 | edump->size = pdev->regions[0].size; 144 | pdev->user_data = (intptr_t)edump; 145 | 146 | if ((err = pci_device_map_range(pdev, edump->base_addr, edump->size, 147 | 0, &edump->io_map)) != 0) { 148 | fprintf(stderr, "%s\n", strerror(err)); 149 | goto map_fail; 150 | } 151 | 152 | printf("Mapped IO region at: %p\n", edump->io_map); 153 | return edump; 154 | 155 | map_fail: 156 | free(edump); 157 | return NULL; 158 | } 159 | 160 | static void cleanup_pci_device(struct edump *edump) 161 | { 162 | int err; 163 | 164 | printf("\nFreeing Mapped IO region at: %p\n", edump->io_map); 165 | 166 | if ((err = pci_device_unmap_range(edump->pdev, edump->io_map, 167 | edump->size)) != 0) 168 | fprintf(stderr, "%s\n", strerror(err)); 169 | 170 | free(edump); 171 | } 172 | 173 | static void hw_read_revisions(struct edump *edump) 174 | { 175 | uint32_t val; 176 | 177 | val = REG_READ(AR_SREV) & AR_SREV_ID; 178 | 179 | if (val == 0xFF) { 180 | val = REG_READ(AR_SREV); 181 | edump->macVersion = (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S; 182 | edump->macRev = MS(val, AR_SREV_REVISION2); 183 | } else { 184 | edump->macVersion = MS(val, AR_SREV_VERSION); 185 | edump->macRev = val & AR_SREV_REVISION; 186 | } 187 | 188 | printf("Atheros AR%s MAC/BB Rev:%x\n", 189 | mac_bb_name(edump->macVersion), edump->macRev); 190 | } 191 | 192 | bool hw_wait(struct edump *edump, uint32_t reg, uint32_t mask, 193 | uint32_t val, uint32_t timeout) 194 | { 195 | int i; 196 | 197 | for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) { 198 | if ((REG_READ(reg) & mask) == val) 199 | return true; 200 | 201 | usleep(AH_TIME_QUANTUM); 202 | } 203 | 204 | return false; 205 | } 206 | 207 | bool pci_eeprom_read(struct edump *edump, uint32_t off, uint16_t *data) 208 | { 209 | (void)REG_READ(AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S)); 210 | 211 | if (!hw_wait(edump, 212 | AR_EEPROM_STATUS_DATA, 213 | AR_EEPROM_STATUS_DATA_BUSY | 214 | AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0, 215 | AH_WAIT_TIMEOUT)) { 216 | return false; 217 | } 218 | 219 | *data = MS(REG_READ(AR_EEPROM_STATUS_DATA), 220 | AR_EEPROM_STATUS_DATA_VAL); 221 | 222 | return true; 223 | } 224 | 225 | int register_eep_ops(struct edump *edump) 226 | { 227 | if (AR_SREV_9300_20_OR_LATER(edump)) { 228 | edump->eep_map = EEP_MAP_9003; 229 | edump->eep_ops = &eep_9003_ops; 230 | } else if (AR_SREV_9287(edump)) { 231 | edump->eep_map = EEP_MAP_9287; 232 | edump->eep_ops = &eep_9287_ops; 233 | } else if (AR_SREV_9285(edump)) { 234 | edump->eep_map = EEP_MAP_4K; 235 | edump->eep_ops = &eep_4k_ops; 236 | } else { 237 | edump->eep_map = EEP_MAP_DEFAULT; 238 | edump->eep_ops = &eep_def_ops; 239 | } 240 | 241 | if (!edump->eep_ops->fill_eeprom(edump)) { 242 | fprintf(stderr, "Unable to fill EEPROM data\n"); 243 | return -1; 244 | } 245 | 246 | if (!edump->eep_ops->check_eeprom(edump)) { 247 | fprintf(stderr, "EEPROM check failed\n"); 248 | return -1; 249 | } 250 | 251 | return 0; 252 | } 253 | 254 | void dump_device(struct edump *edump) 255 | { 256 | hw_read_revisions(edump); 257 | 258 | if (register_eep_ops(edump) < 0) 259 | return; 260 | 261 | switch(dump) { 262 | case DUMP_BASE_HEADER: 263 | edump->eep_ops->dump_base_header(edump); 264 | break; 265 | case DUMP_MODAL_HEADER: 266 | edump->eep_ops->dump_modal_header(edump); 267 | break; 268 | case DUMP_POWER_INFO: 269 | edump->eep_ops->dump_power_info(edump); 270 | break; 271 | case DUMP_ALL: 272 | edump->eep_ops->dump_base_header(edump); 273 | edump->eep_ops->dump_modal_header(edump); 274 | edump->eep_ops->dump_power_info(edump); 275 | break; 276 | } 277 | } 278 | 279 | int main(int argc, char *argv[]) 280 | { 281 | struct edump *edump; 282 | struct pci_device_iterator *iter; 283 | struct pci_device *pdev; 284 | int ret = 0, cnt = 0;; 285 | 286 | dump = DUMP_ALL; 287 | 288 | if (argp_parse(&argp, argc, argv, 0, 0, NULL) != 0) 289 | return -EINVAL; 290 | 291 | if ((ret = pci_system_init()) != 0) { 292 | fprintf(stderr, "%s\n", strerror(ret)); 293 | return ret; 294 | } else { 295 | printf("Initializing PCI\n"); 296 | } 297 | 298 | iter = pci_id_match_iterator_create(pci_id); 299 | if (iter == NULL) { 300 | ret = -EINVAL; 301 | fprintf(stderr, "Iter creation failed\n"); 302 | goto iter_fail; 303 | } 304 | 305 | while((pdev = pci_device_next(iter)) != NULL) { 306 | if ((ret = pci_device_probe(pdev)) != 0) { 307 | fprintf(stderr, "%s\n", strerror(ret)); 308 | continue; 309 | } 310 | 311 | if (!is_supported_chipset(pdev)) 312 | continue; 313 | 314 | edump = init_pci_device(pdev); 315 | if (edump == NULL) 316 | continue; 317 | 318 | cnt++; 319 | dump_device(edump); 320 | cleanup_pci_device(edump); 321 | } 322 | 323 | if (!cnt) 324 | printf("No supported card found\n"); 325 | 326 | pci_iterator_destroy(iter); 327 | 328 | iter_fail: 329 | pci_system_cleanup(); 330 | return ret; 331 | } 332 | -------------------------------------------------------------------------------- /tools/edump/src/edump.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef EDUMP_H 18 | #define EDUMP_H 19 | 20 | #if HAVE_CONFIG_H 21 | #include 22 | #endif 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "eep_common.h" 33 | #include "eep_def.h" 34 | #include "eep_4k.h" 35 | #include "eep_9287.h" 36 | #include "eep_9003.h" 37 | 38 | #if __BYTE_ORDER == __BIG_ENDIAN 39 | #define REG_READ(_reg) \ 40 | bswap_32(*((volatile uint32_t *)(edump->io_map + (_reg)))) 41 | #else 42 | #define REG_READ(_reg) \ 43 | (*((volatile uint32_t *)(edump->io_map + (_reg)))) 44 | #endif 45 | 46 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 47 | #define MS(_v, _f) (((_v) & _f) >> _f##_S) 48 | 49 | enum { 50 | false = 0, 51 | true = 1 52 | }; 53 | 54 | typedef int bool; 55 | 56 | #define ATHEROS_VENDOR_ID 0x168c 57 | #define AR5416_DEVID_PCI 0x0023 58 | #define AR5416_DEVID_PCIE 0x0024 59 | #define AR9160_DEVID_PCI 0x0027 60 | #define AR9280_DEVID_PCI 0x0029 61 | #define AR9280_DEVID_PCIE 0x002a 62 | #define AR9285_DEVID_PCIE 0x002b 63 | #define AR9287_DEVID_PCI 0x002d 64 | #define AR9287_DEVID_PCIE 0x002e 65 | #define AR9300_DEVID_PCIE 0x0030 66 | #define AR9485_DEVID_PCIE 0x0032 67 | #define AR9580_DEVID_PCIE 0x0033 68 | #define AR9462_DEVID_PCIE 0x0034 69 | #define AR9565_DEVID_PCIE 0x0036 70 | #define AR1111_DEVID_PCIE 0x0037 71 | 72 | #define AR_SREV 0x4020 73 | #define AR_SREV_ID 0x000000FF 74 | #define AR_SREV_VERSION 0x000000F0 75 | #define AR_SREV_VERSION_S 4 76 | #define AR_SREV_REVISION 0x00000007 77 | #define AR_SREV_VERSION2 0xFFFC0000 78 | #define AR_SREV_VERSION2_S 18 79 | #define AR_SREV_TYPE2 0x0003F000 80 | #define AR_SREV_TYPE2_S 12 81 | #define AR_SREV_REVISION2 0x00000F00 82 | #define AR_SREV_REVISION2_S 8 83 | 84 | #define AR_SREV_VERSION_5416_PCI 0xD 85 | #define AR_SREV_VERSION_5416_PCIE 0xC 86 | #define AR_SREV_VERSION_9160 0x40 87 | #define AR_SREV_VERSION_9280 0x80 88 | #define AR_SREV_VERSION_9285 0xC0 89 | #define AR_SREV_VERSION_9287 0x180 90 | #define AR_SREV_VERSION_9300 0x1c0 91 | #define AR_SREV_VERSION_9330 0x200 92 | #define AR_SREV_VERSION_9485 0x240 93 | #define AR_SREV_VERSION_9462 0x280 94 | #define AR_SREV_VERSION_9565 0x2c0 95 | #define AR_SREV_VERSION_9340 0x300 96 | #define AR_SREV_VERSION_9550 0x400 97 | 98 | #define AR_SREV_9280_20_OR_LATER(edump) \ 99 | (((edump)->macVersion >= AR_SREV_VERSION_9280)) 100 | #define AR_SREV_9285(_ah) \ 101 | (((edump)->macVersion == AR_SREV_VERSION_9285)) 102 | #define AR_SREV_9287(_ah) \ 103 | (((edump)->macVersion == AR_SREV_VERSION_9287)) 104 | #define AR_SREV_9300_20_OR_LATER(edump) \ 105 | (((edump)->macVersion >= AR_SREV_VERSION_9300)) 106 | #define AR_SREV_9485(edump) \ 107 | (((edump)->macVersion == AR_SREV_VERSION_9485)) 108 | #define AR_SREV_9330(edump) \ 109 | (((edump)->macVersion == AR_SREV_VERSION_9330)) 110 | #define AR_SREV_9340(edump) \ 111 | (((edump)->macVersion == AR_SREV_VERSION_9340)) 112 | #define AR_SREV_9462(edump) \ 113 | (((edump)->macVersion == AR_SREV_VERSION_9462)) 114 | #define AR_SREV_9550(edump) \ 115 | (((edump)->macVersion == AR_SREV_VERSION_9550)) 116 | #define AR_SREV_9565(edump) \ 117 | (((edump)->macVersion == AR_SREV_VERSION_9565)) 118 | 119 | #define AH_WAIT_TIMEOUT 100000 /* (us) */ 120 | #define AH_TIME_QUANTUM 10 121 | 122 | enum dump_data { 123 | DUMP_BASE_HEADER = 1, 124 | DUMP_MODAL_HEADER = 2, 125 | DUMP_POWER_INFO = 3, 126 | DUMP_ALL = 4 127 | }; 128 | 129 | struct edump { 130 | struct pci_device *pdev; 131 | pciaddr_t base_addr; 132 | pciaddr_t size; 133 | void *io_map; 134 | 135 | uint32_t macVersion; 136 | uint16_t macRev; 137 | 138 | struct eeprom_ops *eep_ops; 139 | enum eep_map eep_map; 140 | 141 | union { 142 | struct ar5416_eeprom_def def; 143 | struct ar5416_eeprom_4k map4k; 144 | struct ar9287_eeprom map9287; 145 | struct ar9300_eeprom eep_93k; 146 | } eeprom; 147 | }; 148 | 149 | struct eeprom_ops { 150 | bool (*fill_eeprom)(struct edump *edump); 151 | int (*check_eeprom)(struct edump *edump); 152 | int (*get_eeprom_ver)(struct edump *edump); 153 | int (*get_eeprom_rev)(struct edump *edump); 154 | void (*dump_base_header)(struct edump *edump); 155 | void (*dump_modal_header)(struct edump *edump); 156 | void (*dump_power_info)(struct edump *edump); 157 | }; 158 | 159 | extern struct eeprom_ops eep_def_ops; 160 | extern struct eeprom_ops eep_4k_ops; 161 | extern struct eeprom_ops eep_9287_ops; 162 | extern struct eeprom_ops eep_9003_ops; 163 | 164 | bool pci_eeprom_read(struct edump *edump, uint32_t off, uint16_t *data); 165 | bool hw_wait(struct edump *edump, uint32_t reg, uint32_t mask, 166 | uint32_t val, uint32_t timeout); 167 | 168 | #endif /* EDUMP_H */ 169 | -------------------------------------------------------------------------------- /tools/edump/src/eep_4k.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "edump.h" 18 | 19 | static int get_eeprom_ver_4k(struct edump *edump) 20 | { 21 | return ((edump->eeprom.map4k.baseEepHeader.version >> 12) & 0xF); 22 | } 23 | 24 | static int get_eeprom_rev_4k(struct edump *edump) 25 | { 26 | return ((edump->eeprom.map4k.baseEepHeader.version) & 0xFFF); 27 | } 28 | 29 | static bool fill_eeprom_4k(struct edump *edump) 30 | { 31 | #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(uint16_t)) 32 | 33 | uint16_t *eep_data = (uint16_t *)&edump->eeprom.map4k; 34 | int addr, eep_start_loc = 0; 35 | 36 | eep_start_loc = 64; 37 | 38 | for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { 39 | if (!pci_eeprom_read(edump, addr + eep_start_loc, eep_data)) { 40 | fprintf(stderr, "Unable to read eeprom region\n"); 41 | return false; 42 | } 43 | eep_data++; 44 | } 45 | 46 | return true; 47 | 48 | #undef SIZE_EEPROM_4K 49 | } 50 | 51 | static bool check_eeprom_4k(struct edump *edump) 52 | { 53 | #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(uint16_t)) 54 | 55 | struct ar5416_eeprom_4k *eep = &edump->eeprom.map4k; 56 | uint16_t *eepdata, temp, magic, magic2; 57 | uint32_t sum = 0, el; 58 | bool need_swap = false; 59 | int i, addr; 60 | 61 | if (!pci_eeprom_read(edump, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { 62 | fprintf(stderr, "Reading Magic # failed\n"); 63 | return false; 64 | } 65 | 66 | if (magic != AR5416_EEPROM_MAGIC) { 67 | magic2 = bswap_16(magic); 68 | 69 | if (magic2 == AR5416_EEPROM_MAGIC) { 70 | need_swap = true; 71 | eepdata = (uint16_t *) (&edump->eeprom); 72 | 73 | for (addr = 0; addr < EEPROM_4K_SIZE; addr++) { 74 | temp = bswap_16(*eepdata); 75 | *eepdata = temp; 76 | eepdata++; 77 | } 78 | } else { 79 | fprintf(stderr, "Invalid EEPROM Magic, endianness mismatch.\n"); 80 | return false; 81 | } 82 | } 83 | 84 | if (need_swap) 85 | el = bswap_16(edump->eeprom.map4k.baseEepHeader.length); 86 | else 87 | el = edump->eeprom.map4k.baseEepHeader.length; 88 | 89 | if (el > sizeof(struct ar5416_eeprom_4k)) 90 | el = sizeof(struct ar5416_eeprom_4k) / sizeof(uint16_t); 91 | else 92 | el = el / sizeof(uint16_t); 93 | 94 | eepdata = (uint16_t *)(&edump->eeprom); 95 | 96 | for (i = 0; i < el; i++) 97 | sum ^= *eepdata++; 98 | 99 | if (need_swap) { 100 | uint32_t integer; 101 | uint16_t word; 102 | 103 | printf("EEPROM Endianness is not native.. Changing\n"); 104 | 105 | word = bswap_16(eep->baseEepHeader.length); 106 | eep->baseEepHeader.length = word; 107 | 108 | word = bswap_16(eep->baseEepHeader.checksum); 109 | eep->baseEepHeader.checksum = word; 110 | 111 | word = bswap_16(eep->baseEepHeader.version); 112 | eep->baseEepHeader.version = word; 113 | 114 | word = bswap_16(eep->baseEepHeader.regDmn[0]); 115 | eep->baseEepHeader.regDmn[0] = word; 116 | 117 | word = bswap_16(eep->baseEepHeader.regDmn[1]); 118 | eep->baseEepHeader.regDmn[1] = word; 119 | 120 | word = bswap_16(eep->baseEepHeader.rfSilent); 121 | eep->baseEepHeader.rfSilent = word; 122 | 123 | word = bswap_16(eep->baseEepHeader.blueToothOptions); 124 | eep->baseEepHeader.blueToothOptions = word; 125 | 126 | word = bswap_16(eep->baseEepHeader.deviceCap); 127 | eep->baseEepHeader.deviceCap = word; 128 | 129 | integer = bswap_32(eep->modalHeader.antCtrlCommon); 130 | eep->modalHeader.antCtrlCommon = integer; 131 | 132 | for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { 133 | integer = bswap_32(eep->modalHeader.antCtrlChain[i]); 134 | eep->modalHeader.antCtrlChain[i] = integer; 135 | } 136 | 137 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 138 | word = bswap_16(eep->modalHeader.spurChans[i].spurChan); 139 | eep->modalHeader.spurChans[i].spurChan = word; 140 | } 141 | } 142 | 143 | if (sum != 0xffff || edump->eep_ops->get_eeprom_ver(edump) != AR5416_EEP_VER || 144 | edump->eep_ops->get_eeprom_rev(edump) < AR5416_EEP_NO_BACK_VER) { 145 | fprintf(stderr, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 146 | sum, edump->eep_ops->get_eeprom_ver(edump)); 147 | return false; 148 | } 149 | 150 | return true; 151 | 152 | #undef EEPROM_4K_SIZE 153 | } 154 | 155 | static void base_eeprom_4k(struct edump *edump) 156 | { 157 | struct ar5416_eeprom_4k *ar5416Eep = &edump->eeprom.map4k; 158 | struct base_eep_header_4k *pBase = &ar5416Eep->baseEepHeader; 159 | uint16_t i; 160 | 161 | pBase = &(ar5416Eep->baseEepHeader); 162 | 163 | printf("\n----------------------\n"); 164 | printf("| EEPROM Base Header |\n"); 165 | printf("----------------------\n\n"); 166 | 167 | printf("%-30s : %2d\n", "Major Version", 168 | pBase->version >> 12); 169 | printf("%-30s : %2d\n", "Minor Version", 170 | pBase->version & 0xFFF); 171 | printf("%-30s : 0x%04X\n", "Checksum", 172 | pBase->checksum); 173 | printf("%-30s : 0x%04X\n", "Length", 174 | pBase->length); 175 | printf("%-30s : 0x%04X\n", "RegDomain1", 176 | pBase->regDmn[0]); 177 | printf("%-30s : 0x%04X\n", "RegDomain2", 178 | pBase->regDmn[1]); 179 | printf("%-30s : %02X:%02X:%02X:%02X:%02X:%02X\n", 180 | "MacAddress", 181 | pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2], 182 | pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]); 183 | printf("%-30s : 0x%04X\n", 184 | "TX Mask", pBase->txMask); 185 | printf("%-30s : 0x%04X\n", 186 | "RX Mask", pBase->rxMask); 187 | printf("%-30s : %d\n", 188 | "OpFlags(5GHz)", 189 | !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); 190 | printf("%-30s : %d\n", 191 | "OpFlags(2GHz)", 192 | !!(pBase->opCapFlags & AR5416_OPFLAGS_11G)); 193 | printf("%-30s : %d\n", 194 | "OpFlags(Disable 2GHz HT20)", 195 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20)); 196 | printf("%-30s : %d\n", 197 | "OpFlags(Disable 2GHz HT40)", 198 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40)); 199 | printf("%-30s : %d\n", 200 | "OpFlags(Disable 5Ghz HT20)", 201 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20)); 202 | printf("%-30s : %d\n", 203 | "OpFlags(Disable 5Ghz HT40)", 204 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40)); 205 | printf("%-30s : %d\n", 206 | "Big Endian", 207 | !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN)); 208 | printf("%-30s : %d\n", 209 | "Cal Bin Major Ver", 210 | (pBase->binBuildNumber >> 24) & 0xFF); 211 | printf("%-30s : %d\n", 212 | "Cal Bin Minor Ver", 213 | (pBase->binBuildNumber >> 16) & 0xFF); 214 | printf("%-30s : %d\n", 215 | "Cal Bin Build", 216 | (pBase->binBuildNumber >> 8) & 0xFF); 217 | 218 | if (edump->eep_ops->get_eeprom_rev(edump) >= AR5416_EEP_MINOR_VER_3) { 219 | printf("%-30s : %s\n", 220 | "Device Type", 221 | sDeviceType[(pBase->deviceType & 0x7)]); 222 | } 223 | 224 | printf("\nCustomer Data in hex:\n"); 225 | for (i = 0; i < 64; i++) { 226 | printf("%02X ", ar5416Eep->custData[i]); 227 | if ((i % 16) == 15) 228 | printf("\n"); 229 | } 230 | } 231 | 232 | static void modal_eeprom_4k(struct edump *edump) 233 | { 234 | #define PR(_token, _p, _val_fmt, _val) \ 235 | do { \ 236 | printf("%-23s %-2s", (_token), ":"); \ 237 | printf("%s%"_val_fmt, _p, (_val)); \ 238 | printf("\n"); \ 239 | } while(0) 240 | 241 | struct ar5416_eeprom_4k *ar5416Eep = &edump->eeprom.map4k; 242 | struct modal_eep_4k_header *pModal = &ar5416Eep->modalHeader; 243 | 244 | printf("\n\n-----------------------\n"); 245 | printf("| EEPROM Modal Header |\n"); 246 | printf("-----------------------\n\n"); 247 | 248 | PR("Ant Chain 0", "0x", "X", pModal->antCtrlChain[0]); 249 | PR("Antenna Common", "0x", "X", pModal->antCtrlCommon); 250 | PR("Antenna Gain Chain 0", "", "d", pModal->antennaGainCh[0]); 251 | PR("Switch Settling", "", "d", pModal->switchSettling); 252 | PR("TxRxAttenation Chain 0", "", "d", pModal->txRxAttenCh[0]); 253 | PR("RxTxMargin Chain 0", "", "d", pModal->rxTxMarginCh[0]); 254 | PR("ADC Desired Size", "", "d", pModal->adcDesiredSize); 255 | PR("PGA Desired Size", "", "d", pModal->pgaDesiredSize); 256 | PR("XLNA Gain Chain 0", "", "d", pModal->xlnaGainCh[0]); 257 | PR("TxEndToXpaOff", "", "d", pModal->txEndToXpaOff); 258 | PR("TxEndToRxOn", "", "d", pModal->txEndToRxOn); 259 | PR("TxFrameToXpaOn", "", "d", pModal->txFrameToXpaOn); 260 | PR("Thresh 62", "", "d", pModal->thresh62); 261 | PR("NF Thresh Chain 0", "", "d", pModal->noiseFloorThreshCh[0]); 262 | PR("XPD Gain", "", "d", pModal->xpdGain); 263 | PR("XPD", "", "d", pModal->xpd); 264 | PR("IQ Cal I Chain 0", "", "d", pModal->iqCalICh[0]); 265 | PR("IQ Cal Q Chain 0", "", "d", pModal->iqCalQCh[0]); 266 | PR("PD Gain Overlap", "", "d", pModal->pdGainOverlap); 267 | PR("Output Bias CCK", "", "d", pModal->ob_0); 268 | PR("Output Bias BPSK", "", "d", pModal->ob_1); 269 | PR("Driver 1 Bias CCK", "", "d", pModal->db1_0); 270 | PR("Driver 1 Bias BPSK", "", "d", pModal->db1_1); 271 | PR("XPA Bias Level", "", "d", pModal->xpaBiasLvl); 272 | PR("TX Frame to Data Start", "", "d", pModal->txFrameToDataStart); 273 | PR("TX Frame to PA On", "", "d", pModal->txFrameToPaOn); 274 | PR("HT40PowerIncForPDADC", "", "d", pModal->ht40PowerIncForPdadc); 275 | PR("bsw_atten Chain 0", "", "d", pModal->bswAtten[0]); 276 | PR("bsw_margin Chain 0", "", "d", pModal->bswMargin[0]); 277 | PR("Switch Settling [HT40]", "", "d", pModal->swSettleHt40); 278 | PR("xatten2DB Chain 0", "", "d", pModal->xatten2Db[0]); 279 | PR("xatten2margin Chain 0", "", "d", pModal->xatten2Margin[0]); 280 | PR("Driver 2 Bias CCK", "", "d", pModal->db2_0); 281 | PR("Driver 2 Bias BPSK", "", "d", pModal->db2_1); 282 | PR("ob_db Version", "", "d", pModal->version); 283 | PR("Output Bias QPSK", "", "d", pModal->ob_2); 284 | PR("Output Bias 16QAM", "", "d", pModal->ob_3); 285 | PR("Output Bias 64QAM", "", "d", pModal->ob_4); 286 | PR("Ant diversity ctrl 1", "", "d", pModal->antdiv_ctl1); 287 | PR("Driver 1 Bias QPSK", "", "d", pModal->db1_2); 288 | PR("Driver 1 Bias 16QAM", "", "d", pModal->db1_3); 289 | PR("Driver 1 Bias 64QAM", "", "d", pModal->db1_4); 290 | PR("Ant diversity ctrl 2", "", "d", pModal->antdiv_ctl2); 291 | PR("Driver 2 Bias QPSK", "", "d", pModal->db2_2); 292 | PR("Driver 2 Bias 16QAM", "", "d", pModal->db2_3); 293 | PR("Driver 2 Bias 64QAM", "", "d", pModal->db2_4); 294 | } 295 | 296 | static void power_info_eeprom_4k(struct edump *edump) 297 | { 298 | } 299 | 300 | struct eeprom_ops eep_4k_ops = { 301 | .fill_eeprom = fill_eeprom_4k, 302 | .check_eeprom = check_eeprom_4k, 303 | .get_eeprom_ver = get_eeprom_ver_4k, 304 | .get_eeprom_rev = get_eeprom_rev_4k, 305 | .dump_base_header = base_eeprom_4k, 306 | .dump_modal_header = modal_eeprom_4k, 307 | .dump_power_info = power_info_eeprom_4k, 308 | }; 309 | -------------------------------------------------------------------------------- /tools/edump/src/eep_4k.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef EEP_4K_H 18 | #define EEP_4K_H 19 | 20 | #define AR5416_EEP4K_START_LOC 64 21 | #define AR5416_EEP4K_NUM_2G_CAL_PIERS 3 22 | #define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3 23 | #define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3 24 | #define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3 25 | #define AR5416_EEP4K_NUM_CTLS 12 26 | #define AR5416_EEP4K_NUM_BAND_EDGES 4 27 | #define AR5416_EEP4K_NUM_PD_GAINS 2 28 | #define AR5416_EEP4K_MAX_CHAINS 1 29 | 30 | struct base_eep_header_4k { 31 | uint16_t length; 32 | uint16_t checksum; 33 | uint16_t version; 34 | uint8_t opCapFlags; 35 | uint8_t eepMisc; 36 | uint16_t regDmn[2]; 37 | uint8_t macAddr[6]; 38 | uint8_t rxMask; 39 | uint8_t txMask; 40 | uint16_t rfSilent; 41 | uint16_t blueToothOptions; 42 | uint16_t deviceCap; 43 | uint32_t binBuildNumber; 44 | uint8_t deviceType; 45 | uint8_t txGainType; 46 | } __attribute__ ((packed)); 47 | 48 | struct modal_eep_4k_header { 49 | uint32_t antCtrlChain[AR5416_EEP4K_MAX_CHAINS]; 50 | uint32_t antCtrlCommon; 51 | uint8_t antennaGainCh[AR5416_EEP4K_MAX_CHAINS]; 52 | uint8_t switchSettling; 53 | uint8_t txRxAttenCh[AR5416_EEP4K_MAX_CHAINS]; 54 | uint8_t rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS]; 55 | uint8_t adcDesiredSize; 56 | uint8_t pgaDesiredSize; 57 | uint8_t xlnaGainCh[AR5416_EEP4K_MAX_CHAINS]; 58 | uint8_t txEndToXpaOff; 59 | uint8_t txEndToRxOn; 60 | uint8_t txFrameToXpaOn; 61 | uint8_t thresh62; 62 | uint8_t noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS]; 63 | uint8_t xpdGain; 64 | uint8_t xpd; 65 | uint8_t iqCalICh[AR5416_EEP4K_MAX_CHAINS]; 66 | uint8_t iqCalQCh[AR5416_EEP4K_MAX_CHAINS]; 67 | uint8_t pdGainOverlap; 68 | #if __BYTE_ORDER == __BIG_ENDIAN 69 | uint8_t ob_1:4, ob_0:4; 70 | uint8_t db1_1:4, db1_0:4; 71 | #else 72 | uint8_t ob_0:4, ob_1:4; 73 | uint8_t db1_0:4, db1_1:4; 74 | #endif 75 | uint8_t xpaBiasLvl; 76 | uint8_t txFrameToDataStart; 77 | uint8_t txFrameToPaOn; 78 | uint8_t ht40PowerIncForPdadc; 79 | uint8_t bswAtten[AR5416_EEP4K_MAX_CHAINS]; 80 | uint8_t bswMargin[AR5416_EEP4K_MAX_CHAINS]; 81 | uint8_t swSettleHt40; 82 | uint8_t xatten2Db[AR5416_EEP4K_MAX_CHAINS]; 83 | uint8_t xatten2Margin[AR5416_EEP4K_MAX_CHAINS]; 84 | #if __BYTE_ORDER == __BIG_ENDIAN 85 | uint8_t db2_1:4, db2_0:4; 86 | #else 87 | uint8_t db2_0:4, db2_1:4; 88 | #endif 89 | uint8_t version; 90 | #if __BYTE_ORDER == __BIG_ENDIAN 91 | uint8_t ob_3:4, ob_2:4; 92 | uint8_t antdiv_ctl1:4, ob_4:4; 93 | uint8_t db1_3:4, db1_2:4; 94 | uint8_t antdiv_ctl2:4, db1_4:4; 95 | uint8_t db2_2:4, db2_3:4; 96 | uint8_t reserved:4, db2_4:4; 97 | #else 98 | uint8_t ob_2:4, ob_3:4; 99 | uint8_t ob_4:4, antdiv_ctl1:4; 100 | uint8_t db1_2:4, db1_3:4; 101 | uint8_t db1_4:4, antdiv_ctl2:4; 102 | uint8_t db2_2:4, db2_3:4; 103 | uint8_t db2_4:4, reserved:4; 104 | #endif 105 | uint8_t tx_diversity; 106 | uint8_t flc_pwr_thresh; 107 | uint8_t bb_scale_smrt_antenna; 108 | uint8_t futureModal[1]; 109 | struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; 110 | } __attribute__ ((packed)); 111 | 112 | struct cal_data_per_freq_4k { 113 | uint8_t pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; 114 | uint8_t vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; 115 | } __attribute__ ((packed)); 116 | 117 | struct cal_ctl_data_4k { 118 | struct cal_ctl_edges 119 | ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES]; 120 | } __attribute__ ((packed)); 121 | 122 | struct ar5416_eeprom_4k { 123 | struct base_eep_header_4k baseEepHeader; 124 | uint8_t custData[20]; 125 | struct modal_eep_4k_header modalHeader; 126 | uint8_t calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS]; 127 | struct cal_data_per_freq_4k 128 | calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS]; 129 | struct cal_target_power_leg 130 | calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS]; 131 | struct cal_target_power_leg 132 | calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS]; 133 | struct cal_target_power_ht 134 | calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS]; 135 | struct cal_target_power_ht 136 | calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS]; 137 | uint8_t ctlIndex[AR5416_EEP4K_NUM_CTLS]; 138 | struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS]; 139 | uint8_t padding; 140 | } __attribute__ ((packed)); 141 | 142 | #endif /* EEP_4K_H */ 143 | -------------------------------------------------------------------------------- /tools/edump/src/eep_9003.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef AR9003_EEPROM_H 18 | #define AR9003_EEPROM_H 19 | 20 | #include 21 | #include 22 | 23 | /* 16-bit offset location start of calibration struct */ 24 | #define AR9300_NUM_5G_CAL_PIERS 8 25 | #define AR9300_NUM_2G_CAL_PIERS 3 26 | #define AR9300_NUM_5G_20_TARGET_POWERS 8 27 | #define AR9300_NUM_5G_40_TARGET_POWERS 8 28 | #define AR9300_NUM_2G_CCK_TARGET_POWERS 2 29 | #define AR9300_NUM_2G_20_TARGET_POWERS 3 30 | #define AR9300_NUM_2G_40_TARGET_POWERS 3 31 | /* #define AR9300_NUM_CTLS 21 */ 32 | #define AR9300_NUM_CTLS_5G 9 33 | #define AR9300_NUM_CTLS_2G 12 34 | #define AR9300_NUM_BAND_EDGES_5G 8 35 | #define AR9300_NUM_BAND_EDGES_2G 4 36 | #define AR9300_CUSTOMER_DATA_SIZE 20 37 | 38 | #define AR9300_MAX_CHAINS 3 39 | 40 | #define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) 41 | 42 | /* Delta from which to start power to pdadc table */ 43 | /* This offset is used in both open loop and closed loop power control 44 | * schemes. In open loop power control, it is not really needed, but for 45 | * the "sake of consistency" it was kept. For certain AP designs, this 46 | * value is overwritten by the value in the flag "pwrTableOffset" just 47 | * before writing the pdadc vs pwr into the chip registers. 48 | */ 49 | #define AR9300_PWR_TABLE_OFFSET 0 50 | 51 | /* byte addressable */ 52 | #define AR9300_EEPROM_SIZE (16*1024) 53 | 54 | #define AR9300_BASE_ADDR_4K 0xfff 55 | #define AR9300_BASE_ADDR 0x3ff 56 | #define AR9300_BASE_ADDR_512 0x1ff 57 | 58 | #define AR9300_OTP_BASE 0x14000 59 | #define AR9300_OTP_STATUS 0x15f18 60 | #define AR9300_OTP_STATUS_TYPE 0x7 61 | #define AR9300_OTP_STATUS_VALID 0x4 62 | #define AR9300_OTP_STATUS_ACCESS_BUSY 0x2 63 | #define AR9300_OTP_STATUS_SM_BUSY 0x1 64 | #define AR9300_OTP_READ_DATA 0x15f1c 65 | 66 | struct eepFlags { 67 | uint8_t opFlags; 68 | uint8_t eepMisc; 69 | } __attribute__ ((packed)); 70 | 71 | enum CompressAlgorithm { 72 | _CompressNone = 0, 73 | _CompressLzma, 74 | _CompressPairs, 75 | _CompressBlock, 76 | _Compress4, 77 | _Compress5, 78 | _Compress6, 79 | _Compress7, 80 | }; 81 | 82 | struct ar9300_base_eep_hdr { 83 | int16_t regDmn[2]; 84 | /* 4 bits tx and 4 bits rx */ 85 | uint8_t txrxMask; 86 | struct eepFlags opCapFlags; 87 | uint8_t rfSilent; 88 | uint8_t blueToothOptions; 89 | uint8_t deviceCap; 90 | /* takes lower byte in eeprom location */ 91 | uint8_t deviceType; 92 | /* offset in dB to be added to beginning 93 | * of pdadc table in calibration 94 | */ 95 | int8_t pwrTableOffset; 96 | uint8_t params_for_tuning_caps[2]; 97 | /* 98 | * bit0 - enable tx temp comp 99 | * bit1 - enable tx volt comp 100 | * bit2 - enable fastClock - default to 1 101 | * bit3 - enable doubling - default to 1 102 | * bit4 - enable internal regulator - default to 1 103 | */ 104 | uint8_t featureEnable; 105 | /* misc flags: bit0 - turn down drivestrength */ 106 | uint8_t miscConfiguration; 107 | uint8_t eepromWriteEnableGpio; 108 | uint8_t wlanDisableGpio; 109 | uint8_t wlanLedGpio; 110 | uint8_t rxBandSelectGpio; 111 | uint8_t txrxgain; 112 | /* SW controlled internal regulator fields */ 113 | int32_t swreg; 114 | } __attribute__ ((packed)); 115 | 116 | struct ar9300_modal_eep_header { 117 | /* 4 idle, t1, t2, b (4 bits per setting) */ 118 | int32_t antCtrlCommon; 119 | /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ 120 | int32_t antCtrlCommon2; 121 | /* 6 idle, t, r, rx1, rx12, b (2 bits each) */ 122 | int16_t antCtrlChain[AR9300_MAX_CHAINS]; 123 | /* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ 124 | uint8_t xatten1DB[AR9300_MAX_CHAINS]; 125 | /* 3 xatten1_margin for merlin (0xa20c/b20c 16:12 */ 126 | uint8_t xatten1Margin[AR9300_MAX_CHAINS]; 127 | int8_t tempSlope; 128 | int8_t voltSlope; 129 | /* spur channels in usual fbin coding format */ 130 | uint8_t spurChans[AR_EEPROM_MODAL_SPURS]; 131 | /* 3 Check if the register is per chain */ 132 | int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS]; 133 | uint8_t reserved[11]; 134 | int8_t quick_drop; 135 | uint8_t xpaBiasLvl; 136 | uint8_t txFrameToDataStart; 137 | uint8_t txFrameToPaOn; 138 | uint8_t txClip; 139 | int8_t antennaGain; 140 | uint8_t switchSettling; 141 | int8_t adcDesiredSize; 142 | uint8_t txEndToXpaOff; 143 | uint8_t txEndToRxOn; 144 | uint8_t txFrameToXpaOn; 145 | uint8_t thresh62; 146 | int32_t papdRateMaskHt20; 147 | int32_t papdRateMaskHt40; 148 | int16_t switchcomspdt; 149 | uint8_t xlna_bias_strength; 150 | uint8_t futureModal[7]; 151 | } __attribute__ ((packed)); 152 | 153 | struct ar9300_cal_data_per_freq_op_loop { 154 | int8_t refPower; 155 | /* pdadc voltage at power measurement */ 156 | uint8_t voltMeas; 157 | /* pcdac used for power measurement */ 158 | uint8_t tempMeas; 159 | /* range is -60 to -127 create a mapping equation 1db resolution */ 160 | int8_t rxNoisefloorCal; 161 | /*range is same as noisefloor */ 162 | int8_t rxNoisefloorPower; 163 | /* temp measured when noisefloor cal was performed */ 164 | uint8_t rxTempMeas; 165 | } __attribute__ ((packed)); 166 | 167 | struct cal_tgt_pow_legacy { 168 | uint8_t tPow2x[4]; 169 | } __attribute__ ((packed)); 170 | 171 | struct cal_tgt_pow_ht { 172 | uint8_t tPow2x[14]; 173 | } __attribute__ ((packed)); 174 | 175 | struct cal_ctl_data_2g { 176 | uint8_t ctlEdges[AR9300_NUM_BAND_EDGES_2G]; 177 | } __attribute__ ((packed)); 178 | 179 | struct cal_ctl_data_5g { 180 | uint8_t ctlEdges[AR9300_NUM_BAND_EDGES_5G]; 181 | } __attribute__ ((packed)); 182 | 183 | struct ar9300_BaseExtension_1 { 184 | uint8_t ant_div_control; 185 | uint8_t future[3]; 186 | uint8_t tempslopextension[8]; 187 | int8_t quick_drop_low; 188 | int8_t quick_drop_high; 189 | } __attribute__ ((packed)); 190 | 191 | struct ar9300_BaseExtension_2 { 192 | int8_t tempSlopeLow; 193 | int8_t tempSlopeHigh; 194 | uint8_t xatten1DBLow[AR9300_MAX_CHAINS]; 195 | uint8_t xatten1MarginLow[AR9300_MAX_CHAINS]; 196 | uint8_t xatten1DBHigh[AR9300_MAX_CHAINS]; 197 | uint8_t xatten1MarginHigh[AR9300_MAX_CHAINS]; 198 | } __attribute__ ((packed)); 199 | 200 | struct ar9300_eeprom { 201 | uint8_t eepromVersion; 202 | uint8_t templateVersion; 203 | uint8_t macAddr[6]; 204 | uint8_t custData[AR9300_CUSTOMER_DATA_SIZE]; 205 | 206 | struct ar9300_base_eep_hdr baseEepHeader; 207 | 208 | struct ar9300_modal_eep_header modalHeader2G; 209 | struct ar9300_BaseExtension_1 base_ext1; 210 | uint8_t calFreqPier2G[AR9300_NUM_2G_CAL_PIERS]; 211 | struct ar9300_cal_data_per_freq_op_loop 212 | calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS]; 213 | uint8_t calTarget_freqbin_Cck[AR9300_NUM_2G_CCK_TARGET_POWERS]; 214 | uint8_t calTarget_freqbin_2G[AR9300_NUM_2G_20_TARGET_POWERS]; 215 | uint8_t calTarget_freqbin_2GHT20[AR9300_NUM_2G_20_TARGET_POWERS]; 216 | uint8_t calTarget_freqbin_2GHT40[AR9300_NUM_2G_40_TARGET_POWERS]; 217 | struct cal_tgt_pow_legacy 218 | calTargetPowerCck[AR9300_NUM_2G_CCK_TARGET_POWERS]; 219 | struct cal_tgt_pow_legacy 220 | calTargetPower2G[AR9300_NUM_2G_20_TARGET_POWERS]; 221 | struct cal_tgt_pow_ht 222 | calTargetPower2GHT20[AR9300_NUM_2G_20_TARGET_POWERS]; 223 | struct cal_tgt_pow_ht 224 | calTargetPower2GHT40[AR9300_NUM_2G_40_TARGET_POWERS]; 225 | uint8_t ctlIndex_2G[AR9300_NUM_CTLS_2G]; 226 | uint8_t ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G]; 227 | struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G]; 228 | struct ar9300_modal_eep_header modalHeader5G; 229 | struct ar9300_BaseExtension_2 base_ext2; 230 | uint8_t calFreqPier5G[AR9300_NUM_5G_CAL_PIERS]; 231 | struct ar9300_cal_data_per_freq_op_loop 232 | calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS]; 233 | uint8_t calTarget_freqbin_5G[AR9300_NUM_5G_20_TARGET_POWERS]; 234 | uint8_t calTarget_freqbin_5GHT20[AR9300_NUM_5G_20_TARGET_POWERS]; 235 | uint8_t calTarget_freqbin_5GHT40[AR9300_NUM_5G_40_TARGET_POWERS]; 236 | struct cal_tgt_pow_legacy 237 | calTargetPower5G[AR9300_NUM_5G_20_TARGET_POWERS]; 238 | struct cal_tgt_pow_ht 239 | calTargetPower5GHT20[AR9300_NUM_5G_20_TARGET_POWERS]; 240 | struct cal_tgt_pow_ht 241 | calTargetPower5GHT40[AR9300_NUM_5G_40_TARGET_POWERS]; 242 | uint8_t ctlIndex_5G[AR9300_NUM_CTLS_5G]; 243 | uint8_t ctl_freqbin_5G[AR9300_NUM_CTLS_5G][AR9300_NUM_BAND_EDGES_5G]; 244 | struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G]; 245 | } __attribute__ ((packed)); 246 | 247 | #endif 248 | -------------------------------------------------------------------------------- /tools/edump/src/eep_9287.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "edump.h" 18 | 19 | #define SIZE_EEPROM_AR9287 (sizeof(struct ar9287_eeprom) / sizeof(uint16_t)) 20 | 21 | static int get_eeprom_ver_9287(struct edump *edump) 22 | { 23 | return (edump->eeprom.map9287.baseEepHeader.version >> 12) & 0xF; 24 | } 25 | 26 | static int get_eeprom_rev_9287(struct edump *edump) 27 | { 28 | return (edump->eeprom.map9287.baseEepHeader.version) & 0xFFF; 29 | } 30 | 31 | static bool fill_eeprom_9287(struct edump *edump) 32 | { 33 | uint16_t *eep_data = (uint16_t *)&edump->eeprom.map9287; 34 | int addr, eep_start_loc = 0; 35 | 36 | eep_start_loc = AR9287_EEP_START_LOC; 37 | 38 | for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) { 39 | if (!pci_eeprom_read(edump, addr + eep_start_loc, eep_data)) { 40 | fprintf(stderr, "Unable to read eeprom region\n"); 41 | return false; 42 | } 43 | eep_data++; 44 | } 45 | 46 | return true; 47 | } 48 | 49 | static bool check_eeprom_9287(struct edump *edump) 50 | { 51 | struct ar9287_eeprom *eep = &edump->eeprom.map9287; 52 | uint16_t *eepdata, temp, magic, magic2; 53 | uint32_t sum = 0, el; 54 | bool need_swap = false; 55 | int i, addr; 56 | 57 | if (!pci_eeprom_read(edump, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { 58 | fprintf(stderr, "Reading Magic # failed\n"); 59 | return false; 60 | } 61 | 62 | if (magic != AR5416_EEPROM_MAGIC) { 63 | magic2 = bswap_16(magic); 64 | 65 | if (magic2 == AR5416_EEPROM_MAGIC) { 66 | need_swap = true; 67 | eepdata = (uint16_t *) (&edump->eeprom); 68 | 69 | for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) { 70 | temp = bswap_16(*eepdata); 71 | *eepdata = temp; 72 | eepdata++; 73 | } 74 | } else { 75 | fprintf(stderr, "Invalid EEPROM Magic, endianness mismatch.\n"); 76 | return false; 77 | } 78 | } 79 | 80 | if (need_swap) 81 | el = bswap_16(edump->eeprom.map9287.baseEepHeader.length); 82 | else 83 | el = edump->eeprom.map9287.baseEepHeader.length; 84 | 85 | if (el > sizeof(struct ar9287_eeprom)) 86 | el = sizeof(struct ar9287_eeprom) / sizeof(uint16_t); 87 | else 88 | el = el / sizeof(uint16_t); 89 | 90 | eepdata = (uint16_t *)(&edump->eeprom); 91 | 92 | for (i = 0; i < el; i++) 93 | sum ^= *eepdata++; 94 | 95 | if (need_swap) { 96 | uint32_t integer; 97 | uint16_t word; 98 | 99 | printf("EEPROM Endianness is not native.. Changing\n"); 100 | 101 | word = bswap_16(eep->baseEepHeader.length); 102 | eep->baseEepHeader.length = word; 103 | 104 | word = bswap_16(eep->baseEepHeader.checksum); 105 | eep->baseEepHeader.checksum = word; 106 | 107 | word = bswap_16(eep->baseEepHeader.version); 108 | eep->baseEepHeader.version = word; 109 | 110 | word = bswap_16(eep->baseEepHeader.regDmn[0]); 111 | eep->baseEepHeader.regDmn[0] = word; 112 | 113 | word = bswap_16(eep->baseEepHeader.regDmn[1]); 114 | eep->baseEepHeader.regDmn[1] = word; 115 | 116 | word = bswap_16(eep->baseEepHeader.rfSilent); 117 | eep->baseEepHeader.rfSilent = word; 118 | 119 | word = bswap_16(eep->baseEepHeader.blueToothOptions); 120 | eep->baseEepHeader.blueToothOptions = word; 121 | 122 | word = bswap_16(eep->baseEepHeader.deviceCap); 123 | eep->baseEepHeader.deviceCap = word; 124 | 125 | integer = bswap_32(eep->modalHeader.antCtrlCommon); 126 | eep->modalHeader.antCtrlCommon = integer; 127 | 128 | for (i = 0; i < AR9287_MAX_CHAINS; i++) { 129 | integer = bswap_32(eep->modalHeader.antCtrlChain[i]); 130 | eep->modalHeader.antCtrlChain[i] = integer; 131 | } 132 | 133 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 134 | word = bswap_16(eep->modalHeader.spurChans[i].spurChan); 135 | eep->modalHeader.spurChans[i].spurChan = word; 136 | } 137 | } 138 | 139 | if (sum != 0xffff || edump->eep_ops->get_eeprom_ver(edump) != AR9287_EEP_VER || 140 | edump->eep_ops->get_eeprom_rev(edump) < AR5416_EEP_NO_BACK_VER) { 141 | fprintf(stderr, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 142 | sum, edump->eep_ops->get_eeprom_ver(edump)); 143 | return false; 144 | } 145 | 146 | return true; 147 | } 148 | 149 | static void base_eeprom_9287(struct edump *edump) 150 | { 151 | struct ar9287_eeprom *eep = &edump->eeprom.map9287; 152 | struct base_eep_ar9287_header *pBase = &eep->baseEepHeader; 153 | uint16_t i; 154 | 155 | pBase = &(eep->baseEepHeader); 156 | 157 | printf("\n----------------------\n"); 158 | printf("| EEPROM Base Header |\n"); 159 | printf("----------------------\n\n"); 160 | 161 | printf("%-30s : %2d\n", "Major Version", 162 | pBase->version >> 12); 163 | printf("%-30s : %2d\n", "Minor Version", 164 | pBase->version & 0xFFF); 165 | printf("%-30s : 0x%04X\n", "Checksum", 166 | pBase->checksum); 167 | printf("%-30s : 0x%04X\n", "Length", 168 | pBase->length); 169 | printf("%-30s : 0x%04X\n", "RegDomain1", 170 | pBase->regDmn[0]); 171 | printf("%-30s : 0x%04X\n", "RegDomain2", 172 | pBase->regDmn[1]); 173 | printf("%-30s : %02X:%02X:%02X:%02X:%02X:%02X\n", 174 | "MacAddress", 175 | pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2], 176 | pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]); 177 | printf("%-30s : 0x%04X\n", 178 | "TX Mask", pBase->txMask); 179 | printf("%-30s : 0x%04X\n", 180 | "RX Mask", pBase->rxMask); 181 | printf("%-30s : %d\n", 182 | "OpFlags(5GHz)", 183 | !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); 184 | printf("%-30s : %d\n", 185 | "OpFlags(2GHz)", 186 | !!(pBase->opCapFlags & AR5416_OPFLAGS_11G)); 187 | printf("%-30s : %d\n", 188 | "OpFlags(Disable 2GHz HT20)", 189 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20)); 190 | printf("%-30s : %d\n", 191 | "OpFlags(Disable 2GHz HT40)", 192 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40)); 193 | printf("%-30s : %d\n", 194 | "OpFlags(Disable 5Ghz HT20)", 195 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20)); 196 | printf("%-30s : %d\n", 197 | "OpFlags(Disable 5Ghz HT40)", 198 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40)); 199 | printf("%-30s : %d\n", 200 | "Big Endian", 201 | !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN)); 202 | printf("%-30s : %d\n", 203 | "Wake on Wireless", 204 | !!(pBase->eepMisc & AR9287_EEPMISC_WOW)); 205 | printf("%-30s : %d\n", 206 | "Cal Bin Major Ver", 207 | (pBase->binBuildNumber >> 24) & 0xFF); 208 | printf("%-30s : %d\n", 209 | "Cal Bin Minor Ver", 210 | (pBase->binBuildNumber >> 16) & 0xFF); 211 | printf("%-30s : %d\n", 212 | "Cal Bin Build", 213 | (pBase->binBuildNumber >> 8) & 0xFF); 214 | printf("%-30s : %d\n", 215 | "OpenLoop PowerControl", 216 | (pBase->openLoopPwrCntl & 0x1)); 217 | 218 | if (edump->eep_ops->get_eeprom_rev(edump) >= AR5416_EEP_MINOR_VER_3) { 219 | printf("%-30s : %s\n", 220 | "Device Type", 221 | sDeviceType[(pBase->deviceType & 0x7)]); 222 | } 223 | 224 | printf("\nCustomer Data in hex:\n"); 225 | for (i = 0; i < 64; i++) { 226 | printf("%02X ", eep->custData[i]); 227 | if ((i % 16) == 15) 228 | printf("\n"); 229 | } 230 | } 231 | 232 | static void modal_eeprom_9287(struct edump *edump) 233 | { 234 | #define PR(_token, _p, _val_fmt, _val) \ 235 | do { \ 236 | printf("%-23s %-2s", (_token), ":"); \ 237 | printf("%s%"_val_fmt, _p, (_val)); \ 238 | printf("\n"); \ 239 | } while(0) 240 | 241 | struct ar9287_eeprom *eep = &edump->eeprom.map9287; 242 | struct modal_eep_ar9287_header *pModal = &eep->modalHeader; 243 | 244 | printf("\n\n-----------------------\n"); 245 | printf("| EEPROM Modal Header |\n"); 246 | printf("-----------------------\n\n"); 247 | 248 | PR("Chain0 Ant. Control", "0x", "X", pModal->antCtrlChain[0]); 249 | PR("Chain1 Ant. Control", "0x", "X", pModal->antCtrlChain[1]); 250 | PR("Ant. Common Control", "0x", "X", pModal->antCtrlCommon); 251 | PR("Chain0 Ant. Gain", "", "d", pModal->antennaGainCh[0]); 252 | PR("Chain1 Ant. Gain", "", "d", pModal->antennaGainCh[1]); 253 | PR("Switch Settle", "", "d", pModal->switchSettling); 254 | PR("Chain0 TxRxAtten", "", "d", pModal->txRxAttenCh[0]); 255 | PR("Chain1 TxRxAtten", "", "d", pModal->txRxAttenCh[1]); 256 | PR("Chain0 RxTxMargin", "", "d", pModal->rxTxMarginCh[0]); 257 | PR("Chain1 RxTxMargin", "", "d", pModal->rxTxMarginCh[1]); 258 | PR("ADC Desired size", "", "d", pModal->adcDesiredSize); 259 | PR("txEndToXpaOff", "", "d", pModal->txEndToXpaOff); 260 | PR("txEndToRxOn", "", "d", pModal->txEndToRxOn); 261 | PR("txFrameToXpaOn", "", "d", pModal->txFrameToXpaOn); 262 | PR("CCA Threshold)", "", "d", pModal->thresh62); 263 | PR("Chain0 NF Threshold", "", "d", pModal->noiseFloorThreshCh[0]); 264 | PR("Chain1 NF Threshold", "", "d", pModal->noiseFloorThreshCh[1]); 265 | PR("xpdGain", "", "d", pModal->xpdGain); 266 | PR("External PD", "", "d", pModal->xpd); 267 | PR("Chain0 I Coefficient", "", "d", pModal->iqCalICh[0]); 268 | PR("Chain1 I Coefficient", "", "d", pModal->iqCalICh[1]); 269 | PR("Chain0 Q Coefficient", "", "d", pModal->iqCalQCh[0]); 270 | PR("Chain1 Q Coefficient", "", "d", pModal->iqCalQCh[1]); 271 | PR("pdGainOverlap", "", "d", pModal->pdGainOverlap); 272 | PR("xPA Bias Level", "", "d", pModal->xpaBiasLvl); 273 | PR("txFrameToDataStart", "", "d", pModal->txFrameToDataStart); 274 | PR("txFrameToPaOn", "", "d", pModal->txFrameToPaOn); 275 | PR("HT40 Power Inc.", "", "d", pModal->ht40PowerIncForPdadc); 276 | PR("Chain0 bswAtten", "", "d", pModal->bswAtten[0]); 277 | PR("Chain1 bswAtten", "", "d", pModal->bswAtten[1]); 278 | PR("Chain0 bswMargin", "", "d", pModal->bswMargin[0]); 279 | PR("Chain1 bswMargin", "", "d", pModal->bswMargin[1]); 280 | PR("HT40 Switch Settle", "", "d", pModal->swSettleHt40); 281 | PR("AR92x7 Version", "", "d", pModal->version); 282 | PR("DriverBias1", "", "d", pModal->db1); 283 | PR("DriverBias2", "", "d", pModal->db1); 284 | PR("CCK OutputBias", "", "d", pModal->ob_cck); 285 | PR("PSK OutputBias", "", "d", pModal->ob_psk); 286 | PR("QAM OutputBias", "", "d", pModal->ob_qam); 287 | PR("PAL_OFF OutputBias", "", "d", pModal->ob_pal_off); 288 | 289 | } 290 | 291 | static void power_info_eeprom_9287(struct edump *edump) 292 | { 293 | } 294 | 295 | struct eeprom_ops eep_9287_ops = { 296 | .fill_eeprom = fill_eeprom_9287, 297 | .check_eeprom = check_eeprom_9287, 298 | .get_eeprom_ver = get_eeprom_ver_9287, 299 | .get_eeprom_rev = get_eeprom_rev_9287, 300 | .dump_base_header = base_eeprom_9287, 301 | .dump_modal_header = modal_eeprom_9287, 302 | .dump_power_info = power_info_eeprom_9287, 303 | }; 304 | -------------------------------------------------------------------------------- /tools/edump/src/eep_9287.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef EEP_9287_H 18 | #define EEP_9287_H 19 | 20 | #define AR9287_EEP_VER 0xE 21 | #define AR9287_EEP_START_LOC 128 22 | #define AR9287_DATA_SZ 32 23 | #define AR9287_MAX_CHAINS 2 24 | #define AR9287_NUM_2G_CAL_PIERS 3 25 | #define AR9287_NUM_2G_CCK_TARGET_POWERS 3 26 | #define AR9287_NUM_2G_20_TARGET_POWERS 3 27 | #define AR9287_NUM_2G_40_TARGET_POWERS 3 28 | #define AR9287_NUM_CTLS 12 29 | #define AR9287_NUM_BAND_EDGES 4 30 | #define AR9287_PD_GAIN_ICEPTS 1 31 | #define AR9287_EEPMISC_WOW 0x02 32 | 33 | struct base_eep_ar9287_header { 34 | uint16_t length; 35 | uint16_t checksum; 36 | uint16_t version; 37 | uint8_t opCapFlags; 38 | uint8_t eepMisc; 39 | uint16_t regDmn[2]; 40 | uint8_t macAddr[6]; 41 | uint8_t rxMask; 42 | uint8_t txMask; 43 | uint16_t rfSilent; 44 | uint16_t blueToothOptions; 45 | uint16_t deviceCap; 46 | uint32_t binBuildNumber; 47 | uint8_t deviceType; 48 | uint8_t openLoopPwrCntl; 49 | int8_t pwrTableOffset; 50 | int8_t tempSensSlope; 51 | int8_t tempSensSlopePalOn; 52 | uint8_t futureBase[29]; 53 | } __attribute__ ((packed)); 54 | 55 | struct modal_eep_ar9287_header { 56 | uint32_t antCtrlChain[AR9287_MAX_CHAINS]; 57 | uint32_t antCtrlCommon; 58 | int8_t antennaGainCh[AR9287_MAX_CHAINS]; 59 | uint8_t switchSettling; 60 | uint8_t txRxAttenCh[AR9287_MAX_CHAINS]; 61 | uint8_t rxTxMarginCh[AR9287_MAX_CHAINS]; 62 | int8_t adcDesiredSize; 63 | uint8_t txEndToXpaOff; 64 | uint8_t txEndToRxOn; 65 | uint8_t txFrameToXpaOn; 66 | uint8_t thresh62; 67 | int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS]; 68 | uint8_t xpdGain; 69 | uint8_t xpd; 70 | int8_t iqCalICh[AR9287_MAX_CHAINS]; 71 | int8_t iqCalQCh[AR9287_MAX_CHAINS]; 72 | uint8_t pdGainOverlap; 73 | uint8_t xpaBiasLvl; 74 | uint8_t txFrameToDataStart; 75 | uint8_t txFrameToPaOn; 76 | uint8_t ht40PowerIncForPdadc; 77 | uint8_t bswAtten[AR9287_MAX_CHAINS]; 78 | uint8_t bswMargin[AR9287_MAX_CHAINS]; 79 | uint8_t swSettleHt40; 80 | uint8_t version; 81 | uint8_t db1; 82 | uint8_t db2; 83 | uint8_t ob_cck; 84 | uint8_t ob_psk; 85 | uint8_t ob_qam; 86 | uint8_t ob_pal_off; 87 | uint8_t futureModal[30]; 88 | struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; 89 | } __attribute__ ((packed)); 90 | 91 | struct cal_data_op_loop_ar9287 { 92 | uint8_t pwrPdg[2][5]; 93 | uint8_t vpdPdg[2][5]; 94 | uint8_t pcdac[2][5]; 95 | uint8_t empty[2][5]; 96 | } __attribute__ ((packed)); 97 | 98 | struct cal_data_per_freq_ar9287 { 99 | uint8_t pwrPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; 100 | uint8_t vpdPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; 101 | } __attribute__ ((packed)); 102 | 103 | union cal_data_per_freq_ar9287_u { 104 | struct cal_data_op_loop_ar9287 calDataOpen; 105 | struct cal_data_per_freq_ar9287 calDataClose; 106 | } __attribute__ ((packed)); 107 | 108 | struct cal_ctl_data_ar9287 { 109 | struct cal_ctl_edges 110 | ctlEdges[AR9287_MAX_CHAINS][AR9287_NUM_BAND_EDGES]; 111 | } __attribute__ ((packed)); 112 | 113 | struct ar9287_eeprom { 114 | struct base_eep_ar9287_header baseEepHeader; 115 | uint8_t custData[AR9287_DATA_SZ]; 116 | struct modal_eep_ar9287_header modalHeader; 117 | uint8_t calFreqPier2G[AR9287_NUM_2G_CAL_PIERS]; 118 | union cal_data_per_freq_ar9287_u 119 | calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS]; 120 | struct cal_target_power_leg 121 | calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS]; 122 | struct cal_target_power_leg 123 | calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS]; 124 | struct cal_target_power_ht 125 | calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS]; 126 | struct cal_target_power_ht 127 | calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS]; 128 | uint8_t ctlIndex[AR9287_NUM_CTLS]; 129 | struct cal_ctl_data_ar9287 ctlData[AR9287_NUM_CTLS]; 130 | uint8_t padding; 131 | } __attribute__ ((packed)); 132 | 133 | #endif /* EEP_9287_H */ 134 | -------------------------------------------------------------------------------- /tools/edump/src/eep_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef EEP_COMMON_H 18 | #define EEP_COMMON_H 19 | 20 | #if __BYTE_ORDER == __BIG_ENDIAN 21 | #define AR5416_EEPROM_MAGIC 0x5aa5 22 | #else 23 | #define AR5416_EEPROM_MAGIC 0xa55a 24 | #endif 25 | 26 | #define AR5416_EEPROM_MAGIC_OFFSET 0x0 27 | #define AR5416_EEP_NO_BACK_VER 0x1 28 | #define AR5416_EEP_VER 0xE 29 | 30 | #define AR5416_EEPROM_S 2 31 | #define AR5416_EEPROM_OFFSET 0x2000 32 | 33 | #define AR_EEPROM_STATUS_DATA (AR_SREV_9340(edump) ? 0x40c8 : \ 34 | (AR_SREV_9300_20_OR_LATER(edump) ? \ 35 | 0x4084 : 0x407c)) 36 | #define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff 37 | #define AR_EEPROM_STATUS_DATA_VAL_S 0 38 | #define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 39 | #define AR_EEPROM_STATUS_DATA_BUSY_ACCESS 0x00020000 40 | #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 41 | #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 42 | 43 | #define AR5416_OPFLAGS_11A 0x01 44 | #define AR5416_OPFLAGS_11G 0x02 45 | #define AR5416_OPFLAGS_N_5G_HT40 0x04 46 | #define AR5416_OPFLAGS_N_2G_HT40 0x08 47 | #define AR5416_OPFLAGS_N_5G_HT20 0x10 48 | #define AR5416_OPFLAGS_N_2G_HT20 0x20 49 | 50 | #define AR5416_EEPMISC_BIG_ENDIAN 0x01 51 | #define AR5416_EEP_MINOR_VER_3 0x3 52 | 53 | #define AR_EEPROM_MODAL_SPURS 5 54 | #define AR5416_PD_GAIN_ICEPTS 5 55 | 56 | static char *sDeviceType[] = { 57 | "UNKNOWN [0] ", 58 | "Cardbus ", 59 | "PCI ", 60 | "MiniPCI ", 61 | "Access Point", 62 | "PCIExpress ", 63 | "UNKNOWN [6] ", 64 | "UNKNOWN [7] ", 65 | }; 66 | 67 | enum eep_map { 68 | EEP_MAP_DEFAULT = 0x0, 69 | EEP_MAP_4K, 70 | EEP_MAP_9287, 71 | EEP_MAP_9003, 72 | EEP_MAP_MAX 73 | }; 74 | 75 | struct cal_ctl_edges { 76 | uint8_t bChannel; 77 | uint8_t ctl; 78 | } __attribute__ ((packed)); 79 | 80 | struct cal_target_power_leg { 81 | uint8_t bChannel; 82 | uint8_t tPow2x[4]; 83 | } __attribute__ ((packed)); 84 | 85 | struct cal_target_power_ht { 86 | uint8_t bChannel; 87 | uint8_t tPow2x[8]; 88 | } __attribute__ ((packed)); 89 | 90 | #endif /* EEP_COMMON_H */ 91 | -------------------------------------------------------------------------------- /tools/edump/src/eep_def.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "edump.h" 18 | 19 | static int get_eeprom_ver_def(struct edump *edump) 20 | { 21 | return ((edump->eeprom.def.baseEepHeader.version >> 12) & 0xF); 22 | } 23 | 24 | static int get_eeprom_rev_def(struct edump *edump) 25 | { 26 | return ((edump->eeprom.def.baseEepHeader.version) & 0xFFF); 27 | } 28 | 29 | static bool fill_eeprom_def(struct edump *edump) 30 | { 31 | #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(uint16_t)) 32 | 33 | uint16_t *eep_data = (uint16_t *)&edump->eeprom.def; 34 | int addr, ar5416_eep_start_loc = 0x100; 35 | 36 | for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) { 37 | if (!pci_eeprom_read(edump, addr + ar5416_eep_start_loc, 38 | eep_data)) { 39 | fprintf(stderr, "Unable to read eeprom region\n"); 40 | return false; 41 | } 42 | eep_data++; 43 | } 44 | return true; 45 | 46 | #undef SIZE_EEPROM_DEF 47 | } 48 | 49 | static bool check_eeprom_def(struct edump *edump) 50 | { 51 | struct ar5416_eeprom_def *eep = (struct ar5416_eeprom_def *)&edump->eeprom.def; 52 | uint16_t *eepdata, temp, magic, magic2; 53 | uint32_t sum = 0, el; 54 | bool need_swap = false; 55 | int i, addr, size; 56 | 57 | if (!pci_eeprom_read(edump, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { 58 | fprintf(stderr, "Reading Magic # failed\n"); 59 | return false; 60 | } 61 | 62 | if (magic != AR5416_EEPROM_MAGIC) { 63 | printf("Read Magic = 0x%04X\n", magic); 64 | 65 | magic2 = bswap_16(magic); 66 | 67 | if (magic2 == AR5416_EEPROM_MAGIC) { 68 | size = sizeof(struct ar5416_eeprom_def); 69 | need_swap = true; 70 | eepdata = (uint16_t *) (&edump->eeprom); 71 | 72 | for (addr = 0; addr < size / sizeof(uint16_t); addr++) { 73 | temp = bswap_16(*eepdata); 74 | *eepdata = temp; 75 | eepdata++; 76 | } 77 | } else { 78 | fprintf(stderr, "Invalid EEPROM Magic, endianness mismatch\n"); 79 | return false; 80 | } 81 | } 82 | 83 | if (need_swap) 84 | el = bswap_16(edump->eeprom.def.baseEepHeader.length); 85 | else 86 | el = edump->eeprom.def.baseEepHeader.length; 87 | 88 | if (el > sizeof(struct ar5416_eeprom_def)) 89 | el = sizeof(struct ar5416_eeprom_def) / sizeof(uint16_t); 90 | else 91 | el = el / sizeof(uint16_t); 92 | 93 | eepdata = (uint16_t *)(&edump->eeprom); 94 | 95 | for (i = 0; i < el; i++) 96 | sum ^= *eepdata++; 97 | 98 | if (need_swap) { 99 | uint32_t integer, j; 100 | uint16_t word; 101 | 102 | printf("EEPROM Endianness is not native.. Changing.\n"); 103 | 104 | word = bswap_16(eep->baseEepHeader.length); 105 | eep->baseEepHeader.length = word; 106 | 107 | word = bswap_16(eep->baseEepHeader.checksum); 108 | eep->baseEepHeader.checksum = word; 109 | 110 | word = bswap_16(eep->baseEepHeader.version); 111 | eep->baseEepHeader.version = word; 112 | 113 | word = bswap_16(eep->baseEepHeader.regDmn[0]); 114 | eep->baseEepHeader.regDmn[0] = word; 115 | 116 | word = bswap_16(eep->baseEepHeader.regDmn[1]); 117 | eep->baseEepHeader.regDmn[1] = word; 118 | 119 | word = bswap_16(eep->baseEepHeader.rfSilent); 120 | eep->baseEepHeader.rfSilent = word; 121 | 122 | word = bswap_16(eep->baseEepHeader.blueToothOptions); 123 | eep->baseEepHeader.blueToothOptions = word; 124 | 125 | word = bswap_16(eep->baseEepHeader.deviceCap); 126 | eep->baseEepHeader.deviceCap = word; 127 | 128 | for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) { 129 | struct modal_eep_header *pModal = &eep->modalHeader[j]; 130 | 131 | integer = bswap_32(pModal->antCtrlCommon); 132 | pModal->antCtrlCommon = integer; 133 | 134 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { 135 | integer = bswap_32(pModal->antCtrlChain[i]); 136 | pModal->antCtrlChain[i] = integer; 137 | } 138 | 139 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 140 | word = bswap_16(pModal->spurChans[i].spurChan); 141 | pModal->spurChans[i].spurChan = word; 142 | } 143 | } 144 | } 145 | 146 | if (sum != 0xffff || edump->eep_ops->get_eeprom_ver(edump) != AR5416_EEP_VER || 147 | edump->eep_ops->get_eeprom_rev(edump) < AR5416_EEP_NO_BACK_VER) { 148 | fprintf(stderr, "Bad EEPROM checksum 0x%x or revision 0x%04x\n", 149 | sum, edump->eep_ops->get_eeprom_ver(edump)); 150 | return false; 151 | } 152 | 153 | return true; 154 | } 155 | 156 | static void base_eeprom_def(struct edump *edump) 157 | { 158 | struct ar5416_eeprom_def *ar5416Eep = &edump->eeprom.def; 159 | struct base_eep_header *pBase = &ar5416Eep->baseEepHeader; 160 | uint16_t i; 161 | 162 | pBase = &(ar5416Eep->baseEepHeader); 163 | 164 | printf("\n----------------------\n"); 165 | printf("| EEPROM Base Header |\n"); 166 | printf("----------------------\n\n"); 167 | 168 | printf("%-30s : %2d\n", "Major Version", 169 | pBase->version >> 12); 170 | printf("%-30s : %2d\n", "Minor Version", 171 | pBase->version & 0xFFF); 172 | printf("%-30s : 0x%04X\n", "Checksum", 173 | pBase->checksum); 174 | printf("%-30s : 0x%04X\n", "Length", 175 | pBase->length); 176 | printf("%-30s : 0x%04X\n", "RegDomain1", 177 | pBase->regDmn[0]); 178 | printf("%-30s : 0x%04X\n", "RegDomain2", 179 | pBase->regDmn[1]); 180 | printf("%-30s : %02X:%02X:%02X:%02X:%02X:%02X\n", 181 | "MacAddress", 182 | pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2], 183 | pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]); 184 | printf("%-30s : 0x%04X\n", 185 | "TX Mask", pBase->txMask); 186 | printf("%-30s : 0x%04X\n", 187 | "RX Mask", pBase->rxMask); 188 | printf("%-30s : %d\n", 189 | "OpFlags(5GHz)", 190 | !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); 191 | printf("%-30s : %d\n", 192 | "OpFlags(2GHz)", 193 | !!(pBase->opCapFlags & AR5416_OPFLAGS_11G)); 194 | printf("%-30s : %d\n", 195 | "OpFlags(Disable 2GHz HT20)", 196 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20)); 197 | printf("%-30s : %d\n", 198 | "OpFlags(Disable 2GHz HT40)", 199 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40)); 200 | printf("%-30s : %d\n", 201 | "OpFlags(Disable 5Ghz HT20)", 202 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20)); 203 | printf("%-30s : %d\n", 204 | "OpFlags(Disable 5Ghz HT40)", 205 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40)); 206 | printf("%-30s : %d\n", 207 | "Big Endian", 208 | !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN)); 209 | printf("%-30s : %d\n", 210 | "Cal Bin Major Ver", 211 | (pBase->binBuildNumber >> 24) & 0xFF); 212 | printf("%-30s : %d\n", 213 | "Cal Bin Minor Ver", 214 | (pBase->binBuildNumber >> 16) & 0xFF); 215 | printf("%-30s : %d\n", 216 | "Cal Bin Build", 217 | (pBase->binBuildNumber >> 8) & 0xFF); 218 | 219 | if (edump->eep_ops->get_eeprom_rev(edump) >= AR5416_EEP_MINOR_VER_3) { 220 | printf("%-30s : %s\n", 221 | "Device Type", 222 | sDeviceType[(pBase->deviceType & 0x7)]); 223 | } 224 | 225 | printf("\nCustomer Data in hex:\n"); 226 | for (i = 0; i < 64; i++) { 227 | printf("%02X ", ar5416Eep->custData[i]); 228 | if ((i % 16) == 15) 229 | printf("\n"); 230 | } 231 | } 232 | 233 | static void modal_eeprom_def(struct edump *edump) 234 | { 235 | #define PR(_token, _p, _val_fmt, _val) \ 236 | do { \ 237 | printf("%-23s %-8s", (_token), ":"); \ 238 | if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { \ 239 | pModal = &(ar5416Eep->modalHeader[1]); \ 240 | printf("%s%-6"_val_fmt, _p, (_val)); \ 241 | } \ 242 | if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { \ 243 | pModal = &(ar5416Eep->modalHeader[0]); \ 244 | printf("%8s%"_val_fmt"\n", _p, (_val)); \ 245 | } else { \ 246 | printf("\n"); \ 247 | } \ 248 | } while(0) 249 | 250 | struct ar5416_eeprom_def *ar5416Eep = &edump->eeprom.def; 251 | struct base_eep_header *pBase = &ar5416Eep->baseEepHeader; 252 | struct modal_eep_header *pModal = NULL; 253 | 254 | pBase = &(ar5416Eep->baseEepHeader); 255 | 256 | printf("\n\n-----------------------\n"); 257 | printf("| EEPROM Modal Header |\n"); 258 | printf("-----------------------\n\n"); 259 | 260 | if (pBase->opCapFlags & AR5416_OPFLAGS_11G) 261 | printf("%34s", "2G"); 262 | if (pBase->opCapFlags & AR5416_OPFLAGS_11A) 263 | printf("%16s", "5G\n\n"); 264 | else 265 | printf("\n\n"); 266 | 267 | PR("Ant Chain 0", "0x", "X", pModal->antCtrlChain[0]); 268 | PR("Ant Chain 1", "0x", "X", pModal->antCtrlChain[1]); 269 | PR("Ant Chain 2", "0x", "X", pModal->antCtrlChain[2]); 270 | PR("Antenna Common", "0x", "X", pModal->antCtrlCommon); 271 | PR("Antenna Gain Chain 0", "", "d", pModal->antennaGainCh[0]); 272 | PR("Antenna Gain Chain 1", "", "d", pModal->antennaGainCh[1]); 273 | PR("Antenna Gain Chain 2", "", "d", pModal->antennaGainCh[2]); 274 | PR("Switch Settling", "", "d", pModal->switchSettling); 275 | PR("TxRxAttenuation Ch 0", "", "d", pModal->txRxAttenCh[0]); 276 | PR("TxRxAttenuation Ch 1", "", "d", pModal->txRxAttenCh[1]); 277 | PR("TxRxAttenuation Ch 2", "", "d", pModal->txRxAttenCh[2]); 278 | PR("RxTxMargin Chain 0", "", "d", pModal->rxTxMarginCh[0]); 279 | PR("RxTxMargin Chain 1", "", "d", pModal->rxTxMarginCh[1]); 280 | PR("RxTxMargin Chain 2", "", "d", pModal->rxTxMarginCh[2]); 281 | PR("ADC Desired Size", "", "d", pModal->adcDesiredSize); 282 | PR("PGA Desired Size", "", "d", pModal->pgaDesiredSize); 283 | PR("TX end to xlna on", "", "d", pModal->txEndToRxOn); 284 | PR("xlna gain Chain 0", "", "d", pModal->xlnaGainCh[0]); 285 | PR("xlna gain Chain 1", "", "d", pModal->xlnaGainCh[1]); 286 | PR("xlna gain Chain 2", "", "d", pModal->xlnaGainCh[2]); 287 | PR("TX end to xpa off", "", "d", pModal->txEndToXpaOff); 288 | PR("TX frame to xpa on", "", "d", pModal->txFrameToXpaOn); 289 | PR("THRESH62", "", "d", pModal->thresh62); 290 | PR("NF Thresh 0", "", "d", pModal->noiseFloorThreshCh[0]); 291 | PR("NF Thresh 1", "", "d", pModal->noiseFloorThreshCh[1]); 292 | PR("NF Thresh 2", "", "d", pModal->noiseFloorThreshCh[2]); 293 | PR("Xpd Gain Mask", "0x", "X", pModal->xpdGain); 294 | PR("Xpd", "", "d", pModal->xpd); 295 | PR("IQ Cal I Chain 0", "", "d", pModal->iqCalICh[0]); 296 | PR("IQ Cal I Chain 1", "", "d", pModal->iqCalICh[1]); 297 | PR("IQ Cal I Chain 2", "", "d", pModal->iqCalICh[2]); 298 | PR("IQ Cal Q Chain 0", "", "d", pModal->iqCalQCh[0]); 299 | PR("IQ Cal Q Chain 1", "", "d", pModal->iqCalQCh[1]); 300 | PR("IQ Cal Q Chain 2", "", "d", pModal->iqCalQCh[2]); 301 | PR("Analog Output Bias(ob)", "", "d", pModal->ob); 302 | PR("Analog Driver Bias(db)", "", "d", pModal->db); 303 | PR("Xpa bias level", "", "d", pModal->xpaBiasLvl); 304 | PR("Xpa bias level Freq 0", "", "d", pModal->xpaBiasLvlFreq[0]); 305 | PR("Xpa bias level Freq 1", "", "d", pModal->xpaBiasLvlFreq[1]); 306 | PR("Xpa bias level Freq 2", "", "d", pModal->xpaBiasLvlFreq[2]); 307 | PR("LNA Control", "0x", "X", pModal->lna_ctl); 308 | 309 | printf("%-23s %-7s", "pdGain Overlap (dB)", ":"); 310 | if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { 311 | pModal = &(ar5416Eep->modalHeader[1]); 312 | printf("%2d.%-6d", pModal->pdGainOverlap / 2, 313 | (pModal->pdGainOverlap % 2) * 5); 314 | } 315 | if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { 316 | pModal = &(ar5416Eep->modalHeader[0]); 317 | printf("%7d.%d\n", pModal->pdGainOverlap / 2, 318 | (pModal->pdGainOverlap % 2) * 5); 319 | } else { 320 | printf("\n"); 321 | } 322 | 323 | printf("%-23s %-7s", "PWR dec 2 chain", ":"); 324 | if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { 325 | pModal = &(ar5416Eep->modalHeader[1]); 326 | printf("%2d.%-6d", pModal->pwrDecreaseFor2Chain / 2, 327 | (pModal->pwrDecreaseFor2Chain % 2) * 5); 328 | } 329 | if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { 330 | pModal = &(ar5416Eep->modalHeader[0]); 331 | printf("%7d.%d\n", pModal->pwrDecreaseFor2Chain / 2, 332 | (pModal->pwrDecreaseFor2Chain % 2) * 5); 333 | } else { 334 | printf("\n"); 335 | } 336 | 337 | printf("%-23s %-7s", "PWR dec 3 chain", ":"); 338 | if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { 339 | pModal = &(ar5416Eep->modalHeader[1]); 340 | printf("%2d.%-6d", pModal->pwrDecreaseFor3Chain / 2, 341 | (pModal->pwrDecreaseFor3Chain % 2) * 5); 342 | } 343 | if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { 344 | pModal = &(ar5416Eep->modalHeader[0]); 345 | printf("%7d.%d\n", pModal->pwrDecreaseFor3Chain / 2, 346 | (pModal->pwrDecreaseFor3Chain % 2) * 5); 347 | } else { 348 | printf("\n"); 349 | } 350 | 351 | if (AR_SREV_9280_20_OR_LATER(edump)) { 352 | PR("xatten2Db Chain 0", "", "d", pModal->xatten2Db[0]); 353 | PR("xatten2Db Chain 1", "", "d", pModal->xatten2Db[1]); 354 | PR("xatten2Margin Chain 0", "", "d", pModal->xatten2Margin[0]); 355 | PR("xatten2Margin Chain 1", "", "d", pModal->xatten2Margin[1]); 356 | PR("ob_ch1", "", "d", pModal->ob_ch1); 357 | PR("db_ch1", "", "d", pModal->db_ch1); 358 | } 359 | 360 | if (edump->eep_ops->get_eeprom_rev(edump) >= AR5416_EEP_MINOR_VER_3) { 361 | PR("txFrameToDataStart", "", "d", pModal->txFrameToDataStart); 362 | PR("txFrameToPaOn", "", "d", pModal->txFrameToPaOn); 363 | PR("HT40PowerIncForPDADC", "", "d", pModal->ht40PowerIncForPdadc); 364 | PR("bswAtten Chain 0", "", "d", pModal->bswAtten[0]); 365 | } 366 | 367 | #undef PR 368 | } 369 | 370 | static void power_info_eeprom_def(struct edump *edump) 371 | { 372 | } 373 | 374 | struct eeprom_ops eep_def_ops = { 375 | .fill_eeprom = fill_eeprom_def, 376 | .check_eeprom = check_eeprom_def, 377 | .get_eeprom_ver = get_eeprom_ver_def, 378 | .get_eeprom_rev = get_eeprom_rev_def, 379 | .dump_base_header = base_eeprom_def, 380 | .dump_modal_header = modal_eeprom_def, 381 | .dump_power_info = power_info_eeprom_def, 382 | }; 383 | -------------------------------------------------------------------------------- /tools/edump/src/eep_def.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef EEP_DEF_H 18 | #define EEP_DEF_H 19 | 20 | #define AR5416_MAX_CHAINS 3 21 | #define AR5416_NUM_PD_GAINS 4 22 | #define AR5416_NUM_BAND_EDGES 8 23 | #define AR5416_NUM_5G_CAL_PIERS 8 24 | #define AR5416_NUM_2G_CAL_PIERS 4 25 | #define AR5416_NUM_CTLS 24 26 | #define AR5416_NUM_5G_20_TARGET_POWERS 8 27 | #define AR5416_NUM_5G_40_TARGET_POWERS 8 28 | #define AR5416_NUM_2G_CCK_TARGET_POWERS 3 29 | #define AR5416_NUM_2G_20_TARGET_POWERS 4 30 | #define AR5416_NUM_2G_40_TARGET_POWERS 4 31 | 32 | struct base_eep_header { 33 | uint16_t length; 34 | uint16_t checksum; 35 | uint16_t version; 36 | uint8_t opCapFlags; 37 | uint8_t eepMisc; 38 | uint16_t regDmn[2]; 39 | uint8_t macAddr[6]; 40 | uint8_t rxMask; 41 | uint8_t txMask; 42 | uint16_t rfSilent; 43 | uint16_t blueToothOptions; 44 | uint16_t deviceCap; 45 | uint32_t binBuildNumber; 46 | uint8_t deviceType; 47 | uint8_t pwdclkind; 48 | uint8_t futureBase_1[2]; 49 | uint8_t rxGainType; 50 | uint8_t dacHiPwrMode_5G; 51 | uint8_t openLoopPwrCntl; 52 | uint8_t dacLpMode; 53 | uint8_t txGainType; 54 | uint8_t rcChainMask; 55 | uint8_t desiredScaleCCK; 56 | uint8_t power_table_offset; 57 | uint8_t frac_n_5g; 58 | uint8_t futureBase_3[21]; 59 | } __attribute__ ((packed)); 60 | 61 | struct spur_chan { 62 | uint16_t spurChan; 63 | uint8_t spurRangeLow; 64 | uint8_t spurRangeHigh; 65 | } __attribute__ ((packed)); 66 | 67 | struct modal_eep_header { 68 | uint32_t antCtrlChain[AR5416_MAX_CHAINS]; 69 | uint32_t antCtrlCommon; 70 | uint8_t antennaGainCh[AR5416_MAX_CHAINS]; 71 | uint8_t switchSettling; 72 | uint8_t txRxAttenCh[AR5416_MAX_CHAINS]; 73 | uint8_t rxTxMarginCh[AR5416_MAX_CHAINS]; 74 | uint8_t adcDesiredSize; 75 | uint8_t pgaDesiredSize; 76 | uint8_t xlnaGainCh[AR5416_MAX_CHAINS]; 77 | uint8_t txEndToXpaOff; 78 | uint8_t txEndToRxOn; 79 | uint8_t txFrameToXpaOn; 80 | uint8_t thresh62; 81 | uint8_t noiseFloorThreshCh[AR5416_MAX_CHAINS]; 82 | uint8_t xpdGain; 83 | uint8_t xpd; 84 | uint8_t iqCalICh[AR5416_MAX_CHAINS]; 85 | uint8_t iqCalQCh[AR5416_MAX_CHAINS]; 86 | uint8_t pdGainOverlap; 87 | uint8_t ob; 88 | uint8_t db; 89 | uint8_t xpaBiasLvl; 90 | uint8_t pwrDecreaseFor2Chain; 91 | uint8_t pwrDecreaseFor3Chain; 92 | uint8_t txFrameToDataStart; 93 | uint8_t txFrameToPaOn; 94 | uint8_t ht40PowerIncForPdadc; 95 | uint8_t bswAtten[AR5416_MAX_CHAINS]; 96 | uint8_t bswMargin[AR5416_MAX_CHAINS]; 97 | uint8_t swSettleHt40; 98 | uint8_t xatten2Db[AR5416_MAX_CHAINS]; 99 | uint8_t xatten2Margin[AR5416_MAX_CHAINS]; 100 | uint8_t ob_ch1; 101 | uint8_t db_ch1; 102 | uint8_t lna_ctl; 103 | uint8_t miscBits; 104 | uint16_t xpaBiasLvlFreq[3]; 105 | uint8_t futureModal[6]; 106 | struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; 107 | } __attribute__ ((packed)); 108 | 109 | struct cal_data_per_freq { 110 | uint8_t pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; 111 | uint8_t vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; 112 | } __attribute__ ((packed)); 113 | 114 | struct cal_ctl_data { 115 | struct cal_ctl_edges 116 | ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; 117 | } __attribute__ ((packed)); 118 | 119 | struct ar5416_eeprom_def { 120 | struct base_eep_header baseEepHeader; 121 | uint8_t custData[64]; 122 | struct modal_eep_header modalHeader[2]; 123 | uint8_t calFreqPier5G[AR5416_NUM_5G_CAL_PIERS]; 124 | uint8_t calFreqPier2G[AR5416_NUM_2G_CAL_PIERS]; 125 | struct cal_data_per_freq 126 | calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS]; 127 | struct cal_data_per_freq 128 | calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; 129 | struct cal_target_power_leg 130 | calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS]; 131 | struct cal_target_power_ht 132 | calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS]; 133 | struct cal_target_power_ht 134 | calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS]; 135 | struct cal_target_power_leg 136 | calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS]; 137 | struct cal_target_power_leg 138 | calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS]; 139 | struct cal_target_power_ht 140 | calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS]; 141 | struct cal_target_power_ht 142 | calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS]; 143 | uint8_t ctlIndex[AR5416_NUM_CTLS]; 144 | struct cal_ctl_data ctlData[AR5416_NUM_CTLS]; 145 | uint8_t padding; 146 | } __attribute__ ((packed)); 147 | 148 | #endif /* EEP_DEF_H */ 149 | -------------------------------------------------------------------------------- /tools/halregdump/Makefile: -------------------------------------------------------------------------------- 1 | COMMON_HEADERS=ah_regdomain_common.h ah_regdomain.h 2 | 3 | all: hal-reg-dump 4 | 5 | hal-reg-dump: hal-reg-dump.c $(COMMON_HEADERS) 6 | gcc -o $@ hal-reg-dump.c 7 | 8 | clean: 9 | rm -f hal-reg-dump 10 | 11 | .PHONY: all 12 | -------------------------------------------------------------------------------- /tools/halregdump/hal-reg-dump.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 Atheros Communications Inc. 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | #include "ah_regdomain_common.h" 20 | 21 | #define CONFIG_DEBUG 0 22 | #define CONFIG_PRINT_TURBO 0 23 | #define CONFIG_NEW_DFS_RULES 1 24 | #define CONFIG_NEW_JAPAN_RULES 1 25 | #define CONFIG_NEW_CANADA_RULES 1 26 | #define CONFIG_NEW_AU_RULES 1 27 | #define CONFIG_NEW_KR_RULES 1 /* Korea */ 28 | 29 | #if CONFIG_DEBUG 30 | #define DEBUG_PRINT(fmt, ...) do { \ 31 | printf(fmt, ##__VA_ARGS__); \ 32 | } while (0) 33 | #else 34 | #define DEBUG_PRINT(fmt, ...) do { /* nothing */ } while(0) 35 | #endif 36 | 37 | /* 38 | * Test to see if the bitmask array is all zeros 39 | */ 40 | static int 41 | isChanBitMaskZero(u_int64_t *bitmask) 42 | { 43 | int i; 44 | 45 | for (i=0; ichan11a[0] || regd->chan11a[1]) 148 | return 1; 149 | if (regd->chan11a_turbo[0] || regd->chan11a_turbo[1]) 150 | return 1; 151 | if (regd->chan11a_dyn_turbo[0] || regd->chan11a_dyn_turbo[1]) 152 | return 1; 153 | return 0; 154 | } 155 | 156 | static inline int 157 | is_reg_2ghz(struct reg_domain *regd) 158 | { 159 | if (regd->chan11b[0] || regd->chan11b[1]) 160 | return 1; 161 | if (regd->chan11g[0] || regd->chan11g[1]) 162 | return 1; 163 | if (regd->chan11g_turbo[0] || regd->chan11g_turbo[1]) 164 | return 1; 165 | return 0; 166 | } 167 | 168 | static void 169 | print_country_flags(struct reg_domain *regd, 170 | struct country_code_to_enum_rd *rd) 171 | { 172 | if (is_reg_5ghz(regd)) { 173 | if (! rd->allow11na40) 174 | printf(", NO-HT40"); 175 | } 176 | else if (is_reg_2ghz(regd)) { 177 | if (! rd->allow11ng40) 178 | printf(", NO-HT40"); 179 | } 180 | else 181 | printf("BUG - regd determined to not be 2ghz or 5ghz...\n"); 182 | printf("\n"); 183 | 184 | /* outdoorChanStart seems useless, its always = 7000 */ 185 | } 186 | 187 | #if CONFIG_PRINT_TURBO 188 | static void 189 | print_regd_flags_turbo(struct reg_domain *regd) 190 | { 191 | if (regd->flags & DISALLOW_ADHOC_11A_TURB) 192 | printf(", REQ_DISALLOW_ADHOC_11A_TURB"); 193 | } 194 | #else 195 | static inline int 196 | print_regd_flags_turbo(struct reg_domain *regd) 197 | { 198 | return; 199 | } 200 | #endif /* CONFIG_PRINT_TURBO */ 201 | 202 | static void 203 | print_regd_flags(struct reg_domain *regd) 204 | { 205 | /* XXX: Finish printing out flags per regd */ 206 | /* 207 | printf(", EDGE-POWER-%d", print_ctl(regd->conformanceTestLimit)); 208 | */ 209 | if (regd->flags & NO_REQ) { 210 | return; 211 | } 212 | /* Note: we ignore NEED_NFC as per advise that we 213 | * already do noise floor anyway */ 214 | 215 | /* Note: DISALLOW_ADHOC_11A is no IBSS on 802.11a but 216 | * since we are printing the flags per frequency range 217 | * and since this flag is per major band pair 218 | * (2ghz or 5 ghz) there is no need to make it 219 | * IEEE-802.11 sepecific, just say NO-IBSS 220 | */ 221 | 222 | /* This takes into consideration of new DFS rules 223 | * as per Michael Green */ 224 | #ifndef CONFIG_NEW_DFS_RULES 225 | if (regd->flags & DISALLOW_ADHOC_11A) 226 | printf(", NO-IBSS"); 227 | #endif 228 | if (regd->flags & ADHOC_PER_11D) 229 | printf(", REQ-ADHOC_PER-11D"); 230 | #ifndef CONFIG_NEW_DFS_RULES 231 | if (regd->flags & ADHOC_NO_11A) 232 | printf(", NO-IBSS2"); 233 | #endif 234 | if (regd->flags & PUBLIC_SAFETY_DOMAIN) 235 | printf(", REQ-PUBLIC-SAFETY-DOMAIN"); 236 | if (regd->flags & LIMIT_FRAME_4MS) 237 | printf(", REQ-LIMIT_FRAME-4MS"); 238 | if (regd->flags & NO_HOSTAP) 239 | printf(", REQ-NO-HOSTAP"); 240 | 241 | print_regd_flags_turbo(regd); 242 | } 243 | 244 | #define IS_DFS_FREQ(freq) (freq >= 5260 && freq <= 5700) 245 | 246 | /* Both of the structures here have passive scan and DFS flags. 247 | * To deal with them -inline- we use this routine. */ 248 | static void 249 | print_common_regd_freq_flags(struct reg_domain *regd, 250 | struct reg_dmn_freq_band *freq, 251 | struct reg_dmn_pair_mapping *reg_pair_map) 252 | { 253 | u_int64_t pscan; 254 | pscan = regd->pscan & reg_pair_map->pscanMask; 255 | 256 | /* As per Michael Green, these are the new DFS rules */ 257 | #ifndef CONFIG_NEW_DFS_RULES 258 | if (freq->usePassScan & pscan) 259 | printf(", PASSIVE-SCAN"); 260 | if (freq->useDfs & regd->dfsMask) 261 | printf(", DFS"); 262 | #endif 263 | } 264 | 265 | #if CONFIG_PRINT_TURBO 266 | static int 267 | can_print_from_freq_coll_turbo(struct reg_dmn_freq_band *freq_coll) 268 | { 269 | if (freq_coll == regDmn5GhzTurboFreq) 270 | return 1; 271 | else if (freq_coll == regDmn5GhzTurboFreq) 272 | return 1; 273 | else if (freq_coll == regDmn2Ghz11gTurboFreq) 274 | return 1; 275 | else 276 | return 0; 277 | } 278 | #else 279 | static inline int 280 | can_print_from_freq_coll_turbo(struct reg_dmn_freq_band *freq_coll) 281 | { 282 | return 0; 283 | } 284 | #endif /* CONFIG_PRINT_TURBO */ 285 | 286 | static int 287 | can_print_from_freq_coll(struct reg_dmn_freq_band *freq_coll) { 288 | if (freq_coll == regdmn5ghzfreq) 289 | return 1; 290 | else if (freq_coll == regDmn2GhzFreq) 291 | return 1; 292 | else if (freq_coll == regDmn2Ghz11gFreq) 293 | return 1; 294 | else { 295 | if (can_print_from_freq_coll_turbo(freq_coll)) 296 | return 1; 297 | else 298 | return 0; 299 | } 300 | return 0; 301 | } 302 | 303 | /* XXX: I tried to remove this macro but can't figure a clean 304 | * way to pass the freq_collection in such as way the receiver 305 | * call iterate over it */ 306 | #define PRINT_FREQ(bitmap, freq_collection) \ 307 | size_of_collection = array_size(freq_collection); \ 308 | DEBUG_PRINT("Array size: %d\n", size_of_collection); \ 309 | if (is_bit_set(i, bitmap)) { \ 310 | if (i > size_of_collection) { \ 311 | printf("BUG - bit (%d) out of " \ 312 | "bounds on bitmap %s\n", i, #bitmap); \ 313 | } \ 314 | else { \ 315 | DEBUG_PRINT("Channels on %s\n", #bitmap); \ 316 | if (can_print_from_freq_coll(freq_collection)) { \ 317 | char antenna_gain[5]; \ 318 | struct reg_dmn_freq_band *freq = \ 319 | &freq_collection[i]; \ 320 | if (freq->antennaMax == 0) \ 321 | sprintf(antenna_gain, "N/A"); \ 322 | else \ 323 | sprintf(antenna_gain, "%d", freq->antennaMax); \ 324 | printf( "\t(%d - %d @ %d), " \ 325 | "(%s, %d)", \ 326 | freq->lowChannel - (freq->channelBW/2), \ 327 | freq->highChannel + (freq->channelBW/2), \ 328 | freq->channelBW, \ 329 | antenna_gain, \ 330 | freq->powerDfs \ 331 | ); \ 332 | print_common_regd_freq_flags(regd, freq, reg_pair_map); \ 333 | print_regd_flags(regd); \ 334 | print_country_flags(regd, rd); \ 335 | } \ 336 | } \ 337 | } 338 | 339 | static void 340 | print_regd(struct reg_domain *regd, 341 | struct country_code_to_enum_rd *rd, 342 | struct reg_dmn_pair_mapping *reg_pair_map) 343 | { 344 | int i; 345 | 346 | /* Each frequency can have 128 frequency ranges. As it stands 347 | * 5 GHz has 64 frequency ranges defined, 2 GHz has a lot less. 348 | * After a 64 bits has been used is_bit_set() converts the bit 349 | * number to an array index offset. We only support 2 right now, 350 | * each holding 64 bits. 351 | */ 352 | 353 | for (i=0; i<128; i++) { 354 | int size_of_collection = 0; 355 | 356 | DEBUG_PRINT("On bit #%d\n", i); 357 | 358 | /* We deal with not printing turbo through compile flags. 359 | * This is in case we later want to add this to a private 360 | * CRDA DB. */ 361 | PRINT_FREQ(regd->chan11a, regdmn5ghzfreq); 362 | PRINT_FREQ(regd->chan11a_turbo, regDmn5GhzTurboFreq); 363 | PRINT_FREQ(regd->chan11a_dyn_turbo, regDmn5GhzTurboFreq); 364 | PRINT_FREQ(regd->chan11b, regDmn2GhzFreq); 365 | PRINT_FREQ(regd->chan11g, regDmn2Ghz11gFreq); 366 | PRINT_FREQ(regd->chan11g_turbo, regDmn2Ghz11gTurboFreq); 367 | } 368 | 369 | } 370 | 371 | int main(int argc, char **argv) { 372 | int i; 373 | int same_freq_count, prev_low, prev_high; 374 | u_int16_t country_code; 375 | 376 | if (argc != 1 && argc != 2) { 377 | printf("Usage: dump_ah_regdb [country_alpha2]\n"); 378 | printf("Examples:\n"); 379 | printf("\tThis dumps the entire db:\n"); 380 | printf("\tdump_ah_regdb\n"); 381 | printf("\tThis dumps info only for US\n"); 382 | printf("\tdump_ah_regdb US\n"); 383 | return 1; 384 | } 385 | 386 | /* This print should match CRDA db.txt as much as possible 387 | * git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/crda.git */ 388 | 389 | if (argc == 2) { 390 | struct country_code_to_enum_rd *rd; 391 | struct reg_dmn_pair_mapping *reg_pair_map; 392 | struct reg_domain *regd_5ghz; 393 | struct reg_domain *regd_2ghz; 394 | 395 | country_code = findCountryCode(argv[1]); 396 | rd = findCountry(country_code); 397 | if (!rd) { 398 | printf("Regdomain not found\n"); 399 | return 1; 400 | } 401 | 402 | if (strcmp(argv[1], rd->isoName) != 0) { 403 | printf("No match found\n"); 404 | return 1; 405 | } 406 | 407 | #ifdef CONFIG_NEW_JAPAN_RULES 408 | if (strcmp("JP", rd->isoName) == 0) { 409 | switch(rd->regDmnEnum) { 410 | case MKK5_MKKA2: 411 | case MKK5_MKKC: 412 | case MKK11_MKKA2: 413 | case MKK11_MKKC: 414 | break; /* allowed */ 415 | default: 416 | /* XXX: we should just iterate over the DB 417 | * until we found all 4 of the above and print them */ 418 | printf("Outdated regulatory domain detected for JP (0x%X),\n" 419 | "the first JP regdomain needs to be updated.\n" 420 | "Valid regulatory domains:\n" 421 | "\t0x%X, 0x%X, 0x%X, 0x%X\n", 422 | rd->regDmnEnum, 423 | MKK5_MKKA2, 424 | MKK5_MKKC, 425 | MKK11_MKKA2, 426 | MKK11_MKKC); 427 | return 1; 428 | } 429 | } 430 | #endif 431 | #ifdef CONFIG_NEW_CANADA_RULES 432 | if (strcmp("CA", rd->isoName) == 0) { 433 | switch(rd->regDmnEnum) { 434 | case FCC3_FCCA: 435 | break; /* allowed */ 436 | default: 437 | /* XXX: we should just iterate over the DB 438 | * until we find the one above and print it */ 439 | printf("Outdated regulatory domain detected for CA (0x%X),\n" 440 | "the first CA regdomain needs to be updated.\n" 441 | "Valid regulatory domain: 0x%X\n", 442 | rd->regDmnEnum, FCC3_FCCA); 443 | return 1; 444 | } 445 | } 446 | #endif 447 | #ifdef CONFIG_NEW_AU_RULES 448 | if (strcmp("AU", rd->isoName) == 0) { 449 | switch(rd->regDmnEnum) { 450 | case FCC2_WORLD: 451 | break; /* allowed */ 452 | default: 453 | /* XXX: we should just iterate over the DB 454 | * until we find the one above and print it */ 455 | printf("Outdated regulatory domain detected for AU (0x%X),\n" 456 | "the first CA regdomain needs to be updated.\n" 457 | "Valid regulatory domain: 0x%X\n", 458 | rd->regDmnEnum, FCC2_WORLD); 459 | return 1; 460 | } 461 | } 462 | #endif 463 | #ifdef CONFIG_NEW_KR_RULES 464 | if ((strcmp("K2", rd->isoName) == 0) || 465 | (strcmp("K3", rd->isoName) == 0)) { 466 | printf("K2 and K3 are not supported with new reg rules\n"); 467 | return 1; 468 | } 469 | if (strcmp("KR", rd->isoName) == 0) { 470 | switch(rd->regDmnEnum) { 471 | case APL10_WORLD: 472 | break; /* allowed */ 473 | default: 474 | /* XXX: we should just iterate over the DB 475 | * until we find the one above and print it */ 476 | printf("Outdated regulatory domain detected for KR (0x%X),\n" 477 | "the first CA regdomain needs to be updated.\n" 478 | "Valid regulatory domain: 0x%X\n", 479 | rd->regDmnEnum, APL10_WORLD); 480 | return 1; 481 | } 482 | } 483 | #endif 484 | 485 | printf("country %s:\n", rd->isoName); 486 | 487 | reg_pair_map = find_reg_pair_map(rd->regDmnEnum); 488 | if (!reg_pair_map) { 489 | printf("Regdomain pair map not found\n"); 490 | return 1; 491 | } 492 | 493 | regd_5ghz = find_regd(reg_pair_map->regDmn5GHz); 494 | regd_2ghz = find_regd(reg_pair_map->regDmn2GHz); 495 | 496 | print_regd(regd_5ghz, rd, reg_pair_map); 497 | print_regd(regd_2ghz, rd, reg_pair_map); 498 | 499 | printf("\n\n"); 500 | 501 | return 0; 502 | } 503 | 504 | /* Print all frequency ranges (called a "band" in db.txt */ 505 | 506 | /* For upstream CRDA db.txt we don't need Turbo channels, 507 | * they are not used for HT20 or HT40. To prevent its print we 508 | * use can_print_from_freq_coll() as a check */ 509 | 510 | for (i=0; iisoName) == 0) { 524 | switch(rd->regDmnEnum) { 525 | case MKK5_MKKA2: 526 | case MKK5_MKKC: 527 | case MKK11_MKKA2: 528 | case MKK11_MKKC: 529 | /* allowed */ 530 | break; 531 | default: 532 | /* Not allowed, skip */ 533 | continue; 534 | } 535 | } 536 | #endif 537 | #ifdef CONFIG_NEW_CANADA_RULES 538 | if (strcmp("CA", rd->isoName) == 0) { 539 | switch(rd->regDmnEnum) { 540 | case FCC3_FCCA: 541 | /* allowed */ 542 | break; 543 | default: 544 | /* Not allowed, skip */ 545 | continue; 546 | } 547 | } 548 | #endif 549 | #ifdef CONFIG_NEW_AU_RULES 550 | if (strcmp("AU", rd->isoName) == 0) { 551 | switch(rd->regDmnEnum) { 552 | case FCC2_WORLD: 553 | /* allowed */ 554 | break; 555 | default: 556 | /* Not allowed, skip */ 557 | continue; 558 | } 559 | } 560 | #endif 561 | #ifdef CONFIG_NEW_KR_RULES 562 | if ((strcmp("K2", rd->isoName) == 0) || 563 | (strcmp("K3", rd->isoName) == 0)) { 564 | continue; 565 | } 566 | if (strcmp("KR", rd->isoName) == 0) { 567 | switch(rd->regDmnEnum) { 568 | case APL10_WORLD: 569 | /* allowed */ 570 | break; 571 | default: 572 | /* Not allowed, skip */ 573 | continue; 574 | } 575 | } 576 | #endif 577 | 578 | printf("country %s:\n", rd->isoName); 579 | 580 | reg_pair_map = find_reg_pair_map(rd->regDmnEnum); 581 | if (!reg_pair_map) { 582 | printf("Regdomain pair map not found\n"); 583 | return 1; 584 | } 585 | 586 | regd_5ghz = find_regd(reg_pair_map->regDmn5GHz); 587 | regd_2ghz = find_regd(reg_pair_map->regDmn2GHz); 588 | 589 | print_regd(regd_5ghz, rd, reg_pair_map); 590 | print_regd(regd_2ghz, rd, reg_pair_map); 591 | 592 | printf("\n"); 593 | } 594 | return 0; 595 | } 596 | -------------------------------------------------------------------------------- /tools/initvals/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS= 2 | ATH9K_DIR=. 3 | 4 | LOCAL_CFLAGS=$(CFLAGS) -I"$(ATH9K_DIR)" 5 | ifdef ATHEROS 6 | LOCAL_CFLAGS += -DATHEROS 7 | 8 | ATHEROS_DEPS += \ 9 | ar5416.ini \ 10 | ar5416_howl.ini \ 11 | ar5416_sowl.ini \ 12 | ar9280_merlin2.ini \ 13 | ar9285.ini \ 14 | ar9285_v1_2.ini \ 15 | ar9287_1_1.ini \ 16 | ar9271.ini \ 17 | ar9300_osprey22.ini \ 18 | ar9330_11.ini \ 19 | ar9330_12.ini \ 20 | ar9340.ini \ 21 | ar955x.ini \ 22 | ar9580.ini \ 23 | ar9300_jupiter20.ini \ 24 | ar9300_jupiter21.ini \ 25 | ar9300_aphrodite10.ini 26 | endif 27 | 28 | ATH9K_HEADERS = \ 29 | ar5008:ar5008_initvals.h \ 30 | ar9001:ar9001_initvals.h \ 31 | ar9002:ar9002_initvals.h \ 32 | ar9003-2p2:ar9003_2p2_initvals.h \ 33 | ar9330-1p1:ar9330_1p1_initvals.h \ 34 | ar9330-1p2:ar9330_1p2_initvals.h \ 35 | ar9340:ar9340_initvals.h \ 36 | ar9485:ar9485_initvals.h \ 37 | ar955x-1p0:ar955x_1p0_initvals.h \ 38 | ar9580-1p0:ar9580_1p0_initvals.h \ 39 | ar9462-2p0:ar9462_2p0_initvals.h \ 40 | ar9462-2p1:ar9462_2p1_initvals.h \ 41 | ar9565-1p0:ar9565_1p0_initvals.h 42 | 43 | ifndef ATHEROS 44 | ATH9K_DEPS := $(foreach header,$(ATH9K_HEADERS),$(word 2,$(subst :, $(ATH9K_DIR)/,$(header)))) 45 | endif 46 | 47 | SOURCES:=initvals.c sha1.c 48 | 49 | initvals: $(ATH9K_DEPS) $(ATHEROS_DEPS) $(SOURCES) 50 | gcc $(LOCAL_CFLAGS) -o $@ $(SOURCES) 51 | 52 | define refresh_command 53 | ./initvals -w -f $(word 1,$(subst :, ,$(1))) > $(word 2,$(subst :, $(ATH9K_DIR)/,$(1))) 54 | 55 | endef 56 | 57 | refresh: initvals 58 | $(foreach header,$(ATH9K_HEADERS),$(call refresh_command,$(header))) 59 | ./initvals > checksums.txt 60 | 61 | all: initvals 62 | 63 | clean: 64 | rm -f initvals 65 | -------------------------------------------------------------------------------- /tools/initvals/ar9330_1p2_initvals.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. 3 | * Copyright (c) 2011-2012 Qualcomm Atheros Inc. 4 | * 5 | * Permission to use, copy, modify, and/or distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #ifndef INITVALS_9330_1P2_H 19 | #define INITVALS_9330_1P2_H 20 | 21 | static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = { 22 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 23 | {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, 24 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, 25 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, 26 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, 27 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, 28 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, 29 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, 30 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, 31 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, 32 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, 33 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, 34 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, 35 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, 36 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, 37 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, 38 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, 39 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, 40 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, 41 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, 42 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, 43 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, 44 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, 45 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, 46 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, 47 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, 48 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, 49 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, 50 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, 51 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, 52 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, 53 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, 54 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, 55 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, 56 | {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, 57 | {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, 58 | {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, 59 | {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, 60 | {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, 61 | {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, 62 | {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, 63 | {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, 64 | {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, 65 | {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, 66 | {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, 67 | {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, 68 | {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, 69 | {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, 70 | {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, 71 | {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, 72 | {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, 73 | {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, 74 | {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, 75 | {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, 76 | {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, 77 | {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, 78 | {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, 79 | {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, 80 | {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, 81 | {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, 82 | {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, 83 | {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, 84 | {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, 85 | {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, 86 | {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, 87 | {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, 88 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 89 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 90 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 91 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 92 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 93 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, 94 | {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, 95 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, 96 | {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, 97 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, 98 | {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, 99 | {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, 100 | {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, 101 | {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, 102 | {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, 103 | {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, 104 | }; 105 | 106 | #define ar9331_modes_high_power_tx_gain_1p2 ar9331_modes_high_ob_db_tx_gain_1p2 107 | 108 | #define ar9331_modes_low_ob_db_tx_gain_1p2 ar9331_modes_high_power_tx_gain_1p2 109 | 110 | #define ar9331_modes_lowest_ob_db_tx_gain_1p2 ar9331_modes_low_ob_db_tx_gain_1p2 111 | 112 | static const u32 ar9331_1p2_baseband_postamble[][5] = { 113 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 114 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, 115 | {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, 116 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, 117 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, 118 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, 119 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, 120 | {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, 121 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4}, 122 | {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, 123 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, 124 | {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e}, 125 | {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, 126 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 127 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, 128 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, 129 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00003221, 0x00003221}, 130 | {0x00009e3c, 0xcf946222, 0xcf946222, 0xcf946222, 0xcf946222}, 131 | {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, 132 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, 133 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, 134 | {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0}, 135 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, 136 | {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, 137 | {0x0000a234, 0x00000fff, 0x00000fff, 0x10000fff, 0x00000fff}, 138 | {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, 139 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, 140 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, 141 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, 142 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, 143 | {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, 144 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, 145 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, 146 | {0x0000a284, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 147 | {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 148 | {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 149 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 150 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981}, 151 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, 152 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 153 | {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, 154 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 155 | }; 156 | 157 | static const u32 ar9331_1p2_radio_core[][2] = { 158 | /* Addr allmodes */ 159 | {0x00016000, 0x36db6db6}, 160 | {0x00016004, 0x6db6db40}, 161 | {0x00016008, 0x73800000}, 162 | {0x0001600c, 0x00000000}, 163 | {0x00016040, 0x7f80fff8}, 164 | {0x00016044, 0x03d6d2db}, 165 | {0x00016048, 0x6c924268}, 166 | {0x0001604c, 0x000f0278}, 167 | {0x00016050, 0x4db6db8c}, 168 | {0x00016054, 0x6db60000}, 169 | {0x00016080, 0x00080000}, 170 | {0x00016084, 0x0e48048c}, 171 | {0x00016088, 0x14214514}, 172 | {0x0001608c, 0x119f081c}, 173 | {0x00016090, 0x24926490}, 174 | {0x00016098, 0xd411eb84}, 175 | {0x000160a0, 0xc2108ffe}, 176 | {0x000160a4, 0x812fc370}, 177 | {0x000160a8, 0x423c8000}, 178 | {0x000160ac, 0x24651800}, 179 | {0x000160b0, 0x03284f3e}, 180 | {0x000160b4, 0x92480040}, 181 | {0x000160c0, 0x006db6db}, 182 | {0x000160c4, 0x0186db60}, 183 | {0x000160c8, 0x6db6db6c}, 184 | {0x000160cc, 0x6de6c300}, 185 | {0x000160d0, 0x14500820}, 186 | {0x00016100, 0x04cb0001}, 187 | {0x00016104, 0xfff80015}, 188 | {0x00016108, 0x00080010}, 189 | {0x0001610c, 0x00170000}, 190 | {0x00016140, 0x10804000}, 191 | {0x00016144, 0x01884080}, 192 | {0x00016148, 0x000080c0}, 193 | {0x00016280, 0x01000015}, 194 | {0x00016284, 0x14d20000}, 195 | {0x00016288, 0x00318000}, 196 | {0x0001628c, 0x50000000}, 197 | {0x00016290, 0x4b96210f}, 198 | {0x00016380, 0x00000000}, 199 | {0x00016384, 0x00000000}, 200 | {0x00016388, 0x00800700}, 201 | {0x0001638c, 0x00800700}, 202 | {0x00016390, 0x00800700}, 203 | {0x00016394, 0x00000000}, 204 | {0x00016398, 0x00000000}, 205 | {0x0001639c, 0x00000000}, 206 | {0x000163a0, 0x00000001}, 207 | {0x000163a4, 0x00000001}, 208 | {0x000163a8, 0x00000000}, 209 | {0x000163ac, 0x00000000}, 210 | {0x000163b0, 0x00000000}, 211 | {0x000163b4, 0x00000000}, 212 | {0x000163b8, 0x00000000}, 213 | {0x000163bc, 0x00000000}, 214 | {0x000163c0, 0x000000a0}, 215 | {0x000163c4, 0x000c0000}, 216 | {0x000163c8, 0x14021402}, 217 | {0x000163cc, 0x00001402}, 218 | {0x000163d0, 0x00000000}, 219 | {0x000163d4, 0x00000000}, 220 | }; 221 | 222 | #define ar9331_1p2_baseband_core_txfir_coeff_japan_2484 ar9331_1p1_baseband_core_txfir_coeff_japan_2484 223 | 224 | #define ar9331_1p2_xtal_25M ar9331_1p1_xtal_25M 225 | 226 | #define ar9331_1p2_xtal_40M ar9331_1p1_xtal_40M 227 | 228 | #define ar9331_1p2_baseband_core ar9331_1p1_baseband_core 229 | 230 | #define ar9331_1p2_soc_postamble ar9331_1p1_soc_postamble 231 | 232 | #define ar9331_1p2_mac_postamble ar9331_1p1_mac_postamble 233 | 234 | #define ar9331_1p2_soc_preamble ar9331_1p1_soc_preamble 235 | 236 | #define ar9331_1p2_mac_core ar9331_1p1_mac_core 237 | 238 | #define ar9331_common_wo_xlna_rx_gain_1p2 ar9331_common_wo_xlna_rx_gain_1p1 239 | 240 | static const u32 ar9331_common_rx_gain_1p2[][2] = { 241 | /* Addr allmodes */ 242 | {0x0000a000, 0x00010000}, 243 | {0x0000a004, 0x00030002}, 244 | {0x0000a008, 0x00050004}, 245 | {0x0000a00c, 0x00810080}, 246 | {0x0000a010, 0x01800082}, 247 | {0x0000a014, 0x01820181}, 248 | {0x0000a018, 0x01840183}, 249 | {0x0000a01c, 0x01880185}, 250 | {0x0000a020, 0x018a0189}, 251 | {0x0000a024, 0x02850284}, 252 | {0x0000a028, 0x02890288}, 253 | {0x0000a02c, 0x03850384}, 254 | {0x0000a030, 0x03890388}, 255 | {0x0000a034, 0x038b038a}, 256 | {0x0000a038, 0x038d038c}, 257 | {0x0000a03c, 0x03910390}, 258 | {0x0000a040, 0x03930392}, 259 | {0x0000a044, 0x03950394}, 260 | {0x0000a048, 0x00000396}, 261 | {0x0000a04c, 0x00000000}, 262 | {0x0000a050, 0x00000000}, 263 | {0x0000a054, 0x00000000}, 264 | {0x0000a058, 0x00000000}, 265 | {0x0000a05c, 0x00000000}, 266 | {0x0000a060, 0x00000000}, 267 | {0x0000a064, 0x00000000}, 268 | {0x0000a068, 0x00000000}, 269 | {0x0000a06c, 0x00000000}, 270 | {0x0000a070, 0x00000000}, 271 | {0x0000a074, 0x00000000}, 272 | {0x0000a078, 0x00000000}, 273 | {0x0000a07c, 0x00000000}, 274 | {0x0000a080, 0x28282828}, 275 | {0x0000a084, 0x28282828}, 276 | {0x0000a088, 0x28282828}, 277 | {0x0000a08c, 0x28282828}, 278 | {0x0000a090, 0x28282828}, 279 | {0x0000a094, 0x21212128}, 280 | {0x0000a098, 0x171c1c1c}, 281 | {0x0000a09c, 0x02020212}, 282 | {0x0000a0a0, 0x00000202}, 283 | {0x0000a0a4, 0x00000000}, 284 | {0x0000a0a8, 0x00000000}, 285 | {0x0000a0ac, 0x00000000}, 286 | {0x0000a0b0, 0x00000000}, 287 | {0x0000a0b4, 0x00000000}, 288 | {0x0000a0b8, 0x00000000}, 289 | {0x0000a0bc, 0x00000000}, 290 | {0x0000a0c0, 0x001f0000}, 291 | {0x0000a0c4, 0x111f1100}, 292 | {0x0000a0c8, 0x111d111e}, 293 | {0x0000a0cc, 0x111b111c}, 294 | {0x0000a0d0, 0x22032204}, 295 | {0x0000a0d4, 0x22012202}, 296 | {0x0000a0d8, 0x221f2200}, 297 | {0x0000a0dc, 0x221d221e}, 298 | {0x0000a0e0, 0x33013302}, 299 | {0x0000a0e4, 0x331f3300}, 300 | {0x0000a0e8, 0x4402331e}, 301 | {0x0000a0ec, 0x44004401}, 302 | {0x0000a0f0, 0x441e441f}, 303 | {0x0000a0f4, 0x55015502}, 304 | {0x0000a0f8, 0x551f5500}, 305 | {0x0000a0fc, 0x6602551e}, 306 | {0x0000a100, 0x66006601}, 307 | {0x0000a104, 0x661e661f}, 308 | {0x0000a108, 0x7703661d}, 309 | {0x0000a10c, 0x77017702}, 310 | {0x0000a110, 0x00007700}, 311 | {0x0000a114, 0x00000000}, 312 | {0x0000a118, 0x00000000}, 313 | {0x0000a11c, 0x00000000}, 314 | {0x0000a120, 0x00000000}, 315 | {0x0000a124, 0x00000000}, 316 | {0x0000a128, 0x00000000}, 317 | {0x0000a12c, 0x00000000}, 318 | {0x0000a130, 0x00000000}, 319 | {0x0000a134, 0x00000000}, 320 | {0x0000a138, 0x00000000}, 321 | {0x0000a13c, 0x00000000}, 322 | {0x0000a140, 0x001f0000}, 323 | {0x0000a144, 0x111f1100}, 324 | {0x0000a148, 0x111d111e}, 325 | {0x0000a14c, 0x111b111c}, 326 | {0x0000a150, 0x22032204}, 327 | {0x0000a154, 0x22012202}, 328 | {0x0000a158, 0x221f2200}, 329 | {0x0000a15c, 0x221d221e}, 330 | {0x0000a160, 0x33013302}, 331 | {0x0000a164, 0x331f3300}, 332 | {0x0000a168, 0x4402331e}, 333 | {0x0000a16c, 0x44004401}, 334 | {0x0000a170, 0x441e441f}, 335 | {0x0000a174, 0x55015502}, 336 | {0x0000a178, 0x551f5500}, 337 | {0x0000a17c, 0x6602551e}, 338 | {0x0000a180, 0x66006601}, 339 | {0x0000a184, 0x661e661f}, 340 | {0x0000a188, 0x7703661d}, 341 | {0x0000a18c, 0x77017702}, 342 | {0x0000a190, 0x00007700}, 343 | {0x0000a194, 0x00000000}, 344 | {0x0000a198, 0x00000000}, 345 | {0x0000a19c, 0x00000000}, 346 | {0x0000a1a0, 0x00000000}, 347 | {0x0000a1a4, 0x00000000}, 348 | {0x0000a1a8, 0x00000000}, 349 | {0x0000a1ac, 0x00000000}, 350 | {0x0000a1b0, 0x00000000}, 351 | {0x0000a1b4, 0x00000000}, 352 | {0x0000a1b8, 0x00000000}, 353 | {0x0000a1bc, 0x00000000}, 354 | {0x0000a1c0, 0x00000000}, 355 | {0x0000a1c4, 0x00000000}, 356 | {0x0000a1c8, 0x00000000}, 357 | {0x0000a1cc, 0x00000000}, 358 | {0x0000a1d0, 0x00000000}, 359 | {0x0000a1d4, 0x00000000}, 360 | {0x0000a1d8, 0x00000000}, 361 | {0x0000a1dc, 0x00000000}, 362 | {0x0000a1e0, 0x00000000}, 363 | {0x0000a1e4, 0x00000000}, 364 | {0x0000a1e8, 0x00000000}, 365 | {0x0000a1ec, 0x00000000}, 366 | {0x0000a1f0, 0x00000396}, 367 | {0x0000a1f4, 0x00000396}, 368 | {0x0000a1f8, 0x00000396}, 369 | {0x0000a1fc, 0x00000296}, 370 | }; 371 | 372 | #endif /* INITVALS_9330_1P2_H */ 373 | -------------------------------------------------------------------------------- /tools/initvals/sha1.c: -------------------------------------------------------------------------------- 1 | /* 2 | SHA-1 in C 3 | By Steve Reid 4 | 100% Public Domain 5 | 6 | ----------------- 7 | Modified 7/98 8 | By James H. Brown 9 | Still 100% Public Domain 10 | 11 | Corrected a problem which generated improper hash values on 16 bit machines 12 | Routine SHA1Update changed from 13 | void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int 14 | len) 15 | to 16 | void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned 17 | long len) 18 | 19 | The 'len' parameter was declared an int which works fine on 32 bit machines. 20 | However, on 16 bit machines an int is too small for the shifts being done 21 | against 22 | it. This caused the hash function to generate incorrect values if len was 23 | greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). 24 | 25 | Since the file IO in main() reads 16K at a time, any file 8K or larger would 26 | be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million 27 | "a"s). 28 | 29 | I also changed the declaration of variables i & j in SHA1Update to 30 | unsigned long from unsigned int for the same reason. 31 | 32 | These changes should make no difference to any 32 bit implementations since 33 | an 34 | int and a long are the same size in those environments. 35 | 36 | -- 37 | I also corrected a few compiler warnings generated by Borland C. 38 | 1. Added #include for exit() prototype 39 | 2. Removed unused variable 'j' in SHA1Final 40 | 3. Changed exit(0) to return(0) at end of main. 41 | 42 | ALL changes I made can be located by searching for comments containing 'JHB' 43 | ----------------- 44 | Modified 8/98 45 | By Steve Reid 46 | Still 100% public domain 47 | 48 | 1- Removed #include and used return() instead of exit() 49 | 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) 50 | 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net 51 | 52 | ----------------- 53 | Modified 4/01 54 | By Saul Kravitz 55 | Still 100% PD 56 | Modified to run on Compaq Alpha hardware. 57 | 58 | ----------------- 59 | Modified 07/2002 60 | By Ralph Giles 61 | Still 100% public domain 62 | modified for use with stdint types, autoconf 63 | code cleanup, removed attribution comments 64 | switched SHA1Final() argument order for consistency 65 | use SHA1_ prefix for public api 66 | move public api to sha1.h 67 | */ 68 | 69 | /* 70 | Test Vectors (from FIPS PUB 180-1) 71 | "abc" 72 | A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 73 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 74 | 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 75 | A million repetitions of "a" 76 | 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 77 | */ 78 | 79 | /* #define SHA1HANDSOFF */ 80 | 81 | #ifdef HAVE_CONFIG_H 82 | #include "config.h" 83 | #endif 84 | 85 | #include 86 | #include 87 | 88 | #include 89 | #include "sha1.h" 90 | 91 | void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]); 92 | 93 | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 94 | 95 | /* blk0() and blk() perform the initial expand. */ 96 | /* I got the idea of expanding during the round function from SSLeay */ 97 | /* FIXME: can we do this in an endian-proof way? */ 98 | #ifdef WORDS_BIGENDIAN 99 | #define blk0(i) block->l[i] 100 | #else 101 | #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ 102 | |(rol(block->l[i],8)&0x00FF00FF)) 103 | #endif 104 | #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ 105 | ^block->l[(i+2)&15]^block->l[i&15],1)) 106 | 107 | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 108 | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 109 | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 110 | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 111 | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 112 | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 113 | 114 | 115 | #ifdef VERBOSE /* SAK */ 116 | void SHAPrintContext(SHA1_CTX *context, char *msg){ 117 | printf("%s (%d,%d) %x %x %x %x %x\n", 118 | msg, 119 | context->count[0], context->count[1], 120 | context->state[0], 121 | context->state[1], 122 | context->state[2], 123 | context->state[3], 124 | context->state[4]); 125 | } 126 | #endif /* VERBOSE */ 127 | 128 | /* Hash a single 512-bit block. This is the core of the algorithm. */ 129 | void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]) 130 | { 131 | uint32_t a, b, c, d, e; 132 | typedef union { 133 | uint8_t c[64]; 134 | uint32_t l[16]; 135 | } CHAR64LONG16; 136 | CHAR64LONG16* block; 137 | 138 | #ifdef SHA1HANDSOFF 139 | static uint8_t workspace[64]; 140 | block = (CHAR64LONG16*)workspace; 141 | memcpy(block, buffer, 64); 142 | #else 143 | block = (CHAR64LONG16*)buffer; 144 | #endif 145 | 146 | /* Copy context->state[] to working vars */ 147 | a = state[0]; 148 | b = state[1]; 149 | c = state[2]; 150 | d = state[3]; 151 | e = state[4]; 152 | 153 | /* 4 rounds of 20 operations each. Loop unrolled. */ 154 | R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 155 | R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 156 | R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 157 | R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 158 | R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 159 | R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 160 | R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 161 | R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 162 | R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 163 | R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 164 | R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 165 | R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 166 | R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 167 | R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 168 | R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 169 | R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 170 | R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 171 | R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 172 | R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 173 | R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 174 | 175 | /* Add the working vars back into context.state[] */ 176 | state[0] += a; 177 | state[1] += b; 178 | state[2] += c; 179 | state[3] += d; 180 | state[4] += e; 181 | 182 | /* Wipe variables */ 183 | a = b = c = d = e = 0; 184 | } 185 | 186 | 187 | /* SHA1Init - Initialize new context */ 188 | void SHA1_Init(SHA1_CTX* context) 189 | { 190 | /* SHA1 initialization constants */ 191 | context->state[0] = 0x67452301; 192 | context->state[1] = 0xEFCDAB89; 193 | context->state[2] = 0x98BADCFE; 194 | context->state[3] = 0x10325476; 195 | context->state[4] = 0xC3D2E1F0; 196 | context->count[0] = context->count[1] = 0; 197 | } 198 | 199 | 200 | /* Run your data through this. */ 201 | void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len) 202 | { 203 | size_t i, j; 204 | 205 | #ifdef VERBOSE 206 | SHAPrintContext(context, "before"); 207 | #endif 208 | 209 | j = (context->count[0] >> 3) & 63; 210 | if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; 211 | context->count[1] += (len >> 29); 212 | if ((j + len) > 63) { 213 | memcpy(&context->buffer[j], data, (i = 64-j)); 214 | SHA1_Transform(context->state, context->buffer); 215 | for ( ; i + 63 < len; i += 64) { 216 | SHA1_Transform(context->state, data + i); 217 | } 218 | j = 0; 219 | } 220 | else i = 0; 221 | memcpy(&context->buffer[j], &data[i], len - i); 222 | 223 | #ifdef VERBOSE 224 | SHAPrintContext(context, "after "); 225 | #endif 226 | } 227 | 228 | 229 | /* Add padding and return the message digest. */ 230 | void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) 231 | { 232 | uint32_t i; 233 | uint8_t finalcount[8]; 234 | 235 | for (i = 0; i < 8; i++) { 236 | finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] 237 | >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ 238 | } 239 | SHA1_Update(context, (uint8_t *)"\200", 1); 240 | while ((context->count[0] & 504) != 448) { 241 | SHA1_Update(context, (uint8_t *)"\0", 1); 242 | } 243 | SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */ 244 | for (i = 0; i < SHA1_DIGEST_SIZE; i++) { 245 | digest[i] = (uint8_t) 246 | ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); 247 | } 248 | 249 | /* Wipe variables */ 250 | i = 0; 251 | memset(context->buffer, 0, 64); 252 | memset(context->state, 0, 20); 253 | memset(context->count, 0, 8); 254 | memset(finalcount, 0, 8); /* SWR */ 255 | 256 | #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */ 257 | SHA1_Transform(context->state, context->buffer); 258 | #endif 259 | } 260 | 261 | /*************************************************************/ 262 | 263 | #if 0 264 | int main(int argc, char** argv) 265 | { 266 | int i, j; 267 | SHA1_CTX context; 268 | unsigned char digest[SHA1_DIGEST_SIZE], buffer[16384]; 269 | FILE* file; 270 | 271 | if (argc > 2) { 272 | puts("Public domain SHA-1 implementation - by Steve Reid "); 273 | puts("Modified for 16 bit environments 7/98 - by James H. Brown "); /* JHB */ 274 | puts("Produces the SHA-1 hash of a file, or stdin if no file is specified."); 275 | return(0); 276 | } 277 | if (argc < 2) { 278 | file = stdin; 279 | } 280 | else { 281 | if (!(file = fopen(argv[1], "rb"))) { 282 | fputs("Unable to open file.", stderr); 283 | return(-1); 284 | } 285 | } 286 | SHA1_Init(&context); 287 | while (!feof(file)) { /* note: what if ferror(file) */ 288 | i = fread(buffer, 1, 16384, file); 289 | SHA1_Update(&context, buffer, i); 290 | } 291 | SHA1_Final(&context, digest); 292 | fclose(file); 293 | for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) { 294 | for (j = 0; j < 4; j++) { 295 | printf("%02X", digest[i*4+j]); 296 | } 297 | putchar(' '); 298 | } 299 | putchar('\n'); 300 | return(0); /* JHB */ 301 | } 302 | #endif 303 | 304 | /* self test */ 305 | 306 | #ifdef TEST 307 | 308 | static char *test_data[] = { 309 | "abc", 310 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 311 | "A million repetitions of 'a'"}; 312 | static char *test_results[] = { 313 | "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D", 314 | "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1", 315 | "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"}; 316 | 317 | 318 | void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output) 319 | { 320 | int i,j; 321 | char *c = output; 322 | 323 | for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) { 324 | for (j = 0; j < 4; j++) { 325 | sprintf(c,"%02X", digest[i*4+j]); 326 | c += 2; 327 | } 328 | sprintf(c, " "); 329 | c += 1; 330 | } 331 | *(c - 1) = '\0'; 332 | } 333 | 334 | int main(int argc, char** argv) 335 | { 336 | int k; 337 | SHA1_CTX context; 338 | uint8_t digest[20]; 339 | char output[80]; 340 | 341 | fprintf(stdout, "verifying SHA-1 implementation... "); 342 | 343 | for (k = 0; k < 2; k++){ 344 | SHA1_Init(&context); 345 | SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k])); 346 | SHA1_Final(&context, digest); 347 | digest_to_hex(digest, output); 348 | 349 | if (strcmp(output, test_results[k])) { 350 | fprintf(stdout, "FAIL\n"); 351 | fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[k]); 352 | fprintf(stderr,"\t%s returned\n", output); 353 | fprintf(stderr,"\t%s is correct\n", test_results[k]); 354 | return (1); 355 | } 356 | } 357 | /* million 'a' vector we feed separately */ 358 | SHA1_Init(&context); 359 | for (k = 0; k < 1000000; k++) 360 | SHA1_Update(&context, (uint8_t*)"a", 1); 361 | SHA1_Final(&context, digest); 362 | digest_to_hex(digest, output); 363 | if (strcmp(output, test_results[2])) { 364 | fprintf(stdout, "FAIL\n"); 365 | fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]); 366 | fprintf(stderr,"\t%s returned\n", output); 367 | fprintf(stderr,"\t%s is correct\n", test_results[2]); 368 | return (1); 369 | } 370 | 371 | /* success */ 372 | fprintf(stdout, "ok\n"); 373 | return(0); 374 | } 375 | #endif /* TEST */ 376 | -------------------------------------------------------------------------------- /tools/initvals/sha1.h: -------------------------------------------------------------------------------- 1 | /* public api for steve reid's public domain SHA-1 implementation */ 2 | /* this file is in the public domain */ 3 | 4 | #ifndef __SHA1_H 5 | #define __SHA1_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct { 12 | uint32_t state[5]; 13 | uint32_t count[2]; 14 | uint8_t buffer[64]; 15 | } SHA1_CTX; 16 | 17 | #define SHA1_DIGEST_SIZE 20 18 | 19 | void SHA1_Init(SHA1_CTX* context); 20 | void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len); 21 | void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif /* __SHA1_H */ 28 | -------------------------------------------------------------------------------- /tools/initvals/verify_checksums.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CSUM_DIR=".tmp_checksum" 4 | get_family_checksum() 5 | { 6 | local family="$1" 7 | local suffix="$2" 8 | local flag 9 | 10 | [ "$suffix" == "hal" ] && flag="ATHEROS=1" 11 | [ -n "$ATH9K_DIR" ] && flag="$flag ATH9K_DIR=$ATH9K_DIR" 12 | 13 | make clean all $flag >/dev/null 14 | ./initvals -f $family > "$CSUM_DIR/${family}_$suffix.txt" 15 | ./initvals -f $family | sha1sum | sed -e 's/[ -]//g' 16 | } 17 | 18 | verify_family_checksum() 19 | { 20 | local family="$1" 21 | local sum_hal 22 | local sum_ath9k 23 | local res 24 | 25 | sum_hal=$(get_family_checksum $family hal) 26 | sum_ath9k=$(get_family_checksum $family ath9k) 27 | 28 | [ "$sum_hal" == "$sum_ath9k" ] && res="pass" || res="fail" 29 | printf "%-14s %-40s %s\n" "$family" "$sum_hal" "$res" 30 | [ "$res" == "fail" ] && \ 31 | diff -Nurw "$CSUM_DIR/${family}_hal.txt" "$CSUM_DIR/${family}_ath9k.txt" | grep '^+[0-9a-f]' 32 | } 33 | 34 | FAMILIES="$@" 35 | [ -z "$FAMILIES" ] && FAMILIES="ar5008 ar9001 ar9002 ar9003-2p2 ar9330-1p1 ar9330-1p2 ar9340 ar9462-1p0 ar9485 ar955x-1p0 ar9565-1p0 ar9580-1p0" 36 | 37 | mkdir -p "$CSUM_DIR" 38 | for family in $FAMILIES; do 39 | verify_family_checksum $family 40 | done 41 | rm -rf "$CSUM_DIR" 42 | -------------------------------------------------------------------------------- /tools/scripts/ath10k/ath10k-check: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2015-2017 Qualcomm Atheros, Inc. 4 | # Copyright (c) 2018, The Linux Foundation. All rights reserved. 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for any 7 | # purpose with or without fee is hereby granted, provided that the above 8 | # copyright notice and this permission notice appear in all copies. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | # 18 | # Run 'ath10k-check --help' to see the instructions 19 | # 20 | 21 | import subprocess 22 | import os 23 | import logging 24 | import sys 25 | import argparse 26 | import re 27 | import tempfile 28 | import queue 29 | import threading 30 | import string 31 | import hashlib 32 | import distutils.spawn 33 | 34 | CHECKPATCH_COMMIT = '362173572a4018e9c8e39c616823189c41d39d41' 35 | 36 | GIT_URL = 'https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/scripts/checkpatch.pl?id=%s' 37 | 38 | DRIVER_DIR = 'drivers/net/wireless/ath/ath10k/' 39 | 40 | FILTER_REGEXP = r'/ath' 41 | 42 | IGNORE_FILES = ['trace.h'] 43 | 44 | CHECKPATCH_IGNORE = ['MSLEEP', 45 | 'USLEEP_RANGE', 46 | 'PRINTK_WITHOUT_KERN_LEVEL', 47 | 48 | # ath10k does not follow networking comment style 49 | 'NETWORKING_BLOCK_COMMENT_STYLE', 50 | 51 | 'LINUX_VERSION_CODE', 52 | 'COMPLEX_MACRO', 53 | 'PREFER_DEV_LEVEL', 54 | 'PREFER_PR_LEVEL', 55 | 'COMPARISON_TO_NULL', 56 | 'BIT_MACRO', 57 | 'CONSTANT_COMPARISON', 58 | 'MACRO_WITH_FLOW_CONTROL', 59 | 60 | # Spams hundreds of lines useless 'struct should 61 | # normally be const' warnings, maybe a bug in 62 | # checkpatch? 63 | 'CONST_STRUCT', 64 | 65 | # TODO: look like valid warnings, investigate 66 | 'MACRO_ARG_REUSE', 67 | 'OPEN_ENDED_LINE', 68 | 'FUNCTION_ARGUMENTS', 69 | 'CONFIG_DESCRIPTION', 70 | 'ASSIGNMENT_CONTINUATIONS', 71 | 'UNNECESSARY_PARENTHESES', 72 | 73 | # Not sure if these really useful warnings, 74 | # disable for now. 75 | 'MACRO_ARG_PRECEDENCE', 76 | 77 | 'BOOL_MEMBER', 78 | ] 79 | 80 | CHECKPATCH_OPTS = ['--strict', '-q', '--terse', '--no-summary', 81 | '--max-line-length=90', '--show-types'] 82 | 83 | checkpatch_filter = [ 84 | ('ath10k_read_simulate_fw_crash', 'LONG_LINE'), 85 | ('wmi_ops', 'LONG_LINE'), 86 | ('wmi_tlv_policy', 'SPACING'), 87 | ('ath10k_core_register_work', 'RETURN_VOID'), 88 | ('ATH10K_HW_RATE_CCK_.*', 'LONG_LINE'), 89 | 90 | # checkpatch doesn't like uninitialized_var() 91 | ('ath10k_init_hw_params', 'FUNCTION_ARGUMENTS'), 92 | ] 93 | 94 | # global variables 95 | 96 | logger = logging.getLogger('ath10k-check') 97 | 98 | threads = 1 99 | 100 | 101 | class CPWarning(): 102 | 103 | def __str__(self): 104 | return 'CPWarning(%s, %s, %s, %s, %s)' % (self.path, self.lineno, 105 | self.tag, self.type, 106 | self.msg) 107 | 108 | def __init__(self): 109 | self.path = '' 110 | self.lineno = '' 111 | self.type = '' 112 | self.msg = '' 113 | self.tag = '' 114 | 115 | 116 | def run_gcc(args): 117 | # to disable utf-8 from gcc, easier to paste that way 118 | os.environ['LC_CTYPE'] = 'C' 119 | 120 | cmd = 'rm -f %s/*.o' % (DRIVER_DIR) 121 | logger.debug('%s' % cmd) 122 | subprocess.call(cmd, shell=True, universal_newlines=True) 123 | 124 | cmd = ['make', '-k', '-j', str(threads)] 125 | 126 | if not args.no_extra: 127 | cmd.append('W=1') 128 | 129 | cmd.append(DRIVER_DIR) 130 | 131 | env = os.environ.copy() 132 | 133 | # disable ccache in case it's in use, it's useless as we are 134 | # compiling only few files and it also breaks GCC's 135 | # -Wimplicit-fallthrough check 136 | env['CCACHE_DISABLE'] = '1' 137 | 138 | logger.debug('%s' % cmd) 139 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 140 | env=env, universal_newlines=True) 141 | (stdout, stderr) = p.communicate() 142 | 143 | stderr = stderr.strip() 144 | 145 | if len(stderr) > 0: 146 | for line in stderr.splitlines(): 147 | match = re.search(FILTER_REGEXP, line) 148 | if not args.no_filter and not match: 149 | logger.debug('FILTERED: %s' % line) 150 | continue 151 | 152 | print(line.strip()) 153 | 154 | return p.returncode 155 | 156 | 157 | def run_sparse(args): 158 | cmd = ['make', '-k', '-j', 159 | str(threads), DRIVER_DIR, 'C=2', 'CF="-D__CHECK_ENDIAN__"'] 160 | logger.debug('%s' % cmd) 161 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 162 | universal_newlines=True) 163 | (stdout, stderr) = p.communicate() 164 | 165 | stderr = stderr.strip() 166 | 167 | if len(stderr) > 0: 168 | for line in stderr.splitlines(): 169 | match = re.search(FILTER_REGEXP, line) 170 | if not args.no_filter and not match: 171 | logger.debug('FILTERED: %s' % line) 172 | continue 173 | 174 | print(line.strip()) 175 | 176 | return p.returncode 177 | 178 | 179 | def find_tagname(tag_map, filename, lineno): 180 | if filename.find('Kconfig') != -1: 181 | return None 182 | 183 | if filename not in tag_map: 184 | return None 185 | 186 | # we need the tags sorted per linenumber 187 | sorted_tags = sorted(tag_map[filename], key=lambda tup: tup[0]) 188 | 189 | lineno = int(lineno) 190 | 191 | prev = None 192 | 193 | # find the tag which is in lineno 194 | for (l, tag) in sorted_tags: 195 | if l > lineno: 196 | return prev 197 | 198 | prev = tag 199 | 200 | return None 201 | 202 | 203 | def parse_checkpatch_warning(line): 204 | m = re.match(r'(.*?):(\d+): .*?:(.*?): (.*)', line, re.M | re.I) 205 | result = CPWarning() 206 | result.path = m.group(1) 207 | result.lineno = m.group(2) 208 | result.type = m.group(3) 209 | result.msg = m.group(4) 210 | 211 | return result 212 | 213 | 214 | def is_filtered(cpwarning): 215 | if cpwarning.tag is None: 216 | return False 217 | 218 | for (tag, type) in checkpatch_filter: 219 | matchobj = re.match(tag, cpwarning.tag) 220 | if matchobj is None: 221 | continue 222 | 223 | if cpwarning.type == type: 224 | return True 225 | 226 | return False 227 | 228 | 229 | def get_checkpatch_cmdline(): 230 | return ['checkpatch.pl'] + CHECKPATCH_OPTS + \ 231 | ['--ignore', ",".join(CHECKPATCH_IGNORE)] 232 | 233 | 234 | def run_checkpatch_cmd(args, q, tag_map): 235 | checkpatch_cmd = get_checkpatch_cmdline() + ['-f'] 236 | 237 | while True: 238 | try: 239 | f = q.get_nowait() 240 | except queue.Empty: 241 | # no more files to check 242 | break 243 | 244 | cmd = checkpatch_cmd + [f] 245 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 246 | universal_newlines=True) 247 | (stdoutdata, stderrdata) = p.communicate() 248 | 249 | if stdoutdata is None: 250 | continue 251 | 252 | lines = stdoutdata.splitlines() 253 | for line in lines: 254 | w = parse_checkpatch_warning(line) 255 | w.tag = find_tagname(tag_map, f, w.lineno) 256 | 257 | if not args.no_filter and is_filtered(w): 258 | logger.debug('FILTERED: %s' % w) 259 | continue 260 | 261 | logger.debug(w) 262 | print('%s:%s: %s' % (w.path, w.lineno, w.msg)) 263 | 264 | q.task_done() 265 | 266 | 267 | def run_checkpatch(args): 268 | # get all files which need to be checked 269 | cmd = 'git ls-tree HEAD %s | cut -f 2' % (DRIVER_DIR) 270 | output = subprocess.check_output(cmd, shell=True, universal_newlines=True) 271 | driver_files = output.splitlines() 272 | 273 | # drop files we need to ignore 274 | for name in IGNORE_FILES: 275 | full_name = '%s%s' % (DRIVER_DIR, name) 276 | if full_name in driver_files: 277 | driver_files.remove(full_name) 278 | 279 | logger.debug('driver_files: %s' % (driver_files)) 280 | 281 | # create global index file 282 | (fd, tmpfilename) = tempfile.mkstemp() 283 | f = os.fdopen(fd, 'w') 284 | f.write('\n'.join(driver_files)) 285 | f.close() 286 | 287 | # FIXME: do we need to call os.close(fd) still? 288 | 289 | cmd = 'gtags -f %s' % (tmpfilename) 290 | logger.debug('%s' % (cmd)) 291 | output = subprocess.check_output(cmd, shell=True, universal_newlines=True) 292 | 293 | os.remove(tmpfilename) 294 | 295 | # tag_map[FILENAME] = [(start line, tagname)] 296 | tag_map = {} 297 | 298 | # create tag mapping 299 | for f in driver_files: 300 | # global gives an error from Kconfig and Makefile 301 | if f.endswith('Kconfig') or f.endswith('Makefile'): 302 | continue 303 | 304 | cmd = 'global -f %s' % (f) 305 | output = subprocess.check_output(cmd, shell=True, universal_newlines=True) 306 | lines = output.splitlines() 307 | for l in lines: 308 | columns = l.split() 309 | tagname = columns[0] 310 | line = int(columns[1]) 311 | 312 | if f not in tag_map: 313 | tag_map[f] = [] 314 | 315 | tag_map[f].append((line, tagname)) 316 | 317 | q = queue.Queue() 318 | 319 | for f in driver_files: 320 | q.put(f) 321 | 322 | # run checkpatch for all files 323 | for i in range(threads): 324 | t = threading.Thread( 325 | target=run_checkpatch_cmd, args=(args, q, tag_map)) 326 | t.daemon = True 327 | t.start() 328 | 329 | q.join() 330 | 331 | return 0 332 | 333 | 334 | def show_version(args): 335 | gcc_version = 'not found' 336 | sparse_version = 'not found' 337 | checkpatch_version = 'not found' 338 | checkpatch_md5sum = 'N/A' 339 | gtags_version = 'not found' 340 | 341 | run = subprocess.check_output 342 | 343 | f = open(sys.argv[0], 'rb') 344 | ath10kcheck_md5sum = hashlib.md5(f.read()).hexdigest() 345 | f.close() 346 | 347 | try: 348 | gcc_version = run(['gcc', '--version'], 349 | universal_newlines=True).splitlines()[0] 350 | except: 351 | pass 352 | 353 | try: 354 | sparse_version = run(['sparse', '--version'], 355 | universal_newlines=True).splitlines()[0] 356 | except: 357 | pass 358 | 359 | try: 360 | checkpatch_version = run(['checkpatch.pl', '--version'], 361 | universal_newlines=True).splitlines()[1] 362 | path = distutils.spawn.find_executable( 363 | 'checkpatch.pl', os.environ['PATH']) 364 | f = open(path, 'rb') 365 | checkpatch_md5sum = hashlib.md5(f.read()).hexdigest() 366 | f.close() 367 | except: 368 | pass 369 | 370 | try: 371 | gtags_version = run(['gtags', '--version'], 372 | universal_newlines=True).splitlines()[0] 373 | except: 374 | pass 375 | 376 | print('ath10k-check (md5sum %s)' % (ath10kcheck_md5sum)) 377 | print 378 | print('gcc:\t\t%s' % (gcc_version)) 379 | print('sparse:\t\t%s' % (sparse_version)) 380 | print('checkpatch.pl:\t%s (md5sum %s)' % (checkpatch_version, checkpatch_md5sum)) 381 | print('gtags:\t\t%s' % (gtags_version)) 382 | 383 | sys.exit(0) 384 | 385 | 386 | def main(): 387 | global threads 388 | 389 | checkpatch_url = GIT_URL % (CHECKPATCH_COMMIT) 390 | 391 | description = '''ath10k source code checker 392 | 393 | Runs various tests (gcc, sparse and checkpatch) with filtering 394 | unnecessary warnings away, the goal is to have empty output from the 395 | script. 396 | 397 | Run this from the main kernel source directory which is preconfigured 398 | with ath10k enabled. gcc recompilation is forced every time, 399 | irrespective if there are any changes in source or not. So this can be 400 | run multiple times and every time the same warnings will appear. 401 | 402 | Requirements (all available in $PATH): 403 | 404 | * gcc 405 | * sparse 406 | * checkpatch.pl 407 | * gtags (from package global) 408 | 409 | ''' 410 | 411 | s = '''Installation: 412 | 413 | As checkpatch is evolving this script always matches a certain version 414 | of checkpatch. Download the checkpatch version from the URL below and 415 | install it somewhere in your $$PATH: 416 | 417 | $CHECKPATCH_URL 418 | 419 | Alternatively if you want manually run checkpatch with the same 420 | settings as ath10k-check uses here's the command line: 421 | 422 | $CHECKPATCH_CMDLINE 423 | ''' 424 | 425 | checkpatch_cmdline = '%s foo.patch' % ' '.join(get_checkpatch_cmdline()) 426 | epilog = string.Template(s).substitute(CHECKPATCH_URL=checkpatch_url, 427 | CHECKPATCH_CMDLINE=checkpatch_cmdline) 428 | 429 | parser = argparse.ArgumentParser(description=description, epilog=epilog, 430 | formatter_class=argparse.RawTextHelpFormatter) 431 | 432 | parser.add_argument('-d', '--debug', action='store_true', 433 | help='enable debug messages') 434 | 435 | parser.add_argument('--fast', action='store_true', 436 | help='run only tests which finish in few seconds') 437 | 438 | parser.add_argument('--no-extra', action='store_true', 439 | help='Do not run extra checks like W=1') 440 | 441 | parser.add_argument('--no-filter', action='store_true', 442 | help='Don\'t filter output with regexp: %r' % (FILTER_REGEXP)) 443 | 444 | parser.add_argument('--version', action='store_true', 445 | help='Show version information about dependencies') 446 | 447 | args = parser.parse_args() 448 | 449 | timefmt = '' 450 | 451 | if args.debug: 452 | logger.setLevel(logging.DEBUG) 453 | timefmt = '%(asctime)s ' 454 | 455 | logfmt = '%s%%(levelname)s: %%(message)s' % (timefmt) 456 | 457 | logging.basicConfig(format=logfmt) 458 | 459 | if args.version: 460 | show_version(args) 461 | 462 | if args.fast: 463 | gcc = True 464 | sparse = True 465 | checkpatch = False 466 | else: 467 | gcc = True 468 | sparse = True 469 | checkpatch = True 470 | 471 | try: 472 | cores = subprocess.check_output(['nproc'], universal_newlines=True) 473 | except (OSError, subprocess.CalledProcessError): 474 | cores = '4' 475 | logger.warning('Failed to run nproc, assuming %s cores' % (cores)) 476 | 477 | threads = int(cores) + 2 478 | 479 | logger.debug('threads %d' % (threads)) 480 | 481 | if gcc: 482 | ret = run_gcc(args) 483 | if ret != 0: 484 | logger.debug('gcc failed: %d', ret) 485 | sys.exit(1) 486 | 487 | if sparse: 488 | ret = run_sparse(args) 489 | if ret != 0: 490 | logger.debug('sparse failed: %d', ret) 491 | sys.exit(2) 492 | 493 | if checkpatch: 494 | ret = run_checkpatch(args) 495 | if ret != 0: 496 | logger.debug('checkpatch failed: %d', ret) 497 | sys.exit(3) 498 | 499 | if __name__ == "__main__": 500 | main() 501 | -------------------------------------------------------------------------------- /tools/scripts/ath11k/ath11k-check: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2015-2017 Qualcomm Atheros, Inc. 4 | # Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for any 7 | # purpose with or without fee is hereby granted, provided that the above 8 | # copyright notice and this permission notice appear in all copies. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | # 18 | # Run 'ath11k-check --help' to see the instructions 19 | # 20 | 21 | import subprocess 22 | import os 23 | import logging 24 | import sys 25 | import argparse 26 | import re 27 | import tempfile 28 | import queue 29 | import threading 30 | import string 31 | import hashlib 32 | import shutil 33 | 34 | CHECKPATCH_COMMIT = '296455ade1fdcf5f8f8c033201633b60946c589a' 35 | CHECKPATCH_MD5SUM = '77c655474ed7622c0077caf2f0d7c440' 36 | 37 | GIT_URL = 'https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/scripts/checkpatch.pl?id=%s' 38 | 39 | DRIVER_DIR = 'drivers/net/wireless/ath/ath11k/' 40 | 41 | FILTER_REGEXP = r'/ath' 42 | 43 | IGNORE_FILES = [] 44 | 45 | CHECKPATCH_IGNORE = ['MSLEEP', 46 | 'USLEEP_RANGE', 47 | 'PRINTK_WITHOUT_KERN_LEVEL', 48 | 49 | # ath10k does not follow networking comment style 50 | 'NETWORKING_BLOCK_COMMENT_STYLE', 51 | 52 | 'LINUX_VERSION_CODE', 53 | 'COMPLEX_MACRO', 54 | 'PREFER_DEV_LEVEL', 55 | 'PREFER_PR_LEVEL', 56 | 'COMPARISON_TO_NULL', 57 | 'BIT_MACRO', 58 | 'CONSTANT_COMPARISON', 59 | 'MACRO_WITH_FLOW_CONTROL', 60 | 61 | # Spams hundreds of lines useless 'struct should 62 | # normally be const' warnings, maybe a bug in 63 | # checkpatch? 64 | 'CONST_STRUCT', 65 | 66 | # TODO: look like valid warnings, investigate 67 | 'MACRO_ARG_REUSE', 68 | 'OPEN_ENDED_LINE', 69 | 'FUNCTION_ARGUMENTS', 70 | 'CONFIG_DESCRIPTION', 71 | 'ASSIGNMENT_CONTINUATIONS', 72 | 'UNNECESSARY_PARENTHESES', 73 | 74 | # Not sure if these really useful warnings, 75 | # disable for now. 76 | 'MACRO_ARG_PRECEDENCE', 77 | 78 | 'BOOL_MEMBER', 79 | 80 | # TODO: ath11k uses volatile for now, fix it 81 | 'VOLATILE', 82 | 83 | # TODO: document all DT usage in ath11k 84 | 'UNDOCUMENTED_DT_STRING', 85 | ] 86 | 87 | CHECKPATCH_OPTS = ['--strict', '-q', '--terse', '--no-summary', 88 | '--max-line-length=90', '--show-types'] 89 | 90 | checkpatch_filter = [ 91 | ('ath11k_read_simulate_fw_crash', 'LONG_LINE'), 92 | ('qmi_wlanfw_respond_mem_req_msg_v01', 'LONG_LINE'), 93 | ] 94 | 95 | sparse_filter = [r'warning: dubious: x & !y'] 96 | 97 | # global variables 98 | 99 | logger = logging.getLogger('ath11k-check') 100 | 101 | threads = 1 102 | 103 | 104 | class CPWarning(): 105 | 106 | def __str__(self): 107 | return 'CPWarning(%s, %s, %s, %s, %s)' % (self.path, self.lineno, 108 | self.tag, self.type, 109 | self.msg) 110 | 111 | def __init__(self): 112 | self.path = '' 113 | self.lineno = '' 114 | self.type = '' 115 | self.msg = '' 116 | self.tag = '' 117 | 118 | 119 | def run_gcc(args): 120 | # to disable utf-8 from gcc, easier to paste that way 121 | os.environ['LC_CTYPE'] = 'C' 122 | 123 | cmd = 'rm -f %s/*.o' % (DRIVER_DIR) 124 | logger.debug('%s' % cmd) 125 | subprocess.call(cmd, shell=True, universal_newlines=True) 126 | 127 | cmd = ['make', '-k', '-j', str(threads)] 128 | 129 | if not args.no_extra: 130 | cmd.append('W=1') 131 | 132 | cmd.append(DRIVER_DIR) 133 | 134 | env = os.environ.copy() 135 | 136 | # disable ccache in case it's in use, it's useless as we are 137 | # compiling only few files and it also breaks GCC's 138 | # -Wimplicit-fallthrough check 139 | env['CCACHE_DISABLE'] = '1' 140 | 141 | logger.debug('%s' % cmd) 142 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 143 | env=env, universal_newlines=True) 144 | (stdout, stderr) = p.communicate() 145 | 146 | stderr = stderr.strip() 147 | 148 | if len(stderr) > 0: 149 | for line in stderr.splitlines(): 150 | match = re.search(FILTER_REGEXP, line) 151 | if not args.no_filter and not match: 152 | logger.debug('FILTERED: %s' % line) 153 | continue 154 | 155 | print(line.strip()) 156 | 157 | return p.returncode 158 | 159 | 160 | def run_sparse(args): 161 | cmd = ['make', '-k', '-j', 162 | str(threads), DRIVER_DIR, 'C=2', 'CF="-D__CHECK_ENDIAN__"'] 163 | logger.debug('%s' % cmd) 164 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 165 | universal_newlines=True) 166 | (stdout, stderr) = p.communicate() 167 | 168 | stderr = stderr.strip() 169 | 170 | if len(stderr) > 0: 171 | for line in stderr.splitlines(): 172 | match = re.search(FILTER_REGEXP, line) 173 | if not args.no_filter and not match: 174 | logger.debug('FILTERED: %s' % line) 175 | continue 176 | 177 | drop = False 178 | 179 | for f in sparse_filter: 180 | match = re.search(f, line) 181 | if not args.no_filter and match: 182 | logger.debug('sparse_filter: %s' % line) 183 | drop = True 184 | break 185 | 186 | if not drop: 187 | print(line.strip()) 188 | 189 | return p.returncode 190 | 191 | 192 | def find_tagname(tag_map, filename, lineno): 193 | if filename.find('Kconfig') != -1: 194 | return None 195 | 196 | if filename not in tag_map: 197 | return None 198 | 199 | # we need the tags sorted per linenumber 200 | sorted_tags = sorted(tag_map[filename], key=lambda tup: tup[0]) 201 | 202 | lineno = int(lineno) 203 | 204 | prev = None 205 | 206 | # find the tag which is in lineno 207 | for (l, tag) in sorted_tags: 208 | if l > lineno: 209 | return prev 210 | 211 | prev = tag 212 | 213 | return None 214 | 215 | 216 | def parse_checkpatch_warning(line): 217 | m = re.match(r'(.*?):(\d+): .*?:(.*?): (.*)', line, re.M | re.I) 218 | result = CPWarning() 219 | result.path = m.group(1) 220 | result.lineno = m.group(2) 221 | result.type = m.group(3) 222 | result.msg = m.group(4) 223 | 224 | return result 225 | 226 | 227 | def is_filtered(cpwarning): 228 | if cpwarning.tag is None: 229 | return False 230 | 231 | for (tag, type) in checkpatch_filter: 232 | matchobj = re.match(tag, cpwarning.tag) 233 | if matchobj is None: 234 | continue 235 | 236 | if cpwarning.type == type: 237 | return True 238 | 239 | return False 240 | 241 | 242 | def get_checkpatch_md5sum(): 243 | path = shutil.which('checkpatch.pl') 244 | f = open(path, 'rb') 245 | md5sum = hashlib.md5(f.read()).hexdigest() 246 | f.close() 247 | 248 | return md5sum 249 | 250 | def get_checkpatch_cmdline(): 251 | return ['checkpatch.pl'] + CHECKPATCH_OPTS + \ 252 | ['--ignore', ",".join(CHECKPATCH_IGNORE)] 253 | 254 | 255 | def run_checkpatch_cmd(args, q, tag_map): 256 | checkpatch_cmd = get_checkpatch_cmdline() + ['-f'] 257 | 258 | while True: 259 | try: 260 | f = q.get_nowait() 261 | except queue.Empty: 262 | # no more files to check 263 | break 264 | 265 | cmd = checkpatch_cmd + [f] 266 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 267 | universal_newlines=True) 268 | (stdoutdata, stderrdata) = p.communicate() 269 | 270 | if stdoutdata is None: 271 | continue 272 | 273 | lines = stdoutdata.splitlines() 274 | for line in lines: 275 | w = parse_checkpatch_warning(line) 276 | w.tag = find_tagname(tag_map, f, w.lineno) 277 | 278 | if not args.no_filter and is_filtered(w): 279 | logger.debug('FILTERED: %s' % w) 280 | continue 281 | 282 | logger.debug(w) 283 | print('%s:%s: %s' % (w.path, w.lineno, w.msg)) 284 | 285 | q.task_done() 286 | 287 | 288 | def run_checkpatch(args): 289 | md5sum = get_checkpatch_md5sum() 290 | if md5sum != CHECKPATCH_MD5SUM: 291 | print('WARNING: checkpatch.pl md5sum %s does not match with %s' % 292 | (md5sum, CHECKPATCH_MD5SUM)) 293 | 294 | # get all files which need to be checked 295 | cmd = 'git ls-tree HEAD %s | cut -f 2' % (DRIVER_DIR) 296 | output = subprocess.check_output(cmd, shell=True, universal_newlines=True) 297 | driver_files = output.splitlines() 298 | 299 | # drop files we need to ignore 300 | for name in IGNORE_FILES: 301 | full_name = '%s%s' % (DRIVER_DIR, name) 302 | if full_name in driver_files: 303 | driver_files.remove(full_name) 304 | 305 | logger.debug('driver_files: %s' % (driver_files)) 306 | 307 | # create global index file 308 | (fd, tmpfilename) = tempfile.mkstemp() 309 | f = os.fdopen(fd, 'w') 310 | f.write('\n'.join(driver_files)) 311 | f.close() 312 | 313 | # FIXME: do we need to call os.close(fd) still? 314 | 315 | cmd = 'gtags -f %s' % (tmpfilename) 316 | logger.debug('%s' % (cmd)) 317 | output = subprocess.check_output(cmd, shell=True, universal_newlines=True) 318 | 319 | os.remove(tmpfilename) 320 | 321 | # tag_map[FILENAME] = [(start line, tagname)] 322 | tag_map = {} 323 | 324 | # create tag mapping 325 | for f in driver_files: 326 | # global gives an error from Kconfig and Makefile 327 | if f.endswith('Kconfig') or f.endswith('Makefile'): 328 | continue 329 | 330 | cmd = 'global -f %s' % (f) 331 | output = subprocess.check_output(cmd, shell=True, universal_newlines=True) 332 | lines = output.splitlines() 333 | for l in lines: 334 | columns = l.split() 335 | tagname = columns[0] 336 | line = int(columns[1]) 337 | 338 | if f not in tag_map: 339 | tag_map[f] = [] 340 | 341 | tag_map[f].append((line, tagname)) 342 | 343 | q = queue.Queue() 344 | 345 | for f in driver_files: 346 | q.put(f) 347 | 348 | # run checkpatch for all files 349 | for i in range(threads): 350 | t = threading.Thread( 351 | target=run_checkpatch_cmd, args=(args, q, tag_map)) 352 | t.daemon = True 353 | t.start() 354 | 355 | q.join() 356 | 357 | return 0 358 | 359 | 360 | def show_version(args): 361 | gcc_version = 'not found' 362 | sparse_version = 'not found' 363 | checkpatch_version = 'not found' 364 | checkpatch_md5sum = 'N/A' 365 | gtags_version = 'not found' 366 | 367 | run = subprocess.check_output 368 | 369 | f = open(sys.argv[0], 'rb') 370 | ath11kcheck_md5sum = hashlib.md5(f.read()).hexdigest() 371 | f.close() 372 | 373 | try: 374 | gcc_version = run(['gcc', '--version'], 375 | universal_newlines=True).splitlines()[0] 376 | except: 377 | pass 378 | 379 | try: 380 | sparse_version = run(['sparse', '--version'], 381 | universal_newlines=True).splitlines()[0] 382 | except: 383 | pass 384 | 385 | try: 386 | checkpatch_version = run(['checkpatch.pl', '--version'], 387 | universal_newlines=True).splitlines()[1] 388 | checkpatch_md5sum = get_checkpatch_md5sum() 389 | except: 390 | pass 391 | 392 | try: 393 | gtags_version = run(['gtags', '--version'], 394 | universal_newlines=True).splitlines()[0] 395 | except: 396 | pass 397 | 398 | print('ath11k-check (md5sum %s)' % (ath11kcheck_md5sum)) 399 | print() 400 | print('python:\t\t%s' % (sys.version)) 401 | print('gcc:\t\t%s' % (gcc_version)) 402 | print('sparse:\t\t%s' % (sparse_version)) 403 | print('checkpatch.pl:\t%s (md5sum %s)' % (checkpatch_version, checkpatch_md5sum)) 404 | print('gtags:\t\t%s' % (gtags_version)) 405 | 406 | sys.exit(0) 407 | 408 | 409 | def main(): 410 | global threads 411 | 412 | checkpatch_url = GIT_URL % (CHECKPATCH_COMMIT) 413 | 414 | description = '''ath11k source code checker 415 | 416 | Runs various tests (gcc, sparse and checkpatch) with filtering 417 | unnecessary warnings away, the goal is to have empty output from the 418 | script. 419 | 420 | Run this from the main kernel source directory which is preconfigured 421 | with ath11k enabled. gcc recompilation is forced every time, 422 | irrespective if there are any changes in source or not. So this can be 423 | run multiple times and every time the same warnings will appear. 424 | 425 | Requirements (all available in $PATH): 426 | 427 | * gcc 428 | * sparse 429 | * checkpatch.pl 430 | * gtags (from package global) 431 | 432 | ''' 433 | 434 | s = '''Installation: 435 | 436 | As checkpatch is evolving this script always matches a certain version 437 | of checkpatch. Download the checkpatch version from the URL below and 438 | install it somewhere in your $$PATH: 439 | 440 | $CHECKPATCH_URL 441 | 442 | Alternatively if you want manually run checkpatch with the same 443 | settings as ath11k-check uses here's the command line: 444 | 445 | $CHECKPATCH_CMDLINE 446 | ''' 447 | 448 | checkpatch_cmdline = '%s foo.patch' % ' '.join(get_checkpatch_cmdline()) 449 | epilog = string.Template(s).substitute(CHECKPATCH_URL=checkpatch_url, 450 | CHECKPATCH_CMDLINE=checkpatch_cmdline) 451 | 452 | parser = argparse.ArgumentParser(description=description, epilog=epilog, 453 | formatter_class=argparse.RawTextHelpFormatter) 454 | 455 | parser.add_argument('-d', '--debug', action='store_true', 456 | help='enable debug messages') 457 | 458 | parser.add_argument('--fast', action='store_true', 459 | help='run only tests which finish in few seconds') 460 | 461 | parser.add_argument('--no-extra', action='store_true', 462 | help='Do not run extra checks like W=1') 463 | 464 | parser.add_argument('--no-filter', action='store_true', 465 | help='Don\'t filter output with regexp: %r' % (FILTER_REGEXP)) 466 | 467 | parser.add_argument('--version', action='store_true', 468 | help='Show version information about dependencies') 469 | 470 | args = parser.parse_args() 471 | 472 | timefmt = '' 473 | 474 | if args.debug: 475 | logger.setLevel(logging.DEBUG) 476 | timefmt = '%(asctime)s ' 477 | 478 | logfmt = '%s%%(levelname)s: %%(message)s' % (timefmt) 479 | 480 | logging.basicConfig(format=logfmt) 481 | 482 | if args.version: 483 | show_version(args) 484 | 485 | if args.fast: 486 | gcc = True 487 | sparse = True 488 | checkpatch = False 489 | else: 490 | gcc = True 491 | sparse = True 492 | checkpatch = True 493 | 494 | try: 495 | cores = subprocess.check_output(['nproc'], universal_newlines=True) 496 | except OSError as xxx_todo_changeme: 497 | subprocess.CalledProcessError = xxx_todo_changeme 498 | cores = '4' 499 | logger.warning('Failed to run nproc, assuming %s cores' % (cores)) 500 | 501 | threads = int(cores) + 2 502 | 503 | logger.debug('threads %d' % (threads)) 504 | 505 | if gcc: 506 | ret = run_gcc(args) 507 | if ret != 0: 508 | logger.debug('gcc failed: %d', ret) 509 | sys.exit(1) 510 | 511 | if sparse: 512 | ret = run_sparse(args) 513 | if ret != 0: 514 | logger.debug('sparse failed: %d', ret) 515 | sys.exit(2) 516 | 517 | if checkpatch: 518 | ret = run_checkpatch(args) 519 | if ret != 0: 520 | logger.debug('checkpatch failed: %d', ret) 521 | sys.exit(3) 522 | 523 | if __name__ == "__main__": 524 | main() 525 | -------------------------------------------------------------------------------- /tools/scripts/ath12k/ath12k-check: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2015-2017 Qualcomm Atheros, Inc. 4 | # Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for any 7 | # purpose with or without fee is hereby granted, provided that the above 8 | # copyright notice and this permission notice appear in all copies. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | # 18 | # Run 'ath12k-check --help' to see the instructions 19 | # 20 | 21 | import subprocess 22 | import os 23 | import logging 24 | import sys 25 | import argparse 26 | import re 27 | import tempfile 28 | import queue 29 | import threading 30 | import string 31 | import hashlib 32 | import shutil 33 | 34 | CHECKPATCH_COMMIT = '296455ade1fdcf5f8f8c033201633b60946c589a' 35 | CHECKPATCH_MD5SUM = '77c655474ed7622c0077caf2f0d7c440' 36 | 37 | GIT_URL = 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/scripts/checkpatch.pl?id=%s' 38 | 39 | DRIVER_DIR = 'drivers/net/wireless/ath/ath12k/' 40 | 41 | FILTER_REGEXP = r'/ath' 42 | 43 | # Example: CONFIG_CC_VERSION_TEXT="x86_64-linux-gcc (GCC) 13.2.0" 44 | CONFIG_CC_REGEXP = r'^CONFIG_CC_VERSION_TEXT="(.*)"$' 45 | 46 | IGNORE_FILES = [] 47 | 48 | CHECKPATCH_IGNORE = [ 49 | # some find extra parentheses helpful so ignore the warnings 50 | 'UNNECESSARY_PARENTHESES', 51 | ] 52 | 53 | CHECKPATCH_OPTS = ['--strict', '-q', '--terse', '--no-summary', 54 | '--max-line-length=90', '--show-types'] 55 | 56 | checkpatch_filter = [ 57 | ('qmi_wlanfw_respond_mem_req_msg_v01', 'LONG_LINE'), 58 | ('qmi_wlanfw_host_cap_req_msg_v01', 'LONG_LINE'), 59 | ('qmi_wlfw_qdss_trace_config_download_req_msg_v01_ei', 'LONG_LINE'), 60 | ('qmi_wlanfw_qdss_trace_config_download_resp_msg_v01_ei', 'LONG_LINE'), 61 | 62 | # workaround for long lines in 63 | # qmi_wlfw_qdss_trace_config_download_req_msg_v01_ei, for some 64 | # reason gtags claim they are part of 65 | # ATH12K_QMI_MAX_CHUNK_SIZE 66 | ('ATH12K_QMI_MAX_CHUNK_SIZE', 'LONG_LINE'), 67 | 68 | # allow long line copyrights 69 | # note gtags returns None so search for the literal string 70 | ('Copyright (c)', 'LONG_LINE_COMMENT'), 71 | 72 | # trace.h has warnings which don't make sense to fix 73 | ('TRACE_SYSTEM', 'OPEN_ENDED_LINE'), 74 | 75 | # couldn't figure out how to make checkpatch happy with these macros 76 | ('SVC', 'COMPLEX_MACRO'), 77 | ('C2S', 'COMPLEX_MACRO'), 78 | ('C2S', 'MACRO_WITH_FLOW_CONTROL'), 79 | 80 | # this use of volatile should be ok 81 | ('ath12k_hal_srng_access_begin', 'VOLATILE'), 82 | ('ath12k_hal_srng_access_end', 'VOLATILE'), 83 | ('hal_srng', 'VOLATILE'), 84 | 85 | # __ath12k_dbg has to use dev_printk() so that debug_mask always work 86 | ('__ath12k_dbg', 'PREFER_DEV_LEVEL'), 87 | ('__ath12k_dbg', 'PREFER_PR_LEVEL'), 88 | 89 | # couldn't figure a way to avoid the reuse warning 90 | ('for_each_ar', 'MACRO_ARG_REUSE'), 91 | ] 92 | 93 | sparse_filter = [] 94 | 95 | # global variables 96 | 97 | logger = logging.getLogger('ath12k-check') 98 | 99 | threads = 1 100 | 101 | 102 | class CPWarning(): 103 | 104 | def __str__(self): 105 | return 'CPWarning(%s, %s, %s, %s, %s)' % (self.path, self.lineno, 106 | self.tag, self.type, 107 | self.msg) 108 | 109 | def __init__(self): 110 | self.path = '' 111 | self.lineno = '' 112 | self.type = '' 113 | self.msg = '' 114 | self.tag = '' 115 | 116 | 117 | def run_gcc(args): 118 | # to disable utf-8 from gcc, easier to paste that way 119 | os.environ['LC_CTYPE'] = 'C' 120 | 121 | cmd = 'find %s -name "*.o" -type f -delete' % (DRIVER_DIR) 122 | logger.debug('%s' % cmd) 123 | subprocess.call(cmd, shell=True, universal_newlines=True) 124 | 125 | cmd = ['make', '-k', '-j', str(threads)] 126 | 127 | if not args.no_extra: 128 | cmd.append('W=1') 129 | 130 | cmd.append(DRIVER_DIR) 131 | 132 | env = os.environ.copy() 133 | 134 | # disable ccache in case it's in use, it's useless as we are 135 | # compiling only few files and it also breaks GCC's 136 | # -Wimplicit-fallthrough check 137 | env['CCACHE_DISABLE'] = '1' 138 | 139 | logger.debug('%s' % cmd) 140 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 141 | env=env, universal_newlines=True) 142 | (stdout, stderr) = p.communicate() 143 | 144 | stderr = stderr.strip() 145 | 146 | if len(stderr) > 0: 147 | for line in stderr.splitlines(): 148 | match = re.search(FILTER_REGEXP, line) 149 | if not args.no_filter and not match: 150 | logger.debug('FILTERED: %s' % line) 151 | continue 152 | 153 | print(line.strip()) 154 | 155 | return p.returncode 156 | 157 | 158 | def run_sparse(args): 159 | cmd = ['make', '-k', '-j', 160 | str(threads), DRIVER_DIR, 'C=2', 'CF="-D__CHECK_ENDIAN__"'] 161 | logger.debug('%s' % cmd) 162 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 163 | universal_newlines=True) 164 | (stdout, stderr) = p.communicate() 165 | 166 | stderr = stderr.strip() 167 | 168 | if len(stderr) > 0: 169 | for line in stderr.splitlines(): 170 | match = re.search(FILTER_REGEXP, line) 171 | if not args.no_filter and not match: 172 | logger.debug('FILTERED: %s' % line) 173 | continue 174 | 175 | drop = False 176 | 177 | for f in sparse_filter: 178 | match = re.search(f, line) 179 | if not args.no_filter and match: 180 | logger.debug('sparse_filter: %s' % line) 181 | drop = True 182 | break 183 | 184 | if not drop: 185 | print(line.strip()) 186 | 187 | return p.returncode 188 | 189 | 190 | def find_tagname(tag_map, filename, lineno): 191 | if filename.find('Kconfig') != -1: 192 | return None 193 | 194 | if filename not in tag_map: 195 | return None 196 | 197 | # we need the tags sorted per linenumber 198 | sorted_tags = sorted(tag_map[filename], key=lambda tup: tup[0]) 199 | 200 | lineno = int(lineno) 201 | 202 | prev = None 203 | 204 | # find the tag which is in lineno 205 | for (l, tag) in sorted_tags: 206 | if l > lineno: 207 | return prev 208 | 209 | prev = tag 210 | 211 | return None 212 | 213 | 214 | def parse_checkpatch_warning(line): 215 | m = re.match(r'(.*?):(\d+): .*?:(.*?): (.*)', line, re.M | re.I) 216 | result = CPWarning() 217 | result.path = m.group(1) 218 | result.lineno = m.group(2) 219 | result.type = m.group(3) 220 | result.msg = m.group(4) 221 | 222 | return result 223 | 224 | 225 | def is_filtered(cpwarning): 226 | for (tag, type) in checkpatch_filter: 227 | if cpwarning.tag is not None: 228 | # the global tool was able to find a tag name for this 229 | # line so use it directly 230 | matchobj = re.match(tag, cpwarning.tag) 231 | if matchobj is None: 232 | continue 233 | 234 | if cpwarning.type == type: 235 | return True 236 | else: 237 | # the global tool was not able to find a tag name for this 238 | # line so instead check the actual line in the file 239 | f = open(cpwarning.path) 240 | buf = f.read() 241 | f.close() 242 | 243 | lineno = int(cpwarning.lineno) - 1 244 | lines = buf.splitlines() 245 | line = lines[lineno] 246 | logger.debug('file %r tag %r line %r' % (cpwarning.path, tag, line)) 247 | 248 | if tag in line: 249 | return True 250 | 251 | return False 252 | 253 | 254 | def get_checkpatch_md5sum(): 255 | path = shutil.which('checkpatch.pl') 256 | f = open(path, 'rb') 257 | md5sum = hashlib.md5(f.read()).hexdigest() 258 | f.close() 259 | 260 | return md5sum 261 | 262 | def get_checkpatch_cmdline(): 263 | return ['checkpatch.pl'] + CHECKPATCH_OPTS + \ 264 | ['--ignore', ",".join(CHECKPATCH_IGNORE)] 265 | 266 | 267 | def run_checkpatch_cmd(args, q, tag_map): 268 | checkpatch_cmd = get_checkpatch_cmdline() + ['-f'] 269 | 270 | while True: 271 | try: 272 | f = q.get_nowait() 273 | except queue.Empty: 274 | # no more files to check 275 | break 276 | 277 | cmd = checkpatch_cmd + [f] 278 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 279 | universal_newlines=True) 280 | (stdoutdata, stderrdata) = p.communicate() 281 | 282 | if stdoutdata is None: 283 | continue 284 | 285 | lines = stdoutdata.splitlines() 286 | for line in lines: 287 | w = parse_checkpatch_warning(line) 288 | w.tag = find_tagname(tag_map, f, w.lineno) 289 | 290 | if not args.no_filter and is_filtered(w): 291 | logger.debug('FILTERED: %s' % w) 292 | continue 293 | 294 | logger.debug(w) 295 | print('%s:%s: %s' % (w.path, w.lineno, w.msg)) 296 | 297 | q.task_done() 298 | 299 | # get all driver files which are commited to git, includes Kconfig, Makefile etc 300 | def get_commited_files(): 301 | cmd = ['git', 'ls-tree', '-r', '--name-only', 'HEAD', DRIVER_DIR] 302 | output = subprocess.check_output(cmd, universal_newlines=True) 303 | return output.splitlines() 304 | 305 | def run_checkpatch(args): 306 | md5sum = get_checkpatch_md5sum() 307 | if md5sum != CHECKPATCH_MD5SUM: 308 | print('WARNING: checkpatch.pl md5sum %s does not match with %s' % 309 | (md5sum, CHECKPATCH_MD5SUM)) 310 | 311 | driver_files = get_commited_files() 312 | 313 | # drop files we need to ignore 314 | for name in IGNORE_FILES: 315 | full_name = '%s%s' % (DRIVER_DIR, name) 316 | if full_name in driver_files: 317 | driver_files.remove(full_name) 318 | 319 | logger.debug('driver_files: %s' % (driver_files)) 320 | 321 | # create global index file 322 | (fd, tmpfilename) = tempfile.mkstemp() 323 | f = os.fdopen(fd, 'w') 324 | f.write('\n'.join(driver_files)) 325 | f.close() 326 | 327 | # FIXME: do we need to call os.close(fd) still? 328 | 329 | cmd = 'gtags -f %s' % (tmpfilename) 330 | logger.debug('%s' % (cmd)) 331 | output = subprocess.check_output(cmd, shell=True, universal_newlines=True) 332 | 333 | os.remove(tmpfilename) 334 | 335 | # tag_map[FILENAME] = [(start line, tagname)] 336 | tag_map = {} 337 | 338 | # create tag mapping 339 | for f in driver_files: 340 | # global gives an error from Kconfig and Makefile 341 | if f.endswith('Kconfig') or f.endswith('Makefile'): 342 | continue 343 | 344 | cmd = 'global -f %s' % (f) 345 | output = subprocess.check_output(cmd, shell=True, universal_newlines=True) 346 | lines = output.splitlines() 347 | for l in lines: 348 | columns = l.split() 349 | tagname = columns[0] 350 | line = int(columns[1]) 351 | 352 | if f not in tag_map: 353 | tag_map[f] = [] 354 | 355 | tag_map[f].append((line, tagname)) 356 | 357 | q = queue.Queue() 358 | 359 | for f in driver_files: 360 | q.put(f) 361 | 362 | # run checkpatch for all files 363 | for i in range(threads): 364 | t = threading.Thread( 365 | target=run_checkpatch_cmd, args=(args, q, tag_map)) 366 | t.daemon = True 367 | t.start() 368 | 369 | q.join() 370 | 371 | return 0 372 | 373 | def run_kdoc(args): 374 | p = subprocess.run(['scripts/kernel-doc', '-Werror', '-none'] + 375 | get_commited_files()) 376 | return p.returncode 377 | 378 | def show_version(args): 379 | host_gcc_version = 'not found' 380 | config_cc_version = 'not found' 381 | sparse_version = 'not found' 382 | checkpatch_version = 'not found' 383 | checkpatch_md5sum = 'N/A' 384 | gtags_version = 'not found' 385 | 386 | run = subprocess.check_output 387 | 388 | f = open(sys.argv[0], 'rb') 389 | ath12kcheck_md5sum = hashlib.md5(f.read()).hexdigest() 390 | f.close() 391 | 392 | try: 393 | host_gcc_version = run(['gcc', '--version'], 394 | universal_newlines=True).splitlines()[0] 395 | except: 396 | pass 397 | 398 | try: 399 | f = open('.config') 400 | m = re.search(CONFIG_CC_REGEXP, f.read(), re.MULTILINE) 401 | if m is not None: 402 | config_cc_version = m.group(1) 403 | f.close() 404 | except: 405 | pass 406 | 407 | try: 408 | sparse_version = run(['sparse', '--version'], 409 | universal_newlines=True).splitlines()[0] 410 | except: 411 | pass 412 | 413 | try: 414 | checkpatch_version = run(['checkpatch.pl', '--version'], 415 | universal_newlines=True).splitlines()[1] 416 | checkpatch_md5sum = get_checkpatch_md5sum() 417 | except: 418 | pass 419 | 420 | try: 421 | gtags_version = run(['gtags', '--version'], 422 | universal_newlines=True).splitlines()[0] 423 | except: 424 | pass 425 | 426 | print('ath12k-check (md5sum %s)' % (ath12kcheck_md5sum)) 427 | print() 428 | print('python:\t\t%s' % (sys.version)) 429 | print('host gcc:\t%s' % (host_gcc_version)) 430 | print('config cc:\t%s' % (config_cc_version)) 431 | print('sparse:\t\t%s' % (sparse_version)) 432 | print('checkpatch.pl:\t%s (md5sum %s)' % (checkpatch_version, checkpatch_md5sum)) 433 | print('gtags:\t\t%s' % (gtags_version)) 434 | 435 | sys.exit(0) 436 | 437 | 438 | def main(): 439 | global threads 440 | 441 | checkpatch_url = GIT_URL % (CHECKPATCH_COMMIT) 442 | 443 | description = '''ath12k source code checker 444 | 445 | Runs various tests (gcc, sparse and checkpatch) with filtering 446 | unnecessary warnings away, the goal is to have empty output from the 447 | script. 448 | 449 | Run this from the main kernel source directory which is preconfigured 450 | with ath12k enabled. gcc recompilation of ath12k is forced every time, 451 | irrespective if there are any changes in source or not. So this can be 452 | run multiple times and every time the same warnings will appear. 453 | 454 | Requirements (all available in $PATH): 455 | 456 | * gcc 457 | * sparse 458 | * checkpatch.pl 459 | * gtags (from package global) 460 | 461 | ''' 462 | 463 | s = '''Installation: 464 | 465 | It is assumed below that ~/bin is part of user's $$PATH. If it's not, 466 | replace ~/bin with a suitable directory. 467 | 468 | To install or update to the latest version of ath12k-check: 469 | 470 | wget https://github.com/qca/qca-swiss-army-knife/raw/master/tools/scripts/ath12k/ath12k-check 471 | cp ath12k-check ~/bin/ 472 | 473 | It's strongly recommend to use the latest GCC version from crosstool: 474 | 475 | https://mirrors.edge.kernel.org/pub/tools/crosstool/ 476 | 477 | Unpack the compiler for example to /opt/cross/ and in the Linux kernel 478 | sources create a new file called GNUmakefile with contents: 479 | 480 | ARCH=x86 481 | CROSS_COMPILE=/opt/cross/gcc-13.2.0-nolibc/x86_64-linux/bin/x86_64-linux- 482 | export ARCH 483 | export CROSS_COMPILE 484 | 485 | Now the kernel will be compiled with the compiler from /opt/cross. 486 | 487 | Latest development version of sparse is needed, install it manually 488 | from the git repository: 489 | 490 | git clone https://git.kernel.org/pub/scm/devel/sparse/sparse.git/ 491 | cd sparse 492 | make 493 | cp sparse ~/bin/ 494 | 495 | As checkpatch is evolving and new tests are added, it's important that 496 | a correct version of checkpatch is used. If a wrong version is used 497 | ath12k-check will warn about that. To download the correct checkpatch 498 | version and install it to ~/bin: 499 | 500 | wget -O checkpatch.pl $CHECKPATCH_URL 501 | cp checkpatch.pl ~/bin/ 502 | 503 | Note that the URL in above wget command is dynamically created and 504 | will change everytime ath12k-check is updated to use a new version of 505 | checkpatch.pl 506 | 507 | For gtags program you need to install package named global, for 508 | example in Debian/Ubuntu you can do that using apt: 509 | 510 | apt install global 511 | 512 | Alternatively (but not recommended!) if you want manually run 513 | checkpatch with the same settings as ath12k-check uses here's the 514 | command line: 515 | 516 | $CHECKPATCH_CMDLINE 517 | ''' 518 | 519 | checkpatch_cmdline = '%s foo.patch' % ' '.join(get_checkpatch_cmdline()) 520 | epilog = string.Template(s).substitute(CHECKPATCH_URL=checkpatch_url, 521 | CHECKPATCH_CMDLINE=checkpatch_cmdline) 522 | 523 | parser = argparse.ArgumentParser(description=description, epilog=epilog, 524 | formatter_class=argparse.RawTextHelpFormatter) 525 | 526 | parser.add_argument('-d', '--debug', action='store_true', 527 | help='enable debug messages') 528 | 529 | parser.add_argument('--fast', action='store_true', 530 | help='run only tests which finish in few seconds') 531 | 532 | parser.add_argument('--no-extra', action='store_true', 533 | help='Do not run extra checks like W=1') 534 | 535 | parser.add_argument('--no-filter', action='store_true', 536 | help='Don\'t filter output with regexp: %r' % (FILTER_REGEXP)) 537 | 538 | parser.add_argument('--version', action='store_true', 539 | help='Show version information about dependencies') 540 | 541 | args = parser.parse_args() 542 | 543 | timefmt = '' 544 | 545 | if args.debug: 546 | logger.setLevel(logging.DEBUG) 547 | timefmt = '%(asctime)s ' 548 | 549 | logfmt = '%s%%(levelname)s: %%(message)s' % (timefmt) 550 | 551 | logging.basicConfig(format=logfmt) 552 | 553 | if args.version: 554 | show_version(args) 555 | 556 | if args.fast: 557 | gcc = True 558 | sparse = True 559 | checkpatch = False 560 | else: 561 | gcc = True 562 | sparse = True 563 | checkpatch = True 564 | 565 | try: 566 | cores = subprocess.check_output(['nproc'], universal_newlines=True) 567 | except OSError as xxx_todo_changeme: 568 | subprocess.CalledProcessError = xxx_todo_changeme 569 | cores = '4' 570 | logger.warning('Failed to run nproc, assuming %s cores' % (cores)) 571 | 572 | threads = int(cores) + 2 573 | 574 | logger.debug('threads %d' % (threads)) 575 | 576 | if gcc: 577 | ret = run_gcc(args) 578 | if ret != 0: 579 | logger.debug('gcc failed: %d', ret) 580 | sys.exit(1) 581 | 582 | if sparse: 583 | ret = run_sparse(args) 584 | if ret != 0: 585 | logger.debug('sparse failed: %d', ret) 586 | sys.exit(2) 587 | 588 | if checkpatch: 589 | ret = run_checkpatch(args) 590 | if ret != 0: 591 | logger.debug('checkpatch failed: %d', ret) 592 | sys.exit(3) 593 | 594 | ret = run_kdoc(args) 595 | if ret != 0: 596 | logger.debug('kernel-doc failed: %d', ret) 597 | sys.exit(4) 598 | 599 | if __name__ == "__main__": 600 | main() 601 | -------------------------------------------------------------------------------- /tools/scripts/ath9k/irq-watch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # Copyright (c) 2010 Atheros Communications Inc. 3 | # 4 | # Permission to use, copy, modify, and/or distribute this software for any 5 | # purpose with or without fee is hereby granted, provided that the above 6 | # copyright notice and this permission notice appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | # 16 | 17 | # IRQ monitor utility for ath9k. 18 | 19 | # The ath9k debugfs stuff is nice but sometimes you want more 20 | # complicated analysis of the values. This shows you the actual 21 | # number of IRQs, the average and the rate of change. 22 | 23 | my $file="/sys/kernel/debug/ath9k/phy0/interrupt"; 24 | 25 | my %irqs = (); 26 | my %irqs_next = (); 27 | my %irqs_total = (); 28 | my $loop_count = 0; 29 | my %old_irq_diff = 0; 30 | 31 | while (1) { 32 | open(FILE, $file) or die "Cannot open $file: $!.\n"; 33 | while () { 34 | if (m/^\s*(\S*):\s+(\d+)/o) { 35 | $irqs{$1} = $2; 36 | } 37 | } 38 | close(FILE); 39 | 40 | sleep 1; 41 | 42 | system("clear"); 43 | printf("IRQ monitor for ath9k, Loop count: %d\n", $loop_count+1); 44 | printf("%10s\t%10s\t%10s\t%10s\n", "IRQ-type", "delta", "Average", "dy/dx"); 45 | 46 | open(FILE, $file) or die "Cannot open $file: $!.\n"; 47 | while () { 48 | if (m/^\s*(\S*):\s+(\d+)/o) { 49 | $irqs_next{$1} = $2; 50 | } 51 | } 52 | close(FILE); 53 | 54 | $loop_count++; 55 | 56 | foreach $irq (keys %irqs) { 57 | my $irq_diff = $irqs_next{$irq} - $irqs{$irq}; 58 | 59 | $irqs_total{$irq} += $irq_diff; 60 | 61 | printf("%10s\t%10d\t%10d\t%10d\n", 62 | $irq, 63 | $irq_diff, 64 | $irqs_total{$irq} / $loop_count, 65 | $irq_diff - $old_irq_diff{$irq}); 66 | 67 | $old_irq_diff{$irq} = $irq_diff; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tools/scripts/ath9k/read-powers: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # Copyright (c) 2010 Atheros Communications Inc. 4 | # 5 | # Written by Luis R. Rodriguez 6 | # 7 | # Permission to use, copy, modify, and/or distribute this software for any 8 | # purpose with or without fee is hereby granted, provided that the above 9 | # copyright notice and this permission notice appear in all copies. 10 | # 11 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 | 19 | # This script can be used to read and interpret the power rate registers 20 | # for AR9003 using ath9k through debugfs. To use this you will need applied: 21 | # 22 | # 0001-ath9k-Add-debugfs-interface-to-dump-registers.patch 23 | # 24 | # from the crap/ directory of compat-wireless 25 | # 26 | # Usage: cat /sys/kernel/debug/ath9k/phy0/regdump | read-powers 27 | 28 | # TODO: 29 | # 30 | # - fix floating point calculations, right now we round off 31 | # - test with AR5008, AR9001, AR9002, and then ath5k family. 32 | 33 | import string, sys 34 | 35 | cck_rates = { 36 | "1L" : 0, # DSSS 37 | "2L" : 0, # DSSS 38 | "2S" : 0, # DSSS 39 | "5.5L" : 0, # CCK 40 | "5.5S" : 0, # CCK 41 | "11L" : 0, # CCK 42 | "11S" : 0, # CCK 43 | } 44 | 45 | ofdm_rates = { 46 | "6" : 0, 47 | "9" : 0, 48 | "12" : 0, 49 | "18" : 0, 50 | "24" : 0, 51 | "36" : 0, 52 | "48" : 0, 53 | "54" : 0, 54 | } 55 | 56 | mcs_rates_ht20 = { 57 | "0" : 0, 58 | "1" : 0, 59 | "2" : 0, 60 | "3" : 0, 61 | "4" : 0, 62 | "5" : 0, 63 | "6" : 0, 64 | "7" : 0, 65 | "8" : 0, 66 | "9" : 0, 67 | "10" : 0, 68 | "11" : 0, 69 | "12" : 0, 70 | "13" : 0, 71 | "14" : 0, 72 | "15" : 0, 73 | "16" : 0, 74 | "17" : 0, 75 | "18" : 0, 76 | "19" : 0, 77 | "20" : 0, 78 | "21" : 0, 79 | } 80 | 81 | mcs_rates_ht40 = { 82 | "0" : 0, 83 | "1" : 0, 84 | "2" : 0, 85 | "3" : 0, 86 | "4" : 0, 87 | "5" : 0, 88 | "6" : 0, 89 | "7" : 0, 90 | "8" : 0, 91 | "9" : 0, 92 | "10" : 0, 93 | "11" : 0, 94 | "12" : 0, 95 | "13" : 0, 96 | "14" : 0, 97 | "15" : 0, 98 | "16" : 0, 99 | "17" : 0, 100 | "18" : 0, 101 | "19" : 0, 102 | "20" : 0, 103 | "21" : 0, 104 | } 105 | 106 | # Not sure what this is 107 | ext_dup_rates = { 108 | "40 dup CCK" : 0, 109 | "40 dup OFDM" : 0, 110 | "20 ext CCK" : 0, 111 | "20 ext OFDM" : 0, 112 | } 113 | 114 | def powertx_rate1 (val): 115 | ofdm_rates["6"] = (val >> 0) & 0xff; 116 | ofdm_rates["9"] = (val >> 8) & 0xff; 117 | ofdm_rates["12"] = (val >> 16) & 0xff 118 | ofdm_rates["18"] = (val >> 24) & 0xff 119 | 120 | print("%010s: 0x%08x" % ("Rate 1", val)) 121 | 122 | def powertx_rate2 (val): 123 | ofdm_rates["24"] = (val >> 0) & 0xff; 124 | ofdm_rates["36"] = (val >> 8) & 0xff; 125 | ofdm_rates["48"] = (val >> 16) & 0xff 126 | ofdm_rates["54"] = (val >> 24) & 0xff 127 | 128 | print("%010s: 0x%08x" % ("Rate 2", val)) 129 | 130 | def powertx_rate3 (val): 131 | cck_rates["1L"] = (val >> 0) & 0xff; 132 | # 1S is undefined 133 | #cck_rates["1S"] = (val >> 8) & 0xff; 134 | cck_rates["2L"] = (val >> 16) & 0xff; 135 | cck_rates["2S"] = (val >> 24) & 0xff; 136 | 137 | print("%010s: 0x%08x" % ("Rate 3", val)) 138 | 139 | def powertx_rate4 (val): 140 | cck_rates["5.5L"] = (val >> 0) & 0xff; 141 | cck_rates["5.5S"] = (val >> 8) & 0xff; 142 | cck_rates["11L"] = (val >> 16) & 0xff 143 | cck_rates["11S"] = (val >> 24) & 0xff 144 | 145 | print("%010s: 0x%08x" % ("Rate 4", val)) 146 | 147 | def powertx_rate5 (val): 148 | mcs_rates_ht20["0"] = (val >> 0) & 0xff; 149 | mcs_rates_ht20["8"] = (val >> 0) & 0xff; 150 | mcs_rates_ht20["16"] = (val >> 0) & 0xff; 151 | 152 | mcs_rates_ht20["1"] = (val >> 8) & 0xff; 153 | mcs_rates_ht20["2"] = (val >> 8) & 0xff; 154 | mcs_rates_ht20["3"] = (val >> 8) & 0xff; 155 | 156 | mcs_rates_ht20["9"] = (val >> 8) & 0xff; 157 | mcs_rates_ht20["10"] = (val >> 8) & 0xff; 158 | mcs_rates_ht20["11"] = (val >> 8) & 0xff; 159 | 160 | mcs_rates_ht20["17"] = (val >> 8) & 0xff; 161 | mcs_rates_ht20["18"] = (val >> 8) & 0xff; 162 | mcs_rates_ht20["19"] = (val >> 8) & 0xff; 163 | 164 | mcs_rates_ht20["4"] = (val >> 16) & 0xff 165 | 166 | mcs_rates_ht20["5"] = (val >> 24) & 0xff 167 | 168 | print("%010s: 0x%08x" % ("Rate 5", val)) 169 | 170 | def powertx_rate6 (val): 171 | mcs_rates_ht20["6"] = (val >> 0) & 0xff; 172 | mcs_rates_ht20["7"] = (val >> 8) & 0xff; 173 | mcs_rates_ht20["12"] = (val >> 16) & 0xff 174 | mcs_rates_ht20["13"] = (val >> 24) & 0xff 175 | 176 | print("%010s: 0x%08x" % ("Rate 6", val)) 177 | 178 | def powertx_rate7 (val): 179 | mcs_rates_ht40["0"] = (val >> 0) & 0xff; 180 | mcs_rates_ht40["8"] = (val >> 0) & 0xff; 181 | mcs_rates_ht40["16"] = (val >> 0) & 0xff; 182 | 183 | mcs_rates_ht40["1"] = (val >> 8) & 0xff; 184 | mcs_rates_ht40["2"] = (val >> 8) & 0xff; 185 | mcs_rates_ht40["3"] = (val >> 8) & 0xff; 186 | 187 | mcs_rates_ht40["9"] = (val >> 8) & 0xff; 188 | mcs_rates_ht40["10"] = (val >> 8) & 0xff; 189 | mcs_rates_ht40["11"] = (val >> 8) & 0xff; 190 | 191 | mcs_rates_ht40["17"] = (val >> 8) & 0xff; 192 | mcs_rates_ht40["18"] = (val >> 8) & 0xff; 193 | mcs_rates_ht40["19"] = (val >> 8) & 0xff; 194 | 195 | mcs_rates_ht40["4"] = (val >> 16) & 0xff 196 | 197 | mcs_rates_ht40["5"] = (val >> 24) & 0xff 198 | 199 | print("%010s: 0x%08x" % ("Rate 7", val)) 200 | 201 | def powertx_rate8 (val): 202 | mcs_rates_ht40["6"] = (val >> 0) & 0xff; 203 | mcs_rates_ht40["7"] = (val >> 8) & 0xff; 204 | mcs_rates_ht40["12"] = (val >> 16) & 0xff 205 | mcs_rates_ht40["13"] = (val >> 24) & 0xff 206 | 207 | print("%010s: 0x%08x" % ("Rate 8", val)) 208 | 209 | # What is 40 dup CCK, 40 dup OFDM, 20 ext cck, 20 ext ODFM ? 210 | def powertx_rate9 (val): 211 | ext_dup_rates["40 dup CCK"] = (val >> 0) & 0xff; 212 | ext_dup_rates["40 dup OFDM"] = (val >> 8) & 0xff; 213 | ext_dup_rates["20 ext CCK"] = (val >> 16) & 0xff 214 | ext_dup_rates["20 ext OFDM"] = (val >> 24) & 0xff 215 | 216 | print("%010s: 0x%08x" % ("Rate 9", val)) 217 | 218 | def powertx_rate10 (val): 219 | mcs_rates_ht20["14"] = (val >> 0) & 0xff; 220 | mcs_rates_ht20["15"] = (val >> 8) & 0xff; 221 | mcs_rates_ht20["20"] = (val >> 16) & 0xff 222 | mcs_rates_ht20["21"] = (val >> 24) & 0xff 223 | 224 | print("%010s: 0x%08x" % ("Rate 10", val)) 225 | 226 | def powertx_rate11 (val): 227 | mcs_rates_ht20["22"] = (val >> 0) & 0xff; 228 | mcs_rates_ht20["23"] = (val >> 8) & 0xff; 229 | 230 | mcs_rates_ht40["22"] = (val >> 16) & 0xff 231 | mcs_rates_ht40["23"] = (val >> 24) & 0xff 232 | 233 | print("%010s: 0x%08x" % ("Rate 11", val)) 234 | 235 | def powertx_rate12 (val): 236 | mcs_rates_ht40["14"] = (val >> 0) & 0xff; 237 | mcs_rates_ht40["15"] = (val >> 8) & 0xff; 238 | mcs_rates_ht40["20"] = (val >> 16) & 0xff 239 | mcs_rates_ht40["21"] = (val >> 24) & 0xff 240 | 241 | print("%010s: 0x%08x" % ("Rate 12", val)) 242 | 243 | registers = { 244 | "0x00a3c0" : powertx_rate1, 245 | "0x00a3c4" : powertx_rate2, 246 | "0x00a3c8" : powertx_rate3, 247 | "0x00a3cc" : powertx_rate4, 248 | "0x00a3d0" : powertx_rate5, 249 | "0x00a3d4" : powertx_rate6, 250 | "0x00a3d8" : powertx_rate7, 251 | "0x00a3dc" : powertx_rate8, 252 | "0x00a3e0" : powertx_rate9, 253 | "0x00a3e4" : powertx_rate10, 254 | "0x00a3e8" : powertx_rate11, 255 | "0x00a3ec" : powertx_rate12, 256 | } 257 | 258 | def process_cck_rates(): 259 | print("CCK Rates") 260 | print("======================") 261 | for rate, double_dbm in cck_rates.items(): 262 | dbm = "%.2f dBm" % (double_dbm / 2) 263 | print("%010s %010s" % (rate + " Mbps", dbm)) 264 | 265 | def process_ofdm_rates(): 266 | print("OFDM Rates") 267 | print("======================") 268 | for rate, double_dbm in sorted(ofdm_rates.items(), key=lambda i: int(i[0], 0)): 269 | rate_s = "%s" % rate 270 | dbm = "%.02f dBm" % (double_dbm / 2) 271 | print("%010s %010s" % (rate_s + " Mbps", dbm)) 272 | 273 | def process_mcs_ht20_rates(): 274 | print("MCS20 Rates") 275 | print("======================") 276 | for rate, double_dbm in sorted(mcs_rates_ht20.items(), key=lambda i: int(i[0], 0)): 277 | rate_s = "%s" % rate 278 | dbm = "%.02f dBm" % (double_dbm / 2) 279 | print("%010s %010s" % ("MCS" + rate_s, dbm)) 280 | 281 | 282 | def process_mcs_ht40_rates(): 283 | print("MCS40 Rates") 284 | print("======================") 285 | for rate, double_dbm in sorted(mcs_rates_ht40.items(), key=lambda i: int(i[0], 0)): 286 | rate_s = "%s" % rate 287 | dbm = "%.2f dBm" % (double_dbm / 2) 288 | print("%010s %010s" % ("MCS" + rate_s, dbm)) 289 | 290 | def process_ext_dup_rates(): 291 | print("EXT-DUP Rates") 292 | print("==========================") 293 | for rate, double_dbm in ext_dup_rates.items(): 294 | dbm = "%.2f dBm" % (double_dbm / 2) 295 | print("%015s %010s" % (rate, dbm)) 296 | 297 | def print_power_reg (reg, val): 298 | if not reg in map(lambda x: int(x, 0), registers.keys()): 299 | return 300 | registers.get("0x%06x" % reg)(val) 301 | 302 | try: 303 | print("Power register") 304 | print("======================") 305 | for line in sys.stdin.readlines(): 306 | reg, val = map(lambda x: int(x, 0), line.split()) 307 | print_power_reg(reg, val) 308 | print("-------------------------------------") 309 | 310 | process_cck_rates() 311 | process_ofdm_rates() 312 | process_mcs_ht20_rates() 313 | process_mcs_ht40_rates() 314 | process_ext_dup_rates() 315 | 316 | except SystemExit: pass 317 | 318 | except: 319 | sys.stdout.write("uknown error\n") 320 | -------------------------------------------------------------------------------- /tracing/plugins/ath10k_pktlog.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2014-2017 Qualcomm Atheros, Inc. 3 | # 4 | # Permission to use, copy, modify, and/or distribute this software for any 5 | # purpose with or without fee is hereby granted, provided that the above 6 | # copyright notice and this permission notice appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | # 16 | # trace-cmd pktlog plugin for ath10k, QCA Linux wireless driver 17 | # 18 | # TODO: 19 | # 20 | # o create class for struct ieee80211_hdr each packet headers with 21 | # pack() and unpack() methods 22 | 23 | import struct 24 | import binascii 25 | 26 | DEBUG = 1 27 | 28 | CUR_PKTLOG_VER = 10010 29 | PKTLOG_MAGIC_NUM = 7735225 30 | 31 | IEEE80211_FCTL_TODS = 0x0100 32 | IEEE80211_FCTL_FROMDS = 0x0200 33 | TARGET_NUM_MSDU_DESC = (1024 + 400) 34 | MAX_PKT_INFO_MSDU_ID = 192 35 | MAX_10_4_PKT_INFO_MSDU_ID = 1 36 | PKTLOG_MAX_TXCTL_WORDS = 57 37 | 38 | # must match with enum ath10k_hw_rev from ath10k and existing values 39 | # should not change 40 | ATH10K_PKTLOG_HW_QCA988X = 0 41 | ATH10K_PKTLOG_HW_QCA6174 = 1 42 | ATH10K_PKTLOG_HW_QCA99X0 = 2 43 | ATH10K_PKTLOG_HW_QCA9888 = 3 44 | ATH10K_PKTLOG_HW_QCA9984 = 4 45 | ATH10K_PKTLOG_HW_QCA9377 = 5 46 | ATH10K_PKTLOG_HW_QCA40XX = 6 47 | ATH10K_PKTLOG_HW_QCA9887 = 7 48 | 49 | ATH10K_PKTLOG_TYPE_TX_CTRL = 1 50 | ATH10K_PKTLOG_TYPE_TX_STAT = 2 51 | ATH10K_PKTLOG_TYPE_TX_MSDU_ID = 3 52 | ATH10K_PKTLOG_TYPE_TX_FRM_HDR = 4 53 | ATH10K_PKTLOG_TYPE_RX_STAT = 5 54 | ATH10K_PKTLOG_TYPE_RC_FIND = 6 55 | ATH10K_PKTLOG_TYPE_RC_UPDATE = 7 56 | ATH10K_PKTLOG_TYPE_TX_VIRT_ADDR = 8 57 | ATH10K_PKTLOG_TYPE_DBG_PRINT = 9 58 | 59 | ATH10K_PKTLOG_FLG_TYPE_LOCAL_S = 0 60 | ATH10K_PKTLOG_FLG_TYPE_REMOTE_S = 1 61 | ATH10K_PKTLOG_FLG_TYPE_CLONE_S = 2 62 | ATH10K_PKTLOG_FLG_TYPE_UNKNOWN_S = 3 63 | 64 | # sizeof(ath10k_pktlog_txctl) = 12 + 4 * 57 65 | ATH10K_PKTLOG_TXCTL_LEN = 240 66 | ATH10K_PKTLOG_MAX_TXCTL_WORDS = 57 67 | # sizeof(ath10k_pktlog_10_4_txctl)2 = 16 + 4 * 153 68 | ATH10K_PKTLOG_10_4_TXCTL_LEN = 624 69 | ATH10K_PKTLOG_10_4_MAX_TXCTL_WORDS = 153 70 | 71 | msdu_len_tbl = {} 72 | output_file = None 73 | frm_hdr = None 74 | 75 | 76 | def dbg(msg): 77 | if DEBUG == 0: 78 | return 79 | 80 | print(msg) 81 | 82 | 83 | def hexdump(buf, prefix=None): 84 | s = binascii.b2a_hex(buf) 85 | s_len = len(s) 86 | result = "" 87 | 88 | if prefix is None: 89 | prefix = "" 90 | 91 | for i in range(s_len / 2): 92 | if i % 16 == 0: 93 | result = result + ("%s%04x: " % (prefix, i)) 94 | 95 | result = result + (s[2 * i] + s[2 * i + 1] + " ") 96 | 97 | if (i + 1) % 16 == 0: 98 | result = result + "\n" 99 | 100 | # FIXME: if len(s) % 16 == 0 there's an extra \n in the end 101 | 102 | return result 103 | 104 | # struct ath10k_pktlog_hdr { 105 | # unsigned short flags; 106 | # unsigned short missed_cnt; 107 | # unsigned short log_type; 108 | # unsigned short size; 109 | # unsigned int timestamp; 110 | # unsigned char payload[0]; 111 | # } __attribute__((__packed__)); 112 | 113 | 114 | class Ath10kPktlogHdr: 115 | # 2 + 2 + 2 + 2 + 4 = 12 116 | hdr_len = 12 117 | struct_fmt = '= 4: 280 | txctl, = struct.unpack_from(' 0: 325 | num_msdu = num_msdu - 1 326 | msdu_id, = struct.unpack_from(' TARGET_NUM_MSDU_DESC: 428 | dbg('Invalid msdu_id in tx: %d' % (msdu_id)) 429 | return 430 | 431 | msdu_len_tbl[msdu_id] = msdu_len 432 | 433 | 434 | def ath10k_txrx_tx_unref_handler(pevent, trace_seq, event): 435 | global msdu_len_tbl 436 | msdu_id = int(event['msdu_id']) 437 | 438 | trace_seq.puts('msdu_id %d\n' % (msdu_id)) 439 | 440 | if msdu_id > TARGET_NUM_MSDU_DESC: 441 | dbg('Invalid msdu_id from unref: %d' % (msdu_id)) 442 | return 443 | 444 | msdu_len_tbl[msdu_id] = 0 445 | 446 | 447 | def ath10k_tx_hdr_handler(pevent, trace_seq, event): 448 | buf = event['data'].data 449 | 450 | pktlog_tx_frm_hdr(buf[0:]) 451 | 452 | 453 | def register(pevent): 454 | 455 | output_open() 456 | 457 | pevent.register_event_handler("ath10k", "ath10k_htt_pktlog", 458 | lambda *args: 459 | ath10k_htt_pktlog_handler(pevent, *args)) 460 | pevent.register_event_handler("ath10k", "ath10k_htt_rx_desc", 461 | lambda *args: 462 | ath10k_htt_rx_desc_handler(pevent, *args)) 463 | pevent.register_event_handler("ath10k", "ath10k_htt_tx", 464 | lambda *args: 465 | ath10k_htt_tx_handler(pevent, *args)) 466 | pevent.register_event_handler("ath10k", "ath10k_txrx_tx_unref", 467 | lambda *args: 468 | ath10k_txrx_tx_unref_handler(pevent, *args)) 469 | pevent.register_event_handler("ath10k", "ath10k_tx_hdr", 470 | lambda *args: 471 | ath10k_tx_hdr_handler(pevent, *args)) 472 | -------------------------------------------------------------------------------- /tracing/plugins/ath6kl.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2012 Qualcomm Atheros, Inc. 3 | # 4 | # Permission to use, copy, modify, and/or distribute this software for any 5 | # purpose with or without fee is hereby granted, provided that the above 6 | # copyright notice and this permission notice appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | # 16 | # To install the plugin: 17 | # 18 | # cp ath6kl.py ~/.trace-cmd/plugins/ 19 | # 20 | # When making changes to the plugin use -V to see all python errors/warnings: 21 | # 22 | # trace-cmd report -V trace.dat 23 | 24 | import tracecmd 25 | import struct 26 | import binascii 27 | 28 | def hexdump(buf, prefix=None): 29 | s = binascii.b2a_hex(buf) 30 | s_len = len(s) 31 | result = "" 32 | 33 | if prefix == None: 34 | prefix = "" 35 | 36 | for i in range(s_len / 2): 37 | if i % 16 == 0: 38 | result = result + ("%s%04x: " % (prefix, i)) 39 | 40 | result = result + (s[2*i] + s[2*i+1] + " ") 41 | 42 | if (i + 1) % 16 == 0: 43 | result = result + "\n" 44 | 45 | # FIXME: if len(s) % 16 == 0 there's an extra \n in the end 46 | 47 | return result 48 | 49 | def wmi_event_bssinfo(pevent, trace_seq, event, buf): 50 | hdr = struct.unpack("> 4 169 | 170 | trace_seq.puts("seqno %d endpoint %d payload_len %d flags 0x%x bundle_count %d\n" % 171 | (seqno, endpoint, payload_len, flags, bundle_count)) 172 | 173 | if (flags & 0xf) != 0: 174 | trace_seq.puts("\t\t\t\t\t\t") 175 | 176 | if flags & 0x1: 177 | trace_seq.puts(" UNUSED") 178 | 179 | if flags & 0x2: 180 | trace_seq.puts(" TRAILER") 181 | 182 | if (flags & 0xf) != 0: 183 | trace_seq.puts("\n") 184 | 185 | def ath6kl_sdio_handler(pevent, trace_seq, event): 186 | tx = long(event['tx']) 187 | addr = event['addr'] 188 | flags = event['flags'] 189 | 190 | buf_len = long(event['buf_len']) 191 | buf = event['buf'].data 192 | 193 | if tx == 1: 194 | direction = "tx" 195 | else: 196 | direction = "rx" 197 | 198 | trace_seq.puts("%s addr 0x%x flags 0x%x buf_len %d\n" % 199 | (direction, addr, flags, buf_len)) 200 | trace_seq.puts("%s\n" % hexdump(buf)) 201 | 202 | def ath6kl_sdio_scat_handler(pevent, trace_seq, event): 203 | tx = long(event['tx']) 204 | addr = long(event['addr']) 205 | flags = long(event['flags']) 206 | entries = long(event['entries']) 207 | total_len = long(event['total_len']) 208 | 209 | len_array_data = event['len_array'].data 210 | data = event['data'].data 211 | 212 | if tx == 1: 213 | direction = "tx" 214 | else: 215 | direction = "rx" 216 | 217 | trace_seq.puts("%s addr 0x%x flags 0x%x entries %d total_len %d\n" % 218 | (direction, addr, flags, entries, total_len)) 219 | 220 | offset = 0 221 | 222 | len_array = struct.unpack("<%dI" % entries, len_array_data[0:8]) 223 | 224 | for i in range(entries): 225 | length = len_array[i] 226 | start = offset 227 | end = start + length 228 | 229 | trace_seq.puts("%s\n" % hexdump(data[start:end])) 230 | 231 | offset = offset + length 232 | 233 | def register(pevent): 234 | pevent.register_event_handler("ath6kl", "ath6kl_wmi_cmd", 235 | lambda *args: 236 | ath6kl_wmi_cmd_handler(pevent, *args)) 237 | pevent.register_event_handler("ath6kl", "ath6kl_wmi_event", 238 | lambda *args: 239 | ath6kl_wmi_event_handler(pevent, *args)) 240 | pevent.register_event_handler("ath6kl", "ath6kl_htc_tx", 241 | lambda *args: 242 | ath6kl_htc_tx_handler(pevent, *args)) 243 | pevent.register_event_handler("ath6kl", "ath6kl_htc_rx", 244 | lambda *args: 245 | ath6kl_htc_rx_handler(pevent, *args)) 246 | pevent.register_event_handler("ath6kl", "ath6kl_sdio", 247 | lambda *args: 248 | ath6kl_sdio_handler(pevent, *args)) 249 | pevent.register_event_handler("ath6kl", "ath6kl_sdio_scat", 250 | lambda *args: 251 | ath6kl_sdio_scat_handler(pevent, *args)) 252 | --------------------------------------------------------------------------------