[openfirmware] [commit] r2760 - in dev/ath9k: . build

repository service svn at openfirmware.info
Fri Dec 9 21:31:15 CET 2011


Author: lwalter
Date: Fri Dec  9 21:31:14 2011
New Revision: 2760
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2760

Log:
First version of atheros 9382 driver

Added:
   dev/ath9k/
   dev/ath9k/ani.fth
   dev/ath9k/ar9382.bth
   dev/ath9k/ath9k.fth
   dev/ath9k/build/
   dev/ath9k/calib.fth
   dev/ath9k/debug.fth
   dev/ath9k/domain.fth
   dev/ath9k/eep9382.fth
   dev/ath9k/eepdump.fth
   dev/ath9k/eeprom.fth
   dev/ath9k/global.fth
   dev/ath9k/ini9382.fth
   dev/ath9k/init.fth
   dev/ath9k/key.fth
   dev/ath9k/mac.fth
   dev/ath9k/paprd.fth
   dev/ath9k/phy.fth
   dev/ath9k/reg.fth
   dev/ath9k/rx.fth
   dev/ath9k/tx.fth

Added: dev/ath9k/ani.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/ani.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,292 @@
+purpose: ATH9K Adaptive Noise Immunity (ANI) code
+\ See license at end of file
+
+headers
+hex
+
+\ SI: Spur immunity
+\ FS: FIR Step
+\ WS: OFDM / CCK Weak Signal detection
+\ MRC: Maximal Ratio Combining for CCK
+
+d# 10 constant #ofdm-lvl
+create ofdm-spur-immunity 0 c, 1 c, 2 c, 3 c, 4 c, 5 c, 6 c, 7 c, 7 c, 7 c,
+create ofdm-fir-step      0 c, 1 c, 2 c, 2 c, 3 c, 4 c, 5 c, 6 c, 7 c, 8 c,
+create ofdm-weak-sig-det  1 c, 1 c, 1 c, 1 c, 1 c, 1 c, 1 c, 1 c, 1 c, 0 c,
+
+: ofdm-spur-immunity@  ( lvl -- val )  ofdm-spur-immunity + c@  ;
+: ofdm-fir-step@       ( lvl -- val )  ofdm-fir-step      + c@  ;
+: ofdm-weak-sig-det@   ( lvl -- val )  ofdm-weak-sig-det  + c@  ;
+
+9 constant #cck-lvl
+7 constant #cck-lvl-low-rssi
+create cck-fir-step       0 c, 1 c, 2 c, 3 c, 4 c, 5 c, 6 c, 7 c, 8 c,
+create cck-mrc            1 c, 1 c, 1 c, 1 c, 0 c, 0 c, 0 c, 0 c, 0 c,
+
+: cck-fir-step@  ( lvl -- val )  cck-fir-step + c@  ;
+: cck-mrc@       ( lvl -- val )  cck-mrc      + c@  ;
+
+: firstep@  ( lvl -- val )  2 - 2*  ;
+: cycpwrThr1@  ( lvl -- val )  3 - 2*  ;
+
+: clear-mib-counters  ( -- )  809c 8088  do  i reg@ drop  4 +loop  ;
+
+: restart-ani  ( -- )
+   0 curchan >ani-listenTime !
+   0 curchan >ani-ofdmPhyErrCnt !
+   0 curchan >ani-cckPhyErrCnt !
+
+   \ Restart PHY error counters
+   0 812c reg!               \ Clear PHY error counter 1
+   0 8134 reg!               \ Clear PHY error counter 2
+   0002.0000 8130 reg!       \ PHY error counter 1 mask AR_PHY_ERR_OFDM_TIMING
+   0200.0000 8138 reg!       \ PHY error counter 2 mask AR_PHY_ERR_CCK_TIMING
+
+   clear-mib-counters
+;
+
+: cache-ani-ini-regs  ( -- )
+   curchan >r
+   9828 reg@ 0fff.ff00 and          r@ >ani-ini-sfcorr-low !
+   9824 reg@ 7ffe.001f and          r@ >ani-ini-sfcorr !
+   982c reg@ 0fff.ffff and          r@ >ani-ini-sfcorr-ext !
+   9e10 reg@    3.f000 and d# 12 >> r@ >ani-ini-firstep !
+   9820 reg@       fc0 and     6 >> r@ >ani-ini-firstepLow !
+   9810 reg@        fe and     1 >> r@ >ani-ini-cycpwrThr1 !
+   9830 reg@      fe00 and     9 >> r@ >ani-ini-cycpwrThr1Ext !
+   3 r@ >ani-spurImmunityLevel !
+   2 r@ >ani-firstepLevel !
+   0 r@ >ani-ofdmWeakSigDetectOff !
+   0 r> >ani-mrcCCKOff !
+;
+
+: set-firstep-lvl  ( lvl -- )
+   dup firstep@  2 firstep@ - curchan >ani-ini-firstep    @ + 0 max d# 20 min d# 12 <<
+   3.f000 9e10 reg@!
+   dup firstep@  2 firstep@ - curchan >ani-ini-firstepLow @ + 0 max d# 20 min     6 <<
+   fc0 9820 reg@!
+   curchan >ani-firstepLevel !
+;
+: set-ofdm-weak-signal-detect  ( on? -- )
+   0fff.ff00 over  if  curchan >ani-ini-sfcorr-low @ swap  else  dup  then  9828 reg@!
+   7ffe.001f over  if  curchan >ani-ini-sfcorr     @ swap  else  dup  then  9824 reg@!
+   0fff.ffff over  if  curchan >ani-ini-sfcorr-ext @ swap  else  dup  then  982c reg@!
+   dup  if  1  else  0  then  1  9828 reg@!
+   1 xor curchan >ani-ofdmWeakSigDetectOff !
+;
+: set-spur-immunity-lvl  ( lvl -- )
+   dup cycpwrThr1@ 3 cycpwrThr1@ - curchan >ani-ini-cycpwrThr1    @ + 0 max d# 22 min 1 <<
+   fe 9810 reg@!
+   dup cycpwrThr1@ 3 cycpwrThr1@ - curchan >ani-ini-cycpwrThr1Ext @ + 0 max d# 22 min 9 <<
+   fe00 9830 reg@!
+   curchan >ani-spurImmunityLevel !
+; 
+: set-mrcCCKoff  ( on? -- )
+   1 and dup 3 * 3  9fd0 reg@!
+   1 xor curchan >ani-mrcCCKOff !
+;
+
+: set-ofdm-nil  ( lvl -- )  \ OFDM Noise Immunity Level
+   dup curchan >ani-ofdmNoiseImmunityLevel !   ( lvl )
+   avgbrssi curchan >ani-noiseFloor !          ( lvl )
+
+   dup ofdm-spur-immunity@ curchan >ani-spurImmunityLevel @ over  <>  ( lvl SI )
+   if  set-spur-immunity-lvl  else  drop  then                    ( lvl )
+
+   dup ofdm-fir-step@ curchan >ani-firstepLevel @ over <>  ( lvl FS flag )
+   over 3 pick cck-fir-step@ >=  and                   ( lvl FS )
+   if  set-firstep-lvl  else  drop  then               ( lvl )
+
+   opmode IFTYPE_STATION <>  opmode IFTYPE_ADHOC <>  and
+   curchan >ani-noiseFloor @ curchan >ani-rssiThrHigh @ <= or  if
+      curchan >ani-ofdmWeakSigDetectOff @  if
+         1 set-ofdm-weak-signal-detect
+      else
+         dup ofdm-weak-sig-det@ curchan >ani-ofdmWeakSigDetectOff @ over  =
+         if  set-ofdm-weak-signal-detect  else  drop  then
+      then
+   then  drop
+;
+
+: set-cck-nil  ( lvl -- )  \ CCK Noise Immunity Level
+   avgbrssi curchan >ani-noiseFloor !
+   opmode IFTYPE_STATION =  opmode IFTYPE_ADHOC =  or  if
+      curchan >ani-noiseFloor @ curchan >ani-rssiThrLow @ <=
+      if  #cck-lvl-low-rssi min  then       ( lvl' )
+   then
+   dup curchan >ani-cckNoiseImmunityLevel !  ( lvl )
+
+   dup cck-fir-step@ curchan >ani-firstepLevel @ over <>  ( lvl FS flag )
+   over 3 pick ofdm-fir-step@ >= and  if  set-firstep-lvl  else  drop  then
+
+   cck-mrc@ curchan >ani-mrcCCKOff @ over =  if  set-mrcCCKoff  else  drop  then
+;
+
+: reset-ani  ( scanning? -- )
+   opmode IFTYPE_STATION <>  opmode IFTYPE_ADHOC <> and or  if
+      curchan >ani-ofdmNoiseImmunityLevel @ 3 <>
+      curchan >ani-cckNoiseImmunityLevel  @ 2 <> or  if
+         3 set-ofdm-nil
+         2 set-cck-nil
+      then
+   else
+      curchan >ani-ofdmNoiseImmunityLevel @ set-ofdm-nil
+      curchan >ani-cckNoiseImmunityLevel  @ set-cck-nil
+   then
+   restart-ani
+;
+
+[ifdef] notyet
+d# 1000 value aniperiod
+
+\ Cycle counters for computing listen time
+0 value ani-cycles
+0 value ani-rx-busy
+0 value ani-rx-frames
+0 value ani-tx-frames
+
+\ Cycle counters for computing busy time
+0 value survey-cycles
+0 value survey-rx-busy
+0 value survey-rx-frames
+0 value survey-tx-frames
+
+: ofdm-err-trigger  ( -- )
+   curchan >ani-ofdmNoiseImmunityLevel @ 1+ dup #ofdm-lvl <
+   if  set-ofdm-nil  else  drop  then
+;
+: cck-err-trigger  ( -- )
+   curchan >ani-cckNoiseImmunityLevel @ 1+ dup #cck-lvl <  
+   if  set-cck-nil  else  drop  then
+;
+: ani-lower-immunity  ( -- )
+   curchan >ani-ofdmNoiseImmunityLevel @ dup 0>  if
+      curchan >ani-ofdmsTurn @ curchan >ani-cckNoiseImmunityLevel @ 0=  or  if
+         1- set-ofdm-nil
+         exit
+      then
+   then  drop
+
+   curchan >ani-cckNoiseImmunityLevel @ dup 0>  if  1- set-cck-nil  else  drop  then
+;
+: update-cycle-cnts  ( -- )
+   2 40 reg!                \ freeze
+   80f8 reg@ dup ani-cycles       + to ani-cycles
+                 survey-cycles    + to survey-cycles
+   80f4 reg@ dup ani-rx-busy      + to ani-rx-busy
+                 survey-rx-busy   + to survey-rx-busy
+   80f0 reg@ dup ani-rx-frames    + to ani-rx-frames
+                 survey-rx-frames + to survey-rx-frames
+   80ec reg@ dup ani-tx-frames    + to ani-tx-frames
+                 survey-tx-frames + to survey-tx-frames
+   80fc 80ec  do  0 i reg!  4 +loop
+   0 40 reg!                \ unfreeze
+;
+: listen-time  ( -- time )
+   ani-cycles ani-rx-frames - ani-tx-frames - clockrate d# 1000 * /
+   0 to ani-cycles 0 to ani-rx-busy 0 to ani-rx-frames 0 to ani-tx-frames
+;
+: ani-read-cnts  ( -- ok? )
+   update-cycle-cnts
+   listen-time  dup 0<=  if  drop restart-ani false exit  then
+   curchan >ani-listenTime tuck @ + swap !
+   clear-mib-counters
+
+   812c reg@ curchan >ani-ofdmPhyErrCnt !
+   8134 reg@ curchan >ani-cckPhyErrCnt !
+   true
+;
+: monitor-ani  ( -- )
+   ani-read-cnts 0=  if  exit  then
+   curchan >ani-ofdmPhyErrCnt @ d# 1000 * curchan >ani-listenTime @ /  \ ofdmPhyErrRate
+   curchan >ani-cckPhyErrCnt  @ d# 1000 * curchan >ani-listenTime @ /  \ cckPhyErrRate
+
+   curchan >ani-listenTime @ aniperiod 5 * >  if
+      2dup d# 300 <= swap d# 400 <= and  if
+         ani-lower-immunity
+         curchan >ani-ofdmsTurn dup @ -1 xor swap !
+      then
+      restart-ani
+   else
+   curchan >ani-listenTime @ aniperiod >  if
+      2dup d# 600 <= curchan >ani-ofdmsTurn @ or swap d# 1000 >  and  if
+         ofdm-err-trigger
+         restart-ani
+         false curchan >ani-ofdmsTurn !
+      else
+      dup d# 600 >  if
+         cck-err-trigger
+         restart-ani
+         true curchan >ani-ofdmsTurn !
+      then then
+   then  then  2drop
+;
+: proc-mib-event  ( -- )
+   0 8124 reg!               \ Filtered OFDM counter
+   0 8128 reg!               \ Filtered CCK counter
+   8258 reg@ 2 and  if  1 8248 reg!  then
+   clear-mib-counters
+   812c reg@ c0.0000 and  8134 reg@ c0.0000 and  or  if
+      restart-ani
+   then
+;
+[then]
+
+: enable-mib-counters  ( -- )
+   clear-mib-counters
+   0 8124 reg!               \ Filtered OFDM counter
+   0 8128 reg!               \ Filtered CCK counter
+   0 40 reg!                 \ MIB control
+   0002.0000 8130 reg!       \ PHY error counter 1 mask AR_PHY_ERR_OFDM_TIMING
+   0200.0000 8138 reg!       \ PHY error counter 2 mask AR_PHY_ERR_CCK_TIMING
+;
+
+: disable-mib-counters  ( -- )
+   2 40 reg!
+   clear-mib-counters
+   4 40 reg!
+   0 8124 reg!               \ Filtered OFDM counter
+   0 8128 reg!               \ Filtered CCK counter
+;
+
+: init-ani  ( -- )
+   #channels 0  do
+      i 'channel >r
+      3 r@ >ani-spurImmunityLevel !
+      2 r@ >ani-firstepLevel !
+      0 r@ >ani-mrcCCKOff !
+      true r@ >ani-ofdmsTurn !
+      d# 40 r@ >ani-rssiThrHigh !
+      7 r@ >ani-rssiThrLow !
+      false r@ >ani-ofdmWeakSigDetectOff !
+      2 r> >ani-cckNoiseImmunityLevel !
+   loop
+
+   restart-ani
+   enable-mib-counters
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/ar9382.bth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/ar9382.bth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,59 @@
+purpose: Load file for Atheros 9382 WIFI Driver
+\ See license at end of file
+
+command: &tokenize &this
+build-now
+
+silent on
+
+begin-tokenizing ar9382.fc
+
+FCode-version2
+
+fload ${BP}/dev/ath9k/reg.fth         \ Misc words, variables, constants
+fload ${BP}/dev/ath9k/ini9382.fth     \ Chip specific initial values
+fload ${BP}/dev/ath9k/eep9382.fth     \ Chip specific "EEPROM" initial values
+fload ${BP}/dev/ath9k/eeprom.fth      \ "EEPROM" manipulation
+\ fload ${BP}/dev/ath9k/domain.fth      \ Country code, domain code, mapping
+fload ${BP}/dev/ath9k/global.fth      \ Global variables
+fload ${BP}/dev/ath9k/ani.fth
+fload ${BP}/dev/ath9k/phy.fth
+fload ${BP}/dev/ath9k/paprd.fth
+fload ${BP}/dev/ath9k/calib.fth
+fload ${BP}/dev/ath9k/key.fth
+fload ${BP}/dev/ath9k/init.fth
+fload ${BP}/dev/ath9k/mac.fth
+fload ${BP}/dev/ath9k/rx.fth
+fload ${BP}/dev/ath9k/tx.fth
+fload ${BP}/dev/ath9k/ath9k.fth
+fload ${BP}/dev/ath9k/debug.fth
+fload ${BP}/dev/ath9k/eepdump.fth
+
+end0
+
+end-tokenizing
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/ath9k.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/ath9k.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,394 @@
+purpose: ATH9K driver
+\ See license at end of file
+
+hex
+external
+
+: enable-rsn   ( -- ok? )  true  ;
+: disable-rsn  ( -- ok? )  false to gkey-enabled?
+                           false to pkey-enabled? true  ;
+: disable-wep  ( -- ok? )  false to wep-enabled? true  ;
+: set-ptk  ( ptk$ -- )
+   /aes =  if  p-aes /aes  else  p-tkip /tkip  then  move
+   set-key-cache
+   true to pkey-enabled?
+;
+: set-gtk-idx  ( idx -- )  debug?  if  dup ." GTK idx = " . cr  then  to grp-idx  ;
+: set-gtk  ( gtk$ -- )  
+   /aes =  if  g-aes /aes  else  g-tkip /tkip  then  move
+   set-key-cache
+   true to gkey-enabled?
+;
+: enforce-protection  ( -- )  ;
+: disable-protection  ( -- )
+   reset-key-cache 
+   false to gkey-enabled?
+   false to pkey-enabled?
+   false to wep-enabled?
+;
+: ?set-wep  ( -- )  ;
+
+headers
+: make-mac-address-property  ( -- )
+   " mac-address"  get-my-property  if   ( )
+      mac-adr$ encode-bytes  " local-mac-address" property
+      mac-address encode-bytes " mac-address" property
+   else                                  ( adr len )
+      2drop
+   then
+;
+
+d# 200 constant rx-detect-time-limit
+0 value last-rx-time
+: timeout-wait-for-resp?  ( -- timeout? )
+   get-msecs last-rx-time - rx-detect-time-limit >=
+;
+\  0 = got response
+\ -1 = timeout waiting for response or disconnected
+\ -2 = timeout waiting for transmit after retries
+: wait-for-resp  ( resp-type -- -2|-1|0 )
+   to resp-type  get-msecs to last-rx-time
+   wait-tx-done 0=  if  -2 exit  then  \ Fail to transmit
+   false to got-response?
+   resp-wait 0  do
+      queue-rx
+      deque-rx  if            ( node adr len )
+         2 pick >r            ( node adr len )  ( R: node )
+         process-rx           ( node )  ( R: node )
+         r> over <>  if  debug-me  then
+         free-rx              ( )
+         got-response?  if  leave  then
+         disconnected?  if  leave  then
+         get-msecs to last-rx-time
+      else
+         timeout-wait-for-resp?  if  leave  then
+      then
+      1 ms
+   loop
+   got-response?  if  0  else  -1  then
+;
+
+defer process-resp          ' noop to process-resp
+: wait-for-more  ( resp-type -- )
+   to resp-type
+   resp-wait-xlong 0  do
+      queue-rx
+      deque-rx  if
+         process-rx
+         free-rx
+         got-response?  if  process-resp  then
+         disconnected?  if  leave  then
+      then
+      1 ms
+   loop
+;
+
+: (probe-ssid)  ( -- found? )
+   debug?  if  ." Scan channel: " curchan >ch-hw-val @ .d cr  then
+   scan-ssid count broadcast-mac$ make-probe-req
+   xmit-data  50 wait-for-resp 0=  if  add-scan-response  then
+   get-scan-actual 3 >
+;
+: probe-ssid-chs  ( ch hi lo -- found? )
+   false -rot  ?do                ( ch flag )
+      over i <>  if               \ Not the default channel
+         i re-set-channel         ( ch flag )
+         (probe-ssid)  if  drop true leave  then
+      then                        ( ch flag )
+   loop  nip                      ( flag )
+;
+\ XXX Channel range depends on the domain
+: probe-ssid-2GHz  ( ch -- found? )  d# 11 0 probe-ssid-chs  ;
+: probe-ssid-5GHz  ( ch -- found? )
+   dup d# 18 d# 14 probe-ssid-chs  if  drop true exit  then
+   dup d# 22 d# 18 probe-ssid-chs  if  drop true exit  then
+\   dup d# 33 d# 22 probe-ssid-chs  if  drop true exit  then
+       d# 38 d# 33 probe-ssid-chs
+;
+: probe-ssid  ( adr len -- actual )
+   " ---- probe-ssid ----" vtype
+   start-scan-response
+   (probe-ssid)  if  get-scan-actual exit  then
+   curchan >ch-hw-val @
+   dup probe-ssid-2GHz  if  drop get-scan-actual exit  then
+       probe-ssid-5GHz  drop  get-scan-actual
+;
+
+\ Probe with broadcast ssid
+: probe-broadcast-ssid  ( adr len -- actual )   \ Gather all responses within channel
+   start-scan-response
+   ['] add-scan-response to process-resp
+   0 0 broadcast-mac$ make-probe-req
+   xmit-data  50 wait-for-resp  case
+      0  of  add-scan-response
+             50 wait-for-more    endof  \ Got one already, maybe more
+     -1  of  50 wait-for-more    endof  \ Didn't get one last time, maybe more
+     ( otherwise )  \ Didn't even manage to send the request
+   endcase
+   get-scan-actual
+;
+: authenticate  ( target-mac$ -- ok? )
+   " ---- authenticate ----" vtype
+   2dup 1 -rot make-authenticate-req
+   xmit-data  b0 wait-for-resp 0<>  if  ." auth 1 failed to get response" cr 2drop false exit  then
+   respbuf dup /802.11n-data-hdr + 4 + le-w@ 0<>  if  ." auth 1 rejected" cr 2drop false exit  then
+
+   /respbuf respbuf /802.11n-data-hdr 88 + >=  if
+      key-wep? not  if  ." Shared key expected by the AP" cr 2drop false exit  then
+      respbuf dup /802.11n-data-hdr + 6 + dup c@ d# 16 <>  if  ." auth 2 challenge missing" cr 3drop false exit  then
+      " ---- authenticate 3 ----" vtype
+      dup 2 + swap 1+ c@                  ( target-mac$ challenge$ )
+      2swap 3 -rot make-authenticate-req  ( adr len )
+      xmit-data  b0 wait-for-resp 0<>  if  ." auth 3 failed to get response" cr false false to wep-enabled? exit  then
+      respbuf dup /802.11n-data-hdr + 4 + le-w@ 0=
+      dup 0=  if  ." auth 3 rejected" cr false to wep-enabled?  then
+   else
+      2drop true
+   then
+;
+
+: deauthenticate  ( target-mac$ -- )
+   " ---- deauthenticate ----" vtype
+   make-deauthenticate-req
+   xmit-data  wait-tx-done  drop
+   reset-driver-state
+;
+: (associate)  ( ch ssid$ target-mac$ -- ok? )
+   " ---- (associate) ----" vtype
+   make-associate-req                 ( adr len )
+   xmit-data  10 wait-for-resp 0= dup  if
+      respbuf dup /802.11n-data-hdr 4 + + le-w@ 3fff and to curaid
+      dummy-rssi dup to last-rssi to avgbrssi
+   then
+;
+
+external
+: get-mac-address  ( -- adr len )  mac-adr$  ;
+
+: associate  ( ch ssid$ target-mac$ -- ok? )
+   " ---- associate ----" vtype
+   4 pick 1- curchan >ch-hw-val @ <>  if
+      4 pick  debug?  if  ." Set to channel: " dup .d cr  then
+      1- dup to defch       \ Save for next open
+      re-set-channel
+   then
+
+   ?set-wep
+   2dup authenticate 0=  if  2drop 3drop false exit  then
+                                    ( ch ssid$ target-mac$ )
+   d# 10 0 do                       ( ch ssid$ target-mac$ )
+      4 pick  4 pick  4 pick  4 pick  4 pick  ( ch ssid$ target-mac$  ch ssid$ target-mac$ )
+      (associate)                   ( ch ssid$ target-mac$ ok? )
+      if  2drop 3drop true unloop  exit  then
+   loop
+   2drop 3drop
+   false
+;
+
+: scan  ( adr len -- actual )
+   passive-scan?  ap-mode? or  if
+      scan-passive
+   else
+      scan-ssid c@  if  probe-ssid  else  probe-broadcast-ssid  then
+   then
+;
+
+headers
+
+: do-associate  ( -- ok? )
+   reset-driver-state
+   ['] 2drop to ?process-eapol  \ Don't reenter the supplicant while associating
+   supplicant-associate dup  if
+      ds-associated set-driver-state
+      target-mac curbssid /mac-adr move
+      write-associd
+      key-wep?  if
+         set-key-cache
+         true to wep-enabled?
+      then
+   then
+   ['] do-process-eapol to ?process-eapol
+;
+
+: ?reassociate  ( -- ok? )
+   link-up? 0=  if  do-associate  else  true  then
+;
+
+: disassociate  ( mac$ -- )
+   " ---- disassociate ----" vtype
+   make-disassociate-req
+   xmit-data  wait-tx-done
+   reset-driver-state
+;
+
+external
+: write-force  ( adr len -- actual )
+   queue-rx
+   tuck  make-data-frame         ( len adr' len' )
+   xmit-data  wait-tx-done 0=  if  drop 0  then
+   queue-rx
+;
+
+: write  ( adr len -- actual )
+   " ---- write ---- " vtype
+   ap-mode?  if
+      write-force
+   else
+      queue-rx
+      ?reassociate 0=  if  2drop 0 exit  then   \ In case if the connection is dropped
+      write-force
+   then
+;
+
+: read-force  ( adr len -- actual )
+   queue-rx
+   deque-rx  if                          ( adr len node buf blen )
+      process-rx  -rot                   ( node adr len )
+      got-data?  if
+         debug?  if  ." Got data" cr  data 20 cdump cr  then
+         /data min tuck  data -rot move  ( node actual )
+      else  2drop 0  then                ( node actual )
+      swap free-rx                       ( actual )
+   else
+      2drop 0                            ( actual )
+   then
+   queue-rx
+;
+
+: read  ( adr len -- actual )
+   \ If a good receive packet is ready, copy it out and return actual length
+   \ If a bad packet came in, discard it and return -1
+   \ If no packet is currently available, return -2
+
+   queue-rx
+   ?reassociate 0=  if  2drop 0 exit  then  \ In case if the connection is dropped
+   read-force
+;
+
+headers
+
+\ Set to true to force open the driver without association.
+\ Normal operation should have force-open? be false.
+false instance value force-open?
+: debug-on  ( -- )  true to debug?  enable-emit  ;
+				
+: parse-args  ( $ -- )
+   false to use-promiscuous?
+   begin  ?dup  while
+      ascii , left-parse-string
+      2dup " debug" $=  if  debug-on  then
+      2dup " promiscuous" $=  if  true to use-promiscuous?  then
+           " force" $=  if  true to force-open?  then
+   repeat drop
+;
+: init-buf  ( -- )
+   init-buf
+   alloc-packet init-rx-bufs  init-tx-bufs
+   broadcast-mac$ bssidmask swap move  
+;
+: free-buf  ( -- )  free-packet  free-tx-bufs  free-rx-bufs  ;
+
+\ Enable non-beacon broadcast plus other people's unicast packets
+: set-bssid-regs  ( -- )
+   \ Enable non-beacon broadcast from the AP
+   target-mac le-l@ 8008 reg!
+   target-mac 4 + le-w@ curaid 10 << or  800c reg!  
+;
+
+external
+: open  ( -- ok? )
+   my-args parse-args
+   map-regs
+   " " set-ssid
+   opencount @ 0=  if
+      init-buf  init-device
+      make-mac-address-property
+      start  d# 100 ms
+      my-args " supplicant" $open-package to supplicant-ih
+      supplicant-ih 0=  if  free-buf false exit  then
+      force-open?  if
+         reset-driver-state
+      else
+         link-up? 0=  if
+            do-associate 0=  if
+               supplicant-ih close-package  0 to supplicant-ih
+               free-buf false exit
+            then
+         then
+      then
+   then
+   opencount @ 1+ opencount !
+   true
+;
+: close  ( -- )
+   opencount @ 1- 0 max  opencount !
+   opencount @ 0=  if
+      link-up?  if  target-mac$ deauthenticate  then
+      reset-driver-state
+      ['] 2drop to ?process-eapol
+      stop
+      supplicant-ih ?dup  if  close-package 0 to supplicant-ih  then
+      free-buf
+      unmap-regs
+   then
+;
+
+: load  ( adr -- len )
+   link-up? 0=  if  drop 0 exit  then   \ Not associated yet.
+
+   " obp-tftp" find-package  if         ( adr phandle )
+      my-args rot  open-package         ( adr ihandle|0 )
+   else                                 ( adr )
+      0                                 ( adr 0 )
+   then                                 ( adr ihandle|0 )
+
+   dup  0=  if  ." Can't open obp-tftp support package" stop abort  then
+                                        ( adr ihandle )
+
+   >r
+   " load" r@ ['] $call-method  catch   ( len false | x x x true )
+   r> close-package
+   throw
+;
+
+800 constant /tmp-buf
+0 value tmp-buf
+: (scan-wifi)  ( -- error? )
+   true to force-open?
+   open
+   false to force-open?
+   0=  if  ." Can't open Atheros wireless" cr true close  exit  then
+
+   /tmp-buf alloc-mem to tmp-buf
+   tmp-buf /tmp-buf  scan-passive
+   tmp-buf /tmp-buf free-mem
+
+   close  false
+;
+: scan-wifi  ( -- )  (scan-wifi) drop  ;
+: selftest  ( -- error? )  (scan-wifi)  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/calib.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/calib.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,545 @@
+purpose: ATH9K Calibration
+\ See license at end of file
+
+headers
+hex
+
+struct
+   5 /n* field >nfCalBuffer
+   /n field >currIndex
+   /n field >privNF
+   /n field >invalidNFcount
+constant /nfCalHist
+
+struct
+   /n field >cd-ch
+   /n field >cd-chFlags
+   /n field >calValid
+   /n field >iCoff
+   /n field >Coff
+   /n field >paprd-done?
+   /n field >nfcal-pending?
+   /n field >nfcal-interference?
+   3 /n* field >small-signal-gain
+   d# 24 3 * /n* field >pa-table
+   /nfCalHist 6 * field >nfCalHist
+constant /caldata
+
+/caldata buffer: caldata
+: init-buf  ( -- )  caldata /caldata erase  ;
+
+\ iq-calState definitions
+0 constant CAL_INACTIVE
+1 constant CAL_WAITING
+2 constant CAL_RUNNING
+3 constant CAL_DONE
+CAL_INACTIVE value iq-calState
+
+struct
+   /n field >nf-nominal
+   /n field >nf-max
+   /n field >nf-min
+constant /nf-limit
+
+3 /n* buffer: measI
+3 /n* buffer: measQ
+3 /n* buffer: measIQ
+create nf-2g  d# -110 , d#  -95 , d# -125 ,
+create nf-5g  d# -115 , d# -100 , d# -125 ,
+
+: sort  ( buf size -- )
+   dup 0  do                 ( buf size )
+      dup 1  do              ( buf size )
+         over i na+ @ 2 pick i 1- na+ @ 2dup >  if  ( buf size buf[i] buf[i-1] )
+            3 pick i na+ !  2 pick i 1- na+ !       ( buf size )
+         else                                       ( buf size buf[i] buf[i-1] )
+            2drop                                   ( buf size )
+         then
+      loop
+   loop  2drop
+;
+
+5 /n* buffer: tmpbuf
+: get-nf-hist-mid  ( nfCalBuf -- nfval )
+   tmpbuf 5 /n* move
+   tmpbuf 5 sort
+   tmpbuf 2 na+ @
+;
+
+: get-nf-limits  ( ch -- 'limit )
+   ?dup 0=  if  nf-2g exit  then
+   is-2GHz?  if  nf-2g  else  nf-5g  then
+;
+
+: get-nf-default  ( ch -- default )
+   get-nf-limits >nf-nominal @
+;
+
+6 /n* buffer: nfarray
+0 value nh
+0 value nmax
+0 value nlimit
+0 value ncmask
+0 value high-nf-mid
+: 'nh  ( idx -- adr )  /nfCalHist * nh +  ;
+: update-nfcal-hist  ( caldata -- )
+   dup >nfCalHist to nh                      ( calData )
+   curchan get-nf-limits >nf-max @ to nmax   ( calData )
+   rxchainmask dup 3 << or to ncmask         ( calData )
+   false to high-nf-mid                      ( calData )
+
+   6 0  do
+      ncmask 1 i << and
+      conf-is-ht40?  i 3 >=  and not  and  if
+         nfarray i na+ @             ( calData nfarray[i] )
+         i 'nh >nfCalBuffer i 'nh >currIndex @ na+ !
+         i 'nh >currIndex @ 1+  dup 5 >=  if  drop 0  then
+         i 'nh >currIndex !
+         i 'nh >invalidNFcount @ dup 0>  if
+            1- i 'nh >invalidNFCount !
+            nfarray i na+ @ 
+         else
+            drop  i 'nh >nfCalBuffer get-nf-hist-mid
+         then  dup i 'nh >privNF !
+         nmax >  if
+            true to high-nf-mid
+            dup >nfcal-interference? @ 0=  if
+               nmax i 'nh >privNF !
+            then
+         then
+      then
+   loop
+   high-nf-mid swap >nfcal-interference? !
+;
+
+: get-nf-thresh  ( band -- nf-thresh )  drop 0  ;
+
+: setup-calibration  ( -- )
+   a000 f000 980c reg@!
+   0 a2c8 reg!
+   1.0000 dup 980c reg@!      \ kick off cal
+;
+
+: reset-calibration  ( -- )
+   setup-calibration
+   CAL_RUNNING to iq-calState
+   measI  3 /n* erase
+   measQ  3 /n* erase
+   measIQ 3 /n* erase
+;
+
+: reset-calvalid?  ( -- notdone? )
+   iq-calState CAL_DONE  <>  if  true exit  then
+   CAL_WAITING to iq-calState
+   false
+;
+
+: start-nfcal  ( update? -- )
+   true caldata >nfcal-pending? !
+   if  8002  else  2.8002  then  2.8002 a2c4 reg@!
+;
+
+0 value dnf
+create nf-regs 9e1c , ae1c , be1c , 9830 , a830 , b830 , 
+
+: load-nf  ( ch -- )
+   rxchainmask dup 3 << or to ncmask
+   get-nf-default to dnf
+   caldata >nfCalHist to nh
+
+   6 0  do
+      ncmask 1 i << and
+      conf-is-ht40?  i 3 >=  and not  and  if
+         nh  if  i 'nh >privNF @  else  dnf  then  1 <<  1ff and
+         1ff nf-regs i na+ @ reg@!         
+      then
+   loop
+
+   8000 2.0002 a2c4 reg@!
+   0 2 a2c4 wait-hw 0=  if  " Timeout waiting for NF to load" vtype exit  then
+
+   \ Restore maxCCAPower
+   6 0  do
+      ncmask 1 i << and
+      conf-is-ht40?  i 3 >=  and not  and  if
+         19c 1ff nf-regs i na+ @ reg@!         
+      then
+   loop
+;
+
+: sanitize-nf  ( 'nf -- )
+   curchan is-2GHz?  if  nf-2g  else  nf-5g  then  to nlimit
+   6 0  do
+      dup i na+ @ d# -60 >  if
+         nlimit >nf-max @ over i na+ !
+      else
+      dup i na+ @ nlimit >nf-min @ <  if
+         nlimit >nf-nominal @ over i na+ !
+      then  then
+   loop  drop
+;
+
+: sign-extend32  ( val index -- val' )  d# 31 swap - tuck << swap >>a  ;
+: do-get-nf  ( nfarray -- )
+   3 0  do
+      1 i << rxchainmask and  if
+         nf-regs i na+ @ reg@ 1ff0.0000 and d# 20 >>  8 sign-extend32  over i na+ !
+         curchan is-ht40?  if
+            nf-regs i 3 + na+ @ reg@ 1ff.0000 and d# 16 >>  8 sign-extend32  over i 3 + na+ !
+         then
+      then
+   loop  drop
+;
+
+: get-nf  ( ch -- ok? )
+   nfarray 6 /n* erase
+   CH_CW_INT not over >ch-flags @ and over >ch-flags !
+   a2c4 reg@ 2 and  if  " NF did not complete" vtype drop false exit  then
+   nfarray do-get-nf
+   nfarray sanitize-nf
+   nfarray @ 0 >  if
+      " Noise floor detection failed" vtype
+      CH_CW_INT over >ch-flags @ or over >ch-flags !
+   then
+
+   false caldata >nfcal-pending? !
+   caldata update-nfcal-hist
+   caldata >nfcalHist >privNF @ swap >ch-noisefloor !
+   true
+;
+
+: init-nfcal-hist  ( ch -- )
+   dup >ch-freq @ caldata >cd-ch !
+   dup >ch-flags @ CH_CW_INT invert and caldata >cd-chFlags !
+   caldata >nfCalHist to nh
+   get-nf-default                  ( default-nf )
+
+   6 0  do
+      0 i 'nh >currIndex !
+      dup i 'nh >privNF !
+      3 i 'nh >invalidNFcount !
+      i 'nh >nfCalBuffer 5 /n* 2 pick " lfill" evaluate
+   loop  drop
+;
+
+[ifdef] notyet
+: get-ch-noise  ( ch -- noisefloor )
+   curchan ?dup 0=  if  get-nf-default exit  then
+   >ch-noiseFloor @ ?dup  if  nip  else  get-nf-default  then
+;
+
+: bstuck-nfcal  ( -- )
+   caldata >nfcal-pending? @  if
+      a2c4 reg@ 2 and 0=  if  curchan get-nf drop  then
+   else
+      true start-nfcal
+   then
+   true caldata >nfcal-interference? !
+;
+
+: #rxchains   ( -- #chains )  0  6 0  do  rxchainmask i >> 1 and +  loop  ;
+
+: collect-iqcal  ( -- )
+   3 0  do
+      98c0 i 1000 * + reg@ measI  i na+ !
+      98c4 i 1000 * + reg@ measQ  i na+ !
+      98c8 i 1000 * + reg@ measIQ i na+ !
+   loop
+;
+
+0 value iqCorrNeg
+: calibrate-iq  ( #chains -- )
+   0  do
+      false to iqCorrNeg
+      measI i na+ @  measQ i na+ @  measIQ i na+ @
+      dup 8000.0000 u>  if  not 1+  true to iqCorrNeg  then
+                      ( powerMeasI powerMeasQ iqCorrMeas' )
+      -rot over 1 >> over 1 >> + 8 >>  ( iqCorrMeas powerMeasI powerMeasQ iCoffDenom )
+      swap 6 >>                        ( iqCorrMeas powerMeasI iCoffDenom qCoffDenom )
+      2dup or  if                      \ Avoid divide by zero
+         rot swap / d# 64 -            ( iqCorrMeas iCoffDenom qCoff )
+         d# 63 min  d# -63 max  7f and ( iqCorrMeas iCoffDenom qCoff' )
+         -rot / d# 63 min  d# -63 max  ( qCoff iCoff )
+         iqCorrNeg 0=  if  negate  then  7f and  ( qCoff iCoff' )
+         7 << or 3fff 98dc i 1000 * + reg@!
+      then
+   loop                      
+   4000 dup 98dc reg@!
+;
+
+: (calibrate)  ( -- done? )
+   iq-calState CAL_RUNNING =  if
+      980c reg@ 1.0000 and 0=  if
+         collect-iqcal
+         #rxchains calibrate-iq
+         CAL_DONE to iq-calState
+      then
+   then
+   iq-calState CAL_DONE = 
+;
+
+: calibrate  ( ch longcal? -- done? )
+   (calibrate) -rot      ( done? ch longcal? )
+
+   if
+      get-nf  drop
+      curchan load-nf
+      false start-nfcal
+   else
+      drop
+   then                  ( done? )
+;
+[then]
+
+3 /n* constant /coeff-meas                \ 3 passes per measurement
+/coeff-meas 8 * constant /coeff-chain     \ 8 measurements per chain
+
+/coeff-chain 6 * buffer: mag-coeff  \ [AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]
+/coeff-chain 6 * buffer: phs-coeff  \ [AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]
+2 /n* buffer: iq-coeff
+6 /n* buffer: iq-res
+
+: 'mag-coeff  ( m chain -- adr )  /coeff-chain * swap /coeff-meas * + mag-coeff +  ;
+: 'phs-coeff  ( m chain -- adr )  /coeff-chain * swap /coeff-meas * + phs-coeff +  ;
+: coeff@      ( i adr -- n )      swap na+ @  ;
+: coeff!      ( n i adr -- )      swap na+ !  ;
+: mag-coeff@  ( i m chain -- n )  'mag-coeff coeff@  ;
+: mag-coeff!  ( n i m chain -- )  'mag-coeff coeff!  ;
+: phs-coeff@  ( i m chain -- n )  'phs-coeff coeff@  ;
+: phs-coeff!  ( n i m chain -- )  'phs-coeff coeff!  ;
+
+\ Local variables for the iq calibration
+0 value sin-2phi-1  0 value sin-2phi-2
+0 value cos-2phi-1  0 value cos-2phi-2
+0 value mag-a0-d0   0 value mag-a1-d0
+0 value phs-a0-d0   0 value phs-a1-d0
+0 value if1
+0 value if2
+0 value if3
+0 value mag-tx
+0 value mag-rx
+0 value phs-tx
+0 value phs-rx
+
+\ Solve 4x4 linear equation used in loopback iq cal.
+: solve-iq-cal  ( -- solved? )
+   cos-2phi-1 cos-2phi-2 - to if1
+   sin-2phi-1 sin-2phi-2 - to if3
+   if1 if1 * if3 if3 * + d# 15 >>a ?dup  0=  if  false exit  then  \ Divide by zero
+   to if2
+   mag-a0-d0 mag-a1-d0 - if1 *  phs-a0-d0 phs-a1-d0 - if3 * + if2 / to mag-tx
+   mag-a1-d0 mag-a0-d0 - if3 *  phs-a0-d0 phs-a1-d0 - if1 * + if2 / to phs-tx
+
+   mag-a0-d0 cos-2phi-1 mag-tx * sin-2phi-1 phs-tx * + d# 15 >>a - to mag-rx
+   phs-a0-d0 sin-2phi-1 mag-tx * cos-2phi-1 phs-tx * - d# 15 >>a + to phs-rx
+   true
+;
+
+: find-mag  ( i q -- mag )
+   abs swap abs                   ( abs[i] abs [q] )
+   2dup max -rot min              ( max-abs min-abs )
+   over 5 >> swap dup 3 >> swap 2 >> + + -
+;
+
+\ Local variables
+0 value i2-m-q2-a0-d0  0 value i2-p-q2-a0-d0  0 value iq-corr-a0-d0
+0 value i2-m-q2-a0-d1  0 value i2-p-q2-a0-d1  0 value iq-corr-a0-d1
+0 value i2-m-q2-a1-d0  0 value i2-p-q2-a1-d0  0 value iq-corr-a1-d0
+0 value i2-m-q2-a1-d1  0 value i2-p-q2-a1-d1  0 value iq-corr-a1-d1
+0 value mag-a0-d1      0 value mag-a1-d1
+0 value phs-a0-d1      0 value phs-a1-d1
+0 value mag-corr-tx    0 value phs-corr-tx
+0 value mag-corr-rx    0 value phs-corr-rx
+0 value mag1           0 value mag2
+
+: ?sign-800  ( n -- )  dup 800 >  if  d# 20 << d# 20 >>a  then  ;
+: calc-iq-corr  ( -- ok? )
+   iq-res @          fff and  ?sign-800  to i2-m-q2-a0-d0
+   iq-res @ d# 12 >> fff and  ?sign-800  to i2-p-q2-a0-d0
+   iq-res @ d# 24 >>          ?sign-800  to iq-corr-a0-d0
+
+   iq-res na1+  @     4 >> fff and  ?sign-800  to i2-m-q2-a0-d1
+   iq-res 2 na+ @          fff and  ?sign-800  to i2-p-q2-a0-d1
+   iq-res 2 na+ @ d# 12 >> fff and  ?sign-800  to iq-corr-a0-d1
+
+   iq-res 2 na+ @ d# 24 >>          ?sign-800  to i2-m-q2-a1-d0
+   iq-res 3 na+ @     4 >> fff and  ?sign-800  to i2-p-q2-a1-d0
+   iq-res 4 na+ @          fff and  ?sign-800  to iq-corr-a1-d0
+
+   iq-res 4 na+ @ d# 12 >> fff and  ?sign-800  to i2-m-q2-a1-d1
+   iq-res 4 na+ @ d# 24 >>          ?sign-800  to i2-p-q2-a1-d1
+   iq-res 5 na+ @     4 >> fff and  ?sign-800  to iq-corr-a1-d1
+
+   i2-p-q2-a0-d0 0= i2-p-q2-a0-d1 0= or i2-p-q2-a1-d0 0= or i2-p-q2-a1-d1 0= or
+   if  false exit  then        \ Divide by zero
+
+   i2-m-q2-a0-d0 d# 15 << i2-p-q2-a0-d0 / to mag-a0-d0
+   iq-corr-a0-d0 d# 15 << i2-p-q2-a0-d0 / to phs-a0-d0
+
+   i2-m-q2-a0-d1 d# 15 << i2-p-q2-a0-d1 / to mag-a0-d1
+   iq-corr-a0-d1 d# 15 << i2-p-q2-a0-d1 / to phs-a0-d1
+
+   i2-m-q2-a1-d0 d# 15 << i2-p-q2-a1-d0 / to mag-a1-d0
+   iq-corr-a1-d0 d# 15 << i2-p-q2-a1-d0 / to phs-a1-d0
+
+   i2-m-q2-a1-d1 d# 15 << i2-p-q2-a1-d1 / to mag-a1-d1
+   iq-corr-a1-d1 d# 15 << i2-p-q2-a1-d1 / to phs-a1-d1
+
+   \ W/o analog phase shift
+   mag-a0-d0 mag-a0-d1 - 8 << 5 >>a to sin-2phi-1
+   phs-a0-d1 phs-a0-d0 - 8 << 5 >>a to cos-2phi-1
+   mag-a1-d0 mag-a1-d1 - 8 << 5 >>a to sin-2phi-2
+   phs-a1-d1 phs-a1-d0 - 8 << 5 >>a to cos-2phi-2
+
+   \ Force sin2 + cos2 = 1
+   \ Find magnitude by approximation
+   cos-2phi-1 sin-2phi-1 find-mag to mag1
+   cos-2phi-2 sin-2phi-2 find-mag to mag2
+   mag1 0= mag2 0= or  if  false exit  then  \ Divide by zero
+
+   \ Normalize sin and cos by mag
+   sin-2phi-1 d# 15 << mag1 / to sin-2phi-1
+   cos-2phi-1 d# 15 << mag1 / to cos-2phi-1
+   sin-2phi-2 d# 15 << mag2 / to sin-2phi-2
+   cos-2phi-2 d# 15 << mag2 / to cos-2phi-2
+
+   \ Calculate IQ mismatch
+   solve-iq-cal 0=  if  false exit  then  \ Failure
+
+   mag-tx 8000 =  if  false exit  then    \ Divide by zero
+
+   \ Calculate and quantize tx IQ correction factor
+   mag-tx d# 15 <<  8000 mag-tx - / to mag-corr-tx
+   phs-tx negate to phs-corr-tx
+
+   mag-corr-tx 7 << d# 15 >>a  d# -63 max  d# 63 min  7 <<
+   phs-corr-tx 8 << d# 15 >>a  d# -63 max  d# 63 min  +     iq-coeff !
+
+   mag-rx negate 8000 =  if  false exit  then   \ Divide by zero
+
+   \ Calculate and quantize rx IQ correction factor
+   mag-rx negate d# 15 <<  8000 mag-rx + / to mag-corr-rx
+   phs-rx negate to phs-corr-rx
+
+   mag-corr-rx 7 << d# 15 >>a  d# -63 max  d# 63 min  7 <<
+   phs-corr-rx 8 << d# 15 >>a  d# -63 max  d# 63 min  +     iq-coeff na1+ !
+   true
+;
+
+: compute-avg  ( coeff[] -- false | avg true )
+   >r
+   0 r@ coeff@  1 r@ coeff@ - abs  ( diff0 )  ( R: coeff[] )
+   1 r@ coeff@  2 r@ coeff@ - abs  ( diff0 diff1 )  ( R: coeff[] )
+   2 r@ coeff@  0 r@ coeff@ - abs  ( diff0 diff1 diff2 )  ( R: coeff[] )
+
+   3dup + + d# 33 >  if  r> 4drop false  exit  then
+                                   ( diff0 diff1 diff2 )  ( R: coeff[] )
+   rot dup 3 pick <= swap 2 pick <=  and  if
+      2drop 0 r@ coeff@  1 r@ coeff@ + 1 >>a
+   else  <=  if
+      1 r@ coeff@  2 r@ coeff@ + 1 >>a
+   else
+      2 r@ coeff@  0 r@ coeff@ + 1 >>a
+   then  then
+   true  r> drop
+;
+
+\ Local variables
+8 6 * /n* buffer: tx-cc-regs  \ [MAX_MEASUREMENT][AR9300_MAX_CHAINS]
+: txcc@  ( c m -- n )  6 * /n* tx-cc-regs + swap na+ @  ;
+: txcc!  ( n c m -- )  6 * /n* tx-cc-regs + swap na+ !  ;
+
+: load-tx-iq-cal-avg-2passes  ( #chains -- )
+   \ Setup array of register addresses
+   4 0  do
+      a650 i na+ dup  0 i 2* txcc!  0 i 2* 1+ txcc!
+      b650 i na+ dup  1 i 2* txcc!  1 i 2* 1+ txcc!
+      c650 i na+ dup  2 i 2* txcc!  2 i 2* 1+ txcc!
+   loop
+
+   \ Load the average of 2 passes
+   ( #chains ) false swap  0  do               \ Chain loop
+      a68c reg@ 3e and 1 >> 8 min  0  do       \ Measurement loop
+         i j 'mag-coeff compute-avg 0=  if   drop true leave  then  7f and ( mag )
+         i j 'phs-coeff compute-avg 0=  if  2drop true leave  then  7f and ( mag phase )
+         7 << or
+         i 1 and  if  d# 14 << fff.c000  else  3fff  then
+         j i txcc@ reg@!
+      loop
+      dup  if  leave  then
+   loop
+   ( failed? )  if  0 0  else  2000.0000 8000.0000  then
+   8000.0000 98b0 reg@!
+   2000.0000 98dc reg@!
+;
+
+: cal-tx-iq  ( -- )
+   false 3 0  do                           \ Pass loop
+      80.0000 01fc.0000 a648 reg@!
+      1 1 a640 reg@!
+      0 1 a640 wait-hw  0=  if
+         " TX IQ cal not complete" vtype
+         drop true leave
+      then
+
+      a68c reg@ 3e and 1 >> 8 min i        ( flag #meas pass# )
+      tx-chainmask get-streams  0  do      \ Chain loop
+         over 0  do                        \ Measurement loop
+            a68c j 1000 * + reg@ 1 and  if  rot drop true -rot leave  then
+            9b00 j 1000 * +                ( flag #meas pass# reg-base )
+            3 0  do
+               j 3 * i + 4 * over +        \ reg
+               0 8 a370 reg@!
+               dup reg@  iq-res i 2* na+ !
+               8 8 a370 reg@!
+               reg@ ffff and  iq-res i 2* 1+ na+ !
+            loop  drop                     ( flag #meas pass# )
+            calc-iq-corr 0=  if  rot drop true -rot leave  then
+            iq-coeff @ 7f and dup d# 63 >  if  d# 128 -  then
+            over i j mag-coeff!
+            iq-coeff @ 7 >> 7f and  dup d# 63 >  if  d# 128 -  then
+            over i j phs-coeff!
+         loop                              ( flag #meas pass# )
+      loop  2drop  dup  if  leave  then
+      dup  if  leave  then
+   loop
+   0=  if  tx-chainmask get-streams load-tx-iq-cal-avg-2passes  then
+;
+
+: init-cal  ( -- )
+   40d8 reg@ 2.0000 and  if  3 3  else  7 7  then  set-chain-masks
+   cal-tx-iq                  \ Do tx IQ calibration
+   0 a20c reg!
+   5 us
+   1 a20c reg!
+   1 1 a2c4 reg@!             \ Calibrate the AGC
+   0 1 a2c4 wait-hw drop
+   txchainmask rxchainmask set-chain-masks    \ Restore chain masks
+   true start-nfcal
+   reset-calibration
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/debug.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/debug.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,232 @@
+purpose: ATH9K driver test words
+\ See license at end of file
+
+headers
+hex
+
+: ll  ( idx -- )  dup f and 0=  if  cr 4 u.r ."   "  else  drop  then  ;
+: dump-reg  ( reg len -- )  bounds do i ll i reg@ 8 u.r space 4  +loop  ;
+: .regs  ( -- )
+     0    100 dump-reg    \ General, DMA
+     800   50 dump-reg    \ QCU
+     900  100 dump-reg
+     a00   50 dump-reg
+    1000  130 dump-reg    \ DCU
+    1270   10 dump-reg
+    12f0   10 dump-reg
+    4000   e0 dump-reg    \ Host Interface
+    7000   60 dump-reg    \ RTC
+    8000  400 dump-reg    \ PCU
+    8800  800 dump-reg    \ Key
+    9000  800 dump-reg
+   \ Undocumented PHY
+    9800  400 dump-reg    \ CHAN_BASE
+    a800  400 dump-reg    \ CHAN1_BASE
+    b800  400 dump-reg    \ CHAN2_BASE
+    9c00   40 dump-reg    \ MRC_BASE
+    9d00   20 dump-reg    \ BBB_BASE
+    9e00  200 dump-reg    \ AGC_BASE
+    ae00  200 dump-reg    \ AGC_BASE1
+    be00  200 dump-reg    \ AGC_BASE2
+    a200  600 dump-reg    \ SMB_BASE
+    b200  600 dump-reg    \ SM_BASE1
+    c200  600 dump-reg    \ SM_BASE2
+;
+: .uregs  ( -- )
+   \ Unknown, non-zero, not badc0ffe, not deadbeef
+    1430   10 dump-reg
+    1470   10 dump-reg
+    1f00  100 dump-reg
+    8400  100 dump-reg
+    d800  440 dump-reg
+    dd00   20 dump-reg
+    de00  200 dump-reg
+    e000 2000 dump-reg
+   10000   40 dump-reg
+   11000 1e00 dump-reg
+   15f00   40 dump-reg
+   16000  c00 dump-reg
+   17c00  400 dump-reg
+;
+
+d# 80 /n* buffer: tx-stat-buf   \ tx statistics buffer
+      	  	 		\ It is indexed with #tx-retry.  Each word
+				\ is # of time that said #tx-retry happened.
+: init-debug  ( -- )  tx-stat-buf d# 80 /n* erase  ;
+: sd  ( -- )
+   true to force-open?
+   a to defch
+   " load-base" evaluate 80.0000 + to debug-base
+   open .
+   " TP-LINK" set-ssid   
+   " "(f4 ec 38 a4 87 2f)" target-mac swap move
+   init-debug
+;
+
+: tx-stat-buf@  ( i -- n )  tx-stat-buf swap na+ @  ;
+: tx-stat-buf++  ( i -- )   tx-stat-buf swap na+ dup @ 1+ swap !  ;
+: log-tx-stat  ( -- )  #tx-retry tx-stat-buf++  ;
+
+0 value testi                   \ test iteration #
+0 value #test                   \ # iteration of test
+0 value #testf                  \ # of test failure
+: testi++   ( -- )  testi  1+ to testi   ;
+: #test++   ( -- )  #test  1+ to #test   ;
+: #testf++  ( -- )  #testf 1+ to #testf  ;
+
+0 value #tx-reset-save
+: save-#tx-reset  ( -- )  #tx-reset to #tx-reset-save  ;
+
+0 value #test-tx-retry          \ Success count
+0 value #test-tx-retry-fail     \ Failure count
+: ?#test-tx-retry++  ( -- )
+   #tx-reset #tx-reset-save >  if  #test-tx-retry 1+ to #test-tx-retry  then  
+;
+: ?#test-tx-retry-fail++  ( -- )
+   #tx-reset #tx-reset-save >  if  #test-tx-retry-fail 1+ to #test-tx-retry-fail  then  
+;
+
+0 value test-start-ms
+0 value test-end-ms
+: 2u.r  ( n -- )  <# u# u# u#> type  ;
+: 3u.r  ( n -- )  <# u# u# u# u#> type  ;
+: .time  ( ms -- )
+   base @ >r decimal         ( ms )  ( R: base )
+   d# 1000 /mod              ( ms' sec )  ( R: base )
+   d# 60 /mod                ( ms sec' min )  ( R: base )
+   d# 60 /mod                ( ms sec min' hr )  ( R: base )
+   2u.r ascii : emit 2u.r ascii : emit 2u.r ascii . emit 3u.r
+   r> base !                 ( )
+;
+: .stat  ( -- )
+   ." elapse time = " test-end-ms test-start-ms - .time cr
+   .rx-stat  .tx-stat 
+   ." #test             = " #test .d cr
+   ." #test failure     = " #testf .d cr 
+   ." #tx-reset success = " #test-tx-retry .d cr
+   ." #tx-reset failure = " #test-tx-retry-fail .d cr
+   ." #tx-reset-max     = " #tx-reset-max .d cr
+   ." tx-stat-buf dump:" cr
+   tx-stat-buf tx-retry-cnt /n* " ldump" evaluate
+;
+: .graph  ( -- )
+   \ Publish test parameters
+   ." tx desc retry cnt        = " rseries @ .d cr
+   ." tx-retry-delay-time (ms) = " tx-retry-delay-time .d cr
+   \ Determine the largest count
+   0 tx-retry-cnt 1+ 1  do  i tx-stat-buf@ max  loop
+   \ Determine the scale for the graph, at least 1
+   d# 100 /mod swap if 1+ then 1 max
+   \ Graph it
+   tx-retry-cnt 1+ 1  do
+      i 2 u.r space space
+      i tx-stat-buf@ over /mod swap if 1+ then
+      ?dup  if  0  do  ascii * emit  loop  then
+      cr
+   loop drop
+;
+
+\ ********************************************************************************
+\ TX, no ACK test
+\
+\ Reminder: set-ssid before testp
+
+: proc-queued-resp  ( -- )
+   begin  deque-rx  while
+      process-rx
+      free-rx
+      got-response?  if  ascii R  else  ascii .  then  emit
+   repeat
+;
+
+: my-probe-ssid  ( adr len -- found? )
+   start-scan-response
+   (probe-ssid)
+;
+: testp  ( -- )
+   ." ---- probe-ssid ----" cr
+   0 to testi
+   get-msecs to test-start-ms
+   begin
+      debug? 0=  if  (cr testi .  then  testi++
+      #test++  save-#tx-reset
+      debug-base 40.0000 + 800 my-probe-ssid 0=  if
+         debug? 0=  if  ."  failed" cr  then
+         log-tx-stat
+         ?#test-tx-retry-fail++
+         #testf++
+      else
+         log-tx-stat
+         ?#test-tx-retry++
+      then
+      400 ms key?
+   until
+   get-msecs to test-end-ms
+;
+
+\ ********************************************************************************
+\ TX, ACK test
+
+: testa  ( -- )
+   ." ---- athenticate ----" cr
+   0 to testi
+   get-msecs to test-start-ms
+   begin  
+      debug? 0=  if  (cr testi .  then  testi++
+      #test++  save-#tx-reset
+      target-mac$ authenticate 0=  if 
+         log-tx-stat
+         ?#test-tx-retry-fail++
+         #testf++
+      else
+         log-tx-stat
+         ?#test-tx-retry++
+      then
+      400 ms key? 
+   until  
+   get-msecs to test-end-ms
+;
+
+\ ********************************************************************************
+\ Associate test
+
+d# 2,000 constant read-timeout-limit
+0 value read-ms
+: read-loop  ( -- )
+   get-msecs read-timeout-limit + to read-ms
+   begin
+      debug-base 10.0000 + 800 read-force drop
+   get-msecs read-ms >= until
+;
+: testd  ( -- )
+   " reset-rcnt" $call-supplicant
+   do-associate 0=  if  ." Fail to associate" cr exit  then
+   ['] 2drop to ?process-eapol
+   read-loop
+   target-mac$ deauthenticate
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/domain.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/domain.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,707 @@
+Purpose: Atheros regulatory domain constants
+\ See license at end of file
+
+headers
+hex
+
+00 constant NO_ENUMRD
+03 constant NULL1_WORLD
+07 constant NULL1_ETSIB
+08 constant NULL1_ETSIC
+10 constant FCC1_FCCA
+11 constant FCC1_WORLD
+12 constant FCC4_FCCA
+13 constant FCC5_FCCA
+14 constant FCC6_FCCA
+
+20 constant FCC2_FCCA
+21 constant FCC2_WORLD
+22 constant FCC2_ETSIC
+23 constant FCC6_WORLD
+31 constant FRANCE_RES
+3a constant FCC3_FCCA
+3b constant FCC3_WORLD
+
+37 constant ETSI1_WORLD
+32 constant ETSI3_ETSIA
+35 constant ETSI2_WORLD
+36 constant ETSI3_WORLD
+30 constant ETSI4_WORLD
+38 constant ETSI4_ETSIC
+39 constant ETSI5_WORLD
+34 constant ETSI6_WORLD
+33 constant ETSI_RESERVED
+
+40 constant MKK1_MKKA
+41 constant MKK1_MKKB
+42 constant APL4_WORLD
+43 constant MKK2_MKKA
+44 constant APL_RESERVED
+45 constant APL2_WORLD
+46 constant APL2_APLC
+47 constant APL3_WORLD
+48 constant MKK1_FCCA
+49 constant APL2_APLD
+4a constant MKK1_MKKA1
+4b constant MKK1_MKKA2
+4c constant MKK1_MKKC
+
+50 constant APL3_FCCA
+52 constant APL1_WORLD
+53 constant APL1_FCCA
+54 constant APL1_APLA
+55 constant APL1_ETSIC
+56 constant APL2_ETSIC
+58 constant APL5_WORLD
+5b constant APL6_WORLD
+5c constant APL7_FCCA 
+5d constant APL8_WORLD
+5e constant APL9_WORLD
+
+60 constant WOR0_WORLD
+61 constant WOR1_WORLD
+62 constant WOR2_WORLD
+63 constant WOR3_WORLD
+64 constant WOR4_WORLD
+65 constant WOR5_ETSIC
+
+66 constant WOR01_WORLD
+67 constant WOR02_WORLD
+68 constant EU1_WORLD
+
+69 constant WOR9_WORLD
+6a constant WORA_WORLD
+6b constant WORB_WORLD
+
+80 constant MKK3_MKKB
+81 constant MKK3_MKKA2
+82 constant MKK3_MKKC 
+
+83 constant MKK4_MKKB 
+84 constant MKK4_MKKA2
+85 constant MKK4_MKKC 
+
+86 constant MKK5_MKKB 
+87 constant MKK5_MKKA2
+88 constant MKK5_MKKC 
+
+89 constant MKK6_MKKB 
+8a constant MKK6_MKKA2
+8b constant MKK6_MKKC 
+
+8c constant MKK7_MKKB 
+8d constant MKK7_MKKA2
+8e constant MKK7_MKKC 
+
+8f constant MKK8_MKKB 
+90 constant MKK8_MKKA2
+91 constant MKK8_MKKC 
+
+92 constant MKK14_MKKA1
+93 constant MKK15_MKKA1
+
+d0 constant MKK10_FCCA 
+d1 constant MKK10_MKKA1
+d2 constant MKK10_MKKC 
+d3 constant MKK10_MKKA2
+
+d4 constant MKK11_MKKA 
+d5 constant MKK11_FCCA 
+d6 constant MKK11_MKKA1
+d7 constant MKK11_MKKC 
+d8 constant MKK11_MKKA2
+
+d9 constant MKK12_MKKA 
+da constant MKK12_FCCA 
+db constant MKK12_MKKA1
+dc constant MKK12_MKKC 
+dd constant MKK12_MKKA2
+
+de constant MKK13_MKKB 
+
+f0 constant MKK3_MKKA 
+f1 constant MKK3_MKKA1
+f2 constant MKK3_FCCA 
+f3 constant MKK4_MKKA 
+f4 constant MKK4_MKKA1
+f5 constant MKK4_FCCA 
+f6 constant MKK9_MKKA 
+f7 constant MKK10_MKKA
+f8 constant MKK6_MKKA1
+f9 constant MKK6_FCCA 
+fa constant MKK7_MKKA1
+fb constant MKK7_FCCA 
+fc constant MKK9_FCCA 
+fd constant MKK9_MKKA1
+fe constant MKK9_MKKC 
+ff constant MKK9_MKKA2
+
+0199 constant WORLD
+01ff constant DEBUG_REG_DMN
+
+40 constant CTL_MKK
+30 constant CTL_ETSI
+ff constant NO_CTL   
+
+\ Regpair to CTL band mapping
+create regDomainPairs
+here
+	\ regpair , 5 GHz CTL , 2 GHz CTL 
+	NO_ENUMRD , DEBUG_REG_DMN , DEBUG_REG_DMN ,
+	NULL1_WORLD , NO_CTL , CTL_ETSI ,
+	NULL1_ETSIB , NO_CTL , CTL_ETSI ,
+	NULL1_ETSIC , NO_CTL , CTL_ETSI ,
+
+	FCC2_FCCA , CTL_FCC , CTL_FCC ,
+	FCC2_WORLD , CTL_FCC , CTL_ETSI ,
+	FCC2_ETSIC , CTL_FCC , CTL_ETSI ,
+	FCC3_FCCA , CTL_FCC , CTL_FCC ,
+	FCC3_WORLD , CTL_FCC , CTL_ETSI ,
+	FCC4_FCCA , CTL_FCC , CTL_FCC ,
+	FCC5_FCCA , CTL_FCC , CTL_FCC ,
+	FCC6_FCCA , CTL_FCC , CTL_FCC ,
+	FCC6_WORLD , CTL_FCC , CTL_ETSI ,
+
+	ETSI1_WORLD , CTL_ETSI , CTL_ETSI ,
+	ETSI2_WORLD , CTL_ETSI , CTL_ETSI ,
+	ETSI3_WORLD , CTL_ETSI , CTL_ETSI ,
+	ETSI4_WORLD , CTL_ETSI , CTL_ETSI ,
+	ETSI5_WORLD , CTL_ETSI , CTL_ETSI ,
+	ETSI6_WORLD , CTL_ETSI , CTL_ETSI ,
+
+	ETSI3_ETSIA , CTL_ETSI , CTL_ETSI ,
+	FRANCE_RES , CTL_ETSI , CTL_ETSI ,
+
+	FCC1_WORLD , CTL_FCC , CTL_ETSI ,
+	FCC1_FCCA , CTL_FCC , CTL_FCC ,
+	APL1_WORLD , CTL_FCC , CTL_ETSI ,
+	APL2_WORLD , CTL_FCC , CTL_ETSI ,
+	APL3_WORLD , CTL_FCC , CTL_ETSI ,
+	APL4_WORLD , CTL_FCC , CTL_ETSI ,
+	APL5_WORLD , CTL_FCC , CTL_ETSI ,
+	APL6_WORLD , CTL_ETSI , CTL_ETSI ,
+	APL8_WORLD , CTL_ETSI , CTL_ETSI ,
+	APL9_WORLD , CTL_ETSI , CTL_ETSI ,
+
+	APL3_FCCA , CTL_FCC , CTL_FCC ,
+	APL7_FCCA , CTL_FCC , CTL_FCC ,
+	APL1_ETSIC , CTL_FCC , CTL_ETSI ,
+	APL2_ETSIC , CTL_FCC , CTL_ETSI ,
+	APL2_APLD , CTL_FCC , NO_CTL ,
+
+	MKK1_MKKA , CTL_MKK , CTL_MKK ,
+	MKK1_MKKB , CTL_MKK , CTL_MKK ,
+	MKK1_FCCA , CTL_MKK , CTL_FCC ,
+	MKK1_MKKA1 , CTL_MKK , CTL_MKK ,
+	MKK1_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK1_MKKC , CTL_MKK , CTL_MKK ,
+
+	MKK2_MKKA , CTL_MKK , CTL_MKK ,
+	MKK3_MKKA , CTL_MKK , CTL_MKK ,
+	MKK3_MKKB , CTL_MKK , CTL_MKK ,
+	MKK3_MKKA1 , CTL_MKK , CTL_MKK ,
+	MKK3_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK3_MKKC , CTL_MKK , CTL_MKK ,
+	MKK3_FCCA , CTL_MKK , CTL_FCC ,
+
+	MKK4_MKKA , CTL_MKK , CTL_MKK ,
+	MKK4_MKKB , CTL_MKK , CTL_MKK ,
+	MKK4_MKKA1 , CTL_MKK , CTL_MKK ,
+	MKK4_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK4_MKKC , CTL_MKK , CTL_MKK ,
+	MKK4_FCCA , CTL_MKK , CTL_FCC ,
+
+	MKK5_MKKB , CTL_MKK , CTL_MKK ,
+	MKK5_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK5_MKKC , CTL_MKK , CTL_MKK ,
+
+	MKK6_MKKB , CTL_MKK , CTL_MKK ,
+	MKK6_MKKA1 , CTL_MKK , CTL_MKK ,
+	MKK6_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK6_MKKC , CTL_MKK , CTL_MKK ,
+	MKK6_FCCA , CTL_MKK , CTL_FCC ,
+
+	MKK7_MKKB , CTL_MKK , CTL_MKK ,
+	MKK7_MKKA1 , CTL_MKK , CTL_MKK ,
+	MKK7_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK7_MKKC , CTL_MKK , CTL_MKK ,
+	MKK7_FCCA , CTL_MKK , CTL_FCC ,
+
+	MKK8_MKKB , CTL_MKK , CTL_MKK ,
+	MKK8_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK8_MKKC , CTL_MKK , CTL_MKK ,
+
+	MKK9_MKKA , CTL_MKK , CTL_MKK ,
+	MKK9_FCCA , CTL_MKK , CTL_FCC ,
+	MKK9_MKKA1 , CTL_MKK , CTL_MKK ,
+	MKK9_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK9_MKKC , CTL_MKK , CTL_MKK ,
+
+	MKK10_MKKA , CTL_MKK , CTL_MKK ,
+	MKK10_FCCA , CTL_MKK , CTL_FCC ,
+	MKK10_MKKA1 , CTL_MKK , CTL_MKK ,
+	MKK10_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK10_MKKC , CTL_MKK , CTL_MKK ,
+
+	MKK11_MKKA , CTL_MKK , CTL_MKK ,
+	MKK11_FCCA , CTL_MKK , CTL_FCC ,
+	MKK11_MKKA1 , CTL_MKK , CTL_MKK ,
+	MKK11_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK11_MKKC , CTL_MKK , CTL_MKK ,
+
+	MKK12_MKKA , CTL_MKK , CTL_MKK ,
+	MKK12_FCCA , CTL_MKK , CTL_FCC ,
+	MKK12_MKKA1 , CTL_MKK , CTL_MKK ,
+	MKK12_MKKA2 , CTL_MKK , CTL_MKK ,
+	MKK12_MKKC , CTL_MKK , CTL_MKK ,
+
+	MKK13_MKKB , CTL_MKK , CTL_MKK ,
+	MKK14_MKKA1 , CTL_MKK , CTL_MKK ,
+	MKK15_MKKA1 , CTL_MKK , CTL_MKK ,
+
+	WOR0_WORLD , NO_CTL , NO_CTL ,
+	WOR1_WORLD , NO_CTL , NO_CTL ,
+	WOR2_WORLD , NO_CTL , NO_CTL ,
+	WOR3_WORLD , NO_CTL , NO_CTL ,
+	WOR4_WORLD , NO_CTL , NO_CTL ,
+	WOR5_ETSIC , NO_CTL , NO_CTL ,
+	WOR01_WORLD , NO_CTL , NO_CTL ,
+	WOR02_WORLD , NO_CTL , NO_CTL ,
+	EU1_WORLD , NO_CTL , NO_CTL ,
+	WOR9_WORLD , NO_CTL , NO_CTL ,
+	WORA_WORLD , NO_CTL , NO_CTL ,
+	WORB_WORLD , NO_CTL , NO_CTL ,
+here swap - 3 /n* / constant #regDomainPairs
+
+0 constant CTRY_DEFAULT
+1ff constant CTRY_DEBUG
+
+\ Country codes
+decimal
+   8 constant CTRY_ALBANIA
+  12 constant CTRY_ALGERIA
+  32 constant CTRY_ARGENTINA
+  51 constant CTRY_ARMENIA
+ 533 constant CTRY_ARUBA
+  36 constant CTRY_AUSTRALIA
+  40 constant CTRY_AUSTRIA
+  31 constant CTRY_AZERBAIJAN
+
+  48 constant CTRY_BAHRAIN
+  50 constant CTRY_BANGLADESH
+  52 constant CTRY_BARBADOS
+ 112 constant CTRY_BELARUS
+  56 constant CTRY_BELGIUM
+  84 constant CTRY_BELIZE
+  68 constant CTRY_BOLIVIA
+  70 constant CTRY_BOSNIA_HERZ
+  76 constant CTRY_BRAZIL
+  96 constant CTRY_BRUNEI_DARUSSALAM
+ 100 constant CTRY_BULGARIA
+
+ 116 constant CTRY_CAMBODIA
+ 124 constant CTRY_CANADA
+ 152 constant CTRY_CHILE
+ 156 constant CTRY_CHINA
+ 170 constant CTRY_COLOMBIA
+ 188 constant CTRY_COSTA_RICA
+ 190 constant CTRY_CROATIA
+ 196 constant CTRY_CYPRUS
+ 203 constant CTRY_CZECH
+
+ 208 constant CTRY_DENMARK
+ 214 constant CTRY_DOMINICAN_REPUBLIC
+
+ 218 constant CTRY_ECUADOR
+ 818 constant CTRY_EGYPT
+ 222 constant CTRY_EL_SALVADOR
+ 233 constant CTRY_ESTONIA
+
+ 234 constant CTRY_FAEROE_ISLANDS
+ 246 constant CTRY_FINLAND
+ 250 constant CTRY_FRANCE
+
+ 268 constant CTRY_GEORGIA
+ 276 constant CTRY_GERMANY
+ 300 constant CTRY_GREECE 
+ 304 constant CTRY_GREENLAND
+ 308 constant CTRY_GRENEDA 
+ 316 constant CTRY_GUAM
+ 320 constant CTRY_GUATEMALA
+
+ 332 constant CTRY_HAITI
+ 340 constant CTRY_HONDURAS
+ 344 constant CTRY_HONG_KONG
+ 348 constant CTRY_HUNGARY
+
+ 352 constant CTRY_ICELAND
+ 356 constant CTRY_INDIA 
+ 360 constant CTRY_INDONESIA 
+ 365 constant CTRY_IRAN 
+ 368 constant CTRY_IRAQ 
+ 372 constant CTRY_IRELAND
+ 376 constant CTRY_ISRAEL 
+ 380 constant CTRY_ITALY 
+
+ 388 constant CTRY_JAMAICA
+ 392 constant CTRY_JAPAN
+ 400 constant CTRY_JORDAN
+
+ 398 constant CTRY_KAZAKHSTAN
+ 404 constant CTRY_KENYA 
+ 408 constant CTRY_KOREA_NORTH
+ 410 constant CTRY_KOREA_ROC 
+ 411 constant CTRY_KOREA_ROC2
+ 412 constant CTRY_KOREA_ROC3
+ 414 constant CTRY_KUWAIT 
+
+ 428 constant CTRY_LATVIA
+ 422 constant CTRY_LEBANON
+ 434 constant CTRY_LIBYA 
+ 438 constant CTRY_LIECHTENSTEIN
+ 440 constant CTRY_LITHUANIA 
+ 442 constant CTRY_LUXEMBOURG
+
+ 446 constant CTRY_MACAU 
+ 807 constant CTRY_MACEDONIA
+ 458 constant CTRY_MALAYSIA 
+ 470 constant CTRY_MALTA 
+ 484 constant CTRY_MEXICO
+ 492 constant CTRY_MONACO
+ 504 constant CTRY_MOROCCO
+
+ 524 constant CTRY_NEPAL
+ 528 constant CTRY_NETHERLANDS
+ 530 constant CTRY_NETHERLANDS_ANTILLES
+ 554 constant CTRY_NEW_ZEALAND
+ 558 constant CTRY_NICARAGUA 
+ 578 constant CTRY_NORWAY
+
+ 512 constant CTRY_OMAN
+
+ 586 constant CTRY_PAKISTAN
+ 591 constant CTRY_PANAMA 
+ 598 constant CTRY_PAPUA_NEW_GUINEA
+ 600 constant CTRY_PARAGUAY
+ 604 constant CTRY_PERU 
+ 608 constant CTRY_PHILIPPINES
+ 616 constant CTRY_POLAND
+ 620 constant CTRY_PORTUGAL
+ 630 constant CTRY_PUERTO_RICO
+
+ 634 constant CTRY_QATAR
+
+ 642 constant CTRY_ROMANIA
+ 643 constant CTRY_RUSSIA
+
+ 682 constant CTRY_SAUDI_ARABIA
+ 891 constant CTRY_SERBIA_MONTENEGRO 
+ 702 constant CTRY_SINGAPORE
+ 703 constant CTRY_SLOVAKIA 
+ 705 constant CTRY_SLOVENIA 
+ 710 constant CTRY_SOUTH_AFRICA
+ 724 constant CTRY_SPAIN 
+ 144 constant CTRY_SRI_LANKA
+ 752 constant CTRY_SWEDEN 
+ 756 constant CTRY_SWITZERLAND
+ 760 constant CTRY_SYRIA 
+
+ 158 constant CTRY_TAIWAN
+ 764 constant CTRY_THAILAND
+ 780 constant CTRY_TRINIDAD_Y_TOBAGO
+ 788 constant CTRY_TUNISIA 
+ 792 constant CTRY_TURKEY 
+
+ 784 constant CTRY_UAE
+ 804 constant CTRY_UKRAINE
+ 826 constant CTRY_UNITED_KINGDOM 
+ 840 constant CTRY_UNITED_STATES
+ 842 constant CTRY_UNITED_STATES_FCC49
+ 858 constant CTRY_URUGUAY 
+ 860 constant CTRY_UZBEKISTAN 
+
+ 862 constant CTRY_VENEZUELA 
+ 704 constant CTRY_VIET_NAM 
+
+ 877 constant CTRY_YEMEN
+
+ 716 constant CTRY_ZIMBABWE 
+
+ 393 constant CTRY_JAPAN1 
+ 394 constant CTRY_JAPAN2 
+ 395 constant CTRY_JAPAN3 
+ 396 constant CTRY_JAPAN4 
+ 397 constant CTRY_JAPAN5 
+4006 constant CTRY_JAPAN6 
+4007 constant CTRY_JAPAN7 
+4008 constant CTRY_JAPAN8 
+4009 constant CTRY_JAPAN9 
+4010 constant CTRY_JAPAN10
+4011 constant CTRY_JAPAN11
+4012 constant CTRY_JAPAN12
+4013 constant CTRY_JAPAN13
+4014 constant CTRY_JAPAN14
+4015 constant CTRY_JAPAN15
+4016 constant CTRY_JAPAN16
+4017 constant CTRY_JAPAN17
+4018 constant CTRY_JAPAN18
+4019 constant CTRY_JAPAN19
+4020 constant CTRY_JAPAN20
+4021 constant CTRY_JAPAN21
+4022 constant CTRY_JAPAN22
+4023 constant CTRY_JAPAN23
+4024 constant CTRY_JAPAN24
+4025 constant CTRY_JAPAN25
+4026 constant CTRY_JAPAN26
+4027 constant CTRY_JAPAN27
+4028 constant CTRY_JAPAN28
+4029 constant CTRY_JAPAN29
+4030 constant CTRY_JAPAN30
+4031 constant CTRY_JAPAN31
+4032 constant CTRY_JAPAN32
+4033 constant CTRY_JAPAN33
+4034 constant CTRY_JAPAN34
+4035 constant CTRY_JAPAN35
+4036 constant CTRY_JAPAN36
+4037 constant CTRY_JAPAN37
+4038 constant CTRY_JAPAN38
+4039 constant CTRY_JAPAN39
+4040 constant CTRY_JAPAN40
+4041 constant CTRY_JAPAN41
+4042 constant CTRY_JAPAN42
+4043 constant CTRY_JAPAN43
+4044 constant CTRY_JAPAN44
+4045 constant CTRY_JAPAN45
+4046 constant CTRY_JAPAN46
+4047 constant CTRY_JAPAN47
+4048 constant CTRY_JAPAN48
+4049 constant CTRY_JAPAN49
+4050 constant CTRY_JAPAN50
+4051 constant CTRY_JAPAN51
+4052 constant CTRY_JAPAN52
+4053 constant CTRY_JAPAN53
+4054 constant CTRY_JAPAN54
+4055 constant CTRY_JAPAN55
+4056 constant CTRY_JAPAN56
+4057 constant CTRY_JAPAN57
+4058 constant CTRY_JAPAN58
+4059 constant CTRY_JAPAN59
+
+5000 constant CTRY_AUSTRALIA2
+5001 constant CTRY_CANADA2 
+5002 constant CTRY_BELGIUM2
+hex
+
+create allCountries
+here
+	CTRY_DEBUG  , NO_ENUMRD  , " DB" $,
+	CTRY_DEFAULT  , FCC1_FCCA  , " CO" $,
+	CTRY_ALBANIA  , NULL1_WORLD  , " AL" $,
+	CTRY_ALGERIA  , NULL1_WORLD  , " DZ" $,
+	CTRY_ARGENTINA  , FCC3_WORLD  , " AR" $,
+	CTRY_ARMENIA  , ETSI4_WORLD  , " AM" $,
+	CTRY_ARUBA  , ETSI1_WORLD  , " AW" $,
+	CTRY_AUSTRALIA  , FCC2_WORLD  , " AU" $,
+	CTRY_AUSTRALIA2  , FCC6_WORLD  , " AU" $,
+	CTRY_AUSTRIA  , ETSI1_WORLD  , " AT" $,
+	CTRY_AZERBAIJAN  , ETSI4_WORLD  , " AZ" $,
+	CTRY_BAHRAIN  , APL6_WORLD  , " BH" $,
+	CTRY_BANGLADESH  , NULL1_WORLD  , " BD" $,
+	CTRY_BARBADOS  , FCC2_WORLD  , " BB" $,
+	CTRY_BELARUS  , ETSI1_WORLD  , " BY" $,
+	CTRY_BELGIUM  , ETSI1_WORLD  , " BE" $,
+	CTRY_BELGIUM2  , ETSI4_WORLD  , " BL" $,
+	CTRY_BELIZE  , APL1_ETSIC  , " BZ" $,
+	CTRY_BOLIVIA  , APL1_ETSIC  , " BO" $,
+	CTRY_BOSNIA_HERZ  , ETSI1_WORLD  , " BA" $,
+	CTRY_BRAZIL  , FCC3_WORLD  , " BR" $,
+	CTRY_BRUNEI_DARUSSALAM  , APL1_WORLD  , " BN" $,
+	CTRY_BULGARIA  , ETSI6_WORLD  , " BG" $,
+	CTRY_CAMBODIA  , ETSI1_WORLD  , " KH" $,
+	CTRY_CANADA  , FCC3_FCCA  , " CA" $,
+	CTRY_CANADA2  , FCC6_FCCA  , " CA" $,
+	CTRY_CHILE  , APL6_WORLD  , " CL" $,
+	CTRY_CHINA  , APL1_WORLD  , " CN" $,
+	CTRY_COLOMBIA  , FCC1_FCCA  , " CO" $,
+	CTRY_COSTA_RICA  , FCC1_WORLD  , " CR" $,
+	CTRY_CROATIA  , ETSI1_WORLD  , " HR" $,
+	CTRY_CYPRUS  , ETSI1_WORLD  , " CY" $,
+	CTRY_CZECH  , ETSI3_WORLD  , " CZ" $,
+	CTRY_DENMARK  , ETSI1_WORLD  , " DK" $,
+	CTRY_DOMINICAN_REPUBLIC  , FCC1_FCCA  , " DO" $,
+	CTRY_ECUADOR  , FCC1_WORLD  , " EC" $,
+	CTRY_EGYPT  , ETSI3_WORLD  , " EG" $,
+	CTRY_EL_SALVADOR  , FCC1_WORLD  , " SV" $,
+	CTRY_ESTONIA  , ETSI1_WORLD  , " EE" $,
+	CTRY_FINLAND  , ETSI1_WORLD  , " FI" $,
+	CTRY_FRANCE  , ETSI1_WORLD  , " FR" $,
+	CTRY_GEORGIA  , ETSI4_WORLD  , " GE" $,
+	CTRY_GERMANY  , ETSI1_WORLD  , " DE" $,
+	CTRY_GREECE  , ETSI1_WORLD  , " GR" $,
+	CTRY_GREENLAND  , ETSI1_WORLD  , " GL" $,
+	CTRY_GRENEDA  , FCC3_FCCA  , " GD" $,
+	CTRY_GUAM  , FCC1_FCCA  , " GU" $,
+	CTRY_GUATEMALA  , FCC1_FCCA  , " GT" $,
+	CTRY_HAITI  , ETSI1_WORLD  , " HT" $,
+	CTRY_HONDURAS  , NULL1_WORLD  , " HN" $,
+	CTRY_HONG_KONG  , FCC3_WORLD  , " HK" $,
+	CTRY_HUNGARY  , ETSI1_WORLD  , " HU" $,
+	CTRY_ICELAND  , ETSI1_WORLD  , " IS" $,
+	CTRY_INDIA  , APL6_WORLD  , " IN" $,
+	CTRY_INDONESIA  , NULL1_WORLD  , " ID" $,
+	CTRY_IRAN  , APL1_WORLD  , " IR" $,
+	CTRY_IRELAND  , ETSI1_WORLD  , " IE" $,
+	CTRY_ISRAEL  , NULL1_WORLD  , " IL" $,
+	CTRY_ITALY  , ETSI1_WORLD  , " IT" $,
+	CTRY_JAMAICA  , FCC3_WORLD  , " JM" $,
+
+	CTRY_JAPAN  , MKK1_MKKA  , " JP" $,
+	CTRY_JAPAN1  , MKK1_MKKB  , " JP" $,
+	CTRY_JAPAN2  , MKK1_FCCA  , " JP" $,
+	CTRY_JAPAN3  , MKK2_MKKA  , " JP" $,
+	CTRY_JAPAN4  , MKK1_MKKA1  , " JP" $,
+	CTRY_JAPAN5  , MKK1_MKKA2  , " JP" $,
+	CTRY_JAPAN6  , MKK1_MKKC  , " JP" $,
+	CTRY_JAPAN7  , MKK3_MKKB  , " JP" $,
+	CTRY_JAPAN8  , MKK3_MKKA2  , " JP" $,
+	CTRY_JAPAN9  , MKK3_MKKC  , " JP" $,
+	CTRY_JAPAN10  , MKK4_MKKB  , " JP" $,
+	CTRY_JAPAN11  , MKK4_MKKA2  , " JP" $,
+	CTRY_JAPAN12  , MKK4_MKKC  , " JP" $,
+	CTRY_JAPAN13  , MKK5_MKKB  , " JP" $,
+	CTRY_JAPAN14  , MKK5_MKKA2  , " JP" $,
+	CTRY_JAPAN15  , MKK5_MKKC  , " JP" $,
+	CTRY_JAPAN16  , MKK6_MKKB  , " JP" $,
+	CTRY_JAPAN17  , MKK6_MKKA2  , " JP" $,
+	CTRY_JAPAN18  , MKK6_MKKC  , " JP" $,
+	CTRY_JAPAN19  , MKK7_MKKB  , " JP" $,
+	CTRY_JAPAN20  , MKK7_MKKA2  , " JP" $,
+	CTRY_JAPAN21  , MKK7_MKKC  , " JP" $,
+	CTRY_JAPAN22  , MKK8_MKKB  , " JP" $,
+	CTRY_JAPAN23  , MKK8_MKKA2  , " JP" $,
+	CTRY_JAPAN24  , MKK8_MKKC  , " JP" $,
+	CTRY_JAPAN25  , MKK3_MKKA  , " JP" $,
+	CTRY_JAPAN26  , MKK3_MKKA1  , " JP" $,
+	CTRY_JAPAN27  , MKK3_FCCA  , " JP" $,
+	CTRY_JAPAN28  , MKK4_MKKA1  , " JP" $,
+	CTRY_JAPAN29  , MKK4_FCCA  , " JP" $,
+	CTRY_JAPAN30  , MKK6_MKKA1  , " JP" $,
+	CTRY_JAPAN31  , MKK6_FCCA  , " JP" $,
+	CTRY_JAPAN32  , MKK7_MKKA1  , " JP" $,
+	CTRY_JAPAN33  , MKK7_FCCA  , " JP" $,
+	CTRY_JAPAN34  , MKK9_MKKA  , " JP" $,
+	CTRY_JAPAN35  , MKK10_MKKA  , " JP" $,
+	CTRY_JAPAN36  , MKK4_MKKA  , " JP" $,
+	CTRY_JAPAN37  , MKK9_FCCA  , " JP" $,
+	CTRY_JAPAN38  , MKK9_MKKA1  , " JP" $,
+	CTRY_JAPAN39  , MKK9_MKKC  , " JP" $,
+	CTRY_JAPAN40  , MKK9_MKKA2  , " JP" $,
+	CTRY_JAPAN41  , MKK10_FCCA  , " JP" $,
+	CTRY_JAPAN42  , MKK10_MKKA1  , " JP" $,
+	CTRY_JAPAN43  , MKK10_MKKC  , " JP" $,
+	CTRY_JAPAN44  , MKK10_MKKA2  , " JP" $,
+	CTRY_JAPAN45  , MKK11_MKKA  , " JP" $,
+	CTRY_JAPAN46  , MKK11_FCCA  , " JP" $,
+	CTRY_JAPAN47  , MKK11_MKKA1  , " JP" $,
+	CTRY_JAPAN48  , MKK11_MKKC  , " JP" $,
+	CTRY_JAPAN49  , MKK11_MKKA2  , " JP" $,
+	CTRY_JAPAN50  , MKK12_MKKA  , " JP" $,
+	CTRY_JAPAN51  , MKK12_FCCA  , " JP" $,
+	CTRY_JAPAN52  , MKK12_MKKA1  , " JP" $,
+	CTRY_JAPAN53  , MKK12_MKKC  , " JP" $,
+	CTRY_JAPAN54  , MKK12_MKKA2  , " JP" $,
+	CTRY_JAPAN57  , MKK13_MKKB  , " JP" $,
+	CTRY_JAPAN58  , MKK14_MKKA1  , " JP" $,
+	CTRY_JAPAN59  , MKK15_MKKA1  , " JP" $,
+
+	CTRY_JORDAN  , ETSI2_WORLD  , " JO" $,
+	CTRY_KAZAKHSTAN  , NULL1_WORLD  , " KZ" $,
+	CTRY_KOREA_NORTH  , APL9_WORLD  , " KP" $,
+	CTRY_KOREA_ROC  , APL9_WORLD  , " KR" $,
+	CTRY_KOREA_ROC2  , APL2_WORLD  , " K2" $,
+	CTRY_KOREA_ROC3  , APL9_WORLD  , " K3" $,
+	CTRY_KUWAIT  , ETSI3_WORLD  , " KW" $,
+	CTRY_LATVIA  , ETSI1_WORLD  , " LV" $,
+	CTRY_LEBANON  , NULL1_WORLD  , " LB" $,
+	CTRY_LIECHTENSTEIN  , ETSI1_WORLD  , " LI" $,
+	CTRY_LITHUANIA  , ETSI1_WORLD  , " LT" $,
+	CTRY_LUXEMBOURG  , ETSI1_WORLD  , " LU" $,
+	CTRY_MACAU  , FCC2_WORLD  , " MO" $,
+	CTRY_MACEDONIA  , NULL1_WORLD  , " MK" $,
+	CTRY_MALAYSIA  , APL8_WORLD  , " MY" $,
+	CTRY_MALTA  , ETSI1_WORLD  , " MT" $,
+	CTRY_MEXICO  , FCC1_FCCA  , " MX" $,
+	CTRY_MONACO  , ETSI4_WORLD  , " MC" $,
+	CTRY_MOROCCO  , APL4_WORLD  , " MA" $,
+	CTRY_NEPAL  , APL1_WORLD  , " NP" $,
+	CTRY_NETHERLANDS  , ETSI1_WORLD  , " NL" $,
+	CTRY_NETHERLANDS_ANTILLES  , ETSI1_WORLD  , " AN" $,
+	CTRY_NEW_ZEALAND  , FCC2_ETSIC  , " NZ" $,
+	CTRY_NORWAY  , ETSI1_WORLD  , " NO" $,
+	CTRY_OMAN  , FCC3_WORLD  , " OM" $,
+	CTRY_PAKISTAN  , NULL1_WORLD  , " PK" $,
+	CTRY_PANAMA  , FCC1_FCCA  , " PA" $,
+	CTRY_PAPUA_NEW_GUINEA  , FCC1_WORLD  , " PG" $,
+	CTRY_PERU  , APL1_WORLD  , " PE" $,
+	CTRY_PHILIPPINES  , APL1_WORLD  , " PH" $,
+	CTRY_POLAND  , ETSI1_WORLD  , " PL" $,
+	CTRY_PORTUGAL  , ETSI1_WORLD  , " PT" $,
+	CTRY_PUERTO_RICO  , FCC1_FCCA  , " PR" $,
+	CTRY_QATAR  , APL1_WORLD  , " QA" $,
+	CTRY_ROMANIA  , NULL1_WORLD  , " RO" $,
+	CTRY_RUSSIA  , NULL1_WORLD  , " RU" $,
+	CTRY_SAUDI_ARABIA  , NULL1_WORLD  , " SA" $,
+	CTRY_SERBIA_MONTENEGRO  , ETSI1_WORLD  , " CS" $,
+	CTRY_SINGAPORE  , APL6_WORLD  , " SG" $,
+	CTRY_SLOVAKIA  , ETSI1_WORLD  , " SK" $,
+	CTRY_SLOVENIA  , ETSI1_WORLD  , " SI" $,
+	CTRY_SOUTH_AFRICA  , FCC3_WORLD  , " ZA" $,
+	CTRY_SPAIN  , ETSI1_WORLD  , " ES" $,
+	CTRY_SRI_LANKA  , FCC3_WORLD  , " LK" $,
+	CTRY_SWEDEN  , ETSI1_WORLD  , " SE" $,
+	CTRY_SWITZERLAND  , ETSI1_WORLD  , " CH" $,
+	CTRY_SYRIA  , NULL1_WORLD  , " SY" $,
+	CTRY_TAIWAN  , APL3_FCCA  , " TW" $,
+	CTRY_THAILAND  , FCC3_WORLD  , " TH" $,
+	CTRY_TRINIDAD_Y_TOBAGO  , FCC3_WORLD  , " TT" $,
+	CTRY_TUNISIA  , ETSI3_WORLD  , " TN" $,
+	CTRY_TURKEY  , ETSI3_WORLD  , " TR" $,
+	CTRY_UKRAINE  , NULL1_WORLD  , " UA" $,
+	CTRY_UAE  , NULL1_WORLD  , " AE" $,
+	CTRY_UNITED_KINGDOM  , ETSI1_WORLD  , " GB" $,
+	CTRY_UNITED_STATES  , FCC3_FCCA  , " US" $,
+
+	CTRY_UNITED_STATES_FCC49  , FCC4_FCCA  , " PS" $,
+	CTRY_URUGUAY  , FCC3_WORLD  , " UY" $,
+	CTRY_UZBEKISTAN  , FCC3_FCCA  , " UZ" $,
+	CTRY_VENEZUELA  , APL2_ETSIC  , " VE" $,
+	CTRY_VIET_NAM  , NULL1_WORLD  , " VN" $,
+	CTRY_YEMEN  , NULL1_WORLD  , " YE" $,
+	CTRY_ZIMBABWE  , NULL1_WORLD  , " ZW" $,
+here swap - 2 /n* 2 + / constant #allCountries
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/eep9382.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/eep9382.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,194 @@
+purpose: Atheros 9382 "EEPROM" code
+\ See license at end of file
+
+headers
+hex
+
+create eeprom
+here
+   02 c, 04 c,                                 \ eepromVersion, templateVersion
+   00 c, 03 c, 7f c, 00 c, 00 c, 00 c,         \ macAddr
+   " h116-041-f0000" $,                        \ custData
+   00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
+   \ baseEepHeader
+   0000 w, 001f w, 33 c, 03 c, 00 c, 00 c, 00 c, 00 c, 05 c,
+   00 c, 00 c, 00 c, 0d c, 00 c, 06 c, 00 c, 08 c, ff c, 10 c, 0 l,
+   \ modalHeader2G
+   0000.0110 l, 0004.4444 l,         \ antCtrlCommon, antCtrlCommon2
+   0010 w, 0010 w, 0010 w,           \ antCtrlChain
+   1f c, 1f c, 1f c,                 \ xatten1DB
+   12 c, 12 c, 12 c,                 \ xatten1Margin
+   19 c, 00 c,                       \ tempSlope, voltSlope
+   a4 c, 00 c, 00 c, 00 c, 00 c,     \ spurChans: FREQ2FBIN(2464, 1)
+   ff c, 00 c, 00 c,                 \ noiseFloorThreshCh
+   01 c, 01 c, 01 c,                 \ ob
+   01 c, 01 c, 01 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, \ db_stage2-4
+   00 c, 0e c, 0e c, 03 c, 00 c, 2c c, e2 c, 00 c, 02 c, 0e c, 1c c,
+   0c80.c080 l, 0080.c080 l,         \ papdRateMaskHt20, 40
+   00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
+   \ base_ext1
+   00 c, 00 c,
+   00 c, 00 c, 00 c,  00 c, 00 c, 00 c,  00 c, 00 c, 00 c,  00 c, 00 c, 00 c,
+   \ calFreqPier2G
+   70 c, 89 c, ac c,                 \ 2412, 2437, 2472
+   \ calPierData2G
+   6 3 * 3 * here over allot swap erase
+   \ calTarget_freqbin_Cck
+   70 c, ac c,                       \ 2412, 2472
+   \ calTarget_freqbin_2G
+   70 c, 89 c, ac c,                 \ 2412, 2437, 2472
+   \ calTarget_freqbin_2GHT20
+   70 c, 89 c, ac c,                 \ 2412, 2437, 2472
+   \ calTarget_freqbin_2GHT40
+   70 c, 89 c, ac c,                 \ 2412, 2437, 2472
+   \ calTargetPowerCck
+decimal
+   34 c, 34 c, 34 c, 34 c, 
+   34 c, 34 c, 34 c, 34 c,
+   \ calTargetPower2G 
+   34 c, 34 c, 32 c, 32 c, 
+   34 c, 34 c, 32 c, 32 c, 
+   34 c, 34 c, 32 c, 32 c, 
+   \ calTargetPower2GHT20
+   32 c, 32 c, 32 c, 32 c, 32 c, 30 c, 32 c, 32 c, 30 c, 28 c, 0 c, 0 c, 0 c, 0 c,
+   32 c, 32 c, 32 c, 32 c, 32 c, 30 c, 32 c, 32 c, 30 c, 28 c, 0 c, 0 c, 0 c, 0 c,
+   32 c, 32 c, 32 c, 32 c, 32 c, 30 c, 32 c, 32 c, 30 c, 28 c, 0 c, 0 c, 0 c, 0 c,
+   \ calTargetPower2GHT40
+   30 c, 30 c, 30 c, 30 c, 30 c, 28 c, 30 c, 30 c, 28 c, 26 c, 0 c, 0 c, 0 c, 0 c,
+   30 c, 30 c, 30 c, 30 c, 30 c, 28 c, 30 c, 30 c, 28 c, 26 c, 0 c, 0 c, 0 c, 0 c,
+   30 c, 30 c, 30 c, 30 c, 30 c, 28 c, 30 c, 30 c, 28 c, 26 c, 0 c, 0 c, 0 c, 0 c,
+hex
+   \ ctlIndex_2G
+   11 c, 12 c, 15 c, 17 c, 41 c, 42 c,
+   45 c, 47 c, 31 c, 32 c, 35 c, 37 c,
+   \ ctlfreqbin_2G
+   70 c, 75 c, 9d c, a2 c,
+   70 c, 75 c, a2 c, ff c,
+   70 c, 75 c, a2 c, ff c,
+   7a c, 7f c, 93 c, 98 c,
+   70 c, 75 c, ac c, b9 c,
+   70 c, 75 c, ac c, 00 c,
+   70 c, 75 c, ac c, 00 c,
+   7a c, 7f c, 93 c, a2 c,
+   70 c, 75 c, ac c, 00 c,
+   70 c, 75 c, ac c, 00 c,
+   70 c, 75 c, ac c, 00 c,
+   7a c, 7f c, 93 c, a2 c,
+   \ ctlPowerData_2G
+   3c c, 7c c, 3c c, 3c c,
+   3c c, 7c c, 3c c, 3c c,
+   7c c, 3c c, 3c c, 7c c,
+   7c c, 3c c, 00 c, 00 c,
+   3c c, 7c c, 3c c, 3c c,
+   3c c, 7c c, 3c c, 3c c,
+   3c c, 7c c, 7c c, 3c c,
+   3c c, 7c c, 3c c, 3c c,
+   3c c, 7c c, 3c c, 3c c,
+   3c c, 7c c, 3c c, 3c c,
+   3c c, 7c c, 7c c, 7c c,
+   3c c, 7c c, 7c c, 7c c,
+   \ modalHeader5G
+   0000.0220 l, 0004.4444 l,         \ antCtrlCommon, antCtrlCommon2
+   0150 w, 0150 w, 0150 w,           \ antCtrlChain
+   19 c, 19 c, 19 c,                 \ xatten1DB
+   14 c, 14 c, 14 c,                 \ xatten1Margin
+   46 c, 00 c,                       \ tempSlope, voltSlope
+   00 c, 00 c, 00 c, 00 c, 00 c,     \ spurChans: FREQ2FBIN(2464, 1)
+   ff c, 00 c, 00 c,                 \ noiseFloorThreshCh
+   03 c, 03 c, 03 c,                 \ ob
+   03 c, 03 c, 03 c, 03 c, 03 c, 03 c, 03 c, 03 c, 03 c, \ db_stage2-4
+   00 c, 0e c, 0e c, 03 c, 00 c, 2d c, e2 c, 00 c, 02 c, 0e c, 1c c,
+   0cf0.e0e0 l, 6cf0.e0e0 l,         \ papdRateMaskHt20, 40
+   00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c,
+   \ base_ext2
+   23 c, 32 c,
+   00 c, 00 c, 00 c,  00 c, 00 c, 00 c,  00 c, 00 c, 00 c,  00 c, 00 c, 00 c,
+   \ calFreqPier5G
+   4c c, 54 c, 68 c, 78 c, 8c c, a0 c, b4 c, c5 c,  \ 5180, 5220, 5320, 5400, 5500, 5600, 5700, 5785
+   \ calPierData5G
+   6 8 * 3 * here over allot swap erase
+   \ calTarget_freqbin_5G
+   4c c, 58 c, 68 c, 78 c, 8c c, a0 c, b4 c, cd c,  \ 5180, 5240, 5320, 5400, 5500, 5600, 5700, 5825
+   \ calTarget_freqbin_5GHT20
+   4c c, 58 c, 68 c, 78 c, 8c c, b4 c, bd c, cd c,  \ 5180, 5240, 5320, 5400, 5500, 5700, 5745, 5825
+   \ calTarget_freqbin_5GHT40
+   4c c, 58 c, 68 c, 78 c, 8c c, b4 c, bd c, cd c,  \ 5180, 5240, 5320, 5400, 5500, 5700, 5745, 5825
+   \ calTargetPower5G
+decimal 
+   30 c, 30 c, 28 c, 24 c,
+   30 c, 30 c, 28 c, 24 c,
+   30 c, 30 c, 28 c, 24 c,
+   30 c, 30 c, 28 c, 24 c,
+   30 c, 30 c, 28 c, 24 c,
+   30 c, 30 c, 28 c, 24 c,
+   30 c, 30 c, 28 c, 24 c,
+   30 c, 30 c, 28 c, 24 c,
+   \ calTargetPower5GHT20
+   30 c, 30 c, 30 c, 28 c, 24 c, 20 c, 30 c, 28 c, 24 c, 20 c, 0 c, 0 c, 0 c, 0 c,
+   30 c, 30 c, 30 c, 28 c, 24 c, 20 c, 30 c, 28 c, 24 c, 20 c, 0 c, 0 c, 0 c, 0 c,
+   30 c, 30 c, 30 c, 26 c, 22 c, 18 c, 30 c, 26 c, 22 c, 18 c, 0 c, 0 c, 0 c, 0 c,
+   30 c, 30 c, 30 c, 26 c, 22 c, 18 c, 30 c, 26 c, 22 c, 18 c, 0 c, 0 c, 0 c, 0 c,
+   30 c, 30 c, 30 c, 24 c, 20 c, 16 c, 30 c, 24 c, 20 c, 16 c, 0 c, 0 c, 0 c, 0 c,
+   30 c, 30 c, 30 c, 24 c, 20 c, 16 c, 30 c, 24 c, 20 c, 16 c, 0 c, 0 c, 0 c, 0 c,
+   30 c, 30 c, 30 c, 22 c, 18 c, 14 c, 30 c, 22 c, 18 c, 14 c, 0 c, 0 c, 0 c, 0 c,
+   30 c, 30 c, 30 c, 22 c, 18 c, 14 c, 30 c, 22 c, 18 c, 14 c, 0 c, 0 c, 0 c, 0 c,
+   \ calTargetPower5GHT40
+   28 c, 28 c, 28 c, 26 c, 22 c, 18 c, 28 c, 26 c, 22 c, 18 c, 0 c, 0 c, 0 c, 0 c,
+   28 c, 28 c, 28 c, 26 c, 22 c, 18 c, 28 c, 26 c, 22 c, 18 c, 0 c, 0 c, 0 c, 0 c,
+   28 c, 28 c, 28 c, 24 c, 20 c, 16 c, 28 c, 24 c, 20 c, 16 c, 0 c, 0 c, 0 c, 0 c,
+   28 c, 28 c, 28 c, 24 c, 20 c, 16 c, 28 c, 24 c, 20 c, 16 c, 0 c, 0 c, 0 c, 0 c,
+   28 c, 28 c, 28 c, 22 c, 18 c, 14 c, 28 c, 22 c, 18 c, 14 c, 0 c, 0 c, 0 c, 0 c,
+   28 c, 28 c, 28 c, 22 c, 18 c, 14 c, 28 c, 22 c, 18 c, 14 c, 0 c, 0 c, 0 c, 0 c,
+   28 c, 28 c, 28 c, 20 c, 16 c, 12 c, 28 c, 20 c, 16 c, 12 c, 0 c, 0 c, 0 c, 0 c,
+   28 c, 28 c, 28 c, 20 c, 16 c, 12 c, 28 c, 20 c, 16 c, 12 c, 0 c, 0 c, 0 c, 0 c,
+hex
+   \ ctlIndex_5G
+   10 c, 16 c, 18 c, 40 c, 46 c, 48 c, 30 c, 36 c, 38 c,
+   \ ctlfreqbin_5G
+   4c c, 5c c, 60 c, 8c c, a0 c, b4 c, bd c, cd c,
+   4c c, 5c c, 60 c, 8c c, 90 c, b4 c, bd c, cd c,
+   4e c, 56 c, 5e c, 66 c, 8e c, 96 c, ae c, bf c,
+   4c c, 50 c, 5c c, 68 c, 8c c, b4 c, ff c, ff c,
+   4c c, 5c c, 8c c, b4 c, ff c, ff c, ff c, ff c,
+   4e c, 5e c, 66 c, 8e c, 9e c, ae c, ff c, ff c,
+   4c c, 50 c, 54 c, 5c c, 8c c, a0 c, b4 c, bd c,
+   4c c, 5c c, 68 c, 8c c, 98 c, b4 c, bd c, cd c,
+   4e c, 56 c, 5e c, 8e c, 96 c, ae c, b4 c, c7 c,
+   \ ctlPowerData_5G
+   7c c, 7c c, 7c c, 7c c, 7c c, 7c c, 7c c, 3c c,
+   7c c, 7c c, 7c c, 7c c, 7c c, 7c c, 7c c, 3c c,
+   3c c, 7c c, 3c c, 7c c, 7c c, 7c c, 7c c, 7c c,
+   3c c, 7c c, 7c c, 3c c, 7c c, 3c c, 3c c, 3c c,
+   7c c, 7c c, 7c c, 3c c, 3c c, 3c c, 3c c, 3c c,
+   7c c, 7c c, 7c c, 7c c, 7c c, 3c c, 3c c, 3c c,
+   7c c, 7c c, 7c c, 7c c, 7c c, 7c c, 7c c, 7c c,
+   7c c, 7c c, 3c c, 7c c, 7c c, 7c c, 7c c, 3c c,
+   7c c, 3c c, 7c c, 7c c, 7c c, 7c c, 3c c, 7c c,
+
+here swap - constant /eeprom-init
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/eepdump.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/eepdump.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,147 @@
+purpose: Atheros 9382 "EEPROM" dump
+\ See license at end of file
+
+headers
+hex
+
+: scdump  ( adr len -- )  bounds  ?do  i sign-c@  s.  loop  ;
+: .tab  ( -- )  ."   "  ;
+: .array   ( adr x y -- )  0  do  .tab 2dup cdump cr  loop  2drop  ;
+: .warray  ( adr x -- )  0  do  dup i wa+ le-w@ . .tab  loop  drop  ;
+: .baseEepHeader  ( adr -- )
+   dup >regDmn0 le-w@              ."   regDmn0 =                " . cr
+   dup >regDmn1 le-w@              ."   regDmn1 =                " . cr
+   dup >txrxMask c@                ."   txrxMask =               " . cr
+   dup >opFlags c@                 ."   opFlags =                " . cr
+   dup >eepMisc c@                 ."   eepMisc =                " . cr
+   dup >rfSilent c@                ."   rfSilent =               " . cr
+   dup >blueToothOptions c@        ."   blueToothOptions =       " . cr
+   dup >deviceCap c@               ."   deviceCap =              " . cr
+   dup >deviceType c@              ."   deviceType =             " . cr
+   dup >pwrTableOffset sign-c@     ."   pwrTableOffset =         " s. cr
+   dup >params_for_tuning_caps c@  ."   params_for_tuning_caps = " . cr
+   dup >featureEnable c@           ."   featureEnable =          " . cr
+   dup >miscConfiguration c@       ."   miscConfiguration =      " . cr
+   dup >eepromWriteEnableGpio c@   ."   eepromWriteEnableGpio =  " . cr
+   dup >wlanDisableGpio c@         ."   wlanDisableGpio =        " . cr
+   dup >rxBandSelectGpio c@        ."   rxBandSelectGpio =       " . cr
+   dup >txrxgain c@                ."   txrxgain =               " . cr
+       >swreg le-l@                ."   swreg =                  " . cr
+;
+: .modalHeader  ( adr -- )
+   dup >antCtrlCommon le-l@        ."   antCtrlCommon =          " . cr
+   dup >antCtrlCommon2 le-l@       ."   antCtrlCommon2 =         " . cr
+   dup >antCtrlChain               ."   antCtrlChain =           " 3 .warray cr
+   dup >xatten1DB                  ."   xatten1DB =              " 3 cdump cr
+   dup >xatten1Margin              ."   xatten1Margin =          " 3 cdump cr
+   dup >tempSlope sign-c@          ."   tempSlope =              " s. cr
+   dup >voltSlope sign-c@          ."   voltSlope =              " s. cr
+   dup >spurChans                  ."   spurChans =              " 5 cdump cr
+   dup >noiseFloorThreshCh         ."   noiseFloorThreshCh =     " 3 scdump cr
+   dup >ob                         ."   ob =                     " 3 cdump cr
+   dup >db_stage2                  ."   db_stage2 =              " 3 cdump cr
+   dup >db_stage3                  ."   db_stage3 =              " 3 cdump cr
+   dup >db_stage4                  ."   db_stage4 =              " 3 cdump cr
+   dup >xpaBiasLvl c@              ."   xpaBiasLvl =             " . cr
+   dup >txFrameToDataStart c@      ."   txFrameToDataStart =     " . cr
+   dup >txFrameToPaOn c@           ."   txFrameToPaOn =          " . cr
+   dup >txClip c@                  ."   txClip =                 " . cr
+   dup >antennaGain sign-c@        ."   antennaGain =            " s. cr
+   dup >switchSettling c@          ."   switchSettling =         " . cr
+   dup >adcDesiredSize sign-c@     ."   adcDesiredSize =         " s. cr
+   dup >txEndToXpaOff c@           ."   txEndToXpaOff =          " . cr
+   dup >txEndToRxOn c@             ."   txEndToRxOn =            " . cr
+   dup >txFrameToXpaOn c@          ."   txFrameToXpaOn =         " . cr
+   dup >thresh62 c@                ."   thresh62 =               " . cr
+   dup >papdRateMaskHt20 le-l@     ."   papdRateMaskHt20 =       " . cr
+       >papdRateMaskHt40 le-l@     ."   papdRateMaskHt40 =       " . cr
+;
+: .base_ext2  ( adr -- )
+   dup >tempSlopeLow sign-c@   ."   tempSlopeLow =           " s. cr
+   dup >tempSlopeHigh sign-c@  ."   tempSlopeHigh =          " s. cr
+   dup >xatten1DBLow           ."   xatten1DBLow =           " 3 cdump cr
+   dup >xatten1MarginLow       ."   xatten1MarginLow =       " 3 cdump cr
+   dup >xatten1DBHigh          ."   xatten1DBHigh =          " 3 cdump cr
+       >xatten1MarginHigh      ."   xatten1MarginHigh =      " 3 cdump cr
+;
+: .tabx  ( -- )  ."      "  ;
+: .calPierData  ( adr #piers #chains -- )
+   ."   chain#  pier#  refPwr voltM  tempM  rxNFC  rxNFP  rxTempM" cr
+   0  do                          ( adr #piers )
+      dup 0  do                   ( adr #piers )
+         .tabx j .  .tabx  i .  .tabx
+         2dup j * i + /cal-data-per-freq-op-loop * +     ( adr #piers adr )
+         dup >refPower sign-c@           s. .tabx
+         dup >voltMeas c@                . .tabx
+         dup >tempMeas c@                . .tabx
+         dup >rxNoisefloorCal sign-c@    s. .tabx
+         dup >rxNoisefloorPower sign-c@  s. .tabx
+             >rxTempMeas c@              . cr
+      loop
+   loop  2drop
+;
+
+: .eeprom  ( -- )
+   eeprom >r
+   r@ >eepromVersion c@         ." EEPROM version =           " . cr
+   r@ >templateVersion c@       ." Template version =         " . cr
+   r@ >macAddr                  ." MAC address =              " 6 cdump cr
+   r@ >custData                 ." Customer data =            " d# 20 cdump cr
+   r@ >baseEepHeader            ." Base EEPROM Header:" cr  .baseEepHeader cr
+
+   r@ >modalHeader2G            ." 2GHz Modal Header:" cr  .modalHeader cr
+   r@ >base_ext1                ." base_ext1 =                " d# 14 cdump cr
+   r@ >calFreqPier2G            ." calFreqPier2G =            " 3 cdump cr
+   r@ >calPierData2G            ." calPierData2G:" cr  3 3 .calPierData
+   r@ >calTarget_freqbin_Cck    ." calTarget_freqbin_Cck =    " 2 cdump cr
+   r@ >calTarget_freqbin_2G     ." calTarget_freqbin_2G =     " 3 cdump cr
+   r@ >calTarget_freqbin_2GHT20 ." calTarget_freqbin_2GHT20 = " 3 cdump cr
+   r@ >calTarget_freqbin_2GHT40 ." calTarget_freqbin_2GHT40 = " 3 cdump cr
+   r@ >calTargetPowerCck        ." calTargetPowerCck.tPow2x:"    cr      4 2 .array
+   r@ >calTargetPower2G         ." calTargetPower2G.tPow2x:"     cr      4 3 .array
+   r@ >calTargetPower2GHT20     ." calTargetPower2GHT20.tPow2x:" cr  d# 14 3 .array
+   r@ >calTargetPower2GHT40     ." calTargetPower2GHT40.tPow2x:" cr  d# 14 3 .array
+   r@ >ctlIndex_2G              ." ctlIndex_2G =              " d# 12 cdump cr
+   r@ >ctl_freqbin_2G           ." ctl_freqbin_2G:"  cr  d# 12 4 .array
+   r@ >ctlPowerData_2G          ." ctlPowerData_2G:" cr  d# 12 4 .array
+
+   r@ >modalHeader5G            ." 5GHz Modal Header:" cr  .modalHeader cr
+   r@ >base_ext2                ." base_ext2:" cr  .base_ext2
+   r@ >calFreqPier5G            ." calFreqPier5G =            " 8 cdump cr
+   r@ >calPierData5G            ." calPierData5G:" cr  8 3 .calPierData
+   r@ >calTarget_freqbin_5G     ." calTarget_freqbin_5G =     " 8 cdump cr
+   r@ >calTarget_freqbin_5GHT20 ." calTarget_freqbin_5GHT20 = " 8 cdump cr
+   r@ >calTarget_freqbin_5GHT40 ." calTarget_freqbin_5GHT40 = " 8 cdump cr
+   r@ >calTargetPower5GHT20     ." calTargetPower5GHT20.tPow2x:" cr  d# 14 8 .array
+   r@ >calTargetPower5GHT40     ." calTargetPower5GHT40.tPow2x:" cr  d# 14 8 .array
+   r@ >ctlIndex_5G              ." ctlIndex_5G =              " 9 cdump cr
+   r@ >ctl_freqbin_5G           ." ctl_freqbin_5G:"  cr  9 8 .array
+   r@ >ctlPowerData_5G          ." ctlPowerData_5G:" cr  9 8 .array
+
+   r>  drop
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/eeprom.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/eeprom.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,349 @@
+purpose: ATH9K EEPROM and OTP manipulation
+\ See license at end of file
+
+headers
+hex
+
+\ Eeprom data structure definition
+struct
+   2 field >regDmn0
+   2 field >regDmn1
+   1 field >txrxMask
+   1 field >opFlags
+   1 field >eepMisc
+   1 field >rfSilent
+   1 field >blueToothOptions
+   1 field >deviceCap
+   1 field >deviceType
+   1 field >pwrTableOffset         \ Signed
+   2 field >params_for_tuning_caps
+   1 field >featureEnable
+   1 field >miscConfiguration
+   1 field >eepromWriteEnableGpio
+   1 field >wlanDisableGpio
+   1 field >wlanLedGpio
+   1 field >rxBandSelectGpio
+   1 field >txrxgain
+   4 field >swreg
+constant /baseEepHeader
+
+struct
+   4 field >antCtrlCommon
+   4 field >antCtrlCommon2
+   3 /w* field >antCtrlChain
+   3 field >xatten1DB
+   3 field >xatten1Margin
+   1 field >tempSlope           \ Signed
+   1 field >voltSlope           \ Signed
+   5 field >spurChans
+   3 field >noiseFloorThreshCh  \ Signed
+   3 field >ob
+   3 field >db_stage2
+   3 field >db_stage3
+   3 field >db_stage4
+   1 field >xpaBiasLvl
+   1 field >txFrameToDataStart
+   1 field >txFrameToPaOn
+   1 field >txClip
+   1 field >antennaGain         \ Signed
+   1 field >switchSettling
+   1 field >adcDesiredSize      \ Signed
+   1 field >txEndToXpaOff
+   1 field >txEndToRxOn
+   1 field >txFrameToXpaOn
+   1 field >thresh62
+   4 field >papdRateMaskHt20
+   4 field >papdRateMaskHt40
+   d# 10 +
+constant /modalHeader
+
+struct
+   1 field >ant_div_control
+   d# 13 +
+constant /base_ext1
+
+struct
+   1 field >tempSlopeLow          \ signed
+   1 field >tempSlopeHigh         \ signed
+   3 field >xatten1DBLow
+   3 field >xatten1MarginLow
+   3 field >xatten1DBHigh
+   3 field >xatten1MarginHigh
+constant /base_ext2
+
+struct
+   1 field >refPower             \ signed
+   1 field >voltMeas
+   1 field >tempMeas
+   1 field >rxNoisefloorCal      \ signed
+   1 field >rxNoisefloorPower    \ signed
+   1 field >rxTempMeas
+constant /cal-data-per-freq-op-loop
+
+struct
+   1 field >eepromVersion
+   1 field >templateVersion
+   6 field >macAddr
+   d# 20 field >custData
+   /baseEepHeader field >baseEepHeader
+   /modalHeader field >modalHeader2G
+   /base_ext1 field >base_ext1
+   3 field >calFreqPier2G
+   6 3 * 3 * field >calPierData2G
+   2 field >calTarget_freqbin_Cck
+   3 field >calTarget_freqbin_2G
+   3 field >calTarget_freqbin_2GHT20
+   3 field >calTarget_freqbin_2GHT40
+   4 2 * field >calTargetPowerCck
+   4 3 * field >calTargetPower2G
+   d# 14 3 * field >calTargetPower2GHT20
+   d# 14 3 * field >calTargetPower2GHT40
+   d# 12 field >ctlIndex_2G
+   d# 12 4 * field >ctl_freqbin_2G
+   d# 12 4 * field >ctlPowerData_2G
+   /modalHeader field >modalHeader5G
+   /base_ext2 field >base_ext2
+   8 field >calFreqPier5G
+   6 8 * 3 * field >calPierData5G
+   8 field >calTarget_freqbin_5G
+   8 field >calTarget_freqbin_5GHT20
+   8 field >calTarget_freqbin_5GHT40
+   4 8 * field >calTargetPower5G
+   d# 14 8 * field >calTargetPower5GHT20
+   d# 14 8 * field >calTargetPower5GHT40
+   9 field >ctlIndex_5G
+   9 8 * field >ctl_freqbin_5G
+   9 8 * field >ctlPowerData_5G
+constant /eeprom
+/eeprom-init /eeprom <>  if  ." eeprom data structure is inconsistent" cr  then
+
+\ Words to facilitate signed-byte eeprom data accesses
+: sign-c  ( b -- n )  d# 24 << d# 24 >>a  ;
+: sign-c@  ( adr -- n )  c@ sign-c  ;
+
+: baseEepHeader    ( -- adr )  eeprom >baseEepHeader  ;
+: base_ext2        ( -- adr )  eeprom >base_ext2  ;
+: pwrTableOffset@  ( -- n )    baseEepHeader >pwrTableOffset sign-c@  ;
+: tempSlopeLow@    ( -- n )    base_ext2 >tempSlopeLow sign-c@  ;
+: tempSlopeHigh@   ( -- n )    base_ext2 >tempSlopeHigh sign-c@  ;
+
+\ ModalHeader based data:
+: tempSlope@  ( adr -- n )  >tempSlope sign-c@  ;
+: voltSlope@  ( adr -- n )  >voltSlope sign-c@  ;
+: noiseFloorThreshCh@  ( adr -- n )  >noiseFloorThreshCh sign-c@  ;
+: antennaGain@  ( adr -- n )  >antennaGain sign-c@  ;
+: adcDesiredSize@  ( adr -- n )  >adcDesiredSize sign-c@  ;
+
+: modalHeader2G  ( -- adr )  eeprom >modalHeader2G  ;
+: tempSlope2G@  ( adr -- n )  modalHeader2G tempSlope@  ;
+: voltSlope2G@  ( adr -- n )  modalHeader2G voltSlope@  ;
+: noiseFloorThreshCh2G@  ( adr -- n )  modalHeader2G noiseFloorThreshCh@  ;
+: antennaGain2G@  ( adr -- n )  modalHeader2G antennaGain@  ;
+: adcDesiredSize2G@  ( adr -- n )  modalHeader2G adcDesiredSize@  ;
+
+: modalHeader5G  ( -- adr )  eeprom >modalHeader5G  ;
+: tempSlope5G@  ( adr -- n )  modalHeader5G tempSlope@  ;
+: voltSlope5G@  ( adr -- n )  modalHeader5G voltSlope@  ;
+: noiseFloorThreshCh5G@  ( adr -- n )  modalHeader5G noiseFloorThreshCh@  ;
+: antennaGain5G@  ( adr -- n )  modalHeader5G antennaGain@  ;
+: adcDesiredSize5G@  ( adr -- n )  modalHeader5G adcDesiredSize@  ;
+
+\ calPierData based data accesses:
+: calPierData2G  ( pier chain -- adr )
+   3 * + /cal-data-per-freq-op-loop *  eeprom >calPierData2G +
+;
+: refPower2G@           ( pier chain -- n )  calPierData2G >refPower sign-c@  ;
+: voltMeas2G@           ( pier chain -- n )  calPierData2G >voltMeas c@  ;
+: tempMeas2G@           ( pier chain -- n )  calPierData2G >tempMeas c@  ;
+: rxTempMeas2G@         ( pier chain -- n )  calPierData2G >rxtempMeas c@  ;
+: rxNoisefloorCal2G@    ( pier chain -- n )  calPierData2G >rxNoisefloorCal sign-c@  ;
+: rxNoisefloorPower2G@  ( pier chain -- n )  calPierData2G >rxNoisefloorPower sign-c@  ;
+
+: calPierData5G  ( pier chain -- adr )
+   8 * + /cal-data-per-freq-op-loop *  eeprom >calPierData5G +
+;
+: refPower5G@           ( pier chain -- n )  calPierData5G >refPower sign-c@  ;
+: voltMeas5G@           ( pier chain -- n )  calPierData5G >voltMeas c@  ;
+: tempMeas5G@           ( pier chain -- n )  calPierData5G >tempMeas c@  ;
+: rxtempMeas5G@         ( pier chain -- n )  calPierData5G >rxtempMeas c@  ;
+: rxNoisefloorCal5G@    ( pier chain -- n )  calPierData5G >rxNoisefloorCal sign-c@  ;
+: rxNoisefloorPower5G@  ( pier chain -- n )  calPierData5G >rxNoisefloorPower sign-c@  ;
+
+\ calTargetPower based data accesses
+: calTargetPowerCck@     ( idx pier -- n )  4 * +  eeprom >calTargetPowerCck + c@  ;
+: calTargetPower2G@      ( idx pier -- n )  4 * +  eeprom >calTargetPower2G + c@  ;
+: calTargetPower2GHT20@  ( idx pier -- n )  d# 14 * +  eeprom >calTargetPower2GHT20 + c@  ;
+: calTargetPower2GHT40@  ( idx pier -- n )  d# 14 * +  eeprom >calTargetPower2GHT40 + c@  ;
+
+: calTargetPower5G@      ( idx pier -- n )  4 * +  eeprom >calTargetPower5G + c@  ;
+: calTargetPower5GHT20@  ( idx pier -- n )  d# 14 * +  eeprom >calTargetPower5GHT40 + c@  ;
+: calTargetPower5GHT40@  ( idx pier -- n )  d# 14 * +  eeprom >calTargetPower5GHT40 + c@  ;
+
+\ ctl based data accesses
+: ctl_freqbin_2G@   ( ctl edge -- n )  d# 12 * +  eeprom >ctl_freqbin_2G + c@  ;
+: ctlPowerData_2G@  ( ctl edge -- n )  d# 12 * +  eeprom >ctlPowerData_2G + c@  ;
+
+: ctl_freqbin_5G@   ( ctl edge -- n )  9 * +  eeprom >ctl_freqbin_5G + c@  ;
+: ctlPowerData_5G@  ( ctl edge -- n )  9 * +  eeprom >ctlPowerData_5G + c@  ;
+
+\ Words to modify the eeprom data structure based on OTP/EEPROM content
+0 value epptr
+0 value edptr
+0 value edend
+: epptr+  ( n -- )  epptr + to epptr  ;
+: edptr+  ( n -- )  2 + edptr + to edptr  ;
+: (process-edata)  ( adr len -- )
+   over + to edend to edptr
+   eeprom to epptr
+   begin  edptr edend <  while
+      edptr c@ epptr+
+      edptr 1+ c@ edptr 2 + epptr 2 pick move
+      dup epptr+  edptr+
+   repeat
+;
+
+: wait-hw  ( val mask reg -- ok? )
+   d# 1.0000 0  do
+      3dup reg@ and =  ?leave
+      d# 10 us
+   loop
+   reg@ and =
+;
+
+: fbin2freq  ( freq is2GHz? -- freq' )
+   over  ff =  if  drop exit  then
+   if  d# 2300 +  else  5 * d# 4800 +  then
+;
+: fbin2freq2G  ( freq -- freq' )  true  fbin2freq  ;
+: fbin2freq5G  ( freq -- freq' )  false fbin2freq  ;
+
+: interpolate  ( x xa xb ya yb -- y )
+   over >r
+   \ y = (yb - ya) * (x - xa) / (xb - xa) + ya
+   swap - 2* >r over - -rot - r> * swap /
+   2 /mod r> + +
+;
+
+: eeprom@  ( idx -- data )   \ On 32-bit boundary, read 32 bits
+   fffc and 2000 + reg@ drop
+   0 5.0000 4084 wait-hw drop    \ Wait till data is valid
+   4084 reg@  ffff and
+;
+: eeprom-b@  ( idx -- b )  dup eeprom@ swap 3 and 8 * >> ff and  ;
+
+\ One time programmable memory read
+: otp@  ( idx -- data )      \ On 32-bit boundary, read 32 bits
+   fffc and 1.4000 + reg@ drop
+   4 7 1.5f18 wait-hw drop       \ Wait till data is valid
+   1.5f1c reg@
+;
+: otp-b@  ( idx -- b )  dup otp@ swap 3 and 8 * >> ff and  ;
+
+: hdr>len  ( header -- len )  lbflip dup 4 >> 7f0 and swap d# 20 >> f and or  ;
+: .hdr  ( header -- )
+   dup                                     ." Header    = " u. cr
+   lbflip
+   dup 5 >> 7 and                          ." Code      = " u. cr
+   dup 1f and over d# 10 >> 20 and or      ." Reference = " u. cr
+   dup 4 >> 7f0 and over d# 20 >> f and or ." Length    = " u. cr
+   dup d# 16 >> f and                      ." Major     = " u. cr
+       d# 24 >> ff and                     ." Minor     = " u. cr
+;
+
+\ To decipher the content of EEPROM or OTP
+\ 0. format: 4-byte hdr, data, 2-byte chksum (read backwards)
+\ 1. see if 3fc eeprom@ is a valid hdr (not 0's and ff's)
+\ 2. if not, see if 1fc eeprom@ is a valid hdr else goto step 6
+\ 3. if not, see if 3fc otp@ is a valid hdr else goto step 6
+\ 4. if not, see if 1fc otp@ is a valid hdr else goto step 7
+\ 5. if not, bad else goto step 7
+\ 6. use eeprom@, goto step 8
+\ 7. use otp@, goto step 8
+\ 8. from current idx down upto 100 times
+\       decipher hdr
+\       if len>=1024, idx--
+\       else verify checksum (sum of all data bytes)
+\            if checksum bad, idx-=len+4+2
+\ 9. save good content in eeprom
+
+\ OTP data block format, entries of:
+\    data-offset  data-len   data
+\ They correspond to C struct ar9300_eeprom.
+\ The AR9382 in Alex correspond to ar9300_h116.
+\ So far, the interesting one is the first entry, which is the mac address.
+
+false value edata-found?
+defer read-op
+defer read-bop
+0 value ehdr
+0 value eptr
+0 value elen
+d# 1024 buffer: edata
+
+: check-hdr  ( -- ok? )  eptr read-op dup  0<>  swap -1 <> and  ;
+: (read-edata)  ( len -- ok? )
+   0 swap                                      ( chksum len )
+   dup to elen 0  do                           ( chksum )
+      eptr i - read-bop dup edata i + c! +     ( chksum' )
+   loop  ffff and                              ( chksum' )
+   eptr elen - dup read-bop swap 1- read-bop   ( chksum cs.lo cs.hi )
+   bwjoin  = dup to edata-found?
+;
+: read-edata  ( -- )
+   d# 100 0  do
+      eptr read-op dup to ehdr hdr>len         ( elen )
+      eptr 4 - to eptr
+      dup d# 1024 >=  if  drop  else  (read-edata) ?leave  then
+   loop
+;
+: process-edata  ( -- )
+    edata elen (process-edata)
+    edata 2 + mac-adr /mac-adr move
+;
+
+: (init-edata)  ( -- )  \ ath9k_hw_eeprom_init
+   false to edata-found?
+   3ff to eptr  ['] eeprom-b@ to read-bop  ['] eeprom@ to read-op
+   check-hdr  if  read-edata  exit  then
+   1ff to eptr
+   check-hdr  if  read-edata  exit  then
+   3ff to eptr  ['] otp-b@ to read-bop  ['] otp@ to read-op
+   check-hdr  if  read-edata  exit  then
+   1ff to eptr
+   check-hdr  if  read-edata  then
+;
+: init-edata  ( -- )
+   (init-edata)
+   edata-found?  if
+      process-edata
+   else
+      ." WARNING: did not found data in OTP" cr
+   then
+;
+
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/global.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/global.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,447 @@
+purpose: ATH9K global variables
+\ See license at end of file
+
+headers
+hex
+
+\ Global variables
+0 value macVersion
+0 value macRev
+0 value phyRev
+
+0 value WARegVal            \ AR_WA register value
+1000.0004 value misc-mode   \ AR_PCU_MISC register value
+0 value ent-mode            \ Value of reg 40d8, enterprise mode
+
+\ opmode values
+1 constant IFTYPE_ADHOC
+2 constant IFTYPE_STATION
+3 constant IFTYPE_AP
+6 constant IFTYPE_MONITOR
+7 constant IFTYPE_MESH_POINT
+
+IFTYPE_STATION value opmode
+: ap-mode?  ( -- AP? )  opmode IFTYPE_AP =  ;
+
+\ (d# 3840 + 4 + (3 + 1 + 4)) / 2 + /rx-stat
+d# 1926 d# 12 + value rx-bufsize
+
+\ ieee80211_rate
+struct
+   /n field >br-bitrate
+   /n field >br-hw-val
+   /n field >br-hw-val-short
+   /n field >br-flags
+constant /rates
+
+\ >br-flags bit definitions
+01 constant br-spream
+02 constant br-mand-a
+04 constant br-mand-b
+08 constant br-mand-g
+10 constant br-erp-g
+
+create legacy-rates
+here
+   d#  10 , 1b ,  0 , 0c ,  \ CCK 1MB
+   d#  20 , 1a , 1e , 09 ,  \ CCK 2MB
+   d#  55 , 19 , 1d , 09 ,  \ CCK 5.5MB
+   d# 110 , 18 , 1c , 09 ,  \ CCK 11MB
+   d#  60 , 0b ,  0 , 19 ,  \ OFDM 6MB
+   d#  90 , 0f ,  0 , 10 ,  \ OFDM 9MB
+   d# 120 , 0a ,  0 , 1b ,  \ OFDM 12MB
+   d# 180 , 0e ,  0 , 10 ,  \ OFDM 18MB
+   d# 240 , 09 ,  0 , 1b ,  \ OFDM 24MB
+   d# 360 , 0d ,  0 , 10 ,  \ OFDM 36MB
+   d# 480 , 08 ,  0 , 10 ,  \ OFDM 48MB
+   d# 540 , 0c ,  0 , 10 ,  \ OFDM 54MB
+here swap - /rates / constant #legacy-rates
+
+: 'legacy-rates  ( i -- adr )  /rates * legacy-rates +  ;
+
+\ ieee80211_supported_band
+struct
+   /n field >band-type            \ Band type
+   /n field >band-channel         \ Pointer to array of channels structures
+   /n field >band-bitrates        \ Pointer to array of bitrates structures
+   /n field >band-#chan
+   /n field >band-#rate
+   /n field >band-ht-cap
+   /n field >band-ht?
+   /n field >band-ampdu-factor
+   /n field >band-ampdu-density
+   /n field >band-tx-params
+   /n field >band-rx-highest
+   10 field >band-rx-mask
+constant /band
+
+\ >band-type values
+0 constant BAND_2GHZ
+1 constant BAND_5GHZ
+
+/band buffer: band-2GHz
+/band buffer: band-5GHz
+create sband band-2GHz , band-5GHz ,
+
+\ >band-ht-cap definitions
+0001 constant HT_CAP_LDPC_CODING     
+0002 constant HT_CAP_SUP_WIDTH_20_40 
+000c constant HT_CAP_SM_PS           
+0010 constant HT_CAP_GRN_FLD         
+0020 constant HT_CAP_SGI_20          
+0040 constant HT_CAP_SGI_40          
+0080 constant HT_CAP_TX_STBC         
+0300 constant HT_CAP_RX_STBC         
+0400 constant HT_CAP_DELAY_BA        
+0800 constant HT_CAP_MAX_AMSDU       
+1000 constant HT_CAP_DSSSCCK40       
+2000 constant HT_CAP_RESERVED        
+4000 constant HT_CAP_40MHZ_INTOLERANT
+8000 constant HT_CAP_LSIG_TXOP_PROT  
+
+\ >band-ampdu-factor values
+0 constant HT_MAX_AMPDU_8K 
+1 constant HT_MAX_AMPDU_16K
+2 constant HT_MAX_AMPDU_32K
+3 constant HT_MAX_AMPDU_64K
+d# 13 constant HT_MAX_AMPDU_FACTOR
+
+\ >band-ampdu-density values
+0 constant HT_MPDU_DENSITY_NONE      \ No restriction
+1 constant HT_MPDU_DENSITY_0_25      \ 1/4 usec
+2 constant HT_MPDU_DENSITY_0_5       \ 1/2 usec
+3 constant HT_MPDU_DENSITY_1         \ 1 usec
+4 constant HT_MPDU_DENSITY_2         \ 2 usec
+5 constant HT_MPDU_DENSITY_4         \ 4 usec
+6 constant HT_MPDU_DENSITY_8         \ 8 usec
+7 constant HT_MPDU_DENSITY_16        \ 16 usec
+
+\ >band-tx-params value
+01 constant HT_MCS_TX_DEFINED 
+02 constant HT_MCS_TX_RX_DIFF 
+10 constant HT_MCS_TX_UNEQUAL_MODULATION 
+
+\ channel structure include the ieee fields
+struct
+   \ ieee80211_channel
+   /n field >ch-band              \ >band-type
+   /n field >ch-freq
+   /n field >ch-hw-val            \ Index to channels
+   /n field >ch-max-power
+   /n field >ch-flags
+   /n field >ch-max-antenna-gain
+   /n field >ch-beacon?
+
+   \ ath9k_channel
+   /n field >ch-mode
+   /n field >ch-noiseFloor
+
+   \ ANI variables
+   /n field >ani-listenTime
+   /n field >ani-ofdmPhyErrCnt
+   /n field >ani-cckPhyErrCnt
+   /n field >ani-ofdmNoiseImmunityLevel
+   /n field >ani-cckNoiseImmunityLevel
+   /n field >ani-spurImmunityLevel
+   /n field >ani-firstepLevel
+   /n field >ani-noiseFloor
+   /n field >ani-rssiThrHigh
+   /n field >ani-rssiThrLow
+   /n field >ani-ofdmWeakSigDetectOff
+   /n field >ani-mrcCCKOff
+   /n field >ani-ofdmsTurn
+
+   \ Cached ANI register values
+   /n field >ani-ini-sfcorr
+   /n field >ani-ini-sfcorr-low
+   /n field >ani-ini-sfcorr-ext
+   /n field >ani-ini-firstep
+   /n field >ani-ini-firstepLow
+   /n field >ani-ini-cycpwrThr1
+   /n field >ani-ini-cycpwrThr1Ext
+constant /channel
+
+: 'band-ch  ( bandadr i -- adr )  /channel * swap >band-channel @ +  ;
+
+decimal
+: ch-allot  ( -- )  here /channel 4 /n* - dup allot erase  ;
+create channels
+here
+   0 , 2412 ,  0 , 20 , ch-allot   \ ch 1
+   0 , 2417 ,  1 , 20 , ch-allot   \ ch 2
+   0 , 2422 ,  2 , 20 , ch-allot   \ ch 3
+   0 , 2427 ,  3 , 20 , ch-allot   \ ch 4
+   0 , 2432 ,  4 , 20 , ch-allot   \ ch 5
+   0 , 2437 ,  5 , 20 , ch-allot   \ ch 6 
+   0 , 2442 ,  6 , 20 , ch-allot   \ ch 7
+   0 , 2447 ,  7 , 20 , ch-allot   \ ch 8
+   0 , 2452 ,  8 , 20 , ch-allot   \ ch 9
+   0 , 2457 ,  9 , 20 , ch-allot   \ ch 10
+   0 , 2462 , 10 , 20 , ch-allot   \ ch 11
+   0 , 2467 , 11 , 20 , ch-allot   \ ch 12
+   0 , 2472 , 12 , 20 , ch-allot   \ ch 13
+   0 , 2484 , 13 , 20 , ch-allot   \ ch 14
+here swap - /channel / ( constant #ch-2GHz )
+
+here
+   \ UNIT 1
+   1 , 5180 , 14 , 20 , ch-allot   \ ch 36
+   1 , 5200 , 15 , 20 , ch-allot   \ ch 40
+   1 , 5220 , 16 , 20 , ch-allot   \ ch 44
+   1 , 5240 , 17 , 20 , ch-allot   \ ch 48
+   \ UNIT 2
+   1 , 5260 , 18 , 20 , ch-allot   \ ch 52
+   1 , 5280 , 19 , 20 , ch-allot   \ ch 56
+   1 , 5300 , 20 , 20 , ch-allot   \ ch 60
+   1 , 5320 , 21 , 20 , ch-allot   \ ch 64
+   \ Middle band
+   1 , 5500 , 22 , 20 , ch-allot   \ ch 100
+   1 , 5520 , 23 , 20 , ch-allot   \ ch 104
+   1 , 5540 , 24 , 20 , ch-allot   \ ch 108
+   1 , 5560 , 25 , 20 , ch-allot   \ ch 112
+   1 , 5580 , 26 , 20 , ch-allot   \ ch 116
+   1 , 5600 , 27 , 20 , ch-allot   \ ch 120
+   1 , 5620 , 28 , 20 , ch-allot   \ ch 124
+   1 , 5640 , 29 , 20 , ch-allot   \ ch 128
+   1 , 5660 , 30 , 20 , ch-allot   \ ch 132
+   1 , 5680 , 31 , 20 , ch-allot   \ ch 136
+   1 , 5700 , 32 , 20 , ch-allot   \ ch 140
+   \ UNIT 3
+   1 , 5745 , 33 , 20 , ch-allot   \ ch 149
+   1 , 5765 , 34 , 20 , ch-allot   \ ch 153
+   1 , 5785 , 35 , 20 , ch-allot   \ ch 157
+   1 , 5805 , 36 , 20 , ch-allot   \ ch 161
+   1 , 5825 , 37 , 20 , ch-allot   \ ch 165
+here swap - /channel / constant #ch-5GHz  constant #ch-2GHz
+
+#ch-5GHz #ch-2GHz + constant #channels
+
+channels value ch-2GHz
+channels #ch-2GHz /channel * + value ch-5GHz
+
+0 value defch       \ 0 based index into channels
+: 'channel  ( ch -- adr )  /channel * channels +  ;
+
+create channel#  1 c, 2 c, 3 c, 4 c, 5 c, 6 c, 7 c, 8 c,
+                 9 c, 10 c, 11 c, 12 c, 13 c, 14 c,
+                 36 c, 40 c, 44 c, 48 c,
+                 52 c, 56 c, 60 c, 64 c,
+                 100 c, 104 c, 108 c, 112 c, 116 c, 120 c,
+		 124 c, 128 c, 132 c, 136 c, 140 c,
+                 149 c, 153 c, 157 c, 161 c, 165 c, 
+: idx>ch  ( idx -- ch# )  channel# + c@  ;
+
+hex
+\ >ch-mode and >ch-flags bit definitions
+0000.0002 constant CH_CW_INT
+0000.0020 constant CH_CCK
+0000.0040 constant CH_OFDM
+0000.0080 constant CH_2GHZ
+0000.0100 constant CH_5GHZ
+0000.0200 constant CH_PASSIVE
+0000.0400 constant CH_DYN
+0000.4000 constant CH_HALF
+0000.8000 constant CH_QUARTER
+0001.0000 constant CH_HT20
+0002.0000 constant CH_HT40+
+0004.0000 constant CH_HT40-
+
+CH_5GHZ CH_OFDM  or constant CH_A
+CH_2GHZ CH_CCK   or constant CH_B
+CH_2GHZ CH_OFDM  or constant CH_G
+CH_2GHZ CH_HT20  or constant CH_G_HT20
+CH_5GHZ CH_HT20  or constant CH_A_HT20
+CH_2GHZ CH_HT40+ or constant CH_G_HT40+
+CH_2GHZ CH_HT40- or constant CH_G_HT40-
+CH_5GHZ CH_HT40+ or constant CH_A_HT40+
+CH_5GHZ CH_HT40- or constant CH_A_HT40-
+CH_OFDM CH_CCK or CH_2GHZ or CH_5GHZ or CH_HT20 or CH_HT40+ or CH_HT40- or constant CH_ALL
+
+: is-g?     ( ch -- flag )
+   >ch-flags @ dup CH_G and CH_G =
+   over CH_G_HT20 and CH_G_HT20 = or
+   over CH_G_HT40+ and CH_G_HT40+ = or
+   swap CH_G_HT40- and CH_G_HT40- = or
+;
+: is-ofdm?  ( ch -- flag )  >ch-flags @ CH_OFDM and  ;
+: is-5GHz?  ( ch -- flag )  >ch-flags @ CH_5GHZ and  ;
+: is-2GHz?  ( ch -- flag )  >ch-flags @ CH_2GHZ and  ;
+: is-half-rate?  ( ch -- flag )  >ch-flags @ CH_HALF and  ;
+: is-quarter-rate?  ( ch -- flag )  >ch-flags @ CH_QUARTER and  ;
+: is-a-fast?  ( ch -- flag )  >ch-flags @ CH_5GHZ and  ;
+: is-b?     ( ch -- flag )  >ch-mode @  CH_B =  ;
+: is-ht20?  ( ch -- flag )  >ch-mode @  CH_HT20 and  ;
+: is-ht40?  ( ch -- flag )  >ch-mode @  CH_HT40+ CH_HT40- or and  ;
+: is-ht?    ( ch -- flag )  dup is-ht20? swap is-ht40? or  ;
+
+hex
+
+\ Rate control phy values
+0 constant WLAN_RC_PHY_OFDM
+1 constant WLAN_RC_PHY_CCK
+2 constant WLAN_RC_PHY_HT_20_SS
+3 constant WLAN_RC_PHY_HT_20_DS
+4 constant WLAN_RC_PHY_HT_20_TS
+5 constant WLAN_RC_PHY_HT_40_SS
+6 constant WLAN_RC_PHY_HT_40_DS
+7 constant WLAN_RC_PHY_HT_40_TS
+8 constant WLAN_RC_PHY_HT_20_SS_HGI
+9 constant WLAN_RC_PHY_HT_20_DS_HGI
+a constant WLAN_RC_PHY_HT_20_TS_HGI
+b constant WLAN_RC_PHY_HT_40_SS_HGI
+c constant WLAN_RC_PHY_HT_40_DS_HGI
+d constant WLAN_RC_PHY_HT_40_TS_HGI
+e constant WLAN_RC_PHY_MAX
+
+\ hw-caps bit definitions
+0000.0001 constant HW_CAP_HT
+0000.0002 constant HW_CAP_RFSILENT
+0000.0004 constant HW_CAP_CST     
+0000.0008 constant HW_CAP_ENHANCEDPM
+0000.0010 constant HW_CAP_AUTOSLEEP 
+0000.0020 constant HW_CAP_4KB_SPLITTRANS
+0000.0040 constant HW_CAP_EDMA		
+0000.0080 constant HW_CAP_RAC_SUPPORTED	
+0000.0100 constant HW_CAP_LDPC		
+0000.0200 constant HW_CAP_FASTCLOCK	
+0000.0400 constant HW_CAP_SGI_20	
+0000.0800 constant HW_CAP_PAPRD		
+0000.1000 constant HW_CAP_ANT_DIV_COMB	
+0000.2000 constant HW_CAP_2GHZ		
+0000.4000 constant HW_CAP_5GHZ		
+0000.8000 constant HW_CAP_APM		
+HW_CAP_HT HW_CAP_CST or HW_CAP_ENHANCEDPM or HW_CAP_AUTOSLEEP or
+HW_CAP_4KB_SPLITTRANS or HW_CAP_EDMA or HW_CAP_FASTCLOCK or HW_CAP_LDPC or
+HW_CAP_RAC_SUPPORTED or HW_CAP_SGI_20 or HW_CAP_5GHZ or HW_CAP_2GHZ or
+value hw-caps
+
+d# 12 /n* constant rx-status-len
+d# 32 /n* constant tx-desc-len
+h# 127 constant dummy-rssi
+
+0 value curchan               \ Points to one of the channels
+d# 20 value slottime
+dummy-rssi value last-rssi
+dummy-rssi value avgbrssi
+0 value max-txchains
+
+\ channel-type definitions
+0 constant NL80211_CHAN_NO_HT
+1 constant NL80211_CHAN_HT20
+2 constant NL80211_CHAN_HT40MINUS
+3 constant NL80211_CHAN_HT40PLUS
+0 value channel-type
+
+: conf-is-ht20?   ( -- flag )  channel-type NL80211_CHAN_HT20 =  ;
+: conf-is-ht40-?  ( -- flag )  channel-type NL80211_CHAN_HT40MINUS =  ;
+: conf-is-ht40+?  ( -- flag )  channel-type NL80211_CHAN_HT40PLUS  =  ;
+: conf-is-ht40?   ( -- flag )  conf-is-ht40-?  conf-is-ht40+?  or  ;
+: conf-is-ht?     ( -- flag )  channel-type  ;
+
+0 value coverage-class
+
+0 value txchainmask
+0 value rxchainmask
+0 value paprd-ratemask
+0 value paprd-ratemask-ht40
+0 value paprd-table-write-done?
+0 value paprd-target-power
+
+1 constant led-pin
+0 constant LED_OFF
+
+/mac-adr buffer: curbssid
+/mac-adr buffer: bssidmask
+0 value curaid
+
+0 value tx-chainmask
+0 value rx-chainmask
+
+0 value clockrate
+\ clockrate values
+d# 22 constant CLOCK_RATE_CCK	
+d# 40 constant CLOCK_RATE_5GHZ_OFDM
+d# 44 constant CLOCK_RATE_2GHZ_OFDM
+d# 44 constant CLOCK_FAST_RATE_5GHZ_OFDM
+
+\ Regulatory
+0 value reg-cap
+
+struct
+   /n field >reg-dmn-enum
+   /n field >reg-5ghz-ctl
+   /n field >reg-2ghz-ctl
+constant /reg-dmn-pair
+
+\ CTL constants
+e0 constant SD_NO_CTL
+0f constant CTL_MODE_M
+00 constant CTL_11A   
+01 constant CTL_11B   
+02 constant CTL_11G   
+05 constant CTL_2GHT20
+06 constant CTL_5GHT20
+07 constant CTL_2GHT40
+08 constant CTL_5GHT40
+CTL_11A 8000 or constant CTL_11A_EXT
+CTL_11B 8000 or constant CTL_11B_EXT
+CTL_11G 8000 or constant CTL_11G_EXT
+
+struct
+   /n field >reg-country
+   /n field >reg-max-power
+   /n field >reg-tp-scale
+   /n field >reg-cur-rd
+   /n field >reg-cur-rd-ext
+   /n field >reg-power-limit
+   /n field >reg-pair
+   2  field >reg-alpha2
+constant /regulatory
+
+/regulatory buffer: regulatory
+
+0 value sc-flags
+\ sc-flags bit definitions
+0001 constant SC_OP_INVALID
+0002 constant SC_OP_BEACONS
+0004 constant SC_OP_RXAGGR 
+0008 constant SC_OP_TXAGGR 
+0010 constant SC_OP_OFFCHANNEL
+0020 constant SC_OP_PREAMBLE_SHORT
+0040 constant SC_OP_PROTECT_ENABLE
+0080 constant SC_OP_RXFLUSH
+0100 constant SC_OP_LED_ASSOCIATED
+0200 constant SC_OP_LED_ON 
+0400 constant SC_OP_TSF_RESET
+0800 constant SC_OP_BT_PRIORITY_DETECTED
+1000 constant SC_OP_BT_SCAN
+2000 constant SC_OP_ANI_RUN
+4000 constant SC_OP_ENABLE_APM
+
+0 value rx-defant
+0 value rs-otherant-cnt
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/ini9382.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/ini9382.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,1486 @@
+purpose: Atheros 9382 initialization arrays
+\ See license at end of file
+
+headers
+hex
+
+create array-soc-preamble
+here
+        \ Addr     allmodes 
+        000040a4 , 00a0c1c9 ,
+        00007008 , 00000000 ,
+        00007020 , 00000000 ,
+        00007034 , 00000002 ,
+        00007038 , 000004c2 ,
+        00007048 , 00000008 ,
+here swap - 2 /n* / constant soc-preamble-#row
+
+create array-soc-postamble
+here
+        \ Addr     5G_HT20    5G_HT40    2G_HT40    2G_HT20 
+        00007010 , 00000023 , 00000023 , 00000023 , 00000023 ,
+here swap - 5 /n* / constant soc-postamble-#row
+
+create array-mac-core
+here
+        \ Addr     allmodes
+        00000008 , 00000000 ,
+        00000030 , 00020085 ,
+        00000034 , 00000005 ,
+        00000040 , 00000000 ,
+        00000044 , 00000000 ,
+        00000048 , 00000008 ,
+        0000004c , 00000010 ,
+        00000050 , 00000000 ,
+        00001040 , 002ffc0f ,
+        00001044 , 002ffc0f ,
+        00001048 , 002ffc0f ,
+        0000104c , 002ffc0f ,
+        00001050 , 002ffc0f ,
+        00001054 , 002ffc0f ,
+        00001058 , 002ffc0f ,
+        0000105c , 002ffc0f ,
+        00001060 , 002ffc0f ,
+        00001064 , 002ffc0f ,
+        000010f0 , 00000100 ,
+        00001270 , 00000000 ,
+        000012b0 , 00000000 ,
+        000012f0 , 00000000 ,
+        0000143c , 00000000 ,
+        0000147c , 00000000 ,
+        00008000 , 00000000 ,
+        00008004 , 00000000 ,
+        00008008 , 00000000 ,
+        0000800c , 00000000 ,
+        00008018 , 00000000 ,
+        00008020 , 00000000 ,
+        00008038 , 00000000 ,
+        0000803c , 00000000 ,
+        00008040 , 00000000 ,
+        00008044 , 00000000 ,
+        00008048 , 00000000 ,
+        0000804c , ffffffff ,
+        00008054 , 00000000 ,
+        00008058 , 00000000 ,
+        0000805c , 000fc78f ,
+        00008060 , 0000000f ,
+        00008064 , 00000000 ,
+        00008070 , 00000310 ,
+        00008074 , 00000020 ,
+        00008078 , 00000000 ,
+        0000809c , 0000000f ,
+        000080a0 , 00000000 ,
+        000080a4 , 02ff0000 ,
+        000080a8 , 0e070605 ,
+        000080ac , 0000000d ,
+        000080b0 , 00000000 ,
+        000080b4 , 00000000 ,
+        000080b8 , 00000000 ,
+        000080bc , 00000000 ,
+        000080c0 , 2a800000 ,
+        000080c4 , 06900168 ,
+        000080c8 , 13881c20 ,
+        000080cc , 01f40000 ,
+        000080d0 , 00252500 ,
+        000080d4 , 00a00000 ,
+        000080d8 , 00400000 ,
+        000080dc , 00000000 ,
+        000080e0 , ffffffff ,
+        000080e4 , 0000ffff ,
+        000080e8 , 3f3f3f3f ,
+        000080ec , 00000000 ,
+        000080f0 , 00000000 ,
+        000080f4 , 00000000 ,
+        000080fc , 00020000 ,
+        00008100 , 00000000 ,
+        00008108 , 00000052 ,
+        0000810c , 00000000 ,
+        00008110 , 00000000 ,
+        00008114 , 000007ff ,
+        00008118 , 000000aa ,
+        0000811c , 00003210 ,
+        00008124 , 00000000 ,
+        00008128 , 00000000 ,
+        0000812c , 00000000 ,
+        00008130 , 00000000 ,
+        00008134 , 00000000 ,
+        00008138 , 00000000 ,
+        0000813c , 0000ffff ,
+        00008144 , ffffffff ,
+        00008168 , 00000000 ,
+        0000816c , 00000000 ,
+        000081c0 , 00000000 ,
+        000081c4 , 33332210 ,
+        000081c8 , 00000000 ,
+        000081cc , 00000000 ,
+        000081ec , 00000000 ,
+        000081f0 , 00000000 ,
+        000081f4 , 00000000 ,
+        000081f8 , 00000000 ,
+        000081fc , 00000000 ,
+        00008240 , 00100000 ,
+        00008244 , 0010f424 ,
+        00008248 , 00000800 ,
+        0000824c , 0001e848 ,
+        00008250 , 00000000 ,
+        00008254 , 00000000 ,
+        00008258 , 00000000 ,
+        0000825c , 40000000 ,
+        00008260 , 00080922 ,
+        00008264 , 9bc00010 ,
+        00008268 , ffffffff ,
+        0000826c , 0000ffff ,
+        00008270 , 00000000 ,
+        00008274 , 40000000 ,
+        00008278 , 003e4180 ,
+        0000827c , 00000004 ,
+        00008284 , 0000002c ,
+        00008288 , 0000002c ,
+        0000828c , 000000ff ,
+        00008294 , 00000000 ,
+        00008298 , 00000000 ,
+        0000829c , 00000000 ,
+        00008300 , 00000140 ,
+        00008314 , 00000000 ,
+        0000831c , 0000010d ,
+        00008328 , 00000000 ,
+        0000832c , 00000007 ,
+        00008330 , 00000302 ,
+        00008334 , 00000700 ,
+        00008338 , 00ff0000 ,
+        0000833c , 02400000 ,
+        00008340 , 000107ff ,
+        00008344 , aa48105b ,
+        00008348 , 008f0000 ,
+        0000835c , 00000000 ,
+        00008360 , ffffffff ,
+        00008364 , ffffffff ,
+        00008368 , 00000000 ,
+        00008370 , 00000000 ,
+        00008374 , 000000ff ,
+        00008378 , 00000000 ,
+        0000837c , 00000000 ,
+        00008380 , ffffffff ,
+        00008384 , ffffffff ,
+        00008390 , ffffffff ,
+        00008394 , ffffffff ,
+        00008398 , 00000000 ,
+        0000839c , 00000000 ,
+        000083a0 , 00000000 ,
+        000083a4 , 0000fa14 ,
+        000083a8 , 000f0c00 ,
+        000083ac , 33332210 ,
+        000083b0 , 33332210 ,
+        000083b4 , 33332210 ,
+        000083b8 , 33332210 ,
+        000083bc , 00000000 ,
+        000083c0 , 00000000 ,
+        000083c4 , 00000000 ,
+        000083c8 , 00000000 ,
+        000083cc , 00000200 ,
+        000083d0 , 000301ff ,
+here swap - 2 /n* / constant mac-core-#row
+
+create array-mac-postamble
+here
+        \ Addr     5G_HT20    5G_HT40    2G_HT40    2G_HT20
+        00001030 , 00000230 , 00000460 , 000002c0 , 00000160 ,
+        00001070 , 00000168 , 000002d0 , 00000318 , 0000018c ,
+        000010b0 , 00000e60 , 00001cc0 , 00007c70 , 00003e38 ,
+        00008014 , 03e803e8 , 07d007d0 , 10801600 , 08400b00 ,
+        0000801c , 128d8027 , 128d804f , 12e00057 , 12e0002b ,
+        00008120 , 08f04800 , 08f04800 , 08f04810 , 08f04810 ,
+        000081d0 , 00003210 , 00003210 , 0000320a , 0000320a ,
+        00008318 , 00003e80 , 00007d00 , 00006880 , 00003440 ,
+here swap - 5 /n* / constant mac-postamble-#row
+
+create array-bb-core
+here
+        \ Addr     allmodes 
+        00009800 , afe68e30 ,
+        00009804 , fd14e000 ,
+        00009808 , 9c0a9f6b ,
+        0000980c , 04900000 ,
+        00009814 , 9280c00a ,
+        00009818 , 00000000 ,
+        0000981c , 00020028 ,
+        00009834 , 6400a290 ,
+        00009838 , 0108ecff ,
+        0000983c , 0d000600 ,
+        00009880 , 201fff00 ,
+        00009884 , 00001042 ,
+        000098a4 , 00200400 ,
+        000098b0 , 32840bbe ,
+        000098d0 , 004b6a8e ,
+        000098d4 , 00000820 ,
+        000098dc , 00000000 ,
+        000098f0 , 00000000 ,
+        000098f4 , 00000000 ,
+        00009c04 , ff55ff55 ,
+        00009c08 , 0320ff55 ,
+        00009c0c , 00000000 ,
+        00009c10 , 00000000 ,
+        00009c14 , 00046384 ,
+        00009c18 , 05b6b440 ,
+        00009c1c , 00b6b440 ,
+        00009d00 , c080a333 ,
+        00009d04 , 40206c10 ,
+        00009d08 , 009c4060 ,
+        00009d0c , 9883800a ,
+        00009d10 , 01834061 ,
+        00009d14 , 00c0040b ,
+        00009d18 , 00000000 ,
+        00009e08 , 0038230c ,
+        00009e24 , 990bb515 ,
+        00009e28 , 0c6f0000 ,
+        00009e30 , 06336f77 ,
+        00009e34 , 6af6532f ,
+        00009e38 , 0cc80c00 ,
+        00009e40 , 0d261820 ,
+        00009e4c , 00001004 ,
+        00009e50 , 00ff03f1 ,
+        00009e54 , 00000000 ,
+        00009fc0 , 803e4788 ,
+        00009fc4 , 0001efb5 ,
+        00009fcc , 40000014 ,
+        00009fd0 , 01193b93 ,
+        0000a20c , 00000000 ,
+        0000a220 , 00000000 ,
+        0000a224 , 00000000 ,
+        0000a228 , 10002310 ,
+        0000a23c , 00000000 ,
+        0000a244 , 0c000000 ,
+        0000a2a0 , 00000001 ,
+        0000a2c0 , 00000001 ,
+        0000a2c8 , 00000000 ,
+        0000a2cc , 18c43433 ,
+        0000a2d4 , 00000000 ,
+        0000a2ec , 00000000 ,
+        0000a2f0 , 00000000 ,
+        0000a2f4 , 00000000 ,
+        0000a2f8 , 00000000 ,
+        0000a344 , 00000000 ,
+        0000a34c , 00000000 ,
+        0000a350 , 0000a000 ,
+        0000a364 , 00000000 ,
+        0000a370 , 00000000 ,
+        0000a390 , 00000001 ,
+        0000a394 , 00000444 ,
+        0000a398 , 001f0e0f ,
+        0000a39c , 0075393f ,
+        0000a3a0 , b79f6427 ,
+        0000a3a4 , 00000000 ,
+        0000a3a8 , aaaaaaaa ,
+        0000a3ac , 3c466478 ,
+        0000a3c0 , 20202020 ,
+        0000a3c4 , 22222220 ,
+        0000a3c8 , 20200020 ,
+        0000a3cc , 20202020 ,
+        0000a3d0 , 20202020 ,
+        0000a3d4 , 20202020 ,
+        0000a3d8 , 20202020 ,
+        0000a3dc , 20202020 ,
+        0000a3e0 , 20202020 ,
+        0000a3e4 , 20202020 ,
+        0000a3e8 , 20202020 ,
+        0000a3ec , 20202020 ,
+        0000a3f0 , 00000000 ,
+        0000a3f4 , 00000246 ,
+        0000a3f8 , 0cdbd380 ,
+        0000a3fc , 000f0f01 ,
+        0000a400 , 8fa91f01 ,
+        0000a404 , 00000000 ,
+        0000a408 , 0e79e5c6 ,
+        0000a40c , 00820820 ,
+        0000a414 , 1ce739ce ,
+        0000a418 , 2d001dce ,
+        0000a41c , 1ce739ce ,
+        0000a420 , 000001ce ,
+        0000a424 , 1ce739ce ,
+        0000a428 , 000001ce ,
+        0000a42c , 1ce739ce ,
+        0000a430 , 1ce739ce ,
+        0000a434 , 00000000 ,
+        0000a438 , 00001801 ,
+        0000a43c , 00100000 ,
+        0000a440 , 00000000 ,
+        0000a444 , 00000000 ,
+        0000a448 , 06000080 ,
+        0000a44c , 00000001 ,
+        0000a450 , 00010000 ,
+        0000a458 , 00000000 ,
+        0000a640 , 00000000 ,
+        0000a644 , 3fad9d74 ,
+        0000a648 , 0048060a ,
+        0000a64c , 00003c37 ,
+        0000a670 , 03020100 ,
+        0000a674 , 09080504 ,
+        0000a678 , 0d0c0b0a ,
+        0000a67c , 13121110 ,
+        0000a680 , 31301514 ,
+        0000a684 , 35343332 ,
+        0000a688 , 00000036 ,
+        0000a690 , 00000838 ,
+        0000a7c0 , 00000000 ,
+        0000a7c4 , fffffffc ,
+        0000a7c8 , 00000000 ,
+        0000a7cc , 00000000 ,
+        0000a7d0 , 00000000 ,
+        0000a7d4 , 00000004 ,
+        0000a7dc , 00000001 ,
+        0000a8d0 , 004b6a8e ,
+        0000a8d4 , 00000820 ,
+        0000a8dc , 00000000 ,
+        0000a8f0 , 00000000 ,
+        0000a8f4 , 00000000 ,
+        0000b2d0 , 00000080 ,
+        0000b2d4 , 00000000 ,
+        0000b2ec , 00000000 ,
+        0000b2f0 , 00000000 ,
+        0000b2f4 , 00000000 ,
+        0000b2f8 , 00000000 ,
+        0000b408 , 0e79e5c0 ,
+        0000b40c , 00820820 ,
+        0000b420 , 00000000 ,
+        0000b8d0 , 004b6a8e ,
+        0000b8d4 , 00000820 ,
+        0000b8dc , 00000000 ,
+        0000b8f0 , 00000000 ,
+        0000b8f4 , 00000000 ,
+        0000c2d0 , 00000080 ,
+        0000c2d4 , 00000000 ,
+        0000c2ec , 00000000 ,
+        0000c2f0 , 00000000 ,
+        0000c2f4 , 00000000 ,
+        0000c2f8 , 00000000 ,
+        0000c408 , 0e79e5c0 ,
+        0000c40c , 00820820 ,
+        0000c420 , 00000000 ,
+here swap - 2 /n* / constant bb-core-#row
+
+create array-bb-postamble
+here
+        \ Addr     5G_HT20    5G_HT40    2G_HT40    2G_HT20 
+        00009810 , d00a8005 , d00a8005 , d00a8011 , d00a8011 ,
+        00009820 , 206a022e , 206a022e , 206a012e , 206a012e ,
+        00009824 , 5ac640d0 , 5ac640d0 , 5ac640d0 , 5ac640d0 ,
+        00009828 , 06903081 , 06903081 , 06903881 , 06903881 ,
+        0000982c , 05eea6d4 , 05eea6d4 , 05eea6d4 , 05eea6d4 ,
+        00009830 , 0000059c , 0000059c , 0000119c , 0000119c ,
+        00009c00 , 000000c4 , 000000c4 , 000000c4 , 000000c4 ,
+        00009e00 , 0372111a , 0372111a , 037216a0 , 037216a0 ,
+        00009e04 , 001c2020 , 001c2020 , 001c2020 , 001c2020 ,
+        00009e0c , 6c4000e2 , 6d4000e2 , 6d4000e2 , 6c4000e2 ,
+        00009e10 , 7ec88d2e , 7ec88d2e , 7ec84d2e , 7ec84d2e ,
+        00009e14 , 37b95d5e , 37b9605e , 3379605e , 33795d5e ,
+        00009e18 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        00009e1c , 0001cf9c , 0001cf9c , 00021f9c , 00021f9c ,
+        00009e20 , 000003b5 , 000003b5 , 000003ce , 000003ce ,
+        00009e2c , 0000001c , 0000001c , 00000021 , 00000021 ,
+        00009e3c , cf946220 , cf946220 , cf946222 , cf946222 ,
+        00009e44 , 02321e27 , 02321e27 , 02291e27 , 02291e27 ,
+        00009e48 , 5030201a , 5030201a , 50302012 , 50302012 ,
+        00009fc8 , 0003f000 , 0003f000 , 0001a000 , 0001a000 ,
+        0000a204 , 000037c0 , 000037c4 , 000037c4 , 000037c0 ,
+        0000a208 , 00000104 , 00000104 , 00000004 , 00000004 ,
+        0000a22c , 01026a2f , 01026a2f , 01026a2f , 01026a2f ,
+        0000a230 , 0000000a , 00000014 , 00000016 , 0000000b ,
+        0000a234 , 00000fff , 10000fff , 10000fff , 00000fff ,
+        0000a238 , ffb81018 , ffb81018 , ffb81018 , ffb81018 ,
+        0000a250 , 00000000 , 00000000 , 00000210 , 00000108 ,
+        0000a254 , 000007d0 , 00000fa0 , 00001130 , 00000898 ,
+        0000a258 , 02020002 , 02020002 , 02020002 , 02020002 ,
+        0000a25c , 01000e0e , 01000e0e , 01000e0e , 01000e0e ,
+        0000a260 , 0a021501 , 0a021501 , 3a021501 , 3a021501 ,
+        0000a264 , 00000e0e , 00000e0e , 00000e0e , 00000e0e ,
+        0000a280 , 00000007 , 00000007 , 0000000b , 0000000b ,
+        0000a284 , 00000000 , 00000000 , 00000150 , 00000150 ,
+        0000a288 , 00000110 , 00000110 , 00000110 , 00000110 ,
+        0000a28c , 00022222 , 00022222 , 00022222 , 00022222 ,
+        0000a2c4 , 00158d18 , 00158d18 , 00158d18 , 00158d18 ,
+        0000a2d0 , 00071981 , 00071981 , 00071981 , 00071982 ,
+        0000a2d8 , 7999a83a , 7999a83a , 7999a83a , 7999a83a ,
+        0000a358 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a830 , 0000019c , 0000019c , 0000019c , 0000019c ,
+        0000ae04 , 001c0000 , 001c0000 , 001c0000 , 001c0000 ,
+        0000ae18 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000ae1c , 0000019c , 0000019c , 0000019c , 0000019c ,
+        0000ae20 , 000001b5 , 000001b5 , 000001ce , 000001ce ,
+        0000b284 , 00000000 , 00000000 , 00000150 , 00000150 ,
+        0000b830 , 0000019c , 0000019c , 0000019c , 0000019c ,
+        0000be04 , 001c0000 , 001c0000 , 001c0000 , 001c0000 ,
+        0000be18 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000be1c , 0000019c , 0000019c , 0000019c , 0000019c ,
+        0000be20 , 000001b5 , 000001b5 , 000001ce , 000001ce ,
+        0000c284 , 00000000 , 00000000 , 00000150 , 00000150 ,
+here swap - 5 /n* / constant bb-postamble-#row
+
+create array-radio-core
+here
+        \ Addr     allmodes
+        00016000 , 36db6db6 ,
+        00016004 , 6db6db40 ,
+        00016008 , 73f00000 ,
+        0001600c , 00000000 ,
+        00016040 , 7f80fff8 ,
+        0001604c , 76d005b5 ,
+        00016050 , 556cf031 ,
+        00016054 , 13449440 ,
+        00016058 , 0c51c92c ,
+        0001605c , 3db7fffc ,
+        00016060 , fffffffc ,
+        00016064 , 000f0278 ,
+        0001606c , 6db60000 ,
+        00016080 , 00000000 ,
+        00016084 , 0e48048c ,
+        00016088 , 54214514 ,
+        0001608c , 119f481e ,
+        00016090 , 24926490 ,
+        00016098 , d2888888 ,
+        000160a0 , 0a108ffe ,
+        000160a4 , 812fc370 ,
+        000160a8 , 423c8000 ,
+        000160b4 , 92480080 ,
+        000160c0 , 00adb6d0 ,
+        000160c4 , 6db6db60 ,
+        000160c8 , 6db6db6c ,
+        000160cc , 01e6c000 ,
+        00016100 , 3fffbe01 ,
+        00016104 , fff80000 ,
+        00016108 , 00080010 ,
+        00016144 , 02084080 ,
+        00016148 , 00000000 ,
+        00016280 , 058a0001 ,
+        00016284 , 3d840208 ,
+        00016288 , 05a20408 ,
+        0001628c , 00038c07 ,
+        00016290 , 00000004 ,
+        00016294 , 458aa14f ,
+        00016380 , 00000000 ,
+        00016384 , 00000000 ,
+        00016388 , 00800700 ,
+        0001638c , 00800700 ,
+        00016390 , 00800700 ,
+        00016394 , 00000000 ,
+        00016398 , 00000000 ,
+        0001639c , 00000000 ,
+        000163a0 , 00000001 ,
+        000163a4 , 00000001 ,
+        000163a8 , 00000000 ,
+        000163ac , 00000000 ,
+        000163b0 , 00000000 ,
+        000163b4 , 00000000 ,
+        000163b8 , 00000000 ,
+        000163bc , 00000000 ,
+        000163c0 , 000000a0 ,
+        000163c4 , 000c0000 ,
+        000163c8 , 14021402 ,
+        000163cc , 00001402 ,
+        000163d0 , 00000000 ,
+        000163d4 , 00000000 ,
+        00016400 , 36db6db6 ,
+        00016404 , 6db6db40 ,
+        00016408 , 73f00000 ,
+        0001640c , 00000000 ,
+        00016440 , 7f80fff8 ,
+        0001644c , 76d005b5 ,
+        00016450 , 556cf031 ,
+        00016454 , 13449440 ,
+        00016458 , 0c51c92c ,
+        0001645c , 3db7fffc ,
+        00016460 , fffffffc ,
+        00016464 , 000f0278 ,
+        0001646c , 6db60000 ,
+        00016500 , 3fffbe01 ,
+        00016504 , fff80000 ,
+        00016508 , 00080010 ,
+        00016544 , 02084080 ,
+        00016548 , 00000000 ,
+        00016780 , 00000000 ,
+        00016784 , 00000000 ,
+        00016788 , 00800700 ,
+        0001678c , 00800700 ,
+        00016790 , 00800700 ,
+        00016794 , 00000000 ,
+        00016798 , 00000000 ,
+        0001679c , 00000000 ,
+        000167a0 , 00000001 ,
+        000167a4 , 00000001 ,
+        000167a8 , 00000000 ,
+        000167ac , 00000000 ,
+        000167b0 , 00000000 ,
+        000167b4 , 00000000 ,
+        000167b8 , 00000000 ,
+        000167bc , 00000000 ,
+        000167c0 , 000000a0 ,
+        000167c4 , 000c0000 ,
+        000167c8 , 14021402 ,
+        000167cc , 00001402 ,
+        000167d0 , 00000000 ,
+        000167d4 , 00000000 ,
+        00016800 , 36db6db6 ,
+        00016804 , 6db6db40 ,
+        00016808 , 73f00000 ,
+        0001680c , 00000000 ,
+        00016840 , 7f80fff8 ,
+        0001684c , 76d005b5 ,
+        00016850 , 556cf031 ,
+        00016854 , 13449440 ,
+        00016858 , 0c51c92c ,
+        0001685c , 3db7fffc ,
+        00016860 , fffffffc ,
+        00016864 , 000f0278 ,
+        0001686c , 6db60000 ,
+        00016900 , 3fffbe01 ,
+        00016904 , fff80000 ,
+        00016908 , 00080010 ,
+        00016944 , 02084080 ,
+        00016948 , 00000000 ,
+        00016b80 , 00000000 ,
+        00016b84 , 00000000 ,
+        00016b88 , 00800700 ,
+        00016b8c , 00800700 ,
+        00016b90 , 00800700 ,
+        00016b94 , 00000000 ,
+        00016b98 , 00000000 ,
+        00016b9c , 00000000 ,
+        00016ba0 , 00000001 ,
+        00016ba4 , 00000001 ,
+        00016ba8 , 00000000 ,
+        00016bac , 00000000 ,
+        00016bb0 , 00000000 ,
+        00016bb4 , 00000000 ,
+        00016bb8 , 00000000 ,
+        00016bbc , 00000000 ,
+        00016bc0 , 000000a0 ,
+        00016bc4 , 000c0000 ,
+        00016bc8 , 14021402 ,
+        00016bcc , 00001402 ,
+        00016bd0 , 00000000 ,
+        00016bd4 , 00000000 ,
+here swap - 2 /n* / constant radio-core-#row
+
+create array-radio-postamble
+here
+        \ Addr     5G_HT20    5G_HT40    2G_HT40    2G_HT20
+        0001609c , 0dd08f29 , 0dd08f29 , 0b283f31 , 0b283f31 ,
+        000160ac , a4653c00 , a4653c00 , 24652800 , 24652800 ,
+        000160b0 , 03284f3e , 03284f3e , 05d08f20 , 05d08f20 ,
+        0001610c , 08000000 , 00000000 , 00000000 , 00000000 ,
+        00016140 , 10804008 , 10804008 , 50804008 , 50804008 ,
+        0001650c , 08000000 , 00000000 , 00000000 , 00000000 ,
+        00016540 , 10804008 , 10804008 , 50804008 , 50804008 ,
+        0001690c , 08000000 , 00000000 , 00000000 , 00000000 ,
+        00016940 , 10804008 , 10804008 , 50804008 , 50804008 ,
+here swap - 5 /n* / constant radio-postamble-#row
+
+create array-tx-gain-lowest
+here
+        \ Addr     5G_HT20    5G_HT40    2G_HT40    2G_HT20 
+        0000a2dc , 00033800 , 00033800 , 00637800 , 00637800 ,
+        0000a2e0 , 0003c000 , 0003c000 , 03838000 , 03838000 ,
+        0000a2e4 , 03fc0000 , 03fc0000 , 03fc0000 , 03fc0000 ,
+        0000a2e8 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a410 , 000050d9 , 000050d9 , 000050d9 , 000050d9 ,
+        0000a500 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a504 , 06000003 , 06000003 , 04000002 , 04000002 ,
+        0000a508 , 0a000020 , 0a000020 , 08000004 , 08000004 ,
+        0000a50c , 10000023 , 10000023 , 0b000200 , 0b000200 ,
+        0000a510 , 16000220 , 16000220 , 0f000202 , 0f000202 ,
+        0000a514 , 1c000223 , 1c000223 , 12000400 , 12000400 ,
+        0000a518 , 21002220 , 21002220 , 16000402 , 16000402 ,
+        0000a51c , 27002223 , 27002223 , 19000404 , 19000404 ,
+        0000a520 , 2b022220 , 2b022220 , 1c000603 , 1c000603 ,
+        0000a524 , 2f022222 , 2f022222 , 21000a02 , 21000a02 ,
+        0000a528 , 34022225 , 34022225 , 25000a04 , 25000a04 ,
+        0000a52c , 3a02222a , 3a02222a , 28000a20 , 28000a20 ,
+        0000a530 , 3e02222c , 3e02222c , 2c000e20 , 2c000e20 ,
+        0000a534 , 4202242a , 4202242a , 30000e22 , 30000e22 ,
+        0000a538 , 4702244a , 4702244a , 34000e24 , 34000e24 ,
+        0000a53c , 4b02244c , 4b02244c , 38001640 , 38001640 ,
+        0000a540 , 4e02246c , 4e02246c , 3c001660 , 3c001660 ,
+        0000a544 , 52022470 , 52022470 , 3f001861 , 3f001861 ,
+        0000a548 , 55022490 , 55022490 , 43001a81 , 43001a81 ,
+        0000a54c , 59022492 , 59022492 , 47001a83 , 47001a83 ,
+        0000a550 , 5d022692 , 5d022692 , 4a001c84 , 4a001c84 ,
+        0000a554 , 61022892 , 61022892 , 4e001ce3 , 4e001ce3 ,
+        0000a558 , 65024890 , 65024890 , 52001ce5 , 52001ce5 ,
+        0000a55c , 69024892 , 69024892 , 56001ce9 , 56001ce9 ,
+        0000a560 , 6e024c92 , 6e024c92 , 5a001ceb , 5a001ceb ,
+        0000a564 , 74026e92 , 74026e92 , 5d001eec , 5d001eec ,
+        0000a568 , 74026e92 , 74026e92 , 5d001eec , 5d001eec ,
+        0000a56c , 74026e92 , 74026e92 , 5d001eec , 5d001eec ,
+        0000a570 , 74026e92 , 74026e92 , 5d001eec , 5d001eec ,
+        0000a574 , 74026e92 , 74026e92 , 5d001eec , 5d001eec ,
+        0000a578 , 74026e92 , 74026e92 , 5d001eec , 5d001eec ,
+        0000a57c , 74026e92 , 74026e92 , 5d001eec , 5d001eec ,
+        0000a580 , 00800000 , 00800000 , 00800000 , 00800000 ,
+        0000a584 , 06800003 , 06800003 , 04800002 , 04800002 ,
+        0000a588 , 0a800020 , 0a800020 , 08800004 , 08800004 ,
+        0000a58c , 10800023 , 10800023 , 0b800200 , 0b800200 ,
+        0000a590 , 16800220 , 16800220 , 0f800202 , 0f800202 ,
+        0000a594 , 1c800223 , 1c800223 , 12800400 , 12800400 ,
+        0000a598 , 21802220 , 21802220 , 16800402 , 16800402 ,
+        0000a59c , 27802223 , 27802223 , 19800404 , 19800404 ,
+        0000a5a0 , 2b822220 , 2b822220 , 1c800603 , 1c800603 ,
+        0000a5a4 , 2f822222 , 2f822222 , 21800a02 , 21800a02 ,
+        0000a5a8 , 34822225 , 34822225 , 25800a04 , 25800a04 ,
+        0000a5ac , 3a82222a , 3a82222a , 28800a20 , 28800a20 ,
+        0000a5b0 , 3e82222c , 3e82222c , 2c800e20 , 2c800e20 ,
+        0000a5b4 , 4282242a , 4282242a , 30800e22 , 30800e22 ,
+        0000a5b8 , 4782244a , 4782244a , 34800e24 , 34800e24 ,
+        0000a5bc , 4b82244c , 4b82244c , 38801640 , 38801640 ,
+        0000a5c0 , 4e82246c , 4e82246c , 3c801660 , 3c801660 ,
+        0000a5c4 , 52822470 , 52822470 , 3f801861 , 3f801861 ,
+        0000a5c8 , 55822490 , 55822490 , 43801a81 , 43801a81 ,
+        0000a5cc , 59822492 , 59822492 , 47801a83 , 47801a83 ,
+        0000a5d0 , 5d822692 , 5d822692 , 4a801c84 , 4a801c84 ,
+        0000a5d4 , 61822892 , 61822892 , 4e801ce3 , 4e801ce3 ,
+        0000a5d8 , 65824890 , 65824890 , 52801ce5 , 52801ce5 ,
+        0000a5dc , 69824892 , 69824892 , 56801ce9 , 56801ce9 ,
+        0000a5e0 , 6e824c92 , 6e824c92 , 5a801ceb , 5a801ceb ,
+        0000a5e4 , 74826e92 , 74826e92 , 5d801eec , 5d801eec ,
+        0000a5e8 , 74826e92 , 74826e92 , 5d801eec , 5d801eec ,
+        0000a5ec , 74826e92 , 74826e92 , 5d801eec , 5d801eec ,
+        0000a5f0 , 74826e92 , 74826e92 , 5d801eec , 5d801eec ,
+        0000a5f4 , 74826e92 , 74826e92 , 5d801eec , 5d801eec ,
+        0000a5f8 , 74826e92 , 74826e92 , 5d801eec , 5d801eec ,
+        0000a5fc , 74826e92 , 74826e92 , 5d801eec , 5d801eec ,
+        0000a600 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a604 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a608 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a60c , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a610 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a614 , 02004000 , 02004000 , 01404000 , 01404000 ,
+        0000a618 , 02004801 , 02004801 , 01404501 , 01404501 ,
+        0000a61c , 02808a02 , 02808a02 , 02008501 , 02008501 ,
+        0000a620 , 0380ce03 , 0380ce03 , 0280ca03 , 0280ca03 ,
+        0000a624 , 04411104 , 04411104 , 03010c04 , 03010c04 ,
+        0000a628 , 04411104 , 04411104 , 04014c04 , 04014c04 ,
+        0000a62c , 04411104 , 04411104 , 04015005 , 04015005 ,
+        0000a630 , 04411104 , 04411104 , 04015005 , 04015005 ,
+        0000a634 , 04411104 , 04411104 , 04015005 , 04015005 ,
+        0000a638 , 04411104 , 04411104 , 04015005 , 04015005 ,
+        0000a63c , 04411104 , 04411104 , 04015005 , 04015005 ,
+        0000b2dc , 00033800 , 00033800 , 00637800 , 00637800 ,
+        0000b2e0 , 0003c000 , 0003c000 , 03838000 , 03838000 ,
+        0000b2e4 , 03fc0000 , 03fc0000 , 03fc0000 , 03fc0000 ,
+        0000b2e8 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000c2dc , 00033800 , 00033800 , 00637800 , 00637800 ,
+        0000c2e0 , 0003c000 , 0003c000 , 03838000 , 03838000 ,
+        0000c2e4 , 03fc0000 , 03fc0000 , 03fc0000 , 03fc0000 ,
+        0000c2e8 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        00016044 , 012492d4 , 012492d4 , 012492d4 , 012492d4 ,
+        00016048 , 62480001 , 62480001 , 62480001 , 62480001 ,
+        00016068 , 6db6db6c , 6db6db6c , 6db6db6c , 6db6db6c ,
+        00016444 , 012492d4 , 012492d4 , 012492d4 , 012492d4 ,
+        00016448 , 62480001 , 62480001 , 62480001 , 62480001 ,
+        00016468 , 6db6db6c , 6db6db6c , 6db6db6c , 6db6db6c ,
+        00016844 , 012492d4 , 012492d4 , 012492d4 , 012492d4 ,
+        00016848 , 62480001 , 62480001 , 62480001 , 62480001 ,
+        00016868 , 6db6db6c , 6db6db6c , 6db6db6c , 6db6db6c ,
+here swap - 5 /n* / constant tx-gain-lowest-#row
+
+create array-tx-gain-low
+here
+        \ Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20 
+        0000a2dc , 0380c7fc , 0380c7fc , 00637800 , 00637800 ,
+        0000a2e0 , 0000f800 , 0000f800 , 03838000 , 03838000 ,
+        0000a2e4 , 03ff0000 , 03ff0000 , 03fc0000 , 03fc0000 ,
+        0000a2e8 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a410 , 000050d9 , 000050d9 , 000050d9 , 000050d9 ,
+        0000a500 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a504 , 06000003 , 06000003 , 04000002 , 04000002 ,
+        0000a508 , 0a000020 , 0a000020 , 08000004 , 08000004 ,
+        0000a50c , 10000023 , 10000023 , 0b000200 , 0b000200 ,
+        0000a510 , 16000220 , 16000220 , 0f000202 , 0f000202 ,
+        0000a514 , 1c000223 , 1c000223 , 12000400 , 12000400 ,
+        0000a518 , 21002220 , 21002220 , 16000402 , 16000402 ,
+        0000a51c , 27002223 , 27002223 , 19000404 , 19000404 ,
+        0000a520 , 2b022220 , 2b022220 , 1c000603 , 1c000603 ,
+        0000a524 , 2f022222 , 2f022222 , 21000a02 , 21000a02 ,
+        0000a528 , 34022225 , 34022225 , 25000a04 , 25000a04 ,
+        0000a52c , 3a02222a , 3a02222a , 28000a20 , 28000a20 ,
+        0000a530 , 3e02222c , 3e02222c , 2c000e20 , 2c000e20 ,
+        0000a534 , 4202242a , 4202242a , 30000e22 , 30000e22 ,
+        0000a538 , 4702244a , 4702244a , 34000e24 , 34000e24 ,
+        0000a53c , 4b02244c , 4b02244c , 38001640 , 38001640 ,
+        0000a540 , 4e02246c , 4e02246c , 3c001660 , 3c001660 ,
+        0000a544 , 5302266c , 5302266c , 3f001861 , 3f001861 ,
+        0000a548 , 5702286c , 5702286c , 43001a81 , 43001a81 ,
+        0000a54c , 5c02486b , 5c02486b , 47001a83 , 47001a83 ,
+        0000a550 , 61024a6c , 61024a6c , 4a001c84 , 4a001c84 ,
+        0000a554 , 66026a6c , 66026a6c , 4e001ce3 , 4e001ce3 ,
+        0000a558 , 6b026e6c , 6b026e6c , 52001ce5 , 52001ce5 ,
+        0000a55c , 7002708c , 7002708c , 56001ce9 , 56001ce9 ,
+        0000a560 , 7302b08a , 7302b08a , 5a001ceb , 5a001ceb ,
+        0000a564 , 7702b08c , 7702b08c , 5d001eec , 5d001eec ,
+        0000a568 , 7702b08c , 7702b08c , 5d001eec , 5d001eec ,
+        0000a56c , 7702b08c , 7702b08c , 5d001eec , 5d001eec ,
+        0000a570 , 7702b08c , 7702b08c , 5d001eec , 5d001eec ,
+        0000a574 , 7702b08c , 7702b08c , 5d001eec , 5d001eec ,
+        0000a578 , 7702b08c , 7702b08c , 5d001eec , 5d001eec ,
+        0000a57c , 7702b08c , 7702b08c , 5d001eec , 5d001eec ,
+        0000a580 , 00800000 , 00800000 , 00800000 , 00800000 ,
+        0000a584 , 06800003 , 06800003 , 04800002 , 04800002 ,
+        0000a588 , 0a800020 , 0a800020 , 08800004 , 08800004 ,
+        0000a58c , 10800023 , 10800023 , 0b800200 , 0b800200 ,
+        0000a590 , 16800220 , 16800220 , 0f800202 , 0f800202 ,
+        0000a594 , 1c800223 , 1c800223 , 12800400 , 12800400 ,
+        0000a598 , 21802220 , 21802220 , 16800402 , 16800402 ,
+        0000a59c , 27802223 , 27802223 , 19800404 , 19800404 ,
+        0000a5a0 , 2b822220 , 2b822220 , 1c800603 , 1c800603 ,
+        0000a5a4 , 2f822222 , 2f822222 , 21800a02 , 21800a02 ,
+        0000a5a8 , 34822225 , 34822225 , 25800a04 , 25800a04 ,
+        0000a5ac , 3a82222a , 3a82222a , 28800a20 , 28800a20 ,
+        0000a5b0 , 3e82222c , 3e82222c , 2c800e20 , 2c800e20 ,
+        0000a5b4 , 4282242a , 4282242a , 30800e22 , 30800e22 ,
+        0000a5b8 , 4782244a , 4782244a , 34800e24 , 34800e24 ,
+        0000a5bc , 4b82244c , 4b82244c , 38801640 , 38801640 ,
+        0000a5c0 , 4e82246c , 4e82246c , 3c801660 , 3c801660 ,
+        0000a5c4 , 5382266c , 5382266c , 3f801861 , 3f801861 ,
+        0000a5c8 , 5782286c , 5782286c , 43801a81 , 43801a81 ,
+        0000a5cc , 5c82486b , 5c82486b , 47801a83 , 47801a83 ,
+        0000a5d0 , 61824a6c , 61824a6c , 4a801c84 , 4a801c84 ,
+        0000a5d4 , 66826a6c , 66826a6c , 4e801ce3 , 4e801ce3 ,
+        0000a5d8 , 6b826e6c , 6b826e6c , 52801ce5 , 52801ce5 ,
+        0000a5dc , 7082708c , 7082708c , 56801ce9 , 56801ce9 ,
+        0000a5e0 , 7382b08a , 7382b08a , 5a801ceb , 5a801ceb ,
+        0000a5e4 , 7782b08c , 7782b08c , 5d801eec , 5d801eec ,
+        0000a5e8 , 7782b08c , 7782b08c , 5d801eec , 5d801eec ,
+        0000a5ec , 7782b08c , 7782b08c , 5d801eec , 5d801eec ,
+        0000a5f0 , 7782b08c , 7782b08c , 5d801eec , 5d801eec ,
+        0000a5f4 , 7782b08c , 7782b08c , 5d801eec , 5d801eec ,
+        0000a5f8 , 7782b08c , 7782b08c , 5d801eec , 5d801eec ,
+        0000a5fc , 7782b08c , 7782b08c , 5d801eec , 5d801eec ,
+        0000a600 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a604 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a608 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a60c , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a610 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a614 , 01404000 , 01404000 , 01404000 , 01404000 ,
+        0000a618 , 01404501 , 01404501 , 01404501 , 01404501 ,
+        0000a61c , 02008802 , 02008802 , 02008501 , 02008501 ,
+        0000a620 , 0300cc03 , 0300cc03 , 0280ca03 , 0280ca03 ,
+        0000a624 , 0300cc03 , 0300cc03 , 03010c04 , 03010c04 ,
+        0000a628 , 0300cc03 , 0300cc03 , 04014c04 , 04014c04 ,
+        0000a62c , 03810c03 , 03810c03 , 04015005 , 04015005 ,
+        0000a630 , 03810e04 , 03810e04 , 04015005 , 04015005 ,
+        0000a634 , 03810e04 , 03810e04 , 04015005 , 04015005 ,
+        0000a638 , 03810e04 , 03810e04 , 04015005 , 04015005 ,
+        0000a63c , 03810e04 , 03810e04 , 04015005 , 04015005 ,
+        0000b2dc , 0380c7fc , 0380c7fc , 00637800 , 00637800 ,
+        0000b2e0 , 0000f800 , 0000f800 , 03838000 , 03838000 ,
+        0000b2e4 , 03ff0000 , 03ff0000 , 03fc0000 , 03fc0000 ,
+        0000b2e8 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000c2dc , 0380c7fc , 0380c7fc , 00637800 , 00637800 ,
+        0000c2e0 , 0000f800 , 0000f800 , 03838000 , 03838000 ,
+        0000c2e4 , 03ff0000 , 03ff0000 , 03fc0000 , 03fc0000 ,
+        0000c2e8 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        00016044 , 012492d4 , 012492d4 , 012492d4 , 012492d4 ,
+        00016048 , 66480001 , 66480001 , 66480001 , 66480001 ,
+        00016068 , 6db6db6c , 6db6db6c , 6db6db6c , 6db6db6c ,
+        00016444 , 012492d4 , 012492d4 , 012492d4 , 012492d4 ,
+        00016448 , 66480001 , 66480001 , 66480001 , 66480001 ,
+        00016468 , 6db6db6c , 6db6db6c , 6db6db6c , 6db6db6c ,
+        00016844 , 012492d4 , 012492d4 , 012492d4 , 012492d4 ,
+        00016848 , 66480001 , 66480001 , 66480001 , 66480001 ,
+        00016868 , 6db6db6c , 6db6db6c , 6db6db6c , 6db6db6c ,
+here swap - 5 /n* / constant tx-gain-low-#row
+
+create array-tx-gain-hi
+here
+        \ Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20 
+        0000a2dc , 01feee00 , 01feee00 , 00637800 , 00637800 ,
+        0000a2e0 , 0000f000 , 0000f000 , 03838000 , 03838000 ,
+        0000a2e4 , 01ff0000 , 01ff0000 , 03fc0000 , 03fc0000 ,
+        0000a2e8 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a410 , 000050d8 , 000050d8 , 000050d9 , 000050d9 ,
+        0000a500 , 00002220 , 00002220 , 00000000 , 00000000 ,
+        0000a504 , 04002222 , 04002222 , 04000002 , 04000002 ,
+        0000a508 , 09002421 , 09002421 , 08000004 , 08000004 ,
+        0000a50c , 0d002621 , 0d002621 , 0b000200 , 0b000200 ,
+        0000a510 , 13004620 , 13004620 , 0f000202 , 0f000202 ,
+        0000a514 , 19004a20 , 19004a20 , 11000400 , 11000400 ,
+        0000a518 , 1d004e20 , 1d004e20 , 15000402 , 15000402 ,
+        0000a51c , 21005420 , 21005420 , 19000404 , 19000404 ,
+        0000a520 , 26005e20 , 26005e20 , 1b000603 , 1b000603 ,
+        0000a524 , 2b005e40 , 2b005e40 , 1f000a02 , 1f000a02 ,
+        0000a528 , 2f005e42 , 2f005e42 , 23000a04 , 23000a04 ,
+        0000a52c , 33005e44 , 33005e44 , 26000a20 , 26000a20 ,
+        0000a530 , 38005e65 , 38005e65 , 2a000e20 , 2a000e20 ,
+        0000a534 , 3c005e69 , 3c005e69 , 2e000e22 , 2e000e22 ,
+        0000a538 , 40005e6b , 40005e6b , 31000e24 , 31000e24 ,
+        0000a53c , 44005e6d , 44005e6d , 34001640 , 34001640 ,
+        0000a540 , 49005e72 , 49005e72 , 38001660 , 38001660 ,
+        0000a544 , 4e005eb2 , 4e005eb2 , 3b001861 , 3b001861 ,
+        0000a548 , 53005f12 , 53005f12 , 3e001a81 , 3e001a81 ,
+        0000a54c , 59025eb2 , 59025eb2 , 42001a83 , 42001a83 ,
+        0000a550 , 5e025f12 , 5e025f12 , 44001c84 , 44001c84 ,
+        0000a554 , 61027f12 , 61027f12 , 48001ce3 , 48001ce3 ,
+        0000a558 , 6702bf12 , 6702bf12 , 4c001ce5 , 4c001ce5 ,
+        0000a55c , 6b02bf14 , 6b02bf14 , 50001ce9 , 50001ce9 ,
+        0000a560 , 6f02bf16 , 6f02bf16 , 54001ceb , 54001ceb ,
+        0000a564 , 6f02bf16 , 6f02bf16 , 56001eec , 56001eec ,
+        0000a568 , 6f02bf16 , 6f02bf16 , 56001eec , 56001eec ,
+        0000a56c , 6f02bf16 , 6f02bf16 , 56001eec , 56001eec ,
+        0000a570 , 6f02bf16 , 6f02bf16 , 56001eec , 56001eec ,
+        0000a574 , 6f02bf16 , 6f02bf16 , 56001eec , 56001eec ,
+        0000a578 , 6f02bf16 , 6f02bf16 , 56001eec , 56001eec ,
+        0000a57c , 6f02bf16 , 6f02bf16 , 56001eec , 56001eec ,
+        0000a580 , 00802220 , 00802220 , 00800000 , 00800000 ,
+        0000a584 , 04802222 , 04802222 , 04800002 , 04800002 ,
+        0000a588 , 09802421 , 09802421 , 08800004 , 08800004 ,
+        0000a58c , 0d802621 , 0d802621 , 0b800200 , 0b800200 ,
+        0000a590 , 13804620 , 13804620 , 0f800202 , 0f800202 ,
+        0000a594 , 19804a20 , 19804a20 , 11800400 , 11800400 ,
+        0000a598 , 1d804e20 , 1d804e20 , 15800402 , 15800402 ,
+        0000a59c , 21805420 , 21805420 , 19800404 , 19800404 ,
+        0000a5a0 , 26805e20 , 26805e20 , 1b800603 , 1b800603 ,
+        0000a5a4 , 2b805e40 , 2b805e40 , 1f800a02 , 1f800a02 ,
+        0000a5a8 , 2f805e42 , 2f805e42 , 23800a04 , 23800a04 ,
+        0000a5ac , 33805e44 , 33805e44 , 26800a20 , 26800a20 ,
+        0000a5b0 , 38805e65 , 38805e65 , 2a800e20 , 2a800e20 ,
+        0000a5b4 , 3c805e69 , 3c805e69 , 2e800e22 , 2e800e22 ,
+        0000a5b8 , 40805e6b , 40805e6b , 31800e24 , 31800e24 ,
+        0000a5bc , 44805e6d , 44805e6d , 34801640 , 34801640 ,
+        0000a5c0 , 49805e72 , 49805e72 , 38801660 , 38801660 ,
+        0000a5c4 , 4e805eb2 , 4e805eb2 , 3b801861 , 3b801861 ,
+        0000a5c8 , 53805f12 , 53805f12 , 3e801a81 , 3e801a81 ,
+        0000a5cc , 59825eb2 , 59825eb2 , 42801a83 , 42801a83 ,
+        0000a5d0 , 5e825f12 , 5e825f12 , 44801c84 , 44801c84 ,
+        0000a5d4 , 61827f12 , 61827f12 , 48801ce3 , 48801ce3 ,
+        0000a5d8 , 6782bf12 , 6782bf12 , 4c801ce5 , 4c801ce5 ,
+        0000a5dc , 6b82bf14 , 6b82bf14 , 50801ce9 , 50801ce9 ,
+        0000a5e0 , 6f82bf16 , 6f82bf16 , 54801ceb , 54801ceb ,
+        0000a5e4 , 6f82bf16 , 6f82bf16 , 56801eec , 56801eec ,
+        0000a5e8 , 6f82bf16 , 6f82bf16 , 56801eec , 56801eec ,
+        0000a5ec , 6f82bf16 , 6f82bf16 , 56801eec , 56801eec ,
+        0000a5f0 , 6f82bf16 , 6f82bf16 , 56801eec , 56801eec ,
+        0000a5f4 , 6f82bf16 , 6f82bf16 , 56801eec , 56801eec ,
+        0000a5f8 , 6f82bf16 , 6f82bf16 , 56801eec , 56801eec ,
+        0000a5fc , 6f82bf16 , 6f82bf16 , 56801eec , 56801eec ,
+        0000a600 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a604 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a608 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a60c , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000a610 , 00804000 , 00804000 , 00000000 , 00000000 ,
+        0000a614 , 00804201 , 00804201 , 01404000 , 01404000 ,
+        0000a618 , 0280c802 , 0280c802 , 01404501 , 01404501 ,
+        0000a61c , 0280ca03 , 0280ca03 , 02008501 , 02008501 ,
+        0000a620 , 04c15104 , 04c15104 , 0280ca03 , 0280ca03 ,
+        0000a624 , 04c15305 , 04c15305 , 03010c04 , 03010c04 ,
+        0000a628 , 04c15305 , 04c15305 , 04014c04 , 04014c04 ,
+        0000a62c , 04c15305 , 04c15305 , 04015005 , 04015005 ,
+        0000a630 , 04c15305 , 04c15305 , 04015005 , 04015005 ,
+        0000a634 , 04c15305 , 04c15305 , 04015005 , 04015005 ,
+        0000a638 , 04c15305 , 04c15305 , 04015005 , 04015005 ,
+        0000a63c , 04c15305 , 04c15305 , 04015005 , 04015005 ,
+        0000b2dc , 01feee00 , 01feee00 , 00637800 , 00637800 ,
+        0000b2e0 , 0000f000 , 0000f000 , 03838000 , 03838000 ,
+        0000b2e4 , 01ff0000 , 01ff0000 , 03fc0000 , 03fc0000 ,
+        0000b2e8 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        0000c2dc , 01feee00 , 01feee00 , 00637800 , 00637800 ,
+        0000c2e0 , 0000f000 , 0000f000 , 03838000 , 03838000 ,
+        0000c2e4 , 01ff0000 , 01ff0000 , 03fc0000 , 03fc0000 ,
+        0000c2e8 , 00000000 , 00000000 , 00000000 , 00000000 ,
+        00016044 , 056db2e4 , 056db2e4 , 056db2e4 , 056db2e4 ,
+        00016048 , 8e480001 , 8e480001 , 8e480001 , 8e480001 ,
+        00016068 , 6db6db6c , 6db6db6c , 6db6db6c , 6db6db6c ,
+        00016444 , 056db2e4 , 056db2e4 , 056db2e4 , 056db2e4 ,
+        00016448 , 8e480001 , 8e480001 , 8e480001 , 8e480001 ,
+        00016468 , 6db6db6c , 6db6db6c , 6db6db6c , 6db6db6c ,
+        00016844 , 056db2e4 , 056db2e4 , 056db2e4 , 056db2e4 ,
+        00016848 , 8e480001 , 8e480001 , 8e480001 , 8e480001 ,
+        00016868 , 6db6db6c , 6db6db6c , 6db6db6c , 6db6db6c ,
+here swap - 5 /n* / constant tx-gain-hi-#row
+
+array-tx-gain-lowest value array-tx-gain
+tx-gain-lowest-#row  value tx-gain-#row
+
+create array-rx-gain-common
+here
+        \ Addr     allmodes 
+        0000a000 , 00010000 ,
+        0000a004 , 00030002 ,
+        0000a008 , 00050004 ,
+        0000a00c , 00810080 ,
+        0000a010 , 00830082 ,
+        0000a014 , 01810180 ,
+        0000a018 , 01830182 ,
+        0000a01c , 01850184 ,
+        0000a020 , 01890188 ,
+        0000a024 , 018b018a ,
+        0000a028 , 018d018c ,
+        0000a02c , 01910190 ,
+        0000a030 , 01930192 ,
+        0000a034 , 01950194 ,
+        0000a038 , 038a0196 ,
+        0000a03c , 038c038b ,
+        0000a040 , 0390038d ,
+        0000a044 , 03920391 ,
+        0000a048 , 03940393 ,
+        0000a04c , 03960395 ,
+        0000a050 , 00000000 ,
+        0000a054 , 00000000 ,
+        0000a058 , 00000000 ,
+        0000a05c , 00000000 ,
+        0000a060 , 00000000 ,
+        0000a064 , 00000000 ,
+        0000a068 , 00000000 ,
+        0000a06c , 00000000 ,
+        0000a070 , 00000000 ,
+        0000a074 , 00000000 ,
+        0000a078 , 00000000 ,
+        0000a07c , 00000000 ,
+        0000a080 , 22222229 ,
+        0000a084 , 1d1d1d1d ,
+        0000a088 , 1d1d1d1d ,
+        0000a08c , 1d1d1d1d ,
+        0000a090 , 171d1d1d ,
+        0000a094 , 11111717 ,
+        0000a098 , 00030311 ,
+        0000a09c , 00000000 ,
+        0000a0a0 , 00000000 ,
+        0000a0a4 , 00000000 ,
+        0000a0a8 , 00000000 ,
+        0000a0ac , 00000000 ,
+        0000a0b0 , 00000000 ,
+        0000a0b4 , 00000000 ,
+        0000a0b8 , 00000000 ,
+        0000a0bc , 00000000 ,
+        0000a0c0 , 001f0000 ,
+        0000a0c4 , 01000101 ,
+        0000a0c8 , 011e011f ,
+        0000a0cc , 011c011d ,
+        0000a0d0 , 02030204 ,
+        0000a0d4 , 02010202 ,
+        0000a0d8 , 021f0200 ,
+        0000a0dc , 0302021e ,
+        0000a0e0 , 03000301 ,
+        0000a0e4 , 031e031f ,
+        0000a0e8 , 0402031d ,
+        0000a0ec , 04000401 ,
+        0000a0f0 , 041e041f ,
+        0000a0f4 , 0502041d ,
+        0000a0f8 , 05000501 ,
+        0000a0fc , 051e051f ,
+        0000a100 , 06010602 ,
+        0000a104 , 061f0600 ,
+        0000a108 , 061d061e ,
+        0000a10c , 07020703 ,
+        0000a110 , 07000701 ,
+        0000a114 , 00000000 ,
+        0000a118 , 00000000 ,
+        0000a11c , 00000000 ,
+        0000a120 , 00000000 ,
+        0000a124 , 00000000 ,
+        0000a128 , 00000000 ,
+        0000a12c , 00000000 ,
+        0000a130 , 00000000 ,
+        0000a134 , 00000000 ,
+        0000a138 , 00000000 ,
+        0000a13c , 00000000 ,
+        0000a140 , 001f0000 ,
+        0000a144 , 01000101 ,
+        0000a148 , 011e011f ,
+        0000a14c , 011c011d ,
+        0000a150 , 02030204 ,
+        0000a154 , 02010202 ,
+        0000a158 , 021f0200 ,
+        0000a15c , 0302021e ,
+        0000a160 , 03000301 ,
+        0000a164 , 031e031f ,
+        0000a168 , 0402031d ,
+        0000a16c , 04000401 ,
+        0000a170 , 041e041f ,
+        0000a174 , 0502041d ,
+        0000a178 , 05000501 ,
+        0000a17c , 051e051f ,
+        0000a180 , 06010602 ,
+        0000a184 , 061f0600 ,
+        0000a188 , 061d061e ,
+        0000a18c , 07020703 ,
+        0000a190 , 07000701 ,
+        0000a194 , 00000000 ,
+        0000a198 , 00000000 ,
+        0000a19c , 00000000 ,
+        0000a1a0 , 00000000 ,
+        0000a1a4 , 00000000 ,
+        0000a1a8 , 00000000 ,
+        0000a1ac , 00000000 ,
+        0000a1b0 , 00000000 ,
+        0000a1b4 , 00000000 ,
+        0000a1b8 , 00000000 ,
+        0000a1bc , 00000000 ,
+        0000a1c0 , 00000000 ,
+        0000a1c4 , 00000000 ,
+        0000a1c8 , 00000000 ,
+        0000a1cc , 00000000 ,
+        0000a1d0 , 00000000 ,
+        0000a1d4 , 00000000 ,
+        0000a1d8 , 00000000 ,
+        0000a1dc , 00000000 ,
+        0000a1e0 , 00000000 ,
+        0000a1e4 , 00000000 ,
+        0000a1e8 , 00000000 ,
+        0000a1ec , 00000000 ,
+        0000a1f0 , 00000396 ,
+        0000a1f4 , 00000396 ,
+        0000a1f8 , 00000396 ,
+        0000a1fc , 00000196 ,
+        0000b000 , 00010000 ,
+        0000b004 , 00030002 ,
+        0000b008 , 00050004 ,
+        0000b00c , 00810080 ,
+        0000b010 , 00830082 ,
+        0000b014 , 01810180 ,
+        0000b018 , 01830182 ,
+        0000b01c , 01850184 ,
+        0000b020 , 02810280 ,
+        0000b024 , 02830282 ,
+        0000b028 , 02850284 ,
+        0000b02c , 02890288 ,
+        0000b030 , 028b028a ,
+        0000b034 , 0388028c ,
+        0000b038 , 038a0389 ,
+        0000b03c , 038c038b ,
+        0000b040 , 0390038d ,
+        0000b044 , 03920391 ,
+        0000b048 , 03940393 ,
+        0000b04c , 03960395 ,
+        0000b050 , 00000000 ,
+        0000b054 , 00000000 ,
+        0000b058 , 00000000 ,
+        0000b05c , 00000000 ,
+        0000b060 , 00000000 ,
+        0000b064 , 00000000 ,
+        0000b068 , 00000000 ,
+        0000b06c , 00000000 ,
+        0000b070 , 00000000 ,
+        0000b074 , 00000000 ,
+        0000b078 , 00000000 ,
+        0000b07c , 00000000 ,
+        0000b080 , 2a2d2f32 ,
+        0000b084 , 21232328 ,
+        0000b088 , 19191c1e ,
+        0000b08c , 12141417 ,
+        0000b090 , 07070e0e ,
+        0000b094 , 03030305 ,
+        0000b098 , 00000003 ,
+        0000b09c , 00000000 ,
+        0000b0a0 , 00000000 ,
+        0000b0a4 , 00000000 ,
+        0000b0a8 , 00000000 ,
+        0000b0ac , 00000000 ,
+        0000b0b0 , 00000000 ,
+        0000b0b4 , 00000000 ,
+        0000b0b8 , 00000000 ,
+        0000b0bc , 00000000 ,
+        0000b0c0 , 003f0020 ,
+        0000b0c4 , 00400041 ,
+        0000b0c8 , 0140005f ,
+        0000b0cc , 0160015f ,
+        0000b0d0 , 017e017f ,
+        0000b0d4 , 02410242 ,
+        0000b0d8 , 025f0240 ,
+        0000b0dc , 027f0260 ,
+        0000b0e0 , 0341027e ,
+        0000b0e4 , 035f0340 ,
+        0000b0e8 , 037f0360 ,
+        0000b0ec , 04400441 ,
+        0000b0f0 , 0460045f ,
+        0000b0f4 , 0541047f ,
+        0000b0f8 , 055f0540 ,
+        0000b0fc , 057f0560 ,
+        0000b100 , 06400641 ,
+        0000b104 , 0660065f ,
+        0000b108 , 067e067f ,
+        0000b10c , 07410742 ,
+        0000b110 , 075f0740 ,
+        0000b114 , 077f0760 ,
+        0000b118 , 07800781 ,
+        0000b11c , 07a0079f ,
+        0000b120 , 07c107bf ,
+        0000b124 , 000007c0 ,
+        0000b128 , 00000000 ,
+        0000b12c , 00000000 ,
+        0000b130 , 00000000 ,
+        0000b134 , 00000000 ,
+        0000b138 , 00000000 ,
+        0000b13c , 00000000 ,
+        0000b140 , 003f0020 ,
+        0000b144 , 00400041 ,
+        0000b148 , 0140005f ,
+        0000b14c , 0160015f ,
+        0000b150 , 017e017f ,
+        0000b154 , 02410242 ,
+        0000b158 , 025f0240 ,
+        0000b15c , 027f0260 ,
+        0000b160 , 0341027e ,
+        0000b164 , 035f0340 ,
+        0000b168 , 037f0360 ,
+        0000b16c , 04400441 ,
+        0000b170 , 0460045f ,
+        0000b174 , 0541047f ,
+        0000b178 , 055f0540 ,
+        0000b17c , 057f0560 ,
+        0000b180 , 06400641 ,
+        0000b184 , 0660065f ,
+        0000b188 , 067e067f ,
+        0000b18c , 07410742 ,
+        0000b190 , 075f0740 ,
+        0000b194 , 077f0760 ,
+        0000b198 , 07800781 ,
+        0000b19c , 07a0079f ,
+        0000b1a0 , 07c107bf ,
+        0000b1a4 , 000007c0 ,
+        0000b1a8 , 00000000 ,
+        0000b1ac , 00000000 ,
+        0000b1b0 , 00000000 ,
+        0000b1b4 , 00000000 ,
+        0000b1b8 , 00000000 ,
+        0000b1bc , 00000000 ,
+        0000b1c0 , 00000000 ,
+        0000b1c4 , 00000000 ,
+        0000b1c8 , 00000000 ,
+        0000b1cc , 00000000 ,
+        0000b1d0 , 00000000 ,
+        0000b1d4 , 00000000 ,
+        0000b1d8 , 00000000 ,
+        0000b1dc , 00000000 ,
+        0000b1e0 , 00000000 ,
+        0000b1e4 , 00000000 ,
+        0000b1e8 , 00000000 ,
+        0000b1ec , 00000000 ,
+        0000b1f0 , 00000396 ,
+        0000b1f4 , 00000396 ,
+        0000b1f8 , 00000396 ,
+        0000b1fc , 00000196 ,
+here swap - 2 /n* / constant rx-gain-common-#row
+
+create array-rx-gain-wo-xlna
+here
+        \ Addr      allmodes 
+        0000a000 , 00010000 ,
+        0000a004 , 00030002 ,
+        0000a008 , 00050004 ,
+        0000a00c , 00810080 ,
+        0000a010 , 00830082 ,
+        0000a014 , 01810180 ,
+        0000a018 , 01830182 ,
+        0000a01c , 01850184 ,
+        0000a020 , 01890188 ,
+        0000a024 , 018b018a ,
+        0000a028 , 018d018c ,
+        0000a02c , 03820190 ,
+        0000a030 , 03840383 ,
+        0000a034 , 03880385 ,
+        0000a038 , 038a0389 ,
+        0000a03c , 038c038b ,
+        0000a040 , 0390038d ,
+        0000a044 , 03920391 ,
+        0000a048 , 03940393 ,
+        0000a04c , 03960395 ,
+        0000a050 , 00000000 ,
+        0000a054 , 00000000 ,
+        0000a058 , 00000000 ,
+        0000a05c , 00000000 ,
+        0000a060 , 00000000 ,
+        0000a064 , 00000000 ,
+        0000a068 , 00000000 ,
+        0000a06c , 00000000 ,
+        0000a070 , 00000000 ,
+        0000a074 , 00000000 ,
+        0000a078 , 00000000 ,
+        0000a07c , 00000000 ,
+        0000a080 , 29292929 ,
+        0000a084 , 29292929 ,
+        0000a088 , 29292929 ,
+        0000a08c , 29292929 ,
+        0000a090 , 22292929 ,
+        0000a094 , 1d1d2222 ,
+        0000a098 , 0c111117 ,
+        0000a09c , 00030303 ,
+        0000a0a0 , 00000000 ,
+        0000a0a4 , 00000000 ,
+        0000a0a8 , 00000000 ,
+        0000a0ac , 00000000 ,
+        0000a0b0 , 00000000 ,
+        0000a0b4 , 00000000 ,
+        0000a0b8 , 00000000 ,
+        0000a0bc , 00000000 ,
+        0000a0c0 , 001f0000 ,
+        0000a0c4 , 01000101 ,
+        0000a0c8 , 011e011f ,
+        0000a0cc , 011c011d ,
+        0000a0d0 , 02030204 ,
+        0000a0d4 , 02010202 ,
+        0000a0d8 , 021f0200 ,
+        0000a0dc , 0302021e ,
+        0000a0e0 , 03000301 ,
+        0000a0e4 , 031e031f ,
+        0000a0e8 , 0402031d ,
+        0000a0ec , 04000401 ,
+        0000a0f0 , 041e041f ,
+        0000a0f4 , 0502041d ,
+        0000a0f8 , 05000501 ,
+        0000a0fc , 051e051f ,
+        0000a100 , 06010602 ,
+        0000a104 , 061f0600 ,
+        0000a108 , 061d061e ,
+        0000a10c , 07020703 ,
+        0000a110 , 07000701 ,
+        0000a114 , 00000000 ,
+        0000a118 , 00000000 ,
+        0000a11c , 00000000 ,
+        0000a120 , 00000000 ,
+        0000a124 , 00000000 ,
+        0000a128 , 00000000 ,
+        0000a12c , 00000000 ,
+        0000a130 , 00000000 ,
+        0000a134 , 00000000 ,
+        0000a138 , 00000000 ,
+        0000a13c , 00000000 ,
+        0000a140 , 001f0000 ,
+        0000a144 , 01000101 ,
+        0000a148 , 011e011f ,
+        0000a14c , 011c011d ,
+        0000a150 , 02030204 ,
+        0000a154 , 02010202 ,
+        0000a158 , 021f0200 ,
+        0000a15c , 0302021e ,
+        0000a160 , 03000301 ,
+        0000a164 , 031e031f ,
+        0000a168 , 0402031d ,
+        0000a16c , 04000401 ,
+        0000a170 , 041e041f ,
+        0000a174 , 0502041d ,
+        0000a178 , 05000501 ,
+        0000a17c , 051e051f ,
+        0000a180 , 06010602 ,
+        0000a184 , 061f0600 ,
+        0000a188 , 061d061e ,
+        0000a18c , 07020703 ,
+        0000a190 , 07000701 ,
+        0000a194 , 00000000 ,
+        0000a198 , 00000000 ,
+        0000a19c , 00000000 ,
+        0000a1a0 , 00000000 ,
+        0000a1a4 , 00000000 ,
+        0000a1a8 , 00000000 ,
+        0000a1ac , 00000000 ,
+        0000a1b0 , 00000000 ,
+        0000a1b4 , 00000000 ,
+        0000a1b8 , 00000000 ,
+        0000a1bc , 00000000 ,
+        0000a1c0 , 00000000 ,
+        0000a1c4 , 00000000 ,
+        0000a1c8 , 00000000 ,
+        0000a1cc , 00000000 ,
+        0000a1d0 , 00000000 ,
+        0000a1d4 , 00000000 ,
+        0000a1d8 , 00000000 ,
+        0000a1dc , 00000000 ,
+        0000a1e0 , 00000000 ,
+        0000a1e4 , 00000000 ,
+        0000a1e8 , 00000000 ,
+        0000a1ec , 00000000 ,
+        0000a1f0 , 00000396 ,
+        0000a1f4 , 00000396 ,
+        0000a1f8 , 00000396 ,
+        0000a1fc , 00000196 ,
+        0000b000 , 00010000 ,
+        0000b004 , 00030002 ,
+        0000b008 , 00050004 ,
+        0000b00c , 00810080 ,
+        0000b010 , 00830082 ,
+        0000b014 , 01810180 ,
+        0000b018 , 01830182 ,
+        0000b01c , 01850184 ,
+        0000b020 , 02810280 ,
+        0000b024 , 02830282 ,
+        0000b028 , 02850284 ,
+        0000b02c , 02890288 ,
+        0000b030 , 028b028a ,
+        0000b034 , 0388028c ,
+        0000b038 , 038a0389 ,
+        0000b03c , 038c038b ,
+        0000b040 , 0390038d ,
+        0000b044 , 03920391 ,
+        0000b048 , 03940393 ,
+        0000b04c , 03960395 ,
+        0000b050 , 00000000 ,
+        0000b054 , 00000000 ,
+        0000b058 , 00000000 ,
+        0000b05c , 00000000 ,
+        0000b060 , 00000000 ,
+        0000b064 , 00000000 ,
+        0000b068 , 00000000 ,
+        0000b06c , 00000000 ,
+        0000b070 , 00000000 ,
+        0000b074 , 00000000 ,
+        0000b078 , 00000000 ,
+        0000b07c , 00000000 ,
+        0000b080 , 32323232 ,
+        0000b084 , 2f2f3232 ,
+        0000b088 , 23282a2d ,
+        0000b08c , 1c1e2123 ,
+        0000b090 , 14171919 ,
+        0000b094 , 0e0e1214 ,
+        0000b098 , 03050707 ,
+        0000b09c , 00030303 ,
+        0000b0a0 , 00000000 ,
+        0000b0a4 , 00000000 ,
+        0000b0a8 , 00000000 ,
+        0000b0ac , 00000000 ,
+        0000b0b0 , 00000000 ,
+        0000b0b4 , 00000000 ,
+        0000b0b8 , 00000000 ,
+        0000b0bc , 00000000 ,
+        0000b0c0 , 003f0020 ,
+        0000b0c4 , 00400041 ,
+        0000b0c8 , 0140005f ,
+        0000b0cc , 0160015f ,
+        0000b0d0 , 017e017f ,
+        0000b0d4 , 02410242 ,
+        0000b0d8 , 025f0240 ,
+        0000b0dc , 027f0260 ,
+        0000b0e0 , 0341027e ,
+        0000b0e4 , 035f0340 ,
+        0000b0e8 , 037f0360 ,
+        0000b0ec , 04400441 ,
+        0000b0f0 , 0460045f ,
+        0000b0f4 , 0541047f ,
+        0000b0f8 , 055f0540 ,
+        0000b0fc , 057f0560 ,
+        0000b100 , 06400641 ,
+        0000b104 , 0660065f ,
+        0000b108 , 067e067f ,
+        0000b10c , 07410742 ,
+        0000b110 , 075f0740 ,
+        0000b114 , 077f0760 ,
+        0000b118 , 07800781 ,
+        0000b11c , 07a0079f ,
+        0000b120 , 07c107bf ,
+        0000b124 , 000007c0 ,
+        0000b128 , 00000000 ,
+        0000b12c , 00000000 ,
+        0000b130 , 00000000 ,
+        0000b134 , 00000000 ,
+        0000b138 , 00000000 ,
+        0000b13c , 00000000 ,
+        0000b140 , 003f0020 ,
+        0000b144 , 00400041 ,
+        0000b148 , 0140005f ,
+        0000b14c , 0160015f ,
+        0000b150 , 017e017f ,
+        0000b154 , 02410242 ,
+        0000b158 , 025f0240 ,
+        0000b15c , 027f0260 ,
+        0000b160 , 0341027e ,
+        0000b164 , 035f0340 ,
+        0000b168 , 037f0360 ,
+        0000b16c , 04400441 ,
+        0000b170 , 0460045f ,
+        0000b174 , 0541047f ,
+        0000b178 , 055f0540 ,
+        0000b17c , 057f0560 ,
+        0000b180 , 06400641 ,
+        0000b184 , 0660065f ,
+        0000b188 , 067e067f ,
+        0000b18c , 07410742 ,
+        0000b190 , 075f0740 ,
+        0000b194 , 077f0760 ,
+        0000b198 , 07800781 ,
+        0000b19c , 07a0079f ,
+        0000b1a0 , 07c107bf ,
+        0000b1a4 , 000007c0 ,
+        0000b1a8 , 00000000 ,
+        0000b1ac , 00000000 ,
+        0000b1b0 , 00000000 ,
+        0000b1b4 , 00000000 ,
+        0000b1b8 , 00000000 ,
+        0000b1bc , 00000000 ,
+        0000b1c0 , 00000000 ,
+        0000b1c4 , 00000000 ,
+        0000b1c8 , 00000000 ,
+        0000b1cc , 00000000 ,
+        0000b1d0 , 00000000 ,
+        0000b1d4 , 00000000 ,
+        0000b1d8 , 00000000 ,
+        0000b1dc , 00000000 ,
+        0000b1e0 , 00000000 ,
+        0000b1e4 , 00000000 ,
+        0000b1e8 , 00000000 ,
+        0000b1ec , 00000000 ,
+        0000b1f0 , 00000396 ,
+        0000b1f4 , 00000396 ,
+        0000b1f8 , 00000396 ,
+        0000b1fc , 00000196 ,
+here swap - 2 /n* / constant rx-gain-wo-xlna-#row
+
+array-rx-gain-common value array-rx-gain
+rx-gain-common-#row  value rx-gain-#row
+
+create array-fast-clk
+here
+        \ Addr     5G_HT20    5G_HT40 
+        00001030 , 00000268 , 000004d0 ,
+        00001070 , 0000018c , 00000318 ,
+        000010b0 , 00000fd0 , 00001fa0 ,
+        00008014 , 044c044c , 08980898 ,
+        0000801c , 148ec02b , 148ec057 ,
+        00008318 , 000044c0 , 00008980 ,
+        00009e00 , 0372131c , 0372131c ,
+        0000a230 , 0000000b , 00000016 ,
+        0000a254 , 00000898 , 00001130 ,
+here swap - 2 /n* / constant fast-clk-#row
+
+create array-pcie-serdes
+here
+        \ Addr     allmodes 
+        00004040 , 0821265e ,
+        00004040 , 0008003b ,
+        00004044 , 00000000 ,
+here swap - 2 /n* / constant pcie-serdes-#row
+
+create array-fast-clock
+here
+        \ Addr      5G_HT20     5G_HT40 
+        00001030 , 00000268 , 000004d0 ,
+        00001070 , 0000018c , 00000318 ,
+        000010b0 , 00000fd0 , 00001fa0 ,
+        00008014 , 044c044c , 08980898 ,
+        0000801c , 148ec02b , 148ec057 ,
+        00008318 , 000044c0 , 00008980 ,
+        00009e00 , 0372131c , 0372131c ,
+        0000a230 , 0000000b , 00000016 ,
+        0000a254 , 00000898 , 00001130 ,
+here swap - 3 /n* / constant fast-clock-#row
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/init.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/init.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,839 @@
+purpose: ATH9K initialization
+\ See license at end of file
+
+headers
+hex
+
+0 value rfkill-gpio
+0 value rfkill-polarity
+
+\ cfg-output type definitions
+0 constant GPIO_OUTPUT_MUX_AS_OUTPUT 
+1 constant GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED
+2 constant GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED    
+3 constant GPIO_OUTPUT_MUX_AS_TX_FRAME          
+4 constant GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL 
+5 constant GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED   
+6 constant GPIO_OUTPUT_MUX_AS_MAC_POWER_LED     
+
+: cfg-gpio-input  ( gpio -- )  0 1 rot 2* << 4050 reg@!  ;
+: cfg-output  ( gpio type -- )
+   over 6 mod 5 * tuck << 1f rot <<  ( gpio type' mask )
+   2 pick d# 11 >  if  4070  else  2 pick 5 >  if  4064  else  4060  then  then  reg@!
+   3 swap 2* << dup 4050 reg@!       ( )
+;
+: set-gpio  ( value gpio -- )  swap 1 and over << 1 rot << 4048 reg@!  ;
+: get-gpio  ( gpio -- value )  404c reg@  1 rot << and  ;
+
+\ bt hardware settings
+0 value bt-scheme
+0 value bt-wlanactive-gpio
+0 value bt-active-gpio
+0 value bt-priority-gpio
+0 value bt-coex-mode      \ Register setting for AR_BT_COEX_MODE
+0 value bt-coex-weights   \ Register setting for AR_BT_COEX_WEIGHT
+0 value bt-coex-mode2     \ Register setting for AR_BT_COEX_MODE2
+
+\ bt-scheme
+0 constant BTCOEX_CFG_NONE,
+1 constant BTCOEX_CFG_2WIRE
+2 constant BTCOEX_CFG_3WIRE
+
+\ bt-mode definitions
+0 constant BT_COEX_MODE_LEGACY        \ legacy rx_clear mode
+1 constant BT_COEX_MODE_UNSLOTTED     \ untimed/unslotted mode
+2 constant BT_COEX_MODE_SLOTTED       \ slotted mode
+3 constant BT_COEX_MODE_DISALBED      \ coexistence disabled
+
+\ bt configuration
+BT_COEX_MODE_SLOTTED value bt-mode
+0 value bt-time-extend
+true value bt-txstate-extend?
+true value bt-txframe-extend?
+true value bt-quiet-collision?
+true value bt-hold-rx-clear?
+true value bt-rxclear-polarity?
+2 value bt-priority-time
+5 value bt-first-slot-time
+
+: init-btcoex-hw  ( qnum -- )
+   d# 13 << 2.1300 or
+   bt-mode d# 10 << or bt-priority-time d# 18 << or
+   bt-first-slot-time d# 24 << or  to  bt-coex-mode
+
+   1.0032 to bt-coex-mode2
+; 
+: init-btcoex-2wire  ( -- )
+   1000 100c 405c reg@!                       \ Connect bt_active to baseband
+   bt-active-gpio d# 16 << f.0000 4060 reg@!  \ Input mux bt_active to GPIO
+   bt-active-gpio cfg-gpio-input
+;
+: init-btcoex-3wire  ( -- )
+   1400 dup 405c reg@!   \ Connect bt_priority_async and bt_active_async to baseband
+   bt-active-gpio d# 16 << bt-priority-gpio 8 << or
+   f.0f00 4060 reg@!     \ Input mux for bt_priority_async and bt_active_async to GPIO
+   bt-active-gpio   cfg-gpio-input
+   bt-priority-gpio cfg-gpio-input
+;
+: enable-btcoex-2wire  ( -- )
+   bt-wlanactive-gpio GPIO_OUTPUT_MUX_AS_TX_FRAME cfg-output
+;
+: enable-btcoex-3wire  ( -- )
+   bt-coex-mode    8170 reg!
+   bt-coex-weights 8174 reg!
+   bt-coex-mode2   817c reg!
+   2.0000 dup      80fc reg@!
+   0      10.0000  8120 reg@!
+   bt-wlanactive-gpio GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL cfg-output
+;
+
+: enable-btcoex  ( -- )
+   bt-scheme BTCOEX_CFG_2WIRE =  if  enable-btcoex-2wire  then
+   bt-scheme BTCOEX_CFG_3WIRE =  if  enable-btcoex-3wire  then
+   2 bt-active-gpio 2* <<  3 bt-active-gpio 2* << 4090 reg@!
+;
+
+: disable-btcoex  ( -- )
+   0 bt-wlanactive-gpio set-gpio
+   bt-wlanactive-gpio GPIO_OUTPUT_MUX_AS_OUTPUT cfg-output
+   bt-scheme BTCOEX_CFG_3WIRE =  if
+      1c00  8170 reg!
+      0 8174 reg!
+      0 817c reg!
+   then
+;
+
+: set-clockrate  ( -- )
+   curchan 0=  if  CLOCK_RATE_CCK
+   else
+   curchan >ch-band @ BAND_2GHZ =  if  CLOCK_RATE_2GHZ_OFDM
+   else
+   hw-caps HW_CAP_FASTCLOCK and  if  CLOCK_FAST_RATE_5GHZ_OFDM
+   else  CLOCK_RATE_5GHZ_OFDM
+   then  then  then
+
+   conf-is-ht40?  if  2*  then  to clockrate
+;
+
+: mac>clks  ( us -- clks )  clockrate *  ;
+: flip-bits  ( val n -- val' )  0 swap  0  do  1 << over i >> 1 and or  loop  nip  ;
+
+: get-ch-edges  ( flag -- false | lo hi true )
+   dup CH_5GHZ and  if  drop d# 4920  d# 6100  true  exit  then
+       CH_2GHZ and  if  d# 2312  d# 2372  true  exit  then
+   false
+;
+
+: get-nic-rev  ( -- )  \ ath9k_hw_read_revisions
+   \ macVersion and macRev
+   4020 reg@ dup h# fffc.0000 and d# 12 >> to macVersion
+   h# f00 and 8 >> to macRev
+   macVersion h# 1c0 =  macRev 2 >=  and  not  if
+      ." WARNING: driver may not support this version of Atheros chip"  cr
+   then
+;
+
+: roundup/  ( x y -- x/y )  /mod swap  if  1+  then  ;
+: compute-txtime  ( kbps framelen shortpre? phy -- txtime )
+   3 pick 0=  if  4drop 0 exit  then
+   case
+      WLAN_RC_PHY_CCK  of                 ( kbps framelen shortpre? )
+            d# 192 swap  if  1 >>  then   ( kbps framelen phytime )
+            -rot 3 << d# 1000 * swap /    ( phytime frametime )
+            + d# 10 +                     ( txtime )
+         endof
+      WLAN_RC_PHY_OFDM  of                ( kbps framelen shortpre? )
+            drop                          ( kbps framelen )
+            3 << d# 22 + swap             ( numbits kbps )
+            curchan 0=  if                ( numbits kbps )
+               2 << d# 1000 /             ( numbits bits/symbol )
+               roundup/                   ( numsymbols )
+               2 << d# 36 +               ( txtime )
+            else
+            curchan is-quarter-rate?  if  ( numbits kbps )
+               4 << d# 1000 /             ( numbits bits/symbol )
+               roundup/                   ( numsymbols )
+               4 << d# 144 +              ( txtime )
+            else
+            curchan is-half-rate?  if     ( numbits kbps )
+               3 << d# 1000 /             ( numbits bits/symbol )
+               roundup/                   ( numsymbols )
+               3 << d# 72 +               ( txtime )
+            else                          ( numbits kbps )
+               2 << d# 1000 /             ( numbits bits/symbol )
+               roundup/                   ( numsymbols )
+               2 << d# 36 +               ( txtime )
+            then  then  then
+         endof
+      ( otherwise )  3drop 0 swap
+   endcase
+;
+: (test-chip)  ( data reg -- error? )  2dup reg!  reg@ <>  ;
+: test-chip  ( -- error? )
+   8000 reg@                         \ Save register content
+   0 h# 100 0  do  i d# 16 << 8000 (test-chip) or  loop
+   h# 5555.5555 8000 (test-chip) or
+   h# aaaa.aaaa 8000 (test-chip) or
+   h# 6666.6666 8000 (test-chip) or
+   h# 9999.9999 8000 (test-chip) or
+   swap 8000 reg!                    \ Restore register content
+   d# 100 us
+;
+
+: init-defaults  ( -- )
+   regulatory /regulatory erase
+   CTRY_DEFAULT regulatory >reg-country   !
+   d# 63        regulatory >reg-max-power !
+
+   d# 20 to slottime
+;
+
+: init-post  ( -- )
+   init-edata
+   init-ani
+;
+
+\ reset types
+1 constant RESET_WARM
+3 constant RESET_COLD
+
+: WARegVal!  ( -- )  WARegVal 4004 reg!  d# 10 us  ;
+: set-reset  ( reset-type -- )
+   WARegVal!  3 704c reg!
+   4028 reg@ 3000 and  if
+      0 402c reg!
+      100 4000 reg!
+   then
+   ( reset-type )  7000 reg!
+   d# 50 us
+   0 7000 reg!
+   0 3 7000 wait-hw drop
+   0 4000 reg!
+;
+: set-reset-power-on  ( -- )
+   WARegVal!  3 704c reg!
+   0 7040 reg!
+   1 7040 reg!
+   2 f 7044 wait-hw  drop
+   RESET_WARM set-reset
+;
+
+: set-power-awake  ( -- )
+   WARegVal!
+   7044 reg@ f and 1 =  if  set-reset-power-on  then
+   d# 200 0  do
+      1 1 704c reg@!  d# 50 us
+      7044 reg@ f and 2 =  if  leave  then
+   loop
+   0 4.0000 8004 reg@!
+;
+
+: fill-cap-info  ( -- )
+   eeprom >baseEepHeader >r
+   r@ >regDmn0 le-w@  regulatory >reg-cur-rd !
+   r@ >regDmn1 le-w@ 1f or  regulatory >reg-cur-rd-ext !
+   r@ >txrxmask c@ dup f and  to rx-chainmask
+                       4 >>   to tx-chainmask
+   r@ >deviceCap c@
+   f000 and ?dup  if  d# 12 >>  else  d# 128  then  to keymax
+
+[ifdef] CONFIG_RFKILL
+   r@ >rfSilent c@ dup  to rfsilent
+   dup 1 and  if
+      dup 1c and 2 >> to rfkill-gpio
+      dup  2 and 1 >> to rfkill-polarity
+      hw-caps HW_CAP_RFSILENT or to hw-caps
+   then  drop
+[then]
+
+   regulatory >reg-cur-rd-ext @ 2 and  if  b80  else  880  then  to reg-cap
+   6 to bt-active-gpio
+   5 to bt-wlanactive-gpio
+   BTCOEX_CFG_2WIRE to bt-scheme
+
+   40d8 reg@ to ent-mode
+   r> >miscConfiguration c@ 8 and  if  hw-caps HW_CAP_APM or to hw-caps then
+   tx-chainmask get-streams to max-txchains
+;
+
+: init-hw  ( -- )
+   get-nic-rev
+   4004 reg@ 2.4000 or to WARegVal
+   set-reset-power-on
+   init-defaults
+   set-power-awake
+   9818 reg@ to phyRev
+   0 config-pci-powersave
+   init-post
+   init-mode-gain-tables
+   fill-cap-info
+;
+
+: init-qos  ( -- )
+   0001.00aa 8118 reg!
+   0000.3210 811c reg!
+   0000.0052 8108 reg!
+   0000.00ff 81ec reg!
+   8200 81f0  do  ffff.ffff i reg!  4 +loop
+;
+
+: init-pll  ( ch -- )
+   compute-pll-control  7014 reg!
+   d# 100 us
+   2 7048 reg!
+;
+
+: init-intr-masks  ( -- )
+   8180.0965  ap-mode?  if  1000 or  then  a0 reg!
+   80.0000 ac reg!
+   0 40d4 reg!  0 40c8 reg!  0 40c4 reg!  0  40cc reg!
+;
+
+: set-slottime     ( us -- )  mac>clks ffff min  1070 reg!  ;
+: set-ack-timeout  ( us -- )  mac>clks 3fff min  3fff 8014 reg@!  ;
+: set-cts-timeout  ( us -- )  mac>clks 3fff min  d# 16 << 3fff.0000 8014 reg@!  ;
+
+: init-global-settings  ( -- )
+   misc-mode ?dup  if  dup 8120 reg@!  then
+
+   curchan ?dup  if
+      >ch-band @ BAND_5GHZ =  if  d# 16  else  d# 10  then
+   else  d# 10  then                   ( sifstime )
+   dup slottime coverage-class 3 * + + ( sifstime acktimeout )
+   curchan ?dup  if
+      >ch-band @ BAND_2GHZ =  if
+          d# 64 + over - slottime -    ( sifstime acktimeout' )
+      then
+   then  nip                           ( acktimeout )
+   slottime set-slottime
+   dup set-ack-timeout
+       set-cts-timeout
+;
+
+defer reset-txstatus-ring   ' noop to reset-txstatus-ring
+: set-dma  ( -- )
+   5 7 30 reg@!        \ MAC DMA read in 128 byte chunks
+   5 7 34 reg@!        \ MAC DMA write in 128 byte chunks
+   200 8114 reg!       \ Setup rx FIFO
+   101 3f0f 18 reg@!   \ Setup rx threshold
+   rx-bufsize rx-status-len - fff and 60 reg!  \ Setup rx bufsize
+   700 8340 reg!       \ Setup usable entries in PCU txbuf
+   reset-txstatus-ring
+;
+
+: set-opmode  ( -- )
+   8004 reg@ fffc.ffff and    ( val )
+   opmode  case
+      IFTYPE_AP          of  1001.0000 or 8004 reg!   0 20 14 reg@!  endof
+      IFTYPE_ADHOC       of  1002.0000 or 8004 reg!  20 20 14 reg@!  endof
+      IFTYPE_MESH_POINT  of  1002.0000 or 8004 reg!  20 20 14 reg@!  endof
+      IFTYPE_STATION     of  1000.0000 or 8004 reg!  endof
+      IFTYPE_MONITOR     of  1000.0000 or 8004 reg!  endof
+   endcase
+;
+
+: reset-chip  ( ch -- )
+   RESET_WARM set-reset
+   dup init-pll
+       set-rfmode
+;
+
+: change-channel  ( ch -- error? )
+   rfbus-req? 0=  if  drop true exit  then
+   dup set-ch-regs
+   dup set-channel
+   set-clockrate
+   dup false set-txpower
+   rfbus-done
+   dup is-ofdm?  over is-ht? or  if  dup set-delta-slope  then
+   spur-mitigate
+   false
+;
+
+: set-bssidmask  ( -- )
+   bssidmask le-l@  80e0 reg!
+   bssidmask 4 + le-w@  80e4 reg!
+;
+: write-associd  ( -- )
+   curbssid le-l@  8008 reg!
+   curbssid 4 + le-w@  curaid 3fff and wljoin  800c reg!
+;
+: reset-bssidmask  ( -- )
+   mac-adr      @ curbssid      @ xor invert            bssidmask      !
+   mac-adr 4 + w@ curbssid 4 + w@ xor invert  ffff and  bssidmask 4 + w!
+   set-bssidmask
+;
+
+defer reset-txqueue    ' noop to reset-txqueue
+
+: reset-hw  ( ch ch-change? -- )
+   tx-chainmask to txchainmask
+   rx-chainmask to rxchainmask
+
+   curchan ?dup  if  get-nf drop   then
+   over >ch-freq @ caldata >cd-ch @ <>
+   2 pick >ch-flags @ CH_CW_INT not and caldata >cd-chFlags @ CH_CW_INT not and <>  or  if
+      caldata /caldata erase
+      over init-nfcal-hist
+   then                         ( ch ch-change? )
+
+   ( ch-change? )  if
+      curchan  if
+         dup >ch-freq @ curchan >ch-freq <>
+         over >ch-flags @ CH_ALL and curchan >ch-flags @ CH_ALL and =  and  if
+            dup change-channel 0=  if
+               curchan load-nf
+ 	       true start-nfcal
+               drop exit
+            then
+         then
+      then
+   then
+
+   1f04 reg@ ff8 and            ( ch led )
+   8058 reg@ 1 max              ( ch led defAnt )
+   8004 reg@ 200.0000 and       ( ch led defAnt macStaId1 )
+
+   mark-phy-inactive
+   false to paprd-table-write-done?
+   3 pick reset-chip
+
+   2.0000 dup 405c reg@!
+   3 pick process-ini
+
+   c7ff.0000 ffff.0000 8060 reg@!   \ Setup MFP options for CMP
+   3 pick is-ofdm?  4 pick is-ht? or  if  3 pick set-delta-slope  then
+   3 pick spur-mitigate
+   3 pick set-board-values
+                                ( ch led defAnt macStaId1 )
+   mac-adr le-l@ 8000 reg!
+   mac-adr 4 + le-w@ or 8880.0000 or 8004 reg!
+   set-bssidmask
+                                ( ch led defAnt )
+   8058 reg!                    ( ch led )
+   write-associd
+   ffff.ffff 80 reg!
+   700 8018 reg!
+
+   set-opmode
+   over set-channel
+   set-clockrate
+
+   d# 10 0  do  1 i << 1000 i na+ reg!  loop
+
+   reset-txqueue
+
+   init-intr-masks
+   cache-ani-ini-regs
+   init-qos
+
+   hw-caps HW_CAP_RFSILENT and  if  rfkill-gpio cfg-gpio-input  then
+   init-global-settings
+
+   2000.0000 dup 8004 reg@!
+   set-dma
+   8 4088 reg!
+   7d0.01f4 2c reg!
+
+   over init-bb
+        init-cal
+
+   ( led ) 3 or 1f04 reg!
+
+   in-little-endian? 0=  if  5 14 reg!  then
+
+   enable-btcoex
+   config-bb-watchdog
+;
+
+: reset-tsf  ( -- )
+   0 20.0000 8244 wait-hw  drop
+   100.0000 8020 reg!
+;
+
+[ifdef] notyet
+struct
+   /n field >bs-nexttbtt
+   /n field >bs-nextdtim
+   /n field >bs-intval
+   /n field >bs-dtimperiod
+   /n field >bs-cfpperiod
+   /n field >bs-cfpmaxduration
+   /n field >bs-cfpnext
+   /n field >bs-timoffset
+   /n field >bs-bmissthreshold
+   /n field >bs-sleepduration
+   /n field >bs-tsfoor-threshold
+constant /beacon-state
+
+/beacon-state buffer: bstate
+
+: tu>us  ( tu -- us )  d# 10 <<  ;
+: init-beacon  ( period next -- )
+   opmode IFTYPE_ADHOC =  opmode IFTYPE_MESH_POINT = or  if
+      800 dup 30 reg@!
+      1+ tu>us 821c reg!
+      80
+   else
+   opmode IFTYPE_AP =  if
+      dup tu>us 8200 reg!
+      dup 2 - tu>us 8204 reg!
+          d# 10 - tu>us 8208 reg!
+      7
+   else
+      2drop exit
+   then  then  swap         ( flags period )
+
+   dup tu>us dup  8220 reg!  dup 8224 reg!  dup 8228 reg!  823c reg!
+   100.0000 and if  reset-tsf  then
+   dup 8240 reg@!                ( )
+;
+
+: set-beacon-timers  ( -- )
+   bstate >bs-nexttbtt @ tu>us  8200 reg!
+   bstate >bs-intval @ ffff and tu>us dup  8220 reg!  8224 reg!
+   bstate >bs-bmissthreshold @ ff and 8 <<  8018 reg!
+   bstate >bs-nextdtim @ 3 - tu>us  8214 reg!
+   bstate >bs-intval @ ffff and  bstate >bs-sleepduration @ max
+   bstate >bs-dtimperiod @  bstate >bs-sleepduration @ max
+   2dup =  if  bstate >bs-nextdtim  else  bstate >bs-nexttbtt  then
+   @ ( nextTbtt ) 3 - tu>us  8210 reg!
+   0a08.0000 80d4 reg!
+   hw-caps HW_CAP_AUTOSLEEP and  if  a00.0000  else  20.0000  then  80d8 reg!
+   ( dtimperiod )   tu>us  8234 reg!
+   ( beaconintval ) tu>us  8230 reg!
+   31 dup 8240 reg@!
+   bstate >bs-tsfoor-threshold @  813c reg!
+;
+[then]
+
+: get-defant  ( -- ant )  8054 reg@ 7 and  ;
+: set-defant  ( ant -- )  7 and 8054 reg!  ;
+
+\ rxfilter bit definitions
+0001 constant RX_FILTER_UCAST              \ Always on
+0002 constant RX_FILTER_MCAST              \ Always on     
+0004 constant RX_FILTER_BCAST              \ Always on
+0008 constant RX_FILTER_CONTROL
+0010 constant RX_FILTER_BEACON             \ On for AP
+0020 constant RX_FILTER_PROM               \ On if use-promiscuous?
+0080 constant RX_FILTER_PROBEREQ           \ On for AP
+0100 constant RX_FILTER_PHYERR 
+0200 constant RX_FILTER_MYBEACON           \ On for station
+0400 constant RX_FILTER_COMP_BAR           \ On if HT
+0800 constant RX_FILTER_COMP_BA 
+1000 constant RX_FILTER_UNCOMP_BA_BAR
+4000 constant RX_FILTER_PSPOLL		   \ On for PSpoll
+2000 constant RX_FILTER_PHYRADAR
+8000 constant RX_FILTER_MCAST_BCAST_ALL    \ On for other BSS
+
+: get-rxfilter  ( -- bits )
+   810c reg@
+   803c reg@
+   over       20 and  if  RX_FILTER_PHYRADAR or  then
+   swap 202.0000 and  if  RX_FILTER_PHYERR   or  then
+;
+: set-rxfilter  ( bits -- )
+   dup 803c reg!
+   0 over RX_FILTER_PHYRADAR and  if        20 or  then
+   swap   RX_FILTER_PHYERR   and  if  202.0000 or  then
+   dup 810c reg!
+   if  10 dup  else  0 10  then  34 reg@!
+;
+
+: disable-phy  ( -- )
+   RESET_WARM set-reset
+   0 init-pll
+;
+
+: disable-hw  ( -- )
+   RESET_COLD set-reset
+   0 init-pll
+;
+
+: set-txpower-limit  ( test? limit -- )
+   d# 63 min  regulatory >reg-power-limit !
+   curchan swap set-txpower
+;
+
+: set-mcastfilter  ( filter0 filter1 -- )  8044 reg!  8040 reg!  ;
+
+: get-tsf64  ( -- lo hi )
+   8050 reg@              ( hi1 )
+   d# 10 0  do
+      804c reg@           ( hi1 lo )
+      8050 reg@           ( hi1 lo hi2 )
+      rot over =  if  swap leave   then
+      swap                ( hi1' lo )
+   loop  swap             ( lo hi )
+;
+
+: set-tsf64  ( lo hi -- )  swap 804c reg!  8050 reg!  ;
+
+: set-tsfadjust  ( setting -- )
+   misc-mode swap  if  8  or  else  ffff.fff7 and  then
+   to misc-mode 
+;
+
+: set-led-brightness  ( brightness -- )  LED_OFF = led-pin  set-gpio  ;
+
+: deinit-leds         ( -- )  LED_OFF set-led-brightness  ;
+
+: init-leds  ( -- )
+   1 to led-pin
+   led-pin GPIO_OUTPUT_MUX_AS_OUTPUT cfg-output
+   LED_OFF set-led-brightness
+;
+
+: setup-ht-cap  ( 'band -- )
+   >r
+   true r@ >band-ht? !
+   HT_CAP_SUP_WIDTH_20_40 HT_CAP_SM_PS or HT_CAP_SGI_40 or HT_CAP_DSSSCCK40 or
+   HT_CAP_TX_STBC or 100 or
+   hw-caps HW_CAP_LDPC and  if  HT_CAP_LDPC_CODING or  then
+   hw-caps HW_CAP_SGI_20 and  if  HT_CAP_SGI_20 or  then
+   r@ >band-ht-cap !
+   HT_MAX_AMPDU_64K r@ >band-ampdu-factor !
+   HT_MPDU_DENSITY_8 r@ >band-ampdu-density !
+   0 r@ >band-rx-highest !
+   r@ >band-rx-mask d# 10 erase
+   tx-chainmask get-streams       ( #txstreams )
+   rx-chainmask get-streams       ( #txstreams #rxstreams )
+   2dup <>  if                    ( #txstreams #rxstreams )
+      over 1- 2 << HT_MCS_TX_RX_DIFF or HT_MCS_TX_DEFINED or
+   else
+      HT_MCS_TX_DEFINED
+   then
+   r@ >band-tx-params !           ( #txstreams #rxstreams )
+   nip                            ( #rxstreams )
+   r> >band-rx-mask swap ff fill
+;
+
+: init-crypto  ( -- )
+   keymax 0  do  i reset-key  loop
+   misc-mode 4 and  if  crypt-caps CRYPT_CAP_MIC_COMBINED or to crypt-caps  then
+;
+
+: init-btcoex  ( -- )
+   bt-scheme BTCOEX_CFG_2WIRE =  if  init-btcoex-2wire  then
+   \ XXX Do not support 3wire
+;
+
+defer setup-descdma          ' noop to setup-descdma
+defer init-queues            ' noop to init-queues
+
+: init-ch-rates  ( -- )
+   band-2GHz sband !
+   band-5GHz sband na1+ !
+
+   band-2GHz >r
+   BAND_2GHZ      r@ >band-type     !
+   ch-2GHz        r@ >band-channel  !
+   #ch-2GHz       r@ >band-#chan    !
+   legacy-rates   r@ >band-bitrates !
+   #legacy-rates  r> >band-#rate    !
+
+   band-5GHz >r
+   BAND_5GHZ      r@ >band-type     !
+   ch-5GHz        r@ >band-channel  !
+   #ch-5GHz       r@ >band-#chan    !
+   legacy-rates   4 +  r@ >band-bitrates !
+   #legacy-rates  1-   r> >band-#rate    !
+;
+
+: init-misc  ( -- )
+   \ XXX kick off timer for ath_ani_calibrate
+   hw-caps HW_CAP_HT and  if  sc-flags SC_OP_TXAGGR or SC_OP_RXAGGR or to sc-flags  then
+   true set-diversity
+   get-defant 1 max to rx-defant
+;
+
+: init-softc  ( -- )
+   0 to curaid
+   curbssid /mac-adr erase
+   init-hw
+   init-queues
+   init-btcoex
+   init-ch-rates
+   init-crypto
+   init-misc
+;
+
+: get-extchanmode  ( type -- ch-mode )
+   curchan >ch-band @ dup BAND_2GHZ =  if
+      drop  case
+         NL80211_CHAN_NO_HT     of  CH_G_HT20   endof
+         NL80211_CHAN_HT20      of  CH_G_HT20   endof
+         NL80211_CHAN_HT40PLUS  of  CH_G_HT40+  endof
+         NL80211_CHAN_HT40MINUS of  CH_G_HT40-  endof
+         ( otherwise )  0 swap
+      endcase
+   else
+   BAND_5GHZ =  if
+      case
+         NL80211_CHAN_NO_HT     of  CH_A_HT20   endof
+         NL80211_CHAN_HT20      of  CH_A_HT20   endof
+         NL80211_CHAN_HT40PLUS  of  CH_A_HT40+  endof
+         NL80211_CHAN_HT40MINUS of  CH_A_HT40-  endof
+         ( otherwise )  0 swap
+      endcase
+   else
+      drop 0
+   then  then
+;
+
+: update-ichannel  ( type -- )
+   curchan >ch-band @ BAND_2GHZ =  if
+      CH_G curchan >ch-mode !
+      CH_2GHZ CH_OFDM or CH_G or curchan >ch-flags !
+   else
+      CH_A curchan >ch-mode !
+      CH_5GHZ CH_OFDM or curchan >ch-flags !
+   then
+   dup NL80211_CHAN_NO_HT <>  if
+      get-extchanmode curchan >ch-mode !
+   else  drop  then
+;
+
+: init-band-txpower  ( band -- )
+   dup >band-#chan @ 0  do                     ( band )
+      dup i 'band-ch to curchan                ( band )
+      NL80211_CHAN_HT20 update-ichannel        ( band )
+      true d# 63 set-txpower-limit             ( band )
+      regulatory >reg-max-power @ 2/ curchan >ch-max-power !  ( band )
+   loop  drop                                  ( )
+;
+
+: init-txpower-limits  ( -- )
+   curchan                       \ Save
+   band-2GHz init-band-txpower
+   band-5GHz init-band-txpower
+   to curchan                    \ Restore
+;
+
+: set-hw-cap  ( -- )
+   band-2GHz setup-ht-cap
+   band-5GHz setup-ht-cap
+;
+
+: is-world-regd?  ( -- flag )
+   regulatory >reg-cur-rd @ ffff.bfff and  is-wwr-sku?
+;
+
+create def-reg-pair FCC3_FCCA , CTL_FCC , CTL_FCC ,
+: default-init-regd  ( -- )
+   \ XXX US: channels 1-11 are valid, no mid-band channels in 5GHz band
+   CTRY_UNITED_STATES regulatory >reg-country !
+   def-reg-pair regulatory >reg-pair !
+   ascii U regulatory >reg-alpha2 c!
+   ascii S regulatory >reg-alpha2 1+ c!
+;
+defer init-regd              ' default-init-regd to init-regd
+
+defer init-tx                ' noop to init-tx
+defer init-rx                ' noop to init-rx
+
+: init-le  ( -- )
+   \ Determine processor's endianness
+   opencount @                \ Save opencount
+   h# 12345678 dup opencount !
+   opencount le-l@ =  to in-little-endian?
+   opencount !                \ Restore opencount
+;
+
+: init-device  ( -- )
+   init-le
+   init-softc
+   set-hw-cap
+   init-regd
+   init-tx
+   init-rx
+   init-txpower-limits
+   dummy-rssi to last-rssi
+   init-leds
+;
+
+: disable-interrupts  ( -- )
+   0   24 reg!  24   reg@ drop
+   0 403c reg!  403c reg@ drop
+   0 402c reg!  402c reg@ drop
+;
+: set-interrupts  ( -- )
+   \ XXX
+;
+
+defer start-receive                ' noop to start-receive
+defer stop-tx                      ' noop to stop-tx
+defer stop-rx                      ' noop to stop-rx
+
+: re-set-channel  ( ch# -- )       \ 0 based
+   'channel
+   stop-tx
+   stop-rx
+   ( ch ) true reset-hw
+   start-receive
+   false regulatory >reg-power-limit @ set-txpower-limit
+   set-interrupts
+;
+
+: reset  ( -- )
+   disable-interrupts
+   stop-tx
+   stop-rx
+   curchan false reset-hw
+   start-receive
+   false regulatory >reg-power-limit @ set-txpower-limit
+   set-interrupts
+;
+
+: start  ( -- )
+   0 config-pci-powersave
+   defch 'channel false reset-hw
+   false regulatory >reg-power-limit @ set-txpower-limit
+   start-receive
+   set-interrupts
+   ff55 a8a8 wljoin to bt-coex-weights
+   enable-btcoex
+   80 my-b@ fc and 80 my-b!      \ Disable ASPM
+;
+
+: stop  ( -- )
+   disable-btcoex
+   disable-interrupts
+   stop-rx
+   disable-phy
+   disable-hw
+   1 config-pci-powersave
+;
+
+[ifdef] notyet
+: set-coverage-class  ( cc -- )
+   to coverage-class
+   init-global-settings
+;
+[then]
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/key.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/key.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,150 @@
+purpose: ATH9K key cache manipulation
+\ See license at end of file
+
+headers
+hex
+
+0 value keymax
+0 value crypt-caps
+1 constant CRYPT_CAP_CIPHER_AESCCM
+2 constant CRYPT_CAP_MIC_COMBINED
+
+/mac-adr buffer: keymac
+0 value keyptr
+0 value rxmicptr
+0 value txmicptr
+: set-key-mac  ( idx -- )
+   5 << 8800 +                                ( reg-base )
+   keymac le-l@ 1 >>  keymac 4 + le-w@ 1 and d# 31 << or  ( reg-base macL )
+   over d# 24 + reg!                          ( reg-base )
+   keymac c@ 1 and  if  0  else  8000  then   ( reg-base unicast )
+   keymac 4 + le-w@ 1 >> or                   ( reg-base macH )
+   swap d# 28 + reg!                          ( )
+;
+
+: set-key-entry  ( type idx -- )
+   tuck 5 << 8800 +                           ( idx type reg-base )
+   keyptr         le-l@  over         reg!
+   keyptr     4 + le-w@  over     4 + reg!
+   keyptr     6 + le-l@  over     8 + reg!
+   keyptr d# 10 + le-w@  over d# 12 + reg!
+   keyptr d# 12 + le-l@  over d# 16 + reg!
+                              d# 20 + reg!
+   ( idx )  set-key-mac
+;
+: set-key-wep  ( -- )
+   wep1 to keyptr
+   /wep1     5 =  if  KEYTABLE_TYPE_40   0 set-key-entry  then
+   /wep1 d# 13 =  if  KEYTABLE_TYPE_104  0 set-key-entry  then
+   wep2 to keyptr
+   /wep2     5 =  if  KEYTABLE_TYPE_40   1 set-key-entry  then
+   /wep2 d# 13 =  if  KEYTABLE_TYPE_104  1 set-key-entry  then
+   wep3 to keyptr
+   /wep3     5 =  if  KEYTABLE_TYPE_40   2 set-key-entry  then
+   /wep3 d# 13 =  if  KEYTABLE_TYPE_104  2 set-key-entry  then
+   wep4 to keyptr
+   /wep4     5 =  if  KEYTABLE_TYPE_40   3 set-key-entry  then
+   /wep4 d# 13 =  if  KEYTABLE_TYPE_104  3 set-key-entry  then
+;
+: set-key-aes  ( -- )
+   p-aes to keyptr
+   KEYTABLE_TYPE_CCM pair-idx set-key-entry
+;
+: set-key-aes-group  ( -- )
+   g-aes to keyptr
+   KEYTABLE_TYPE_CCM grp-idx set-key-entry
+;
+: set-tkip-entry  ( type idx -- )
+   tuck 5 << 8800 +                           ( idx type reg-base )
+   keyptr         le-l@ invert over         reg!
+   keyptr     4 + le-w@ invert over     4 + reg!
+   keyptr     6 + le-l@        over     8 + reg!
+   keyptr d# 10 + le-w@        over d# 12 + reg!
+   keyptr d# 12 + le-l@        over d# 16 + reg!
+   ( type )                    tuck d# 20 + reg!
+   swap set-key-mac                           ( reg-base )
+
+   rxmicptr     le-l@  over  800 + reg!
+   txmicptr 2 + le-w@  over  804 + reg!
+   rxmicptr 4 + le-l@  over  808 + reg!
+   txmicptr     le-w@  over  80c + reg!
+   txmicptr 4 + le-l@  over  810 + reg!
+   KEYTABLE_TYPE_CLR   over  814 + reg!
+   0                   over  818 + reg!
+   0                   over  81c + reg!
+
+   keyptr     le-l@ over     reg!
+   keyptr 4 + le-w@ swap 4 + reg!
+;
+: set-key-tkip  ( -- )
+   p-tkip to keyptr
+   p-tkip d# 24 + to rxmicptr
+   p-tkip d# 16 + to txmicptr
+   KEYTABLE_TYPE_TKIP pair-idx set-tkip-entry
+;
+: set-key-tkip-group  ( -- )
+   keymac /mac-adr erase  1 keymac c!
+   g-tkip to keyptr
+   ap-mode?  if
+      g-tkip d# 16 + to rxmicptr
+      g-tkip d# 16 + to txmicptr
+   else
+      g-tkip d# 24 + to rxmicptr
+      g-tkip d# 24 + to txmicptr
+   then
+   KEYTABLE_TYPE_TKIP grp-idx set-tkip-entry
+;
+
+: set-key-cache  ( -- )
+   target-mac keymac /mac-adr  move
+   key-wep?  if  set-key-wep exit  then
+   pkey-tkip?  if  set-key-tkip  then
+   pkey-aes?   if  set-key-aes   then
+\   keymac c@ 1 or keymac c!        \ Multicast key for AP or adhoc
+   gkey-tkip?  if  set-key-tkip-group  then
+   gkey-aes?   if  set-key-aes-group  then
+;
+
+: reset-key  ( i -- )
+   dup 5 << 8800 +                 ( i reg-base )
+   dup d# 20 + reg@ swap           ( i type reg-base )
+   0 over         reg!  0 over     4 + reg!
+   0 over     8 + reg!  0 over d# 12 + reg!
+   0 over d# 16 + reg!  7 over d# 20 + reg!   \ CLR
+   0 over d# 24 + reg!  0 swap d# 28 + reg!  ( i type )
+   4 =  if      \ TKIP             ( i )
+      d# 64 + 5 << 8800 +          ( reg-base )
+      0 over         reg!  0 over     4 + reg!
+      0 over     8 + reg!  0 over d# 12 + reg!
+      0 over d# 16 + reg!  7 over d# 20 + reg!   \ CLR if MIC_COMBINED
+   then  drop
+;
+
+: reset-key-cache  ( -- )
+   keymax 0  do  i reset-key  loop
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/mac.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/mac.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,835 @@
+purpose: ATH9K MAC layer
+\ See license at end of file
+
+headers
+hex
+
+\ =======================================================================
+\ Driver variables
+\ =======================================================================
+
+\ driver-state definitions
+0 constant ds-ready                  \ Initial state, can probe/scan/authenticate
+1 constant ds-associated             \ Associated and WPA key handshake ok
+2 constant ds-disconnected           \ Disconnected
+
+ds-ready instance value driver-state
+
+: set-driver-state    ( state -- )  to driver-state  ;
+: reset-driver-state  ( -- )  ds-ready to driver-state  ;
+: process-disconnect  ( -- )
+   ds-disconnected set-driver-state  
+   reset-key-cache
+   false to wep-enabled?
+   false to gkey-enabled?
+   false to pkey-enabled?
+;
+
+\ bss-type values
+1 constant bss-type-managed
+2 constant bss-type-adhoc
+bss-type-managed value bss-type
+
+0 value currate
+0 value basic-rate
+0 value basic-rate-hw-val
+0 value pkt-type
+true value basic-rate-erp?
+
+d# 256 buffer: ssid
+0 value /ssid
+: ssid$  ( -- $ )  ssid /ssid  ;
+d# 34 instance buffer: scan-ssid
+
+0 value tx-tkip-iv16           0 value rx-tkip-iv16
+0 value tx-tkip-iv32           0 value rx-tkip-iv32
+6 constant /pn
+/pn buffer: tx-pn              /pn buffer: rx-pn   \ Big endian
+
+0 value atim
+d# 11 value channel
+d# 80 buffer: wpa-ie            \ WPA IE saved for EAPOL phases
+0 value /wpa-ie
+
+external
+: wpa-ie$  ( -- adr len )  wpa-ie /wpa-ie  ;
+headers
+
+\ Miscellaneous
+0 value preamble                \ 0=long, 2=short, 4=auto
+0 value auth-mode               \ 0: open; 1: shared key; 2: EAP
+h# 401 value cap                \ Capabilities
+false value passive-scan?
+defer setup-data-series         ' noop to setup-data-series
+
+: currate>bitrate  ( -- rate )  currate 'legacy-rates >br-bitrate @  ;
+: bitrate>idx  ( bitrate -- idx )
+   0 swap #legacy-rates 0  do             ( hw-val bitrate )
+      i 'legacy-rates >br-bitrate @ over =  if
+         nip i swap leave
+      then
+   loop  drop
+;
+: bitrate>hw-val  ( bitrate -- hw-val )
+   bitrate>idx
+   'legacy-rates preamble  if  >br-hw-val-short  else  >br-hw-val  then  @
+;
+: is-common-rate?  ( bitrate -- common? )
+   5 /  0 swap                         ( common? rate )
+   #rates 0  do
+      common-rates i + c@ 7f and over =  if  nip true swap leave  then
+   loop  drop
+;
+: find-fastest-rate  ( adr len -- rateidx )
+   0 -rot  bounds  do  i c@ 7f and max  loop    ( rate )
+   0 swap                                       ( rateidx rate )
+   #rates 0  do  supported-rates i + c@ over =  if  nip i swap leave  then loop
+   drop                                         ( rateidx' )
+;
+: (find-basic-rate)  ( br-flag -- rate )
+   0 swap
+   #legacy-rates 0  do                ( rate br-flag )
+      dup i 'legacy-rates >br-flags @ and  if
+         i 'legacy-rates >br-bitrate @ dup is-common-rate?  if
+	    currate>bitrate over >=  if
+               rot max swap
+            else  drop  then
+         else  drop  then
+      then                            ( rate' br-flag )
+   loop
+   drop
+   ?dup 0=  if
+      curchan is-2GHz?  if  band-2GHz  else  band-5GHz  then
+      >band-channel @ >br-bitrate @
+   then
+;
+: find-basic-rate  ( -- rate )
+   curchan is-5GHz?  if  br-mand-a
+   else
+      curchan is-b?  if  br-mand-b  else  br-mand-g  then
+   then
+   (find-basic-rate)
+;
+
+external
+: set-atim-window  ( n -- )  d# 50 min  to atim  ;
+: set-preamble  ( preamble -- )  ( XXX to preamble ) drop  ;
+: set-cap  ( cap -- )  to cap  ;
+: set-auth-mode  ( amode -- )  to auth-mode  ;
+: set-bss-type  ( bssType -- ok? )  to bss-type true  ;
+: set-country-info  ( adr len -- )  2drop  ;  \ XXX Country IE, affect regulatory
+: set-ssid  ( adr len -- )
+   2dup  " mesh" $=  if  true to passive-scan?  then
+
+   h# 32 min scan-ssid pack drop  
+;
+: supported-rates$  ( -- adr len )  supported-rates #rates  ;
+: set-common-rates  ( adr len -- )
+   2dup find-fastest-rate to currate
+   common-rates #rates erase
+   #rates min common-rates swap move
+   find-basic-rate to basic-rate
+   basic-rate bitrate>hw-val to basic-rate-hw-val
+   basic-rate bitrate>idx 'legacy-rates >br-flags @ br-erp-g and to basic-rate-erp?
+   setup-data-series
+;
+: disconnected?  ( -- flag )  driver-state ds-disconnected =  ;
+
+headers
+: link-up?  ( -- flag )  driver-state ds-associated =  ;
+
+: null$  ( -- adr len )  " "  ;
+: zero$  ( -- adr len )  " "(00 00 00 00 00 00)"  ;
+: broadcast-mac$  ( -- adr len )  " "(ff ff ff ff ff ff)"  ;
+
+0 value supplicant-ih
+: $call-supplicant  ( ...$ -- ... )  supplicant-ih $call-method  ;
+: supplicant-associate   ( -- flag )  " do-associate" $call-supplicant  ;
+: supplicant-process-eapol  ( adr len -- )  " process-eapol" $call-supplicant  ;
+: .scan  ( adr -- )  " .scan" $call-supplicant  ;
+: .ssids  ( adr -- )  " .ssids" $call-supplicant  ;
+: rc4  ( data$ key$ -- )  " rc4" $call-supplicant  ;
+
+: invalid-rssi  ( -- rssi )  80  ;
+defer rx-rssi         ( -- rssi )         ['] invalid-rssi to rx-rssi
+defer ?process-eapol  ( adr len -- )      ['] 2drop to ?process-eapol
+
+d# 24 constant /802.11-data-hdr      \ Basic data frame header len
+rx-bufsize constant /packet-buf
+0 value packet-buf
+0 instance value seq#
+
+: alloc-packet  ( -- )
+   packet-buf 0=  if  /packet-buf dma-alloc to packet-buf  then
+;
+: free-packet  ( -- )
+   packet-buf  if
+      packet-buf /packet-buf dma-free
+      0 to packet-buf
+   then
+;
+
+true instance value got-data?
+true instance value got-response?
+0 instance value /respbuf
+/packet-buf instance buffer: respbuf
+0 instance value /data
+0 instance value data
+
+/802.11-data-hdr d# 22 + constant /rx-min  \ MAC header + ethernet header with SNAP
+
+false value HT-mode?
+
+: seq#++  ( -- )  seq# h# 20 +  to seq#  ;  \ The 4 LSBs are the fragment number
+: addr4-present?  ( adr -- present? )  le-w@  h# 300 and  h# 300 =  ;
+: QoS-present?    ( adr -- present? )  le-w@  h# 88 and  h# 88 =  ;
+: HT-present?     ( adr -- present? )  dup QoS-present? swap le-w@ h# 8000 and or  ;
+
+: /802.11n-data-hdr  ( adr -- len )
+   /802.11-data-hdr
+   over  addr4-present?  if  6 +  then
+   swap  QoS-present?    if  HT-mode?  if  6  else  2  then  +  then
+;
+
+: snap-header  " "(aa aa 03 00 00 00)"  ;
+
+\ MAC frame format:
+\ Frame header
+\   2-byte frame control
+\   2-byte duration/id
+\   6-byte address 1
+\   6-byte address 2
+\   6-byte address 3
+\   2-byte sequence control
+\   6-byte address 4
+\   2-byte QoS control
+\   4-byte HT control
+\ 0-7955 bytes frame body
+\ 4-byte FCS
+
+\ The low byte of the frame control word is:
+\ ssssTTpp
+\ pp is protocol version, always 00
+\ TT is type, 00 for management, 01 (i.e. 4) control, 10 (i.e. 8) data, 11 reserved
+\ ssss is subtype
+\ Management subtypes are:
+\ 0000 (00) Association request
+\ 0001 (10) Association response
+\ 0010 (20) Reassociation request
+\ 0011 (30) Reassociation response
+\ 0100 (40) Probe request
+\ 0101 (50) Probe response
+\ 0110-0111 (60-70) Reserved
+\ 1000 (80) Beacon
+\ 1001 (90) ATIM
+\ 1010 (a0) Disassociation
+\ 1011 (b0) Authentication
+\ 1100 (c0) Deauthentication
+\ 1101 (d0) Action
+\ 1110 (e0) Action No Ack
+\ 1111 (f0) Reserved
+\ Control subtypes are (other codes are reserved):
+\ 0111 (74) Control Wrapper
+\ 1000 (84) Block Ack Request
+\ 1001 (94) Block Ack
+\ 1010 (a4) PS-Poll
+\ 1011 (b4) RTS
+\ 1100 (c4) CTS
+\ 1101 (d4) ACK
+\ 1110 (e4) CF End
+\ 1111 (f4) CF End + CF ACK
+\ Data subtypes are (other codes are reserved):
+\ 0000 (08) Data
+\ 0001 (18) Data+CF-ACK
+\ 0010 (28) Data+CF-Poll
+\ 0011 (38) Data+CF-ACK+CF-Poll
+\ 0100 (48) Null (no data)
+\ 0101 (58) CF-ACK (no data)
+\ 0110 (68) CF-Poll (no data),
+\ 0111 (78) CF-ACK+CF-Poll (no-data)
+
+\ The upper byte of the frame control word is:
+\ bit 7  Order: set to 1 in a non-QoS STA transmits using the StrictlyOrdered service class;
+\               set to 1 in a QoS data or management frame, it indicates that the HT Control field exists
+\ bit 6  Protected Frame: set if the frame body is encrypted
+\ bit 5  More Data: set to indicate to a STA in PS mode that more data are buffered for that STA
+\ bit 4  Power Management: set if STA is to be in PS mode with a frame exchange
+\ bit 3  Retry: set if the frame is a retransmission
+\ bit 2  More Fragment
+\ bit 1  From DS
+\ bit 0  To DS
+\
+\ From/TO DS
+\  00  All management and control frames, data frames within an IBSS
+\  01  Data frames transmitted from a STA in an infrastructure network
+\  10  Data frames received for a STA in an infrastructure network
+\  11  Data frames on a "wireless bridge"
+
+\ Duration/ID
+\   0-7fff    Duration (in us) used to set the NAV (network allocation vector)
+\   8000      Contention free transmission, NAV=8000
+\   c001-c7d7 AID (BSS associated ID) in PS-Poll frames
+\
+\ Sequence control
+\   ssss.ssss.ssss.ffff
+
+\ QoS control
+\   Applicable Frames                        bits 15-0
+\   QoS CF-Poll, CF-ACK+Poll by HC           llll.llll.raae.tid
+\   QoS Data+CF-Poll, Data+CF-ACK+Poll by HC llll.llll.paae.tid
+\   QoS Data, Data+CF-ACK by HC              bbbb.bbbb.paae.tid
+\   QoS Null by HC                           bbbb.bbbb.raae.tid
+\   QoS Data, Data+CF-ACK by non-AP STA      dddd.dddd.paa0.tid
+\                                            qqqq.qqqq.paa1.tid
+\   QoS Null by non-AP STA                   dddd.dddd.raa0.tid
+\                                            qqqq.qqqq.raa1.tid
+\
+\ tid: 0-7 user priority; 8-f transmit stream id
+\ e: EOSP (end of service period)
+\ aa: ACK policy
+\     00 normal or implicit block ACK
+\     01 no ACK
+\     10 no explicit or PSMP ack (power save mult poll)
+\     11 block ACK
+\ r: reserved
+\ p: A-MSDU present
+\ l's: TXOP limit
+\ b's: AP PS buffer state
+\         llll.ppsr
+\      llll:  total PS buffer size in units of 4096 bytes
+\      pp:    AC of the highest priority traffic buffered at the AP
+\      s:     buffered state, set if llll and pp are valid
+\ d's: TXOP duration requested
+\ q's: Queue size in units of 256 bytes
+
+\ HT control: present for Control Wrapper Frame and Order=1 for Qos frames
+\   bit 31    RDG/More PPDU, depends on RD initiator/responder
+\   bit 30    AC constraint, 0=response may contain data frames from any TID
+\             1=response may contain data frames only rom the same AC
+\   bit 24    NDP Announcement, 1=null data packet will follow
+\   bit 22:23 CSI/Steering
+\             0=no feedback required, 1=CSI, 2=noncompressed beamforming, 3=compressed beamforming
+\   bit 18:19 Calibration sequence
+\   bit 16:17 Calibration position
+\             0=not a calibration frame, 1=start, 2=sounding response, 3=complete
+\   bit 0:15  Link Adaptation Control
+\             bit 9:15 MFB/ASELC, 127=no feedback, if MAI<>e, recommended MFB
+\                      if MAI=e, dddddccc
+\                        ccc command                                        ddddd
+\                         0  Transmit Antenna Selection Sounding Indication  0-15
+\                         1  Transmit Antenna Selection Sounding Request     0
+\                            Transmit ASEL Sounding Resumption               1-15
+\                         2  Receive Antenna Selection Sounding Indication   0-15
+\                         3  Receive Antenna Selection Sounding Request      0-15
+\                         4  Sounding Label                                  0-15
+\                         5  No feedback due to ASEL training failure        0-15
+\                         6  TXASSI-request feedback of explicit CSI         0-15
+\             bit 6:8  MFSI, MSI value, 7=unsolicited MFB
+\             bit 2:5  MAI, e=ASELI, iiiq: MRQ sequence id (MSI) & MCS request
+\             bit 1    TRQ Training request
+
+\ =================================================================================
+\ Process received MAC frames
+\ =================================================================================
+
+struct
+   /n field >dadr
+   /n field >dlen
+constant /qentry
+0 instance value qhead        \ Retrieve from qhead
+0 instance value qend         \ Insert to qend
+0 instance value queue
+d# 128 constant /queue
+
+: qend++   ( -- )
+   qend 1+ dup /queue =  if  drop 0 then
+   dup qhead =  if  ." WARNING: queue overflow" cr drop  else  to qend  then
+;
+: qhead++  ( -- )  qhead 1+ dup /queue =  if  drop 0  then  to qhead  ;
+: queue-adr  ( idx -- adr )  /qentry * queue +  ;
+: qhead-adr  ( -- adr )  qhead queue-adr  ;
+: qend-adr   ( -- adr )  qend queue-adr  ;
+: init-queue  ( -- )
+   queue 0=  if
+      /qentry /queue * alloc-mem  to queue
+   then
+   0 to qhead  0 to qend
+;
+: enque  ( adr len -- )
+   \ Remove snap header
+   over d# 14 + snap-header comp 0=  if       ( adr len )
+      8 - dup alloc-mem dup qend-adr >dadr !  ( adr len' qadr )
+      over qend-adr >dlen !                   ( adr len qadr )
+      rot 2dup d# 12 move                     ( len qadr adr ) \ Copy MAC addresses
+      d# 20 + -rot swap d# 12 /string         ( adr qadr len )
+   else
+      dup alloc-mem dup qend-adr >dadr !      ( adr len qadr )
+      over qend-adr >dlen ! swap              ( adr qadr len )
+   then
+   move                                       \ Copy the rest
+   qend++
+;
+: deque  ( adr len -- actual )
+   qhead qend =  if  2drop 0  exit  then
+   qhead-adr >dadr @                        ( adr len qadr )
+   qhead-adr >dlen @                        ( adr len qadr qlen )
+   rot min rot swap                         ( qadr adr actual )
+   dup >r  move                             ( qadr qlen )  ( R: actual )
+   free-mem  r>                             ( actual )
+;
+
+: skip-802.11n-data-hdr  ( adr len -- adr' len' )
+   \ Go to the payload, skipping the MAC frame header
+   over /802.11n-data-hdr  /string          ( adr' len' )
+;
+
+: skip-802.11n-mgr-hdr  ( adr len -- adr' len' )
+   \ Go to the payload, skipping the MAC frame header
+   over  HT-present?   if  4  else  0  then
+   /802.11-data-hdr +  /string         ( adr' len' )
+;
+
+0 value rs-rssi
+: compute-avgbrssi  ( -- )
+   rx-rssi sign-c dup  to rs-rssi
+   -80 <>  if
+      rs-rssi d# -20 >=  if
+         rs-rssi 7 <<
+         last-rssi dummy-rssi <>  if
+            last-rssi 9 * + d# 10 /
+         then  to last-rssi
+      then
+   then
+   last-rssi dummy-rssi =  if
+      rs-rssi
+   else
+      last-rssi 7 >>  last-rssi 7f and 40 >=  if  1+  then
+   then  0 max 
+   dup to rs-rssi to avgbrssi
+;
+: ?compute-avgbrssi  ( adr -- )
+   d# 16 + target-mac$ comp 0=  if  compute-avgbrssi  then
+;
+: (process-mgt)  ( adr len -- )
+   drop dup >r c@  case
+      80  of  r@ ?compute-avgbrssi  endof
+      90  of  " ATIM" vtype  endof
+      a0  of  " Disassociated"   vtype  process-disconnect  endof
+      c0  of  " Deauthenticated" vtype  process-disconnect  endof
+      d0  of  " ACTION" vtype  endof
+   endcase
+   r> drop
+;
+
+0 instance value resp-type
+: process-mgt  ( adr len -- )
+   over c@  resp-type =  to got-response?
+   2dup (process-mgt)
+   got-response?  if
+      dup to /respbuf
+      respbuf swap move
+   else
+      2drop
+   then
+;
+
+: process-ctl  ( adr len -- )  " Got a control frame" vtype vcdump  ;
+
+\ XXX For TKIP and AES, should check duplicate sequence number
+: 802.11n>ethernet  ( adr len -- adr' len' )
+   over >r                              ( adr len )  ( R: adr )
+   \ Skip 802.11n header
+   r@ /802.11n-data-hdr                 ( adr len slen )  ( R: adr )
+   r@ le-w@ 4000 and  if                \ Skip IV or CCMP header
+      key-wep?  if  4  else  8  then  +
+   then
+   \ Skip snap header, if any
+   dup r@ + snap-header comp 0=  if  6 +  then  ( adr len slen' )  ( R: adr )
+   \ Recreate ethernet header
+   d# 12 - /string                      ( adr' len' )  ( R: adr )
+   \ Move source mac
+   r@ d# 16 + 2 pick /mac-adr + /mac-adr move   ( adr' len' )  ( R: adr )
+   \ Move destination mac
+   r>     4 + 2 pick            /mac-adr move   ( adr' len' )
+;
+
+: (process-data)  ( adr len -- )
+   802.11n>ethernet  to /data  to data      ( )
+   true to got-data?
+   data d# 12 + be-w@  h# 888e =  if  \ Pass EAPOL messages to supplicant
+      data /data ?process-eapol
+   then
+
+;
+: do-process-eapol  ( adr len -- )  false to got-data?  supplicant-process-eapol  ;
+
+: process-subframe  ( adr len -- )
+   over d# 12 + le-w@  min            ( adr len' )
+   swap d# 14 + swap                  ( adr' len )
+   enque                              ( )
+;
+: process-a-msdu  ( adr len -- )
+   \ A-MSDU subframe 1, A-MSDU subframe 2, ...
+   \ A-MSDU subframe header: 6-byte DA, 6-byte SA, 2-byte length
+   \ 0-2304 bytes of MSDU, 0-3 padding bytes
+
+   \ XXX unpack, return first packet, queue the rest
+   dup /rx-min <  if  exit  then      \ Invalid data packet: too small
+   skip-802.11n-data-hdr              \ Skip to the subframes
+                                      ( adr len )
+   begin  ?dup  while                 ( adr len )
+      2dup  process-subframe          ( adr len )
+      over d# 12 + le-w@  4 round-up d# 14 +  /string  ( adr' len' )
+      0 min                           ( adr len )
+   repeat  drop
+;
+\ XXX Need to be able to process QoS data...
+: process-data  ( adr len -- )
+   over le-w@ h# f0 and 0=  if
+      (process-data)
+   else
+      2drop
+   then
+;
+
+\ XXX Take care of multicast packets.
+: rx-for-me?  ( adr -- mine? )
+   4 + dup broadcast-mac$ comp 0=  if
+      d# 12 + mac-adr$ comp            \ Filter out msg I send
+      dup  if  ascii b  else  ascii x  then  vemit
+      exit
+   then
+   dup c@ 1 and  if  ascii m vemit drop false  exit  then
+   mac-adr$ comp 0= dup  if  ascii u  else  ascii o  then  vemit
+;
+: process-rx  ( adr len -- )
+   false to got-data?
+   false to got-response?
+   over rx-for-me? 0=  if  2drop exit  then
+   over le-w@ h# c and  case          \ Frame control type
+     0  of  process-mgt   endof       \ Management
+     4  of  process-ctl   endof       \ Control
+     8  of  process-data  endof       \ Data
+     ( otherwise )  debug-me nip nip
+   endcase
+;
+
+\ =================================================================================
+\ Create MAC frames
+\ =================================================================================
+
+0 value x                       \ Temporary variables to assist frame creation
+0 value /x
+
+: set-x  ( offset adr -- )  to x  to /x  ;
+: 'x   ( -- adr )  x /x +  ;
+: +x   ( n -- )  /x + to /x  ;
+: +x$  ( $ -- )  'x swap dup +x move  ;
+: +xl  ( n -- )  'x le-l!  /l +x  ;
+: +xw  ( n -- )  'x le-w!  /w +x  ;
+: +xb  ( n -- )  'x c!     /c +x  ;
+: +xbl ( n -- )  'x be-l!  /l +x  ;
+: +xerase  ( n -- )  'x over erase  +x  ;
+
+: set-802.11-data-hdr  ( adr3$ adr2$ adr1$ duration frame-type -- )
+   0 packet-buf set-x
+   dup to pkt-type
+   +xw                             ( adr3$ adr2$ adr1$ duration )
+   +xw                             ( adr3$ adr2$ adr1$ )
+   +x$                             ( adr3$ adr2$ )
+   +x$                             ( adr3$ )
+   +x$                             ( )
+   seq# +xw seq#++                 ( )
+   resp-wait-short to resp-wait
+;
+
+: set-802.11n-data-hdr  ( HT QoS adr4$ adr3$ adr2$ adr1$ duration frame-type -- )
+   set-802.11-data-hdr                           ( HT QoS adr4$ )
+   x addr4-present?  if  +x$  else  2drop  then  ( HT QoS )
+   x QoS-present?    if  +xw  else  drop   then  ( HT )
+   HT-mode?          if  +xw  else  drop   then  ( )
+;
+
+: set-802.11n-mgr-hdr  ( BSSID$ DA$ duration frame-type -- )
+   0 packet-buf set-x
+   dup to pkt-type
+   ( frame-type ) +xw           \ Frame control
+   ( duration )   +xw           \ Duration
+   ( DA$ )        +x$           \ Destination MAC
+   mac-adr$       +x$           \ Source MAC
+   ( BSSID$ )     +x$           \ BSSID
+   seq# +xw  seq#++             \ Sequence #
+   resp-wait-long to resp-wait
+   
+;
+
+\ Time in us for one ACK and one SIFS interval; management frame only
+: nav  ( -- duration )
+   curchan is-2GHz?  if
+      preamble  if  d# 218  else  d# 314  then
+   else
+      d# 55                   \ 5GHz band
+   then
+;
+
+\ Time in us for one ACK and one SIFS interval; unicast data frame only
+: data-nav  ( len -- duration )
+   4 +  basic-rate swap                          ( rate len' )
+   curchan is-5GHz?  basic-rate-erp? or  if
+      8 * d# 22 + d# 10 * swap 2 << /mod swap  if  1+  then  2 << ( duration )
+      d# 36 +                                    ( duration' )
+   else
+      d# 80 * swap /mod swap  if  1+  then       ( duration )
+      preamble  if  d# 106  else  d# 202  then + ( duration' )
+   then
+;
+
+: get-iv  ( -- iv )
+   804c reg@                  \ Timestamp
+   dup ff00 and ff00 =  if    ( iv )
+      dup d# 16 >> ff and     ( iv iv.hi )
+      dup 3 >=  swap /wep1 3 + <  and  if  100 +  then
+   then                       ( iv' )
+
+   8 << wep-idx 6 << or       ( iv' )  \ In big endian
+;
+d# 16 buffer: rc4key
+: make-rc4key  ( iv.lo iv.mi iv.hi -- )
+   rc4key d# 16 erase
+   rc4key c!  rc4key 1+ c!  rc4key 2 + c!
+   wep-idx wep-key$ rc4key 3 + swap move
+;
+: compute-icv  ( adr len -- icv )  " $crc" evaluate  ;
+: encrypt-wep  ( adr len -- )  rc4key /wep1 3 + rc4  ;
+0 value au-dt-adr
+0 value /au-dt
+: make-authenticate-req  ( [challenge$] seq target-mac$ -- adr len )
+   over target-mac$ move
+   2dup nav
+   5 pick 3 =  if h# 40b0  else  h# b0  then  set-802.11n-mgr-hdr
+
+   dup 1 =  if
+      auth-mode +xw                     \ Authentication algorithm
+      ( seq ) +xw                       \ Authentication sequence number
+      0 +xw                             \ Status code
+   else
+      get-iv lbsplit 3dup make-rc4key   \ Generate iv and rc4key
+      +xb +xb +xb +xb                   \ IV
+      'x to au-dt-adr  /x to /au-dt     \ Save data adr/len to be encrypted
+      auth-mode +xw                     ( challenge$ seq )
+      ( seq ) +xw                       \ Authentication sequence number
+      0 +xw                             \ Status code
+      d# 16 +xb dup +xb +x$             \ Challenge text
+      /x /au-dt - to /au-dt             \ Update data len
+      au-dt-adr /au-dt compute-icv +xl  \ ICV
+      au-dt-adr /au-dt 4 + encrypt-wep  \ Encrypt data + ICV
+   then
+   x /x                         ( adr len )
+;
+
+: make-deauthenticate-req  ( target-mac$ -- adr len )
+   2dup nav h# c0 set-802.11n-mgr-hdr
+   3 +xw                        \ Reason code: station is leaving
+   x /x
+;
+
+: make-disassociate-req  ( target-mac$ -- adr len )
+   2dup nav h# a0 set-802.11n-mgr-hdr
+   3 +xw                        \ Reason code: station is leaving
+   x /x
+;
+
+: save-associate-params  ( ch ssid$ target-mac$ -- ch ssid$ target-mac$ )
+   over target-mac$ move
+   2over dup to /ssid
+   ssid swap move
+   4 pick to channel
+;
+: save-wpa-ie  ( boffset eoffset -- )
+   over - to /wpa-ie            \ Len of wpa-ie
+   x + wpa-ie /wpa-ie move      \ Copy IE
+;
+: moui  ( ct -- )  ct-tkip =  if  moui-tkip  else  moui-aes  then  ;
+: oui   ( ct -- )  ct-tkip =  if  oui-tkip   else  oui-aes   then  ;
+
+: make-associate-req  ( ch ssid$ target-mac$ -- adr len )
+   save-associate-params
+   2dup nav 0 set-802.11n-mgr-hdr
+
+   cap    +xw                           \ Capability info: ESS, short slot, WEP
+   d# 300 +xw                           \ Listen interval
+
+   \ SSID
+   0   +xb                              \ element ID = SSID 
+   dup +xb                              \ len
+   ( ssid$ ) +x$                        \ SSID
+
+   \ DS param
+   3      +xb                           \ element ID = DS param set
+   1      +xb                           \ len
+   ( ch ) +xb                           \ channel
+
+   \ Common supported rates
+   1      +xb                           \ element ID = rates
+   #rates 8 min +xb                     \ len
+   common-rates #rates 8 min +x$        \ common supported data rates
+
+   \ Extended common supported rates
+   #rates 8 >  if
+      d# 50       +xb                   \ element ID = Extended rates
+      #rates 8 -  +xb                   \ len
+      common-rates 8 + #rates 8 - +x$   \ common supported data rates
+   then
+
+   \ RSN (WPA2)
+   ktype kt-wpa2 =  if
+      /x                                \ Save beginning offset
+      d# 48  +xb                        \ element ID = RSN
+      d# 20  +xb                        \ len
+      1      +xw                        \ version
+      ctype-g oui +xbl                  \ group cipher suite
+      1      +xw                        \ count of pairwise cipher suite
+      ctype-p oui +xbl                  \ pairwise cipher suite
+      1      +xw                        \ count of authentication suite
+      aoui   +xbl                       \ authentication suite
+      0      +xw                        \ RSN capabilities
+      /x save-wpa-ie                    \ Save IE in wpa-ie
+   then
+
+   \ WPA param
+   ktype kt-wpa =  if
+      /x                                \ Save beginning offset
+      d# 221  +xb                       \ element ID = WPA
+      d# 22   +xb                       \ len
+      wpa-tag +xbl                      \ WPA-specific tag
+      1 +xw                             \ version
+      ctype-g moui +xbl                 \ group cipher suite
+      1       +xw                       \ count of pairwise cipher suite
+      ctype-p moui +xbl                 \ pairwise cipher suite
+      1       +xw                       \ count of authentication suite
+      amoui   +xbl                      \ authentication suite
+      /x save-wpa-ie                    \ Save IE in wpa-ie
+   then
+
+   x /x
+;
+
+: make-probe-req  ( ssid$ target-mac$ -- )
+   2dup 0 h# 40 set-802.11n-mgr-hdr
+
+   0 +xb dup +xb ( ssid$ ) +x$
+   1 +xb #rates 8 min dup +xb supported-rates swap  +x$
+   #rates 8 >  if
+      d# 50 +xb #rates 8 - dup +xb supported-rates over + swap  +x$
+   then
+
+   x /x
+;
+
+: +wep-iv  ( -- )  get-iv lbsplit +xb +xb +xb +xb  ;
+: tx-tkip-iv++  ( -- )
+   tx-tkip-iv16 1+ dup to tx-tkip-iv16
+   0=  if  tx-tkip-iv32 1+ to tx-tkip-iv32  then
+;
+: +tkip-iv   ( -- )
+   tx-tkip-iv++  
+   tx-tkip-iv16 wbsplit dup +xb 20 or 7f and +xb +xb 20 +xb
+   tx-tkip-iv32 +xl
+;
+: tx-pn++  ( -- )
+   tx-pn 2 + be-l@ 1+ dup tx-pn 2 + be-l!
+   0=  if  tx-pn be-w@ 1+ tx-pn be-w!  then
+;
+: +ccmp-hdr  ( -- )
+   tx-pn++
+   tx-pn 4 + be-w@ +xw
+   0 +xb
+   20 +xb
+   tx-pn     be-l@ +xl
+;
+: protect-data?  ( -- flag )  key-enabled? ?dup 0=  if  key-wpax?  then  ;
+\ XXX Right now, support only managed mode; adhoc in the future
+: make-data-frame  ( adr len -- adr' len' )
+   over /mac-adr mac-adr$ target-mac$ d# 10 data-nav
+   108  key-enabled?  if  4000 or  then  set-802.11-data-hdr
+   key-enabled?  if
+      key-wep?  if
+         +wep-iv
+      else
+         pkey-tkip?  if  +tkip-iv  else  +ccmp-hdr  then
+      then
+   then
+   snap-header +x$
+   ( adr len ) d# 12 /string +x$
+   x /x
+;
+
+\ =================================================================================
+\ Create "libertas" like scan results to match supplicant package expectation:
+\    - 2 bytes of ??
+\    - 1 byte of # of APs scanned
+\    - AP[#AP]
+\
+\ Each AP[] has:
+\    - 2 bytes of length (does not include these 2 bytes)
+\    - 6 bytes AP ethernet address
+\    - 1 byte of RSSI
+\    - frame body of probe request or beacon
+\
+\ Assumption: respbuf /respbuf has the data to be put here
+\ =================================================================================
+
+0 instance value scanbuf             \ Save original buffer address
+0 instance value /scanbuf            \ Save original buffer size
+0 value /tsbuf                       \ Current size of data in scanbuf
+: scanbuf-have-room?  ( -- ok? )
+   /respbuf respbuf /802.11n-data-hdr - 9 +  \ Space needed
+   /scanbuf /tsbuf -                         \ Space available
+   <=                         ( ok? )
+;
+: add-scan-response  ( -- )
+   scanbuf-have-room? 0=  if  ." Run out of scan buffer space" cr exit  then
+   scanbuf 2 + c@ 1+ scanbuf 2 + c!  \ Increment #APs
+   /tsbuf scanbuf set-x              \ Get to the next buffer location for the new AP
+   respbuf /respbuf skip-802.11n-mgr-hdr  ( rbuf' rlen' )
+   dup 7 + +xw                       \ length of AP data
+   respbuf d# 10 + /mac-adr +x$      \ AP mac address
+   rx-rssi +xb                       \ RSSI
+   +x$                               \ AP data
+   /x to /tsbuf
+;
+: start-scan-response  ( target-adr target-len -- )
+   to /scanbuf  to scanbuf
+   0 scanbuf set-x
+   0   +xw                  \ 2 unknown bytes
+   0   +xb                  \ #APs
+   /x to /tsbuf
+;
+: restart-scan-response  ( -- )  scanbuf /scanbuf start-scan-response  ;
+: get-scan-actual  ( -- actual )  /tsbuf  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
+

Added: dev/ath9k/paprd.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/paprd.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,428 @@
+purpose: ATH9K PAPRD code
+\ See license at end of file
+
+headers
+hex
+
+: get-streams  ( chainmask -- #1bits )
+   ( val ) 0  3 0  do  over i >> 1 and +  loop  nip
+;
+
+: enable-paprd  ( flag -- )
+   dup  if
+      true to paprd-table-write-done?
+      curchan false set-txpower
+   then
+   dup 1 98f0 reg@!
+   tx-chainmask 2 and  if  dup 1 a8f0 reg@!  then
+   tx-chainmask 4 and  if  dup 1 b9f0 reg@!  then
+   drop
+;
+
+[ifdef] notyet
+0 value paprd-training-power
+d# 32 /n* buffer: paprd-gain-table-entry
+d# 32 buffer: paprd-gain-table-index
+
+: get-training-power-2G  ( -- power )
+   eeprom >modalHeader2G >papdRateMaskHt20 le-l@ d# 25 >> 7 and
+   paprd-target-power over - abs dup ( power delta delta )
+   a3d0 reg@  3f and                 ( power delta delta scale )
+   >  if  2drop -1  exit  then       ( power delta )
+   dup 4 <  if  + 4 -  then          ( power' )
+;
+
+: get-training-power-5G  ( -- power )
+   curchan >ch-freq @ d# 5700 >=  if
+      eeprom >modalHeader5G >papdRateMaskHt20 le-l@ d# 25 >>
+   else
+   curchan >ch-freq @ d# 5400 >=  if
+      eeprom >modalHeader5G >papdRateMaskHt40 le-l@ d# 28 >>
+   else
+      eeprom >modalHeader5G >papdRateMaskHt40 le-l@ d# 25 >>
+   then  then  7 and                ( scale )
+
+   curchan is-ht40?  if  a3dc  else  a3d4  then  reg@ 8 >> 3f and over +
+                                    ( scale power )
+   paprd-target-power over - abs    ( scale power delta )
+   rot >  if  drop -1 exit  then    ( power )
+   tx-chainmask get-streams 2* +    ( power' )
+;
+
+create ctrl0  98f0 , a8f0 , b8f0 ,
+create ctrl1  98f4 , a8f4 , b8f4 ,
+: setup-paprd-single-table  ( -- )
+   curchan is-2GHz?  if  get-training-power-2G  else  get-training-power-5G  then
+   dup 0<  if
+      " ERROR: PAPRD target power out of training range" vtype
+      drop exit
+   then
+   to paprd-training-power
+
+   paprd-ratemask 1ff.ffff 98e4 reg@!
+   paprd-ratemask 1ff.ffff 98e8 reg@!
+   paprd-ratemask-ht40 1ff.ffff 98ec reg@!
+
+   max-txchains 0  do
+      1800.0002 f800.0002 ctrl0 i na+ @ reg@!
+      02d2.0006 0fff.fe07 ctrl1 i na+ @ reg@!
+   loop
+
+   false enable-paprd
+   0003.0c39 0003.ff7f a690 reg@!
+   d# 147 a694 reg!
+   244e.1eb1 2fff.ffff a698 reg@!
+   0064.0190 03ff.ffff a69c reg@!
+   d# 261376 3.ffff 9900 reg@!
+   d# 248079 3.ffff 9904 reg@!
+   d# 233759 3.ffff 9908 reg@!
+   d# 330464 3.ffff 990c reg@!
+   d# 208194 3.ffff 9910 reg@!
+   d# 196949 3.ffff 9914 reg@!
+   d# 185706 3.ffff 9918 reg@!
+   d# 175487 3.ffff 991c reg@!
+;
+
+: get-paprd-gain-table  ( -- )
+   d# 32 0  do
+      a500 i la+ reg@
+      dup paprd-gain-table-entry i na+ !
+      d# 24 >> paprd-gain-table-index i + c!
+   loop
+;
+
+0 value desired-scale
+0 value alpha-therm
+0 value alpha-volt
+0 value therm-cal-val
+0 value volt-cal-val
+0 value therm-val
+0 value volt-val
+: get-desired-gain  ( target-power chain -- desired-gain )
+   0 1 a6a0 reg@!
+   a42a reg@ 3e00.0000 and d# 25 >> to desired-scale
+   a440 reg@ 001f.00ff and dup d# 16 >> to alpha-volt
+                               ff and   to alpha-therm
+   a43c reg@ 0000.ffff and dup 8 >>     to volt-cal-val
+                               ff and   to therm-cal-val
+   a454 reg@ 0000.ffff and dup 8 >>     to volt-val
+                               ff and   to therm-val
+   ( chain ) 1000 * a420 + reg@  ff.0000 and d# 16 >>
+   dup d# 128 >  if  d# 256 -  then  -  ( desired-gain )
+   alpha-therm therm-val therm-cal-val - * d# 128 + 8 >>a -
+   alpha-volt  volt-val  volt-cal-val  - * d#  64 + 7 >>a -
+   desired-scale +                      ( desired-gain' )
+;
+
+: force-tx-gain  ( gain-idx -- )
+   paprd-gain-table-entry swap na+ @       ( gain-entry )
+   00ff.ffff and 1 << 01ff.ffff a458 reg@! ( )
+   0 3f a3f8 reg@!
+;
+
+: setup-paprd-gain-table  ( chain -- )
+   paprd-training-power swap get-desired-gain
+   0 swap  d# 32 0  do             ( idx desired-gain )
+      paprd-gain-table-index i + c@ over >=  if  nip i swap leave  then
+   loop  drop                      ( idx )
+   force-tx-gain
+   0 1 a6a0 reg@!
+;
+
+: init-paprd-table  ( -- )
+   setup-paprd-single-table
+   get-paprd-gain-table
+;
+
+: populate-paprd-single-table  ( chain caldata -- )
+   dup >pa-table 2 pick d# 24 * na+   ( chain caldata patable[chain] )
+   2 pick 1000 * 9920 +               ( chain caldata patable[chain] reg )
+   d# 24 0  do
+      over i na+ @ over i na+ reg!
+   loop  2drop                        ( chain caldata )
+
+   >small-signal-gain over na+ @      ( chain small-signal-gain[chain] )
+   swap 1000 * 98f8 +                 ( small-signal-gain[chain] reg )
+   3ff swap reg@!                     ( )
+   paprd-training-power 3 << 1f8 98f4 reg@!
+   tx-chainmask 2 and  if  paprd-training-power 3 << 1f8 a8f4 reg@!  then
+   tx-chainmask 4 and  if  paprd-training-power 3 << 1f8 b8f4 reg@!  then
+;
+
+: paprd-done?  ( -- done? )  a6a0 reg@ 1 and  ;
+
+\ Arguments from create-paprd-curve
+d# 48 2* /n* buffer: data-buf
+0 value data-l
+0 value data-u
+
+\ Local variables
+d# 24 constant #bin
+#bin /n* constant /binbuf
+/binbuf buffer: theta
+/binbuf buffer: y
+/binbuf buffer: yest
+/binbuf buffer: xest
+/binbuf buffer: xtilde
+/binbuf buffer: b1tmp
+/binbuf buffer: b2tmp
+/binbuf buffer: PAin
+0 value max-idx
+0 value accum-cnt
+0 value G-fxp
+0 value cM
+0 value cI
+0 value cL
+0 value sum-y2
+0 value sum-y4
+0 value xtilde-abs
+0 value Qx
+0 value Qb1
+0 value Qb2
+0 value beta
+0 value alpha
+0 value beta-raw
+0 value alpha-raw
+0 value scale-b
+0 value Qscale-b
+0 value Qbeta
+0 value Qalpha
+0 value order1-5x
+0 value order2-3x
+0 value order1-5x-rem
+0 value order2-3x-rem
+
+\ Local routines
+: data-l@  ( i -- n )  data-l swap na+ @  ;
+: data-u@  ( i -- n )  data-u swap na+ @  ;
+: xtilde@  ( i -- n )  xtilde swap na+ @  ;
+: xtilde!  ( n i -- )  xtilde swap na+ !  ;
+: xest@    ( i -- n )  xest swap na+ @  ;
+: xest!    ( n i -- )  xest swap na+ !  ;
+: theta@   ( i -- n )  theta swap na+ @  ;
+: theta!   ( n i -- )  theta swap na+ !  ;
+: y@       ( i -- n )  y swap na+ @  ;
+: y!       ( n i -- )  y swap na+ !  ;
+: yest@    ( i -- n )  yest swap na+ @  ;
+: yest!    ( n i -- )  yest swap na+ !  ;
+: b1tmp@   ( i -- n )  b1tmp swap na+ @  ;
+: b1tmp!   ( n i -- )  b1tmp swap na+ !  ;
+: b2tmp@   ( i -- n )  b2tmp swap na+ @  ;
+: b2tmp!   ( n i -- )  b2tmp swap na+ !  ;
+: PAin@    ( i -- n )  PAin swap na+ @  ;
+: PAin!    ( n i -- )  PAin swap na+ !  ;
+: scale@   ( n -- scale )  log2 d# 10 - 0 max  ;
+: up>>  ( n scale -- n' )  1 over << 1- rot + swap >>  ;
+: up>>a  ( n scale -- n' )  1 over << 1- rot + swap >>a  ;
+: up/   ( n r -- r' )  tuck 1- + swap /  ;
+
+: (create-paprd-curve)  ( pa-table gain -- error? )
+   y     /binbuf erase   yest   /binbuf erase    theta /binbuf erase  
+   xest  /binbuf erase   xtilde /binbuf erase
+   0 to max-idx
+   #bin 1- 0  do
+      i data-l@ ffff and dup to accum-cnt  d# 16 >  if       \ Enough samples
+         \ sum of tx amplitude
+         i data-l@ d# 16 >> i data-u@ 7ff and  wljoin 5 <<
+         accum-cnt up/ 5 up>>  i 1+ xest!
+         \ sum of rx amplitude to lower bin edge
+         i data-u@ d# 11 >> 1f and  i d# 23 + data-l@ ffff and 5 <<  or 5 <<
+         accum-cnt up/ 5 up>> max-idx 5 << + d# 16 +  i 1+ y!
+         \ sum of angles
+         i d# 23 + data-l@ d# 16 >> i d# 23 + data-u@ 7ff and wljoin
+         dup 400.0000 >=  if  800.0000 -  then  5 <<
+         accum-cnt up/  i 1+ theta!
+         max-idx 1+ to max-idx
+      then
+   loop
+
+   \ Find average theta of first 5 bin and all of those to same value.
+   \ Curve is linear at that range.
+   0  6 0  do  i theta@ +  loop  5 /      ( pa-table gain theta-avg )
+   6 0  do  dup i theta!  loop            ( pa-table gain theta-avg )
+   max-idx 1+ 0  do  i theta@ over - i theta!  loop  drop
+
+   6 xest@ 3 xest@ =  if  2drop true exit  then  \ Low signal gain
+
+   6 y@ 3 y@ - 8 <<  6 xest@ 3 xest@ - up/
+   ?dup 0=  if  2drop true exit  then     \ Prevent divide by 0
+   dup to G-fxp
+
+   0 xest@ 3 xest@ - * d# 256 up/ 3 y@ +  ( pa-table gain y-intercept )
+   max-idx 1+ 0  do  i y@ over - i yest!  loop  drop
+   4 0  do
+      i 5 << dup i yest!
+      ( yest[i] ) 8 <<  G-fxp up/  i xest!
+   loop
+
+   max-idx yest@ ?dup 0=  if  2drop true exit  then
+
+   max-idx xest@ over 8 <<  G-fxp up/ -  swap up/  case
+      0  of  d# 10  endof
+      1  of      9  endof
+      ( otherwise )  8 swap
+   endcase  to cM
+   max-idx 1 >> 7 min to cI
+   max-idx cI - 1+ to cL
+
+   0 to sum-y2  0 to sum-y4  0 to xtilde-abs
+   false cL 0  do               ( pa-table gain false )
+      i cI + yest@ ?dup 0=  if  drop true leave  then
+                  ( pa-table gain false yest[i+cI] )
+      i cI + xest@ over 8 << - G-fxp up/ cM << over up/
+                                         cM << over up/
+                                         cM << over up/
+      dup i xtilde!             ( pa-table gain false yest[i+cI] xtilde[i] )
+      abs  dup xtilde-abs >  if  to xtilde-abs  else  drop  then
+      dup * d# 64 up/           ( pa-table gain false yest[i+cI]**2 )
+      dup sum-y2 + to sum-y2    ( pa-table gain false yest[i+cI]**2 )
+      dup i b2tmp!              ( pa-table gain false yest[i+cI]**2 )
+      dup cL * i b1tmp!         ( pa-table gain false yest[i+cI]**2 )
+      dup * sum-y4 + to sum-y4  ( pa-table gain false )
+   loop
+   if  2drop true exit  then
+
+   0 0  cL 0  do                ( pa-table gain max-b1-abs max-b2-abs )
+      i b1tmp@ sum-y2 - dup i b1tmp!
+      abs rot max swap          ( pa-table gain max-b1-abs' max-b2-abs )
+      sum-y4 i b2tmp@ sum-y2 * - dup i b2tmp!
+      abs max                   ( pa-table gain max-b1-abs max-b2-abs' )
+   loop
+
+   ( max-b2-abs ) scale@ to Qb2
+   ( max-b1-abs ) scale@ to Qb1
+   xtilde-abs scale@ to Qx
+   0 to beta-raw   0 to alpha-raw
+   cL 0  do
+      i xtilde@ Qx  >>a dup i xtilde!   ( pa-table gain xtilde[i] )
+      i b1tmp@  Qb1 >>a dup i b1tmp!    ( pa-table gain xtilde[i] b1tmp[i] )
+      over * beta-raw + to beta-raw     ( pa-table gain xtilde[i] )
+      i b2tmp@  Qb2 >>a dup i b2tmp!    ( pa-table gain xtilde[i] b2tmp[i] )
+      * alpha-raw + to alpha-raw        ( pa-table gain )
+   loop
+
+   sum-y4 3 >>a cL *  sum-y2 dup 3 >>a * 3 << -    ( pa-table gain scale-b )
+   dup abs scale@ dup to Qscale-b >>a              ( pa-table gain scale-b' )
+   ?dup 0=  if  2drop true exit  then  to scale-b  ( pa-table gain )
+
+   beta-raw  dup abs scale@ dup to Qbeta   >>a dup to beta-raw
+   d# 10 << scale-b / to beta
+   alpha-raw dup abs scale@ dup to Qalpha  >>a dup to alpha-raw
+   d# 10 << scale-b / to alpha
+
+   cM 3 * Qx - d# 10 + Qscale-b + dup
+   Qb1 - Qbeta  - 5 /mod  to order1-5x  to order1-5x-rem
+   Qb2 - Qalpha - 3 /mod  to order2-3x  to order2-3x-rem
+
+   #bin 0  do
+      i 5 <<                             ( pa-table gain i*32 )
+      beta over * order1-5x 6 + >>       ( pa-table gain i*32 y5 )
+      4 0  do  over * order1-5x >>  loop ( pa-table gain i*32 y5' )
+      order1-5x-rem >>                   ( pa-table gain i*32 y5' )
+      swap alpha                         ( pa-table gain y5 i*32 y3 )
+      3 0  do  over * order2-3x >>  loop ( pa-table gain y5 i*32 y3' )
+      order2-3x-rem >>                   ( pa-table gain y5 i*32 y3' )
+      swap 8 << G-fxp / + + i PAin!      ( pa-table gain )
+      i 2 >=  if
+         i PAin@ i 1- PAin@ <  if
+            i 1- PAin@ dup i 2 - PAin@ - +  i PAin!
+         then
+      then
+      i PAin@ d# 1400 min  i PAin!
+   loop
+
+   0 to beta-raw  0 to alpha-raw
+   cL 0  do
+      i cI + yest@                       ( pa-table gain yest[i+cI] )
+      i cI + theta@ cM << over up/       ( pa-table gain yest[i+cI] theta~ )
+                    cM << over up/       ( pa-table gain yest[i+cI] theta~' )
+                    cM << swap up/       ( pa-table gain theta~' )
+      dup i b1tmp@ * beta-raw + to beta-raw
+          i b2tmp@ * alpha-raw + to alpha-raw
+   loop
+
+   beta-raw  dup abs scale@ dup to Qbeta  >>a to beta-raw
+   alpha-raw dup abs scale@ dup to Qalpha >>a to alpha-raw
+
+   alpha-raw d# 10 << scale-b / to alpha
+   beta-raw  d# 10 << scale-b / to beta
+   cM 3 * Qx - d# 10 + Qscale-b + 5 + dup
+   Qb1 - Qbeta  - 5 /mod  to order1-5x  to order1-5x-rem
+   Qb2 - Qalpha - 3 /mod  to order2-3x  to order2-3x-rem
+
+   #bin 0  do
+      i 4 <>  if
+         i 4 <  if
+            0                            ( pa-table gain pa-angle )
+         else
+            i 5 <<
+            beta 0>=  if
+               beta over * order1-5x 6 + >>
+            else
+               beta over * order1-5x 6 + up>>a
+            then
+            4 0  do  over * order1-5x >>a  loop
+            order1-5x-rem >>a            ( pa-table gain i*32 y5 )
+
+            swap alpha 0>=  if
+               alpha over * order2-3x >>
+            else
+               alpha over * order2-3x up>>a
+            then
+            over * order2-3x >>a  swap * order2-3x >>a  order2-3x-rem >>a
+                                         ( pa-table gain y5 y3 )
+            + d# -150 max  d# 150 min    ( pa-table gain pa-angle )
+         then
+         dup 7ff and i PAin@ 7ff and d# 11 << or 3 pick i na+ ! \ pa-table[i] !
+         i 5 =  if
+            1+ 1 >> 7ff and  i 1- PAin@ 7ff and d# 11 << or  2 pick i 1- na+ ! \ pa-table[i-1] !
+         else
+            drop
+         then
+      then
+   loop
+
+   G-fxp swap !  drop  false             ( false )
+;
+
+: create-paprd-curve  ( caldata chain -- error? )
+   2dup  d# 24 /n* * swap >pa-table + dup d# 24 /n* erase
+                                   ( caldata chain 'pa-table[chain] )
+   data-buf to data-l
+   data-buf d# 48 /n* + to data-u
+   0 8 a370 reg@!
+   d# 48 0  do  9b00 i na+ reg@  data-l i na+ !  loop
+   8 8 a370 reg@!
+   d# 48 0  do  9b00 i na+ reg@  data-u i na+ !  loop
+
+   rot >small-signal-gain rot +    ( 'pa-table[chain] 'small-signal-gain[chain] )
+   (create-paprd-curve)  if  true exit  then
+   0 1 a6a0 reg@!
+   false
+;
+[then]
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/phy.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/phy.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,1173 @@
+purpose: ATH9K PHY code
+\ See license at end of file
+
+headers
+
+decimal
+0   constant CTRY_DEFAULT
+840 constant CTRY_UNITED_STATES
+hex
+
+0199 constant WORLD
+
+3a constant FCC3_FCCA
+
+10 constant CTL_FCC
+ff constant NO_CTL   
+
+\ targetPowerHTRates 
+0  dup constant HT_TARGET_RATE_0_8_16
+1+ dup constant HT_TARGET_RATE_1_3_9_11_17_19
+1+ dup constant HT_TARGET_RATE_4
+1+ dup constant HT_TARGET_RATE_5
+1+ dup constant HT_TARGET_RATE_6
+1+ dup constant HT_TARGET_RATE_7
+1+ dup constant HT_TARGET_RATE_12
+1+ dup constant HT_TARGET_RATE_13
+1+ dup constant HT_TARGET_RATE_14
+1+ dup constant HT_TARGET_RATE_15
+1+ dup constant HT_TARGET_RATE_20
+1+ dup constant HT_TARGET_RATE_21
+1+ dup constant HT_TARGET_RATE_22
+1+     constant HT_TARGET_RATE_23
+
+\ targetPowerLegacyRates
+0  dup constant LEGACY_TARGET_RATE_6_24
+1+ dup constant LEGACY_TARGET_RATE_36
+1+ dup constant LEGACY_TARGET_RATE_48
+1+     constant LEGACY_TARGET_RATE_54
+
+\ targetPowerCckRates
+0  dup constant LEGACY_TARGET_RATE_1L_5L
+1+ dup constant LEGACY_TARGET_RATE_5S
+1+ dup constant LEGACY_TARGET_RATE_11L
+1+     constant LEGACY_TARGET_RATE_11S
+
+\ ar9300_Rates
+0  dup constant ALL_TARGET_LEGACY_6_24
+1+ dup constant ALL_TARGET_LEGACY_36
+1+ dup constant ALL_TARGET_LEGACY_48
+1+ dup constant ALL_TARGET_LEGACY_54
+1+ dup constant ALL_TARGET_LEGACY_1L_5L
+1+ dup constant ALL_TARGET_LEGACY_5S
+1+ dup constant ALL_TARGET_LEGACY_11L
+1+ dup constant ALL_TARGET_LEGACY_11S
+1+ dup constant ALL_TARGET_HT20_0_8_16
+1+ dup constant ALL_TARGET_HT20_1_3_9_11_17_19
+1+ dup constant ALL_TARGET_HT20_4
+1+ dup constant ALL_TARGET_HT20_5
+1+ dup constant ALL_TARGET_HT20_6
+1+ dup constant ALL_TARGET_HT20_7
+1+ dup constant ALL_TARGET_HT20_12
+1+ dup constant ALL_TARGET_HT20_13
+1+ dup constant ALL_TARGET_HT20_14
+1+ dup constant ALL_TARGET_HT20_15
+1+ dup constant ALL_TARGET_HT20_20
+1+ dup constant ALL_TARGET_HT20_21
+1+ dup constant ALL_TARGET_HT20_22
+1+ dup constant ALL_TARGET_HT20_23
+1+ dup constant ALL_TARGET_HT40_0_8_16
+1+ dup constant ALL_TARGET_HT40_1_3_9_11_17_19
+1+ dup constant ALL_TARGET_HT40_4
+1+ dup constant ALL_TARGET_HT40_5
+1+ dup constant ALL_TARGET_HT40_6
+1+ dup constant ALL_TARGET_HT40_7
+1+ dup constant ALL_TARGET_HT40_12
+1+ dup constant ALL_TARGET_HT40_13
+1+ dup constant ALL_TARGET_HT40_14
+1+ dup constant ALL_TARGET_HT40_15
+1+ dup constant ALL_TARGET_HT40_20
+1+ dup constant ALL_TARGET_HT40_21
+1+ dup constant ALL_TARGET_HT40_22
+1+ dup constant ALL_TARGET_HT40_23
+1+     constant /RateTable
+
+\ This function takes the channel value in MHz and sets
+\ hardware channel value. Assumes writes have been enabled to analog bus.
+\
+\ Actual Expression,
+\
+\ For 2GHz channel,
+\ Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+\ (freq_ref = 40MHz)
+\
+\ For 5GHz channel,
+\ Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
+\ (freq_ref = 40MHz/(24>>amodeRefSel))
+\
+\ For 5GHz channels which are 5MHz spaced,
+\ Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+\ (freq_ref = 40MHz)
+
+: get-chan-centers  ( ch -- ctl-center ext-center synth-center )
+   dup >ch-freq @  over is-ht40? not  if  nip dup dup  exit  then
+   swap >ch-mode @ CH_HT40+ and  if     ( sc )
+      d# 10 +                           ( sc' )
+      dup d# 10 - swap                  ( cc sc )
+      dup d# 10 + swap                  ( cc ec sc )
+   else
+      d# 10 -                           ( sc' )
+      dup d# 10 + swap                  ( cc sc )
+      dup d# 10 - swap                  ( cc ec sc )
+   then  
+;
+
+: set-xpa-bias-level  ( is2GHz? -- )
+   if  modalHeader2G  else  modalHeader5G  then  >xpaBiasLvl c@
+   dup 8 << 300 16288 reg@!
+   2 >> 4 or 7 16290 reg@!
+;
+
+: set-ant-ctrl  ( is2GHz? -- )
+   if  modalHeader2G  else  modalHeader5G  then
+   dup >antCtrlCommon le-l@  ffff and ffff a288 reg@!
+   dup >antCtrlCommon2 le-l@  ff.ffff and ff.ffff a28c reg@!
+   >antCtrlChain dup le-w@  fff and fff a284 reg@!
+   wa1+ dup le-w@  fff and fff b284 reg@!
+   wa1+ le-w@  fff and fff c284 reg@!
+;
+
+: set-drive-strength  ( -- )
+   baseEepHeader >miscConfiguration c@ 1 and  0=  if  exit  then
+   00b6.db40 00ff.ffc0 160c0 reg@!
+   b6db.6da0 ffff.ffe0 160c4 reg@!
+   b680.0000 ff80.0000 160cc reg@!
+;
+
+\ Arguments for interpolate-power
+8 /n* buffer: px
+8 /n* buffer: py
+\ Local variables for interpolate-power
+false value lhave  0 value lx  0 value ly
+false value hhave  0 value hx  0 value hy
+\ Returns the interpolated y value corresponding to the specified x value
+\ from the np ordered pairs of data (px,py).
+\ The pairs do not have to be in any order.
+\ If the specified x value is less than any of the px,
+\ the returned y value is equal to the py for the lowest px.
+\ If the specified x value is greater than any of the px,
+\ the returned y value is equal to the py for the highest px.
+\
+: set-hhave  ( idx -- )
+   px over na+ @ to hx
+   py swap na+ @ to hy
+   true to hhave
+;
+: set-lhave  ( idx -- )
+   px over na+ @ to lx
+   py swap na+ @ to ly
+   true to lhave
+;
+: interpolate-power  ( x #p -- y )
+   \ identify best lower and higher x calibration measurement
+   false to lhave  false to hhave
+   0  do
+      dup px i na+ @ -         ( x dx )
+      dup 0<=  if
+         hhave  if
+            2dup swap hx - >  if  i set-hhave  then
+         else
+            i set-hhave
+         then
+      then
+      dup 0>=  if
+         lhave  if
+            2dup swap lx - <  if  i set-lhave  then
+         else
+            i set-lhave
+         then
+      then  drop
+   loop                         ( x )
+
+   lhave  if
+      hhave  if
+         hx lx =  if  ly  else  dup lx hx ly hy interpolate  then
+      else  ly  then
+   else
+      hhave  if  hy  else  c000.0000  then
+   then  nip
+;
+
+: get-atten-chain  ( ch chain -- atten )
+   over is-2ghz?  if
+      modalHeader2G >xatten1DB + c@  nip
+   else
+      base_ext2 >xatten1DBLow over + c@  if
+         base_ext2 >xatten1DBLow over + c@  py !
+         modalHeader5G >xatten1DB over + c@ py na1+ !
+         base_ext2 >xatten1DBHigh + c@ py 2 na+ !
+         d# 5180 px !  d# 5500 px na1+ !  d# 5785 px 2 na+ !
+         ( ch ) >ch-freq @ 3 interpolate-power
+      else
+         modalHeader5G >xatten1DB + c@  nip
+      then
+   then
+;
+: get-atten-chain-margin  ( ch chain -- atten )
+   over is-2ghz?  if
+      modalHeader2G >xatten1Margin + c@  nip
+   else
+      base_ext2 >xatten1MarginLow over + c@  if
+         base_ext2 >xatten1MarginLow over + c@  py !
+         modalHeader5G >xatten1Margin over + c@ py na1+ !
+         base_ext2 >xatten1MarginHigh + c@ py 2 na+ !
+         d# 5180 px !  d# 5500 px na1+ !  d# 5785 px 2 na+ !
+         ( ch ) >ch-freq @ 3 interpolate-power
+      else
+         modalHeader5G >xatten1Margin + c@  nip
+      then
+   then
+;
+
+create ext-atten-reg  9e18 , ae18 , be18 ,
+: set-atten  ( ch -- )
+   3 0  do
+      dup i get-atten-chain 3f and                          ( ch atten )
+      over i get-atten-chain-margin 1f and d# 12 <<  or     ( ch atten' )
+      1.f03f ext-atten-reg i na+ @ reg@!
+   loop  drop
+;
+
+: set-internal-regulator  ( -- )
+   baseEepHeader >featureEnable c@ 10 and  if
+      0 1 700c reg@!
+      baseEepHeader >swreg le-l@  7008 reg!
+      1 1 700c reg@!
+   else
+      4 0 7048 reg@!   \ Force sw regulator
+   then
+;
+
+: set-board-values  ( ch -- )
+   dup is-2ghz?  set-xpa-bias-level
+   dup is-2ghz?  set-ant-ctrl
+   set-drive-strength
+   ( ch ) set-atten
+   set-internal-regulator
+;
+
+: get-tgt-pwr2G  ( freq idx -- power )
+   3 0  do
+      eeprom >calTarget_freqbin_2G i + c@ fbin2freq2G px i na+ !
+      dup i calTargetPower2G@ py i na+ !
+   loop  drop
+   ( freq ) 3 interpolate-power
+;
+: get-tgt-pwr5G  ( freq idx -- power )
+   8 0  do
+      eeprom >calTarget_freqbin_5G i + c@ fbin2freq5G px i na+ !
+      dup i calTargetPower5G@ py i na+ !
+   loop  drop
+   ( freq ) 8 interpolate-power
+;
+: get-tgt-pwr  ( freq idx is2Ghz? -- power )
+   if  get-tgt-pwr2G  else  get-tgt-pwr5G  then  
+;
+: get-tgt-pwr-2Ght20  ( freq idx  -- power )
+   3 0  do
+      eeprom >calTarget_freqbin_2GHT20 i + c@ fbin2freq2G px i na+ !
+      dup i calTargetPower2GHT20@ py i na+ !
+   loop  drop
+   ( freq ) 3 interpolate-power
+;
+: get-tgt-pwr-5Ght20  ( freq idx  -- power )
+   8 0  do
+      eeprom >calTarget_freqbin_5GHT20 i + c@ fbin2freq5G px i na+ !
+      dup i calTargetPower5GHT20@ py i na+ !
+   loop  drop
+   ( freq ) 8 interpolate-power
+;
+: get-tgt-pwr-ht20  ( freq idx is2Ghz? -- power )  
+   if  get-tgt-pwr-2Ght20  else  get-tgt-pwr-5Ght20  then  
+;
+: get-tgt-pwr-2Ght40  ( freq idx -- power )
+   3 0  do
+      eeprom >calTarget_freqbin_2GHT40 i + c@ fbin2freq2G px i na+ !
+      dup i calTargetPower2GHT40@ py i na+ !
+   loop  drop
+   ( freq ) 3 interpolate-power
+;
+: get-tgt-pwr-5Ght40  ( freq idx -- power )
+   8 0  do
+      eeprom >calTarget_freqbin_5GHT40 i + c@ fbin2freq5G px i na+ !
+      dup i calTargetPower5GHT40@ py i na+ !
+   loop  drop
+   ( freq ) 8 interpolate-power
+;
+: get-tgt-pwr-ht40  ( freq idx is2Ghz? -- power )
+   if  get-tgt-pwr-2Ght40  else  get-tgt-pwr-5Ght40  then  
+;
+: get-tgt-pwr-cck  ( freq idx -- power )
+   2 0  do
+      eeprom >calTarget_freqbin_Cck i + c@ fbin2freq2G  px i na+ !
+      dup i calTargetPowerCck@  py i na+ !
+   loop  drop
+   ( freq ) 2 interpolate-power
+;
+
+\ Variables local to tx-power* routines
+/RateTable buffer: targetPowerValT2
+/RateTable buffer: target_power_val_t2_eep
+
+: pow@      ( idx -- val )  targetPowerValT2 + c@  ;
+: pow-sm@   ( idx -- val )  pow@ 3f and  ;
+: pow!      ( val idx -- )  targetPowerValT2 + c!  ;
+: pow-eep@  ( idx -- val )  target_power_val_t2_eep + c@  ;
+: pow-eep!  ( val idx -- )  target_power_val_t2_eep + c!  ;
+
+: tx-power-reg!  ( -- )
+   0 a458 reg!            \ Reset forced gain
+
+   \ OFDM power per rate set
+   ALL_TARGET_LEGACY_6_24 pow-sm@  dup dup dup bljoin  a3c0 reg! 
+   ALL_TARGET_LEGACY_6_24 pow-sm@  ALL_TARGET_LEGACY_36 pow-sm@
+   ALL_TARGET_LEGACY_48   pow-sm@  ALL_TARGET_LEGACY_54 pow-sm@
+   bljoin a3c0 1 la+ reg!
+
+   \ CCK power per rate set
+   ALL_TARGET_LEGACY_1L_5L pow-sm@  0 over dup bljoin a3c0 2 la+ reg!
+   ALL_TARGET_LEGACY_1L_5L pow-sm@  ALL_TARGET_LEGACY_5S  pow-sm@
+   ALL_TARGET_LEGACY_11L   pow-sm@  ALL_TARGET_LEGACY_11S pow-sm@
+   bljoin a3c0 3 la+ reg!
+
+   \ Power for duplicated frames - HT40
+   ALL_TARGET_LEGACY_1L_5L pow-sm@  ALL_TARGET_LEGACY_6_24 pow-sm@
+   2dup bljoin a3e0 reg!
+
+   \ HT20 power per rate set
+   ALL_TARGET_HT20_0_8_16 pow-sm@  ALL_TARGET_HT20_1_3_9_11_17_19 pow-sm@
+   ALL_TARGET_HT20_4      pow-sm@  ALL_TARGET_HT20_5              pow-sm@
+   bljoin a3c0 4 la+ reg!
+
+   ALL_TARGET_HT20_6  pow-sm@  ALL_TARGET_HT20_7  pow-sm@
+   ALL_TARGET_HT20_12 pow-sm@  ALL_TARGET_HT20_13 pow-sm@
+   bljoin a3c0 5 la+ reg!
+
+   ALL_TARGET_HT20_14 pow-sm@  ALL_TARGET_HT20_15  pow-sm@
+   ALL_TARGET_HT20_20 pow-sm@  ALL_TARGET_HT20_21 pow-sm@
+   bljoin a3c0 9 la+ reg!
+
+   \ Mixed HT20 and HT40 rates
+   ALL_TARGET_HT20_22 pow-sm@  ALL_TARGET_HT20_23 pow-sm@
+   ALL_TARGET_HT40_22 pow-sm@  ALL_TARGET_HT40_23 pow-sm@
+   bljoin a3c0 d# 10 la+ reg!
+
+   \ HT40 power per rate set
+   ALL_TARGET_HT40_0_8_16 pow-sm@  ALL_TARGET_HT40_1_3_9_11_17_19 pow-sm@
+   ALL_TARGET_HT40_4      pow-sm@  ALL_TARGET_HT40_5              pow-sm@
+   bljoin a3c0 6 la+ reg!
+
+   ALL_TARGET_HT40_6  pow-sm@  ALL_TARGET_HT40_7  pow-sm@
+   ALL_TARGET_HT40_12 pow-sm@  ALL_TARGET_HT40_13 pow-sm@
+   bljoin a3c0 7 la+ reg!
+
+   ALL_TARGET_HT40_14 pow-sm@  ALL_TARGET_HT40_15  pow-sm@
+   ALL_TARGET_HT40_20 pow-sm@  ALL_TARGET_HT40_21 pow-sm@
+   bljoin a3c0 d# 11 la+ reg!
+;
+
+: set-target-power ( freq -- )
+   dup d# 4000 <                      ( freq is2GHz? )
+   ALL_TARGET_LEGACY_6_24 3dup swap get-tgt-pwr swap pow!
+   ALL_TARGET_LEGACY_36   3dup swap get-tgt-pwr swap pow!
+   ALL_TARGET_LEGACY_48   3dup swap get-tgt-pwr swap pow!
+   ALL_TARGET_LEGACY_54   3dup swap get-tgt-pwr swap pow!
+
+   over ALL_TARGET_LEGACY_1L_5L tuck get-tgt-pwr-cck swap pow!
+   over LEGACY_TARGET_RATE_5S   tuck get-tgt-pwr-cck swap pow!
+   over ALL_TARGET_LEGACY_11L   tuck get-tgt-pwr-cck swap pow!
+   over ALL_TARGET_LEGACY_11S   tuck get-tgt-pwr-cck swap pow!
+
+   ALL_TARGET_HT20_0_8_16         3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_1_3_9_11_17_19 3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_4              3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_5              3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_6              3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_7              3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_12             3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_13             3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_14             3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_15             3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_20             3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_21             3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_22             3dup swap get-tgt-pwr-ht20 swap pow!
+   ALL_TARGET_HT20_23             3dup swap get-tgt-pwr-ht20 swap pow!
+
+   ALL_TARGET_HT40_0_8_16         3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_1_3_9_11_17_19 3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_4              3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_5              3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_6              3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_7              3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_12             3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_13             3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_14             3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_15             3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_20             3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_21             3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_22             3dup swap get-tgt-pwr-ht40 swap pow!
+   ALL_TARGET_HT40_23             3dup swap get-tgt-pwr-ht40 swap pow!
+
+   2drop
+;
+
+: get-cal-pier  ( freq ipier ichain -- cor temp volt freq )
+   rot d# 4000 >=  if                               ( ipier ichain )
+      2dup refPower5G@ -rot                         \ cor
+      2dup tempMeas5G@ -rot                         \ temp
+      2dup voltMeas5G@ -rot                         \ volt
+      drop eeprom >calFreqPier5G + c@ fbin2freq5G   \ freq
+   else
+      2dup refPower2G@ -rot                         \ cor
+      2dup tempMeas2G@ -rot                         \ temp
+      2dup voltMeas2G@ -rot                         \ volt
+      drop eeprom >calFreqPier2G + c@ fbin2freq2G   \ freq
+   then
+;
+
+\ Local calibration arrays
+3 /n* buffer: lfreq      3 /n* buffer: hfreq
+3 /n* buffer: lcorr      3 /n* buffer: hcorr      3 /n* buffer: corr
+3 /n* buffer: ltemp      3 /n* buffer: htemp      3 /n* buffer: temp
+3 /n* buffer: lvolt      3 /n* buffer: hvolt      3 /n* buffer: volt
+
+: override-power-control  ( freq -- )
+   corr @ ff and d# 16 << ff.0000 a420 reg@!
+   tx-chainmask 2 and  if  corr 1 na+ @ ff and d# 16 << ff.0000 b420 reg@!  then
+   tx-chainmask 4 and  if  corr 2 na+ @ ff and d# 16 << ff.0000 c420 reg@!  then
+
+   \ Enable open loop power control on chip
+   300.0000 dup a40c reg@!
+   tx-chainmask 2 and  if  300.0000 dup b40c reg@!  then
+   tx-chainmask 4 and  if  300.0000 dup c40c reg@!  then
+
+   \ Enable temperature compensation
+   dup d# 4000 <  if
+      tempSlope2G@
+   else
+      tempSlopeLow@  if
+         tempSlopeLow@  py !  tempSlope5G@ py na1+ !  tempSlopeHigh@ py 2 na+ !
+         d# 5180 px !  d# 5500 px na1+ !  d# 5785 px 2 na+ !
+         dup 3 interpolate-power
+      else
+         tempSlope5G@
+      then
+   then    ff a440 reg@!
+   temp c@ ff a43c reg@!
+   drop
+;
+
+: hfreq@  ( ichain -- hfreq )  hfreq swap na+ @  ;
+: lfreq@  ( ichain -- lfreq )  lfreq swap na+ @  ;
+: use-low  ( ichain -- )
+   >r
+   lcorr r@ na+ @ corr r@ na+ !
+   lvolt r@ na+ @ volt r@ na+ !
+   ltemp r@ na+ @ temp r> na+ !
+;
+: use-high  ( ichain -- )
+   >r
+   hcorr r@ na+ @ corr r@ na+ !
+   hvolt r@ na+ @ volt r@ na+ !
+   htemp r@ na+ @ temp r> na+ !
+;
+: set-calibration  ( freq -- )
+   3 0  do  0 lfreq i na+ !  d# 10.0000 hfreq i na+ !  loop
+
+   \ Identify best lower and higher frequency calibration measurements
+   3 0  do
+      dup d# 4000 >=  if  8  else  3  then  0  do
+         dup i j get-cal-pier        ( freq cor temp volt pfreq )
+         dup 5 pick >=  if           ( freq cor temp volt pfreq )
+            dup j hfreq@ <=  if      ( freq cor temp volt pfreq )
+               dup    hfreq j na+ !  over   hvolt j na+ !
+               2 pick htemp j na+ !  3 pick hcorr j na+ !
+            then
+         then                        ( freq cor temp volt pfreq )
+         dup 5 pick <=  if           ( freq cor temp volt pfreq )
+            dup j lfreq@ >=  if      ( freq cor temp volt pfreq )
+               dup    lfreq j na+ !  over   lvolt j na+ !
+               2 pick ltemp j na+ !  3 pick lcorr j na+ !
+            then
+         then  4drop                 ( freq )
+      loop                           ( freq )
+   loop                              ( freq )
+
+   \ Interpolate
+   3 0  do
+      i hfreq@ i lfreq@ =  if              \ Same, pick one
+         i use-low
+      else
+         dup i lfreq@ - d# 1000 <  if      \ Low is good
+            i hfreq@ over - d# 1000 <  if  \ High is good too
+               dup i lfreq@ i hfreq@ lcorr i na+ @ hcorr i na+ @  interpolate  corr i na+ !
+               dup i lfreq@ i hfreq@ lvolt i na+ @ hvolt i na+ @  interpolate  volt i na+ !
+               dup i lfreq@ i hfreq@ ltemp i na+ @ htemp i na+ @  interpolate  temp i na+ !
+            else                           \ Only low is good
+               i use-low
+            then
+         else                              \ Low is not good
+            i hfreq@ over - d# 1000 <  if  \ Only high is good
+               i use-high
+            else                           \ No good value
+               0 corr i na+ !  0 volt i na+ !  0 temp na+ !
+            then
+         then
+      then
+   loop
+
+   override-power-control
+;
+
+: get-direct-edge-power2G  ( ctl edge -- power )  ctlPowerData_2G@  ;
+: get-direct-edge-power5G  ( ctl edge -- power )  ctlPowerData_5G@  ;
+
+: get-indirect-edge-power2G  ( freq ctl edge -- power )
+   d# 63  >r           \ Default to max power
+   2dup ctlPowerData_2G@ c0 and  if
+      2dup ctl_freqbin_2G@ fbin2freq2G 3 pick <  if
+         2dup ctlPowerData_2G@ 3f and  r> drop  >r
+      then
+   then  3drop
+   r>
+;
+: get-indirect-edge-power5G  ( freq ctl edge -- power )
+   d# 63  >r           \ Default to max power
+   2dup ctlPowerData_5G@ c0 and  if
+      2dup ctl_freqbin_5G@ fbin2freq5G 3 pick <  if
+         2dup ctlPowerData_5G@ 3f and  r> drop  >r
+      then
+   then  3drop
+   r>
+;
+: get-max-edge-power2G  ( freq ctl -- power )
+   d# 63 -rot                  ( power freq ctl )
+   4 0  do
+      dup i ctl_freqbin_2G@ fbin2freq2G 2 pick =  if
+         rot drop
+         dup i get-direct-edge-power2G  -rot    ( power' freq ctl )
+         leave
+      else
+         i 0>  if
+            dup i ctl_freqbin_2G@ fbin2freq2G 2 pick >  if
+               rot drop
+               2dup i 1- get-indirect-edge-power2G -rot  ( power' freq ctl )
+               leave
+            then
+         then
+      then
+   loop  2drop
+;
+: get-max-edge-power5G  ( freq ctl -- power )
+   d# 63 -rot                        ( power freq ctl )
+   8 0  do
+      dup i ctl_freqbin_5G@ fbin2freq5G 2 pick =  if
+         rot drop
+         dup i get-direct-edge-power5G -rot  ( power' freq ctl )
+         leave
+      else
+         i 0>  if
+            dup i ctl_freqbin_5G@ fbin2freq5G 2 pick >  if
+               rot drop
+               2dup i 1- get-indirect-edge-power5G -rot  ( power' freq ctl )
+               leave
+            then
+         then
+      then
+   loop  2drop
+;
+: get-max-edge-power  ( freq ctl is2GHz? -- power )
+   if  get-max-edge-power2G  else  get-max-edge-power5G  then
+;
+
+: get-#txchains  ( mask -- )
+   0  3 0  do
+      over i >> 1 and +
+   loop  nip
+;
+create tpScaleReductionTable 0 c, 3 c, 6 c, 9 c, d# 63 c,
+create ctlModesFor11a  CTL_11A , CTL_5GHT20 , CTL_11A_EXT , CTL_5GHT40  ,
+create ctlModesFor11g  CTL_11B , CTL_11G ,    CTL_2GHT20  , CTL_11B_EXT , CTL_11G_EXT , CTL_2GHT40 ,
+0 value 'ctlMode
+0 value tscaledPower
+0 value tchan
+0 value tcfgctl      \ Care about the upper nibble only
+0 value tfreq
+0 value 'ctlIndex
+d# 63 value twiceMaxEdgePower
+0 value tminCtlPower
+0 value tsynth-center  0 value text-center  0 value tctl-center
+: ctlMode@   ( idx -- val )  'ctlMode swap na+ @  ;
+: ctlIndex@  ( idx -- val )  'ctlIndex + c@  ;
+: set-power-array  ( start end -- )
+   1+ swap  do
+      tminCtlPower targetPowerValT2 i + c@ min targetPowerValT2 i + c!
+   loop
+;
+: set-power-per-rate-table  ( ch cfgctl powerLimit twiceMaxRegPower twiceAntRed -- )
+   d# 63 to twiceMaxEdgePower
+   4 pick get-chan-centers  to tsynth-center  to text-center  to tctl-center
+
+   \ Compute TxPower reduction due to antenna gain
+   \ scaledPower is the min of user input power level and regulatory allowed power level
+   4 pick is-2GHz?  if  antennaGain2G@  else  antennaGain5G@  then  - 0 min +  \ maxRegAllowedPower
+   ( powerLimit maxRegAllowedPower ) min   ( ch cfgctl scaledPower )
+   -rot f0 and to tcfgctl  to tchan        ( scaledPower )
+   
+   \ Reduce scaled power by # of chains active to get per chain tx power level
+   txchainmask get-#txchains  case
+      2  of      6 -  endof
+      3  of  d# 10 -  endof
+   endcase  0  max  to tscaledPower
+
+   tchan is-2GHz?  if
+      ctlModesFor11g to 'ctlMode
+      tchan is-ht40?  if  6  else  3  then
+   else
+      ctlModesfor11a to 'ctlMode
+      tchan is-ht40?  if  4  else  2  then
+   then
+
+   \ For MIMO, need to apply regulatory caps individually across
+   \ dynamically running modes: CCK, OFDM, HT20, HT40
+   \
+   \ The outer loop walks through each possible applicable runtime mode.
+   \ The inner loop walks through each ctlIndex entry in EEPROM.
+   \ The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
+   0  do
+      i ctlMode@ dup CTL_5GHT40 = swap CTL_2GHT40 = or
+      if  tsynth-center
+      else  i ctlMode@ 8000 and  if
+         text-center
+      else
+         tctl-center
+      then  then  to tfreq
+
+      \ Walk through each CTL index in eeprom
+      tchan is-2GHz?  if
+         eeprom >ctlIndex_2G to 'ctlIndex  d# 12
+      else
+         eeprom >ctlIndex_5G to 'ctlIndex  9
+      then
+
+      0  do
+         i ctlIndex@ 0=  if  leave  then
+         
+         tcfgctl j ctlMode@ f and or  i ctlIndex@ =
+         tcfgctl j ctlMode@ f and or  i ctlIndex@ f and e0 or =  or  if
+            tfreq i tchan is-2GHz? get-max-edge-power  \ twiceMinEdgePower
+            tcfgCtl e0 =  if
+               twiceMaxEdgePower min  to twiceMaxEdgePower
+            else
+               to twiceMaxEdgePower
+               leave
+            then
+         then
+      loop
+      tscaledPower twiceMaxEdgePower min  to tminCtlPower
+
+      \ Apply CTL mode to correct target power set
+      i ctlMode@  case
+         CTL_11B  of  ALL_TARGET_LEGACY_1L_5L ALL_TARGET_LEGACY_11S  set-power-array  endof
+         CTL_11A  of  ALL_TARGET_LEGACY_6_24 ALL_TARGET_LEGACY_54  set-power-array  endof
+         CTL_11G  of  ALL_TARGET_LEGACY_6_24 ALL_TARGET_LEGACY_54  set-power-array  endof
+         CTL_2GHT20  of  ALL_TARGET_HT20_0_8_16 ALL_TARGET_HT20_23  set-power-array  endof
+         CTL_5GHT20  of  ALL_TARGET_HT20_0_8_16 ALL_TARGET_HT20_23  set-power-array  endof
+         CTL_2GHT40  of  ALL_TARGET_HT40_0_8_16 ALL_TARGET_HT40_23  set-power-array  endof
+         CTL_5GHT40  of  ALL_TARGET_HT40_0_8_16 ALL_TARGET_HT40_23  set-power-array  endof
+      endcase
+   loop
+;
+
+: mcsidx-to-tgtpwridx  ( mcs-idx base-idx -- pwridx )
+   over 7 and            ( mcs-idx base-idx mod-idx )
+   ?dup 0=  if  nip exit  then
+   3 >  if
+      over 3 >> 2 << + swap 7 and 2 - +
+   else
+      1+ nip
+   then                  ( pwridx )
+;
+
+: get-paprd-scale-factor  ( ch -- val )
+   dup is-2ghz?  if
+      modalHeader2G >papdRateMaskHt20 le-l@ d# 25 >>
+   else
+      dup >ch-freq @
+      dup d# 5700 >=  if
+         drop modalHeader5G >papdRateMaskHt20 le-l@ d# 25 >>
+      else
+         modalHeader5G >papdRateMaskHt40 le-l@
+         swap d# 5400 >=  if  d# 28  else  d# 25  then  >>
+      then
+   then  nip
+;
+
+: is-wwr-sku?  ( regd -- flag )
+   dup and 8000 0=           ( regd flag )
+   over WORLD = 	     ( regd flag flag )
+   rot f0 and f0 = or and    ( flag' )
+;
+: get-band-ctl  ( ch -- ctl )
+   regulatory 0=  if  drop SD_NO_CTL exit  then
+   regulatory >reg-country @ 0= 
+   regulatory >reg-cur-rd @ 3fff and  is-wwr-sku?  and  if  drop SD_NO_CTL exit  then
+   dup >ch-band @ BAND_2GHZ =  if  drop regulatory >reg-pair @ >reg-2ghz-ctl @ exit  then
+   dup >ch-band @ BAND_5GHZ =  if  drop regulatory >reg-pair @ >reg-5ghz-ctl @ exit  then
+   drop NO_CTL
+;
+: get-regd-ctl  ( ch -- ctl )
+   dup get-band-ctl
+   over is-b?  if  CTL_11B or  nip exit  then
+   swap is-g?  if  CTL_11G  else  CTL_11A  then  or
+;
+
+0 value cfgCtl
+0 value twiceAntennaReduction
+0 value twiceMaxRegulatoryPower
+0 value powerLimit
+0 value paprd-scale-factor
+0 value min-pwridx
+: (set-txpower)  ( ch -- )
+    dup >ch-freq @ set-target-power
+    baseEepHeader >featureEnable c@ 20 and  if
+       dup is-2GHz?  if  modalHeader2G  else  modalHeader5G  then
+       dup >papdRateMaskHt20 le-l@ 1ff.ffff and to paprd-ratemask
+           >papdRateMaskHt40 le-l@ 1ff.ffff and to paprd-ratemask-ht40
+       dup get-paprd-scale-factor to paprd-scale-factor
+       dup is-ht40?  if  ALL_TARGET_HT40_0_8_16  else  ALL_TARGET_HT20_0_8_16  then
+       to min-pwridx
+       paprd-table-write-done? not  if
+          targetPowerValT2 target_power_val_t2_eep /RateTable move
+          d# 24 0  do
+             i min-pwridx  mcsidx-to-tgtpwridx         ( pwridx )
+             paprd-ratemask 1 i << and  if             ( pwridx )
+                dup pow@ ?dup  if                      ( pwridx pwr )
+                   over pow-eep@ over =  if            ( pwridx pwr )
+                      paprd-scale-factor - swap pow!   ( )
+                   else  2drop  then
+                else  drop  then
+             else  drop  then
+          loop
+       then
+       targetPowerValT2 target_power_val_t2_eep /RateTable move
+    then
+
+    ( ch ) dup get-regd-ctl                  ( ch cfgctl )
+    regulatory >reg-power-limit @ d# 63 min  ( ch cfgctl powerLimit )
+    2 pick >ch-max-power @ 2*                ( ch cfgctl pl 2maxregpwr )
+    3 pick >ch-max-antenna-gain @ 2*         ( ch cfgctl pl 2maxregpwr 2maxag )
+    set-power-per-rate-table                 ( )
+
+    baseEepHeader >featureEnable c@ 20 and  if
+       /RateTable 0  do
+          paprd-ratemask 1 i << and  if
+             i pow@ i pow-eep@ - abs paprd-scale-factor >  if
+                paprd-ratemask 1 i << invert and to paprd-ratemask
+             then
+          then
+       loop
+    then
+
+    0 regulatory >reg-max-power !
+    /RateTable 0  do
+       i pow@ regulatory >reg-max-power @  max
+       regulatory >reg-max-power !
+    loop
+;
+: set-txpower  ( ch test? -- )
+    over (set-txpower)
+    ( test? )  if  drop exit  then
+
+    \ This is the TX power we send back to driver core.
+    \ Since power is rate dependent, use one of the indices
+    \ from the AR9300_Rates enum to select an entry from
+    \ targetPowerValT2[] to report. Currently returns the
+    \ power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
+    \ as CCK power is less interesting (?).
+    dup is-ht40?  if
+       ALL_TARGET_HT40_0_8_16
+    else  dup is-ht20?  if 
+       ALL_TARGET_HT20_0_8_16
+    else
+       ALL_TARGET_LEGACY_6_24
+    then  then                  ( ch i )
+    pow@ regulatory >reg-max-power !
+
+    \ Write target power array to registers
+    tx-power-reg!
+    dup >ch-freq @ set-calibration
+
+    dup is-2GHz?  if
+       is-ht40?  if  ALL_TARGET_HT40_0_8_16  else  ALL_TARGET_HT20_0_8_16  then
+    else
+       is-ht40?  if  ALL_TARGET_HT40_7  else  ALL_TARGET_HT20_7  then
+    then
+    pow@ to paprd-target-power
+;
+
+: chansel-2GHz  ( freq -- freq' )  1.0000 * d# 15 /  ;
+: chansel-5GHz  ( freq -- freq' )    8000 * d# 15 /  ;
+: set-channel  ( ch -- )
+   dup get-chan-centers nip nip         ( ch freq )
+   dup d# 4800 <  if
+      chansel-2GHz  1
+   else
+      chansel-5GHz 1 >>  0
+   then                                 ( ch freq' synth-control )
+   d# 29 << a340 reg!                   \ PHY synthesizer control
+   2 dup 1608c reg@!                    \ Enable long shift
+   ( freq ) 2 <<  4000.0000 or dup 16098 reg!    \ Program synthesizer
+   8000.0000 or 16098 reg!              \ Toggle load synth channel bit
+   to curchan
+;
+
+false value spur-in-range?
+create spur-freq  d# 2420 , d# 2440 , d# 2464 , d# 2480 ,
+: spur-mitigate-mrc-cck  ( ch -- )
+   false to spur-in-range?
+   >ch-freq @
+   4 0  do
+      spur-freq i na+ @ over -       \ cur_bb_spur
+      dup abs d# 10 <  if
+         true to spur-in-range?
+         1c0 3c0 a2c4 reg@!
+         d# 19 << d# 11 / f.ffff and 9 <<
+         4000.00ff or 8000.0000 9fcc reg@!
+         leave
+      else  drop  then
+   loop  drop
+   spur-in-range? 0=  if
+      140 3c0 a2c4 reg@!
+      0 e000.1ffe 9fcc reg@!
+   then
+;
+
+: spur-ofdm-clear  ( -- )
+   0 f000.0000 980c reg@!
+   0 9818 reg!
+   0 1000.0000 982c reg@!
+   0 07fe.0100 981c reg@!
+   0 0000.0fff 9c0c reg@!
+   0 0001.ffff a220 reg@!
+   0 0000.0fff 9c10 reg@!
+;
+
+: spur-ofdm  ( freq-offset spur-subch-sd spur-delta sfreq-sd -- )
+   4000.0000 dup 980c reg@!
+   ( spur-delta sfreq-sd ) d# 20 << or 3fff.ffff 9818 reg@!
+   ( spur-subch-sd )       d# 28 <<    1000.0000 982c reg@!
+   c000.0000 dup 9818 reg@!
+   8000.0000 dup 980c reg@!
+   122 0000.01ff 981c reg@!
+   a208 reg@ 4 and  if  400.0000 dup 981c reg@!  then
+
+   ( freq_offset )  4 << 5 /  dup 0<  if  1-  then  7f and   ( mask-index )
+ 
+   0002.0000 dup 981c reg@!
+   3000.0000 dup 980c reg@!  
+   dup 5 << c or 0000.0fff 9c0c reg@!
+   dup d# 10 << a0 or 0001.ffff a220 reg@!
+       5 << c or 0000.0fff 9c10 reg@!
+   03fc.0000 dup 981c reg@!
+;
+
+: spur-ofdm-work  ( freq-offset ch -- )
+   is-ht40?  if
+      dup 0<  if
+         a204 reg@  10 and  if  0  else  1  then  ( freq-offset spur-subch-sd )
+	 over d# 10 +              ( freq-offset spur-subch-sd spur-freq-sd )
+      else
+         a204 reg@  10 and  if  1  else  0  then  ( freq-offset spur-subch-sd )
+         over d# 10 -              ( freq-offset spur-subch-sd spur-freq-sd )
+      then
+      2 pick d# 17 <<      ( freq-offset spur-subch-sd spur-freq-sd spur-delta-phase )
+   else
+      0 over dup d# 18 <<  ( freq-offset spur-subch-sd spur-freq-sd spur-delta-phase )
+   then
+   ( spur-delta-phase )  5 / f.ffff and swap
+   ( spur-freq-sd )  d# 11 /    3ff and
+   spur-ofdm               ( )
+;
+
+0 value range
+0 value synth-freq
+: spur-mitigate-ofdm2G  ( ch -- )
+   modalHeader2G >spurChans c@ 0=  if  drop exit  then
+
+   dup >ch-freq @              ( ch freq )
+   over is-ht40?  if
+      d# 10  a204 reg@ 10 and  if  +  else  -  then
+      d# 19
+   else
+      d# 10
+   then  to range  to synth-freq
+   spur-ofdm-clear
+
+   5 0  do                     ( ch )
+      modalHeader2G >spurChans i + c@ ?dup 0=  if  leave  then
+      ( spurChans ) fbin2freq2G synth-freq -   \ freq_offset
+      dup abs  range <  if  over spur-ofdm-work  else  drop  then
+   loop  drop
+;
+: spur-mitigate-ofdm5G  ( ch -- )
+   modalHeader5G >spurChans c@ 0=  if  drop exit  then
+
+   dup >ch-freq @              ( ch freq )
+   over is-ht40?  if
+      d# 10  a204 reg@ 10 and  if  +  else  -  then
+      d# 19
+   else
+      d# 10
+   then  to range  to synth-freq
+   spur-ofdm-clear
+
+   5 0  do                     ( ch )
+      modalHeader5G >spurChans i + c@ ?dup 0=  if  leave  then
+      ( spurChans ) fbin2freq5G synth-freq -   \ freq_offset
+      dup abs  range <  if  over spur-ofdm-work  else  drop  then
+   loop  drop
+;
+: spur-mitigate-ofdm  ( ch -- )
+   dup is-5GHz?  if  spur-mitigate-ofdm5G  else  spur-mitigate-ofdm2G  then
+;
+
+: spur-mitigate  ( ch -- )
+   dup spur-mitigate-mrc-cck
+       spur-mitigate-ofdm
+;
+
+: compute-pll-control  ( ch -- pll )
+   ?dup 0=  if  1400 exit  then
+   142c
+   over is-half-rate?  if  4000 or  then
+   swap is-quarter-rate?  if  8000 or  then
+;
+
+: set-11nmac2040  ( -- )
+   conf-is-ht40?  if  1  else  0  then
+   8318 reg!
+;
+
+: set-ch-regs  ( ch -- )
+   a204 reg@ 3c0 or
+   over is-ht40?  if
+      4 or  over >ch-mode @ CH_HT40+ and  if  10 or  then
+   then
+   400 invert and  a204 reg!
+   is-ht40?  if  1  else  0  then  8318 reg!
+   50.0000 64 reg!
+   f.0000  6c reg!
+;
+
+: init-bb  ( ch -- )
+   1 a20c reg!             \ Activate PHY
+   a254 reg@  3fff and
+   swap is-b?  if  4 * d# 22 / else  d# 10 /  then
+   d# 100 + us
+;
+
+: set-chain-masks  ( tx rx -- )
+   dup 5 =  if  40 dup a34c reg@!  then
+   dup 1 3 between over  5 = or  over 7 =  or  if
+      dup a2a0 reg!  dup a2c0 reg!
+   then  drop
+
+   hw-caps HW_CAP_APM and  if  3  else  dup  then  832c reg!
+   5 =  if  40 dup a34c reg@!  then
+;
+
+: override-ini  ( -- )
+   0200.0020 dup 8048 reg@!
+   2.0008 40 8344 reg@!
+;
+
+0 value array-#col
+: array@  ( col array row -- data )  array-#col /n* * +  swap /n* + @  ;
+: array-reg!  ( col array #row #col -- )
+   to array-#col
+   ( #row ) 0  do             ( col array )
+      2dup i array@           ( col array val )
+      0 2 pick i array@       ( col array val reg )
+      reg!  1 us              ( col array )
+   loop  2drop
+;
+
+: process-ini  ( ch -- )
+   dup >ch-mode @ >r
+   r@ CH_A =  r@ CH_A_HT20 = or  if  1 
+   else  r@ CH_A_HT40+ =  r@ CH_A_HT40- =  or  if  2
+   else  r@ CH_G =  r@ CH_G_HT20 = or  r@ CH_B =  or  if  4
+   else  3  then then then       ( modesIdx )
+   r> drop
+
+   1   array-soc-preamble    soc-preamble-#row    2 array-reg!
+   1   array-mac-core        mac-core-#row        2 array-reg!
+   1   array-bb-core         bb-core-#row         2 array-reg!
+   1   array-radio-core      radio-core-#row      2 array-reg!
+   dup array-soc-postamble   soc-postamble-#row   5 array-reg!
+   dup array-mac-postamble   mac-postamble-#row   5 array-reg!
+   dup array-bb-postamble    bb-postamble-#row    5 array-reg!
+   dup array-radio-postamble radio-postamble-#row 5 array-reg!
+   1   array-rx-gain         rx-gain-#row         2 array-reg!
+   dup array-tx-gain         tx-gain-#row         5 array-reg!
+
+   over is-a-fast?  if
+      dup  array-fast-clk fast-clk-#row 3 array-reg!
+   then  drop
+
+   override-ini
+   dup set-ch-regs
+   txchainmask rxchainmask set-chain-masks
+
+   ( ch ) false set-txpower
+;
+
+: set-rfmode  ( ch -- )
+   ?dup 0=  if  exit  then
+   dup  is-b?  over is-g? or  if  4  else  0  then
+   swap is-a-fast?  if  104 or  then
+   a208 reg!
+;
+
+: mark-phy-inactive  ( -- )  0 a20c reg!  ; 
+
+: log2  ( n -- log2-of-n )
+   0  begin        ( n log )
+      swap 1 >>    ( log n' )
+   ?dup  while     ( log n' )
+      swap 1+      ( n' log' )
+   repeat          ( log )
+;
+: get-delta-slope-vals  ( coef -- man exp )
+   dup log2                          ( coef exp )
+   d# 38 swap -                      ( coef exp' )
+   tuck d# 23 swap - 1 swap << +     ( exp man )
+   d# 24 2 pick - >>                 ( exp man' )
+   swap d# 16 -                      ( man exp' )
+;
+
+: set-delta-slope  ( ch -- )
+   6400.0000                              ( ch coef )
+   over is-half-rate?     if  1 >>  then  ( ch coef' )
+   over is-quarter-rate?  if  2 >>  then  ( ch coef' )
+
+   \ ALGO -> coef = 1e8/fcarrier*fclock/40
+   swap get-chan-centers  nip nip /       ( coef' )
+   dup get-delta-slope-vals               ( coef man exp )
+   f and d# 13 << swap  7fff and d# 17 << or  ffff.e000  9808 reg@!
+
+   \ For short GI, scaled coeff is 9/10 that of normal coeff
+   9 * d# 10 /                            ( coef' )
+   get-delta-slope-vals                   ( man exp )
+   f and swap 7fff and 4 << or 7.ffff  9c14 reg@!
+;
+
+: rfbus-req?  ( -- ok? )
+   1 a23c reg!          \ Enable RF bus request
+   1 1 a240 wait-hw
+;
+
+: rfbus-done  ( -- )
+   a254 reg@ 3fff and      ( ch rx-delay )
+   curchan is-b?  if  4 * d# 22 /  else  d# 10 /  then
+   d# 100 + us
+   0 a23c reg!
+;
+
+: set-diversity  ( set? -- )
+   if  2000  else  0  then  2000 9fc0 reg@!
+;
+
+: set-radar  ( -- )
+   e400.a611 9834 reg!
+   0008.ccff 9838 reg!
+   0 4000 983c reg@!
+;
+
+: config-bb-watchdog  ( timeout -- )
+   ?dup  if
+      d# 10000 min            \ bound limit to 10 secs
+      4 6 a7c8 reg@!
+      \ The time unit for watchdog event is 2^15 44/88MHz cycles.
+      \ For HT20 we have a time unit of 2^15/44 MHz = .74 ms per tick
+      \ For HT40 we have a time unit of 2^15/88 MHz = .37 ms per tick
+      d# 100 *
+      curchan is-ht40?  if  d# 37  else  d#  74  then  /  fffc and
+      ffff.0002 or a7c4 reg!
+   else
+      0 6 a7c8 reg@!
+      0 3 a7c4 reg@!
+   then
+;
+
+: read-bb-watchdog  ( -- )
+   0 8 a7c0 reg@!           \ Reset and clear watchdog status
+;
+
+: set-tx-gain-table  ( -- )
+   eeprom >baseEepHeader >txrxgain c@ 4 >>  case
+      0  of  array-tx-gain-lowest to array-tx-gain
+             tx-gain-lowest-#row  to tx-gain-#row
+             endof
+      1  of  array-tx-gain-hi to array-tx-gain
+             tx-gain-hi-#row  to tx-gain-#row
+             endof
+      2  of  array-tx-gain-low to array-tx-gain
+             tx-gain-low-#row  to tx-gain-#row
+             endof
+      3  of  array-tx-gain-hi to array-tx-gain
+             tx-gain-hi-#row  to tx-gain-#row
+             endof
+   endcase
+;
+
+: set-rx-gain-table  ( -- )
+   eeprom >baseEepHeader >txrxgain c@ f and  case
+      0  of  array-rx-gain-common to array-rx-gain
+             rx-gain-common-#row  to rx-gain-#row
+             endof
+      1  of  array-rx-gain-wo-xlna to array-rx-gain
+             rx-gain-wo-xlna-#row  to rx-gain-#row
+	     endof
+   endcase
+;
+
+: init-mode-gain-tables  ( -- )
+   set-tx-gain-table
+   set-rx-gain-table
+;
+
+: config-pci-powersave  ( restore? -- )
+   0=  if
+      8.0000 dup 4014 reg@!    \ Allow forcing of PCIe core into L1 state
+      WARegVal 4004 reg!
+   then
+
+   1 array-pcie-serdes pcie-serdes-#row 2 array-reg!
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/reg.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/reg.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,212 @@
+purpose: PCI access and misc words for ATH9K driver
+\ See license at end of file
+
+headers
+hex
+
+" wlan" device-name
+" wireless-network" device-type
+
+168c constant ATHEROS_ID
+true value in-little-endian?
+variable opencount 0 opencount !
+
+0 value chipbase
+2.0000 value /regs
+: reg@  ( r -- v )  chipbase + rl@  ;
+: reg!  ( v r -- )  chipbase + rl!  ;
+: reg@!  ( v m r -- )  dup reg@  rot invert and  rot or  swap reg!  ;
+
+: my-b@  ( offset -- b )  my-space +  " config-b@" $call-parent  ;
+: my-b!  ( b offset -- )  my-space +  " config-b!" $call-parent  ;
+
+: my-w@  ( offset -- w )  my-space +  " config-w@" $call-parent  ;
+: my-w!  ( w offset -- )  my-space +  " config-w!" $call-parent  ;
+
+: map-regs  ( -- )
+   0 0 my-space h# 0200.0010 + /regs " map-in" $call-parent to chipbase
+   4 my-w@  6 or  4 my-w!
+;
+: unmap-regs  ( -- )
+   4 my-w@  6 invert and  4 my-w!
+   chipbase /regs " map-out" $call-parent
+;
+
+: dma-sync     ( virt phys size -- )         " dma-sync" $call-parent     ;
+: dma-alloc    ( size -- virt )              " dma-alloc" $call-parent    ;
+: dma-free     ( virt size -- )              " dma-free" $call-parent     ;
+: dma-map-in   ( virt size cache? -- phys )  " dma-map-in" $call-parent   ;
+: dma-map-out  ( virt phys size -- )         " dma-map-out" $call-parent  ;
+
+\ Little endian operations
+: le-w@   ( a -- w )   dup c@ swap ca1+ c@ bwjoin  ;
+: le-w!   ( w a -- )   >r  wbsplit r@ ca1+ c! r> c!  ;
+: le-l@   ( a -- l )   >r  r@ c@  r@ 1+ c@  r@ 2+ c@  r> 3 + c@  bljoin  ;
+: le-l!   ( l a -- )   >r lbsplit  r@ 3 + c!  r@ 2+ c!  r@ 1+ c!  r> c!  ;
+
+\ Big endian operations
+: be-w@   ( a -- w )   dup ca1+ c@ swap c@ bwjoin  ;
+: be-w!   ( w a -- )   >r wbsplit r@ c! r> ca1+ c!  ;
+: be-l@   ( a -- l )   dup wa1+ be-w@ swap be-w@ wljoin  ;
+: be-l!   ( l a -- )   >r lwsplit r@ be-w! r> wa1+ be-w!  ;
+
+\ Misc helpers
+: $, ( adr len -- )  here over allot  swap move  ;
+: 4drop  ( n1 n2 n3 n4 -- )  2drop 2drop  ;
+: cdump  ( adr len -- )  bounds  ?do  i c@  3 u.r  loop  ;
+: $=  ( $1 $2 -- flag )
+   rot tuck <>  if  3drop false exit  then
+   comp 0=
+;
+: /string  ( adr len n -- )  tuck  2swap +  -rot -  ;
+: round-up  ( n align -- n' )  1- tuck + swap invert and  ;
+
+\ Debug helpers
+false instance value debug?
+defer vemit             ' drop  to vemit
+defer vtype             ' 2drop to vtype
+defer vcdump            ' 2drop to vcdump
+: (vtype)   ( adr len -- )  type  cr  ;
+: (vcdump)  ( adr len -- )  cdump cr  ;
+: enable-emit  ( -- )
+   ['] emit     to vemit
+   ['] (vtype)  to vtype
+   ['] (vcdump) to vcdump
+;
+: disable-emit  ( -- )
+   ['] drop to vemit
+   ['] 2drop to vtype
+   ['] 2drop to vcdump
+;
+
+\ Response wait time (ms)
+d# 1,000 constant resp-wait-short
+d# 1,500 constant resp-wait-long
+d# 5,000 constant resp-wait-xlong
+resp-wait-short instance value resp-wait
+
+\ MAC addresses
+6 constant /mac-adr
+create mac-adr 0 c, 3 c, 7f c, 0 c, 0 c, 0 c, 0 c, 0 c,
+: mac-adr$  ( -- $ )  mac-adr /mac-adr  ;
+
+/mac-adr buffer: target-mac
+: target-mac$  ( -- $ )  target-mac /mac-adr  ;
+
+\ Data rates
+d# 12  constant #rates
+create supported-rates 02 c, 04 c, 0b c, 16 c, 0c c, 12 c, 18 c, 24 c,
+                       30 c, 48 c, 60 c, 6c c,
+#rates buffer: common-rates
+
+\ WPA/WPA2 keys
+0 value ktype                   \ Key type
+0 value ctype-g                 \ Group (multicast) cipher type
+0 value ctype-p                 \ Pairwise (unicast) cipher type
+
+\ ktype values
+0 constant kt-wep
+1 constant kt-wpa
+2 constant kt-wpa2
+h# ff constant kt-none
+
+d# 16 constant /aes
+d# 32 constant /tkip
+/tkip buffer: g-tkip
+/aes  buffer: g-aes
+/tkip buffer: p-tkip
+/aes  buffer: p-aes
+
+\ ctype-x values
+0 constant ct-none
+1 constant ct-tkip
+2 constant ct-aes
+
+\ hardware key type values
+0 constant KEYTABLE_TYPE_40
+1 constant KEYTABLE_TYPE_104
+3 constant KEYTABLE_TYPE_128
+4 constant KEYTABLE_TYPE_TKIP
+5 constant KEYTABLE_TYPE_AES   \ DO NOT use this
+6 constant KEYTABLE_TYPE_CCM   \ AES (CCM)
+7 constant KEYTABLE_TYPE_CLR
+
+1 value grp-idx              \ groupwise key table idx
+0 value pair-idx             \ pairwise key table idx
+0 value wep-idx              \ wep key table idx (0-3)
+
+d# 16 buffer: wep1  0 constant /wep1
+d# 16 buffer: wep2  0 constant /wep2
+d# 16 buffer: wep3  0 constant /wep3
+d# 16 buffer: wep4  0 constant /wep4
+: wep1$  ( -- $ )  wep1 /wep1  ;
+: wep2$  ( -- $ )  wep2 /wep2  ;
+: wep3$  ( -- $ )  wep3 /wep3  ;
+: wep4$  ( -- $ )  wep4 /wep4  ;
+: wep-key$  ( idx -- $ )
+   case
+      0  of  wep1 /wep1  endof
+      1  of  wep2 /wep2  endof
+      2  of  wep3 /wep3  endof
+      3  of  wep4 /wep4  endof
+      ( otherwise )  0 0 rot
+   endcase
+;
+external
+: set-wep  ( wep4$ wep3$ wep2$ wep1$ idx -- ok? )
+   to wep-idx
+   dup to /wep1 wep1 swap move
+   dup to /wep2 wep2 swap move
+   dup to /wep3 wep3 swap move
+   dup to /wep4 wep4 swap move
+   true
+;
+: set-key-type  ( ctp ctg ktype -- )  to ktype  to ctype-g  to ctype-p  ;
+headers
+: key-wep?    ( -- wep? )   ktype kt-wep =  ;
+: key-wpa?    ( -- wpa? )   ktype kt-wpa =  ;
+: key-wpa2?   ( -- wpa2? )  ktype kt-wpa2 =  ;
+: key-wpax?   ( -- wpa|wap )  key-wpa? key-wpa2? or  ;
+: pkey-tkip?  ( -- tkip? )  key-wpax?  if  ctype-p ct-tkip =  else false  then  ;
+: gkey-tkip?  ( -- tkip? )  key-wpax?  if  ctype-g ct-tkip =  else false  then  ;
+: pkey-aes?   ( -- tkip? )  key-wpax?  if  ctype-p ct-aes  =  else false  then  ;
+: gkey-aes?   ( -- tkip? )  key-wpax?  if  ctype-g ct-aes  =  else false  then  ;
+
+false value wep-enabled?
+false value gkey-enabled?
+false value pkey-enabled?
+: key-enabled?  ( -- flag )  wep-enabled? pkey-enabled?  or  ;
+
+\ OUI values (big-endian)
+h# 0050.f201 constant wpa-tag                   \ WPA tag
+h# 0050.f202 constant moui-tkip                 \ WPA cipher suite TKIP
+h# 0050.f204 constant moui-aes                  \ WPA cipher suite AES
+h# 000f.ac02 constant oui-tkip                  \ WPA2 cipher suite TKIP
+h# 000f.ac04 constant oui-aes                   \ WPA2 cipher suite AES
+h# 000f.ac02 constant aoui                      \ WPA2 authentication suite
+h# 0050.f202 constant amoui                     \ WPA authentication suite
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/rx.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/rx.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,397 @@
+purpose: ATH9K RX code
+\ See license at end of file
+
+headers
+hex
+
+false instance value use-promiscuous?
+
+\ rx data structures:
+\   - an array of rx-buf
+\   - a link list of free rx-buf starting at frx-head,
+\     add and remove from frx-head
+\   - a link list of completed high priority rx-buf,
+\     read from hrx-head (oldest packet), add to hrx-end (newest packet)
+\   - a link list of completed low priority rx-buf,
+\     read from lrx-head, add to lrx-end
+\   - lrx-cur points to the current rx-buf in reg 78
+\   - hrx-cur points to the current rx-buf in reg 74
+
+d# 512 constant #rx-bufs
+
+struct
+   /n field >rx-next
+   /n field >rx-buf
+   /n field >rx-buf-phy
+constant /rx-list
+/rx-list #rx-bufs * buffer: rx-list
+: 'rx-list  ( idx -- adr )
+   dup #rx-bufs >=  if  drop 0  else  /rx-list * rx-list +  then
+;
+
+struct
+   4 field >rxs-info
+   4 field >rxs-stat1
+   4 field >rxs-stat2
+   4 field >rxs-stat3
+   4 field >rxs-stat4
+   4 field >rxs-stat5
+   4 field >rxs-stat6
+   4 field >rxs-stat7
+   4 field >rxs-stat8
+   4 field >rxs-stat9
+   4 field >rxs-stat10
+   4 field >rxs-stat11
+   0 field >rxs-data            \ Start of received data
+constant /rx-stat
+
+rx-bufsize 400 round-up constant /rx-buf
+#rx-bufs /rx-buf * constant /rx-bufs
+/rx-stat buffer: rx-stat-save
+
+: (rx-rssi)  ( -- rssi )  rx-stat-save >rxs-stat5 le-l@ d# 24 >>  ;
+' (rx-rssi) to rx-rssi
+\ After rx buffer is filled, queue it for later read operations.
+\ However, we should take care of antenna issue now, theoretically.
+\ But empirically a bad idea.
+: ?change-ant  ( node -- )
+   >rx-buf @ >rxs-stat4 le-l@ 8 >> dup rx-defant <>  if
+      rs-otherant-cnt 1+ dup 3 >  if  drop set-defant 0  else  nip  then
+   else
+      drop 0
+   then  to rs-otherant-cnt
+;
+
+0 value rx-bufs
+0 value rx-bufs-phy
+0 value frx-head
+0 value hrx-head   0 value hrx-end
+0 value lrx-head   0 value lrx-end
+0 value lrx-cur    0 value hrx-cur
+
+\ Statistics:  #hrx + #lrx + #frx should equal #rx-buf
+0 value #hrx  0 value #lrx  0 value #frx
+0 value rxs-stat11       \ OR all the >rxs-stat11 values
+: rxs-stat11!  ( n -- )  rxs-stat11 or to rxs-stat11  ;
+: #hrx++  ( -- )  #hrx 1+ to #hrx  ;
+: #hrx--  ( -- )  #hrx 1- to #hrx  ;
+: #lrx++  ( -- )  #lrx 1+ to #lrx  ;
+: #lrx--  ( -- )  #lrx 1- to #lrx  ;
+: #frx++  ( -- )  #frx 1+ to #frx  ;
+: #frx--  ( -- )  #frx 1- to #frx  ;
+
+\ Statistics for lrx:
+\ #rx  = total rx received  (#rx = #rxq + #rxe)
+\ #rxq = total rx deemed ok to queue
+\ #rxe = total rx deemed not ok to queue
+\ #rxd = total rx dequeued  (#rxd <= #rxq)
+\ #rxf = total rx freed (#rxd+#rxe <= #rxf <= #rx)
+0 value #rx   0 value #rxq  0 value #rxe  0 value #rxd  0 value #rxf
+: #rx++   ( -- )  #rx  1+ to #rx   ;
+: #rxq++  ( -- )  #rxq 1+ to #rxq  ;
+: #rxe++  ( -- )  #rxe 1+ to #rxe  ;
+: #rxd++  ( -- )  #rxd 1+ to #rxd  ;
+: #rxf++  ( -- )  #rxf 1+ to #rxf  ;
+: init-rx-stat  ( -- )  0 to #rx   0 to #rxq  0 to #rxe  0 to #rxd  0 to #rxf  ;
+: .rx-stat  ( -- )
+   ." #rx = " #rx .d
+   ." #rxq = " #rxq .d
+   ." #rxe = " #rxe .d
+   ." #rxd = " #rxd .d
+   ." #rxf = " #rxf .d cr
+;
+
+: 'rx-buf      ( idx -- adr )  /rx-buf * rx-bufs +  ;
+: 'rx-buf-phy  ( idx -- adr )  /rx-buf * rx-bufs-phy +  ;
+
+: free-rx-bufs  ( -- )
+   rx-bufs 0=  if  exit  then
+   rx-bufs rx-bufs-phy /rx-bufs dma-map-out
+   rx-bufs /rx-bufs dma-free
+   0 to rx-bufs
+;
+: alloc-rx-bufs  ( -- )
+   rx-bufs  if  exit  then
+   /rx-bufs dma-alloc to rx-bufs
+   rx-bufs  /rx-bufs  false dma-map-in to rx-bufs-phy
+;
+: init-rx-lists  ( -- )
+   rx-list to frx-head
+   #rx-bufs 0  do
+      i 'rx-list                        ( 'list[i] )
+      i 1+ 'rx-list over >rx-next !     ( 'list[i] )
+      i 'rx-buf     over >rx-buf  !     ( 'list[i] )
+      i 'rx-buf-phy swap >rx-buf-phy !  ( )
+   loop
+   0 to lrx-head  0 to lrx-end
+   0 to hrx-head  0 to hrx-end
+   0 to lrx-cur   0 to hrx-cur
+\   0 to #hrx  0 to #lrx  #rx-bufs to #frx
+;
+: init-rx-bufs  ( -- )
+   alloc-rx-bufs
+   init-rx-lists
+;
+
+\ After rx buffer is read, put it back into the free rx-list
+: free-rx  ( rx-list -- )  #rxf++  frx-head over >rx-next !  to frx-head  #frx++  ;
+
+\ Use to get the next free rx buffer in the rx-list
+: next-frx  ( -- rx-list )
+   frx-head 0=  if  debug-me abort" Run out of free rx buffers"  then
+   frx-head dup >rx-next @ to frx-head
+   0 over >rx-next !
+   #frx--
+;
+: node>pbuf  ( rx-list -- padr )
+   dup 0=  if  debug-me abort" rx-list address is 0"  then
+   dup >rx-buf-phy @
+   swap >rx-buf @  /rx-stat erase   \ Clear rx status
+;
+: next-hrx  ( -- rx-list )  next-frx dup to hrx-cur  ;
+: next-lrx  ( -- rx-list )  next-frx dup to lrx-cur  ;
+
+: (queue-hrx)  ( -- )
+   #hrx++
+   ascii ` vemit
+   hrx-end 0=  if
+      hrx-cur dup  to hrx-end  to hrx-head
+   else
+      hrx-cur dup  hrx-end >rx-next !  to hrx-end
+   then
+;
+: (queue-lrx)  ( -- )
+   #lrx++
+   ascii . vemit
+   lrx-end 0=  if
+      lrx-cur dup  to lrx-end  to lrx-head
+   else
+      lrx-cur dup  lrx-end >rx-next !  to lrx-end
+   then
+;
+: (restart-hrx)  ( rx-list -- )  node>pbuf 74 reg!  ;
+: (restart-lrx)  ( rx-list -- )  node>pbuf 78 reg!  ;
+: restart-hrx  ( -- )  next-hrx  (restart-hrx)  ;
+: restart-lrx  ( -- )  next-lrx  (restart-lrx)  ;
+: done-rx?  ( adr -- done? )  wa1+ le-w@ ATHEROS_ID =  ;
+: ok-rx?  ( adr -- ok? )  >rxs-stat11 c@ dup rxs-stat11! 3 and 3 =  ;
+: queue-hrx  ( -- )
+   hrx-cur 0=  if  exit  then
+   hrx-cur >rx-buf @ 
+   dup done-rx?  if
+      ok-rx?  if
+         (queue-hrx)  restart-hrx
+      else
+         ascii ? vemit
+         hrx-cur (restart-hrx)
+      then
+   else  drop  then
+;
+: queue-lrx  ( -- )
+   lrx-cur 0=  if  exit  then
+   lrx-cur >rx-buf @
+   dup done-rx?  if
+      #rx++
+      ok-rx?  if
+         (queue-lrx)  restart-lrx
+         #rxq++ 
+      else
+         #rxe++ ascii ? vemit
+         lrx-cur (restart-lrx)
+      then
+   else  drop  then
+;
+: queue-rx   ( -- )  queue-hrx  queue-lrx  ;
+
+\ Retrieve rx buffer for read operations
+\ The descriptor is not freed here.  When the caller is done with the buffer
+\ it needs to call free-rx to return the descriptor/buffer pair to the free list.
+
+: (deque-hrx)  ( -- node adr len )
+   #hrx--
+   hrx-head dup >rx-buf @                      ( node buf )
+   dup rx-stat-save /rx-stat move              \ Save the rx status descriptor
+   dup >rxs-data                               ( node buf adr )
+   swap >rxs-stat2 le-l@ fff and               ( node adr len )
+   4 -
+   hrx-head >rx-next @  dup to hrx-head
+   0=  if  0 to hrx-end  then
+;
+: (deque-lrx)  ( -- node adr len )
+   #lrx--  #rxd++
+   lrx-head dup >rx-buf @                      ( node buf )
+   dup rx-stat-save /rx-stat move              \ Save the rx status descriptor
+   dup >rxs-data                               ( node buf adr )
+   swap >rxs-stat2 le-l@ fff and               ( node adr len )
+   4 -
+   lrx-head >rx-next @  dup to lrx-head
+   0=  if  0 to lrx-end  then
+;
+: deque-rx  ( -- false | node adr len true )
+   hrx-head  if  (deque-hrx) true  else  false  then
+   ?dup 0=  if
+      lrx-head  if  (deque-lrx) true  else  false  then
+   then
+;
+: flush-rxq  ( -- )
+   begin  queue-rx deque-rx  while  2drop free-rx  repeat  
+   0 to rs-otherant-cnt
+;
+
+: calc-rxfilter  ( -- filter )
+   get-rxfilter RX_FILTER_PHYERR RX_FILTER_PHYRADAR or and
+   RX_FILTER_UCAST or RX_FILTER_BCAST or ( RX_FILTER_MCAST or )
+   RX_FILTER_BEACON or
+   use-promiscuous?  if  RX_FILTER_PROM or  then
+;
+
+: init-opmode  ( -- )
+   calc-rxfilter
+   set-rxfilter
+   set-bssidmask
+   set-opmode
+   -1 -1 set-mcastfilter
+;
+
+: start-pcu-receive  ( scanning? -- )
+   enable-mib-counters
+   reset-ani
+   0 200.0020 8048 reg@!
+;
+
+true value first-start-rx?
+: start-rx  ( -- )
+\   init-rx-stat
+   0 to rs-otherant-cnt
+   0 8 reg!
+   hrx-cur ?dup  if  (restart-hrx)  else  restart-hrx  then
+   lrx-cur ?dup  if  (restart-lrx)  else  restart-lrx  then
+   init-opmode
+   first-start-rx? start-pcu-receive
+   false to first-start-rx?
+;
+' start-rx to start-receive
+
+: stop-rx-dma  ( -- )
+   8100 58 reg!
+   20    8 reg!
+   20 20 8 wait-hw drop
+;
+
+: (stop-rx)  ( -- )
+   200.0020 dup 8048 reg@!
+   disable-mib-counters
+   0 set-rxfilter
+   stop-rx-dma
+   flush-rxq
+;
+' (stop-rx) to stop-rx
+
+\ =================================================================================
+d# 2000 constant scan-time
+d#    1 constant scan-time-interval  ( ms )
+
+d# 32 constant max-cmac
+/mac-adr max-cmac * constant /cmac
+/cmac buffer: cmac
+0 value #cmac
+
+: mac-cached?  ( adr -- found? )
+   #cmac 0=  if  drop false exit  then
+   false swap  #cmac 0  do
+      dup cmac i /mac-adr * + /mac-adr comp  0=  if  nip true swap leave  then
+   loop  drop
+;
+: ?cache-mac  ( adr -- new? )
+   dup mac-cached?  if  drop false exit  then
+   #cmac max-cmac >=  if
+      ." Run out of space to cache unique source addresses" cr
+      drop true exit              \ Assume it's new
+   then
+   /mac-adr #cmac * cmac + /mac-adr move
+   #cmac 1+ to #cmac
+   true
+;
+: ?add-scan-response  ( -- )
+   respbuf d# 10 +  ?cache-mac  if  add-scan-response  then
+;
+
+d# 500 constant scan-threshold
+0 value scan-start-ms
+: (scan-ch)  ( -- )
+   get-msecs to scan-start-ms
+   scan-time 0  do
+      queue-rx
+      deque-rx  if                 ( node adr len )
+         process-rx                ( node )
+         free-rx
+         got-response?  if  ?add-scan-response  then
+         get-msecs to scan-start-ms
+      else
+         get-msecs scan-start-ms - scan-threshold >=  if  leave  then
+      then
+      scan-time-interval ms
+   loop
+;
+
+: scan-ch  ( ch# -- )
+   restart-scan-response
+   ." Scanning channel: " dup idx>ch .d ." ..." cr
+   re-set-channel (scan-ch)
+   scanbuf .ssids
+;
+: scan-ch-2GHz  ( -- )  d# 11 0  do  i scan-ch  loop  ;
+: scan-ch-5GHz-1  ( -- )  d# 18 d# 14  do  i scan-ch  loop  ;
+: scan-ch-5GHz-2  ( -- )  d# 22 d# 18  do  i scan-ch  loop  ;
+: scan-ch-5GHz-M  ( -- )  d# 33 d# 22  do  i scan-ch  loop  ;
+: scan-ch-5GHz-3  ( -- )  d# 38 d# 33  do  i scan-ch  loop  ;
+: scan-ch-5GHz  ( -- )
+   scan-ch-5GHz-1
+   scan-ch-5GHz-2
+\   scan-ch-5GHz-M
+   scan-ch-5GHz-3
+;
+: scan-ch-all  ( -- )
+   scan-ch-2GHz
+   scan-ch-5GHz
+;
+
+: scan-passive  ( adr len -- )
+   0 to #cmac
+   80 to resp-type
+   start-scan-response
+   scan-ch-all
+;
+
+: scan-passive-quick  ( adr len -- )
+   0 to #cmac
+   80 to resp-type
+   start-scan-response
+   (scan-ch)
+   scanbuf .ssids
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/ath9k/tx.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dev/ath9k/tx.fth	Fri Dec  9 21:31:14 2011	(r2760)
@@ -0,0 +1,588 @@
+purpose: ATH9K tx code
+\ See license at end of file
+
+headers
+hex
+
+\ tx data structures
+
+0 constant data-qcu
+8 constant cab-qcu
+9 constant beacon-qcu
+
+: qreg@   ( reg q -- val )  2 << + reg@  ;
+: qreg!   ( val reg q -- )  2 << + reg!  ;
+: qreg@!  ( val mask reg q -- )  2 << + reg@!  ;
+
+struct
+   /n field >rs-tries
+   /n field >rs-rate
+   /n field >rs-chain
+   /n field >rs-duration
+   /n field >rs-flags
+   /n field >rs-idx
+constant /rate-series
+
+0 value rseries
+
+create noack-series   1 , 1b , 3 , 0 , 0 ,  0 ,
+                      0 ,  0 , 0 , 0 , 0 , -1 ,
+                      0 ,  0 , 0 , 0 , 0 , -1 ,
+                      0 ,  0 , 0 , 0 , 0 , -1 ,
+
+create nondata-series a , 1b , 3 , 0 , 0 ,  0 ,
+                      0 ,  0 , 0 , 0 , 0 , -1 ,
+                      0 ,  0 , 0 , 0 , 0 , -1 ,
+                      0 ,  0 , 0 , 0 , 0 , -1 ,
+
+create data-series    4 ,  c , 3 , 0 , 0 ,  b ,
+                      4 ,  8 , 3 , 0 , 1 ,  a ,
+                      4 ,  d , 3 , 0 , 1 ,  9 ,
+                      8 ,  9 , 3 , 0 , 1 ,  8 ,
+
+create beacon-series  1 , 1b , 3 , 0 , 0 ,  0 ,
+                      0 ,  0 , 0 , 0 , 0 , -1 ,
+                      0 ,  0 , 0 , 0 , 0 , -1 ,
+                      0 ,  0 , 0 , 0 , 0 , -1 ,
+
+\ >rs-flags bit definitions
+1 constant RS_RTS_CTS  \ program RTS/CTS rate and enable either RTS or CTS
+2 constant RS_2040     \ 40MHz width
+4 constant RS_HALFGI
+8 constant RS_STBC
+
+: 'series    ( adr idx -- adr[idx] )  /rate-series * +  ;
+: rs-tries@  ( adr idx -- tries )  'series >rs-tries @  ;
+: rs-rate@   ( adr idx -- rate )   'series >rs-rate  @  ;
+: rs-dur@    ( adr idx -- dur )    'series >rs-duration @  ;
+: rs-flags@  ( adr idx -- flags )  'series >rs-flags @  ;
+: rs-chain@  ( adr idx -- chain )  'series >rs-chain @  ;
+: rs-idx@    ( adr idx -- br-idx ) 'series >rs-idx   @  ;
+: rs-tries!  ( tries adr idx -- )  'series >rs-tries !  ;
+: rs-rate!   ( rate  adr idx -- )  'series >rs-rate  !  ;
+: rs-dur!    ( dur   adr idx -- )  'series >rs-duration !  ;
+: rs-flags!  ( flags adr idx -- )  'series >rs-flags !  ;
+: rs-chain!  ( chain adr idx -- )  'series >rs-chain !  ;
+: rs-idx!    ( br-idx adr idx -- ) 'series >rs-idx   !  ;
+
+false value noack?
+0 value fctl
+0 value rtsctsrate
+0 value data-rtsctsrate
+0 value txd-flag
+: idx>hw-val  ( idx -- hw-val )
+   'legacy-rates preamble  if  >br-hw-val-short  else  >br-hw-val  then  @
+;
+: find-next-lower-rate  ( idx -- idx | -1 )
+   dup -1 =  if  exit  then     ( -1 )
+   1-  begin                    ( idx-1 )
+      dup 'legacy-rates >br-bitrate @ is-common-rate?  if  exit  then
+      1-
+   0<  until                    ( -1 )
+;
+: do-one-rate  ( idx -- -1 )  drop -1  ;
+: (setup-data-series)  ( -- )
+   data-series /rate-series 4 * erase
+   currate 4 0  do
+      dup data-series i rs-idx!
+      dup -1 <>  if
+         dup idx>hw-val dup to data-rtsctsrate data-series i rs-rate!
+         txchainmask data-series i rs-chain!
+         i  if  1 data-series i rs-flags!  then
+         i 3 =  if  8  else  4  then  data-series i rs-tries!
+         find-next-lower-rate
+noop
+      then
+   loop  drop
+;
+: setup-series  ( -- )
+   curchan is-5GHz?  if  1  else  0  then
+   dup noack-series   0 rs-idx!
+   dup nondata-series 0 rs-idx!
+   idx>hw-val dup noack-series   0 rs-rate!
+                  nondata-series 0 rs-rate!
+   txchainmask noack-series   0 rs-chain!
+   txchainmask nondata-series 0 rs-chain!
+   txchainmask beacon-series  0 rs-chain!
+   (setup-data-series)
+;
+' setup-series to setup-data-series
+
+: setup-rseries  ( framelen -- )
+   \ Determine the series and the rtsctsrate to use
+   noack?  if
+      noack-series  dup 0 rs-rate@  0
+   else
+      fctl c and 8 =  if
+         data-series  data-rtsctsrate  1
+      else
+         nondata-series  dup 0 rs-rate@  0
+      then 
+   then  to txd-flag  to rtsctsrate  to rseries
+
+   \ Compute tx duration per valid entry in the series
+   4 0  do                    ( framelen )
+      rseries i rs-idx@ dup -1 =  if  drop leave  then
+      'legacy-rates >br-bitrate @ d# 100 * over preamble ( framelen kbps framelen shortpre? )
+      curchan is-2GHz?  if
+         rseries i rs-idx@ 'legacy-rates >br-flags @ br-erp-g and
+         if  WLAN_RC_PHY_OFDM  else  WLAN_RC_PHY_CCK  then
+      else
+         WLAN_RC_PHY_OFDM
+      then
+      compute-txtime                          ( framelen duration )
+      rseries i rs-dur!                       ( framelen )
+   loop  drop
+;
+
+struct
+   4 field >tx-info
+   4 field >tx-link
+   4 field >tx-buf0
+   4 field >tx-len0
+   6 4 * +            \ buf1-3, len1-3
+   4 field >tx-ctl10
+   4 field >tx-ctl11
+   4 field >tx-ctl12
+   4 field >tx-ctl13
+   4 field >tx-ctl14
+   4 field >tx-ctl15
+   4 field >tx-ctl16
+   4 field >tx-ctl17
+   4 field >tx-ctl18
+   4 field >tx-ctl19
+   4 field >tx-ctl20
+   4 field >tx-ctl21
+   4 field >tx-ctl22
+   d# 128 round-up
+constant /tx-desc
+d# 2 constant #tx-descs
+#tx-descs /tx-desc * constant /tx-descs
+0 value beacon-desc   0 value beacon-desc-phy
+0 value tx-desc       0 value tx-desc-phy
+0 value /beacon
+
+struct
+   4 field >txs-info
+   4 field >txs-s1
+   4 field >txs-s2
+   4 field >txs-s3
+   4 field >txs-s4
+   4 field >txs-s5
+   4 field >txs-s6
+   4 field >txs-s7
+   4 field >txs-s8
+constant /txs-desc
+d# 64 constant #txs-desc
+#txs-desc /txs-desc * constant /txs-ring
+0 value txs-start   0 value txs-start-phy
+0 value txs-end     0 value txs-end-phy
+0 value txs-cur
+
+/rx-buf /tx-desc + constant /tx-buf
+0 value tx-beacon   0 value tx-beacon-phy
+
+: txs>phy   ( virt -- phys )  txs-start - txs-start-phy +  ;
+: txs>virt  ( phys -- virt )  txs-start-phy - txs-start +  ;
+
+\ In the ideal world where the hardware works properly, txs-cur++ is ok.
+: txs-cur++  ( -- )  
+   txs-cur /txs-desc +  dup txs-end >=  if  drop txs-start  then
+   to txs-cur
+;
+\ In the real world where the hardware does not always advance the status ring, we
+\ have to sync our view with its view and clear memory between its pointer and ours.
+: clear-txs  ( htxs -- )
+   txs-cur over >  if         \ Ring wrapped around
+      txs-cur txs-end over - erase
+      txs-start tuck - erase
+   else
+      txs-cur tuck - erase
+   then
+;
+: sync-txs-cur  ( -- )
+   838 reg@  txs>virt dup clear-txs  to txs-cur
+;
+
+: free-txs-ring  ( -- )
+   txs-start 0=  if  exit  then
+   txs-start txs-start-phy /txs-ring dma-map-out
+   txs-start /txs-ring dma-free
+   0 to txs-start
+;
+: alloc-txs-ring  ( -- )
+   txs-start  if  exit  then
+   /txs-ring dma-alloc to txs-start
+   txs-start /txs-ring erase
+   txs-start /txs-ring false dma-map-in to txs-start-phy
+   txs-start /txs-ring + to txs-end
+   txs-start-phy /txs-ring + to txs-end-phy
+;
+: free-tx-desc  ( -- )
+   tx-desc 0=  if  exit  then
+   tx-desc tx-desc-phy /tx-descs dma-map-out
+   tx-desc /tx-descs dma-free
+   0 to tx-desc
+;
+: alloc-tx-desc  ( -- )
+   tx-desc  if  exit  then
+   /tx-descs dma-alloc to tx-desc
+   tx-desc /tx-descs erase
+   tx-desc /tx-descs false dma-map-in to tx-desc-phy
+;
+: free-beacon-buf  ( -- )
+   tx-beacon 0=  if  exit  then
+   tx-beacon tx-beacon-phy /tx-buf dma-map-out
+   tx-beacon /tx-buf dma-free
+   0 to tx-beacon
+;
+: alloc-beacon-buf  ( -- )
+   tx-beacon  if  exit  then
+   /tx-buf dma-alloc to tx-beacon
+   tx-beacon /tx-buf erase
+   tx-beacon /tx-buf false dma-map-in to tx-beacon-phy
+;
+: free-tx-bufs  ( -- )
+   free-txs-ring
+   free-tx-desc
+   free-beacon-buf
+;
+: init-tx-bufs  ( -- )
+   alloc-txs-ring
+   txs-start to txs-cur
+   alloc-tx-desc
+   alloc-beacon-buf
+   tx-desc     /tx-desc +  to beacon-desc
+   tx-desc-phy /tx-desc +  to beacon-desc-phy
+;
+
+: set-txs-ring  ( -- )
+   txs-start-phy 830 reg!
+   txs-end-phy   834 reg!
+;
+' set-txs-ring to reset-txstatus-ring
+
+: fill-txd-11n  ( keytype type key pwr flen desc -- )
+   >r
+   ( flen ) swap ( pwr ) d# 16 << or  3 pick ( keytype )  if  4000.0000 or  then
+   100.0000 or r@ >tx-ctl11 le-l!
+   \ type: 0-normal, 1-atim, 2-pspoll, 3-beacon, 4-probe resp, 5-chirp, 6-grp-poll
+   ( key ) 7f and d# 13 <<  swap 
+   ( type ) dup d# 20 <<  swap 3 =  if  100.0000 or  then  or
+   r@ >tx-ctl12 le-l@ or  r@ >tx-ctl12 le-l!
+   \ XXX If both us and AP supports LDPC, ctl17 |= 8000.0000
+   \ keytype: 0-none, 1-wep, 2-aes, 3-tkip
+   ( keytype ) d# 26 <<  r@ >tx-ctl17 le-l!
+   2000.0000 r> >tx-ctl19 le-l!
+;
+
+: fill-txd-rate  ( ctsrate series flag desc -- )
+   >r
+   r@ >tx-ctl11 le-l@ 8040.0000 invert and
+   swap ?dup  if  1 =  if  40.0000 or  else  80.0000 or  then  then
+   r@ >tx-ctl11 le-l!
+
+   dup  0 rs-tries@  d# 16 <<        ( ctrrate series tries )
+   over 1 rs-tries@  d# 20 <<  or    ( ctrrate series tries' )
+   over 2 rs-tries@  d# 24 <<  or    ( ctrrate series tries' )
+   over 3 rs-tries@  d# 28 <<  or    ( ctrrate series tries' )
+   r@ >tx-ctl13 le-l!                ( ctrrate series )
+
+   dup  0 rs-rate@ 
+   over 1 rs-rate@  d#  8 <<  or
+   over 2 rs-rate@  d# 16 <<  or
+   over 3 rs-rate@  d# 24 <<  or
+   r@ >tx-ctl14 le-l!
+
+   dup  0 rs-dur@  over   0 rs-flags@ 1 and  if  8000 or  then
+   over 1 rs-dur@  2 pick 1 rs-flags@ 1 and  if  8000 or  then
+   wljoin  r@ >tx-ctl15 le-l!
+   dup  2 rs-dur@  over   2 rs-flags@ 1 and  if  8000 or  then
+   over 3 rs-dur@  2 pick 3 rs-flags@ 1 and  if  8000 or  then
+   wljoin  r@ >tx-ctl16 le-l!
+
+   dup  0 rs-chain@  d#  2 <<        ( ctrrate series chain )
+   over 1 rs-chain@  d#  7 << or     ( ctrrate series chain' )
+   over 2 rs-chain@  d# 12 << or     ( ctrrate series chain' )
+   over 3 rs-chain@  d# 17 << or     ( ctrrate series chain' )
+   nip swap d# 20 << or  r> >tx-ctl18 le-l!
+;
+: chksum-tx-desc  ( desc -- chksum )
+   0  d# 10 0  do  over i la+ le-l@ +  loop  nip
+   lwsplit + ffff and
+;
+: fill-txd  ( noack? len padr qcu desc -- )
+   >r  
+   ( qcu )  8 << ATHEROS_ID d# 16 << or c017 or r@ >tx-info le-l!
+   ( padr ) r@ >tx-buf0 le-l!
+   ( len )  d# 16 << r@ >tx-len0 le-l!
+   r@ chksum-tx-desc r@ >tx-ctl10 le-l!
+   ( noack? ) 1 and d# 24 << r> >tx-ctl12 le-l!
+;
+
+: (xmit)  ( padr qcu -- )  sync-txs-cur 2 << 800 + reg!  ;
+
+: key-type  ( -- keytype keyidx )
+   wep-enabled?  if  1 wep-idx exit  then
+   pkey-enabled?  if  pkey-tkip?  if  3  else  2  then  pair-idx  exit  then
+   0 0 exit
+;
+
+: (xmit-data)  ( -- )  tx-desc-phy data-qcu (xmit)  ;
+: xmit-data  ( adr len -- )
+   2dup >r dup le-w@ to fctl                ( adr len adr )  ( R: len )
+   4 + c@ 1 and dup to noack? -rot          ( noack? adr len )  ( R: len )
+   tuck false dma-map-in                    ( noack? len padr )  ( R: len )
+   data-qcu tx-desc fill-txd                ( )  ( R: len )
+   r> 4 +  fctl 4000 and  if                \ Compute framelen, add ICV or MIC len
+       wep-enabled?  if  4 +  then
+       pkey-enabled?  if  pkey-tkip?  if  d# 12  else  8  then  +  then
+   then  >r                                 ( )  ( R: flen )
+   key-type 0 swap d# 63 r@ tx-desc fill-txd-11n  ( )  ( R: flen )
+   r> setup-rseries                         ( )
+   rtsctsrate rseries txd-flag tx-desc fill-txd-rate  ( )
+   (xmit-data)
+;
+
+: (xmit-cab)  ( -- )  tx-desc-phy cab-qcu (xmit)  ;
+: xmit-cab  ( adr len -- )
+   dup >r true -rot                         ( noack? adr len )  ( R: len )
+   tuck false dma-map-in                    ( noack? len padr )  ( R: len )
+   cab-qcu tx-desc fill-txd                 ( )  ( R: len )
+   0 0 0 d# 63 r> 4 + tx-desc fill-txd-11n  ( )
+   0 beacon-series 0 tx-desc fill-txd-rate  ( )
+   (xmit-cab)
+;
+
+\ XXX beacon-qcu fails for some reason.  It used to work.
+: (xmit-beacon)  ( -- )  beacon-desc-phy beacon-qcu (xmit)  ;
+: xmit-beacon  ( -- )
+   true /beacon tx-beacon-phy beacon-qcu beacon-desc fill-txd
+   0 3 0 d# 63 /beacon 4 + beacon-desc fill-txd-11n
+   0 beacon-series 0 beacon-desc fill-txd-rate
+   (xmit-beacon)
+;
+
+\ XXX hard code
+: hard-code-beacon  ( -- )
+   " dummy-ap" dup to /ssid ssid swap move
+   broadcast-mac$ 2dup 0 h# 80 set-802.11n-mgr-hdr
+
+   0 +xl        0 +xl  \ 8-byte timestamp
+   d# 100         +xw  \ Beacon interval
+   411            +xw  \ Capability mask
+
+   0              +xb  \ element ID = SSID
+   ssid$ dup      +xb  \ length  ( adr len )
+   ( adr len )    +x$  \ SSID
+
+   1              +xb  \ element ID = Supported rates
+   8              +xb  \ length
+   2     +xb  4     +xb  d# 11 +xb  d# 22 +xb  \ 1 2 5.5 11 Mb/sec
+   d# 12 +xb  d# 18 +xb  d# 24 +xb  d# 36 +xb  \ 6 9 12 18 Mb/sec
+   
+   3              +xb  \ element ID = DS parameter set
+   1              +xb  \ length
+   d# 11          +xb  \ Channel number
+
+   5              +xb  \ element ID = TIM (Traffic Indicator Map) parameter set
+   4              +xb  \ length
+   0              +xb  \ DTIM Count
+   1              +xb  \ DTIM Period
+   0              +xb  \ Bitmap control
+   0              +xb  \ Bitmap
+
+   7              +xb  \ element ID = country
+   6              +xb  \ length
+   " US "         +x$  \ Country string
+   1              +xb  \ First channel
+   d# 11          +xb  \ Number of channels
+   12             +xb  \ Max transmit power
+
+   d# 42          +xb  \ element ID = ERP info
+   1              +xb  \ length
+   0              +xb  \ no non-ERP stations, do not use protection, short or long preambles
+
+   d# 50          +xb  \ element ID = Extended supported rates
+   4              +xb  \ length
+   d# 48 +xb  d# 72 +xb  d# 96 +xb  d# 108 +xb  \ 24 36 48 54 Mb/sec
+
+   \ XXX HT capabilities, HT Information, Overlap BSS Scan, Extended Capabilities
+
+   /x to /beacon
+   packet-buf tx-beacon /beacon move
+;
+
+: reset-beacon-queue  ( -- )
+   10.0000 1040 beacon-qcu qreg!  \ DCU IFS settings
+    8.200a 1080 beacon-qcu qreg!  \ DCU retry limits
+       8a0  9c0 beacon-qcu qreg!  \ QCU misc settings
+   24.1002 1100 beacon-qcu qreg!  \ DCU misc settings (don't set beacon bit)
+         0 10c0 beacon-qcu qreg!  \ DCU channel time settings
+;
+: reset-data-queue  ( -- )
+   curchan is-b?  if  1f  else  f  then
+   3f.fc00 or 1040 data-qcu qreg!  \ DCU IFS settings
+    8.200a 1080 data-qcu qreg!     \ DCU retry limits
+       800  9c0 data-qcu qreg!     \ QCU misc settings
+      1002 1100 data-qcu qreg!     \ DCU misc settings (1102 to enable fragment wait)
+         0 10c0 data-qcu qreg!     \ DCU channel time settings, no burst
+;
+
+: .txs  ( ok? -- )
+   0=  if  txs-cur >txs-s3 @ .  then
+;
+
+d#  10 constant tx-retry-cnt
+d#   1 constant tx-retry-delay-time
+d# 100 constant tx-wait-delay
+: tx-delay  ( -- )  tx-wait-delay us  ;
+: tickle-txs  ( -- )  838 reg@ drop  ;    \ Supersition
+
+\ Empirically, the chip does not update the status ring immediately.
+\ Sometimes, a few frames later, it regurgitates the stale status descriptors.
+\ To avoid waiting on the wrong location, we need to sync our pointer with
+\ the hardware pointer.  We do that here and before transmit to catch as many
+\ cases as possible.
+
+\ Statistics:
+\ (probe-ssid): i = 1-0x20+
+\ authenticate : i = 1-0x20+, status = 1 or 102, response or no regardless of status
+
+\ Theoretically, the code should really examine the status bits.
+\ Empirically, I found them unreliable.  An ACKed packet may have the status 0x102.
+\ And yet, I see the ACK and the response on the air.  So, ignore for now.
+
+0 value isr-sp
+0 value isr-s0
+0 value isr-s1
+0 value isr-s2
+0 value isr-adr
+0 value #tx-reset
+0 value #tx-reseti
+0 value #tx-reset-max
+0 value #tx-retry
+0 value debug-base
+: #tx-reset++  ( -- )
+   #tx-reset 1+ to #tx-reset
+   #tx-reseti 1+ dup to #tx-reseti
+   #tx-reset-max max to #tx-reset-max
+;
+: .tx-stat  ( -- )  ." #tx-reset = " #tx-reset .d cr  ;
+: tx-timeout?  ( -- flag )  isr-s2 80.0000 and  ;
+
+: init-isr-dump  ( -- )  debug-base to isr-adr  ;
+: isr-dump!  ( n -- )
+   debug-base  if
+      isr-adr !  isr-adr na1+ to isr-adr
+   else
+      drop
+   then
+;
+: isr-status@  ( -- )
+   c0 reg@ to isr-sp
+   c4 reg@ to isr-s0
+   c8 reg@ to isr-s1
+   d0 reg@ to isr-s2
+   isr-s0 isr-dump!  isr-s1 isr-dump!  isr-s2 isr-dump!  64 reg@ isr-dump!
+;
+: tx-reset  ( -- )
+   ascii r vemit  #tx-reset++
+   a00 data-qcu qreg@ isr-dump! 840 reg@ isr-dump!
+   reset
+   a00 data-qcu qreg@ isr-dump! 840 reg@ isr-dump!
+;
+: tx-retry-delay  ( -- )
+   queue-rx
+   4 0 do -1 isr-dump! loop
+   tx-retry-delay-time ms
+   queue-rx
+;
+
+: (wait-tx-done)  ( -- done? )
+   begin
+      queue-rx    \ In case if the chip got stuck in txstat update, we won't miss rx
+      tx-delay
+      isr-status@
+   isr-s1 ffff and ( TXERR ) isr-s0 ( TXOK ) or tx-timeout? or  until
+
+   isr-s0
+   debug?  if  txs-cur >txs-s3 le-l@ .  then
+   sync-txs-cur
+   queue-rx
+;
+
+: wait-tx-done  ( -- done? )
+   0 to #tx-reseti
+   init-isr-dump
+   false tx-retry-cnt 1+ 0  do
+      i to #tx-retry
+      (wait-tx-done)  if  drop true leave  then
+      ascii | vemit
+      i tx-retry-cnt <  if
+         isr-s1 ffff and 0=  if  tx-reset  then
+         tx-retry-delay (xmit-data)  
+      then
+   loop
+;
+
+: send-beacon  ( -- done? )
+   xmit-beacon (wait-tx-done)   \ No need to retry
+;
+
+: (reset-txqueue)  ( -- )
+   reset-beacon-queue
+   reset-data-queue
+   1 a40 reg!            \ Chksum ptr & len
+;
+' (reset-txqueue) to reset-txqueue
+' set-txs-ring to init-tx
+
+: drain-txqueue  ( -- )
+   \ Abort tx dma
+   3ff 880 reg!                \ Disable tx queues
+   104.0000 dup 8120 reg@!     \ Force quiet collision, Clear virtual more fragment
+   40.0000 dup 8048 reg@!      \ Force RX_CLEAR high
+   1000.0000 dup 10f0 reg@!    \ Ignore backoff
+
+   d# 10 0  do
+      d# 1000 0  do
+         a00 j qreg@ 3 and 0=  if
+            840 reg@ 1 j << and 0=  if  leave  then
+         then
+         5 us
+      loop
+   loop
+
+   0 104.0000 8120 reg@!
+   0 1000.0000 10f0 reg@!
+   0 40.0000 8048 reg@!
+   0 880 reg!
+;
+' drain-txqueue to stop-tx
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END



More information about the openfirmware mailing list