aboutsummaryrefslogtreecommitdiff
path: root/tools/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools/tools')
-rw-r--r--tools/tools/README73
-rw-r--r--tools/tools/aac/Makefile8
-rw-r--r--tools/tools/aac/aac_checkq.c84
-rw-r--r--tools/tools/ansify/Makefile6
-rw-r--r--tools/tools/ansify/ansify.pl162
-rw-r--r--tools/tools/ath/Makefile7
-rw-r--r--tools/tools/ath/Makefile.inc14
-rw-r--r--tools/tools/ath/arcode/Makefile8
-rw-r--r--tools/tools/ath/arcode/arcode.c114
-rw-r--r--tools/tools/ath/ath_ee_9287_print/9287.c316
-rw-r--r--tools/tools/ath/ath_ee_9287_print/9287.h15
-rw-r--r--tools/tools/ath/ath_ee_9287_print/Makefile12
-rw-r--r--tools/tools/ath/ath_ee_9287_print/eeprom.c72
-rw-r--r--tools/tools/ath/ath_ee_9287_print/eeprom.h8
-rw-r--r--tools/tools/ath/ath_ee_9287_print/main.c85
-rw-r--r--tools/tools/ath/ath_ee_v14_print/Makefile11
-rw-r--r--tools/tools/ath/ath_ee_v14_print/ath_ee_v14_print.c473
-rw-r--r--tools/tools/ath/ath_ee_v4k_print/Makefile12
-rw-r--r--tools/tools/ath/ath_ee_v4k_print/eeprom.c72
-rw-r--r--tools/tools/ath/ath_ee_v4k_print/eeprom.h8
-rw-r--r--tools/tools/ath/ath_ee_v4k_print/main.c85
-rw-r--r--tools/tools/ath/ath_ee_v4k_print/v4k.c300
-rw-r--r--tools/tools/ath/ath_ee_v4k_print/v4k.h15
-rw-r--r--tools/tools/ath/ath_prom_read/Makefile22
-rw-r--r--tools/tools/ath/ath_prom_read/ath_prom_read.c134
-rw-r--r--tools/tools/ath/athctrl.sh42
-rw-r--r--tools/tools/ath/athdebug/Makefile7
-rw-r--r--tools/tools/ath/athdebug/athdebug.c230
-rw-r--r--tools/tools/ath/athdecode/Makefile24
-rw-r--r--tools/tools/ath/athdecode/main.c425
-rw-r--r--tools/tools/ath/athkey/Makefile18
-rw-r--r--tools/tools/ath/athkey/athkey.c203
-rw-r--r--tools/tools/ath/athpoke/Makefile24
-rw-r--r--tools/tools/ath/athpoke/athpoke.c247
-rw-r--r--tools/tools/ath/athpow/Makefile7
-rw-r--r--tools/tools/ath/athpow/athpow.c198
-rw-r--r--tools/tools/ath/athprom/Makefile26
-rw-r--r--tools/tools/ath/athprom/athprom.c979
-rw-r--r--tools/tools/ath/athprom/eeprom-14120
-rw-r--r--tools/tools/ath/athprom/eeprom-3165
-rw-r--r--tools/tools/ath/athprom/eeprom-4206
-rw-r--r--tools/tools/ath/athprom/eeprom-5245
-rw-r--r--tools/tools/ath/athradar/Makefile16
-rw-r--r--tools/tools/ath/athradar/athradar.c311
-rw-r--r--tools/tools/ath/athrd/Makefile21
-rw-r--r--tools/tools/ath/athrd/athrd.1172
-rw-r--r--tools/tools/ath/athrd/athrd.c1673
-rwxr-xr-xtools/tools/ath/athrd/run.sh17
-rw-r--r--tools/tools/ath/athregs/Makefile23
-rw-r--r--tools/tools/ath/athregs/dumpregs.c721
-rw-r--r--tools/tools/ath/athstats/Makefile26
-rw-r--r--tools/tools/ath/athstats/athstats.c1109
-rw-r--r--tools/tools/ath/athstats/athstats.h54
-rw-r--r--tools/tools/ath/athstats/main.c164
-rw-r--r--tools/tools/ath/athstats/statfoo.c206
-rw-r--r--tools/tools/ath/athstats/statfoo.h128
-rw-r--r--tools/tools/ath/common/ah_osdep.h75
-rw-r--r--tools/tools/ath/common/diag.h61
-rw-r--r--tools/tools/ath/common/dumpregs.h98
-rw-r--r--tools/tools/ath/common/dumpregs_5210.c125
-rw-r--r--tools/tools/ath/common/dumpregs_5211.c293
-rw-r--r--tools/tools/ath/common/dumpregs_5212.c433
-rw-r--r--tools/tools/ath/common/dumpregs_5416.c423
-rw-r--r--tools/tools/backout_commit/backout_commit.rb350
-rw-r--r--tools/tools/build_option_survey/listallopts.sh22
-rw-r--r--tools/tools/build_option_survey/mkhtml.sh224
-rw-r--r--tools/tools/build_option_survey/option_survey.sh198
-rw-r--r--tools/tools/build_option_survey/reduce.sh77
-rw-r--r--tools/tools/bus_autoconf/Makefile46
-rw-r--r--tools/tools/bus_autoconf/bus_autoconf.c125
-rw-r--r--tools/tools/bus_autoconf/bus_autoconf.h31
-rw-r--r--tools/tools/bus_autoconf/bus_autoconf.sh78
-rw-r--r--tools/tools/bus_autoconf/bus_autoconf_format_example.txt111
-rw-r--r--tools/tools/bus_autoconf/bus_load_file.c76
-rw-r--r--tools/tools/bus_autoconf/bus_load_file.h33
-rw-r--r--tools/tools/bus_autoconf/bus_sections.c223
-rw-r--r--tools/tools/bus_autoconf/bus_sections.h35
-rw-r--r--tools/tools/bus_autoconf/bus_usb.c386
-rw-r--r--tools/tools/bus_autoconf/bus_usb.h73
-rwxr-xr-xtools/tools/cd2dvd/cd2dvd.sh267
-rw-r--r--tools/tools/cfi/Makefile8
-rw-r--r--tools/tools/cfi/cfi.c157
-rw-r--r--tools/tools/commitsdb/make_commit_db105
-rw-r--r--tools/tools/commitsdb/query_commit_db93
-rw-r--r--tools/tools/crypto/Makefile64
-rw-r--r--tools/tools/crypto/README44
-rw-r--r--tools/tools/crypto/cryptokeytest.c287
-rw-r--r--tools/tools/crypto/cryptostats.c105
-rw-r--r--tools/tools/crypto/cryptotest.c622
-rw-r--r--tools/tools/crypto/hifnstats.c60
-rw-r--r--tools/tools/crypto/ipsecstats.c179
-rw-r--r--tools/tools/crypto/safestats.c69
-rw-r--r--tools/tools/crypto/ubsecstats.c69
-rw-r--r--tools/tools/cxgbetool/Makefile9
-rw-r--r--tools/tools/cxgbetool/cxgbetool.c1634
-rw-r--r--tools/tools/cxgbetool/reg_defs_t4.c40394
-rw-r--r--tools/tools/cxgbetool/reg_defs_t4vf.c122
-rw-r--r--tools/tools/cxgbtool/Makefile10
-rw-r--r--tools/tools/cxgbtool/cxgbtool.c1771
-rw-r--r--tools/tools/cxgbtool/reg_defs.c837
-rw-r--r--tools/tools/cxgbtool/reg_defs_t3.c2676
-rw-r--r--tools/tools/cxgbtool/reg_defs_t3b.c2832
-rw-r--r--tools/tools/cxgbtool/reg_defs_t3c.c3119
-rw-r--r--tools/tools/cxgbtool/version.h32
-rw-r--r--tools/tools/editing/freebsd.el40
-rw-r--r--tools/tools/editing/freebsd.vim68
-rw-r--r--tools/tools/epfe/epfe.pl38
-rw-r--r--tools/tools/ether_reflect/Makefile11
-rw-r--r--tools/tools/ether_reflect/ether_reflect.1108
-rw-r--r--tools/tools/ether_reflect/ether_reflect.c164
-rw-r--r--tools/tools/find-sb/Makefile7
-rw-r--r--tools/tools/find-sb/README18
-rw-r--r--tools/tools/find-sb/find-sb.c133
-rw-r--r--tools/tools/find-sb/mini_ufs.h155
-rw-r--r--tools/tools/fixwhite/Makefile7
-rw-r--r--tools/tools/fixwhite/fixwhite.148
-rw-r--r--tools/tools/fixwhite/fixwhite.c180
-rw-r--r--tools/tools/gdb_regofs/Makefile5
-rw-r--r--tools/tools/gdb_regofs/ia64.c213
-rw-r--r--tools/tools/genericize/Makefile6
-rwxr-xr-xtools/tools/genericize/genericize.pl137
-rw-r--r--tools/tools/hcomp/Makefile13
-rw-r--r--tools/tools/hcomp/hcomp.pl93
-rw-r--r--tools/tools/html-mv/html-mv59
-rw-r--r--tools/tools/ifinfo/Makefile7
-rw-r--r--tools/tools/ifinfo/ifinfo.c303
-rw-r--r--tools/tools/ifinfo/ifinfo.h38
-rw-r--r--tools/tools/ifinfo/rfc1650.c124
-rw-r--r--tools/tools/ipw/Makefile6
-rw-r--r--tools/tools/ipw/ipwstats.c277
-rwxr-xr-xtools/tools/iso/check-iso3166.pl164
-rwxr-xr-xtools/tools/iso/check-iso639.pl98
-rw-r--r--tools/tools/iwi/Makefile7
-rw-r--r--tools/tools/iwi/iwistats.c129
-rwxr-xr-xtools/tools/kdrv/KernelDriver1081
-rw-r--r--tools/tools/kdrv/sample.drvinfo44
-rw-r--r--tools/tools/kernelcruft/kernelcruft.sh43
-rw-r--r--tools/tools/kerninclude/kerninclude.sh303
-rw-r--r--tools/tools/kernxref/kernxref.sh158
-rw-r--r--tools/tools/kttcp/Makefile23
-rw-r--r--tools/tools/kttcp/README24
-rw-r--r--tools/tools/kttcp/kttcp.c307
-rw-r--r--tools/tools/kttcp/sys/Makefile8
-rw-r--r--tools/tools/kttcp/sys/kttcp.c274
-rw-r--r--tools/tools/kttcp/sys/kttcpio.h59
-rw-r--r--tools/tools/mcgrab/Makefile6
-rw-r--r--tools/tools/mcgrab/mcgrab.183
-rw-r--r--tools/tools/mcgrab/mcgrab.cc189
-rw-r--r--tools/tools/mctest/Makefile7
-rw-r--r--tools/tools/mctest/mctest.1121
-rw-r--r--tools/tools/mctest/mctest.cc525
-rw-r--r--tools/tools/mctest/mctest.h33
-rw-r--r--tools/tools/mctest/mctest_run.sh74
-rw-r--r--tools/tools/mfc/Makefile10
-rw-r--r--tools/tools/mfc/README19
-rw-r--r--tools/tools/mfc/mfc.awk33
-rw-r--r--tools/tools/mfc/mfc.pl450
-rw-r--r--tools/tools/mfc/mfc.sh38
-rw-r--r--tools/tools/mfi/Makefile7
-rw-r--r--tools/tools/mfi/mfi_checkq.c81
-rw-r--r--tools/tools/mfi/runmegacli.sh37
-rwxr-xr-xtools/tools/mid/mid-build46
-rwxr-xr-xtools/tools/mid/mid-index83
-rwxr-xr-xtools/tools/mid/mid-master33
-rwxr-xr-xtools/tools/mid/mid-master-index21
-rw-r--r--tools/tools/mtxstat/mtxratio.sh2
-rw-r--r--tools/tools/mtxstat/mtxstat.pl130
-rw-r--r--tools/tools/mwl/Makefile5
-rw-r--r--tools/tools/mwl/mwldebug/Makefile7
-rw-r--r--tools/tools/mwl/mwldebug/mwldebug.c212
-rw-r--r--tools/tools/mwl/mwlstats/Makefile11
-rw-r--r--tools/tools/mwl/mwlstats/main.c128
-rw-r--r--tools/tools/mwl/mwlstats/mwlstats.c578
-rw-r--r--tools/tools/mwl/mwlstats/mwlstats.h52
-rw-r--r--tools/tools/mwl/mwlstats/statfoo.c184
-rw-r--r--tools/tools/mwl/mwlstats/statfoo.h127
-rw-r--r--tools/tools/nanobsd/Files/root/change_password40
-rw-r--r--tools/tools/nanobsd/Files/root/save_cfg42
-rw-r--r--tools/tools/nanobsd/Files/root/save_sshkeys40
-rw-r--r--tools/tools/nanobsd/Files/root/update44
-rw-r--r--tools/tools/nanobsd/Files/root/updatep154
-rw-r--r--tools/tools/nanobsd/Files/root/updatep261
-rw-r--r--tools/tools/nanobsd/FlashDevice.sub254
-rw-r--r--tools/tools/nanobsd/fill_pkg.sh96
-rw-r--r--tools/tools/nanobsd/gateworks/Files/root/.profile15
-rw-r--r--tools/tools/nanobsd/gateworks/Files/root/updatep154
-rw-r--r--tools/tools/nanobsd/gateworks/Files/root/updatep262
-rw-r--r--tools/tools/nanobsd/gateworks/G2348119
-rw-r--r--tools/tools/nanobsd/gateworks/G2358130
-rw-r--r--tools/tools/nanobsd/gateworks/avila10
-rw-r--r--tools/tools/nanobsd/gateworks/cambria10
-rw-r--r--tools/tools/nanobsd/gateworks/cfg/motd1
-rw-r--r--tools/tools/nanobsd/gateworks/cfg/rc.conf24
-rw-r--r--tools/tools/nanobsd/gateworks/cfg/ssh/sshd_config126
-rw-r--r--tools/tools/nanobsd/gateworks/common360
-rw-r--r--tools/tools/nanobsd/nanobsd.sh962
-rw-r--r--tools/tools/nanobsd/pcengines/ALIX_DSK113
-rw-r--r--tools/tools/nanobsd/pcengines/ALIX_NFS121
-rw-r--r--tools/tools/nanobsd/pcengines/Files/etc/rc.conf13
-rw-r--r--tools/tools/nanobsd/pcengines/Files/etc/ttys565
-rw-r--r--tools/tools/nanobsd/pcengines/Files/root/.cshrc35
-rw-r--r--tools/tools/nanobsd/pcengines/Files/root/.k5login4
-rw-r--r--tools/tools/nanobsd/pcengines/Files/root/.login9
-rw-r--r--tools/tools/nanobsd/pcengines/Files/root/change_password40
-rw-r--r--tools/tools/nanobsd/pcengines/Files/root/save_cfg42
-rw-r--r--tools/tools/nanobsd/pcengines/Files/root/save_sshkeys40
-rw-r--r--tools/tools/nanobsd/pcengines/Files/root/updatep154
-rw-r--r--tools/tools/nanobsd/pcengines/Files/root/updatep261
-rw-r--r--tools/tools/nanobsd/pcengines/Files/usr/ports/.keepme0
-rw-r--r--tools/tools/nanobsd/pcengines/alix_dsk.conf29
-rw-r--r--tools/tools/nanobsd/pcengines/alix_nfs.conf26
-rwxr-xr-xtools/tools/nanobsd/pcengines/build.sh18
-rw-r--r--tools/tools/nanobsd/pcengines/common.conf83
-rwxr-xr-xtools/tools/nanobsd/pcengines/test.sh59
-rw-r--r--tools/tools/nanobsd/rescue/Files/etc/ssh/ssh_config46
-rw-r--r--tools/tools/nanobsd/rescue/Files/etc/ssh/sshd_config117
-rw-r--r--tools/tools/nanobsd/rescue/Files/etc/ttys565
-rw-r--r--tools/tools/nanobsd/rescue/Files/root/.cshrc41
-rwxr-xr-xtools/tools/nanobsd/rescue/Files/root/GPT4ZFS_Create.sh50
-rw-r--r--tools/tools/nanobsd/rescue/Files/root/ZFS_Create.txt35
-rw-r--r--tools/tools/nanobsd/rescue/Files/usr/ports/.keepme0
-rwxr-xr-xtools/tools/nanobsd/rescue/build.sh18
-rw-r--r--tools/tools/nanobsd/rescue/common115
-rwxr-xr-xtools/tools/nanobsd/rescue/merge.sh18
-rw-r--r--tools/tools/nanobsd/rescue/rescue_amd64.conf10
-rw-r--r--tools/tools/nanobsd/rescue/rescue_i386.conf10
-rw-r--r--tools/tools/ncpus/Makefile15
-rw-r--r--tools/tools/ncpus/acpi.c332
-rw-r--r--tools/tools/ncpus/acpidump.h177
-rw-r--r--tools/tools/ncpus/biosmptable.c270
-rw-r--r--tools/tools/ncpus/ncpus.c16
-rw-r--r--tools/tools/net80211/Makefile5
-rw-r--r--tools/tools/net80211/README16
-rw-r--r--tools/tools/net80211/scripts/config71
-rw-r--r--tools/tools/net80211/scripts/mesh/common13
-rw-r--r--tools/tools/net80211/scripts/mesh/config.mesh17
-rw-r--r--tools/tools/net80211/scripts/mesh/setup.simple13
-rw-r--r--tools/tools/net80211/scripts/mesh/topology.line38
-rw-r--r--tools/tools/net80211/scripts/mesh/topology.ring40
-rw-r--r--tools/tools/net80211/scripts/mesh/topology.star38
-rw-r--r--tools/tools/net80211/scripts/mesh/topology.tree47
-rw-r--r--tools/tools/net80211/scripts/setup.dfs26
-rw-r--r--tools/tools/net80211/scripts/setup.fixed17
-rw-r--r--tools/tools/net80211/scripts/setup.local16
-rw-r--r--tools/tools/net80211/scripts/setup.mixed62
-rw-r--r--tools/tools/net80211/scripts/setup.simple16
-rw-r--r--tools/tools/net80211/scripts/setup.simple224
-rw-r--r--tools/tools/net80211/scripts/setup.sta15
-rw-r--r--tools/tools/net80211/scripts/setup.tdma-master20
-rw-r--r--tools/tools/net80211/scripts/setup.tdma-slave19
-rw-r--r--tools/tools/net80211/scripts/setup.tsn55
-rw-r--r--tools/tools/net80211/scripts/setup.updown26
-rw-r--r--tools/tools/net80211/scripts/setup.updown.wpa61
-rw-r--r--tools/tools/net80211/scripts/setup.wds21
-rw-r--r--tools/tools/net80211/scripts/setup.wdsmain40
-rw-r--r--tools/tools/net80211/scripts/setup.wdsrelay35
-rw-r--r--tools/tools/net80211/scripts/setup.wep21
-rw-r--r--tools/tools/net80211/scripts/setup.wpa53
-rw-r--r--tools/tools/net80211/scripts/setup.wpa1.aes53
-rw-r--r--tools/tools/net80211/scripts/setup.wpa1.tkip53
-rw-r--r--tools/tools/net80211/scripts/setup.wpa254
-rw-r--r--tools/tools/net80211/scripts/setup.wpa2.tkip54
-rw-r--r--tools/tools/net80211/stumbler/Makefile10
-rw-r--r--tools/tools/net80211/stumbler/stumbler.c1039
-rw-r--r--tools/tools/net80211/w00t/Makefile5
-rw-r--r--tools/tools/net80211/w00t/Makefile.inc12
-rw-r--r--tools/tools/net80211/w00t/README78
-rw-r--r--tools/tools/net80211/w00t/ap/Makefile7
-rw-r--r--tools/tools/net80211/w00t/ap/ap.c916
-rw-r--r--tools/tools/net80211/w00t/assoc/Makefile7
-rw-r--r--tools/tools/net80211/w00t/assoc/assoc.c938
-rw-r--r--tools/tools/net80211/w00t/expand/Makefile7
-rw-r--r--tools/tools/net80211/w00t/expand/expand.c468
-rw-r--r--tools/tools/net80211/w00t/libw00t/Makefile7
-rw-r--r--tools/tools/net80211/w00t/libw00t/w00t.c414
-rw-r--r--tools/tools/net80211/w00t/libw00t/w00t.h57
-rw-r--r--tools/tools/net80211/w00t/prga/Makefile7
-rw-r--r--tools/tools/net80211/w00t/prga/prga.c664
-rw-r--r--tools/tools/net80211/w00t/redir/Makefile7
-rw-r--r--tools/tools/net80211/w00t/redir/buddy.c158
-rw-r--r--tools/tools/net80211/w00t/redir/redir.c709
-rw-r--r--tools/tools/net80211/wesside/Makefile5
-rw-r--r--tools/tools/net80211/wesside/README35
-rw-r--r--tools/tools/net80211/wesside/dics/Makefile10
-rw-r--r--tools/tools/net80211/wesside/dics/dics.c455
-rw-r--r--tools/tools/net80211/wesside/udps/Makefile10
-rw-r--r--tools/tools/net80211/wesside/udps/udps.c197
-rw-r--r--tools/tools/net80211/wesside/wesside/Makefile11
-rw-r--r--tools/tools/net80211/wesside/wesside/aircrack-ptw-lib.c489
-rw-r--r--tools/tools/net80211/wesside/wesside/aircrack-ptw-lib.h84
-rw-r--r--tools/tools/net80211/wesside/wesside/wesside.c2814
-rw-r--r--tools/tools/net80211/wlaninject/Makefile8
-rw-r--r--tools/tools/net80211/wlaninject/README82
-rw-r--r--tools/tools/net80211/wlaninject/wlaninject.c806
-rw-r--r--tools/tools/net80211/wlanstats/Makefile9
-rw-r--r--tools/tools/net80211/wlanstats/main.c276
-rw-r--r--tools/tools/net80211/wlanstats/statfoo.c201
-rw-r--r--tools/tools/net80211/wlanstats/statfoo.h128
-rw-r--r--tools/tools/net80211/wlanstats/wlanstats.c1034
-rw-r--r--tools/tools/net80211/wlanstats/wlanstats.h56
-rw-r--r--tools/tools/net80211/wlantxtime/Makefile7
-rw-r--r--tools/tools/net80211/wlantxtime/wlantxtime.c584
-rw-r--r--tools/tools/net80211/wlanwatch/Makefile13
-rw-r--r--tools/tools/net80211/wlanwatch/wlanwatch.c457
-rw-r--r--tools/tools/net80211/wlanwds/Makefile7
-rw-r--r--tools/tools/net80211/wlanwds/wlanwds.c507
-rw-r--r--tools/tools/netmap/Makefile25
-rw-r--r--tools/tools/netmap/README11
-rw-r--r--tools/tools/netmap/bridge.c462
-rw-r--r--tools/tools/netmap/click-test.cfg19
-rw-r--r--tools/tools/netmap/pcap.c762
-rw-r--r--tools/tools/netmap/pkt-gen.c1027
-rw-r--r--tools/tools/netrate/Makefile7
-rw-r--r--tools/tools/netrate/Makefile.inc4
-rw-r--r--tools/tools/netrate/README57
-rw-r--r--tools/tools/netrate/http/Makefile9
-rw-r--r--tools/tools/netrate/http/http.c361
-rw-r--r--tools/tools/netrate/httpd/Makefile9
-rw-r--r--tools/tools/netrate/httpd/httpd.c313
-rw-r--r--tools/tools/netrate/juggle/Makefile9
-rw-r--r--tools/tools/netrate/juggle/juggle.c592
-rw-r--r--tools/tools/netrate/netblast/Makefile8
-rw-r--r--tools/tools/netrate/netblast/netblast.c221
-rw-r--r--tools/tools/netrate/netreceive/Makefile8
-rw-r--r--tools/tools/netrate/netreceive/netreceive.c141
-rw-r--r--tools/tools/netrate/netsend/Makefile9
-rw-r--r--tools/tools/netrate/netsend/netsend.c381
-rw-r--r--tools/tools/netrate/tcpconnect/Makefile7
-rw-r--r--tools/tools/netrate/tcpconnect/tcpconnect.c136
-rw-r--r--tools/tools/netrate/tcpp/Makefile9
-rw-r--r--tools/tools/netrate/tcpp/README108
-rw-r--r--tools/tools/netrate/tcpp/parallelism.csh28
-rwxr-xr-xtools/tools/netrate/tcpp/runit.pl64
-rw-r--r--tools/tools/netrate/tcpp/tcpp.c212
-rw-r--r--tools/tools/netrate/tcpp/tcpp.h52
-rw-r--r--tools/tools/netrate/tcpp/tcpp_client.c377
-rw-r--r--tools/tools/netrate/tcpp/tcpp_server.c349
-rw-r--r--tools/tools/netrate/tcpp/tcpp_util.c48
-rw-r--r--tools/tools/netrate/tcpreceive/Makefile7
-rw-r--r--tools/tools/netrate/tcpreceive/tcpreceive.c113
-rw-r--r--tools/tools/notescheck/Makefile5
-rw-r--r--tools/tools/notescheck/notescheck.py361
-rw-r--r--tools/tools/npe/Makefile5
-rw-r--r--tools/tools/npe/npestats/Makefile8
-rw-r--r--tools/tools/npe/npestats/main.c143
-rw-r--r--tools/tools/npe/npestats/npestats.c278
-rw-r--r--tools/tools/npe/npestats/npestats.h50
-rw-r--r--tools/tools/npe/npestats/statfoo.c192
-rw-r--r--tools/tools/npe/npestats/statfoo.h127
-rw-r--r--tools/tools/nxge/Makefile7
-rw-r--r--tools/tools/nxge/xge_cmn.h150
-rw-r--r--tools/tools/nxge/xge_info.c606
-rw-r--r--tools/tools/nxge/xge_info.h79
-rw-r--r--tools/tools/nxge/xge_log.c321
-rw-r--r--tools/tools/nxge/xge_log.h2592
-rw-r--r--tools/tools/pciroms/Makefile10
-rw-r--r--tools/tools/pciroms/pciroms.c412
-rw-r--r--tools/tools/pirtool/Makefile7
-rw-r--r--tools/tools/pirtool/pirtable.h79
-rw-r--r--tools/tools/pirtool/pirtool.c302
-rw-r--r--tools/tools/portsinfo/portsinfo.sh84
-rw-r--r--tools/tools/prstats/prstats.pl357
-rw-r--r--tools/tools/release/chk_dokern.sh_and_drivers.conf55
-rw-r--r--tools/tools/scsi-defects/README5
-rwxr-xr-xtools/tools/scsi-defects/scsi-defects.pl94
-rw-r--r--tools/tools/sysbuild/README153
-rw-r--r--tools/tools/sysbuild/sysbuild.sh613
-rw-r--r--tools/tools/syscall_timing/Makefile9
-rw-r--r--tools/tools/syscall_timing/syscall_timing.c782
-rw-r--r--tools/tools/sysdoc/Makefile12
-rw-r--r--tools/tools/sysdoc/sysctl.sh51
-rw-r--r--tools/tools/sysdoc/sysdoc.sh247
-rw-r--r--tools/tools/sysdoc/tunables.mdoc2410
-rwxr-xr-xtools/tools/termcap/termcap.pl165
-rw-r--r--tools/tools/tinybsd/CHANGES43
-rw-r--r--tools/tools/tinybsd/README259
-rw-r--r--tools/tools/tinybsd/conf/bridge/TINYBSD162
-rw-r--r--tools/tools/tinybsd/conf/bridge/etc/fstab2
-rw-r--r--tools/tools/tinybsd/conf/bridge/etc/rc.conf17
-rw-r--r--tools/tools/tinybsd/conf/bridge/etc/sysctl.conf5
-rw-r--r--tools/tools/tinybsd/conf/bridge/tinybsd.basefiles236
-rw-r--r--tools/tools/tinybsd/conf/bridge/tinybsd.ports9
-rw-r--r--tools/tools/tinybsd/conf/default/TINYBSD178
-rw-r--r--tools/tools/tinybsd/conf/default/etc/fstab2
-rw-r--r--tools/tools/tinybsd/conf/default/etc/rc.conf12
-rw-r--r--tools/tools/tinybsd/conf/default/tinybsd.basefiles247
-rw-r--r--tools/tools/tinybsd/conf/default/tinybsd.ports9
-rw-r--r--tools/tools/tinybsd/conf/firewall/TINYBSD175
-rw-r--r--tools/tools/tinybsd/conf/firewall/etc/authpf/authpf.rules1
-rw-r--r--tools/tools/tinybsd/conf/firewall/etc/fstab2
-rw-r--r--tools/tools/tinybsd/conf/firewall/etc/natd.conf1
-rw-r--r--tools/tools/tinybsd/conf/firewall/etc/pf.conf78
-rw-r--r--tools/tools/tinybsd/conf/firewall/etc/pf.os549
-rw-r--r--tools/tools/tinybsd/conf/firewall/etc/rc.conf41
-rw-r--r--tools/tools/tinybsd/conf/firewall/etc/rc.firewall302
-rw-r--r--tools/tools/tinybsd/conf/firewall/etc/sysctl.conf5
-rw-r--r--tools/tools/tinybsd/conf/firewall/tinybsd.basefiles240
-rw-r--r--tools/tools/tinybsd/conf/firewall/tinybsd.ports9
-rw-r--r--tools/tools/tinybsd/conf/minimal/TINYBSD83
-rw-r--r--tools/tools/tinybsd/conf/minimal/etc/fstab2
-rw-r--r--tools/tools/tinybsd/conf/minimal/etc/rc.conf12
-rw-r--r--tools/tools/tinybsd/conf/minimal/tinybsd.basefiles167
-rw-r--r--tools/tools/tinybsd/conf/minimal/tinybsd.ports9
-rw-r--r--tools/tools/tinybsd/conf/vpn/TINYBSD161
-rw-r--r--tools/tools/tinybsd/conf/vpn/etc/fstab2
-rw-r--r--tools/tools/tinybsd/conf/vpn/etc/rc.conf22
-rw-r--r--tools/tools/tinybsd/conf/vpn/etc/setkey.conf1
-rw-r--r--tools/tools/tinybsd/conf/vpn/tinybsd.basefiles222
-rw-r--r--tools/tools/tinybsd/conf/vpn/tinybsd.ports9
-rw-r--r--tools/tools/tinybsd/conf/wireless/TINYBSD174
-rw-r--r--tools/tools/tinybsd/conf/wireless/etc/authpf/authpf.rules1
-rw-r--r--tools/tools/tinybsd/conf/wireless/etc/fstab2
-rw-r--r--tools/tools/tinybsd/conf/wireless/etc/natd.conf1
-rw-r--r--tools/tools/tinybsd/conf/wireless/etc/pf.conf78
-rw-r--r--tools/tools/tinybsd/conf/wireless/etc/pf.os549
-rw-r--r--tools/tools/tinybsd/conf/wireless/etc/rc.conf32
-rw-r--r--tools/tools/tinybsd/conf/wireless/etc/rc.firewall302
-rw-r--r--tools/tools/tinybsd/conf/wireless/tinybsd.basefiles232
-rw-r--r--tools/tools/tinybsd/conf/wireless/tinybsd.ports9
-rw-r--r--tools/tools/tinybsd/conf/wrap/TINYBSD141
-rw-r--r--tools/tools/tinybsd/conf/wrap/etc/fstab2
-rw-r--r--tools/tools/tinybsd/conf/wrap/etc/rc.conf12
-rw-r--r--tools/tools/tinybsd/conf/wrap/etc/ttys308
-rw-r--r--tools/tools/tinybsd/conf/wrap/tinybsd.basefiles232
-rw-r--r--tools/tools/tinybsd/conf/wrap/tinybsd.ports9
-rwxr-xr-xtools/tools/tinybsd/tinybsd526
-rw-r--r--tools/tools/tionxcl/Makefile6
-rw-r--r--tools/tools/tionxcl/tionxcl.c101
-rw-r--r--tools/tools/track/Makefile7
-rw-r--r--tools/tools/track/track.sh49
-rw-r--r--tools/tools/umastat/Makefile10
-rw-r--r--tools/tools/umastat/umastat.c456
-rw-r--r--tools/tools/usb/print-usb-if-vids.sh31
-rw-r--r--tools/tools/vhba/Makefile29
-rw-r--r--tools/tools/vhba/README16
-rw-r--r--tools/tools/vhba/faulty/Makefile7
-rw-r--r--tools/tools/vhba/faulty/vhba_faulty.c349
-rw-r--r--tools/tools/vhba/lots/Makefile7
-rw-r--r--tools/tools/vhba/lots/vhba_lots.c335
-rw-r--r--tools/tools/vhba/medium/Makefile7
-rw-r--r--tools/tools/vhba/medium/vhba_medium.c337
-rw-r--r--tools/tools/vhba/mptest/Makefile31
-rw-r--r--tools/tools/vhba/mptest/vhba_mptest.c459
-rw-r--r--tools/tools/vhba/opt_cam.h1
-rw-r--r--tools/tools/vhba/rptluns/Makefile7
-rw-r--r--tools/tools/vhba/rptluns/vhba_rptluns.c366
-rw-r--r--tools/tools/vhba/simple/Makefile7
-rw-r--r--tools/tools/vhba/simple/vhba_simple.c337
-rw-r--r--tools/tools/vhba/vhba.c431
-rw-r--r--tools/tools/vhba/vhba.h116
-rw-r--r--tools/tools/vimage/Makefile14
-rw-r--r--tools/tools/vimage/vimage.8195
-rw-r--r--tools/tools/vimage/vimage.c390
-rw-r--r--tools/tools/vop_table/README2
-rw-r--r--tools/tools/vop_table/vop_table.pl255
-rw-r--r--tools/tools/vop_table/vop_table.tcl213
-rw-r--r--tools/tools/vxge/Makefile7
-rw-r--r--tools/tools/vxge/vxge_cmn.h260
-rw-r--r--tools/tools/vxge/vxge_info.c867
-rw-r--r--tools/tools/vxge/vxge_info.h90
-rw-r--r--tools/tools/vxge/vxge_log.c594
-rw-r--r--tools/tools/vxge/vxge_log.h1872
-rw-r--r--tools/tools/whereintheworld/Makefile5
-rw-r--r--tools/tools/whereintheworld/whereintheworld.pl69
-rw-r--r--tools/tools/wtap/Makefile5
-rw-r--r--tools/tools/wtap/vis_map/Makefile10
-rw-r--r--tools/tools/wtap/vis_map/vis_map.c117
-rw-r--r--tools/tools/wtap/wtap/Makefile10
-rw-r--r--tools/tools/wtap/wtap/wtap.c82
-rw-r--r--tools/tools/zfsboottest/Makefile29
-rw-r--r--tools/tools/zfsboottest/zfsboottest.c182
-rwxr-xr-xtools/tools/zfsboottest/zfsboottest.sh130
472 files changed, 129381 insertions, 0 deletions
diff --git a/tools/tools/README b/tools/tools/README
new file mode 100644
index 000000000000..9c3db2fc5364
--- /dev/null
+++ b/tools/tools/README
@@ -0,0 +1,73 @@
+# $FreeBSD$
+
+This directory is for tools.
+
+A tool is something which is sometimes useful, and doesn't fit any of
+the other categories.
+
+Please make a subdir per program, and add a brief description to this
+file.
+
+ansify Convert K&R-style function definitions to ANSI style
+ath Tools specific to the Atheros 802.11 support
+backout_commit A tool for reading in a commit message and generating
+ a script that will backout the commit.
+cfi Common Flash Interface (CFI) tool
+commitsdb A tool for reconstructing commit history using md5
+ checksums of the commit logs.
+crypto Test and exercise tools related to the crypto framework
+cxgbetool A tool for the cxgbe(4) driver.
+cxgbtool A tool for the cxgb(4) driver.
+diffburst OBSOLETE: equivalent functionality is available via split -p.
+ For example: "split -p ^diff < patchfile". See split(1).
+editing Editor modes and the like to help editing FreeBSD code.
+epfe Extract printing filter examples from printing.sgml.
+ether_reflect An Ethernet packet reflector for low level testing.
+find-sb Scan a disk for possible filesystem superblocks.
+gdb_regofs A simple tool that prints out a register offset table
+ for mapping gdb(1) register numbers to struct reg and
+ struct fpreg offsets. The tool is useful on selected
+ platforms only.
+genericize Turn a kernel config into something that can more easily
+ be diffed against the appropriate GENERIC.
+hcomp Compress header files by removing comments and whitespace.
+html-mv Rename HTML generated filenames to human readable filenames.
+ifinfo Uses the interface MIB to print out all the information
+ an interface exports in an ugly form.
+iso Tool to compare the iso3166 and iso639 files in
+ /usr/share/misc with the data from the master sites.
+iwi Tools specific to the Intel PRO/Wireless 2200BG/2225BG/2915ABG
+ support.
+kdrv KernelDriver; add/list/remove third-party kernel driver
+ source to/in/from a kernel source tree.
+kernelcruft Shellscript to find orphaned *.c files in /sys
+kerninclude Shellscript to find unused #includes in the kernel.
+kernxref Shellscript to cross reference symbols in the LINT kernel.
+kttcp An in-kernel version of the ttcp network performance tool
+mctest A multicast test program
+mfc Merge a directory from HEAD to a branch where it does not
+ already exist and other MFC related script(s).
+mid Create a Message-ID database for mailing lists.
+mwl Tools specific to the Marvell 88W8363 support
+ncpus Count the number of processors
+netmap Test applications for netmap(4)
+notescheck Check for missing devices and options in NOTES files.
+npe Tools specific to the Intel IXP4XXX NPE device
+nxge A diagnostic tool for the nxge(4) driver
+pciid Generate src/share/misc/pci_vendors.
+pciroms A tool for dumping PCI ROM images. WARNING: alpha quality.
+pirtool A tool for dumping the $PIR table on i386 machines at runtime.
+portsinfo Generate list of new ports for last two weeks.
+prstats Generate statistics about the PR database.
+recoverdisk Copy as much data as possible from a defective disk.
+scsi-defects Get at the primary or grown defect list of a SCSI disk.
+sysdoc Build a manual page with available sysctls for a specific
+ kernel configuration.
+tinybsd Script to build FreeBSD embedded systems.
+track Track the progress of a world / kernel build
+vimage An interim utility for managing the virtualized network
+ stack infrastructure.
+vop_table Generates a HTML document that shows all the VOP's in
+ the kernel.
+vxge A diagnostic tool for the vxge(4) driver
+whereintheworld Summarizes "make world" output.
diff --git a/tools/tools/aac/Makefile b/tools/tools/aac/Makefile
new file mode 100644
index 000000000000..7a472321a039
--- /dev/null
+++ b/tools/tools/aac/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+PROG= aac_checkq
+NO_MAN=
+WARNS?=6
+BINDIR?=/usr/local/bin
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/aac/aac_checkq.c b/tools/tools/aac/aac_checkq.c
new file mode 100644
index 000000000000..62eedb20aa51
--- /dev/null
+++ b/tools/tools/aac/aac_checkq.c
@@ -0,0 +1,84 @@
+/*-
+ * Copyright (c) 2004 Scott Long
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/aac_ioctl.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+
+void usage(void);
+
+/*
+ * Simple program to print out the queue stats on the given queue index.
+ * See /sys/sys/aac_ioctl.h for the definitions of each queue index.
+ */
+
+void
+usage(void)
+{
+ printf("Usage: aac_checkq <queue_number>\n");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ union aac_statrequest sr;
+ int fd, retval, queue;
+
+ if (argc != 2)
+ usage();
+
+ fd = open("/dev/aac0", O_RDWR);
+ if (fd == -1) {
+ printf("couldn't open aac0: %s\n", strerror(errno));
+ return (-1);
+ }
+
+ queue = atoi(argv[1]);
+ printf("Getting stats for queue %d\n", queue);
+ bzero(&sr, sizeof(union aac_statrequest));
+ sr.as_item = queue;
+ retval = ioctl(fd, AACIO_STATS, &sr);
+ if (retval == -1) {
+ printf("error on ioctl: %s\n", strerror(errno));
+ return (-1);
+ }
+
+ printf("length= %d, max= %d\n",sr.as_qstat.q_length, sr.as_qstat.q_max);
+
+ close(fd);
+ return 0;
+}
diff --git a/tools/tools/ansify/Makefile b/tools/tools/ansify/Makefile
new file mode 100644
index 000000000000..9519a4ce9fb2
--- /dev/null
+++ b/tools/tools/ansify/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+SCRIPTS= ansify.pl
+BINDIR?= /usr/local/bin
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ansify/ansify.pl b/tools/tools/ansify/ansify.pl
new file mode 100644
index 000000000000..e35546548425
--- /dev/null
+++ b/tools/tools/ansify/ansify.pl
@@ -0,0 +1,162 @@
+#!/usr/bin/perl -w
+#-
+# Copyright (c) 2005 Dag-Erling Coïdan Smørgrav
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer
+# in this position and unchanged.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+use v5.6.0;
+use strict;
+
+use Getopt::Long;
+
+my $caddr_t;
+
+sub ansify($$$) {
+ my $ifh = shift;
+ my $ofh = shift;
+ my $fn = shift;
+
+ my $line = 0;
+ OUTER:
+ while (<$ifh>) {
+ # look for K&R-style function definitions
+ if (m/^(\w+)\s*\(([\w,\s]+)\)$/) {
+ my @saved = ($_);
+ my $func = $1;
+ my @args = split(/\s*,\s*/, $2);
+ my $arglist = "";
+ # capture K&R-style argument list
+ while (<$ifh>) {
+ push(@saved, $_);
+ last if (m/^\{\s*$/);
+ $arglist .= $_;
+ }
+ # remove comments (common in vfs code)
+ $arglist =~ s/\/\*([^*]|\*[^\/])*\*\// /gs;
+ # identify type of each argument
+ my %type;
+ foreach (split('\n', $arglist)) {
+ s/\s+/ /g;
+ if (!/^\s*([\w\s\*]+?)\s*(\w+?);\s*$/) {
+ warn("[$fn:$line] $func(): can't parse argument list\n");
+ print $ofh @saved;
+ $line += @saved;
+ next OUTER;
+ }
+ $type{$2} = $1;
+ }
+ # construct ANSI-style function definition
+ my $repl = "$func(";
+ foreach my $arg (@args) {
+ # missing arguments in argument list
+ if (!exists($type{$arg})) {
+ warn("[$fn:$line] $func(): unknown type for '$arg' argument\n");
+ print $ofh @saved;
+ $line += @saved;
+ next OUTER;
+ }
+ if ($caddr_t) {
+ $type{$arg} = "void *"
+ if $type{$arg} eq "caddr_t";
+ }
+ $repl .= $type{$arg};
+ $repl .= " "
+ unless ($type{$arg} =~ m/\*$/);
+ $repl .= $arg;
+ $repl .= ", "
+ unless $arg eq $args[-1];
+ delete $type{$arg};
+ }
+ $repl .= ")";
+ # extra arguments in argument list
+ if (%type) {
+ warn("[$fn:$line] $func(): too many arguments\n");
+ print $ofh @saved;
+ $line += @saved;
+ next OUTER;
+ }
+ print $ofh "$repl\n";
+ ++$line;
+ # warn about long lines so they can be fixed up manually
+ warn("[$fn:$line] $func(): definition exceeds 80 characters\n")
+ if length($repl) >= 80;
+ print $ofh "{\n";
+ ++$line;
+ } else {
+ print $ofh $_;
+ ++$line;
+ }
+ }
+}
+
+sub ansify_file($) {
+ my $fn = shift;
+
+ my $tfn = "$fn.ansify";
+ local *IN;
+ local *OUT;
+
+ if (open(IN, "<", $fn)) {
+ if (open(OUT, ">", $tfn)) {
+ ansify(*IN{IO}, *OUT{IO}, $fn);
+ if (!rename($tfn, $fn)) {
+ warn("$fn: $!\n");
+ unlink($tfn);
+ }
+ } else {
+ warn("$fn.ansify: $!\n");
+ }
+ } else {
+ warn("$fn: $!\n");
+ }
+}
+
+sub usage() {
+ print STDERR "usage: ansify [options] [file ...]
+
+Options:
+ -c, --caddr_t Replace caddr_t with void * in converted
+ function definitions
+";
+ exit(1);
+}
+
+MAIN:{
+ Getopt::Long::Configure("auto_abbrev", "bundling");
+ GetOptions(
+ "c|caddr_t" => \$caddr_t,
+ )
+ or usage();
+
+ if (@ARGV) {
+ foreach (@ARGV) {
+ ansify_file($_);
+ }
+ } else {
+ ansify(*STDIN{IO}, *STDOUT{IO}, "(stdin)");
+ }
+}
diff --git a/tools/tools/ath/Makefile b/tools/tools/ath/Makefile
new file mode 100644
index 000000000000..3d603e656d8a
--- /dev/null
+++ b/tools/tools/ath/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+SUBDIR= arcode athdebug athdecode athkey athpoke athprom athrd athregs
+SUBDIR+= athstats ath_prom_read athradar
+SUBDIR+= ath_ee_v14_print ath_ee_v4k_print ath_ee_9287_print
+
+.include <bsd.subdir.mk>
diff --git a/tools/tools/ath/Makefile.inc b/tools/tools/ath/Makefile.inc
new file mode 100644
index 000000000000..901844ea7f72
--- /dev/null
+++ b/tools/tools/ath/Makefile.inc
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+BINDIR= /usr/local/bin
+NO_MAN=
+
+ATH_DEFAULT= ath0
+
+CFLAGS+=-DATH_DEFAULT='"${ATH_DEFAULT}"'
+CFLAGS+=-I${.CURDIR}
+CFLAGS+=-I${.CURDIR}/../common
+CFLAGS+=-I${.CURDIR}/../../../../sys
+CFLAGS+=-I${.CURDIR}/../../../../sys/dev/ath
+CFLAGS+=-I${.CURDIR}/../../../../sys/dev/ath/ath_hal
+CFLAGS+=-I${.OBJDIR}
diff --git a/tools/tools/ath/arcode/Makefile b/tools/tools/ath/arcode/Makefile
new file mode 100644
index 000000000000..9611a6ff9c36
--- /dev/null
+++ b/tools/tools/ath/arcode/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+PROG= arcode
+NOMAN= yes
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/arcode/arcode.c b/tools/tools/ath/arcode/arcode.c
new file mode 100644
index 000000000000..31e02cdb84eb
--- /dev/null
+++ b/tools/tools/ath/arcode/arcode.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/alq.h>
+
+#include "ah_decode.h"
+
+#define MAX_MARKERS 9
+
+const char *markers[] = {
+ "AH_MARK_RESET", /* ar*Reset entry, bChannelChange */
+ "AH_MARK_RESET_LINE", /* ar*_reset.c, line %d */
+ "AH_MARK_RESET_DONE", /* ar*Reset exit, error code */
+ "AH_MARK_CHIPRESET", /* ar*ChipReset, channel num */
+ "AH_MARK_PERCAL", /* ar*PerCalibration, channel num */
+ "AH_MARK_SETCHANNEL", /* ar*SetChannel, channel num */
+ "AH_MARK_ANI_RESET", /* ar*AniReset, opmode */
+ "AH_MARK_ANI_POLL", /* ar*AniReset, listen time */
+ "AH_MARK_ANI_CONTROL", /* ar*AniReset, cmd */
+};
+
+static void
+op_read(struct athregrec *a)
+{
+ printf("read\t%.8x = %.8x\n", a->reg, a->val);
+}
+
+static void
+op_write(struct athregrec *a)
+{
+ printf("write\t%.8x = %.8x\n", a->reg, a->val);
+}
+
+static void
+op_device(struct athregrec *a)
+{
+ printf("device\t0x%x/0x%x\n", a->reg, a->val);
+}
+
+static void
+op_mark(struct athregrec *a)
+{
+ const char *s = "UNKNOWN";
+ if (a->reg <= MAX_MARKERS)
+ s = markers[a->reg];
+
+ printf("mark\t%s (%d): %d\n", s, a->reg, a->val);
+}
+
+int
+main(int argc, const char *argv[])
+{
+ const char *file = argv[1];
+ int fd;
+ struct athregrec a;
+ int r;
+
+ if (argc < 2) {
+ printf("usage: %s <ahq log>\n", argv[0]);
+ exit(127);
+ }
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ exit(127);
+ }
+
+ while (1) {
+ r = read(fd, &a, sizeof(a));
+ if (r != sizeof(a))
+ break;
+ switch (a.op) {
+ case OP_READ:
+ op_read(&a);
+ break;
+ case OP_WRITE:
+ op_write(&a);
+ break;
+ case OP_DEVICE:
+ op_device(&a);
+ break;
+ case OP_MARK:
+ op_mark(&a);
+ break;
+ default:
+ printf("op: %s; reg: %x; val: %x\n",
+ a.op, a.reg, a.val);
+ }
+ }
+ close(fd);
+}
diff --git a/tools/tools/ath/ath_ee_9287_print/9287.c b/tools/tools/ath/ath_ee_9287_print/9287.c
new file mode 100644
index 000000000000..3ed970cba65d
--- /dev/null
+++ b/tools/tools/ath/ath_ee_9287_print/9287.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <err.h>
+
+typedef enum {
+ AH_FALSE = 0, /* NB: lots of code assumes false is zero */
+ AH_TRUE = 1,
+} HAL_BOOL;
+
+typedef enum {
+ HAL_OK = 0, /* No error */
+} HAL_STATUS;
+
+struct ath_hal;
+
+#include "ah_eeprom_v14.h"
+#include "ah_eeprom_9287.h"
+
+void
+eeprom_9287_base_print(uint16_t *buf)
+{
+ HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf;
+ BASE_EEP_9287_HEADER *eh = &eep->ee_base.baseEepHeader;
+ int i;
+
+ printf("| Version: 0x%.4x | Length: 0x%.4x | Checksum: 0x%.4x ",
+ eh->version, eh->length, eh->checksum);
+ printf("| CapFlags: 0x%.2x | eepMisc: 0x%.2x | RegDomain: 0x%.4x 0x%.4x | \n",
+ eh->opCapFlags, eh->eepMisc, eh->regDmn[0], eh->regDmn[1]);
+ printf("| MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ",
+ eh->macAddr[0], eh->macAddr[1], eh->macAddr[2],
+ eh->macAddr[3], eh->macAddr[4], eh->macAddr[5]);
+ printf("| RxMask: 0x%.2x | TxMask: 0x%.2x | RfSilent: 0x%.4x | btOptions: 0x%.4x |\n",
+ eh->rxMask, eh->txMask, eh->rfSilent, eh->blueToothOptions);
+ printf("| DeviceCap: 0x%.4x | binBuildNumber: %.8x | deviceType: 0x%.2x | openLoopPwrCntl 0x%.2x |\n",
+ eh->deviceCap, eh->binBuildNumber, eh->deviceType, eh->openLoopPwrCntl);
+ printf("| pwrTableOffset: %d | tempSensSlope: %d | tempSensSlopePalOn: %d |\n",
+ eh->pwrTableOffset, eh->tempSensSlope, eh->tempSensSlopePalOn);
+
+ printf("Future:\n");
+ for (i = 0; i < sizeof(eh->futureBase) / sizeof(uint16_t); i++) {
+ printf("0x%.2x ", eh->futureBase[i]);
+ }
+ printf("\n");
+}
+
+void
+eeprom_9287_custdata_print(uint16_t *buf)
+{
+ HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf;
+ uint8_t *custdata = (uint8_t *) &eep->ee_base.custData;
+ int i;
+
+ printf("\n| Custdata: |\n");
+ for (i = 0; i < 20; i++) {
+ printf("%s0x%.2x %s",
+ i % 16 == 0 ? "| " : "",
+ custdata[i],
+ i % 16 == 15 ? "|\n" : "");
+ }
+ printf("\n");
+}
+
+void
+eeprom_9287_modal_print(uint16_t *buf)
+{
+ HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf;
+ MODAL_EEP_9287_HEADER *mh = &eep->ee_base.modalHeader;
+ int i;
+
+ printf("| antCtrlCommon: 0x%.8x |\n", mh->antCtrlCommon);
+ printf("| switchSettling: 0x%.2x |\n", mh->switchSettling);
+ printf("| adcDesiredSize: %d |\n", mh->adcDesiredSize);
+
+ for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+ printf("| Chain %d:\n", i);
+ printf("| antCtrlChain: 0:0x%.4x |\n", mh->antCtrlChain[i]);
+ printf("| antennaGainCh: 0:0x%.2x |\n", mh->antennaGainCh[i]);
+ printf("| txRxAttenCh: 0:0x%.2x |\n", mh->txRxAttenCh[i]);
+ printf("| rxTxMarginCh: 0:0x%.2x |\n", mh->rxTxMarginCh[i]);
+ printf("| noiseFloorThresCh: 0:0x%.2x |\n", mh->noiseFloorThreshCh[i]);
+ printf("| iqCalICh: 0:0x%.2x |\n", mh->iqCalICh[i]);
+ printf("| iqCalQCh: 0:0x%.2x |\n", mh->iqCalQCh[i]);
+ printf("| bswAtten: 0:0x%.2x |\n", mh->bswAtten[i]);
+ printf("| bswMargin: 0:0x%.2x |\n", mh->bswMargin[i]);
+ printf("\n");
+ }
+
+ printf("| txEndToXpaOff: 0x%.2x | txEndToRxOn: 0x%.2x | txFrameToXpaOn: 0x%.2x |\n",
+ mh->txEndToXpaOff, mh->txEndToRxOn, mh->txFrameToXpaOn);
+ printf("| thres62: 0x%.2x\n", mh->thresh62);
+ printf("| xpdGain: 0x%.2x | xpd: 0x%.2x |\n", mh->xpdGain, mh->xpd);
+
+ printf("| pdGainOverlap: 0x%.2x xpaBiasLvl: 0x%.2x |\n", mh->pdGainOverlap, mh->xpaBiasLvl);
+ printf("| txFrameToDataStart: 0x%.2x | txFrameToPaOn: 0x%.2x |\n", mh->txFrameToDataStart, mh->txFrameToPaOn);
+ printf("| ht40PowerIncForPdadc: 0x%.2x |\n", mh->ht40PowerIncForPdadc);
+ printf("| swSettleHt40: 0x%.2x |\n", mh->swSettleHt40);
+
+ printf("| Modal Version: %.2x |\n", mh->version);
+ printf("| db1 = %d | db2 = %d |\n", mh->db1, mh->db2);
+ printf("| ob_cck = %d | ob_psk = %d | ob_qam = %d | ob_pal_off = %d |\n",
+ mh->ob_cck, mh->ob_psk, mh->ob_qam, mh->ob_pal_off);
+
+ printf("| futureModal: ");
+ for (i = 0; i < sizeof(mh->futureModal) / sizeof(uint16_t); i++) {
+ printf("0x%.2x ", mh->futureModal[i]);
+ }
+ printf("\n");
+
+ /* and now, spur channels */
+ for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+ printf("| Spur %d: spurChan: 0x%.4x spurRangeLow: 0x%.2x spurRangeHigh: 0x%.2x |\n",
+ i, mh->spurChans[i].spurChan,
+ (int) mh->spurChans[i].spurRangeLow,
+ (int) mh->spurChans[i].spurRangeHigh);
+ }
+}
+
+static void
+eeprom_9287_print_caldata_oploop(struct cal_data_op_loop_ar9287 *f)
+{
+ int i, j;
+
+ /* XXX flesh out the rest */
+ for (i = 0; i < 2; i++) {
+ printf(" pwrPdg:");
+ for (j = 0; j < 5; j++) {
+ printf("[%d][%d]=%d, ", i, j, f->pwrPdg[i][j]);
+ }
+ printf("\n");
+
+ printf(" vpdPdg:");
+ for (j = 0; j < 5; j++) {
+ printf("[%d][%d]=%d, ", i, j, f->vpdPdg[i][j]);
+ }
+ printf("\n");
+
+ printf(" pcdac:");
+ for (j = 0; j < 5; j++) {
+ printf("[%d][%d]=%d, ", i, j, f->pcdac[i][j]);
+ }
+ printf("\n");
+
+ printf(" empty:");
+ for (j = 0; j < 5; j++) {
+ printf("[%d][%d]=%d, ", i, j, f->empty[i][j]);
+ }
+ printf("\n\n");
+ }
+}
+
+void
+eeprom_9287_calfreqpiers_print(uint16_t *buf)
+{
+ HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf;
+ int i, n;
+
+ /* 2ghz cal piers */
+ printf("calFreqPier2G: ");
+ for (i = 0; i < AR9287_NUM_2G_CAL_PIERS; i++) {
+ printf(" 0x%.2x ", eep->ee_base.calFreqPier2G[i]);
+ }
+ printf("|\n");
+
+ for (i = 0; i < AR9287_NUM_2G_CAL_PIERS; i++) {
+ if (eep->ee_base.calFreqPier2G[i] == 0xff)
+ continue;
+ printf("2Ghz Cal Pier %d\n", i);
+ for (n = 0; n < AR9287_MAX_CHAINS; n++) {
+ printf(" Chain %d:\n", n);
+ eeprom_9287_print_caldata_oploop((void *)&eep->ee_base.calPierData2G[n][i]);
+ }
+ }
+
+ printf("\n");
+}
+
+/* XXX these should just reference the v14 print routines */
+static void
+eeprom_v14_target_legacy_print(CAL_TARGET_POWER_LEG *l)
+{
+ int i;
+ if (l->bChannel == 0xff)
+ return;
+ printf(" bChannel: %d;", l->bChannel);
+ for (i = 0; i < 4; i++) {
+ printf(" %.2f", (float) l->tPow2x[i] / 2.0);
+ }
+ printf(" (dBm)\n");
+}
+
+static void
+eeprom_v14_target_ht_print(CAL_TARGET_POWER_HT *l)
+{
+ int i;
+ if (l->bChannel == 0xff)
+ return;
+ printf(" bChannel: %d;", l->bChannel);
+ for (i = 0; i < 8; i++) {
+ printf(" %.2f", (float) l->tPow2x[i] / 2.0);
+ }
+ printf(" (dBm)\n");
+}
+
+void
+eeprom_9287_print_targets(uint16_t *buf)
+{
+ HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf;
+ int i;
+
+ /* 2ghz rates */
+ printf("2Ghz CCK:\n");
+ for (i = 0; i < AR9287_NUM_2G_CCK_TARGET_POWERS; i++) {
+ eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPowerCck[i]);
+ }
+ printf("2Ghz 11g:\n");
+ for (i = 0; i < AR9287_NUM_2G_20_TARGET_POWERS; i++) {
+ eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPower2G[i]);
+ }
+ printf("2Ghz HT20:\n");
+ for (i = 0; i < AR9287_NUM_2G_20_TARGET_POWERS; i++) {
+ eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT20[i]);
+ }
+ printf("2Ghz HT40:\n");
+ for (i = 0; i < AR9287_NUM_2G_40_TARGET_POWERS; i++) {
+ eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT40[i]);
+ }
+
+}
+
+static void
+eeprom_9287_ctl_edge_print(struct cal_ctl_data_ar9287 *ctl)
+{
+ int i, j;
+ uint8_t pow, flag;
+
+ for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+ printf(" chain %d: ", i);
+ for (j = 0; j < AR9287_NUM_BAND_EDGES; j++) {
+ pow = ctl->ctlEdges[i][j].tPowerFlag & 0x3f;
+ flag = (ctl->ctlEdges[i][j].tPowerFlag & 0xc0) >> 6;
+ printf(" %d:pow=%d,flag=%.2x", j, pow, flag);
+ }
+ printf("\n");
+ }
+}
+
+void
+eeprom_9287_ctl_print(uint16_t *buf)
+{
+ HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf;
+ int i;
+
+ for (i = 0; i < AR9287_NUM_CTLS; i++) {
+ if (eep->ee_base.ctlIndex[i] == 0)
+ continue;
+ printf("| ctlIndex: offset %d, value %d\n", i, eep->ee_base.ctlIndex[i]);
+ eeprom_9287_ctl_edge_print(&eep->ee_base.ctlData[i]);
+ }
+}
+
+void
+eeprom_9287_print_edges(uint16_t *buf)
+{
+ HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf;
+ int i;
+
+ printf("| eeNumCtls: %d\n", eep->ee_numCtls);
+ for (i = 0; i < NUM_EDGES*eep->ee_numCtls; i++) {
+ /* XXX is flag 8 or 32 bits? */
+ printf("| edge %2d/%2d: rdEdge: %5d EdgePower: %.2f dBm Flag: 0x%.8x\n",
+ i / NUM_EDGES, i % NUM_EDGES,
+ eep->ee_rdEdgesPower[i].rdEdge,
+ (float) eep->ee_rdEdgesPower[i].twice_rdEdgePower / 2.0,
+ eep->ee_rdEdgesPower[i].flag);
+
+ if (i % NUM_EDGES == (NUM_EDGES -1))
+ printf("|\n");
+ }
+}
+
+void
+eeprom_9287_print_other(uint16_t *buf)
+{
+ HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf;
+}
diff --git a/tools/tools/ath/ath_ee_9287_print/9287.h b/tools/tools/ath/ath_ee_9287_print/9287.h
new file mode 100644
index 000000000000..4cfc4241fdf3
--- /dev/null
+++ b/tools/tools/ath/ath_ee_9287_print/9287.h
@@ -0,0 +1,15 @@
+/* $FreeBSD$ */
+
+#ifndef __9287_H__
+#define __9287_H__
+
+extern void eeprom_9287_base_print(uint16_t *buf);
+extern void eeprom_9287_custdata_print(uint16_t *buf);
+extern void eeprom_9287_modal_print(uint16_t *buf);
+extern void eeprom_9287_calfreqpiers_print(uint16_t *buf);
+extern void eeprom_9287_ctl_print(uint16_t *buf);
+extern void eeprom_9287_print_targets(uint16_t *buf);
+extern void eeprom_9287_print_edges(uint16_t *buf);
+extern void eeprom_9287_print_other(uint16_t *buf);
+
+#endif
diff --git a/tools/tools/ath/ath_ee_9287_print/Makefile b/tools/tools/ath/ath_ee_9287_print/Makefile
new file mode 100644
index 000000000000..b25172bfead5
--- /dev/null
+++ b/tools/tools/ath/ath_ee_9287_print/Makefile
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal
+
+PROG= ath_ee_9287_print
+SRCS= main.c eeprom.c 9287.c
+NOMAN= yes
+NO_MAN= yes
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/ath_ee_9287_print/eeprom.c b/tools/tools/ath/ath_ee_9287_print/eeprom.c
new file mode 100644
index 000000000000..9e5c865a48da
--- /dev/null
+++ b/tools/tools/ath/ath_ee_9287_print/eeprom.c
@@ -0,0 +1,72 @@
+
+/*
+ * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <err.h>
+
+#include "eeprom.h"
+
+void
+load_eeprom_dump(const char *file, uint16_t *buf)
+{
+ unsigned int r[8];
+ FILE *fp;
+ char b[1024];
+ int i;
+
+ fp = fopen(file, "r");
+ if (!fp)
+ err(1, "fopen");
+
+ while (!feof(fp)) {
+ if (fgets(b, 1024, fp) == NULL)
+ break;
+ if (feof(fp))
+ break;
+ if (strlen(b) > 0)
+ b[strlen(b)-1] = '\0';
+ if (strlen(b) == 0)
+ break;
+ sscanf(b, "%x: %x %x %x %x %x %x %x %x\n",
+ &i, &r[0], &r[1], &r[2], &r[3], &r[4],
+ &r[5], &r[6], &r[7]);
+ buf[i++] = r[0];
+ buf[i++] = r[1];
+ buf[i++] = r[2];
+ buf[i++] = r[3];
+ buf[i++] = r[4];
+ buf[i++] = r[5];
+ buf[i++] = r[6];
+ buf[i++] = r[7];
+ }
+ fclose(fp);
+}
diff --git a/tools/tools/ath/ath_ee_9287_print/eeprom.h b/tools/tools/ath/ath_ee_9287_print/eeprom.h
new file mode 100644
index 000000000000..a5fc76a9b58d
--- /dev/null
+++ b/tools/tools/ath/ath_ee_9287_print/eeprom.h
@@ -0,0 +1,8 @@
+/* $FreeBSD$ */
+
+#ifndef __EEPROM_H__
+#define __EEPROM_H__
+
+extern void load_eeprom_dump(const char *file, uint16_t *buf);
+
+#endif
diff --git a/tools/tools/ath/ath_ee_9287_print/main.c b/tools/tools/ath/ath_ee_9287_print/main.c
new file mode 100644
index 000000000000..128b01fe4092
--- /dev/null
+++ b/tools/tools/ath/ath_ee_9287_print/main.c
@@ -0,0 +1,85 @@
+
+/*
+ * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <err.h>
+
+#include "eeprom.h"
+#include "9287.h"
+
+void
+usage(char *argv[])
+{
+ printf("Usage: %s <eeprom dump file>\n", argv[0]);
+ printf("\n");
+ printf(" The eeprom dump file is a text hexdump of an EEPROM.\n");
+ printf(" The lines must be formatted as follows:\n");
+ printf(" 0xAAAA: 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD\n");
+ printf(" where each line must have exactly eight data bytes.\n");
+ exit(127);
+}
+
+int
+main(int argc, char *argv[])
+{
+ uint16_t *eep = NULL;
+ eep = calloc(4096, sizeof(int16_t));
+
+ if (argc < 2)
+ usage(argv);
+
+ load_eeprom_dump(argv[1], eep);
+
+ eeprom_9287_base_print(eep);
+ eeprom_9287_custdata_print(eep);
+ printf("\n2.4ghz:\n");
+ eeprom_9287_modal_print(eep);
+ printf("\n");
+
+ eeprom_9287_calfreqpiers_print(eep);
+ printf("\n");
+
+ eeprom_9287_print_targets(eep);
+ printf("\n");
+
+ eeprom_9287_ctl_print(eep);
+ printf("\n");
+
+ eeprom_9287_print_edges(eep);
+ printf("\n");
+
+ eeprom_9287_print_other(eep);
+ printf("\n");
+
+ free(eep);
+ exit(0);
+}
diff --git a/tools/tools/ath/ath_ee_v14_print/Makefile b/tools/tools/ath/ath_ee_v14_print/Makefile
new file mode 100644
index 000000000000..552aaa0313f7
--- /dev/null
+++ b/tools/tools/ath/ath_ee_v14_print/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal
+
+PROG= ath_ee_v14_print
+NOMAN= yes
+NO_MAN= yes
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/ath_ee_v14_print/ath_ee_v14_print.c b/tools/tools/ath/ath_ee_v14_print/ath_ee_v14_print.c
new file mode 100644
index 000000000000..1340c78a814a
--- /dev/null
+++ b/tools/tools/ath/ath_ee_v14_print/ath_ee_v14_print.c
@@ -0,0 +1,473 @@
+
+/*
+ * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <err.h>
+
+typedef enum {
+ AH_FALSE = 0, /* NB: lots of code assumes false is zero */
+ AH_TRUE = 1,
+} HAL_BOOL;
+
+typedef enum {
+ HAL_OK = 0, /* No error */
+} HAL_STATUS;
+
+struct ath_hal;
+
+#include "ah_eeprom_v14.h"
+
+void
+load_eeprom_dump(const char *file, uint16_t *buf)
+{
+ unsigned int r[8];
+ FILE *fp;
+ char b[1024];
+ int i;
+
+ fp = fopen(file, "r");
+ if (!fp)
+ err(1, "fopen");
+
+ while (!feof(fp)) {
+ if (fgets(b, 1024, fp) == NULL)
+ break;
+ if (feof(fp))
+ break;
+ if (strlen(b) > 0)
+ b[strlen(b)-1] = '\0';
+ if (strlen(b) == 0)
+ break;
+ sscanf(b, "%x: %x %x %x %x %x %x %x %x\n",
+ &i, &r[0], &r[1], &r[2], &r[3], &r[4],
+ &r[5], &r[6], &r[7]);
+ buf[i++] = r[0];
+ buf[i++] = r[1];
+ buf[i++] = r[2];
+ buf[i++] = r[3];
+ buf[i++] = r[4];
+ buf[i++] = r[5];
+ buf[i++] = r[6];
+ buf[i++] = r[7];
+ }
+ fclose(fp);
+}
+
+static void
+eeprom_v14_base_print(uint16_t *buf)
+{
+ HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf;
+ BASE_EEP_HEADER *eh = &eep->ee_base.baseEepHeader;
+ int i;
+
+ printf("| Version: 0x%.4x | Length: 0x%.4x | Checksum: 0x%.4x ",
+ eh->version, eh->length, eh->checksum);
+ printf("| CapFlags: 0x%.2x\n", eh->opCapFlags);
+
+ printf("| eepMisc: 0x%.2x | RegDomain: 0x%.4x 0x%.4x | \n",
+ eh->eepMisc, eh->regDmn[0], eh->regDmn[1]);
+ printf("| MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ",
+ eh->macAddr[0], eh->macAddr[1], eh->macAddr[2],
+ eh->macAddr[3], eh->macAddr[4], eh->macAddr[5]);
+ printf("| RxMask: 0x%.2x | TxMask: 0x%.2x | RfSilent: 0x%.4x | btOptions: 0x%.4x |\n",
+ eh->rxMask, eh->txMask, eh->rfSilent, eh->blueToothOptions);
+ printf("| DeviceCap: 0x%.4x | binBuildNumber: %.8x | deviceType: 0x%.2x |\n",
+ eh->deviceCap, eh->binBuildNumber, eh->deviceType);
+
+ printf("| pwdclkind: 0x%.2x | fastClk5g: 0x%.2x | divChain: 0x%.2x | rxGainType: 0x%.2x |\n",
+ (int) eh->pwdclkind, (int) eh->fastClk5g, (int) eh->divChain,
+ (int) eh->rxGainType);
+
+ printf("| dacHiPwrMode_5G: 0x%.2x | openLoopPwrCntl: 0x%.2x | dacLpMode: 0x%.2x\n",
+ (int) eh->dacHiPwrMode_5G, (int) eh->openLoopPwrCntl, (int) eh->dacLpMode);
+ printf("| txGainType: 0x%.2x | rcChainMask: 0x%.2x |\n",
+ (int) eh->txGainType, (int) eh->rcChainMask);
+
+ printf("| desiredScaleCCK: 0x%.2x | pwr_table_offset: 0x%.2x | frac_n_5g: %.2x\n",
+ (int) eh->desiredScaleCCK, (int) eh->pwr_table_offset, (int) eh->frac_n_5g);
+
+ /* because it's convienent */
+ printf("| antennaGainMax[0]: 0x%.2x antennaGainMax[1]: 0x%.2x |\n",
+ eep->ee_antennaGainMax[0], eep->ee_antennaGainMax[1]);
+
+ printf(" | futureBase:");
+ for (i = 0; i < sizeof(eh->futureBase) / sizeof(uint8_t); i++)
+ printf(" %.2x", (int) eh->futureBase[i]);
+ printf("\n");
+}
+
+static void
+eeprom_v14_custdata_print(uint16_t *buf)
+{
+ HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf;
+ uint8_t *custdata = (uint8_t *) &eep->ee_base.custData;
+ int i;
+
+ printf("\n| Custdata: |\n");
+ for (i = 0; i < 64; i++) {
+ printf("%s0x%.2x %s",
+ i % 16 == 0 ? "| " : "",
+ custdata[i],
+ i % 16 == 15 ? "|\n" : "");
+ }
+}
+
+static void
+eeprom_v14_modal_print(uint16_t *buf, int m)
+{
+ HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf;
+ MODAL_EEP_HEADER *mh = &eep->ee_base.modalHeader[m];
+ int i;
+
+ printf("| antCtrlCommon: 0x%.8x |\n", mh->antCtrlCommon);
+ printf("| switchSettling: 0x%.2x |\n", mh->switchSettling);
+ printf("| adcDesiredSize: %d |\n| pgaDesiredSize: %.2f dBm |\n",
+ mh->adcDesiredSize, (float) mh->pgaDesiredSize / 2.0);
+
+ printf("| antCtrlChain: 0:0x%.8x 1:0x%.8x 2:0x%.8x |\n",
+ mh->antCtrlChain[0], mh->antCtrlChain[1], mh->antCtrlChain[2]);
+ printf("| antennaGainCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n",
+ mh->antennaGainCh[0], mh->antennaGainCh[1], mh->antennaGainCh[2]);
+ printf("| txRxAttenCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n",
+ mh->txRxAttenCh[0], mh->txRxAttenCh[1], mh->txRxAttenCh[2]);
+ printf("| rxTxMarginCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n",
+ mh->rxTxMarginCh[0], mh->rxTxMarginCh[1], mh->rxTxMarginCh[2]);
+ printf("| noiseFloorThresCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n",
+ mh->noiseFloorThreshCh[0], mh->noiseFloorThreshCh[1], mh->noiseFloorThreshCh[2]);
+ printf("| xlnaGainCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n",
+ mh->xlnaGainCh[0], mh->xlnaGainCh[1], mh->xlnaGainCh[2]);
+ printf("| iqCalICh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n| iqCalQCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n",
+ mh->iqCalICh[0], mh->iqCalICh[1], mh->iqCalICh[2],
+ mh->iqCalQCh[0], mh->iqCalQCh[1], mh->iqCalQCh[2]);
+ printf("| bswAtten: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n",
+ mh->bswAtten[0], mh->bswAtten[1], mh->bswAtten[2]);
+ printf("| bswMargin: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n",
+ mh->bswMargin[0], mh->bswMargin[1], mh->bswMargin[2]);
+ printf("| xatten2Db: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n",
+ mh->xatten2Db[0], mh->xatten2Db[1], mh->xatten2Db[2]);
+ printf("| xatten2Margin: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n",
+ mh->xatten2Margin[0], mh->xatten2Margin[1], mh->xatten2Margin[2]);
+
+ printf("| txEndToXpaOff: 0x%.2x | txEndToRxOn: 0x%.2x | txFrameToXpaOn: 0x%.2x |\n",
+ mh->txEndToXpaOff, mh->txEndToRxOn, mh->txFrameToXpaOn);
+
+ printf("| thres62: 0x%.2x\n", mh->thresh62);
+
+ printf("| xpdGain: 0x%.2x | xpd: 0x%.2x |\n", mh->xpdGain, mh->xpd);
+ printf("| xpaBiasLvlFreq: 0:0x%.4x 1:0x%.4x 2:0x%.4x |\n",
+ mh->xpaBiasLvlFreq[0], mh->xpaBiasLvlFreq[1], mh->xpaBiasLvlFreq[2]);
+
+ printf("| pdGainOverlap: 0x%.2x | ob: 0x%.2x | db: 0x%.2x | xpaBiasLvl: 0x%.2x |\n",
+ mh->pdGainOverlap, mh->ob, mh->db, mh->xpaBiasLvl);
+
+ printf("| pwrDecreaseFor2Chain: 0x%.2x | pwrDecreaseFor3Chain: 0x%.2x | txFrameToDataStart: 0x%.2x | txFrameToPaOn: 0x%.2x |\n",
+ mh->pwrDecreaseFor2Chain, mh->pwrDecreaseFor3Chain, mh->txFrameToDataStart,
+ mh->txFrameToPaOn);
+
+ printf("| ht40PowerIncForPdadc: 0x%.2x |\n", mh->ht40PowerIncForPdadc);
+
+ printf("| swSettleHt40: 0x%.2x |\n", mh->swSettleHt40);
+
+ printf("| ob_ch1: 0x%.2x | db_ch1: 0x%.2x |\n", mh->ob_ch1, mh->db_ch1);
+
+ printf("| flagBits: 0x%.2x | miscBits: 0x%.2x |\n", mh->flagBits, mh->miscBits);
+
+
+ printf("| futureModal: 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x |\n",
+ mh->futureModal[0],
+ mh->futureModal[1],
+ mh->futureModal[2],
+ mh->futureModal[3],
+ mh->futureModal[4],
+ mh->futureModal[5]);
+
+ /* and now, spur channels */
+ for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+ printf("| Spur %d: spurChan: 0x%.4x spurRangeLow: 0x%.2x spurRangeHigh: 0x%.2x |\n",
+ i, mh->spurChans[i].spurChan,
+ (int) mh->spurChans[i].spurRangeLow,
+ (int) mh->spurChans[i].spurRangeHigh);
+ }
+}
+
+static void
+eeprom_v14_print_caldata_perfreq_op_loop(CAL_DATA_PER_FREQ_OP_LOOP *f)
+{
+ int i, j;
+ for (i = 0; i < 2; i++) {
+ printf(" Gain: %d:\n", i);
+ for (j = 0; j < 5; j++) {
+ printf(" %d: pwrPdg: %d, vpdPdg: %d, pcdac: %d, empty: %d\n",
+ j, f->pwrPdg[i][j], f->vpdPdg[i][j], f->pcdac[i][j], f->empty[i][j]);
+ }
+ printf("\n");
+ }
+}
+
+static void
+eeprom_v14_print_caldata_perfreq(CAL_DATA_PER_FREQ *f)
+{
+ int i, j;
+
+ for (i = 0; i < AR5416_NUM_PD_GAINS; i++) {
+ printf(" Gain %d: pwr dBm/vpd: ", i);
+ for (j = 0; j < AR5416_PD_GAIN_ICEPTS; j++) {
+ /* These are stored in 0.25dBm increments */
+ printf("%d:(%.2f/%d) ", j, (float) f->pwrPdg[i][j] / 4.00,
+ f->vpdPdg[i][j]);
+ }
+ printf("\n");
+ }
+}
+
+static void
+eeprom_v14_calfreqpiers_print(uint16_t *buf)
+{
+ HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf;
+ int i, n;
+
+ /* 2ghz cal piers */
+ printf("calFreqPier2G: ");
+ for (i = 0; i < AR5416_NUM_2G_CAL_PIERS; i++) {
+ printf(" 0x%.2x ", eep->ee_base.calFreqPier2G[i]);
+ }
+ printf("|\n");
+
+ for (i = 0; i < AR5416_NUM_2G_CAL_PIERS; i++) {
+ if (eep->ee_base.calFreqPier2G[i] == 0xff)
+ continue;
+ printf("2Ghz Cal Pier %d\n", i);
+ for (n = 0; n < AR5416_MAX_CHAINS; n++) {
+ printf(" Chain %d:\n", n);
+ if (eep->ee_base.baseEepHeader.openLoopPwrCntl)
+ eeprom_v14_print_caldata_perfreq_op_loop((void *) (&eep->ee_base.calPierData2G[n][i]));
+ else
+ eeprom_v14_print_caldata_perfreq(&eep->ee_base.calPierData2G[n][i]);
+ }
+ }
+
+ printf("\n");
+
+ /* 5ghz cal piers */
+ printf("calFreqPier5G: ");
+ for (i = 0; i < AR5416_NUM_5G_CAL_PIERS; i++) {
+ printf(" 0x%.2x ", eep->ee_base.calFreqPier5G[i]);
+ }
+ printf("|\n");
+ for (i = 0; i < AR5416_NUM_5G_CAL_PIERS; i++) {
+ if (eep->ee_base.calFreqPier5G[i] == 0xff)
+ continue;
+ printf("5Ghz Cal Pier %d\n", i);
+ for (n = 0; n < AR5416_MAX_CHAINS; n++) {
+ printf(" Chain %d:\n", n);
+ if (eep->ee_base.baseEepHeader.openLoopPwrCntl)
+ eeprom_v14_print_caldata_perfreq_op_loop((void *) (&eep->ee_base.calPierData5G[n][i]));
+ else
+ eeprom_v14_print_caldata_perfreq(&eep->ee_base.calPierData5G[n][i]);
+ }
+ }
+}
+
+static void
+eeprom_v14_target_legacy_print(CAL_TARGET_POWER_LEG *l)
+{
+ int i;
+ if (l->bChannel == 0xff)
+ return;
+ printf(" bChannel: %d;", l->bChannel);
+ for (i = 0; i < 4; i++) {
+ printf(" %.2f", (float) l->tPow2x[i] / 2.0);
+ }
+ printf(" (dBm)\n");
+}
+
+static void
+eeprom_v14_target_ht_print(CAL_TARGET_POWER_HT *l)
+{
+ int i;
+ if (l->bChannel == 0xff)
+ return;
+ printf(" bChannel: %d;", l->bChannel);
+ for (i = 0; i < 8; i++) {
+ printf(" %.2f", (float) l->tPow2x[i] / 2.0);
+ }
+ printf(" (dBm)\n");
+}
+
+static void
+eeprom_v14_print_targets(uint16_t *buf)
+{
+ HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf;
+ int i;
+
+ /* 2ghz rates */
+ printf("2Ghz CCK:\n");
+ for (i = 0; i < AR5416_NUM_2G_CCK_TARGET_POWERS; i++) {
+ eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPowerCck[i]);
+ }
+ printf("2Ghz 11g:\n");
+ for (i = 0; i < AR5416_NUM_2G_20_TARGET_POWERS; i++) {
+ eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPower2G[i]);
+ }
+ printf("2Ghz HT20:\n");
+ for (i = 0; i < AR5416_NUM_2G_20_TARGET_POWERS; i++) {
+ eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT20[i]);
+ }
+ printf("2Ghz HT40:\n");
+ for (i = 0; i < AR5416_NUM_2G_40_TARGET_POWERS; i++) {
+ eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT40[i]);
+ }
+
+ /* 5ghz rates */
+ printf("5Ghz 11a:\n");
+ for (i = 0; i < AR5416_NUM_5G_20_TARGET_POWERS; i++) {
+ eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPower5G[i]);
+ }
+ printf("5Ghz HT20:\n");
+ for (i = 0; i < AR5416_NUM_5G_20_TARGET_POWERS; i++) {
+ eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower5GHT20[i]);
+ }
+ printf("5Ghz HT40:\n");
+ for (i = 0; i < AR5416_NUM_5G_40_TARGET_POWERS; i++) {
+ eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower5GHT40[i]);
+ }
+
+}
+
+static void
+eeprom_v14_ctl_edge_print(CAL_CTL_DATA *ctl)
+{
+ int i, j;
+ uint8_t pow, flag;
+
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+ printf(" chain %d: ", i);
+ for (j = 0; j < AR5416_NUM_BAND_EDGES; j++) {
+ pow = ctl->ctlEdges[i][j].tPowerFlag & 0x3f;
+ flag = (ctl->ctlEdges[i][j].tPowerFlag & 0xc0) >> 6;
+ printf(" %d:pow=%d,flag=%.2x", j, pow, flag);
+ }
+ printf("\n");
+ }
+}
+
+static void
+eeprom_v14_ctl_print(uint16_t *buf)
+{
+ HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf;
+ int i;
+
+ for (i = 0; i < AR5416_NUM_CTLS; i++) {
+ if (eep->ee_base.ctlIndex[i] == 0)
+ continue;
+ printf("| ctlIndex: offset %d, value %d\n", i, eep->ee_base.ctlIndex[i]);
+ eeprom_v14_ctl_edge_print(&eep->ee_base.ctlData[i]);
+ }
+}
+
+static void
+eeprom_v14_print_edges(uint16_t *buf)
+{
+ HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf;
+ int i;
+
+ printf("| eeNumCtls: %d\n", eep->ee_numCtls);
+ for (i = 0; i < NUM_EDGES*eep->ee_numCtls; i++) {
+ /* XXX is flag 8 or 32 bits? */
+ printf("| edge %2d/%2d: rdEdge: %5d EdgePower: %.2f dBm Flag: 0x%.8x\n",
+ i / NUM_EDGES, i % NUM_EDGES,
+ eep->ee_rdEdgesPower[i].rdEdge,
+ (float) eep->ee_rdEdgesPower[i].twice_rdEdgePower / 2.0,
+ eep->ee_rdEdgesPower[i].flag);
+
+ if (i % NUM_EDGES == (NUM_EDGES -1))
+ printf("|\n");
+ }
+#if 0
+typedef struct {
+ uint16_t rdEdge;
+ uint16_t twice_rdEdgePower;
+ HAL_BOOL flag;
+ } RD_EDGES_POWER;
+
+#endif
+}
+
+void
+usage(char *argv[])
+{
+ printf("Usage: %s <eeprom dump file>\n", argv[0]);
+ printf("\n");
+ printf(" The eeprom dump file is a text hexdump of an EEPROM.\n");
+ printf(" The lines must be formatted as follows:\n");
+ printf(" 0xAAAA: 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD\n");
+ printf(" where each line must have exactly eight data bytes.\n");
+ exit(127);
+}
+
+int
+main(int argc, char *argv[])
+{
+ uint16_t *eep = NULL;
+ eep = calloc(4096, sizeof(int16_t));
+
+ if (argc < 2)
+ usage(argv);
+
+ load_eeprom_dump(argv[1], eep);
+
+ eeprom_v14_base_print(eep);
+ eeprom_v14_custdata_print(eep);
+
+ /* 2.4ghz */
+ printf("\n2.4ghz:\n");
+ eeprom_v14_modal_print(eep, 1);
+ /* 5ghz */
+ printf("\n5ghz:\n");
+ eeprom_v14_modal_print(eep, 0);
+ printf("\n");
+
+ eeprom_v14_calfreqpiers_print(eep);
+ printf("\n");
+
+ eeprom_v14_print_targets(eep);
+ printf("\n");
+
+ eeprom_v14_ctl_print(eep);
+ printf("\n");
+
+ eeprom_v14_print_edges(eep);
+ printf("\n");
+
+ free(eep);
+ exit(0);
+}
diff --git a/tools/tools/ath/ath_ee_v4k_print/Makefile b/tools/tools/ath/ath_ee_v4k_print/Makefile
new file mode 100644
index 000000000000..4bb3225b80b6
--- /dev/null
+++ b/tools/tools/ath/ath_ee_v4k_print/Makefile
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal
+
+PROG= ath_ee_v4k_print
+SRCS= main.c eeprom.c v4k.c
+NOMAN= yes
+NO_MAN= yes
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/ath_ee_v4k_print/eeprom.c b/tools/tools/ath/ath_ee_v4k_print/eeprom.c
new file mode 100644
index 000000000000..9e5c865a48da
--- /dev/null
+++ b/tools/tools/ath/ath_ee_v4k_print/eeprom.c
@@ -0,0 +1,72 @@
+
+/*
+ * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <err.h>
+
+#include "eeprom.h"
+
+void
+load_eeprom_dump(const char *file, uint16_t *buf)
+{
+ unsigned int r[8];
+ FILE *fp;
+ char b[1024];
+ int i;
+
+ fp = fopen(file, "r");
+ if (!fp)
+ err(1, "fopen");
+
+ while (!feof(fp)) {
+ if (fgets(b, 1024, fp) == NULL)
+ break;
+ if (feof(fp))
+ break;
+ if (strlen(b) > 0)
+ b[strlen(b)-1] = '\0';
+ if (strlen(b) == 0)
+ break;
+ sscanf(b, "%x: %x %x %x %x %x %x %x %x\n",
+ &i, &r[0], &r[1], &r[2], &r[3], &r[4],
+ &r[5], &r[6], &r[7]);
+ buf[i++] = r[0];
+ buf[i++] = r[1];
+ buf[i++] = r[2];
+ buf[i++] = r[3];
+ buf[i++] = r[4];
+ buf[i++] = r[5];
+ buf[i++] = r[6];
+ buf[i++] = r[7];
+ }
+ fclose(fp);
+}
diff --git a/tools/tools/ath/ath_ee_v4k_print/eeprom.h b/tools/tools/ath/ath_ee_v4k_print/eeprom.h
new file mode 100644
index 000000000000..a5fc76a9b58d
--- /dev/null
+++ b/tools/tools/ath/ath_ee_v4k_print/eeprom.h
@@ -0,0 +1,8 @@
+/* $FreeBSD$ */
+
+#ifndef __EEPROM_H__
+#define __EEPROM_H__
+
+extern void load_eeprom_dump(const char *file, uint16_t *buf);
+
+#endif
diff --git a/tools/tools/ath/ath_ee_v4k_print/main.c b/tools/tools/ath/ath_ee_v4k_print/main.c
new file mode 100644
index 000000000000..5ce3c3347766
--- /dev/null
+++ b/tools/tools/ath/ath_ee_v4k_print/main.c
@@ -0,0 +1,85 @@
+
+/*
+ * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <err.h>
+
+#include "eeprom.h"
+#include "v4k.h"
+
+void
+usage(char *argv[])
+{
+ printf("Usage: %s <eeprom dump file>\n", argv[0]);
+ printf("\n");
+ printf(" The eeprom dump file is a text hexdump of an EEPROM.\n");
+ printf(" The lines must be formatted as follows:\n");
+ printf(" 0xAAAA: 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD\n");
+ printf(" where each line must have exactly eight data bytes.\n");
+ exit(127);
+}
+
+int
+main(int argc, char *argv[])
+{
+ uint16_t *eep = NULL;
+ eep = calloc(4096, sizeof(int16_t));
+
+ if (argc < 2)
+ usage(argv);
+
+ load_eeprom_dump(argv[1], eep);
+
+ eeprom_v4k_base_print(eep);
+ eeprom_v4k_custdata_print(eep);
+ printf("\n2.4ghz:\n");
+ eeprom_v4k_modal_print(eep);
+ printf("\n");
+
+ eeprom_v4k_calfreqpiers_print(eep);
+ printf("\n");
+
+ eeprom_v4k_print_targets(eep);
+ printf("\n");
+
+ eeprom_v4k_ctl_print(eep);
+ printf("\n");
+
+ eeprom_v4k_print_edges(eep);
+ printf("\n");
+
+ eeprom_v4k_print_other(eep);
+ printf("\n");
+
+ free(eep);
+ exit(0);
+}
diff --git a/tools/tools/ath/ath_ee_v4k_print/v4k.c b/tools/tools/ath/ath_ee_v4k_print/v4k.c
new file mode 100644
index 000000000000..a3a8e6d28b3b
--- /dev/null
+++ b/tools/tools/ath/ath_ee_v4k_print/v4k.c
@@ -0,0 +1,300 @@
+
+/*
+ * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <err.h>
+
+typedef enum {
+ AH_FALSE = 0, /* NB: lots of code assumes false is zero */
+ AH_TRUE = 1,
+} HAL_BOOL;
+
+typedef enum {
+ HAL_OK = 0, /* No error */
+} HAL_STATUS;
+
+struct ath_hal;
+
+#include "ah_eeprom_v4k.h"
+
+void
+eeprom_v4k_base_print(uint16_t *buf)
+{
+ HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf;
+ BASE_EEP4K_HEADER *eh = &eep->ee_base.baseEepHeader;
+
+ printf("| Version: 0x%.4x | Length: 0x%.4x | Checksum: 0x%.4x ",
+ eh->version, eh->length, eh->checksum);
+ printf("| CapFlags: 0x%.2x | eepMisc: 0x%.2x | RegDomain: 0x%.4x 0x%.4x | \n",
+ eh->opCapFlags, eh->eepMisc, eh->regDmn[0], eh->regDmn[1]);
+ printf("| MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ",
+ eh->macAddr[0], eh->macAddr[1], eh->macAddr[2],
+ eh->macAddr[3], eh->macAddr[4], eh->macAddr[5]);
+ printf("| RxMask: 0x%.2x | TxMask: 0x%.2x | RfSilent: 0x%.4x | btOptions: 0x%.4x |\n",
+ eh->rxMask, eh->txMask, eh->rfSilent, eh->blueToothOptions);
+ printf("| DeviceCap: 0x%.4x | binBuildNumber: %.8x | deviceType: 0x%.2x | txGainType 0x%.2x |\n",
+ eh->deviceCap, eh->binBuildNumber, eh->deviceType, eh->txGainType);
+}
+
+void
+eeprom_v4k_custdata_print(uint16_t *buf)
+{
+ HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf;
+ uint8_t *custdata = (uint8_t *) &eep->ee_base.custData;
+ int i;
+
+ printf("\n| Custdata: |\n");
+ for (i = 0; i < 20; i++) {
+ printf("%s0x%.2x %s",
+ i % 16 == 0 ? "| " : "",
+ custdata[i],
+ i % 16 == 15 ? "|\n" : "");
+ }
+ printf("\n");
+}
+
+void
+eeprom_v4k_modal_print(uint16_t *buf)
+{
+ HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf;
+ MODAL_EEP4K_HEADER *mh = &eep->ee_base.modalHeader;
+ int i;
+
+ printf("| antCtrlCommon: 0x%.8x |\n", mh->antCtrlCommon);
+ printf("| switchSettling: 0x%.2x |\n", mh->switchSettling);
+ printf("| adcDesiredSize: %d |\n| pgaDesiredSize: %.2f dBm |\n",
+ mh->adcDesiredSize, (float) mh->pgaDesiredSize / 2.0);
+
+ printf("| antCtrlChain: 0:0x%.4x |\n", mh->antCtrlChain[0]);
+ printf("| antennaGainCh: 0:0x%.2x |\n", mh->antennaGainCh[0]);
+ printf("| txRxAttenCh: 0:0x%.2x |\n", mh->txRxAttenCh[0]);
+ printf("| rxTxMarginCh: 0:0x%.2x |\n", mh->rxTxMarginCh[0]);
+ printf("| noiseFloorThresCh: 0:0x%.2x |\n", mh->noiseFloorThreshCh[0]);
+ printf("| xlnaGainCh: 0:0x%.2x |\n", mh->xlnaGainCh[0]);
+ printf("| iqCalICh: 0:0x%.2x |\n", mh->iqCalICh[0]);
+ printf("| iqCalQCh: 0:0x%.2x |\n", mh->iqCalQCh[0]);
+ printf("| bswAtten: 0:0x%.2x |\n", mh->bswAtten[0]);
+ printf("| bswMargin: 0:0x%.2x |\n", mh->bswMargin[0]);
+ printf("| xatten2Db: 0:0x%.2x |\n", mh->xatten2Db[0]);
+ printf("| xatten2Margin: 0:0x%.2x |\n", mh->xatten2Margin[0]);
+
+ printf("| txEndToXpaOff: 0x%.2x | txEndToRxOn: 0x%.2x | txFrameToXpaOn: 0x%.2x |\n",
+ mh->txEndToXpaOff, mh->txEndToRxOn, mh->txFrameToXpaOn);
+ printf("| thres62: 0x%.2x\n", mh->thresh62);
+ printf("| xpdGain: 0x%.2x | xpd: 0x%.2x |\n", mh->xpdGain, mh->xpd);
+
+ printf("| pdGainOverlap: 0x%.2x xpaBiasLvl: 0x%.2x |\n", mh->pdGainOverlap, mh->xpaBiasLvl);
+ printf("| txFrameToDataStart: 0x%.2x | txFrameToPaOn: 0x%.2x |\n", mh->txFrameToDataStart, mh->txFrameToPaOn);
+ printf("| ht40PowerIncForPdadc: 0x%.2x |\n", mh->ht40PowerIncForPdadc);
+ printf("| swSettleHt40: 0x%.2x |\n", mh->swSettleHt40);
+
+ printf("| ob_0: 0x%.2x | ob_1: 0x%.2x | ob_2: 0x%.2x | ob_3: 0x%.2x |\n",
+ mh->ob_0, mh->ob_1, mh->ob_2, mh->ob_3);
+ printf("| db_1_0: 0x%.2x | db_1_1: 0x%.2x | db_1_2: 0x%.2x | db_1_3: 0x%.2x db_1_4: 0x%.2x|\n",
+ mh->db1_0, mh->db1_1, mh->db1_2, mh->db1_3, mh->db1_4);
+ printf("| db_1_0: 0x%.2x | db_1_1: 0x%.2x | db_1_2: 0x%.2x | db_1_3: 0x%.2x db_1_4: 0x%.2x|\n",
+ mh->db2_0, mh->db2_1, mh->db2_2, mh->db2_3, mh->db2_4);
+
+ printf("| antdiv_ctl1: 0x%.2x antdiv_ctl2: 0x%.2x |\n", mh->antdiv_ctl1, mh->antdiv_ctl2);
+
+ printf("| Modal Version: %.2x |\n", mh->version);
+
+ printf("| futureModal: 0x%.2x 0x%.2x 0x%.2x 0x%.2x |\n",
+ mh->futureModal[0],
+ mh->futureModal[1],
+ mh->futureModal[2],
+ mh->futureModal[3]
+ );
+
+ /* and now, spur channels */
+ for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+ printf("| Spur %d: spurChan: 0x%.4x spurRangeLow: 0x%.2x spurRangeHigh: 0x%.2x |\n",
+ i, mh->spurChans[i].spurChan,
+ (int) mh->spurChans[i].spurRangeLow,
+ (int) mh->spurChans[i].spurRangeHigh);
+ }
+}
+
+static void
+eeprom_v4k_print_caldata_perfreq(CAL_DATA_PER_FREQ_4K *f)
+{
+ int i, j;
+
+ for (i = 0; i < AR5416_4K_NUM_PD_GAINS; i++) {
+ printf(" Gain %d: pwr dBm/vpd: ", i);
+ for (j = 0; j < AR5416_PD_GAIN_ICEPTS; j++) {
+ /* These are stored in 0.25dBm increments */
+ /* XXX is this assumption correct for ar9285? */
+ /* XXX shouldn't we care about the power table offset, if there is one? */
+ printf("%d:(%.2f/%d) ", j, (float) f->pwrPdg[i][j] / 4.00,
+ f->vpdPdg[i][j]);
+ }
+ printf("\n");
+ }
+}
+
+void
+eeprom_v4k_calfreqpiers_print(uint16_t *buf)
+{
+ HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf;
+ int i, n;
+
+ /* 2ghz cal piers */
+ printf("calFreqPier2G: ");
+ for (i = 0; i < AR5416_4K_NUM_2G_CAL_PIERS; i++) {
+ printf(" 0x%.2x ", eep->ee_base.calFreqPier2G[i]);
+ }
+ printf("|\n");
+
+ for (i = 0; i < AR5416_4K_NUM_2G_CAL_PIERS; i++) {
+ if (eep->ee_base.calFreqPier2G[i] == 0xff)
+ continue;
+ printf("2Ghz Cal Pier %d\n", i);
+ for (n = 0; n < AR5416_4K_MAX_CHAINS; n++) {
+ printf(" Chain %d:\n", n);
+ eeprom_v4k_print_caldata_perfreq(&eep->ee_base.calPierData2G[n][i]);
+ }
+ }
+
+ printf("\n");
+}
+
+/* XXX these should just reference the v14 print routines */
+static void
+eeprom_v14_target_legacy_print(CAL_TARGET_POWER_LEG *l)
+{
+ int i;
+ if (l->bChannel == 0xff)
+ return;
+ printf(" bChannel: %d;", l->bChannel);
+ for (i = 0; i < 4; i++) {
+ printf(" %.2f", (float) l->tPow2x[i] / 2.0);
+ }
+ printf(" (dBm)\n");
+}
+
+static void
+eeprom_v14_target_ht_print(CAL_TARGET_POWER_HT *l)
+{
+ int i;
+ if (l->bChannel == 0xff)
+ return;
+ printf(" bChannel: %d;", l->bChannel);
+ for (i = 0; i < 8; i++) {
+ printf(" %.2f", (float) l->tPow2x[i] / 2.0);
+ }
+ printf(" (dBm)\n");
+}
+
+void
+eeprom_v4k_print_targets(uint16_t *buf)
+{
+ HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf;
+ int i;
+
+ /* 2ghz rates */
+ printf("2Ghz CCK:\n");
+ for (i = 0; i < AR5416_4K_NUM_2G_CCK_TARGET_POWERS; i++) {
+ eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPowerCck[i]);
+ }
+ printf("2Ghz 11g:\n");
+ for (i = 0; i < AR5416_4K_NUM_2G_20_TARGET_POWERS; i++) {
+ eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPower2G[i]);
+ }
+ printf("2Ghz HT20:\n");
+ for (i = 0; i < AR5416_4K_NUM_2G_20_TARGET_POWERS; i++) {
+ eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT20[i]);
+ }
+ printf("2Ghz HT40:\n");
+ for (i = 0; i < AR5416_4K_NUM_2G_40_TARGET_POWERS; i++) {
+ eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT40[i]);
+ }
+
+}
+
+static void
+eeprom_v4k_ctl_edge_print(CAL_CTL_DATA_4K *ctl)
+{
+ int i, j;
+ uint8_t pow, flag;
+
+ for (i = 0; i < AR5416_4K_MAX_CHAINS; i++) {
+ printf(" chain %d: ", i);
+ for (j = 0; j < AR5416_4K_NUM_BAND_EDGES; j++) {
+ pow = ctl->ctlEdges[i][j].tPowerFlag & 0x3f;
+ flag = (ctl->ctlEdges[i][j].tPowerFlag & 0xc0) >> 6;
+ printf(" %d:pow=%d,flag=%.2x", j, pow, flag);
+ }
+ printf("\n");
+ }
+}
+
+void
+eeprom_v4k_ctl_print(uint16_t *buf)
+{
+ HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf;
+ int i;
+
+ for (i = 0; i < AR5416_4K_NUM_CTLS; i++) {
+ if (eep->ee_base.ctlIndex[i] == 0)
+ continue;
+ printf("| ctlIndex: offset %d, value %d\n", i, eep->ee_base.ctlIndex[i]);
+ eeprom_v4k_ctl_edge_print(&eep->ee_base.ctlData[i]);
+ }
+}
+
+void
+eeprom_v4k_print_edges(uint16_t *buf)
+{
+ HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf;
+ int i;
+
+ printf("| eeNumCtls: %d\n", eep->ee_numCtls);
+ for (i = 0; i < NUM_EDGES*eep->ee_numCtls; i++) {
+ /* XXX is flag 8 or 32 bits? */
+ printf("| edge %2d/%2d: rdEdge: %5d EdgePower: %.2f dBm Flag: 0x%.8x\n",
+ i / NUM_EDGES, i % NUM_EDGES,
+ eep->ee_rdEdgesPower[i].rdEdge,
+ (float) eep->ee_rdEdgesPower[i].twice_rdEdgePower / 2.0,
+ eep->ee_rdEdgesPower[i].flag);
+
+ if (i % NUM_EDGES == (NUM_EDGES -1))
+ printf("|\n");
+ }
+}
+
+void
+eeprom_v4k_print_other(uint16_t *buf)
+{
+ HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf;
+ printf("| ee_antennaGainMax: %.2x\n", eep->ee_antennaGainMax);
+}
diff --git a/tools/tools/ath/ath_ee_v4k_print/v4k.h b/tools/tools/ath/ath_ee_v4k_print/v4k.h
new file mode 100644
index 000000000000..efe2dc945b86
--- /dev/null
+++ b/tools/tools/ath/ath_ee_v4k_print/v4k.h
@@ -0,0 +1,15 @@
+/* $FreeBSD$ */
+
+#ifndef __V4K_H__
+#define __V4K_H__
+
+extern void eeprom_v4k_base_print(uint16_t *buf);
+extern void eeprom_v4k_custdata_print(uint16_t *buf);
+extern void eeprom_v4k_modal_print(uint16_t *buf);
+extern void eeprom_v4k_calfreqpiers_print(uint16_t *buf);
+extern void eeprom_v4k_ctl_print(uint16_t *buf);
+extern void eeprom_v4k_print_targets(uint16_t *buf);
+extern void eeprom_v4k_print_edges(uint16_t *buf);
+extern void eeprom_v4k_print_other(uint16_t *buf);
+
+#endif
diff --git a/tools/tools/ath/ath_prom_read/Makefile b/tools/tools/ath/ath_prom_read/Makefile
new file mode 100644
index 000000000000..8183200f6f36
--- /dev/null
+++ b/tools/tools/ath/ath_prom_read/Makefile
@@ -0,0 +1,22 @@
+# $FreeBSD$
+
+PROG= ath_prom_read
+
+.include <bsd.prog.mk>
+
+.include <../Makefile.inc>
+
+CLEANFILES+= opt_ah.h ah_osdep.h
+
+CFLAGS+=-DATH_SUPPORT_ANI
+CFLAGS+=-DATH_SUPPORT_TDMA
+
+CFLAGS+=-I${.CURDIR}
+CFLAGS+=-I${SRCDIR}/sys/net80211
+
+opt_ah.h:
+ touch opt_ah.h
+ah_osdep.h:
+ echo 'typedef void *HAL_SOFTC;' >ah_osdep.h
+ echo 'typedef int HAL_BUS_TAG;' >>ah_osdep.h
+ echo 'typedef void *HAL_BUS_HANDLE;' >>ah_osdep.h
diff --git a/tools/tools/ath/ath_prom_read/ath_prom_read.c b/tools/tools/ath/ath_prom_read/ath_prom_read.c
new file mode 100644
index 000000000000..f123aaa186b3
--- /dev/null
+++ b/tools/tools/ath/ath_prom_read/ath_prom_read.c
@@ -0,0 +1,134 @@
+/*-
+ * Copyright (c) 2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_diagcodes.h"
+
+#include <getopt.h>
+#include <errno.h>
+#include <err.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+struct ath_diag atd;
+int s;
+const char *progname;
+
+/* XXX this should likely be defined somewhere in the HAL */
+/* XXX This is a lot larger than the v14 ROM */
+#define MAX_EEPROM_SIZE 16384
+
+uint16_t eep[MAX_EEPROM_SIZE];
+
+static void
+usage()
+{
+ fprintf(stderr, " %s [-i ifname] -d <dumpfile>\n", progname);
+ exit(-1);
+}
+
+#define NUM_PER_LINE 8
+
+static void
+do_eeprom_dump(const char *dumpfile, uint16_t *eebuf, int eelen)
+{
+ FILE *fp;
+ int i;
+
+ fp = fopen(dumpfile, "w");
+ if (!fp) {
+ err(1, "fopen");
+ }
+
+ /* eelen is in bytes; eebuf is in 2 byte words */
+ for (i = 0; i < eelen / 2; i++) {
+ if (i % NUM_PER_LINE == 0)
+ fprintf(fp, "%.4x: ", i);
+ fprintf(fp, "%.4x%s", (int32_t)(eebuf[i]), i % NUM_PER_LINE == (NUM_PER_LINE - 1) ? "\n" : " ");
+ }
+ fprintf(fp, "\n");
+ fclose(fp);
+}
+
+int
+main(int argc, char *argv[])
+{
+ FILE *fd = NULL;
+ const char *ifname;
+ int c;
+ const char *dumpname = NULL;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ err(1, "socket");
+ ifname = getenv("ATH");
+ if (!ifname)
+ ifname = ATH_DEFAULT;
+
+ progname = argv[0];
+ while ((c = getopt(argc, argv, "d:i:t:")) != -1)
+ switch (c) {
+ case 'd':
+ dumpname = optarg;
+ break;
+ case 'i':
+ ifname = optarg;
+ break;
+ case 't':
+ fd = fopen(optarg, "r");
+ if (fd == NULL)
+ err(-1, "Cannot open %s", optarg);
+ break;
+ default:
+ usage();
+ /*NOTREACHED*/
+ }
+ argc -= optind;
+ argv += optind;
+
+ strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
+
+ /* Read in the entire EEPROM */
+ atd.ad_id = HAL_DIAG_EEPROM;
+ atd.ad_out_data = (caddr_t) eep;
+ atd.ad_out_size = sizeof(eep);
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+
+ /* Dump file? Then just write to it */
+ if (dumpname != NULL) {
+ do_eeprom_dump(dumpname, (uint16_t *) &eep, sizeof(eep));
+ }
+ return 0;
+}
+
diff --git a/tools/tools/ath/athctrl.sh b/tools/tools/ath/athctrl.sh
new file mode 100644
index 000000000000..5adee1c3c4a4
--- /dev/null
+++ b/tools/tools/ath/athctrl.sh
@@ -0,0 +1,42 @@
+#! /bin/sh
+#
+# Set the IFS parameters for an interface configured for
+# point-to-point use at a specific distance. Based on a
+# program by Gunter Burchardt.
+#
+# $FreeBSD$
+#
+DEV=ath0
+d=0
+
+usage()
+{
+ echo "Usage: $0 [-i athX] [-d meters]"
+ exit 2
+}
+
+args=`getopt d:i: $*`
+test $? -ne 0 && usage
+
+set -- $args
+for i; do
+ case "$i" in
+ -i) DEV="$2"; shift; shift;;
+ -d) d="$2"; shift; shift;;
+ --) shift; break;
+ esac
+done
+
+test $d -eq 0 && usage
+
+slottime=`expr 9 + \( $d / 300 \)`
+if expr \( $d % 300 \) != 0 >/dev/null 2>&1; then
+ slottime=`expr $slottime + 1`
+fi
+timeout=`expr $slottime \* 2 + 3`
+
+printf "Setup IFS parameters on interface ${DEV} for %i meter p-2-p link\n" $d
+ATHN=`echo $DEV | sed 's/ath//'`
+sysctl dev.ath.$ATHN.slottime=$slottime
+sysctl dev.ath.$ATHN.acktimeout=$timeout
+sysctl dev.ath.$ATHN.ctstimeout=$timeout
diff --git a/tools/tools/ath/athdebug/Makefile b/tools/tools/ath/athdebug/Makefile
new file mode 100644
index 000000000000..0b75f26662b0
--- /dev/null
+++ b/tools/tools/ath/athdebug/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+PROG= athdebug
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athdebug/athdebug.c b/tools/tools/ath/athdebug/athdebug.c
new file mode 100644
index 000000000000..d1c2c1482614
--- /dev/null
+++ b/tools/tools/ath/athdebug/athdebug.c
@@ -0,0 +1,230 @@
+/*-
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * athdebug [-i interface] flags
+ * (default interface is ath0).
+ */
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <err.h>
+
+#define N(a) (sizeof(a)/sizeof(a[0]))
+
+const char *progname;
+
+enum {
+ ATH_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
+ ATH_DEBUG_XMIT_DESC = 0x00000002, /* xmit descriptors */
+ ATH_DEBUG_RECV = 0x00000004, /* basic recv operation */
+ ATH_DEBUG_RECV_DESC = 0x00000008, /* recv descriptors */
+ ATH_DEBUG_RATE = 0x00000010, /* rate control */
+ ATH_DEBUG_RESET = 0x00000020, /* reset processing */
+ ATH_DEBUG_MODE = 0x00000040, /* mode init/setup */
+ ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */
+ ATH_DEBUG_WATCHDOG = 0x00000100, /* watchdog timeout */
+ ATH_DEBUG_INTR = 0x00001000, /* ISR */
+ ATH_DEBUG_TX_PROC = 0x00002000, /* tx ISR proc */
+ ATH_DEBUG_RX_PROC = 0x00004000, /* rx ISR proc */
+ ATH_DEBUG_BEACON_PROC = 0x00008000, /* beacon ISR proc */
+ ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */
+ ATH_DEBUG_KEYCACHE = 0x00020000, /* key cache management */
+ ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */
+ ATH_DEBUG_NODE = 0x00080000, /* node management */
+ ATH_DEBUG_LED = 0x00100000, /* led management */
+ ATH_DEBUG_FF = 0x00200000, /* fast frames */
+ ATH_DEBUG_DFS = 0x00400000, /* DFS processing */
+ ATH_DEBUG_TDMA = 0x00800000, /* TDMA processing */
+ ATH_DEBUG_TDMA_TIMER = 0x01000000, /* TDMA timer processing */
+ ATH_DEBUG_REGDOMAIN = 0x02000000, /* regulatory processing */
+ ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
+ ATH_DEBUG_ANY = 0xffffffff
+};
+
+static struct {
+ const char *name;
+ u_int bit;
+} flags[] = {
+ { "xmit", ATH_DEBUG_XMIT },
+ { "xmit_desc", ATH_DEBUG_XMIT_DESC },
+ { "recv", ATH_DEBUG_RECV },
+ { "recv_desc", ATH_DEBUG_RECV_DESC },
+ { "rate", ATH_DEBUG_RATE },
+ { "reset", ATH_DEBUG_RESET },
+ { "mode", ATH_DEBUG_MODE },
+ { "beacon", ATH_DEBUG_BEACON },
+ { "watchdog", ATH_DEBUG_WATCHDOG },
+ { "intr", ATH_DEBUG_INTR },
+ { "xmit_proc", ATH_DEBUG_TX_PROC },
+ { "recv_proc", ATH_DEBUG_RX_PROC },
+ { "beacon_proc",ATH_DEBUG_BEACON_PROC },
+ { "calibrate", ATH_DEBUG_CALIBRATE },
+ { "keycache", ATH_DEBUG_KEYCACHE },
+ { "state", ATH_DEBUG_STATE },
+ { "node", ATH_DEBUG_NODE },
+ { "led", ATH_DEBUG_LED },
+ { "ff", ATH_DEBUG_FF },
+ { "dfs", ATH_DEBUG_DFS },
+ { "tdma", ATH_DEBUG_TDMA },
+ { "tdma_timer", ATH_DEBUG_TDMA_TIMER },
+ { "regdomain", ATH_DEBUG_REGDOMAIN },
+ { "fatal", ATH_DEBUG_FATAL },
+};
+
+static u_int
+getflag(const char *name, int len)
+{
+ int i;
+
+ for (i = 0; i < N(flags); i++)
+ if (strncasecmp(flags[i].name, name, len) == 0)
+ return flags[i].bit;
+ return 0;
+}
+
+static const char *
+getflagname(u_int flag)
+{
+ int i;
+
+ for (i = 0; i < N(flags); i++)
+ if (flags[i].bit == flag)
+ return flags[i].name;
+ return "???";
+}
+
+static void
+usage(void)
+{
+ int i;
+
+ fprintf(stderr, "usage: %s [-i device] [flags]\n", progname);
+ fprintf(stderr, "where flags are:\n");
+ for (i = 0; i < N(flags); i++)
+ printf("%s\n", flags[i].name);
+ exit(-1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *ifname;
+ const char *cp, *tp;
+ const char *sep;
+ int c, op, i;
+ u_int32_t debug, ndebug;
+ size_t debuglen;
+ char oid[256];
+
+ ifname = getenv("ATH");
+ if (ifname == NULL)
+ ifname = "ath0";
+ progname = argv[0];
+ if (argc > 1) {
+ if (strcmp(argv[1], "-i") == 0) {
+ if (argc < 2)
+ errx(1, "missing interface name for -i option");
+ ifname = argv[2];
+ if (strncmp(ifname, "ath", 3) != 0)
+ errx(2, "huh, this is for ath devices?");
+ argc -= 2, argv += 2;
+ } else if (strcmp(argv[1], "-?") == 0)
+ usage();
+ }
+
+#ifdef __linux__
+ snprintf(oid, sizeof(oid), "dev.%s.debug", ifname);
+#else
+ snprintf(oid, sizeof(oid), "dev.ath.%s.debug", ifname+3);
+#endif
+ debuglen = sizeof(debug);
+ if (sysctlbyname(oid, &debug, &debuglen, NULL, 0) < 0)
+ err(1, "sysctl-get(%s)", oid);
+ ndebug = debug;
+ for (; argc > 1; argc--, argv++) {
+ cp = argv[1];
+ do {
+ u_int bit;
+
+ if (*cp == '-') {
+ cp++;
+ op = -1;
+ } else if (*cp == '+') {
+ cp++;
+ op = 1;
+ } else
+ op = 0;
+ for (tp = cp; *tp != '\0' && *tp != '+' && *tp != '-';)
+ tp++;
+ bit = getflag(cp, tp-cp);
+ if (op < 0)
+ ndebug &= ~bit;
+ else if (op > 0)
+ ndebug |= bit;
+ else {
+ if (bit == 0) {
+ if (isdigit(*cp))
+ bit = strtoul(cp, NULL, 0);
+ else
+ errx(1, "unknown flag %.*s",
+ tp-cp, cp);
+ }
+ ndebug = bit;
+ }
+ } while (*(cp = tp) != '\0');
+ }
+ if (debug != ndebug) {
+ printf("%s: 0x%x => ", oid, debug);
+ if (sysctlbyname(oid, NULL, NULL, &ndebug, sizeof(ndebug)) < 0)
+ err(1, "sysctl-set(%s)", oid);
+ printf("0x%x", ndebug);
+ debug = ndebug;
+ } else
+ printf("%s: 0x%x", oid, debug);
+ sep = "<";
+ for (i = 0; i < N(flags); i++)
+ if (debug & flags[i].bit) {
+ printf("%s%s", sep, flags[i].name);
+ sep = ",";
+ }
+ printf("%s\n", *sep != '<' ? ">" : "");
+ return 0;
+}
diff --git a/tools/tools/ath/athdecode/Makefile b/tools/tools/ath/athdecode/Makefile
new file mode 100644
index 000000000000..00c452497a5c
--- /dev/null
+++ b/tools/tools/ath/athdecode/Makefile
@@ -0,0 +1,24 @@
+#
+# $FreeBSD$
+
+PROG= athdecode
+
+.PATH.c: ${.CURDIR}/../common
+
+SRCS= main.c
+SRCS+= dumpregs_5210.c
+SRCS+= dumpregs_5211.c
+SRCS+= dumpregs_5212.c
+SRCS+= dumpregs_5416.c
+SRCS+= opt_ah.h
+
+CLEANFILES+= opt_ah.h
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+ echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athdecode/main.c b/tools/tools/ath/athdecode/main.c
new file mode 100644
index 000000000000..1ab5c6d317c0
--- /dev/null
+++ b/tools/tools/ath/athdecode/main.c
@@ -0,0 +1,425 @@
+/*-
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ah_decode.h"
+
+#include "dumpregs.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+typedef struct {
+ HAL_REVS revs;
+ int chipnum;
+#define MAXREGS 5*1024
+ struct dumpreg *regs[MAXREGS];
+ u_int nregs;
+} dumpregs_t;
+static dumpregs_t state;
+
+static void opdevice(const struct athregrec *r);
+static const char* opmark(FILE *, int, const struct athregrec *);
+static void oprw(FILE *fd, int recnum, struct athregrec *r);
+
+int
+main(int argc, char *argv[])
+{
+ int fd, i, nrecs, same;
+ struct stat sb;
+ void *addr;
+ const char *filename = "/tmp/ath_hal.log";
+ struct athregrec *rprev;
+
+ if (argc > 1)
+ filename = argv[1];
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ err(1, filename);
+ if (fstat(fd, &sb) < 0)
+ err(1, "fstat");
+ addr = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE|MAP_NOCORE, fd, 0);
+ if (addr == MAP_FAILED)
+ err(1, "mmap");
+ nrecs = sb.st_size / sizeof (struct athregrec);
+ printf("%u records", nrecs);
+ rprev = NULL;
+ same = 0;
+ state.chipnum = 5210;
+ for (i = 0; i < nrecs; i++) {
+ struct athregrec *r = &((struct athregrec *) addr)[i];
+ if (rprev && bcmp(r, rprev, sizeof (*r)) == 0) {
+ same++;
+ continue;
+ }
+ if (same)
+ printf("\t\t+%u time%s", same, same == 1 ? "" : "s");
+ switch (r->op) {
+ case OP_DEVICE:
+ opdevice(r);
+ break;
+ case OP_READ:
+ case OP_WRITE:
+ oprw(stdout, i, r);
+ break;
+ case OP_MARK:
+ opmark(stdout, i, r);
+ break;
+ }
+ rprev = r;
+ same = 0;
+ }
+ putchar('\n');
+ return 0;
+}
+
+static const char*
+opmark(FILE *fd, int i, const struct athregrec *r)
+{
+ fprintf(fd, "\n%05d: ", i);
+ switch (r->reg) {
+ case AH_MARK_RESET:
+ fprintf(fd, "ar%uReset %s", state.chipnum,
+ r->val ? "change channel" : "no channel change");
+ break;
+ case AH_MARK_RESET_LINE:
+ fprintf(fd, "ar%u_reset.c; line %u", state.chipnum, r->val);
+ break;
+ case AH_MARK_RESET_DONE:
+ if (r->val)
+ fprintf(fd, "ar%uReset (done), FAIL, error %u",
+ state.chipnum, r->val);
+ else
+ fprintf(fd, "ar%uReset (done), OK", state.chipnum);
+ break;
+ case AH_MARK_CHIPRESET:
+ fprintf(fd, "ar%uChipReset, channel %u MHz", state.chipnum, r->val);
+ break;
+ case AH_MARK_PERCAL:
+ fprintf(fd, "ar%uPerCalibration, channel %u MHz", state.chipnum, r->val);
+ break;
+ case AH_MARK_SETCHANNEL:
+ fprintf(fd, "ar%uSetChannel, channel %u MHz", state.chipnum, r->val);
+ break;
+ case AH_MARK_ANI_RESET:
+ switch (r->val) {
+ case HAL_M_STA:
+ fprintf(fd, "ar%uAniReset, HAL_M_STA", state.chipnum);
+ break;
+ case HAL_M_IBSS:
+ fprintf(fd, "ar%uAniReset, HAL_M_IBSS", state.chipnum);
+ break;
+ case HAL_M_HOSTAP:
+ fprintf(fd, "ar%uAniReset, HAL_M_HOSTAP", state.chipnum);
+ break;
+ case HAL_M_MONITOR:
+ fprintf(fd, "ar%uAniReset, HAL_M_MONITOR", state.chipnum);
+ break;
+ default:
+ fprintf(fd, "ar%uAniReset, opmode %u", state.chipnum, r->val);
+ break;
+ }
+ break;
+ case AH_MARK_ANI_POLL:
+ fprintf(fd, "ar%uAniPoll, listenTime %u", state.chipnum, r->val);
+ break;
+ case AH_MARK_ANI_CONTROL:
+ switch (r->val) {
+ case HAL_ANI_PRESENT:
+ fprintf(fd, "ar%uAniControl, PRESENT", state.chipnum);
+ break;
+ case HAL_ANI_NOISE_IMMUNITY_LEVEL:
+ fprintf(fd, "ar%uAniControl, NOISE_IMMUNITY", state.chipnum);
+ break;
+ case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION:
+ fprintf(fd, "ar%uAniControl, OFDM_WEAK_SIGNAL", state.chipnum);
+ break;
+ case HAL_ANI_CCK_WEAK_SIGNAL_THR:
+ fprintf(fd, "ar%uAniControl, CCK_WEAK_SIGNAL", state.chipnum);
+ break;
+ case HAL_ANI_FIRSTEP_LEVEL:
+ fprintf(fd, "ar%uAniControl, FIRSTEP_LEVEL", state.chipnum);
+ break;
+ case HAL_ANI_SPUR_IMMUNITY_LEVEL:
+ fprintf(fd, "ar%uAniControl, SPUR_IMMUNITY", state.chipnum);
+ break;
+ case HAL_ANI_MODE:
+ fprintf(fd, "ar%uAniControl, MODE", state.chipnum);
+ break;
+ case HAL_ANI_PHYERR_RESET:
+ fprintf(fd, "ar%uAniControl, PHYERR_RESET", state.chipnum);
+ break;
+ default:
+ fprintf(fd, "ar%uAniControl, cmd %u", state.chipnum, r->val);
+ break;
+ }
+ break;
+ default:
+ fprintf(fd, "mark #%u value %u/0x%x", r->reg, r->val, r->val);
+ break;
+ }
+}
+
+#include "ah_devid.h"
+
+static void
+opdevice(const struct athregrec *r)
+{
+ switch (r->val) {
+ case AR5210_PROD:
+ case AR5210_DEFAULT:
+ state.chipnum = 5210;
+ state.revs.ah_macVersion = 1;
+ state.revs.ah_macRev = 0;
+ break;
+ case AR5211_DEVID:
+ case AR5311_DEVID:
+ case AR5211_DEFAULT:
+ case AR5211_FPGA11B:
+ state.chipnum = 5211;
+ state.revs.ah_macVersion = 2;
+ state.revs.ah_macRev = 0;
+ break;
+ /* AR5212 */
+ case AR5212_DEFAULT:
+ case AR5212_DEVID:
+ case AR5212_FPGA:
+ case AR5212_DEVID_IBM:
+ case AR5212_AR5312_REV2:
+ case AR5212_AR5312_REV7:
+ case AR5212_AR2313_REV8:
+ case AR5212_AR2315_REV6:
+ case AR5212_AR2315_REV7:
+ case AR5212_AR2317_REV1:
+ case AR5212_AR2317_REV2:
+
+ /* AR5212 compatible devid's also attach to 5212 */
+ case AR5212_DEVID_0014:
+ case AR5212_DEVID_0015:
+ case AR5212_DEVID_0016:
+ case AR5212_DEVID_0017:
+ case AR5212_DEVID_0018:
+ case AR5212_DEVID_0019:
+ case AR5212_AR2413:
+ case AR5212_AR5413:
+ case AR5212_AR5424:
+ case AR5212_AR2417:
+ case AR5212_DEVID_FF19:
+ state.chipnum = 5212;
+ state.revs.ah_macVersion = 4;
+ state.revs.ah_macRev = 5;
+ break;
+
+ /* AR5213 */
+ case AR5213_SREV_1_0:
+ case AR5213_SREV_REG:
+ state.chipnum = 5213;
+ state.revs.ah_macVersion = 5;
+ state.revs.ah_macRev = 9;
+ break;
+
+ /* AR5416 compatible devid's */
+ case AR5416_DEVID_PCI:
+ case AR5416_DEVID_PCIE:
+ case AR9160_DEVID_PCI:
+ case AR9280_DEVID_PCI:
+ case AR9280_DEVID_PCIE:
+ case AR9285_DEVID_PCIE:
+ state.chipnum = 5416;
+ state.revs.ah_macVersion = 13;
+ state.revs.ah_macRev = 8;
+ break;
+ default:
+ printf("Unknown device id 0x%x\n", r->val);
+ exit(-1);
+ }
+}
+
+static int
+regcompar(const void *a, const void *b)
+{
+ const struct dumpreg *ra = *(const struct dumpreg **)a;
+ const struct dumpreg *rb = *(const struct dumpreg **)b;
+ return ra->addr - rb->addr;
+}
+
+void
+register_regs(struct dumpreg *chipregs, u_int nchipregs,
+ int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
+{
+ const int existing_regs = state.nregs;
+ int i, j;
+
+ for (i = 0; i < nchipregs; i++) {
+ struct dumpreg *nr = &chipregs[i];
+ if (nr->srevMin == 0)
+ nr->srevMin = def_srev_min;
+ if (nr->srevMax == 0)
+ nr->srevMax = def_srev_max;
+ if (nr->phyMin == 0)
+ nr->phyMin = def_phy_min;
+ if (nr->phyMax == 0)
+ nr->phyMax = def_phy_max;
+ for (j = 0; j < existing_regs; j++) {
+ struct dumpreg *r = state.regs[j];
+ /*
+ * Check if we can just expand the mac+phy
+ * coverage for the existing entry.
+ */
+ if (nr->addr == r->addr &&
+ (nr->name == r->name ||
+ nr->name != NULL && r->name != NULL &&
+ strcmp(nr->name, r->name) == 0)) {
+ if (nr->srevMin < r->srevMin &&
+ (r->srevMin <= nr->srevMax &&
+ nr->srevMax+1 <= r->srevMax)) {
+ r->srevMin = nr->srevMin;
+ goto skip;
+ }
+ if (nr->srevMax > r->srevMax &&
+ (r->srevMin <= nr->srevMin &&
+ nr->srevMin <= r->srevMax)) {
+ r->srevMax = nr->srevMax;
+ goto skip;
+ }
+ }
+ if (r->addr > nr->addr)
+ break;
+ }
+ /*
+ * New item, add to the end, it'll be sorted below.
+ */
+ if (state.nregs == MAXREGS)
+ errx(-1, "too many registers; bump MAXREGS");
+ state.regs[state.nregs++] = nr;
+ skip:
+ ;
+ }
+ qsort(state.regs, state.nregs, sizeof(struct dumpreg *), regcompar);
+}
+
+void
+register_keycache(u_int nslots,
+ int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
+{
+ /* discard, no use */
+}
+
+void
+register_range(u_int brange, u_int erange, int type,
+ int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
+{
+ /* discard, no use */
+}
+
+static const struct dumpreg *
+findreg(int reg)
+{
+ const HAL_REVS *revs = &state.revs;
+ int i;
+
+ for (i = 0; i < state.nregs; i++) {
+ const struct dumpreg *dr = state.regs[i];
+ if (dr->addr == reg &&
+ MAC_MATCH(dr, revs->ah_macVersion, revs->ah_macRev))
+ return dr;
+ }
+ return NULL;
+}
+
+/* XXX cheat, 5212 has a superset of the key table defs */
+#include "ar5212/ar5212reg.h"
+#include "ar5212/ar5212phy.h"
+
+#define PWR_TABLE_SIZE 64
+
+static void
+oprw(FILE *fd, int recnum, struct athregrec *r)
+{
+ const struct dumpreg *dr;
+ char buf[64];
+ const char* bits;
+ int i;
+
+ fprintf(fd, "\n%05d: [%d] ", recnum, r->threadid);
+ dr = findreg(r->reg);
+ if (dr != NULL && dr->name != NULL) {
+ snprintf(buf, sizeof (buf), "AR_%s (0x%x)", dr->name, r->reg);
+ bits = dr->bits;
+ } else if (AR_KEYTABLE(0) <= r->reg && r->reg < AR_KEYTABLE(128)) {
+ snprintf(buf, sizeof (buf), "AR_KEYTABLE%u(%u) (0x%x)",
+ ((r->reg - AR_KEYTABLE_0) >> 2) & 7,
+ (r->reg - AR_KEYTABLE_0) >> 5, r->reg);
+ bits = NULL;
+#if 0
+ } else if (AR_PHY_PCDAC_TX_POWER(0) <= r->reg && r->reg < AR_PHY_PCDAC_TX_POWER(PWR_TABLE_SIZE/2)) {
+ snprintf(buf, sizeof (buf), "AR_PHY_PCDAC_TX_POWER(%u) (0x%x)",
+ (r->reg - AR_PHY_PCDAC_TX_POWER_0) >> 2, r->reg);
+ bits = NULL;
+#endif
+ } else if (AR_RATE_DURATION(0) <= r->reg && r->reg < AR_RATE_DURATION(32)) {
+ snprintf(buf, sizeof (buf), "AR_RATE_DURATION(0x%x) (0x%x)",
+ (r->reg - AR_RATE_DURATION_0) >> 2, r->reg);
+ bits = NULL;
+ } else if (AR_PHY_BASE <= r->reg) {
+ snprintf(buf, sizeof (buf), "AR_PHY(%u) (0x%x)",
+ (r->reg - AR_PHY_BASE) >> 2, r->reg);
+ bits = NULL;
+ } else {
+ snprintf(buf, sizeof (buf), "0x%x", r->reg);
+ bits = NULL;
+ }
+ fprintf(fd, "%-30s %s 0x%x", buf, r->op ? "<=" : "=>", r->val);
+ if (bits) {
+ const char *p = bits;
+ int tmp, n;
+
+ for (tmp = 0, p++; *p;) {
+ n = *p++;
+ if (r->val & (1 << (n - 1))) {
+ putc(tmp ? ',' : '<', fd);
+ for (; (n = *p) > ' '; ++p)
+ putc(n, fd);
+ tmp = 1;
+ } else
+ for (; *p > ' '; ++p)
+ continue;
+ }
+ if (tmp)
+ putc('>', fd);
+ }
+}
diff --git a/tools/tools/ath/athkey/Makefile b/tools/tools/ath/athkey/Makefile
new file mode 100644
index 000000000000..7aee04837957
--- /dev/null
+++ b/tools/tools/ath/athkey/Makefile
@@ -0,0 +1,18 @@
+# $FreeBSD$
+
+PROG= athkey
+
+SRCS= athkey.c
+SRCS+= opt_ah.h
+
+CLEANFILES+= opt_ah.h
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+ echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h
+
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athkey/athkey.c b/tools/tools/ath/athkey/athkey.c
new file mode 100644
index 000000000000..d25410554d72
--- /dev/null
+++ b/tools/tools/ath/athkey/athkey.c
@@ -0,0 +1,203 @@
+/*-
+ * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <err.h>
+#include <ctype.h>
+#include <getopt.h>
+
+const char *progname;
+
+static int
+toint(int c)
+{
+ return isdigit(c) ? c - '0' : isupper(c) ? c - 'A' + 10 : c - 'a' + 10;
+}
+
+static int
+getdata(const char *arg, u_int8_t *data, size_t maxlen)
+{
+ const char *cp = arg;
+ int len;
+
+ if (cp[0] == '0' && (cp[1] == 'x' || cp[1] == 'X'))
+ cp += 2;
+ len = 0;
+ while (*cp) {
+ int b0, b1;
+ if (cp[0] == ':' || cp[0] == '-' || cp[0] == '.') {
+ cp++;
+ continue;
+ }
+ if (!isxdigit(cp[0])) {
+ fprintf(stderr, "%s: invalid data value %c (not hex)\n",
+ progname, cp[0]);
+ exit(-1);
+ }
+ b0 = toint(cp[0]);
+ if (cp[1] != '\0') {
+ if (!isxdigit(cp[1])) {
+ fprintf(stderr, "%s: invalid data value %c "
+ "(not hex)\n", progname, cp[1]);
+ exit(-1);
+ }
+ b1 = toint(cp[1]);
+ cp += 2;
+ } else { /* fake up 0<n> */
+ b1 = b0, b0 = 0;
+ cp += 1;
+ }
+ if (len > maxlen) {
+ fprintf(stderr,
+ "%s: too much data in %s, max %u bytes\n",
+ progname, arg, maxlen);
+ }
+ data[len++] = (b0<<4) | b1;
+ }
+ return len;
+}
+
+/* XXX this assumes 5212 key types are common to 5211 and 5210 */
+
+static int
+getcipher(const char *name)
+{
+#define streq(a,b) (strcasecmp(a,b) == 0)
+
+ if (streq(name, "wep"))
+ return HAL_CIPHER_WEP;
+ if (streq(name, "tkip"))
+ return HAL_CIPHER_TKIP;
+ if (streq(name, "aes-ocb") || streq(name, "ocb"))
+ return HAL_CIPHER_AES_OCB;
+ if (streq(name, "aes-ccm") || streq(name, "ccm") ||
+ streq(name, "aes"))
+ return HAL_CIPHER_AES_CCM;
+ if (streq(name, "ckip"))
+ return HAL_CIPHER_CKIP;
+ if (streq(name, "none") || streq(name, "clr"))
+ return HAL_CIPHER_CLR;
+
+ fprintf(stderr, "%s: unknown cipher %s\n", progname, name);
+ exit(-1);
+#undef streq
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [-i device] keyix cipher keyval [mac]\n",
+ progname);
+ exit(-1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *ifname;
+ struct ath_diag atd;
+ HAL_DIAG_KEYVAL setkey;
+ const char *cp;
+ int s, c;
+ u_int16_t keyix;
+ int op = HAL_DIAG_SETKEY;
+ int xor = 0;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ err(1, "socket");
+ ifname = getenv("ATH");
+ if (!ifname)
+ ifname = ATH_DEFAULT;
+
+ progname = argv[0];
+ while ((c = getopt(argc, argv, "di:x")) != -1)
+ switch (c) {
+ case 'd':
+ op = HAL_DIAG_RESETKEY;
+ break;
+ case 'i':
+ ifname = optarg;
+ break;
+ case 'x':
+ xor = 1;
+ break;
+ default:
+ usage();
+ /*NOTREACHED*/
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc < 1)
+ usage();
+
+ keyix = (u_int16_t) atoi(argv[0]);
+ if (keyix > 127)
+ errx(-1, "%s: invalid key index %s, must be [0..127]",
+ progname, argv[0]);
+ strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
+ atd.ad_id = op | ATH_DIAG_IN | ATH_DIAG_DYN;
+ atd.ad_out_data = NULL;
+ atd.ad_out_size = 0;
+ switch (op) {
+ case HAL_DIAG_RESETKEY:
+ atd.ad_in_data = (caddr_t) &keyix;
+ atd.ad_in_size = sizeof(u_int16_t);
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+ return 0;
+ case HAL_DIAG_SETKEY:
+ if (argc != 3 && argc != 4)
+ usage();
+ memset(&setkey, 0, sizeof(setkey));
+ setkey.dk_keyix = keyix;
+ setkey.dk_xor = xor;
+ setkey.dk_keyval.kv_type = getcipher(argv[1]);
+ setkey.dk_keyval.kv_len = getdata(argv[2],
+ setkey.dk_keyval.kv_val, sizeof(setkey.dk_keyval.kv_val));
+ /* XXX MIC */
+ if (argc == 4)
+ (void) getdata(argv[3], setkey.dk_mac,
+ IEEE80211_ADDR_LEN);
+ atd.ad_in_data = (caddr_t) &setkey;
+ atd.ad_in_size = sizeof(setkey);
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+ return 0;
+ }
+ return -1;
+}
diff --git a/tools/tools/ath/athpoke/Makefile b/tools/tools/ath/athpoke/Makefile
new file mode 100644
index 000000000000..a33c7396348b
--- /dev/null
+++ b/tools/tools/ath/athpoke/Makefile
@@ -0,0 +1,24 @@
+# $FreeBSD$
+
+PROG= athpoke
+LINKS= ${BINDIR}/${PROG} ${BINDIR}/athpeek
+
+.PATH.c: ${.CURDIR}/../common
+
+SRCS= athpoke.c
+SRCS+= dumpregs_5210.c
+SRCS+= dumpregs_5211.c
+SRCS+= dumpregs_5212.c
+SRCS+= dumpregs_5416.c
+SRCS+= opt_ah.h
+
+CLEANFILES+= opt_ah.h
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+ echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athpoke/athpoke.c b/tools/tools/ath/athpoke/athpoke.c
new file mode 100644
index 000000000000..1749b7b52b78
--- /dev/null
+++ b/tools/tools/ath/athpoke/athpoke.c
@@ -0,0 +1,247 @@
+/*-
+ * Copyright (c) 2009 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+
+#include "dumpregs.h"
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+
+typedef struct {
+ HAL_REVS revs;
+#define MAXREGS 5*1024
+ struct dumpreg *regs[MAXREGS];
+ u_int nregs;
+} dumpregs_t;
+static dumpregs_t state;
+
+static uint32_t regread(int s, struct ath_diag *atd, uint32_t r);
+static void regwrite(int s, struct ath_diag *atd, uint32_t r, uint32_t v);
+static const struct dumpreg *reglookup(const char *v);
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: athpoke [-i interface] [reg[=value]] ...\n");
+ exit(-1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct ath_diag atd;
+ const char *ifname;
+ char *eptr;
+ int c, s;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ err(1, "socket");
+ ifname = getenv("ATH");
+ if (!ifname)
+ ifname = ATH_DEFAULT;
+
+ while ((c = getopt(argc, argv, "i:")) != -1)
+ switch (c) {
+ case 'i':
+ ifname = optarg;
+ break;
+ default:
+ usage();
+ /*NOTREACHED*/
+ }
+ strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
+
+ atd.ad_id = HAL_DIAG_REVS;
+ atd.ad_out_data = (caddr_t) &state.revs;
+ atd.ad_out_size = sizeof(state.revs);
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+
+ argc -= optind;
+ argv += optind;
+
+ for (; argc > 0; argc--, argv++) {
+ char *cp;
+ const struct dumpreg *dr;
+ uint32_t reg;
+
+ cp = strchr(argv[0], '=');
+ if (cp != NULL)
+ *cp++ = '\0';
+ dr = reglookup(argv[0]);
+ if (dr == NULL) {
+ errno = 0;
+ reg = (uint32_t) strtoul(argv[0], &eptr, 0);
+ if (argv[0] == eptr || eptr[0] != '\0')
+ errx(1, "invalid register \"%s\"", argv[0]);
+ } else
+ reg = dr->addr;
+ if (cp != NULL)
+ regwrite(s, &atd, reg, (uint32_t) strtoul(cp, NULL, 0));
+ printf("%s = %08x\n", argv[0], regread(s, &atd, reg));
+ }
+ return 0;
+}
+
+static uint32_t
+regread(int s, struct ath_diag *atd, uint32_t r)
+{
+ HAL_REGRANGE ra;
+ uint32_t v[2];
+
+ ra.start = r;
+ ra.end = 0;
+
+ atd->ad_in_data = (caddr_t) &ra;
+ atd->ad_in_size = sizeof(ra);
+ atd->ad_out_data = (caddr_t) v;
+ atd->ad_out_size = sizeof(v);
+ atd->ad_id = HAL_DIAG_REGS | ATH_DIAG_IN | ATH_DIAG_DYN;
+ if (ioctl(s, SIOCGATHDIAG, atd) < 0)
+ err(1, atd->ad_name);
+ return v[1];
+}
+
+static void
+regwrite(int s, struct ath_diag *atd, uint32_t r, uint32_t v)
+{
+ HAL_REGWRITE rw;
+
+ rw.addr = r;
+ rw.value = v;
+ atd->ad_in_data = (caddr_t) &rw;
+ atd->ad_in_size = sizeof(rw);
+ atd->ad_id = HAL_DIAG_SETREGS | ATH_DIAG_IN;
+ if (ioctl(s, SIOCGATHDIAG, atd) < 0)
+ err(1, atd->ad_name);
+}
+
+static int
+regcompar(const void *a, const void *b)
+{
+ const struct dumpreg *ra = *(const struct dumpreg **)a;
+ const struct dumpreg *rb = *(const struct dumpreg **)b;
+ return ra->addr - rb->addr;
+}
+
+void
+register_regs(struct dumpreg *chipregs, u_int nchipregs,
+ int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
+{
+ const int existing_regs = state.nregs;
+ int i, j;
+
+ for (i = 0; i < nchipregs; i++) {
+ struct dumpreg *nr = &chipregs[i];
+ if (nr->srevMin == 0)
+ nr->srevMin = def_srev_min;
+ if (nr->srevMax == 0)
+ nr->srevMax = def_srev_max;
+ if (nr->phyMin == 0)
+ nr->phyMin = def_phy_min;
+ if (nr->phyMax == 0)
+ nr->phyMax = def_phy_max;
+ for (j = 0; j < existing_regs; j++) {
+ struct dumpreg *r = state.regs[j];
+ /*
+ * Check if we can just expand the mac+phy
+ * coverage for the existing entry.
+ */
+ if (nr->addr == r->addr &&
+ (nr->name == r->name ||
+ nr->name != NULL && r->name != NULL &&
+ strcmp(nr->name, r->name) == 0)) {
+ if (nr->srevMin < r->srevMin &&
+ (r->srevMin <= nr->srevMax &&
+ nr->srevMax+1 <= r->srevMax)) {
+ r->srevMin = nr->srevMin;
+ goto skip;
+ }
+ if (nr->srevMax > r->srevMax &&
+ (r->srevMin <= nr->srevMin &&
+ nr->srevMin <= r->srevMax)) {
+ r->srevMax = nr->srevMax;
+ goto skip;
+ }
+ }
+ if (r->addr > nr->addr)
+ break;
+ }
+ /*
+ * New item, add to the end, it'll be sorted below.
+ */
+ if (state.nregs == MAXREGS)
+ errx(-1, "too many registers; bump MAXREGS");
+ state.regs[state.nregs++] = nr;
+ skip:
+ ;
+ }
+ qsort(state.regs, state.nregs, sizeof(struct dumpreg *), regcompar);
+}
+
+void
+register_keycache(u_int nslots,
+ int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
+{
+ /* discard, no use */
+}
+
+void
+register_range(u_int brange, u_int erange, int type,
+ int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
+{
+ /* discard, no use */
+}
+
+static const struct dumpreg *
+reglookup(const char *v)
+{
+ const HAL_REVS *revs = &state.revs;
+ int i;
+
+ if (strncasecmp(v, "AR_", 3) == 0)
+ v += 3;
+ for (i = 0; i < state.nregs; i++) {
+ const struct dumpreg *dr = state.regs[i];
+ if (MAC_MATCH(dr, revs->ah_macVersion, revs->ah_macRev) &&
+ strcasecmp(v, dr->name) == 0)
+ return dr;
+ }
+ return NULL;
+}
diff --git a/tools/tools/ath/athpow/Makefile b/tools/tools/ath/athpow/Makefile
new file mode 100644
index 000000000000..f3b36731db16
--- /dev/null
+++ b/tools/tools/ath/athpow/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+PROG= athpow
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athpow/athpow.c b/tools/tools/ath/athpow/athpow.c
new file mode 100644
index 000000000000..2b2683d9e6da
--- /dev/null
+++ b/tools/tools/ath/athpow/athpow.c
@@ -0,0 +1,198 @@
+/*-
+ * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ah_eeprom.h"
+#include "ah_eeprom_v1.h"
+#include "ah_eeprom_v3.h"
+#include "ah_eeprom_v14.h"
+#include "ar5212/ar5212reg.h"
+#define IS_5112(ah) \
+ (((ah)->ah_analog5GhzRev&0xf0) >= AR_RAD5112_SREV_MAJOR \
+ && ((ah)->ah_analog5GhzRev&0xf0) < AR_RAD2316_SREV_MAJOR )
+#define IS_2316(ah) \
+ ((ah)->ah_macVersion == AR_SREV_2415)
+#define IS_2413(ah) \
+ ((ah)->ah_macVersion == AR_SREV_2413 || IS_2316(ah))
+#define IS_5424(ah) \
+ ((ah)->ah_macVersion == AR_SREV_5424 || \
+ ((ah)->ah_macVersion == AR_SREV_5413 && \
+ (ah)->ah_macRev <= AR_SREV_D2PLUS_MS))
+#define IS_5413(ah) \
+ ((ah)->ah_macVersion == AR_SREV_5413 || IS_5424(ah))
+
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+static void printPcdacTable(FILE *fd, u_int16_t pcdac[], u_int n);
+static void printPowerPerRate(FILE *fd, u_int16_t ratesArray[], u_int n);
+static void printRevs(FILE *fd, const HAL_REVS *revs);
+
+static void
+usage(const char *progname)
+{
+ fprintf(stderr, "usage: %s [-v] [-i dev]\n", progname);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int s, i, verbose = 0, c;
+ struct ath_diag atd;
+ const char *ifname;
+ HAL_REVS revs;
+ u_int16_t pcdacTable[MAX(PWR_TABLE_SIZE,PWR_TABLE_SIZE_2413)];
+ u_int16_t ratesArray[37];
+ u_int nrates, npcdac;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ err(1, "socket");
+ ifname = getenv("ATH");
+ if (!ifname)
+ ifname = ATH_DEFAULT;
+ while ((c = getopt(argc, argv, "i:v")) != -1)
+ switch (c) {
+ case 'i':
+ ifname = optarg;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ default:
+ usage(argv[0]);
+ }
+ strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
+
+ atd.ad_id = HAL_DIAG_REVS;
+ atd.ad_out_data = (caddr_t) &revs;
+ atd.ad_out_size = sizeof(revs);
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+
+ if (verbose)
+ printRevs(stdout, &revs);
+
+ atd.ad_id = HAL_DIAG_TXRATES;
+ atd.ad_out_data = (caddr_t) ratesArray;
+ atd.ad_out_size = sizeof(ratesArray);
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+ nrates = sizeof(ratesArray) / sizeof(u_int16_t);
+
+ atd.ad_id = HAL_DIAG_PCDAC;
+ atd.ad_out_data = (caddr_t) pcdacTable;
+ atd.ad_out_size = sizeof(pcdacTable);
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+ if (IS_2413(&revs) || IS_5413(&revs))
+ npcdac = PWR_TABLE_SIZE_2413;
+ else
+ npcdac = PWR_TABLE_SIZE;
+
+ printf("PCDAC table:\n");
+ printPcdacTable(stdout, pcdacTable, npcdac);
+
+ printf("Power per rate table:\n");
+ printPowerPerRate(stdout, ratesArray, nrates);
+
+ return 0;
+}
+
+static void
+printPcdacTable(FILE *fd, u_int16_t pcdac[], u_int n)
+{
+ int i, halfRates = n/2;
+
+ for (i = 0; i < halfRates; i += 2)
+ fprintf(fd, "[%2u] %04x %04x [%2u] %04x %04x\n",
+ i, pcdac[2*i + 1], pcdac[2*i],
+ i+1, pcdac[2*(i+1) + 1], pcdac[2*(i+1)]);
+}
+
+static void
+printPowerPerRate(FILE *fd, u_int16_t ratesArray[], u_int n)
+{
+ const char *rateString[] = {
+ " 6mb OFDM", " 9mb OFDM", "12mb OFDM", "18mb OFDM",
+ "24mb OFDM", "36mb OFDM", "48mb OFDM", "54mb OFDM",
+ "1L CCK ", "2L CCK ", "2S CCK ", "5.5L CCK ",
+ "5.5S CCK ", "11L CCK ", "11S CCK ", "XR "
+ };
+ int i, halfRates = n/2;
+
+ for (i = 0; i < halfRates; i++)
+ fprintf(fd, " %s %3d.%1d dBm | %s %3d.%1d dBm\n",
+ rateString[i], ratesArray[i]/2,
+ (ratesArray[i] %2) * 5,
+ rateString[i + halfRates],
+ ratesArray[i + halfRates]/2,
+ (ratesArray[i + halfRates] %2) *5);
+}
+
+static void
+printRevs(FILE *fd, const HAL_REVS *revs)
+{
+ const char *rfbackend;
+
+ fprintf(fd, "PCI device id 0x%x subvendor id 0x%x\n",
+ revs->ah_devid, revs->ah_subvendorid);
+ fprintf(fd, "mac %d.%d phy %d.%d"
+ , revs->ah_macVersion, revs->ah_macRev
+ , revs->ah_phyRev >> 4, revs->ah_phyRev & 0xf
+ );
+ rfbackend = IS_5413(revs) ? "5413" :
+ IS_2413(revs) ? "2413" :
+ IS_5112(revs) ? "5112" :
+ "5111";
+ if (revs->ah_analog5GhzRev && revs->ah_analog2GhzRev)
+ fprintf(fd, " 5ghz radio %d.%d 2ghz radio %d.%d (%s)\n"
+ , revs->ah_analog5GhzRev >> 4
+ , revs->ah_analog5GhzRev & 0xf
+ , revs->ah_analog2GhzRev >> 4
+ , revs->ah_analog2GhzRev & 0xf
+ , rfbackend
+ );
+ else
+ fprintf(fd, " radio %d.%d (%s)\n"
+ , revs->ah_analog5GhzRev >> 4
+ , revs->ah_analog5GhzRev & 0xf
+ , rfbackend
+ );
+}
diff --git a/tools/tools/ath/athprom/Makefile b/tools/tools/ath/athprom/Makefile
new file mode 100644
index 000000000000..f7b596728699
--- /dev/null
+++ b/tools/tools/ath/athprom/Makefile
@@ -0,0 +1,26 @@
+# $FreeBSD$
+
+PROG= athprom
+
+.include <../Makefile.inc>
+
+TEMPLATEDIR= /usr/local/libdata/athprom
+TEXTMODE?= 444
+
+SRCS= athprom.c
+SRCS+= opt_ah.h
+CLEANFILES+= opt_ah.h
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+ echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h
+
+CFLAGS+=-DDIR_TEMPLATE='"${TEMPLATEDIR}"'
+
+beforeinstall:
+ mkdir -p ${DESTDIR}${TEMPLATEDIR}
+ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${TEXTMODE} \
+ ${.CURDIR}/eeprom-* ${DESTDIR}${TEMPLATEDIR}/
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athprom/athprom.c b/tools/tools/ath/athprom/athprom.c
new file mode 100644
index 000000000000..6f2b32b1252c
--- /dev/null
+++ b/tools/tools/ath/athprom/athprom.c
@@ -0,0 +1,979 @@
+/*-
+ * Copyright (c) 2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ah_eeprom_v1.h"
+#include "ah_eeprom_v3.h"
+#include "ah_eeprom_v14.h"
+
+#define IS_VERS(op, v) (eeprom.ee_version op (v))
+
+#include <getopt.h>
+#include <errno.h>
+#include <err.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifndef DIR_TEMPLATE
+#define DIR_TEMPLATE "/usr/local/libdata/athprom"
+#endif
+
+struct ath_diag atd;
+int s;
+const char *progname;
+union {
+ HAL_EEPROM legacy; /* format v3.x ... v5.x */
+ struct ar5416eeprom v14; /* 11n format v14.x ... */
+} eep;
+#define eeprom eep.legacy
+#define eepromN eep.v14
+
+static void parseTemplate(FILE *ftemplate, FILE *fd);
+static uint16_t eeread(uint16_t);
+static void eewrite(uint16_t, uint16_t);
+
+static void
+usage()
+{
+ fprintf(stderr, "usage: %s [-i ifname] [-t pathname] [offset | offset=value]\n", progname);
+ exit(-1);
+}
+
+static FILE *
+opentemplate(const char *dir)
+{
+ char filename[PATH_MAX];
+ FILE *fd;
+
+ /* find the template using the eeprom version */
+ snprintf(filename, sizeof(filename), "%s/eeprom-%d.%d",
+ dir, eeprom.ee_version >> 12, eeprom.ee_version & 0xfff);
+ fd = fopen(filename, "r");
+ if (fd == NULL && errno == ENOENT) {
+ /* retry with just the major version */
+ snprintf(filename, sizeof(filename), "%s/eeprom-%d",
+ dir, eeprom.ee_version >> 12);
+ fd = fopen(filename, "r");
+ if (fd != NULL) /* XXX verbose */
+ warnx("Using template file %s", filename);
+ }
+ return fd;
+}
+
+int
+main(int argc, char *argv[])
+{
+ FILE *fd = NULL;
+ const char *ifname;
+ int c;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ err(1, "socket");
+ ifname = getenv("ATH");
+ if (!ifname)
+ ifname = ATH_DEFAULT;
+
+ progname = argv[0];
+ while ((c = getopt(argc, argv, "i:t:")) != -1)
+ switch (c) {
+ case 'i':
+ ifname = optarg;
+ break;
+ case 't':
+ fd = fopen(optarg, "r");
+ if (fd == NULL)
+ err(-1, "Cannot open %s", optarg);
+ break;
+ default:
+ usage();
+ /*NOTREACHED*/
+ }
+ argc -= optind;
+ argv += optind;
+
+ strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
+
+ if (argc != 0) {
+ for (; argc > 0; argc--, argv++) {
+ uint16_t off, val, oval;
+ char line[256];
+ char *cp;
+
+ cp = strchr(argv[0], '=');
+ if (cp != NULL)
+ *cp = '\0';
+ off = (uint16_t) strtoul(argv[0], NULL, 0);
+ if (off == 0 && errno == EINVAL)
+ errx(1, "%s: invalid eeprom offset %s",
+ progname, argv[0]);
+ if (cp == NULL) {
+ printf("%04x: %04x\n", off, eeread(off));
+ } else {
+ val = (uint16_t) strtoul(cp+1, NULL, 0);
+ if (val == 0 && errno == EINVAL)
+ errx(1, "%s: invalid eeprom value %s",
+ progname, cp+1);
+ oval = eeread(off);
+ printf("Write %04x: %04x = %04x? ",
+ off, oval, val);
+ fflush(stdout);
+ if (fgets(line, sizeof(line), stdin) != NULL &&
+ line[0] == 'y')
+ eewrite(off, val);
+ }
+ }
+ } else {
+ atd.ad_id = HAL_DIAG_EEPROM;
+ atd.ad_out_data = (caddr_t) &eep;
+ atd.ad_out_size = sizeof(eep);
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+ if (fd == NULL) {
+ fd = opentemplate(DIR_TEMPLATE);
+ if (fd == NULL)
+ fd = opentemplate(".");
+ if (fd == NULL)
+ errx(-1, "Cannot locate template file for "
+ "v%d.%d EEPROM", eeprom.ee_version >> 12,
+ eeprom.ee_version & 0xfff);
+ }
+ parseTemplate(fd, stdout);
+ fclose(fd);
+ }
+ return 0;
+}
+
+static u_int16_t
+eeread(u_int16_t off)
+{
+ u_int16_t eedata;
+
+ atd.ad_id = HAL_DIAG_EEREAD | ATH_DIAG_IN | ATH_DIAG_DYN;
+ atd.ad_in_size = sizeof(off);
+ atd.ad_in_data = (caddr_t) &off;
+ atd.ad_out_size = sizeof(eedata);
+ atd.ad_out_data = (caddr_t) &eedata;
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+ return eedata;
+}
+
+static void
+eewrite(uint16_t off, uint16_t value)
+{
+ HAL_DIAG_EEVAL eeval;
+
+ eeval.ee_off = off;
+ eeval.ee_data = value;
+
+ atd.ad_id = HAL_DIAG_EEWRITE | ATH_DIAG_IN;
+ atd.ad_in_size = sizeof(eeval);
+ atd.ad_in_data = (caddr_t) &eeval;
+ atd.ad_out_size = 0;
+ atd.ad_out_data = NULL;
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+}
+
+#define MAXID 128
+int lineno;
+int bol;
+int curmode = -1;
+int curchan;
+int curpdgain; /* raw pdgain index */
+int curlpdgain; /* logical pdgain index */
+int curpcdac;
+int curctl;
+int numChannels;
+const RAW_DATA_STRUCT_2413 *pRaw;
+const TRGT_POWER_INFO *pPowerInfo;
+const DATA_PER_CHANNEL *pDataPerChannel;
+const EEPROM_POWER_EXPN_5112 *pExpnPower;
+int singleXpd;
+
+static int
+token(FILE *fd, char id[], int maxid, const char *what)
+{
+ int c, i;
+
+ i = 0;
+ for (;;) {
+ c = getc(fd);
+ if (c == EOF)
+ return EOF;
+ if (!isalnum(c) && c != '_') {
+ ungetc(c, fd);
+ break;
+ }
+ if (i == maxid-1) {
+ warnx("line %d, %s too long", lineno, what);
+ break;
+ }
+ id[i++] = c;
+ }
+ id[i] = '\0';
+ if (i != 0)
+ bol = 0;
+ return i;
+}
+
+static int
+skipto(FILE *fd, const char *what)
+{
+ char id[MAXID];
+ int c;
+
+ for (;;) {
+ c = getc(fd);
+ if (c == EOF)
+ goto bad;
+ if (c == '.' && bol) { /* .directive */
+ if (token(fd, id, MAXID, ".directive") == EOF)
+ goto bad;
+ if (strcasecmp(id, what) == 0)
+ break;
+ continue;
+ }
+ if (c == '\\') { /* escape next character */
+ c = getc(fd);
+ if (c == EOF)
+ goto bad;
+ }
+ bol = (c == '\n');
+ if (bol)
+ lineno++;
+ }
+ return 0;
+bad:
+ warnx("EOF with no matching .%s", what);
+ return EOF;
+}
+
+static int
+skipws(FILE *fd)
+{
+ int c, i;
+
+ i = 0;
+ while ((c = getc(fd)) != EOF && isblank(c))
+ i++;
+ if (c != EOF)
+ ungetc(c, fd);
+ if (i != 0)
+ bol = 0;
+ return 0;
+}
+
+static void
+setmode(int mode)
+{
+ EEPROM_POWER_EXPN_5112 *exp;
+
+ curmode = mode;
+ curchan = -1;
+ curctl = -1;
+ curpdgain = -1;
+ curlpdgain = -1;
+ curpcdac = -1;
+ switch (curmode) {
+ case headerInfo11A:
+ pPowerInfo = eeprom.ee_trgtPwr_11a;
+ pDataPerChannel = eeprom.ee_dataPerChannel11a;
+ break;
+ case headerInfo11B:
+ pPowerInfo = eeprom.ee_trgtPwr_11b;
+ pDataPerChannel = eeprom.ee_dataPerChannel11b;
+ break;
+ case headerInfo11G:
+ pPowerInfo = eeprom.ee_trgtPwr_11g;
+ pDataPerChannel = eeprom.ee_dataPerChannel11g;
+ break;
+ }
+ if (IS_VERS(<, AR_EEPROM_VER4_0)) /* nothing to do */
+ return;
+ if (IS_VERS(<, AR_EEPROM_VER5_0)) {
+ exp = &eeprom.ee_modePowerArray5112[curmode];
+ /* fetch indirect data*/
+ atd.ad_id = HAL_DIAG_EEPROM_EXP_11A+curmode;
+ atd.ad_out_size = roundup(
+ sizeof(u_int16_t) * exp->numChannels, sizeof(u_int32_t))
+ + sizeof(EXPN_DATA_PER_CHANNEL_5112) * exp->numChannels;
+ atd.ad_out_data = (caddr_t) malloc(atd.ad_out_size);
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+ exp->pChannels = (void *) atd.ad_out_data;
+ exp->pDataPerChannel = (void *)((char *)atd.ad_out_data +
+ roundup(sizeof(u_int16_t) * exp->numChannels, sizeof(u_int32_t)));
+ pExpnPower = exp;
+ numChannels = pExpnPower->numChannels;
+ if (exp->xpdMask != 0x9) {
+ for (singleXpd = 0; singleXpd < NUM_XPD_PER_CHANNEL; singleXpd++)
+ if (exp->xpdMask == (1<<singleXpd))
+ break;
+ } else
+ singleXpd = 0;
+ } else if (IS_VERS(<, AR_EEPROM_VER14_2)) {
+ pRaw = &eeprom.ee_rawDataset2413[curmode];
+ numChannels = pRaw->numChannels;
+ }
+}
+
+int
+nextctl(int start)
+{
+ int i;
+
+ for (i = start; i < eeprom.ee_numCtls && eeprom.ee_ctl[i]; i++) {
+ switch (eeprom.ee_ctl[i] & 3) {
+ case 0: case 3:
+ if (curmode != headerInfo11A)
+ continue;
+ break;
+ case 1:
+ if (curmode != headerInfo11B)
+ continue;
+ break;
+ case 2:
+ if (curmode != headerInfo11G)
+ continue;
+ break;
+ }
+ return i;
+ }
+ return -1;
+}
+
+static void
+printAntennaControl(FILE *fd, int ant)
+{
+ fprintf(fd, "0x%02X", eeprom.ee_antennaControl[ant][curmode]);
+}
+
+static void
+printEdge(FILE *fd, int edge)
+{
+ const RD_EDGES_POWER *pRdEdgePwrInfo =
+ &eeprom.ee_rdEdgesPower[curctl*NUM_EDGES];
+
+ if (pRdEdgePwrInfo[edge].rdEdge == 0)
+ fprintf(fd, " -- ");
+ else
+ fprintf(fd, "%04d", pRdEdgePwrInfo[edge].rdEdge);
+}
+
+static void
+printEdgePower(FILE *fd, int edge)
+{
+ const RD_EDGES_POWER *pRdEdgePwrInfo =
+ &eeprom.ee_rdEdgesPower[curctl*NUM_EDGES];
+
+ if (pRdEdgePwrInfo[edge].rdEdge == 0)
+ fprintf(fd, " -- ");
+ else
+ fprintf(fd, "%2d.%d",
+ pRdEdgePwrInfo[edge].twice_rdEdgePower / 2,
+ (pRdEdgePwrInfo[edge].twice_rdEdgePower % 2) * 5);
+}
+
+static void
+printEdgeFlag(FILE *fd, int edge)
+{
+ const RD_EDGES_POWER *pRdEdgePwrInfo =
+ &eeprom.ee_rdEdgesPower[curctl*NUM_EDGES];
+
+ if (pRdEdgePwrInfo[edge].rdEdge == 0)
+ fprintf(fd, "--");
+ else
+ fprintf(fd, " %1d", pRdEdgePwrInfo[edge].flag);
+}
+
+static int16_t
+getMaxPowerV5(const RAW_DATA_PER_CHANNEL_2413 *data)
+{
+ uint32_t i;
+ uint16_t numVpd;
+
+ for (i = 0; i < MAX_NUM_PDGAINS_PER_CHANNEL; i++) {
+ numVpd = data->pDataPerPDGain[i].numVpd;
+ if (numVpd > 0)
+ return data->pDataPerPDGain[i].pwr_t4[numVpd-1];
+ }
+ return 0;
+}
+
+static void
+printQuarterDbmPower(FILE *fd, int16_t power25dBm)
+{
+ fprintf(fd, "%2d.%02d", power25dBm / 4, (power25dBm % 4) * 25);
+}
+
+static void
+printHalfDbmPower(FILE *fd, int16_t power5dBm)
+{
+ fprintf(fd, "%2d.%d", power5dBm / 2, (power5dBm % 2) * 5);
+}
+
+static void
+printVpd(FILE *fd, int vpd)
+{
+ fprintf(fd, "[%3d]", vpd);
+}
+
+static void
+printPcdacValue(FILE *fd, int v)
+{
+ fprintf(fd, "%2d.%02d", v / EEP_SCALE, v % EEP_SCALE);
+}
+
+static void
+undef(const char *what)
+{
+ warnx("%s undefined for version %d.%d format EEPROM", what,
+ eeprom.ee_version >> 12, eeprom.ee_version & 0xfff);
+}
+
+static int
+pdgain(int lpdgain)
+{
+ uint32_t mask;
+ int i, l = lpdgain;
+
+ if (IS_VERS(<, AR_EEPROM_VER5_0))
+ mask = pExpnPower->xpdMask;
+ else
+ mask = pRaw->xpd_mask;
+ for (i = 0; mask != 0; mask >>= 1, i++)
+ if ((mask & 1) && l-- == 0)
+ return i;
+ warnx("can't find logical pdgain %d", lpdgain);
+ return -1;
+}
+
+#define COUNTRY_ERD_FLAG 0x8000
+#define WORLDWIDE_ROAMING_FLAG 0x4000
+
+void
+eevar(FILE *fd, const char *var)
+{
+#define streq(a,b) (strcasecmp(a,b) == 0)
+#define strneq(a,b,n) (strncasecmp(a,b,n) == 0)
+ if (streq(var, "mode")) {
+ fprintf(fd, "%s",
+ curmode == headerInfo11A ? "11a" :
+ curmode == headerInfo11B ? "11b" :
+ curmode == headerInfo11G ? "11g" : "???");
+ } else if (streq(var, "version")) {
+ fprintf(fd, "%04x", eeprom.ee_version);
+ } else if (streq(var, "V_major")) {
+ fprintf(fd, "%2d", eeprom.ee_version >> 12);
+ } else if (streq(var, "V_minor")) {
+ fprintf(fd, "%2d", eeprom.ee_version & 0xfff);
+ } else if (streq(var, "earStart")) {
+ fprintf(fd, "%03x", eeprom.ee_earStart);
+ } else if (streq(var, "tpStart")) {
+ fprintf(fd, "%03x", eeprom.ee_targetPowersStart);
+ } else if (streq(var, "eepMap")) {
+ fprintf(fd, "%3d", eeprom.ee_eepMap);
+ } else if (streq(var, "exist32KHzCrystal")) {
+ fprintf(fd, "%3d", eeprom.ee_exist32kHzCrystal);
+ } else if (streq(var, "eepMap2PowerCalStart")) {
+ fprintf(fd , "%3d", eeprom.ee_eepMap2PowerCalStart);
+ } else if (streq(var, "Amode")) {
+ fprintf(fd , "%1d", eeprom.ee_Amode);
+ } else if (streq(var, "Bmode")) {
+ fprintf(fd , "%1d", eeprom.ee_Bmode);
+ } else if (streq(var, "Gmode")) {
+ fprintf(fd , "%1d", eeprom.ee_Gmode);
+ } else if (streq(var, "regdomain")) {
+ if ((eeprom.ee_regdomain & COUNTRY_ERD_FLAG) == 0)
+ fprintf(fd, "%03X ", eeprom.ee_regdomain >> 15);
+ else
+ fprintf(fd, "%-3dC", eeprom.ee_regdomain & 0xfff);
+ } else if (streq(var, "turbo2Disable")) {
+ fprintf(fd, "%1d", eeprom.ee_turbo2Disable);
+ } else if (streq(var, "turbo5Disable")) {
+ fprintf(fd, "%1d", eeprom.ee_turbo5Disable);
+ } else if (streq(var, "rfKill")) {
+ fprintf(fd, "%1d", eeprom.ee_rfKill);
+ } else if (streq(var, "disableXr5")) {
+ fprintf(fd, "%1d", eeprom.ee_disableXr5);
+ } else if (streq(var, "disableXr2")) {
+ fprintf(fd, "%1d", eeprom.ee_disableXr2);
+ } else if (streq(var, "turbo2WMaxPower5")) {
+ fprintf(fd, "%2d", eeprom.ee_turbo2WMaxPower5);
+ } else if (streq(var, "cckOfdmDelta")) {
+ fprintf(fd, "%2d", eeprom.ee_cckOfdmPwrDelta);
+ } else if (streq(var, "gainI")) {
+ fprintf(fd, "%2d", eeprom.ee_gainI[curmode]);
+ } else if (streq(var, "WWR")) {
+ fprintf(fd, "%1x",
+ (eeprom.ee_regdomain & WORLDWIDE_ROAMING_FLAG) != 0);
+ } else if (streq(var, "falseDetectBackoff")) {
+ fprintf(fd, "0x%02x", eeprom.ee_falseDetectBackoff[curmode]);
+ } else if (streq(var, "deviceType")) {
+ fprintf(fd, "%1x", eeprom.ee_deviceType);
+ } else if (streq(var, "switchSettling")) {
+ if (IS_VERS(<, AR_EEPROM_VER14_2))
+ fprintf(fd, "0x%02x", eeprom.ee_switchSettling[curmode]);
+ else
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].switchSettling);
+ } else if (streq(var, "adcDesiredSize")) {
+ if (IS_VERS(<, AR_EEPROM_VER14_2))
+ fprintf(fd, "%2d", eeprom.ee_adcDesiredSize[curmode]);
+ else
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].adcDesiredSize);
+ } else if (streq(var, "xlnaGain")) {
+ fprintf(fd, "0x%02x", eeprom.ee_xlnaGain[curmode]);
+ } else if (streq(var, "txEndToXLNAOn")) {
+ fprintf(fd, "0x%02x", eeprom.ee_txEndToXLNAOn[curmode]);
+ } else if (streq(var, "thresh62")) {
+ if (IS_VERS(<, AR_EEPROM_VER14_2))
+ fprintf(fd, "0x%02x", eeprom.ee_thresh62[curmode]);
+ else
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].thresh62);
+ } else if (streq(var, "txEndToRxOn")) {
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].txEndToRxOn);
+ } else if (streq(var, "txEndToXPAOff")) {
+ if (IS_VERS(<, AR_EEPROM_VER14_2))
+ fprintf(fd, "0x%02x", eeprom.ee_txEndToXPAOff[curmode]);
+ else
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].txEndToXpaOff);
+ } else if (streq(var, "txFrameToXPAOn")) {
+ if (IS_VERS(<, AR_EEPROM_VER14_2))
+ fprintf(fd, "0x%02x", eeprom.ee_txFrameToXPAOn[curmode]);
+ else
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].txEndToRxOn);
+ } else if (streq(var, "pgaDesiredSize")) {
+ if (IS_VERS(<, AR_EEPROM_VER14_2))
+ fprintf(fd, "%2d", eeprom.ee_pgaDesiredSize[curmode]);
+ else
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].pgaDesiredSize);
+ } else if (streq(var, "noiseFloorThresh")) {
+ fprintf(fd, "%3d", eeprom.ee_noiseFloorThresh[curmode]);
+ } else if (strneq(var, "noiseFloorThreshCh", 18)) {
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].noiseFloorThreshCh[atoi(var+18)]);
+ } else if (strneq(var, "xlnaGainCh", 10)) {
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].xlnaGainCh[atoi(var+10)]);
+ } else if (streq(var, "xgain")) {
+ fprintf(fd, "0x%02x", eeprom.ee_xgain[curmode]);
+ } else if (streq(var, "xpd")) {
+ if (IS_VERS(<, AR_EEPROM_VER14_2))
+ fprintf(fd, "%1d", eeprom.ee_xpd[curmode]);
+ else
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].xpd);
+ } else if (streq(var, "txrxAtten")) {
+ fprintf(fd, "0x%02x", eeprom.ee_txrxAtten[curmode]);
+ } else if (streq(var, "capField")) {
+ fprintf(fd, "0x%04X", eeprom.ee_capField);
+ } else if (streq(var, "txrxAttenTurbo")) {
+ fprintf(fd, "0x%02x",
+ eeprom.ee_txrxAtten[curmode != headerInfo11A]);
+ } else if (streq(var, "switchSettlingTurbo")) {
+ fprintf(fd, "0x%02X",
+ eeprom.ee_switchSettlingTurbo[curmode != headerInfo11A]);
+ } else if (streq(var, "adcDesiredSizeTurbo")) {
+ fprintf(fd, "%2d",
+ eeprom.ee_adcDesiredSizeTurbo[curmode != headerInfo11A]);
+ } else if (streq(var, "pgaDesiredSizeTurbo")) {
+ fprintf(fd, "%2d",
+ eeprom.ee_pgaDesiredSizeTurbo[curmode != headerInfo11A]);
+ } else if (streq(var, "rxtxMarginTurbo")) {
+ fprintf(fd, "0x%02x",
+ eeprom.ee_rxtxMarginTurbo[curmode != headerInfo11A]);
+ } else if (strneq(var, "antennaControl", 14)) {
+ printAntennaControl(fd, atoi(var+14));
+ } else if (strneq(var, "antCtrlChain", 12)) {
+ fprintf(fd, "0x%08X",
+ eepromN.modalHeader[curmode].antCtrlChain[atoi(var+12)]);
+ } else if (strneq(var, "antGainCh", 9)) {
+ fprintf(fd, "%3d",
+ eepromN.modalHeader[curmode].antennaGainCh[atoi(var+9)]);
+ } else if (strneq(var, "txRxAttenCh", 11)) {
+ fprintf(fd, "%3d",
+ eepromN.modalHeader[curmode].txRxAttenCh[atoi(var+11)]);
+ } else if (strneq(var, "rxTxMarginCh", 12)) {
+ fprintf(fd, "%3d",
+ eepromN.modalHeader[curmode].rxTxMarginCh[atoi(var+12)]);
+ } else if (streq(var, "xpdGain")) {
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].xpdGain);
+ } else if (strneq(var, "iqCalICh", 8)) {
+ fprintf(fd, "%3d",
+ eepromN.modalHeader[curmode].iqCalICh[atoi(var+8)]);
+ } else if (strneq(var, "iqCalQCh", 8)) {
+ fprintf(fd, "%3d",
+ eepromN.modalHeader[curmode].iqCalQCh[atoi(var+8)]);
+ } else if (streq(var, "pdGainOverlap")) {
+ printHalfDbmPower(fd, eepromN.modalHeader[curmode].pdGainOverlap);
+ } else if (streq(var, "ob1")) {
+ fprintf(fd, "%1d", eeprom.ee_ob1);
+ } else if (streq(var, "ob2")) {
+ fprintf(fd, "%1d", eeprom.ee_ob2);
+ } else if (streq(var, "ob3")) {
+ fprintf(fd, "%1d", eeprom.ee_ob3);
+ } else if (streq(var, "ob4")) {
+ fprintf(fd, "%1d", eeprom.ee_ob4);
+ } else if (streq(var, "db1")) {
+ fprintf(fd, "%1d", eeprom.ee_db1);
+ } else if (streq(var, "db2")) {
+ fprintf(fd, "%1d", eeprom.ee_db2);
+ } else if (streq(var, "db3")) {
+ fprintf(fd, "%1d", eeprom.ee_db3);
+ } else if (streq(var, "db4")) {
+ fprintf(fd, "%1d", eeprom.ee_db4);
+ } else if (streq(var, "obFor24")) {
+ fprintf(fd, "%1d", eeprom.ee_obFor24);
+ } else if (streq(var, "ob2GHz0")) {
+ fprintf(fd, "%1d", eeprom.ee_ob2GHz[0]);
+ } else if (streq(var, "dbFor24")) {
+ fprintf(fd, "%1d", eeprom.ee_dbFor24);
+ } else if (streq(var, "db2GHz0")) {
+ fprintf(fd, "%1d", eeprom.ee_db2GHz[0]);
+ } else if (streq(var, "obFor24g")) {
+ fprintf(fd, "%1d", eeprom.ee_obFor24g);
+ } else if (streq(var, "ob2GHz1")) {
+ fprintf(fd, "%1d", eeprom.ee_ob2GHz[1]);
+ } else if (streq(var, "dbFor24g")) {
+ fprintf(fd, "%1d", eeprom.ee_dbFor24g);
+ } else if (streq(var, "db2GHz1")) {
+ fprintf(fd, "%1d", eeprom.ee_db2GHz[1]);
+ } else if (streq(var, "ob")) {
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].ob);
+ } else if (streq(var, "db")) {
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].db);
+ } else if (streq(var, "xpaBiasLvl")) {
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].xpaBiasLvl);
+ } else if (streq(var, "pwrDecreaseFor2Chain")) {
+ printHalfDbmPower(fd, eepromN.modalHeader[curmode].pwrDecreaseFor2Chain);
+ } else if (streq(var, "pwrDecreaseFor3Chain")) {
+ printHalfDbmPower(fd, eepromN.modalHeader[curmode].pwrDecreaseFor3Chain);
+ } else if (streq(var, "txFrameToDataStart")) {
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].txFrameToDataStart);
+ } else if (streq(var, "txFrameToPaOn")) {
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].txFrameToPaOn);
+ } else if (streq(var, "ht40PowerIncForPdadc")) {
+ fprintf(fd, "%3d", eepromN.modalHeader[curmode].ht40PowerIncForPdadc);
+ } else if (streq(var, "checksum")) {
+ fprintf(fd, "0x%04X", eepromN.baseEepHeader.checksum);
+ } else if (streq(var, "length")) {
+ fprintf(fd, "0x%04X", eepromN.baseEepHeader.length);
+ } else if (streq(var, "regDmn0")) {
+ fprintf(fd, "0x%04X", eepromN.baseEepHeader.regDmn[0]);
+ } else if (streq(var, "regDmn1")) {
+ fprintf(fd, "0x%04X", eepromN.baseEepHeader.regDmn[1]);
+ } else if (streq(var, "txMask")) {
+ fprintf(fd, "0x%04X", eepromN.baseEepHeader.txMask);
+ } else if (streq(var, "rxMask")) {
+ fprintf(fd, "0x%04X", eepromN.baseEepHeader.rxMask);
+ } else if (streq(var, "rfSilent")) {
+ fprintf(fd, "0x%04X", eepromN.baseEepHeader.rfSilent);
+ } else if (streq(var, "btOptions")) {
+ fprintf(fd, "0x%04X", eepromN.baseEepHeader.blueToothOptions);
+ } else if (streq(var, "deviceCap")) {
+ fprintf(fd, "0x%04X", eepromN.baseEepHeader.deviceCap);
+ } else if (strneq(var, "macaddr", 7)) {
+ fprintf(fd, "%02X",
+ eepromN.baseEepHeader.macAddr[atoi(var+7)]);
+ } else if (streq(var, "opCapFlags")) {
+ fprintf(fd, "0x%02X", eepromN.baseEepHeader.opCapFlags);
+ } else if (streq(var, "eepMisc")) {
+ fprintf(fd, "0x%02X", eepromN.baseEepHeader.eepMisc);
+ } else if (strneq(var, "binBuildNumber", 14)) {
+ fprintf(fd, "%3d",
+ (eepromN.baseEepHeader.binBuildNumber >> (8*atoi(var+14)))
+ & 0xff);
+ } else if (strneq(var, "custData", 8)) {
+ fprintf(fd, "%2.2X", eepromN.custData[atoi(var+8)]);
+ } else if (streq(var, "xpd_mask")) {
+ if (IS_VERS(<, AR_EEPROM_VER5_0))
+ fprintf(fd, "0x%02x", pExpnPower->xpdMask);
+ else
+ fprintf(fd, "0x%02x", pRaw->xpd_mask);
+ } else if (streq(var, "numChannels")) {
+ if (IS_VERS(<, AR_EEPROM_VER5_0))
+ fprintf(fd, "%2d", pExpnPower->numChannels);
+ else
+ fprintf(fd, "%2d", pRaw->numChannels);
+ } else if (streq(var, "freq")) {
+ if (IS_VERS(<, AR_EEPROM_VER5_0))
+ fprintf(fd, "%4d", pExpnPower->pChannels[curchan]);
+ else
+ fprintf(fd, "%4d", pRaw->pChannels[curchan]);
+ } else if (streq(var, "maxpow")) {
+ int16_t maxPower_t4;
+ if (IS_VERS(<, AR_EEPROM_VER5_0)) {
+ maxPower_t4 = pExpnPower->pDataPerChannel[curchan].maxPower_t4;
+ } else {
+ maxPower_t4 = pRaw->pDataPerChannel[curchan].maxPower_t4;
+ if (maxPower_t4 == 0)
+ maxPower_t4 = getMaxPowerV5(&pRaw->pDataPerChannel[curchan]);
+ }
+ printQuarterDbmPower(fd, maxPower_t4);
+ } else if (streq(var, "pd_gain")) {
+ fprintf(fd, "%4d", pRaw->pDataPerChannel[curchan].
+ pDataPerPDGain[curpdgain].pd_gain);
+ } else if (strneq(var, "maxpwr", 6)) {
+ int vpd = atoi(var+6);
+ if (vpd < pRaw->pDataPerChannel[curchan].pDataPerPDGain[curpdgain].numVpd)
+ printQuarterDbmPower(fd, pRaw->pDataPerChannel[curchan].
+ pDataPerPDGain[curpdgain].pwr_t4[vpd]);
+ else
+ fprintf(fd, " ");
+ } else if (strneq(var, "pwr_t4_", 7)) {
+ printQuarterDbmPower(fd, pExpnPower->pDataPerChannel[curchan].
+ pDataPerXPD[singleXpd].pwr_t4[atoi(var+7)]);
+ } else if (strneq(var, "Vpd", 3)) {
+ int vpd = atoi(var+3);
+ if (vpd < pRaw->pDataPerChannel[curchan].pDataPerPDGain[curpdgain].numVpd)
+ printVpd(fd, pRaw->pDataPerChannel[curchan].
+ pDataPerPDGain[curpdgain].Vpd[vpd]);
+ else
+ fprintf(fd, " ");
+ } else if (streq(var, "CTL")) {
+ fprintf(fd, "0x%2x", eeprom.ee_ctl[curctl] & 0xff);
+ } else if (streq(var, "ctlType")) {
+ static const char *ctlType[16] = {
+ "11a base", "11b", "11g", "11a TURBO", "108g",
+ "2GHT20", "5GHT20", "2GHT40", "5GHT40",
+ "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf",
+ };
+ fprintf(fd, "%8s", ctlType[eeprom.ee_ctl[curctl] & CTL_MODE_M]);
+ } else if (streq(var, "ctlRD")) {
+ static const char *ctlRD[8] = {
+ "0x00", " FCC", "0x20", "ETSI",
+ " MKK", "0x50", "0x60", "0x70"
+ };
+ fprintf(fd, "%s", ctlRD[(eeprom.ee_ctl[curctl] >> 4) & 7]);
+ } else if (strneq(var, "rdEdgePower", 11)) {
+ printEdgePower(fd, atoi(var+11));
+ } else if (strneq(var, "rdEdgeFlag", 10)) {
+ printEdgeFlag(fd, atoi(var+10));
+ } else if (strneq(var, "rdEdge", 6)) {
+ printEdge(fd, atoi(var+6));
+ } else if (strneq(var, "testChannel", 11)) {
+ fprintf(fd, "%4d", pPowerInfo[atoi(var+11)].testChannel);
+ } else if (strneq(var, "pwr6_24_", 8)) {
+ printHalfDbmPower(fd, pPowerInfo[atoi(var+8)].twicePwr6_24);
+ } else if (strneq(var, "pwr36_", 6)) {
+ printHalfDbmPower(fd, pPowerInfo[atoi(var+6)].twicePwr36);
+ } else if (strneq(var, "pwr48_", 6)) {
+ printHalfDbmPower(fd, pPowerInfo[atoi(var+6)].twicePwr48);
+ } else if (strneq(var, "pwr54_", 6)) {
+ printHalfDbmPower(fd, pPowerInfo[atoi(var+6)].twicePwr54);
+ } else if (strneq(var, "channelValue", 12)) {
+ fprintf(fd, "%4d", pDataPerChannel[atoi(var+12)].channelValue);
+ } else if (strneq(var, "pcdacMin", 8)) {
+ fprintf(fd, "%02d", pDataPerChannel[atoi(var+8)].pcdacMin);
+ } else if (strneq(var, "pcdacMax", 8)) {
+ fprintf(fd, "%02d", pDataPerChannel[atoi(var+8)].pcdacMax);
+ } else if (strneq(var, "pcdac", 5)) {
+ if (IS_VERS(<, AR_EEPROM_VER4_0)) {
+ fprintf(fd, "%02d", pDataPerChannel[atoi(var+5)].
+ PcdacValues[curpcdac]);
+ } else if (IS_VERS(<, AR_EEPROM_VER5_0)) {
+ fprintf(fd, "%02d",
+ pExpnPower->pDataPerChannel[curchan].
+ pDataPerXPD[singleXpd].pcdac[atoi(var+5)]);
+ } else
+ undef("pcdac");
+ } else if (strneq(var, "pwrValue", 8)) {
+ printPcdacValue(fd,
+ pDataPerChannel[atoi(var+8)].PwrValues[curpcdac]);
+ } else if (streq(var, "singleXpd")) {
+ fprintf(fd, "%2d", singleXpd);
+ } else
+ warnx("line %u, unknown EEPROM variable \"%s\"", lineno, var);
+#undef strneq
+#undef streq
+}
+
+static void
+ifmode(FILE *ftemplate, const char *mode)
+{
+ if (strcasecmp(mode, "11a") == 0) {
+ if (IS_VERS(<, AR_EEPROM_VER14_2)) {
+ if (eeprom.ee_Amode)
+ setmode(headerInfo11A);
+ else
+ skipto(ftemplate, "endmode");
+ return;
+ }
+ if (IS_VERS(>=, AR_EEPROM_VER14_2)) {
+ if (eepromN.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A)
+ setmode(headerInfo11A);
+ else
+ skipto(ftemplate, "endmode");
+ return;
+ }
+ } else if (strcasecmp(mode, "11g") == 0) {
+ if (IS_VERS(<, AR_EEPROM_VER14_2)) {
+ if (eeprom.ee_Gmode)
+ setmode(headerInfo11G);
+ else
+ skipto(ftemplate, "endmode");
+ return;
+ }
+ if (IS_VERS(>=, AR_EEPROM_VER14_2)) {
+ if (eepromN.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G)
+ setmode(headerInfo11B); /* NB: 2.4GHz */
+ else
+ skipto(ftemplate, "endmode");
+ return;
+ }
+ } else if (strcasecmp(mode, "11b") == 0) {
+ if (IS_VERS(<, AR_EEPROM_VER14_2)) {
+ if (eeprom.ee_Bmode)
+ setmode(headerInfo11B);
+ else
+ skipto(ftemplate, "endmode");
+ return;
+ }
+ }
+ warnx("line %d, unknown/unexpected mode \"%s\" ignored",
+ lineno, mode);
+ skipto(ftemplate, "endmode");
+}
+
+static void
+parseTemplate(FILE *ftemplate, FILE *fd)
+{
+ int c, i;
+ char id[MAXID];
+ long forchan, forpdgain, forctl, forpcdac;
+
+ lineno = 1;
+ bol = 1;
+ while ((c = getc(ftemplate)) != EOF) {
+ if (c == '#') { /* comment */
+ skiptoeol:
+ while ((c = getc(ftemplate)) != EOF && c != '\n')
+ ;
+ if (c == EOF)
+ return;
+ lineno++;
+ bol = 1;
+ continue;
+ }
+ if (c == '.' && bol) { /* .directive */
+ if (token(ftemplate, id, MAXID, ".directive") == EOF)
+ return;
+ /* process directive */
+ if (strcasecmp(id, "ifmode") == 0) {
+ skipws(ftemplate);
+ if (token(ftemplate, id, MAXID, "id") == EOF)
+ return;
+ ifmode(ftemplate, id);
+ } else if (strcasecmp(id, "endmode") == 0) {
+ /* XXX free malloc'd indirect data */
+ curmode = -1; /* NB: undefined */
+ } else if (strcasecmp(id, "forchan") == 0) {
+ forchan = ftell(ftemplate) - sizeof("forchan");
+ if (curchan == -1)
+ curchan = 0;
+ } else if (strcasecmp(id, "endforchan") == 0) {
+ if (++curchan < numChannels)
+ fseek(ftemplate, forchan, SEEK_SET);
+ else
+ curchan = -1;
+ } else if (strcasecmp(id, "ifpdgain") == 0) {
+ skipws(ftemplate);
+ if (token(ftemplate, id, MAXID, "pdgain") == EOF)
+ return;
+ curlpdgain = strtoul(id, NULL, 0);
+ if (curlpdgain >= pRaw->pDataPerChannel[curchan].numPdGains) {
+ skipto(ftemplate, "endpdgain");
+ curlpdgain = -1;
+ } else
+ curpdgain = pdgain(curlpdgain);
+ } else if (strcasecmp(id, "endpdgain") == 0) {
+ curlpdgain = curpdgain = -1;
+ } else if (strcasecmp(id, "forpdgain") == 0) {
+ forpdgain = ftell(ftemplate) - sizeof("forpdgain");
+ if (curlpdgain == -1) {
+ skipws(ftemplate);
+ if (token(ftemplate, id, MAXID, "pdgain") == EOF)
+ return;
+ curlpdgain = strtoul(id, NULL, 0);
+ if (curlpdgain >= pRaw->pDataPerChannel[curchan].numPdGains) {
+ skipto(ftemplate, "endforpdgain");
+ curlpdgain = -1;
+ } else
+ curpdgain = pdgain(curlpdgain);
+ }
+ } else if (strcasecmp(id, "endforpdgain") == 0) {
+ if (++curpdgain < pRaw->pDataPerChannel[curchan].numPdGains)
+ fseek(ftemplate, forpdgain, SEEK_SET);
+ else
+ curpdgain = -1;
+ } else if (strcasecmp(id, "forpcdac") == 0) {
+ forpcdac = ftell(ftemplate) - sizeof("forpcdac");
+ if (curpcdac == -1)
+ curpcdac = 0;
+ } else if (strcasecmp(id, "endforpcdac") == 0) {
+ if (++curpcdac < pDataPerChannel[0].numPcdacValues)
+ fseek(ftemplate, forpcdac, SEEK_SET);
+ else
+ curpcdac = -1;
+ } else if (strcasecmp(id, "forctl") == 0) {
+ forctl = ftell(ftemplate) - sizeof("forchan");
+ if (curctl == -1)
+ curctl = nextctl(0);
+ } else if (strcasecmp(id, "endforctl") == 0) {
+ curctl = nextctl(curctl+1);
+ if (curctl != -1)
+ fseek(ftemplate, forctl, SEEK_SET);
+ } else {
+ warnx("line %d, unknown directive %s ignored",
+ lineno, id);
+ }
+ goto skiptoeol;
+ }
+ if (c == '$') { /* $variable reference */
+ if (token(ftemplate, id, MAXID, "$var") == EOF)
+ return;
+ /* XXX not valid if variable depends on curmode */
+ eevar(fd, id);
+ continue;
+ }
+ if (c == '\\') { /* escape next character */
+ c = getc(ftemplate);
+ if (c == EOF)
+ return;
+ }
+ fputc(c, fd);
+ bol = (c == '\n');
+ if (bol)
+ lineno++;
+ }
+}
diff --git a/tools/tools/ath/athprom/eeprom-14 b/tools/tools/ath/athprom/eeprom-14
new file mode 100644
index 000000000000..ef2b1c69dd03
--- /dev/null
+++ b/tools/tools/ath/athprom/eeprom-14
@@ -0,0 +1,120 @@
+# $FreeBSD$
+#
+# v14 format EEPROM template (AR5416 and later 11n parts)
+#
+ |===================== Header Information ====================|
+ | Major Version $V_major | Minor Version $V_minor |
+ |-------------------------------------------------------------|
+ | Checksum $checksum | Length $length |
+ | RegDomain 1 $regDmn0 | RegDomain 2 $regDmn1 |
+ | TX Mask $txMask | RX Mask $rxMask |
+ | rfSilent $rfSilent | btOptions $btOptions |
+ | deviceCap $deviceCap | |
+ | MacAddress: $macaddr0:$macaddr1:$macaddr2:$macaddr3:$macaddr4:$macaddr5 |
+ | OpFlags: [$opCapFlags] 11A 1, 11G 1 |
+ | eepMisc: [$eepMisc] endian 0 |
+ |-------------------------------------------------------------|
+ | Customer Data in hex |
+ |= $custData0 $custData1 $custData2 $custData3 $custData4 $custData5 $custData6 $custData7 $custData8 $custData9 $custData10 $custData11 $custData12 $custData13 $custData14 $custData15 =|
+ |= $custData16 $custData17 $custData18 $custData19 $custData20 $custData21 $custData22 $custData23 $custData24 $custData25 $custData26 $custData27 $custData28 $custData29 $custData30 $custData31 =|
+ |= $custData32 $custData33 $custData34 $custData35 $custData36 $custData37 $custData38 $custData39 $custData40 $custData41 $custData42 $custData43 $custData44 $custData45 $custData46 $custData47 =|
+ |= $custData48 $custData49 $custData50 $custData51 $custData52 $custData53 $custData54 $custData55 $custData56 $custData57 $custData58 $custData59 $custData60 $custData61 $custData62 $custData63 =|
+ |=============================================================|
+
+.ifmode 11a
+ |=========== 5GHz Modal Header ===========|
+ | Ant Chain 0 $antCtrlChain0 |
+ | Ant Chain 1 $antCtrlChain1 |
+ | Ant Chain 2 $antCtrlChain2 |
+ | Ant Chain common 0x00001120 |
+ | Antenna Gain Chain 0 $antGainCh0 |
+ | Antenna Gain Chain 1 $antGainCh1 |
+ | Antenna Gain Chain 2 $antGainCh2 |
+ | Switch Settling $switchSettling |
+ | TxRxAttenuation Ch 0 $txRxAttenCh0 |
+ | TxRxAttenuation Ch 1 $txRxAttenCh1 |
+ | TxRxAttenuation Ch 2 $txRxAttenCh2 |
+ | RxTxMargin Chain 0 $rxTxMarginCh0 |
+ | RxTxMargin Chain 1 $rxTxMarginCh1 |
+ | RxTxMargin Chain 2 $rxTxMarginCh2 |
+ | adc desired size $adcDesiredSize |
+ | pga desired size $pgaDesiredSize |
+ | xlna gain Chain 0 $xlnaGainCh0 |
+ | xlna gain Chain 1 $xlnaGainCh1 |
+ | xlna gain Chain 2 $xlnaGainCh2 |
+ | tx end to xpa off $txEndToXPAOff |
+ | tx end to rx on $txEndToRxOn |
+ | tx frame to xpa on $txFrameToXPAOn |
+ | thresh62 $thresh62 |
+ | noise floor thres 0 $noiseFloorThreshCh0 |
+ | noise floor thres 1 $noiseFloorThreshCh1 |
+ | noise floor thres 2 $noiseFloorThreshCh2 |
+ | Xpd Gain Mask $xpdGain |
+ | Xpd extern $xpd |
+ | IQ Cal I, Q Chain 0 $iqCalICh0, $iqCalQCh0 |
+ | IQ Cal I, Q Chain 1 $iqCalICh1, $iqCalQCh1 |
+ | IQ Cal I, Q Chain 2 $iqCalICh2, $iqCalQCh2 |
+ | pdGain Overlap $pdGainOverlap dB |
+ | Analog Output Bias (ob) $ob |
+ | Analog Driver Bias (db) $db |
+ | Xpa bias level $xpaBiasLvl |
+ | pwr dec 2 chain $pwrDecreaseFor2Chain dB |
+ | pwr dec 3 chain $pwrDecreaseFor3Chain dB |
+ | txFrameToDataStart $txFrameToDataStart |
+ | txFrameToPaOn $txFrameToPaOn |
+ | ht40PowerIncForPdadc $ht40PowerIncForPdadc |
+ |=========================================|
+
+============================Target Power Info===============================
+| rate | $testChannel0 | $testChannel1 | $testChannel2 | $testChannel3 |
+|==============|==============|==============|==============|==============|
+| 6-24 | $pwr6_24_0 | $pwr6_24_1 | $pwr6_24_2 | $pwr6_24_3 |
+| 36 | $pwr36_0 | $pwr36_1 | $pwr36_2 | $pwr36_3 |
+| 48 | $pwr48_0 | $pwr48_1 | $pwr48_2 | $pwr48_3 |
+| 54 | $pwr54_0 | $pwr54_1 | $pwr54_2 | $pwr54_3 |
+|==============|==============|==============|==============|==============|
+| rate | $testChannel4 | $testChannel5 | $testChannel6 | $testChannel7 |
+|==============|==============|==============|==============|==============|
+| 6-24 | $pwr6_24_4 | $pwr6_24_5 | $pwr6_24_6 | $pwr6_24_7 |
+| 36 | $pwr36_4 | $pwr36_5 | $pwr36_6 | $pwr36_7 |
+| 48 | $pwr48_4 | $pwr48_5 | $pwr48_6 | $pwr48_7 |
+| 54 | $pwr54_4 | $pwr54_5 | $pwr54_6 | $pwr54_7 |
+|==============|==============|==============|==============|==============|
+
+=======================Test Group Band Edge Power========================
+.forctl
+| |
+| CTL: $CTL [ $ctlRD $ctlType mode ] |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 |
+=========================================================================
+.endforctl
+.endmode
+
+.ifmode 11g
+=============Target Power Info================
+| rate | $testChannel0 | $testChannel1 |
+|==============|==============|==============|
+| 1 | $pwr6_24_0 | $pwr6_24_1 |
+| 2 | $pwr36_0 | $pwr36_1 |
+| 5.5 | $pwr48_0 | $pwr48_1 |
+| 11 | $pwr54_0 | $pwr54_1 |
+|==============|==============|==============|
+
+=======================Test Group Band Edge Power========================
+.forctl
+| |
+| CTL: $CTL [ $ctlRD $ctlType mode ] |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 |
+=========================================================================
+.endforctl
+.endmode
diff --git a/tools/tools/ath/athprom/eeprom-3 b/tools/tools/ath/athprom/eeprom-3
new file mode 100644
index 000000000000..73c7033705d6
--- /dev/null
+++ b/tools/tools/ath/athprom/eeprom-3
@@ -0,0 +1,165 @@
+# $FreeBSD$
+#
+# v3 format EEPROM template
+#
+.ifmode 11a
+ =================Header Information for mode 11a===============
+ | Major Version $V_major | Minor Version $V_minor |
+ |-------------------------------------------------------------|
+ | A Mode $Amode | B Mode $Bmode | G Mode $Gmode |
+ | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable |
+ | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 |
+ | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI |
+ |-------------------------------------------------------------|
+ | device type $deviceType | Switch Settling Time $switchSettling |
+ | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain |
+ | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 |
+ | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn |
+ | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh |
+ | XPD Gain $xgain | XPD $xpd |
+ | txrx Attenuation $txrxAtten | Capabilities $capField |
+ | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 |
+ | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 |
+ | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 |
+ | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 |
+ | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 |
+ | Antenna control 10 $antennaControl10 | |
+ |-------------------------------------------------------------|
+ | OB_1 $ob1 | OB_2 $ob2 | OB_3 $ob3 | OB_4 $ob4 |
+ | DB_1 $db1 | DB_2 $db2 | DB_3 $db3 | DB_4 $db4 |
+ ===============================================================
+
+ =========================Calibration Information============================
+ | $channelValue0 | $channelValue1 | $channelValue2 | $channelValue3 | $channelValue4 |
+ |==============|==============|==============|==============|==============|
+ |pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|
+.forpcdac
+ | $pcdac0 $pwrValue0 | $pcdac1 $pwrValue1 | $pcdac2 $pwrValue2 | $pcdac3 $pwrValue3 | $pcdac4 $pwrValue4 |
+.endforpcdac
+ | | | | | |
+ | pcdac min $pcdacMin0 | pcdac min $pcdacMin1 | pcdac min $pcdacMin2 | pcdac min $pcdacMin3 | pcdac min $pcdacMin4 |
+ | pcdac max $pcdacMax0 | pcdac max $pcdacMax1 | pcdac max $pcdacMax2 | pcdac max $pcdacMax3 | pcdac max $pcdacMax4 |
+ |==============|==============|==============|==============|==============|
+ | $channelValue5 | $channelValue6 | $channelValue7 | $channelValue8 | $channelValue9 |
+ |==============|==============|==============|==============|==============|
+ |pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|
+.forpcdac
+ | $pcdac5 $pwrValue5 | $pcdac6 $pwrValue6 | $pcdac7 $pwrValue7 | $pcdac8 $pwrValue8 | $pcdac9 $pwrValue9 |
+.endforpcdac
+ | | | | | |
+ | pcdac min $pcdacMin5 | pcdac min $pcdacMin6 | pcdac min $pcdacMin7 | pcdac min $pcdacMin8 | pcdac min $pcdacMin9 |
+ | pcdac max $pcdacMax5 | pcdac max $pcdacMax6 | pcdac max $pcdacMax7 | pcdac max $pcdacMax8 | pcdac max $pcdacMax9 |
+ |==============|==============|==============|==============|==============|
+
+ ============================Target Power Info===============================
+ | rate | $testChannel0 | $testChannel1 | $testChannel2 | $testChannel3 |
+ |==============|==============|==============|==============|==============|
+ | 6-24 | $pwr6_24_0 | $pwr6_24_1 | $pwr6_24_2 | $pwr6_24_3 |
+ | 36 | $pwr36_0 | $pwr36_1 | $pwr36_2 | $pwr36_3 |
+ | 48 | $pwr48_0 | $pwr48_1 | $pwr48_2 | $pwr48_3 |
+ | 54 | $pwr54_0 | $pwr54_1 | $pwr54_2 | $pwr54_3 |
+ |==============|==============|==============|==============|==============|
+ | rate | $testChannel4 | $testChannel5 | $testChannel6 | $testChannel7 |
+ |==============|==============|==============|==============|==============|
+ | 6-24 | $pwr6_24_4 | $pwr6_24_5 | $pwr6_24_6 | $pwr6_24_7 |
+ | 36 | $pwr36_4 | $pwr36_5 | $pwr36_6 | $pwr36_7 |
+ | 48 | $pwr48_4 | $pwr48_5 | $pwr48_6 | $pwr48_7 |
+ | 54 | $pwr54_4 | $pwr54_5 | $pwr54_6 | $pwr54_7 |
+ |==============|==============|==============|==============|==============|
+.endmode
+
+.ifmode 11b
+ =================Header Information for mode 11b===============
+ | Major Version $V_major | Minor Version $V_minor |
+ |-------------------------------------------------------------|
+ | A Mode $Amode | B Mode $Bmode | G Mode $Gmode |
+ | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable |
+ | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 |
+ | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI |
+ |-------------------------------------------------------------|
+ | device type $deviceType | Switch Settling Time $switchSettling |
+ | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain |
+ | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 |
+ | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn |
+ | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh |
+ | XPD Gain $xgain | XPD $xpd |
+ | txrx Attenuation $txrxAtten | Capabilities $capField |
+ | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 |
+ | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 |
+ | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 |
+ | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 |
+ | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 |
+ | Antenna control 10 $antennaControl10 | |
+ |-------------------------------------------------------------|
+ | OB_1 $obFor24 | B_OB $ob2GHz0 | DB_1 $dbFor24 | B_DB $db2GHz0 |
+ ===============================================================
+
+ ==========Calibration Information=============
+ | $channelValue0 | $channelValue1 | $channelValue2 |
+ |==============|==============|==============|
+ |pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|
+.forpcdac
+ | $pcdac0 $pwrValue0 | $pcdac1 $pwrValue1 | $pcdac2 $pwrValue2 |
+.endforpcdac
+ | | | |
+ | pcdac min $pcdacMin0 | pcdac min $pcdacMin1 | pcdac min $pcdacMin2 |
+ | pcdac max $pcdacMax0 | pcdac max $pcdacMax1 | pcdac max $pcdacMax2 |
+ |==============|==============|==============|
+
+ =============Target Power Info================
+ | rate | $testChannel0 | $testChannel1 |
+ |==============|==============|==============|
+ | 1 | $pwr6_24_0 | $pwr6_24_1 |
+ | 2 | $pwr36_0 | $pwr36_1 |
+ | 5.5 | $pwr48_0 | $pwr48_1 |
+ | 11 | $pwr54_0 | $pwr54_1 |
+ |==============|==============|==============|
+.endmode
+
+.ifmode 11g
+ =================Header Information for mode 11g===============
+ | Major Version $V_major | Minor Version $V_minor |
+ |-------------------------------------------------------------|
+ | A Mode $Amode | B Mode $Bmode | G Mode $Gmode |
+ | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable |
+ | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 |
+ | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI |
+ |-------------------------------------------------------------|
+ | device type $deviceType | Switch Settling Time $switchSettling |
+ | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain |
+ | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 |
+ | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn |
+ | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh |
+ | XPD Gain $xgain | XPD $xpd |
+ | txrx Attenuation $txrxAtten | Capabilities $capField |
+ | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 |
+ | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 |
+ | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 |
+ | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 |
+ | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 |
+ | Antenna control 10 $antennaControl10 | |
+ |-------------------------------------------------------------|
+ | OB_1 $obFor24g | B_OB $ob2GHz1 | DB_1 $dbFor24g | B_DB $db2GHz1 |
+ ===============================================================
+
+ ==========Calibration Information=============
+ | $channelValue0 | $channelValue1 | $channelValue2 |
+ |==============|==============|==============|
+ |pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|
+.forpcdac
+ | $pcdac0 $pwrValue0 | $pcdac1 $pwrValue1 | $pcdac2 $pwrValue2 |
+.endforpcdac
+ | | | |
+ | pcdac min $pcdacMin0 | pcdac min $pcdacMin1 | pcdac min $pcdacMin2 |
+ | pcdac max $pcdacMax0 | pcdac max $pcdacMax1 | pcdac max $pcdacMax2 |
+ |==============|==============|==============|
+
+ =============Target Power Info================
+ | rate | $testChannel0 | $testChannel1 |
+ |==============|==============|==============|
+ | 1 | $pwr6_24_0 | $pwr6_24_1 |
+ | 2 | $pwr36_0 | $pwr36_1 |
+ | 5.5 | $pwr48_0 | $pwr48_1 |
+ | 11 | $pwr54_0 | $pwr54_1 |
+ |==============|==============|==============|
+.endmode
diff --git a/tools/tools/ath/athprom/eeprom-4 b/tools/tools/ath/athprom/eeprom-4
new file mode 100644
index 000000000000..0d4708bebc63
--- /dev/null
+++ b/tools/tools/ath/athprom/eeprom-4
@@ -0,0 +1,206 @@
+# $FreeBSD$
+#
+# v4 format EEPROM template
+#
+.ifmode 11a
+ =================Header Information for mode $mode===============
+ | Major Version $V_major | Minor Version $V_minor |
+ | EAR Start $earStart | Target Power Start $tpStart |
+ | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal |
+ |-------------------------------------------------------------|
+ | A Mode $Amode | B Mode $Bmode | G Mode $Gmode |
+ | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable |
+ | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 |
+ | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI |
+ |-------------------------------------------------------------|
+ | worldwide roaming $WWR | False detect backoff $falseDetectBackoff |
+ | device type $deviceType | Switch Settling Time $switchSettling |
+ | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain |
+ | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 |
+ | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn |
+ | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh |
+ | XPD Gain $xgain | XPD $xpd |
+ | txrx Attenuation $txrxAtten | Capabilities $capField |
+ | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 |
+ | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 |
+ | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 |
+ | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 |
+ | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 |
+ | Antenna control 10 $antennaControl10 | |
+ |-------------------------------------------------------------|
+ | OB_1 $ob1 | OB_2 $ob2 | OB_3 $ob3 | OB_4 $ob4 |
+ | DB_1 $db1 | DB_2 $db2 | DB_3 $db3 | DB_4 $db4 |
+ ===============================================================
+
+ =========5112 Power Calibration Information==========
+ | XPD_Gain_mask $xpd_mask | Number of channels $numChannels |
+ | XPD_GAIN $singleXpd | |
+ |======|========|========|========|========|========|
+ | freq | pwr1 | pwr2 | pwr3 | pwr4 | maxPow |
+ | | [pcd] | [pcd] | [pcd] | [pcd] | |
+ |======|========|========|========|========|========|
+.forchan
+ | $freq | $pwr_t4_0 | $pwr_t4_1 | $pwr_t4_2 | $pwr_t4_3 | $maxpow |
+ | | [$pcdac0] | [$pcdac1] | [$pcdac2] | [$pcdac3] | |
+ |======|========|========|========|========|========|
+.endforchan
+
+ ============================Target Power Info===============================
+ | rate | $testChannel0 | $testChannel1 | $testChannel2 | $testChannel3 |
+ |==============|==============|==============|==============|==============|
+ | 6-24 | $pwr6_24_0 | $pwr6_24_1 | $pwr6_24_2 | $pwr6_24_3 |
+ | 36 | $pwr36_0 | $pwr36_1 | $pwr36_2 | $pwr36_3 |
+ | 48 | $pwr48_0 | $pwr48_1 | $pwr48_2 | $pwr48_3 |
+ | 54 | $pwr54_0 | $pwr54_1 | $pwr54_2 | $pwr54_3 |
+ |==============|==============|==============|==============|==============|
+ | rate | $testChannel4 | $testChannel5 | $testChannel6 | $testChannel7 |
+ |==============|==============|==============|==============|==============|
+ | 6-24 | $pwr6_24_4 | $pwr6_24_5 | $pwr6_24_6 | $pwr6_24_7 |
+ | 36 | $pwr36_4 | $pwr36_5 | $pwr36_6 | $pwr36_7 |
+ | 48 | $pwr48_4 | $pwr48_5 | $pwr48_6 | $pwr48_7 |
+ | 54 | $pwr54_4 | $pwr54_5 | $pwr54_6 | $pwr54_7 |
+ |==============|==============|==============|==============|==============|
+
+ =======================Test Group Band Edge Power========================
+.forctl
+ | |
+ | CTL: $CTL [ $ctlRD $ctlType mode ] |
+ |=======|=======|=======|=======|=======|=======|=======|=======|=======|
+ | edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 |
+ |=======|=======|=======|=======|=======|=======|=======|=======|=======|
+ | power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 |
+ |=======|=======|=======|=======|=======|=======|=======|=======|=======|
+ | flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 |
+ =========================================================================
+.endforctl
+.endmode
+
+.ifmode 11b
+ =================Header Information for mode $mode===============
+ | Major Version $V_major | Minor Version $V_minor |
+ | EAR Start $earStart | Target Power Start $tpStart |
+ | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal |
+ |-------------------------------------------------------------|
+ | A Mode $Amode | B Mode $Bmode | G Mode $Gmode |
+ | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable |
+ | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 |
+ | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI |
+ |-------------------------------------------------------------|
+ | worldwide roaming $WWR | False detect backoff $falseDetectBackoff |
+ | device type $deviceType | Switch Settling Time $switchSettling |
+ | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain |
+ | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 |
+ | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn |
+ | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh |
+ | XPD Gain $xgain | XPD $xpd |
+ | txrx Attenuation $txrxAtten | Capabilities $capField |
+ | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 |
+ | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 |
+ | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 |
+ | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 |
+ | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 |
+ | Antenna control 10 $antennaControl10 | |
+ |-------------------------------------------------------------|
+ | OB_1 $obFor24 | B_OB $ob2GHz0 | DB_1 $dbFor24 | B_DB $db2GHz0 |
+ ===============================================================
+
+ =========5112 Power Calibration Information==========
+ | XPD_Gain_mask $xpd_mask | Number of channels $numChannels |
+ | XPD_GAIN $singleXpd | |
+ |======|========|========|========|========|========|
+ | freq | pwr1 | pwr2 | pwr3 | pwr4 | maxPow |
+ | | [pcd] | [pcd] | [pcd] | [pcd] | |
+ |======|========|========|========|========|========|
+.forchan
+ | $freq | $pwr_t4_0 | $pwr_t4_1 | $pwr_t4_2 | $pwr_t4_3 | $maxpow |
+ | | [$pcdac0] | [$pcdac1] | [$pcdac2] | [$pcdac3] | |
+ |======|========|========|========|========|========|
+.endforchan
+
+ =============Target Power Info================
+ | rate | $testChannel0 | $testChannel1 |
+ |==============|==============|==============|
+ | 1 | $pwr6_24_0 | $pwr6_24_1 |
+ | 2 | $pwr36_0 | $pwr36_1 |
+ | 5.5 | $pwr48_0 | $pwr48_1 |
+ | 11 | $pwr54_0 | $pwr54_1 |
+ |==============|==============|==============|
+
+ =======================Test Group Band Edge Power========================
+.forctl
+ | |
+ | CTL: $CTL [ $ctlRD $ctlType mode ] |
+ |=======|=======|=======|=======|=======|=======|=======|=======|=======|
+ | edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 |
+ |=======|=======|=======|=======|=======|=======|=======|=======|=======|
+ | power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 |
+ |=======|=======|=======|=======|=======|=======|=======|=======|=======|
+ | flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 |
+ =========================================================================
+.endforctl
+.endmode
+
+.ifmode 11g
+ =================Header Information for mode $mode===============
+ | Major Version $V_major | Minor Version $V_minor |
+ | EAR Start $earStart | Target Power Start $tpStart |
+ | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal |
+ |-------------------------------------------------------------|
+ | A Mode $Amode | B Mode $Bmode | G Mode $Gmode |
+ | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable |
+ | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 |
+ | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI |
+ |-------------------------------------------------------------|
+ | worldwide roaming $WWR | False detect backoff $falseDetectBackoff |
+ | device type $deviceType | Switch Settling Time $switchSettling |
+ | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain |
+ | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 |
+ | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn |
+ | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh |
+ | XPD Gain $xgain | XPD $xpd |
+ | txrx Attenuation $txrxAtten | Capabilities $capField |
+ | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 |
+ | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 |
+ | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 |
+ | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 |
+ | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 |
+ | Antenna control 10 $antennaControl10 | |
+ |-------------------------------------------------------------|
+ | OB_1 $obFor24g | B_OB $ob2GHz1 | DB_1 $dbFor24g | B_DB $db2GHz1 |
+ ===============================================================
+
+ =========5112 Power Calibration Information==========
+ | XPD_Gain_mask $xpd_mask | Number of channels $numChannels |
+ | XPD_GAIN $singleXpd | |
+ |======|========|========|========|========|========|
+ | freq | pwr1 | pwr2 | pwr3 | pwr4 | maxPow |
+ | | [pcd] | [pcd] | [pcd] | [pcd] | |
+ |======|========|========|========|========|========|
+.forchan
+ | $freq | $pwr_t4_0 | $pwr_t4_1 | $pwr_t4_2 | $pwr_t4_3 | $maxpow |
+ | | [$pcdac0] | [$pcdac1] | [$pcdac2] | [$pcdac3] | |
+ |======|========|========|========|========|========|
+.endforchan
+
+ =============Target Power Info================
+ | rate | $testChannel0 | $testChannel1 |
+ |==============|==============|==============|
+ | 6-24 | $pwr6_24_0 | $pwr6_24_1 |
+ | 35 | $pwr36_0 | $pwr36_1 |
+ | 48 | $pwr48_0 | $pwr48_1 |
+ | 54 | $pwr54_0 | $pwr54_1 |
+ |==============|==============|==============|
+
+ =======================Test Group Band Edge Power========================
+.forctl
+ | |
+ | CTL: $CTL [ $ctlRD $ctlType mode ] |
+ |=======|=======|=======|=======|=======|=======|=======|=======|=======|
+ | edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 |
+ |=======|=======|=======|=======|=======|=======|=======|=======|=======|
+ | power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 |
+ |=======|=======|=======|=======|=======|=======|=======|=======|=======|
+ | flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 |
+ =========================================================================
+.endforctl
+.endmode
diff --git a/tools/tools/ath/athprom/eeprom-5 b/tools/tools/ath/athprom/eeprom-5
new file mode 100644
index 000000000000..b48a42ad3e91
--- /dev/null
+++ b/tools/tools/ath/athprom/eeprom-5
@@ -0,0 +1,245 @@
+# $FreeBSD$
+#
+# v5 format EEPROM template
+#
+.ifmode 11a
+ =================Header Information for mode 11a===============
+ | Major Version $V_major | Minor Version $V_minor |
+ | EAR Start $earStart | Target Power Start $tpStart |
+ | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal |
+ | EEP Map2PowerCalStart $eepMap2PowerCalStart | |
+ |-------------------------------------------------------------|
+ | A Mode $Amode | B Mode $Bmode | G Mode $Gmode |
+ | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable |
+ | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 |
+ | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI |
+ |-------------------------------------------------------------|
+ | worldwide roaming $WWR | False detect backoff $falseDetectBackoff |
+ | device type $deviceType | Switch Settling Time $switchSettling |
+ | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain |
+ | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 |
+ | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn |
+ | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh |
+ | XPD Gain $xgain | XPD $xpd |
+ | txrx Attenuation $txrxAtten | Capabilities $capField |
+ | Turbo txrx Attenuat $txrxAttenTurbo | Turbo Switch Settling $switchSettlingTurbo |
+ | Turbo ADC Desired Size $adcDesiredSizeTurbo | Turbo PGA Desired Size $pgaDesiredSizeTurbo |
+ | Turbo rxtx Margin $rxtxMarginTurbo | |
+ | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 |
+ | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 |
+ | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 |
+ | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 |
+ | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 |
+ | Antenna control 10 $antennaControl10 | |
+ |-------------------------------------------------------------|
+ | OB_1 $ob1 | OB_2 $ob2 | OB_3 $ob3 | OB_4 $ob4 |
+ | DB_1 $db1 | DB_2 $db2 | DB_3 $db3 | DB_4 $db4 |
+ ===============================================================
+
+=========2413 Power Calibration Information===================
+| XPD_Gain_mask $xpd_mask | Number of channels $numChannels | |
+|========|======|========|========|========|========|========|
+| freq | pd | pwr1 | pwr2 | pwr3 | pwr4 | pwr5 |
+| maxpow | gain | [Vpd] | [Vpd] | [Vpd] | [Vpd] | [Vpd] |
+|========|======|========|========|========|========|========|
+.forchan
+.ifpdgain 0
+| $freq | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 |
+| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 |
+.endpdgain
+.ifpdgain 1
+| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 |
+| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 |
+.endpdgain
+.forpdgain 2
+| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 |
+| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 |
+.endforpdgain
+|========|======|========|========|========|========|========|
+.endforchan
+
+============================Target Power Info===============================
+| rate | $testChannel0 | $testChannel1 | $testChannel2 | $testChannel3 |
+|==============|==============|==============|==============|==============|
+| 6-24 | $pwr6_24_0 | $pwr6_24_1 | $pwr6_24_2 | $pwr6_24_3 |
+| 36 | $pwr36_0 | $pwr36_1 | $pwr36_2 | $pwr36_3 |
+| 48 | $pwr48_0 | $pwr48_1 | $pwr48_2 | $pwr48_3 |
+| 54 | $pwr54_0 | $pwr54_1 | $pwr54_2 | $pwr54_3 |
+|==============|==============|==============|==============|==============|
+| rate | $testChannel4 | $testChannel5 | $testChannel6 | $testChannel7 |
+|==============|==============|==============|==============|==============|
+| 6-24 | $pwr6_24_4 | $pwr6_24_5 | $pwr6_24_6 | $pwr6_24_7 |
+| 36 | $pwr36_4 | $pwr36_5 | $pwr36_6 | $pwr36_7 |
+| 48 | $pwr48_4 | $pwr48_5 | $pwr48_6 | $pwr48_7 |
+| 54 | $pwr54_4 | $pwr54_5 | $pwr54_6 | $pwr54_7 |
+|==============|==============|==============|==============|==============|
+
+=======================Test Group Band Edge Power========================
+.forctl
+| |
+| CTL: $CTL [ $ctlRD $ctlType mode ] |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 |
+=========================================================================
+.endforctl
+.endmode
+
+.ifmode 11b
+ =================Header Information for mode 11b===============
+ | Major Version $V_major | Minor Version $V_minor |
+ | EAR Start $earStart | Target Power Start $tpStart |
+ | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal |
+ | EEP Map2PowerCalStart $eepMap2PowerCalStart | |
+ |-------------------------------------------------------------|
+ | A Mode $Amode | B Mode $Bmode | G Mode $Gmode |
+ | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable |
+ | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 |
+ | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI |
+ |-------------------------------------------------------------|
+ | worldwide roaming $WWR | False detect backoff $falseDetectBackoff |
+ | device type $deviceType | Switch Settling Time $switchSettling |
+ | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain |
+ | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 |
+ | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn |
+ | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh |
+ | XPD Gain $xgain | XPD $xpd |
+ | txrx Attenuation $txrxAtten | Capabilities $capField |
+ | Turbo txrx Attenuat $txrxAttenTurbo | Turbo Switch Settling $switchSettlingTurbo |
+ | Turbo ADC Desired Size $adcDesiredSizeTurbo | Turbo PGA Desired Size $pgaDesiredSizeTurbo |
+ | Turbo rxtx Margin $rxtxMarginTurbo | |
+ | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 |
+ | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 |
+ | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 |
+ | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 |
+ | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 |
+ | Antenna control 10 $antennaControl10 | |
+ |-------------------------------------------------------------|
+ | OB_1 $obFor24 | B_OB $ob2GHz0 | DB_1 $dbFor24 | B_DB $db2GHz0 |
+ ===============================================================
+
+=========2413 Power Calibration Information===================
+| XPD_Gain_mask $xpd_mask | Number of channels $numChannels | |
+|========|======|========|========|========|========|========|
+| freq | pd | pwr1 | pwr2 | pwr3 | pwr4 | pwr5 |
+| maxpow | gain | [Vpd] | [Vpd] | [Vpd] | [Vpd] | [Vpd] |
+|========|======|========|========|========|========|========|
+.forchan
+.ifpdgain 0
+| $freq | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 |
+| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 |
+.endpdgain
+.ifpdgain 1
+| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 |
+| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 |
+.endpdgain
+.forpdgain 2
+| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 |
+| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 |
+.endforpdgain
+|========|======|========|========|========|========|========|
+.endforchan
+
+=============Target Power Info================
+| rate | $testChannel0 | $testChannel1 |
+|==============|==============|==============|
+| 1 | $pwr6_24_0 | $pwr6_24_1 |
+| 2 | $pwr36_0 | $pwr36_1 |
+| 5.5 | $pwr48_0 | $pwr48_1 |
+| 11 | $pwr54_0 | $pwr54_1 |
+|==============|==============|==============|
+
+=======================Test Group Band Edge Power========================
+.forctl
+| |
+| CTL: $CTL [ $ctlRD $ctlType mode ] |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 |
+=========================================================================
+.endforctl
+.endmode
+
+.ifmode 11g
+ =================Header Information for mode 11g===============
+ | Major Version $V_major | Minor Version $V_minor |
+ | EAR Start $earStart | Target Power Start $tpStart |
+ | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal |
+ | EEP Map2PowerCalStart $eepMap2PowerCalStart | |
+ |-------------------------------------------------------------|
+ | A Mode $Amode | B Mode $Bmode | G Mode $Gmode |
+ | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable |
+ | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 |
+ | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI |
+ |-------------------------------------------------------------|
+ | worldwide roaming $WWR | False detect backoff $falseDetectBackoff |
+ | device type $deviceType | Switch Settling Time $switchSettling |
+ | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain |
+ | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 |
+ | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn |
+ | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh |
+ | XPD Gain $xgain | XPD $xpd |
+ | txrx Attenuation $txrxAtten | Capabilities $capField |
+ | Turbo txrx Attenuat $txrxAttenTurbo | Turbo Switch Settling $switchSettlingTurbo |
+ | Turbo ADC Desired Size $adcDesiredSizeTurbo | Turbo PGA Desired Size $pgaDesiredSizeTurbo |
+ | Turbo rxtx Margin $rxtxMarginTurbo | |
+ | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 |
+ | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 |
+ | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 |
+ | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 |
+ | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 |
+ | Antenna control 10 $antennaControl10 | |
+ |-------------------------------------------------------------|
+ | OB_1 $obFor24g | B_OB $ob2GHz1 | DB_1 $dbFor24g | B_DB $db2GHz1 |
+ ===============================================================
+
+=========2413 Power Calibration Information===================
+| XPD_Gain_mask $xpd_mask | Number of channels $numChannels | |
+|========|======|========|========|========|========|========|
+| freq | pd | pwr1 | pwr2 | pwr3 | pwr4 | pwr5 |
+| maxpow | gain | [Vpd] | [Vpd] | [Vpd] | [Vpd] | [Vpd] |
+|========|======|========|========|========|========|========|
+.forchan
+.ifpdgain 0
+| $freq | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 |
+| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 |
+.endpdgain
+.ifpdgain 1
+| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 |
+| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 |
+.endpdgain
+.forpdgain 2
+| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 |
+| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 |
+.endforpdgain
+|========|======|========|========|========|========|========|
+.endforchan
+
+=============Target Power Info================
+| rate | $testChannel0 | $testChannel1 |
+|==============|==============|==============|
+| 6-24 | $pwr6_24_0 | $pwr6_24_1 |
+| 36 | $pwr36_0 | $pwr36_1 |
+| 48 | $pwr48_0 | $pwr48_1 |
+| 54 | $pwr54_0 | $pwr54_1 |
+|==============|==============|==============|
+
+=======================Test Group Band Edge Power========================
+.forctl
+| |
+| CTL: $CTL [ $ctlRD $ctlType mode ] |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 |
+|=======|=======|=======|=======|=======|=======|=======|=======|=======|
+| flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 |
+=========================================================================
+.endforctl
+.endmode
diff --git a/tools/tools/ath/athradar/Makefile b/tools/tools/ath/athradar/Makefile
new file mode 100644
index 000000000000..23d3012f2344
--- /dev/null
+++ b/tools/tools/ath/athradar/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+PROG= athradar
+
+.include <../Makefile.inc>
+
+SRCS= athradar.c
+SRCS+= opt_ah.h
+CLEANFILES+= opt_ah.h
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+ echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athradar/athradar.c b/tools/tools/ath/athradar/athradar.c
new file mode 100644
index 000000000000..f40e1bd09be5
--- /dev/null
+++ b/tools/tools/ath/athradar/athradar.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+
+#ifndef ATH_DEFAULT
+#define ATH_DEFAULT "ath0"
+#endif
+
+#include <getopt.h>
+#include <errno.h>
+#include <err.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+
+struct radarhandler {
+ struct ath_diag atd;
+ int s;
+ struct ifreq ifr;
+ int ah_devid;
+};
+
+int
+radar_opendev(struct radarhandler *radar, const char *devid)
+{
+ HAL_REVS revs;
+
+ radar->s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (radar->s < 0) {
+ warn("socket");
+ return 0;
+ }
+
+ strncpy(radar->atd.ad_name, devid, sizeof (radar->atd.ad_name));
+
+ /* Get the hardware revision, just to verify things are working */
+ radar->atd.ad_id = HAL_DIAG_REVS;
+ radar->atd.ad_out_data = (caddr_t) &revs;
+ radar->atd.ad_out_size = sizeof(revs);
+ if (ioctl(radar->s, SIOCGATHDIAG, &radar->atd) < 0) {
+ warn(radar->atd.ad_name);
+ return 0;
+ }
+ radar->ah_devid = revs.ah_devid;
+ return 1;
+}
+
+void
+radar_closedev(struct radarhandler *radar)
+{
+ close(radar->s);
+ radar->s = -1;
+}
+
+void
+radarset(struct radarhandler *radar, int op, u_int32_t param)
+{
+ HAL_PHYERR_PARAM pe;
+
+ pe.pe_firpwr = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_rrssi = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_height = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_prssi = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_inband = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_enabled = HAL_PHYERR_PARAM_NOVAL;
+
+ pe.pe_relpwr = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_relstep = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_maxlen = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_usefir128 = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_blockradar = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_enmaxrssi = HAL_PHYERR_PARAM_NOVAL;
+
+ pe.pe_extchannel = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_enrelpwr = HAL_PHYERR_PARAM_NOVAL;
+ pe.pe_en_relstep_check = HAL_PHYERR_PARAM_NOVAL;
+
+ switch (op) {
+ case DFS_PARAM_ENABLE:
+ pe.pe_enabled = param;
+ break;
+ case DFS_PARAM_FIRPWR:
+ pe.pe_firpwr = param;
+ break;
+ case DFS_PARAM_RRSSI:
+ pe.pe_rrssi = param;
+ break;
+ case DFS_PARAM_HEIGHT:
+ pe.pe_height = param;
+ break;
+ case DFS_PARAM_PRSSI:
+ pe.pe_prssi = param;
+ break;
+ case DFS_PARAM_INBAND:
+ pe.pe_inband = param;
+ break;
+ case DFS_PARAM_RELPWR:
+ pe.pe_relpwr = param;
+ break;
+ case DFS_PARAM_RELSTEP:
+ pe.pe_relstep = param;
+ break;
+ case DFS_PARAM_MAXLEN:
+ pe.pe_maxlen = param;
+ break;
+ case DFS_PARAM_USEFIR128:
+ pe.pe_usefir128 = param;
+ break;
+ case DFS_PARAM_BLOCKRADAR:
+ pe.pe_blockradar = param;
+ break;
+ case DFS_PARAM_MAXRSSI_EN:
+ pe.pe_enmaxrssi = param;
+ break;
+ case DFS_PARAM_EN_EXTCH:
+ pe.pe_extchannel = param;
+ break;
+ case DFS_PARAM_RELPWR_EN:
+ pe.pe_enrelpwr = param;
+ break;
+ case DFS_PARAM_RELSTEP_EN:
+ pe.pe_en_relstep_check = param;
+ break;
+ }
+
+ radar->atd.ad_id = DFS_SET_THRESH | ATH_DIAG_IN;
+ radar->atd.ad_out_data = NULL;
+ radar->atd.ad_out_size = 0;
+ radar->atd.ad_in_data = (caddr_t) &pe;
+ radar->atd.ad_in_size = sizeof(HAL_PHYERR_PARAM);
+ if (ioctl(radar->s, SIOCGATHPHYERR, &radar->atd) < 0)
+ err(1, radar->atd.ad_name);
+}
+
+static void
+radar_get(struct radarhandler *radar)
+{
+ HAL_PHYERR_PARAM pe;
+
+ radar->atd.ad_id = DFS_GET_THRESH | ATH_DIAG_DYN;
+ memset(&pe, 0, sizeof(pe));
+
+ radar->atd.ad_in_data = NULL;
+ radar->atd.ad_in_size = 0;
+ radar->atd.ad_out_data = (caddr_t) &pe;
+ radar->atd.ad_out_size = sizeof(pe);
+
+ if (ioctl(radar->s, SIOCGATHPHYERR, &radar->atd) < 0)
+ err(1, radar->atd.ad_name);
+
+ printf("Radar parameters (raw):\n");
+ printf(" pe_enabled: %d\n", pe.pe_enabled);
+ printf(" pe_firpwr: %d\n", pe.pe_firpwr);
+ printf(" pe_rrssi: %d\n", pe.pe_rrssi);
+ printf(" pe_height: %d\n", pe.pe_height);
+ printf(" pe_prssi: %d\n", pe.pe_prssi);
+ printf(" pe_inband: %d\n", pe.pe_inband);
+ printf(" pe_relpwr: %d\n", pe.pe_relpwr);
+ printf(" pe_relstep: %d\n", pe.pe_relstep);
+ printf(" pe_maxlen: %d\n", pe.pe_maxlen);
+ printf(" pe_usefir128: %d\n", pe.pe_usefir128);
+ printf(" pe_blockradar: %d\n", pe.pe_blockradar);
+ printf(" pe_enmaxrssi: %d\n", pe.pe_enmaxrssi);
+ printf(" pe_extchannel: %d\n", pe.pe_extchannel);
+ printf(" pe_enrelpwr: %d\n", pe.pe_enrelpwr);
+ printf(" pe_en_relstep_check: %d\n", pe.pe_en_relstep_check);
+}
+
+static int
+radar_set_param(struct radarhandler *radar, const char *param,
+ const char *val)
+{
+ int v;
+
+ v = atoi(val);
+
+ if (strcmp(param, "enabled") == 0) {
+ radarset(radar, DFS_PARAM_ENABLE, v);
+ } else if (strcmp(param, "firpwr") == 0) {
+ radarset(radar, DFS_PARAM_FIRPWR, v);
+ } else if (strcmp(param, "rrssi") == 0) {
+ radarset(radar, DFS_PARAM_RRSSI, v);
+ } else if (strcmp(param, "height") == 0) {
+ radarset(radar, DFS_PARAM_HEIGHT, v);
+ } else if (strcmp(param, "prssi") == 0) {
+ radarset(radar, DFS_PARAM_PRSSI, v);
+ } else if (strcmp(param, "inband") == 0) {
+ radarset(radar, DFS_PARAM_INBAND, v);
+ } else if (strcmp(param, "relpwr") == 0) {
+ radarset(radar, DFS_PARAM_RELPWR, v);
+ } else if (strcmp(param, "relstep") == 0) {
+ radarset(radar, DFS_PARAM_RELSTEP, v);
+ } else if (strcmp(param, "maxlen") == 0) {
+ radarset(radar, DFS_PARAM_MAXLEN, v);
+ } else if (strcmp(param, "usefir128") == 0) {
+ radarset(radar, DFS_PARAM_USEFIR128, v);
+ } else if (strcmp(param, "blockradar") == 0) {
+ radarset(radar, DFS_PARAM_BLOCKRADAR, v);
+ } else if (strcmp(param, "enmaxrssi") == 0) {
+ radarset(radar, DFS_PARAM_MAXRSSI_EN, v);
+ } else if (strcmp(param, "extchannel") == 0) {
+ radarset(radar, DFS_PARAM_EN_EXTCH, v);
+ } else if (strcmp(param, "enrelpwr") == 0) {
+ radarset(radar, DFS_PARAM_RELPWR_EN, v);
+ } else if (strcmp(param, "en_relstep_check") == 0) {
+ radarset(radar, DFS_PARAM_RELSTEP_EN, v);
+ } else {
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+usage(const char *progname)
+{
+ printf("Usage:\n");
+ printf("\t%s: [-i <interface>] <cmd> (<arg>)\n", progname);
+ printf("\t%s: [-h]\n", progname);
+ printf("\n");
+ printf("Valid commands:\n");
+ printf("\tget:\t\tGet current radar parameters\n");
+ printf("\tset <param> <value>:\t\tSet radar parameter\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct radarhandler radar;
+ const char *devname = ATH_DEFAULT;
+ const char *progname = argv[0];
+
+ memset(&radar, 0, sizeof(radar));
+
+ /* Parse command line options */
+ if (argc >= 2 && strcmp(argv[1], "-h") == 0) {
+ usage(progname);
+ exit(0);
+ }
+ if (argc >= 2 && strcmp(argv[1], "-?") == 0) {
+ usage(progname);
+ exit(0);
+ }
+
+ if (argc >= 2 && strcmp(argv[1], "-i") == 0) {
+ if (argc == 2) {
+ usage(progname);
+ exit(127);
+ }
+ devname = argv[2];
+ argc -= 2; argv += 2;
+ }
+
+ /* At this point we require at least one command */
+ if (argc == 1) {
+ usage(progname);
+ exit(127);
+ }
+
+ if (radar_opendev(&radar, devname) == 0)
+ exit(127);
+
+ if (strcasecmp(argv[1], "get") == 0) {
+ radar_get(&radar);
+ } else if (strcasecmp(argv[1], "set") == 0) {
+ if (argc < 4) {
+ usage(progname);
+ exit(127);
+ }
+ if (radar_set_param(&radar, argv[2], argv[3]) == 0) {
+ usage(progname);
+ exit(127);
+ }
+ } else {
+ usage(progname);
+ exit(127);
+ }
+
+ /* wrap up */
+ radar_closedev(&radar);
+ exit(0);
+}
diff --git a/tools/tools/ath/athrd/Makefile b/tools/tools/ath/athrd/Makefile
new file mode 100644
index 000000000000..352d712e621a
--- /dev/null
+++ b/tools/tools/ath/athrd/Makefile
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal
+
+PROG= athrd
+
+SRCS= athrd.c ah_regdomain.c opt_ah.h
+
+CLEANFILES+= opt_ah.h
+
+CFLAGS+= -fno-inline
+
+.include <../Makefile.inc>
+
+MAN= athrd.1
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athrd/athrd.1 b/tools/tools/ath/athrd/athrd.1
new file mode 100644
index 000000000000..59c86f98c56d
--- /dev/null
+++ b/tools/tools/ath/athrd/athrd.1
@@ -0,0 +1,172 @@
+.\"-
+.\" Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
+.\" All rights reserved.
+.\""
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer,
+.\" without modification.
+.\" 2. Redistributions in binary form must reproduce at minimum a disclaimer
+.\" similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+.\" redistribution must be conditioned upon including a substantially
+.\" similar Disclaimer requirement for further binary redistribution.
+.\"
+.\" NO WARRANTY
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+.\" THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+.\" OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" THE POSSIBILITY OF SUCH DAMAGES.
+.\"
+.\" $FreeBSD$
+.\"/
+.Dd January 27, 2009
+.Dt ATHRD 1
+.Os
+.Sh NAME
+.Nm athrd
+.Nd list channels and transmit power for a country/regulatory domain
+.Sh SYNOPSIS
+.Nm
+.Op Fl aedlpcfr4ABGT
+.Op Fl m Ar mode
+.Bk
+.Op Ar country
+.Ek
+.Sh DESCRIPTION
+.Nm
+displays the list of frequencies and the associated maximum transmit
+power permitted within a regulatory domain and/or country.
+.Pp
+If no command line options are given, a default country (\c
+.Ql US )
+is used.
+Country and regulatory names are case insensitive.
+.Pp
+The following options are available:
+.Bl -tag -width indent
+.It Fl a
+By default
+.Nm
+will display B channels only if they are not also marked as available for
+use as G channels and similary for A and T channels.
+With this option
+.Nm
+will list all channels.
+.It Fl e
+Calculate channels not assuming extended channel mode.
+.It Fl d
+Enabling debugging in the HAL code that calculates the available channels
+and transmit power values.
+.It Fl l
+Provide a list of all known country and regulatory domain names.
+.It Fl m Ar mode
+Calculate channels and transmit power for operation in
+.Ql mode ;
+one of
+.Ql station ,
+.Ql ibss ,
+.Ql monitor ,
+and
+.Ql ap
+(or the first two letters).
+.It Fl p
+Mark passive scan channels with lower case letters and active
+scan channels with upper case letters.
+.It Fl r
+Mark channels that require DFS with a
+.Ql * .
+.It Fl 4
+Mark channels that have a 4ms packet limit with a
+.Ql 4 .
+.It Fl c
+Display IEEE channel numbers instead of frequencies.
+.It Fl f
+Display frequencies (default).
+.It Fl A
+Display only 11A channels.
+.It Fl B
+Display only 11B channels.
+.It Fl G
+Display only 11G channels.
+.It Fl T
+Display only Turbo channels.
+.El
+.Sh EXAMPLES
+The following demonstrates how to list the permissible frequencies
+and maximum transport power per channel for use in Spain:
+.Pp
+.nf
+tubby% athrd es
+\&
+SPAIN (ES, 0x2d4, 724) NULL1_WORLD (0x3, 3)
+2412G 14.0 2417G 14.0 2422G 14.0 2427G 17.0 2432G 14.0 2437G 17.0
+2442G 14.0 2447G 17.0 2452G 17.0 2457G 14.0 2462G 17.0
+.fi
+.Pp
+Each frequency has a suffix that is one of:
+.Ql G ,
+.Ql B ,
+.Ql A ,
+or
+.Ql T
+according to whether the channel is usable with 802.11g, 802.11b,
+802.11a, or Atheros Turbo mode.
+All channels listed as
+.Ql G
+are also usable in
+.Ql B .
+Likewise, all channels listed as
+.Ql A
+are usable in
+.Ql T .
+Channels listed as
+.Ql B
+or
+.Ql T
+are only usable in those modes.
+(Note that when the
+.Fl p
+option is specified passive scan channels are marked with a lower case
+.Ql g ,
+.Ql b ,
+.Ql a ,
+or
+.Ql t .)
+The transmit power is given in units of dbM.
+.Sh DIAGNOSTICS
+Various diagnostics about unknown regulatory domains and/or country
+codes may be encountered.
+Use the
+.Fl l
+option for a list of valid names.
+.Sh SEE ALSO
+.Xr ath 4 ,
+.Xr ath_hal 4
+.Sh STANDARDS
+Lots belong here.
+.Sh NOTES
+.Nm
+use the HAL to calculate the set of channels.
+The transmit power calculations are done by emulating
+how the HAL works.
+Because
+.Nm
+does not
+read the actual EEPROM contents from a device this emulation may lag
+behind current practice.
+.Sh BUGS
+The HAL reset logic should be used to calculate the transmit power
+for each channel instead of using a separate copy of the code.
+The data presented by
+.Nm
+are the expected values; for compliance testing one must measure the actual
+operation of the driver and the HAL.
diff --git a/tools/tools/ath/athrd/athrd.c b/tools/tools/ath/athrd/athrd.c
new file mode 100644
index 000000000000..c4fc40c63714
--- /dev/null
+++ b/tools/tools/ath/athrd/athrd.c
@@ -0,0 +1,1673 @@
+/*-
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+
+#include "ah.h"
+
+#include <net80211/_ieee80211.h>
+#include <net80211/ieee80211_regdomain.h>
+
+#include "ah_internal.h"
+#include "ah_eeprom_v3.h" /* XXX */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+
+int ath_hal_debug = 0;
+HAL_CTRY_CODE cc = CTRY_DEFAULT;
+HAL_REG_DOMAIN rd = 169; /* FCC */
+HAL_BOOL Amode = 1;
+HAL_BOOL Bmode = 1;
+HAL_BOOL Gmode = 1;
+HAL_BOOL HT20mode = 1;
+HAL_BOOL HT40mode = 1;
+HAL_BOOL turbo5Disable = AH_FALSE;
+HAL_BOOL turbo2Disable = AH_FALSE;
+
+u_int16_t _numCtls = 8;
+u_int16_t _ctl[32] =
+ { 0x10, 0x13, 0x40, 0x30, 0x11, 0x31, 0x12, 0x32 };
+RD_EDGES_POWER _rdEdgesPower[NUM_EDGES*NUM_CTLS] = {
+ { 5180, 28, 0 }, /* 0x10 */
+ { 5240, 60, 0 },
+ { 5260, 36, 0 },
+ { 5320, 27, 0 },
+ { 5745, 36, 0 },
+ { 5765, 36, 0 },
+ { 5805, 36, 0 },
+ { 5825, 36, 0 },
+
+ { 5210, 28, 0 }, /* 0x13 */
+ { 5250, 28, 0 },
+ { 5290, 30, 0 },
+ { 5760, 36, 0 },
+ { 5800, 36, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+
+ { 5170, 60, 0 }, /* 0x40 */
+ { 5230, 60, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+
+ { 5180, 33, 0 }, /* 0x30 */
+ { 5320, 33, 0 },
+ { 5500, 34, 0 },
+ { 5700, 34, 0 },
+ { 5745, 35, 0 },
+ { 5765, 35, 0 },
+ { 5785, 35, 0 },
+ { 5825, 35, 0 },
+
+ { 2412, 36, 0 }, /* 0x11 */
+ { 2417, 36, 0 },
+ { 2422, 36, 0 },
+ { 2432, 36, 0 },
+ { 2442, 36, 0 },
+ { 2457, 36, 0 },
+ { 2467, 36, 0 },
+ { 2472, 36, 0 },
+
+ { 2412, 36, 0 }, /* 0x31 */
+ { 2417, 36, 0 },
+ { 2422, 36, 0 },
+ { 2432, 36, 0 },
+ { 2442, 36, 0 },
+ { 2457, 36, 0 },
+ { 2467, 36, 0 },
+ { 2472, 36, 0 },
+
+ { 2412, 36, 0 }, /* 0x12 */
+ { 2417, 36, 0 },
+ { 2422, 36, 0 },
+ { 2432, 36, 0 },
+ { 2442, 36, 0 },
+ { 2457, 36, 0 },
+ { 2467, 36, 0 },
+ { 2472, 36, 0 },
+
+ { 2412, 28, 0 }, /* 0x32 */
+ { 2417, 28, 0 },
+ { 2422, 28, 0 },
+ { 2432, 28, 0 },
+ { 2442, 28, 0 },
+ { 2457, 28, 0 },
+ { 2467, 28, 0 },
+ { 2472, 28, 0 },
+};
+
+u_int16_t turbo2WMaxPower5 = 32;
+u_int16_t turbo2WMaxPower2;
+int8_t antennaGainMax[2] = { 0, 0 }; /* XXX */
+int eeversion = AR_EEPROM_VER3_1;
+TRGT_POWER_ALL_MODES tpow = {
+ 8, {
+ { 22, 24, 28, 32, 5180 },
+ { 22, 24, 28, 32, 5200 },
+ { 22, 24, 28, 32, 5320 },
+ { 26, 30, 34, 34, 5500 },
+ { 26, 30, 34, 34, 5700 },
+ { 20, 30, 34, 36, 5745 },
+ { 20, 30, 34, 36, 5825 },
+ { 20, 30, 34, 36, 5850 },
+ },
+ 2, {
+ { 23, 27, 31, 34, 2412 },
+ { 23, 27, 31, 34, 2447 },
+ },
+ 2, {
+ { 36, 36, 36, 36, 2412 },
+ { 36, 36, 36, 36, 2484 },
+ }
+};
+#define numTargetPwr_11a tpow.numTargetPwr_11a
+#define trgtPwr_11a tpow.trgtPwr_11a
+#define numTargetPwr_11g tpow.numTargetPwr_11g
+#define trgtPwr_11g tpow.trgtPwr_11g
+#define numTargetPwr_11b tpow.numTargetPwr_11b
+#define trgtPwr_11b tpow.trgtPwr_11b
+
+static HAL_BOOL
+getChannelEdges(struct ath_hal *ah, u_int16_t flags, u_int16_t *low, u_int16_t *high)
+{
+ struct ath_hal_private *ahp = AH_PRIVATE(ah);
+ HAL_CAPABILITIES *pCap = &ahp->ah_caps;
+
+ if (flags & IEEE80211_CHAN_5GHZ) {
+ *low = pCap->halLow5GhzChan;
+ *high = pCap->halHigh5GhzChan;
+ return AH_TRUE;
+ }
+ if (flags & IEEE80211_CHAN_2GHZ) {
+ *low = pCap->halLow2GhzChan;
+ *high = pCap->halHigh2GhzChan;
+ return AH_TRUE;
+ }
+ return AH_FALSE;
+}
+
+static u_int
+getWirelessModes(struct ath_hal *ah)
+{
+ u_int mode = 0;
+
+ if (Amode) {
+ mode = HAL_MODE_11A;
+ if (!turbo5Disable)
+ mode |= HAL_MODE_TURBO;
+ }
+ if (Bmode)
+ mode |= HAL_MODE_11B;
+ if (Gmode) {
+ mode |= HAL_MODE_11G;
+ if (!turbo2Disable)
+ mode |= HAL_MODE_108G;
+ }
+ if (HT20mode)
+ mode |= HAL_MODE_11NG_HT20|HAL_MODE_11NA_HT20;
+ if (HT40mode)
+ mode |= HAL_MODE_11NG_HT40PLUS|HAL_MODE_11NA_HT40PLUS
+ | HAL_MODE_11NG_HT40MINUS|HAL_MODE_11NA_HT40MINUS
+ ;
+ return mode;
+}
+
+/* Enumerated Regulatory Domain Information 8 bit values indicate that
+ * the regdomain is really a pair of unitary regdomains. 12 bit values
+ * are the real unitary regdomains and are the only ones which have the
+ * frequency bitmasks and flags set.
+ */
+
+enum EnumRd {
+ /*
+ * The following regulatory domain definitions are
+ * found in the EEPROM. Each regulatory domain
+ * can operate in either a 5GHz or 2.4GHz wireless mode or
+ * both 5GHz and 2.4GHz wireless modes.
+ * In general, the value holds no special
+ * meaning and is used to decode into either specific
+ * 2.4GHz or 5GHz wireless mode for that particular
+ * regulatory domain.
+ */
+ NO_ENUMRD = 0x00,
+ NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */
+ NULL1_ETSIB = 0x07, /* Israel */
+ NULL1_ETSIC = 0x08,
+ FCC1_FCCA = 0x10, /* USA */
+ FCC1_WORLD = 0x11, /* Hong Kong */
+ FCC4_FCCA = 0x12, /* USA - Public Safety */
+
+ FCC2_FCCA = 0x20, /* Canada */
+ FCC2_WORLD = 0x21, /* Australia & HK */
+ FCC2_ETSIC = 0x22,
+ FRANCE_RES = 0x31, /* Legacy France for OEM */
+ FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */
+ FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */
+
+ ETSI1_WORLD = 0x37,
+ ETSI3_ETSIA = 0x32, /* France (optional) */
+ ETSI2_WORLD = 0x35, /* Hungary & others */
+ ETSI3_WORLD = 0x36, /* France & others */
+ ETSI4_WORLD = 0x30,
+ ETSI4_ETSIC = 0x38,
+ ETSI5_WORLD = 0x39,
+ ETSI6_WORLD = 0x34, /* Bulgaria */
+ ETSI_RESERVED = 0x33, /* Reserved (Do not used) */
+
+ MKK1_MKKA = 0x40, /* Japan (JP1) */
+ MKK1_MKKB = 0x41, /* Japan (JP0) */
+ APL4_WORLD = 0x42, /* Singapore */
+ MKK2_MKKA = 0x43, /* Japan with 4.9G channels */
+ APL_RESERVED = 0x44, /* Reserved (Do not used) */
+ APL2_WORLD = 0x45, /* Korea */
+ APL2_APLC = 0x46,
+ APL3_WORLD = 0x47,
+ MKK1_FCCA = 0x48, /* Japan (JP1-1) */
+ APL2_APLD = 0x49, /* Korea with 2.3G channels */
+ MKK1_MKKA1 = 0x4A, /* Japan (JE1) */
+ MKK1_MKKA2 = 0x4B, /* Japan (JE2) */
+ MKK1_MKKC = 0x4C, /* Japan (MKK1_MKKA,except Ch14) */
+
+ APL3_FCCA = 0x50,
+ APL1_WORLD = 0x52, /* Latin America */
+ APL1_FCCA = 0x53,
+ APL1_APLA = 0x54,
+ APL1_ETSIC = 0x55,
+ APL2_ETSIC = 0x56, /* Venezuela */
+ APL5_WORLD = 0x58, /* Chile */
+ APL6_WORLD = 0x5B, /* Singapore */
+ APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */
+ APL8_WORLD = 0x5D, /* Malaysia 5GHz */
+ APL9_WORLD = 0x5E, /* Korea 5GHz */
+
+ /*
+ * World mode SKUs
+ */
+ WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */
+ WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */
+ WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */
+ WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */
+ WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */
+ WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */
+
+ WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */
+ WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */
+ EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */
+
+ WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */
+ WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */
+
+ MKK3_MKKB = 0x80, /* Japan UNI-1 even + MKKB */
+ MKK3_MKKA2 = 0x81, /* Japan UNI-1 even + MKKA2 */
+ MKK3_MKKC = 0x82, /* Japan UNI-1 even + MKKC */
+
+ MKK4_MKKB = 0x83, /* Japan UNI-1 even + UNI-2 + MKKB */
+ MKK4_MKKA2 = 0x84, /* Japan UNI-1 even + UNI-2 + MKKA2 */
+ MKK4_MKKC = 0x85, /* Japan UNI-1 even + UNI-2 + MKKC */
+
+ MKK5_MKKB = 0x86, /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */
+ MKK5_MKKA2 = 0x87, /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */
+ MKK5_MKKC = 0x88, /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */
+
+ MKK6_MKKB = 0x89, /* Japan UNI-1 even + UNI-1 odd MKKB */
+ MKK6_MKKA2 = 0x8A, /* Japan UNI-1 even + UNI-1 odd + MKKA2 */
+ MKK6_MKKC = 0x8B, /* Japan UNI-1 even + UNI-1 odd + MKKC */
+
+ MKK7_MKKB = 0x8C, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */
+ MKK7_MKKA2 = 0x8D, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */
+ MKK7_MKKC = 0x8E, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */
+
+ MKK8_MKKB = 0x8F, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */
+ MKK8_MKKA2 = 0x90, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */
+ MKK8_MKKC = 0x91, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */
+
+ /* Following definitions are used only by s/w to map old
+ * Japan SKUs.
+ */
+ MKK3_MKKA = 0xF0, /* Japan UNI-1 even + MKKA */
+ MKK3_MKKA1 = 0xF1, /* Japan UNI-1 even + MKKA1 */
+ MKK3_FCCA = 0xF2, /* Japan UNI-1 even + FCCA */
+ MKK4_MKKA = 0xF3, /* Japan UNI-1 even + UNI-2 + MKKA */
+ MKK4_MKKA1 = 0xF4, /* Japan UNI-1 even + UNI-2 + MKKA1 */
+ MKK4_FCCA = 0xF5, /* Japan UNI-1 even + UNI-2 + FCCA */
+ MKK9_MKKA = 0xF6, /* Japan UNI-1 even + 4.9GHz */
+ MKK10_MKKA = 0xF7, /* Japan UNI-1 even + UNI-2 + 4.9GHz */
+
+ /*
+ * Regulator domains ending in a number (e.g. APL1,
+ * MK1, ETSI4, etc) apply to 5GHz channel and power
+ * information. Regulator domains ending in a letter
+ * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and
+ * power information.
+ */
+ APL1 = 0x0150, /* LAT & Asia */
+ APL2 = 0x0250, /* LAT & Asia */
+ APL3 = 0x0350, /* Taiwan */
+ APL4 = 0x0450, /* Jordan */
+ APL5 = 0x0550, /* Chile */
+ APL6 = 0x0650, /* Singapore */
+ APL8 = 0x0850, /* Malaysia */
+ APL9 = 0x0950, /* Korea (South) ROC 3 */
+
+ ETSI1 = 0x0130, /* Europe & others */
+ ETSI2 = 0x0230, /* Europe & others */
+ ETSI3 = 0x0330, /* Europe & others */
+ ETSI4 = 0x0430, /* Europe & others */
+ ETSI5 = 0x0530, /* Europe & others */
+ ETSI6 = 0x0630, /* Europe & others */
+ ETSIA = 0x0A30, /* France */
+ ETSIB = 0x0B30, /* Israel */
+ ETSIC = 0x0C30, /* Latin America */
+
+ FCC1 = 0x0110, /* US & others */
+ FCC2 = 0x0120, /* Canada, Australia & New Zealand */
+ FCC3 = 0x0160, /* US w/new middle band & DFS */
+ FCC4 = 0x0165, /* US Public Safety */
+ FCCA = 0x0A10,
+
+ APLD = 0x0D50, /* South Korea */
+
+ MKK1 = 0x0140, /* Japan (UNI-1 odd)*/
+ MKK2 = 0x0240, /* Japan (4.9 GHz + UNI-1 odd) */
+ MKK3 = 0x0340, /* Japan (UNI-1 even) */
+ MKK4 = 0x0440, /* Japan (UNI-1 even + UNI-2) */
+ MKK5 = 0x0540, /* Japan (UNI-1 even + UNI-2 + mid-band) */
+ MKK6 = 0x0640, /* Japan (UNI-1 odd + UNI-1 even) */
+ MKK7 = 0x0740, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */
+ MKK8 = 0x0840, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */
+ MKK9 = 0x0940, /* Japan (UNI-1 even + 4.9 GHZ) */
+ MKK10 = 0x0B40, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
+ MKKA = 0x0A40, /* Japan */
+ MKKC = 0x0A50,
+
+ NULL1 = 0x0198,
+ WORLD = 0x0199,
+ DEBUG_REG_DMN = 0x01ff,
+};
+#define DEF_REGDMN FCC1_FCCA
+
+static struct {
+ const char *name;
+ HAL_REG_DOMAIN rd;
+} domains[] = {
+#define D(_x) { #_x, _x }
+ D(NO_ENUMRD),
+ D(NULL1_WORLD), /* For 11b-only countries (no 11a allowed) */
+ D(NULL1_ETSIB), /* Israel */
+ D(NULL1_ETSIC),
+ D(FCC1_FCCA), /* USA */
+ D(FCC1_WORLD), /* Hong Kong */
+ D(FCC4_FCCA), /* USA - Public Safety */
+
+ D(FCC2_FCCA), /* Canada */
+ D(FCC2_WORLD), /* Australia & HK */
+ D(FCC2_ETSIC),
+ D(FRANCE_RES), /* Legacy France for OEM */
+ D(FCC3_FCCA),
+ D(FCC3_WORLD),
+
+ D(ETSI1_WORLD),
+ D(ETSI3_ETSIA), /* France (optional) */
+ D(ETSI2_WORLD), /* Hungary & others */
+ D(ETSI3_WORLD), /* France & others */
+ D(ETSI4_WORLD),
+ D(ETSI4_ETSIC),
+ D(ETSI5_WORLD),
+ D(ETSI6_WORLD), /* Bulgaria */
+ D(ETSI_RESERVED), /* Reserved (Do not used) */
+
+ D(MKK1_MKKA), /* Japan (JP1) */
+ D(MKK1_MKKB), /* Japan (JP0) */
+ D(APL4_WORLD), /* Singapore */
+ D(MKK2_MKKA), /* Japan with 4.9G channels */
+ D(APL_RESERVED), /* Reserved (Do not used) */
+ D(APL2_WORLD), /* Korea */
+ D(APL2_APLC),
+ D(APL3_WORLD),
+ D(MKK1_FCCA), /* Japan (JP1-1) */
+ D(APL2_APLD), /* Korea with 2.3G channels */
+ D(MKK1_MKKA1), /* Japan (JE1) */
+ D(MKK1_MKKA2), /* Japan (JE2) */
+ D(MKK1_MKKC),
+
+ D(APL3_FCCA),
+ D(APL1_WORLD), /* Latin America */
+ D(APL1_FCCA),
+ D(APL1_APLA),
+ D(APL1_ETSIC),
+ D(APL2_ETSIC), /* Venezuela */
+ D(APL5_WORLD), /* Chile */
+ D(APL6_WORLD), /* Singapore */
+ D(APL7_FCCA), /* Taiwan 5.47 Band */
+ D(APL8_WORLD), /* Malaysia 5GHz */
+ D(APL9_WORLD), /* Korea 5GHz */
+
+ D(WOR0_WORLD), /* World0 (WO0 SKU) */
+ D(WOR1_WORLD), /* World1 (WO1 SKU) */
+ D(WOR2_WORLD), /* World2 (WO2 SKU) */
+ D(WOR3_WORLD), /* World3 (WO3 SKU) */
+ D(WOR4_WORLD), /* World4 (WO4 SKU) */
+ D(WOR5_ETSIC), /* World5 (WO5 SKU) */
+
+ D(WOR01_WORLD), /* World0-1 (WW0-1 SKU) */
+ D(WOR02_WORLD), /* World0-2 (WW0-2 SKU) */
+ D(EU1_WORLD),
+
+ D(WOR9_WORLD), /* World9 (WO9 SKU) */
+ D(WORA_WORLD), /* WorldA (WOA SKU) */
+
+ D(MKK3_MKKB), /* Japan UNI-1 even + MKKB */
+ D(MKK3_MKKA2), /* Japan UNI-1 even + MKKA2 */
+ D(MKK3_MKKC), /* Japan UNI-1 even + MKKC */
+
+ D(MKK4_MKKB), /* Japan UNI-1 even + UNI-2 + MKKB */
+ D(MKK4_MKKA2), /* Japan UNI-1 even + UNI-2 + MKKA2 */
+ D(MKK4_MKKC), /* Japan UNI-1 even + UNI-2 + MKKC */
+
+ D(MKK5_MKKB), /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */
+ D(MKK5_MKKA2), /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */
+ D(MKK5_MKKC), /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */
+
+ D(MKK6_MKKB), /* Japan UNI-1 even + UNI-1 odd MKKB */
+ D(MKK6_MKKA2), /* Japan UNI-1 even + UNI-1 odd + MKKA2 */
+ D(MKK6_MKKC), /* Japan UNI-1 even + UNI-1 odd + MKKC */
+
+ D(MKK7_MKKB), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */
+ D(MKK7_MKKA2), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */
+ D(MKK7_MKKC), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */
+
+ D(MKK8_MKKB), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */
+ D(MKK8_MKKA2), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */
+ D(MKK8_MKKC), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */
+
+ D(MKK3_MKKA), /* Japan UNI-1 even + MKKA */
+ D(MKK3_MKKA1), /* Japan UNI-1 even + MKKA1 */
+ D(MKK3_FCCA), /* Japan UNI-1 even + FCCA */
+ D(MKK4_MKKA), /* Japan UNI-1 even + UNI-2 + MKKA */
+ D(MKK4_MKKA1), /* Japan UNI-1 even + UNI-2 + MKKA1 */
+ D(MKK4_FCCA), /* Japan UNI-1 even + UNI-2 + FCCA */
+ D(MKK9_MKKA), /* Japan UNI-1 even + 4.9GHz */
+ D(MKK10_MKKA), /* Japan UNI-1 even + UNI-2 + 4.9GHz */
+
+ D(APL1), /* LAT & Asia */
+ D(APL2), /* LAT & Asia */
+ D(APL3), /* Taiwan */
+ D(APL4), /* Jordan */
+ D(APL5), /* Chile */
+ D(APL6), /* Singapore */
+ D(APL8), /* Malaysia */
+ D(APL9), /* Korea (South) ROC 3 */
+
+ D(ETSI1), /* Europe & others */
+ D(ETSI2), /* Europe & others */
+ D(ETSI3), /* Europe & others */
+ D(ETSI4), /* Europe & others */
+ D(ETSI5), /* Europe & others */
+ D(ETSI6), /* Europe & others */
+ D(ETSIA), /* France */
+ D(ETSIB), /* Israel */
+ D(ETSIC), /* Latin America */
+
+ D(FCC1), /* US & others */
+ D(FCC2),
+ D(FCC3), /* US w/new middle band & DFS */
+ D(FCC4), /* US Public Safety */
+ D(FCCA),
+
+ D(APLD), /* South Korea */
+
+ D(MKK1), /* Japan (UNI-1 odd)*/
+ D(MKK2), /* Japan (4.9 GHz + UNI-1 odd) */
+ D(MKK3), /* Japan (UNI-1 even) */
+ D(MKK4), /* Japan (UNI-1 even + UNI-2) */
+ D(MKK5), /* Japan (UNI-1 even + UNI-2 + mid-band) */
+ D(MKK6), /* Japan (UNI-1 odd + UNI-1 even) */
+ D(MKK7), /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */
+ D(MKK8), /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */
+ D(MKK9), /* Japan (UNI-1 even + 4.9 GHZ) */
+ D(MKK10), /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
+ D(MKKA), /* Japan */
+ D(MKKC),
+
+ D(NULL1),
+ D(WORLD),
+ D(DEBUG_REG_DMN),
+#undef D
+};
+
+static HAL_BOOL
+rdlookup(const char *name, HAL_REG_DOMAIN *rd)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(domains); i++)
+ if (strcasecmp(domains[i].name, name) == 0) {
+ *rd = domains[i].rd;
+ return AH_TRUE;
+ }
+ return AH_FALSE;
+#undef N
+}
+
+static const char *
+getrdname(HAL_REG_DOMAIN rd)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(domains); i++)
+ if (domains[i].rd == rd)
+ return domains[i].name;
+ return NULL;
+#undef N
+}
+
+static void
+rdlist()
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ printf("\nRegulatory domains:\n\n");
+ for (i = 0; i < N(domains); i++)
+ printf("%-15s%s", domains[i].name,
+ ((i+1)%5) == 0 ? "\n" : "");
+ printf("\n");
+#undef N
+}
+
+typedef struct {
+ HAL_CTRY_CODE countryCode;
+ HAL_REG_DOMAIN regDmnEnum;
+ const char* isoName;
+ const char* name;
+} COUNTRY_CODE_TO_ENUM_RD;
+
+/*
+ * Country Code Table to Enumerated RD
+ */
+static COUNTRY_CODE_TO_ENUM_RD allCountries[] = {
+ {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG" },
+ {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET" },
+ {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA" },
+ {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA" },
+ {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA" },
+ {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA" },
+ {CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA" },
+ {CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA" },
+ {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN" },
+ {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN" },
+ {CTRY_BELARUS, NULL1_WORLD, "BY", "BELARUS" },
+ {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM" },
+ {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE" },
+ {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA" },
+ {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL" },
+ {CTRY_BRUNEI_DARUSSALAM,APL1_WORLD,"BN", "BRUNEI DARUSSALAM" },
+ {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA" },
+ {CTRY_CANADA, FCC2_FCCA, "CA", "CANADA" },
+ {CTRY_CHILE, APL6_WORLD, "CL", "CHILE" },
+ {CTRY_CHINA, APL1_WORLD, "CN", "CHINA" },
+ {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA" },
+ {CTRY_COSTA_RICA, NULL1_WORLD, "CR", "COSTA RICA" },
+ {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA" },
+ {CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS" },
+ {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC" },
+ {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK" },
+ {CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA,"DO", "DOMINICAN REPUBLIC" },
+ {CTRY_ECUADOR, NULL1_WORLD, "EC", "ECUADOR" },
+ {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT" },
+ {CTRY_EL_SALVADOR, NULL1_WORLD, "SV", "EL SALVADOR" },
+ {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA" },
+ {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND" },
+ {CTRY_FRANCE, ETSI3_WORLD, "FR", "FRANCE" },
+ {CTRY_FRANCE2, ETSI3_WORLD, "F2", "FRANCE_RES" },
+ {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA" },
+ {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY" },
+ {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE" },
+ {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA" },
+ {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS" },
+ {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG" },
+ {CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY" },
+ {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND" },
+ {CTRY_INDIA, APL6_WORLD, "IN", "INDIA" },
+ {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA" },
+ {CTRY_IRAN, APL1_WORLD, "IR", "IRAN" },
+ {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND" },
+ {CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL" },
+ {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY" },
+ {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN" },
+ {CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1" },
+ {CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2" },
+ {CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3" },
+ {CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4" },
+ {CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5" },
+ {CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6" },
+
+ {CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7" },
+ {CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8" },
+ {CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9" },
+
+ {CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10" },
+ {CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11" },
+ {CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12" },
+
+ {CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13" },
+ {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14" },
+ {CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15" },
+
+ {CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16" },
+ {CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17" },
+ {CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18" },
+
+ {CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19" },
+ {CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20" },
+ {CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21" },
+
+ {CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22" },
+ {CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23" },
+ {CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24" },
+
+ {CTRY_JORDAN, APL4_WORLD, "JO", "JORDAN" },
+ {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN" },
+ {CTRY_KOREA_NORTH, APL2_WORLD, "KP", "NORTH KOREA" },
+ {CTRY_KOREA_ROC, APL2_WORLD, "KR", "KOREA REPUBLIC" },
+ {CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2" },
+ {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3" },
+ {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT" },
+ {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA" },
+ {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON" },
+ {CTRY_LIECHTENSTEIN,ETSI1_WORLD, "LI", "LIECHTENSTEIN" },
+ {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA" },
+ {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG" },
+ {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU" },
+ {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA" },
+ {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA" },
+ {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA" },
+ {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO" },
+ {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO" },
+ {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO" },
+ {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS" },
+ {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND" },
+ {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY" },
+ {CTRY_OMAN, APL6_WORLD, "OM", "OMAN" },
+ {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN" },
+ {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA" },
+ {CTRY_PERU, APL1_WORLD, "PE", "PERU" },
+ {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES" },
+ {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND" },
+ {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL" },
+ {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO" },
+ {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR" },
+ {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA" },
+ {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA" },
+ {CTRY_SAUDI_ARABIA,NULL1_WORLD, "SA", "SAUDI ARABIA" },
+ {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE" },
+ {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC" },
+ {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA" },
+ {CTRY_SOUTH_AFRICA,FCC3_WORLD, "ZA", "SOUTH AFRICA" },
+ {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN" },
+ {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN" },
+ {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND" },
+ {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA" },
+ {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN" },
+ {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND" },
+ {CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD,"TT", "TRINIDAD & TOBAGO" },
+ {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA" },
+ {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY" },
+ {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE" },
+ {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES" },
+ {CTRY_UNITED_KINGDOM, ETSI1_WORLD,"GB", "UNITED KINGDOM" },
+ {CTRY_UNITED_STATES, FCC1_FCCA, "US", "UNITED STATES" },
+ {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS", "UNITED STATES (PUBLIC SAFETY)" },
+ {CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY" },
+ {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN" },
+ {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA" },
+ {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM" },
+ {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN" },
+ {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE" }
+};
+
+static HAL_BOOL
+cclookup(const char *name, HAL_REG_DOMAIN *rd, HAL_CTRY_CODE *cc)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(allCountries); i++)
+ if (strcasecmp(allCountries[i].isoName, name) == 0 ||
+ strcasecmp(allCountries[i].name, name) == 0) {
+ *rd = allCountries[i].regDmnEnum;
+ *cc = allCountries[i].countryCode;
+ return AH_TRUE;
+ }
+ return AH_FALSE;
+#undef N
+}
+
+static const char *
+getccname(HAL_CTRY_CODE cc)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(allCountries); i++)
+ if (allCountries[i].countryCode == cc)
+ return allCountries[i].name;
+ return NULL;
+#undef N
+}
+
+static const char *
+getccisoname(HAL_CTRY_CODE cc)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ for (i = 0; i < N(allCountries); i++)
+ if (allCountries[i].countryCode == cc)
+ return allCountries[i].isoName;
+ return NULL;
+#undef N
+}
+
+static void
+cclist()
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+
+ printf("\nCountry codes:\n");
+ for (i = 0; i < N(allCountries); i++)
+ printf("%2s %-15.15s%s",
+ allCountries[i].isoName,
+ allCountries[i].name,
+ ((i+1)%4) == 0 ? "\n" : " ");
+ printf("\n");
+#undef N
+}
+
+static HAL_BOOL
+setRateTable(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ int16_t tpcScaleReduction, int16_t powerLimit,
+ int16_t *pMinPower, int16_t *pMaxPower);
+
+static void
+calctxpower(struct ath_hal *ah,
+ int nchan, const struct ieee80211_channel *chans,
+ int16_t tpcScaleReduction, int16_t powerLimit, int16_t *txpow)
+{
+ int16_t minpow;
+ int i;
+
+ for (i = 0; i < nchan; i++)
+ if (!setRateTable(ah, &chans[i],
+ tpcScaleReduction, powerLimit, &minpow, &txpow[i])) {
+ printf("unable to set rate table\n");
+ exit(-1);
+ }
+}
+
+int n = 1;
+const char *sep = "";
+int dopassive = 0;
+int showchannels = 0;
+int isdfs = 0;
+int is4ms = 0;
+
+static int
+anychan(const struct ieee80211_channel *chans, int nc, int flag)
+{
+ int i;
+
+ for (i = 0; i < nc; i++)
+ if ((chans[i].ic_flags & flag) != 0)
+ return 1;
+ return 0;
+}
+
+static __inline int
+mapgsm(u_int freq, u_int flags)
+{
+ freq *= 10;
+ if (flags & IEEE80211_CHAN_QUARTER)
+ freq += 5;
+ else if (flags & IEEE80211_CHAN_HALF)
+ freq += 10;
+ else
+ freq += 20;
+ return (freq - 24220) / 5;
+}
+
+static __inline int
+mappsb(u_int freq, u_int flags)
+{
+ return ((freq * 10) + (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
+}
+
+/*
+ * Convert GHz frequency to IEEE channel number.
+ */
+int
+ath_hal_mhz2ieee(struct ath_hal *ah, u_int freq, u_int flags)
+{
+ if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */
+ if (freq == 2484)
+ return 14;
+ if (freq < 2484)
+ return ((int)freq - 2407) / 5;
+ else
+ return 15 + ((freq - 2512) / 20);
+ } else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */
+ if (IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq))
+ return mappsb(freq, flags);
+ else if ((flags & IEEE80211_CHAN_A) && (freq <= 5000))
+ return (freq - 4000) / 5;
+ else
+ return (freq - 5000) / 5;
+ } else { /* either, guess */
+ if (freq == 2484)
+ return 14;
+ if (freq < 2484)
+ return ((int)freq - 2407) / 5;
+ if (freq < 5000) {
+ if (IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq))
+ return mappsb(freq, flags);
+ else if (freq > 4900)
+ return (freq - 4000) / 5;
+ else
+ return 15 + ((freq - 2512) / 20);
+ }
+ return (freq - 5000) / 5;
+ }
+}
+
+#define IEEE80211_IS_CHAN_4MS(_c) \
+ (((_c)->ic_flags & IEEE80211_CHAN_4MSXMIT) != 0)
+
+static void
+dumpchannels(struct ath_hal *ah, int nc,
+ const struct ieee80211_channel *chans, int16_t *txpow)
+{
+ int i;
+
+ for (i = 0; i < nc; i++) {
+ const struct ieee80211_channel *c = &chans[i];
+ int type;
+
+ if (showchannels)
+ printf("%s%3d", sep,
+ ath_hal_mhz2ieee(ah, c->ic_freq, c->ic_flags));
+ else
+ printf("%s%u", sep, c->ic_freq);
+ if (IEEE80211_IS_CHAN_HALF(c))
+ type = 'H';
+ else if (IEEE80211_IS_CHAN_QUARTER(c))
+ type = 'Q';
+ else if (IEEE80211_IS_CHAN_TURBO(c))
+ type = 'T';
+ else if (IEEE80211_IS_CHAN_HT(c))
+ type = 'N';
+ else if (IEEE80211_IS_CHAN_A(c))
+ type = 'A';
+ else if (IEEE80211_IS_CHAN_108G(c))
+ type = 'T';
+ else if (IEEE80211_IS_CHAN_G(c))
+ type = 'G';
+ else
+ type = 'B';
+ if (dopassive && IEEE80211_IS_CHAN_PASSIVE(c))
+ type = tolower(type);
+ if (isdfs && is4ms)
+ printf("%c%c%c %d.%d", type,
+ IEEE80211_IS_CHAN_DFS(c) ? '*' : ' ',
+ IEEE80211_IS_CHAN_4MS(c) ? '4' : ' ',
+ txpow[i]/2, (txpow[i]%2)*5);
+ else if (isdfs)
+ printf("%c%c %d.%d", type,
+ IEEE80211_IS_CHAN_DFS(c) ? '*' : ' ',
+ txpow[i]/2, (txpow[i]%2)*5);
+ else if (is4ms)
+ printf("%c%c %d.%d", type,
+ IEEE80211_IS_CHAN_4MS(c) ? '4' : ' ',
+ txpow[i]/2, (txpow[i]%2)*5);
+ else
+ printf("%c %d.%d", type, txpow[i]/2, (txpow[i]%2)*5);
+ if ((n++ % (showchannels ? 7 : 6)) == 0)
+ sep = "\n";
+ else
+ sep = " ";
+ }
+}
+
+static void
+intersect(struct ieee80211_channel *dst, int16_t *dtxpow, int *nd,
+ const struct ieee80211_channel *src, int16_t *stxpow, int ns)
+{
+ int i = 0, j, k, l;
+ while (i < *nd) {
+ for (j = 0; j < ns && dst[i].ic_freq != src[j].ic_freq; j++)
+ ;
+ if (j < ns && dtxpow[i] == stxpow[j]) {
+ for (k = i+1, l = i; k < *nd; k++, l++)
+ dst[l] = dst[k];
+ (*nd)--;
+ } else
+ i++;
+ }
+}
+
+static void
+usage(const char *progname)
+{
+ printf("usage: %s [-acdefoilpr4ABGT] [-m opmode] [cc | rd]\n", progname);
+ exit(-1);
+}
+
+static HAL_BOOL
+getChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)
+{
+}
+
+static HAL_BOOL
+eepromRead(struct ath_hal *ah, u_int off, u_int16_t *data)
+{
+ /* emulate enough stuff to handle japan channel shift */
+ switch (off) {
+ case AR_EEPROM_VERSION:
+ *data = eeversion;
+ return AH_TRUE;
+ case AR_EEPROM_REG_CAPABILITIES_OFFSET:
+ *data = AR_EEPROM_EEREGCAP_EN_KK_NEW_11A;
+ return AH_TRUE;
+ case AR_EEPROM_REG_CAPABILITIES_OFFSET_PRE4_0:
+ *data = AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0;
+ return AH_TRUE;
+ }
+ return AH_FALSE;
+}
+
+HAL_STATUS
+getCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
+ uint32_t capability, uint32_t *result)
+{
+ const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
+
+ switch (type) {
+ case HAL_CAP_REG_DMN: /* regulatory domain */
+ *result = AH_PRIVATE(ah)->ah_currentRD;
+ return HAL_OK;
+ default:
+ return HAL_EINVAL;
+ }
+}
+
+#define HAL_MODE_HT20 \
+ (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20)
+#define HAL_MODE_HT40 \
+ (HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \
+ HAL_MODE_11NA_HT40PLUS | HAL_MODE_11NA_HT40MINUS)
+#define HAL_MODE_HT (HAL_MODE_HT20 | HAL_MODE_HT40)
+
+int
+main(int argc, char *argv[])
+{
+ static const u_int16_t tpcScaleReductionTable[5] =
+ { 0, 3, 6, 9, MAX_RATE_POWER };
+ struct ath_hal_private ahp;
+ struct ieee80211_channel achans[IEEE80211_CHAN_MAX];
+ int16_t atxpow[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel bchans[IEEE80211_CHAN_MAX];
+ int16_t btxpow[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel gchans[IEEE80211_CHAN_MAX];
+ int16_t gtxpow[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel tchans[IEEE80211_CHAN_MAX];
+ int16_t ttxpow[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel tgchans[IEEE80211_CHAN_MAX];
+ int16_t tgtxpow[IEEE80211_CHAN_MAX];
+ struct ieee80211_channel nchans[IEEE80211_CHAN_MAX];
+ int16_t ntxpow[IEEE80211_CHAN_MAX];
+ int i, na, nb, ng, nt, ntg, nn;
+ HAL_BOOL showall = AH_FALSE;
+ HAL_BOOL extendedChanMode = AH_TRUE;
+ int modes = 0;
+ int16_t tpcReduction, powerLimit;
+ int showdfs = 0;
+ int show4ms = 0;
+
+ memset(&ahp, 0, sizeof(ahp));
+ ahp.ah_getChannelEdges = getChannelEdges;
+ ahp.ah_getWirelessModes = getWirelessModes;
+ ahp.ah_eepromRead = eepromRead;
+ ahp.ah_getChipPowerLimits = getChipPowerLimits;
+ ahp.ah_caps.halWirelessModes = HAL_MODE_ALL;
+ ahp.ah_caps.halLow5GhzChan = 4920;
+ ahp.ah_caps.halHigh5GhzChan = 6100;
+ ahp.ah_caps.halLow2GhzChan = 2312;
+ ahp.ah_caps.halHigh2GhzChan = 2732;
+ ahp.ah_caps.halChanHalfRate = AH_TRUE;
+ ahp.ah_caps.halChanQuarterRate = AH_TRUE;
+ ahp.h.ah_getCapability = getCapability;
+ ahp.ah_opmode = HAL_M_STA;
+
+ tpcReduction = tpcScaleReductionTable[0];
+ powerLimit = MAX_RATE_POWER;
+
+ while ((i = getopt(argc, argv, "acdeflm:pr4ABGhHNT")) != -1)
+ switch (i) {
+ case 'a':
+ showall = AH_TRUE;
+ break;
+ case 'c':
+ showchannels = AH_TRUE;
+ break;
+ case 'd':
+ ath_hal_debug = HAL_DEBUG_ANY;
+ break;
+ case 'e':
+ extendedChanMode = AH_FALSE;
+ break;
+ case 'f':
+ showchannels = AH_FALSE;
+ break;
+ case 'l':
+ cclist();
+ rdlist();
+ exit(0);
+ case 'm':
+ if (strncasecmp(optarg, "sta", 2) == 0)
+ ahp.ah_opmode = HAL_M_STA;
+ else if (strncasecmp(optarg, "ibss", 2) == 0)
+ ahp.ah_opmode = HAL_M_IBSS;
+ else if (strncasecmp(optarg, "adhoc", 2) == 0)
+ ahp.ah_opmode = HAL_M_IBSS;
+ else if (strncasecmp(optarg, "ap", 2) == 0)
+ ahp.ah_opmode = HAL_M_HOSTAP;
+ else if (strncasecmp(optarg, "hostap", 2) == 0)
+ ahp.ah_opmode = HAL_M_HOSTAP;
+ else if (strncasecmp(optarg, "monitor", 2) == 0)
+ ahp.ah_opmode = HAL_M_MONITOR;
+ else
+ usage(argv[0]);
+ break;
+ case 'p':
+ dopassive = 1;
+ break;
+ case 'A':
+ modes |= HAL_MODE_11A;
+ break;
+ case 'B':
+ modes |= HAL_MODE_11B;
+ break;
+ case 'G':
+ modes |= HAL_MODE_11G;
+ break;
+ case 'h':
+ modes |= HAL_MODE_HT20;
+ break;
+ case 'H':
+ modes |= HAL_MODE_HT40;
+ break;
+ case 'N':
+ modes |= HAL_MODE_HT;
+ break;
+ case 'T':
+ modes |= HAL_MODE_TURBO | HAL_MODE_108G;
+ break;
+ case 'r':
+ showdfs = 1;
+ break;
+ case '4':
+ show4ms = 1;
+ break;
+ default:
+ usage(argv[0]);
+ }
+ switch (argc - optind) {
+ case 0:
+ if (!cclookup("US", &rd, &cc)) {
+ printf("%s: unknown country code\n", "US");
+ exit(-1);
+ }
+ break;
+ case 1: /* cc/regdomain */
+ if (!cclookup(argv[optind], &rd, &cc)) {
+ if (!rdlookup(argv[optind], &rd)) {
+ const char* rdname;
+
+ rd = strtoul(argv[optind], NULL, 0);
+ rdname = getrdname(rd);
+ if (rdname == NULL) {
+ printf("%s: unknown country/regulatory "
+ "domain code\n", argv[optind]);
+ exit(-1);
+ }
+ }
+ cc = CTRY_DEFAULT;
+ }
+ break;
+ default: /* regdomain cc */
+ if (!rdlookup(argv[optind], &rd)) {
+ const char* rdname;
+
+ rd = strtoul(argv[optind], NULL, 0);
+ rdname = getrdname(rd);
+ if (rdname == NULL) {
+ printf("%s: unknown country/regulatory "
+ "domain code\n", argv[optind]);
+ exit(-1);
+ }
+ }
+ if (!cclookup(argv[optind+1], &rd, &cc))
+ cc = strtoul(argv[optind+1], NULL, 0);
+ break;
+ }
+ if (cc != CTRY_DEFAULT)
+ printf("\n%s (%s, 0x%x, %u) %s (0x%x, %u)\n",
+ getccname(cc), getccisoname(cc), cc, cc,
+ getrdname(rd), rd, rd);
+ else
+ printf("\n%s (0x%x, %u)\n",
+ getrdname(rd), rd, rd);
+
+ if (modes == 0) {
+ /* NB: no HAL_MODE_HT */
+ modes = HAL_MODE_11A | HAL_MODE_11B |
+ HAL_MODE_11G | HAL_MODE_TURBO | HAL_MODE_108G;
+ }
+ na = nb = ng = nt = ntg = nn = 0;
+ if (modes & HAL_MODE_11G) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, gchans, IEEE80211_CHAN_MAX, &ng,
+ HAL_MODE_11G, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, ng, gchans, tpcReduction, powerLimit, gtxpow);
+ if (showdfs)
+ isdfs |= anychan(gchans, ng, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(gchans, ng, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+ if (modes & HAL_MODE_11B) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, bchans, IEEE80211_CHAN_MAX, &nb,
+ HAL_MODE_11B, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, nb, bchans, tpcReduction, powerLimit, btxpow);
+ if (showdfs)
+ isdfs |= anychan(bchans, nb, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(bchans, nb, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+ if (modes & HAL_MODE_11A) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, achans, IEEE80211_CHAN_MAX, &na,
+ HAL_MODE_11A, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, na, achans, tpcReduction, powerLimit, atxpow);
+ if (showdfs)
+ isdfs |= anychan(achans, na, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(achans, na, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+ if (modes & HAL_MODE_TURBO) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, tchans, IEEE80211_CHAN_MAX, &nt,
+ HAL_MODE_TURBO, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, nt, tchans, tpcReduction, powerLimit, ttxpow);
+ if (showdfs)
+ isdfs |= anychan(tchans, nt, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(tchans, nt, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+ if (modes & HAL_MODE_108G) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, tgchans, IEEE80211_CHAN_MAX, &ntg,
+ HAL_MODE_108G, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, ntg, tgchans, tpcReduction, powerLimit, tgtxpow);
+ if (showdfs)
+ isdfs |= anychan(tgchans, ntg, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(tgchans, ntg, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+ if (modes & HAL_MODE_HT) {
+ ahp.ah_currentRD = rd;
+ if (ath_hal_getchannels(&ahp.h, nchans, IEEE80211_CHAN_MAX, &nn,
+ modes & HAL_MODE_HT, cc, rd, extendedChanMode) == HAL_OK) {
+ calctxpower(&ahp.h, nn, nchans, tpcReduction, powerLimit, ntxpow);
+ if (showdfs)
+ isdfs |= anychan(nchans, nn, IEEE80211_CHAN_DFS);
+ if (show4ms)
+ is4ms |= anychan(nchans, nn, IEEE80211_CHAN_4MSXMIT);
+ }
+ }
+
+ if (!showall) {
+#define CHECKMODES(_modes, _m) ((_modes & (_m)) == (_m))
+ if (CHECKMODES(modes, HAL_MODE_11B|HAL_MODE_11G)) {
+ /* b ^= g */
+ intersect(bchans, btxpow, &nb, gchans, gtxpow, ng);
+ }
+ if (CHECKMODES(modes, HAL_MODE_11A|HAL_MODE_TURBO)) {
+ /* t ^= a */
+ intersect(tchans, ttxpow, &nt, achans, atxpow, na);
+ }
+ if (CHECKMODES(modes, HAL_MODE_11G|HAL_MODE_108G)) {
+ /* tg ^= g */
+ intersect(tgchans, tgtxpow, &ntg, gchans, gtxpow, ng);
+ }
+ if (CHECKMODES(modes, HAL_MODE_11G|HAL_MODE_HT)) {
+ /* g ^= n */
+ intersect(gchans, gtxpow, &ng, nchans, ntxpow, nn);
+ }
+ if (CHECKMODES(modes, HAL_MODE_11A|HAL_MODE_HT)) {
+ /* a ^= n */
+ intersect(achans, atxpow, &na, nchans, ntxpow, nn);
+ }
+#undef CHECKMODES
+ }
+
+ if (modes & HAL_MODE_11G)
+ dumpchannels(&ahp.h, ng, gchans, gtxpow);
+ if (modes & HAL_MODE_11B)
+ dumpchannels(&ahp.h, nb, bchans, btxpow);
+ if (modes & HAL_MODE_11A)
+ dumpchannels(&ahp.h, na, achans, atxpow);
+ if (modes & HAL_MODE_108G)
+ dumpchannels(&ahp.h, ntg, tgchans, tgtxpow);
+ if (modes & HAL_MODE_TURBO)
+ dumpchannels(&ahp.h, nt, tchans, ttxpow);
+ if (modes & HAL_MODE_HT)
+ dumpchannels(&ahp.h, nn, nchans, ntxpow);
+ printf("\n");
+ return (0);
+}
+
+/*
+ * Search a list for a specified value v that is within
+ * EEP_DELTA of the search values. Return the closest
+ * values in the list above and below the desired value.
+ * EEP_DELTA is a factional value; everything is scaled
+ * so only integer arithmetic is used.
+ *
+ * NB: the input list is assumed to be sorted in ascending order
+ */
+static void
+ar5212GetLowerUpperValues(u_int16_t v, u_int16_t *lp, u_int16_t listSize,
+ u_int16_t *vlo, u_int16_t *vhi)
+{
+ u_int32_t target = v * EEP_SCALE;
+ u_int16_t *ep = lp+listSize;
+
+ /*
+ * Check first and last elements for out-of-bounds conditions.
+ */
+ if (target < (u_int32_t)(lp[0] * EEP_SCALE - EEP_DELTA)) {
+ *vlo = *vhi = lp[0];
+ return;
+ }
+ if (target > (u_int32_t)(ep[-1] * EEP_SCALE + EEP_DELTA)) {
+ *vlo = *vhi = ep[-1];
+ return;
+ }
+
+ /* look for value being near or between 2 values in list */
+ for (; lp < ep; lp++) {
+ /*
+ * If value is close to the current value of the list
+ * then target is not between values, it is one of the values
+ */
+ if (abs(lp[0] * EEP_SCALE - target) < EEP_DELTA) {
+ *vlo = *vhi = lp[0];
+ return;
+ }
+ /*
+ * Look for value being between current value and next value
+ * if so return these 2 values
+ */
+ if (target < (u_int32_t)(lp[1] * EEP_SCALE - EEP_DELTA)) {
+ *vlo = lp[0];
+ *vhi = lp[1];
+ return;
+ }
+ }
+}
+
+/*
+ * Find the maximum conformance test limit for the given channel and CTL info
+ */
+static u_int16_t
+ar5212GetMaxEdgePower(u_int16_t channel, RD_EDGES_POWER *pRdEdgesPower)
+{
+ /* temp array for holding edge channels */
+ u_int16_t tempChannelList[NUM_EDGES];
+ u_int16_t clo, chi, twiceMaxEdgePower;
+ int i, numEdges;
+
+ /* Get the edge power */
+ for (i = 0; i < NUM_EDGES; i++) {
+ if (pRdEdgesPower[i].rdEdge == 0)
+ break;
+ tempChannelList[i] = pRdEdgesPower[i].rdEdge;
+ }
+ numEdges = i;
+
+ ar5212GetLowerUpperValues(channel, tempChannelList,
+ numEdges, &clo, &chi);
+ /* Get the index for the lower channel */
+ for (i = 0; i < numEdges && clo != tempChannelList[i]; i++)
+ ;
+ /* Is lower channel ever outside the rdEdge? */
+ HALASSERT(i != numEdges);
+
+ if ((clo == chi && clo == channel) || (pRdEdgesPower[i].flag)) {
+ /*
+ * If there's an exact channel match or an inband flag set
+ * on the lower channel use the given rdEdgePower
+ */
+ twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower;
+ HALASSERT(twiceMaxEdgePower > 0);
+ } else
+ twiceMaxEdgePower = MAX_RATE_POWER;
+ return twiceMaxEdgePower;
+}
+
+/*
+ * Returns interpolated or the scaled up interpolated value
+ */
+static u_int16_t
+interpolate(u_int16_t target, u_int16_t srcLeft, u_int16_t srcRight,
+ u_int16_t targetLeft, u_int16_t targetRight)
+{
+ u_int16_t rv;
+ int16_t lRatio;
+
+ /* to get an accurate ratio, always scale, if want to scale, then don't scale back down */
+ if ((targetLeft * targetRight) == 0)
+ return 0;
+
+ if (srcRight != srcLeft) {
+ /*
+ * Note the ratio always need to be scaled,
+ * since it will be a fraction.
+ */
+ lRatio = (target - srcLeft) * EEP_SCALE / (srcRight - srcLeft);
+ if (lRatio < 0) {
+ /* Return as Left target if value would be negative */
+ rv = targetLeft;
+ } else if (lRatio > EEP_SCALE) {
+ /* Return as Right target if Ratio is greater than 100% (SCALE) */
+ rv = targetRight;
+ } else {
+ rv = (lRatio * targetRight + (EEP_SCALE - lRatio) *
+ targetLeft) / EEP_SCALE;
+ }
+ } else {
+ rv = targetLeft;
+ }
+ return rv;
+}
+
+/*
+ * Return the four rates of target power for the given target power table
+ * channel, and number of channels
+ */
+static void
+ar5212GetTargetPowers(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ TRGT_POWER_INFO *powInfo,
+ u_int16_t numChannels, TRGT_POWER_INFO *pNewPower)
+{
+ /* temp array for holding target power channels */
+ u_int16_t tempChannelList[NUM_TEST_FREQUENCIES];
+ u_int16_t clo, chi, ixlo, ixhi;
+ int i;
+
+ /* Copy the target powers into the temp channel list */
+ for (i = 0; i < numChannels; i++)
+ tempChannelList[i] = powInfo[i].testChannel;
+
+ ar5212GetLowerUpperValues(chan->ic_freq, tempChannelList,
+ numChannels, &clo, &chi);
+
+ /* Get the indices for the channel */
+ ixlo = ixhi = 0;
+ for (i = 0; i < numChannels; i++) {
+ if (clo == tempChannelList[i]) {
+ ixlo = i;
+ }
+ if (chi == tempChannelList[i]) {
+ ixhi = i;
+ break;
+ }
+ }
+
+ /*
+ * Get the lower and upper channels, target powers,
+ * and interpolate between them.
+ */
+ pNewPower->twicePwr6_24 = interpolate(chan->ic_freq, clo, chi,
+ powInfo[ixlo].twicePwr6_24, powInfo[ixhi].twicePwr6_24);
+ pNewPower->twicePwr36 = interpolate(chan->ic_freq, clo, chi,
+ powInfo[ixlo].twicePwr36, powInfo[ixhi].twicePwr36);
+ pNewPower->twicePwr48 = interpolate(chan->ic_freq, clo, chi,
+ powInfo[ixlo].twicePwr48, powInfo[ixhi].twicePwr48);
+ pNewPower->twicePwr54 = interpolate(chan->ic_freq, clo, chi,
+ powInfo[ixlo].twicePwr54, powInfo[ixhi].twicePwr54);
+}
+
+static RD_EDGES_POWER*
+findEdgePower(struct ath_hal *ah, u_int ctl)
+{
+ int i;
+
+ for (i = 0; i < _numCtls; i++)
+ if (_ctl[i] == ctl)
+ return &_rdEdgesPower[i * NUM_EDGES];
+ return AH_NULL;
+}
+
+/*
+ * Sets the transmit power in the baseband for the given
+ * operating channel and mode.
+ */
+static HAL_BOOL
+setRateTable(struct ath_hal *ah, const struct ieee80211_channel *chan,
+ int16_t tpcScaleReduction, int16_t powerLimit,
+ int16_t *pMinPower, int16_t *pMaxPower)
+{
+ u_int16_t ratesArray[16];
+ u_int16_t *rpow = ratesArray;
+ u_int16_t twiceMaxRDPower, twiceMaxEdgePower, twiceMaxEdgePowerCck;
+ int8_t twiceAntennaGain, twiceAntennaReduction;
+ TRGT_POWER_INFO targetPowerOfdm, targetPowerCck;
+ RD_EDGES_POWER *rep;
+ int16_t scaledPower;
+ u_int8_t cfgCtl;
+
+ twiceMaxRDPower = chan->ic_maxregpower * 2;
+ *pMaxPower = -MAX_RATE_POWER;
+ *pMinPower = MAX_RATE_POWER;
+
+ /* Get conformance test limit maximum for this channel */
+ cfgCtl = ath_hal_getctl(ah, chan);
+ rep = findEdgePower(ah, cfgCtl);
+ if (rep != AH_NULL)
+ twiceMaxEdgePower = ar5212GetMaxEdgePower(chan->ic_freq, rep);
+ else
+ twiceMaxEdgePower = MAX_RATE_POWER;
+
+ if (IEEE80211_IS_CHAN_G(chan)) {
+ /* Check for a CCK CTL for 11G CCK powers */
+ cfgCtl = (cfgCtl & 0xFC) | 0x01;
+ rep = findEdgePower(ah, cfgCtl);
+ if (rep != AH_NULL)
+ twiceMaxEdgePowerCck = ar5212GetMaxEdgePower(chan->ic_freq, rep);
+ else
+ twiceMaxEdgePowerCck = MAX_RATE_POWER;
+ } else {
+ /* Set the 11B cck edge power to the one found before */
+ twiceMaxEdgePowerCck = twiceMaxEdgePower;
+ }
+
+ /* Get Antenna Gain reduction */
+ if (IEEE80211_IS_CHAN_5GHZ(chan)) {
+ twiceAntennaGain = antennaGainMax[0];
+ } else {
+ twiceAntennaGain = antennaGainMax[1];
+ }
+ twiceAntennaReduction =
+ ath_hal_getantennareduction(ah, chan, twiceAntennaGain);
+
+ if (IEEE80211_IS_CHAN_OFDM(chan)) {
+ /* Get final OFDM target powers */
+ if (IEEE80211_IS_CHAN_G(chan)) {
+ /* TODO - add Turbo 2.4 to this mode check */
+ ar5212GetTargetPowers(ah, chan, trgtPwr_11g,
+ numTargetPwr_11g, &targetPowerOfdm);
+ } else {
+ ar5212GetTargetPowers(ah, chan, trgtPwr_11a,
+ numTargetPwr_11a, &targetPowerOfdm);
+ }
+
+ /* Get Maximum OFDM power */
+ /* Minimum of target and edge powers */
+ scaledPower = AH_MIN(twiceMaxEdgePower,
+ twiceMaxRDPower - twiceAntennaReduction);
+
+ /*
+ * If turbo is set, reduce power to keep power
+ * consumption under 2 Watts. Note that we always do
+ * this unless specially configured. Then we limit
+ * power only for non-AP operation.
+ */
+ if (IEEE80211_IS_CHAN_TURBO(chan)
+#ifdef AH_ENABLE_AP_SUPPORT
+ && AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP
+#endif
+ ) {
+ /*
+ * If turbo is set, reduce power to keep power
+ * consumption under 2 Watts
+ */
+ if (eeversion >= AR_EEPROM_VER3_1)
+ scaledPower = AH_MIN(scaledPower,
+ turbo2WMaxPower5);
+ /*
+ * EEPROM version 4.0 added an additional
+ * constraint on 2.4GHz channels.
+ */
+ if (eeversion >= AR_EEPROM_VER4_0 &&
+ IEEE80211_IS_CHAN_2GHZ(chan))
+ scaledPower = AH_MIN(scaledPower,
+ turbo2WMaxPower2);
+ }
+ /* Reduce power by max regulatory domain allowed restrictions */
+ scaledPower -= (tpcScaleReduction * 2);
+ scaledPower = (scaledPower < 0) ? 0 : scaledPower;
+ scaledPower = AH_MIN(scaledPower, powerLimit);
+
+ scaledPower = AH_MIN(scaledPower, targetPowerOfdm.twicePwr6_24);
+
+ /* Set OFDM rates 9, 12, 18, 24, 36, 48, 54, XR */
+ rpow[0] = rpow[1] = rpow[2] = rpow[3] = rpow[4] = scaledPower;
+ rpow[5] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr36);
+ rpow[6] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr48);
+ rpow[7] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr54);
+
+#ifdef notyet
+ if (eeversion >= AR_EEPROM_VER4_0) {
+ /* Setup XR target power from EEPROM */
+ rpow[15] = AH_MIN(scaledPower, IS_CHAN_2GHZ(chan) ?
+ xrTargetPower2 : xrTargetPower5);
+ } else {
+ /* XR uses 6mb power */
+ rpow[15] = rpow[0];
+ }
+#else
+ rpow[15] = rpow[0];
+#endif
+
+ *pMinPower = rpow[7];
+ *pMaxPower = rpow[0];
+
+#if 0
+ ahp->ah_ofdmTxPower = rpow[0];
+#endif
+
+ HALDEBUG(ah, HAL_DEBUG_ANY,
+ "%s: MaxRD: %d TurboMax: %d MaxCTL: %d "
+ "TPC_Reduction %d\n", __func__,
+ twiceMaxRDPower, turbo2WMaxPower5,
+ twiceMaxEdgePower, tpcScaleReduction * 2);
+ }
+
+ if (IEEE80211_IS_CHAN_CCK(chan)) {
+ /* Get final CCK target powers */
+ ar5212GetTargetPowers(ah, chan, trgtPwr_11b,
+ numTargetPwr_11b, &targetPowerCck);
+
+ /* Reduce power by max regulatory domain allowed restrictions */
+ scaledPower = AH_MIN(twiceMaxEdgePowerCck,
+ twiceMaxRDPower - twiceAntennaReduction);
+
+ scaledPower -= (tpcScaleReduction * 2);
+ scaledPower = (scaledPower < 0) ? 0 : scaledPower;
+ scaledPower = AH_MIN(scaledPower, powerLimit);
+
+ rpow[8] = (scaledPower < 1) ? 1 : scaledPower;
+
+ /* Set CCK rates 2L, 2S, 5.5L, 5.5S, 11L, 11S */
+ rpow[8] = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24);
+ rpow[9] = AH_MIN(scaledPower, targetPowerCck.twicePwr36);
+ rpow[10] = rpow[9];
+ rpow[11] = AH_MIN(scaledPower, targetPowerCck.twicePwr48);
+ rpow[12] = rpow[11];
+ rpow[13] = AH_MIN(scaledPower, targetPowerCck.twicePwr54);
+ rpow[14] = rpow[13];
+
+ /* Set min/max power based off OFDM values or initialization */
+ if (rpow[13] < *pMinPower)
+ *pMinPower = rpow[13];
+ if (rpow[9] > *pMaxPower)
+ *pMaxPower = rpow[9];
+
+ }
+#if 0
+ ahp->ah_tx6PowerInHalfDbm = *pMaxPower;
+#endif
+ return AH_TRUE;
+}
+
+void*
+ath_hal_malloc(size_t size)
+{
+ return calloc(1, size);
+}
+
+void
+ath_hal_free(void* p)
+{
+ return free(p);
+}
+
+void
+ath_hal_vprintf(struct ath_hal *ah, const char* fmt, va_list ap)
+{
+ vprintf(fmt, ap);
+}
+
+void
+ath_hal_printf(struct ath_hal *ah, const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ ath_hal_vprintf(ah, fmt, ap);
+ va_end(ap);
+}
+
+void
+DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)
+{
+ __va_list ap;
+ va_start(ap, fmt);
+ ath_hal_vprintf(ah, fmt, ap);
+ va_end(ap);
+}
diff --git a/tools/tools/ath/athrd/run.sh b/tools/tools/ath/athrd/run.sh
new file mode 100755
index 000000000000..3e1e01a27be4
--- /dev/null
+++ b/tools/tools/ath/athrd/run.sh
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+COUNTRIES=${@:-"
+ DB NA AL DZ AR AM AU AT AZ BH BY BE BZ BO BR BN BG
+ CA CL CN CO CR HR CY CZ DK DO EC EG SV EE FI FR GE
+ DE GR GT HN HK HU IS IN ID IR IE IL IT JP J1 J2 J3
+ J4 J5 JO KZ KP KR K2 KW LV LB LI LT LU MO MK MY MX
+ MC MA NL NZ NO OM PK PA PE PH PL PT PR QA RO RU SA
+ SG SK SI ZA ES SE CH SY TW TH TT TN TR UA AE GB US
+ UY UZ VE VN YE ZW WOR0_WORLD WOR1_WORLD WOR2_WORLD WOR3_WORLD
+ WOR4_WORLD, WOR5_ETSIC EU1_WORLD WOR01_WORLD WOR02_WORLD
+"}
+
+for i in $COUNTRIES
+do
+ ./athrd -o $i
+done
diff --git a/tools/tools/ath/athregs/Makefile b/tools/tools/ath/athregs/Makefile
new file mode 100644
index 000000000000..6b61b32ceb51
--- /dev/null
+++ b/tools/tools/ath/athregs/Makefile
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+PROG= athregs
+
+.PATH.c: ${.CURDIR}/../common
+
+SRCS= dumpregs.c
+SRCS+= dumpregs_5210.c
+SRCS+= dumpregs_5211.c
+SRCS+= dumpregs_5212.c
+SRCS+= dumpregs_5416.c
+SRCS+= opt_ah.h
+
+CLEANFILES+= opt_ah.h
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+ echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athregs/dumpregs.c b/tools/tools/ath/athregs/dumpregs.c
new file mode 100644
index 000000000000..50e8a1e03978
--- /dev/null
+++ b/tools/tools/ath/athregs/dumpregs.c
@@ -0,0 +1,721 @@
+/*-
+ * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+/* XXX cheat, 5212 has a superset of the key table defs */
+#include "ar5212/ar5212reg.h"
+
+#include "dumpregs.h"
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <err.h>
+
+typedef struct {
+ HAL_REVS revs;
+ u_int32_t regdata[0xffff / sizeof(u_int32_t)];
+#define MAXREGS 5*1024
+ struct dumpreg *regs[MAXREGS];
+ u_int nregs;
+ u_int show_names : 1,
+ show_addrs : 1;
+} dumpregs_t;
+static dumpregs_t state;
+
+#undef OS_REG_READ
+#define OS_REG_READ(ah, off) state.regdata[(off) >> 2]
+
+static int ath_hal_anyregs(int what);
+static int ath_hal_setupregs(struct ath_diag *atd, int what);
+static u_int ath_hal_setupdiagregs(const HAL_REGRANGE regs[], u_int nr);
+static void ath_hal_dumpregs(FILE *fd, int what);
+static void ath_hal_dumprange(FILE *fd, u_int a, u_int b);
+static void ath_hal_dumpkeycache(FILE *fd, int nkeys);
+static void ath_hal_dumpint(FILE *fd, int what);
+static void ath_hal_dumpqcu(FILE *fd, int what);
+static void ath_hal_dumpdcu(FILE *fd, int what);
+static void ath_hal_dumpbb(FILE *fd, int what);
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: athregs [-i interface] [-abdkmqxz]\n");
+ fprintf(stderr, "-a display all registers\n");
+ fprintf(stderr, "-b display baseband registers\n");
+ fprintf(stderr, "-d display DCU registers\n");
+ fprintf(stderr, "-k display key cache registers\n");
+ fprintf(stderr, "-m display \"MAC\" registers (default)\n");
+ fprintf(stderr, "-q display QCU registers\n");
+ fprintf(stderr, "-x display XR registers\n");
+ fprintf(stderr, "-z display interrupt registers\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "-A display register address\n");
+ fprintf(stderr, "-N suppress display of register name\n");
+ exit(-1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct ath_diag atd;
+ const char *ifname;
+ u_int32_t *data;
+ u_int32_t *dp, *ep;
+ int what, c, s, i;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ err(1, "socket");
+ ifname = getenv("ATH");
+ if (!ifname)
+ ifname = ATH_DEFAULT;
+
+ what = 0;
+ state.show_addrs = 0;
+ state.show_names = 1;
+ while ((c = getopt(argc, argv, "i:aAbdkmNqxz")) != -1)
+ switch (c) {
+ case 'a':
+ what |= DUMP_ALL;
+ break;
+ case 'A':
+ state.show_addrs = 1;
+ break;
+ case 'b':
+ what |= DUMP_BASEBAND;
+ break;
+ case 'd':
+ what |= DUMP_DCU;
+ break;
+ case 'k':
+ what |= DUMP_KEYCACHE;
+ break;
+ case 'i':
+ ifname = optarg;
+ break;
+ case 'm':
+ what |= DUMP_BASIC;
+ break;
+ case 'N':
+ state.show_names = 0;
+ break;
+ case 'q':
+ what |= DUMP_QCU;
+ break;
+ case 'x':
+ what |= DUMP_XR;
+ break;
+ case 'z':
+ what |= DUMP_INTERRUPT;
+ break;
+ default:
+ usage();
+ /*NOTREACHED*/
+ }
+ strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
+
+ argc -= optind;
+ argv += optind;
+ if (what == 0)
+ what = DUMP_BASIC;
+
+ atd.ad_id = HAL_DIAG_REVS;
+ atd.ad_out_data = (caddr_t) &state.revs;
+ atd.ad_out_size = sizeof(state.revs);
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+
+ if (ath_hal_setupregs(&atd, what) == 0)
+ errx(-1, "no registers are known for this part "
+ "(devid 0x%x mac %d.%d phy %d)", state.revs.ah_devid,
+ state.revs.ah_macVersion, state.revs.ah_macRev,
+ state.revs.ah_phyRev);
+
+ atd.ad_out_size = ath_hal_setupdiagregs((HAL_REGRANGE *) atd.ad_in_data,
+ atd.ad_in_size / sizeof(HAL_REGRANGE));
+ atd.ad_out_data = (caddr_t) malloc(atd.ad_out_size);
+ if (atd.ad_out_data == NULL) {
+ fprintf(stderr, "Cannot malloc output buffer, size %u\n",
+ atd.ad_out_size);
+ exit(-1);
+ }
+ atd.ad_id = HAL_DIAG_REGS | ATH_DIAG_IN | ATH_DIAG_DYN;
+ if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
+ err(1, atd.ad_name);
+
+ /*
+ * Expand register data into global space that can be
+ * indexed directly by register offset.
+ */
+ dp = (u_int32_t *)atd.ad_out_data;
+ ep = (u_int32_t *)(atd.ad_out_data + atd.ad_out_size);
+ while (dp < ep) {
+ u_int r = dp[0] >> 16; /* start of range */
+ u_int e = dp[0] & 0xffff; /* end of range */
+ dp++;
+ /* convert offsets to indices */
+ r >>= 2; e >>= 2;
+ do {
+ if (dp >= ep) {
+ fprintf(stderr, "Warning, botched return data;"
+ "register at offset 0x%x not present\n",
+ r << 2);
+ break;
+ }
+ state.regdata[r++] = *dp++;
+ } while (r <= e);
+ }
+
+ if (what & DUMP_BASIC)
+ ath_hal_dumpregs(stdout, DUMP_BASIC);
+ if ((what & DUMP_INTERRUPT) && ath_hal_anyregs(DUMP_INTERRUPT)) {
+ if (what & DUMP_BASIC)
+ putchar('\n');
+ if (state.show_addrs)
+ ath_hal_dumpregs(stdout, DUMP_INTERRUPT);
+ else
+ ath_hal_dumpint(stdout, what);
+ }
+ if ((what & DUMP_QCU) && ath_hal_anyregs(DUMP_QCU)) {
+ if (what & (DUMP_BASIC|DUMP_INTERRUPT))
+ putchar('\n');
+ if (state.show_addrs)
+ ath_hal_dumpregs(stdout, DUMP_QCU);
+ else
+ ath_hal_dumpqcu(stdout, what);
+ }
+ if ((what & DUMP_DCU) && ath_hal_anyregs(DUMP_DCU)) {
+ if (what & (DUMP_BASIC|DUMP_INTERRUPT|DUMP_QCU))
+ putchar('\n');
+ if (state.show_addrs)
+ ath_hal_dumpregs(stdout, DUMP_DCU);
+ else
+ ath_hal_dumpdcu(stdout, what);
+ }
+ if (what & DUMP_KEYCACHE) {
+ if (state.show_addrs) {
+ if (what & (DUMP_BASIC|DUMP_INTERRUPT|DUMP_QCU|DUMP_DCU))
+ putchar('\n');
+ ath_hal_dumpregs(stdout, DUMP_KEYCACHE);
+ } else
+ ath_hal_dumpkeycache(stdout, 128);
+ }
+ if (what & DUMP_BASEBAND) {
+ if (what &~ DUMP_BASEBAND)
+ fprintf(stdout, "\n");
+ ath_hal_dumpbb(stdout, what);
+ }
+ return 0;
+}
+
+static int
+regcompar(const void *a, const void *b)
+{
+ const struct dumpreg *ra = *(const struct dumpreg **)a;
+ const struct dumpreg *rb = *(const struct dumpreg **)b;
+ return ra->addr - rb->addr;
+}
+
+void
+register_regs(struct dumpreg *chipregs, u_int nchipregs,
+ int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
+{
+ const int existing_regs = state.nregs;
+ int i, j;
+
+ for (i = 0; i < nchipregs; i++) {
+ struct dumpreg *nr = &chipregs[i];
+ if (nr->srevMin == 0)
+ nr->srevMin = def_srev_min;
+ if (nr->srevMax == 0)
+ nr->srevMax = def_srev_max;
+ if (nr->phyMin == 0)
+ nr->phyMin = def_phy_min;
+ if (nr->phyMax == 0)
+ nr->phyMax = def_phy_max;
+ for (j = 0; j < existing_regs; j++) {
+ struct dumpreg *r = state.regs[j];
+ /*
+ * Check if we can just expand the mac+phy
+ * coverage for the existing entry.
+ */
+ if (nr->addr == r->addr &&
+ (nr->name == r->name ||
+ nr->name != NULL && r->name != NULL &&
+ strcmp(nr->name, r->name) == 0)) {
+ if (nr->srevMin < r->srevMin &&
+ (r->srevMin <= nr->srevMax &&
+ nr->srevMax+1 <= r->srevMax)) {
+ r->srevMin = nr->srevMin;
+ goto skip;
+ }
+ if (nr->srevMax > r->srevMax &&
+ (r->srevMin <= nr->srevMin &&
+ nr->srevMin <= r->srevMax)) {
+ r->srevMax = nr->srevMax;
+ goto skip;
+ }
+ }
+ if (r->addr > nr->addr)
+ break;
+ }
+ /*
+ * New item, add to the end, it'll be sorted below.
+ */
+ if (state.nregs == MAXREGS)
+ errx(-1, "too many registers; bump MAXREGS");
+ state.regs[state.nregs++] = nr;
+ skip:
+ ;
+ }
+ qsort(state.regs, state.nregs, sizeof(struct dumpreg *), regcompar);
+}
+
+void
+register_keycache(u_int nslots,
+ int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
+{
+#define SET(r, a) do { \
+ r->addr = a; r->type = DUMP_KEYCACHE; r++; \
+} while(0)
+ struct dumpreg *keyregs, *r;
+ int i;
+
+ keyregs = (struct dumpreg *) calloc(nslots, 8*sizeof(struct dumpreg));
+ if (keyregs == NULL)
+ errx(-1, "no space to %d keycache slots\n", nslots);
+ r = keyregs;
+ for (i = 0; i < nslots; i++) {
+ SET(r, AR_KEYTABLE_KEY0(i));
+ SET(r, AR_KEYTABLE_KEY1(i));
+ SET(r, AR_KEYTABLE_KEY2(i));
+ SET(r, AR_KEYTABLE_KEY3(i));
+ SET(r, AR_KEYTABLE_KEY4(i));
+ SET(r, AR_KEYTABLE_TYPE(i));
+ SET(r, AR_KEYTABLE_MAC0(i));
+ SET(r, AR_KEYTABLE_MAC1(i));
+ }
+ register_regs(keyregs, 8*nslots,
+ def_srev_min, def_srev_max, def_phy_min, def_phy_max);
+#undef SET
+}
+
+void
+register_range(u_int brange, u_int erange, int type,
+ int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
+{
+ struct dumpreg *bbregs, *r;
+ int i, nregs;
+
+ nregs = (erange - brange) / sizeof(uint32_t);
+ bbregs = (struct dumpreg *) calloc(nregs, sizeof(struct dumpreg));
+ if (bbregs == NULL)
+ errx(-1, "no space for %d register slots (type %d)\n",
+ nregs, type);
+ r = bbregs;
+ for (i = 0; i < nregs; i++) {
+ r->addr = brange + (i<<2);
+ r->type = type;
+ r++;
+ }
+ register_regs(bbregs, nregs,
+ def_srev_min, def_srev_max, def_phy_min, def_phy_max);
+}
+
+static __inline int
+match(const struct dumpreg *dr, const HAL_REVS *revs)
+{
+ if (!MAC_MATCH(dr, revs->ah_macVersion, revs->ah_macRev))
+ return 0;
+ if ((dr->type & DUMP_BASEBAND) && !PHY_MATCH(dr, revs->ah_phyRev))
+ return 0;
+ return 1;
+}
+
+static int
+ath_hal_anyregs(int what)
+{
+ const HAL_REVS *revs = &state.revs;
+ int i;
+
+ for (i = 0; i < state.nregs; i++) {
+ const struct dumpreg *dr = state.regs[i];
+ if ((what & dr->type) && match(dr, revs))
+ return 1;
+ }
+ return 0;
+}
+
+static int
+ath_hal_setupregs(struct ath_diag *atd, int what)
+{
+ const HAL_REVS *revs = &state.revs;
+ HAL_REGRANGE r;
+ size_t space = 0;
+ u_int8_t *cp;
+ int i, brun, erun;
+
+ brun = erun = -1;
+ for (i = 0; i < state.nregs; i++) {
+ const struct dumpreg *dr = state.regs[i];
+ if ((what & dr->type) && match(dr, revs)) {
+ if (erun + 4 != dr->addr) {
+ if (brun != -1)
+ space += sizeof(HAL_REGRANGE);
+ brun = erun = dr->addr;
+ } else
+ erun = dr->addr;
+ }
+ }
+ space += sizeof(HAL_REGRANGE);
+
+ atd->ad_in_data = (caddr_t) malloc(space);
+ if (atd->ad_in_data == NULL) {
+ fprintf(stderr, "Cannot malloc memory for registers!\n");
+ exit(-1);
+ }
+ atd->ad_in_size = space;
+ cp = (u_int8_t *) atd->ad_in_data;
+ brun = erun = -1;
+ for (i = 0; i < state.nregs; i++) {
+ const struct dumpreg *dr = state.regs[i];
+ if ((what & dr->type) && match(dr, revs)) {
+ if (erun + 4 != dr->addr) {
+ if (brun != -1) {
+ r.start = brun, r.end = erun;
+ memcpy(cp, &r, sizeof(r));
+ cp += sizeof(r);
+ }
+ brun = erun = dr->addr;
+ } else
+ erun = dr->addr;
+ }
+ }
+ if (brun != -1) {
+ r.start = brun, r.end = erun;
+ memcpy(cp, &r, sizeof(r));
+ cp += sizeof(r);
+ }
+ return space / sizeof(uint32_t);
+}
+
+static void
+ath_hal_dumpregs(FILE *fd, int what)
+{
+ const HAL_REVS *revs = &state.revs;
+ const char *sep = "";
+ int i, count, itemsperline;
+
+ count = 0;
+ itemsperline = 4;
+ if (state.show_names && state.show_addrs)
+ itemsperline--;
+ for (i = 0; i < state.nregs; i++) {
+ const struct dumpreg *dr = state.regs[i];
+ if ((what & dr->type) && match(dr, revs)) {
+ if (state.show_names && dr->name != NULL) {
+ fprintf(fd, "%s%-8s", sep, dr->name);
+ if (state.show_addrs)
+ fprintf(fd, " [%04x]", dr->addr);
+ } else
+ fprintf(fd, "%s%04x", sep, dr->addr);
+ fprintf(fd, " %08x", OS_REG_READ(ah, dr->addr));
+ sep = " ";
+ if ((++count % itemsperline) == 0)
+ sep = "\n";
+ }
+ }
+ if (count)
+ fprintf(fd, "\n");
+}
+
+static void
+ath_hal_dumprange(FILE *fd, u_int a, u_int b)
+{
+ u_int r;
+
+ for (r = a; r+16 <= b; r += 5*4)
+ fprintf(fd,
+ "%04x %08x %04x %08x %04x %08x %04x %08x %04x %08x\n"
+ , r, OS_REG_READ(ah, r)
+ , r+4, OS_REG_READ(ah, r+4)
+ , r+8, OS_REG_READ(ah, r+8)
+ , r+12, OS_REG_READ(ah, r+12)
+ , r+16, OS_REG_READ(ah, r+16)
+ );
+ switch (b-r) {
+ case 16:
+ fprintf(fd
+ , "%04x %08x %04x %08x %04x %08x %04x %08x\n"
+ , r, OS_REG_READ(ah, r)
+ , r+4, OS_REG_READ(ah, r+4)
+ , r+8, OS_REG_READ(ah, r+8)
+ , r+12, OS_REG_READ(ah, r+12)
+ );
+ break;
+ case 12:
+ fprintf(fd, "%04x %08x %04x %08x %04x %08x\n"
+ , r, OS_REG_READ(ah, r)
+ , r+4, OS_REG_READ(ah, r+4)
+ , r+8, OS_REG_READ(ah, r+8)
+ );
+ break;
+ case 8:
+ fprintf(fd, "%04x %08x %04x %08x\n"
+ , r, OS_REG_READ(ah, r)
+ , r+4, OS_REG_READ(ah, r+4)
+ );
+ break;
+ case 4:
+ fprintf(fd, "%04x %08x\n"
+ , r, OS_REG_READ(ah, r)
+ );
+ break;
+ }
+}
+
+static void
+ath_hal_dumpint(FILE *fd, int what)
+{
+ int i;
+
+ /* Interrupt registers */
+ fprintf(fd, "IMR: %08x S0 %08x S1 %08x S2 %08x S3 %08x S4 %08x\n"
+ , OS_REG_READ(ah, AR_IMR)
+ , OS_REG_READ(ah, AR_IMR_S0)
+ , OS_REG_READ(ah, AR_IMR_S1)
+ , OS_REG_READ(ah, AR_IMR_S2)
+ , OS_REG_READ(ah, AR_IMR_S3)
+ , OS_REG_READ(ah, AR_IMR_S4)
+ );
+ fprintf(fd, "ISR: %08x S0 %08x S1 %08x S2 %08x S3 %08x S4 %08x\n"
+ , OS_REG_READ(ah, AR_ISR)
+ , OS_REG_READ(ah, AR_ISR_S0)
+ , OS_REG_READ(ah, AR_ISR_S1)
+ , OS_REG_READ(ah, AR_ISR_S2)
+ , OS_REG_READ(ah, AR_ISR_S3)
+ , OS_REG_READ(ah, AR_ISR_S4)
+ );
+}
+
+static void
+ath_hal_dumpqcu(FILE *fd, int what)
+{
+ int i;
+
+ /* QCU registers */
+ fprintf(fd, "%-8s %08x %-8s %08x %-8s %08x\n"
+ , "Q_TXE", OS_REG_READ(ah, AR_Q_TXE)
+ , "Q_TXD", OS_REG_READ(ah, AR_Q_TXD)
+ , "Q_RDYTIMSHD", OS_REG_READ(ah, AR_Q_RDYTIMESHDN)
+ );
+ fprintf(fd, "Q_ONESHOTARM_SC %08x Q_ONESHOTARM_CC %08x\n"
+ , OS_REG_READ(ah, AR_Q_ONESHOTARM_SC)
+ , OS_REG_READ(ah, AR_Q_ONESHOTARM_CC)
+ );
+ for (i = 0; i < 10; i++)
+ fprintf(fd, "Q[%u] TXDP %08x CBR %08x RDYT %08x MISC %08x STS %08x\n"
+ , i
+ , OS_REG_READ(ah, AR_QTXDP(i))
+ , OS_REG_READ(ah, AR_QCBRCFG(i))
+ , OS_REG_READ(ah, AR_QRDYTIMECFG(i))
+ , OS_REG_READ(ah, AR_QMISC(i))
+ , OS_REG_READ(ah, AR_QSTS(i))
+ );
+}
+
+static void
+ath_hal_dumpdcu(FILE *fd, int what)
+{
+ int i;
+
+ /* DCU registers */
+ for (i = 0; i < 10; i++)
+ fprintf(fd, "D[%u] MASK %08x IFS %08x RTRY %08x CHNT %08x MISC %06x\n"
+ , i
+ , OS_REG_READ(ah, AR_DQCUMASK(i))
+ , OS_REG_READ(ah, AR_DLCL_IFS(i))
+ , OS_REG_READ(ah, AR_DRETRY_LIMIT(i))
+ , OS_REG_READ(ah, AR_DCHNTIME(i))
+ , OS_REG_READ(ah, AR_DMISC(i))
+ );
+}
+
+static void
+ath_hal_dumpbb(FILE *fd, int what)
+{
+ const HAL_REVS *revs = &state.revs;
+ int i, brun, erun;
+
+ brun = erun = 0;
+ for (i = 0; i < state.nregs; i++) {
+ const struct dumpreg *dr = state.regs[i];
+ if (!match(dr, revs))
+ continue;
+ if (dr->type & DUMP_BASEBAND) {
+ if (brun == 0) {
+ brun = erun = dr->addr;
+ } else if (dr->addr == erun + sizeof(uint32_t)) {
+ erun = dr->addr;
+ } else {
+ ath_hal_dumprange(fd, brun, erun);
+ brun = erun = dr->addr;
+ }
+ } else {
+ if (brun != 0)
+ ath_hal_dumprange(fd, brun, erun);
+ brun = erun = 0;
+ }
+ }
+ if (brun != 0)
+ ath_hal_dumprange(fd, brun, erun);
+}
+
+static u_int
+ath_hal_setupdiagregs(const HAL_REGRANGE regs[], u_int nr)
+{
+ u_int space;
+ int i;
+
+ space = 0;
+ for (i = 0; i < nr; i++) {
+ u_int n = 2 * sizeof(u_int32_t); /* reg range + first */
+ if (regs[i].end) {
+ if (regs[i].end < regs[i].start) {
+ fprintf(stderr, "%s: bad register range, "
+ "end 0x%x < start 0x%x\n",
+ __func__, regs[i].end, regs[i].end);
+ exit(-1);
+ }
+ n += regs[i].end - regs[i].start;
+ }
+ space += n;
+ }
+ return space;
+}
+
+/*
+ * Format an Ethernet MAC for printing.
+ */
+static const char*
+ether_sprintf(const u_int8_t *mac)
+{
+ static char etherbuf[18];
+ snprintf(etherbuf, sizeof(etherbuf), "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ return etherbuf;
+}
+
+#ifndef isclr
+#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+#endif
+
+static void
+ath_hal_dumpkeycache(FILE *fd, int nkeys)
+{
+ static const char *keytypenames[] = {
+ "WEP-40", /* AR_KEYTABLE_TYPE_40 */
+ "WEP-104", /* AR_KEYTABLE_TYPE_104 */
+ "#2",
+ "WEP-128", /* AR_KEYTABLE_TYPE_128 */
+ "TKIP", /* AR_KEYTABLE_TYPE_TKIP */
+ "AES-OCB", /* AR_KEYTABLE_TYPE_AES */
+ "AES-CCM", /* AR_KEYTABLE_TYPE_CCM */
+ "CLR", /* AR_KEYTABLE_TYPE_CLR */
+ };
+ int micEnabled = SREV(state.revs.ah_macVersion, state.revs.ah_macRev) < SREV(4,8) ? 0 :
+ OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_CRPT_MIC_ENABLE;
+ u_int8_t mac[IEEE80211_ADDR_LEN];
+ u_int8_t ismic[128/NBBY];
+ int entry;
+ int first = 1;
+
+ memset(ismic, 0, sizeof(ismic));
+ for (entry = 0; entry < nkeys; entry++) {
+ u_int32_t macLo, macHi, type;
+ u_int32_t key0, key1, key2, key3, key4;
+
+ macHi = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry));
+ if ((macHi & AR_KEYTABLE_VALID) == 0 && isclr(ismic, entry))
+ continue;
+ macLo = OS_REG_READ(ah, AR_KEYTABLE_MAC0(entry));
+ macHi <<= 1;
+ if (macLo & (1<<31))
+ macHi |= 1;
+ macLo <<= 1;
+ mac[4] = macHi & 0xff;
+ mac[5] = macHi >> 8;
+ mac[0] = macLo & 0xff;
+ mac[1] = macLo >> 8;
+ mac[2] = macLo >> 16;
+ mac[3] = macLo >> 24;
+ type = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry));
+ if ((type & 7) == AR_KEYTABLE_TYPE_TKIP && micEnabled)
+ setbit(ismic, entry+64);
+ key0 = OS_REG_READ(ah, AR_KEYTABLE_KEY0(entry));
+ key1 = OS_REG_READ(ah, AR_KEYTABLE_KEY1(entry));
+ key2 = OS_REG_READ(ah, AR_KEYTABLE_KEY2(entry));
+ key3 = OS_REG_READ(ah, AR_KEYTABLE_KEY3(entry));
+ key4 = OS_REG_READ(ah, AR_KEYTABLE_KEY4(entry));
+ if (first) {
+ fprintf(fd, "\n");
+ first = 0;
+ }
+ fprintf(fd, "KEY[%03u] MAC %s %-7s %02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x\n"
+ , entry
+ , ether_sprintf(mac)
+ , isset(ismic, entry) ? "MIC" : keytypenames[type & 7]
+ , (key0 >> 0) & 0xff
+ , (key0 >> 8) & 0xff
+ , (key0 >> 16) & 0xff
+ , (key0 >> 24) & 0xff
+ , (key1 >> 0) & 0xff
+ , (key1 >> 8) & 0xff
+ , (key2 >> 0) & 0xff
+ , (key2 >> 8) & 0xff
+ , (key2 >> 16) & 0xff
+ , (key2 >> 24) & 0xff
+ , (key3 >> 0) & 0xff
+ , (key3 >> 8) & 0xff
+ , (key4 >> 0) & 0xff
+ , (key4 >> 8) & 0xff
+ , (key4 >> 16) & 0xff
+ , (key4 >> 24) & 0xff
+ );
+ }
+}
diff --git a/tools/tools/ath/athstats/Makefile b/tools/tools/ath/athstats/Makefile
new file mode 100644
index 000000000000..b1b976619f8a
--- /dev/null
+++ b/tools/tools/ath/athstats/Makefile
@@ -0,0 +1,26 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal
+
+PROG= athstats
+
+SRCS= main.c statfoo.c athstats.c opt_ah.h ah_osdep.h
+
+CLEANFILES+= opt_ah.h
+
+.include <../Makefile.inc>
+
+CFLAGS+=-DATH_SUPPORT_ANI
+CFLAGS+=-DATH_SUPPORT_TDMA
+
+opt_ah.h:
+ echo "#define AH_DEBUG 1" > opt_ah.h
+ echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h
+ echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h
+
+ah_osdep.h:
+ echo 'typedef void *HAL_SOFTC;' >ah_osdep.h
+ echo 'typedef int HAL_BUS_TAG;' >>ah_osdep.h
+ echo 'typedef void *HAL_BUS_HANDLE;' >>ah_osdep.h
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ath/athstats/athstats.c b/tools/tools/ath/athstats/athstats.c
new file mode 100644
index 000000000000..c36dfa030b66
--- /dev/null
+++ b/tools/tools/ath/athstats/athstats.c
@@ -0,0 +1,1109 @@
+/*-
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#include "opt_ah.h"
+
+/*
+ * ath statistics class.
+ */
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_var.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include <err.h>
+
+#include "ah.h"
+#include "ah_desc.h"
+#include "net80211/ieee80211_ioctl.h"
+#include "net80211/ieee80211_radiotap.h"
+#include "if_athioctl.h"
+
+#include "athstats.h"
+
+#ifdef ATH_SUPPORT_ANI
+#define HAL_EP_RND(x,mul) \
+ ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+#define HAL_RSSI(x) HAL_EP_RND(x, HAL_RSSI_EP_MULTIPLIER)
+#endif
+
+#define NOTPRESENT { 0, "", "" }
+
+#define AFTER(prev) ((prev)+1)
+
+static const struct fmt athstats[] = {
+#define S_INPUT 0
+ { 8, "input", "input", "data frames received" },
+#define S_OUTPUT AFTER(S_INPUT)
+ { 8, "output", "output", "data frames transmit" },
+#define S_TX_ALTRATE AFTER(S_OUTPUT)
+ { 7, "altrate", "altrate", "tx frames with an alternate rate" },
+#define S_TX_SHORTRETRY AFTER(S_TX_ALTRATE)
+ { 7, "short", "short", "short on-chip tx retries" },
+#define S_TX_LONGRETRY AFTER(S_TX_SHORTRETRY)
+ { 7, "long", "long", "long on-chip tx retries" },
+#define S_TX_XRETRIES AFTER(S_TX_LONGRETRY)
+ { 6, "xretry", "xretry", "tx failed 'cuz too many retries" },
+#define S_MIB AFTER(S_TX_XRETRIES)
+ { 5, "mib", "mib", "mib overflow interrupts" },
+#ifndef __linux__
+#define S_TX_LINEAR AFTER(S_MIB)
+ { 5, "txlinear", "txlinear", "tx linearized to cluster" },
+#define S_BSTUCK AFTER(S_TX_LINEAR)
+ { 5, "bstuck", "bstuck", "stuck beacon conditions" },
+#define S_INTRCOAL AFTER(S_BSTUCK)
+ { 5, "intrcoal", "intrcoal", "interrupts coalesced" },
+#define S_RATE AFTER(S_INTRCOAL)
+#else
+#define S_RATE AFTER(S_MIB)
+#endif
+ { 5, "rate", "rate", "current transmit rate" },
+#define S_WATCHDOG AFTER(S_RATE)
+ { 5, "wdog", "wdog", "watchdog timeouts" },
+#define S_FATAL AFTER(S_WATCHDOG)
+ { 5, "fatal", "fatal", "hardware error interrupts" },
+#define S_BMISS AFTER(S_FATAL)
+ { 5, "bmiss", "bmiss", "beacon miss interrupts" },
+#define S_RXORN AFTER(S_BMISS)
+ { 5, "rxorn", "rxorn", "recv overrun interrupts" },
+#define S_RXEOL AFTER(S_RXORN)
+ { 5, "rxeol", "rxeol", "recv eol interrupts" },
+#define S_TXURN AFTER(S_RXEOL)
+ { 5, "txurn", "txurn", "txmit underrun interrupts" },
+#define S_TX_MGMT AFTER(S_TXURN)
+ { 5, "txmgt", "txmgt", "tx management frames" },
+#define S_TX_DISCARD AFTER(S_TX_MGMT)
+ { 5, "txdisc", "txdisc", "tx frames discarded prior to association" },
+#define S_TX_INVALID AFTER(S_TX_DISCARD)
+ { 5, "txinv", "txinv", "tx invalid (19)" },
+#define S_TX_QSTOP AFTER(S_TX_INVALID)
+ { 5, "qstop", "qstop", "tx stopped 'cuz no xmit buffer" },
+#define S_TX_ENCAP AFTER(S_TX_QSTOP)
+ { 5, "txencode", "txencode", "tx encapsulation failed" },
+#define S_TX_NONODE AFTER(S_TX_ENCAP)
+ { 5, "txnonode", "txnonode", "tx failed 'cuz no node" },
+#define S_TX_NOBUF AFTER(S_TX_NONODE)
+ { 5, "txnobuf", "txnobuf", "tx failed 'cuz dma buffer allocation failed" },
+#define S_TX_NOFRAG AFTER(S_TX_NOBUF)
+ { 5, "txnofrag", "txnofrag", "tx failed 'cuz frag buffer allocation(s) failed" },
+#define S_TX_NOMBUF AFTER(S_TX_NOFRAG)
+ { 5, "txnombuf", "txnombuf", "tx failed 'cuz mbuf allocation failed" },
+#ifndef __linux__
+#define S_TX_NOMCL AFTER(S_TX_NOMBUF)
+ { 5, "txnomcl", "txnomcl", "tx failed 'cuz cluster allocation failed" },
+#define S_TX_FIFOERR AFTER(S_TX_NOMCL)
+#else
+#define S_TX_FIFOERR AFTER(S_TX_NOMBUF)
+#endif
+ { 5, "efifo", "efifo", "tx failed 'cuz FIFO underrun" },
+#define S_TX_FILTERED AFTER(S_TX_FIFOERR)
+ { 5, "efilt", "efilt", "tx failed 'cuz destination filtered" },
+#define S_TX_BADRATE AFTER(S_TX_FILTERED)
+ { 5, "txbadrate", "txbadrate", "tx failed 'cuz bogus xmit rate" },
+#define S_TX_NOACK AFTER(S_TX_BADRATE)
+ { 5, "noack", "noack", "tx frames with no ack marked" },
+#define S_TX_RTS AFTER(S_TX_NOACK)
+ { 5, "rts", "rts", "tx frames with rts enabled" },
+#define S_TX_CTS AFTER(S_TX_RTS)
+ { 5, "cts", "cts", "tx frames with cts enabled" },
+#define S_TX_SHORTPRE AFTER(S_TX_CTS)
+ { 5, "shpre", "shpre", "tx frames with short preamble" },
+#define S_TX_PROTECT AFTER(S_TX_SHORTPRE)
+ { 5, "protect", "protect", "tx frames with 11g protection" },
+#define S_RX_ORN AFTER(S_TX_PROTECT)
+ { 5, "rxorn", "rxorn", "rx failed 'cuz of desc overrun" },
+#define S_RX_CRC_ERR AFTER(S_RX_ORN)
+ { 6, "crcerr", "crcerr", "rx failed 'cuz of bad CRC" },
+#define S_RX_FIFO_ERR AFTER(S_RX_CRC_ERR)
+ { 5, "rxfifo", "rxfifo", "rx failed 'cuz of FIFO overrun" },
+#define S_RX_CRYPTO_ERR AFTER(S_RX_FIFO_ERR)
+ { 5, "crypt", "crypt", "rx failed 'cuz decryption" },
+#define S_RX_MIC_ERR AFTER(S_RX_CRYPTO_ERR)
+ { 4, "mic", "mic", "rx failed 'cuz MIC failure" },
+#define S_RX_TOOSHORT AFTER(S_RX_MIC_ERR)
+ { 5, "rxshort", "rxshort", "rx failed 'cuz frame too short" },
+#define S_RX_NOMBUF AFTER(S_RX_TOOSHORT)
+ { 5, "rxnombuf", "rxnombuf", "rx setup failed 'cuz no mbuf" },
+#define S_RX_MGT AFTER(S_RX_NOMBUF)
+ { 5, "rxmgt", "rxmgt", "rx management frames" },
+#define S_RX_CTL AFTER(S_RX_MGT)
+ { 5, "rxctl", "rxctl", "rx control frames" },
+#define S_RX_PHY_ERR AFTER(S_RX_CTL)
+ { 7, "phyerr", "phyerr", "rx failed 'cuz of PHY err" },
+#define S_RX_PHY_UNDERRUN AFTER(S_RX_PHY_ERR)
+ { 4, "phyund", "TUnd", "transmit underrun" },
+#define S_RX_PHY_TIMING AFTER(S_RX_PHY_UNDERRUN)
+ { 4, "phytim", "Tim", "timing error" },
+#define S_RX_PHY_PARITY AFTER(S_RX_PHY_TIMING)
+ { 4, "phypar", "IPar", "illegal parity" },
+#define S_RX_PHY_RATE AFTER(S_RX_PHY_PARITY)
+ { 4, "phyrate", "IRate", "illegal rate" },
+#define S_RX_PHY_LENGTH AFTER(S_RX_PHY_RATE)
+ { 4, "phylen", "ILen", "illegal length" },
+#define S_RX_PHY_RADAR AFTER(S_RX_PHY_LENGTH)
+ { 4, "phyradar", "Radar", "radar detect" },
+#define S_RX_PHY_SERVICE AFTER(S_RX_PHY_RADAR)
+ { 4, "physervice", "Service", "illegal service" },
+#define S_RX_PHY_TOR AFTER(S_RX_PHY_SERVICE)
+ { 4, "phytor", "TOR", "transmit override receive" },
+#define S_RX_PHY_OFDM_TIMING AFTER(S_RX_PHY_TOR)
+ { 6, "ofdmtim", "ofdmtim", "OFDM timing" },
+#define S_RX_PHY_OFDM_SIGNAL_PARITY AFTER(S_RX_PHY_OFDM_TIMING)
+ { 6, "ofdmsig", "ofdmsig", "OFDM illegal parity" },
+#define S_RX_PHY_OFDM_RATE_ILLEGAL AFTER(S_RX_PHY_OFDM_SIGNAL_PARITY)
+ { 6, "ofdmrate", "ofdmrate", "OFDM illegal rate" },
+#define S_RX_PHY_OFDM_POWER_DROP AFTER(S_RX_PHY_OFDM_RATE_ILLEGAL)
+ { 6, "ofdmpow", "ofdmpow", "OFDM power drop" },
+#define S_RX_PHY_OFDM_SERVICE AFTER(S_RX_PHY_OFDM_POWER_DROP)
+ { 6, "ofdmservice", "ofdmservice", "OFDM illegal service" },
+#define S_RX_PHY_OFDM_RESTART AFTER(S_RX_PHY_OFDM_SERVICE)
+ { 6, "ofdmrestart", "ofdmrestart", "OFDM restart" },
+#define S_RX_PHY_CCK_TIMING AFTER(S_RX_PHY_OFDM_RESTART)
+ { 6, "ccktim", "ccktim", "CCK timing" },
+#define S_RX_PHY_CCK_HEADER_CRC AFTER(S_RX_PHY_CCK_TIMING)
+ { 6, "cckhead", "cckhead", "CCK header crc" },
+#define S_RX_PHY_CCK_RATE_ILLEGAL AFTER(S_RX_PHY_CCK_HEADER_CRC)
+ { 6, "cckrate", "cckrate", "CCK illegal rate" },
+#define S_RX_PHY_CCK_SERVICE AFTER(S_RX_PHY_CCK_RATE_ILLEGAL)
+ { 6, "cckservice", "cckservice", "CCK illegal service" },
+#define S_RX_PHY_CCK_RESTART AFTER(S_RX_PHY_CCK_SERVICE)
+ { 6, "cckrestar", "cckrestar", "CCK restart" },
+#define S_BE_NOMBUF AFTER(S_RX_PHY_CCK_RESTART)
+ { 4, "benombuf", "benombuf", "beacon setup failed 'cuz no mbuf" },
+#define S_BE_XMIT AFTER(S_BE_NOMBUF)
+ { 7, "bexmit", "bexmit", "beacons transmitted" },
+#define S_PER_CAL AFTER(S_BE_XMIT)
+ { 4, "pcal", "pcal", "periodic calibrations" },
+#define S_PER_CALFAIL AFTER(S_PER_CAL)
+ { 4, "pcalf", "pcalf", "periodic calibration failures" },
+#define S_PER_RFGAIN AFTER(S_PER_CALFAIL)
+ { 4, "prfga", "prfga", "rfgain value change" },
+#if ATH_SUPPORT_TDMA
+#define S_TDMA_UPDATE AFTER(S_PER_RFGAIN)
+ { 5, "tdmau", "tdmau", "TDMA slot timing updates" },
+#define S_TDMA_TIMERS AFTER(S_TDMA_UPDATE)
+ { 5, "tdmab", "tdmab", "TDMA slot update set beacon timers" },
+#define S_TDMA_TSF AFTER(S_TDMA_TIMERS)
+ { 5, "tdmat", "tdmat", "TDMA slot update set TSF" },
+#define S_TDMA_TSFADJ AFTER(S_TDMA_TSF)
+ { 8, "tdmadj", "tdmadj", "TDMA slot adjust (usecs, smoothed)" },
+#define S_TDMA_ACK AFTER(S_TDMA_TSFADJ)
+ { 5, "tdmack", "tdmack", "TDMA tx failed 'cuz ACK required" },
+#define S_RATE_CALLS AFTER(S_TDMA_ACK)
+#else
+#define S_RATE_CALLS AFTER(S_PER_RFGAIN)
+#endif
+ { 5, "ratec", "ratec", "rate control checks" },
+#define S_RATE_RAISE AFTER(S_RATE_CALLS)
+ { 5, "rate+", "rate+", "rate control raised xmit rate" },
+#define S_RATE_DROP AFTER(S_RATE_RAISE)
+ { 5, "rate-", "rate-", "rate control dropped xmit rate" },
+#define S_TX_RSSI AFTER(S_RATE_DROP)
+ { 4, "arssi", "arssi", "rssi of last ack" },
+#define S_RX_RSSI AFTER(S_TX_RSSI)
+ { 4, "rssi", "rssi", "avg recv rssi" },
+#define S_RX_NOISE AFTER(S_RX_RSSI)
+ { 5, "noise", "noise", "rx noise floor" },
+#define S_BMISS_PHANTOM AFTER(S_RX_NOISE)
+ { 5, "bmissphantom", "bmissphantom", "phantom beacon misses" },
+#define S_TX_RAW AFTER(S_BMISS_PHANTOM)
+ { 5, "txraw", "txraw", "tx frames through raw api" },
+#define S_TX_RAW_FAIL AFTER(S_TX_RAW)
+ { 5, "txrawfail", "txrawfail", "raw tx failed 'cuz interface/hw down" },
+#define S_RX_TOOBIG AFTER(S_TX_RAW_FAIL)
+ { 5, "rx2big", "rx2big", "rx failed 'cuz frame too large" },
+#define S_RX_AGG AFTER(S_RX_TOOBIG)
+ { 5, "rxagg", "rxagg", "A-MPDU sub-frames received" },
+#define S_RX_HALFGI AFTER(S_RX_AGG)
+ { 5, "rxhalfgi", "rxhgi", "Half-GI frames received" },
+#define S_RX_2040 AFTER(S_RX_HALFGI)
+ { 6, "rx2040", "rx2040", "40MHz frames received" },
+#define S_RX_PRE_CRC_ERR AFTER(S_RX_2040)
+ { 11, "rxprecrcerr", "rxprecrcerr", "CRC errors for non-last A-MPDU subframes" },
+#define S_RX_POST_CRC_ERR AFTER(S_RX_PRE_CRC_ERR)
+ { 12, "rxpostcrcerr", "rxpostcrcerr", "CRC errors for last subframe in an A-MPDU" },
+#define S_RX_DECRYPT_BUSY_ERR AFTER(S_RX_POST_CRC_ERR)
+ { 10, "rxdescbusy", "rxdescbusy", "Decryption engine busy" },
+#define S_RX_HI_CHAIN AFTER(S_RX_DECRYPT_BUSY_ERR)
+ { 4, "rxhi", "rxhi", "Frames received with RX chain in high power mode" },
+#define S_TX_HTPROTECT AFTER(S_RX_HI_CHAIN)
+ { 7, "txhtprot", "txhtprot", "Frames transmitted with HT Protection" },
+#define S_RX_QEND AFTER(S_TX_HTPROTECT)
+ { 7, "rxquend", "rxquend", "Hit end of RX descriptor queue" },
+#define S_TX_TIMEOUT AFTER(S_RX_QEND)
+ { 4, "txtimeout", "TXTX", "TX Timeout" },
+#define S_TX_CSTIMEOUT AFTER(S_TX_TIMEOUT)
+ { 4, "csttimeout", "CSTX", "Carrier Sense Timeout" },
+#define S_TX_XTXOP_ERR AFTER(S_TX_CSTIMEOUT)
+ { 5, "xtxoperr", "TXOPX", "TXOP exceed" },
+#define S_TX_TIMEREXPIRED_ERR AFTER(S_TX_XTXOP_ERR)
+ { 7, "texperr", "texperr", "TX Timer expired" },
+#define S_TX_DESCCFG_ERR AFTER(S_TX_TIMEREXPIRED_ERR)
+ { 10, "desccfgerr", "desccfgerr", "TX descriptor error" },
+#define S_TX_SWRETRIES AFTER(S_TX_DESCCFG_ERR)
+ { 9, "txswretry", "txswretry", "Number of frames retransmitted in software" },
+#define S_TX_SWRETRIES_MAX AFTER(S_TX_SWRETRIES)
+ { 7, "txswmax", "txswmax", "Number of frames exceeding software retry" },
+#define S_TX_DATA_UNDERRUN AFTER(S_TX_SWRETRIES_MAX)
+ { 5, "txdataunderrun", "TXDAU", "A-MPDU TX FIFO data underrun" },
+#define S_TX_DELIM_UNDERRUN AFTER(S_TX_DATA_UNDERRUN)
+ { 5, "txdelimunderrun", "TXDEU", "A-MPDU TX Delimiter underrun" },
+#define S_TX_AGGR_OK AFTER(S_TX_DELIM_UNDERRUN)
+ { 5, "txaggrok", "TXAOK", "A-MPDU sub-frame TX attempt success" },
+#define S_TX_AGGR_FAIL AFTER(S_TX_AGGR_OK)
+ { 4, "txaggrfail", "TXAF", "A-MPDU sub-frame TX attempt failures" },
+#define S_TX_AGGR_FAILALL AFTER(S_TX_AGGR_FAIL)
+ { 7, "txaggrfailall", "TXAFALL", "A-MPDU TX frame failures" },
+#ifndef __linux__
+#define S_CABQ_XMIT AFTER(S_TX_AGGR_FAILALL)
+ { 5, "cabxmit", "cabxmit", "cabq frames transmitted" },
+#define S_CABQ_BUSY AFTER(S_CABQ_XMIT)
+ { 5, "cabqbusy", "cabqbusy", "cabq xmit overflowed beacon interval" },
+#define S_TX_NODATA AFTER(S_CABQ_BUSY)
+ { 5, "txnodata", "txnodata", "tx discarded empty frame" },
+#define S_TX_BUSDMA AFTER(S_TX_NODATA)
+ { 5, "txbusdma", "txbusdma", "tx failed for dma resrcs" },
+#define S_RX_BUSDMA AFTER(S_TX_BUSDMA)
+ { 5, "rxbusdma", "rxbusdma", "rx setup failed for dma resrcs" },
+#define S_FF_TXOK AFTER(S_RX_BUSDMA)
+#else
+#define S_FF_TXOK AFTER(S_TX_AGGR_FAILALL)
+#endif
+ { 5, "fftxok", "fftxok", "fast frames xmit successfully" },
+#define S_FF_TXERR AFTER(S_FF_TXOK)
+ { 5, "fftxerr", "fftxerr", "fast frames not xmit due to error" },
+#define S_FF_RX AFTER(S_FF_TXERR)
+ { 5, "ffrx", "ffrx", "fast frames received" },
+#define S_FF_FLUSH AFTER(S_FF_RX)
+ { 5, "ffflush", "ffflush", "fast frames flushed from staging q" },
+#define S_TX_QFULL AFTER(S_FF_FLUSH)
+ { 5, "txqfull", "txqfull", "tx discarded 'cuz queue is full" },
+#define S_ANT_DEFSWITCH AFTER(S_TX_QFULL)
+ { 5, "defsw", "defsw", "switched default/rx antenna" },
+#define S_ANT_TXSWITCH AFTER(S_ANT_DEFSWITCH)
+ { 5, "txsw", "txsw", "tx used alternate antenna" },
+#ifdef ATH_SUPPORT_ANI
+#define S_ANI_NOISE AFTER(S_ANT_TXSWITCH)
+ { 2, "ni", "NI", "noise immunity level" },
+#define S_ANI_SPUR AFTER(S_ANI_NOISE)
+ { 2, "si", "SI", "spur immunity level" },
+#define S_ANI_STEP AFTER(S_ANI_SPUR)
+ { 2, "step", "ST", "first step level" },
+#define S_ANI_OFDM AFTER(S_ANI_STEP)
+ { 4, "owsd", "OWSD", "OFDM weak signal detect" },
+#define S_ANI_CCK AFTER(S_ANI_OFDM)
+ { 4, "cwst", "CWST", "CCK weak signal threshold" },
+#define S_ANI_MAXSPUR AFTER(S_ANI_CCK)
+ { 3, "maxsi","MSI", "max spur immunity level" },
+#define S_ANI_LISTEN AFTER(S_ANI_MAXSPUR)
+ { 6, "listen","LISTEN", "listen time" },
+#define S_ANI_NIUP AFTER(S_ANI_LISTEN)
+ { 4, "ni+", "NI-", "ANI increased noise immunity" },
+#define S_ANI_NIDOWN AFTER(S_ANI_NIUP)
+ { 4, "ni-", "NI-", "ANI decrease noise immunity" },
+#define S_ANI_SIUP AFTER(S_ANI_NIDOWN)
+ { 4, "si+", "SI+", "ANI increased spur immunity" },
+#define S_ANI_SIDOWN AFTER(S_ANI_SIUP)
+ { 4, "si-", "SI-", "ANI decrease spur immunity" },
+#define S_ANI_OFDMON AFTER(S_ANI_SIDOWN)
+ { 5, "ofdm+","OFDM+", "ANI enabled OFDM weak signal detect" },
+#define S_ANI_OFDMOFF AFTER(S_ANI_OFDMON)
+ { 5, "ofdm-","OFDM-", "ANI disabled OFDM weak signal detect" },
+#define S_ANI_CCKHI AFTER(S_ANI_OFDMOFF)
+ { 5, "cck+", "CCK+", "ANI enabled CCK weak signal threshold" },
+#define S_ANI_CCKLO AFTER(S_ANI_CCKHI)
+ { 5, "cck-", "CCK-", "ANI disabled CCK weak signal threshold" },
+#define S_ANI_STEPUP AFTER(S_ANI_CCKLO)
+ { 5, "step+","STEP+", "ANI increased first step level" },
+#define S_ANI_STEPDOWN AFTER(S_ANI_STEPUP)
+ { 5, "step-","STEP-", "ANI decreased first step level" },
+#define S_ANI_OFDMERRS AFTER(S_ANI_STEPDOWN)
+ { 8, "ofdm", "OFDM", "cumulative OFDM phy error count" },
+#define S_ANI_CCKERRS AFTER(S_ANI_OFDMERRS)
+ { 8, "cck", "CCK", "cumulative CCK phy error count" },
+#define S_ANI_RESET AFTER(S_ANI_CCKERRS)
+ { 5, "reset","RESET", "ANI parameters zero'd for non-STA operation" },
+#define S_ANI_LZERO AFTER(S_ANI_RESET)
+ { 5, "lzero","LZERO", "ANI forced listen time to zero" },
+#define S_ANI_LNEG AFTER(S_ANI_LZERO)
+ { 5, "lneg", "LNEG", "ANI calculated listen time < 0" },
+#define S_MIB_ACKBAD AFTER(S_ANI_LNEG)
+ { 5, "ackbad","ACKBAD", "missing ACK's" },
+#define S_MIB_RTSBAD AFTER(S_MIB_ACKBAD)
+ { 5, "rtsbad","RTSBAD", "RTS without CTS" },
+#define S_MIB_RTSGOOD AFTER(S_MIB_RTSBAD)
+ { 5, "rtsgood","RTSGOOD", "successful RTS" },
+#define S_MIB_FCSBAD AFTER(S_MIB_RTSGOOD)
+ { 5, "fcsbad","FCSBAD", "bad FCS" },
+#define S_MIB_BEACONS AFTER(S_MIB_FCSBAD)
+ { 5, "beacons","beacons", "beacons received" },
+#define S_NODE_AVGBRSSI AFTER(S_MIB_BEACONS)
+ { 3, "avgbrssi","BSI", "average rssi (beacons only)" },
+#define S_NODE_AVGRSSI AFTER(S_NODE_AVGBRSSI)
+ { 3, "avgrssi","DSI", "average rssi (all rx'd frames)" },
+#define S_NODE_AVGARSSI AFTER(S_NODE_AVGRSSI)
+ { 3, "avgtxrssi","TSI", "average rssi (ACKs only)" },
+#define S_ANT_TX0 AFTER(S_NODE_AVGARSSI)
+#else
+#define S_ANT_TX0 AFTER(S_ANT_TXSWITCH)
+#endif /* ATH_SUPPORT_ANI */
+ { 8, "tx0", "ant0(tx)", "frames tx on antenna 0" },
+#define S_ANT_TX1 AFTER(S_ANT_TX0)
+ { 8, "tx1", "ant1(tx)", "frames tx on antenna 1" },
+#define S_ANT_TX2 AFTER(S_ANT_TX1)
+ { 8, "tx2", "ant2(tx)", "frames tx on antenna 2" },
+#define S_ANT_TX3 AFTER(S_ANT_TX2)
+ { 8, "tx3", "ant3(tx)", "frames tx on antenna 3" },
+#define S_ANT_TX4 AFTER(S_ANT_TX3)
+ { 8, "tx4", "ant4(tx)", "frames tx on antenna 4" },
+#define S_ANT_TX5 AFTER(S_ANT_TX4)
+ { 8, "tx5", "ant5(tx)", "frames tx on antenna 5" },
+#define S_ANT_TX6 AFTER(S_ANT_TX5)
+ { 8, "tx6", "ant6(tx)", "frames tx on antenna 6" },
+#define S_ANT_TX7 AFTER(S_ANT_TX6)
+ { 8, "tx7", "ant7(tx)", "frames tx on antenna 7" },
+#define S_ANT_RX0 AFTER(S_ANT_TX7)
+ { 8, "rx0", "ant0(rx)", "frames rx on antenna 0" },
+#define S_ANT_RX1 AFTER(S_ANT_RX0)
+ { 8, "rx1", "ant1(rx)", "frames rx on antenna 1" },
+#define S_ANT_RX2 AFTER(S_ANT_RX1)
+ { 8, "rx2", "ant2(rx)", "frames rx on antenna 2" },
+#define S_ANT_RX3 AFTER(S_ANT_RX2)
+ { 8, "rx3", "ant3(rx)", "frames rx on antenna 3" },
+#define S_ANT_RX4 AFTER(S_ANT_RX3)
+ { 8, "rx4", "ant4(rx)", "frames rx on antenna 4" },
+#define S_ANT_RX5 AFTER(S_ANT_RX4)
+ { 8, "rx5", "ant5(rx)", "frames rx on antenna 5" },
+#define S_ANT_RX6 AFTER(S_ANT_RX5)
+ { 8, "rx6", "ant6(rx)", "frames rx on antenna 6" },
+#define S_ANT_RX7 AFTER(S_ANT_RX6)
+ { 8, "rx7", "ant7(rx)", "frames rx on antenna 7" },
+#define S_TX_SIGNAL AFTER(S_ANT_RX7)
+ { 4, "asignal", "asig", "signal of last ack (dBm)" },
+#define S_RX_SIGNAL AFTER(S_TX_SIGNAL)
+ { 4, "signal", "sig", "avg recv signal (dBm)" },
+
+};
+#define S_PHY_MIN S_RX_PHY_UNDERRUN
+#define S_PHY_MAX S_RX_PHY_CCK_RESTART
+#define S_LAST S_ANT_TX0
+#define S_MAX S_ANT_RX7+1
+
+/*
+ * XXX fold this into the external HAL definitions! -adrian
+ */
+struct _athstats {
+ struct ath_stats ath;
+#ifdef ATH_SUPPORT_ANI
+ struct {
+ uint32_t ast_ani_niup; /* increased noise immunity */
+ uint32_t ast_ani_nidown; /* decreased noise immunity */
+ uint32_t ast_ani_spurup; /* increased spur immunity */
+ uint32_t ast_ani_spurdown; /* descreased spur immunity */
+ uint32_t ast_ani_ofdmon; /* OFDM weak signal detect on */
+ uint32_t ast_ani_ofdmoff; /* OFDM weak signal detect off*/
+ uint32_t ast_ani_cckhigh; /* CCK weak signal thr high */
+ uint32_t ast_ani_ccklow; /* CCK weak signal thr low */
+ uint32_t ast_ani_stepup; /* increased first step level */
+ uint32_t ast_ani_stepdown; /* decreased first step level */
+ uint32_t ast_ani_ofdmerrs; /* cumulative ofdm phy err cnt*/
+ uint32_t ast_ani_cckerrs; /* cumulative cck phy err cnt */
+ uint32_t ast_ani_reset; /* params zero'd for non-STA */
+ uint32_t ast_ani_lzero; /* listen time forced to zero */
+ uint32_t ast_ani_lneg; /* listen time calculated < 0 */
+ HAL_MIB_STATS ast_mibstats; /* MIB counter stats */
+ HAL_NODE_STATS ast_nodestats; /* latest rssi stats */
+ } ani_stats;
+ struct {
+ uint8_t noiseImmunityLevel;
+ uint8_t spurImmunityLevel;
+ uint8_t firstepLevel;
+ uint8_t ofdmWeakSigDetectOff;
+ uint8_t cckWeakSigThreshold;
+ uint32_t listenTime;
+ } ani_state;
+#endif
+};
+
+struct athstatfoo_p {
+ struct athstatfoo base;
+ int s;
+ int optstats;
+#define ATHSTATS_ANI 0x0001
+ struct ifreq ifr;
+ struct ath_diag atd;
+ struct _athstats cur;
+ struct _athstats total;
+};
+
+static void
+ath_setifname(struct athstatfoo *wf0, const char *ifname)
+{
+ struct athstatfoo_p *wf = (struct athstatfoo_p *) wf0;
+
+ strncpy(wf->ifr.ifr_name, ifname, sizeof (wf->ifr.ifr_name));
+#ifdef ATH_SUPPORT_ANI
+ strncpy(wf->atd.ad_name, ifname, sizeof (wf->atd.ad_name));
+ wf->optstats |= ATHSTATS_ANI;
+#endif
+}
+
+static void
+ath_zerostats(struct athstatfoo *wf0)
+{
+ struct athstatfoo_p *wf = (struct athstatfoo_p *) wf0;
+
+ if (ioctl(wf->s, SIOCZATHSTATS, &wf->ifr) < 0)
+ err(-1, wf->ifr.ifr_name);
+}
+
+static void
+ath_collect(struct athstatfoo_p *wf, struct _athstats *stats)
+{
+ wf->ifr.ifr_data = (caddr_t) &stats->ath;
+ if (ioctl(wf->s, SIOCGATHSTATS, &wf->ifr) < 0)
+ err(1, wf->ifr.ifr_name);
+#ifdef ATH_SUPPORT_ANI
+ if (wf->optstats & ATHSTATS_ANI) {
+ wf->atd.ad_id = 5;
+ wf->atd.ad_out_data = (caddr_t) &stats->ani_state;
+ wf->atd.ad_out_size = sizeof(stats->ani_state);
+ if (ioctl(wf->s, SIOCGATHDIAG, &wf->atd) < 0) {
+ warn(wf->atd.ad_name);
+ wf->optstats &= ~ATHSTATS_ANI;
+ }
+ wf->atd.ad_id = 8;
+ wf->atd.ad_out_data = (caddr_t) &stats->ani_stats;
+ wf->atd.ad_out_size = sizeof(stats->ani_stats);
+ if (ioctl(wf->s, SIOCGATHDIAG, &wf->atd) < 0)
+ warn(wf->atd.ad_name);
+ }
+#endif /* ATH_SUPPORT_ANI */
+}
+
+static void
+ath_collect_cur(struct statfoo *sf)
+{
+ struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
+
+ ath_collect(wf, &wf->cur);
+}
+
+static void
+ath_collect_tot(struct statfoo *sf)
+{
+ struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
+
+ ath_collect(wf, &wf->total);
+}
+
+static void
+ath_update_tot(struct statfoo *sf)
+{
+ struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
+
+ wf->total = wf->cur;
+}
+
+static void
+snprintrate(char b[], size_t bs, int rate)
+{
+ if (rate & IEEE80211_RATE_MCS)
+ snprintf(b, bs, "MCS%u", rate &~ IEEE80211_RATE_MCS);
+ else if (rate & 1)
+ snprintf(b, bs, "%u.5M", rate / 2);
+ else
+ snprintf(b, bs, "%uM", rate / 2);
+}
+
+static int
+ath_get_curstat(struct statfoo *sf, int s, char b[], size_t bs)
+{
+ struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
+#define STAT(x) \
+ snprintf(b, bs, "%u", wf->cur.ath.ast_##x - wf->total.ath.ast_##x); return 1
+#define PHY(x) \
+ snprintf(b, bs, "%u", wf->cur.ath.ast_rx_phy[x] - wf->total.ath.ast_rx_phy[x]); return 1
+#define ANI(x) \
+ snprintf(b, bs, "%u", wf->cur.ani_state.x); return 1
+#define ANISTAT(x) \
+ snprintf(b, bs, "%u", wf->cur.ani_stats.ast_ani_##x - wf->total.ani_stats.ast_ani_##x); return 1
+#define MIBSTAT(x) \
+ snprintf(b, bs, "%u", wf->cur.ani_stats.ast_mibstats.x - wf->total.ani_stats.ast_mibstats.x); return 1
+#define TXANT(x) \
+ snprintf(b, bs, "%u", wf->cur.ath.ast_ant_tx[x] - wf->total.ath.ast_ant_tx[x]); return 1
+#define RXANT(x) \
+ snprintf(b, bs, "%u", wf->cur.ath.ast_ant_rx[x] - wf->total.ath.ast_ant_rx[x]); return 1
+
+ switch (s) {
+ case S_INPUT:
+ snprintf(b, bs, "%lu",
+ (wf->cur.ath.ast_rx_packets - wf->total.ath.ast_rx_packets) -
+ (wf->cur.ath.ast_rx_mgt - wf->total.ath.ast_rx_mgt));
+ return 1;
+ case S_OUTPUT:
+ snprintf(b, bs, "%lu",
+ wf->cur.ath.ast_tx_packets - wf->total.ath.ast_tx_packets);
+ return 1;
+ case S_RATE:
+ snprintrate(b, bs, wf->cur.ath.ast_tx_rate);
+ return 1;
+ case S_WATCHDOG: STAT(watchdog);
+ case S_FATAL: STAT(hardware);
+ case S_BMISS: STAT(bmiss);
+ case S_BMISS_PHANTOM: STAT(bmiss_phantom);
+#ifdef S_BSTUCK
+ case S_BSTUCK: STAT(bstuck);
+#endif
+ case S_RXORN: STAT(rxorn);
+ case S_RXEOL: STAT(rxeol);
+ case S_TXURN: STAT(txurn);
+ case S_MIB: STAT(mib);
+#ifdef S_INTRCOAL
+ case S_INTRCOAL: STAT(intrcoal);
+#endif
+ case S_TX_MGMT: STAT(tx_mgmt);
+ case S_TX_DISCARD: STAT(tx_discard);
+ case S_TX_QSTOP: STAT(tx_qstop);
+ case S_TX_ENCAP: STAT(tx_encap);
+ case S_TX_NONODE: STAT(tx_nonode);
+ case S_TX_NOBUF: STAT(tx_nobuf);
+ case S_TX_NOFRAG: STAT(tx_nofrag);
+ case S_TX_NOMBUF: STAT(tx_nombuf);
+#ifdef S_TX_NOMCL
+ case S_TX_NOMCL: STAT(tx_nomcl);
+ case S_TX_LINEAR: STAT(tx_linear);
+ case S_TX_NODATA: STAT(tx_nodata);
+ case S_TX_BUSDMA: STAT(tx_busdma);
+#endif
+ case S_TX_XRETRIES: STAT(tx_xretries);
+ case S_TX_FIFOERR: STAT(tx_fifoerr);
+ case S_TX_FILTERED: STAT(tx_filtered);
+ case S_TX_SHORTRETRY: STAT(tx_shortretry);
+ case S_TX_LONGRETRY: STAT(tx_longretry);
+ case S_TX_BADRATE: STAT(tx_badrate);
+ case S_TX_NOACK: STAT(tx_noack);
+ case S_TX_RTS: STAT(tx_rts);
+ case S_TX_CTS: STAT(tx_cts);
+ case S_TX_SHORTPRE: STAT(tx_shortpre);
+ case S_TX_ALTRATE: STAT(tx_altrate);
+ case S_TX_PROTECT: STAT(tx_protect);
+ case S_TX_RAW: STAT(tx_raw);
+ case S_TX_RAW_FAIL: STAT(tx_raw_fail);
+ case S_RX_NOMBUF: STAT(rx_nombuf);
+#ifdef S_RX_BUSDMA
+ case S_RX_BUSDMA: STAT(rx_busdma);
+#endif
+ case S_RX_ORN: STAT(rx_orn);
+ case S_RX_CRC_ERR: STAT(rx_crcerr);
+ case S_RX_FIFO_ERR: STAT(rx_fifoerr);
+ case S_RX_CRYPTO_ERR: STAT(rx_badcrypt);
+ case S_RX_MIC_ERR: STAT(rx_badmic);
+ case S_RX_PHY_ERR: STAT(rx_phyerr);
+ case S_RX_PHY_UNDERRUN: PHY(HAL_PHYERR_UNDERRUN);
+ case S_RX_PHY_TIMING: PHY(HAL_PHYERR_TIMING);
+ case S_RX_PHY_PARITY: PHY(HAL_PHYERR_PARITY);
+ case S_RX_PHY_RATE: PHY(HAL_PHYERR_RATE);
+ case S_RX_PHY_LENGTH: PHY(HAL_PHYERR_LENGTH);
+ case S_RX_PHY_RADAR: PHY(HAL_PHYERR_RADAR);
+ case S_RX_PHY_SERVICE: PHY(HAL_PHYERR_SERVICE);
+ case S_RX_PHY_TOR: PHY(HAL_PHYERR_TOR);
+ case S_RX_PHY_OFDM_TIMING: PHY(HAL_PHYERR_OFDM_TIMING);
+ case S_RX_PHY_OFDM_SIGNAL_PARITY: PHY(HAL_PHYERR_OFDM_SIGNAL_PARITY);
+ case S_RX_PHY_OFDM_RATE_ILLEGAL: PHY(HAL_PHYERR_OFDM_RATE_ILLEGAL);
+ case S_RX_PHY_OFDM_POWER_DROP: PHY(HAL_PHYERR_OFDM_POWER_DROP);
+ case S_RX_PHY_OFDM_SERVICE: PHY(HAL_PHYERR_OFDM_SERVICE);
+ case S_RX_PHY_OFDM_RESTART: PHY(HAL_PHYERR_OFDM_RESTART);
+ case S_RX_PHY_CCK_TIMING: PHY(HAL_PHYERR_CCK_TIMING);
+ case S_RX_PHY_CCK_HEADER_CRC: PHY(HAL_PHYERR_CCK_HEADER_CRC);
+ case S_RX_PHY_CCK_RATE_ILLEGAL: PHY(HAL_PHYERR_CCK_RATE_ILLEGAL);
+ case S_RX_PHY_CCK_SERVICE: PHY(HAL_PHYERR_CCK_SERVICE);
+ case S_RX_PHY_CCK_RESTART: PHY(HAL_PHYERR_CCK_RESTART);
+ case S_RX_TOOSHORT: STAT(rx_tooshort);
+ case S_RX_TOOBIG: STAT(rx_toobig);
+ case S_RX_MGT: STAT(rx_mgt);
+ case S_RX_CTL: STAT(rx_ctl);
+ case S_TX_RSSI:
+ snprintf(b, bs, "%d", wf->cur.ath.ast_tx_rssi);
+ return 1;
+ case S_RX_RSSI:
+ snprintf(b, bs, "%d", wf->cur.ath.ast_rx_rssi);
+ return 1;
+ case S_BE_XMIT: STAT(be_xmit);
+ case S_BE_NOMBUF: STAT(be_nombuf);
+ case S_PER_CAL: STAT(per_cal);
+ case S_PER_CALFAIL: STAT(per_calfail);
+ case S_PER_RFGAIN: STAT(per_rfgain);
+#ifdef S_TDMA_UPDATE
+ case S_TDMA_UPDATE: STAT(tdma_update);
+ case S_TDMA_TIMERS: STAT(tdma_timers);
+ case S_TDMA_TSF: STAT(tdma_tsf);
+ case S_TDMA_TSFADJ:
+ snprintf(b, bs, "-%d/+%d",
+ wf->cur.ath.ast_tdma_tsfadjm, wf->cur.ath.ast_tdma_tsfadjp);
+ return 1;
+ case S_TDMA_ACK: STAT(tdma_ack);
+#endif
+ case S_RATE_CALLS: STAT(rate_calls);
+ case S_RATE_RAISE: STAT(rate_raise);
+ case S_RATE_DROP: STAT(rate_drop);
+ case S_ANT_DEFSWITCH: STAT(ant_defswitch);
+ case S_ANT_TXSWITCH: STAT(ant_txswitch);
+#ifdef S_ANI_NOISE
+ case S_ANI_NOISE: ANI(noiseImmunityLevel);
+ case S_ANI_SPUR: ANI(spurImmunityLevel);
+ case S_ANI_STEP: ANI(firstepLevel);
+ case S_ANI_OFDM: ANI(ofdmWeakSigDetectOff);
+ case S_ANI_CCK: ANI(cckWeakSigThreshold);
+ case S_ANI_LISTEN: ANI(listenTime);
+ case S_ANI_NIUP: ANISTAT(niup);
+ case S_ANI_NIDOWN: ANISTAT(nidown);
+ case S_ANI_SIUP: ANISTAT(spurup);
+ case S_ANI_SIDOWN: ANISTAT(spurdown);
+ case S_ANI_OFDMON: ANISTAT(ofdmon);
+ case S_ANI_OFDMOFF: ANISTAT(ofdmoff);
+ case S_ANI_CCKHI: ANISTAT(cckhigh);
+ case S_ANI_CCKLO: ANISTAT(ccklow);
+ case S_ANI_STEPUP: ANISTAT(stepup);
+ case S_ANI_STEPDOWN: ANISTAT(stepdown);
+ case S_ANI_OFDMERRS: ANISTAT(ofdmerrs);
+ case S_ANI_CCKERRS: ANISTAT(cckerrs);
+ case S_ANI_RESET: ANISTAT(reset);
+ case S_ANI_LZERO: ANISTAT(lzero);
+ case S_ANI_LNEG: ANISTAT(lneg);
+ case S_MIB_ACKBAD: MIBSTAT(ackrcv_bad);
+ case S_MIB_RTSBAD: MIBSTAT(rts_bad);
+ case S_MIB_RTSGOOD: MIBSTAT(rts_good);
+ case S_MIB_FCSBAD: MIBSTAT(fcs_bad);
+ case S_MIB_BEACONS: MIBSTAT(beacons);
+ case S_NODE_AVGBRSSI:
+ snprintf(b, bs, "%u",
+ HAL_RSSI(wf->cur.ani_stats.ast_nodestats.ns_avgbrssi));
+ return 1;
+ case S_NODE_AVGRSSI:
+ snprintf(b, bs, "%u",
+ HAL_RSSI(wf->cur.ani_stats.ast_nodestats.ns_avgrssi));
+ return 1;
+ case S_NODE_AVGARSSI:
+ snprintf(b, bs, "%u",
+ HAL_RSSI(wf->cur.ani_stats.ast_nodestats.ns_avgtxrssi));
+ return 1;
+#endif
+ case S_ANT_TX0: TXANT(0);
+ case S_ANT_TX1: TXANT(1);
+ case S_ANT_TX2: TXANT(2);
+ case S_ANT_TX3: TXANT(3);
+ case S_ANT_TX4: TXANT(4);
+ case S_ANT_TX5: TXANT(5);
+ case S_ANT_TX6: TXANT(6);
+ case S_ANT_TX7: TXANT(7);
+ case S_ANT_RX0: RXANT(0);
+ case S_ANT_RX1: RXANT(1);
+ case S_ANT_RX2: RXANT(2);
+ case S_ANT_RX3: RXANT(3);
+ case S_ANT_RX4: RXANT(4);
+ case S_ANT_RX5: RXANT(5);
+ case S_ANT_RX6: RXANT(6);
+ case S_ANT_RX7: RXANT(7);
+#ifdef S_CABQ_XMIT
+ case S_CABQ_XMIT: STAT(cabq_xmit);
+ case S_CABQ_BUSY: STAT(cabq_busy);
+#endif
+ case S_FF_TXOK: STAT(ff_txok);
+ case S_FF_TXERR: STAT(ff_txerr);
+ case S_FF_RX: STAT(ff_rx);
+ case S_FF_FLUSH: STAT(ff_flush);
+ case S_TX_QFULL: STAT(tx_qfull);
+ case S_RX_NOISE:
+ snprintf(b, bs, "%d", wf->cur.ath.ast_rx_noise);
+ return 1;
+ case S_TX_SIGNAL:
+ snprintf(b, bs, "%d",
+ wf->cur.ath.ast_tx_rssi + wf->cur.ath.ast_rx_noise);
+ return 1;
+ case S_RX_SIGNAL:
+ snprintf(b, bs, "%d",
+ wf->cur.ath.ast_rx_rssi + wf->cur.ath.ast_rx_noise);
+ return 1;
+ case S_RX_AGG: STAT(rx_agg);
+ case S_RX_HALFGI: STAT(rx_halfgi);
+ case S_RX_2040: STAT(rx_2040);
+ case S_RX_PRE_CRC_ERR: STAT(rx_pre_crc_err);
+ case S_RX_POST_CRC_ERR: STAT(rx_post_crc_err);
+ case S_RX_DECRYPT_BUSY_ERR: STAT(rx_decrypt_busy_err);
+ case S_RX_HI_CHAIN: STAT(rx_hi_rx_chain);
+ case S_TX_HTPROTECT: STAT(tx_htprotect);
+ case S_RX_QEND: STAT(rx_hitqueueend);
+ case S_TX_TIMEOUT: STAT(tx_timeout);
+ case S_TX_CSTIMEOUT: STAT(tx_cst);
+ case S_TX_XTXOP_ERR: STAT(tx_xtxop);
+ case S_TX_TIMEREXPIRED_ERR: STAT(tx_timerexpired);
+ case S_TX_DESCCFG_ERR: STAT(tx_desccfgerr);
+ case S_TX_SWRETRIES: STAT(tx_swretries);
+ case S_TX_SWRETRIES_MAX: STAT(tx_swretrymax);
+ case S_TX_DATA_UNDERRUN: STAT(tx_data_underrun);
+ case S_TX_DELIM_UNDERRUN: STAT(tx_delim_underrun);
+ case S_TX_AGGR_OK: STAT(tx_aggr_ok);
+ case S_TX_AGGR_FAIL: STAT(tx_aggr_fail);
+ case S_TX_AGGR_FAILALL: STAT(tx_aggr_failall);
+ }
+ b[0] = '\0';
+ return 0;
+#undef RXANT
+#undef TXANT
+#undef ANI
+#undef ANISTAT
+#undef MIBSTAT
+#undef PHY
+#undef STAT
+}
+
+static int
+ath_get_totstat(struct statfoo *sf, int s, char b[], size_t bs)
+{
+ struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
+#define STAT(x) \
+ snprintf(b, bs, "%u", wf->total.ath.ast_##x); return 1
+#define PHY(x) \
+ snprintf(b, bs, "%u", wf->total.ath.ast_rx_phy[x]); return 1
+#define ANI(x) \
+ snprintf(b, bs, "%u", wf->total.ani_state.x); return 1
+#define ANISTAT(x) \
+ snprintf(b, bs, "%u", wf->total.ani_stats.ast_ani_##x); return 1
+#define MIBSTAT(x) \
+ snprintf(b, bs, "%u", wf->total.ani_stats.ast_mibstats.x); return 1
+#define TXANT(x) \
+ snprintf(b, bs, "%u", wf->total.ath.ast_ant_tx[x]); return 1
+#define RXANT(x) \
+ snprintf(b, bs, "%u", wf->total.ath.ast_ant_rx[x]); return 1
+
+ switch (s) {
+ case S_INPUT:
+ snprintf(b, bs, "%lu",
+ wf->total.ath.ast_rx_packets - wf->total.ath.ast_rx_mgt);
+ return 1;
+ case S_OUTPUT:
+ snprintf(b, bs, "%lu", wf->total.ath.ast_tx_packets);
+ return 1;
+ case S_RATE:
+ snprintrate(b, bs, wf->total.ath.ast_tx_rate);
+ return 1;
+ case S_WATCHDOG: STAT(watchdog);
+ case S_FATAL: STAT(hardware);
+ case S_BMISS: STAT(bmiss);
+ case S_BMISS_PHANTOM: STAT(bmiss_phantom);
+#ifdef S_BSTUCK
+ case S_BSTUCK: STAT(bstuck);
+#endif
+ case S_RXORN: STAT(rxorn);
+ case S_RXEOL: STAT(rxeol);
+ case S_TXURN: STAT(txurn);
+ case S_MIB: STAT(mib);
+#ifdef S_INTRCOAL
+ case S_INTRCOAL: STAT(intrcoal);
+#endif
+ case S_TX_MGMT: STAT(tx_mgmt);
+ case S_TX_DISCARD: STAT(tx_discard);
+ case S_TX_QSTOP: STAT(tx_qstop);
+ case S_TX_ENCAP: STAT(tx_encap);
+ case S_TX_NONODE: STAT(tx_nonode);
+ case S_TX_NOBUF: STAT(tx_nobuf);
+ case S_TX_NOFRAG: STAT(tx_nofrag);
+ case S_TX_NOMBUF: STAT(tx_nombuf);
+#ifdef S_TX_NOMCL
+ case S_TX_NOMCL: STAT(tx_nomcl);
+ case S_TX_LINEAR: STAT(tx_linear);
+ case S_TX_NODATA: STAT(tx_nodata);
+ case S_TX_BUSDMA: STAT(tx_busdma);
+#endif
+ case S_TX_XRETRIES: STAT(tx_xretries);
+ case S_TX_FIFOERR: STAT(tx_fifoerr);
+ case S_TX_FILTERED: STAT(tx_filtered);
+ case S_TX_SHORTRETRY: STAT(tx_shortretry);
+ case S_TX_LONGRETRY: STAT(tx_longretry);
+ case S_TX_BADRATE: STAT(tx_badrate);
+ case S_TX_NOACK: STAT(tx_noack);
+ case S_TX_RTS: STAT(tx_rts);
+ case S_TX_CTS: STAT(tx_cts);
+ case S_TX_SHORTPRE: STAT(tx_shortpre);
+ case S_TX_ALTRATE: STAT(tx_altrate);
+ case S_TX_PROTECT: STAT(tx_protect);
+ case S_TX_RAW: STAT(tx_raw);
+ case S_TX_RAW_FAIL: STAT(tx_raw_fail);
+ case S_RX_NOMBUF: STAT(rx_nombuf);
+#ifdef S_RX_BUSDMA
+ case S_RX_BUSDMA: STAT(rx_busdma);
+#endif
+ case S_RX_ORN: STAT(rx_orn);
+ case S_RX_CRC_ERR: STAT(rx_crcerr);
+ case S_RX_FIFO_ERR: STAT(rx_fifoerr);
+ case S_RX_CRYPTO_ERR: STAT(rx_badcrypt);
+ case S_RX_MIC_ERR: STAT(rx_badmic);
+ case S_RX_PHY_ERR: STAT(rx_phyerr);
+ case S_RX_PHY_UNDERRUN: PHY(HAL_PHYERR_UNDERRUN);
+ case S_RX_PHY_TIMING: PHY(HAL_PHYERR_TIMING);
+ case S_RX_PHY_PARITY: PHY(HAL_PHYERR_PARITY);
+ case S_RX_PHY_RATE: PHY(HAL_PHYERR_RATE);
+ case S_RX_PHY_LENGTH: PHY(HAL_PHYERR_LENGTH);
+ case S_RX_PHY_RADAR: PHY(HAL_PHYERR_RADAR);
+ case S_RX_PHY_SERVICE: PHY(HAL_PHYERR_SERVICE);
+ case S_RX_PHY_TOR: PHY(HAL_PHYERR_TOR);
+ case S_RX_PHY_OFDM_TIMING: PHY(HAL_PHYERR_OFDM_TIMING);
+ case S_RX_PHY_OFDM_SIGNAL_PARITY: PHY(HAL_PHYERR_OFDM_SIGNAL_PARITY);
+ case S_RX_PHY_OFDM_RATE_ILLEGAL: PHY(HAL_PHYERR_OFDM_RATE_ILLEGAL);
+ case S_RX_PHY_OFDM_POWER_DROP: PHY(HAL_PHYERR_OFDM_POWER_DROP);
+ case S_RX_PHY_OFDM_SERVICE: PHY(HAL_PHYERR_OFDM_SERVICE);
+ case S_RX_PHY_OFDM_RESTART: PHY(HAL_PHYERR_OFDM_RESTART);
+ case S_RX_PHY_CCK_TIMING: PHY(HAL_PHYERR_CCK_TIMING);
+ case S_RX_PHY_CCK_HEADER_CRC: PHY(HAL_PHYERR_CCK_HEADER_CRC);
+ case S_RX_PHY_CCK_RATE_ILLEGAL: PHY(HAL_PHYERR_CCK_RATE_ILLEGAL);
+ case S_RX_PHY_CCK_SERVICE: PHY(HAL_PHYERR_CCK_SERVICE);
+ case S_RX_PHY_CCK_RESTART: PHY(HAL_PHYERR_CCK_RESTART);
+ case S_RX_TOOSHORT: STAT(rx_tooshort);
+ case S_RX_TOOBIG: STAT(rx_toobig);
+ case S_RX_MGT: STAT(rx_mgt);
+ case S_RX_CTL: STAT(rx_ctl);
+ case S_TX_RSSI:
+ snprintf(b, bs, "%d", wf->total.ath.ast_tx_rssi);
+ return 1;
+ case S_RX_RSSI:
+ snprintf(b, bs, "%d", wf->total.ath.ast_rx_rssi);
+ return 1;
+ case S_BE_XMIT: STAT(be_xmit);
+ case S_BE_NOMBUF: STAT(be_nombuf);
+ case S_PER_CAL: STAT(per_cal);
+ case S_PER_CALFAIL: STAT(per_calfail);
+ case S_PER_RFGAIN: STAT(per_rfgain);
+#ifdef S_TDMA_UPDATE
+ case S_TDMA_UPDATE: STAT(tdma_update);
+ case S_TDMA_TIMERS: STAT(tdma_timers);
+ case S_TDMA_TSF: STAT(tdma_tsf);
+ case S_TDMA_TSFADJ:
+ snprintf(b, bs, "-%d/+%d",
+ wf->total.ath.ast_tdma_tsfadjm,
+ wf->total.ath.ast_tdma_tsfadjp);
+ return 1;
+ case S_TDMA_ACK: STAT(tdma_ack);
+#endif
+ case S_RATE_CALLS: STAT(rate_calls);
+ case S_RATE_RAISE: STAT(rate_raise);
+ case S_RATE_DROP: STAT(rate_drop);
+ case S_ANT_DEFSWITCH: STAT(ant_defswitch);
+ case S_ANT_TXSWITCH: STAT(ant_txswitch);
+#ifdef S_ANI_NOISE
+ case S_ANI_NOISE: ANI(noiseImmunityLevel);
+ case S_ANI_SPUR: ANI(spurImmunityLevel);
+ case S_ANI_STEP: ANI(firstepLevel);
+ case S_ANI_OFDM: ANI(ofdmWeakSigDetectOff);
+ case S_ANI_CCK: ANI(cckWeakSigThreshold);
+ case S_ANI_LISTEN: ANI(listenTime);
+ case S_ANI_NIUP: ANISTAT(niup);
+ case S_ANI_NIDOWN: ANISTAT(nidown);
+ case S_ANI_SIUP: ANISTAT(spurup);
+ case S_ANI_SIDOWN: ANISTAT(spurdown);
+ case S_ANI_OFDMON: ANISTAT(ofdmon);
+ case S_ANI_OFDMOFF: ANISTAT(ofdmoff);
+ case S_ANI_CCKHI: ANISTAT(cckhigh);
+ case S_ANI_CCKLO: ANISTAT(ccklow);
+ case S_ANI_STEPUP: ANISTAT(stepup);
+ case S_ANI_STEPDOWN: ANISTAT(stepdown);
+ case S_ANI_OFDMERRS: ANISTAT(ofdmerrs);
+ case S_ANI_CCKERRS: ANISTAT(cckerrs);
+ case S_ANI_RESET: ANISTAT(reset);
+ case S_ANI_LZERO: ANISTAT(lzero);
+ case S_ANI_LNEG: ANISTAT(lneg);
+ case S_MIB_ACKBAD: MIBSTAT(ackrcv_bad);
+ case S_MIB_RTSBAD: MIBSTAT(rts_bad);
+ case S_MIB_RTSGOOD: MIBSTAT(rts_good);
+ case S_MIB_FCSBAD: MIBSTAT(fcs_bad);
+ case S_MIB_BEACONS: MIBSTAT(beacons);
+ case S_NODE_AVGBRSSI:
+ snprintf(b, bs, "%u",
+ HAL_RSSI(wf->total.ani_stats.ast_nodestats.ns_avgbrssi));
+ return 1;
+ case S_NODE_AVGRSSI:
+ snprintf(b, bs, "%u",
+ HAL_RSSI(wf->total.ani_stats.ast_nodestats.ns_avgrssi));
+ return 1;
+ case S_NODE_AVGARSSI:
+ snprintf(b, bs, "%u",
+ HAL_RSSI(wf->total.ani_stats.ast_nodestats.ns_avgtxrssi));
+ return 1;
+#endif
+ case S_ANT_TX0: TXANT(0);
+ case S_ANT_TX1: TXANT(1);
+ case S_ANT_TX2: TXANT(2);
+ case S_ANT_TX3: TXANT(3);
+ case S_ANT_TX4: TXANT(4);
+ case S_ANT_TX5: TXANT(5);
+ case S_ANT_TX6: TXANT(6);
+ case S_ANT_TX7: TXANT(7);
+ case S_ANT_RX0: RXANT(0);
+ case S_ANT_RX1: RXANT(1);
+ case S_ANT_RX2: RXANT(2);
+ case S_ANT_RX3: RXANT(3);
+ case S_ANT_RX4: RXANT(4);
+ case S_ANT_RX5: RXANT(5);
+ case S_ANT_RX6: RXANT(6);
+ case S_ANT_RX7: RXANT(7);
+#ifdef S_CABQ_XMIT
+ case S_CABQ_XMIT: STAT(cabq_xmit);
+ case S_CABQ_BUSY: STAT(cabq_busy);
+#endif
+ case S_FF_TXOK: STAT(ff_txok);
+ case S_FF_TXERR: STAT(ff_txerr);
+ case S_FF_RX: STAT(ff_rx);
+ case S_FF_FLUSH: STAT(ff_flush);
+ case S_TX_QFULL: STAT(tx_qfull);
+ case S_RX_NOISE:
+ snprintf(b, bs, "%d", wf->total.ath.ast_rx_noise);
+ return 1;
+ case S_TX_SIGNAL:
+ snprintf(b, bs, "%d",
+ wf->total.ath.ast_tx_rssi + wf->total.ath.ast_rx_noise);
+ return 1;
+ case S_RX_SIGNAL:
+ snprintf(b, bs, "%d",
+ wf->total.ath.ast_rx_rssi + wf->total.ath.ast_rx_noise);
+ return 1;
+ case S_RX_AGG: STAT(rx_agg);
+ case S_RX_HALFGI: STAT(rx_halfgi);
+ case S_RX_2040: STAT(rx_2040);
+ case S_RX_PRE_CRC_ERR: STAT(rx_pre_crc_err);
+ case S_RX_POST_CRC_ERR: STAT(rx_post_crc_err);
+ case S_RX_DECRYPT_BUSY_ERR: STAT(rx_decrypt_busy_err);
+ case S_RX_HI_CHAIN: STAT(rx_hi_rx_chain);
+ case S_TX_HTPROTECT: STAT(tx_htprotect);
+ case S_RX_QEND: STAT(rx_hitqueueend);
+ case S_TX_TIMEOUT: STAT(tx_timeout);
+ case S_TX_CSTIMEOUT: STAT(tx_cst);
+ case S_TX_XTXOP_ERR: STAT(tx_xtxop);
+ case S_TX_TIMEREXPIRED_ERR: STAT(tx_timerexpired);
+ case S_TX_DESCCFG_ERR: STAT(tx_desccfgerr);
+ case S_TX_SWRETRIES: STAT(tx_swretries);
+ case S_TX_SWRETRIES_MAX: STAT(tx_swretrymax);
+ case S_TX_DATA_UNDERRUN: STAT(tx_data_underrun);
+ case S_TX_DELIM_UNDERRUN: STAT(tx_delim_underrun);
+ case S_TX_AGGR_OK: STAT(tx_aggr_ok);
+ case S_TX_AGGR_FAIL: STAT(tx_aggr_fail);
+ case S_TX_AGGR_FAILALL: STAT(tx_aggr_failall);
+ }
+ b[0] = '\0';
+ return 0;
+#undef RXANT
+#undef TXANT
+#undef ANI
+#undef ANISTAT
+#undef MIBSTAT
+#undef PHY
+#undef STAT
+}
+
+static void
+ath_print_verbose(struct statfoo *sf, FILE *fd)
+{
+ struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
+#define isphyerr(i) (S_PHY_MIN <= i && i <= S_PHY_MAX)
+ const struct fmt *f;
+ char s[32];
+ const char *indent;
+ int i, width;
+
+ width = 0;
+ for (i = 0; i < S_LAST; i++) {
+ f = &sf->stats[i];
+ if (!isphyerr(i) && f->width > width)
+ width = f->width;
+ }
+ for (i = 0; i < S_LAST; i++) {
+ if (ath_get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) {
+ if (isphyerr(i))
+ indent = " ";
+ else
+ indent = "";
+ fprintf(fd, "%s%-*s %s\n", indent, width, s, athstats[i].desc);
+ }
+ }
+ fprintf(fd, "Antenna profile:\n");
+ for (i = 0; i < 8; i++)
+ if (wf->total.ath.ast_ant_rx[i] || wf->total.ath.ast_ant_tx[i])
+ fprintf(fd, "[%u] tx %8u rx %8u\n", i,
+ wf->total.ath.ast_ant_tx[i],
+ wf->total.ath.ast_ant_rx[i]);
+#undef isphyerr
+}
+
+STATFOO_DEFINE_BOUNCE(athstatfoo)
+
+struct athstatfoo *
+athstats_new(const char *ifname, const char *fmtstring)
+{
+#define N(a) (sizeof(a) / sizeof(a[0]))
+ struct athstatfoo_p *wf;
+
+ wf = calloc(1, sizeof(struct athstatfoo_p));
+ if (wf != NULL) {
+ statfoo_init(&wf->base.base, "athstats", athstats, N(athstats));
+ /* override base methods */
+ wf->base.base.collect_cur = ath_collect_cur;
+ wf->base.base.collect_tot = ath_collect_tot;
+ wf->base.base.get_curstat = ath_get_curstat;
+ wf->base.base.get_totstat = ath_get_totstat;
+ wf->base.base.update_tot = ath_update_tot;
+ wf->base.base.print_verbose = ath_print_verbose;
+
+ /* setup bounce functions for public methods */
+ STATFOO_BOUNCE(wf, athstatfoo);
+
+ /* setup our public methods */
+ wf->base.setifname = ath_setifname;
+#if 0
+ wf->base.setstamac = wlan_setstamac;
+#endif
+ wf->base.zerostats = ath_zerostats;
+ wf->s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (wf->s < 0)
+ err(1, "socket");
+
+ ath_setifname(&wf->base, ifname);
+ wf->base.setfmt(&wf->base, fmtstring);
+ }
+ return &wf->base;
+#undef N
+}
diff --git a/tools/tools/ath/athstats/athstats.h b/tools/tools/ath/athstats/athstats.h
new file mode 100644
index 000000000000..cfd44ca7fb1b
--- /dev/null
+++ b/tools/tools/ath/athstats/athstats.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _ATHSTATS_H_
+#define _ATHSTATS_H_
+
+#include "statfoo.h"
+
+/*
+ * ath statistics class.
+ */
+struct athstatfoo {
+ struct statfoo base;
+
+ STATFOO_DECL_METHODS(struct athstatfoo *);
+
+ /* set the network interface name for collection */
+ void (*setifname)(struct athstatfoo *, const char *ifname);
+ /* set the mac address of the associated station/ap */
+ void (*setstamac)(struct athstatfoo *, const uint8_t mac[]);
+ /* zero in-kernel statistics */
+ void (*zerostats)(struct athstatfoo *);
+};
+
+struct athstatfoo *athstats_new(const char *ifname, const char *fmtstring);
+#endif /* _ATHSTATS_H_ */
diff --git a/tools/tools/ath/athstats/main.c b/tools/tools/ath/athstats/main.c
new file mode 100644
index 000000000000..489c0bd796f6
--- /dev/null
+++ b/tools/tools/ath/athstats/main.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Simple Atheros-specific tool to inspect and monitor network traffic
+ * statistics.
+ *
+ * athstats [-i interface] [-bz] [-l] [-o fmtstring] [interval]
+ *
+ * (default interface is ath0). If interval is specified a rolling output
+ * a la netstat -i is displayed every interval seconds. The format of
+ * the rolling display can be controlled a la ps. The -l option will
+ * print a list of all possible statistics for use with the -o option.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <err.h>
+
+#include "athstats.h"
+
+static struct {
+ const char *tag;
+ const char *fmt;
+} tags[] = {
+ { "default",
+ "input,output,altrate,short,long,xretry,crcerr,crypt,phyerr,rssi,rate"
+ },
+ { "ani",
+ "avgbrssi,avgrssi,avgtxrssi,NI,SI,step,owsd,cwst,NI+,NI-,SI+,SI-,OFDM,CCK,LISTEN"
+ },
+ { "tdma",
+ "input,output,bexmit,tdmau,tdmadj,crcerr,phyerr,phytor,rssi,noise,rate"
+ },
+};
+
+static const char *
+getfmt(const char *tag)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ int i;
+ for (i = 0; i < N(tags); i++)
+ if (strcasecmp(tags[i].tag, tag) == 0)
+ return tags[i].fmt;
+ return tag;
+#undef N
+}
+
+static int signalled;
+
+static void
+catchalarm(int signo __unused)
+{
+ signalled = 1;
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct athstatfoo *wf;
+ const char *ifname;
+ int c, banner = 1;
+
+ ifname = getenv("ATH");
+ if (ifname == NULL)
+ ifname = "ath0";
+ wf = athstats_new(ifname, getfmt("default"));
+ while ((c = getopt(argc, argv, "bi:lo:z")) != -1) {
+ switch (c) {
+ case 'b':
+ banner = 0;
+ break;
+ case 'i':
+ wf->setifname(wf, optarg);
+ break;
+ case 'l':
+ wf->print_fields(wf, stdout);
+ return 0;
+ case 'o':
+ wf->setfmt(wf, getfmt(optarg));
+ break;
+ case 'z':
+ wf->zerostats(wf);
+ break;
+ default:
+ errx(-1, "usage: %s [-a] [-i ifname] [-l] [-o fmt] [-z] [interval]\n", argv[0]);
+ /*NOTREACHED*/
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 0) {
+ u_long interval = strtoul(argv[0], NULL, 0);
+ int line, omask;
+
+ if (interval < 1)
+ interval = 1;
+ signal(SIGALRM, catchalarm);
+ signalled = 0;
+ alarm(interval);
+ banner:
+ if (banner)
+ wf->print_header(wf, stdout);
+ line = 0;
+ loop:
+ if (line != 0) {
+ wf->collect_cur(wf);
+ wf->print_current(wf, stdout);
+ wf->update_tot(wf);
+ } else {
+ wf->collect_tot(wf);
+ wf->print_total(wf, stdout);
+ }
+ fflush(stdout);
+ omask = sigblock(sigmask(SIGALRM));
+ if (!signalled)
+ sigpause(0);
+ sigsetmask(omask);
+ signalled = 0;
+ alarm(interval);
+ line++;
+ if (line == 21) /* XXX tty line count */
+ goto banner;
+ else
+ goto loop;
+ /*NOTREACHED*/
+ } else {
+ wf->collect_tot(wf);
+ wf->print_verbose(wf, stdout);
+ }
+ return 0;
+}
diff --git a/tools/tools/ath/athstats/statfoo.c b/tools/tools/ath/athstats/statfoo.c
new file mode 100644
index 000000000000..eb39e25bbab8
--- /dev/null
+++ b/tools/tools/ath/athstats/statfoo.c
@@ -0,0 +1,206 @@
+/*-
+ * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "statfoo.h"
+
+static void
+statfoo_setfmt(struct statfoo *sf, const char *fmt0)
+{
+#define N(a) (sizeof(a)/sizeof(a[0]))
+ char fmt[4096];
+ char *fp, *tok;
+ int i, j;
+
+ j = 0;
+ strlcpy(fmt, fmt0, sizeof(fmt));
+ for (fp = fmt; (tok = strsep(&fp, ", ")) != NULL;) {
+ for (i = 0; i < sf->nstats; i++)
+ if (strcasecmp(tok, sf->stats[i].name) == 0)
+ break;
+ if (i >= sf->nstats) {
+ fprintf(stderr, "%s: unknown statistic name \"%s\" "
+ "skipped\n", sf->name, tok);
+ continue;
+ }
+ if (j+3 > sizeof(sf->fmts)) {
+ fprintf(stderr, "%s: not enough room for all stats; "
+ "stopped at %s\n", sf->name, tok);
+ break;
+ }
+ if (j != 0)
+ sf->fmts[j++] = ' ';
+ sf->fmts[j++] = FMTS_IS_STAT;
+ sf->fmts[j++] = i & 0xff;
+ sf->fmts[j++] = (i >> 8) & 0xff;
+ }
+ sf->fmts[j] = '\0';
+#undef N
+}
+
+static void
+statfoo_collect(struct statfoo *sf)
+{
+ fprintf(stderr, "%s: don't know how to collect data\n", sf->name);
+}
+
+static void
+statfoo_update_tot(struct statfoo *sf)
+{
+ fprintf(stderr, "%s: don't know how to update total data\n", sf->name);
+}
+
+static int
+statfoo_get(struct statfoo *sf, int s, char b[], size_t bs)
+{
+ fprintf(stderr, "%s: don't know how to get stat #%u\n", sf->name, s);
+ return 0;
+}
+
+static void
+statfoo_print_header(struct statfoo *sf, FILE *fd)
+{
+ const unsigned char *cp;
+ int i;
+ const struct fmt *f;
+
+ for (cp = sf->fmts; *cp != '\0'; cp++) {
+ if (*cp == FMTS_IS_STAT) {
+ i = *(++cp);
+ i |= ((int) *(++cp)) << 8;
+ f = &sf->stats[i];
+ fprintf(fd, "%*s", f->width, f->label);
+ } else
+ putc(*cp, fd);
+ }
+ putc('\n', fd);
+}
+
+static void
+statfoo_print_current(struct statfoo *sf, FILE *fd)
+{
+ char buf[32];
+ const unsigned char *cp;
+ int i;
+ const struct fmt *f;
+
+ for (cp = sf->fmts; *cp != '\0'; cp++) {
+ if (*cp == FMTS_IS_STAT) {
+ i = *(++cp);
+ i |= ((int) *(++cp)) << 8;
+ f = &sf->stats[i];
+ if (sf->get_curstat(sf, i, buf, sizeof(buf)))
+ fprintf(fd, "%*s", f->width, buf);
+ } else
+ putc(*cp, fd);
+ }
+ putc('\n', fd);
+}
+
+static void
+statfoo_print_total(struct statfoo *sf, FILE *fd)
+{
+ char buf[32];
+ const unsigned char *cp;
+ const struct fmt *f;
+ int i;
+
+ for (cp = sf->fmts; *cp != '\0'; cp++) {
+ if (*cp == FMTS_IS_STAT) {
+ i = *(++cp);
+ i |= ((int) *(++cp)) << 8;
+ f = &sf->stats[i];
+ if (sf->get_totstat(sf, i, buf, sizeof(buf)))
+ fprintf(fd, "%*s", f->width, buf);
+ } else
+ putc(*cp, fd);
+ }
+ putc('\n', fd);
+}
+
+static void
+statfoo_print_verbose(struct statfoo *sf, FILE *fd)
+{
+ const struct fmt *f;
+ char s[32];
+ int i, width;
+
+ width = 0;
+ for (i = 0; i < sf->nstats; i++) {
+ f = &sf->stats[i];
+ if (f->width > width)
+ width = f->width;
+ }
+ for (i = 0; i < sf->nstats; i++) {
+ f = &sf->stats[i];
+ if (sf->get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0"))
+ fprintf(fd, "%-*s %s\n", width, s, f->desc);
+ }
+}
+
+static void
+statfoo_print_fields(struct statfoo *sf, FILE *fd)
+{
+ int i, w, width;
+
+ width = 0;
+ for (i = 0; i < sf->nstats; i++) {
+ w = strlen(sf->stats[i].name);
+ if (w > width)
+ width = w;
+ }
+ for (i = 0; i < sf->nstats; i++) {
+ const struct fmt *f = &sf->stats[i];
+ if (f->width != 0)
+ fprintf(fd, "%-*s %s\n", width, f->name, f->desc);
+ }
+}
+
+void
+statfoo_init(struct statfoo *sf, const char *name, const struct fmt *stats, int nstats)
+{
+ sf->name = name;
+ sf->stats = stats;
+ sf->nstats = nstats;
+ sf->setfmt = statfoo_setfmt;
+ sf->collect_cur = statfoo_collect;
+ sf->collect_tot = statfoo_collect;
+ sf->update_tot = statfoo_update_tot;
+ sf->get_curstat = statfoo_get;
+ sf->get_totstat = statfoo_get;
+ sf->print_header = statfoo_print_header;
+ sf->print_current = statfoo_print_current;
+ sf->print_total = statfoo_print_total;
+ sf->print_verbose = statfoo_print_verbose;
+ sf->print_fields = statfoo_print_fields;
+}
diff --git a/tools/tools/ath/athstats/statfoo.h b/tools/tools/ath/athstats/statfoo.h
new file mode 100644
index 000000000000..849a271913cc
--- /dev/null
+++ b/tools/tools/ath/athstats/statfoo.h
@@ -0,0 +1,128 @@
+/*-
+ * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _STATFOO_H_
+#define _STATFOO_H_
+/*
+ * Base class for managing+displaying periodically collected statistics.
+ */
+
+/*
+ * Statistic definition/description. The are defined
+ * for stats that correspond 1-1 w/ a collected stat
+ * and for stats that are calculated indirectly.
+ */
+struct fmt {
+ int width; /* printed field width */
+ const char* name; /* stat field name referenced by user */
+ const char* label; /* printed header label */
+ const char* desc; /* verbose description */
+};
+
+#define STATFOO_DECL_METHODS(_p) \
+ /* set the format of the statistics to display */ \
+ void (*setfmt)(_p, const char *); \
+ /* collect+store ``current statistics'' */ \
+ void (*collect_cur)(_p); \
+ /* collect+store ``total statistics'' */ \
+ void (*collect_tot)(_p); \
+ /* update ``total statistics'' if necessary from current */ \
+ void (*update_tot)(_p); \
+ /* format a statistic from the current stats */ \
+ int (*get_curstat)(_p, int, char [], size_t); \
+ /* format a statistic from the total stats */ \
+ int (*get_totstat)(_p, int, char [], size_t); \
+ /* print field headers terminated by a \n */ \
+ void (*print_header)(_p, FILE *); \
+ /* print current statistics terminated by a \n */ \
+ void (*print_current)(_p, FILE *); \
+ /* print total statistics terminated by a \n */ \
+ void (*print_total)(_p, FILE *); \
+ /* print total statistics in a verbose (1 stat/line) format */ \
+ void (*print_verbose)(_p, FILE *); \
+ /* print available statistics */ \
+ void (*print_fields)(_p, FILE *)
+
+/*
+ * Statistics base class. This class is not usable; only
+ * classes derived from it are useful.
+ */
+struct statfoo {
+ const char *name; /* statistics name, e.g. wlanstats */
+ const struct fmt *stats; /* statistics in class */
+ int nstats; /* number of stats */
+#define FMTS_IS_STAT 0x80 /* the following two bytes are the stat id */
+ unsigned char fmts[4096]; /* private: compiled stats to display */
+
+ STATFOO_DECL_METHODS(struct statfoo *);
+};
+
+void statfoo_init(struct statfoo *, const char *name,
+ const struct fmt *stats, int nstats);
+
+#define STATFOO_DEFINE_BOUNCE(_t) \
+static void _t##_setfmt(struct _t *wf, const char *fmt0) \
+ { wf->base.setfmt(&wf->base, fmt0); } \
+static void _t##_collect_cur(struct _t *wf) \
+ { wf->base.collect_cur(&wf->base); } \
+static void _t##_collect_tot(struct _t *wf) \
+ { wf->base.collect_tot(&wf->base); } \
+static void _t##_update_tot(struct _t *wf) \
+ { wf->base.update_tot(&wf->base); } \
+static int _t##_get_curstat(struct _t *wf, int s, char b[], size_t bs) \
+ { return wf->base.get_curstat(&wf->base, s, b, bs); } \
+static int _t##_get_totstat(struct _t *wf, int s, char b[], size_t bs) \
+ { return wf->base.get_totstat(&wf->base, s, b, bs); } \
+static void _t##_print_header(struct _t *wf, FILE *fd) \
+ { wf->base.print_header(&wf->base, fd); } \
+static void _t##_print_current(struct _t *wf, FILE *fd) \
+ { wf->base.print_current(&wf->base, fd); } \
+static void _t##_print_total(struct _t *wf, FILE *fd) \
+ { wf->base.print_total(&wf->base, fd); } \
+static void _t##_print_verbose(struct _t *wf, FILE *fd) \
+ { wf->base.print_verbose(&wf->base, fd); } \
+static void _t##_print_fields(struct _t *wf, FILE *fd) \
+ { wf->base.print_fields(&wf->base, fd); }
+
+#define STATFOO_BOUNCE(_p, _t) do { \
+ _p->base.setfmt = _t##_setfmt; \
+ _p->base.collect_cur = _t##_collect_cur; \
+ _p->base.collect_tot = _t##_collect_tot; \
+ _p->base.update_tot = _t##_update_tot; \
+ _p->base.get_curstat = _t##_get_curstat; \
+ _p->base.get_totstat = _t##_get_totstat; \
+ _p->base.print_header = _t##_print_header; \
+ _p->base.print_current = _t##_print_current; \
+ _p->base.print_total = _t##_print_total; \
+ _p->base.print_verbose = _t##_print_verbose; \
+ _p->base.print_fields = _t##_print_fields; \
+} while (0)
+#endif /* _STATFOO_H_ */
diff --git a/tools/tools/ath/common/ah_osdep.h b/tools/tools/ath/common/ah_osdep.h
new file mode 100644
index 000000000000..047811159a42
--- /dev/null
+++ b/tools/tools/ath/common/ah_osdep.h
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#ifndef _ATH_AH_OSDEP_H_
+#define _ATH_AH_OSDEP_H_
+/*
+ * Atheros Hardware Access Layer (HAL) OS Dependent Definitions.
+ */
+#include <sys/param.h>
+
+/*
+ * Bus i/o type definitions.
+ */
+typedef void *HAL_SOFTC;
+typedef int HAL_BUS_TAG;
+typedef void *HAL_BUS_HANDLE;
+
+#define OS_DELAY(_n) DELAY(_n)
+#define OS_INLINE __inline
+#define OS_MEMZERO(_a, _size) bzero((_a), (_size))
+#define OS_MEMCPY(_dst, _src, _size) bcopy((_src), (_dst), (_size))
+#define OS_MACEQU(_a, _b) \
+ (bcmp((_a), (_b), IEEE80211_ADDR_LEN) == 0)
+
+struct ath_hal;
+extern u_int32_t OS_GETUPTIME(struct ath_hal *);
+extern void OS_REG_WRITE(struct ath_hal *, u_int32_t, u_int32_t);
+extern u_int32_t OS_REG_READ(struct ath_hal *, u_int32_t);
+extern void OS_MARK(struct ath_hal *, u_int id, u_int32_t value);
+#define OS_GETUPTIME(_ah) 0
+#define OS_REG_WRITE(_ah, _reg, _val)
+#define OS_REG_READ(_ah, _reg) 0
+#define OS_MARK(_ah, _id, _v)
+#define __packed __attribute__((__packed__))
+
+/*
+ * Linux/BSD gcc compatibility shims.
+ */
+#ifndef __printflike
+#define __printflike(_a,_b) \
+ __attribute__ ((__format__ (__printf__, _a, _b)))
+#endif
+#include <stdarg.h>
+#ifndef __va_list
+#define __va_list va_list
+#endif
+#define OS_INLINE __inline
+#endif /* _ATH_AH_OSDEP_H_ */
diff --git a/tools/tools/ath/common/diag.h b/tools/tools/ath/common/diag.h
new file mode 100644
index 000000000000..8c0c1a7f1c4b
--- /dev/null
+++ b/tools/tools/ath/common/diag.h
@@ -0,0 +1,61 @@
+#ifndef _DIAG_
+#define _DIAG_
+/*-
+ * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <stdio.h>
+
+#include <net80211/ieee80211_radiotap.h>
+#include "if_athioctl.h"
+
+struct statshandler {
+ u_long interval;
+ void *total;
+ void *cur;
+
+ void (*getstats)(struct statshandler *, void *);
+ void (*update)(struct statshandler *);
+
+ void (*printbanner)(struct statshandler *, FILE *);
+ void (*reportdelta)(struct statshandler *, FILE *);
+ void (*reporttotal)(struct statshandler *, FILE *);
+ void (*reportverbose)(struct statshandler *, FILE *);
+};
+
+extern void reportstats(FILE *fd, struct statshandler *sh);
+extern void runstats(FILE *fd, struct statshandler *sh);
+extern void reportcol(FILE *fd, u_int32_t v, const char *def_fmt,
+ u_int32_t max, const char *alt_fmt);
+#endif /* _DIAG_ */
diff --git a/tools/tools/ath/common/dumpregs.h b/tools/tools/ath/common/dumpregs.h
new file mode 100644
index 000000000000..88689cf766a3
--- /dev/null
+++ b/tools/tools/ath/common/dumpregs.h
@@ -0,0 +1,98 @@
+#ifndef _DUMPREGS_
+#define _DUMPREGS_
+/*-
+ * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#define __constructor __attribute__((constructor))
+
+struct dumpreg {
+ uint32_t addr;
+ const char *name;
+ const char *bits;
+ int type;
+ u_int srevMin, srevMax;
+ u_int phyMin, phyMax;
+};
+#define SREV(v,r) (((v) << 16) | (r))
+#define MAC_MATCH(dr, mv, mr) \
+ ((dr)->srevMin <= SREV(mv,mr) && SREV(mv,mr) < (dr)->srevMax)
+
+#define PHY_MATCH(dr, pr) \
+ ((dr)->phyMin <= (pr) && (pr) < (dr)->phyMax)
+#define PHYANY 0,0xffff
+
+enum {
+ DUMP_BASIC = 0x0001, /* basic/default registers */
+ DUMP_KEYCACHE = 0x0002, /* key cache */
+ DUMP_BASEBAND = 0x0004, /* baseband */
+ DUMP_INTERRUPT = 0x0008, /* interrupt state */
+ DUMP_XR = 0x0010, /* XR state */
+ DUMP_QCU = 0x0020, /* QCU state */
+ DUMP_DCU = 0x0040, /* DCU state */
+
+ DUMP_PUBLIC = 0x0061, /* public = BASIC+QCU+DCU */
+ DUMP_ALL = 0xffff
+};
+
+#define _DEFREG(_addr, _name, _type) \
+ { .addr = _addr, .name = _name, .type = _type }
+#define _DEFREGx(_addr, _name, _type, _srevmin, _srevmax) \
+ { .addr = _addr, .name = _name, .type = _type, \
+ .srevMin = _srevmin, .srevMax = _srevmax }
+#define _DEFREGfmt(_addr, _name, _type, _fmt) \
+ { .addr = _addr, .name = _name, .type = _type, .bits = _fmt }
+#define DEFVOID(_addr, _name) _DEFREG(_addr, _name, 0)
+#define DEFVOIDx(_addr, _name, _smin, _smax) \
+ __DEFREGx(_addr, _name, _smin, _smax, 0)
+#define DEFVOIDfmt(_addr, _name, _fmt) \
+ _DEFREGfmt(_addr, _name, 0, _fmt)
+#define DEFBASIC(_addr, _name) _DEFREG(_addr, _name, DUMP_BASIC)
+#define DEFBASICfmt(_addr, _name, _fmt) \
+ _DEFREGfmt(_addr, _name, DUMP_BASIC, _fmt)
+#define DEFBASICx(_addr, _name, _smin, _smax) \
+ _DEFREGx(_addr, _name, DUMP_BASIC, _smin, _smax)
+#define DEFBB(_addr, _name) _DEFREG(_addr, _name, DUMP_BASEBAND)
+#define DEFINT(_addr, _name) _DEFREG(_addr, _name, DUMP_INTERRUPT)
+#define DEFINTfmt(_addr, _name, _fmt) \
+ _DEFREGfmt(_addr, _name, DUMP_INTERRUPT, _fmt)
+#define DEFQCU(_addr, _name) _DEFREG(_addr, _name, DUMP_QCU)
+#define DEFDCU(_addr, _name) _DEFREG(_addr, _name, DUMP_DCU)
+
+void register_regs(struct dumpreg *_regs, u_int _nregs,
+ int def_srev_min, int def_srev_max,
+ int def_phy_min, int def_phy_max);
+void register_keycache(u_int nslots,
+ int def_srev_min, int def_srev_max,
+ int def_phy_min, int def_phy_max);
+void register_range(u_int brange, u_int erange, int what,
+ int def_srev_min, int def_srev_max,
+ int def_phy_min, int def_phy_max);
+#endif /* _DUMPREGS_ */
diff --git a/tools/tools/ath/common/dumpregs_5210.c b/tools/tools/ath/common/dumpregs_5210.c
new file mode 100644
index 000000000000..f7b273b0ca38
--- /dev/null
+++ b/tools/tools/ath/common/dumpregs_5210.c
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ar5210/ar5210reg.h"
+#include "ar5210/ar5210phy.h"
+
+#include "dumpregs.h"
+
+#define N(a) (sizeof(a) / sizeof(a[0]))
+
+static struct dumpreg ar5210regs[] = {
+ DEFBASIC(AR_TXDP0, "TXDP0"),
+ DEFBASIC(AR_TXDP1, "TXDP1"),
+ DEFBASICfmt(AR_CR, "CR", AR_CR_BITS),
+ DEFBASIC(AR_RXDP, "RXDP"),
+ DEFBASICfmt(AR_CFG, "CFG", AR_CFG_BITS),
+ /* NB: read clears pending interrupts */
+ DEFVOIDfmt(AR_ISR, "ISR", AR_ISR_BITS),
+ DEFBASICfmt(AR_IMR, "IMR", AR_IMR_BITS),
+ DEFBASICfmt(AR_IER, "IER", AR_IER_BITS),
+ DEFBASICfmt(AR_BCR, "BCR", AR_BCR_BITS),
+ DEFBASICfmt(AR_BSR, "BSR", AR_BSR_BITS),
+ DEFBASICfmt(AR_TXCFG, "TXCFG", AR_TXCFG_BITS),
+ DEFBASIC(AR_RXCFG, "RXCFG"),
+ DEFBASIC(AR_MIBC, "MIBC"),
+ DEFBASIC(AR_TOPS, "TOPS"),
+ DEFBASIC(AR_RXNOFRM, "RXNOFR"),
+ DEFBASIC(AR_TXNOFRM, "TXNOFR"),
+ DEFBASIC(AR_RPGTO, "RPGTO"),
+ DEFBASIC(AR_RFCNT, "RFCNT"),
+ DEFBASIC(AR_MISC, "MISC"),
+ DEFBASICfmt(AR_RC, "RC", AR_RC_BITS),
+ DEFBASICfmt(AR_SCR, "SCR", AR_SCR_BITS),
+ DEFBASICfmt(AR_INTPEND, "INTPEND", AR_INTPEND_BITS),
+ DEFBASIC(AR_SFR, "SFR"),
+ DEFBASICfmt(AR_PCICFG, "PCICFG", AR_PCICFG_BITS),
+ DEFBASIC(AR_GPIOCR, "GPIOCR"),
+ DEFVOID(AR_GPIODO, "GPIODO"),
+ DEFVOID(AR_GPIODI, "GPIODI"),
+ DEFBASIC(AR_SREV, "SREV"),
+ DEFBASIC(AR_STA_ID0, "STA_ID0"),
+ DEFBASICfmt(AR_STA_ID1, "STA_ID1", AR_STA_ID1_BITS),
+ DEFBASIC(AR_BSS_ID0, "BSS_ID0"),
+ DEFBASIC(AR_BSS_ID1, "BSS_ID1"),
+ DEFBASIC(AR_SLOT_TIME, "SLOTTIME"),
+ DEFBASIC(AR_TIME_OUT, "TIME_OUT"),
+ DEFBASIC(AR_RSSI_THR, "RSSI_THR"),
+ DEFBASIC(AR_RETRY_LMT, "RETRY_LM"),
+ DEFBASIC(AR_USEC, "USEC"),
+ DEFBASICfmt(AR_BEACON, "BEACON", AR_BEACON_BITS),
+ DEFBASIC(AR_CFP_PERIOD, "CFP_PER"),
+ DEFBASIC(AR_TIMER0, "TIMER0"),
+ DEFBASIC(AR_TIMER1, "TIMER1"),
+ DEFBASIC(AR_TIMER2, "TIMER2"),
+ DEFBASIC(AR_TIMER3, "TIMER3"),
+ DEFBASIC(AR_IFS0, "IFS0"),
+ DEFBASIC(AR_IFS1, "IFS1" ),
+ DEFBASIC(AR_CFP_DUR, "CFP_DUR"),
+ DEFBASICfmt(AR_RX_FILTER, "RXFILTER", AR_BEACON_BITS),
+ DEFBASIC(AR_MCAST_FIL0, "MCAST_0"),
+ DEFBASIC(AR_MCAST_FIL1, "MCAST_1"),
+ DEFBASIC(AR_TX_MASK0, "TX_MASK0"),
+ DEFBASIC(AR_TX_MASK1, "TX_MASK1"),
+ DEFVOID(AR_CLR_TMASK, "CLR_TMASK"),
+ DEFBASIC(AR_TRIG_LEV, "TRIG_LEV"),
+ DEFBASICfmt(AR_DIAG_SW, "DIAG_SW", AR_DIAG_SW_BITS),
+ DEFBASIC(AR_TSF_L32, "TSF_L32"),
+ DEFBASIC(AR_TSF_U32, "TSF_U32"),
+ DEFBASIC(AR_LAST_TSTP, "LAST_TST"),
+ DEFBASIC(AR_RETRY_CNT, "RETRYCNT"),
+ DEFBASIC(AR_BACKOFF, "BACKOFF"),
+ DEFBASIC(AR_NAV, "NAV"),
+ DEFBASIC(AR_RTS_OK, "RTS_OK"),
+ DEFBASIC(AR_RTS_FAIL, "RTS_FAIL"),
+ DEFBASIC(AR_ACK_FAIL, "ACK_FAIL"),
+ DEFBASIC(AR_FCS_FAIL, "FCS_FAIL"),
+ DEFBASIC(AR_BEACON_CNT, "BEAC_CNT"),
+
+ DEFVOIDfmt(AR_PHY_FRCTL, "PHY_FRCTL", AR_PHY_FRCTL_BITS),
+ DEFVOIDfmt(AR_PHY_AGC, "PHY_AGC", AR_PHY_AGC_BITS),
+ DEFVOID(AR_PHY_CHIPID, "PHY_CHIPID"),
+ DEFVOIDfmt(AR_PHY_ACTIVE, "PHY_ACTIVE", AR_PHY_ACTIVE_BITS),
+ DEFVOIDfmt(AR_PHY_AGCCTL, "PHY_AGCCTL", AR_PHY_AGCCTL_BITS),
+};
+
+static __constructor void
+ar5210_ctor(void)
+{
+#define MAC5210 SREV(1,0), SREV(2,0)
+ register_regs(ar5210regs, N(ar5210regs), MAC5210, PHYANY);
+ register_keycache(64, MAC5210, PHYANY);
+
+ register_range(0x9800, 0x9840, DUMP_BASEBAND, MAC5210, PHYANY);
+}
diff --git a/tools/tools/ath/common/dumpregs_5211.c b/tools/tools/ath/common/dumpregs_5211.c
new file mode 100644
index 000000000000..17ecbced2ef1
--- /dev/null
+++ b/tools/tools/ath/common/dumpregs_5211.c
@@ -0,0 +1,293 @@
+/*-
+ * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ar5211/ar5211reg.h"
+#include "ar5211/ar5211phy.h"
+
+#include "dumpregs.h"
+
+#define N(a) (sizeof(a) / sizeof(a[0]))
+
+static struct dumpreg ar5211regs[] = {
+ DEFBASICfmt(AR_CR, "CR", AR_CR_BITS),
+ DEFBASIC(AR_RXDP, "RXDP"),
+ DEFBASICfmt(AR_CFG, "CFG", AR_CFG_BITS),
+ DEFBASICfmt(AR_IER, "IER", AR_IER_BITS),
+ DEFBASIC(AR_RTSD0, "RTSD0"),
+ DEFBASIC(AR_RTSD1, "RTSD1"),
+ DEFBASICfmt(AR_TXCFG, "TXCFG", AR_TXCFG_BITS),
+ DEFBASIC(AR_RXCFG, "RXCFG"),
+ DEFBASIC(AR5211_JUMBO_LAST, "JLAST"),
+ DEFBASIC(AR_MIBC, "MIBC"),
+ DEFBASIC(AR_TOPS, "TOPS"),
+ DEFBASIC(AR_RXNPTO, "RXNPTO"),
+ DEFBASIC(AR_TXNPTO, "TXNPTO"),
+ DEFBASIC(AR_RFGTO, "RFGTO"),
+ DEFBASIC(AR_RFCNT, "RFCNT"),
+ DEFBASIC(AR_MACMISC, "MISC"),
+ DEFVOID(AR5311_QDCLKGATE, "AR5311_QDCLKGATE"),
+
+ DEFINT(AR_ISR, "ISR"),
+ DEFINT(AR_ISR_S0, "ISR_S0"),
+ DEFINT(AR_ISR_S1, "ISR_S1"),
+ DEFINT(AR_ISR_S2, "ISR_S2"),
+ DEFINT(AR_ISR_S3, "ISR_S3"),
+ DEFINT(AR_ISR_S4, "ISR_S4"),
+ DEFINT(AR_IMR, "IMR"),
+ DEFINT(AR_IMR_S0, "IMR_S0"),
+ DEFINT(AR_IMR_S1, "IMR_S1"),
+ DEFINT(AR_IMR_S2, "IMR_S2"),
+ DEFINT(AR_IMR_S3, "IMR_S3"),
+ DEFINT(AR_IMR_S4, "IMR_S4"),
+ /* NB: don't read the RAC so we don't affect operation */
+ DEFVOID(AR_ISR_RAC, "ISR_RAC"),
+ DEFINT(AR_ISR_S0_S, "ISR_S0_S"),
+ DEFINT(AR_ISR_S1_S, "ISR_S1_S"),
+ DEFINT(AR_ISR_S2_S, "ISR_S2_S"),
+ DEFINT(AR_ISR_S3_S, "ISR_S3_S"),
+ DEFINT(AR_ISR_S4_S, "ISR_S4_S"),
+
+ DEFQCU(AR_Q0_TXDP, "Q0_TXDP"),
+ DEFQCU(AR_Q1_TXDP, "Q1_TXDP"),
+ DEFQCU(AR_Q2_TXDP, "Q2_TXDP"),
+ DEFQCU(AR_Q3_TXDP, "Q3_TXDP"),
+ DEFQCU(AR_Q4_TXDP, "Q4_TXDP"),
+ DEFQCU(AR_Q5_TXDP, "Q5_TXDP"),
+ DEFQCU(AR_Q6_TXDP, "Q6_TXDP"),
+ DEFQCU(AR_Q7_TXDP, "Q7_TXDP"),
+ DEFQCU(AR_Q8_TXDP, "Q8_TXDP"),
+ DEFQCU(AR_Q9_TXDP, "Q9_TXDP"),
+
+ DEFQCU(AR_Q_TXE, "Q_TXE"),
+ DEFQCU(AR_Q_TXD, "Q_TXD"),
+
+ DEFQCU(AR_Q0_CBRCFG, "Q0_CBR"),
+ DEFQCU(AR_Q1_CBRCFG, "Q1_CBR"),
+ DEFQCU(AR_Q2_CBRCFG, "Q2_CBR"),
+ DEFQCU(AR_Q3_CBRCFG, "Q3_CBR"),
+ DEFQCU(AR_Q4_CBRCFG, "Q4_CBR"),
+ DEFQCU(AR_Q5_CBRCFG, "Q5_CBR"),
+ DEFQCU(AR_Q6_CBRCFG, "Q6_CBR"),
+ DEFQCU(AR_Q7_CBRCFG, "Q7_CBR"),
+ DEFQCU(AR_Q8_CBRCFG, "Q8_CBR"),
+ DEFQCU(AR_Q9_CBRCFG, "Q9_CBR"),
+
+ DEFQCU(AR_Q0_RDYTIMECFG, "Q0_RDYT"),
+ DEFQCU(AR_Q1_RDYTIMECFG, "Q1_RDYT"),
+ DEFQCU(AR_Q2_RDYTIMECFG, "Q2_RDYT"),
+ DEFQCU(AR_Q3_RDYTIMECFG, "Q3_RDYT"),
+ DEFQCU(AR_Q4_RDYTIMECFG, "Q4_RDYT"),
+ DEFQCU(AR_Q5_RDYTIMECFG, "Q5_RDYT"),
+ DEFQCU(AR_Q6_RDYTIMECFG, "Q6_RDYT"),
+ DEFQCU(AR_Q7_RDYTIMECFG, "Q7_RDYT"),
+ DEFQCU(AR_Q8_RDYTIMECFG, "Q8_RDYT"),
+ DEFQCU(AR_Q9_RDYTIMECFG, "Q9_RDYT"),
+
+ DEFQCU(AR_Q_ONESHOTARM_SC, "Q_ONESHOTARM_SC"),
+ DEFQCU(AR_Q_ONESHOTARM_CC, "Q_ONESHOTARM_CC"),
+
+ DEFQCU(AR_Q0_MISC, "Q0_MISC"),
+ DEFQCU(AR_Q1_MISC, "Q1_MISC"),
+ DEFQCU(AR_Q2_MISC, "Q2_MISC"),
+ DEFQCU(AR_Q3_MISC, "Q3_MISC"),
+ DEFQCU(AR_Q4_MISC, "Q4_MISC"),
+ DEFQCU(AR_Q5_MISC, "Q5_MISC"),
+ DEFQCU(AR_Q6_MISC, "Q6_MISC"),
+ DEFQCU(AR_Q7_MISC, "Q7_MISC"),
+ DEFQCU(AR_Q8_MISC, "Q8_MISC"),
+ DEFQCU(AR_Q9_MISC, "Q9_MISC"),
+
+ DEFQCU(AR_Q0_STS, "Q0_STS"),
+ DEFQCU(AR_Q1_STS, "Q1_STS"),
+ DEFQCU(AR_Q2_STS, "Q2_STS"),
+ DEFQCU(AR_Q3_STS, "Q3_STS"),
+ DEFQCU(AR_Q4_STS, "Q4_STS"),
+ DEFQCU(AR_Q5_STS, "Q5_STS"),
+ DEFQCU(AR_Q6_STS, "Q6_STS"),
+ DEFQCU(AR_Q7_STS, "Q7_STS"),
+ DEFQCU(AR_Q8_STS, "Q8_STS"),
+ DEFQCU(AR_Q9_STS, "Q9_STS"),
+
+ DEFQCU(AR_Q_RDYTIMESHDN, "Q_RDYTIMSHD"),
+
+ DEFQCU(AR_D0_QCUMASK, "D0_MASK"),
+ DEFQCU(AR_D1_QCUMASK, "D1_MASK"),
+ DEFQCU(AR_D2_QCUMASK, "D2_MASK"),
+ DEFQCU(AR_D3_QCUMASK, "D3_MASK"),
+ DEFQCU(AR_D4_QCUMASK, "D4_MASK"),
+ DEFQCU(AR_D5_QCUMASK, "D5_MASK"),
+ DEFQCU(AR_D6_QCUMASK, "D6_MASK"),
+ DEFQCU(AR_D7_QCUMASK, "D7_MASK"),
+ DEFQCU(AR_D8_QCUMASK, "D8_MASK"),
+ DEFQCU(AR_D9_QCUMASK, "D9_MASK"),
+
+ DEFDCU(AR_D0_LCL_IFS, "D0_IFS"),
+ DEFDCU(AR_D1_LCL_IFS, "D1_IFS"),
+ DEFDCU(AR_D2_LCL_IFS, "D2_IFS"),
+ DEFDCU(AR_D3_LCL_IFS, "D3_IFS"),
+ DEFDCU(AR_D4_LCL_IFS, "D4_IFS"),
+ DEFDCU(AR_D5_LCL_IFS, "D5_IFS"),
+ DEFDCU(AR_D6_LCL_IFS, "D6_IFS"),
+ DEFDCU(AR_D7_LCL_IFS, "D7_IFS"),
+ DEFDCU(AR_D8_LCL_IFS, "D8_IFS"),
+ DEFDCU(AR_D9_LCL_IFS, "D9_IFS"),
+
+ DEFDCU(AR_D0_RETRY_LIMIT, "D0_RTRY"),
+ DEFDCU(AR_D1_RETRY_LIMIT, "D1_RTRY"),
+ DEFDCU(AR_D2_RETRY_LIMIT, "D2_RTRY"),
+ DEFDCU(AR_D3_RETRY_LIMIT, "D3_RTRY"),
+ DEFDCU(AR_D4_RETRY_LIMIT, "D4_RTRY"),
+ DEFDCU(AR_D5_RETRY_LIMIT, "D5_RTRY"),
+ DEFDCU(AR_D6_RETRY_LIMIT, "D6_RTRY"),
+ DEFDCU(AR_D7_RETRY_LIMIT, "D7_RTRY"),
+ DEFDCU(AR_D8_RETRY_LIMIT, "D8_RTRY"),
+ DEFDCU(AR_D9_RETRY_LIMIT, "D9_RTRY"),
+
+ DEFDCU(AR_D0_CHNTIME, "D0_CHNT"),
+ DEFDCU(AR_D1_CHNTIME, "D1_CHNT"),
+ DEFDCU(AR_D2_CHNTIME, "D2_CHNT"),
+ DEFDCU(AR_D3_CHNTIME, "D3_CHNT"),
+ DEFDCU(AR_D4_CHNTIME, "D4_CHNT"),
+ DEFDCU(AR_D5_CHNTIME, "D5_CHNT"),
+ DEFDCU(AR_D6_CHNTIME, "D6_CHNT"),
+ DEFDCU(AR_D7_CHNTIME, "D7_CHNT"),
+ DEFDCU(AR_D8_CHNTIME, "D8_CHNT"),
+ DEFDCU(AR_D9_CHNTIME, "D9_CHNT"),
+
+ DEFDCU(AR_D0_MISC, "D0_MISC"),
+ DEFDCU(AR_D1_MISC, "D1_MISC"),
+ DEFDCU(AR_D2_MISC, "D2_MISC"),
+ DEFDCU(AR_D3_MISC, "D3_MISC"),
+ DEFDCU(AR_D4_MISC, "D4_MISC"),
+ DEFDCU(AR_D5_MISC, "D5_MISC"),
+ DEFDCU(AR_D6_MISC, "D6_MISC"),
+ DEFDCU(AR_D7_MISC, "D7_MISC"),
+ DEFDCU(AR_D8_MISC, "D8_MISC"),
+ DEFDCU(AR_D9_MISC, "D9_MISC"),
+
+ DEFDCU(AR_D0_SEQNUM, "D0_SEQ"),
+ DEFDCU(AR_D1_SEQNUM, "D1_SEQ"),
+ DEFDCU(AR_D2_SEQNUM, "D2_SEQ"),
+ DEFDCU(AR_D3_SEQNUM, "D3_SEQ"),
+ DEFDCU(AR_D4_SEQNUM, "D4_SEQ"),
+ DEFDCU(AR_D5_SEQNUM, "D5_SEQ"),
+ DEFDCU(AR_D6_SEQNUM, "D6_SEQ"),
+ DEFDCU(AR_D7_SEQNUM, "D7_SEQ"),
+ DEFDCU(AR_D8_SEQNUM, "D8_SEQ"),
+ DEFDCU(AR_D9_SEQNUM, "D9_SEQ"),
+
+ DEFBASIC(AR_D_GBL_IFS_SIFS, "D_SIFS"),
+ DEFBASIC(AR_D_GBL_IFS_SLOT, "D_SLOT"),
+ DEFBASIC(AR_D_GBL_IFS_EIFS, "D_EIFS"),
+ DEFBASIC(AR_D_GBL_IFS_MISC, "D_MISC"),
+ DEFBASIC(AR_D_FPCTL, "D_FPCTL"),
+ DEFBASIC(AR_D_TXPSE, "D_TXPSE"),
+ DEFVOID(AR_D_TXBLK_CMD, "D_CMD"),
+#if 0
+ DEFVOID(AR_D_TXBLK_DATA, "D_DATA"),
+#endif
+ DEFVOID(AR_D_TXBLK_CLR, "D_CLR"),
+ DEFVOID(AR_D_TXBLK_SET, "D_SET"),
+ DEFBASICfmt(AR_RC, "RC", AR_RC_BITS),
+ DEFBASICfmt(AR_SCR, "SCR", AR_SCR_BITS),
+ DEFBASICfmt(AR_INTPEND, "INTPEND", AR_INTPEND_BITS),
+ DEFBASIC(AR_SFR, "SFR"),
+ DEFBASICfmt(AR_PCICFG, "PCICFG", AR_PCICFG_BITS),
+ DEFBASIC(AR_GPIOCR, "GPIOCR"),
+ DEFBASIC(AR_GPIODO, "GPIODO"),
+ DEFBASIC(AR_GPIODI, "GPIODI"),
+ DEFBASIC(AR_SREV, "SREV"),
+ DEFVOID(AR_EEPROM_ADDR, "EEADDR"),
+ DEFVOID(AR_EEPROM_DATA, "EEDATA"),
+ DEFVOID(AR_EEPROM_CMD, "EECMD"),
+ DEFVOID(AR_EEPROM_STS, "EESTS"),
+ DEFVOID(AR_EEPROM_CFG, "EECFG"),
+ DEFBASIC(AR_STA_ID0, "STA_ID0"),
+ DEFBASICfmt(AR_STA_ID1, "STA_ID1", AR_STA_ID1_BITS),
+ DEFBASIC(AR_BSS_ID0, "BSS_ID0"),
+ DEFBASIC(AR_BSS_ID1, "BSS_ID1"),
+ DEFBASIC(AR_SLOT_TIME, "SLOTTIME"),
+ DEFBASIC(AR_TIME_OUT, "TIME_OUT"),
+ DEFBASIC(AR_RSSI_THR, "RSSI_THR"),
+ DEFBASIC(AR_USEC, "USEC"),
+ DEFBASICfmt(AR_BEACON, "BEACON", AR_BEACON_BITS),
+ DEFBASIC(AR_CFP_PERIOD, "CFP_PER"),
+ DEFBASIC(AR_TIMER0, "TIMER0"),
+ DEFBASIC(AR_TIMER1, "TIMER1"),
+ DEFBASIC(AR_TIMER2, "TIMER2"),
+ DEFBASIC(AR_TIMER3, "TIMER3"),
+ DEFBASIC(AR_CFP_DUR, "CFP_DUR"),
+ DEFBASICfmt(AR_RX_FILTER, "RXFILTER", AR_RX_FILTER_BITS),
+ DEFBASIC(AR_MCAST_FIL0, "MCAST_0"),
+ DEFBASIC(AR_MCAST_FIL1, "MCAST_1"),
+ DEFBASICfmt(AR_DIAG_SW, "DIAG_SW", AR_DIAG_SW_BITS),
+ DEFBASIC(AR_TSF_L32, "TSF_L32"),
+ DEFBASIC(AR_TSF_U32, "TSF_U32"),
+ DEFBASIC(AR_TST_ADDAC, "TST_ADAC"),
+ DEFBASIC(AR_DEF_ANTENNA, "DEF_ANT"),
+
+ DEFBASIC(AR_LAST_TSTP, "LAST_TST"),
+ DEFBASIC(AR_NAV, "NAV"),
+ DEFBASIC(AR_RTS_OK, "RTS_OK"),
+ DEFBASIC(AR_RTS_FAIL, "RTS_FAIL"),
+ DEFBASIC(AR_ACK_FAIL, "ACK_FAIL"),
+ DEFBASIC(AR_FCS_FAIL, "FCS_FAIL"),
+ DEFBASIC(AR_BEACON_CNT, "BEAC_CNT"),
+
+ DEFVOID(AR_PHY_TURBO, "PHY_TURBO"),
+ DEFVOID(AR_PHY_CHIP_ID, "PHY_CHIP_ID"),
+ DEFVOID(AR_PHY_ACTIVE, "PHY_ACTIVE"),
+ DEFVOID(AR_PHY_AGC_CONTROL, "PHY_AGC_CONTROL"),
+ DEFVOID(AR_PHY_PLL_CTL, "PHY_PLL_CTL"),
+ DEFVOID(AR_PHY_RX_DELAY, "PHY_RX_DELAY"),
+ DEFVOID(AR_PHY_TIMING_CTRL4,"PHY_TIMING_CTRL4"),
+ DEFVOID(AR_PHY_RADAR_0, "PHY_RADAR_0"),
+ DEFVOID(AR_PHY_IQCAL_RES_PWR_MEAS_I,"PHY_IQCAL_RES_PWR_MEAS_I"),
+ DEFVOID(AR_PHY_IQCAL_RES_PWR_MEAS_Q,"PHY_IQCAL_RES_PWR_MEAS_Q"),
+ DEFVOID(AR_PHY_IQCAL_RES_IQ_CORR_MEAS,"PHY_IQCAL_RES_IQ_CORR_MEAS"),
+ DEFVOID(AR_PHY_CURRENT_RSSI,"PHY_CURRENT_RSSI"),
+ DEFVOID(AR5211_PHY_MODE, "PHY_MODE"),
+};
+
+static __constructor void
+ar5211_ctor(void)
+{
+#define MAC5211 SREV(2,0), SREV(4,5)
+ register_regs(ar5211regs, N(ar5211regs), MAC5211, PHYANY);
+ register_keycache(128, MAC5211, PHYANY);
+
+ register_range(0x9800, 0x987c, DUMP_BASEBAND, MAC5211, PHYANY);
+ register_range(0x9900, 0x995c, DUMP_BASEBAND, MAC5211, PHYANY);
+ register_range(0x9c00, 0x9c1c, DUMP_BASEBAND, MAC5211, PHYANY);
+}
diff --git a/tools/tools/ath/common/dumpregs_5212.c b/tools/tools/ath/common/dumpregs_5212.c
new file mode 100644
index 000000000000..8d129ecd4e30
--- /dev/null
+++ b/tools/tools/ath/common/dumpregs_5212.c
@@ -0,0 +1,433 @@
+/*-
+ * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ar5212/ar5212reg.h"
+#include "ar5212/ar5212phy.h"
+
+#include "dumpregs.h"
+
+#define N(a) (sizeof(a) / sizeof(a[0]))
+
+#define MAC5212 SREV(4,5), SREV(16,0)
+#define MAC5213 SREV(5,9), SREV(16,0)
+
+static struct dumpreg ar5212regs[] = {
+ DEFBASIC(AR_CR, "CR"),
+ DEFBASIC(AR_RXDP, "RXDP"),
+ DEFBASICfmt(AR_CFG, "CFG",
+ "\20\1SWTD\2SWTB\3SWRD\4SWRB\5SWRG\6AP_ADHOC\11PHOK\12EEBS"),
+ DEFBASIC(AR_IER, "IER"),
+ DEFBASIC(AR_TXCFG, "TXCFG"),
+ DEFBASICfmt(AR_RXCFG, "RXCFG",
+ "\20\6JUMBO_ENA\7JUMBO_WRAP\10SLEEP_DEBUG"),
+ DEFBASIC(AR_MIBC, "MIBC"),
+ DEFBASIC(AR_TOPS, "TOPS"),
+ DEFBASIC(AR_RXNPTO, "RXNPTO"),
+ DEFBASIC(AR_TXNPTO, "TXNPTO"),
+ DEFBASIC(AR_RPGTO, "RPGTO"),
+ DEFBASIC(AR_RPCNT, "RPCNT"),
+ DEFBASIC(AR_MACMISC, "MACMISC"),
+ DEFBASIC(AR_SPC_0, "SPC_0"),
+ DEFBASIC(AR_SPC_1, "SPC_1"),
+
+ DEFINTfmt(AR_ISR, "ISR",
+ "\20\1RXOK\2RXDESC\3RXERR\4RXNOPKT\5RXEOL\6RXORN\7TXOK\10TXDESC"
+ "\11TXERR\12TXNOPKT\13TXEOL\14TXURN\15MIB\16SWI\17RXPHY\20RXKCM"
+ "\21SWBA\22BRSSI\23BMISS\24HIUERR\25BNR\26RXCHIRP\27RXDOPPL\30BCNMISS"
+ "\31TIM\32GPIO\33QCBROVF\34QCBRURN\35QTRIG"),
+ DEFINT(AR_ISR_S0, "ISR_S0"),
+ DEFINT(AR_ISR_S1, "ISR_S1"),
+ DEFINTfmt(AR_ISR_S2, "ISR_S2",
+ "\20\21MCABT\22SSERR\23DPERR\24TIM\25CABEND\26DTIMSYNC\27BCNTO"
+ "\30CABTO\31DTIM"),
+ DEFINT(AR_ISR_S3, "ISR_S3"),
+ DEFINT(AR_ISR_S4, "ISR_S4"),
+ DEFINTfmt(AR_IMR, "IMR",
+ "\20\1RXOK\2RXDESC\3RXERR\4RXNOPKT\5RXEOL\6RXORN\7TXOK\10TXDESC"
+ "\11TXERR\12TXNOPKT\13TXEOL\14TXURN\15MIB\16SWI\17RXPHY\20RXKCM"
+ "\21SWBA\22BRSSI\23BMISS\24HIUERR\25BNR\26RXCHIRP\27RXDOPPL\30BCNMISS"
+ "\31TIM\32GPIO\33QCBROVF\34QCBRURN\35QTRIG"),
+ DEFINT(AR_IMR_S0, "IMR_S0"),
+ DEFINT(AR_IMR_S1, "IMR_S1"),
+ DEFINTfmt(AR_IMR_S2, "IMR_S2",
+ "\20\21MCABT\22SSERR\23DPERR\24TIM\25CABEND\26DTIMSYNC\27BCNTO"
+ "\30CABTO\31DTIM"),
+ DEFINT(AR_IMR_S3, "IMR_S3"),
+ DEFINT(AR_IMR_S4, "IMR_S4"),
+ /* NB: don't read the RAC so we don't affect operation */
+ DEFVOID(AR_ISR_RAC, "ISR_RAC"),
+ DEFINT(AR_ISR_S0_S, "ISR_S0_S"),
+ DEFINT(AR_ISR_S1_S, "ISR_S1_S"),
+ DEFINT(AR_ISR_S2_S, "ISR_S2_S"),
+ DEFINT(AR_ISR_S3_S, "ISR_S3_S"),
+ DEFINT(AR_ISR_S4_S, "ISR_S4_S"),
+
+ DEFBASIC(AR_DMADBG_0, "DMADBG0"),
+ DEFBASIC(AR_DMADBG_1, "DMADBG1"),
+ DEFBASIC(AR_DMADBG_2, "DMADBG2"),
+ DEFBASIC(AR_DMADBG_3, "DMADBG3"),
+ DEFBASIC(AR_DMADBG_4, "DMADBG4"),
+ DEFBASIC(AR_DMADBG_5, "DMADBG5"),
+ DEFBASIC(AR_DMADBG_6, "DMADBG6"),
+ DEFBASIC(AR_DMADBG_7, "DMADBG7"),
+
+ DEFBASIC(AR_DCM_A, "DCM_A"),
+ DEFBASIC(AR_DCM_D, "DCM_D"),
+ DEFBASIC(AR_DCCFG, "DCCFG"),
+ DEFBASIC(AR_CCFG, "CCFG"),
+ DEFBASIC(AR_CCUCFG, "CCUCFG"),
+ DEFBASIC(AR_CPC_0, "CPC0"),
+ DEFBASIC(AR_CPC_1, "CPC1"),
+ DEFBASIC(AR_CPC_2, "CPC2"),
+ DEFBASIC(AR_CPC_3, "CPC3"),
+ DEFBASIC(AR_CPCOVF, "CPCOVF"),
+
+ DEFQCU(AR_Q0_TXDP, "Q0_TXDP"),
+ DEFQCU(AR_Q1_TXDP, "Q1_TXDP"),
+ DEFQCU(AR_Q2_TXDP, "Q2_TXDP"),
+ DEFQCU(AR_Q3_TXDP, "Q3_TXDP"),
+ DEFQCU(AR_Q4_TXDP, "Q4_TXDP"),
+ DEFQCU(AR_Q5_TXDP, "Q5_TXDP"),
+ DEFQCU(AR_Q6_TXDP, "Q6_TXDP"),
+ DEFQCU(AR_Q7_TXDP, "Q7_TXDP"),
+ DEFQCU(AR_Q8_TXDP, "Q8_TXDP"),
+ DEFQCU(AR_Q9_TXDP, "Q9_TXDP"),
+
+ DEFQCU(AR_Q_TXE, "Q_TXE"),
+ DEFQCU(AR_Q_TXD, "Q_TXD"),
+
+ DEFQCU(AR_Q0_CBRCFG, "Q0_CBR"),
+ DEFQCU(AR_Q1_CBRCFG, "Q1_CBR"),
+ DEFQCU(AR_Q2_CBRCFG, "Q2_CBR"),
+ DEFQCU(AR_Q3_CBRCFG, "Q3_CBR"),
+ DEFQCU(AR_Q4_CBRCFG, "Q4_CBR"),
+ DEFQCU(AR_Q5_CBRCFG, "Q5_CBR"),
+ DEFQCU(AR_Q6_CBRCFG, "Q6_CBR"),
+ DEFQCU(AR_Q7_CBRCFG, "Q7_CBR"),
+ DEFQCU(AR_Q8_CBRCFG, "Q8_CBR"),
+ DEFQCU(AR_Q9_CBRCFG, "Q9_CBR"),
+
+ DEFQCU(AR_Q0_RDYTIMECFG, "Q0_RDYT"),
+ DEFQCU(AR_Q1_RDYTIMECFG, "Q1_RDYT"),
+ DEFQCU(AR_Q2_RDYTIMECFG, "Q2_RDYT"),
+ DEFQCU(AR_Q3_RDYTIMECFG, "Q3_RDYT"),
+ DEFQCU(AR_Q4_RDYTIMECFG, "Q4_RDYT"),
+ DEFQCU(AR_Q5_RDYTIMECFG, "Q5_RDYT"),
+ DEFQCU(AR_Q6_RDYTIMECFG, "Q6_RDYT"),
+ DEFQCU(AR_Q7_RDYTIMECFG, "Q7_RDYT"),
+ DEFQCU(AR_Q8_RDYTIMECFG, "Q8_RDYT"),
+ DEFQCU(AR_Q9_RDYTIMECFG, "Q9_RDYT"),
+
+ DEFQCU(AR_Q_ONESHOTARM_SC, "Q_ONESHOTARM_SC"),
+ DEFQCU(AR_Q_ONESHOTARM_CC, "Q_ONESHOTARM_CC"),
+
+ DEFQCU(AR_Q0_MISC, "Q0_MISC"),
+ DEFQCU(AR_Q1_MISC, "Q1_MISC"),
+ DEFQCU(AR_Q2_MISC, "Q2_MISC"),
+ DEFQCU(AR_Q3_MISC, "Q3_MISC"),
+ DEFQCU(AR_Q4_MISC, "Q4_MISC"),
+ DEFQCU(AR_Q5_MISC, "Q5_MISC"),
+ DEFQCU(AR_Q6_MISC, "Q6_MISC"),
+ DEFQCU(AR_Q7_MISC, "Q7_MISC"),
+ DEFQCU(AR_Q8_MISC, "Q8_MISC"),
+ DEFQCU(AR_Q9_MISC, "Q9_MISC"),
+
+ DEFQCU(AR_Q0_STS, "Q0_STS"),
+ DEFQCU(AR_Q1_STS, "Q1_STS"),
+ DEFQCU(AR_Q2_STS, "Q2_STS"),
+ DEFQCU(AR_Q3_STS, "Q3_STS"),
+ DEFQCU(AR_Q4_STS, "Q4_STS"),
+ DEFQCU(AR_Q5_STS, "Q5_STS"),
+ DEFQCU(AR_Q6_STS, "Q6_STS"),
+ DEFQCU(AR_Q7_STS, "Q7_STS"),
+ DEFQCU(AR_Q8_STS, "Q8_STS"),
+ DEFQCU(AR_Q9_STS, "Q9_STS"),
+
+ DEFQCU(AR_Q_RDYTIMESHDN, "Q_RDYTIMSHD"),
+
+ DEFQCU(AR_Q_CBBS, "Q_CBBS"),
+ DEFQCU(AR_Q_CBBA, "Q_CBBA"),
+ DEFQCU(AR_Q_CBC, "Q_CBC"),
+
+ DEFDCU(AR_D0_QCUMASK, "D0_MASK"),
+ DEFDCU(AR_D1_QCUMASK, "D1_MASK"),
+ DEFDCU(AR_D2_QCUMASK, "D2_MASK"),
+ DEFDCU(AR_D3_QCUMASK, "D3_MASK"),
+ DEFDCU(AR_D4_QCUMASK, "D4_MASK"),
+ DEFDCU(AR_D5_QCUMASK, "D5_MASK"),
+ DEFDCU(AR_D6_QCUMASK, "D6_MASK"),
+ DEFDCU(AR_D7_QCUMASK, "D7_MASK"),
+ DEFDCU(AR_D8_QCUMASK, "D8_MASK"),
+ DEFDCU(AR_D9_QCUMASK, "D9_MASK"),
+
+ DEFDCU(AR_D0_LCL_IFS, "D0_IFS"),
+ DEFDCU(AR_D1_LCL_IFS, "D1_IFS"),
+ DEFDCU(AR_D2_LCL_IFS, "D2_IFS"),
+ DEFDCU(AR_D3_LCL_IFS, "D3_IFS"),
+ DEFDCU(AR_D4_LCL_IFS, "D4_IFS"),
+ DEFDCU(AR_D5_LCL_IFS, "D5_IFS"),
+ DEFDCU(AR_D6_LCL_IFS, "D6_IFS"),
+ DEFDCU(AR_D7_LCL_IFS, "D7_IFS"),
+ DEFDCU(AR_D8_LCL_IFS, "D8_IFS"),
+ DEFDCU(AR_D9_LCL_IFS, "D9_IFS"),
+
+ DEFDCU(AR_D0_RETRY_LIMIT, "D0_RTRY"),
+ DEFDCU(AR_D1_RETRY_LIMIT, "D1_RTRY"),
+ DEFDCU(AR_D2_RETRY_LIMIT, "D2_RTRY"),
+ DEFDCU(AR_D3_RETRY_LIMIT, "D3_RTRY"),
+ DEFDCU(AR_D4_RETRY_LIMIT, "D4_RTRY"),
+ DEFDCU(AR_D5_RETRY_LIMIT, "D5_RTRY"),
+ DEFDCU(AR_D6_RETRY_LIMIT, "D6_RTRY"),
+ DEFDCU(AR_D7_RETRY_LIMIT, "D7_RTRY"),
+ DEFDCU(AR_D8_RETRY_LIMIT, "D8_RTRY"),
+ DEFDCU(AR_D9_RETRY_LIMIT, "D9_RTRY"),
+
+ DEFDCU(AR_D0_CHNTIME, "D0_CHNT"),
+ DEFDCU(AR_D1_CHNTIME, "D1_CHNT"),
+ DEFDCU(AR_D2_CHNTIME, "D2_CHNT"),
+ DEFDCU(AR_D3_CHNTIME, "D3_CHNT"),
+ DEFDCU(AR_D4_CHNTIME, "D4_CHNT"),
+ DEFDCU(AR_D5_CHNTIME, "D5_CHNT"),
+ DEFDCU(AR_D6_CHNTIME, "D6_CHNT"),
+ DEFDCU(AR_D7_CHNTIME, "D7_CHNT"),
+ DEFDCU(AR_D8_CHNTIME, "D8_CHNT"),
+ DEFDCU(AR_D9_CHNTIME, "D9_CHNT"),
+
+ DEFDCU(AR_D0_MISC, "D0_MISC"),
+ DEFDCU(AR_D1_MISC, "D1_MISC"),
+ DEFDCU(AR_D2_MISC, "D2_MISC"),
+ DEFDCU(AR_D3_MISC, "D3_MISC"),
+ DEFDCU(AR_D4_MISC, "D4_MISC"),
+ DEFDCU(AR_D5_MISC, "D5_MISC"),
+ DEFDCU(AR_D6_MISC, "D6_MISC"),
+ DEFDCU(AR_D7_MISC, "D7_MISC"),
+ DEFDCU(AR_D8_MISC, "D8_MISC"),
+ DEFDCU(AR_D9_MISC, "D9_MISC"),
+
+ _DEFREG(AR_D_SEQNUM, "D_SEQ", DUMP_BASIC | DUMP_DCU),
+ DEFBASIC(AR_D_GBL_IFS_SIFS, "D_SIFS"),
+ DEFBASIC(AR_D_GBL_IFS_SLOT, "D_SLOT"),
+ DEFBASIC(AR_D_GBL_IFS_EIFS, "D_EIFS"),
+ DEFBASIC(AR_D_GBL_IFS_MISC, "D_MISC"),
+ DEFBASIC(AR_D_FPCTL, "D_FPCTL"),
+ DEFBASIC(AR_D_TXPSE, "D_TXPSE"),
+ DEFVOID(AR_D_TXBLK_CMD, "D_CMD"),
+#if 0
+ DEFVOID(AR_D_TXBLK_DATA, "D_DATA"),
+#endif
+ DEFVOID(AR_D_TXBLK_CLR, "D_CLR"),
+ DEFVOID(AR_D_TXBLK_SET, "D_SET"),
+ DEFBASIC(AR_RC, "RC"),
+ DEFBASICfmt(AR_SCR, "SCR",
+ "\20\22SLDTP\23SLDWP\24SLEPOL\25MIBIE"),
+ DEFBASIC(AR_INTPEND, "INTPEND"),
+ DEFBASIC(AR_SFR, "SFR"),
+ DEFBASIC(AR_PCICFG, "PCICFG"),
+ DEFBASIC(AR_GPIOCR, "GPIOCR"),
+ DEFBASIC(AR_GPIODO, "GPIODO"),
+ DEFBASIC(AR_GPIODI, "GPIODI"),
+ DEFBASIC(AR_SREV, "SREV"),
+
+ DEFBASICx(AR_PCIE_PMC, "PCIEPMC", SREV(4,8), SREV(13,7)),
+ DEFBASICx(AR_PCIE_SERDES, "SERDES", SREV(4,8), SREV(13,7)),
+ DEFBASICx(AR_PCIE_SERDES2, "SERDES2", SREV(4,8), SREV(13,7)),
+ DEFVOID(AR_EEPROM_ADDR, "EEADDR"),
+ DEFVOID(AR_EEPROM_DATA, "EEDATA"),
+ DEFVOID(AR_EEPROM_CMD, "EECMD"),
+ DEFVOID(AR_EEPROM_STS, "EESTS"),
+ DEFVOID(AR_EEPROM_CFG, "EECFG"),
+ DEFBASIC(AR_STA_ID0, "STA_ID0"),
+ DEFBASICfmt(AR_STA_ID1, "STA_ID1",
+ "\20\21STA_AP\22ADHOC\23PWR_SAV\24KSRCHDIS\25PCF\26USE_DEFANT"
+ "\27UPD_DEFANT\30RTS_USE_DEF\31ACKCTS_6MB\32BASE_RATE11B\33USE_DA_SG"
+ "\34CRPT_MIC_ENABLE\35KSRCH_MODE\36PRE_SEQNUM\37CBCIV_ENDIAN"
+ "\40MCAST_KSRCH"),
+ DEFBASIC(AR_BSS_ID0, "BSS_ID0"),
+ DEFBASIC(AR_BSS_ID1, "BSS_ID1"),
+ DEFBASIC(AR_SLOT_TIME, "SLOTTIME"),
+ DEFBASIC(AR_TIME_OUT, "TIME_OUT"),
+ DEFBASIC(AR_RSSI_THR, "RSSI_THR"),
+ DEFBASIC(AR_USEC, "USEC"),
+ DEFBASIC(AR_BEACON, "BEACON"),
+ DEFBASIC(AR_CFP_PERIOD, "CFP_PER"),
+ DEFBASIC(AR_TIMER0, "TIMER0"),
+ DEFBASIC(AR_TIMER1, "TIMER1"),
+ DEFBASIC(AR_TIMER2, "TIMER2"),
+ DEFBASIC(AR_TIMER3, "TIMER3"),
+ DEFBASIC(AR_CFP_DUR, "CFP_DUR"),
+ DEFBASICfmt(AR_RX_FILTER, "RXFILTER",
+ "\20\1UCAST\2MCAST\3BCAST\4CONTROL\5BEACON\6PROM\7XR_POLL\10PROBE_REQ"),
+ DEFBASIC(AR_MCAST_FIL0, "MCAST_0"),
+ DEFBASIC(AR_MCAST_FIL1, "MCAST_1"),
+ DEFBASICfmt(AR_DIAG_SW, "DIAG_SW",
+ "\20\1CACHE_ACK\2ACK_DIS\3CTS_DIS\4ENCRYPT_DIS\5DECRYPT_DIS\6RX_DIS"
+ "\7CORR_FCS\10CHAN_INFO\11EN_SCRAMSD\22FRAME_NV0\25RX_CLR_HI"
+ "\26IGNORE_CS\27CHAN_IDLE\30PHEAR_ME"),
+ DEFBASIC(AR_TSF_L32, "TSF_L32"),
+ DEFBASIC(AR_TSF_U32, "TSF_U32"),
+ DEFBASIC(AR_TST_ADDAC, "TST_ADAC"),
+ DEFBASIC(AR_DEF_ANTENNA, "DEF_ANT"),
+ DEFBASIC(AR_QOS_MASK, "QOS_MASK"),
+ DEFBASIC(AR_SEQ_MASK, "SEQ_MASK"),
+ DEFBASIC(AR_OBSERV_2, "OBSERV2"),
+ DEFBASIC(AR_OBSERV_1, "OBSERV1"),
+
+ DEFBASIC(AR_LAST_TSTP, "LAST_TST"),
+ DEFBASIC(AR_NAV, "NAV"),
+ DEFBASIC(AR_RTS_OK, "RTS_OK"),
+ DEFBASIC(AR_RTS_FAIL, "RTS_FAIL"),
+ DEFBASIC(AR_ACK_FAIL, "ACK_FAIL"),
+ DEFBASIC(AR_FCS_FAIL, "FCS_FAIL"),
+ DEFBASIC(AR_BEACON_CNT, "BEAC_CNT"),
+
+ DEFBASIC(AR_SLEEP1, "SLEEP1"),
+ DEFBASIC(AR_SLEEP2, "SLEEP2"),
+ DEFBASIC(AR_SLEEP3, "SLEEP3"),
+ DEFBASIC(AR_BSSMSKL, "BSSMSKL"),
+ DEFBASIC(AR_BSSMSKU, "BSSMSKU"),
+ DEFBASIC(AR_TPC, "TPC"),
+ DEFBASIC(AR_TFCNT, "TFCNT"),
+ DEFBASIC(AR_RFCNT, "RFCNT"),
+ DEFBASIC(AR_RCCNT, "RCCNT"),
+ DEFBASIC(AR_CCCNT, "CCCNT"),
+ DEFBASIC(AR_QUIET1, "QUIET1"),
+ DEFBASIC(AR_QUIET2, "QUIET2"),
+ DEFBASIC(AR_TSF_PARM, "TSF_PARM"),
+ DEFBASIC(AR_NOACK, "NOACK"),
+ DEFBASIC(AR_PHY_ERR, "PHY_ERR"),
+ DEFBASIC(AR_QOS_CONTROL, "QOS_CTRL"),
+ DEFBASIC(AR_QOS_SELECT, "QOS_SEL"),
+ DEFBASIC(AR_MISC_MODE, "MISCMODE"),
+ DEFBASIC(AR_FILTOFDM, "FILTOFDM"),
+ DEFBASIC(AR_FILTCCK, "FILTCCK"),
+ DEFBASIC(AR_PHYCNT1, "PHYCNT1"),
+ DEFBASIC(AR_PHYCNTMASK1, "PHYCMSK1"),
+ DEFBASIC(AR_PHYCNT2, "PHYCNT2"),
+ DEFBASIC(AR_PHYCNTMASK2, "PHYCMSK2"),
+
+ DEFVOID(AR_PHYCNT1, "PHYCNT1"),
+ DEFVOID(AR_PHYCNTMASK1, "PHYCNTMASK1"),
+ DEFVOID(AR_PHYCNT2, "PHYCNT2"),
+ DEFVOID(AR_PHYCNTMASK2, "PHYCNTMASK2"),
+
+ DEFVOID(AR_PHY_TEST, "PHY_TEST"),
+ DEFVOID(AR_PHY_TURBO, "PHY_TURBO"),
+ DEFVOID(AR_PHY_TESTCTRL, "PHY_TESTCTRL"),
+ DEFVOID(AR_PHY_TIMING3, "PHY_TIMING3"),
+ DEFVOID(AR_PHY_CHIP_ID, "PHY_CHIP_ID"),
+ DEFVOIDfmt(AR_PHY_ACTIVE, "PHY_ACTIVE", "\20\1ENA"),
+ DEFVOID(AR_PHY_TX_CTL, "PHY_TX_CTL"),
+ DEFVOID(AR_PHY_ADC_CTL, "PHY_ADC_CTL"),
+ DEFVOID(AR_PHY_BB_XP_PA_CTL,"PHY_BB_XP_PA_CTL"),
+ DEFVOID(AR_PHY_TSTDAC_CONST,"PHY_TSTDAC_CONST"),
+ DEFVOID(AR_PHY_SETTLING, "PHY_SETTLING"),
+ DEFVOID(AR_PHY_RXGAIN, "PHY_RXGAIN"),
+ DEFVOID(AR_PHY_DESIRED_SZ, "PHY_DESIRED_SZ"),
+ DEFVOID(AR_PHY_FIND_SIG, "PHY_FIND_SIG"),
+ DEFVOID(AR_PHY_AGC_CTL1, "PHY_AGC_CTL1"),
+ DEFVOIDfmt(AR_PHY_AGC_CONTROL, "PHY_AGC_CONTROL",
+ "\20\1CAL\2NF\16ENA_NF\22NO_UPDATE_NF"),
+ DEFVOIDfmt(AR_PHY_SFCORR_LOW, "PHY_SFCORR_LOW",
+ "\20\1USE_SELF_CORR_LOW"),
+ DEFVOID(AR_PHY_SFCORR, "PHY_SFCORR"),
+ DEFVOID(AR_PHY_SLEEP_CTR_CONTROL, "PHY_SLEEP_CTR_CONTROL"),
+ DEFVOID(AR_PHY_SLEEP_CTR_LIMIT, "PHY_SLEEP_CTR_LIMIT"),
+ DEFVOID(AR_PHY_SLEEP_SCAL, "PHY_SLEEP_SCAL"),
+ DEFVOID(AR_PHY_BIN_MASK_1, "PHY_BIN_MASK_1"),
+ DEFVOID(AR_PHY_BIN_MASK_2, "PHY_BIN_MASK_2"),
+ DEFVOID(AR_PHY_BIN_MASK_3, "PHY_BIN_MASK_3"),
+ DEFVOID(AR_PHY_MASK_CTL, "PHY_MASK_CTL"),
+ DEFVOID(AR_PHY_PLL_CTL, "PHY_PLL_CTL"),
+ DEFVOID(AR_PHY_RX_DELAY, "PHY_RX_DELAY"),
+ DEFVOID(AR_PHY_TIMING_CTRL4,"PHY_TIMING_CTRL4"),
+ DEFVOID(AR_PHY_TIMING5, "PHY_TIMING5"),
+ DEFVOID(AR_PHY_PAPD_PROBE, "PHY_PAPD_PROBE"),
+ DEFVOID(AR_PHY_POWER_TX_RATE1,"PHY_POWER_TX_RATE1"),
+ DEFVOID(AR_PHY_POWER_TX_RATE2,"PHY_POWER_TX_RATE2"),
+ DEFVOID(AR_PHY_POWER_TX_RATE_MAX, "PHY_POWER_TX_RATE_MAX"),
+ DEFVOID(AR_PHY_FRAME_CTL, "PHY_FRAME_CTL"),
+ DEFVOID(AR_PHY_TXPWRADJ, "PHY_TXPWRADJ"),
+ DEFVOID(AR_PHY_RADAR_0, "PHY_RADAR_0"),
+ DEFVOID(AR_PHY_SIGMA_DELTA, "PHY_SIGMA_DELTA"),
+ DEFVOID(AR_PHY_RESTART, "PHY_RESTART"),
+ DEFVOID(AR_PHY_RFBUS_REQ, "PHY_RFBUS_REQ"),
+ DEFVOID(AR_PHY_TIMING7, "PHY_TIMING7"),
+ DEFVOID(AR_PHY_TIMING8, "PHY_TIMING8"),
+ DEFVOID(AR_PHY_BIN_MASK2_1, "PHY_BIN_MASK2_1"),
+ DEFVOID(AR_PHY_BIN_MASK2_2, "PHY_BIN_MASK2_2"),
+ DEFVOID(AR_PHY_BIN_MASK2_3, "PHY_BIN_MASK2_3"),
+ DEFVOID(AR_PHY_BIN_MASK2_4, "PHY_BIN_MASK2_4"),
+ DEFVOID(AR_PHY_TIMING9, "PHY_TIMING9"),
+ DEFVOID(AR_PHY_TIMING10, "PHY_TIMING10"),
+ DEFVOID(AR_PHY_TIMING11, "PHY_TIMING11"),
+ DEFVOID(AR_PHY_HEAVY_CLIP_ENABLE, "PHY_HEAVY_CLIP_ENABLE"),
+ DEFVOID(AR_PHY_M_SLEEP, "PHY_M_SLEEP"),
+ DEFVOID(AR_PHY_REFCLKDLY, "PHY_REFCLKDLY"),
+ DEFVOID(AR_PHY_REFCLKPD, "PHY_REFCLKPD"),
+ DEFVOID(AR_PHY_IQCAL_RES_PWR_MEAS_I, "PHY_IQCAL_RES_PWR_MEAS_I"),
+ DEFVOID(AR_PHY_IQCAL_RES_PWR_MEAS_Q, "PHY_IQCAL_RES_PWR_MEAS_Q"),
+ DEFVOID(AR_PHY_IQCAL_RES_IQ_CORR_MEAS, "PHY_IQCAL_RES_IQ_CORR_MEAS"),
+ DEFVOID(AR_PHY_CURRENT_RSSI,"PHY_CURRENT_RSSI"),
+ DEFVOID(AR_PHY_RFBUS_GNT, "PHY_RFBUS_GNT"),
+ DEFVOIDfmt(AR_PHY_MODE, "PHY_MODE",
+ "\20\1CCK\2RF2GHZ\3DYNAMIC\4AR5112\5HALF\6QUARTER"),
+ DEFVOID(AR_PHY_CCK_TX_CTRL, "PHY_CCK_TX_CTRL"),
+ DEFVOID(AR_PHY_CCK_DETECT, "PHY_CCK_DETECT"),
+ DEFVOID(AR_PHY_GAIN_2GHZ, "PHY_GAIN_2GHZ"),
+ DEFVOID(AR_PHY_CCK_RXCTRL4, "PHY_CCK_RXCTRL4"),
+ DEFVOID(AR_PHY_DAG_CTRLCCK, "PHY_DAG_CTRLCCK"),
+ DEFVOID(AR_PHY_DAG_CTRLCCK, "PHY_DAG_CTRLCCK"),
+ DEFVOID(AR_PHY_POWER_TX_RATE3,"PHY_POWER_TX_RATE3"),
+ DEFVOID(AR_PHY_POWER_TX_RATE4,"PHY_POWER_TX_RATE4"),
+ DEFVOID(AR_PHY_FAST_ADC, "PHY_FAST_ADC"),
+ DEFVOID(AR_PHY_BLUETOOTH, "PHY_BLUETOOTH"),
+ DEFVOID(AR_PHY_TPCRG1, "PHY_TPCRG1"),
+ DEFVOID(AR_PHY_TPCRG5, "PHY_TPCRG5"),
+
+ /* XXX { AR_RATE_DURATION(0), AR_RATE_DURATION(0x20) }, */
+};
+
+static __constructor void
+ar5212_ctor(void)
+{
+ register_regs(ar5212regs, N(ar5212regs), MAC5212, PHYANY);
+ register_keycache(128, MAC5212, PHYANY);
+
+ register_range(0x9800, 0x987c, DUMP_BASEBAND, MAC5212, PHYANY);
+ register_range(0x9900, 0x995c, DUMP_BASEBAND, MAC5212, PHYANY);
+ register_range(0x9c00, 0x9c1c, DUMP_BASEBAND, MAC5212, PHYANY);
+ register_range(0xa180, 0xa238, DUMP_BASEBAND, MAC5212, PHYANY);
+ register_range(0xa258, 0xa26c, DUMP_BASEBAND,
+ SREV(7,8), SREV(15,15), PHYANY);
+}
diff --git a/tools/tools/ath/common/dumpregs_5416.c b/tools/tools/ath/common/dumpregs_5416.c
new file mode 100644
index 000000000000..d52c9ca0c251
--- /dev/null
+++ b/tools/tools/ath/common/dumpregs_5416.c
@@ -0,0 +1,423 @@
+/*-
+ * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+#include "diag.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+
+#include "dumpregs.h"
+
+#define N(a) (sizeof(a) / sizeof(a[0]))
+
+#define MAC5416 SREV(13,8), SREV(0xff,0xff) /* XXX */
+
+static struct dumpreg ar5416regs[] = {
+ DEFBASIC(AR_CR, "CR"),
+ DEFBASIC(AR_RXDP, "RXDP"),
+ DEFBASIC(AR_CFG, "CFG"),
+ DEFBASIC(AR_MIRT, "MIRT"),
+ DEFBASIC(AR_TIMT, "TIMT"),
+ DEFBASIC(AR_CST, "CST"),
+ DEFBASIC(AR_IER, "IER"),
+ DEFBASIC(AR_TXCFG, "TXCFG"),
+ DEFBASICfmt(AR_RXCFG, "RXCFG",
+ "\20\6JUMBO_ENA\7JUMBO_WRAP\10SLEEP_DEBUG"),
+ DEFBASIC(AR_MIBC, "MIBC"),
+ DEFBASIC(AR_TOPS, "TOPS"),
+ DEFBASIC(AR_RXNPTO, "RXNPTO"),
+ DEFBASIC(AR_TXNPTO, "TXNPTO"),
+ DEFBASIC(AR_RPGTO, "RPGTO"),
+ DEFBASIC(AR_RPCNT, "RPCNT"),
+ DEFBASIC(AR_MACMISC, "MACMISC"),
+ DEFBASIC(AR_SPC_0, "SPC_0"),
+ DEFBASIC(AR_SPC_1, "SPC_1"),
+ DEFBASIC(AR_GTXTO, "GTXTO"),
+ DEFBASIC(AR_GTTM, "GTTM"),
+
+ DEFINTfmt(AR_ISR, "ISR",
+ "\20\1RXOK\2RXDESC\3RXERR\4RXNOPKT\5RXEOL\6RXORN\7TXOK\10TXDESC"
+ "\11TXERR\12TXNOPKT\13TXEOL\14TXURN\15MIB\16SWI\17RXPHY\20RXKCM"
+ "\21SWBA\22BRSSI\23BMISS\24HIUERR\25BNR\26RXCHIRP\27RXDOPPL\30BCNMISS"
+ "\31TIM\32GPIO\33QCBROVF\34QCBRURN\35QTRIG"),
+ DEFINT(AR_ISR_S0, "ISR_S0"),
+ DEFINT(AR_ISR_S1, "ISR_S1"),
+ DEFINTfmt(AR_ISR_S2, "ISR_S2",
+ "\20\21MCABT\22SSERR\23DPERR\24TIM\25CABEND\26DTIMSYNC\27BCNTO"
+ "\30CABTO\31DTIM"),
+ DEFINT(AR_ISR_S3, "ISR_S3"),
+ DEFINT(AR_ISR_S4, "ISR_S4"),
+ DEFINT(AR_ISR_S5, "ISR_S5"),
+ DEFINTfmt(AR_IMR, "IMR",
+ "\20\1RXOK\2RXDESC\3RXERR\4RXNOPKT\5RXEOL\6RXORN\7TXOK\10TXDESC"
+ "\11TXERR\12TXNOPKT\13TXEOL\14TXURN\15MIB\16SWI\17RXPHY\20RXKCM"
+ "\21SWBA\22BRSSI\23BMISS\24HIUERR\25BNR\26RXCHIRP\27RXDOPPL\30BCNMISS"
+ "\31TIM\32GPIO\33QCBROVF\34QCBRURN\35QTRIG"),
+ DEFINT(AR_IMR_S0, "IMR_S0"),
+ DEFINT(AR_IMR_S1, "IMR_S1"),
+ DEFINTfmt(AR_IMR_S2, "IMR_S2",
+ "\20\21MCABT\22SSERR\23DPERR\24TIM\25CABEND\26DTIMSYNC\27BCNTO"
+ "\30CABTO\31DTIM"),
+ DEFINT(AR_IMR_S3, "IMR_S3"),
+ DEFINT(AR_IMR_S4, "IMR_S4"),
+ /* NB: don't read the RAC so we don't affect operation */
+ DEFVOID(AR_ISR_RAC, "ISR_RAC"),
+ DEFINT(AR_ISR_S0_S, "ISR_S0_S"),
+ DEFINT(AR_ISR_S1_S, "ISR_S1_S"),
+ DEFINT(AR_ISR_S2_S, "ISR_S2_S"),
+ DEFINT(AR_ISR_S3_S, "ISR_S3_S"),
+ DEFINT(AR_ISR_S4_S, "ISR_S4_S"),
+ DEFINT(AR_ISR_S5_S, "ISR_S5_S"),
+
+ DEFBASIC(AR_DMADBG_0, "DMADBG0"),
+ DEFBASIC(AR_DMADBG_1, "DMADBG1"),
+ DEFBASIC(AR_DMADBG_2, "DMADBG2"),
+ DEFBASIC(AR_DMADBG_3, "DMADBG3"),
+ DEFBASIC(AR_DMADBG_4, "DMADBG4"),
+ DEFBASIC(AR_DMADBG_5, "DMADBG5"),
+ DEFBASIC(AR_DMADBG_6, "DMADBG6"),
+ DEFBASIC(AR_DMADBG_7, "DMADBG7"),
+
+ DEFBASIC(AR_DCM_A, "DCM_A"),
+ DEFBASIC(AR_DCM_D, "DCM_D"),
+ DEFBASIC(AR_DCCFG, "DCCFG"),
+ DEFBASIC(AR_CCFG, "CCFG"),
+ DEFBASIC(AR_CCUCFG, "CCUCFG"),
+ DEFBASIC(AR_CPC_0, "CPC0"),
+ DEFBASIC(AR_CPC_1, "CPC1"),
+ DEFBASIC(AR_CPC_2, "CPC2"),
+ DEFBASIC(AR_CPC_3, "CPC3"),
+ DEFBASIC(AR_CPCOVF, "CPCOVF"),
+
+ DEFQCU(AR_Q0_TXDP, "Q0_TXDP"),
+ DEFQCU(AR_Q1_TXDP, "Q1_TXDP"),
+ DEFQCU(AR_Q2_TXDP, "Q2_TXDP"),
+ DEFQCU(AR_Q3_TXDP, "Q3_TXDP"),
+ DEFQCU(AR_Q4_TXDP, "Q4_TXDP"),
+ DEFQCU(AR_Q5_TXDP, "Q5_TXDP"),
+ DEFQCU(AR_Q6_TXDP, "Q6_TXDP"),
+ DEFQCU(AR_Q7_TXDP, "Q7_TXDP"),
+ DEFQCU(AR_Q8_TXDP, "Q8_TXDP"),
+ DEFQCU(AR_Q9_TXDP, "Q9_TXDP"),
+
+ DEFQCU(AR_Q_TXE, "Q_TXE"),
+ DEFQCU(AR_Q_TXD, "Q_TXD"),
+
+ DEFQCU(AR_Q0_CBRCFG, "Q0_CBR"),
+ DEFQCU(AR_Q1_CBRCFG, "Q1_CBR"),
+ DEFQCU(AR_Q2_CBRCFG, "Q2_CBR"),
+ DEFQCU(AR_Q3_CBRCFG, "Q3_CBR"),
+ DEFQCU(AR_Q4_CBRCFG, "Q4_CBR"),
+ DEFQCU(AR_Q5_CBRCFG, "Q5_CBR"),
+ DEFQCU(AR_Q6_CBRCFG, "Q6_CBR"),
+ DEFQCU(AR_Q7_CBRCFG, "Q7_CBR"),
+ DEFQCU(AR_Q8_CBRCFG, "Q8_CBR"),
+ DEFQCU(AR_Q9_CBRCFG, "Q9_CBR"),
+
+ DEFQCU(AR_Q0_RDYTIMECFG, "Q0_RDYT"),
+ DEFQCU(AR_Q1_RDYTIMECFG, "Q1_RDYT"),
+ DEFQCU(AR_Q2_RDYTIMECFG, "Q2_RDYT"),
+ DEFQCU(AR_Q3_RDYTIMECFG, "Q3_RDYT"),
+ DEFQCU(AR_Q4_RDYTIMECFG, "Q4_RDYT"),
+ DEFQCU(AR_Q5_RDYTIMECFG, "Q5_RDYT"),
+ DEFQCU(AR_Q6_RDYTIMECFG, "Q6_RDYT"),
+ DEFQCU(AR_Q7_RDYTIMECFG, "Q7_RDYT"),
+ DEFQCU(AR_Q8_RDYTIMECFG, "Q8_RDYT"),
+ DEFQCU(AR_Q9_RDYTIMECFG, "Q9_RDYT"),
+
+ DEFQCU(AR_Q_ONESHOTARM_SC, "Q_ONESHOTARM_SC"),
+ DEFQCU(AR_Q_ONESHOTARM_CC, "Q_ONESHOTARM_CC"),
+
+ DEFQCU(AR_Q0_MISC, "Q0_MISC"),
+ DEFQCU(AR_Q1_MISC, "Q1_MISC"),
+ DEFQCU(AR_Q2_MISC, "Q2_MISC"),
+ DEFQCU(AR_Q3_MISC, "Q3_MISC"),
+ DEFQCU(AR_Q4_MISC, "Q4_MISC"),
+ DEFQCU(AR_Q5_MISC, "Q5_MISC"),
+ DEFQCU(AR_Q6_MISC, "Q6_MISC"),
+ DEFQCU(AR_Q7_MISC, "Q7_MISC"),
+ DEFQCU(AR_Q8_MISC, "Q8_MISC"),
+ DEFQCU(AR_Q9_MISC, "Q9_MISC"),
+
+ DEFQCU(AR_Q0_STS, "Q0_STS"),
+ DEFQCU(AR_Q1_STS, "Q1_STS"),
+ DEFQCU(AR_Q2_STS, "Q2_STS"),
+ DEFQCU(AR_Q3_STS, "Q3_STS"),
+ DEFQCU(AR_Q4_STS, "Q4_STS"),
+ DEFQCU(AR_Q5_STS, "Q5_STS"),
+ DEFQCU(AR_Q6_STS, "Q6_STS"),
+ DEFQCU(AR_Q7_STS, "Q7_STS"),
+ DEFQCU(AR_Q8_STS, "Q8_STS"),
+ DEFQCU(AR_Q9_STS, "Q9_STS"),
+
+ DEFQCU(AR_Q_RDYTIMESHDN, "Q_RDYTIMSHD"),
+
+ DEFQCU(AR_Q_CBBS, "Q_CBBS"),
+ DEFQCU(AR_Q_CBBA, "Q_CBBA"),
+ DEFQCU(AR_Q_CBC, "Q_CBC"),
+
+ DEFDCU(AR_D0_QCUMASK, "D0_MASK"),
+ DEFDCU(AR_D1_QCUMASK, "D1_MASK"),
+ DEFDCU(AR_D2_QCUMASK, "D2_MASK"),
+ DEFDCU(AR_D3_QCUMASK, "D3_MASK"),
+ DEFDCU(AR_D4_QCUMASK, "D4_MASK"),
+ DEFDCU(AR_D5_QCUMASK, "D5_MASK"),
+ DEFDCU(AR_D6_QCUMASK, "D6_MASK"),
+ DEFDCU(AR_D7_QCUMASK, "D7_MASK"),
+ DEFDCU(AR_D8_QCUMASK, "D8_MASK"),
+ DEFDCU(AR_D9_QCUMASK, "D9_MASK"),
+
+ DEFDCU(AR_D0_LCL_IFS, "D0_IFS"),
+ DEFDCU(AR_D1_LCL_IFS, "D1_IFS"),
+ DEFDCU(AR_D2_LCL_IFS, "D2_IFS"),
+ DEFDCU(AR_D3_LCL_IFS, "D3_IFS"),
+ DEFDCU(AR_D4_LCL_IFS, "D4_IFS"),
+ DEFDCU(AR_D5_LCL_IFS, "D5_IFS"),
+ DEFDCU(AR_D6_LCL_IFS, "D6_IFS"),
+ DEFDCU(AR_D7_LCL_IFS, "D7_IFS"),
+ DEFDCU(AR_D8_LCL_IFS, "D8_IFS"),
+ DEFDCU(AR_D9_LCL_IFS, "D9_IFS"),
+
+ DEFDCU(AR_D0_RETRY_LIMIT, "D0_RTRY"),
+ DEFDCU(AR_D1_RETRY_LIMIT, "D1_RTRY"),
+ DEFDCU(AR_D2_RETRY_LIMIT, "D2_RTRY"),
+ DEFDCU(AR_D3_RETRY_LIMIT, "D3_RTRY"),
+ DEFDCU(AR_D4_RETRY_LIMIT, "D4_RTRY"),
+ DEFDCU(AR_D5_RETRY_LIMIT, "D5_RTRY"),
+ DEFDCU(AR_D6_RETRY_LIMIT, "D6_RTRY"),
+ DEFDCU(AR_D7_RETRY_LIMIT, "D7_RTRY"),
+ DEFDCU(AR_D8_RETRY_LIMIT, "D8_RTRY"),
+ DEFDCU(AR_D9_RETRY_LIMIT, "D9_RTRY"),
+
+ DEFDCU(AR_D0_CHNTIME, "D0_CHNT"),
+ DEFDCU(AR_D1_CHNTIME, "D1_CHNT"),
+ DEFDCU(AR_D2_CHNTIME, "D2_CHNT"),
+ DEFDCU(AR_D3_CHNTIME, "D3_CHNT"),
+ DEFDCU(AR_D4_CHNTIME, "D4_CHNT"),
+ DEFDCU(AR_D5_CHNTIME, "D5_CHNT"),
+ DEFDCU(AR_D6_CHNTIME, "D6_CHNT"),
+ DEFDCU(AR_D7_CHNTIME, "D7_CHNT"),
+ DEFDCU(AR_D8_CHNTIME, "D8_CHNT"),
+ DEFDCU(AR_D9_CHNTIME, "D9_CHNT"),
+
+ DEFDCU(AR_D0_MISC, "D0_MISC"),
+ DEFDCU(AR_D1_MISC, "D1_MISC"),
+ DEFDCU(AR_D2_MISC, "D2_MISC"),
+ DEFDCU(AR_D3_MISC, "D3_MISC"),
+ DEFDCU(AR_D4_MISC, "D4_MISC"),
+ DEFDCU(AR_D5_MISC, "D5_MISC"),
+ DEFDCU(AR_D6_MISC, "D6_MISC"),
+ DEFDCU(AR_D7_MISC, "D7_MISC"),
+ DEFDCU(AR_D8_MISC, "D8_MISC"),
+ DEFDCU(AR_D9_MISC, "D9_MISC"),
+
+ _DEFREG(AR_D_SEQNUM, "D_SEQ", DUMP_BASIC | DUMP_DCU),
+ DEFBASIC(AR_D_GBL_IFS_SIFS, "D_SIFS"),
+ DEFBASIC(AR_D_GBL_IFS_SLOT, "D_SLOT"),
+ DEFBASIC(AR_D_GBL_IFS_EIFS, "D_EIFS"),
+ DEFBASIC(AR_D_GBL_IFS_MISC, "D_MISC"),
+ DEFBASIC(AR_D_FPCTL, "D_FPCTL"),
+ DEFBASIC(AR_D_TXPSE, "D_TXPSE"),
+ DEFVOID(AR_D_TXBLK_CMD, "D_CMD"),
+#if 0
+ DEFVOID(AR_D_TXBLK_DATA, "D_DATA"),
+#endif
+ DEFVOID(AR_D_TXBLK_CLR, "D_CLR"),
+ DEFVOID(AR_D_TXBLK_SET, "D_SET"),
+
+ DEFBASIC(AR_MAC_LED, "MAC_LED"),
+ DEFBASICfmt(AR_RC, "RC",
+ "\20\1AHB\2APB\11HOSTIF"),
+ DEFBASIC(AR_SCR, "SCR"),
+ DEFBASIC(AR_INTPEND, "INTPEND"),
+ DEFBASIC(AR_SFR, "SFR"),
+ DEFBASIC(AR_PCICFG, "PCICFG"),
+ DEFBASIC(AR_SREV, "SREV"),
+
+ DEFBASIC(AR_AHB_MODE, "AHBMODE"),
+ DEFBASIC(AR_PCIE_PM_CTRL, "PCIEPMC"),
+ DEFBASIC(AR5416_PCIE_SERDES,"SERDES"),
+ DEFBASIC(AR5416_PCIE_SERDES2, "SERDES2"),
+
+ DEFVOID(AR_INTR_SYNC_CAUSE_CLR, "INTR_SYNC_CAUSE_CLR"),
+ DEFVOID(AR_INTR_SYNC_CAUSE, "INTR_SYNC_CAUSE"),
+ DEFVOID(AR_INTR_SYNC_ENABLE,"INTR_SYNC_ENABLE"),
+ DEFBASIC(AR_INTR_ASYNC_MASK,"IASYNCM"),
+ DEFBASIC(AR_INTR_SYNC_MASK, "ISYNCM"),
+ DEFVOID(AR_INTR_ASYNC_CAUSE,"INTR_ASYNC_CAUSE"),
+ DEFVOID(AR_INTR_ASYNC_ENABLE,"INTR_ASYNC_ENABLE"),
+
+ DEFBASICfmt(AR_RTC_RC, "RTC_RC",
+ "\20\1MAC_WARM\2MAC_COLD"),
+ DEFBASIC(AR_RTC_PLL_CONTROL,"RTC_PLL"),
+ DEFVOID(AR_RTC_RESET, "RTC_RESET"),
+ DEFVOIDfmt(AR_RTC_STATUS, "RTC_STATUS",
+ "\20\1SHUTDOWN\2ON\3SLEEP\4WAKEUP\5COLDRESET\6PLLCHANGE"),
+ DEFVOID(AR_RTC_SLEEP_CLK, "RTC_SLEEP_CLK"),
+ DEFVOIDfmt(AR_RTC_FORCE_WAKE,"RTC_FORCE_WAKE",
+ "\20\1EN\2WAKE_ON_INT"),
+ DEFVOID(AR_RTC_INTR_CAUSE, "RTC_INTR_CAUSE"),
+ DEFVOID(AR_RTC_INTR_MASK, "RTC_INTR_MASK"),
+
+ DEFBASIC(AR_GPIO_IN_OUT, "GPIOIO"),
+ DEFBASIC(AR_GPIO_OE_OUT, "GPIOOE"),
+ DEFBASIC(AR_GPIO_INTR_POL, "GPIOPOL"),
+ DEFBASIC(AR_GPIO_INPUT_EN_VAL, "GPIOIEV"),
+ DEFBASIC(AR_GPIO_INPUT_MUX1, "GPIMUX1"),
+ DEFBASIC(AR_GPIO_INPUT_MUX2, "GPIMUX2"),
+ DEFBASIC(AR_GPIO_OUTPUT_MUX1, "GPOMUX1"),
+ DEFBASIC(AR_GPIO_OUTPUT_MUX2, "GPOMUX2"),
+ DEFBASIC(AR_GPIO_OUTPUT_MUX3, "GPOMUX3"),
+ DEFBASIC(AR_OBS, "OBS"),
+ DEFVOID(AR_EEPROM_ADDR, "EEADDR"),
+ DEFVOID(AR_EEPROM_DATA, "EEDATA"),
+ DEFVOID(AR_EEPROM_CMD, "EECMD"),
+ DEFVOID(AR_EEPROM_STS, "EESTS"),
+ DEFVOID(AR_EEPROM_CFG, "EECFG"),
+ DEFBASIC(AR_STA_ID0, "STA_ID0"),
+ DEFBASICfmt(AR_STA_ID1, "STA_ID1",
+ "\20\21AP\22ADHOC\23PWR_SAV\24KSRCHDIS\25PCF\26USE_DEFANT"
+ "\27UPD_DEFANT\30RTS_USE_DEF\31ACKCTS_6MB\32BASE_RATE_11B"
+ "\33USE_DA_SG\34CRPT_MIC_ENABLE\35KSRCH_MODE\36PRE_SEQNUM"
+ "\37CBCIV_ENDIAN\40MCAST_KSRC"),
+ DEFBASIC(AR_BSS_ID0, "BSS_ID0"),
+ DEFBASIC(AR_BSS_ID1, "BSS_ID1"),
+ DEFBASIC(AR_SLOT_TIME, "SLOTTIME"),
+ DEFBASIC(AR_TIME_OUT, "TIME_OUT"),
+ DEFBASIC(AR_RSSI_THR, "RSSI_THR"),
+ DEFBASIC(AR_USEC, "USEC"),
+ DEFBASIC(AR_BEACON, "BEACON"),
+ DEFBASIC(AR_CFP_PERIOD, "CFP_PER"),
+ DEFBASIC(AR_TIMER0, "TIMER0"),
+ DEFBASIC(AR_TIMER1, "TIMER1"),
+ DEFBASIC(AR_TIMER2, "TIMER2"),
+ DEFBASIC(AR_TIMER3, "TIMER3"),
+ DEFBASIC(AR_CFP_DUR, "CFP_DUR"),
+ DEFBASIC(AR_RX_FILTER, "RXFILTER"),
+ DEFBASIC(AR_MCAST_FIL0, "MCAST_0"),
+ DEFBASIC(AR_MCAST_FIL1, "MCAST_1"),
+ DEFBASICfmt(AR_DIAG_SW, "DIAG_SW",
+ "\20\1CACHE_ACK\2ACK_DIS\3CTS_DIS\4ENCRYPT_DIS\5DECRYPT_DIS\6RX_DIS"
+ "\7CORR_FCS\10CHAN_INFO\11EN_SCRAMSD\22FRAME_NV0\25RX_CLR_HI"
+ "\26IGNORE_CS\27CHAN_IDLE\30PHEAR_ME"),
+ DEFBASIC(AR_TSF_L32, "TSF_L32"),
+ DEFBASIC(AR_TSF_U32, "TSF_U32"),
+ DEFBASIC(AR_TST_ADDAC, "TST_ADAC"),
+ DEFBASIC(AR_DEF_ANTENNA, "DEF_ANT"),
+ DEFBASIC(AR_QOS_MASK, "QOS_MASK"),
+ DEFBASIC(AR_SEQ_MASK, "SEQ_MASK"),
+ DEFBASIC(AR_OBSERV_2, "OBSERV2"),
+ DEFBASIC(AR_OBSERV_1, "OBSERV1"),
+
+ DEFBASIC(AR_LAST_TSTP, "LAST_TST"),
+ DEFBASIC(AR_NAV, "NAV"),
+ DEFBASIC(AR_RTS_OK, "RTS_OK"),
+ DEFBASIC(AR_RTS_FAIL, "RTS_FAIL"),
+ DEFBASIC(AR_ACK_FAIL, "ACK_FAIL"),
+ DEFBASIC(AR_FCS_FAIL, "FCS_FAIL"),
+ DEFBASIC(AR_BEACON_CNT, "BEAC_CNT"),
+
+ DEFBASIC(AR_SLEEP1, "SLEEP1"),
+ DEFBASIC(AR_SLEEP2, "SLEEP2"),
+ DEFBASIC(AR_SLEEP3, "SLEEP3"),
+ DEFBASIC(AR_BSSMSKL, "BSSMSKL"),
+ DEFBASIC(AR_BSSMSKU, "BSSMSKU"),
+ DEFBASIC(AR_TPC, "TPC"),
+ DEFBASIC(AR_TFCNT, "TFCNT"),
+ DEFBASIC(AR_RFCNT, "RFCNT"),
+ DEFBASIC(AR_RCCNT, "RCCNT"),
+ DEFBASIC(AR_CCCNT, "CCCNT"),
+ DEFBASIC(AR_QUIET1, "QUIET1"),
+ DEFBASIC(AR_QUIET2, "QUIET2"),
+ DEFBASIC(AR_TSF_PARM, "TSF_PARM"),
+ DEFBASIC(AR_NOACK, "NOACK"),
+ DEFBASIC(AR_PHY_ERR, "PHY_ERR"),
+ DEFBASIC(AR_QOS_CONTROL, "QOS_CTRL"),
+ DEFBASIC(AR_QOS_SELECT, "QOS_SEL"),
+ DEFBASIC(AR_MISC_MODE, "MISCMODE"),
+ DEFBASIC(AR_FILTOFDM, "FILTOFDM"),
+ DEFBASIC(AR_FILTCCK, "FILTCCK"),
+ DEFBASIC(AR_PHYCNT1, "PHYCNT1"),
+ DEFBASIC(AR_PHYCNTMASK1, "PHYCMSK1"),
+ DEFBASIC(AR_PHYCNT2, "PHYCNT2"),
+ DEFBASIC(AR_PHYCNTMASK2, "PHYCMSK2"),
+
+ DEFBASIC(AR_TXOP_X, "TXOPX"),
+ DEFBASIC(AR_NEXT_TBTT, "NXTTBTT"),
+ DEFBASIC(AR_NEXT_DBA, "NXTDBA"),
+ DEFBASIC(AR_NEXT_SWBA, "NXTSWBA"),
+ DEFBASIC(AR_NEXT_CFP, "NXTCFP"),
+ DEFBASIC(AR_NEXT_HCF, "NXTHCF"),
+ DEFBASIC(AR_NEXT_DTIM, "NXTDTIM"),
+ DEFBASIC(AR_NEXT_QUIET, "NXTQUIET"),
+ DEFBASIC(AR_NEXT_NDP, "NXTNDP"),
+ DEFBASIC(AR5416_BEACON_PERIOD, "BCNPER"),
+ DEFBASIC(AR_DBA_PERIOD, "DBAPER"),
+ DEFBASIC(AR_SWBA_PERIOD, "SWBAPER"),
+ DEFBASIC(AR_TIM_PERIOD, "TIMPER"),
+ DEFBASIC(AR_DTIM_PERIOD, "DTIMPER"),
+ DEFBASIC(AR_QUIET_PERIOD, "QUIETPER"),
+ DEFBASIC(AR_NDP_PERIOD, "NDPPER"),
+ DEFBASIC(AR_TIMER_MODE, "TIMERMOD"),
+ DEFBASIC(AR_2040_MODE, "2040MODE"),
+ DEFBASIC(AR_PCU_TXBUF_CTRL, "PCUTXBUF"),
+ DEFBASIC(AR_SLP32_MODE, "SLP32MOD"),
+ DEFBASIC(AR_SLP32_WAKE, "SLP32WAK"),
+ DEFBASIC(AR_SLP32_INC, "SLP32INC"),
+ DEFBASIC(AR_SLP_CNT, "SLPCNT"),
+ DEFBASIC(AR_SLP_MIB_CTRL, "SLPMIB"),
+ DEFBASIC(AR_EXTRCCNT, "EXTRCCNT"),
+ DEFBASIC(AR_PHY_TURBO, "PHYTURBO"),
+
+ DEFVOID(AR_PHY_ADC_SERIAL_CTL, "PHY_ADC_SERIAL_CTL"),
+
+ /* XXX { AR_RATE_DURATION(0), AR_RATE_DURATION(0x20) }, */
+};
+
+static __constructor void
+ar5416_ctor(void)
+{
+ register_regs(ar5416regs, N(ar5416regs), MAC5416, PHYANY);
+ register_keycache(128, MAC5416, PHYANY);
+
+ register_range(0x9800, 0x987c, DUMP_BASEBAND, MAC5416, PHYANY);
+ register_range(0x9900, 0x997c, DUMP_BASEBAND, MAC5416, PHYANY);
+ register_range(0x99a4, 0x99a4, DUMP_BASEBAND, MAC5416, PHYANY);
+ register_range(0x9c00, 0x9c1c, DUMP_BASEBAND, MAC5416, PHYANY);
+ register_range(0xa180, 0xa238, DUMP_BASEBAND, MAC5416, PHYANY);
+ register_range(0xa258, 0xa26c, DUMP_BASEBAND, MAC5416, PHYANY);
+ register_range(0xa3c8, 0xa3d4, DUMP_BASEBAND, MAC5416, PHYANY);
+ register_range(0xa864, 0xa864, DUMP_BASEBAND, MAC5416, PHYANY);
+ register_range(0xa9bc, 0xa9bc, DUMP_BASEBAND, MAC5416, PHYANY);
+ register_range(0xb864, 0xb864, DUMP_BASEBAND, MAC5416, PHYANY);
+ register_range(0xb9bc, 0xb9bc, DUMP_BASEBAND, MAC5416, PHYANY);
+}
diff --git a/tools/tools/backout_commit/backout_commit.rb b/tools/tools/backout_commit/backout_commit.rb
new file mode 100644
index 000000000000..264c271b60bf
--- /dev/null
+++ b/tools/tools/backout_commit/backout_commit.rb
@@ -0,0 +1,350 @@
+#!/usr/bin/env ruby -w
+
+# $FreeBSD$
+
+# Please note, that this utility must be kept in sync with
+# CVSROOT/log_accum.pl. If someone has a different output from their
+# mail client when saving e-mails as text files, feel free to hack it
+# in as an option.
+#
+# If someone would like to hack in the ability to generate diffs based
+# off of this script, by all means, be my guest.
+
+require 'getoptlong'
+
+$basedir = '/usr'
+$backout_script = "backout-#{Time.now.strftime("%Y-%m-%d-%H-%M")}.sh"
+$commit_authors = []
+$commit_dates = []
+$commit_file = nil
+$commit_message = nil
+$cvsbin = nil
+$cvs_path = '/usr/bin/cvs'
+$cvsrc_ignore = true
+$debug = 0
+$echo_path = '/usr/bin/echo'
+$echo_warnings = true
+$force_script_edit = false
+$force_remove = false
+$output = $stdout
+$quiet_script = false
+$shell_path = '/bin/sh'
+$shell_args = '--'
+
+def debug(level, *msgs)
+ if level <= $debug
+ if $debug > 1
+ $output.puts "DEBUG(#{level}): #{msgs.shift}"
+ else
+ $output.puts msgs.shift
+ end
+
+ for msg in msgs
+ $output.puts "\t #{msg}"
+ end
+ end
+end # def debug()
+
+
+def usage(msg, info = nil)
+ out = (msg.nil? ? $stdout : $stderr)
+ out.puts "#{File.basename($0)} usage:" << (msg.nil? ? '' : " #{msg}")
+ out.puts "#{info}" unless info.nil?
+ out.puts ""
+ out.puts " -s, --backout-script=<file> Specifies the filename of the script"
+ out.puts " -D, --basedir=<dir> Specifies the base directory [/usr]"
+ out.puts " -a, --commit-author=<uid> Forces a commit author"
+ out.puts " -d, --commit-date=<date> Forces a commit date"
+ out.puts " -m, --commit-file=<path> Specifies a commit message file"
+ out.puts " -M, --commit-message=<msg> Specifies a commit message"
+ out.puts " -c, --cvs-path=<path> Specifies the CVS binary to be used [cvs]"
+ out.puts " -C, --cvsrc-ignore=<bool> If true, will ignore options in ~/.cvsrc"
+ out.puts " -e, --echo-path=<path> Specifies the path to echo"
+ out.puts " -f, --force-remove=<bool> If true, removes new files [false]"
+ out.puts " -F, --force-edit=<bool> If true, add -C to the shell arguments in"
+ out.puts " the backout script if the shell is sh,"
+ out.puts " which forces an edit of the script"
+ out.puts " -O, --output=<stdio> Specifies what fd to direct the output to"
+ out.puts " -A, --shell-args=<string> Specifies the shell arguments to be used"
+ out.puts " -S, --shell-path=<path> Specifies the shell to be used [/bin/sh]"
+ out.puts " -W, --warnings=<bool> Turns on or off warnings [true]"
+ exit(msg.nil? ? 0 : 1)
+end
+
+
+OPTION_LIST = [
+ ['--backout-script','-s', GetoptLong::REQUIRED_ARGUMENT],
+ ['--basedir','-D', GetoptLong::REQUIRED_ARGUMENT],
+ ['--commit-author','-a', GetoptLong::REQUIRED_ARGUMENT],
+ ['--commit-date','-d', GetoptLong::REQUIRED_ARGUMENT],
+ ['--commit-file','-m', GetoptLong::REQUIRED_ARGUMENT],
+ ['--commit-message','-M', GetoptLong::REQUIRED_ARGUMENT],
+ ['--cvs-path','-c',GetoptLong::REQUIRED_ARGUMENT],
+ ['--cvsrc-ignore','-C',GetoptLong::REQUIRED_ARGUMENT],
+ ['--echo-path','-e',GetoptLong::REQUIRED_ARGUMENT],
+ ['--force-edit','-F',GetoptLong::REQUIRED_ARGUMENT],
+ ['--force-remove','-f',GetoptLong::REQUIRED_ARGUMENT],
+ ['--output', '-O', GetoptLong::REQUIRED_ARGUMENT],
+ ['--quiet-script','-q',GetoptLong::REQUIRED_ARGUMENT],
+ ['--shell-args','-A',GetoptLong::REQUIRED_ARGUMENT],
+ ['--shell-path','-S',GetoptLong::REQUIRED_ARGUMENT],
+ ['--warnings','-w', GetoptLong::REQUIRED_ARGUMENT],
+]
+
+opt_parser = GetoptLong.new(*OPTION_LIST)
+opt_parser.quiet = true
+
+begin
+ opt_parser.each do |opt,arg|
+ case opt
+ when '--backout-script'
+ debug(3, "backout script was #{$backout_script.inspect} : is #{arg.inspect}")
+ $backout_script = arg
+ when '--basedir'
+ debug(3, "base directory was #{$basedir.inspect} : is #{arg.inspect}")
+ $basedir = arg
+ when '--commit-author'
+ debug(3, "commit author #{arg.inspect} added to list")
+ $commit_authors.push(arg.dup)
+ when '--commit-date'
+ debug(3, "commit date #{arg.inspect} added to list")
+ $commit_date.push(arg.dup)
+ when '--commit-file'
+ debug(3, "commit file was #{$commit_file.inspect} : is #{arg.inspect}")
+ $commit_file = arg
+ when '--commit-message'
+ debug(3, "commit message was #{$commit_message.inspect} : is #{arg.inspect}")
+ $commit_message = arg
+ when '--cvs-path'
+ debug(3, "cvs path was #{$cvs_path.inspect} : is #{arg.inspect}")
+ $cvs_path = arg
+ when '--cvsrc-ignore'
+ if arg =~ /true|yes/i
+ $cvsrc_ignore = true
+ elsif arg =~ /false|no/i
+ $cvsrc_ignore = false
+ else
+ usage("#{opt}: unknown bool format \"#{arg}\"", "Valid options are \"true\", \"false\", \"yes\", or \"no\"")
+ end
+ debug(3, "ignoring of ~/.cvsrc is set to #{$cvsrc_ignore.inspect}")
+ when '--echo-path'
+ debug(3, "echo path was #{$echo_path.inspect} : is #{arg.inspect}")
+ $echo_path = arg
+ when '--force-edit'
+ if arg =~ /true|yes/i
+ $force_script_edit = true
+ elsif arg =~ /false|no/i
+ $force_script_edit = false
+ else
+ usage("#{opt}: unknown bool format \"#{arg}\"", "Valid options are \"true\", \"false\", \"yes\", or \"no\"")
+ end
+ debug(3, "force edit of backout script is set to #{$force_script_edit.inspect}")
+ when '--force-remove'
+ if arg =~ /true|yes/i
+ $force_remove = true
+ elsif arg =~ /false|no/i
+ $force_remove = false
+ else
+ usage("#{opt}: unknown bool format \"#{arg}\"", "Valid options are \"true\", \"false\", \"yes\", or \"no\"")
+ end
+ debug(3, "force removal of files is set to #{$force_remove.inspect}")
+ when '--output'
+ case arg
+ when 'stdout'
+ $output = $stdout
+ when 'stderr'
+ $output = $stderr
+ else
+ usage("#{opt}: unknown output format","Valid outputs are \"stdout\" and \"stderr\"")
+ end
+ debug(3, "output set to #{arg}")
+ when '--quiet-script'
+ if arg =~ /true|yes/i
+ $quiet_script = true
+ elsif arg =~ /false|no/i
+ $quiet_script = false
+ else
+ usage("#{opt}: unknown bool format \"#{arg}\"", "Valid options are \"true\", \"false\", \"yes\", or \"no\"")
+ end
+ debug(3, "quiet script is set to #{$quiet_script.inspect}")
+ when '--shell-args'
+ debug(3, "shell args were #{$shell_args.inspect} : is #{arg.inspect}")
+ $shell_args = arg
+ when '--shell-path'
+ debug(3, "shell path was #{$shell_path.inspect} : is #{arg.inspect}")
+ $shell_path = arg
+ when '--warnings'
+ if arg =~ /true|yes/i
+ $echo_warnings = true
+ elsif arg =~ /false|no/i
+ $echo_warnings = false
+ else
+ usage("#{opt}: unknown bool format \"#{arg}\"", "Valid options are \"true\", \"false\", \"yes\", or \"no\"")
+ end
+ debug(3, "warnings are set to #{$echo_warnings.inspect}")
+ end
+ end
+rescue GetoptLong::InvalidOption
+ usage("invalid argument")
+rescue GetoptLong::MissingArgument
+ usage("missing argument")
+rescue GetoptLong::NeedlessArgument => msg
+ usage("passed an extra argument: #{msg}")
+end
+
+debug(3, "Verbosity set to: #{$debug}")
+
+$cvsbin = $cvs_path
+$cvsbin << " -f" if $cvsrc_ignore
+
+if ARGV.length < 1
+ usage("require a commit message to parse")
+end
+
+$output.puts("Backout directory:\t#{$basedir}")
+$output.puts("Backout script:\t\t#{$backout_script}")
+$output.puts("")
+
+# Backout script - to be run by hand
+File.open($backout_script, "w+") do |f|
+ removals = []
+ updates = []
+ files = []
+
+ f.puts("#!#{$shell_path}#{($force_script_edit && $shell_path == '/bin/sh') ? ' -C' : ''} #{$shell_args}")
+ f.puts()
+ f.puts("# Generated at: #{Time.now()}")
+ f.puts("# Generated by: #{ENV['USER']}\@#{ENV['HOST']}")
+ f.puts()
+ f.puts("BASEDIR=#{$basedir}")
+ f.puts('if [ $BASEDIR != $PWD ]; then')
+ f.puts(' echo "Please change to $BASEDIR before running this shell script"')
+ f.puts(' exit 1')
+ f.puts('fi')
+ f.puts()
+
+ author_regexp = Regexp.new(/^([^\ ]+)\s+([\d]{4})\/([\d]{2})\/([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2}) ([A-Z]{3})$/)
+ file_regexp = Regexp.new(/^ ([\d\.]+)\s+\+([\d]+) \-([\d]+)\s+(.*?)$/)
+ newdead_regexp = Regexp.new(/^(.*?) \((new|dead)\)$/)
+ rev_regexp = Regexp.new(/^ Revision Changes Path$/)
+
+ for email_file in ARGV
+ File.open(email_file) do |e|
+ $output.print("Scanning through #{email_file}...")
+ found_files = false
+ for line in e
+ line.chomp!
+ if found_files == false
+ amd = author_regexp.match(line)
+ if !amd.nil?
+ $commit_authors.push(amd[1].dup)
+ $commit_dates.push(Time.local(*amd[2..7]).dup)
+ elsif rev_regexp.match(line)
+ found_files = true
+ end
+ else # if found_files
+ md = file_regexp.match(line)
+ next if md.nil?
+
+ filename = md[4]
+ ndmd = newdead_regexp.match(filename)
+ if !ndmd.nil?
+ filename = ndmd[1]
+ if ndmd[2] == 'new'
+ removals.push(filename)
+ f.puts("#{$force_remove ? '' : '# '}#{$echo_path} -n \"Removing #{filename}...\"") if !$quiet_script
+ f.puts("#{$force_remove ? '' : '# '}#{$cvsbin} rm -f #{filename}")
+ f.puts("#{$force_remove ? '' : '# '}#{$echo_path} \"done.\"") if !$quiet_script
+ f.puts()
+ files.push(filename)
+ next
+ end
+ end
+ f.puts("#{$echo_path} -n \"Updating #{filename} to #{md[1]}...\"") if !$quiet_script
+ f.puts("#{$cvsbin} up -p -r #{md[1]} #{filename} > #{filename}")
+ f.puts("#{$echo_path} \"done.\"") if !$quiet_script
+ f.puts()
+ files.push(filename)
+ end # if found_files
+ end # for line in..
+ $output.puts("done.")
+ end # File.open()
+ end # for email_file in ARGV...
+
+ if removals.length > 0 && $force_remove == false
+ f.puts("#{$echo_warnings ? '' : '# '}#{$echo_path} \"You may want to remove the following file#{removals.length > 1 ? 's' : ''}:\"")
+ for filename in removals
+ f.puts("#{$echo_warnings ? '' : '# '}#{$echo_path} \"\t#{filename}\"")
+ end
+ f.puts()
+ f.puts("#{$echo_warnings ? '' : '# '}#{$echo_path} \"There is code in #{$backout_script} to remove #{removals.length > 1 ? 'these files' : 'this file'} for you,\"")
+ f.puts("#{$echo_warnings ? '' : '# '}#{$echo_path} \"just uncomment them or pass the option --force-remove=true to #{$0}.\"")
+ end
+
+ f.puts()
+ f.puts("# # # Uncomment the following line to commit the backout.")
+ f.puts("# # #{$echo_path} -n \"Committing backout...\"") if !$quiet_script
+ if !$commit_message.nil?
+ if $commit_message.empty? or $commit_message =~ /^default|no|yes|true|false/i
+ $commit_message = "Backout of commit by #{$commit_authors.join(', ')} done on #{$commit_dates.join(', ')} because\n[___FILL_IN_THE_BLANK___]\n"
+ end
+
+ f.puts()
+ f.puts("# # # EDIT COMMIT MESSAGE HERE")
+ f.puts("CVSCOMMITMSG=<<DONTUSECVSMSG")
+ f.puts($commit_message)
+ f.puts('DONTUSECVSMSG')
+ f.puts()
+ elsif !$commit_file.nil?
+ f.puts("if [ ! -r #{$commit_file} ]; then")
+ f.puts(" #{$echo_path} \"The commit message file #{$commit_file} is not readable,\"")
+ f.puts(" #{$echo_path} \"please fix this and re-run the script.\"")
+ f.puts(" exit 1")
+ f.puts("fi")
+ f.puts()
+ end
+
+ f.print("# # #{$cvsbin} ci")
+ if !$commit_message.nil?
+ f.print(" -m \"$CVSCOMMITMSG\"")
+ elsif !$commit_file.nil?
+ f.print(" -F \"#{$commit_file}\"")
+ end
+ f.puts(" #{files.join(' ')}")
+
+ if !$quiet_script
+ if $commit_message.nil? and $commit_file.nil?
+ f.print("# # #{$echo_path} \"Commit complete. Backout should be complete. Please check to verify.\"")
+ else
+ f.puts("# # #{$echo_path} \"done.\"")
+ end
+ end
+end # File.open()
+
+$output.puts()
+$output.puts("Change to #{$basedir} and run this script. Please look through this script and")
+$output.puts("make changes as necessary. There are commented out commands available")
+$output.puts("in the script.")
+$output.puts()
+if !$commit_message.nil?
+ $output.puts("If you scroll to the bottom of #{$backout_script} you should be able to")
+ $output.puts("find a HERE document with your commit message, if you would like to make")
+ $output.puts("any further changes to your message.")
+ $output.puts()
+end
+if !$commit_file.nil?
+ begin
+ stat = File.stat($commit_file)
+ rescue Errno::ENOENT
+ $output.puts("The output file specified, \"#{$commit_file}\" DOES NOT EXIST!!! Please be sure to")
+ $output.puts("create/edit the file \"#{$commit_file}\" before you run this script")
+ $output.puts()
+ end
+end
+$output.puts("Example script usage:")
+$output.puts("\tmv #{$backout_script} #{$basedir}")
+$output.puts("\tcd #{$basedir}")
+$output.puts("\tless #{$backout_script}")
+$output.puts("\t#{$shell_path} #{$backout_script}")
+$output.puts("\trm -f #{$backout_script}")
+$output.puts()
diff --git a/tools/tools/build_option_survey/listallopts.sh b/tools/tools/build_option_survey/listallopts.sh
new file mode 100644
index 000000000000..77c859aaee48
--- /dev/null
+++ b/tools/tools/build_option_survey/listallopts.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+# This file is in the public domain
+
+
+set -e
+
+T=/tmp/_$$
+
+cd /usr/src
+make showconfig __MAKE_CONF=/dev/null SRCCONF=/dev/null |
+ sort |
+ sed '
+ s/^MK_//
+ s/=//
+ ' | awk '
+ $2 == "yes" { printf "WITHOUT_%s\n", $1 }
+ $2 == "no" { printf "WITH_%s\n", $1 }
+ '
+
diff --git a/tools/tools/build_option_survey/mkhtml.sh b/tools/tools/build_option_survey/mkhtml.sh
new file mode 100644
index 000000000000..a6261f918887
--- /dev/null
+++ b/tools/tools/build_option_survey/mkhtml.sh
@@ -0,0 +1,224 @@
+#!/bin/sh
+# This file is in the public domain
+# $FreeBSD$
+
+set -e
+
+sh reduce.sh
+
+OPLIST=`sh listallopts.sh`
+
+ODIR=/usr/obj/`pwd`
+RDIR=${ODIR}/_.result
+export ODIR RDIR
+
+table_td () (
+
+ awk -v R=$1 -v T=$2 -v M=$4 '
+ BEGIN {
+ t= R "-" T
+ }
+ $1 == t {
+ if ($3 == 0 && $5 == 0 && $7 == 0) {
+ printf "<TD align=center COLSPAN=5>no effect</TD>"
+ } else {
+ if ($3 == 0) {
+ printf "<TD align=right>+%d</TD>", $3
+ } else {
+ printf "<TD align=right>"
+ printf "<A HREF=\"%s/%s.mtree.add.txt\">+%d</A>", M, t, $3
+ printf "</TD>"
+ }
+ if ($5 == 0) {
+ printf "<TD align=right>-%d</TD>", $5
+ } else {
+ printf "<TD align=right>"
+ printf "<A HREF=\"%s/%s.mtree.sub.txt\">-%d</A>", M, t, $5
+ printf "</TD>"
+ }
+ if ($7 == 0) {
+ printf "<TD align=right>*%d</TD>", $7
+ } else {
+ printf "<TD align=right>"
+ printf "<A HREF=\"%s/%s.mtree.chg.txt\">*%d</A>", M, t, $7
+ printf "</TD>"
+ }
+ printf "<TD align=right>%d</TD>", $9
+ printf "<TD align=right>%d</TD>", -$11
+ }
+ printf "\n"
+ d = 1
+ }
+ END {
+ if (d != 1) {
+ printf "<TD COLSPAN=5></TD>"
+ }
+ }
+ ' $3/stats
+ mkdir -p $HDIR/$4
+ cp $3/r*.txt $HDIR/$4 || true
+)
+
+HDIR=${ODIR}/HTML
+rm -rf ${HDIR}
+mkdir -p ${HDIR}
+H=${HDIR}/index.html
+
+echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML>' > $H
+
+echo '<HEAD>
+<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<TITLE>FreeBSD Build Options Survey</TITLE>
+</HEAD>
+<BODY bgcolor="#FFFFFF">
+' >> $H
+
+echo '
+<H2>The table is explained at the bottom</H2>
+<HR>
+' >> $H
+
+echo '<TABLE border="1" cellspacing="0">' >> $H
+
+echo "<TR>" >> $H
+echo "<TH ROWSPAN=2>src.conf</TH>" >> $H
+echo "<TH ROWSPAN=2>MK_FOO</TH>" >> $H
+echo "<TH ROWSPAN=2></TH>" >> $H
+echo "<TH COLSPAN=5>BuildWorld</TH>" >> $H
+echo "<TH ROWSPAN=2></TH>" >> $H
+echo "<TH COLSPAN=5>InstallWorld</TH>" >> $H
+echo "<TH ROWSPAN=2></TH>" >> $H
+echo "<TH COLSPAN=5>World</TH>" >> $H
+echo "</TR>" >> $H
+
+echo "<TR>" >> $H
+for i in bw iw w
+do
+ echo "<TH>A</TH>" >> $H
+ echo "<TH>D</TH>" >> $H
+ echo "<TH>C</TH>" >> $H
+ echo "<TH>KB</TH>" >> $H
+ echo "<TH>Delta</TH>" >> $H
+done
+echo "</TR>" >> $H
+
+majcol ( ) (
+ echo "<TD></TD>" >> $H
+ if [ ! -f $3/$1/done ] ; then
+ echo "<TD align=center COLSPAN=5>no data yet</TD>" >> $H
+ elif [ -f $3/$1/_.success ] ; then
+ table_td $2 $1 $3 $4 >> $H
+ else
+ echo "<TD align=center COLSPAN=5>failed</TD>" >> $H
+ fi
+)
+
+
+for o in $OPLIST
+do
+ md=`echo "${o}=foo" | md5`
+ m=${RDIR}/$md
+ if [ ! -d $m ] ; then
+ continue
+ fi
+ if [ ! -f $m/stats ] ; then
+ continue
+ fi
+ echo "=== mkhtml ${d}_${o}"
+
+ echo "<TR>" >> $H
+ echo "<TD><PRE>" >> $H
+ cat $m/src.conf >> $H
+ echo "</PRE></TD>" >> $H
+ echo "<TD><PRE>" >> $H
+ if [ -f $m/bw/_.sc ] ; then
+ comm -13 ${RDIR}/Ref/_.sc $m/bw/_.sc >> $H
+ fi
+ echo "</PRE></TD>" >> $H
+
+ majcol bw r $m $md
+ majcol iw r $m $md
+ majcol w r $m $md
+ echo "</TR>" >> $H
+done
+echo "</TABLE>" >> $H
+echo '
+<HR>
+<H2>How to read this table</H2>
+<P>
+The table has five major columns.
+
+<OL>
+<LI><P><B>src.conf</B></P>
+<P>The name of the option being tested</P>
+<P>
+All options are tested both in their WITH_FOO and WITHOUT_FOO variants
+but if the option has no effect (ie: is the default) it will not appear
+in the table
+</P>
+</LI>
+
+<LI><P><B>MK_FOO</B></P>
+<P>Internal build flags affected by this option </P>
+</LI>
+
+<LI><P><B>Buildworld</B></P>
+<P>What happens when the option is given to buildworld but not installworld</P>
+<PRE>Ie:
+ make buildworld WITH_FOO=yes
+ make installworld
+</PRE>
+</LI>
+
+<LI><P><B>Installworld</B></P>
+<P>What happens when the option is given to installworld but not buildworld</P>
+<PRE>Ie:
+ make buildworld
+ make installworld WITH_FOO=yes
+</PRE>
+</LI>
+
+<LI><P><B>World</B></P>
+<P>What happens when the option is given to both buildworld and installworld</P>
+<PRE>Ie:
+ make buildworld WITH_FOO=yes
+ make installworld WITH_FOO=yes
+</PRE>
+</LI>
+</OL>
+
+<P>Inside each of the last three major columns there are five subcolumns</P>
+<OL>
+<LI><P><B>A</B></P>
+<P>Number of added files/directories (relative to the option not be given</P>
+<P>If non-zero, the number links to a list of the added files/directories</P>
+</LI>
+<LI><P><B>D</B></P>
+<P>Number of deleted files/directories (relative to the option not be given</P>
+<P>If non-zero, the number links to a list of the files not installed files/directories</P>
+</LI>
+<LI><P><B>C</B></P>
+<P>Number of changed files/directories (relative to the option not be given</P>
+<P>If non-zero, the number links to a list of the files/directories which are differnet (two lines each)</P>
+</LI>
+<LI><P><B>KB</B></P>
+<P>Size of installed operating system in kilobytes</P>
+<LI><P><B>Delta</B></P>
+<P>Size change in kilobytes relative to the option not be given</P>
+</LI>
+</OL>
+
+<HR>' >> $H
+echo '
+<p>
+ <a href="http://validator.w3.org/check?uri=referer"><img
+ src="http://www.w3.org/Icons/valid-html401"
+ alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>
+</p>
+
+' >> $H
+echo "</HTML>" >> $H
+
+echo "rsync phk"
+rsync -r $HDIR/. phk@phk:www/misc/build_options
diff --git a/tools/tools/build_option_survey/option_survey.sh b/tools/tools/build_option_survey/option_survey.sh
new file mode 100644
index 000000000000..3fee3164de0f
--- /dev/null
+++ b/tools/tools/build_option_survey/option_survey.sh
@@ -0,0 +1,198 @@
+#!/bin/sh
+# This file is in the public domain
+# $FreeBSD$
+
+set -ex
+
+OPLIST=`sh listallopts.sh`
+
+MDUNIT=47
+export MDUNIT
+
+ODIR=/usr/obj/`pwd`
+FDIR=${ODIR}/files
+MNT=${ODIR}/_.mnt
+RDIR=${ODIR}/_.result
+
+export ODIR MNT RDIR FDIR
+
+bw ( ) (
+ cd ../../..
+ make showconfig \
+ SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \
+ > ${FDIR}/_.sc 2>&1
+ a=$?
+ echo retval $a
+ if [ $a -ne 0 ] ; then
+ exit 1
+ fi
+ make -j 4 buildworld \
+ SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \
+ > ${FDIR}/_.bw 2>&1
+ a=$?
+ echo retval $a
+ if [ $a -ne 0 ] ; then
+ exit 1
+ fi
+ make -j 4 buildkernel \
+ KERNCONF=GENERIC \
+ SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \
+ > ${FDIR}/_.bk 2>&1
+ a=$?
+ echo retval $a
+ if [ $a -ne 0 ] ; then
+ exit 1
+ fi
+ exit 0
+)
+
+iw ( ) (
+ trap "umount ${MNT} || true" 1 2 15 EXIT
+ newfs -O1 -U -b 4096 -f 512 /dev/md$MDUNIT
+ mkdir -p ${MNT}
+ mount /dev/md${MDUNIT} ${MNT}
+
+ cd ../../..
+ make installworld \
+ SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \
+ DESTDIR=${MNT} \
+ > ${FDIR}/_.iw 2>&1
+ a=$?
+ echo retval $a
+ if [ $a -ne 0 ] ; then
+ exit 1
+ fi
+ cd etc
+ make distribution \
+ SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \
+ DESTDIR=${MNT} \
+ > ${FDIR}/_.etc 2>&1
+ a=$?
+ echo retval $a
+ if [ $a -ne 0 ] ; then
+ exit 1
+ fi
+ cd ..
+ make installkernel \
+ KERNCONF=GENERIC \
+ DESTDIR=${MNT} \
+ SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \
+ > ${FDIR}/_.ik 2>&1
+ a=$?
+ echo retval $a
+ if [ $a -ne 0 ] ; then
+ exit 1
+ fi
+
+ sync ${MNT}
+ ( cd ${MNT} && mtree -c ) > ${FDIR}/_.mtree
+ ( cd ${MNT} && du ) > ${FDIR}/_.du
+ ( df -i ${MNT} ) > ${FDIR}/_.df
+ echo success > ${FDIR}/_.success
+ sync
+ sleep 1
+ sync
+ sleep 1
+ trap "" 1 2 15 EXIT
+ umount ${MNT}
+ echo "iw done"
+)
+
+
+# Clean and recreate the ODIR
+
+if true ; then
+ echo "=== Clean and recreate ${ODIR}"
+ if rm -rf ${ODIR} ; then
+ true
+ else
+ chflags -R noschg ${ODIR}
+ rm -rf ${ODIR}
+ fi
+ mkdir -p ${ODIR} ${FDIR} ${MNT}
+
+fi
+
+trap "umount ${MNT} || true; mdconfig -d -u $MDUNIT" 1 2 15 EXIT
+
+umount $MNT || true
+mdconfig -d -u $MDUNIT || true
+dd if=/dev/zero of=${ODIR}/imgfile bs=1m count=250
+mdconfig -a -t vnode -f ${ODIR}/imgfile -u $MDUNIT
+
+# Build & install the reference world
+
+if true ; then
+ echo "=== Build reference world"
+ echo '' > ${ODIR}/src.conf
+ MAKEOBJDIRPREFIX=$ODIR/_.ref
+ export MAKEOBJDIRPREFIX
+ bw
+ echo "=== Install reference world"
+ mkdir -p ${RDIR}/Ref
+ iw
+ mv ${FDIR}/_.* ${RDIR}/Ref
+fi
+
+# Parse option list into subdirectories with src.conf files.
+
+if true ; then
+ rm -rf ${RDIR}/[0-9a-f]*
+ for o in $OPLIST
+ do
+ echo "${o}=foo" > ${FDIR}/_src.conf
+ m=`md5 < ${FDIR}/_src.conf`
+ mkdir -p ${RDIR}/$m
+ mv ${FDIR}/_src.conf ${RDIR}/$m/src.conf
+ done
+fi
+
+# Run through each testtarget in turn
+
+if true ; then
+ for d in ${RDIR}/[0-9a-z]*
+ do
+ if [ ! -d $d ] ; then
+ continue;
+ fi
+ echo '------------------------------------------------'
+ cat $d/src.conf
+ echo '------------------------------------------------'
+ cp $d/src.conf ${ODIR}/src.conf
+
+ if [ ! -f $d/iw/done ] ; then
+ MAKEOBJDIRPREFIX=$ODIR/_.ref
+ export MAKEOBJDIRPREFIX
+ echo "# BW(ref)+IW(ref) `cat $d/src.conf`"
+ rm -rf $d/iw
+ mkdir -p $d/iw
+ iw || true
+ mv ${FDIR}/_.* $d/iw || true
+ touch $d/iw/done
+ fi
+ if [ ! -f $d/bw/done ] ; then
+ MAKEOBJDIRPREFIX=$ODIR/_.tst
+ export MAKEOBJDIRPREFIX
+ echo "# BW(opt) `cat $d/src.conf`"
+ rm -rf $d/w $d/bw
+ mkdir -p $d/w $d/bw
+ if bw ; then
+ mv ${FDIR}/_.* $d/bw || true
+
+ echo "# BW(opt)+IW(opt) `cat $d/src.conf`"
+ iw || true
+ mv ${FDIR}/_.* $d/w || true
+ touch $d/w/done
+
+ echo "# BW(opt)+IW(ref) `cat $d/src.conf`"
+ echo '' > ${ODIR}/src.conf
+ iw || true
+ mv ${FDIR}/_.* $d/bw || true
+ touch $d/bw/done
+ else
+ mv ${FDIR}/_.* $d/bw || true
+ touch $d/bw/done $d/w/done
+ fi
+ fi
+ done
+fi
diff --git a/tools/tools/build_option_survey/reduce.sh b/tools/tools/build_option_survey/reduce.sh
new file mode 100644
index 000000000000..375574987574
--- /dev/null
+++ b/tools/tools/build_option_survey/reduce.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+# This file is in the public domain
+# $FreeBSD$
+
+set -e
+
+OPLIST=`sh listallopts.sh`
+
+ODIR=/usr/obj/`pwd`
+RDIR=${ODIR}/_.result
+export ODIR RDIR
+
+
+compa ( ) (
+ if [ ! -f $1/_.mtree ] ; then
+ return
+ fi
+ if [ ! -f $2/_.mtree ] ; then
+ return
+ fi
+
+ mtree -k uid,gid,mode,nlink,size,link,type,flags \
+ -f ${1}/_.mtree -f $2/_.mtree > $2/_.mtree.all.txt || true
+ grep '^ ' $2/_.mtree.all.txt > $4/$3.mtree.chg.txt || true
+ grep '^[^ ]' $2/_.mtree.all.txt > $4/$3.mtree.sub.txt || true
+ grep '^ [^ ]' $2/_.mtree.all.txt > $4/$3.mtree.add.txt || true
+ a=`wc -l < $4/$3.mtree.add.txt`
+ s=`wc -l < $4/$3.mtree.sub.txt`
+ c=`wc -l < $4/$3.mtree.chg.txt`
+ c=`expr $c / 2 || true`
+
+ br=`awk 'NR == 2 {print $3}' $1/_.df`
+ bt=`awk 'NR == 2 {print $3}' $2/_.df`
+ echo $3 A $a S $s C $c B $bt D `expr $br - $bt`
+)
+
+for o in $OPLIST
+do
+ md=`echo "${o}=foo" | md5`
+ m=${RDIR}/$md
+ if [ ! -d $m ] ; then
+ continue
+ fi
+ if [ ! -d $m/iw -a ! -d $m/bw -a ! -d $m/w ] ; then
+ continue
+ fi
+ echo "=== reduce ${o}"
+
+ echo
+ echo -------------------------------------------------------------
+ echo $md
+ cat $m/src.conf
+ echo -------------------------------------------------------------
+ if [ ! -f $m/iw/done ] ; then
+ echo "IW pending"
+ elif [ ! -f $m/iw/_.success ] ; then
+ echo "IW failed"
+ fi
+ if [ ! -f $m/bw/done ] ; then
+ echo "BW pending"
+ elif [ ! -f $m/bw/_.success ] ; then
+ echo "BW failed"
+ fi
+ if [ ! -f $m/w/done ] ; then
+ echo "W pending"
+ elif [ ! -f $m/w/_.success ] ; then
+ echo "W failed"
+ fi
+ (
+ for x in iw bw w
+ do
+ compa ${RDIR}/Ref/ $m/$x r-$x $m
+ done
+ ) > $m/stats
+ cat $m/stats
+done
+echo "== reduce done"
diff --git a/tools/tools/bus_autoconf/Makefile b/tools/tools/bus_autoconf/Makefile
new file mode 100644
index 000000000000..c7104de478ec
--- /dev/null
+++ b/tools/tools/bus_autoconf/Makefile
@@ -0,0 +1,46 @@
+# $FreeBSD$
+#
+# Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+#
+# Example on how to use:
+#
+# make clean all install
+#
+# ./bus_autoconf.sh /boot/kernel/*.ko | less
+#
+
+PROG= bus_autoconf
+MAN=
+BINDIR?= /usr/local/bin
+
+SRCS+= bus_autoconf.c
+SRCS+= bus_load_file.c
+SRCS+= bus_sections.c
+SRCS+= bus_usb.c
+
+WARNS= 6
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/bus_autoconf/bus_autoconf.c b/tools/tools/bus_autoconf/bus_autoconf.c
new file mode 100644
index 000000000000..bd5d11ef092c
--- /dev/null
+++ b/tools/tools/bus_autoconf/bus_autoconf.c
@@ -0,0 +1,125 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Disclaimer: This utility and format is subject to change and not a
+ * committed interface.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include "bus_autoconf.h"
+#include "bus_sections.h"
+#include "bus_load_file.h"
+#include "bus_usb.h"
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "bus_autoconf - devd config file generator\n"
+ " -i <structure_type,module.ko>\n"
+ " -F <format_file>\n"
+ " -h show usage\n"
+ );
+ exit(EX_USAGE);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *params = "i:F:h";
+ char *fname;
+ char *section;
+ char *module;
+ char *postfix;
+ uint8_t *ptr;
+ uint32_t len;
+ int c;
+ int any_opt = 0;
+
+ while ((c = getopt(argc, argv, params)) != -1) {
+ switch (c) {
+ case 'i':
+ fname = optarg;
+ load_file(fname, &ptr, &len);
+
+ module = strchr(fname, ',');
+ if (module == NULL) {
+ errx(EX_USAGE, "Invalid input "
+ "file name '%s'", fname);
+ }
+ /* split module and section */
+ *module++ = 0;
+
+ /* remove postfix */
+ postfix = strchr(module, '.');
+ if (postfix)
+ *postfix = 0;
+
+ /* get section name */
+ section = fname;
+
+ /* check section type */
+ if (strncmp(section, "usb_", 4) == 0)
+ usb_import_entries(section, module, ptr, len);
+ else
+ errx(EX_USAGE, "Invalid section '%s'", section);
+
+ free(ptr);
+
+ any_opt = 1;
+ break;
+
+ case 'F':
+ fname = optarg;
+ load_file(fname, &ptr, &len);
+ format_parse_entries(ptr, len);
+ free(ptr);
+
+ any_opt = 1;
+ break;
+
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (any_opt == 0)
+ usage();
+
+ usb_dump_entries();
+
+ return (0);
+}
diff --git a/tools/tools/bus_autoconf/bus_autoconf.h b/tools/tools/bus_autoconf/bus_autoconf.h
new file mode 100644
index 000000000000..0a1ca3fb3163
--- /dev/null
+++ b/tools/tools/bus_autoconf/bus_autoconf.h
@@ -0,0 +1,31 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BUS_AUTOCONF_H_
+#define _BUS_AUTOCONF_H_
+
+#endif /* _BUS_AUTOCONF_H_ */
diff --git a/tools/tools/bus_autoconf/bus_autoconf.sh b/tools/tools/bus_autoconf/bus_autoconf.sh
new file mode 100644
index 000000000000..c99df91e18f7
--- /dev/null
+++ b/tools/tools/bus_autoconf/bus_autoconf.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+# Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+OS=FreeBSD
+DOLLAR=$
+OBJCOPY=objcopy
+
+cat <<EOF
+#
+# ${DOLLAR}${OS}${DOLLAR}
+#
+# This file was automatically generated by "tools/bus_autoconf.sh".
+# Please do not edit!
+#
+
+EOF
+
+rm -f bus_autoconf_format.bin
+rm -f bus_autoconf_args.txt
+rm -f bus_autoconf.ids
+
+for F in $*
+do
+
+G=$(basename ${F})
+
+# Format information
+${OBJCOPY} -j bus_autoconf_format -O binary ${F} bus_autoconf.ids 2> /dev/null
+[ -f bus_autoconf.ids ] && cat bus_autoconf.ids >> bus_autoconf_format.bin
+
+# USB Host mode
+${OBJCOPY} -j usb_host_id -O binary ${F} "usb_host_id,${G}" 2> /dev/null
+[ -f "usb_host_id,${G}" ] && (echo -n " -i usb_host_id,${G}" >> bus_autoconf_args.txt)
+
+# USB Device mode
+${OBJCOPY} -j usb_device_id -O binary ${F} "usb_device_id,${G}" 2> /dev/null
+[ -f "usb_device_id,${G}" ] && (echo -n " -i usb_device_id,${G}" >> bus_autoconf_args.txt)
+
+# USB Dual mode
+${OBJCOPY} -j usb_dual_id -O binary ${F} "usb_dual_id,${G}" 2> /dev/null
+[ -f "usb_dual_id,${G}" ] && (echo -n " -i usb_dual_id,${G}" >> bus_autoconf_args.txt)
+
+done
+
+# Dump all data
+bus_autoconf -F bus_autoconf_format.bin $(cat bus_autoconf_args.txt)
+
+# Cleanup
+rm -f -- \
+ $(cat bus_autoconf_args.txt) \
+ bus_autoconf_args.txt \
+ bus_autoconf_format.bin \
+ bus_autoconf.ids
diff --git a/tools/tools/bus_autoconf/bus_autoconf_format_example.txt b/tools/tools/bus_autoconf/bus_autoconf_format_example.txt
new file mode 100644
index 000000000000..e118f1faebcc
--- /dev/null
+++ b/tools/tools/bus_autoconf/bus_autoconf_format_example.txt
@@ -0,0 +1,111 @@
+/* $FreeBSD$ */
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define U16_XOR "8"
+#define U32_XOR "12"
+#define U64_XOR "56"
+#define U8_BITFIELD_XOR "7"
+#define U16_BITFIELD_XOR "15"
+#define U32_BITFIELD_XOR "31"
+#define U64_BITFIELD_XOR "63"
+#else
+#define U16_XOR "0"
+#define U32_XOR "0"
+#define U64_XOR "0"
+#define U8_BITFIELD_XOR "0"
+#define U16_BITFIELD_XOR "0"
+#define U32_BITFIELD_XOR "0"
+#define U64_BITFIELD_XOR "0"
+#endif
+
+#if USB_HAVE_COMPAT_LINUX
+#define MFL_SIZE "1"
+#else
+#define MFL_SIZE "0"
+#endif
+
+static const char __section("bus_autoconf_format") __used usb_id_format[] = {
+
+ /*
+ * Declare three different sections that use the same format.
+ * All sizes are in bits. Fields cannot be greater than
+ * 8 bits in size. Bitfields having a size greater than 1
+ * must fit within the byte in which the bitfield is defined.
+ */
+
+ "usb_host_id{256,:}"
+ "usb_device_id{256,:}"
+ "usb_dual_id{256,:}"
+
+ /*
+ * Describe all fields in the usb_device_id structure
+ * which is found in sys/dev/usb/usbdi.h.
+ */
+
+#if BITS_PER_LONG == 32 || BITS_PER_LONG == 64
+ "unused{0,8}"
+ "unused{0,8}"
+ "unused{0,8}"
+ "unused{0,8}"
+#if BITS_PER_LONG == 64
+ "unused{0,8}"
+ "unused{0,8}"
+ "unused{0,8}"
+ "unused{0,8}"
+#endif
+#else
+#error "Please update code."
+#endif
+
+ "idVendor[0]{" U16_XOR ",8}"
+ "idVendor[1]{" U16_XOR ",8}"
+ "idProduct[0]{" U16_XOR ",8}"
+ "idProduct[1]{" U16_XOR ",8}"
+ "bcdDevice_lo[0]{" U16_XOR ",8}"
+ "bcdDevice_lo[1]{" U16_XOR ",8}"
+ "bcdDevice_hi[0]{" U16_XOR ",8}"
+ "bcdDevice_hi[1]{" U16_XOR ",8}"
+
+ "bDeviceClass{0,8}"
+ "bDeviceSubClass{0,8}"
+ "bDeviceProtocol{0,8}"
+ "bInterfaceClass{0,8}"
+ "bInterfaceSubClass{0,8}"
+ "bInterfaceProtocol{0,8}"
+
+/* NOTE: On big endian machines bitfields are bitreversed. */
+
+ "mf_vendor{" U8_BITFIELD_XOR ",1}"
+ "mf_product{" U8_BITFIELD_XOR ",1}"
+ "mf_dev_lo{" U8_BITFIELD_XOR ",1}"
+ "mf_dev_hi{" U8_BITFIELD_XOR ",1}"
+
+ "mf_dev_class{" U8_BITFIELD_XOR ",1}"
+ "mf_dev_subclass{" U8_BITFIELD_XOR ",1}"
+ "mf_dev_protocol{" U8_BITFIELD_XOR ",1}"
+ "mf_int_class{" U8_BITFIELD_XOR ",1}"
+
+ "mf_int_subclass{" U8_BITFIELD_XOR ",1}"
+ "mf_int_protocol{" U8_BITFIELD_XOR ",1}"
+ "unused{" U8_BITFIELD_XOR ",6}"
+
+ "mfl_vendor{" U16_XOR "," MFL_SIZE "}"
+ "mfl_product{" U16_XOR "," MFL_SIZE "}"
+ "mfl_dev_lo{" U16_XOR "," MFL_SIZE "}"
+ "mfl_dev_hi{" U16_XOR "," MFL_SIZE "}"
+
+ "mfl_dev_class{" U16_XOR "," MFL_SIZE "}"
+ "mfl_dev_subclass{" U16_XOR "," MFL_SIZE "}"
+ "mfl_dev_protocol{" U16_XOR "," MFL_SIZE "}"
+ "mfl_int_class{" U16_XOR "," MFL_SIZE "}"
+
+ "mfl_int_subclass{" U16_XOR "," MFL_SIZE "}"
+ "mfl_int_protocol{" U16_XOR "," MFL_SIZE "}"
+ "unused{" U16_XOR "," MFL_SIZE "}"
+ "unused{" U16_XOR "," MFL_SIZE "}"
+
+ "unused{" U16_XOR "," MFL_SIZE "}"
+ "unused{" U16_XOR "," MFL_SIZE "}"
+ "unused{" U16_XOR "," MFL_SIZE "}"
+ "unused{" U16_XOR "," MFL_SIZE "}"
+};
diff --git a/tools/tools/bus_autoconf/bus_load_file.c b/tools/tools/bus_autoconf/bus_load_file.c
new file mode 100644
index 000000000000..527e5bce49bf
--- /dev/null
+++ b/tools/tools/bus_autoconf/bus_load_file.c
@@ -0,0 +1,76 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <err.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include "bus_load_file.h"
+
+void
+load_file(const char *fname, uint8_t **pptr, uint32_t *plen)
+{
+ uint8_t *ptr;
+ uint32_t len;
+ off_t off;
+ int f;
+
+ f = open(fname, O_RDONLY);
+ if (f < 0)
+ err(EX_NOINPUT, "Cannot open file '%s'", fname);
+
+ off = lseek(f, 0, SEEK_END);
+ if (off < 0) {
+ err(EX_NOINPUT, "Cannot seek to "
+ "end of file '%s'", fname);
+ }
+
+ if (lseek(f, 0, SEEK_SET) < 0) {
+ err(EX_NOINPUT, "Cannot seek to "
+ "beginning of file '%s'", fname);
+ }
+
+ len = off;
+ if (len != off)
+ err(EX_NOINPUT, "File '%s' is too big", fname);
+
+ ptr = malloc(len);
+ if (ptr == NULL)
+ errx(EX_SOFTWARE, "Out of memory");
+
+ if (read(f, ptr, len) != len)
+ err(EX_NOINPUT, "Cannot read all data");
+
+ close(f);
+
+ *pptr = ptr;
+ *plen = len;
+}
diff --git a/tools/tools/bus_autoconf/bus_load_file.h b/tools/tools/bus_autoconf/bus_load_file.h
new file mode 100644
index 000000000000..57e7739c6155
--- /dev/null
+++ b/tools/tools/bus_autoconf/bus_load_file.h
@@ -0,0 +1,33 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BUS_LOAD_FILE_H_
+#define _BUS_LOAD_FILE_H_
+
+void load_file(const char *, uint8_t **, uint32_t *);
+
+#endif /* _BUS_LOAD_FILE_H_ */
diff --git a/tools/tools/bus_autoconf/bus_sections.c b/tools/tools/bus_autoconf/bus_sections.c
new file mode 100644
index 000000000000..c3260487d1c3
--- /dev/null
+++ b/tools/tools/bus_autoconf/bus_sections.c
@@ -0,0 +1,223 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sysexits.h>
+#include <err.h>
+#include <string.h>
+
+#include <sys/queue.h>
+
+#include "bus_sections.h"
+
+#define MAX_STRING 64
+
+struct format_info;
+typedef TAILQ_HEAD(,format_info) format_info_head_t;
+typedef TAILQ_ENTRY(format_info) format_info_entry_t;
+
+static format_info_head_t format_head = TAILQ_HEAD_INITIALIZER(format_head);
+
+struct format_info {
+ format_info_entry_t entry;
+ format_info_head_t fields;
+ char name[MAX_STRING];
+ uint16_t bit_offset;
+ uint16_t bit_size;
+};
+
+static struct format_info *
+format_info_new(char *pstr, uint16_t bo, uint16_t bs)
+{
+ struct format_info *pfi;
+
+ pfi = malloc(sizeof(*pfi));
+ if (pfi == NULL)
+ errx(EX_SOFTWARE, "Out of memory.");
+
+ memset(pfi, 0, sizeof(*pfi));
+
+ TAILQ_INIT(&pfi->fields);
+
+ strlcpy(pfi->name, pstr, sizeof(pfi->name));
+ pfi->bit_offset = bo;
+ pfi->bit_size = bs;
+ return (pfi);
+}
+
+static const struct format_info *
+format_get_section(const char *section)
+{
+ const struct format_info *psub;
+ static const struct format_info *psub_last;
+ static const char *psub_cache;
+
+ if (psub_cache && strcmp(psub_cache, section) == 0)
+ return (psub_last);
+
+ TAILQ_FOREACH(psub, &format_head, entry) {
+ if (strcmp(section, psub->name) == 0) {
+ psub_cache = section;
+ psub_last = psub;
+ return (psub);
+ }
+ }
+ warnx("Section '%s' not found", section);
+ psub_cache = section;
+ psub_last = psub;
+ return (NULL);
+}
+
+uint16_t
+format_get_section_size(const char *section)
+{
+ const struct format_info *pfi;
+
+ pfi = format_get_section(section);
+ if (pfi == NULL)
+ return (0);
+
+ return ((pfi->bit_offset + 7) / 8);
+}
+
+
+uint8_t
+format_get_field(const char *section, const char *field,
+ const uint8_t *ptr, uint16_t size)
+{
+ const struct format_info *pfi;
+ const struct format_info *psub;
+ uint16_t rem;
+ uint16_t off;
+ uint16_t sz;
+
+ pfi = format_get_section(section);
+ if (pfi == NULL)
+ return (0);
+
+ /* skip until we find the fields */
+ while (pfi && TAILQ_FIRST(&pfi->fields) == NULL)
+ pfi = TAILQ_NEXT(pfi, entry);
+
+ if (pfi == NULL)
+ return (0);
+
+ TAILQ_FOREACH(psub, &pfi->fields, entry) {
+ if (strcmp(field, psub->name) == 0) {
+
+ /* range check */
+ if (((psub->bit_offset + psub->bit_size) / 8) > size)
+ return (0);
+
+ /* compute byte offset */
+ rem = psub->bit_offset & 7;
+ off = psub->bit_offset / 8;
+ sz = psub->bit_size;
+
+ /* extract bit-field */
+ return ((ptr[off] >> rem) & ((1 << sz) - 1));
+ }
+ }
+ warnx("Field '%s' not found in '%s'", field, pfi->name);
+ return (0);
+}
+
+void
+format_parse_entries(const uint8_t *ptr, uint32_t len)
+{
+ static const char *command_list = "012345678:";
+ const char *cmd;
+ struct format_info *pfi;
+ struct format_info *pfi_last = NULL;
+ char linebuf[3][MAX_STRING];
+ uint32_t off = 0;
+ uint16_t bit_offset = 0;
+ uint8_t state = 0;
+ uint8_t cmd_index;
+ int c;
+
+ /*
+ * The format we are parsing:
+ * <string>{string,string}<next_string>{...}
+ */
+ while (len--) {
+ c = *(ptr++);
+
+ /* skip some characters */
+ if (c == 0 || c == '\n' || c == '\r' || c == ' ' || c == '\t')
+ continue;
+
+ /* accumulate non-field delimiters */
+ if (strchr("{,}", c) == NULL) {
+ if (off < (MAX_STRING - 1)) {
+ linebuf[state][off] = c;
+ off++;
+ }
+ continue;
+ }
+ /* parse keyword */
+ linebuf[state][off] = 0;
+ off = 0;
+ state++;
+ if (state == 3) {
+ /* check for command in command list */
+ cmd = strchr(command_list, linebuf[2][0]);
+ if (cmd != NULL)
+ cmd_index = cmd - command_list;
+ else
+ cmd_index = 255;
+
+ /*
+ * Check for new field, format is:
+ *
+ * <field_name>{bit_offset_xor, bit_size}
+ */
+ if (cmd_index < 9 && pfi_last != NULL) {
+ pfi = format_info_new(linebuf[0], bit_offset ^
+ atoi(linebuf[1]), cmd_index);
+ TAILQ_INSERT_TAIL(&pfi_last->fields, pfi, entry);
+ bit_offset += cmd_index;
+ }
+ /*
+ * Check for new section, format is:
+ *
+ * <section_name>{section_bit_size, :}
+ */
+ if (cmd_index == 9) {
+ pfi_last = format_info_new(linebuf[0],
+ atoi(linebuf[1]), cmd_index);
+ TAILQ_INSERT_TAIL(&format_head, pfi_last, entry);
+ bit_offset = 0;
+ }
+ state = 0;
+ continue;
+ }
+ }
+}
diff --git a/tools/tools/bus_autoconf/bus_sections.h b/tools/tools/bus_autoconf/bus_sections.h
new file mode 100644
index 000000000000..2c4c6fc86f20
--- /dev/null
+++ b/tools/tools/bus_autoconf/bus_sections.h
@@ -0,0 +1,35 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BUS_SECTIONS_H_
+#define _BUS_SECTIONS_H_
+
+uint16_t format_get_section_size(const char *);
+uint8_t format_get_field(const char *, const char *, const uint8_t *, uint16_t);
+void format_parse_entries(const uint8_t *, uint32_t);
+
+#endif /* _BUS_SECTIONS_H_ */
diff --git a/tools/tools/bus_autoconf/bus_usb.c b/tools/tools/bus_autoconf/bus_usb.c
new file mode 100644
index 000000000000..f15dd49a98b4
--- /dev/null
+++ b/tools/tools/bus_autoconf/bus_usb.c
@@ -0,0 +1,386 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <sys/queue.h>
+
+#include "bus_autoconf.h"
+#include "bus_sections.h"
+#include "bus_usb.h"
+
+struct usb_blob;
+typedef TAILQ_HEAD(,usb_blob) usb_blob_head_t;
+typedef TAILQ_ENTRY(usb_blob) usb_blob_entry_t;
+
+static usb_blob_head_t usb_blob_head = TAILQ_HEAD_INITIALIZER(usb_blob_head);
+static uint32_t usb_blob_count;
+
+struct usb_blob {
+ usb_blob_entry_t entry;
+ struct usb_device_id temp;
+};
+
+/*
+ * To ensure that the correct USB driver is loaded, the driver having
+ * the most information about the device must be probed first. Then
+ * more generic drivers shall be probed.
+ */
+static int
+usb_compare(const void *_a, const void *_b)
+{
+ const struct usb_device_id *a = _a;
+ const struct usb_device_id *b = _b;
+ int retval;
+
+ /* vendor matches first */
+
+ if (a->match_flag_vendor > b->match_flag_vendor)
+ return (-1);
+ if (a->match_flag_vendor < b->match_flag_vendor)
+ return (1);
+
+ /* product matches first */
+
+ if (a->match_flag_product > b->match_flag_product)
+ return (-1);
+ if (a->match_flag_product < b->match_flag_product)
+ return (1);
+
+ /* device class matches first */
+
+ if (a->match_flag_dev_class > b->match_flag_dev_class)
+ return (-1);
+ if (a->match_flag_dev_class < b->match_flag_dev_class)
+ return (1);
+
+ if (a->match_flag_dev_subclass > b->match_flag_dev_subclass)
+ return (-1);
+ if (a->match_flag_dev_subclass < b->match_flag_dev_subclass)
+ return (1);
+
+ /* interface class matches first */
+
+ if (a->match_flag_int_class > b->match_flag_int_class)
+ return (-1);
+ if (a->match_flag_int_class < b->match_flag_int_class)
+ return (1);
+
+ if (a->match_flag_int_subclass > b->match_flag_int_subclass)
+ return (-1);
+ if (a->match_flag_int_subclass < b->match_flag_int_subclass)
+ return (1);
+
+ if (a->match_flag_int_protocol > b->match_flag_int_protocol)
+ return (-1);
+ if (a->match_flag_int_protocol < b->match_flag_int_protocol)
+ return (1);
+
+ /* then sort according to value */
+
+ if (a->idVendor > b->idVendor)
+ return (1);
+ if (a->idVendor < b->idVendor)
+ return (-1);
+ if (a->idProduct > b->idProduct)
+ return (1);
+ if (a->idProduct < b->idProduct)
+ return (-1);
+ if (a->bDeviceClass > b->bDeviceClass)
+ return (1);
+ if (a->bDeviceClass < b->bDeviceClass)
+ return (-1);
+ if (a->bDeviceSubClass > b->bDeviceSubClass)
+ return (1);
+ if (a->bDeviceSubClass < b->bDeviceSubClass)
+ return (-1);
+ if (a->bDeviceProtocol > b->bDeviceProtocol)
+ return (1);
+ if (a->bDeviceProtocol < b->bDeviceProtocol)
+ return (-1);
+ if (a->bInterfaceClass > b->bInterfaceClass)
+ return (1);
+ if (a->bInterfaceClass < b->bInterfaceClass)
+ return (-1);
+ if (a->bInterfaceSubClass > b->bInterfaceSubClass)
+ return (1);
+ if (a->bInterfaceSubClass < b->bInterfaceSubClass)
+ return (-1);
+ if (a->bInterfaceProtocol > b->bInterfaceProtocol)
+ return (1);
+ if (a->bInterfaceProtocol < b->bInterfaceProtocol)
+ return (-1);
+
+ /* in the end sort by module name and mode */
+
+ retval = strcmp(a->module_name, b->module_name);
+ if (retval == 0)
+ retval = strcmp(a->module_mode, b->module_mode);
+ return (retval);
+}
+
+static void
+usb_sort_entries(struct usb_device_id *id, uint32_t nid)
+{
+ qsort(id, nid, sizeof(*id), &usb_compare);
+}
+
+static void
+usb_import_entry(struct usb_device_id *id, const char *type,
+ const char *module, const uint8_t *ptr, uint16_t size)
+{
+ const char *mode;
+
+ if (strstr(type, "_host_"))
+ mode = "host";
+ else if (strstr(type, "_device_"))
+ mode = "device";
+ else
+ mode = "(host|device)";
+
+ strlcpy(id->module_name, module, sizeof(id->module_name));
+ strlcpy(id->module_mode, mode, sizeof(id->module_mode));
+
+ /* import data from binary object */
+
+ if (format_get_field(type, "mfl_vendor", ptr, size))
+ id->match_flag_vendor = 1;
+ if (format_get_field(type, "mfl_product", ptr, size))
+ id->match_flag_product = 1;
+ if (format_get_field(type, "mfl_dev_lo", ptr, size))
+ id->match_flag_dev_lo = 1;
+ if (format_get_field(type, "mfl_dev_hi", ptr, size))
+ id->match_flag_dev_hi = 1;
+ if (format_get_field(type, "mfl_dev_class", ptr, size))
+ id->match_flag_dev_class = 1;
+ if (format_get_field(type, "mfl_dev_subclass", ptr, size))
+ id->match_flag_dev_subclass = 1;
+ if (format_get_field(type, "mfl_dev_protocol", ptr, size))
+ id->match_flag_dev_protocol = 1;
+ if (format_get_field(type, "mfl_int_class", ptr, size))
+ id->match_flag_int_class = 1;
+ if (format_get_field(type, "mfl_int_subclass", ptr, size))
+ id->match_flag_int_subclass = 1;
+ if (format_get_field(type, "mfl_int_protocol", ptr, size))
+ id->match_flag_int_protocol = 1;
+
+ id->idVendor = format_get_field(type, "idVendor[0]", ptr, size) |
+ (format_get_field(type, "idVendor[1]", ptr, size) << 8);
+ id->idProduct = format_get_field(type, "idProduct[0]", ptr, size) |
+ (format_get_field(type, "idProduct[1]", ptr, size) << 8);
+
+ id->bcdDevice_lo = format_get_field(type, "bcdDevice_lo[0]", ptr, size) |
+ (format_get_field(type, "bcdDevice_lo[1]", ptr, size) << 8);
+
+ id->bcdDevice_hi = format_get_field(type, "bcdDevice_hi[0]", ptr, size) |
+ (format_get_field(type, "bcdDevice_hi[1]", ptr, size) << 8);
+
+ id->bDeviceClass = format_get_field(type, "bDeviceClass", ptr, size);
+ id->bDeviceSubClass = format_get_field(type, "bDeviceSubClass", ptr, size);
+ id->bDeviceProtocol = format_get_field(type, "bDeviceProtocol", ptr, size);
+
+ id->bInterfaceClass = format_get_field(type, "bInterfaceClass", ptr, size);
+ id->bInterfaceSubClass = format_get_field(type, "bInterfaceSubClass", ptr, size);
+ id->bInterfaceProtocol = format_get_field(type, "bInterfaceProtocol", ptr, size);
+
+ if (format_get_field(type, "mf_vendor", ptr, size))
+ id->match_flag_vendor = 1;
+ if (format_get_field(type, "mf_product", ptr, size))
+ id->match_flag_product = 1;
+ if (format_get_field(type, "mf_dev_lo", ptr, size))
+ id->match_flag_dev_lo = 1;
+ if (format_get_field(type, "mf_dev_hi", ptr, size))
+ id->match_flag_dev_hi = 1;
+ if (format_get_field(type, "mf_dev_class", ptr, size))
+ id->match_flag_dev_class = 1;
+ if (format_get_field(type, "mf_dev_subclass", ptr, size))
+ id->match_flag_dev_subclass = 1;
+ if (format_get_field(type, "mf_dev_protocol", ptr, size))
+ id->match_flag_dev_protocol = 1;
+ if (format_get_field(type, "mf_int_class", ptr, size))
+ id->match_flag_int_class = 1;
+ if (format_get_field(type, "mf_int_subclass", ptr, size))
+ id->match_flag_int_subclass = 1;
+ if (format_get_field(type, "mf_int_protocol", ptr, size))
+ id->match_flag_int_protocol = 1;
+
+ /* compute some internal fields */
+ id->is_iface = id->match_flag_int_class |
+ id->match_flag_int_protocol |
+ id->match_flag_int_subclass;
+
+ id->is_dev = id->match_flag_dev_class |
+ id->match_flag_dev_subclass;
+
+ id->is_vp = id->match_flag_vendor |
+ id->match_flag_product;
+
+ id->is_any = id->is_vp + id->is_dev + id->is_iface;
+}
+
+static uint32_t
+usb_dump(struct usb_device_id *id, uint32_t nid)
+{
+ uint32_t n = 1;
+
+ if (id->is_any) {
+ printf("nomatch 32 {\n"
+ " match \"bus\" \"uhub[0-9]+\";\n"
+ " match \"mode\" \"%s\";\n", id->module_mode);
+ } else {
+ printf("# skipped entry on module %s\n",
+ id->module_name);
+ return (n);
+ }
+
+ if (id->match_flag_vendor) {
+ printf(" match \"vendor\" \"0x%04x\";\n",
+ id->idVendor);
+ }
+ if (id->match_flag_product) {
+ uint32_t x;
+
+ if (id->is_any == 1 && id->is_vp == 1) {
+ /* try to join similar entries */
+ while (n < nid) {
+ if (id[n].is_any != 1 || id[n].is_vp != 1)
+ break;
+ if (id[n].idVendor != id[0].idVendor)
+ break;
+ if (strcmp(id[n].module_name, id[0].module_name))
+ break;
+ if (strcmp(id[n].module_mode, id[0].module_mode))
+ break;
+ n++;
+ }
+ }
+ if (n == 1) {
+ printf(" match \"product\" \"0x%04x\";\n",
+ id->idProduct);
+ } else {
+ printf(" match \"product\" \"(");
+
+ for (x = 0; x != n; x++) {
+ printf("0x%04x%s", id[x].idProduct,
+ (x == (n - 1)) ? "" : "|");
+ }
+
+ printf(")\";\n");
+ }
+ }
+ if (id->match_flag_dev_class) {
+ printf(" match \"devclass\" \"0x%02x\";\n",
+ id->bDeviceClass);
+ }
+ if (id->match_flag_dev_subclass) {
+ printf(" match \"devsubclass\" \"0x%02x\";\n",
+ id->bDeviceSubClass);
+ }
+ if (id->match_flag_int_class) {
+ printf(" match \"intclass\" \"0x%02x\";\n",
+ id->bInterfaceClass);
+ }
+ if (id->match_flag_int_subclass) {
+ printf(" match \"intsubclass\" \"0x%02x\";\n",
+ id->bInterfaceSubClass);
+ }
+ if (id->match_flag_int_protocol) {
+ printf(" match \"intprotocol\" \"0x%02x\";\n",
+ id->bInterfaceProtocol);
+ }
+ printf(" action \"kldload -n %s\";\n"
+ "};\n\n", id->module_name);
+
+ return (n);
+}
+
+void
+usb_import_entries(const char *section, const char *module,
+ const uint8_t *ptr, uint32_t len)
+{
+ struct usb_blob *pub;
+ uint32_t section_size;
+ uint32_t off;
+
+ section_size = format_get_section_size(section);
+ if (section_size == 0) {
+ errx(EX_DATAERR, "Invalid or non-existing "
+ "section format '%s'", section);
+ }
+ if (len % section_size) {
+ errx(EX_DATAERR, "Length %d is not "
+ "divisible by %d. Section format '%s'",
+ len, section_size, section);
+ }
+ for (off = 0; off != len; off += section_size) {
+ pub = malloc(sizeof(*pub));
+ if (pub == NULL)
+ errx(EX_SOFTWARE, "Out of memory");
+
+ memset(pub, 0, sizeof(*pub));
+
+ usb_import_entry(&pub->temp, section,
+ module, ptr + off, section_size);
+
+ TAILQ_INSERT_TAIL(&usb_blob_head, pub, entry);
+
+ usb_blob_count++;
+ if (usb_blob_count == 0)
+ errx(EX_SOFTWARE, "Too many entries");
+ }
+}
+
+void
+usb_dump_entries(void)
+{
+ struct usb_blob *pub;
+ struct usb_device_id *id;
+ uint32_t x;
+
+ id = malloc(usb_blob_count * sizeof(*id));
+ if (id == NULL)
+ errx(EX_SOFTWARE, "Out of memory");
+
+ /* make linear array of all USB blobs */
+ x = 0;
+ TAILQ_FOREACH(pub, &usb_blob_head, entry)
+ id[x++] = pub->temp;
+
+ usb_sort_entries(id, usb_blob_count);
+
+ for (x = 0; x != usb_blob_count;)
+ x += usb_dump(id + x, usb_blob_count - x);
+
+ free(id);
+
+ printf("# %d USB entries processed\n\n", usb_blob_count);
+}
diff --git a/tools/tools/bus_autoconf/bus_usb.h b/tools/tools/bus_autoconf/bus_usb.h
new file mode 100644
index 000000000000..378df9a64c3e
--- /dev/null
+++ b/tools/tools/bus_autoconf/bus_usb.h
@@ -0,0 +1,73 @@
+/* $FreeBSD$ */
+
+/*-
+ * Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BUS_USB_H_
+#define _BUS_USB_H_
+
+struct usb_device_id {
+
+ /* Internal fields */
+ char module_name[32];
+ char module_mode[32];
+ uint8_t is_iface;
+ uint8_t is_vp;
+ uint8_t is_dev;
+ uint8_t is_any;
+
+ /* Used for product specific matches; the BCD range is inclusive */
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice_lo;
+ uint16_t bcdDevice_hi;
+
+ /* Used for device class matches */
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+
+ /* Used for interface class matches */
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+
+ /* Select which fields to match against */
+ uint8_t match_flag_vendor:1;
+ uint8_t match_flag_product:1;
+ uint8_t match_flag_dev_lo:1;
+ uint8_t match_flag_dev_hi:1;
+ uint8_t match_flag_dev_class:1;
+ uint8_t match_flag_dev_subclass:1;
+ uint8_t match_flag_dev_protocol:1;
+ uint8_t match_flag_int_class:1;
+ uint8_t match_flag_int_subclass:1;
+ uint8_t match_flag_int_protocol:1;
+};
+
+void usb_import_entries(const char *, const char *, const uint8_t *, uint32_t);
+void usb_dump_entries(void);
+
+#endif /* _BUS_USB_H_ */
diff --git a/tools/tools/cd2dvd/cd2dvd.sh b/tools/tools/cd2dvd/cd2dvd.sh
new file mode 100755
index 000000000000..c741344e73bd
--- /dev/null
+++ b/tools/tools/cd2dvd/cd2dvd.sh
@@ -0,0 +1,267 @@
+#!/bin/sh
+#
+# Copyright (C) 2008 Roman Kurakin rik@freebsd.org. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# Merges FreeBSD's several CD installation medias to the single DVD disk.
+#
+# $FreeBSD$
+
+## Helper functions
+usage () {
+ echo "Usage: $0 <dvd_img_name> <cd_img_name <cd_img_name ..>>"
+}
+
+# Copy data from the cd
+# $1 os name
+# $2 disk image name
+# $3 mount dir
+# $4 destination dir
+copycd () {
+ # Set some variables
+ md=""
+ _os="${1}"
+ _img="${2}"
+ _mnt="${3}"
+ _dst="${4}"
+ if [ $# -ne "4" ]
+ then
+ echo "Error: function ${0} takes exactly four parameters."
+ exit 1
+ fi
+ if [ "${_os}" != "FreeBSD" -a "${_os}" != "Linux" ]
+ then
+ echo "Error: do not know how to handle ${_os} os."
+ exit 1
+ fi
+ if [ ! -f "${_img}" ]
+ then
+ echo "Error: file ${_img} does not exists or not a regula file."
+ exit 1
+ fi
+ if [ ! -r "${_img}" ]
+ then
+ echo "Error: you do not have the read permissions."
+ exit 1
+ fi
+ if [ ! -d "${_mnt}" ]
+ then
+ echo "Error: ${_mnt} is not a directory or does not exists."
+ fi
+ if [ ! -d "${_dst}" ]
+ then
+ echo "Error: ${_dst} is not a directory or does not exists."
+ fi
+ if [ ! -w "${_dst}" ]
+ then
+ echo "Error: you do not have write permissions granted for ${_dst} directory."
+ fi
+ if [ "${_os}" != "Linux" ]
+ then
+ md=`mdconfig -a -t vnode -f ${_img}` || exit 1
+ mount_cd9660 /dev/${md} ${_mnt} || exit 1
+ else
+ mount -o loop ${_img} ${_mnt} || exit 1
+ fi
+ if [ ! -f ${_mnt}/cdrom.inf ]
+ then
+ echo "Error: Failed to find cdrom.inf for ${_img}."
+ exit 1
+ fi
+ cdvol=`grep "^CD_VOLUME.*" ${_mnt}/cdrom.inf | sed "s/CD_VOLUME[[:space:]]*=[[:space:]]*//"`
+ if test -z "${cdvol}" -o ! "${cdvol}" -eq "${cdvol}" 2> /dev/null
+ then
+ echo "Error: failed to get volume id for ${_img}."
+ exit 1
+ fi
+ cdver=`grep "^CD_VERSION.*" ${_mnt}/cdrom.inf | sed "s/CD_VERSION[[:space:]]*=[[:space:]]*//"`
+ if test -z "${cdver}"
+ then
+ echo "Error: failed to get version id for ${_img}."
+ exit 1
+ fi
+ if [ -z "${VERID}" ]
+ then
+ VERID="${cdver}"
+ _exclude=""
+ else
+ if [ "${VERID}" != "${cdver}" ]
+ then
+ echo "Error: cd version ids mismatch while processing ${_img}."
+ exit 1
+ fi
+# _exclude="--exclude ./cdrom.inf --exclude ./packages/INDEX"
+ _exclude="! -regex ./cdrom.inf ! -regex ./packages/INDEX"
+ fi
+ echo "Merging ${_img}:"
+# --quite -u -V
+ (cd "${_mnt}" && find . ${_exclude} | cpio -p -d -m -V --quiet "${_dst}") || exit 1
+# (cd "${_mnt}" && tar ${_exclude} -cvf - .) | (cd "${_dst}" && tar xvf -) || exit 1
+ if [ "${_os}" != "Linux" ]
+ then
+ umount /dev/${md} || exit 1
+ mdconfig -d -u "${md}" || exit 1
+ else
+ umount ${_mnt} || exit 1
+ fi
+# exit 0
+}
+
+# Clear mounted image
+# $1 mounted directory
+# $2 error code
+clearmount ()
+{
+ if [ $# -ne "2" ]
+ then
+ echo "Error: function ${0} takes exactly two parameters."
+ exit 1
+ fi
+ if [ -z "${1}" ]
+ then
+ test -z "${2}" || exit "${2}"
+ else
+ # Ignore errors
+ umount "${1}" 2>/dev/null
+ test -z "${2}" || exit "${2}"
+ fi
+}
+
+# Clear CD image allocation
+# $1 os name
+# $2 md
+# $3 error code
+clearmd ()
+{
+ if [ $# -ne "3" ]
+ then
+ echo "Error: function ${0} takes exactly three parameters."
+ exit 1
+ fi
+ if [ "${1}" != "FreeBSD" -o -z "${2}" ]
+ then
+ test -z "${3}" || exit "${3}"
+ else
+ # Ignore errors
+ mdconfig -d -u "${2}" 2>/dev/null
+ test -z "${3}" || exit "${3}"
+ fi
+}
+
+## Check params
+if [ $# -lt 3 ]
+then
+ usage
+ echo "Error, this script should take more than two parameters."
+ exit 1
+fi
+
+# Check if zero
+if [ -z "${1}" ]; then
+ usage
+ exit 1
+fi
+
+# Check if already exists
+if [ -e "${1}" ]; then
+ if [ ! -f "${1}" ]; then
+ echo "Destination DVD image file already exists and is not a regular file."
+ exit 1
+ fi
+ while echo "The ${1} file exists. Overwrite? (y/n)"
+ do
+ read line
+ case "${line}" in
+ y|Y)
+ rm -rf "${1}"
+ touch "${1}"
+ break
+ ;;
+ n|N)
+ echo "Please, run program again with a new value."
+ exit 1
+ ;;
+ esac
+ done
+fi
+DVDIMAGE="${1}"
+
+shift
+
+count=0
+for i in "$@"
+do
+ # Skip empty params.
+ if test -z "${i}"; then
+ continue
+ fi
+ if [ ! -f "${i}" -o ! -r "${i}" ]
+ then
+ echo "Error: The ${i} is not readable, do not exists or not a regular file."
+ exit 1
+ fi
+ count=`expr ${count} \+ 1`
+done
+
+# Check if we have at the least two CD images
+if [ "${count}" -lt 2 ]
+then
+ echo "Error: less than two CD images specified."
+fi
+
+## Some useful variables
+pwd=`pwd`
+tmpdirin="${pwd}/tmp-$$-in"
+tmpdirout="${pwd}/tmp-$$-out"
+system=`uname -s`
+md=""
+
+# set the trap options
+trap 'echo ""; echo "Cleaning up"; clearmount "${tmpdirin}" ""; clearmd "${system}" "${md}" ""; rm -rf "${tmpdirin}" "${tmpdirout}";' 0 1 2 3 15
+mkdir "${tmpdirin}" || (echo "Error: failed to create tempory ${tmpdirin}"; exit 1)
+mkdir "${tmpdirout}" || (echo "Error: failed to create tempory ${tmpdirout}"; exit 1)
+