Page MenuHomeFreeBSD

D49884.diff
No OneTemporary

D49884.diff

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/sys/contrib/dev/athn/LICENSE b/sys/contrib/dev/athn/LICENSE
new file mode 100644
--- /dev/null
+++ b/sys/contrib/dev/athn/LICENSE
@@ -0,0 +1,39 @@
+Copyright (c) 2010-2011, Realtek Semiconductor Corporation
+All rights reserved.
+
+Redistribution. Redistribution and use in binary form, without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions must reproduce the above copyright notice and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of Realtek Semiconductor Corporation nor the names of its
+ suppliers may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+* No reverse engineering, decompilation, or disassembly of this software
+ is permitted.
+
+Limited patent license. Realtek Semiconductor Corporation grants a world-wide,
+royalty-free, non-exclusive license under patents it now or hereafter
+owns or controls to make, have made, use, import, offer to sell and
+sell ("Utilize") this software, but solely to the extent that any
+such patent is necessary to Utilize the software alone, or in
+combination with an operating system licensed under an approved Open
+Source license as listed by the Open Source Initiative at
+http://opensource.org/licenses. The patent license shall not apply to
+any other combinations which include this software. No hardware per
+se is licensed hereunder.
+
+DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/sys/contrib/dev/athn/athn-ar9271fw.fw b/sys/contrib/dev/athn/athn-ar9271fw.fw
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 0
Hc$@<O00001
diff --git a/sys/contrib/dev/athn/athn-ar9271fw.fw.uu b/sys/contrib/dev/athn/athn-ar9271fw.fw.uu
new file mode 100644
--- /dev/null
+++ b/sys/contrib/dev/athn/athn-ar9271fw.fw.uu
@@ -0,0 +1,1137 @@
+begin 644 athn-ar9271fw.fw
+M7W=M:5]C;61?<G-P`'5S8E]R96=?;W5T7W!A=&-H````````````````````
+M``````````"08R@`D&!D`)!3S```````D&)8`)!4,`"05%P`D%1$`)!A4`"0
+M8)0`````````````````````````````````````````````````````````
+M````````````````````````D%$8`)!10`````````````````"08'``D%%@
+M`)!14`"04'@`D&&0`)!0D```````````````````````````````````````
+M`````````````````````)!D@`"09(8`D&2,`)!DD@"09)@`D&2@`)!DI@"0
+M9*P`D&2R871H7V5N86)L95]A9V=R7W1G=```````````&0```#(```!+````
+M4````%,```!5````5P```%@```!:`!H`-@`T`&P`3@"B`&@`V`"<`40`T`&P
+M`.H!Y@$$`AP`-`!L`&@`V`"<`40`T`&P`3@"B`&@`V`!U`/,`@@$."!!7U=$
+M5%])3DE4*"D*#0`@/3T^5T14(')E<V5T/#T]"@`@/3T^=V%R;2!S=&%R=#P]
+M/0H`(#T]/F-O;&0@<W1A<G0\/3T*`$%,3$]#4D%-('-T87)T(#!X)7@@<VEZ
+M92`E9`H`16YA8FQE(%1X(%-T<F5A;2!M;V1E.B`P>"5X#0H`55-"(&UO9&4Z
+M(#!X)7@-"@!49W0@<G5N;FEN9PH-`"5S.B!B=69F97(@86QL;V-A=&EO;B!F
+M;W(@979E;G1?:60@)7@@9F%I;&5D(0H`6RLK*TUA9W!I95]I;FET70H-`%LK
+M*RM60E5&7VEN:70H)60I70H-`$-O;&0@<F5B;V]T(&EN:71I871E9"X`15`T
+M($9)1D\@0G5G/R!"=69F97(@:7,@=&]O(&)I9SH@)7@*`"5S.B!&:6QE9"!T
+M;R!G970@;F5W(&)U9F9E<BX*`"5S.B!$871A(&QE;F=T:"!O;B!%4#0@1DE&
+M3R!I<R!B:6=G97(@87,@86QL;V-A=&5D(&)U9F9E<B!D871A(2!$<F]P(&ET
+M(0H`(&%T:%]H86P@/2`E<"`*`#QW;&%N7W!C:5]P<F]B93XZ($%T=&%C:&EN
+M9R!T:&4@9')I=F5R"@`\=VQA;E]P8VE?<')O8F4^.B!696YD;W(@:60@,'@E
+M>"!$978@:60@,'@E>`H`0V%N;F]T(&UA;&QO8R!S;V9T8PH`(5530B!S=7-P
+M96YD"@T`(5M33U520T5?,%T@8FET-R!O;@H-`"%54T(@<F5S970*#0`A55-"
+M(')E<W5M90H-``H@8VAA;F=E(&-L;V-K('1O(#(R(&%N9"!G;R!T;R!S=7-P
+M96YD(&YO=R$`/&YU;&P^`#`Q,C,T-38W.#D`,#$R,S0U-C<X.6%B8V1E9@`P
+M,3(S-#4V-S@Y04)#1$5&`&%T:%]P8VDZ(&YO(&UE;6]R>2!F;W(@9&5V:6-E
+M('-T871E"@!A=&A?<&-I7W!R;V)E("5X"@!A=&A?<&-I`&%T:%]P8VE?=&=T
+M`%-%15!23TT@4F5A9"!F86EL.B`P>"4P.'@*`$)U9B!N=6QL"@!615)9($Q/
+M3D<@4$%#2T54(2$A(2$*`&1S7W1M<"!I<R!.54Q,"@!;)7-=(&5N86)L95]A
+M9V=R('=I=&@@:6YV86QI9"!T:60@)60H;F]D92`]("5D*0H`9F]U;F0@8F-?
+M:&1R(2`P>"5X"@!R>`!T>`!B96%C;VX`=&ED6R5P72T^:6YC;VUP(&ES(&YO
+M="`P.B`E9`H`9')O<"!F<F%M92!D=64@=&\@5$E$(')E:6YI=`H`5$E$(%)%
+M24Y)5"!$3TY%(&9O<B!T:60@)7`*`$)!($)U9S\*`````%#+0`!0RT``4-=`
+M`%#8"`!0V`@``"[@`%)_]```4T("8EH``%````!0"?@`4`GV`%`)^@`%`$P`
+M4!&0`%#7A`"02U``D$BX`)!)V%]71%0`4!&@`%)_^%]355,`4!&R`%`1Q0!0
+M`=0`4`(,`%`"0`!0`G@`4`*4`%`"J`!0V`@`4G?\`%`1V`"01GP`D#DD`)!&
+MD`"0.HP`D#@D`)`Z]`"0.K``D#?@``$``P`!`0@`4!'U``$!%!``0"```0$0
+M``$!``!0$A,`D$I@`)!*;`"02G@`D$J4`)!*P``%`!``4!(D`%#70`!0V`@`
+M4G?X`%#71`!0UT@`4!```%`2,@!0$F$`4!)T`%#7C`"0-M0`D#;T`)`W3`"0
+M-W``D#>``)`V[`!0UTP`4`G,`)`WO`!0$HD`4,M"`%#79`!0UV``4-=<``$`
+M%``!`/@``0"M``$`O`!0$J``4,M``%#76`!0UU0`4!`-`%`2Q0!0UU``4!+C
+M``$`_`!0"<``4`GL``58'``%7!@`!5D<``5:'`!0"@``4->X`%`)X`!0">0`
+M4`GH`%#7R@!0$RT`4,U\`%#7<`!0$ST``!:,`%`390!0$Y,``````%#7;`!0
+MUV@`D#TT`)`_K`"0/[P`D#Z$`)`\R`"00G``D#S``)`\V`"00\``D#SL`)!!
+MJ`"00`@`D$74`)!$I`"016P`D$6<`)!%2`"01)0`D$2<`)!$N`"01,``D$2(
+M``$`*P!0$ZC__P`````0`!``0$P0`$"(J8*J:@`!``0``0`````1````$@``
+M!0!$``4`0``!`",``0`F``$`)``!`"(`4!.W`%`)\``!``@`4`GT`%`3S0!0
+M$]H``0"N``$`KP`!`1@`4!/H``!+``%/L8``4-=T`%#7>`!0"(P`4!04`%`4
+M&P!0%"8`4!0W``!``!!B3=,0````$`!`.!```"0!!=BZ(@````"````0``"@
+M$`!`/!``0#`0`$`L``/__Q``@%`0`(!,$```#!````@0`(!(```@`'____\0
+M```P$``(`!``"$`0``H``0```"````"``````$`````/````#^``0````'\`
+M_P`<````"``````_````\`````"`````"`#_O___?[___P\`````_P``?_\`
+M````<``/\`````X``&`````#_```_`,``/P#___?____G_______@`#__^__
+M$``(@!``@2`!!```$``0\/[[___O____$`!P1!```,`0``#,`@```!```,00
+M``#($`!`*!``@#P"`@``$`"!#!```#0`4!`@`)!:>`"06X``D%W@`)!>;`"0
+M7O``D%]P`)!?L`"047@`D%'P`)!4C`"05G0`D%>L`)!7T`"07_0`4,M$`%#-
+M@```%H@`4!1(`%`4;0"0;"``4!1_`%`0\`"0:K@`D&1@``#__P!0UWT&^4=`
+M``!P%`!0UWP0`'AL!@```/G______^````,`````0'P`4!23$`!`?```(R@`
+M4!2N```0`@!0SL0`4!2X`%`4SP``$`,``!`%```5V```%9@`4!$4`%`4WP``
+M%B```!7:```5S```%:7@``!Q__[__P`$````4!40`)!F5`"0J'0`D')8`)!R
+M1`"09%@`D'QP`)!G^`"09$@`D&6(`)!D\`!0S<```!>@`%#.P`!0%20`4!4G
+M`%`5*@``%B@`4!$H`%`14,S,S,T`D*YP`%`5,0``%C@``!8[```6.0``%CH`
+M`!`'```670!0%4\`D(^$`)"I=`"0J=``4!5M`%`5B0``$`8`4,[(````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``!L$`18`(\2<6L4<6P,`@"#(!)Q;@,#7W0Y/5MY2QIQ;2,B-PLP`"HB$PN@
+M`",B$0LP`",B7PLP`",B:0LP`",B00LP`!1Q;\`P(T4`%'%P(T4`%'%Q(T4`
+MBBX+H`#5H!-Q<B0B$AIQ<PP"`(,P"T``%G%T%'%U)&8`95`4)R(2)"82%'%V
+M)V8`)"8=%'%W)"8I%'%X=#D<(R(2&G%Y"S``%'%Z#`(`@T"Q,PP"`)-`8``:
+M```4<7MT.0DC(A(:<7Q@``8`(R(2&G%]"S``%'%X$W%R&G%^#`(`E#!;?KX:
+M<7]8`T@:<8!8!5<:<8%8`:H:<8);@^8:<8-;A!`4<806<84H(A*T0P1G#!IQ
+MAMQPVS`+@`#'C'A!"]HP&W%J=DD&8``&`!IQ:0=[`B,B40LP`&50M!-QAR,F
+M?A-QB",F,A-QB2,F@!-QBB,F)1-QBR,F,Q-QC",F+Q-QC2,F)A-QCB,FFQ-Q
+MCR,P`'D_`E@"+1-QD"0B$@P"`(LP&G&1"T``VC#`P<2P6!]_VC#`P"L:`%@?
+M?-HPP,`K*@!8'WK:,,#`*PH!6!]WVC#`RL"P6!]UVC##P,*P6!]SVC#`P"L*
+M`E@?<!-QDB0*H`P"`)0P$W&3#`(`A#`3<91R1P3`0&```<!)#`(`E#`3<94:
+M<98,`@"+,",B$@LP`!-QE\*H(R8W$W&8(R8\$W&9(R8Z$W&:(R9`$W&;(R8]
+M6`816`!"&G&<+%K`*PH`6!]66`)S6`)Z&G&=(B(2"R``6``/``!L$`08<9X9
+M<9_`H&```YJ`M(AY@_@:<809<:`*F0P)*10.F1&IB<"@8``$`)J`M(AYB?C1
+M#P```&P0!!1QH1-QHL`@DD"2,!)Q;B@B7`N``"@B0`N``"@B@,"@"X``6`*"
+M*")M"X``*")%"X``B#!I@`W`@)@PB$"QB)A`8__*`+&(F#!C_\(`;!`$T0\`
+M``!L$`87<6XL;`0H<I+`L0(J`@N```0$3]B@S:$B<A(;<:,:<:3<,`L@`&/_
+M_```R6+)4-M@FA!8`+J)==Q@VU`+D`"($"5RD]Y@W4`##$_;@-H@"U``T0\`
+M;!`$$G%N&G&E(R(2"S``$W&F*"(2*PIDVC`+@``H(J4J"F0+@``H(A(K"F3:
+M,`N``"(BJBH*9`L@`-$/;!`$%7%NUB`J4J8+H`#2H&2@*"I2JPN@`"524M2@
+MVV#`H`M0`,"`FD$F10280"-%!2A%!BA%!Y0@*"4$T0\``&P0!&/__```;!`$
+M8__\``!L$`1C__P``&P0!&/__```;!`$B2`#`T\JD08HD06J.BJ5!@.(#"HA
+M!`@(3RB5!:HS(R4$@I&H(M$/``!L$`2)(`,*3R.1!BB1!0HS#".5!JBH(R$$
+M"`A/*)4%"C,,(R4$@I&H(M$/`&P0!,PA8__\P"#1#VP0!,PA8__\P"#1#VP0
+M!(@@M#G`H&``$RR!!8N!L:JLNYN0*X$&B(";D;B998_HFC#1#P!L$`3,(6/_
+M_+PBT0]L$`2((K&(F"+`@)@QB"#,@Y,@8``#B"&3@9,AT0\``&P0!-@@@B#)
+M*8F"BH&PF9F"P)!Z*0>9@)F!8``$`(HAFH"9(=$/``!L$`02<6[`O"(B4L"@
+M"R``FC#`(\BBP""2H-$/;!`$E##`(-$/````;!`$P("8,-$/````;!`$T0\`
+M``!L$`2((+0YB(#`H&``%0``+($%BX&QJJR[FY`K@0:(@)N1N)EEC^B:,-$/
+M`&P0!-$/````;!`$P"#1#P!L$`84<6Z#(BI"II,0"Z``UZ#,HF/__`"#(,PR
+M8__\`(,PDZ#`,-4PUC!@`"(HH02Q5:@S`P-/B*#(82AF`-:`B(!EC_B8H"BE
+M!"A"J`N``-H@6__#9:_4@A!R40)C__PC=032<-$/`&P0!,!`E#*4,)0Q%G%N
+MA"!@`"8J8J8+H`#5H,RB8__\`"=!!I2@)Z4$P'"7H=N@VC!;_ZF%4(1`EU!E
+M3]4C8JB4("0E!-H@"S``T0]L$`2"(&```=*`B"!EC_C1#P```&P0!-H@6__Y
+M**$&*:$%`P-/J)FCB"BE!B@A!(NAJ#,C)02ILM$/``!L$`3:(%O_[\PA8__\
+M**$&`P-/`X@,**4&*"$$`X,,(R4$T0]L$`2(("*!!=$/``!L$`3:(%O_XR*A
+M!2BA!`*(#"*A!@*"#-$/````;!`$(B$$T0]L$`3`(-$/`&P0!-$/````;!`$
+MP"#1#P!L$`2(("J!!8F!*($&JIF9,)A`T0\```!L$`3`@)@BF""8(=$/````
+M;!`$@B+1#P!L$`2"(-$/`&P0!((AT0\`;!`$@B+`D<"``I@XTH#1#VP0!,"`
+M$G&GVX`I"@IMF`6BBIN@M(C1#VP0!-$/````;!`&$G&G#C,1V4`6<6[`0*,C
+M8``\*F*FF1`+H`#2H"IBJPN@`"AB4M>@VU#`H`N``,"`FG$E=00H=04H=0:7
+M((<P*"4$B1#,<6```9<ADC"Q1'E"O]$/`&P0!!)QIPXS$:,C@C#)(8@AF##`
+M,(@@DR$DA04CA08C)031#VP0!-Q`VS#:(%O_]-*@T0]L$`08<:<.,Q&C@X@P
+MS(%@``&8090PT0]L$`08<:B8(!AQJ9@B&'&JF",8<:N8)!AQK)@E&'&MF"'1
+M#P!L$`2)(-H@*Y$%B)&KB(B`:8`$6`/)T0\8<:Z(@`N``-$/``!L$`2)(1AQ
+MKIF`B2`8<:^9@!EQL)F!B2*"(YF"DH/1#VP0!!)Q;AIQL2@B$@N``!AQ<L"0
+M(B(K#`(`*88`"R``T0\``&P0!!)QLB@A`&2`2!AQKXJ""Z``&'&SFH#)KXF@
+M*Y$%B)$9<;2KB)B0&'&U*:$$*84`P(`H)0!@`!H``!AQMBD*P"*```("1PDB
+M`@P"`"*$`-$/```:<;7$D"BA`,#!>)L)*(S`**4`P,#8D!MQM`@I%(JP#ID1
+MJ:G`T!YQM\#Q8``.``P"`(V@M*H,`@"=X-WP>IGNR-"9L`@(0<N!&7&5:(('
+M:8,)P(=@``;`@V```<"!#`(`F)"(L`P"`(F`&'&W#`(`F8`8<97`GPP"`)F`
+M&7&XP*@HD``("$<*B`(,`@`HE``8<;.*@,BO9,`-&'&O*((#"X``P($H)0#1
+M#P!L$`02<;DD"D`B(``"`D<"`T]S2Q$4<6X:<;HD0A("*P(+0`!;_ZT4<;L5
+M<;PH00#*C1AQKXJ`"Z``&7&]P(":4"B5`,RM$G%N&W&^(B(2&G&_8``QB:`H
+M10"*D1EQP)J0BE#*HQEQO2B1`*@X"`A/*)4`B:`ED01X6Q@2<6X;<;XB(A(:
+M<<$+(`#`(!1QPF``9P```RL4'''``@)!L;4"M3B+P`Y2$:*RP-`5<<+`X6``
+M#@`,`@"-4`P"`)VPM+O=X'LI[LC0DL##+W,C+L`@DI`BE04BE0<HE0:2H1)Q
+MKRBE!((A"R``P"$B10#1#P"Q(@P"`(5``@)/<R/RT0\`;!`$*PIO*@H&6X".
+M*PH&"[H"6X"3*PJ&P*9;@)G`ML"G6X"7Q,#`L<"F6X"=Q,#`L<"F6X"EQ,#`
+ML2H*!EN`J]$/``!L$`08<7`H@0!I@1,8<6\H@0#,BAAQ<2B!`&6``EO_Y]$/
+M``!L$`1;?3L2<<,B(`?(*A)QCR(@`'DO`EO_\1AQQ,`ADH#1#P!L$`08<<,I
+M@0(H"@EXF2T8<6XJ@B4+H``8<<7`H0P"`)J`&''&#`(`FH`8<<<,`@":@!AQ
+MR`P"`)J`8``"6WWGTJ#1#VP0!!)QPR@A`PB(%&F!(!1QR1-QRHM`VC#!PE@`
+M-<>/*#4&&''+DX"#0"@P`6``)&F"/A1QS1-QSBM"`"P*/`,Z`E@`*R0@!\"@
+M>DDG%''+*#$!DT`3<<PB(04H-0!X*P(B-0`2<6XB(C0+(`#`H6```EM\U]*@
+MT0\```!L$`08<6XJ@CT+H`#2H-$/;!`&WA#=4-Q`VS#:(%@%`1AQ;MN@TJ`H
+M@A(:<<\+@`"($)A@T0\``&P0!!AQ;MH@*((Z"X``T0]L$`04<6[3(")"4MLP
+MP*`+(`#2H,BHA$3<,"L*``M``-$/``!L$`31#P```&P0!!AQ;MQ`B(7;,-H@
+M"X``P"#1#P```&P0!!AQT(J`R*$+H`#1#P!L$`08<=&2@-$/``!L$`K!R"L*
+M``$:`EN%7L'`P+`J'!A;A5L2<6X:<=(C(A(+,``3<=,H(A(:<=3;,,+$"X``
+M*")2P+3`H`N``,RJ(B(2&G'5"R``T0\`PB22%Q)QT<#0@B`8<=89<=:3%IT8
+MG1F"()@0F1&8$ID3G10L'!C`L=H0"R``$G'7FB#1#VP0!,`@T0\`;!`$P"#1
+M#P!L$`08<=B(@,B(&7'7BI#(H0N``-$/``!L$`31#P```&P0!"@BD)@P(R:0
+MT0\```!L$`08<6XJ(IHH@G\+@`"XHM$/`&P0!`(J`EO]VB2@`,"X`BH"6_V\
+M#T@1I(@-B!&H,X,RVR"(,HPV!$H""X``T0\``&P0!!AQ;BHBFRB"H-U`W##`
+ML`N``-$/`&P0!A1Q;@(E`B)"4BLJ=,"@"R``B$0L*G3`L-*@"X``B#**,Y@@
+MB#3;$"@FFRA"C"HFFI@0*$*+DA*8$2A"=PN``,"&*":6P(,H)IDH"M@H)I>(
+M,(,Q*":1(R:4P#`C)I4C0HW!C",FBB-"CBHBFB,FBR,M`B@U'<2`*#4<(RHD
+M`R,(DR(C0H$L+!@K+!DB)H\+,``K(!DC0GHJ(IK`P0LP`,`Q(R:(VB`E)I/$
+MP"L*!%O_S2HBFB-">0LP`-$/`&P0!-$/````;!`$T0\```!L$`08<=F8(!AQ
+MVI@D&'';F"48<=R8(QAQW9@B&''>F"88<=^8(1AQX)@G&''AF"@8<>*8*1AQ
+MXY@J&''DF"O1#P```&P0!!AQ;BHBFRB"H]PP*PH`"X``T0\``&P0!!AQ;MH@
+M(H*A*(**(Z*;"X``W*#`L-HP"R``TJ#1#P```&P0!`(J`EO_]<"XU*!;_=<5
+M<6[`R(A4P+#3H`N``,"!*#0!*"*1P+`("$\(B10H-`4H(I0I-`0("$\(B10H
+M-`/!AB@T!BLT`"DT`B-2B=Q`VB`+,`#1#P!L$`0H(H5X,%HH(H9X,%3)12-)
+M!,@T*$D`<X)'B$0C(IES@@-@``D`VB!;_];3H,RN(R*2P$($,P(C)I+1#P``
+M`%O]3\A-B$2QB)A$)`H@!%4"):0!%'%NW#`D0HG`L-H@"T``T0\``&P0!,"X
+MVD`/-A%;_1VC9AAQ;@UF$:8G*()\*W`9*B*:W$`+@``D(I)_1S`H<0+`L;&(
+M*'4"*'$'`#$$`+L:L(@H=0<G(H8+=P(G)H;)5+1LW3"L+-H@6__0T0\`(R*4
+ML3,C)I31#P``;!`$P-'<0-LPVB!;_^/1#VP0!MH0E!"5$9826_V[U*#`4&``
+M%-I`6_VZUJ#<0-U0VS`"*@);_]C48&5/YP\\$:/,#<P1M,S`L=TPK"P`,00`
+MNQK:(%O_MM$/``!L$`3:,%O]$RB@`7J'$@@)1`^8$:F(#8@1J$B)A;"9F87;
+M,-I`6_^&*$*2?H<2QST#B`$H1I+!UL#`Q[_:0%O_I=$/`&P0",!PEQ`H,`+:
+M(`B$$2@P`R4BD`2(`I@46_]^P+K6H%O]8!EQ;L#*C93;<-2@"]``B!3`DRE$
+M`0B)%"E$`B=$`"A$`\&58`!W*R*(>Y)Y*E$(>*EI+3`(P("Z/`V,.(A3WQ"Z
+M3@5:`@N``&6@7(@0*$0(*2*(*40%*%`4*$0&*%`5*$0'#Y@1J8@-B!&H*)6"
+M*S`$"+P1*S`%#+L"*X4(*S`&*X08(S`'(X09(U$)P($(,P(C50FQDR,FB&``
+M"X5095^$P*%@``'`HRI$!!1Q;MQ@(T*)P+#:(`LP`-$/;!`$`BH"6_]+P+36
+MH%O]+15Q;L"PB%3`Q-2@"X``P(`H1``H"@8H1`$K,`(K1`(H4GTJ(IH+@`#)
+MI,"`*$0#+#`#*"*5*2*4J,AXDAI@``3`,6``%"@FE212>BLP`BHBF@M``&``
+M!0#`,B-$`R-2B=Q@P+#:(`LP`-$/`&P0!L@R8__\`+0;W!#:0%O],XL1*+``
+M"(81*+`!!H@"P&%HA!9HA0QI@@[:4%O_G6``!@``VE!;_]/6,"A2DA-Q;G^'
+M"R(RA]Q`P+#:4&``&\"XVD!;_'$/*!&BB`V($:A8(C)\*X`9*E*:W$`+(`#)
+M82)2DL`Q`R("(E:2(E*3R"$+(`#1#P!L$`0I(04H(0"IB"DA!@B(,@D)06B1
+M$,B5:)(38``;``@H$F``%```"!@28``,```/B1&HF`@H$@B(,B@E!-$/;!`(
+M!$H"6_QYU:#:0%O\^9H0P+C:0%O\3RA0`<20"8@"*%0!`PA'*%0`P%`EI`$/
+M-1&C52BD``U5$1AQ;J4E*U`8*()^UJ`J(IH+@`#5H-I`6_S>"E4,VD!;_.8*
+M50S:0%O\W76K!MI`6_S;U:!K5`)@`*TG(H9D<*?`LMI`6_S`P)$II`#`D"FD
+M`=Z@)5S^M"G`PL#08`!IP($`T00`CQI_<%G`LMI`F16<$YT2GA2?$5O\LXT2
+MCQ$MI`")%<>_#[\#*Y$`#W<!*Z0!P*`JE0`JD0:,$XX4?:<0VI"9%9T26_^W
+MCA2-$HP3B14JX`$E7/XJK`(JY`$LS`)N4@FQW2F<&,AQ:U*0)R:&:L$3)6`!
+MP(((50(E9`&%$"QD!*Q5E1"($"HBF@@'3P>%%"5D`@\U$:-3#3,1%7%N)V0#
+MHR,E4GLK,!@$3`(+4`#1#P``;!`(DQ4"(SG<$+0;VC!;_*V%$=<P)E`!?6<"
+M8`"=(U``)4*2`PE/?U<1#Y41J54-51&E12I1![&J*E4'#Y41J54-51&T5<"1
+MI465%`EK`0`Q!`"5&BI"A0"1!``V&LF[!:H"*D:%HVH-JA&J2BJA"'VG'HH4
+M6_]^8``6``#'SP7,`PRJ`2I&A:-J#:H1JDHKI0:C9@UF$<"XVG`&1@A;^^2&
+M8HP5C6:'8=L@`SH""W``C!3=,-M0VD!;_IC1#P``;!`$T0\```!L$`2()I.*
+MP"#1#P!L$`2"(M$/`&P0!((JT0\`;!`$B"O,@Y,K8``#B"R3@),LT0]L$`31
+M#P```&P0!L@R8__\`-I`6_QFTZ!NI%G<$+0;VD!;_&J-$2X\_"O0`"/0`2S0
+M`@B[$0L[`B/0`PC,$8E;##P"M-U@`"F(DX.2P*!@`!8O@0)[^0R/@"B!`\B.
+M>.(.8``)L:JXB'.BY6```<WTB9!EG](3<6Z*4",RA]Q`VR`+,`#1#XJ1"_``
+M8__F``!L$`3:,%O[PXNAP)'`@`N8.-N`&'%NBD$H@J/<,*F["X``T0]L$`08
+M<6[`L"6"H8H@*(**P$$#M#F&(;%$"X``M*S;0-I@"U``TJ#(HUO[L9.AT0]L
+M$`0K"@0#.@);^X<$!$\%!4\DI`$$B!0%A!0DI`(4<6XHI``EI`,D0HF+*HH@
+M`SP""T``T0\``&P0!!-Q;M0@(C)2P[C`H`L@`-*@9*!5P("8JXA`BD&,0I@@
+M*#*@FB$M"G`K"@$+@``H,J"*08Q#P+(M"G`+@``H,IB*0)@D*#*5O"N8)2@R
+MF2,RA9@F*&H$*"40*`ID*"41*!H`*"4.DBD+,`#1#P!L$`08<>68(!AQYI@A
+M&''GF"(8<>B8(QAQZ9@E&''JF"08<>N8)AAQ[)@G&''MF"@8<>Z8*=$/`&P0
+M!",\_2)J0&\R`B(J`-$/````;!`$&'%N*((="X``VB!;>2[1#P!L$`8,`@"2
+M$`P"`(@0*8``QX\$A`,)"4<)1`$,`@"($`-$`@P"`"2$`-$/`&P0!@P"`)(0
+M#`(`B!`,`@"(@`.#`@P"`(@0#`(`DX#1#P```&P0",`@#`(`DA0,`@"2$PP"
+M`)(2&G'OP,3;(`P"`)(1#`(`DA!;_^(3<6X:<?`D,A(+0``8<7L4<7(,`@"8
+M0"0R*0M``"0R*`M``!1Q:QEQ\0P"`(A`"8@!&7'R"8@"#`(`F$`4<?,,`@"(
+M0`P"`)@4#`(`DD`4<?0,`@"(0`P"`)@3&''U#`(`F$`4<?8,`@"$0`P"`)01
+M#`(`DA+#06``3P``(C(Z*CKH"R``$G'V#`(`@B`,`@"2$`P"`(@0#`(`@A%R
+MB102<70,`@"$$H(@(C82PR)R22-@`"@,`@""$`P"`)(1#`(`@A*Q(@P"`)(2
+M#`(`@A)R2ZEC_\D:<??`N%O_MA)Q:Q1Q\0P"`(D@&''X!)D!")D"#`(`F2`,
+M`@")%!AQ\\"Q#`(`F8`,`@")$QAQ]`P"`)F`#`(`B"`$B`$4<?D$B`(4<?H,
+M`@"8(,""#`(`F$#:0%O_H,"`#`(`F$`D,CHJ.N@+0``4<;8I"L`H0``("$<)
+MB`(,`@`H1``4<<7`@0P"`)A`%''&#`(`F$`4<<<,`@"80!1QR`P"`)A`#`(`
+M@B`4<6P"`E]T*0H2<?LD.@`,`@"4("(R*PL@`-$/;!`$$G'\(B```@)'>R<1
+M$W'](S``>3<($W%N(S(R"S``Q(!X(!03<?XC,``#`T=X,`@3<6XC,C,+,`!_
+M+P)@`(X:<?\HH``(`T=XAQ,L"H#`L%O_9AAQ;AIR`"B"$@N``'XW"!AQ;BB"
+M(`N``'TW"!AQ;BB"(0N``'\W"!AQ;BB"'PN``'PW$QAR`<"0*88`&'("*0H!
+M#`(`*80`>S<*$W("P(0,`@`H-``8<<2#@&DR#1-R`L"4#`(`*30`8``+:3$(
+M&7("#`(`(Y0`P#"3@``B,F<@11IQ[R*@``("1WXG&L#"P+!;_T$3<@/`@"@U
+M`!-Q;AIR!",R$@LP`'TG`EO_3GPG%1IQ[\#(P+!;_S<2<6X:<@4B(A(+(`#1
+M#P``;!`$&G(&P,#!L%O_,!IR!\#`*PH06_\M$G&V(PK`*"``P$`("$<#B`(,
+M`@`H)``3<7L2<7+`A`P"`),@$W(($G'Z#`(`E#`,`@"8("L*`0(J`EO_*0P"
+M`)0@P"$,`@"2,!)Q;AIR"2,B$B0J``LP`!-Q^R(B&AMR"AIR"PP"`)0P"R``
+MT0\``&P0!!AR#)*`T0\``&P0!!AR#(*`T0\``&P0!%N`C!AR#-.@*((`""(H
+M6X"(`ZH,<J/VT0]L$`1;@(48<@P2<@W3H(N`*B(`!KL1"CH,6X"\R*"3(!ER
+M#HB0JHJ:D-$/`&P0!%O_]!AR#H*`T0\```!L$`[,+<,@(A0`L1;8,-)@8``N
+M`-<0VT#:(%N`P:I:**``VT`H=`#:(+%V6X"ITJ#78&6OX&/_T[`B)"``)(0`
+ML8AR&?(!8@RB,\!`)#0`T0\```!L$`0"`D=I*0X3<6[`K2@R%`N``&``"`#`
+M/7,A"A-Q;B,R%-H@"S``T0\``&P0$I4?U2`B'#"3'90>DAG`0,`D(QQP)A80
+MDAHB%A0G%A&3&-)`)!85UA!@`Y["A7BA`F`#CRA0`<(]<X$)P)"R5RD6%V``
+M"<`Q*%`"LU<C%A?`4,,P)186<XD)P)$H<``I%A:Q=\`PP+E@``X.-1&C4P\S
+M$2AP`*.3L7<IC-`)"D?5<'J[Y<*>>8DC)1(6*'``L54E%A:Q=\"I8``&```H
+M<`"Q=RF,T`D)1]5P>:OO*0IL)PIB>8$"8`,C*%``>8$%L55@`Q@`*%`!LEEW
+M@3=X<QC$5'6!+WA3!,128``DQ55U@2+%6&``&@``)0IP=8$5>%,&)0ID8``)
+M`"4*=76!!24*>'6);242%,&HM%<E'#!WJ@HE$A1UH@'"="4<<*=5)5S\A5`G
+M%A0E%A75D&``)@``*A(4)QPPM*G!J'FJ"BL2%'NB`<*4)QQPJ7<G?/R,<"D6
+M%"P6%2?ZWP>'`2=\O,UR*1(59Y`-"0D&*185PGU@``0`U9#`<,68>8D"8`"!
+M>),OQ)-YB0)@`0]XDPG"I<22>HDX8`%=Q9-YB0)@`+7%E7F!7,24>8$"8`%0
+M8`!1````*0IP>8$R>),:*0IC>8D"8`#5*0ID>8$V*0IB>8D"8`#O8`$F*0IU
+M>8$D*0IX>8$>*0IS>8%L8`$1PZ!;_W@C"@$J"GA;_W8C%A;`.&``0"8*9':!
+M,GAC%\5E=H$JQ6@=<A)V@2W$9':!`F``]6``%R8*=7:!$28*>':!$R8*<':!
+M`F``W6``!QUR$,#*8``$'7(1P<`J$A7;$%O_3-2@8`#``"02%+1&)`H8=DH1
+M*!(4>$(")@HD)A84)!QP8``%)A84)!PPID0D3/PF0@`4<@\&1C@&:`(&A`RQ
+MB+")*9``99_R8`!]`"D2%,&(M)<C'#!WB@AY@@(G"B0C''"G,R,\_"HP`[$B
+M6_]%)Q848`$&PD`#-#G`8+!)PJ[#L6``&P``+!(5`&`$#`@;"`A`W+`(K#C8
+MP*8<*,0`L69Y8N)@`!_"I5O_-F``&<*E*!896_\S*!(9(BP""(H"6_\P8``"
+M`-80!#,,R'LH$A:P,V2!"&``"@``*1(699"B8`$%VG!;_R>Q(F``E0`G$A?#
+M@&```<*`V3!@`!0``-J`*!89*1886_\>*1(8*!(9L)EKD>G`@`@X-;`SJ"((
+M,PS(==IP6_\7L2+78&``!RIP`+%W6_\3!T@,J&AK@>_`<"@2%P='-;!$IV:G
+M(@=$#,J'US#"@&``#0#:@"@6&5O_""@2&;!W:W'OP'`',S6C(F``!K%56_\"
+ML2(J4`!EK%K1#RD2%V2?9&/_G0``=XD"8_U->',>Q'1WB0)C_4)X<P3$<F``
+M+,5U=XD"8_TRQ7A@`!\``"<*<'>)`F/](GAS!2<*9&``"R<*=7>)`F/]$"<*
+M>'>!`F/]2V/]!``I$A?"@&2?$6/_.2@2%V6/.F/_`VP0!-Q@VT#:,%@$Q-*@
+MT0]L$`1H,1')/B(\_L"!P#`"@SB\,M$/```3<A,B(BL#(@'`,&``!P``(B(K
+M`O)`P(T"@SC2,-$/`&P0!`4%3PQ5$:4SBSO`('*Q6B4P*7)1!VA2+6``2P``
+M)0K`R&<C,#$B"F`#)3D-0A$(2A$"J@P.JA&BJ@VJ$5M_8;JBI2)@`"`.LA$;
+M<A0-1!$+(BHJ3!4"8A0"*P("J@A;?U@.HA$B+"0"`D_1#P!L$`08<A4B.N@(
+M,P@,`@"(,`A(`7A1#2H*"B(L_UOZSV4OZ-$/P"'1#P```&P0!!)R%@P"`(@@
+MP"`(&4"QB`B2.=$/`&P0!"LB-6>P#AAR%\"0#`(`F8`,`@"(@!AR&"E:P`@X
+M`0-J0`F)`@J8.<"7"8D"`PI`"I@Y&7(9>3`%&7(:"8@"&7(;#`(`F)`,`@"(
+MD",F-6<P#Q-R%\`A#`(`DC`,`@`B,@`2<AS`,@P"`),@$G(=#`(`DR`2<AX3
+M<A\,`@"3(-*PT0\```!L$`08<B`;<B$,`@"*@,"3#`(`@[`,`@""@'HA!K"9
+MVB!EG^O1#P``;!`$&'(B#`(`DX#1#P```&P0!!AR(\"4#`(`F8#1#P!L$`09
+M<B3"H`P"`(B0"H@"#`(`F)#1#P!L$`0#"$MZ3Q8(B5<I)`P(B!3`D"DD#2@D
+M#B,D#V``&A-R)0.(`@B#5R,D#`@#5R,D#0B#1R,D#B@D#RD@,,<^")@0*2`Q
+M`)D1")D"*"`R"(@1"8D"*"`S"8@"`X@!"(-7(R0P"`-7(R0Q"(-'(R0R*"0S
+MP"'1#P!L$`0B,#`(*!`B,#$`(A$((@(H,#((B!$"@@(H,#,"B`+`+W^/`F`!
+ML"50,W]?#15R(@P"`(50=4D"8`&<(C`0*3`8""H0(C`1")D0`"(1"B("*C`2
+M*S`<"*H1`J("*C`3"+L0`JH"(C`4+#`@""X0(C`5",P0`"(1#B("+C`6+3`D
+M".X1`N("+C`7"-T0`NX"(C`9)#`;`"(1"2D"(C`:+S`H""(1"2("*3`=`D("
+M`)D1"YL"*3`>)#`?")D1"YD"*S`A"/\0`+L1#+P"*S`B"4D""+L1#+L"+#`E
+M)#`C`,P1#<T"+#`F"TL"",P1#<P"+3`I)#`G`-T1#]\"+3`J(S`K"-T1#]T"
+M#3T"P#`C9`HC9!H.`TN282-E!,`@DF`+@E<B9`P*@A0B9`X*`E\B9`\+@A0B
+M9!$+`E\B9!(J9`TK9!`,3`((DD9WCP(B^O\B9!,($E`)`T`*BE<.SD`B9!<)
+M&4`(`E`.,Q$-F1$J9!0N9!8B9!@),P)YCP1@``8``,$@`C,"(V0:?88*(F`:
+MPC`#(@(B9!IQA@HB8!K$,`,B`B)D&L`R<X@FP"%]CQ[!('*`"PB(%"-D"BAD
+M"V``$,`X<X`%(V0*8``%>H<"(F0*FV><:)UIP"#1#VP0!!1R)BLB-=H@!+L!
+M6_\M%'(G#`(`B4`)1$7(.L./TT!X02BQ0V``!M-`;D(>L$-T,1DK.O`,.!$+
+MB`$KR@\+F0$)B`(9<B<,`@"8D-N@VB`#1`Q;_QO`,<`@!#(YT0\```!L$`08
+M<B@.,Q&H,PP"`)0PP"'1#VP0!,`A&'(I`#$$`",:#`(`DX#1#P```&P0!!AR
+M*@XR$:@B#`(`@B`"`D'-)1AR*0P"`(F`*`H!`#$$`(,:"3,!`X(YT0\``&P0
+M!"D@7-@@")(0*8!=BAH`F1$"F0(B@%X#`TL((A$)*0(B@%\<<BL)(@+'G@DB
+M`0*)5RF$7`()5RF$70*)1RF$7L.?"6DV`)D1`Y,"(H1?PI`2<AH)J0$)*3G`
+MX`.9`M+`"@-``^(XP?`)*0(2<BP/HP$#(SD).0()@E<BA`@)`E?`,B*$"0F"
+M1R*$"@.B`0Q5$`+L.`7"`@*%5R6$#`(%5R6$#8P8`H5')80.%7(O`/$$`,P:
+M!<P!#(57)800#`57)801!X57)804!P57)805!X5'*80+(H0/+H02+H03)806
+M)X07C1DK$@LNA"0CA"4C^H0CA"<OA"8C"O]ST3L3<C`#U1$#50$"50(%@E<B
+MA`P%`E<BA`T%@D<BA`X2<C$EA`\"F0()@E<BA`@)`E<BA`D)@D<BA`HIA`O`
+M/,`A<Z@"8`"=$W(R`+`$`P,;`C,!9#",*8`((X`)")D0`#,1"3D"(X`*'7(M
+M"#,1"3,"*8`+P%`#DP+`F`FI`0E=.-G0P-0-J@$=<BX#F0(*73@-F0*%'`F#
+M5R.$"`4%3@D#5PQ<`B.$"0F#1R.$"@R#5R.$$`R[$`P#5P>W`B.$$0R#1B.$
+M$@>#5R.$%`<#5R.$%0>#1RF$"RR$$R.$%B>$%]$/TC#1#P``;!`$9$!%)"`,
+MP&`(2!`D(`T`1!$(1`(H(`X(B!$$A`(H(`\$B`(4<?(#@P(%1C@&,P(#A%<D
+M)`P#!%<D)`T#A$?58"0D#B,D#V``RV10B20D""0D"20D"B0D"P.$5R0D#`,$
+M5R0D#0.$1R0D#B,D#R5@$`A3$"5@$0!5$0-5`B-@$@@S$04U`B-@$P4S`@.$
+M5R0D$`,$5R0D$0.$1R0D$B,D$R5@%`A3$"5@%0!5$0-5`B-@%@@S$04U`B-@
+M%P4S`@.$5R0D%`,$5R0D%0.$1R0D%B,D%V``/A1Q\B4D"`0S`@.$5R0D#`,$
+M5R0D#0.$1R4D"24D"B4D"R0D#B,D#R4D$"4D$24D$B4D$R4D%"4D%24D%B4D
+M%\`P(R0\(R0](R0^(R0_(R0X(R0Y(R0Z(R0[P"'1#P``;!`$&'(S!C,0"#,!
+M`X-7(R0@P#`C)"$C)"(C)"/`(=$/````;!`$*#!<"(D0*#!=`(@1"8@"*3!>
+M")D1")@"*3!?")D"P(]_GP)@`GK'C@B8`0B*5RHT7`@*5RHT72@T7PB*1P@8
+M2RHT7@B*%"HT9"HP0"@T90BH$"HP0<"P`*H1"*H"*#!"*S1F"(@1"HH"*#!#
+M*S1G"H@""(I7*C1@"`I7*C1A"(I'*C1B*#1C*C`\*#`]"*H0`(@1"HH"*#`^
+M"(@1"H@"*C`_"*@"?H<$P*$J-&9\APHJ,&;`L@NJ`BHT9L"D>H`(*S!F"ZH"
+M*C1F?I8**3!FP*@*F0(I-&9\A@HI,&;!H`J9`BDT9GV&!,"4*31G?H81*#!G
+MP)@)B`(H-&?`L=H@6_Z^*#`]?X<1*#!GP9`)B`(H-&?`L=H@6_ZX*3`X*#`Y
+M")D0`(@1"8D"*#`Z(C`["(@1"8@"""@"<89Q(C!G*C!$*0H!"2(""*D0*C!%
+M(C1G`*H1":H"*3!&")D1"IH"*3!'"ID""8)7*C!((C1T"0)7(C1U*31W"8)'
+M"*D0*C!)(C1V`*H1":H"*3!*")D1"IH"*3!+"ID""8)7(C1X"0)7(C1Y"8)'
+M(C1Z*31[*C!,(C!="*D0*C!-`E)!`*H1":H"*3!.(C1H")D1"IH"*3!/"((4
+M"ID"*#1J"`A?"8I7(C1K*#1L"8(4"0A?*31M*31_*3!0*#1O*#1]")@0*3!1
+M(C1N`)D1")D"*#!2(C1^"(@1"8D"*#!3*C1I"8@""()7*3!4(C2`"`)7(C2!
+M*#2#"()'")@0*3!5(C2"`)D1")D"*#!6*C1\"(@1"8D"*#!7"8@""()7(C2$
+M"`)7(C2%"()'(C2&*#2'*3`\")@0*3`]`)D1")D"*#`^"(@1"8D"*#`_"8@"
+M"$)#(C1P"()#(C1Q",A#P"`H-'(B-'/`@-*`T0]L$`2(&,.?"54V*AH``PE+
+M$W'R"HH!"CHY$W(U`%41`U,!"3,"%7(NP)0)B0$)63D*,P(#DP(5<AK"D`F)
+M`0E9.1IR*P.9`@@%0,`P!3HX":4"&G(L*0H0"8D!":DY&W(Q*@K_!9D""F4,
+M!3LX";4"*0H(&W(M"8D!";DY!9D""857)20("057)20)"85')20**20+>F$(
+M$W(P`V81`V,!%G(V#$00!D0!`T0"%7(KP#(#@P$#4SD$-`(5<C3$,`.#`0-3
+M.00S`B0*@`2(`11R%09W$`A(.0.(`@B#5R,D#`@#5R,D#0B#1R,D#A-R,R@D
+M#P-W`0>'5\`P)R0@(R0A(R0B(R0CT0]L$`:4$B0@",","$80)"`)`$01!D0"
+M)B`*"&81!&0")B`+!&8"%'(Z!&0!>'`:?7<+%'(F!&8!%'(N8``(%'(Y!&8!
+M%'(M!&0"!(97)B0(!`97)B0))"0+!(9'A%`F)`H6<B\`1!$&1`&&51=R-@QF
+M$`=F`09$`H9?%W([!&80!D0"AEK`P`AF$`=F`1=R-P9$`@-S.00S`@.$5R0D
+M$`,$5R0D$0.$1R0D$B,D$R12$"-0!PA$$`0S`H16%G(\"$01!`1/!#,"A%L;
+M<CT`1!$&1`$$,P(#A%<D)!0#!%<D)!4#A$<D)!8C)!>#5(92`P1`!@A.UG`$
+MQCC48(97BED`9A$+9@$9<BT(9@(*"$`(R3@&1`()1`($AE<F)!@$!E<F)!D$
+MAD<F)!HD)!N(7(E>"`1.*%(1"09``(@1W7`+B`$&S3@$B`(D4A/6T!UR+00+
+M0`O-.`AF`@UF`@:(5R@D'`8(5R@D'28D'P:(1P,F0"@D'@]F$0,80`AF`AUR
+M%<"("#,!`\TX!M8"EA"&4\#"P3P.9A$#9@'`M`RC`<+0"Z\!`],YQ-`/WSD=
+M<BP(J@$*VCF-6"XZ@`G=$0[=`0;=`@R>`29*``YN.19R.)T1"YT!#6TY%G(Q
+M")D!"6DYAET;<CX$9A$+9@$,3`&6$PQ\.<!D%W'W!DL!"$@!AA(4<BT+>SD7
+M<C\(2#D,9!"&$0=$`09$`H83!D<")%(2%7)`#T00!40!!'8"A!`$9@(#8P(/
+M/P(*^@(.K@(-[0()V0(,G`(+RP((N`((@U<C)"0(`U<C)"4(@T<C)"8H)"?1
+M#VP0!"D@#`Y$$`B8$"D@#0,#3P"9$0B9`B@@#@B($0F)`B@@#PF(`AER00F(
+M`@B)5RDD#`@)5RDD#2@D#PB)1QAR0BDD#@A$`2@@(`-$`@B#$"@@(0"($0.(
+M`B,@(@@S$0@X`B,@(P@S`AAR0P@S`0-#`@.$5R0D(`,$5R0D(0.$1R0D(B,D
+M(]$/````;!`$*2`,#C,0")@0*2`-`)D1")D"*"`."(@1"8D"*"`/"8@"&7)!
+M"8@""(E7*20,"`E7*20-"(E'*20.*2`@*"0/")@0*2`A`)D1")D"*"`B"(@1
+M"8D"*"`C"8@"&7)$"8@!&7)""3,!"#,"`XA7*"0@`PA7*"0A`XA'*"0B(R0C
+MT0\`;!`$*2`,")@0*2`-`)D1")D"*"`."(@1"8D"*"`/"8@"&7)%"8@!&7(Q
+M"8@""(E7*20,"`E7*20-"(E'*20.*"0/*2`@*"`A")D0`(@1"8D"*"`B"(@1
+M"8@"*2`C")D"&')$*20C")@!"(I7*B0@"`I7"(A'*B0A*"0BT0\```!L$`0I
+M(`PH(`T(F1``B!$)B0(H(`X(B!$)B`(I(`\(F0(8<D8I)`\(F`$(BE<J)`P(
+M"E<(B$<J)`TH)`[1#P``;!`$*2`0`P-.")@0*2`1`)D1")D"*"`2"(@1"8D"
+M*"`3"8@"&7)'"8@!`X,"`XA7*"00`PA7*"01`XA'*"02(R03T0]L$`0K(`@J
+M(`DI(`HL(`O*/0BX$`"J$0BJ`@B8$0J(`AEQ\@C(`@F(`@B)5RDD"`@)5RDD
+M"0B)1RDD"B@D"]$/"+L0`*H1"ZH"")D1"ID"&G)("<D""IH!"HA7*"0("@A7
+M"HI'*"0)*B0**20+T0\`;!`$VB!;]MS1#P``;!`$&'(CPI`,`@"9@,#0P,3`
+MN-H@6_OQP('`(`J".=$/````;!`$$W)))#K_#`(`E#`4<DH5<DL,`@"#0`4S
+M`@P"`)-`%'(D%7(N#`(`@T`%,P(,`@"30!1R3!5R%0P"`(-`!3,"#`(`DT#`
+M5<!`8``9VT#:(%O\W62@6]I0(SS_6_:M93_JTC#1#P`C.NAC_]\3<DH4<DT,
+M`@"",`0B`0P"`)(P$W(D%'(Y#`(`@C`$(@$,`@"2,!-R3!1R3@P"`((P!"(!
+M#`(`DC`2<DD,`@":(,`AT0\`L41I2:YC_[%L$`05<DG`00`Q!`!$&@P"`)10
+M)#KH)0IDVS#:(%O\N\BHVE"P1%OVC&5/[!-R2<`@#`(`DC#`,00R.=$/````
+M;!`$&'(6#`(`B(!^APT8<D\,`@"(@`@(0VB"",`@DC#1#P```!AR4`P"`(F`
+M:)#K&'(8&W(:")@!F#![D!\:<E$,`@"*H'N@!QMR+`N(`I@P>:8)B#`:<E(*
+MB`*8,,"%>)`(B##`H0J(`I@P*%K`>)`UB##$D`F(`B@V`!-R4PP"`(DP$W)4
+M#`(`*#(`"),""0E?"`A?"3,""#,"*"(X`P-)`X,"(R8X$W)5P"$,`@"(,&B`
+M#RD*8'F`"0P"`)@P#`(`@S#1#P!L$`0I2@`#"$<)B`(9<E8,`@"8D"@J``@X
+M`<*0")@Y=S<%$W)7`X@"$W)8&7)9#`(`F##(C0P"`(B0P3`#B`)@``L```P"
+M`(B0QC\#B`$,`@"8D-$/````;!`$*AHP6_9`U2#2H,RDP#*30-$/&W):+`K0
+M6_9&&');DR*8+QAR7)4A*"80&')=*"81&')>*"82&')?*"83&')@*"84&')A
+M*"85&')B*"8@&')C*"8B&')D*"87&')E*"88&')F*"89&')G*"8:&')H*"86
+MT0\`;!`$$G)I(SW`P(`#@CG1#VP0!-$/````;!`$T0\```!L$`3:(%@'Q"HB
+M1E@`*]$/;!`$&G)J6!,4TJ#1#P```&P0!,#!*PH@*@H,6_9)P,$K"JC`K5OV
+M1A9Q;A-R:R)B4MLPP*`+(`#2H,RJ(V(2&G)L"S``T0\`B&3<,,"P"X``(RT!
+M*#`D*?J`"8@"*#0D*T(!)F(2&G)M"V``BD'<4-L@6`:7S:$F,"0;<FX&!D8F
+M-"3:4%@`!=$/P"#1#P``;!`$&G)O6!+ST0\`;!`$&''8P""3@-$/;!`$&''8
+MP)"9@-$/;!`$&'%NVR`H@E+`H`N``-*@T0]L$`08<6[<0(B%VS#:(`N``-$/
+M`&P0!!AQ;MQ`B(3;,-H@"X``T0\`;!`$T0\```!L$`1C__P``&P0!-$/````
+M;!`$*2$(B"8IG?\)"4_`*'DC1!IR<`Z9$:FI@I`*(``CACQ@`#0CACU@`"XC
+MACY@`"@CAC]@`"(CAD!@`!P``".&06``%".&0F``#B.&0V``"".&1&```F/_
+M_,`@T0\`;!`$&')QBB*8,AAR<MLPF#,H:D`H-0K`@"@U"QAQ;I4Q*(*%)#4(
+MDC8+@`#1#P``;!`&W!"T&\P]VD!;]&+`O-I`6_.[8``$VC!;]%Z#$,!K<V,#
+M8__\`"E26X,1L9DF,`$G,`/;0"E66]PPVE!8#:';H,RO$W%NBE(C,H?<0-L@
+M"S``T0\BIB,B,`H,>!$BI)(B,`(BI),'@@P*:!&FB`^($::(HH@.B!$B6I*H
+M6**((H``VE!^)P=8#V'1#P```%@//]$/``!L$`3=(-Q`VS#:4%@.1]$/;!`&
+MAT!@`'TF?!3:8%OT0=F@RZPK<@`J(D8%7`);\\A@`"$``!AQ;HT@*8*CVF"9
+M$9T06_.OC1")$0JL`BL*`]K0"Y``VF!;]#-EK]>:>&``)89XRF`K<@`J(D8%
+M7`(I%@%;\[<8<6Z,>(H@)H*CP+,+8`")$9EXBW`J(D;`8%OSLY9TAWEE?WZ7
+M0)1!P<C;<-HP6_^"T0]L$`08<6[<("B":MM`VC`+@`#1#VP0!!AQ;MH@*()L
+M"X``T0]L$`8E+06#6\!`(Q8`(R+59#"+AC]_;P)@`(.-.&3?[X8YASK(9)=J
+M8``#`"<FUH<ZVM"6<)0X*PHH+18!6_-,PL@K/$#7H%O_88I;AG$HHAX+@``+
+M:`RKBPC\$\!AC1%XLP'60*K*JF:6<!9Q;HHB)F*)FW'<T,"S"V``)B)]QWZQ
+M9B8F?88_E#D'9@&6/R8BUI8ZDV`C/"0C)M9C_VTC(L3`L0.[`H,0*R;$(C(H
+MVC`+(`#1#P``;!`$&')S<HLR#`(`DR`3<?MS*7<2<G0C(`!E,&X3<6XJ"G4H
+M,C<+@``;<@HC,AH:<G4+,`#`,2,D`-$/&')V>"D^&G)W**``SX4;<?H<<GD,
+M`@"8L!AR>`P"`(F`#)D"#`(`F8`,`@")@!QR>@R9`0P"`)F`PH`,`@"8L,"!
+M**0`&'(5J"(,`@`C)@#1#P``;!`$&')[&7(E"#@!>8DU&'(5'')\J#@;<GT,
+M`@"(@"T*``(J`EOZ(LRL$G%N&G)^(B(2VS`+(``2<G\,`@""(`("3]$/$G)S
+M<RH$8``&```2<A6B,PP"`((PT0]L$`0H706*BRBB'@N``"A=%HB-"+L,&'*`
+M>XL1$W%NBE(C,H?<0`(K`@LP`-$/W5#<0-LPVB!;_S#1#P!L$`0H(MPI(O'`
+MT)V)F8J8D"@BW"TFW"B,)"@F\2@BYWV!$"PZP"LZC*PL"RL(`BH"6_],*"+A
+MR(\L.E0K.G3`T:PLJRO:(%O_1]$/;!`&E3"%'(H@!6LHN#V;-,#!6`9]A3*:
+M,851E3/8H&2@;`=L*)@2VL"<$%O^V-6@C!!DH%G`L%O^W\"0E3690)1!B!)@
+M`$$``(H@VU"8$ID16_+WVZ"($HD1SZ&87)A>F%TJ7!28$ID1FQ!;\VR*08L0
+MFEJ;696@*EPDFD&)$8@2BARQF:J(IU5VDKQ@``O!R,"PVC!;_L=C__S`(-$/
+M`&P0!B0M!85+)"+;(R;;S$-@`8```"A`-"-`-0B($``S$0@X`B-`-B9`-P@S
+M$0@S`@-C`F4PN1-Q;BTAEB,RHHH@P\#`LPLP``J#5R-$-`H#5R-$-0J#1R-$
+M-BI$-\V@(R)\)";;L3,C)GS'+]$/````(T`X*T`Y"#,0`+L1`[L"(T`ZW*`(
+M,Q$+,P(K0#LJ(D8#NP+`T5ORQ2I`.2-`.`"J$0@S$`.J`B-`.BM,/`@S$0HS
+M`BI`.P.J`EORQ"-`0`@X$"-`00`S$0@S`BA`0@B($0.#`BA`0P.(`@B#5R-$
+M!`@#5R-$!0B#1R-$!BA$!RA`-"I`-0B($`"J$0BJ`BA`-L`P"(@1"H@"*D`W
+MW!`K'`0(J@(C1``C1`$C1`(C1`-;\Q`H0#0J0#4(B!``JA$(J@(H0#8F4B`(
+MB!$*B`(J0#<(J@);\OC;H-PPVD`+8``K0$@I0$DH0$HC(N\(NQ``F1$J0$L+
+MF0((B!'-,0F+`B-2'PNK`MI0"S``8``)```)B`((J`*8,"0F[R)2)=I0"R``
+MP"#1#VP0!F@C`F`!`")"?MHPL2(B1G[;$%ORL")"UQ-Q;F``Y=H06_)K9*#@
+MW*`E,J.*0,"S"U``*"!,)2!-"(@0`%41"%@")2!.`BL""%41"%4"*"!/!$H"
+M!84"6_^#*"!,+"!0"(H0*"!-*2!2`(@1"H@"*B!.",P0"*H1"*@"*B!/*R!3
+M"*H"*"!1")D1`(@1#(@"")@""+@"R:@(B5<II%`("5<II%$(B4<II%(HI%-@
+M``0``"A&V"D@4"@@40B9$`"($0F)`B@@4@B($0F(`BD@4PB8`IJ`P(`H)$PH
+M)$TH)$XH)$\H0MH(B5<I)%`("5<I)%$(B4<I)%(H)%.2@"(L3")&VM)092\6
+MT0]L$`06<6ZT7"=BDL"PVB`+<`#7H&6@"B)B$AIR@0L@`-$/P)#`@=J0*PIC
+M!8HY=;H""9@">*`0R$W;4`=Z`EOR>]Q0VT!;_@4D8I/>4,#0`PQ/VW#:(`M`
+M`-$/`&P0"B,B26<P!L`P8`81```D+06%2R-2)MI0"S``9*_H(U(GO!O:4`LP
+M`(83(R+$!C,!DQ-Q-ADC4BC`L-I0"S``*CI$JBI;_G?`,6`%T0```'\V0R-2
+M'MI0"S``(RT!FQ&&6RLP')H0VE`+8``J%`@C4AX%6@(+,``C+1::/)L]BB,;
+M<H+<$,#96__&*TK,P,&K*]H@6`[)@Q-Z-P<F(DVQ9B8F37LW""8B3B9L`28F
+M3L-A=C@"8`4@?S<'(R),L3,C)DR$2R8BU905(R+98`3/&G*#L7>)H+"9>7$"
+M8`'O%G%N&G*$)V(2"W``P'!@`=@H,#@K,#D(B!``NQ$(NP(H,#HJ(D8(B!$+
+MB`(K,#LL"@$(NP);\>@I,$PH,$T(F1``B!$)B0(H,$X(B!$)B`(I,$\(F0*9
+M%&60#2)B$AIRA0L@`&/__```*#`T+#`U"(@0`,P1",P"*#`V*6*C"(@1#(@"
+M+#`WBB`(S`+`LPN0`-LP)S0T)S0U)S0V)S0WVB!;_M\H,$\O,$PM,$TI,$Z8
+M%2PP4"LP40C_$`#=$0B9$2@P4@_?`@^?`@C,$(D5`+L1#+L""(@1+C!3#Y\"
+M"X@"9:!O".X"R?8.B%<H]%`."%<H]%$.B$<H]%(N]%-@``(N)MHI,%`H,%$(
+MF1``B!$)B0(H,%((B!$)B`(I,%,(F`*?@"@BVB<T3`B)5RDT4`@)5RDT40B)
+M1R@T4R<T32<T3B<T3RDT4I.`*#Q,*";:8`!Q`,GY".X"#HA7*/10#@A7*/11
+M#HA'*/12+O138``%".@"*";:*3!0*#!1")D0`(@1"8D"*#!2"(@1"8@"*3!3
+M")@"+X8`*"+8)S1,"(E7*310"`E7*311"(E'*#13)S1-)S1.)S1/*312(X8`
+M*#Q,*";8=#D?(R+$Q[X#NP$C4B@K)L0%6@(+,``J.A2J*EO]V&`#$@"#%&4^
+M(V/_URU``"M``0C=$`"[$0V[`BU``@C=$0O=`BM``PV[`F2_MHEO?Y<"8`+8
+M*D!(+$!)"*H0`,P1"LP"*D!**2+>B!4M(N`(JA$,J@(L0$L-G0PI@B*KW0K,
+M`BYL0-M`VH`+D`#`GWFI`F/_;BE`-"I`-0B9$`"J$0FJ`BE`-@B9$0J9`BI`
+M-PFJ`EOQN\ZB*4`T*D`U")D0`*H1":H"*4`V*V$D")D1"ID"*D`W":H"6_&4
+MBA0I820M8%:IJ`@(3Y@49=(AVA"=&%OQN2E`3"=`30B9$`!W$0EY`B=`3HT8
+M"'<1"7<"*4!/!YD"F19@`>\G,#@K,#D(=Q``NQ$'NP(G,#HJ(D8(=Q$+=P(K
+M,#LL"@$'NP(M%@A;\30K,#4G,#0`NQ$(=Q`'NP(G,#8!&@((=Q$+=P(K,#<'
+MNP);\0\O,$TG,$P`_Q$(=Q`']P(O,$Z-&`C_$0?_`B<P3RTT-"TT-2TT-BTT
+M-P]_`LSQ8__\VS#:()T8GQ=;_BXN,$PL,$TG,$X`S!$([A`.S@(K,%`I,%$(
+M=Q$L,$\.?@*-&(\7#LX""+L0`)D19:!^"YL"*3!2")D1"YD"*S!3";D"R>8)
+MAU<GY%`)!U<GY%$)AT<GY%(IY%-@``(I)MHI,%`G,%$(FA``=Q$*>0(G,%((
+M=Q$)=P(I,%,'EP*><"<BVBTT3`>)5RDT4`<)5RDT40>)1R<T4RTT32TT3BTT
+M3RDT4I-P)SQ,)R;:8`"-`,KH"YL"*3!2")D1"YD"*S!3";D""8=7)^10"0=7
+M)^11"8=')^12*>138``4"YD"*S!2"+L1";D"*S!3";D"*2;:*3!0)S!1")H0
+M`'<1"GD")S!2"'<1"7<"*3!3!Y<"GG`G(M@M-$P'B5<I-%`'"5<I-%$'B4<G
+M-%,M-$TM-$XM-$\I-%*3<"<\3"<FV'-)(X,4VA`C921;\-Z#;\!!!#,"DV^:
+M:(,6AFG`@-0PF!37@&``)=/P93X,8__3*D!,*4!-"*H0`)D1"IH"*4!.)$!/
+M")D1"ID""40"94K[8_S/``"#$W0W$",B3\"QL3,C)D^#5]I0"S``*EH<JBI;
+M_0N#$WTV!RHZ)*HJ6_T(A!-R1@<C(E"Q,R,F4,`Q=D8()")1`T0()"91TC#1
+M#VP0!,#0&W*&BB,-W`);_ES1#P``;!`$P-`;<H>*(PW<`EO^5]$/``!L$`87
+M<6ZT;"ARDBL*`0(J`@N```0$3]B@S*%C__S)8LE0VV`J%@!;\-?<8`5;`EO\
+M88@0)7*3WF#=0`,,3]N`VB`+4`#1#P!L$`8#"$\C+06,.P0$3]=0QS]@`",`
+MBW#:P)@1G!!;_3*+<@L[`PJZ`8MQ"ZL"BG"\=UO]"8P0B!$%>0QVDM;`X(HC
+MW>#<0-N`6__;T0\``&P0!"I0`B]0``BN$"I0`RU0`0"J$0ZJ`BY0!`SX$0CN
+M$0KJ`BY0!:^)"NX"`PM/K9HC6G"CJ@ZJ$:HJGJ0$#$_*[,!0P*$I"B!MF!X`
+M400`HQI^,!.OB0Z9$:DI&'*(K9FHF264`&``%;%58``0```.F1&I*15RB*V9
+MI9DNE`#`X(HCW>!;_[C1#P``;!`&*")\BB.8$"@B?<#LF!$H(G[=$`0,3P,+
+M3Y@26_^OT0\`;!`**")2BB.8$"@B4\+DF!$H(E3=$)@2*")5!`Q/F!,H(E8#
+M"T^8%"@B5Y@5*")<F!8H(G:8%R@B=R@6"%O_GM$/``!L$`@H(DR*(Y@0*")-
+MP>B8$2@B3MT0F!(H(D\$#$^8$R@B4`,+3Y@4*")1F!5;_Y'1#P``;!`$)E`,
+M*EHX"F@1IH@/B!&FB`Z&$:IJVU"J*L'&6_OUIB@F6D6FABI@`"E:6`RF$:IF
+M&G*)#F81JF:IB:8FEI`F6E"FAL"0*64`)EI2IH8I90`F6E3`T`,#3P0$3Z:(
+MBB.=@-[0W$#;,%O_==$/`&P0!"4M!85;`BH"6_SCB%;:4`N```,#3P0$3\#@
+MBB/=X-Q`VS!;_VK1#P``;!`$+5```P-/!`1/;M@"8`")"M@1K8@/B!&MB`Z+
+M$:LH*7H\J8@H@`!D@&\L4`%NR!$5<6X;<HHE4A(:<HL+4`!@`%<,R!$,B`P.
+MB!$E4`*KB*@HR5$E6I*EB"F``,!2!9D"*80`8``R)5J2I8@I@`!^ER?'7069
+M`2F$``S)$0R<#`[,$:O,)5I<*%HXI<RHN\#1K"RK*]H@6`X5P."*(]W@W$#;
+M,%O_/]$/`&P0!!IRC-M0"BH(P,A;^Z>(4`,#3P0$3R4M%L#@BB.86-W@W$#;
+M,%O_--$/;!`$*5``*%`$+5`%"(@0"IL1`-T1"-T"J;LH4`8/NQ&INPB($0V(
+M`BE:."U0!PZ[$:F[+%`!N%X(W0(+*P@"*@)8!B\#`T\$!$_`X(HCW>#<0`,[
+M`EO_'=$/``!L$`0H4`0M4`4I4``(B!``W1$(W0(H4`8,FQ&INPB($1ERB0V(
+M`@Z[$2U0!ZF[+%`!N%X(W0*K*]H@6`8?`P-/!`1/P."*(]W@W$#;,%O_"-$/
+M``!L$`0#`T\$!$_74&``"8MQBG`G?`A;_"D%>`QV@N_`X(HCW>#<0`,[`EO^
+M_-$/``!L$!8G+06)>P,#3P0$3\!P8``<``"G6(N`VI`I%B!;_#\'*!0.B!&H
+M&"D2()J`M'=V<N&*(]Y@W1#<0-LP6_[KT0\``&P0!"A0`!=RC0R&$:AF#F81
+MIB:G9]M0)7```P-/`%4R!`1/R%%C__P,BA&HJAARB0ZJ$:BJJBK`S%O[2!AR
+MCMY0J&8H+1:(BMU0F&#`829T`(HCW$#;,%O^U-$/;!`$+5``&7*-#-@1K8@.
+MB!&H**F)`PM/P#`CE``3<H[`D*.(F8`H6D4$#$^H*"\:]RXJ#,"H;:@,(X``
+M?3D$KX,I-`"NB,#@BB,.[0);_K_1#P``;!`$*5``P.`*F!&IB`^($:F(#H@1
+MJ"@I>CRIB,"0*80`BB/=X`0,3P,+3UO^L]$/;!`&VU`E4`PG6C@*5A&E:0^9
+M$:69#ID1IY>G)\'&VG"9$%O[%HD0*%I%J2FHF"J``!QRB0RH$:J(#H@1*UI8
+MK(BKFZ@HF+`H6D:HF2B0``,#3P0$3VF!$0RI$:J9#ID1&'*/J2FHF264`*5H
+M#X@1I8@.B!&H*"5Z/*6%P&$F5``E6E"EA<!@)E4`)5I2I84F50`E6E2EB,!0
+MVG"5@%@'O(HCWE#=4-Q`VS!;_H?1#P!L$`0F*@@E40`L&@`K"O^F*EOZ\RA<
+M?`Z($:@HB8,#`T\$!$_(F(R0*YPPP*!@`!)C__P`*+``*[P0J"BFB"J$`+&J
+M?*+M)2;"P-"P5<!C!=8YU6`I)H$F+0,E9`R*(][0W$#;,%O^;-$/``!L$`0#
+M`T\$!$\E(M5@`"X```"&6,IDBU`J(D;`P5ON_AAQ;H<@*EP4)H*C6^[GW*`K
+M"@/:<`M@`,"`F%B%665?T(HCWE#=4-Q`VS!;_EC1#VP0!"4M!85;`P-/*%(D
+M!5H""X``B%G`L-I0"X``*%(CVE`+@`#`T`0$3XHC+2;OWM#<0-LP6_Y)T0\`
+M`&P0!"4M!89;)6J`)29*P%`E)N\E)ML#`T\$!$\E(ME@`"?;4-H@6_OK9:!)
+M*5!,*%!-")D0`(@1"8D"*%!.)5!/"(@1"8@""%4"95_4*"+9VF`E@$@K@$D(
+M51``NQ$%NP(E@$H(51$+50(K@$LH8A\%NP(+@`#`X(HCW>#<0`,[`EO^)]$/
+M``!L$`8$!$\E+0$#`T^4$0(J`B0M!2=""Y,06`=B)E`DQ(`(9@(F5"2&?2M0
+M'-IP"V``*#K,J"/9,,!P)BT#*F#(`'`$"@H;?Z<,BDN+D(VMF1(+T`")$K%W
+M*9P@:7G>)PH`!W0"*F#(`'`$"@H;?Z\+L7<C/"!I>>M@`"X`P,';,-H@6`MA
+M8``9BKF,NLBDG*I@``(`G#>,NIK`)+0UVB!8"$2+-F6_X&/_Q290)"?ZOP=F
+M`294),#@C!&+$(HC#NT"6_WUT0\``&P0!(M0VB`KO!X+NQ&\NPLK""P*`5@+
+M2@,#3P0$3\#@BB/=X-Q``SL"6_WIT0\``&P0!"@M!8J+`P-/**(.!`1/"X``
+MP."*(]W@W$#;,%O]X-$/`&P0!`,#3P0$3\AK*"T%BHN+4"BB#0N``,#@BB/=
+MX-Q`VS!;_=;1#P!L$`0E.LP#`T\$!$^E)28*`"<M`RAPR`!@!`@(&W^'",#!
+MVU#:(%@+)[%F)5P@:6GBP."*(]W@W$#;,%O]QM$/;!`$)2T%A5L8<I`K"@4H
+M)L3:4`,#3P0$3UOU#,BJ*"+$&7)2"8@"*";$&W)N*B)&6_H:*R+$*%(HVE`+
+M@`#`X(HCW>#<0`,[`EO]LM$/``!L$`0H+04#`T\$!$^*B\"0:60!B5`;<?<H
+M(L1[D`4+B`)@``4;<I$+B`$;<I(H)L1[D`@H(L0+B`(H)L0K(L0HHB@+@`#`
+MX(HCW>#<0-LP6_V=T0]L$`0H+06*BRL*`"BB*`,#3PN```0$3\#@BB/=X-Q`
+MVS!;_9/1#P``;!`&P(&*(R@5`,#DP(3=$`0,3P,+3R@5`5O]B]$/``!L$`3>
+M8-U0!`Q/P+':(%O]AM$/`&P0!"@BPFF!!"(P0-$/P"!RB0(B,$'1#VP0&,TZ
+M)ET%+!QP*QQTVD"':UON@"82'2E@`&^2%6``%1)Q;AIRDR(B$@,[`@L@`&/_
+M_`!C__S`M-I`*18D6^W0*1(D&'*.#)81J68.9A&F5JAFAF#,86/__")F(X)H
+MRB6+8"I21MPP*18D6^W_BFC`M%OMN!)Q;HQH(B*'*V(CBE(+(``I$B0J4D:+
+M8,#0E&@$3`(I%B1;[?&*8+1K(ET%6^WV@BO%P,"P*AP@A&@B%B5;=1XJ8`B"
+M;"D2)"HD!"I@"0R;$2HD!2I@"JF[&7*)*B0&#KL1*F`+P("INR@D`"@D`2@D
+M`B@D`RHD!ZM;!5H"*!8C6_^\*5*!LJH,JA$*F0@ID!`C$B4$2@(I%B`C,A=;
+M[CC`DB@2(YD2*0K_F1$O$B#`D9@4F!.9$+2K*18DP^_`T\'(`BH""S``(Q(E
+M!$H"+S(8+Q8B6^XJ*1(D+Q(BLZK'O-X@W9#<D`NK`=H@"_``*1(D)!(@F1B4
+M&2D2)21=%B@2(R1`)B.2$-R`VX"8'-^`P.0M'"#:()0;"S``)5T!(G(-*U`<
+M!WH""R``*U`<@GJ,;-IP"R``*U`<@GS:<`L@`-$/;!`0*PH!*@H,6^^;"@I'
+MP6`*:C@.JA$J-98;<I0J.A0D-D8D-D7<,*HZ6_GW&W*5*EH<`SP""CH(6_GS
+M&W*6*CHDW#"J.EOY\!MRERHZ1`,\`@HZ"%OY["PR1BX<-,#1`SL"VB!;[SP*
+MI`)DH\$5<6XB/04G4IXJ)@LJ,D4+<``G4G4J-@`J"@`+<``G&D"7%,)QEQ4G
+M,D6:,9<6AS":%Y<8&G*8)U*#IAL+<``=<IFF.YHR+!H!VC!;^7<=<IHL&@(K
+M/"S:,%OY=!URFRP:`RL\2-HP6_EP'7*<+!H$*SQDVC!;^6T7<ITK"KC=<"P:
+M!ZL[`SH"6_EH*PK4W7`L&@BK.P,Z`EOY9"L*G-UP+!H&JSL#.@);^6`K"H#=
+M<"P:!:L[VC!;^5S:8%OY+HA4W&#`L->@"X``PH"8<AARGMQ@F'.(5,"P*APD
+M"X``AC(J'"26&88PEAK`8I8;P&B6'"92D`M@`)HS)E*1VW"3<0M@`(HR)5*&
+MP&D+4``E/0$F5!R**QMR-X6E"U``*C9_BBL;<A.%I0M0`"HV@-HP6`.+*C9(
+M9*)Y%G*?)7I`I34&-@@G*@PH,DB*@%OY"II0IU5V6?`5<H.&4&E@`\!KEE`8
+M<J"%@&E0`\!;E8#%E"4Z="8Z5"<:&)D0I36F-J<WCH`=<J$O"FC<8-M0VG!;
+M^A9EHATI.F2I.2DVVBDZ7*DY*3;8*#+>*C;9*C;7V:#<H&``PP`K@#0J@#4(
+MNQ``JA$+JP(J@#8(JA$+J@(K@#<*N@)DH`XJ"@`JA#0JA#4JA#8JA#<J,D8K
+MC#@H%A,I%A0L%A);[0DH$A,I$A0L$A+(HF/__``J,MXK,N`*B@RKJ@J.5PH-
+M5PJ+1PH*1RZ$2"V$22N$2BJ$2\B:+I0`+90!*Y0"*I0#P)`IA``IA`$IA`(I
+MA`,IA$PIA$TIA$XIA$\I,MJQS`F*5RJ$4`D*5RJ$40F*1RF$4RJ$4IB0*8Q,
+M*3;:V8`HC%0;<J"*L'K+`F/_,2@ZC*@X*!80*#K`J#@I"H@=<J(K$A"9$-R`
+M+PJ4PN+:<"@6$2D6%%OYS]B@*1(4R*-@`"\``!QRI!URHRLZI)D0+PJ4P.&L
+M/*L[VG`H%A-;^<4H$A/)J2P2$2L2$-V`VC!;^0?`T=Q@VU#:,%OY!&``O"4R
+M\,9_)E"'*E2&!V8!)_K?!V8!)E2'AEF'6LAFEVI@``4````G-O&'6L"SEG`E
+M-MP6<J`5<6Z,8"52H(HP+6J`"U``P&`E.LRE-=A@UV#`L<":;9@EN%J:4RI<
+M&)I7`($$`+H:F%"749=2EU2759=6!J8"!@9'L8@E7"`E/0,F5,@E2NRE-94M
+M)4K,I365+"4ZS*4UE2,E.NRE-94D)4H,I365)25*+*4UE28B0B@G-L3`L-I`
+M"R``P"#1#]HP6_EZ@D;:0`L@`-$/`-HP6_EV8__T;!`$$W%NBB,H,I<+@`"*
+M(B@RA`N``(HA*#)V"X``BB`C,I\+,`#1#VP0!!9Q;L"\(F)2P*`+(`":4-2@
+MTJ#)HB)B4MLPP*`+(`""4)I!(R4$(B(!T0\``&P0!&XD!2@*`'PW1\>-""@!
+M*(S[*?K["8@!98`"?S<S*"SX;X0%*`H`?3<GP)'.0&XD'L>+(BSZ""(!`QA`
+M"8@#;R(/P(((,P'`@`.8.6```@#`@=*`T0]L$`8L$1D'"$_`H)@1G!*5$%ON
+M$R,R@MF@B!&+$(P29#'59D'2)R)((B+"#B(1HG*%(:0R)R``R[-IL14F?!X&
+M!D<H"F1V@P-@``X`*"0`8``*O'8'.!0(9@PF)``F,#=V00)@`+W`8"8T-V``
+MM<"I"F8TR\ID@%`&BRB8$:O-#MH1K:H.K1&MJJN+#JH1F1"<$EMR4K>K"KHZ
+M"CH2JGH'.Q0+J@PJ)`"($8D0C!)@`!<:<J4.:Q&KJHJ@!SL4"CH4JGH+J@PJ
+M)``J,#?+J'I)-FMA!0_,$7R*"<"`*#0W8``E```D-'TF(`#!CG:+!,%D)B0`
+MP&`F-#<F4`$&%A0&E@R6/V``"`!J803`8&``$"8P?79)#28P0"@*_WAA!+%F
+M)C1`*B``9$!+PV9Z:T8K,'T.2!$.MA&DB*MF#8@1#681J%BF5HB$AF1X8R@$
+M#$<K,$'`@6``%:8V+6!"?-D()F!!)C1]8``*L8@("$<`AC)[8N.9/W>C!R8P
+M-K!G8`!$#D81I&0-1!$F3.37(*96I%1@`!LJ8``H0`QXJ=JP>"J``"=P`'I[
+M`B>$`->`)FS8=SG@8__!`"0@`"@@`72+`B0D`;$B`R0,=T+K(C(>)%`"`I(,
+M=",?TC!@`!$E(``-5!$%1`P$-!(D)``B+`$#)`QV0N<I-A[1#P``;!`$#ED1
+MI9D-F1$D-`&I*2J0#,>-"*@!P,#'VRB,^\"QU,`-B`$&M#D("$<,1A$(RSD&
+MN`(KK/H-NP$+"T?`8G:S`=;`*JSX"@I'!H@"P&!OI`'`9`:(`B@T`PY8$:6%
+M#541I2(E(!XE-`""*9(Q@I22,L`A(C0"T0\``&P07B8B2"(BPM<P#B(1HF+#
+M9H(A*`H`)C0V)@HV;6@$*'0`L7<G/$+`@"8*-FUH!"AT`+%WP'#9$-IP*RJ(
+M8``4*F0`L6:PB&6/]2J4`"=\-K&9>W$+O':F%L.&8__A````P&(&1@$$"$`F
+M-'PH%JK(5"=0`&5PA"D@`,!@M">I.=4PWF!@`&@O$JK,]2UP!V```P`M<`-I
+MT5$O<`C<X-KPVT`H%K`I%K$M%K(N%K,O%J];_Q\H$K`I$K$M$K(N$K,O$J_*
+MI`_Z$:^JKQP-KQ&OJBO```^J$:H:"ZH(*[P!**0,*\0`+51"!H8W)WPHL54#
+M6`P("$=UF8U@`="G6,"0P'@'3P$I%JG`<L"4!GDX*!:L)1:HV%`O%JW`T2D6
+MKF``IP`O$JK,\XIA8``!BF`K@`$L8!8,NP,+"T9EL'4O$JTK$JX/VS@+J@$+
+MJ@S;X`K;.`L*1R]@"&2@6&_T5=S@VO`$2P(H%K`I%K$M%K(N%K,O%J];_NXH
+M$K`I$K$M$K(N$K,O$J_*J@_Z$:^JKQP-KQ&OJBO```^J$2\2J:H:JZJQNRO$
+M``G_-\#!*:0,+'1"+Q:I)FPHL7<O$JL#>0P)"4=W\0)C_UJQB"82K':!$"<@
+M`+0FISDI%JO7,,#@8__7P&!\3P)@`-TG4!_`@J=5)1:K)1H`!44!)1:M"$@!
+M8`"I`"\2JBU0",SV+%`'8``$```L4`,O$J@K4!8J\"`*N@,*"D9EH&=NU&3`
+M\@_*`<B@R(1^P%AD@%4KO/',MLBD+Q*M9?!(VM#`P-M`*!:P*1:Q+1:R+A:S
+M6_ZU*!*P*1*Q+1*R+A*SRJ0/VA&MJJT<#:T1K:HKP``/JA&J&JNJ*:0,L;O`
+MH2O$`"IT0@EF-R5<*+%W+Q*L`WD,"0E'=_$"8_]>)1*HL54E%J@I$J@O$JM_
+MD1$G(`"T):<Y*1:LUS#`Y&/_S@`O$JD/9C>Q9L!`)C0V)#1]P&"\%RT@`]M@
+MV6#`@6``9R6@`*0T)41"L>4%#D>QJJOD!`1'?.GHW(#;T-I@*!:P*1:Q+1:R
+M+A:S6_Z'*1*Q*!*P+A*SU9`.A3@%!4<M$K+-6@J%.,U5#V41IE4-6A&J50]5
+M$:45KE4E4`LE-'VQ9B=\-FAJ#=M`IA0L0`#:<-Z08_^:I#4E4#XD-$&P1"4T
+M?00$1\"P8``YI3JQ5:4\**!"*<!"#H<1#I81J'>I9@UW$0UF$:<GIB8G<@4F
+M8@5W:P4II$(HQ$(%!4=T4LJP1`0$1\A#U;!C__#1#VP0!"HB@F1@2BN@0<.6
+MP(%@`!D`I:4L4$)TR0NPF210066?Z6``-@"QB`@(1P"%,GM2X&``)ZFI+)!"
+M=,D'L%4DD$%@``VQB`@(1P"),GN2Y&``"<A6*Z!!P(%C_^S20-$/``!L$`B4
+M%"0BPI,3(R)(#D01EQ&D,X@1+!(1EA6&,8,3P'`D,H(("T"7P-IPE1*;%B42
+M$%OL9RQ`0;#("`A'W7"+%F``2J-#*3!"(T!]>3,Z#I,1J3,-,Q&C8XXU?M,1
+M(T!]<W-QCQ%_]VS`<+#,8`!"J4,C,`#`_`\S-R\*9`/S#`XS*'TS`]>0W3"P
+MB`@(1P"#,F<_KF/_Q:=(*8!"<YD-AT\I8`$'IPQWDPU@`"FQ=P<'1WQRX6``
+M'B=`0,EX(X!#P'`H$A$G1$`C1#>:3\!QEX!@``(`TW`G0#9W,@4C?/\#`T<L
+M$A&'P&5Q2`XX$:.(#8@1J&B(A"A&("0B2)A$DT78,-2PRK2)P-1PR9[`X-TP
+MP,';4`9J`EO^E(H3P.#`T=PP!FL"6_^=V*#`08L2BA28%K%'6W"%!`1/#TL1
+MI+N(%@H)1PZ[$=R0P.#=@*M;VF"9%UO^A8D7CQ0'E!P$]`R/$00$1P\?0)\0
+MCQ4/#T^?$6``4XP2L7H*RPR,$,#@"\XXBQ+?D`JZ#`I/.(T1BA/<@-M@F1<O
+M%@9;_X#8H`<*3P^K$8\6JKL.NQ'`X=V`W/"K6P9J`I@66_YLB1>Q=PE$#`<'
+M1P0$1X\2B!9_<J0H(L)I@6@.,A&C(PTS$:-F)&`::71()PH`(TS^!W("`X(X
+M`@-')F`,=S$+(FSZ`G@Y"`)'=RD%:4,D:60A(E`8(E0D(E`;(E0G@E>26F``
+M#B)0`\$P`R("(E0#T0\``&Y$[=$/V##4L&2^\6/^S@#1#P``;!`(V2`DDL(B
+M(D@.1!&D(H0A(C*"V'"2%,!Q9%"FP*+2H`9R.9(5P'#2@&``BP```"X@`63@
+M?BP@`\"R"\H!R*F-%"O0?'JQ`F`!(\"V"\L!:;83*R``#KH1JZH-JA&J2BR@
+M(6``-0`K(`!]QP\.NA&KJ@VJ$:I*+*`@8``>R*X.NA&KJ@VJ$:I*+*`?8``,
+M#KH1JZH-JA&J2BR@'BH2$(T5"@]/GQ#:D-LPF!>9%EO]GXD6B!>Q=[PB=7L"
+M8_]P8``E```B@`';4+`B`GLX"P)'R"JP8MU0`GTX#0)'S"/`<&```]=0P&(/
+M<A&G)PYW$:>()X`#P%(%=0'(5HH4(J!\=2EJP*8*>@$B@`!II@\.)1&B4@TB
+M$:)$+$`A8``U?7<0#B41HE(-(A&B1"Q`(&``(@#)40XE$:)2#2(1HD0L0!]@
+M``\````.)1&B4@TB$:)$+$`>(A(1+A(2`@)/DA`B$A#=8`(/3]LPVI!;_6_1
+M#P``;!`$*2+"*")(#ID1J8@/21&DE`Y$$:0S*3``BH$.F!&IB`V($210`*BJ
+M(J`8#T@1I(BH6'@G.2F@&B*``@D)0P*9`B2``RF$`L"8"4D"*80#*3`#?I<(
+M(@H8`D0")(0#?9<9)(`#PB`"1`(DA`-@``LB@`()"4,"F0(IA`(B,`-[)Q0D
+M4`#`)`]#$:0SHU4C4`,",P(C5`/1#P``;!`$$W%NP;@B,E+`H`L@`-*@R::#
+M-,'(P+`+,``C"HB3(-H@(PH!6`A7DR/1#P``;!`&CA_`@,"1F.`'F#@("$?=
+M<-H@VS#<8,V`!I@XS(N('IX1CQV.')@06_[4T0\`;!`&*$!FP)4)B`':(-LP
+MWU`M0&C`X<R**4!G+`H8#)D!"8XX+$!S)$!QEQ&4$B86`%O_5]$/``!L$`3:
+M(-Q0W6#(1"LR@EO]N]$/`&P0!-H@W%#=8,A$*S*"6_VVT0\`;!`$*RT6B#0I
+M(D@KL";:()N3*X*"W6#<4%O]KM$/``!L$`08<6[<0(B%VS#:(`N``-$/`&P0
+M!"@@`,"<"8D!:905QR`"B`$B"L!R@2\B"M!R@2G!(-$/`"(@`<&H`@)!(BS]
+MP9X"J3G2D"GZC`F(`2H*B+(I"H@,")(XT0_`*M$/````;!`$P)#$@"DE`RDE
+M`B@E!"DD-,"`*20V*20U*2PLF"28(Y@KF2S`X<??*@J`;:@9"%D2#ID1`($$
+M`.L:J2D+W`.+E;&(#+L!FY71#VP0!LPQ8__\(BT%A"N+/BA"&MI`(C(@"X``
+MP("8.8@CF#J3@"@\))@CB"23);&(F"2((<R'B$J,/(L@8``BC#R<@!AR*8L@
+M#`(`B(`,`@"8$`P"`(@0`+`$"`@;?X\&B$K:0`N``(,^BR"3(8-,!$H""S``
+MT0\``&P0!"@A`L"1"#,,B",#`TNH,P-800Z($:@H`#$$`),:QZ\#J@.#A0HS
+M`9.%BB1@`!$H(0*Q,[&("`A+`P-&*"4"DR.#(WHQ%`-8$K2(#H@1J"B,@0`Q
+M!`";&GRPT]$/`&P0!"@P-,V(*#`U`(@RS8#`D2DT-9@YB""8.I.`(SPDDR#1
+M#VP0!"@B:`:&""@B:R8F:`6%""4F:WU'""@B<2B,`2@F<7Q'""@B92B,`2@F
+M97M'!R@B9K&(*"9FRSA_-P<H(FJQB"@F:GXW""@B;BB,`2@F;GTW""@B;RB,
+M`2@F;WPW""@B<"B,`2@F<'LW!R,B;+$S(R9LT0\``&P0!"H\%%OI;8LPBB#`
+MP%OH]-$/;!`$%7%N8``2VC!;Z-S<H"A2ARHB``1+`@N``-HP6^E@9:_DT0\`
+M`&P0!(HPM#N%/%OHZ\#`U%#6P&``?@W($:@X)X`(L-TG1`0G@`DG1`4G@`HG
+M1`8G@`LG1`>QQWS9$B9$`"9$`29$`B9$`Y0^8``B```,>1&GF0V:$8D]JID)
+MBE<J1``)"E<J1`$)BD<J1`(I1`,,W0S`D=I@#9HX+R(8#&DYBX/=H-R0!$H"
+M!5X""_``!PQ')PJ(IT2-,7W+`F/_>-$/``!L$`8I,(0B+06*/(TK*#%$:)$(
+M:9(-P)1@``(`P)@)B`(H-40H,43!D`F(`@@(3Y@0*S$BB-\O,(4N,$DL,$HM
+M"CP+@`"**]LP6__%T0\``&P0!!AQ;MPPB(3`L-H@"X``T0\`;!`2)"T%A$LE
+M(H$D%A6$/"@Q1"06%B0M`R1`#,!LLD0,1!&D5"1`$P:&`206%"0PA,E+)#!0
+M)PK]LD0,1!$$5`@D0`DD3/YW2`4G"@%^ATDJ$A7`M5OO1<BI)#(AP'0$=$`$
+M=C@D/'7`=&``)"1,]"A`#,F+#W01IT0.1!&D-"1`4+)$#$01I%0D0!,D%A1@
+M``2P=VEPU2<*`"L*4`$:`B0*@%O_TJ0T+SQ0V!`D%A<J\`%DH/XM\``L,B$,
+MV1&I62X*0"N0,"0*`'[``B20,0M$`I2!)/`#P+::@,#DP*($24`*2@$.3@$+
+M1`$$E`*4A"LB@7K'!2PQ)V```BPQ(K+4#$01I+0D0!``23)FD!PN,B$D+06*
+M2PYN0"@6&B\6&5OO("@2&B\2&6``8,#1!`E#P+`*VSD`T00`FAJKJ@#1!`"J
+M&AURI@W,$:K:*Z$`*!8:K+HJK!4N%A@O%AE;;H(N$A@H$AHO$AD.J1')XPVI
+M$0J:"`^J$1ERIRJL!`FJ*@HI%`0Z0[FJ#JH1J:HD+18D0"::@I2#R'F$A"D*
+M`0E$`B2&!"3P`W]'"82$P)$)1`(DA@0D$A>\_RB,%'3Q`F/^["02%",R(0Q"
+M$:)5+%`PP"!Y-P(B4#$D$A4J$A8C0A#?8,#DW1`,+`+`L0LP`-$/``!L$`0J
+M/!1;Z*#<H(LPBB#`T%OH(]$/``!L$`35("(BW,PA8__\9$"S)AH8IE;;,-I@
+M6_\F)RP4VG!;Z(TD/!3:0%OH!LRA8__\VZ#:<%OG^]I`6^B+U*#(H6/__(<[
+MQ,R7*R<R(RL\/"<F(R<P32HL/"<D38<X*#(AER@(6$"'-`N)$2@@AY<D)_K?
+M!X@!"8@"*"2'*#%$*"5$6VY\*#"&VR`H)(:(/]I@F"\H,$PH)$PH,)(H))(H
+M,(>4.P>(`2@TAY0XE#0D-40D-@\D-(8D-$Q;_\O;(-I06_\S(U;<T0\```!L
+M$`0J&AC;,*HJ6_[W+#(C*SP4N"I;_OG`0)0XE#3<0`,[`MH@6__#=*$.(R+Q
+ME*F3JIHP*JPD*B;QT0]L$`0D+06&2\!0A#PG"HA@`!\H8A3:0`N``"AB%=I`
+MP+`+@``H8A;:0,"P"X``IT2Q58@Q>%/:*AH8VS"J*EO^VRPR(RL\%"HL"%O^
+MW<!`E#B4/Y0TE#O;,-Q`VB!;_Z8CH(?&7R2DA@4S`2.DAR,B\92IDZJ:,"JL
+M)"HF\=$/`&P0%M<P(RT%ACLC%B`C(GC%L+$S(R9X*AP@6_\/)4P4(PH!(W0T
+M!5H"6^>D+!QP*QQT"J,"6^@@*Q(<VC!;Z`,L&ABL+"D2'=K`VT`L%B(I%B%;
+M_K;;,-I06^>0*1(AP%`EE`$E^H0EE`"%<,"D!%41"E4"!05/)901!8H4)7$"
+M*I00#%41!05/!8L4"%H1"ZH""@I/"HL4*Y02*I03)44CP;3:,%OGWQ5RJ"P2
+M(I5/A7#:P"5$385^VT`E1@1;_VB*0+1+6^>6*&(7VC"%3"@6(5OG\<&1F1(I
+M0$G`,,#[*!(AF1&TJY,4DQ.?$,/LW3#<,-I0"X``*$"'*?K?"8@!*$2'DTLI
+M"HA@`!(`*&(4VE`I%B$+@``I$B&Q,ZE5B$%X,^@C$B#;0(H[(RT66_Z.*#`F
+MP'LC'"`E"@27,)<QF#,C/!2P565?\<#TP,"*3"-B$-O`WO`M'"`+,`#;0-H@
+M6_X5T0\``&P0!",L)"0*`"4*!"@P-I0PDCY_AQT%B`(H-#88<6XL,#<H@A(:
+M<JD`S#+;,`N``&``!0#:,%O]\[%$(SP\:4C*T0\`;!`$(BT6P(`H)#@H)%W1
+M#VP0!"0B215R,05$`65`L2@M%BF`.,!;>5L*)(!==%L"8`"=P$$-11&D60Z9
+M$:29&W*JJ2BKB"R``*N=#\@1K(NIN1MRJZDIJYO`X(H^+K0`'G*L+S"2KIXO
+MY``><JW`\@Z9""XR(PTM"`SN$2Z4`"Z@9G_@""FP``^9`BFT`,&7>>@<I%D.
+MF1&DF:R(J8@9<JNH**F(*8``P+$+F0(IA``LH&BD52L\4-H@#E416_U(I%03
+M<JJD(J,B(R``L3,C)`#1#P!L$`3:,"<B21-R,=M0`W<!97"**"T6*8`X(PH+
+M>3L()X!==S-X)PH!#7,1ISD.F1&GF1QRJJDHK(@L@``/R!&LB*F(&7*L+*"2
+MJ"BIB2R4`"JB(QERK0RJ$:F)*I0`R&X9<JNIB2:0`,"!"&8")I0`R;2G/0[=
+M$19RJJ?=IMTL0&BM+=H@6_TAIS@.B!&GAZ<B%W*JIR(C(`"Q,R,D`-$/;!`$
+M)"))$W(Q`T0!ST0C+18H,#C)@!QRJAMRKHHCPM6L+%OTK20T."0P7<E%''*O
+MBB,;<JX,+`@M"B4B"@!;]*8B-%W1#P``;!`&VB#<$+0;6^=1@A'1#VP0!(@@
+MBCBQB)@@*#"'P2`"B`(H-(<H,(;`*"B,`2@TAEO_\R.@`0(S`B.D`=$/`&P0
+M!B8M!8=K)B)CC32Q9BPP3<"`)B9C+@J(ACQ@`#(`*7(4VF"8$IP1G1">$PN0
+M`"ER%09J`BL*``N0`"ER%MI@P+`+D`".$X@2C1",$:YFL8B),7F#R"8PAL")
+M=HL^#,H1)")T#*H,*S$C#JH1L40JK"2JVB0F=`M+%%O]@\#@C#[=X-LP`BH"
+M6_^3A%#,0Y-0T0\`VS#:(%O^S]$/A3O-524B9]LPL54E)F?`P0(J`EO^A].@
+M8``2#)@1J8@-B!$E^GB&/:6(J&B8/BH:@-LPJBK`(%O_OI(Y@D"2.I,@(SPD
+MDT#1#P!L$"#`4"46,"46+HL^)0JX!14(+`J(`1H")18O)C!,)S(@6_T5*@J(
+M+`HP*SQ0"AH(6_T1M%6(.RT*P-LPH=W<4-H@*!8T6_^T*!(T"(,"98_C+A!Q
+M+1!P+!!G*Q!F`BH"6_UP+0J(BT[<$-]@WF`-'0@"*@);_.`L$C#(Q=M`VB!;
+M_KLC$B[*.B,B9+$S(R9D@TLB$B_(-Y,@@TN2.F```9),(A(N(TPLDDN3*MM`
+M*GP<6_U3T0\`;!`$*C(()#(,6_^%*$!FS8$C0&AX-T`H(EFQB"@F66``-0``
+M?X<-(Z`$?S\'*2)2L9DI)E)]AP@I(E,IG`$I)E-^AP@I(E0IG`$I)E1[AP<H
+M(E6QB"@F52-`<2@B5B1`<*2()")7*"96HT0D)E?1#VP0!&``%8BYB;K(@YF*
+M8``!F3R)NMH@F)!;_FN+.V6_Y"@Q`B@U`X@SF#31#P```&P0!M4@(D`!P&AR
+M:@)@`D4**!&BB`^($:*(#H@1)EHXIH8B>CRH6**"(B``IE8`(C)D(B,B6EBB
+MB(*`P''`@`)X.`@"1V4B#09R.&4B!RA``PR'$0AW#`YW$:=G)W!:?7<-$W%N
+M&G*P(S(2"S``T0\B4O#**<2\*BP\6_U]ARF(*LASF'I@``(H5O&(*I>`)T`#
+M)R1-R'%I<PO`@&``'0!C__P```"P>0D)1\"!;I(,)WS\!P='P(-O<@'`@@Z(
+M$2B-!:A8AX/;,"<F("=`""<DA2=`"2<D22=`!Y8D!P=!)BP4!FH")R2$6^7R
+MVF!;YH33H-I@6^:`S*DB4G:Q(B)6=F`!4,PQ8__\DRC:,%O_'"A`!"-`!0B(
+M$``S$0@X`B-`!M>@"#,1"#,"BB@H(@0D0`>8$%O_$H@0+2!-`T0"#-L1(X$,
+M#;D,L3,.F1$#`TL)B0@LH!8CA0PCD14,#$,,,Q$#`T\C)2,(/A$#@Q0#XP(#
+M#D\CI0L.@Q0#S`(CH`$LI!9]/P@CD14C/`$CE14-NPP.NQ&KB".!%0=Z`@,#
+M2R.%%1-RL2,F$%O\8M.@*B1(!FH"6^926^8]`P-!`Z,,M#,C)2(C<`2**`DV
+M$2,@A\1P`P-&!C,"(R2'AB1;_N@CH`$',P',.2,DA<<_(R1)8``M+""%:,()
+M:,,.:<$38``(`",A(K@S8``$(R$BM#,C)2(CS/X#`T=O,@3;8%@$?",@AW]'
+M!\1`!#,"8``%)/J_!#,!(R2'P#$C)40J&AC`,-L@JEHC)$I;_8O;(-I06_SS
+MT0_`(-$/``!L$!0F'$##L-I@P$`G,@0D%AQ;_0##L"H<$%O\_B4R(2T*@`7=
+M`24\4'39(,#!)!QPG!&<$-MPE!.6$L#TP.K:(%O[],/`VV!@`#L``"8PD]H@
+M#&L1IKL6<HD.NQ&FNZLK)!0U)!0I)!0=)!0T)!0H)!0<)@H!6_=T*A00)A01
+M)!03P\`K'!`%6@);YU+;,-H@6_SE)#(0VS#:(`M``-$/;!`B)BT%AFLL"H`F
+M%BPK"H3--R,<(*L[!$H"##P(6^7MP+C:0%OE1F``#``F'""L;*MKVC!;Y><C
+M$BAO.`)C__PH'"`L"H`K"H2KBZR,VD`F$BE;Y>##L"H<<"<2*5O\Q<6P*AP@
+M6_S#(R+P9#+YB#F).LB%F8I@``0``"DF\8DZF)`H8`#`F'B:`F`"V@J)$:B9
+M#YD1J)D.F1$J6CBJFJHJ*A8TJ2DJ>CRJFBJ@`&2BMBI:6*J9B9!EDK]@`JD`
+M`"E@!2D6,(LP*B)&W$#`T"@6-UOE4MM`E#@J/!1;Y3:$/"\B@206+R@2-\SQ
+M8__\)6`#P*"P5,"1WJ`$GC@D<``E%CG`7"X6-05%`7I9'<>@P+0*1`$K%BW%
+MH'I!$2KZ<*I$!)4X)18M8``#`"H6+21@`=H@#$L1I+L4<HD.NQ&DNPLK""@6
+M-R\6-L!+6_<6*A1P)!1Q+`HP)`H`*QQP*CQ0)!1S6_NO+1!P+Q(V#-01+A(Y
+MI/0L$'$E0#`H$C=IX04I0#$)50(*B1&HF0^9$:B9#ID1+A(TJ2DJ6EBJF8F0
+MGC0N$C/-ZBF1!2X2+BD6,RH2,\"1*PK_?JH/*T`SP)5@``?`P2D*`RL*_RHP
+MA,JA)$`I:4(<=)@9)"T#)$`,LD0,1!$$]`@K0!,D(EHD3`$D)EH*A!&H1`]$
+M$:A$#D01*%I0I"2H1"A!``2*$0A(1PBH`BAU"RA!`,"LL8@("$LH10`*F@%D
+MH$XD"O]TN0-C__P`#+L1*!(YJ_LDL#!I@0THL#$(1`(HL1M@``0``"BQ&BP2
+M+BX2-2H2+`^($=OP*!8W*18V6^NQ*!(WP,&HJBD2-F```P``U*":%"H2,,&`
+M")D"*Q(L`*@RF1*<$)03F!$HLA<M$BTL$C(K$BXJ$B\I%C;?4,/L"X``*1(V
+M*!(Q*35$R8\G<``H"O`(=P$H"K!X>1$I$BPK8`0J$B\FDAD`NS(+8``F+04J
+M8@L#.P);^^@G+18K<"8H'"#`=-V`P,+`H-EP;9@,G("5@9N#FH2P=RB,%"@2
+M+,#P)8(0W$`J$B\D.NRD),#D#_L""U``A6N&0Y<YECJ(/I-@)CPDED.&1)-%
+ML6:61(9!S6*&6HP\BT#:4"@6-PM@`"@2-V```X,\DV`C.NRC(HL@@UR8(=I0
+M"S``T0\`$W%NBB(C,H?<0-M0"S``T0\``"4V(R5@!@=Z`B4TDB5@`P4%024T
+MA"EP`24*0`69`25P!"D6,04%0"46,R@6-UO[(R42*`H)00E5#+15*1(Q*A8R
+M)18N*!(W99SZ)0K_)18P8_SW`&P0!(@TVB#;,,R#8__\```L,$T9<K*9/PS)
+M$0R9#`Z9$:F(*8$4L9D)"4LIA11;_MC1#P!L$`0H,B%[CSXH,2,C(0((2!2-
+M(P.(#`@(2ZV,#`E&"5H2#JH1JBK`L0#!!`"\&HNE#+L"FZ6*)`VJ#`H*1GJ"
+M!K&9"0E&F231#P``;!`$BS0L,B#,L6/__"TP311RLPS:$0VJ#`ZJ$90_A,0J
+MK"2JN@S>$<Y-#>@,#H@1J+@O@A3.\"DQ(R2!%`E)%`29#"2!%@D)2W2:#"B`
+M6,"1")\Y#PA'RH$-Z`P.B!&HN,`@DCDB@A7;H)(ZDR`C/"0CAA4JS!Q;^SG1
+M#]LP6__-*")=VS"QB"@F7=H@6_Z@T0\``&P0#I0:)"T%A$O`8)0;)#$$B3L$
+M%!07<G.4&=5@W6#88"86"(0[S$)C__P`*D$C*S$""DH4"ZH,*S$$"@I+>Z(*
+M)94G*)1,P"'1#P!ET+<J(H$K"H":'"I"(8<^>K`8P*LJ1%#`JBU$=2U$:2U$
+M72I$42U$4V``)"H<$,#!FA,J3%":$IP1G!#`],#JVW#:()@?*1806_I^*1(0
+MB!\=<G,J3%#`Q&W('2N@`<FU*Z``CQRRNPR[$:O[*[`)CJ%IM`P.W3:\JL"@
+M8``$````P*&+%,Z\SJHJ+1:,J"Z@)0S;-@L*3\CL#]H1K:H*.A0,JC8*"D\G
+M<0H*>S8'NCG7H&```<!P!P=/+$$BM,P,#$]D@26F6JRJ>GH"8``2C1G!L,&A
+M?;,&VM!@``&*&7J""B65)RB43,`BT0\`VT#:,)@?*180G!Y;_W:*28M*B!\I
+M$A",'LBCFZI@``&;/(M*CQJ:L(OQP*";2II)E+`K3"2;\8U/&W*SL8A[T0)C
+M__RF529!(@Q5""L*^P4%3W:R""H*_`:J#`HJ$@H*1R9`A2I$2VAB$V]C!6AA
+M$F``&FAC#+RJ:&0/8``/NJI@``<JK$!@``$``"I$2R9`2PP,!HH8#`Q!#F81
+MIL:,3,FJE*N*K@R+5RND`"M`,2ND`2M`,BND`BM`,RND`RT*B&``((\;*T!+
+M+O(2VL"8'RD6$)P>G1T+X`",'HT=*1(0B!^MS(I.?*O9E!B$.\#194WV)94G
+M*)1,TD#1#P"+&<&@>Z,"8_[G8_[T````;!`(A#9D0?.%289*R%266F```@"6
+M-X9*E6`F0#3`4"5$-0!G,L!0=7$"8`'")D`VP%(%9@'`@85`96!0V6`%B3G)
+MF2=<_0>&.<EAL%9N8@\E7/S`@GA3!\"#8``"`,"`#H@1*(T%J"B'@XM+9+%R
+MA;F&NLA3EEI@``&63(:ZVB"58%O][(5T9%_?8`%4UG`%ACD&!D?);29<_=EP
+M!HDY"09'R6"P5FYB#B5<_,"">%,&P(-@``'`@`Z($2B-!:@HB(.&2R4M!9@5
+MA5MD81/`8(=+9'$,W!#;0-H@EA"1$5O_-H<0FA1D</@J<$QIH6@J<(;,IBHB
+M8;&J*B9A*G"'*_K?"ZH!BW$J=(<,NA&KJ@VJ$2OZ>*NKBGTL"HBKJII^)J0`
+M)J0!)J0")J0#EGN+?&``%``N4A3:L"L6!RP6!@O@`(L7C!:LNXI^>ZOFVW#:
+M(%OZPF``<0"*$<*PBJ&.H(KNENLFI``FI`$FI`(FI`,FY$LJ<(<+J@(J=(?;
+M<-H@GA9;^K8K<2<J<@PO4A$L<$L+\`".%L"PBNZ:?F``'``,NA&/[:NJ+%(3
+M#:H1FQ>>%JKZ"\``BQ>.%K&[BN%ZL]Z(%&F$`F/__"QR$`=[`MH@"\``B16(
+ME,R&B!1H@0)C_NV&2\!1R&;;0"H\'%OZ)(<VP&'(='91`F/^!M$/``!L$`8E
+M+06&6\!_A3+,5)4QE371#XA>*6(:VX"8$-I@"Y``B!!WJ1YD0&EI01(I(G6Q
+MF2DF=<"0*81G*81F8``%*?J`*81GB%F)6LB#F8I@``&9,XE:F)"(-+"(F#2(
+M,LR**2)<L9DI)ER8,9@UB%_;4-H@R(0+@`!@``E;^\S;4-H@6_LL94^!VS`"
+M*@);_UQC_W8`T0\``&P0!`(J`B,ZS%O[O@,C""0*`"8M`R5@R`!`!`4%&W]7
+M.R4M!8A<>#DJA5L9<I$K(L0H4B@)NP':4`N``-LPVB#`P%O_R2A2*"LBQ-I0
+M"X``8``)`,#`VS#:(%O_P[%$(SP@:42OVB!;_`31#VP0!(DPVS#)EVB3%;":
+MP(%NHA`IG/S`@GB3","#8``#``#`@`Z($2B-!:@H@X/`@"BT-(B[R(LJ/!Q;
+M^=#;,-H@6_\NT0\``&P0!"@P-]H@L(@("$<H-#?/A2DP-BCZ_@B8`2@T-GV7
+M(AAQ;AIRM"B"$@,[`@N``"@P-L>;"8@!*#0VVC!;^731#P``VS!;_]S1#P!L
+M$`0J,$V+-`RI$0J9#`Z9$:FY*)!:?X<4#*@1"H@,#H@1*(PD"+L(`BH"6__B
+MB#3)C=LPVB!;^W?;,-H@6_Q8C#Z+-,#PP.$M/%`"*@);^23;,-H@6_K@T0\`
+M`&P0)"<P380T#'41!U4,#E41)EPD)18U)3!,ID8E%C3`4"46,`QU$0==#`[9
+M$:E)*)!:)3Q0"`A`9(#M*S(.+`J(VA`I%CTM%CM;^2XH"HBH%P5;`BP*,`=Z
+M`EOY*B4R(2D2/2T2.WI?--LP`BH"6_PU)")>VS`D3`$"*@(D)EY;^T[;,-H@
+M6_J]*1(](Y!:?S\"8`-0VV#:(%O_K]$/V'#5T`F7`BF<6X\[W8#;,,#@W!`"
+M*@(H%CPI%CTO%CM;^V_;,-H@6_JM*1(]*!(\(Y``+Q([L#,#`T<CE`#-.`Y5
+M$:5%(U!:QUX%,P$C=%K;8-H@6_^'8``%#_,"9?^I+A!Q+1!P+!!G*Q!F`BH"
+M6_EH+A(T+0J(P/"M'=P0VT`"*@);^-C1#P```"DR((L^+`J(VA`I%C8H%CQ;
+M^/(J"HC#P-M0JAI;^.\I$&<H$CQIG@)C__PJ,B'"\`K_`67Q+-LPVB"&/H0T
+M)S!-+Q8[6_OU+Q([W5#`X=Q@VT#:(%OXP25@9G]?`F``SR8P32@R(`QD$09$
+M#(<T#D01*!8T*#"&)4PDP*FE=7BK)B0B<RLQ([%$VE`D)G,+2Q1;^1S;,-H@
+M6_K]W##;4-H@6_J,T0\``"@B;8L^L8@H)FTJL``HL`$(JA``B!$*B@(HL`((
+MB!$*B`(JL`,(J`+-@R@B<MLPL8@H)G(L"@$"*@);^AK3H"H:@`HJ"`,[`EO[
+M5@QB$08H#`Z($:AX*H(4*SPDFCG(I9NJ8``$```KAA4&(@P.(A&B<B1,4"D2
+M-",F%*1WESK;4"J<'&`!B@`,>A$E(EX'J@PK,2,.JA$E7`$JK"0*2@@E)EX+
+M2Q1;^.W;,-H@6_K.VS#:(%OZ/=$/```E(E\O$&:Q524F7R4*N*45)18OP%$H
+M%BX/6#@H%C@%]0'(4V``(@``*!$R*!8WSO/5\'^?'R0B:1IRM;%$)"9I%'%N
+M)$(2"T``W&#;,-H@6_MLT0\`*`J\J!@H%CHK,2,H$C<+2Q0(N0R*.PD)3RH6
+M.0D(2\.O>*)'*A(X9*!!"%@2#H@1J!C`X2B"'0"1!`#I&GB0*R@B8MI@KH@H
+M)F(N%CM;^+\N$CLM"HC;,-H@K1W<$%OZS]LPVB!;^@U@`!$`+0K`+!(ZK1W;
+M,-H@6_L2L54C$CEE/X0N$'$M$'`L$&<K$&;:(%OXSRX2-"T*B-P0WU"M'=M`
+MVB!;^#\L$C#(Q=M@VB!;^AHC$BYD,$LC(F0E$B^Q,R,F9`QR$0<C#`XS$:-#
+M*#(4R(F84",R%)4Z8``#`"4V%0<G#"42-2,2+@YW$:='(EQ0*!(V(W84HD24
+M.MM@*HP<6_BJT0]L$`0%!4>&2\%P8`!%`(-IS%0H8B%X<#/6,(-+R3"(.8DZ
+MR(29BF```@"93(DZF)`H,B%X<`HK,2/:0`M+%%OX@=LPVB!;^=-@``<`&'*R
+MF&_6,&5OM\`Q(T0TBD3`8<>_8``]"%,2#C,1HT.%-0"!!`!I&GE0&"Q`-PFY
+M`[',+$0W+$`V!9D!#&P"+$0VF34C00*QB+$S"`A&`P-+F$,C10*(0WJ)O"-`
+M-G\_!MM`VB!;_IW1#P``;!`&*C!-B3X,I!$*1`PFD&:%-`Y$$21,)`8&0*14
+M9&#3)C"&P(EVBVH,J!$*B`P.B!&H6":`)\>=#&P1!LP,#LP1K%8H8%HLS"0)
+MB`$H9%JL7-M0P-$"*@);_[LE4`P;<K8E%`"%:8HC)10!P%$E%`(E%`,E(GG`
+MU+%5`1P")29Y6^\TVT#:(,!`6_LBE#]@`&L``"0B>B60`+%$)"9Z))`!"%40
+M`$01!44"))`""$01!40")9`#!%0"S4(D(GO;,+%$)"9[P,$"*@);^4+3H(0^
+MP%`J&H#;,*HJ)40`)40!)40")40#6_I[VS#:(%OX"=$/``#;0-H@6_Y=EC_;
+M,-H@6_EGT0\`;!`$&'*WF"+1#P``;!`&#`(`DA`,`@"($`P"`(F`QX\$A`,)
+M1`$,`@"($`-$`@P"`)2`T0\```!L$`3:(%OC%<`@T0]L$`31#P```&P0!"@@
+M`"D*C`F(`2D*B`F(#,&HP9P(J3G8D"D@'\*@"0E`":@Y!`1'J")H0@9H0S-@
+M`'H`*#$-L8@("$\H-0W,A(DWL9F9-R@D`"@Q#<!`"(@4*"0!*"`#)"0"PD`$
+MB`)@`#``*#$-L8@("$\H-0W,A(DWL9F9-PB(%"@D`,*0"`A&"8@"*"0!)#$-
+M*"`#)"0""8@"*"0#B#<H)`0(B$<H)`4C,0XC)`8#@Q0C)`?`(=$/````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````0`!````(?\`````````````````````````````````
+M``````````````$```````/H&P""```````!```````'T!H$A`$``````0``
+M````%7P9!(L"``````$``````"KX&`26`P```````@`````7<`L`#`0`````
+M``(`````(R@/`!($``````$"`````"[@"@`8!@`````!`@````!&4`X`)`8`
+M`````0(`````7<`)`#`(``````$"`````(R@#0!("``````!`@````"[@`@`
+M8`@``````0(`````TO`,`&P(``````$$`````!ED@```!``````!!``````R
+MR($``08``````00`````3"R"``(&``````$$`````&60@P`#"``````!!```
+M``"86(0`!`@``````00`````F%B$``0(``````$$`````,L@A0`%"``````!
+M!`````#+((4`!0@``````00`````Y(2&``8(``````$$`````.2$A@`&"```
+M```!!`````#]Z(<`!P@``````00`````_>B'``<(``````$$`````,L@BP`+
+M"``````!!`````$PL(P`#`@``````00````!,+",``P(``````$$`````99`
+MC0`-"``````!!`````&60(T`#0@``````00````!R0B.``X(``````$$````
+M`<D(C@`."``````!!`````'[T(\`#P@``````00````!^]"/``\(``````"0
+M8U@`D&-H`)!C2`"08S@`D&-``````0!0S:``4!2'````````%HP````D____
+M______\``````````````````````)!\1``!````D&10``(```"0?"0``P``
+M`)![_``$````D'NH``4```"0>U@`!@```)![&``'````D'KP``@```"0>LP`
+M"0```)!ZG``*````D'G4``L```"0>4P`#````)!Y$``-````D'C```X```"0
+M>%0`#P```)!WI``0````D'=T`!$```"0=R``$@```)!VQ``3````D':``!0`
+M``"0=E``%0```)!U_``6````D'6@`!<```"0=70`&````)!TR``9````D'2<
+M`!H```"0="P`&P```)!S^``<````D'.T`!T```"0<Y``'@```)!S!``?````
+MD'*T`"```/__________-F0R"`````<````'`````````^@```.$&P`"```!
+M``````,'``````````$````'````!P````````?0```';!H$!`$!`0$!`0$#
+M!P``````````````!P````<````````5?```$R09!`L"`@("`@("`P<`````
+M``````````<````'````````*O@``!^D&`06`P,"`P,#`P,'``````````$`
+M``````````(``````!=P```5&`L`#`0"`00$!`0#!P``````````````````
+M```"```````C*```'G@/`!($`P$%!04%`P<```````````````$````!`@``
+M````+N```"=T"@`8!@0!!@8&!@,'```````````````!`````0(``````$90
+M```W%`X`)`8&`@<'!P<#!P```````````````0````$"``````!=P```120)
+M`#`("@,("`@(`P<``````````0````$````!`@``````C*```%R4#0!("`X#
+M"0D)"0,'```````````````!`````0(``````+N```!K"`@`8`@4`PH*"@H!
+M`0```````````````0````$"``````#2\```>+0,`&P(%P,+"PL+`0$`````
+M`````0``````````!```````&60``!D`@```!`(##"$,(0,'```,D`````$`
+M```"`````@0``````#+(```QG($``08$`PTB#2(#!P``&2(````!`````@``
+M``($``````!,+```27""``(&!@,.(PXC`P<``"6R``````````(````"!```
+M````99```&&H@P`#"`H##R0/)`,'```R1``````````"`````@0``````)A8
+M``"/7(0`!`@.`Q`E$28#!P``2V@````!``````````((``````"I)```F2"$
+M``0(#@,0)1$F`P<``%/4`````0`````````"!```````RR```+ODA0`%"!0#
+M$B<3*`$!``!DC````````````````@@``````.'(``#,3(4`!0@4`Q(G$R@!
+M`0``;\P```````````````($``````#DA```T/R&``8(%P,4*14J`0$``'$<
+M```````````````""```````_>@``.6PA@`&"!<#%"D5*@$!``!]R```````
+M`````````@0``````/WH``#EL8<`!P@9`Q8K%RP!`0``?<@````!````````
+M``((``````$:"```_WB'``<(&0,6*Q<L`0$``(NF`````0````(`````!0``
+M````RR```+ODBP`+"`H#&"T8+0,'``!DB``````````"``````4``````3"P
+M``$/?(P`#`@.`QDN&B\#!P``EL@````!```````````)``````%2K``!,D",
+M``P(#@,9+AHO`P<``*>*`````0````(`````!0`````!ED```5V<C0`-"!0#
+M&S`<,0,%``#)$`````````````````D``````<.0``&5W(T`#0@4`QLP'#$#
+M!0``WV8``````````@`````%``````')"``!FO".``X(%P,=,AXS`P4``.(B
+M````````````````"0`````!^]```<5ZC@`."!<#'3(>,P,%``#[0```````
+M```"``````4``````?O0``'%A(\`#P@9`Q\T(#4#!0``^T`````!`````@``
+M```)``````(T$``!]&2/``\(&0,?-"`U`P4``1="`````0````0````$!@``
+M````-+P``#.0@```"`(##"$A(0,'```:'`````$````$````!`8``````&ML
+M``!E+($``0@$`PTB(B(#!P``-#@````!````!`````0&``````">-```ELB"
+M``((!@,.(R,C`P<``$Y4``````````0````$!@``````TO```,*(@P`#"`H#
+M#R0D)`,'``!H<@`````````$````!`8``````3Y<``$:"(0`!`@.`Q`E)B8#
+M!P``G*@````!``````````0*``````%?D``!/ER$``0(#@,0)28F`P<``*XN
+M`````0`````````$!@`````!I>```6KDA0`%"!0#$B<H*`$!``#0Y```````
+M````````!`H``````=3```&.U(4`!0@4`Q(G*"@!`0``Z#H`````````````
+M``0&``````':G``!D2R&``8(%P,4*2HJ`0$``.K\```````````````$"@``
+M```"#U@``;4<A@`&"!<#%"DJ*@$!``$%&```````````````!`8``````@]8
+M``&U@(<`!P@9`Q8K+"P!`0`!!1@````!``````````0*``````))\``!W)"'
+M``<(&0,6*RPL`0$``2'8`````0````0`````!P`````!I>```6E4BP`+"`H#
+M&"TM+0,'``#0P``````````$``````<``````GC0``'\_(P`#`@.`QDN+R\#
+M!P`!.2`````!```````````+``````*_(``"9.2,``P(#@,9+B\O`P<``5P"
+M`````0````0`````!P`````#2\```GOPC0`-"!0#&S`Q,0,%``&A@```````
+M``````````L``````ZF```*W4(T`#0@4`QLP,3$#!0`!T`8`````````!```
+M```'``````.U.``"N!B.``X(%P,=,C,S`P4``=6P````````````````"P``
+M```$'K```NXRC@`."!<#'3(S,P,%``()X``````````$``````<`````!!ZP
+M``+N9(\`#P@7`Q\T-34#!0`"">``````````!``````+``````23X``#*)B/
+7``\(&0,?-#4U`P4``D.P`````=`B^Z\`
+`
+end
diff --git a/sys/dev/athn/athn.c b/sys/dev/athn/athn.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/athn.c
@@ -0,0 +1,3601 @@
+
+
+/*-
+ * Copyright (c) 2022 Farhan Khan <khanzf@gmail.com>
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Driver for Atheros 802.11a/g/n chipsets.
+ */
+#include "opt_wlan.h"
+
+#include <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+#include <sys/firmware.h>
+#include <sys/kdb.h>
+#include <sys/queue.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_regdomain.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_ratectl.h>
+
+#include <dev/athn/athnreg.h>
+#include <dev/athn/athnvar.h>
+
+int debug_knob = 1;
+
+#define DEBUG_PRINTF(format, ...) if (debug_knob == 1) { printf("DEBUG: " format, ##__VA_ARGS__);}
+/*
+void DEBUG_PRINTF(const char *format, ...) {
+ va_list args;
+ va_start(args format);
+ printf("DEBUG :");
+ vprintf(format, args);
+ va_end(args);
+}
+*/
+
+#ifdef ATHN_DEBUG
+int athn_debug = 0;
+#endif
+
+#if 1
+
+void athn_radiotap_attach(struct athn_softc *);
+void athn_get_chanlist(struct athn_softc *);
+#endif
+const char * athn_get_mac_name(struct athn_softc *);
+const char * athn_get_rf_name(struct athn_softc *);
+#if 1
+void athn_led_init(struct athn_softc *);
+void athn_set_led(struct athn_softc *, int);
+void athn_btcoex_init(struct athn_softc *);
+void athn_btcoex_enable(struct athn_softc *);
+void athn_btcoex_disable(struct athn_softc *);
+void athn_set_rxfilter(struct athn_softc *, uint32_t);
+#endif
+void athn_get_chipid(struct athn_softc *);
+int athn_reset_power_on(struct athn_softc *);
+int athn_reset(struct athn_softc *, int);
+void athn_init_pll(struct athn_softc *,
+ const struct ieee80211_channel *);
+int athn_set_power_awake(struct athn_softc *);
+void athn_set_power_sleep(struct athn_softc *);
+#if 1
+void athn_write_serdes(struct athn_softc *,
+ const struct athn_serdes *);
+void athn_config_pcie(struct athn_softc *);
+void athn_config_nonpcie(struct athn_softc *);
+void athn_set_chan(struct ieee80211com *ic);
+int athn_switch_chan(struct athn_softc *,
+ struct ieee80211_channel *, struct ieee80211_channel *);
+void athn_get_delta_slope(uint32_t, uint32_t *, uint32_t *);
+void athn_reset_key(struct athn_softc *, int);
+int athn_set_key(struct ieee80211com *, struct ieee80211_node *,
+ struct ieee80211_key *);
+void athn_delete_key(struct ieee80211com *, struct ieee80211_node *,
+ struct ieee80211_key *);
+void athn_iter_calib(void *, struct ieee80211_node *);
+int athn_cap_noisefloor(struct athn_softc *, int);
+int athn_nf_hist_mid(int *, int);
+void athn_filter_noisefloor(struct athn_softc *);
+void athn_start_noisefloor_calib(struct athn_softc *, int);
+void athn_calib_to(void *);
+int athn_init_calib(struct athn_softc *,
+ struct ieee80211_channel *, struct ieee80211_channel *);
+#endif
+uint8_t athn_chan2fbin(struct ieee80211_channel *);
+#if 1
+int athn_interpolate(int, int, int, int, int);
+void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *,
+ int *);
+void athn_init_dma(struct athn_softc *);
+void athn_rx_start(struct athn_softc *);
+void athn_inc_tx_trigger_level(struct athn_softc *);
+int athn_stop_rx_dma(struct athn_softc *);
+int athn_rx_abort(struct athn_softc *);
+void athn_tx_reclaim(struct athn_softc *, int);
+int athn_tx_pending(struct athn_softc *, int);
+void athn_stop_tx_dma(struct athn_softc *, int);
+int athn_txtime(struct athn_softc *, int, int, u_int);
+void athn_set_sta_timers(struct athn_softc *);
+void athn_set_hostap_timers(struct athn_softc *);
+void athn_set_opmode(struct athn_softc *);
+void athn_set_bss(struct athn_softc *, struct ieee80211_node *);
+void athn_enable_interrupts(struct athn_softc *);
+void athn_disable_interrupts(struct athn_softc *);
+void athn_init_qos(struct athn_softc *);
+int athn_hw_reset(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *, int);
+
+static struct ieee80211_node *athn_node_alloc(struct ieee80211vap *,
+ const uint8_t [IEEE80211_ADDR_LEN]);
+
+void athn_newassoc(struct ieee80211_node *,
+ int);
+int athn_media_change(struct ifnet *);
+void athn_next_scan(void *);
+//int athn_newstate(struct ieee80211vap *, enum ieee80211_state,
+// int);
+void athn_updateedca(struct ieee80211com *);
+int athn_clock_rate(struct athn_softc *);
+int athn_chan_sifs(struct ieee80211_channel *);
+void athn_setsifs(struct athn_softc *);
+int athn_acktimeout(struct ieee80211_channel *, int);
+void athn_setacktimeout(struct athn_softc *,
+ struct ieee80211_channel *, int);
+void athn_setctstimeout(struct athn_softc *,
+ struct ieee80211_channel *, int);
+void athn_setclockrate(struct athn_softc *);
+void athn_updateslot(struct ieee80211com *);
+void athn_start(struct ifnet *);
+void athn_watchdog(struct ifnet *);
+void athn_set_multi(struct athn_softc *);
+int athn_ioctl(struct ifnet *, u_long, caddr_t);
+static void athn_parent(struct ieee80211com *);
+int athn_init(struct athn_softc *);
+void athn_stop(void *arg);
+void athn_init_tx_queues(struct athn_softc *);
+int32_t athn_ani_get_rssi(struct athn_softc *);
+void athn_ani_ofdm_err_trigger(struct athn_softc *);
+void athn_ani_cck_err_trigger(struct athn_softc *);
+void athn_ani_lower_immunity(struct athn_softc *);
+void athn_ani_restart(struct athn_softc *);
+void athn_ani_monitor(struct athn_softc *);
+#endif
+
+/* Extern functions. */
+int ar5416_attach(struct athn_softc *);
+int ar9280_attach(struct athn_softc *);
+int ar9285_attach(struct athn_softc *);
+int ar9287_attach(struct athn_softc *);
+int ar9380_attach(struct athn_softc *);
+int ar5416_init_calib(struct athn_softc *,
+ struct ieee80211_channel *, struct ieee80211_channel *);
+int ar9285_init_calib(struct athn_softc *,
+ struct ieee80211_channel *, struct ieee80211_channel *);
+int ar9003_init_calib(struct athn_softc *);
+void ar9285_pa_calib(struct athn_softc *);
+void ar9271_pa_calib(struct athn_softc *);
+void ar9287_1_3_enable_async_fifo(struct athn_softc *);
+void ar9287_1_3_setup_async_fifo(struct athn_softc *);
+void ar9003_reset_txsring(struct athn_softc *);
+
+/* Added Definitions */
+void athn_config_ht(struct athn_softc *sc);
+void athn_getradiocaps(struct ieee80211com *ic,
+ int maxchans, int *nchans, struct ieee80211_channel chans[]);
+
+#if 0
+struct cfdriver athn_cd = {
+ NULL, "athn", DV_IFNET
+};
+#endif
+
+void
+athn_config_ht(struct athn_softc *sc)
+{
+ DEBUG_PRINTF("%s implementing\n", __func__);
+ struct ieee80211com *ic = &sc->sc_ic;
+// int i, ntxstreams, nrxstreams;
+ int ntxstreams, nrxstreams;
+
+ if ((sc->flags & ATHN_FLAG_11N) == 0)
+ return;
+
+ /* Set HT capabilities. */
+ // XXX Guess based on OpenBSD's values
+ ic->ic_htcaps = IEEE80211_HTCAP_SMPS_OFF;
+// ic->ic_htcaps = (IEEE80211_HTCAP_SMPS_DIS <<
+// IEEE80211_HTCAP_SMPS_SHIFT);
+#ifdef notyet
+ ic->ic_htcaps |= IEEE80211_HTCAP_CHWIDTH40 |
+ IEEE80211_HTCAP_SHORTGI40 |
+ IEEE80211_HTCAP_DSSSCCK40;
+#endif
+ ic->ic_htextcaps = 0;
+// ic->ic_htxcaps = 0;
+#ifdef notyet
+ DEBUG_PRINTF("not yet set\n");
+ if (AR_SREV_9271(sc) || AR_SREV_9287_10_OR_LATER(sc))
+ ic->ic_htcaps |= IEEE80211_HTCAP_SGI20;
+ if (AR_SREV_9380_10_OR_LATER(sc))
+ ic->ic_htcaps |= IEEE80211_HTCAP_LDPC;
+ if (AR_SREV_9280_10_OR_LATER(sc)) {
+ ic->ic_htcaps |= IEEE80211_HTCAP_TXSTBC;
+ ic->ic_htcaps |= 1 << IEEE80211_HTCAP_RXSTBC_SHIFT;
+ }
+#endif
+ ntxstreams = sc->ntxchains;
+ nrxstreams = sc->nrxchains;
+ if (!AR_SREV_9380_10_OR_LATER(sc)) {
+ ntxstreams = MIN(ntxstreams, 2);
+ nrxstreams = MIN(nrxstreams, 2);
+ }
+ /* Set supported HT rates. */
+// if (ic->ic_flags_ven & IEEE80211_F_NOMIMO)
+// ntxstreams = nrxstreams = 1;
+ // Based on the size, it seems that ic->ic_sup_mcs is ic_modecaps
+ //memset(ic->ic_sup_mcs, 0, sizeof(ic->ic_sup_mcs));
+ memset(ic->ic_modecaps, 0, sizeof(ic->ic_modecaps));
+// for (i = 0; i < nrxstreams; i++)
+// ic->ic_modecaps[i] = 0xff;
+// ic->ic_tx_mcs_set = IEEE80211_TX_MCS_SET_DEFINED;
+// if (ntxstreams != nrxstreams) {
+// ic->ic_tx_mcs_set |= IEEE80211_TX_RX_MCS_NOT_EQUAL;
+// ic->ic_tx_mcs_set |= (ntxstreams - 1) << 2;
+// }
+}
+
+int
+athn_attach(struct athn_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+// struct ifnet *ifp = &ic->ic_if;
+ int error;
+
+ /* Read hardware revision. */
+debug_knob = 0;
+ athn_get_chipid(sc);
+
+ if ((error = athn_reset_power_on(sc)) != 0) {
+ device_printf(sc->sc_dev, "could not reset chip\n");
+ return (error);
+ }
+
+ if ((error = athn_set_power_awake(sc)) != 0) {
+ device_printf(sc->sc_dev, "could not wakeup chip\n");
+ return (error);
+ }
+DEBUG_PRINTF("Exit athn_power_awake\n");
+
+DEBUG_PRINTF("mac_ver is 0%02x\n", sc->mac_rev);
+DEBUG_PRINTF("mac_ver is %d\n", sc->mac_rev);
+
+ if (AR_SREV_5416(sc) || AR_SREV_9160(sc))
+ error = ar5416_attach(sc);
+ else if (AR_SREV_9280(sc))
+ error = ar9280_attach(sc);
+ else if (AR_SREV_9285(sc))
+ error = ar9285_attach(sc);
+//#if NATHN_USB > 0
+ else if (AR_SREV_9271(sc))
+ error = ar9285_attach(sc);
+//#endif
+ else if (AR_SREV_9287(sc))
+ error = ar9287_attach(sc);
+ else if (AR_SREV_9380(sc) || AR_SREV_9485(sc))
+ error = ar9380_attach(sc);
+ else
+ error = ENOTSUP;
+
+ if (error != 0) {
+ device_printf(sc->sc_dev, "could not attach chip\n");
+ return (error);
+ }
+
+debug_knob = 1;
+ /* We can put the chip in sleep state now. */
+ athn_set_power_sleep(sc);
+
+ if (!(sc->flags & ATHN_FLAG_USB)) {
+#if 0
+ error = sc->ops.dma_alloc(sc);
+ if (error != 0) {
+ printf("%s: could not allocate DMA resources\n",
+ ic->ic_name);
+ return (error);
+ }
+ /* Steal one Tx buffer for beacons. */
+ sc->bcnbuf = SIMPLEQ_FIRST(&sc->txbufs);
+ SIMPLEQ_REMOVE_HEAD(&sc->txbufs, bf_list);
+#endif
+ }
+
+ if (sc->flags & ATHN_FLAG_RFSILENT) {
+// DPRINTF(("found RF switch connected to GPIO pin %d\n",
+ }
+ //DPRINTF(("%d key cache entries\n", sc->kc_entries));
+// FreeBSD does not care about this
+#if 0
+ /*
+ * In HostAP mode, the number of STAs that we can handle is
+ * limited by the number of entries in the HW key cache.
+ * TKIP keys would consume 2 entries in this cache but we
+ * only use the hardware crypto engine for CCMP.
+ */
+ ic->ic_max_nnodes = sc->kc_entries - IEEE80211_WEP_NKID;
+ if (ic->ic_max_nnodes > IEEE80211_CACHE_SIZE)
+ ic->ic_max_nnodes = IEEE80211_CACHE_SIZE;
+#endif
+
+// DPRINTF(("using %s loop power control\n",
+// (sc->flags & ATHN_FLAG_OLPC) ? "open" : "closed"));
+
+// DPRINTF(("txchainmask=0x%x rxchainmask=0x%x\n",
+// sc->txchainmask, sc->rxchainmask));
+ /* Count the number of bits set (in lowest 3 bits). */
+ sc->ntxchains =
+ ((sc->txchainmask >> 2) & 1) +
+ ((sc->txchainmask >> 1) & 1) +
+ ((sc->txchainmask >> 0) & 1);
+ sc->nrxchains =
+ ((sc->rxchainmask >> 2) & 1) +
+ ((sc->rxchainmask >> 1) & 1) +
+ ((sc->rxchainmask >> 0) & 1);
+
+ if (AR_SINGLE_CHIP(sc)) {
+ device_printf(sc->sc_dev, "%s rev %d (%dT%dR), ROM rev %d, address %s\n",
+ athn_get_mac_name(sc), sc->mac_rev,
+ sc->ntxchains, sc->nrxchains, sc->eep_rev,
+ ether_sprintf(ic->ic_macaddr));
+ } else {
+ device_printf(sc->sc_dev, "MAC %s rev %d, RF %s (%dT%dR), ROM rev %d, "
+ "address %s\n",
+ athn_get_mac_name(sc), sc->mac_rev,
+ athn_get_rf_name(sc), sc->ntxchains, sc->nrxchains,
+ sc->eep_rev, ether_sprintf(ic->ic_macaddr));
+ }
+
+// timeout_set(&sc->scan_to, athn_next_scan, sc);
+// timeout_set(&sc->calib_to, athn_calib_to, sc);
+ // OpenBSD's timeout_set initializes function names and arguments
+ // FreeBSD's callout_init equivalent just creates the structure
+ callout_init(&sc->scan_to, 0);
+ callout_init(&sc->calib_to, 0);
+
+#if 0 // Not used om FreeBSD
+ sc->amrr.amrr_min_success_threshold = 1;
+ sc->amrr.amrr_max_success_threshold = 15;
+
+#endif
+
+ ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
+ ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
+ // XXX This will be moved to the VAP laye
+// ic->ic_state = IEEE80211_S_INIT;
+
+ /* Set device capabilities. */
+ ic->ic_caps =
+ IEEE80211_C_STA |
+ IEEE80211_C_WPA | // OpenBSD's IEEE80211_C_RSN
+ IEEE80211_C_HOSTAP | // OpenBSD's IEEE80211_C_HOSTAP
+ IEEE80211_C_PMGT | // OpenBSD's IEEE80211_C_APPMGT
+ IEEE80211_C_MONITOR | // OpenBSD's IEEE80211_C_MONITOR
+ IEEE80211_C_SHSLOT | // OpenBSD's IEEE80211_C_SHSLOT
+ IEEE80211_C_SHPREAMBLE | // OpenBSD's IEEE80211_C_SHPREAMBLE
+ IEEE80211_C_TXPMGT; // OpenBSD's IEEE80211_C_APPMGT
+//
+// IEEE80211_C_WEP | /* WEP. */
+// IEEE80211_C_RSN | /* WPA/RSN. */
+//#ifndef IEEE80211_STA_ONLY
+// IEEE80211_C_HOSTAP | /* Host AP mode supported. */
+// IEEE80211_C_APPMGT | /* Host AP power saving supported. */
+//#endif
+// IEEE80211_C_MONITOR | /* Monitor mode supported. */
+// IEEE80211_C_SHSLOT | /* Short slot time supported. */
+// IEEE80211_C_SHPREAMBLE | /* Short preamble supported. */
+// IEEE80211_C_PMGT; /* Power saving supported. */
+
+ athn_config_ht(sc);
+
+ /* Set supported rates. */
+#if 0
+ if (sc->flags & ATHN_FLAG_11G) {
+ ic->ic_sup_rates[IEEE80211_MODE_11B] =
+ ieee80211_rateset_11b;
+ //ieee80211_std_rateset_11b;
+ ic->ic_sup_rates[IEEE80211_MODE_11G] =
+ ieee80211_rateset_11g;
+ //ieee80211_std_rateset_11g;
+ }
+ if (sc->flags & ATHN_FLAG_11A) {
+ ic->ic_sup_rates[IEEE80211_MODE_11A] =
+ ieee80211_rateset_11a;
+ //ieee80211_std_rateset_11a;
+ }
+#endif // Not sure where the values above are set
+
+ /* Get the list of authorized/supported channels. */
+
+#if 0 // New way of setting channels
+ athn_get_chanlist(sc);
+
+ for(int i = 0;i<ic->ic_nchans;i++) {
+ if (ic->ic_channels[i].ic_flags == 0) {
+ DEBUG_PRINTF("Flags is 0\n");
+ ic->ic_channels[i].ic_flags = 0x0;
+ }
+ }
+#endif
+
+ athn_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, ic->ic_channels);
+
+ /* IBSS channel undefined for now. */
+ ic->ic_bsschan = &ic->ic_channels[0];
+
+ // THIS IS HANDLED AT THE VAP LEVEL!
+ /*
+ ifp->if_softc = sc;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_ioctl = athn_ioctl;
+ ifp->if_start = athn_start;
+ ifp->if_watchdog = athn_watchdog;
+ */
+// memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
+
+// if_attach(ifp);
+ ieee80211_ifattach(ic);
+
+ ic->ic_bsschan = &ic->ic_channels[0];
+ /*
+ ic->ic_raw_xmit = ??
+ ic->sc_scan_start = ??
+ ic->sc_scan_curchan = ic->ic_scan_curchan;
+ ic->ic_scan_curchan = ??
+ ic->ic_scan_end = ??
+ ic->ic_update_chw = ??
+ */
+ ic->ic_getradiocaps = athn_getradiocaps;
+ ic->ic_set_channel = athn_set_chan;
+ /*
+ ic->ic_transmit = ??
+ */
+ ic->ic_parent = athn_parent;
+ /*
+ */
+// ic->ic_vap_create = athn_vap_create;
+// ic->ic_vap_delete = athn_vap_delete; // Not finished
+ /*
+ ic->ic_wme.wme_update = ??
+ */
+// ic->ic_updateslot = athn_updateslot;
+ /*
+ ic->ic_update_promisc = ??
+ ic->ic_update_mcast = ??
+ */
+// ic->ic_node_alloc = athn_node_alloc;
+// ic->ic_newassoc = athn_newassoc;
+ /*
+ sc->sc_node_free = ic->ic_node_free;
+ ic->ic_node_free = ??
+ */
+
+ return 0;
+#if 0
+ ic->ic_node_alloc = athn_node_alloc;
+ ic->ic_newassoc = athn_newassoc;
+ ic->ic_updateslot = athn_updateslot;
+ ic->ic_updateedca = athn_updateedca;
+ ic->ic_set_key = athn_set_key;
+ ic->ic_delete_key = athn_delete_key;
+
+ /* Override 802.11 state transition machine. */
+ sc->sc_newstate = ic->ic_newstate;
+ ic->ic_newstate = athn_newstate;
+ ieee80211_media_init(ifp, athn_media_change, ieee80211_media_status);
+
+#if NBPFILTER > 0
+ athn_radiotap_attach(sc);
+#endif
+
+ return (0);
+#endif
+}
+
+void
+athn_detach(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+ int qid;
+
+ timeout_del(&sc->scan_to);
+ timeout_del(&sc->calib_to);
+
+ if (!(sc->flags & ATHN_FLAG_USB)) {
+ for (qid = 0; qid < ATHN_QID_COUNT; qid++)
+ athn_tx_reclaim(sc, qid);
+
+ /* Free Tx/Rx DMA resources. */
+ sc->ops.dma_free(sc);
+ }
+ /* Free ROM copy. */
+ if (sc->eep != NULL)
+ free(sc->eep, M_DEVBUF, 0);
+
+ ieee80211_ifdetach(ifp);
+ if_detach(ifp);
+#endif
+}
+
+//#if NBPFILTER > 0
+/*
+ * Attach the interface to 802.11 radiotap.
+ */
+void
+athn_radiotap_attach(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ bpfattach(&sc->sc_drvbpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO,
+ sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);
+
+ sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
+ sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
+ sc->sc_rxtap.wr_ihdr.it_present = htole32(ATHN_RX_RADIOTAP_PRESENT);
+
+ sc->sc_txtap_len = sizeof(sc->sc_txtapu);
+ sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
+ sc->sc_txtap.wt_ihdr.it_present = htole32(ATHN_TX_RADIOTAP_PRESENT);
+#endif
+}
+//#endif
+
+void
+athn_get_chanlist(struct athn_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint8_t chan;
+ int i;
+
+ if (sc->flags & ATHN_FLAG_11G) {
+ ic->ic_nchans = 14;
+ for (i = 0; i < 14; i++) {
+ chan = i;
+ ic->ic_channels[chan].ic_freq =
+ ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
+ ic->ic_channels[chan].ic_flags =
+ IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
+ IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
+ if (sc->flags & ATHN_FLAG_11N)
+ ic->ic_channels[chan].ic_flags |=
+ IEEE80211_CHAN_HT;
+ DEBUG_PRINTF("2g Chan: %d 0x%02x\n", chan, ic->ic_channels[chan].ic_flags);
+ }
+ }
+ if (sc->flags & ATHN_FLAG_11A) {
+ DEBUG_PRINTF("Adding 5ghz channels...\n");
+ ic->ic_nchans += nitems(athn_5ghz_chans);
+ for (i = 0; i < nitems(athn_5ghz_chans); i++) {
+ chan = athn_5ghz_chans[i];
+ ic->ic_channels[chan].ic_freq =
+ ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
+ ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A;
+ if (sc->flags & ATHN_FLAG_11N)
+ ic->ic_channels[chan].ic_flags |=
+ IEEE80211_CHAN_HT;
+ DEBUG_PRINTF("5g Chan: %d 0x%02x\n", chan, ic->ic_channels[chan].ic_flags);
+ }
+ }
+}
+
+void
+athn_rx_start(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint32_t rfilt;
+
+ /* Setup Rx DMA descriptors. */
+ sc->ops.rx_enable(sc);
+
+ /* Set Rx filter. */
+ rfilt = AR_RX_FILTER_UCAST | AR_RX_FILTER_BCAST | AR_RX_FILTER_MCAST;
+ /* Want Compressed Block Ack Requests. */
+ rfilt |= AR_RX_FILTER_COMPR_BAR;
+ rfilt |= AR_RX_FILTER_BEACON;
+ if (ic->ic_opmode != IEEE80211_M_STA) {
+ rfilt |= AR_RX_FILTER_PROBEREQ;
+ if (ic->ic_opmode == IEEE80211_M_MONITOR)
+ rfilt |= AR_RX_FILTER_PROM;
+#ifndef IEEE80211_STA_ONLY
+ if (AR_SREV_9280_10_OR_LATER(sc) &&
+ ic->ic_opmode == IEEE80211_M_HOSTAP)
+ rfilt |= AR_RX_FILTER_PSPOLL;
+#endif
+ }
+ athn_set_rxfilter(sc, rfilt);
+
+ /* Set BSSID mask. */
+ AR_WRITE(sc, AR_BSSMSKL, 0xffffffff);
+ AR_WRITE(sc, AR_BSSMSKU, 0xffff);
+
+ athn_set_opmode(sc);
+
+ /* Set multicast filter. */
+ AR_WRITE(sc, AR_MCAST_FIL0, 0xffffffff);
+ AR_WRITE(sc, AR_MCAST_FIL1, 0xffffffff);
+
+ AR_WRITE(sc, AR_FILT_OFDM, 0);
+ AR_WRITE(sc, AR_FILT_CCK, 0);
+ AR_WRITE(sc, AR_MIBC, 0);
+ AR_WRITE(sc, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+ AR_WRITE(sc, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+
+ /* XXX ANI. */
+ AR_WRITE(sc, AR_PHY_ERR_1, 0);
+ AR_WRITE(sc, AR_PHY_ERR_2, 0);
+
+ /* Disable HW crypto for now. */
+ AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_ENCRYPT_DIS | AR_DIAG_DECRYPT_DIS);
+
+ /* Start PCU Rx. */
+ AR_CLRBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+athn_set_rxfilter(struct athn_softc *sc, uint32_t rfilt)
+{
+ AR_WRITE(sc, AR_RX_FILTER, rfilt);
+
+#ifdef notyet
+ reg = AR_READ(sc, AR_PHY_ERR);
+ reg &= (AR_PHY_ERR_RADAR | AR_PHY_ERR_OFDM_TIMING |
+ AR_PHY_ERR_CCK_TIMING);
+ AR_WRITE(sc, AR_PHY_ERR, reg);
+ if (reg != 0)
+ AR_SETBITS(sc, AR_RXCFG, AR_RXCFG_ZLFDMA);
+ else
+ AR_CLRBITS(sc, AR_RXCFG, AR_RXCFG_ZLFDMA);
+#else
+ AR_WRITE(sc, AR_PHY_ERR, 0);
+ AR_CLRBITS(sc, AR_RXCFG, AR_RXCFG_ZLFDMA);
+#endif
+ AR_WRITE_BARRIER(sc);
+}
+
+int
+athn_intr(void *xsc)
+{
+ printf("%s unimplemented\n", __func__);
+ return 1;
+#if 0
+ struct athn_softc *sc = xsc;
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+ if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
+ (IFF_UP | IFF_RUNNING))
+ return (0);
+
+ return (sc->ops.intr(sc));
+#endif
+}
+
+void
+athn_get_chipid(struct athn_softc *sc)
+{
+ uint32_t reg;
+ DEBUG_PRINTF("Starting athn_get_chipid\n");
+
+ reg = AR_READ(sc, AR_SREV);
+ DEBUG_PRINTF("Reg is %x %d\n", reg, reg);
+ if (MS(reg, AR_SREV_ID) == 0xff) {
+ sc->mac_ver = MS(reg, AR_SREV_VERSION2);
+ sc->mac_rev = MS(reg, AR_SREV_REVISION2);
+ if (!(reg & AR_SREV_TYPE2_HOST_MODE))
+ sc->flags |= ATHN_FLAG_PCIE;
+ } else {
+ sc->mac_ver = MS(reg, AR_SREV_VERSION);
+ sc->mac_rev = MS(reg, AR_SREV_REVISION);
+ if (sc->mac_ver == AR_SREV_VERSION_5416_PCIE)
+ sc->flags |= ATHN_FLAG_PCIE;
+ }
+
+ DEBUG_PRINTF("Exiting athn_get_chipid\n");
+}
+
+const char *
+athn_get_mac_name(struct athn_softc *sc)
+{
+ switch (sc->mac_ver) {
+ case AR_SREV_VERSION_5416_PCI:
+ return ("AR5416");
+ case AR_SREV_VERSION_5416_PCIE:
+ return ("AR5418");
+ case AR_SREV_VERSION_9160:
+ return ("AR9160");
+ case AR_SREV_VERSION_9280:
+ return ("AR9280");
+ case AR_SREV_VERSION_9285:
+ return ("AR9285");
+ case AR_SREV_VERSION_9271:
+ return ("AR9271");
+ case AR_SREV_VERSION_9287:
+ return ("AR9287");
+ case AR_SREV_VERSION_9380:
+ return ("AR9380");
+ case AR_SREV_VERSION_9485:
+ return ("AR9485");
+ }
+ return ("unknown");
+}
+
+/*
+ * Return RF chip name (not for single-chip solutions).
+ */
+const char *
+athn_get_rf_name(struct athn_softc *sc)
+{
+ KASSERT(!AR_SINGLE_CHIP(sc), ("AR_SINGLE_CHIP"));
+
+ switch (sc->rf_rev) {
+ case AR_RAD5133_SREV_MAJOR: /* Dual-band 3T3R. */
+ return ("AR5133");
+ case AR_RAD2133_SREV_MAJOR: /* Single-band 3T3R. */
+ return ("AR2133");
+ case AR_RAD5122_SREV_MAJOR: /* Dual-band 2T2R. */
+ return ("AR5122");
+ case AR_RAD2122_SREV_MAJOR: /* Single-band 2T2R. */
+ return ("AR2122");
+ }
+ return ("unknown");
+}
+
+int
+athn_reset_power_on(struct athn_softc *sc)
+{
+ DEBUG_PRINTF("start of athn_reset_power_on\n");
+ int ntries;
+
+ /* Set force wake. */
+ AR_WRITE(sc, AR_RTC_FORCE_WAKE,
+ AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
+
+ if (!AR_SREV_9380_10_OR_LATER(sc)) {
+ /* Make sure no DMA is active by doing an AHB reset. */
+ AR_WRITE(sc, AR_RC, AR_RC_AHB);
+ }
+ /* RTC reset and clear. */
+ AR_WRITE(sc, AR_RTC_RESET, 0);
+ AR_WRITE_BARRIER(sc);
+ DELAY(2);
+ if (!AR_SREV_9380_10_OR_LATER(sc))
+ AR_WRITE(sc, AR_RC, 0);
+ AR_WRITE(sc, AR_RTC_RESET, 1);
+
+ /* Poll until RTC is ON. */
+ for (ntries = 0; ntries < 1000; ntries++) {
+ if ((AR_READ(sc, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
+ AR_RTC_STATUS_ON)
+ break;
+ DELAY(10);
+ }
+ if (ntries == 1000) {
+ DPRINTF(("RTC not waking up\n"));
+ return (ETIMEDOUT);
+ }
+ DEBUG_PRINTF("ntries was %d\n", ntries);
+ DEBUG_PRINTF("end of athn_reset_power_on\n");
+ return (athn_reset(sc, 0));
+}
+
+int
+athn_reset(struct athn_softc *sc, int cold)
+{
+ int ntries;
+
+ /* Set force wake. */
+ AR_WRITE(sc, AR_RTC_FORCE_WAKE,
+ AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
+
+ if (AR_READ(sc, AR_INTR_SYNC_CAUSE) &
+ (AR_INTR_SYNC_LOCAL_TIMEOUT | AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
+ AR_WRITE(sc, AR_INTR_SYNC_ENABLE, 0);
+ AR_WRITE(sc, AR_RC, AR_RC_HOSTIF |
+ (!AR_SREV_9380_10_OR_LATER(sc) ? AR_RC_AHB : 0));
+ } else if (!AR_SREV_9380_10_OR_LATER(sc))
+ AR_WRITE(sc, AR_RC, AR_RC_AHB);
+
+ AR_WRITE(sc, AR_RTC_RC, AR_RTC_RC_MAC_WARM |
+ (cold ? AR_RTC_RC_MAC_COLD : 0));
+ AR_WRITE_BARRIER(sc);
+ DELAY(50);
+ AR_WRITE(sc, AR_RTC_RC, 0);
+ for (ntries = 0; ntries < 1000; ntries++) {
+ if (!(AR_READ(sc, AR_RTC_RC) &
+ (AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD)))
+ break;
+ DELAY(10);
+ }
+ if (ntries == 1000) {
+ DPRINTF(("RTC stuck in MAC reset\n"));
+ return (ETIMEDOUT);
+ }
+ AR_WRITE(sc, AR_RC, 0);
+ AR_WRITE_BARRIER(sc);
+ return (0);
+}
+
+int
+athn_set_power_awake(struct athn_softc *sc)
+{
+DEBUG_PRINTF("start of athn_set_power_awake\n");
+ int ntries, error;
+
+ DEBUG_PRINTF("tracing: %s:%d\n", __func__, __LINE__);
+ /* Do a Power-On-Reset if shutdown. */
+ if ((AR_READ(sc, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
+ AR_RTC_STATUS_SHUTDOWN) {
+ DEBUG_PRINTF("tracing: %s:%d\n", __func__, __LINE__);
+ if ((error = athn_reset_power_on(sc)) != 0) {
+ DEBUG_PRINTF("tracing: %s:%d\n", __func__, __LINE__);
+ return (error);
+ }
+ if (!AR_SREV_9380_10_OR_LATER(sc)) {
+ DEBUG_PRINTF("tracing: %s:%d\n", __func__, __LINE__);
+ athn_init_pll(sc, NULL);
+ }
+ }
+ DEBUG_PRINTF("tracing: %s:%d\n", __func__, __LINE__);
+ AR_SETBITS(sc, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN);
+ DEBUG_PRINTF("tracing: %s:%d\n", __func__, __LINE__);
+ AR_WRITE_BARRIER(sc);
+ DEBUG_PRINTF("tracing: %s:%d\n", __func__, __LINE__);
+ DELAY(50); /* Give chip the chance to awake. */
+
+ /* Poll until RTC is ON. */
+ for (ntries = 0; ntries < 4000; ntries++) {
+ if ((AR_READ(sc, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
+ AR_RTC_STATUS_ON) {
+ printf("tracing: %s:%d\n", __func__, __LINE__);
+ break;
+ }
+ DELAY(50);
+ DEBUG_PRINTF("tracing: %s:%d\n", __func__, __LINE__);
+ AR_SETBITS(sc, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN);
+ DEBUG_PRINTF("tracing: %s:%d\n", __func__, __LINE__);
+DEBUG_PRINTF("Times: %d\n", ntries);
+ }
+ if (ntries == 4000) {
+ DPRINTF(("RTC not waking up\n"));
+ return (ETIMEDOUT);
+ }
+
+ AR_CLRBITS(sc, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+ AR_WRITE_BARRIER(sc);
+DEBUG_PRINTF("end of athn_set_power_awake\n");
+ return (0);
+}
+
+void
+athn_set_power_sleep(struct athn_softc *sc)
+{
+DEBUG_PRINTF("Enter athn_set_power_sleep!\n");
+ AR_SETBITS(sc, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+ /* Allow the MAC to go to sleep. */
+ AR_CLRBITS(sc, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN);
+ if (!AR_SREV_9380_10_OR_LATER(sc))
+ AR_WRITE(sc, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
+ /*
+ * NB: Clearing RTC_RESET_EN when setting the chip to sleep mode
+ * results in high power consumption on AR5416 chipsets.
+ */
+ if (!AR_SREV_5416(sc) && !AR_SREV_9271(sc))
+ AR_CLRBITS(sc, AR_RTC_RESET, AR_RTC_RESET_EN);
+ AR_WRITE_BARRIER(sc);
+DEBUG_PRINTF("Exit athn_set_power_sleep!\n");
+}
+
+void
+athn_init_pll(struct athn_softc *sc, const struct ieee80211_channel *c)
+{
+ uint32_t pll;
+
+ if (AR_SREV_9380_10_OR_LATER(sc)) {
+ if (AR_SREV_9485(sc))
+ AR_WRITE(sc, AR_RTC_PLL_CONTROL2, 0x886666);
+ pll = SM(AR_RTC_9160_PLL_REFDIV, 0x5);
+ pll |= SM(AR_RTC_9160_PLL_DIV, 0x2c);
+ } else if (AR_SREV_9280_10_OR_LATER(sc)) {
+ pll = SM(AR_RTC_9160_PLL_REFDIV, 0x05);
+ if (c != NULL && IEEE80211_IS_CHAN_5GHZ(c)) {
+ if (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)
+ pll = 0x142c;
+ else if (AR_SREV_9280_20(sc))
+ pll = 0x2850;
+ else
+ pll |= SM(AR_RTC_9160_PLL_DIV, 0x28);
+ } else
+ pll |= SM(AR_RTC_9160_PLL_DIV, 0x2c);
+ } else if (AR_SREV_9160_10_OR_LATER(sc)) {
+ pll = SM(AR_RTC_9160_PLL_REFDIV, 0x05);
+ if (c != NULL && IEEE80211_IS_CHAN_5GHZ(c))
+ pll |= SM(AR_RTC_9160_PLL_DIV, 0x50);
+ else
+ pll |= SM(AR_RTC_9160_PLL_DIV, 0x58);
+ } else {
+ pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
+ if (c != NULL && IEEE80211_IS_CHAN_5GHZ(c)) {
+ pll |= SM(AR_RTC_PLL_DIV, 0x0a);
+ }
+ else
+ pll |= SM(AR_RTC_PLL_DIV, 0x0b);
+ }
+ DPRINTFN(5, ("AR_RTC_PLL_CONTROL=0x%08x\n", pll));
+ AR_WRITE(sc, AR_RTC_PLL_CONTROL, pll);
+ if (AR_SREV_9271(sc)) {
+ /* Switch core clock to 117MHz. */
+ AR_WRITE_BARRIER(sc);
+ DELAY(500);
+ AR_WRITE(sc, AR9271_CLOCK_CONTROL, 0x304);
+ }
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+ AR_WRITE(sc, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+athn_write_serdes(struct athn_softc *sc, const struct athn_serdes *serdes)
+{
+ int i;
+
+ /* Write sequence to Serializer/Deserializer. */
+ for (i = 0; i < serdes->nvals; i++) {
+ AR_WRITE(sc, serdes->regs[i], serdes->vals[i]);
+ }
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+athn_config_pcie(struct athn_softc *sc)
+{
+ debug_knob = 1;
+ /*
+ * XXX Note to self:
+ * Why is this happening? Using USB, not PCI. Check on the OpenBSD side
+ */
+ /* Disable PLL when in L0s as well as receiver clock when in L1. */
+ athn_write_serdes(sc, sc->serdes);
+
+ DELAY(1000);
+ /* Allow forcing of PCIe core into L1 state. */
+ AR_SETBITS(sc, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+#ifndef ATHN_PCIE_WAEN
+ AR_WRITE(sc, AR_WA, sc->workaround);
+#else
+ AR_WRITE(sc, AR_WA, ATHN_PCIE_WAEN);
+#endif
+ AR_WRITE_BARRIER(sc);
+}
+
+/*
+ * Serializer/Deserializer programming for non-PCIe devices.
+ */
+static const uint32_t ar_nonpcie_serdes_regs[] = {
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES2,
+};
+
+static const uint32_t ar_nonpcie_serdes_vals[] = {
+ 0x9248fc00,
+ 0x24924924,
+ 0x28000029,
+ 0x57160824,
+ 0x25980579,
+ 0x00000000,
+ 0x1aaabe40,
+ 0xbe105554,
+ 0x000e1007,
+ 0x00000000
+};
+
+static const struct athn_serdes ar_nonpcie_serdes = {
+ nitems(ar_nonpcie_serdes_vals),
+ ar_nonpcie_serdes_regs,
+ ar_nonpcie_serdes_vals
+};
+
+void
+athn_config_nonpcie(struct athn_softc *sc)
+{
+ printf("Going into athn_config_nonpcie\n");
+ athn_write_serdes(sc, &ar_nonpcie_serdes);
+}
+
+void
+athn_set_chan(struct ieee80211com *ic)
+{
+ struct athn_softc *sc = ic->ic_softc;
+ struct athn_ops *ops = &sc->ops;
+ int error, qid;
+ struct ieee80211_channel *extc = NULL;
+
+ /* Check that Tx is stopped, otherwise RF Bus grant will not work. */
+ for (qid = 0; qid < ATHN_QID_COUNT; qid++)
+ if (athn_tx_pending(sc, qid)) {
+ return;
+ //return (EBUSY);
+ }
+
+ /* Request RF Bus grant. */
+ if ((error = ops->rf_bus_request(sc)) != 0) {
+ return;
+// return (error);
+ }
+
+ ops->set_phy(sc, ic->ic_curchan, extc);
+
+ /* Change the synthesizer. */
+ if ((error = ops->set_synth(sc, ic->ic_curchan, extc)) != 0) {
+ return;
+// return (error);
+ }
+
+// sc->curchan = ic->ic_curchan;
+ sc->curchanext = extc;
+
+ /* Set transmit power values for new channel. */
+ ops->set_txpower(sc, ic->ic_curchan, extc);
+
+ /* Release the RF Bus grant. */
+ ops->rf_bus_release(sc);
+
+ /* Write delta slope coeffs for modes where OFDM may be used. */
+ if (sc->sc_ic.ic_curmode != IEEE80211_MODE_11B)
+ ops->set_delta_slope(sc, ic->ic_curchan, extc);
+
+ ops->spur_mitigate(sc, ic->ic_curchan, extc);
+
+ printf("End of set channel\n");
+}
+
+int
+athn_switch_chan(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ int error, qid;
+
+ /* Disable interrupts. */
+ athn_disable_interrupts(sc);
+
+ /* Stop all Tx queues. */
+ for (qid = 0; qid < ATHN_QID_COUNT; qid++)
+ athn_stop_tx_dma(sc, qid);
+ for (qid = 0; qid < ATHN_QID_COUNT; qid++)
+ athn_tx_reclaim(sc, qid);
+
+ /* Stop Rx. */
+ AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
+ AR_WRITE(sc, AR_MIBC, AR_MIBC_FMC);
+ AR_WRITE(sc, AR_MIBC, AR_MIBC_CMC);
+ AR_WRITE(sc, AR_FILT_OFDM, 0);
+ AR_WRITE(sc, AR_FILT_CCK, 0);
+ athn_set_rxfilter(sc, 0);
+ error = athn_stop_rx_dma(sc);
+ if (error != 0)
+ goto reset;
+
+#ifdef notyet
+ /* AR9280 needs a full reset. */
+ if (AR_SREV_9280(sc))
+#endif
+ goto reset;
+
+ /* If band or bandwidth changes, we need to do a full reset. */
+ if (c->ic_flags != ic->ic_curchan->ic_flags ||
+ ((extc != NULL) ^ (sc->curchanext != NULL))) {
+ DPRINTFN(2, ("channel band switch\n"));
+ goto reset;
+ }
+ error = athn_set_power_awake(sc);
+ if (error != 0)
+ goto reset;
+
+ athn_set_chan(ic);
+ DEBUG_PRINTF("Need to figure out if an error here occurs...\n");
+ athn_rx_start(sc);
+
+ /* Re-enable interrupts. */
+ athn_enable_interrupts(sc);
+ return (0);
+
+reset: /* Error found, try a full reset. */
+ DPRINTFN(3, ("needs a full reset\n"));
+ error = athn_hw_reset(sc, c, extc, 0);
+ if (error != 0) { /* Hopeless case. */
+ DEBUG_PRINTF("Channel error occurs %d\n", error);
+ return (error);
+ }
+
+ athn_rx_start(sc);
+
+ return (0);
+}
+
+void
+athn_get_delta_slope(uint32_t coeff, uint32_t *exponent, uint32_t *mantissa)
+{
+#define COEFF_SCALE_SHIFT 24
+ uint32_t exp, man;
+
+ /* exponent = 14 - floor(log2(coeff)) */
+ for (exp = 31; exp > 0; exp--)
+ if (coeff & (1 << exp))
+ break;
+ exp = 14 - (exp - COEFF_SCALE_SHIFT);
+
+ /* mantissa = floor(coeff * 2^exponent + 0.5) */
+ man = coeff + (1 << (COEFF_SCALE_SHIFT - exp - 1));
+
+ *mantissa = man >> (COEFF_SCALE_SHIFT - exp);
+ *exponent = exp - 16;
+#undef COEFF_SCALE_SHIFT
+}
+
+void
+athn_reset_key(struct athn_softc *sc, int entry)
+{
+ /*
+ * NB: Key cache registers access special memory area that requires
+ * two 32-bit writes to actually update the values in the internal
+ * memory. Consequently, writes must be grouped by pair.
+ *
+ * All writes to registers with an offset of 0x0 or 0x8 write to a
+ * temporary register. A write to a register with an offset of 0x4
+ * or 0xc writes concatenates the written value with the value in
+ * the temporary register and writes the result to key cache memory.
+ * The actual written memory area is 50 bits wide.
+ */
+ AR_WRITE(sc, AR_KEYTABLE_KEY0(entry), 0);
+ AR_WRITE(sc, AR_KEYTABLE_KEY1(entry), 0);
+
+ AR_WRITE(sc, AR_KEYTABLE_KEY2(entry), 0);
+ AR_WRITE(sc, AR_KEYTABLE_KEY3(entry), 0);
+
+ AR_WRITE(sc, AR_KEYTABLE_KEY4(entry), 0);
+ AR_WRITE(sc, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
+
+ AR_WRITE(sc, AR_KEYTABLE_MAC0(entry), 0);
+ AR_WRITE(sc, AR_KEYTABLE_MAC1(entry), 0);
+
+ AR_WRITE_BARRIER(sc);
+}
+
+int
+athn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
+ struct ieee80211_key *k)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 1;
+#if 0
+ struct athn_softc *sc = ic->ic_softc;
+ const uint8_t *key, *addr;
+ uintptr_t entry;
+ uint32_t lo, hi, unicast;
+
+ if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
+ /* Use software crypto for ciphers other than CCMP. */
+ return ieee80211_set_key(ic, ni, k);
+ }
+
+ if (!(k->k_flags & IEEE80211_KEY_GROUP)) {
+#ifndef IEEE80211_STA_ONLY
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP)
+ entry = IEEE80211_WEP_NKID + IEEE80211_AID(ni->ni_associd);
+ else
+#endif
+ entry = IEEE80211_WEP_NKID;
+ if (entry >= sc->kc_entries - IEEE80211_WEP_NKID)
+ return ENOSPC;
+ } else {
+ entry = k->k_id;
+ if (entry >= IEEE80211_WEP_NKID)
+ return ENOSPC;
+ }
+ k->k_priv = (void *)entry;
+
+ /* NB: See note about key cache registers access above. */
+ key = k->k_key;
+
+ AR_WRITE(sc, AR_KEYTABLE_KEY0(entry), LE_READ_4(&key[ 0]));
+ AR_WRITE(sc, AR_KEYTABLE_KEY1(entry), LE_READ_2(&key[ 4]));
+
+ AR_WRITE(sc, AR_KEYTABLE_KEY2(entry), LE_READ_4(&key[ 6]));
+ AR_WRITE(sc, AR_KEYTABLE_KEY3(entry), LE_READ_2(&key[10]));
+
+ AR_WRITE(sc, AR_KEYTABLE_KEY4(entry), LE_READ_4(&key[12]));
+ AR_WRITE(sc, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CCM);
+
+ unicast = AR_KEYTABLE_VALID;
+ if (!(k->k_flags & IEEE80211_KEY_GROUP)) {
+ addr = ni->ni_macaddr;
+ lo = LE_READ_4(&addr[0]);
+ hi = LE_READ_2(&addr[4]);
+ lo = lo >> 1 | hi << 31;
+ hi = hi >> 1;
+ } else {
+#ifndef IEEE80211_STA_ONLY
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+ uint8_t groupaddr[ETHER_ADDR_LEN];
+ IEEE80211_ADDR_COPY(groupaddr, ic->ic_macaddr);
+ groupaddr[0] |= 0x01;
+ lo = LE_READ_4(&groupaddr[0]);
+ hi = LE_READ_2(&groupaddr[4]);
+ lo = lo >> 1 | hi << 31;
+ hi = hi >> 1;
+ /*
+ * KEYTABLE_VALID indicates that the address
+ * is a unicast address which must match the
+ * transmitter address when decrypting frames.
+ * Not setting KEYTABLE_VALID allows hardware to
+ * use this key for multicast frame decryption.
+ */
+ unicast = 0;
+ } else
+#endif
+ lo = hi = 0;
+ }
+ AR_WRITE(sc, AR_KEYTABLE_MAC0(entry), lo);
+ AR_WRITE(sc, AR_KEYTABLE_MAC1(entry), hi | unicast);
+
+ AR_WRITE_BARRIER(sc);
+
+ /* Enable HW crypto. */
+ AR_CLRBITS(sc, AR_DIAG_SW, AR_DIAG_ENCRYPT_DIS | AR_DIAG_DECRYPT_DIS);
+
+ AR_WRITE_BARRIER(sc);
+ return (0);
+#endif
+}
+
+void
+athn_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
+ struct ieee80211_key *k)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_softc *sc = ic->ic_softc;
+ uintptr_t entry;
+
+ if (k->k_cipher == IEEE80211_CIPHER_CCMP) {
+ entry = (uintptr_t)k->k_priv;
+ athn_reset_key(sc, entry);
+ explicit_bzero(k, sizeof(*k));
+ } else
+ ieee80211_delete_key(ic, ni, k);
+#endif
+}
+
+void
+athn_led_init(struct athn_softc *sc)
+{
+ DEBUG_PRINTF("athn_led_init\n");
+ struct athn_ops *ops = &sc->ops;
+
+ ops->gpio_config_output(sc, sc->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ /* LED off, active low. */
+ athn_set_led(sc, 0);
+}
+
+void
+athn_set_led(struct athn_softc *sc, int on)
+{
+ struct athn_ops *ops = &sc->ops;
+
+ sc->led_state = on;
+ ops->gpio_write(sc, sc->led_pin, !sc->led_state);
+}
+
+#ifdef ATHN_BT_COEXISTENCE
+void
+athn_btcoex_init(struct athn_softc *sc)
+{
+ struct athn_ops *ops = &sc->ops;
+ uint32_t reg;
+
+ if (sc->flags & ATHN_FLAG_BTCOEX2WIRE) {
+ /* Connect bt_active to baseband. */
+ AR_CLRBITS(sc, sc->gpio_input_en_off,
+ AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
+ AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF);
+ AR_SETBITS(sc, sc->gpio_input_en_off,
+ AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+
+ reg = AR_READ(sc, AR_GPIO_INPUT_MUX1);
+ reg = RW(reg, AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+ AR_GPIO_BTACTIVE_PIN);
+ AR_WRITE(sc, AR_GPIO_INPUT_MUX1, reg);
+ AR_WRITE_BARRIER(sc);
+
+ ops->gpio_config_input(sc, AR_GPIO_BTACTIVE_PIN);
+ } else { /* 3-wire. */
+ AR_SETBITS(sc, sc->gpio_input_en_off,
+ AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB |
+ AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+
+ reg = AR_READ(sc, AR_GPIO_INPUT_MUX1);
+ reg = RW(reg, AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+ AR_GPIO_BTACTIVE_PIN);
+ reg = RW(reg, AR_GPIO_INPUT_MUX1_BT_PRIORITY,
+ AR_GPIO_BTPRIORITY_PIN);
+ AR_WRITE(sc, AR_GPIO_INPUT_MUX1, reg);
+ AR_WRITE_BARRIER(sc);
+
+ ops->gpio_config_input(sc, AR_GPIO_BTACTIVE_PIN);
+ ops->gpio_config_input(sc, AR_GPIO_BTPRIORITY_PIN);
+ }
+}
+
+void
+athn_btcoex_enable(struct athn_softc *sc)
+{
+ struct athn_ops *ops = &sc->ops;
+ uint32_t reg;
+
+ if (sc->flags & ATHN_FLAG_BTCOEX3WIRE) {
+ AR_WRITE(sc, AR_BT_COEX_MODE,
+ SM(AR_BT_MODE, AR_BT_MODE_SLOTTED) |
+ SM(AR_BT_PRIORITY_TIME, 2) |
+ SM(AR_BT_FIRST_SLOT_TIME, 5) |
+ SM(AR_BT_QCU_THRESH, ATHN_QID_AC_BE) |
+ AR_BT_TXSTATE_EXTEND | AR_BT_TX_FRAME_EXTEND |
+ AR_BT_QUIET | AR_BT_RX_CLEAR_POLARITY);
+ AR_WRITE(sc, AR_BT_COEX_WEIGHT,
+ SM(AR_BTCOEX_BT_WGHT, AR_STOMP_LOW_BT_WGHT) |
+ SM(AR_BTCOEX_WL_WGHT, AR_STOMP_LOW_WL_WGHT));
+ AR_WRITE(sc, AR_BT_COEX_MODE2,
+ SM(AR_BT_BCN_MISS_THRESH, 50) |
+ AR_BT_HOLD_RX_CLEAR | AR_BT_DISABLE_BT_ANT);
+
+ AR_SETBITS(sc, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE);
+ AR_CLRBITS(sc, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX);
+ AR_WRITE_BARRIER(sc);
+
+ ops->gpio_config_output(sc, AR_GPIO_WLANACTIVE_PIN,
+ AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL);
+
+ } else { /* 2-wire. */
+ ops->gpio_config_output(sc, AR_GPIO_WLANACTIVE_PIN,
+ AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+ }
+ reg = AR_READ(sc, AR_GPIO_PDPU);
+ reg &= ~(0x3 << (AR_GPIO_WLANACTIVE_PIN * 2));
+ reg |= 0x2 << (AR_GPIO_WLANACTIVE_PIN * 2);
+ AR_WRITE(sc, AR_GPIO_PDPU, reg);
+ AR_WRITE_BARRIER(sc);
+
+ /* Disable PCIe Active State Power Management (ASPM). */
+ if (sc->sc_disable_aspm != NULL)
+ sc->sc_disable_aspm(sc);
+
+ /* XXX Start periodic timer. */
+}
+
+void
+athn_btcoex_disable(struct athn_softc *sc)
+{
+ struct athn_ops *ops = &sc->ops;
+
+ ops->gpio_write(sc, AR_GPIO_WLANACTIVE_PIN, 0);
+
+ ops->gpio_config_output(sc, AR_GPIO_WLANACTIVE_PIN,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+
+ if (sc->flags & ATHN_FLAG_BTCOEX3WIRE) {
+ AR_WRITE(sc, AR_BT_COEX_MODE,
+ SM(AR_BT_MODE, AR_BT_MODE_DISABLED) | AR_BT_QUIET);
+ AR_WRITE(sc, AR_BT_COEX_WEIGHT, 0);
+ AR_WRITE(sc, AR_BT_COEX_MODE2, 0);
+ /* XXX Stop periodic timer. */
+ }
+ AR_WRITE_BARRIER(sc);
+ /* XXX Restore ASPM setting? */
+}
+#endif
+
+void
+athn_iter_calib(void *arg, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_softc *sc = arg;
+ struct athn_node *an = (struct athn_node *)ni;
+
+ if ((ni->ni_flags & IEEE80211_NODE_HT) == 0)
+ ieee80211_amrr_choose(&sc->amrr, ni, &an->amn);
+#endif
+}
+
+int
+athn_cap_noisefloor(struct athn_softc *sc, int nf)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 1;
+#if 0
+ int16_t min, max;
+
+ if (nf == 0 || nf == -1) /* invalid measurement */
+ return AR_DEFAULT_NOISE_FLOOR;
+
+ if (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan)) {
+ min = sc->cca_min_2g;
+ max = sc->cca_max_2g;
+ } else {
+ min = sc->cca_min_5g;
+ max = sc->cca_max_5g;
+ }
+
+ if (nf < min)
+ return min;
+ if (nf > max)
+ return max;
+
+ return nf;
+#endif
+}
+
+int
+athn_nf_hist_mid(int *nf_vals, int nvalid)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 1;
+#if 0
+ int nf_sorted[ATHN_NF_CAL_HIST_MAX];
+ int i, j, nf;
+
+ if (nvalid <= 1)
+ return nf_vals[0];
+
+ for (i = 0; i < nvalid; i++)
+ nf_sorted[i] = nf_vals[i];
+
+ for (i = 0; i < nvalid; i++) {
+ for (j = 1; j < nvalid - i; j++) {
+ if (nf_sorted[j] > nf_sorted[j - 1]) {
+ nf = nf_sorted[j];
+ nf_sorted[j] = nf_sorted[j - 1];
+ nf_sorted[j - 1] = nf;
+ }
+ }
+ }
+
+ return nf_sorted[nvalid / 2];
+#endif
+}
+
+void
+athn_filter_noisefloor(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ int nf_vals[ATHN_NF_CAL_HIST_MAX];
+ int nf_ext_vals[ATHN_NF_CAL_HIST_MAX];
+ int i, cur, n;
+
+ for (i = 0; i < sc->nrxchains; i++) {
+ if (sc->nf_hist_cur > 0)
+ cur = sc->nf_hist_cur - 1;
+ else
+ cur = ATHN_NF_CAL_HIST_MAX - 1;
+ for (n = 0; n < sc->nf_hist_nvalid; n++) {
+ nf_vals[n] = sc->nf_hist[cur].nf[i];
+ nf_ext_vals[n] = sc->nf_hist[cur].nf_ext[i];
+ if (++cur >= ATHN_NF_CAL_HIST_MAX)
+ cur = 0;
+ }
+ sc->nf_priv[i] = athn_cap_noisefloor(sc,
+ athn_nf_hist_mid(nf_vals, sc->nf_hist_nvalid));
+ sc->nf_ext_priv[i] = athn_cap_noisefloor(sc,
+ athn_nf_hist_mid(nf_ext_vals, sc->nf_hist_nvalid));
+ }
+#endif
+}
+
+void
+athn_start_noisefloor_calib(struct athn_softc *sc, int reset_history)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ extern int ticks;
+
+ if (reset_history)
+ sc->nf_hist_nvalid = 0;
+
+ sc->nf_calib_pending = 1;
+ sc->nf_calib_ticks = ticks;
+
+ sc->ops.noisefloor_calib(sc);
+#endif
+}
+
+void
+athn_calib_to(void *arg)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ extern int ticks;
+ struct athn_softc *sc = arg;
+ struct athn_ops *ops = &sc->ops;
+ struct ieee80211com *ic = &sc->sc_ic;
+ int s;
+
+ s = splnet();
+
+ /* Do periodic (every 4 minutes) PA calibration. */
+ if (AR_SREV_9285_11_OR_LATER(sc) &&
+ !AR_SREV_9380_10_OR_LATER(sc) &&
+ (ticks - (sc->pa_calib_ticks + 240 * hz)) >= 0) {
+ sc->pa_calib_ticks = ticks;
+ if (AR_SREV_9271(sc))
+ ar9271_pa_calib(sc);
+ else
+ ar9285_pa_calib(sc);
+ }
+
+ /* Do periodic (every 4 minutes) NF calibration. */
+ if (sc->nf_calib_pending && ops->get_noisefloor(sc)) {
+ if (sc->nf_hist_nvalid < ATHN_NF_CAL_HIST_MAX)
+ sc->nf_hist_nvalid++;
+ athn_filter_noisefloor(sc);
+ ops->apply_noisefloor(sc);
+ sc->nf_calib_pending = 0;
+ }
+ if (ticks - (sc->nf_calib_ticks + 240 * hz) >= 0)
+ athn_start_noisefloor_calib(sc, 0);
+
+ /* Do periodic (every 30 seconds) temperature compensation. */
+ if ((sc->flags & ATHN_FLAG_OLPC) &&
+ ticks >= sc->olpc_ticks + 30 * hz) {
+ sc->olpc_ticks = ticks;
+ ops->olpc_temp_compensation(sc);
+ }
+
+#ifdef notyet
+ /* XXX ANI. */
+ athn_ani_monitor(sc);
+#endif
+
+ /* Do periodic (every 30 seconds) ADC/IQ calibration. */
+ if (sc->cur_calib_mask != 0) {
+ ops->next_calib(sc);
+ sc->iqcal_ticks = ticks;
+ } else if (sc->sup_calib_mask != 0 &&
+ ticks >= sc->iqcal_ticks + 30 * hz) {
+ memset(&sc->calib, 0, sizeof(sc->calib));
+ sc->cur_calib_mask = sc->sup_calib_mask;
+ ops->do_calib(sc);
+ sc->iqcal_ticks = ticks;
+ }
+
+ if (ic->ic_fixed_rate == -1) {
+ if (ic->ic_opmode == IEEE80211_M_STA)
+ athn_iter_calib(sc, ic->ic_bss);
+ else
+ ieee80211_iterate_nodes(ic, athn_iter_calib, sc);
+ }
+ timeout_add_msec(&sc->calib_to, 500);
+ splx(s);
+#endif
+}
+
+int
+athn_init_calib(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 1;
+#if 0
+ struct athn_ops *ops = &sc->ops;
+ int error;
+
+ if (AR_SREV_9380_10_OR_LATER(sc))
+ error = ar9003_init_calib(sc);
+ else if (AR_SREV_9285_10_OR_LATER(sc))
+ error = ar9285_init_calib(sc, c, extc);
+ else
+ error = ar5416_init_calib(sc, c, extc);
+ if (error != 0)
+ return (error);
+
+ if (!AR_SREV_9380_10_OR_LATER(sc)) {
+ /* Do PA calibration. */
+ if (AR_SREV_9285_11_OR_LATER(sc)) {
+ extern int ticks;
+ sc->pa_calib_ticks = ticks;
+ if (AR_SREV_9271(sc))
+ ar9271_pa_calib(sc);
+ else
+ ar9285_pa_calib(sc);
+ }
+ }
+
+ /* Do noisefloor calibration. */
+ ops->init_noisefloor_calib(sc);
+
+ if (AR_SREV_9160_10_OR_LATER(sc)) {
+ /* Support IQ calibration. */
+ sc->sup_calib_mask = ATHN_CAL_IQ;
+ if (AR_SREV_9380_10_OR_LATER(sc)) {
+ /* Support temperature compensation calibration. */
+ sc->sup_calib_mask |= ATHN_CAL_TEMP;
+ } else if (IEEE80211_IS_CHAN_5GHZ(c) || extc != NULL) {
+ /*
+ * ADC gain calibration causes uplink throughput
+ * drops in HT40 mode on AR9287.
+ */
+ if (!AR_SREV_9287(sc)) {
+ /* Support ADC gain calibration. */
+ sc->sup_calib_mask |= ATHN_CAL_ADC_GAIN;
+ }
+ /* Support ADC DC offset calibration. */
+ sc->sup_calib_mask |= ATHN_CAL_ADC_DC;
+ }
+ }
+ return (0);
+#endif
+}
+
+/*
+ * Adaptive noise immunity.
+ */
+int32_t
+athn_ani_get_rssi(struct athn_softc *sc)
+{
+ return (0); /* XXX */
+}
+
+void
+athn_ani_ofdm_err_trigger(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_ani *ani = &sc->ani;
+ struct athn_ops *ops = &sc->ops;
+ int32_t rssi;
+
+ /* First, raise noise immunity level, up to max. */
+ if (ani->noise_immunity_level < 4) {
+ ani->noise_immunity_level++;
+ ops->set_noise_immunity_level(sc, ani->noise_immunity_level);
+ return;
+ }
+
+ /* Then, raise our spur immunity level, up to max. */
+ if (ani->spur_immunity_level < 7) {
+ ani->spur_immunity_level++;
+ ops->set_spur_immunity_level(sc, ani->spur_immunity_level);
+ return;
+ }
+
+#ifndef IEEE80211_STA_ONLY
+ if (sc->sc_ic.ic_opmode == IEEE80211_M_HOSTAP) {
+ if (ani->firstep_level < 2) {
+ ani->firstep_level++;
+ ops->set_firstep_level(sc, ani->firstep_level);
+ }
+ return;
+ }
+#endif
+ rssi = athn_ani_get_rssi(sc);
+ if (rssi > ATHN_ANI_RSSI_THR_HIGH) {
+ /*
+ * Beacon RSSI is high, turn off OFDM weak signal detection
+ * or raise first step level as last resort.
+ */
+ if (ani->ofdm_weak_signal) {
+ ani->ofdm_weak_signal = 0;
+ ops->disable_ofdm_weak_signal(sc);
+ ani->spur_immunity_level = 0;
+ ops->set_spur_immunity_level(sc, 0);
+ } else if (ani->firstep_level < 2) {
+ ani->firstep_level++;
+ ops->set_firstep_level(sc, ani->firstep_level);
+ }
+ } else if (rssi > ATHN_ANI_RSSI_THR_LOW) {
+ /*
+ * Beacon RSSI is in mid range, we need OFDM weak signal
+ * detection but we can raise first step level.
+ */
+ if (!ani->ofdm_weak_signal) {
+ ani->ofdm_weak_signal = 1;
+ ops->enable_ofdm_weak_signal(sc);
+ }
+ if (ani->firstep_level < 2) {
+ ani->firstep_level++;
+ ops->set_firstep_level(sc, ani->firstep_level);
+ }
+ } else if (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan)) {
+ /*
+ * Beacon RSSI is low, if in b/g mode, turn off OFDM weak
+ * signal detection and zero first step level to maximize
+ * CCK sensitivity.
+ */
+ if (ani->ofdm_weak_signal) {
+ ani->ofdm_weak_signal = 0;
+ ops->disable_ofdm_weak_signal(sc);
+ }
+ if (ani->firstep_level > 0) {
+ ani->firstep_level = 0;
+ ops->set_firstep_level(sc, 0);
+ }
+ }
+#endif
+}
+
+void
+athn_ani_cck_err_trigger(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_ani *ani = &sc->ani;
+ struct athn_ops *ops = &sc->ops;
+ int32_t rssi;
+
+ /* Raise noise immunity level, up to max. */
+ if (ani->noise_immunity_level < 4) {
+ ani->noise_immunity_level++;
+ ops->set_noise_immunity_level(sc, ani->noise_immunity_level);
+ return;
+ }
+
+#ifndef IEEE80211_STA_ONLY
+ if (sc->sc_ic.ic_opmode == IEEE80211_M_HOSTAP) {
+ if (ani->firstep_level < 2) {
+ ani->firstep_level++;
+ ops->set_firstep_level(sc, ani->firstep_level);
+ }
+ return;
+ }
+#endif
+ rssi = athn_ani_get_rssi(sc);
+ if (rssi > ATHN_ANI_RSSI_THR_LOW) {
+ /*
+ * Beacon RSSI is in mid or high range, raise first step
+ * level.
+ */
+ if (ani->firstep_level < 2) {
+ ani->firstep_level++;
+ ops->set_firstep_level(sc, ani->firstep_level);
+ }
+ } else if (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_bss->ni_chan)) {
+ /*
+ * Beacon RSSI is low, zero first step level to maximize
+ * CCK sensitivity.
+ */
+ if (ani->firstep_level > 0) {
+ ani->firstep_level = 0;
+ ops->set_firstep_level(sc, 0);
+ }
+ }
+#endif
+}
+
+void
+athn_ani_lower_immunity(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_ani *ani = &sc->ani;
+ struct athn_ops *ops = &sc->ops;
+ int32_t rssi;
+
+#ifndef IEEE80211_STA_ONLY
+ if (sc->sc_ic.ic_opmode == IEEE80211_M_HOSTAP) {
+ if (ani->firstep_level > 0) {
+ ani->firstep_level--;
+ ops->set_firstep_level(sc, ani->firstep_level);
+ }
+ return;
+ }
+#endif
+ rssi = athn_ani_get_rssi(sc);
+ if (rssi > ATHN_ANI_RSSI_THR_HIGH) {
+ /*
+ * Beacon RSSI is high, leave OFDM weak signal detection
+ * off or it may oscillate.
+ */
+ } else if (rssi > ATHN_ANI_RSSI_THR_LOW) {
+ /*
+ * Beacon RSSI is in mid range, turn on OFDM weak signal
+ * detection or lower first step level.
+ */
+ if (!ani->ofdm_weak_signal) {
+ ani->ofdm_weak_signal = 1;
+ ops->enable_ofdm_weak_signal(sc);
+ return;
+ }
+ if (ani->firstep_level > 0) {
+ ani->firstep_level--;
+ ops->set_firstep_level(sc, ani->firstep_level);
+ return;
+ }
+ } else {
+ /* Beacon RSSI is low, lower first step level. */
+ if (ani->firstep_level > 0) {
+ ani->firstep_level--;
+ ops->set_firstep_level(sc, ani->firstep_level);
+ return;
+ }
+ }
+ /*
+ * Lower spur immunity level down to zero, or if all else fails,
+ * lower noise immunity level down to zero.
+ */
+ if (ani->spur_immunity_level > 0) {
+ ani->spur_immunity_level--;
+ ops->set_spur_immunity_level(sc, ani->spur_immunity_level);
+ } else if (ani->noise_immunity_level > 0) {
+ ani->noise_immunity_level--;
+ ops->set_noise_immunity_level(sc, ani->noise_immunity_level);
+ }
+#endif
+}
+
+void
+athn_ani_restart(struct athn_softc *sc)
+{
+ struct athn_ani *ani = &sc->ani;
+
+ AR_WRITE(sc, AR_PHY_ERR_1, 0);
+ AR_WRITE(sc, AR_PHY_ERR_2, 0);
+ AR_WRITE(sc, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+ AR_WRITE(sc, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+ AR_WRITE_BARRIER(sc);
+
+ ani->listen_time = 0;
+ ani->ofdm_phy_err_count = 0;
+ ani->cck_phy_err_count = 0;
+}
+
+void
+athn_ani_monitor(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_ani *ani = &sc->ani;
+ uint32_t cyccnt, txfcnt, rxfcnt, phy1, phy2;
+ int32_t cycdelta, txfdelta, rxfdelta;
+ int32_t listen_time;
+
+ txfcnt = AR_READ(sc, AR_TFCNT); /* Tx frame count. */
+ rxfcnt = AR_READ(sc, AR_RFCNT); /* Rx frame count. */
+ cyccnt = AR_READ(sc, AR_CCCNT); /* Cycle count. */
+
+ if (ani->cyccnt != 0 && ani->cyccnt <= cyccnt) {
+ cycdelta = cyccnt - ani->cyccnt;
+ txfdelta = txfcnt - ani->txfcnt;
+ rxfdelta = rxfcnt - ani->rxfcnt;
+
+ listen_time = (cycdelta - txfdelta - rxfdelta) /
+ (athn_clock_rate(sc) * 1000);
+ } else
+ listen_time = 0;
+
+ ani->cyccnt = cyccnt;
+ ani->txfcnt = txfcnt;
+ ani->rxfcnt = rxfcnt;
+
+ if (listen_time < 0) {
+ athn_ani_restart(sc);
+ return;
+ }
+ ani->listen_time += listen_time;
+
+ phy1 = AR_READ(sc, AR_PHY_ERR_1);
+ phy2 = AR_READ(sc, AR_PHY_ERR_2);
+
+ if (phy1 < ani->ofdm_phy_err_base) {
+ AR_WRITE(sc, AR_PHY_ERR_1, ani->ofdm_phy_err_base);
+ AR_WRITE(sc, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+ }
+ if (phy2 < ani->cck_phy_err_base) {
+ AR_WRITE(sc, AR_PHY_ERR_2, ani->cck_phy_err_base);
+ AR_WRITE(sc, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+ }
+ if (phy1 < ani->ofdm_phy_err_base || phy2 < ani->cck_phy_err_base) {
+ AR_WRITE_BARRIER(sc);
+ return;
+ }
+ ani->ofdm_phy_err_count = phy1 - ani->ofdm_phy_err_base;
+ ani->cck_phy_err_count = phy2 - ani->cck_phy_err_base;
+
+ if (ani->listen_time > 5 * ATHN_ANI_PERIOD) {
+ /* Check to see if we need to lower immunity. */
+ if (ani->ofdm_phy_err_count <=
+ ani->listen_time * ani->ofdm_trig_low / 1000 &&
+ ani->cck_phy_err_count <=
+ ani->listen_time * ani->cck_trig_low / 1000)
+ athn_ani_lower_immunity(sc);
+ athn_ani_restart(sc);
+
+ } else if (ani->listen_time > ATHN_ANI_PERIOD) {
+ /* Check to see if we need to raise immunity. */
+ if (ani->ofdm_phy_err_count >
+ ani->listen_time * ani->ofdm_trig_high / 1000) {
+ athn_ani_ofdm_err_trigger(sc);
+ athn_ani_restart(sc);
+ } else if (ani->cck_phy_err_count >
+ ani->listen_time * ani->cck_trig_high / 1000) {
+ athn_ani_cck_err_trigger(sc);
+ athn_ani_restart(sc);
+ }
+ }
+#endif
+}
+
+uint8_t
+athn_chan2fbin(struct ieee80211_channel *c)
+{
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ return (c->ic_freq - 2300);
+ else
+ return ((c->ic_freq - 4800) / 5);
+}
+
+int
+athn_interpolate(int x, int x1, int y1, int x2, int y2)
+{
+ if (x1 == x2) /* Prevents division by zero. */
+ return (y1);
+ /* Linear interpolation. */
+ return (y1 + ((x - x1) * (y2 - y1)) / (x2 - x1));
+}
+
+void
+athn_get_pier_ival(uint8_t fbin, const uint8_t *pierfreq, int npiers,
+ int *lo, int *hi)
+{
+ int i;
+
+ for (i = 0; i < npiers; i++)
+ if (pierfreq[i] == AR_BCHAN_UNUSED ||
+ pierfreq[i] > fbin)
+ break;
+ *hi = i;
+ *lo = *hi - 1;
+ if (*lo == -1)
+ *lo = *hi;
+ else if (*hi == npiers || pierfreq[*hi] == AR_BCHAN_UNUSED)
+ *hi = *lo;
+}
+
+void
+athn_init_dma(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ uint32_t reg;
+
+ if (!AR_SREV_9380_10_OR_LATER(sc)) {
+ /* Set AHB not to do cacheline prefetches. */
+ AR_SETBITS(sc, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN);
+ }
+ reg = AR_READ(sc, AR_TXCFG);
+ /* Let MAC DMA reads be in 128-byte chunks. */
+ reg = RW(reg, AR_TXCFG_DMASZ, AR_DMASZ_128B);
+
+ /* Set initial Tx trigger level. */
+ if (AR_SREV_9285(sc) || AR_SREV_9271(sc))
+ reg = RW(reg, AR_TXCFG_FTRIG, AR_TXCFG_FTRIG_256B);
+ else if (!AR_SREV_9380_10_OR_LATER(sc))
+ reg = RW(reg, AR_TXCFG_FTRIG, AR_TXCFG_FTRIG_512B);
+ AR_WRITE(sc, AR_TXCFG, reg);
+
+ /* Let MAC DMA writes be in 128-byte chunks. */
+ reg = AR_READ(sc, AR_RXCFG);
+ reg = RW(reg, AR_RXCFG_DMASZ, AR_DMASZ_128B);
+ AR_WRITE(sc, AR_RXCFG, reg);
+
+ /* Setup Rx FIFO threshold to hold off Tx activities. */
+ AR_WRITE(sc, AR_RXFIFO_CFG, 512);
+
+ /* Reduce the number of entries in PCU TXBUF to avoid wrap around. */
+ if (AR_SREV_9285(sc)) {
+ AR_WRITE(sc, AR_PCU_TXBUF_CTRL,
+ AR9285_PCU_TXBUF_CTRL_USABLE_SIZE);
+ } else if (!AR_SREV_9271(sc)) {
+ AR_WRITE(sc, AR_PCU_TXBUF_CTRL,
+ AR_PCU_TXBUF_CTRL_USABLE_SIZE);
+ }
+ AR_WRITE_BARRIER(sc);
+
+ /* Reset Tx status ring. */
+ if (AR_SREV_9380_10_OR_LATER(sc))
+ ar9003_reset_txsring(sc);
+#endif
+}
+
+void
+athn_inc_tx_trigger_level(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ uint32_t reg, ftrig;
+
+ reg = AR_READ(sc, AR_TXCFG);
+ ftrig = MS(reg, AR_TXCFG_FTRIG);
+ /*
+ * NB: The AR9285 and all single-stream parts have an issue that
+ * limits the size of the PCU Tx FIFO to 2KB instead of 4KB.
+ */
+ if (ftrig == ((AR_SREV_9285(sc) || AR_SREV_9271(sc)) ? 0x1f : 0x3f))
+ return; /* Already at max. */
+ reg = RW(reg, AR_TXCFG_FTRIG, ftrig + 1);
+ AR_WRITE(sc, AR_TXCFG, reg);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+int
+athn_stop_rx_dma(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 1;
+#if 0
+ int ntries;
+
+ AR_WRITE(sc, AR_CR, AR_CR_RXD);
+ /* Wait for Rx enable bit to go low. */
+ for (ntries = 0; ntries < 100; ntries++) {
+ if (!(AR_READ(sc, AR_CR) & AR_CR_RXE))
+ return (0);
+ DELAY(100);
+ }
+ DPRINTF(("Rx DMA failed to stop\n"));
+ return (ETIMEDOUT);
+#endif
+}
+
+int
+athn_rx_abort(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 1;
+#if 0
+ int ntries;
+
+ AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
+ for (ntries = 0; ntries < 1000; ntries++) {
+ if (MS(AR_READ(sc, AR_OBS_BUS_1), AR_OBS_BUS_1_RX_STATE) == 0)
+ return (0);
+ DELAY(10);
+ }
+ DPRINTF(("Rx failed to go idle in 10ms\n"));
+ AR_CLRBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
+ AR_WRITE_BARRIER(sc);
+ return (ETIMEDOUT);
+#endif
+}
+
+void
+athn_tx_reclaim(struct athn_softc *sc, int qid)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_txq *txq = &sc->txq[qid];
+ struct athn_tx_buf *bf;
+
+ /* Reclaim all buffers queued in the specified Tx queue. */
+ /* NB: Tx DMA must be stopped. */
+ while ((bf = SIMPLEQ_FIRST(&txq->head)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&txq->head, bf_list);
+
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0,
+ bf->bf_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->sc_dmat, bf->bf_map);
+ m_freem(bf->bf_m);
+ bf->bf_m = NULL;
+ bf->bf_ni = NULL; /* Nodes already freed! */
+
+ /* Link Tx buffer back to global free list. */
+ SIMPLEQ_INSERT_TAIL(&sc->txbufs, bf, bf_list);
+ }
+#endif
+}
+
+int
+athn_tx_pending(struct athn_softc *sc, int qid)
+{
+ return (MS(AR_READ(sc, AR_QSTS(qid)), AR_Q_STS_PEND_FR_CNT) != 0 ||
+ (AR_READ(sc, AR_Q_TXE) & (1 << qid)) != 0);
+}
+
+void
+athn_stop_tx_dma(struct athn_softc *sc, int qid)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ uint32_t tsflo;
+ int ntries, i;
+
+ AR_WRITE(sc, AR_Q_TXD, 1 << qid);
+ for (ntries = 0; ntries < 40; ntries++) {
+ if (!athn_tx_pending(sc, qid))
+ break;
+ DELAY(100);
+ }
+ if (ntries == 40) {
+ for (i = 0; i < 2; i++) {
+ tsflo = AR_READ(sc, AR_TSF_L32) / 1024;
+ AR_WRITE(sc, AR_QUIET2,
+ SM(AR_QUIET2_QUIET_DUR, 10));
+ AR_WRITE(sc, AR_QUIET_PERIOD, 100);
+ AR_WRITE(sc, AR_NEXT_QUIET_TIMER, tsflo);
+ AR_SETBITS(sc, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
+ if (AR_READ(sc, AR_TSF_L32) / 1024 == tsflo)
+ break;
+ }
+ AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+ AR_WRITE_BARRIER(sc);
+ DELAY(200);
+ AR_CLRBITS(sc, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
+ AR_WRITE_BARRIER(sc);
+
+ for (ntries = 0; ntries < 40; ntries++) {
+ if (!athn_tx_pending(sc, qid))
+ break;
+ DELAY(100);
+ }
+
+ AR_CLRBITS(sc, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+ }
+ AR_WRITE(sc, AR_Q_TXD, 0);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+int
+athn_txtime(struct athn_softc *sc, int len, int ridx, u_int flags)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 0;
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+#define divround(a, b) (((a) + (b) - 1) / (b))
+ int txtime;
+
+ if (athn_rates[ridx].hwrate & 0x80) { /* MCS */
+ /* Assumes a 20MHz channel, HT-mixed frame format, no STBC. */
+ txtime = 8 + 8 + 4 + 4 + 4 * 4 + 8 /* HT PLCP */
+ + 4 * ((8 * len + 16 + 6) / (athn_rates[ridx].rate * 2));
+ if (IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan))
+ txtime += 6; /* aSignalExtension */
+ } else if (athn_rates[ridx].phy == IEEE80211_T_OFDM) {
+ txtime = divround(8 + 4 * len + 3, athn_rates[ridx].rate);
+ /* SIFS is 10us for 11g but Signal Extension adds 6us. */
+ txtime = 16 + 4 + 4 * txtime + 16;
+ } else {
+ txtime = divround(16 * len, athn_rates[ridx].rate);
+ if (ridx != ATHN_RIDX_CCK1 && (flags & IEEE80211_F_SHPREAMBLE))
+ txtime += 72 + 24;
+ else
+ txtime += 144 + 48;
+ txtime += 10; /* 10us SIFS. */
+ }
+ return (txtime);
+#undef divround
+#endif // FreeBSD endif
+}
+
+void
+athn_init_tx_queues(struct athn_softc *sc)
+{
+ int qid;
+ printf("Start of athn_init_tx_queues\n");
+
+ for (qid = 0; qid < ATHN_QID_COUNT; qid++) {
+ //SIMPLEQ_INIT(&sc->txq[qid].head);
+ STAILQ_INIT(&sc->txq[qid].head);
+ sc->txq[qid].lastds = NULL;
+ sc->txq[qid].wait = NULL;
+ sc->txq[qid].queued = 0;
+
+ AR_WRITE(sc, AR_DRETRY_LIMIT(qid),
+ SM(AR_D_RETRY_LIMIT_STA_SH, 32) |
+ SM(AR_D_RETRY_LIMIT_STA_LG, 32) |
+ SM(AR_D_RETRY_LIMIT_FR_SH, 10));
+ AR_WRITE(sc, AR_QMISC(qid),
+ AR_Q_MISC_DCU_EARLY_TERM_REQ);
+ AR_WRITE(sc, AR_DMISC(qid),
+ SM(AR_D_MISC_BKOFF_THRESH, 2) |
+ AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN);
+ }
+
+ /* Init beacon queue. */
+ AR_SETBITS(sc, AR_QMISC(ATHN_QID_BEACON),
+ AR_Q_MISC_FSP_DBA_GATED | AR_Q_MISC_BEACON_USE |
+ AR_Q_MISC_CBR_INCR_DIS1);
+ AR_SETBITS(sc, AR_DMISC(ATHN_QID_BEACON),
+ SM(AR_D_MISC_ARB_LOCKOUT_CNTRL,
+ AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL) |
+ AR_D_MISC_BEACON_USE |
+ AR_D_MISC_POST_FR_BKOFF_DIS);
+ AR_WRITE(sc, AR_DLCL_IFS(ATHN_QID_BEACON),
+ SM(AR_D_LCL_IFS_CWMIN, 0) |
+ SM(AR_D_LCL_IFS_CWMAX, 0) |
+ SM(AR_D_LCL_IFS_AIFS, 1));
+
+ /* Init CAB (Content After Beacon) queue. */
+ AR_SETBITS(sc, AR_QMISC(ATHN_QID_CAB),
+ AR_Q_MISC_FSP_DBA_GATED | AR_Q_MISC_CBR_INCR_DIS1 |
+ AR_Q_MISC_CBR_INCR_DIS0);
+ AR_SETBITS(sc, AR_DMISC(ATHN_QID_CAB),
+ SM(AR_D_MISC_ARB_LOCKOUT_CNTRL,
+ AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL));
+
+ /* Init PS-Poll queue. */
+ AR_SETBITS(sc, AR_QMISC(ATHN_QID_PSPOLL),
+ AR_Q_MISC_CBR_INCR_DIS1);
+
+ /* Init UAPSD queue. */
+ AR_SETBITS(sc, AR_DMISC(ATHN_QID_UAPSD),
+ AR_D_MISC_POST_FR_BKOFF_DIS);
+
+ if (AR_SREV_9380_10_OR_LATER(sc)) {
+ /* Enable MAC descriptor CRC check. */
+ AR_WRITE(sc, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
+ }
+ /* Enable DESC interrupts for all Tx queues. */
+ AR_WRITE(sc, AR_IMR_S0, 0x00ff0000);
+ /* Enable EOL interrupts for all Tx queues except UAPSD. */
+ AR_WRITE(sc, AR_IMR_S1, 0x00df0000);
+ AR_WRITE_BARRIER(sc);
+ printf("End of athn_init_tx_queues\n");
+}
+
+void
+athn_set_sta_timers(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint32_t tsfhi, tsflo, tsftu, reg;
+ uint32_t intval, next_tbtt, next_dtim;
+ int dtim_period, dtim_count, rem_dtim_count;
+
+ tsfhi = AR_READ(sc, AR_TSF_U32);
+ tsflo = AR_READ(sc, AR_TSF_L32);
+ tsftu = AR_TSF_TO_TU(tsfhi, tsflo) + AR_FUDGE;
+
+ /* Beacon interval in TU. */
+ intval = ic->ic_bss->ni_intval;
+
+ next_tbtt = roundup(tsftu, intval);
+#ifdef notyet
+ dtim_period = ic->ic_dtim_period;
+ if (dtim_period <= 0)
+#endif
+ dtim_period = 1; /* Assume all TIMs are DTIMs. */
+
+#ifdef notyet
+ dtim_count = ic->ic_dtim_count;
+ if (dtim_count >= dtim_period) /* Should not happen. */
+#endif
+ dtim_count = 0; /* Assume last TIM was a DTIM. */
+
+ /* Compute number of remaining TIMs until next DTIM. */
+ rem_dtim_count = 0; /* XXX */
+ next_dtim = next_tbtt + rem_dtim_count * intval;
+
+ AR_WRITE(sc, AR_NEXT_TBTT_TIMER, next_tbtt * IEEE80211_DUR_TU);
+ AR_WRITE(sc, AR_BEACON_PERIOD, intval * IEEE80211_DUR_TU);
+ AR_WRITE(sc, AR_DMA_BEACON_PERIOD, intval * IEEE80211_DUR_TU);
+
+ /*
+ * Set the number of consecutive beacons to miss before raising
+ * a BMISS interrupt to 10.
+ */
+ reg = AR_READ(sc, AR_RSSI_THR);
+ reg = RW(reg, AR_RSSI_THR_BM_THR, 10);
+ AR_WRITE(sc, AR_RSSI_THR, reg);
+
+ AR_WRITE(sc, AR_NEXT_DTIM,
+ (next_dtim - AR_SLEEP_SLOP) * IEEE80211_DUR_TU);
+ AR_WRITE(sc, AR_NEXT_TIM,
+ (next_tbtt - AR_SLEEP_SLOP) * IEEE80211_DUR_TU);
+
+ /* CAB timeout is in 1/8 TU. */
+ AR_WRITE(sc, AR_SLEEP1,
+ SM(AR_SLEEP1_CAB_TIMEOUT, AR_CAB_TIMEOUT_VAL * 8) |
+ AR_SLEEP1_ASSUME_DTIM);
+ AR_WRITE(sc, AR_SLEEP2,
+ SM(AR_SLEEP2_BEACON_TIMEOUT, AR_MIN_BEACON_TIMEOUT_VAL));
+
+ AR_WRITE(sc, AR_TIM_PERIOD, intval * IEEE80211_DUR_TU);
+ AR_WRITE(sc, AR_DTIM_PERIOD, dtim_period * intval * IEEE80211_DUR_TU);
+
+ AR_SETBITS(sc, AR_TIMER_MODE,
+ AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN | AR_DTIM_TIMER_EN);
+
+ /* Set TSF out-of-range threshold (fixed at 16k us). */
+ AR_WRITE(sc, AR_TSFOOR_THRESHOLD, 0x4240);
+
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+#ifndef IEEE80211_STA_ONLY
+void
+athn_set_hostap_timers(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint32_t intval, next_tbtt;
+
+ /* Beacon interval in TU. */
+ intval = ic->ic_bss->ni_intval;
+ next_tbtt = intval;
+
+ AR_WRITE(sc, AR_NEXT_TBTT_TIMER, next_tbtt * IEEE80211_DUR_TU);
+ AR_WRITE(sc, AR_NEXT_DMA_BEACON_ALERT,
+ (next_tbtt - AR_BEACON_DMA_DELAY) * IEEE80211_DUR_TU);
+ AR_WRITE(sc, AR_NEXT_CFP,
+ (next_tbtt - AR_SWBA_DELAY) * IEEE80211_DUR_TU);
+
+ AR_WRITE(sc, AR_BEACON_PERIOD, intval * IEEE80211_DUR_TU);
+ AR_WRITE(sc, AR_DMA_BEACON_PERIOD, intval * IEEE80211_DUR_TU);
+ AR_WRITE(sc, AR_SWBA_PERIOD, intval * IEEE80211_DUR_TU);
+ AR_WRITE(sc, AR_NDP_PERIOD, intval * IEEE80211_DUR_TU);
+
+ AR_WRITE(sc, AR_TIMER_MODE,
+ AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN);
+
+ AR_WRITE_BARRIER(sc);
+#endif // FreeBSD addition
+}
+#endif
+
+void
+athn_set_opmode(struct athn_softc *sc)
+{
+ uint32_t reg;
+
+ switch (sc->sc_ic.ic_opmode) {
+#ifndef IEEE80211_STA_ONLY
+ case IEEE80211_M_HOSTAP:
+ reg = AR_READ(sc, AR_STA_ID1);
+ reg &= ~AR_STA_ID1_ADHOC;
+ reg |= AR_STA_ID1_STA_AP | AR_STA_ID1_KSRCH_MODE;
+ AR_WRITE(sc, AR_STA_ID1, reg);
+
+ AR_CLRBITS(sc, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
+ break;
+ case IEEE80211_M_IBSS:
+ case IEEE80211_M_AHDEMO:
+ reg = AR_READ(sc, AR_STA_ID1);
+ reg &= ~AR_STA_ID1_STA_AP;
+ reg |= AR_STA_ID1_ADHOC | AR_STA_ID1_KSRCH_MODE;
+ AR_WRITE(sc, AR_STA_ID1, reg);
+
+ AR_SETBITS(sc, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
+ break;
+#endif
+ default:
+ reg = AR_READ(sc, AR_STA_ID1);
+ reg &= ~(AR_STA_ID1_ADHOC | AR_STA_ID1_STA_AP);
+ reg |= AR_STA_ID1_KSRCH_MODE;
+ AR_WRITE(sc, AR_STA_ID1, reg);
+ break;
+ }
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+athn_set_bss(struct athn_softc *sc, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ const uint8_t *bssid = ni->ni_bssid;
+
+ AR_WRITE(sc, AR_BSS_ID0, LE_READ_4(&bssid[0]));
+ AR_WRITE(sc, AR_BSS_ID1, LE_READ_2(&bssid[4]) |
+ SM(AR_BSS_ID1_AID, IEEE80211_AID(ni->ni_associd)));
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+athn_enable_interrupts(struct athn_softc *sc)
+{
+ uint32_t mask2;
+
+ athn_disable_interrupts(sc); /* XXX */
+
+ AR_WRITE(sc, AR_IMR, sc->imask);
+
+ mask2 = AR_READ(sc, AR_IMR_S2);
+ mask2 &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
+ AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | AR_IMR_S2_TSFOOR);
+ mask2 |= AR_IMR_S2_GTT | AR_IMR_S2_CST;
+ AR_WRITE(sc, AR_IMR_S2, mask2);
+
+ AR_CLRBITS(sc, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
+
+ AR_WRITE(sc, AR_IER, AR_IER_ENABLE);
+
+ AR_WRITE(sc, AR_INTR_ASYNC_ENABLE, AR_INTR_MAC_IRQ);
+ AR_WRITE(sc, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
+
+ AR_WRITE(sc, AR_INTR_SYNC_ENABLE, sc->isync);
+ AR_WRITE(sc, AR_INTR_SYNC_MASK, sc->isync);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+athn_disable_interrupts(struct athn_softc *sc)
+{
+ AR_WRITE(sc, AR_IER, 0);
+ (void)AR_READ(sc, AR_IER);
+
+ AR_WRITE(sc, AR_INTR_ASYNC_ENABLE, 0);
+ (void)AR_READ(sc, AR_INTR_ASYNC_ENABLE);
+
+ AR_WRITE(sc, AR_INTR_SYNC_ENABLE, 0);
+ (void)AR_READ(sc, AR_INTR_SYNC_ENABLE);
+
+ AR_WRITE(sc, AR_IMR, 0);
+
+ AR_CLRBITS(sc, AR_IMR_S2, AR_IMR_S2_TIM | AR_IMR_S2_DTIM |
+ AR_IMR_S2_DTIMSYNC | AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
+ AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
+
+ AR_CLRBITS(sc, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+athn_init_qos(struct athn_softc *sc)
+{
+ /* Initialize QoS settings. */
+ AR_WRITE(sc, AR_MIC_QOS_CONTROL, 0x100aa);
+ AR_WRITE(sc, AR_MIC_QOS_SELECT, 0x3210);
+ AR_WRITE(sc, AR_QOS_NO_ACK,
+ SM(AR_QOS_NO_ACK_TWO_BIT, 2) |
+ SM(AR_QOS_NO_ACK_BIT_OFF, 5) |
+ SM(AR_QOS_NO_ACK_BYTE_OFF, 0));
+ AR_WRITE(sc, AR_TXOP_X, AR_TXOP_X_VAL);
+ /* Initialize TXOP for all TIDs. */
+ AR_WRITE(sc, AR_TXOP_0_3, 0xffffffff);
+ AR_WRITE(sc, AR_TXOP_4_7, 0xffffffff);
+ AR_WRITE(sc, AR_TXOP_8_11, 0xffffffff);
+ AR_WRITE(sc, AR_TXOP_12_15, 0xffffffff);
+ AR_WRITE_BARRIER(sc);
+}
+
+int
+athn_hw_reset(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc, int init)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct athn_ops *ops = &sc->ops;
+ uint32_t reg, def_ant, sta_id1, cfg_led, tsflo, tsfhi;
+ int i, error;
+
+ printf("working through %s\n", __func__);
+
+ /* XXX not if already awake */
+ if ((error = athn_set_power_awake(sc)) != 0) {
+ printf("%s: could not wakeup chip\n", ic->ic_name);
+ return (error);
+ }
+
+ /* Preserve the antenna on a channel switch. */
+ if ((def_ant = AR_READ(sc, AR_DEF_ANTENNA)) == 0)
+ def_ant = 1;
+ /* Preserve other registers. */
+ sta_id1 = AR_READ(sc, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
+ cfg_led = AR_READ(sc, AR_CFG_LED) & (AR_CFG_LED_ASSOC_CTL_M |
+ AR_CFG_LED_MODE_SEL_M | AR_CFG_LED_BLINK_THRESH_SEL_M |
+ AR_CFG_LED_BLINK_SLOW);
+
+ /* Mark PHY as inactive. */
+ ops->disable_phy(sc);
+
+ if (init && AR_SREV_9271(sc)) {
+ AR_WRITE(sc, AR9271_RESET_POWER_DOWN_CONTROL,
+ AR9271_RADIO_RF_RST);
+ DELAY(50);
+ }
+ if (AR_SREV_9280(sc) && (sc->flags & ATHN_FLAG_OLPC)) {
+ /* Save TSF before it gets cleared. */
+ tsfhi = AR_READ(sc, AR_TSF_U32);
+ tsflo = AR_READ(sc, AR_TSF_L32);
+
+ /* NB: RTC reset clears TSF. */
+ error = athn_reset_power_on(sc);
+ } else
+ error = athn_reset(sc, 0);
+ if (error != 0) {
+ printf("%s: could not reset chip (error=%d)\n",
+ ic->ic_name, error);
+ return (error);
+ }
+
+ /* XXX not if already awake */
+ if ((error = athn_set_power_awake(sc)) != 0) {
+ printf("%s: could not wakeup chip\n", ic->ic_name);
+ return (error);
+ }
+
+ athn_init_pll(sc, c);
+
+ ops->set_rf_mode(sc, c);
+
+ printf("A quick check: %p\n", ops->set_rf_mode);
+
+ if (sc->flags & ATHN_FLAG_RFSILENT) {
+ /* Check that the radio is not disabled by hardware switch. */
+ reg = ops->gpio_read(sc, sc->rfsilent_pin);
+ if (sc->flags & ATHN_FLAG_RFSILENT_REVERSED)
+ reg = !reg;
+ if (!reg) {
+ printf("%s: radio is disabled by hardware switch\n",
+ ic->ic_name);
+ return (EPERM);
+ }
+ }
+
+ if (init && AR_SREV_9271(sc)) {
+ AR_WRITE(sc, AR9271_RESET_POWER_DOWN_CONTROL,
+ AR9271_GATE_MAC_CTL);
+ DELAY(50);
+ }
+ if (AR_SREV_9280(sc) && (sc->flags & ATHN_FLAG_OLPC)) {
+ /* Restore TSF if it got cleared. */
+ AR_WRITE(sc, AR_TSF_L32, tsflo);
+ AR_WRITE(sc, AR_TSF_U32, tsfhi);
+ }
+
+ if (AR_SREV_9280_10_OR_LATER(sc))
+ AR_SETBITS(sc, sc->gpio_input_en_off, AR_GPIO_JTAG_DISABLE);
+
+ if (AR_SREV_9287_13_OR_LATER(sc) && !AR_SREV_9380_10_OR_LATER(sc))
+ ar9287_1_3_enable_async_fifo(sc);
+
+ /* Write init values to hardware. */
+ ops->hw_init(sc, c, extc);
+
+ /*
+ * Only >=AR9280 2.0 parts are capable of encrypting unicast
+ * management frames using CCMP.
+ */
+ if (AR_SREV_9280_20_OR_LATER(sc)) {
+ reg = AR_READ(sc, AR_AES_MUTE_MASK1);
+ /* Do not mask the subtype field in management frames. */
+ reg = RW(reg, AR_AES_MUTE_MASK1_FC0_MGMT, 0xff);
+ reg = RW(reg, AR_AES_MUTE_MASK1_FC1_MGMT,
+ ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT |
+ IEEE80211_FC1_MORE_DATA));
+ AR_WRITE(sc, AR_AES_MUTE_MASK1, reg);
+ } else if (AR_SREV_9160_10_OR_LATER(sc)) {
+ /* Disable hardware crypto for management frames. */
+ AR_CLRBITS(sc, AR_PCU_MISC_MODE2,
+ AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
+ AR_SETBITS(sc, AR_PCU_MISC_MODE2,
+ AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
+ }
+
+ if (ic->ic_curmode != IEEE80211_MODE_11B)
+ ops->set_delta_slope(sc, c, extc);
+
+ ops->spur_mitigate(sc, c, extc);
+ ops->init_from_rom(sc, c, extc);
+
+ /* XXX */
+ AR_WRITE(sc, AR_STA_ID0, LE_READ_4(&ic->ic_macaddr[0]));
+ AR_WRITE(sc, AR_STA_ID1, LE_READ_2(&ic->ic_macaddr[4]) |
+ sta_id1 | AR_STA_ID1_RTS_USE_DEF | AR_STA_ID1_CRPT_MIC_ENABLE);
+
+ athn_set_opmode(sc);
+
+ AR_WRITE(sc, AR_BSSMSKL, 0xffffffff);
+ AR_WRITE(sc, AR_BSSMSKU, 0xffff);
+
+ /* Restore previous antenna. */
+ AR_WRITE(sc, AR_DEF_ANTENNA, def_ant);
+
+ AR_WRITE(sc, AR_BSS_ID0, 0);
+ AR_WRITE(sc, AR_BSS_ID1, 0);
+
+ AR_WRITE(sc, AR_ISR, 0xffffffff);
+
+ AR_WRITE(sc, AR_RSSI_THR, SM(AR_RSSI_THR_BM_THR, 7));
+
+ if ((error = ops->set_synth(sc, c, extc)) != 0) {
+ printf("%s: could not set channel\n", ic->ic_name);
+ return (error);
+ }
+// sc->curchan = c;
+ ic->ic_curchan = c;
+ sc->curchanext = extc;
+
+ for (i = 0; i < AR_NUM_DCU; i++)
+ AR_WRITE(sc, AR_DQCUMASK(i), 1 << i);
+
+ athn_init_tx_queues(sc);
+
+ /* Initialize interrupt mask. */
+ sc->imask =
+ AR_IMR_TXDESC | AR_IMR_TXEOL |
+ AR_IMR_RXERR | AR_IMR_RXEOL | AR_IMR_RXORN |
+ AR_IMR_RXMINTR | AR_IMR_RXINTM |
+ AR_IMR_GENTMR | AR_IMR_BCNMISC;
+ if (AR_SREV_9380_10_OR_LATER(sc))
+ sc->imask |= AR_IMR_RXERR | AR_IMR_HP_RXOK;
+#ifndef IEEE80211_STA_ONLY
+ if (0 && ic->ic_opmode == IEEE80211_M_HOSTAP)
+ sc->imask |= AR_IMR_MIB;
+#endif
+ AR_WRITE(sc, AR_IMR, sc->imask);
+ AR_SETBITS(sc, AR_IMR_S2, AR_IMR_S2_GTT);
+ AR_WRITE(sc, AR_INTR_SYNC_CAUSE, 0xffffffff);
+ sc->isync = AR_INTR_SYNC_DEFAULT;
+ if (sc->flags & ATHN_FLAG_RFSILENT)
+ sc->isync |= AR_INTR_SYNC_GPIO_PIN(sc->rfsilent_pin);
+ AR_WRITE(sc, AR_INTR_SYNC_ENABLE, sc->isync);
+ AR_WRITE(sc, AR_INTR_SYNC_MASK, 0);
+ if (AR_SREV_9380_10_OR_LATER(sc)) {
+ AR_WRITE(sc, AR_INTR_PRIO_ASYNC_ENABLE, 0);
+ AR_WRITE(sc, AR_INTR_PRIO_ASYNC_MASK, 0);
+ AR_WRITE(sc, AR_INTR_PRIO_SYNC_ENABLE, 0);
+ AR_WRITE(sc, AR_INTR_PRIO_SYNC_MASK, 0);
+ }
+
+
+ athn_init_qos(sc);
+
+ AR_SETBITS(sc, AR_PCU_MISC, AR_PCU_MIC_NEW_LOC_ENA);
+
+ athn_setsifs(sc);
+ athn_updateslot(ic);
+ athn_setclockrate(sc);
+ if (AR_SREV_9287_13_OR_LATER(sc) && !AR_SREV_9380_10_OR_LATER(sc)) {
+ printf("Review ar9287_1_3_setup_async_fifo\n");
+ ar9287_1_3_setup_async_fifo(sc);
+ }
+
+ printf("%s not done, so ending early here\n", __func__);
+ return -1;
+ /* Disable sequence number generation in hardware. */
+ AR_SETBITS(sc, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
+
+ athn_init_dma(sc);
+
+ /* Program observation bus to see MAC interrupts. */
+ AR_WRITE(sc, sc->obs_off, 8);
+
+ /* Setup Rx interrupt mitigation. */
+ AR_WRITE(sc, AR_RIMT, SM(AR_RIMT_FIRST, 2000) | SM(AR_RIMT_LAST, 500));
+
+ /* Setup Tx interrupt mitigation. */
+ AR_WRITE(sc, AR_TIMT, SM(AR_TIMT_FIRST, 2000) | SM(AR_TIMT_LAST, 500));
+
+ /* Set maximum interrupt rate threshold (in micro seconds). */
+ AR_WRITE(sc, AR_MIRT, SM(AR_MIRT_RATE_THRES, 2000));
+
+ ops->init_baseband(sc);
+
+ if ((error = athn_init_calib(sc, c, extc)) != 0) {
+ printf("%s: could not initialize calibration\n",
+ ic->ic_name);
+ return (error);
+ }
+
+ ops->set_rxchains(sc);
+
+ AR_WRITE(sc, AR_CFG_LED, cfg_led | AR_CFG_SCLK_32KHZ);
+
+ if (sc->flags & ATHN_FLAG_USB) {
+ if (AR_SREV_9271(sc))
+ AR_WRITE(sc, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB);
+ else
+ AR_WRITE(sc, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
+ }
+#if BYTE_ORDER == BIG_ENDIAN
+ else {
+ /* Default is LE, turn on swapping for BE. */
+ AR_WRITE(sc, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
+ }
+#endif
+ AR_WRITE_BARRIER(sc);
+
+ return (0);
+}
+
+static struct ieee80211_node *
+athn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+ printf("This function should be over-written: %s unimplemented...\n", __func__);
+ return (NULL);
+#if 0
+// printf("%s unimplemented...\n", __func__);
+// return NULL;
+//#if 0
+ printf("Compare this function against other ic_node_alloc implementations...\n");
+ struct athn_node *an;
+
+ an = malloc(sizeof(struct athn_node), M_80211_NODE, M_NOWAIT | M_ZERO);
+ if (an == NULL)
+ return NULL;
+
+// if (an && (ic->ic_htcaps & IEEE80211_HTC_HT))
+// ieee80211_ra_node_init(&an->rn);
+ return (struct ieee80211_node *)an;
+#endif
+}
+
+void
+athn_newassoc(struct ieee80211_node *ni, int isnew)
+{
+#if 0
+ printf("%s unimplemented...\n", __func__);
+ struct athn_node *an = ((struct athn_node *)(ni));
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct athn_softc *sc = vap->iv_ic->ic_softc;
+ struct athn_softc *sc = ic->ic_softc;
+ struct athn_node *an = (void *)ni;
+ struct ieee80211_rateset *rs = &ni->ni_rates;
+ uint8_t rate;
+ int ridx, i, j;
+
+ if ((ni->ni_flags & IEEE80211_NODE_HT) == 0)
+ ieee80211_amrr_node_init(&sc->amrr, &an->amn);
+ else if (ic->ic_opmode == IEEE80211_M_STA)
+ ieee80211_ra_node_init(&an->rn);
+
+ /* Start at lowest available bit-rate, AMRR will raise. */
+ ni->ni_txrate = 0;
+
+ for (i = 0; i < rs->rs_nrates; i++) {
+ rate = rs->rs_rates[i] & IEEE80211_RATE_VAL;
+
+ /* Map 802.11 rate to HW rate index. */
+ for (ridx = 0; ridx <= ATHN_RIDX_MAX; ridx++)
+ if (athn_rates[ridx].rate == rate)
+ break;
+ an->ridx[i] = ridx;
+ DPRINTFN(2, ("rate %d index %d\n", rate, ridx));
+
+ /* Compute fallback rate for retries. */
+ an->fallback[i] = i;
+ for (j = i - 1; j >= 0; j--) {
+ if (athn_rates[an->ridx[j]].phy ==
+ athn_rates[an->ridx[i]].phy) {
+ an->fallback[i] = j;
+ break;
+ }
+ }
+ DPRINTFN(2, ("%d fallbacks to %d\n", i, an->fallback[i]));
+ }
+
+ /* In 11n mode, start at lowest available bit-rate, MiRA will raise. */
+ ni->ni_txmcs = 0;
+
+ for (i = 0; i <= ATHN_MCS_MAX; i++) {
+ /* Map MCS index to HW rate index. */
+ ridx = ATHN_NUM_LEGACY_RATES + i;
+ an->ridx[ridx] = ATHN_RIDX_MCS0 + i;
+
+ DPRINTFN(2, ("mcs %d index %d ", i, ridx));
+ /* Compute fallback rate for retries. */
+ if (i == 0 || i == 8) {
+ /* MCS 0 and 8 fall back to the lowest legacy rate. */
+ if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan))
+ an->fallback[ridx] = ATHN_RIDX_OFDM6;
+ else
+ an->fallback[ridx] = ATHN_RIDX_CCK1;
+ } else {
+ /* Other MCS fall back to next supported lower MCS. */
+ an->fallback[ridx] = ATHN_NUM_LEGACY_RATES + i;
+ for (j = i - 1; j >= 0; j--) {
+ if (!isset(ni->ni_rxmcs, j))
+ continue;
+ an->fallback[ridx] = ATHN_NUM_LEGACY_RATES + j;
+ break;
+ }
+ }
+ DPRINTFN(2, (" fallback to %d\n", an->fallback[ridx]));
+ }
+#endif
+}
+
+int
+athn_media_change(struct ifnet *ifp)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 0;
+#if 0
+ struct athn_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint8_t rate, ridx;
+ int error;
+
+ error = ieee80211_media_change(ifp);
+ if (error != ENETRESET)
+ return (error);
+
+ if (ic->ic_fixed_rate != -1) {
+ rate = ic->ic_sup_rates[ic->ic_curmode].
+ rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
+ /* Map 802.11 rate to HW rate index. */
+ for (ridx = 0; ridx <= ATHN_RIDX_MAX; ridx++)
+ if (athn_rates[ridx].rate == rate)
+ break;
+ sc->fixed_ridx = ridx;
+ }
+ if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
+ (IFF_UP | IFF_RUNNING)) {
+ athn_stop(ifp, 0);
+ error = athn_init(ifp);
+ }
+ return (error);
+#endif
+}
+
+void
+athn_next_scan(void *arg)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_softc *sc = arg;
+ struct ieee80211com *ic = &sc->sc_ic;
+ int s;
+
+ s = splnet();
+ if (ic->ic_state == IEEE80211_S_SCAN)
+ ieee80211_next_scan(&ic->ic_if);
+ splx(s);
+#endif
+}
+
+int
+athn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
+{
+ printf("------------------------WHY IS THIS BREAKING!!!!\n");
+ printf("Not Finished: %s\n", __func__);
+ //struct ifnet *ifp = &ic->ic_if;
+ struct ieee80211com *ic = vap->iv_ic;
+ struct athn_softc *sc = ic->ic_softc;
+ uint32_t reg;
+ int error;
+
+// timeout_del(&sc->calib_to);
+ callout_stop(&sc->calib_to);
+
+ switch (nstate) {
+ case IEEE80211_S_INIT:
+ DEBUG_PRINTF("Mode: IEEE80211_S_INIT\n");
+ athn_set_led(sc, 0);
+ break;
+ case IEEE80211_S_SCAN:
+ DEBUG_PRINTF("Mode: IEEE80211_S_SCAN\n");
+ /* Make the LED blink while scanning. */
+ athn_set_led(sc, !sc->led_state);
+ error = athn_switch_chan(sc, vap->iv_bss->ni_chan, NULL);
+ if (error != 0)
+ return (error);
+ DEBUG_PRINTF("New state needs to fix scan_to time\n");
+ //timeout_add_msec(&sc->scan_to, 200);
+ break;
+ case IEEE80211_S_AUTH:
+ DEBUG_PRINTF("Mode: IEEE80211_S_AUTH\n");
+ athn_set_led(sc, 0);
+ error = athn_switch_chan(sc, vap->iv_bss->ni_chan, NULL);
+ if (error != 0)
+ return (error);
+ break;
+ case IEEE80211_S_ASSOC:
+ DEBUG_PRINTF("Mode: IEEE80211_S_ASSOC\n");
+ break;
+ case IEEE80211_S_RUN:
+ DEBUG_PRINTF("Mode: IEEE80211_S_RUN\n");
+ athn_set_led(sc, 1);
+//#ifndef IEEE80211_STA_ONLY
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+ error = athn_switch_chan(sc, vap->iv_bss->ni_chan, NULL);
+ if (error != 0)
+ return (error);
+ } else
+//#endif
+ if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+ error = athn_switch_chan(sc, ic->ic_bsschan, NULL);
+ if (error != 0)
+ return (error);
+ break;
+ }
+
+ /* Fake a join to initialize the Tx rate. */
+ athn_newassoc(vap->iv_bss, 1);
+
+ athn_set_bss(sc, vap->iv_bss);
+ athn_disable_interrupts(sc);
+//#ifndef IEEE80211_STA_ONLY
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+ athn_set_hostap_timers(sc);
+ /* Enable software beacon alert interrupts. */
+ sc->imask |= AR_IMR_SWBA;
+ } else
+//#endif
+ {
+ athn_set_sta_timers(sc);
+ /* Enable beacon miss interrupts. */
+ sc->imask |= AR_IMR_BMISS;
+
+ /* Stop receiving beacons from other BSS. */
+ reg = AR_READ(sc, AR_RX_FILTER);
+ reg = (reg & ~AR_RX_FILTER_BEACON) |
+ AR_RX_FILTER_MYBEACON;
+ AR_WRITE(sc, AR_RX_FILTER, reg);
+ AR_WRITE_BARRIER(sc);
+ }
+ athn_enable_interrupts(sc);
+
+ if (sc->sup_calib_mask != 0) {
+ memset(&sc->calib, 0, sizeof(sc->calib));
+ sc->cur_calib_mask = sc->sup_calib_mask;
+ sc->ops.do_calib(sc);
+ }
+ /* XXX Start ANI. */
+
+ athn_start_noisefloor_calib(sc, 1);
+ //timeout_add_msec(&sc->calib_to, 500);
+ break;
+ case IEEE80211_S_CAC:
+ case IEEE80211_S_CSA:
+ case IEEE80211_S_SLEEP:
+ default:
+ DEBUG_PRINTF("default case\n");
+ break;
+ }
+
+ return (sc->sc_newstate(ic, nstate, arg));
+}
+
+void
+athn_updateedca(struct ieee80211com *ic)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+#define ATHN_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */
+ struct athn_softc *sc = ic->ic_softc;
+ const struct ieee80211_edca_ac_params *ac;
+ int aci, qid;
+
+ for (aci = 0; aci < EDCA_NUM_AC; aci++) {
+ ac = &ic->ic_edca_ac[aci];
+ qid = athn_ac2qid[aci];
+
+ AR_WRITE(sc, AR_DLCL_IFS(qid),
+ SM(AR_D_LCL_IFS_CWMIN, ATHN_EXP2(ac->ac_ecwmin)) |
+ SM(AR_D_LCL_IFS_CWMAX, ATHN_EXP2(ac->ac_ecwmax)) |
+ SM(AR_D_LCL_IFS_AIFS, ac->ac_aifsn));
+ if (ac->ac_txoplimit != 0) {
+ AR_WRITE(sc, AR_DCHNTIME(qid),
+ SM(AR_D_CHNTIME_DUR,
+ IEEE80211_TXOP_TO_US(ac->ac_txoplimit)) |
+ AR_D_CHNTIME_EN);
+ } else
+ AR_WRITE(sc, AR_DCHNTIME(qid), 0);
+ }
+ AR_WRITE_BARRIER(sc);
+#undef ATHN_EXP2
+#endif // FreeBSD addition
+}
+
+int
+athn_clock_rate(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 0;
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ int clockrate; /* MHz. */
+
+ /*
+ * AR9287 v1.3+ MAC runs at 117MHz (instead of 88/44MHz) when
+ * ASYNC FIFO is enabled.
+ */
+ if (AR_SREV_9287_13_OR_LATER(sc) && !AR_SREV_9380_10_OR_LATER(sc))
+ clockrate = 117;
+ else if (ic->ic_bss->ni_chan != IEEE80211_CHAN_ANYC &&
+ IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) {
+ if (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)
+ clockrate = AR_CLOCK_RATE_FAST_5GHZ_OFDM;
+ else
+ clockrate = AR_CLOCK_RATE_5GHZ_OFDM;
+ } else if (ic->ic_curmode == IEEE80211_MODE_11B) {
+ clockrate = AR_CLOCK_RATE_CCK;
+ } else
+ clockrate = AR_CLOCK_RATE_2GHZ_OFDM;
+ if (sc->curchanext != NULL)
+ clockrate *= 2;
+
+ return (clockrate);
+#endif
+}
+
+int
+athn_chan_sifs(struct ieee80211_channel *c)
+{
+ return IEEE80211_IS_CHAN_2GHZ(c) ? IEEE80211_DUR_DS_SIFS : 16;
+}
+
+void
+athn_setsifs(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ int sifs = athn_chan_sifs(sc->sc_ic.ic_bss->ni_chan);
+ AR_WRITE(sc, AR_D_GBL_IFS_SIFS, (sifs - 2) * athn_clock_rate(sc));
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+int
+athn_acktimeout(struct ieee80211_channel *c, int slot)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 0;
+#if 0
+ int sifs = athn_chan_sifs(c);
+ int ackto = sifs + slot;
+
+ /* Workaround for early ACK timeouts. */
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ ackto += 64 - sifs - slot;
+
+ return ackto;
+#endif
+}
+
+void
+athn_setacktimeout(struct athn_softc *sc, struct ieee80211_channel *c, int slot)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ int ackto = athn_acktimeout(c, slot);
+ uint32_t reg = AR_READ(sc, AR_TIME_OUT);
+ reg = RW(reg, AR_TIME_OUT_ACK, ackto * athn_clock_rate(sc));
+ AR_WRITE(sc, AR_TIME_OUT, reg);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+athn_setctstimeout(struct athn_softc *sc, struct ieee80211_channel *c, int slot)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ int ctsto = athn_acktimeout(c, slot);
+ int sifs = athn_chan_sifs(c);
+ uint32_t reg = AR_READ(sc, AR_TIME_OUT);
+
+ /* Workaround for early CTS timeouts. */
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ ctsto += 48 - sifs - slot;
+
+ reg = RW(reg, AR_TIME_OUT_CTS, ctsto * athn_clock_rate(sc));
+ AR_WRITE(sc, AR_TIME_OUT, reg);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+athn_setclockrate(struct athn_softc *sc)
+{
+ int clockrate = athn_clock_rate(sc);
+ uint32_t reg = AR_READ(sc, AR_USEC);
+ reg = RW(reg, AR_USEC_USEC, clockrate - 1);
+ AR_WRITE(sc, AR_USEC, reg);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+athn_updateslot(struct ieee80211com *ic)
+{
+ printf("This should be overwritten: %s unimplemented...\n", __func__);
+#if 0
+ struct athn_softc *sc = ic->ic_softc;
+ int slot;
+
+ slot = (ic->ic_flags & IEEE80211_F_SHSLOT) ?
+ IEEE80211_DUR_DS_SHSLOT : IEEE80211_DUR_DS_SLOT;
+ AR_WRITE(sc, AR_D_GBL_IFS_SLOT, slot * athn_clock_rate(sc));
+ AR_WRITE_BARRIER(sc);
+
+ athn_setacktimeout(sc, ic->ic_bss->ni_chan, slot);
+ athn_setctstimeout(sc, ic->ic_bss->ni_chan, slot);
+#endif
+}
+
+void
+athn_start(struct ifnet *ifp)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_node *ni;
+ struct mbuf *m;
+
+ if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
+ return;
+
+ for (;;) {
+ if (SIMPLEQ_EMPTY(&sc->txbufs)) {
+ ifq_set_oactive(&ifp->if_snd);
+ break;
+ }
+ /* Send pending management frames first. */
+ m = mq_dequeue(&ic->ic_mgtq);
+ if (m != NULL) {
+ ni = m->m_pkthdr.ph_cookie;
+ goto sendit;
+ }
+ if (ic->ic_state != IEEE80211_S_RUN)
+ break;
+
+ m = mq_dequeue(&ic->ic_pwrsaveq);
+ if (m != NULL) {
+ ni = m->m_pkthdr.ph_cookie;
+ goto sendit;
+ }
+ if (ic->ic_state != IEEE80211_S_RUN)
+ break;
+
+ /* Encapsulate and send data frames. */
+ m = ifq_dequeue(&ifp->if_snd);
+ if (m == NULL)
+ break;
+#if NBPFILTER > 0
+ if (ifp->if_bpf != NULL)
+ bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
+#endif
+ if ((m = ieee80211_encap(ifp, m, &ni)) == NULL)
+ continue;
+ sendit:
+#if NBPFILTER > 0
+ if (ic->ic_rawbpf != NULL)
+ bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
+#endif
+ if (sc->ops.tx(sc, m, ni, 0) != 0) {
+ ieee80211_release_node(ic, ni);
+ ifp->if_oerrors++;
+ continue;
+ }
+
+ sc->sc_tx_timer = 5;
+ ifp->if_timer = 1;
+ }
+#endif
+}
+
+void
+athn_watchdog(struct ifnet *ifp)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_softc *sc = ifp->if_softc;
+
+ ifp->if_timer = 0;
+
+ if (sc->sc_tx_timer > 0) {
+ if (--sc->sc_tx_timer == 0) {
+ printf("%s: device timeout\n", sc->sc_dev.dv_xname);
+ athn_stop(ifp, 1);
+ (void)athn_init(ifp);
+ ifp->if_oerrors++;
+ return;
+ }
+ ifp->if_timer = 1;
+ }
+
+ ieee80211_watchdog(ifp);
+#endif
+}
+
+void
+athn_set_multi(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct arpcom *ac = &sc->sc_ic.ic_ac;
+ struct ifnet *ifp = &ac->ac_if;
+ struct ether_multi *enm;
+ struct ether_multistep step;
+ const uint8_t *addr;
+ uint32_t val, lo, hi;
+ uint8_t bit;
+
+ if (ac->ac_multirangecnt > 0)
+ ifp->if_flags |= IFF_ALLMULTI;
+
+ if ((ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
+ lo = hi = 0xffffffff;
+ goto done;
+ }
+ lo = hi = 0;
+ ETHER_FIRST_MULTI(step, ac, enm);
+ while (enm != NULL) {
+ addr = enm->enm_addrlo;
+ /* Calculate the XOR value of all eight 6-bit words. */
+ val = addr[0] | addr[1] << 8 | addr[2] << 16;
+ bit = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+ val = addr[3] | addr[4] << 8 | addr[5] << 16;
+ bit ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+ bit &= 0x3f;
+ if (bit < 32)
+ lo |= 1 << bit;
+ else
+ hi |= 1 << (bit - 32);
+ ETHER_NEXT_MULTI(step, enm);
+ }
+ done:
+ AR_WRITE(sc, AR_MCAST_FIL0, lo);
+ AR_WRITE(sc, AR_MCAST_FIL1, hi);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+int
+athn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ printf("%s unimplemented...\n", __func__);
+ return 0;
+#if 0
+ struct athn_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifreq *ifr;
+ int s, error = 0;
+
+ s = splnet();
+
+ switch (cmd) {
+ case SIOCSIFADDR:
+ ifp->if_flags |= IFF_UP;
+ /* FALLTHROUGH */
+ case SIOCSIFFLAGS:
+ if (ifp->if_flags & IFF_UP) {
+ if ((ifp->if_flags & IFF_RUNNING) &&
+ ((ifp->if_flags ^ sc->sc_if_flags) &
+ (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
+ athn_set_multi(sc);
+ } else if (!(ifp->if_flags & IFF_RUNNING))
+ error = athn_init(ifp);
+ } else {
+ if (ifp->if_flags & IFF_RUNNING)
+ athn_stop(ifp, 1);
+ }
+ sc->sc_if_flags = ifp->if_flags;
+ break;
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ ifr = (struct ifreq *)data;
+ error = (cmd == SIOCADDMULTI) ?
+ ether_addmulti(ifr, &ic->ic_ac) :
+ ether_delmulti(ifr, &ic->ic_ac);
+ if (error == ENETRESET) {
+ athn_set_multi(sc);
+ error = 0;
+ }
+ break;
+
+ case SIOCS80211CHANNEL:
+ error = ieee80211_ioctl(ifp, cmd, data);
+ if (error == ENETRESET &&
+ ic->ic_opmode == IEEE80211_M_MONITOR) {
+ if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
+ (IFF_UP | IFF_RUNNING))
+ athn_switch_chan(sc, ic->ic_ibss_chan, NULL);
+ error = 0;
+ }
+ break;
+
+ default:
+ error = ieee80211_ioctl(ifp, cmd, data);
+ }
+
+ if (error == ENETRESET) {
+ error = 0;
+ if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
+ (IFF_UP | IFF_RUNNING)) {
+ athn_stop(ifp, 0);
+ error = athn_init(ifp);
+ }
+ }
+
+ splx(s);
+ return (error);
+#endif
+}
+
+int
+athn_init(struct athn_softc *sc)
+{
+ //struct athn_ops *ops = &sc->ops;
+ struct ieee80211com *ic = &sc->sc_ic;
+// struct ieee80211_channel *c, *extc;
+// struct ieee80211_channel *c;
+ int error = 0;
+
+ /* I am not 100% certain what the FreeBSD equivalent of this is */
+ //c = ic->ic_bss->ni_chan = ic->ic_bsschan;
+// c = ic->ic_bsschan;
+// extc = NULL;
+
+ /* In case a new MAC address has been configured. */
+printf("welcome to athn_init\n");
+ /* For CardBus, power on the socket. */
+ if (sc->sc_enable != NULL) {
+ printf("sc_enable not NULL\n");
+ if ((error = sc->sc_enable(sc)) != 0) {
+ printf("%s: could not enable device\n", ic->ic_name);
+ goto fail;
+ }
+ if ((error = athn_reset_power_on(sc)) != 0) {
+ printf("%s: could not power on device\n", ic->ic_name);
+ goto fail;
+ }
+ }
+ printf("done done\n");
+#if 0
+ if (!(sc->flags & ATHN_FLAG_PCIE))
+ athn_config_nonpcie(sc);
+ else
+ athn_config_pcie(sc);
+
+ ops->enable_antenna_diversity(sc);
+
+#ifdef ATHN_BT_COEXISTENCE
+ /* Configure bluetooth coexistence for combo chips. */
+ if (sc->flags & ATHN_FLAG_BTCOEX)
+ athn_btcoex_init(sc);
+#endif
+
+ /* Configure LED. */
+ athn_led_init(sc);
+
+ /* Configure hardware radio switch. */
+ if (sc->flags & ATHN_FLAG_RFSILENT)
+ ops->rfsilent_init(sc);
+
+ if ((error = athn_hw_reset(sc, c, extc, 1)) != 0) {
+ printf("%s: unable to reset hardware; reset status %d\n",
+ sc->sc_dev.dv_xname, error);
+ goto fail;
+ }
+
+ athn_config_ht(sc);
+
+ /* Enable Rx. */
+ athn_rx_start(sc);
+
+ /* Reset HW key cache entries. */
+ for (i = 0; i < sc->kc_entries; i++)
+ athn_reset_key(sc, i);
+
+ /* Enable interrupts. */
+ athn_enable_interrupts(sc);
+
+#ifdef ATHN_BT_COEXISTENCE
+ /* Enable bluetooth coexistence for combo chips. */
+ if (sc->flags & ATHN_FLAG_BTCOEX)
+ athn_btcoex_enable(sc);
+#endif
+
+ ifq_clr_oactive(&ifp->if_snd);
+ ifp->if_flags |= IFF_RUNNING;
+
+#ifdef notyet
+ if (ic->ic_flags & IEEE80211_F_WEPON) {
+ /* Configure WEP keys. */
+ for (i = 0; i < IEEE80211_WEP_NKID; i++)
+ athn_set_key(ic, NULL, &ic->ic_nw_keys[i]);
+ }
+#endif
+ if (ic->ic_opmode == IEEE80211_M_MONITOR)
+ ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+ else
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+
+ return (0);
+ fail:
+ athn_stop(ifp, 1);
+ athn_stop(ifp, 1);
+ return (error);
+#endif
+ fail:
+ return (error);
+}
+
+void
+athn_stop(void *arg)
+// struct ifnet *ifp, int disable)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct athn_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ int qid, i;
+
+ ifp->if_timer = sc->sc_tx_timer = 0;
+ ifp->if_flags &= ~IFF_RUNNING;
+ ifq_clr_oactive(&ifp->if_snd);
+
+ timeout_del(&sc->scan_to);
+
+ ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+
+#ifdef ATHN_BT_COEXISTENCE
+ /* Disable bluetooth coexistence for combo chips. */
+ if (sc->flags & ATHN_FLAG_BTCOEX)
+ athn_btcoex_disable(sc);
+#endif
+
+ /* Disable interrupts. */
+ athn_disable_interrupts(sc);
+ /* Acknowledge interrupts (avoids interrupt storms). */
+ AR_WRITE(sc, AR_INTR_SYNC_CAUSE, 0xffffffff);
+ AR_WRITE(sc, AR_INTR_SYNC_MASK, 0);
+
+ for (qid = 0; qid < ATHN_QID_COUNT; qid++)
+ athn_stop_tx_dma(sc, qid);
+ /* XXX call athn_hw_reset if Tx still pending? */
+ for (qid = 0; qid < ATHN_QID_COUNT; qid++)
+ athn_tx_reclaim(sc, qid);
+
+ /* Stop Rx. */
+ AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
+ AR_WRITE(sc, AR_MIBC, AR_MIBC_FMC);
+ AR_WRITE(sc, AR_MIBC, AR_MIBC_CMC);
+ AR_WRITE(sc, AR_FILT_OFDM, 0);
+ AR_WRITE(sc, AR_FILT_CCK, 0);
+ AR_WRITE_BARRIER(sc);
+ athn_set_rxfilter(sc, 0);
+ athn_stop_rx_dma(sc);
+
+ /* Reset HW key cache entries. */
+ for (i = 0; i < sc->kc_entries; i++)
+ athn_reset_key(sc, i);
+
+ athn_reset(sc, 0);
+ athn_init_pll(sc, NULL);
+ athn_set_power_awake(sc);
+ athn_reset(sc, 1);
+ athn_init_pll(sc, NULL);
+
+ athn_set_power_sleep(sc);
+
+ /* For CardBus, power down the socket. */
+ if (disable && sc->sc_disable != NULL)
+ sc->sc_disable(sc);
+#endif
+}
+
+static void
+athn_parent(struct ieee80211com *ic)
+{
+ struct athn_softc *sc = ic->ic_softc;
+ DEBUG_PRINTF("%s under implemented...\n", __func__);
+// int startall = 0;
+
+ // Some sort of detatched thingy
+// if (sc->sc_
+ printf("helkovmr\n");
+
+ if (ic->ic_nrunning > 0) {
+ DEBUG_PRINTF("Top condition\n");
+ if (sc->sc_init(sc) == 0) {
+// if (athn_usb_init(sc) == 0)
+ DEBUG_PRINTF("ieee80211_start_all\n");
+ ieee80211_start_all(ic);
+ }
+ else {
+ DEBUG_PRINTF("ieee80211_stop_all\n");
+ ieee80211_stop_all(ic);
+ }
+ } else {
+ athn_stop(sc);
+ }
+}
+
+
+void
+athn_suspend(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+ if (ifp->if_flags & IFF_RUNNING)
+ athn_stop(ifp, 1);
+#endif
+}
+
+void
+athn_wakeup(struct athn_softc *sc)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+ if (ifp->if_flags & IFF_UP)
+ athn_init(ifp);
+#endif
+}
+
+void
+athn_getradiocaps(struct ieee80211com *ic,
+ int maxchans, int *nchans, struct ieee80211_channel chans[])
+{
+// struct athn_softc *sc = ic->ic_softc;
+ uint8_t bands[IEEE80211_MODE_BYTES];
+
+ memset(bands, 0, sizeof(bands));
+ setbit(bands, IEEE80211_MODE_11B);
+ setbit(bands, IEEE80211_MODE_11G);
+ setbit(bands, IEEE80211_MODE_11NA);
+ setbit(bands, IEEE80211_MODE_11NG);
+
+ ieee80211_add_channels_default_2ghz(chans, maxchans, nchans,
+ bands, 0); //(ic->ic_htcaps & IEEE80211_HTCAP, CHWIDTH40) ?
+// NET80211_CBW_FLAG_HT40 : 0);
+}
+
+
+MODULE_VERSION(athn, 1);
+MODULE_DEPEND(athn, wlan, 1, 1, 1);
+MODULE_DEPEND(athn, firmware, 1, 1, 1);
diff --git a/sys/dev/athn/athnreg.h b/sys/dev/athn/athnreg.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/athnreg.h
@@ -0,0 +1,1505 @@
+/* $OpenBSD: athnreg.h,v 1.25 2020/04/28 06:58:09 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * MAC registers.
+ */
+
+#ifndef ATHNREG_H
+#define ATHNREG_H
+
+#define AR_CR 0x0008
+#define AR_RXDP 0x000c
+#define AR_CFG 0x0014
+#define AR_RXBP_THRESH 0x0018
+#define AR_MIRT 0x0020
+#define AR_IER 0x0024
+#define AR_TIMT 0x0028
+#define AR_RIMT 0x002c
+#define AR_TXCFG 0x0030
+#define AR_RXCFG 0x0034
+#define AR_MIBC 0x0040
+#define AR_TOPS 0x0044
+#define AR_RXNPTO 0x0048
+#define AR_TXNPTO 0x004c
+#define AR_RPGTO 0x0050
+#define AR_RPCNT 0x0054
+#define AR_MACMISC 0x0058
+#define AR_DATABUF_SIZE 0x0060
+#define AR_GTXTO 0x0064
+#define AR_GTTM 0x0068
+#define AR_CST 0x006c
+#define AR_HP_RXDP 0x0074
+#define AR_LP_RXDP 0x0078
+#define AR_ISR 0x0080
+#define AR_ISR_S0 0x0084
+#define AR_ISR_S1 0x0088
+#define AR_ISR_S2 0x008c
+#define AR_ISR_S3 0x0090
+#define AR_ISR_S4 0x0094
+#define AR_ISR_S5 0x0098
+#define AR_IMR 0x00a0
+#define AR_IMR_S0 0x00a4
+#define AR_IMR_S1 0x00a8
+#define AR_IMR_S2 0x00ac
+#define AR_IMR_S3 0x00b0
+#define AR_IMR_S4 0x00b4
+#define AR_IMR_S5 0x00b8
+#define AR_ISR_RAC 0x00c0
+#define AR_ISR_S0_S 0x00c4
+#define AR_ISR_S1_S 0x00c8
+#define AR_DMADBG(i) (0x00e0 + (i) * 4)
+#define AR_QTXDP(i) (0x0800 + (i) * 4)
+#define AR_Q_STATUS_RING_START 0x0830
+#define AR_Q_STATUS_RING_END 0x0834
+#define AR_Q_TXE 0x0840
+#define AR_Q_TXD 0x0880
+#define AR_QCBRCFG(i) (0x08c0 + (i) * 4)
+#define AR_QRDYTIMECFG(i) (0x0900 + (i) * 4)
+#define AR_Q_ONESHOTARM_SC 0x0940
+#define AR_Q_ONESHOTARM_CC 0x0980
+#define AR_QMISC(i) (0x09c0 + (i) * 4)
+#define AR_QSTS(i) (0x0a00 + (i) * 4)
+#define AR_Q_RDYTIMESHDN 0x0a40
+#define AR_Q_DESC_CRCCHK 0x0a44
+#define AR_DQCUMASK(i) (0x1000 + (i) * 4)
+#define AR_D_GBL_IFS_SIFS 0x1030
+#define AR_D_TXBLK_CMD 0x1038
+#define AR_DLCL_IFS(i) (0x1040 + (i) * 4)
+#define AR_D_GBL_IFS_SLOT 0x1070
+#define AR_DRETRY_LIMIT(i) (0x1080 + (i) * 4)
+#define AR_D_GBL_IFS_EIFS 0x10b0
+#define AR_DCHNTIME(i) (0x10c0 + (i) * 4)
+#define AR_D_GBL_IFS_MISC 0x10f0
+#define AR_DMISC(i) (0x1100 + (i) * 4)
+#define AR_D_SEQNUM 0x1140
+#define AR_D_FPCTL 0x1230
+#define AR_D_TXPSE 0x1270
+#define AR_D_TXSLOTMASK 0x12f0
+#define AR_MAC_SLEEP 0x1f00
+#define AR_CFG_LED 0x1f04
+#define AR_EEPROM_OFFSET(i) (0x2000 + (i) * 4)
+#define AR_RC 0x4000
+#define AR_WA 0x4004
+#define AR_PM_STATE 0x4008
+#define AR_PCIE_PM_CTRL 0x4014
+#define AR_HOST_TIMEOUT 0x4018
+#define AR_EEPROM 0x401c
+#define AR_SREV 0x4020
+#define AR_AHB_MODE 0x4024
+#define AR_INTR_SYNC_CAUSE 0x4028
+#define AR_INTR_SYNC_ENABLE 0x402c
+#define AR_INTR_ASYNC_MASK 0x4030
+#define AR_INTR_SYNC_MASK 0x4034
+#define AR_INTR_ASYNC_CAUSE 0x4038
+#define AR_INTR_ASYNC_ENABLE 0x403c
+#define AR_PCIE_SERDES 0x4040
+#define AR_PCIE_SERDES2 0x4044
+#define AR_INTR_PRIO_SYNC_ENABLE 0x40c4
+#define AR_INTR_PRIO_ASYNC_MASK 0x40c8
+#define AR_INTR_PRIO_SYNC_MASK 0x40cc
+#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
+#define AR_RTC_RC 0x7000
+#define AR_RTC_XTAL_CONTROL 0x7004
+#define AR_RTC_REG_CONTROL0 0x7008
+#define AR_RTC_REG_CONTROL1 0x700c
+#define AR_RTC_PLL_CONTROL 0x7014
+#define AR_RTC_PLL_CONTROL2 0x703c
+#define AR_RTC_RESET 0x7040
+#define AR_RTC_STATUS 0x7044
+#define AR_RTC_SLEEP_CLK 0x7048
+#define AR_RTC_FORCE_WAKE 0x704c
+#define AR_RTC_INTR_CAUSE 0x7050
+#define AR_RTC_INTR_ENABLE 0x7054
+#define AR_RTC_INTR_MASK 0x7058
+#define AR_STA_ID0 0x8000
+#define AR_STA_ID1 0x8004
+#define AR_BSS_ID0 0x8008
+#define AR_BSS_ID1 0x800c
+#define AR_BCN_RSSI_AVE 0x8010
+#define AR_TIME_OUT 0x8014
+#define AR_RSSI_THR 0x8018
+#define AR_USEC 0x801c
+#define AR_RESET_TSF 0x8020
+#define AR_MAX_CFP_DUR 0x8038
+#define AR_RX_FILTER 0x803c
+#define AR_MCAST_FIL0 0x8040
+#define AR_MCAST_FIL1 0x8044
+#define AR_DIAG_SW 0x8048
+#define AR_TSF_L32 0x804c
+#define AR_TSF_U32 0x8050
+#define AR_TST_ADDAC 0x8054
+#define AR_DEF_ANTENNA 0x8058
+#define AR_AES_MUTE_MASK0 0x805c
+#define AR_AES_MUTE_MASK1 0x8060
+#define AR_GATED_CLKS 0x8064
+#define AR_OBS_BUS_CTRL 0x8068
+#define AR_OBS_BUS_1 0x806c
+#define AR_LAST_TSTP 0x8080
+#define AR_NAV 0x8084
+#define AR_RTS_OK 0x8088
+#define AR_RTS_FAIL 0x808c
+#define AR_ACK_FAIL 0x8090
+#define AR_FCS_FAIL 0x8094
+#define AR_BEACON_CNT 0x8098
+#define AR_SLEEP1 0x80d4
+#define AR_SLEEP2 0x80d8
+#define AR_BSSMSKL 0x80e0
+#define AR_BSSMSKU 0x80e4
+#define AR_TPC 0x80e8
+#define AR_TFCNT 0x80ec
+#define AR_RFCNT 0x80f0
+#define AR_RCCNT 0x80f4
+#define AR_CCCNT 0x80f8
+#define AR_QUIET1 0x80fc
+#define AR_QUIET2 0x8100
+#define AR_TSF_PARM 0x8104
+#define AR_QOS_NO_ACK 0x8108
+#define AR_PHY_ERR 0x810c
+#define AR_RXFIFO_CFG 0x8114
+#define AR_MIC_QOS_CONTROL 0x8118
+#define AR_MIC_QOS_SELECT 0x811c
+#define AR_PCU_MISC 0x8120
+#define AR_FILT_OFDM 0x8124
+#define AR_FILT_CCK 0x8128
+#define AR_PHY_ERR_1 0x812c
+#define AR_PHY_ERR_MASK_1 0x8130
+#define AR_PHY_ERR_2 0x8134
+#define AR_PHY_ERR_MASK_2 0x8138
+#define AR_TSFOOR_THRESHOLD 0x813c
+#define AR_PHY_ERR_EIFS_MASK 0x8144
+#define AR_PHY_ERR_3 0x8168
+#define AR_PHY_ERR_MASK_3 0x816c
+#define AR_BT_COEX_MODE 0x8170
+#define AR_BT_COEX_WEIGHT 0x8174
+#define AR_BT_COEX_MODE2 0x817c
+#define AR_NEXT_NDP2_TIMER(i) (0x8180 + (i) * 4)
+#define AR_NDP2_PERIOD(i) (0x81a0 + (i) * 4)
+#define AR_NDP2_TIMER_MODE 0x81c0
+#define AR_TXSIFS 0x81d0
+#define AR_TXOP_X 0x81ec
+#define AR_TXOP_0_3 0x81f0
+#define AR_TXOP_4_7 0x81f4
+#define AR_TXOP_8_11 0x81f8
+#define AR_TXOP_12_15 0x81fc
+#define AR_GEN_TIMER(i) (0x8200 + (i) * 4)
+#define AR_NEXT_TBTT_TIMER AR_GEN_TIMER(0)
+#define AR_NEXT_DMA_BEACON_ALERT AR_GEN_TIMER(1)
+#define AR_NEXT_CFP AR_GEN_TIMER(2)
+#define AR_NEXT_HCF AR_GEN_TIMER(3)
+#define AR_NEXT_TIM AR_GEN_TIMER(4)
+#define AR_NEXT_DTIM AR_GEN_TIMER(5)
+#define AR_NEXT_QUIET_TIMER AR_GEN_TIMER(6)
+#define AR_NEXT_NDP_TIMER AR_GEN_TIMER(7)
+#define AR_BEACON_PERIOD AR_GEN_TIMER(8)
+#define AR_DMA_BEACON_PERIOD AR_GEN_TIMER(9)
+#define AR_SWBA_PERIOD AR_GEN_TIMER(10)
+#define AR_HCF_PERIOD AR_GEN_TIMER(11)
+#define AR_TIM_PERIOD AR_GEN_TIMER(12)
+#define AR_DTIM_PERIOD AR_GEN_TIMER(13)
+#define AR_QUIET_PERIOD AR_GEN_TIMER(14)
+#define AR_NDP_PERIOD AR_GEN_TIMER(15)
+#define AR_TIMER_MODE 0x8240
+#define AR_SLP32_MODE 0x8244
+#define AR_SLP32_WAKE 0x8248
+#define AR_SLP32_INC 0x824c
+#define AR_SLP_CNT 0x8250
+#define AR_SLP_CYCLE_CNT 0x8254
+#define AR_SLP_MIB_CTRL 0x8258
+#define AR_WOW_PATTERN_REG 0x825c
+#define AR_WOW_COUNT_REG 0x8260
+#define AR_MAC_PCU_LOGIC_ANALYZER 0x8264
+#define AR_WOW_BCN_EN_REG 0x8270
+#define AR_WOW_BCN_TIMO_REG 0x8274
+#define AR_WOW_KEEP_ALIVE_TIMO_REG 0x8278
+#define AR_WOW_KEEP_ALIVE_REG 0x827c
+#define AR_WOW_US_SCALAR_REG 0x8284
+#define AR_WOW_KEEP_ALIVE_DELAY_REG 0x8288
+#define AR_WOW_PATTERN_MATCH_REG 0x828c
+#define AR_WOW_PATTERN_OFF1_REG 0x8290
+#define AR_WOW_PATTERN_OFF2_REG 0x8294
+#define AR_WOW_EXACT_REG 0x829c
+#define AR_2040_MODE 0x8318
+#define AR_EXTRCCNT 0x8328
+#define AR_PCU_BA_BAR_CTRL 0x8330
+#define AR_SELFGEN_MASK 0x832c
+#define AR_PCU_TXBUF_CTRL 0x8340
+#define AR_PCU_MISC_MODE2 0x8344
+#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358
+#define AR_WOW_LENGTH1_REG 0x8360
+#define AR_WOW_LENGTH2_REG 0x8364
+#define AR_WOW_PATTERN_MATCH_LT_256B 0x8368
+#define AR_RATE_DURATION(i) (0x8700 + (i) * 4)
+#define AR_KEYTABLE(i) (0x8800 + (i) * 32)
+#define AR_KEYTABLE_KEY0(i) (AR_KEYTABLE(i) + 0)
+#define AR_KEYTABLE_KEY1(i) (AR_KEYTABLE(i) + 4)
+#define AR_KEYTABLE_KEY2(i) (AR_KEYTABLE(i) + 8)
+#define AR_KEYTABLE_KEY3(i) (AR_KEYTABLE(i) + 12)
+#define AR_KEYTABLE_KEY4(i) (AR_KEYTABLE(i) + 16)
+#define AR_KEYTABLE_TYPE(i) (AR_KEYTABLE(i) + 20)
+#define AR_KEYTABLE_MAC0(i) (AR_KEYTABLE(i) + 24)
+#define AR_KEYTABLE_MAC1(i) (AR_KEYTABLE(i) + 28)
+
+
+/* Bits for AR_CR. */
+#define AR_CR_RXE (AR_SREV_9380_20_OR_LATER(sc) ? 0x000c : 0x0004)
+#define AR_CR_RXD 0x00000020
+#define AR_CR_SWI 0x00000040
+
+/* Bits for AR_CFG. */
+#define AR_CFG_SWTD 0x00000001
+#define AR_CFG_SWTB 0x00000002
+#define AR_CFG_SWRD 0x00000004
+#define AR_CFG_SWRB 0x00000008
+#define AR_CFG_SWRG 0x00000010
+#define AR_CFG_AP_ADHOC_INDICATION 0x00000020
+#define AR_CFG_PHOK 0x00000100
+#define AR_CFG_EEBS 0x00000200
+#define AR_CFG_CLK_GATE_DIS 0x00000400
+#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_M 0x00060000
+#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17
+
+/* Bits for AR_RXBP_THRESH. */
+#define AR_RXBP_THRESH_HP_M 0x0000000f
+#define AR_RXBP_THRESH_HP_S 0
+#define AR_RXBP_THRESH_LP_M 0x00003f00
+#define AR_RXBP_THRESH_LP_S 8
+
+/* Bits for AR_IER. */
+#define AR_IER_ENABLE 0x00000001
+
+/* Bits for AR_MIRT. */
+#define AR_MIRT_RATE_THRES_M 0x0000ffff
+#define AR_MIRT_RATE_THRES_S 0
+
+/* Bits for AR_TIMT. */
+#define AR_TIMT_LAST_M 0x0000ffff
+#define AR_TIMT_LAST_S 0
+#define AR_TIMT_FIRST_M 0xffff0000
+#define AR_TIMT_FIRST_S 16
+
+/* Bits for AR_RIMT. */
+#define AR_RIMT_LAST_M 0x0000ffff
+#define AR_RIMT_LAST_S 0
+#define AR_RIMT_FIRST_M 0xffff0000
+#define AR_RIMT_FIRST_S 16
+
+/* Bits for AR_[TR]XCFG_DMASZ fields. */
+#define AR_DMASZ_4B 0
+#define AR_DMASZ_8B 1
+#define AR_DMASZ_16B 2
+#define AR_DMASZ_32B 3
+#define AR_DMASZ_64B 4
+#define AR_DMASZ_128B 5
+#define AR_DMASZ_256B 6
+#define AR_DMASZ_512B 7
+
+/* Bits for AR_TXCFG. */
+#define AR_TXCFG_DMASZ_M 0x00000007
+#define AR_TXCFG_DMASZ_S 0
+#define AR_TXCFG_FTRIG_M 0x000003f0
+#define AR_TXCFG_FTRIG_S 4
+#define AR_TXCFG_FTRIG_IMMED ( 0 / 64)
+#define AR_TXCFG_FTRIG_64B ( 64 / 64)
+#define AR_TXCFG_FTRIG_128B (128 / 64)
+#define AR_TXCFG_FTRIG_192B (192 / 64)
+#define AR_TXCFG_FTRIG_256B (256 / 64)
+#define AR_TXCFG_FTRIG_512B (512 / 64)
+#define AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY 0x00000800
+
+/* Bits for AR_RXCFG. */
+#define AR_RXCFG_DMASZ_M 0x00000007
+#define AR_RXCFG_DMASZ_S 0
+#define AR_RXCFG_CHIRP 0x00000008
+#define AR_RXCFG_ZLFDMA 0x00000010
+
+/* Bits for AR_MIBC. */
+#define AR_MIBC_COW 0x00000001
+#define AR_MIBC_FMC 0x00000002
+#define AR_MIBC_CMC 0x00000004
+#define AR_MIBC_MCS 0x00000008
+
+/* Bits for AR_TOPS. */
+#define AR_TOPS_MASK 0x0000ffff
+
+/* Bits for AR_RXNPTO. */
+#define AR_RXNPTO_MASK 0x000003ff
+
+/* Bits for AR_TXNPTO. */
+#define AR_TXNPTO_MASK 0x000003ff
+#define AR_TXNPTO_QCU_MASK 0x000ffc00
+
+/* Bits for AR_RPGTO. */
+#define AR_RPGTO_MASK 0x000003ff
+
+/* Bits for AR_RPCNT. */
+#define AR_RPCNT_MASK 0x0000001f
+
+/* Bits for AR_MACMISC. */
+#define AR_MACMISC_PCI_EXT_FORCE 0x00000010
+#define AR_MACMISC_DMA_OBS_M 0x000001e0
+#define AR_MACMISC_DMA_OBS_S 5
+#define AR_MACMISC_MISC_OBS_M 0x00000e00
+#define AR_MACMISC_MISC_OBS_S 9
+#define AR_MACMISC_MISC_OBS_BUS_LSB_M 0x00007000
+#define AR_MACMISC_MISC_OBS_BUS_LSB_S 12
+#define AR_MACMISC_MISC_OBS_BUS_MSB_M 0x00038000
+#define AR_MACMISC_MISC_OBS_BUS_MSB_S 15
+
+/* Bits for AR_GTXTO. */
+#define AR_GTXTO_TIMEOUT_COUNTER_M 0x0000ffff
+#define AR_GTXTO_TIMEOUT_COUNTER_S 0
+#define AR_GTXTO_TIMEOUT_LIMIT_M 0xffff0000
+#define AR_GTXTO_TIMEOUT_LIMIT_S 16
+
+/* Bits for AR_GTTM. */
+#define AR_GTTM_USEC 0x00000001
+#define AR_GTTM_IGNORE_IDLE 0x00000002
+#define AR_GTTM_RESET_IDLE 0x00000004
+#define AR_GTTM_CST_USEC 0x00000008
+
+/* Bits for AR_CST. */
+#define AR_CST_TIMEOUT_COUNTER_M 0x0000ffff
+#define AR_CST_TIMEOUT_COUNTER_S 0
+#define AR_CST_TIMEOUT_LIMIT_M 0xffff0000
+#define AR_CST_TIMEOUT_LIMIT_S 16
+
+/* Bits for AR_ISR. */
+#define AR_ISR_RXOK 0x00000001
+#define AR_ISR_HP_RXOK 0x00000001
+#define AR_ISR_RXDESC 0x00000002
+#define AR_ISR_LP_RXOK 0x00000002
+#define AR_ISR_RXERR 0x00000004
+#define AR_ISR_RXNOPKT 0x00000008
+#define AR_ISR_RXEOL 0x00000010
+#define AR_ISR_RXORN 0x00000020
+#define AR_ISR_TXOK 0x00000040
+#define AR_ISR_TXDESC 0x00000080
+#define AR_ISR_TXERR 0x00000100
+#define AR_ISR_TXNOPKT 0x00000200
+#define AR_ISR_TXEOL 0x00000400
+#define AR_ISR_TXURN 0x00000800
+#define AR_ISR_MIB 0x00001000
+#define AR_ISR_SWI 0x00002000
+#define AR_ISR_RXPHY 0x00004000
+#define AR_ISR_RXKCM 0x00008000
+#define AR_ISR_SWBA 0x00010000
+#define AR_ISR_BRSSI 0x00020000
+#define AR_ISR_BMISS 0x00040000
+#define AR_ISR_TXMINTR 0x00080000
+#define AR_ISR_BNR 0x00100000
+#define AR_ISR_RXCHIRP 0x00200000
+#define AR_ISR_BCNMISC 0x00800000
+#define AR_ISR_TIM 0x00800000
+#define AR_ISR_RXMINTR 0x01000000
+#define AR_ISR_QCBROVF 0x02000000
+#define AR_ISR_QCBRURN 0x04000000
+#define AR_ISR_QTRIG 0x08000000
+#define AR_ISR_GENTMR 0x10000000
+#define AR_ISR_TXINTM 0x40000000
+#define AR_ISR_RXINTM 0x80000000
+
+/* Bits for AR_ISR_S0. */
+#define AR_ISR_S0_QCU_TXOK_M 0x000003ff
+#define AR_ISR_S0_QCU_TXOK_S 0
+#define AR_ISR_S0_QCU_TXDESC_M 0x03ff0000
+#define AR_ISR_S0_QCU_TXDESC_S 16
+
+/* Bits for AR_ISR_S1. */
+#define AR_ISR_S1_QCU_TXERR_M 0x000003ff
+#define AR_ISR_S1_QCU_TXERR_S 0
+#define AR_ISR_S1_QCU_TXEOL_M 0x03ff0000
+#define AR_ISR_S1_QCU_TXEOL_S 16
+
+/* Bits for AR_ISR_S2. */
+#define AR_ISR_S2_QCU_TXURN_M 0x000003ff
+#define AR_ISR_S2_QCU_TXURN_S 0
+#define AR_ISR_S2_BB_WATCHDOG 0x00010000
+#define AR_ISR_S2_CST 0x00400000
+#define AR_ISR_S2_GTT 0x00800000
+#define AR_ISR_S2_TIM 0x01000000
+#define AR_ISR_S2_CABEND 0x02000000
+#define AR_ISR_S2_DTIMSYNC 0x04000000
+#define AR_ISR_S2_BCNTO 0x08000000
+#define AR_ISR_S2_CABTO 0x10000000
+#define AR_ISR_S2_DTIM 0x20000000
+#define AR_ISR_S2_TSFOOR 0x40000000
+#define AR_ISR_S2_TBTT_TIME 0x80000000
+
+/* Bits for AR_ISR_S3. */
+#define AR_ISR_S3_QCU_QCBROVF_M 0x000003ff
+#define AR_ISR_S3_QCU_QCBROVF_S 0
+#define AR_ISR_S3_QCU_QCBRURN_M 0x03ff0000
+#define AR_ISR_S3_QCU_QCBRURN_S 0
+
+/* Bits for AR_ISR_S4. */
+#define AR_ISR_S4_QCU_QTRIG_M 0x000003ff
+#define AR_ISR_S4_QCU_QTRIG_S 0
+
+/* Bits for AR_ISR_S5. */
+#define AR_ISR_S5_TIMER_TRIG_M 0x000000ff
+#define AR_ISR_S5_TIMER_TRIG_S 0
+#define AR_ISR_S5_TIMER_THRESH_M 0x0007fe00
+#define AR_ISR_S5_TIMER_THRESH_S 9
+#define AR_ISR_S5_TIM_TIMER 0x00000010
+#define AR_ISR_S5_DTIM_TIMER 0x00000020
+#define AR_ISR_S5_GENTIMER_TRIG_M 0x0000ff80
+#define AR_ISR_S5_GENTIMER_TRIG_S 0
+#define AR_ISR_S5_GENTIMER_THRESH_M 0xff800000
+#define AR_ISR_S5_GENTIMER_THRESH_S 16
+
+/* Bits for AR_IMR. */
+#define AR_IMR_RXOK 0x00000001
+#define AR_IMR_HP_RXOK 0x00000001
+#define AR_IMR_RXDESC 0x00000002
+#define AR_IMR_LP_RXOK 0x00000002
+#define AR_IMR_RXERR 0x00000004
+#define AR_IMR_RXNOPKT 0x00000008
+#define AR_IMR_RXEOL 0x00000010
+#define AR_IMR_RXORN 0x00000020
+#define AR_IMR_TXOK 0x00000040
+#define AR_IMR_TXDESC 0x00000080
+#define AR_IMR_TXERR 0x00000100
+#define AR_IMR_TXNOPKT 0x00000200
+#define AR_IMR_TXEOL 0x00000400
+#define AR_IMR_TXURN 0x00000800
+#define AR_IMR_MIB 0x00001000
+#define AR_IMR_SWI 0x00002000
+#define AR_IMR_RXPHY 0x00004000
+#define AR_IMR_RXKCM 0x00008000
+#define AR_IMR_SWBA 0x00010000
+#define AR_IMR_BRSSI 0x00020000
+#define AR_IMR_BMISS 0x00040000
+#define AR_IMR_TXMINTR 0x00080000
+#define AR_IMR_BNR 0x00100000
+#define AR_IMR_RXCHIRP 0x00200000
+#define AR_IMR_BCNMISC 0x00800000
+#define AR_IMR_TIM 0x00800000
+#define AR_IMR_RXMINTR 0x01000000
+#define AR_IMR_QCBROVF 0x02000000
+#define AR_IMR_QCBRURN 0x04000000
+#define AR_IMR_QTRIG 0x08000000
+#define AR_IMR_GENTMR 0x10000000
+#define AR_IMR_TXINTM 0x40000000
+#define AR_IMR_RXINTM 0x80000000
+
+#define AR_IMR_DEFAULT \
+ (AR_IMR_TXERR | AR_IMR_TXURN | AR_IMR_RXERR | \
+ AR_IMR_RXORN | AR_IMR_BCNMISC | AR_IMR_RXINTM | \
+ AR_IMR_RXMINTR | AR_IMR_TXOK)
+#define AR_IMR_HOSTAP (AR_IMR_DEFAULT | AR_IMR_MIB)
+
+/* Bits for AR_IMR_S0. */
+#define AR_IMR_S0_QCU_TXOK(qid) (1 << (qid))
+#define AR_IMR_S0_QCU_TXDESC(qid) (1 << (16 + (qid)))
+
+/* Bits for AR_IMR_S1. */
+#define AR_IMR_S1_QCU_TXERR(qid) (1 << (qid))
+#define AR_IMR_S1_QCU_TXEOL(qid) (1 << (16 + (qid)))
+
+/* Bits for AR_IMR_S2. */
+#define AR_IMR_S2_QCU_TXURN(qid) (1 << (qid))
+#define AR_IMR_S2_CST 0x00400000
+#define AR_IMR_S2_GTT 0x00800000
+#define AR_IMR_S2_TIM 0x01000000
+#define AR_IMR_S2_CABEND 0x02000000
+#define AR_IMR_S2_DTIMSYNC 0x04000000
+#define AR_IMR_S2_BCNTO 0x08000000
+#define AR_IMR_S2_CABTO 0x10000000
+#define AR_IMR_S2_DTIM 0x20000000
+#define AR_IMR_S2_TSFOOR 0x40000000
+
+/* Bits for AR_IMR_S3. */
+#define AR_IMR_S3_QCU_QCBROVF(qid) (1 << (qid))
+#define AR_IMR_S3_QCU_QCBRURN(qid) (1 << (16 + (qid)))
+
+/* Bits for AR_IMR_S4. */
+#define AR_IMR_S4_QCU_QTRIG(qid) (1 << (qid))
+
+/* Bits for AR_IMR_S5. */
+#define AR_IMR_S5_TIM_TIMER 0x00000010
+#define AR_IMR_S5_DTIM_TIMER 0x00000020
+#define AR_IMR_S5_TIMER_TRIG_M 0x000000ff
+#define AR_IMR_S5_TIMER_TRIG_S 0
+#define AR_IMR_S5_TIMER_THRESH_M 0x0000ff00
+#define AR_IMR_S5_TIMER_THRESH_S 0
+
+#define AR_NUM_QCU 10
+#define AR_QCU(x) (1 << (x))
+
+/* Bits for AR_Q_TXE. */
+#define AR_Q_TXE_M 0x000003ff
+#define AR_Q_TXE_S 0
+
+/* Bits for AR_Q_TXD. */
+#define AR_Q_TXD_M 0x000003ff
+#define AR_Q_TXD_S 0
+
+/* Bits for AR_QCBRCFG_*. */
+#define AR_Q_CBRCFG_INTERVAL_M 0x00ffffff
+#define AR_Q_CBRCFG_INTERVAL_S 0
+#define AR_Q_CBRCFG_OVF_THRESH_M 0xff000000
+#define AR_Q_CBRCFG_OVF_THRESH_S 24
+
+/* Bits for AR_QRDYTIMECFG_*. */
+#define AR_Q_RDYTIMECFG_DURATION_M 0x00ffffff
+#define AR_Q_RDYTIMECFG_DURATION_S 0
+#define AR_Q_RDYTIMECFG_EN 0x01000000
+
+/* Bits for AR_QMISC_*. */
+#define AR_Q_MISC_FSP_M 0x0000000f
+#define AR_Q_MISC_FSP_S 0
+#define AR_Q_MISC_FSP_ASAP 0
+#define AR_Q_MISC_FSP_CBR 1
+#define AR_Q_MISC_FSP_DBA_GATED 2
+#define AR_Q_MISC_FSP_TIM_GATED 3
+#define AR_Q_MISC_FSP_BEACON_SENT_GATED 4
+#define AR_Q_MISC_FSP_BEACON_RCVD_GATED 5
+#define AR_Q_MISC_ONE_SHOT_EN 0x00000010
+#define AR_Q_MISC_CBR_INCR_DIS1 0x00000020
+#define AR_Q_MISC_CBR_INCR_DIS0 0x00000040
+#define AR_Q_MISC_BEACON_USE 0x00000080
+#define AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN 0x00000100
+#define AR_Q_MISC_RDYTIME_EXP_POLICY 0x00000200
+#define AR_Q_MISC_RESET_CBR_EXP_CTR 0x00000400
+#define AR_Q_MISC_DCU_EARLY_TERM_REQ 0x00000800
+
+/* Bits for AR_QSTS_*. */
+#define AR_Q_STS_PEND_FR_CNT_M 0x00000003
+#define AR_Q_STS_PEND_FR_CNT_S 0
+#define AR_Q_STS_CBR_EXP_CNT_M 0x0000ff00
+#define AR_Q_STS_CBR_EXP_CNT_S 8
+
+/* Bits for AR_Q_DESC_CRCCHK. */
+#define AR_Q_DESC_CRCCHK_EN 0x00000001
+
+#define AR_NUM_DCU 10
+#define AR_DCU(x) (1 << (x))
+
+/* Bits for AR_D_QCUMASK_*. */
+#define AR_D_QCUMASK_M 0x000003ff
+#define AR_D_QCUMASK_S 0
+
+/* Bits for AR_D_GBL_IFS_SIFS. */
+#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003ab
+
+/* Bits for AR_D_TXBLK_CMD. */
+#define AR_D_TXBLK_WRITE_BITMASK_M 0x0000ffff
+#define AR_D_TXBLK_WRITE_BITMASK_S 0
+#define AR_D_TXBLK_WRITE_SLICE_M 0x000f0000
+#define AR_D_TXBLK_WRITE_SLICE_S 16
+#define AR_D_TXBLK_WRITE_DCU_M 0x00f00000
+#define AR_D_TXBLK_WRITE_DCU_S 20
+#define AR_D_TXBLK_WRITE_COMMAND_M 0x0f000000
+#define AR_D_TXBLK_WRITE_COMMAND_S 24
+
+/* Bits for AR_DLCL_IFS. */
+#define AR_D_LCL_IFS_CWMIN_M 0x000003ff
+#define AR_D_LCL_IFS_CWMIN_S 0
+#define AR_D_LCL_IFS_CWMAX_M 0x000ffc00
+#define AR_D_LCL_IFS_CWMAX_S 10
+#define AR_D_LCL_IFS_AIFS_M 0x0ff00000
+#define AR_D_LCL_IFS_AIFS_S 20
+
+/* Bits for AR_D_GBL_IFS_SLOT. */
+#define AR_D_GBL_IFS_SLOT_M 0x0000ffff
+#define AR_D_GBL_IFS_SLOT_S 0
+#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR 0x00000420
+
+/* Bits for AR_DRETRY_LIMIT_*. */
+#define AR_D_RETRY_LIMIT_FR_SH_M 0x0000000f
+#define AR_D_RETRY_LIMIT_FR_SH_S 0
+#define AR_D_RETRY_LIMIT_STA_SH_M 0x00003f00
+#define AR_D_RETRY_LIMIT_STA_SH_S 8
+#define AR_D_RETRY_LIMIT_STA_LG_M 0x000fc000
+#define AR_D_RETRY_LIMIT_STA_LG_S 14
+
+/* Bits for AR_D_GBL_IFS_EIFS. */
+#define AR_D_GBL_IFS_EIFS_M 0x0000ffff
+#define AR_D_GBL_IFS_EIFS_S 0
+#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR 0x0000a5eb
+
+/* Bits for AR_DCHNTIME_*. */
+#define AR_D_CHNTIME_DUR_M 0x000fffff
+#define AR_D_CHNTIME_DUR_S 0
+#define AR_D_CHNTIME_EN 0x00100000
+
+/* Bits for AR_D_GBL_IFS_MISC. */
+#define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL 0x00000007
+#define AR_D_GBL_IFS_MISC_TURBO_MODE 0x00000008
+#define AR_D_GBL_IFS_MISC_USEC_DURATION 0x000ffc00
+#define AR_D_GBL_IFS_MISC_DCU_ARBITER_DLY 0x00300000
+#define AR_D_GBL_IFS_MISC_RANDOM_LFSR_SLICE_DIS 0x01000000
+#define AR_D_GBL_IFS_MISC_SLOT_XMIT_WIND_LEN 0x06000000
+#define AR_D_GBL_IFS_MISC_FORCE_XMIT_SLOT_BOUND 0x08000000
+#define AR_D_GBL_IFS_MISC_IGNORE_BACKOFF 0x10000000
+
+/* Bits for AR_DMISC_*. */
+#define AR_D_MISC_BKOFF_THRESH_M 0x0000003f
+#define AR_D_MISC_BKOFF_THRESH_S 0
+#define AR_D_MISC_RETRY_CNT_RESET_EN 0x00000040
+#define AR_D_MISC_CW_RESET_EN 0x00000080
+#define AR_D_MISC_FRAG_WAIT_EN 0x00000100
+#define AR_D_MISC_FRAG_BKOFF_EN 0x00000200
+#define AR_D_MISC_CW_BKOFF_EN 0x00001000
+#define AR_D_MISC_VIR_COL_HANDLING_M 0x0000c000
+#define AR_D_MISC_VIR_COL_HANDLING_S 14
+#define AR_D_MISC_VIR_COL_HANDLING_DEFAULT 0
+#define AR_D_MISC_VIR_COL_HANDLING_IGNORE 1
+#define AR_D_MISC_BEACON_USE 0x00010000
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_M 0x00060000
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_S 17
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_NONE 0
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR 1
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL 2
+#define AR_D_MISC_ARB_LOCKOUT_IGNORE 0x00080000
+#define AR_D_MISC_SEQ_NUM_INCR_DIS 0x00100000
+#define AR_D_MISC_POST_FR_BKOFF_DIS 0x00200000
+#define AR_D_MISC_VIT_COL_CW_BKOFF_EN 0x00400000
+#define AR_D_MISC_BLOWN_IFS_RETRY_EN 0x00800000
+
+/* Bits for AR_D_FPCTL. */
+#define AR_D_FPCTL_DCU_M 0x0000000f
+#define AR_D_FPCTL_DCU_S 0
+#define AR_D_FPCTL_PREFETCH_EN 0x00000010
+#define AR_D_FPCTL_BURST_PREFETCH_M 0x00007fe0
+#define AR_D_FPCTL_BURST_PREFETCH_S 5
+
+/* Bits for AR_D_TXPSE. */
+#define AR_D_TXPSE_CTRL_M 0x000003ff
+#define AR_D_TXPSE_CTRL_S 0
+#define AR_D_TXPSE_STATUS 0x00010000
+
+/* Bits for AR_D_TXSLOTMASK. */
+#define AR_D_TXSLOTMASK_NUM 0x0000000f
+
+/* Bits for AR_MAC_SLEEP. */
+#define AR_MAC_SLEEP_MAC_ASLEEP 0x00000001
+
+/* Bits for AR_CFG_LED. */
+#define AR_CFG_SCLK_RATE_IND_M 0x00000003
+#define AR_CFG_SCLK_RATE_IND_S 0
+#define AR_CFG_SCLK_32MHZ 0
+#define AR_CFG_SCLK_4MHZ 1
+#define AR_CFG_SCLK_1MHZ 2
+#define AR_CFG_SCLK_32KHZ 3
+#define AR_CFG_LED_BLINK_SLOW 0x00000008
+#define AR_CFG_LED_BLINK_THRESH_SEL_M 0x00000070
+#define AR_CFG_LED_BLINK_THRESH_SEL_S 4
+#define AR_CFG_LED_MODE_SEL_M 0x00000380
+#define AR_CFG_LED_MODE_SEL_S 7
+#define AR_CFG_LED_POWER_M 0x00000280
+#define AR_CFG_LED_POWER_S 7
+#define AR_CFG_LED_NETWORK_M 0x00000300
+#define AR_CFG_LED_NETWORK_S 7
+#define AR_CFG_LED_MODE_PROP 0
+#define AR_CFG_LED_MODE_RPROP 1
+#define AR_CFG_LED_MODE_SPLIT 2
+#define AR_CFG_LED_MODE_RAND 3
+#define AR_CFG_LED_MODE_POWER_OFF 4
+#define AR_CFG_LED_MODE_POWER_ON 5
+#define AR_CFG_LED_MODE_NETWORK_OFF 4
+#define AR_CFG_LED_MODE_NETWORK_ON 6
+#define AR_CFG_LED_ASSOC_CTL_M 0x00000c00
+#define AR_CFG_LED_ASSOC_CTL_S 10
+#define AR_CFG_LED_ASSOC_NONE 0
+#define AR_CFG_LED_ASSOC_ACTIVE 1
+#define AR_CFG_LED_ASSOC_PENDING 2
+
+/* Bit for AR_RC. */
+#define AR_RC_AHB 0x00000001
+#define AR_RC_APB 0x00000002
+#define AR_RC_HOSTIF 0x00000100
+
+/* Bits for AR_WA. */
+#define AR5416_WA_DEFAULT 0x0000073f
+#define AR9280_WA_DEFAULT 0x0040073b
+#define AR9285_WA_DEFAULT 0x004a050b
+#define AR_WA_UNTIE_RESET_EN 0x00008000
+#define AR_WA_RESET_EN 0x00040000
+#define AR_WA_ANALOG_SHIFT 0x00100000
+#define AR_WA_POR_SHORT 0x00200000
+
+/* Bits for AR_PM_STATE. */
+#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
+
+/* Bits for AR_PCIE_PM_CTRL. */
+#define AR_PCIE_PM_CTRL_ENA 0x00080000
+
+/* Bits for AR_HOST_TIMEOUT. */
+#define AR_HOST_TIMEOUT_APB_CNTR_M 0x0000ffff
+#define AR_HOST_TIMEOUT_APB_CNTR_S 0
+#define AR_HOST_TIMEOUT_LCL_CNTR_M 0xffff0000
+#define AR_HOST_TIMEOUT_LCL_CNTR_S 16
+
+/* Bits for AR_EEPROM. */
+#define AR_EEPROM_ABSENT 0x00000100
+#define AR_EEPROM_CORRUPT 0x00000200
+#define AR_EEPROM_PROT_MASK_M 0x03fffc00
+#define AR_EEPROM_PROT_MASK_S 10
+
+/* Bits for AR_SREV. */
+#define AR_SREV_ID_M 0x000000ff
+#define AR_SREV_ID_S 0
+#define AR_SREV_REVISION_M 0x00000007
+#define AR_SREV_REVISION_S 0
+#define AR_SREV_VERSION_M 0x000000f0
+#define AR_SREV_VERSION_S 4
+#define AR_SREV_VERSION2_M 0xfffc0000
+#define AR_SREV_VERSION2_S 12 /* XXX Hack. */
+#define AR_SREV_TYPE2_M 0x0003f000
+#define AR_SREV_TYPE2_S 12
+#define AR_SREV_TYPE2_CHAIN 0x00001000
+#define AR_SREV_TYPE2_HOST_MODE 0x00002000
+#define AR_SREV_REVISION2_M 0x00000f00
+#define AR_SREV_REVISION2_S 8
+#define AR_SREV_VERSION_5416_PCI 0x00d
+#define AR_SREV_VERSION_5416_PCIE 0x00c
+#define AR_SREV_REVISION_5416_10 0
+#define AR_SREV_REVISION_5416_20 1
+#define AR_SREV_REVISION_5416_22 2
+#define AR_SREV_VERSION_9100 0x014
+#define AR_SREV_VERSION_9160 0x040
+#define AR_SREV_REVISION_9160_10 0
+#define AR_SREV_REVISION_9160_11 1
+#define AR_SREV_VERSION_9280 0x080
+#define AR_SREV_REVISION_9280_10 0
+#define AR_SREV_REVISION_9280_20 1
+#define AR_SREV_REVISION_9280_21 2
+#define AR_SREV_VERSION_9285 0x0c0
+#define AR_SREV_REVISION_9285_10 0
+#define AR_SREV_REVISION_9285_11 1
+#define AR_SREV_REVISION_9285_12 2
+#define AR_SREV_VERSION_9271 0x140
+#define AR_SREV_REVISION_9271_10 0
+#define AR_SREV_REVISION_9271_11 1
+#define AR_SREV_VERSION_9287 0x180
+#define AR_SREV_REVISION_9287_10 0
+#define AR_SREV_REVISION_9287_11 1
+#define AR_SREV_REVISION_9287_12 2
+#define AR_SREV_REVISION_9287_13 3
+#define AR_SREV_VERSION_9380 0x1c0
+#define AR_SREV_REVISION_9380_10 0
+#define AR_SREV_REVISION_9380_20 2
+#define AR_SREV_VERSION_9485 0x240
+#define AR_SREV_REVISION_9485_10 0
+
+/* Bits for AR_AHB_MODE. */
+#define AR_AHB_EXACT_WR_EN 0x00000000
+#define AR_AHB_BUF_WR_EN 0x00000001
+#define AR_AHB_EXACT_RD_EN 0x00000000
+#define AR_AHB_CACHELINE_RD_EN 0x00000002
+#define AR_AHB_PREFETCH_RD_EN 0x00000004
+#define AR_AHB_PAGE_SIZE_1K 0x00000000
+#define AR_AHB_PAGE_SIZE_2K 0x00000008
+#define AR_AHB_PAGE_SIZE_4K 0x00000010
+#define AR_AHB_CUSTOM_BURST_M 0x000000c0
+#define AR_AHB_CUSTOM_BURST_S 6
+#define AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL 3
+
+/* Bits for AR_INTR_SYNC_CAUSE. */
+#define AR_INTR_SYNC_RTC_IRQ 0x00000001
+#define AR_INTR_SYNC_MAC_IRQ 0x00000002
+#define AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS 0x00000004
+#define AR_INTR_SYNC_APB_TIMEOUT 0x00000008
+#define AR_INTR_SYNC_PCI_MODE_CONFLICT 0x00000010
+#define AR_INTR_SYNC_HOST1_FATAL 0x00000020
+#define AR_INTR_SYNC_HOST1_PERR 0x00000040
+#define AR_INTR_SYNC_TRCV_FIFO_PERR 0x00000080
+#define AR_INTR_SYNC_RADM_CPL_EP 0x00000100
+#define AR_INTR_SYNC_RADM_CPL_DLLP_ABORT 0x00000200
+#define AR_INTR_SYNC_RADM_CPL_TLP_ABORT 0x00000400
+#define AR_INTR_SYNC_RADM_CPL_ECRC_ERR 0x00000800
+#define AR_INTR_SYNC_RADM_CPL_TIMEOUT 0x00001000
+#define AR_INTR_SYNC_LOCAL_TIMEOUT 0x00002000
+#define AR_INTR_SYNC_PM_ACCESS 0x00004000
+#define AR_INTR_SYNC_MAC_AWAKE 0x00008000
+#define AR_INTR_SYNC_MAC_ASLEEP 0x00010000
+#define AR_INTR_SYNC_MAC_SLEEP_ACCESS 0x00020000
+#define AR_INTR_SYNC_ALL 0x0003ffff
+#define AR_INTR_SYNC_GPIO_PIN(i) (1 << (18 + (i)))
+
+#define AR_INTR_SYNC_DEFAULT \
+ (AR_INTR_SYNC_HOST1_FATAL | \
+ AR_INTR_SYNC_HOST1_PERR | \
+ AR_INTR_SYNC_RADM_CPL_EP | \
+ AR_INTR_SYNC_RADM_CPL_DLLP_ABORT | \
+ AR_INTR_SYNC_RADM_CPL_TLP_ABORT | \
+ AR_INTR_SYNC_RADM_CPL_ECRC_ERR | \
+ AR_INTR_SYNC_RADM_CPL_TIMEOUT | \
+ AR_INTR_SYNC_LOCAL_TIMEOUT | \
+ AR_INTR_SYNC_MAC_SLEEP_ACCESS)
+
+/* Bits for AR_INTR_ASYNC_CAUSE. */
+#define AR_INTR_RTC_IRQ 0x00000001
+#define AR_INTR_MAC_IRQ 0x00000002
+#define AR_INTR_EEP_PROT_ACCESS 0x00000004
+#define AR_INTR_MAC_AWAKE 0x00020000
+#define AR_INTR_MAC_ASLEEP 0x00040000
+#define AR_INTR_GPIO_PIN(i) (1 << (18 + (i)))
+#define AR_INTR_SPURIOUS 0xffffffff
+
+/* Bits for AR_GPIO_OE_OUT. */
+#define AR_GPIO_OE_OUT_DRV_M 0x00000003
+#define AR_GPIO_OE_OUT_DRV_S 0
+#define AR_GPIO_OE_OUT_DRV_NO 0
+#define AR_GPIO_OE_OUT_DRV_LOW 1
+#define AR_GPIO_OE_OUT_DRV_HI 2
+#define AR_GPIO_OE_OUT_DRV_ALL 3
+
+/* Bits for AR_GPIO_INTR_POL. */
+#define AR_GPIO_INTR_POL_PIN(i) (1 << (i))
+
+/* Bits for AR_GPIO_INPUT_EN_VAL. */
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF 0x00000010
+#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB 0x00000400
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB 0x00001000
+#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000
+#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
+#define AR_GPIO_JTAG_DISABLE 0x00020000
+
+/* Bits for AR_GPIO_INPUT_MUX1. */
+#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_M 0x00000f00
+#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_M 0x000f0000
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16
+
+/* Bits for AR_GPIO_INPUT_MUX2. */
+#define AR_GPIO_INPUT_MUX2_CLK25_M 0x0000000f
+#define AR_GPIO_INPUT_MUX2_CLK25_S 0
+#define AR_GPIO_INPUT_MUX2_RFSILENT_M 0x000000f0
+#define AR_GPIO_INPUT_MUX2_RFSILENT_S 4
+#define AR_GPIO_INPUT_MUX2_RTC_RESET_M 0x00000f00
+#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8
+
+/* Bits for AR_GPIO_OUTPUT_MUX[1-3]. */
+#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
+#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME 3
+#define AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL 4
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
+
+/* Bits for AR_EEPROM_STATUS_DATA. */
+#define AR_EEPROM_STATUS_DATA_VAL_M 0x0000ffff
+#define AR_EEPROM_STATUS_DATA_VAL_S 0
+#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000
+#define AR_EEPROM_STATUS_DATA_BUSY_ACCESS 0x00020000
+#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000
+#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000
+
+/* Bits for AR_PCIE_MSI. */
+#define AR_PCIE_MSI_ENABLE 0x00000001
+
+/* Bits for AR_RTC_RC. */
+#define AR_RTC_RC_MAC_WARM 0x00000001
+#define AR_RTC_RC_MAC_COLD 0x00000002
+#define AR_RTC_RC_COLD_RESET 0x00000004
+#define AR_RTC_RC_WARM_RESET 0x00000008
+
+/* Bits for AR_RTC_REG_CONTROL1. */
+#define AR_RTC_REG_CONTROL1_SWREG_PROGRAM 0x00000001
+
+/* Bits for AR_RTC_PLL_CONTROL. */
+#define AR_RTC_PLL_DIV_M 0x0000001f
+#define AR_RTC_PLL_DIV_S 0
+#define AR_RTC_PLL_DIV2 0x00000020
+#define AR_RTC_PLL_REFDIV_5 0x000000c0
+#define AR_RTC_PLL_CLKSEL_M 0x00000300
+#define AR_RTC_PLL_CLKSEL_S 8
+#define AR_RTC_9160_PLL_DIV_M 0x000003ff
+#define AR_RTC_9160_PLL_DIV_S 0
+#define AR_RTC_9160_PLL_REFDIV_M 0x00003c00
+#define AR_RTC_9160_PLL_REFDIV_S 10
+#define AR_RTC_9160_PLL_CLKSEL_M 0x0000c000
+#define AR_RTC_9160_PLL_CLKSEL_S 14
+
+/* Bits for AR_RTC_RESET. */
+#define AR_RTC_RESET_EN 0x00000001
+
+/* Bits for AR_RTC_STATUS. */
+#define AR_RTC_STATUS_M 0x0000000f
+#define AR_RTC_STATUS_S 0
+#define AR_RTC_STATUS_SHUTDOWN 0x00000001
+#define AR_RTC_STATUS_ON 0x00000002
+#define AR_RTC_STATUS_SLEEP 0x00000004
+#define AR_RTC_STATUS_WAKEUP 0x00000008
+
+/* Bits for AR_RTC_SLEEP_CLK. */
+#define AR_RTC_FORCE_DERIVED_CLK 0x00000002
+#define AR_RTC_FORCE_SWREG_PRD 0x00000004
+
+/* Bits for AR_RTC_FORCE_WAKE. */
+#define AR_RTC_FORCE_WAKE_EN 0x00000001
+#define AR_RTC_FORCE_WAKE_ON_INT 0x00000002
+
+/* Bits for AR_STA_ID1. */
+#define AR_STA_ID1_SADH_M 0x0000ffff
+#define AR_STA_ID1_SADH_S 0
+#define AR_STA_ID1_STA_AP 0x00010000
+#define AR_STA_ID1_ADHOC 0x00020000
+#define AR_STA_ID1_PWR_SAV 0x00040000
+#define AR_STA_ID1_KSRCHDIS 0x00080000
+#define AR_STA_ID1_PCF 0x00100000
+#define AR_STA_ID1_USE_DEFANT 0x00200000
+#define AR_STA_ID1_DEFANT_UPDATE 0x00400000
+#define AR_STA_ID1_RTS_USE_DEF 0x00800000
+#define AR_STA_ID1_ACKCTS_6MB 0x01000000
+#define AR_STA_ID1_BASE_RATE_11B 0x02000000
+#define AR_STA_ID1_SECTOR_SELF_GEN 0x04000000
+#define AR_STA_ID1_CRPT_MIC_ENABLE 0x08000000
+#define AR_STA_ID1_KSRCH_MODE 0x10000000
+#define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000
+#define AR_STA_ID1_CBCIV_ENDIAN 0x40000000
+#define AR_STA_ID1_MCAST_KSRCH 0x80000000
+
+/* Bits for AR_BSS_ID1. */
+#define AR_BSS_ID1_U16_M 0x0000ffff
+#define AR_BSS_ID1_U16_S 0
+#define AR_BSS_ID1_AID_M 0x07ff0000
+#define AR_BSS_ID1_AID_S 16
+
+/* Bits for AR_TIME_OUT. */
+#define AR_TIME_OUT_ACK_M 0x00003fff
+#define AR_TIME_OUT_ACK_S 0
+#define AR_TIME_OUT_CTS_M 0x3fff0000
+#define AR_TIME_OUT_CTS_S 16
+#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR 0x16001d56
+
+/* Bits for AR_RSSI_THR. */
+#define AR_RSSI_THR_M 0x000000ff
+#define AR_RSSI_THR_S 0
+#define AR_RSSI_THR_BM_THR_M 0x0000ff00
+#define AR_RSSI_THR_BM_THR_S 8
+#define AR_RSSI_BCN_WEIGHT_M 0x1f000000
+#define AR_RSSI_BCN_WEIGHT_S 24
+#define AR_RSSI_BCN_RSSI_RST 0x20000000
+
+/* Bits for AR_USEC. */
+#define AR_USEC_USEC_M 0x0000007f
+#define AR_USEC_USEC_S 0
+#define AR_USEC_TX_LAT_M 0x007fc000
+#define AR_USEC_TX_LAT_S 14
+#define AR_USEC_RX_LAT_M 0x1f800000
+#define AR_USEC_RX_LAT_S 23
+#define AR_USEC_ASYNC_FIFO_DUR 0x12e00074
+
+/* Bits for AR_RESET_TSF. */
+#define AR_RESET_TSF_ONCE 0x01000000
+
+/* Bits for AR_RX_FILTER. */
+#define AR_RX_FILTER_UCAST 0x00000001
+#define AR_RX_FILTER_MCAST 0x00000002
+#define AR_RX_FILTER_BCAST 0x00000004
+#define AR_RX_FILTER_CONTROL 0x00000008
+#define AR_RX_FILTER_BEACON 0x00000010
+#define AR_RX_FILTER_PROM 0x00000020
+#define AR_RX_FILTER_PROBEREQ 0x00000080
+#define AR_RX_FILTER_MYBEACON 0x00000200
+#define AR_RX_FILTER_COMPR_BAR 0x00000400
+#define AR_RX_FILTER_PSPOLL 0x00004000
+
+/* Bits for AR_DIAG_SW. */
+#define AR_DIAG_CACHE_ACK 0x00000001
+#define AR_DIAG_ACK_DIS 0x00000002
+#define AR_DIAG_CTS_DIS 0x00000004
+#define AR_DIAG_ENCRYPT_DIS 0x00000008
+#define AR_DIAG_DECRYPT_DIS 0x00000010
+#define AR_DIAG_RX_DIS 0x00000020
+#define AR_DIAG_LOOP_BACK 0x00000040
+#define AR_DIAG_CORR_FCS 0x00000080
+#define AR_DIAG_CHAN_INFO 0x00000100
+#define AR_DIAG_SCRAM_SEED_M 0x0001fe00
+#define AR_DIAG_SCRAM_SEED_S 8 /* XXX should be 9? */
+#define AR_DIAG_FRAME_NV0 0x00020000
+#define AR_DIAG_OBS_PT_SEL1_M 0x000c0000
+#define AR_DIAG_OBS_PT_SEL1_S 18
+#define AR_DIAG_FORCE_RX_CLEAR 0x00100000
+#define AR_DIAG_IGNORE_VIRT_CS 0x00200000
+#define AR_DIAG_FORCE_CH_IDLE_HIGH 0x00400000
+#define AR_DIAG_EIFS_CTRL_ENA 0x00800000
+#define AR_DIAG_DUAL_CHAIN_INFO 0x01000000
+#define AR_DIAG_RX_ABORT 0x02000000
+#define AR_DIAG_SATURATE_CYCLE_CNT 0x04000000
+#define AR_DIAG_OBS_PT_SEL2 0x08000000
+#define AR_DIAG_RX_CLEAR_CTL_LOW 0x10000000
+#define AR_DIAG_RX_CLEAR_EXT_LOW 0x20000000
+
+/* Bits for AR_AES_MUTE_MASK0. */
+#define AR_AES_MUTE_MASK0_FC_M 0x0000ffff
+#define AR_AES_MUTE_MASK0_FC_S 0
+#define AR_AES_MUTE_MASK0_QOS_M 0xffff0000
+#define AR_AES_MUTE_MASK0_QOS_S 16
+
+/* Bits for AR_AES_MUTE_MASK1. */
+#define AR_AES_MUTE_MASK1_SEQ_M 0x0000ffff
+#define AR_AES_MUTE_MASK1_SEQ_S 0
+#define AR_AES_MUTE_MASK1_FC_MGMT_M 0xffff0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
+#define AR_AES_MUTE_MASK1_FC0_MGMT_M 0x00ff0000
+#define AR_AES_MUTE_MASK1_FC0_MGMT_S 16
+#define AR_AES_MUTE_MASK1_FC1_MGMT_M 0xff000000
+#define AR_AES_MUTE_MASK1_FC1_MGMT_S 24
+
+/* Bits for AR_GATED_CLKS. */
+#define AR_GATED_CLKS_TX 0x00000002
+#define AR_GATED_CLKS_RX 0x00000004
+#define AR_GATED_CLKS_REG 0x00000008
+
+/* Bits for AR_OBS_BUS_CTRL. */
+#define AR_OBS_BUS_SEL_1 0x00040000
+#define AR_OBS_BUS_SEL_2 0x00080000
+#define AR_OBS_BUS_SEL_3 0x000c0000
+#define AR_OBS_BUS_SEL_4 0x08040000
+#define AR_OBS_BUS_SEL_5 0x08080000
+
+/* Bits for AR_OBS_BUS_1. */
+#define AR_OBS_BUS_1_PCU 0x00000001
+#define AR_OBS_BUS_1_RX_END 0x00000002
+#define AR_OBS_BUS_1_RX_WEP 0x00000004
+#define AR_OBS_BUS_1_RX_BEACON 0x00000008
+#define AR_OBS_BUS_1_RX_FILTER 0x00000010
+#define AR_OBS_BUS_1_TX_HCF 0x00000020
+#define AR_OBS_BUS_1_QUIET_TIME 0x00000040
+#define AR_OBS_BUS_1_CHAN_IDLE 0x00000080
+#define AR_OBS_BUS_1_TX_HOLD 0x00000100
+#define AR_OBS_BUS_1_TX_FRAME 0x00000200
+#define AR_OBS_BUS_1_RX_FRAME 0x00000400
+#define AR_OBS_BUS_1_RX_CLEAR 0x00000800
+#define AR_OBS_BUS_1_WEP_STATE_M 0x0003f000
+#define AR_OBS_BUS_1_WEP_STATE_S 12
+#define AR_OBS_BUS_1_RX_STATE_M 0x01f00000
+#define AR_OBS_BUS_1_RX_STATE_S 20
+#define AR_OBS_BUS_1_TX_STATE_M 0x7e000000
+#define AR_OBS_BUS_1_TX_STATE_S 25
+
+/* Bits for AR_SLEEP1. */
+#define AR_SLEEP1_ASSUME_DTIM 0x00080000
+#define AR_SLEEP1_CAB_TIMEOUT_M 0xffe00000
+#define AR_SLEEP1_CAB_TIMEOUT_S 21
+/* Default value. */
+#define AR_CAB_TIMEOUT_VAL 10
+
+/* Bits for AR_SLEEP2. */
+#define AR_SLEEP2_BEACON_TIMEOUT_M 0xffe00000
+#define AR_SLEEP2_BEACON_TIMEOUT_S 21
+
+/* Bits for AR_TPC. */
+#define AR_TPC_ACK_M 0x0000003f
+#define AR_TPC_ACK_S 0
+#define AR_TPC_CTS_M 0x00003f00
+#define AR_TPC_CTS_S 8
+#define AR_TPC_CHIRP_M 0x003f0000
+#define AR_TPC_CHIRP_S 16
+
+/* Bits for AR_QUIET1. */
+#define AR_QUIET1_NEXT_QUIET_M 0x0000ffff
+#define AR_QUIET1_NEXT_QUIET_S 0
+#define AR_QUIET1_QUIET_ENABLE 0x00010000
+#define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x00020000
+
+/* Bits for AR_QUIET2. */
+#define AR_QUIET2_QUIET_PERIOD_M 0x0000ffff
+#define AR_QUIET2_QUIET_PERIOD_S 0
+#define AR_QUIET2_QUIET_DUR_M 0xffff0000
+#define AR_QUIET2_QUIET_DUR_S 16
+
+/* Bits for AR_TSF_PARM. */
+#define AR_TSF_INCREMENT_M 0x000000ff
+#define AR_TSF_INCREMENT_S 0
+
+/* Bits for AR_QOS_NO_ACK. */
+#define AR_QOS_NO_ACK_TWO_BIT_M 0x0000000f
+#define AR_QOS_NO_ACK_TWO_BIT_S 0
+#define AR_QOS_NO_ACK_BIT_OFF_M 0x0000007f
+#define AR_QOS_NO_ACK_BIT_OFF_S 4
+#define AR_QOS_NO_ACK_BYTE_OFF_M 0x00000180
+#define AR_QOS_NO_ACK_BYTE_OFF_S 7
+
+/* Bits for AR_PHY_ERR. */
+#define AR_PHY_ERR_DCHIRP 0x00000008
+#define AR_PHY_ERR_RADAR 0x00000020
+#define AR_PHY_ERR_OFDM_TIMING 0x00020000
+#define AR_PHY_ERR_CCK_TIMING 0x02000000
+
+/* Bits for AR_PCU_MISC. */
+#define AR_PCU_FORCE_BSSID_MATCH 0x00000001
+#define AR_PCU_MIC_NEW_LOC_ENA 0x00000004
+#define AR_PCU_TX_ADD_TSF 0x00000008
+#define AR_PCU_CCK_SIFS_MODE 0x00000010
+#define AR_PCU_RX_ANT_UPDT 0x00000800
+#define AR_PCU_TXOP_TBTT_LIMIT_ENA 0x00001000
+#define AR_PCU_MISS_BCN_IN_SLEEP 0x00004000
+#define AR_PCU_BUG_12306_FIX_ENA 0x00020000
+#define AR_PCU_FORCE_QUIET_COLL 0x00040000
+#define AR_PCU_BT_ANT_PREVENT_RX 0x00100000
+#define AR_PCU_TBTT_PROTECT 0x00200000
+#define AR_PCU_CLEAR_VMF 0x01000000
+#define AR_PCU_CLEAR_BA_VALID 0x04000000
+
+/* Bits for AR_BT_COEX_MODE. */
+#define AR_BT_TIME_EXTEND_M 0x000000ff
+#define AR_BT_TIME_EXTEND_S 0
+#define AR_BT_TXSTATE_EXTEND 0x00000100
+#define AR_BT_TX_FRAME_EXTEND 0x00000200
+#define AR_BT_MODE_M 0x00000c00
+#define AR_BT_MODE_S 10
+#define AR_BT_MODE_LEGACY 0
+#define AR_BT_MODE_UNSLOTTED 1
+#define AR_BT_MODE_SLOTTED 2
+#define AR_BT_MODE_DISABLED 3
+#define AR_BT_QUIET 0x00001000
+#define AR_BT_QCU_THRESH_M 0x0001e000
+#define AR_BT_QCU_THRESH_S 13
+#define AR_BT_RX_CLEAR_POLARITY 0x00020000
+#define AR_BT_PRIORITY_TIME_M 0x00fc0000
+#define AR_BT_PRIORITY_TIME_S 18
+#define AR_BT_FIRST_SLOT_TIME_M 0xff000000
+#define AR_BT_FIRST_SLOT_TIME_S 24
+
+/* Bits for AR_BT_COEX_WEIGHT. */
+#define AR_BTCOEX_BT_WGHT_M 0x0000ffff
+#define AR_BTCOEX_BT_WGHT_S 0
+#define AR_STOMP_LOW_BT_WGHT 0xff55
+#define AR_BTCOEX_WL_WGHT_M 0xffff0000
+#define AR_BTCOEX_WL_WGHT_S 16
+#define AR_STOMP_LOW_WL_WGHT 0xaaa8
+
+/* Bits for AR_BT_COEX_MODE2. */
+#define AR_BT_BCN_MISS_THRESH_M 0x000000ff
+#define AR_BT_BCN_MISS_THRESH_S 0
+#define AR_BT_BCN_MISS_CNT_M 0x0000ff00
+#define AR_BT_BCN_MISS_CNT_S 8
+#define AR_BT_HOLD_RX_CLEAR 0x00010000
+#define AR_BT_DISABLE_BT_ANT 0x00100000
+
+/* Bits for AR_PCU_BA_BAR_CTRL. */
+#define AR_PCU_BA_BAR_COMRESSED 0x00000100
+#define AR_PCU_BA_BAR_ACK_POLICY 0x00000200
+#define AR_PCU_BA_BAR_ACK_POLICY_OFFSET_M 0x000000f0
+#define AR_PCU_BA_BAR_ACK_POLICY_OFFSET_S 4
+#define AR_PCU_BA_BAR_COMPRESSED_OFFSET_M 0x0000000f
+#define AR_PCU_BA_BAR_COMPRESSED_OFFSET_S 0
+
+/* Bits for AR_PCU_TXBUF_CTRL. */
+#define AR_PCU_TXBUF_CTRL_SIZE_M 0x000007ff
+#define AR_PCU_TXBUF_CTRL_SIZE_S 0
+#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 1792
+#define AR9285_PCU_TXBUF_CTRL_USABLE_SIZE (1792 / 2)
+
+/* Bits for AR_PCU_MISC_MODE2. */
+#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002
+#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT 0x00000004
+#define AR_PCU_MISC_MODE2_AGG_WEP_ENABLE_FIX 0x00000008
+#define AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE 0x00000040
+#define AR_PCU_MISC_MODE2_CFP_IGNORE 0x00000080
+#define AR_PCU_MISC_MODE2_MGMT_QOS_M 0x0000ff00
+#define AR_PCU_MISC_MODE2_MGMT_QOS_S 8
+#define AR_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DUR 0x00010000
+#define AR_PCU_MISC_MODE2_ENABLE_AGGWEP 0x00020000
+#define AR_PCU_MISC_MODE2_HWWAR1 0x00100000
+#define AR_PCU_MISC_MODE2_HWWAR2 0x02000000
+
+/* Bits for AR_MAC_PCU_LOGIC_ANALYZER. */
+#define AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768 0x20000000
+
+/* Bits for AR_MAC_PCU_ASYNC_FIFO_REG3. */
+#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400
+#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000
+
+/* Bits for AR_PHY_ERR_[123]. */
+#define AR_PHY_ERR_COUNT_M 0x00ffffff
+#define AR_PHY_ERR_COUNT_S 0
+
+/* Bits for AR_TSFOOR_THRESHOLD. */
+#define AR_TSFOOR_THRESHOLD_VAL_M 0x0000ffff
+#define AR_TSFOOR_THRESHOLD_VAL_S 0
+
+/* Bit for AR_TXSIFS. */
+#define AR_TXSIFS_TIME_M 0x000000ff
+#define AR_TXSIFS_TIME_S 0
+#define AR_TXSIFS_TX_LATENCY_M 0x00000f00
+#define AR_TXSIFS_TX_LATENCY_S 8
+#define AR_TXSIFS_ACK_SHIFT_M 0x00007000
+#define AR_TXSIFS_ACK_SHIFT_S 12
+
+/* Bits for AR_TXOP_X. */
+#define AR_TXOP_X_VAL 0x000000ff
+
+/* Bits for AR_TIMER_MODE. */
+#define AR_TBTT_TIMER_EN 0x00000001
+#define AR_DBA_TIMER_EN 0x00000002
+#define AR_SWBA_TIMER_EN 0x00000004
+#define AR_HCF_TIMER_EN 0x00000008
+#define AR_TIM_TIMER_EN 0x00000010
+#define AR_DTIM_TIMER_EN 0x00000020
+#define AR_QUIET_TIMER_EN 0x00000040
+#define AR_NDP_TIMER_EN 0x00000080
+#define AR_TIMER_OVERFLOW_INDEX_M 0x00000700
+#define AR_TIMER_OVERFLOW_INDEX_S 8
+#define AR_TIMER_THRESH_M 0xfffff000
+#define AR_TIMER_THRESH_S 12
+
+/* Bits for AR_SLP32_MODE. */
+#define AR_SLP32_HALF_CLK_LATENCY_M 0x000fffff
+#define AR_SLP32_HALF_CLK_LATENCY_S 0
+#define AR_SLP32_ENA 0x00100000
+#define AR_SLP32_TSF_WRITE_STATUS 0x00200000
+
+/* Bits for AR_SLP32_WAKE. */
+#define AR_SLP32_WAKE_XTL_TIME_M 0x0000ffff
+#define AR_SLP32_WAKE_XTL_TIME_S 0
+
+/* Bits for AR_SLP_MIB_CTRL. */
+#define AR_SLP_MIB_CLEAR 0x00000001
+#define AR_SLP_MIB_PENDING 0x00000002
+
+/* Bits for AR_2040_MODE. */
+#define AR_2040_JOINED_RX_CLEAR 0x00000001
+
+/* Bits for AR_KEYTABLE_TYPE. */
+#define AR_KEYTABLE_TYPE_M 0x00000007
+#define AR_KEYTABLE_TYPE_S 0
+#define AR_KEYTABLE_TYPE_40 0
+#define AR_KEYTABLE_TYPE_104 1
+#define AR_KEYTABLE_TYPE_128 3
+#define AR_KEYTABLE_TYPE_TKIP 4
+#define AR_KEYTABLE_TYPE_AES 5
+#define AR_KEYTABLE_TYPE_CCM 6
+#define AR_KEYTABLE_TYPE_CLR 7
+#define AR_KEYTABLE_ANT 0x00000008
+#define AR_KEYTABLE_VALID 0x00008000
+
+/*
+ * AR9271 specific registers.
+ */
+#define AR9271_CLOCK_CONTROL 0x050040
+#define AR9271_RESET_POWER_DOWN_CONTROL 0x050044
+#define AR9271_FIRMWARE 0x501000
+#define AR9271_FIRMWARE_TEXT 0x903000
+#define AR7010_FIRMWARE_TEXT 0x906000
+
+/* Bits for AR9271_RESET_POWER_DOWN_CONTROL. */
+#define AR9271_RADIO_RF_RST 0x00000020
+#define AR9271_GATE_MAC_CTL 0x00004000
+
+
+#define AR_BASE_PHY_ACTIVE_DELAY 100
+
+#define AR_CLOCK_RATE_CCK 22
+#define AR_CLOCK_RATE_5GHZ_OFDM 40
+#define AR_CLOCK_RATE_FAST_5GHZ_OFDM 44
+#define AR_CLOCK_RATE_2GHZ_OFDM 44
+
+#define AR_PWR_DECREASE_FOR_2_CHAIN 6 /* 10 * log10(2) * 2 */
+#define AR_PWR_DECREASE_FOR_3_CHAIN 9 /* 10 * log10(3) * 2 */
+
+#define AR_SLEEP_SLOP 3 /* TUs */
+
+#define AR_MIN_BEACON_TIMEOUT_VAL 1
+#define AR_FUDGE 2
+#define AR_BEACON_DMA_DELAY 2
+#define AR_SWBA_DELAY 10
+/* Divides by 1024 (usecs to TU) without doing 64-bit arithmetic. */
+#define AR_TSF_TO_TU(hi, lo) ((hi) << 22 | (lo) >> 10)
+
+#define AR_KEY_CACHE_SIZE 128
+#define AR_RSVD_KEYTABLE_ENTRIES 4
+
+#define AR_CAL_SAMPLES 64 /* XXX AR9280? */
+#define AR_MAX_LOG_CAL 2 /* XXX AR9280? */
+
+/* Maximum number of chains supported by any chipset. */
+#define AR_MAX_CHAINS 3
+
+/* Default number of key cache entries. */
+#define AR_KEYTABLE_SIZE 128
+
+/* GPIO pins. */
+#define AR_GPIO_WLANACTIVE_PIN 5
+#define AR_GPIO_BTACTIVE_PIN 6
+#define AR_GPIO_BTPRIORITY_PIN 7
+
+#define AR_SREV_5416(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_5416_PCI || \
+ (sc)->mac_ver == AR_SREV_VERSION_5416_PCIE)
+#define AR_SREV_5416_20_OR_LATER(sc) \
+ ((AR_SREV_5416(sc) && \
+ (sc)->mac_rev >= AR_SREV_REVISION_5416_20) || \
+ (sc)->mac_ver >= AR_SREV_VERSION_9100)
+#define AR_SREV_5416_22_OR_LATER(sc) \
+ ((AR_SREV_5416(sc) && \
+ (sc)->mac_rev >= AR_SREV_REVISION_5416_22) || \
+ (sc)->mac_ver >= AR_SREV_VERSION_9100)
+
+#define AR_SREV_9160(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_9160)
+#define AR_SREV_9160_10_OR_LATER(sc) \
+ ((sc)->mac_ver >= AR_SREV_VERSION_9160)
+#define AR_SREV_9160_11(sc) \
+ (AR_SREV_9160(sc) && \
+ (sc)->mac_rev == AR_SREV_REVISION_9160_11)
+
+#define AR_SREV_9280(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_9280)
+#define AR_SREV_9280_10_OR_LATER(sc) \
+ ((sc)->mac_ver >= AR_SREV_VERSION_9280)
+#define AR_SREV_9280_10(sc) \
+ (AR_SREV_9280(sc) && \
+ (sc)->mac_rev == AR_SREV_REVISION_9280_10)
+#define AR_SREV_9280_20(sc) \
+ (AR_SREV_9280(sc) && \
+ (sc)->mac_rev >= AR_SREV_REVISION_9280_20)
+#define AR_SREV_9280_20_OR_LATER(sc) \
+ ((sc)->mac_ver > AR_SREV_VERSION_9280 || \
+ (AR_SREV_9280(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9280_20))
+
+#define AR_SREV_9285(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_9285)
+#define AR_SREV_9285_10_OR_LATER(sc) \
+ ((sc)->mac_ver >= AR_SREV_VERSION_9285)
+#define AR_SREV_9285_11(sc) \
+ (AR_SREV_9285(sc) && \
+ (sc)->mac_rev == AR_SREV_REVISION_9285_11)
+#define AR_SREV_9285_11_OR_LATER(sc) \
+ ((sc)->mac_ver > AR_SREV_VERSION_9285 || \
+ (AR_SREV_9285(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9285_11))
+#define AR_SREV_9285_12(sc) \
+ (AR_SREV_9285(sc) && \
+ ((sc)->mac_rev == AR_SREV_REVISION_9285_12))
+#define AR_SREV_9285_12_OR_LATER(sc) \
+ ((sc)->mac_ver > AR_SREV_VERSION_9285 || \
+ (AR_SREV_9285(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9285_12))
+
+#define AR_SREV_9271(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_9271)
+#define AR_SREV_9271_10(sc) \
+ (AR_SREV_9271(sc) && \
+ (sc)->mac_rev == AR_SREV_REVISION_9271_10)
+
+#define AR_SREV_9287(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_9287)
+#define AR_SREV_9287_10_OR_LATER(sc) \
+ ((sc)->mac_ver >= AR_SREV_VERSION_9287)
+#define AR_SREV_9287_10(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_9287 && \
+ (sc)->mac_rev == AR_SREV_REVISION_9287_10)
+#define AR_SREV_9287_11(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_9287 && \
+ (sc)->mac_rev == AR_SREV_REVISION_9287_11)
+#define AR_SREV_9287_11_OR_LATER(sc) \
+ ((sc)->mac_ver > AR_SREV_VERSION_9287 || \
+ (AR_SREV_9287(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9287_11))
+#define AR_SREV_9287_12(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_9287 && \
+ (sc)->mac_rev == AR_SREV_REVISION_9287_12)
+#define AR_SREV_9287_12_OR_LATER(sc) \
+ ((sc)->mac_ver > AR_SREV_VERSION_9287 || \
+ (AR_SREV_9287(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9287_12))
+#define AR_SREV_9287_13_OR_LATER(sc) \
+ ((sc)->mac_ver > AR_SREV_VERSION_9287 || \
+ (AR_SREV_9287(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9287_13))
+
+#define AR_SREV_9380(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_9380)
+#define AR_SREV_9380_10_OR_LATER(sc) \
+ ((sc)->mac_ver >= AR_SREV_VERSION_9380)
+#define AR_SREV_9380_20(sc) \
+ (AR_SREV_9380(sc) && \
+ (sc)->mac_rev == AR_SREV_REVISION_9380_20)
+#define AR_SREV_9380_20_OR_LATER(sc) \
+ ((sc)->mac_ver > AR_SREV_VERSION_9380 || \
+ (AR_SREV_9380(sc) && (sc)->mac_rev >= AR_SREV_REVISION_9380_20))
+
+#define AR_SREV_9485(sc) \
+ ((sc)->mac_ver == AR_SREV_VERSION_9485)
+
+#define AR_SINGLE_CHIP(sc) AR_SREV_9280_10_OR_LATER(sc)
+
+#define AR_RADIO_SREV_MAJOR 0xf0
+#define AR_RAD5133_SREV_MAJOR 0xc0
+#define AR_RAD2133_SREV_MAJOR 0xd0
+#define AR_RAD5122_SREV_MAJOR 0xe0
+#define AR_RAD2122_SREV_MAJOR 0xf0
+
+#define AR_BCHAN_UNUSED 0xff
+#define AR_PD_GAINS_IN_MASK 4 /* NB: Max for all chips. */
+#define AR_MAX_RATE_POWER 63
+
+#define AR_HT40_POWER_INC_FOR_PDADC 2
+#define AR_PWR_TABLE_OFFSET_DB (-5)
+#define AR9280_TX_GAIN_TABLE_SIZE 22
+#define AR9003_TX_GAIN_TABLE_SIZE 32
+#define AR9003_PAPRD_MEM_TAB_SIZE 24
+
+#define AR_BASE_FREQ_2GHZ 2300
+#define AR_BASE_FREQ_5GHZ 4900
+
+#define AR_SD_NO_CTL 0xe0
+#define AR_NO_CTL 0xff
+#define AR_CTL_MODE_M 0x07
+#define AR_CTL_MODE_S 0
+#define AR_CTL_11A 0
+#define AR_CTL_11B 1
+#define AR_CTL_11G 2
+#define AR_CTL_2GHT20 5
+#define AR_CTL_5GHT20 6
+#define AR_CTL_2GHT40 7
+#define AR_CTL_5GHT40 8
+
+#define AR_DEFAULT_NOISE_FLOOR (-100)
+
+/*
+ * Macros to access registers.
+ */
+#define AR_READ(sc, reg) \
+ (sc)->ops.read((sc), (reg))
+
+#define AR_WRITE(sc, reg, val) \
+ (sc)->ops.write((sc), (reg), (val))
+
+#define AR_WRITE_BARRIER(sc) \
+ (sc)->ops.write_barrier((sc))
+
+#define AR_SETBITS(sc, reg, mask) \
+ AR_WRITE(sc, reg, AR_READ(sc, reg) | (mask))
+
+#define AR_CLRBITS(sc, reg, mask) \
+ AR_WRITE(sc, reg, AR_READ(sc, reg) & ~(mask))
+
+/*
+ * Macros to access subfields in registers.
+ */
+/* Mask and Shift (getter). */
+#define MS(val, field) \
+ (((uint32_t)(val) & field##_M) >> field##_S)
+
+/* Shift and Mask (setter). */
+#define SM(field, val) \
+ (((uint32_t)(val) << field##_S) & field##_M)
+
+/* Rewrite. */
+#define RW(var, field, val) \
+ (((var) & ~field##_M) | SM(field, val))
+
+#endif /* ATHNREG_H */
diff --git a/sys/dev/athn/athnvar.h b/sys/dev/athn/athnvar.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/athnvar.h
@@ -0,0 +1,661 @@
+/* $OpenBSD: athnvar.h,v 1.42 2021/04/15 18:25:43 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2022 Farhan Khan <farhan@farhan.codes>
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ATHNVAR_H
+#define ATHNVAR_H
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <dev/athn/athnreg.h>
+
+// XXX TODO: Figure out what the enum should look like with WME_AC_BE, might not be relevant
+enum {
+ ATHN_TX_DATA,
+ ATHN_RX_DATA,
+ ATHN_RX_INTR,
+ ATHN_TX_INTR,
+ ATHN_N_TRANSFERS, // A semi-copy from RTWN_N_TRANSFER
+};
+
+#ifdef notyet
+#define ATHN_BT_COEXISTENCE 1
+#endif
+
+#ifdef ATHN_DEBUG
+#define DPRINTF(x) do { if (athn_debug > 0) printf x; } while (0)
+#define DPRINTFN(n, x) do { if (athn_debug >= (n)) printf x; } while (0)
+extern int athn_debug;
+#else
+#define DPRINTF(x)
+#define DPRINTFN(n, x)
+#endif
+
+#define LE_READ_4(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24)
+#define LE_READ_2(p) ((p)[0] | (p)[1] << 8)
+
+#define ATHN_RXBUFSZ 3872
+#define ATHN_TXBUFSZ 4096
+
+#define ATHN_NRXBUFS 64
+#define ATHN_NTXBUFS 64 /* Shared between all Tx queues. */
+
+struct athn_rx_radiotap_header {
+ struct ieee80211_radiotap_header wr_ihdr;
+ uint64_t wr_tsft;
+ uint8_t wr_flags;
+ uint8_t wr_rate;
+ uint16_t wr_chan_freq;
+ uint16_t wr_chan_flags;
+ int8_t wr_dbm_antsignal;
+ uint8_t wr_antenna;
+} __packed;
+
+#define ATHN_RX_RADIOTAP_PRESENT \
+ (1 << IEEE80211_RADIOTAP_TSFT | \
+ 1 << IEEE80211_RADIOTAP_FLAGS | \
+ 1 << IEEE80211_RADIOTAP_RATE | \
+ 1 << IEEE80211_RADIOTAP_CHANNEL | \
+ 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL | \
+ 1 << IEEE80211_RADIOTAP_ANTENNA)
+
+struct athn_tx_radiotap_header {
+ struct ieee80211_radiotap_header wt_ihdr;
+ uint8_t wt_flags;
+ uint8_t wt_rate;
+ uint16_t wt_chan_freq;
+ uint16_t wt_chan_flags;
+} __packed;
+
+#define ATHN_TX_RADIOTAP_PRESENT \
+ (1 << IEEE80211_RADIOTAP_FLAGS | \
+ 1 << IEEE80211_RADIOTAP_RATE | \
+ 1 << IEEE80211_RADIOTAP_CHANNEL)
+
+struct athn_tx_buf {
+// LIST_ENTRY(athn_tx_buf) bf_list;
+
+ void *bf_descs;
+ bus_dmamap_t bf_map;
+ bus_addr_t bf_daddr;
+
+ struct mbuf *bf_m;
+ struct ieee80211_node *bf_ni;
+ int bf_txmcs;
+ int bf_txflags;
+#define ATHN_TXFLAG_PAPRD (1 << 0)
+#define ATHN_TXFLAG_CAB (1 << 1)
+};
+
+struct athn_txq {
+ STAILQ_HEAD(, athn_tx_buf) head;
+ void *lastds;
+ struct athn_tx_buf *wait;
+ int queued;
+};
+
+struct athn_rx_buf {
+ //LIST_ENTRY(athn_rx_buf) bf_list;
+
+ void *bf_desc;
+ bus_dmamap_t bf_map;
+
+ struct mbuf *bf_m;
+ bus_addr_t bf_daddr;
+};
+
+struct athn_rxq {
+ struct athn_rx_buf *bf;
+
+ void *descs;
+ void *lastds;
+#if 0
+ bus_dmamap_t map;
+ bus_dma_segment_t seg;
+#endif
+ int count;
+
+ //LIST_HEAD(, athn_rx_buf) head;
+};
+
+/* Software rate indexes. */
+#define ATHN_RIDX_CCK1 0
+#define ATHN_RIDX_CCK2 1
+#define ATHN_RIDX_OFDM6 4
+#define ATHN_RIDX_MCS0 12
+#define ATHN_RIDX_MCS8 (ATHN_RIDX_MCS0 + 8)
+#define ATHN_RIDX_MCS15 27
+#define ATHN_RIDX_MAX 27
+#define ATHN_MCS_MAX 15
+#define ATHN_NUM_MCS (ATHN_MCS_MAX + 1)
+#define ATHN_IS_HT_RIDX(ridx) ((ridx) >= ATHN_RIDX_MCS0)
+#define ATHN_IS_MIMO_RIDX(ridx) ((ridx) >= ATHN_RIDX_MCS8)
+
+static const struct athn_rate {
+ uint16_t rate; /* Rate in 500Kbps unit. */
+ uint8_t hwrate; /* HW representation. */
+ uint8_t rspridx; /* Control Response Frame rate index. */
+ enum ieee80211_phytype phy;
+} athn_rates[] = {
+ { 2, 0x1b, 0, IEEE80211_T_DS },
+ { 4, 0x1a, 1, IEEE80211_T_DS },
+ { 11, 0x19, 1, IEEE80211_T_DS },
+ { 22, 0x18, 1, IEEE80211_T_DS },
+ { 12, 0x0b, 4, IEEE80211_T_OFDM },
+ { 18, 0x0f, 4, IEEE80211_T_OFDM },
+ { 24, 0x0a, 6, IEEE80211_T_OFDM },
+ { 36, 0x0e, 6, IEEE80211_T_OFDM },
+ { 48, 0x09, 8, IEEE80211_T_OFDM },
+ { 72, 0x0d, 8, IEEE80211_T_OFDM },
+ { 96, 0x08, 8, IEEE80211_T_OFDM },
+ { 108, 0x0c, 8, IEEE80211_T_OFDM },
+ { 13, 0x80, 4, IEEE80211_T_OFDM },
+ { 26, 0x81, 6, IEEE80211_T_OFDM },
+ { 39, 0x82, 6, IEEE80211_T_OFDM },
+ { 52, 0x83, 8, IEEE80211_T_OFDM },
+ { 78, 0x84, 8, IEEE80211_T_OFDM },
+ { 104, 0x85, 8, IEEE80211_T_OFDM },
+ { 117, 0x86, 8, IEEE80211_T_OFDM },
+ { 130, 0x87, 8, IEEE80211_T_OFDM },
+ { 26, 0x88, 4, IEEE80211_T_OFDM },
+ { 52, 0x89, 6, IEEE80211_T_OFDM },
+ { 78, 0x8a, 8, IEEE80211_T_OFDM },
+ { 104, 0x8b, 8, IEEE80211_T_OFDM },
+ { 156, 0x8c, 8, IEEE80211_T_OFDM },
+ { 208, 0x8d, 8, IEEE80211_T_OFDM },
+ { 234, 0x8e, 8, IEEE80211_T_OFDM },
+ { 260, 0x8f, 8, IEEE80211_T_OFDM }
+};
+
+struct athn_series {
+ uint16_t dur;
+ uint8_t hwrate;
+};
+
+struct athn_pier {
+ uint8_t fbin;
+ const uint8_t *pwr[AR_PD_GAINS_IN_MASK];
+ const uint8_t *vpd[AR_PD_GAINS_IN_MASK];
+};
+
+/*
+ * Structures used to store initialization values.
+ */
+struct athn_ini {
+ int nregs;
+ const uint16_t *regs;
+ const uint32_t *vals_5g20;
+ const uint32_t *vals_5g40;
+ const uint32_t *vals_2g40;
+ const uint32_t *vals_2g20;
+ int ncmregs;
+ const uint16_t *cmregs;
+ const uint32_t *cmvals;
+ int nfastregs;
+ const uint16_t *fastregs;
+ const uint32_t *fastvals_5g20;
+ const uint32_t *fastvals_5g40;
+};
+
+struct athn_gain {
+ int nregs;
+ const uint16_t *regs;
+ const uint32_t *vals_5g;
+ const uint32_t *vals_2g;
+};
+
+struct athn_addac {
+ int nvals;
+ const uint32_t *vals;
+};
+
+struct athn_serdes {
+ int nvals;
+ const uint32_t *regs;
+ const uint32_t *vals;
+};
+
+/* Rx queue software indexes. */
+#define ATHN_QID_LP 0
+#define ATHN_QID_HP 1
+
+/* Tx queue software indexes. */
+#define ATHN_QID_AC_BE 0
+#define ATHN_QID_PSPOLL 1
+#define ATHN_QID_AC_BK 2
+#define ATHN_QID_AC_VI 3
+#define ATHN_QID_AC_VO 4
+#define ATHN_QID_UAPSD 5
+#define ATHN_QID_CAB 6
+#define ATHN_QID_BEACON 7
+#define ATHN_QID_COUNT 8
+
+/* Map Access Category to Tx queue Id. */
+#if 0
+static const uint8_t athn_ac2qid[EDCA_NUM_AC] = {
+ ATHN_QID_AC_BE, /* EDCA_AC_BE */
+ ATHN_QID_AC_BK, /* EDCA_AC_BK */
+ ATHN_QID_AC_VI, /* EDCA_AC_VI */
+ ATHN_QID_AC_VO /* EDCA_AC_VO */
+};
+#endif
+
+static const uint8_t athn_5ghz_chans[] = {
+ /* UNII 1. */
+ 36, 40, 44, 48,
+ /* UNII 2. */
+ 52, 56, 60, 64,
+ /* Middle band. */
+ 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
+ /* UNII 3. */
+ 149, 153, 157, 161, 165
+};
+
+/* Number of data bits per OFDM symbol for MCS[0-15]. */
+/* See tables 20-29, 20-30, 20-33, 20-34. */
+static const uint16_t ar_mcs_ndbps[][2] = {
+ /* 20MHz 40MHz */
+ { 26, 54 }, /* MCS0 */
+ { 52, 108 }, /* MCS1 */
+ { 78, 162 }, /* MCS2 */
+ { 104, 216 }, /* MCS3 */
+ { 156, 324 }, /* MCS4 */
+ { 208, 432 }, /* MCS5 */
+ { 234, 486 }, /* MCS6 */
+ { 260, 540 }, /* MCS7 */
+ { 26, 108 }, /* MCS8 */
+ { 52, 216 }, /* MCS9 */
+ { 78, 324 }, /* MCS10 */
+ { 104, 432 }, /* MCS11 */
+ { 156, 648 }, /* MCS12 */
+ { 208, 864 }, /* MCS13 */
+ { 234, 972 }, /* MCS14 */
+ { 260, 1080 } /* MCS15 */
+};
+
+#define ATHN_POWER_OFDM6 0
+#define ATHN_POWER_OFDM9 1
+#define ATHN_POWER_OFDM12 2
+#define ATHN_POWER_OFDM18 3
+#define ATHN_POWER_OFDM24 4
+#define ATHN_POWER_OFDM36 5
+#define ATHN_POWER_OFDM48 6
+#define ATHN_POWER_OFDM54 7
+#define ATHN_POWER_CCK1_LP 8
+#define ATHN_POWER_CCK2_LP 9
+#define ATHN_POWER_CCK2_SP 10
+#define ATHN_POWER_CCK55_LP 11
+#define ATHN_POWER_CCK55_SP 12
+#define ATHN_POWER_CCK11_LP 13
+#define ATHN_POWER_CCK11_SP 14
+#define ATHN_POWER_XR 15
+#define ATHN_POWER_HT20(mcs) (16 + (mcs))
+#define ATHN_POWER_HT40(mcs) (40 + (mcs))
+#define ATHN_POWER_CCK_DUP 64
+#define ATHN_POWER_OFDM_DUP 65
+#define ATHN_POWER_CCK_EXT 66
+#define ATHN_POWER_OFDM_EXT 67
+#define ATHN_POWER_COUNT 68
+
+#define ATHN_NUM_LEGACY_RATES IEEE80211_RATE_MAXSIZE
+#define ATHN_NUM_RATES (ATHN_NUM_LEGACY_RATES + ATHN_NUM_MCS)
+struct athn_node {
+ struct ieee80211_node ni;
+#if 0
+ struct ieee80211_amrr_node amn;
+ struct ieee80211_ra_node rn;
+#endif
+ uint8_t ridx[ATHN_NUM_RATES];
+ uint8_t fallback[ATHN_NUM_RATES];
+ uint8_t sta_index;
+};
+
+/*
+ * Adaptive noise immunity state.
+ */
+#define ATHN_ANI_PERIOD 100
+#define ATHN_ANI_RSSI_THR_HIGH 40
+#define ATHN_ANI_RSSI_THR_LOW 7
+struct athn_ani {
+ uint8_t noise_immunity_level;
+ uint8_t spur_immunity_level;
+ uint8_t firstep_level;
+ uint8_t ofdm_weak_signal;
+ uint8_t cck_weak_signal;
+
+ uint32_t listen_time;
+
+ uint32_t ofdm_trig_high;
+ uint32_t ofdm_trig_low;
+
+ int32_t cck_trig_high;
+ int32_t cck_trig_low;
+
+ uint32_t ofdm_phy_err_base;
+ uint32_t cck_phy_err_base;
+ uint32_t ofdm_phy_err_count;
+ uint32_t cck_phy_err_count;
+
+ uint32_t cyccnt;
+ uint32_t txfcnt;
+ uint32_t rxfcnt;
+};
+
+struct athn_iq_cal {
+ uint32_t pwr_meas_i;
+ uint32_t pwr_meas_q;
+ int32_t iq_corr_meas;
+};
+
+struct athn_adc_cal {
+ uint32_t pwr_meas_odd_i;
+ uint32_t pwr_meas_even_i;
+ uint32_t pwr_meas_odd_q;
+ uint32_t pwr_meas_even_q;
+};
+
+struct athn_calib {
+ int nsamples;
+ struct athn_iq_cal iq[AR_MAX_CHAINS];
+ struct athn_adc_cal adc_gain[AR_MAX_CHAINS];
+ struct athn_adc_cal adc_dc_offset[AR_MAX_CHAINS];
+};
+
+#define ATHN_NF_CAL_HIST_MAX 5
+
+struct athn_softc;
+
+#define ATHN_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
+#define ATHN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
+
+struct athn_ops {
+ /* Bus callbacks. */
+ uint32_t (*read)(struct athn_softc *, uint32_t);
+ void (*write)(struct athn_softc *, uint32_t, uint32_t);
+ void (*write_barrier)(struct athn_softc *);
+
+ void (*setup)(struct athn_softc *);
+ void (*set_txpower)(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+ void (*spur_mitigate)(struct athn_softc *,
+ struct ieee80211_channel *, struct ieee80211_channel *);
+ const struct ar_spur_chan *
+ (*get_spur_chans)(struct athn_softc *, int);
+ void (*init_from_rom)(struct athn_softc *,
+ struct ieee80211_channel *, struct ieee80211_channel *);
+ int (*set_synth)(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+ int (*read_rom_data)(struct athn_softc *, uint32_t, void *, int);
+ const uint8_t *
+ (*get_rom_template)(struct athn_softc *, uint8_t);
+ void (*swap_rom)(struct athn_softc *);
+ void (*olpc_init)(struct athn_softc *);
+ void (*olpc_temp_compensation)(struct athn_softc *);
+ /* GPIO callbacks. */
+ int (*gpio_read)(struct athn_softc *, int);
+ void (*gpio_write)(struct athn_softc *, int, int);
+ void (*gpio_config_input)(struct athn_softc *, int);
+ void (*gpio_config_output)(struct athn_softc *, int, int);
+ void (*rfsilent_init)(struct athn_softc *);
+ /* DMA callbacks. */
+ int (*dma_alloc)(struct athn_softc *);
+ void (*dma_free)(struct athn_softc *);
+ void (*rx_enable)(struct athn_softc *);
+ int (*intr)(struct athn_softc *);
+ int (*tx)(struct athn_softc *, struct mbuf *,
+ struct ieee80211_node *, int);
+ /* PHY callbacks. */
+ void (*set_rf_mode)(struct athn_softc *,
+ struct ieee80211_channel *);
+ int (*rf_bus_request)(struct athn_softc *);
+ void (*rf_bus_release)(struct athn_softc *);
+ void (*set_phy)(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+ void (*set_delta_slope)(struct athn_softc *,
+ struct ieee80211_channel *, struct ieee80211_channel *);
+ void (*enable_antenna_diversity)(struct athn_softc *);
+ void (*init_baseband)(struct athn_softc *);
+ void (*disable_phy)(struct athn_softc *);
+ void (*set_rxchains)(struct athn_softc *);
+ void (*noisefloor_calib)(struct athn_softc *);
+ void (*init_noisefloor_calib)(struct athn_softc *);
+ int (*get_noisefloor)(struct athn_softc *);
+ void (*apply_noisefloor)(struct athn_softc *);
+ void (*do_calib)(struct athn_softc *);
+ void (*next_calib)(struct athn_softc *);
+ void (*hw_init)(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+ void (*get_paprd_masks)(struct athn_softc *sc,
+ struct ieee80211_channel *, uint32_t *, uint32_t *);
+ /* ANI callbacks. */
+ void (*set_noise_immunity_level)(struct athn_softc *, int);
+ void (*enable_ofdm_weak_signal)(struct athn_softc *);
+ void (*disable_ofdm_weak_signal)(struct athn_softc *);
+ void (*set_cck_weak_signal)(struct athn_softc *, int);
+ void (*set_firstep_level)(struct athn_softc *, int);
+ void (*set_spur_immunity_level)(struct athn_softc *, int);
+};
+
+struct athn_softc {
+ device_t sc_dev;
+ struct ieee80211com sc_ic;
+
+ int (*sc_enable)(struct athn_softc *);
+ void (*sc_disable)(struct athn_softc *);
+ void (*sc_power)(struct athn_softc *, int);
+ void (*sc_disable_aspm)(struct athn_softc *);
+ void (*sc_enable_extsynch)(
+ struct athn_softc *);
+
+ int (*sc_newstate)(struct ieee80211com *,
+ enum ieee80211_state, int);
+
+ bus_dma_tag_t sc_dmat;
+
+ struct callout scan_to;
+ struct callout calib_to;
+#if 0
+ struct ieee80211_amrr amrr;
+#endif
+
+ u_int flags;
+#define ATHN_FLAG_PCIE (1 << 0)
+#define ATHN_FLAG_USB (1 << 1)
+#define ATHN_FLAG_OLPC (1 << 2)
+#define ATHN_FLAG_PAPRD (1 << 3)
+#define ATHN_FLAG_FAST_PLL_CLOCK (1 << 4)
+#define ATHN_FLAG_RFSILENT (1 << 5)
+#define ATHN_FLAG_RFSILENT_REVERSED (1 << 6)
+#define ATHN_FLAG_BTCOEX2WIRE (1 << 7)
+#define ATHN_FLAG_BTCOEX3WIRE (1 << 8)
+/* Shortcut. */
+#define ATHN_FLAG_BTCOEX (ATHN_FLAG_BTCOEX2WIRE | ATHN_FLAG_BTCOEX3WIRE)
+#define ATHN_FLAG_11A (1 << 9)
+#define ATHN_FLAG_11G (1 << 10)
+#define ATHN_FLAG_11N (1 << 11)
+#define ATHN_FLAG_AN_TOP2_FIXUP (1 << 12)
+#define ATHN_FLAG_NON_ENTERPRISE (1 << 13)
+#define ATHN_FLAG_3TREDUCE_CHAIN (1 << 14)
+
+ uint8_t ngpiopins;
+ int led_pin;
+ int rfsilent_pin;
+ int led_state;
+ uint32_t isync;
+ uint32_t imask;
+
+ uint16_t mac_ver;
+ uint8_t mac_rev;
+ uint8_t rf_rev;
+ uint16_t eep_rev;
+
+ uint8_t txchainmask;
+ uint8_t rxchainmask;
+ uint8_t ntxchains;
+ uint8_t nrxchains;
+
+ uint8_t sup_calib_mask;
+ uint8_t cur_calib_mask;
+#define ATHN_CAL_IQ (1 << 0)
+#define ATHN_CAL_ADC_GAIN (1 << 1)
+#define ATHN_CAL_ADC_DC (1 << 2)
+#define ATHN_CAL_TEMP (1 << 3)
+
+ // There is now ic->ic_curchan
+// struct ieee80211_channel *curchan;
+ // Not sure about this
+ struct ieee80211_channel *curchanext;
+
+ /* Open Loop Power Control. */
+ int8_t tx_gain_tbl[AR9280_TX_GAIN_TABLE_SIZE];
+ int8_t pdadc;
+ int8_t tcomp;
+ int olpc_ticks;
+ int iqcal_ticks;
+
+ /* PA predistortion. */
+ uint16_t gain1[AR_MAX_CHAINS];
+ uint32_t txgain[AR9003_TX_GAIN_TABLE_SIZE];
+ int16_t pa_in[AR_MAX_CHAINS]
+ [AR9003_PAPRD_MEM_TAB_SIZE];
+ int16_t angle[AR_MAX_CHAINS]
+ [AR9003_PAPRD_MEM_TAB_SIZE];
+ int32_t trainpow;
+ uint8_t paprd_curchain;
+
+ uint32_t rwbuf[64];
+
+ int kc_entries;
+
+ void *eep;
+ const void *eep_def;
+ uint32_t eep_base;
+ uint32_t eep_size;
+
+ struct athn_rxq rxq[2];
+ struct athn_txq txq[31];
+
+ void *descs;
+#if 0
+ bus_dmamap_t map;
+ bus_dma_segment_t seg;
+#endif
+ //LIST_HEAD(, athn_tx_buf) txbufs;
+ struct athn_tx_buf *bcnbuf;
+ struct athn_tx_buf txpool[ATHN_NTXBUFS];
+
+#if 0
+ bus_dmamap_t txsmap;
+ bus_dma_segment_t txsseg;
+#endif
+ void *txsring;
+ int txscur;
+
+ int sc_if_flags;
+ int sc_tx_timer;
+
+ const struct athn_ini *ini;
+ const struct athn_gain *rx_gain;
+ const struct athn_gain *tx_gain;
+ const struct athn_addac *addac;
+ const struct athn_serdes *serdes;
+ uint32_t workaround;
+ uint32_t obs_off;
+ uint32_t gpio_input_en_off;
+
+ struct athn_ops ops;
+
+ int fixed_ridx;
+
+ int16_t cca_min_2g;
+ int16_t cca_max_2g;
+ int16_t cca_min_5g;
+ int16_t cca_max_5g;
+ struct {
+ int16_t nf[AR_MAX_CHAINS];
+ int16_t nf_ext[AR_MAX_CHAINS];
+ } nf_hist[ATHN_NF_CAL_HIST_MAX];
+ int nf_hist_cur;
+ int nf_hist_nvalid;
+ int16_t nf_priv[AR_MAX_CHAINS];
+ int16_t nf_ext_priv[AR_MAX_CHAINS];
+ int nf_calib_pending;
+ int nf_calib_ticks;
+ int pa_calib_ticks;
+
+ struct athn_calib calib;
+ struct athn_ani ani;
+
+#if 0
+#if NBPFILTER > 0
+ caddr_t sc_drvbpf;
+
+ union {
+ struct athn_rx_radiotap_header th;
+ uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
+ } sc_rxtapu;
+#define sc_rxtap sc_rxtapu.th
+ int sc_rxtap_len;
+
+ union {
+ struct athn_tx_radiotap_header th;
+ uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
+ } sc_txtapu;
+#define sc_txtap sc_txtapu.th
+ int sc_txtap_len;
+#endif
+#endif
+ /* FreeBSD additions */
+ struct mtx sc_mtx;
+
+ struct mtx cmdq_mtx;
+ struct task cmdq_task;
+ uint8_t cmdq_first;
+ uint8_t cmdq_last;
+
+ int (*sc_key_delete)(struct ieee80211vap *, const struct ieee80211_key *);
+ int (*sc_key_set)(struct ieee80211vap *, const struct ieee80211_key *);
+ int (*sc_init)(struct athn_softc *);
+
+ /* Firmware-specific */
+ const char *fwname;
+ uint16_t fwver;
+ uint16_t fwsig;
+ int fwcur;
+ int fwsize_limit;
+};
+
+extern int athn_attach(struct athn_softc *);
+extern void athn_detach(struct athn_softc *);
+extern void athn_suspend(struct athn_softc *);
+extern void athn_wakeup(struct athn_softc *);
+extern int athn_intr(void *);
+
+/* FreeBSD Additions */
+#define ATHN_CMDQ_LOCK_INIT(sc) \
+ mtx_init(&(sc)->cmdq_mtx, "cmdq lock", NULL, MTX_DEF)
+
+struct athn_vap {
+ struct ieee80211vap vap;
+ int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int);
+};
+
+int athn_newstate(struct ieee80211vap *, enum ieee80211_state,
+ int);
+
+#endif /* ATHNVAR_H */
diff --git a/sys/dev/athn/ic/ar5008.c b/sys/dev/athn/ic/ar5008.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar5008.c
@@ -0,0 +1,3058 @@
+/* $OpenBSD: ar5008.c,v 1.70 2022/04/21 21:03:02 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Driver for Atheros 802.11a/g/n chipsets.
+ * Routines common to AR5008, AR9001 and AR9002 families.
+ */
+
+#include <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/kernel.h>
+//#include <sys/timeout.h>
+#include <sys/conf.h>
+//#include <sys/device.h>
+#include <sys/stdint.h> /* uintptr_t */
+#include <sys/endian.h>
+#include <sys/bus.h>
+
+//#include <machine/bus.h>
+
+//#if NBPFILTER > 0
+//#include <net/bpf.h>
+//#endif
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+//#include <net80211/ieee80211_ra.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/athn/athnreg.h>
+#include <dev/athn/athnvar.h>
+
+#include <dev/athn/ic/ar5008reg.h>
+
+int ar5008_attach(struct athn_softc *);
+int ar5008_read_eep_word(struct athn_softc *, uint32_t, uint16_t *);
+int ar5008_read_rom(struct athn_softc *);
+void ar5008_swap_rom(struct athn_softc *);
+int ar5008_gpio_read(struct athn_softc *, int);
+void ar5008_gpio_write(struct athn_softc *, int, int);
+void ar5008_gpio_config_input(struct athn_softc *, int);
+void ar5008_gpio_config_output(struct athn_softc *, int, int);
+void ar5008_rfsilent_init(struct athn_softc *);
+int ar5008_dma_alloc(struct athn_softc *);
+void ar5008_dma_free(struct athn_softc *);
+int ar5008_tx_alloc(struct athn_softc *);
+void ar5008_tx_free(struct athn_softc *);
+int ar5008_rx_alloc(struct athn_softc *);
+void ar5008_rx_free(struct athn_softc *);
+void ar5008_rx_enable(struct athn_softc *);
+void ar5008_rx_radiotap(struct athn_softc *, struct mbuf *,
+ struct ar_rx_desc *);
+int ar5008_ccmp_decap(struct athn_softc *, struct mbuf *,
+ struct ieee80211_node *);
+void ar5008_rx_intr(struct athn_softc *);
+int ar5008_tx_process(struct athn_softc *, int);
+void ar5008_tx_intr(struct athn_softc *);
+int ar5008_swba_intr(struct athn_softc *);
+int ar5008_intr(struct athn_softc *);
+int ar5008_ccmp_encap(struct mbuf *, u_int, struct ieee80211_key *);
+int ar5008_tx(struct athn_softc *, struct mbuf *, struct ieee80211_node *,
+ int);
+void ar5008_set_rf_mode(struct athn_softc *, struct ieee80211_channel *);
+int ar5008_rf_bus_request(struct athn_softc *);
+void ar5008_rf_bus_release(struct athn_softc *);
+void ar5008_set_phy(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar5008_set_delta_slope(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar5008_enable_antenna_diversity(struct athn_softc *);
+void ar5008_init_baseband(struct athn_softc *);
+void ar5008_disable_phy(struct athn_softc *);
+void ar5008_init_chains(struct athn_softc *);
+void ar5008_set_rxchains(struct athn_softc *);
+void ar5008_read_noisefloor(struct athn_softc *, int16_t *, int16_t *);
+void ar5008_write_noisefloor(struct athn_softc *, int16_t *, int16_t *);
+int ar5008_get_noisefloor(struct athn_softc *);
+void ar5008_apply_noisefloor(struct athn_softc *);
+void ar5008_bb_load_noisefloor(struct athn_softc *);
+void ar5008_do_noisefloor_calib(struct athn_softc *);
+void ar5008_init_noisefloor_calib(struct athn_softc *);
+void ar5008_do_calib(struct athn_softc *);
+void ar5008_next_calib(struct athn_softc *);
+void ar5008_calib_iq(struct athn_softc *);
+void ar5008_calib_adc_gain(struct athn_softc *);
+void ar5008_calib_adc_dc_off(struct athn_softc *);
+void ar5008_write_txpower(struct athn_softc *, int16_t power[ATHN_POWER_COUNT]);
+void ar5008_set_viterbi_mask(struct athn_softc *, int);
+void ar5008_hw_init(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+uint8_t ar5008_get_vpd(uint8_t, const uint8_t *, const uint8_t *, int);
+void ar5008_get_pdadcs(struct athn_softc *, uint8_t, struct athn_pier *,
+ struct athn_pier *, int, int, uint8_t, uint8_t *, uint8_t *);
+void ar5008_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *,
+ uint8_t, const struct ar_cal_target_power_leg *, int, uint8_t[4]);
+void ar5008_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *,
+ uint8_t, const struct ar_cal_target_power_ht *, int, uint8_t[8]);
+void ar5008_set_noise_immunity_level(struct athn_softc *, int);
+void ar5008_enable_ofdm_weak_signal(struct athn_softc *);
+void ar5008_disable_ofdm_weak_signal(struct athn_softc *);
+void ar5008_set_cck_weak_signal(struct athn_softc *, int);
+void ar5008_set_firstep_level(struct athn_softc *, int);
+void ar5008_set_spur_immunity_level(struct athn_softc *, int);
+
+/* Extern functions. */
+void athn_stop(struct ifnet *, int);
+int athn_interpolate(int, int, int, int, int);
+int athn_txtime(struct athn_softc *, int, int, u_int);
+void athn_inc_tx_trigger_level(struct athn_softc *);
+int athn_tx_pending(struct athn_softc *, int);
+void athn_stop_tx_dma(struct athn_softc *, int);
+void athn_get_delta_slope(uint32_t, uint32_t *, uint32_t *);
+void athn_config_pcie(struct athn_softc *);
+void athn_config_nonpcie(struct athn_softc *);
+uint8_t athn_chan2fbin(struct ieee80211_channel *);
+uint8_t ar5416_get_rf_rev(struct athn_softc *);
+void ar5416_reset_addac(struct athn_softc *, struct ieee80211_channel *);
+void ar5416_rf_reset(struct athn_softc *, struct ieee80211_channel *);
+void ar5416_reset_bb_gain(struct athn_softc *, struct ieee80211_channel *);
+void ar9280_reset_rx_gain(struct athn_softc *, struct ieee80211_channel *);
+void ar9280_reset_tx_gain(struct athn_softc *, struct ieee80211_channel *);
+
+
+int
+ar5008_attach(struct athn_softc *sc)
+{
+ struct athn_ops *ops = &sc->ops;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ar_base_eep_header *base;
+ uint8_t eep_ver, kc_entries_log;
+ int error;
+
+ /* Set callbacks for AR5008, AR9001 and AR9002 families. */
+ ops->gpio_read = ar5008_gpio_read;
+ ops->gpio_write = ar5008_gpio_write;
+ ops->gpio_config_input = ar5008_gpio_config_input;
+ ops->gpio_config_output = ar5008_gpio_config_output;
+ ops->rfsilent_init = ar5008_rfsilent_init;
+
+ ops->dma_alloc = ar5008_dma_alloc;
+ ops->dma_free = ar5008_dma_free;
+ ops->rx_enable = ar5008_rx_enable;
+ ops->intr = ar5008_intr;
+ ops->tx = ar5008_tx;
+
+ ops->set_rf_mode = ar5008_set_rf_mode;
+ ops->rf_bus_request = ar5008_rf_bus_request;
+ ops->rf_bus_release = ar5008_rf_bus_release;
+ ops->set_phy = ar5008_set_phy;
+ ops->set_delta_slope = ar5008_set_delta_slope;
+ ops->enable_antenna_diversity = ar5008_enable_antenna_diversity;
+ ops->init_baseband = ar5008_init_baseband;
+ ops->disable_phy = ar5008_disable_phy;
+ ops->set_rxchains = ar5008_set_rxchains;
+ ops->noisefloor_calib = ar5008_do_noisefloor_calib;
+ ops->init_noisefloor_calib = ar5008_init_noisefloor_calib;
+ ops->get_noisefloor = ar5008_get_noisefloor;
+ ops->apply_noisefloor = ar5008_apply_noisefloor;
+ ops->do_calib = ar5008_do_calib;
+ ops->next_calib = ar5008_next_calib;
+ ops->hw_init = ar5008_hw_init;
+
+ ops->set_noise_immunity_level = ar5008_set_noise_immunity_level;
+ ops->enable_ofdm_weak_signal = ar5008_enable_ofdm_weak_signal;
+ ops->disable_ofdm_weak_signal = ar5008_disable_ofdm_weak_signal;
+ ops->set_cck_weak_signal = ar5008_set_cck_weak_signal;
+ ops->set_firstep_level = ar5008_set_firstep_level;
+ ops->set_spur_immunity_level = ar5008_set_spur_immunity_level;
+
+ /* Set MAC registers offsets. */
+ sc->obs_off = AR_OBS;
+ sc->gpio_input_en_off = AR_GPIO_INPUT_EN_VAL;
+
+ if (!(sc->flags & ATHN_FLAG_PCIE)) {
+ printf("non-pcie\n");
+ athn_config_nonpcie(sc);
+ }
+ else {
+ printf("pcie\n");
+ athn_config_pcie(sc);
+ printf("Exits PCIe condition\n");
+ }
+
+ /* Read entire ROM content in memory. */
+ if ((error = ar5008_read_rom(sc)) != 0) {
+ device_printf(sc->sc_dev, "could not read ROM\n");
+ return (error);
+ }
+
+ /* Get RF revision. */
+ sc->rf_rev = ar5416_get_rf_rev(sc);
+
+ base = sc->eep;
+ eep_ver = (base->version >> 12) & 0xf;
+ sc->eep_rev = (base->version & 0xfff);
+ if (eep_ver != AR_EEP_VER || sc->eep_rev == 0) {
+ device_printf(sc->sc_dev, "unsupported ROM version %d.%d\n",
+ eep_ver, sc->eep_rev);
+ return (EINVAL);
+ }
+
+ if (base->opCapFlags & AR_OPFLAGS_11A) {
+ sc->flags |= ATHN_FLAG_11A;
+ if ((base->opCapFlags & AR_OPFLAGS_11N_5G20) == 0)
+ sc->flags |= ATHN_FLAG_11N;
+#ifdef notyet
+ if ((base->opCapFlags & AR_OPFLAGS_11N_5G40) == 0)
+ sc->flags |= ATHN_FLAG_11N;
+#endif
+ }
+ if (base->opCapFlags & AR_OPFLAGS_11G) {
+ sc->flags |= ATHN_FLAG_11G;
+ if ((base->opCapFlags & AR_OPFLAGS_11N_2G20) == 0)
+ sc->flags |= ATHN_FLAG_11N;
+#ifdef notyet
+ if ((base->opCapFlags & AR_OPFLAGS_11N_2G40) == 0)
+ sc->flags |= ATHN_FLAG_11N;
+#endif
+ }
+
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, base->macAddr);
+
+ /* Check if we have a hardware radio switch. */
+ if (base->rfSilent & AR_EEP_RFSILENT_ENABLED) {
+ sc->flags |= ATHN_FLAG_RFSILENT;
+ /* Get GPIO pin used by hardware radio switch. */
+ sc->rfsilent_pin = MS(base->rfSilent,
+ AR_EEP_RFSILENT_GPIO_SEL);
+ /* Get polarity of hardware radio switch. */
+ if (base->rfSilent & AR_EEP_RFSILENT_POLARITY)
+ sc->flags |= ATHN_FLAG_RFSILENT_REVERSED;
+ }
+
+ /* Get the number of HW key cache entries. */
+ kc_entries_log = MS(base->deviceCap, AR_EEP_DEVCAP_KC_ENTRIES);
+ sc->kc_entries = (kc_entries_log != 0) ?
+ 1 << kc_entries_log : AR_KEYTABLE_SIZE;
+ if (sc->kc_entries > AR_KEYTABLE_SIZE)
+ sc->kc_entries = AR_KEYTABLE_SIZE;
+
+ sc->txchainmask = base->txMask;
+ if (sc->mac_ver == AR_SREV_VERSION_5416_PCI &&
+ !(base->opCapFlags & AR_OPFLAGS_11A)) {
+ /* For single-band AR5416 PCI, use GPIO pin 0. */
+ sc->rxchainmask = ar5008_gpio_read(sc, 0) ? 0x5 : 0x7;
+ } else
+ sc->rxchainmask = base->rxMask;
+
+ ops->setup(sc);
+ return (0);
+}
+
+/*
+ * Read 16-bit word from ROM.
+ */
+int
+ar5008_read_eep_word(struct athn_softc *sc, uint32_t addr, uint16_t *val)
+{
+ uint32_t reg;
+ int ntries;
+
+ reg = AR_READ(sc, AR_EEPROM_OFFSET(addr));
+ for (ntries = 0; ntries < 1000; ntries++) {
+ reg = AR_READ(sc, AR_EEPROM_STATUS_DATA);
+ if (!(reg & (AR_EEPROM_STATUS_DATA_BUSY |
+ AR_EEPROM_STATUS_DATA_PROT_ACCESS))) {
+ *val = MS(reg, AR_EEPROM_STATUS_DATA_VAL);
+ return (0);
+ }
+ DELAY(10);
+ }
+ *val = 0xffff;
+ return (ETIMEDOUT);
+}
+
+int
+ar5008_read_rom(struct athn_softc *sc)
+{
+ uint32_t addr, end;
+ uint16_t magic, sum, *eep;
+ int need_swap = 0;
+ int error;
+
+ /* Determine ROM endianness. */
+ error = ar5008_read_eep_word(sc, AR_EEPROM_MAGIC_OFFSET, &magic);
+ if (error != 0)
+ return (error);
+ if (magic != AR_EEPROM_MAGIC) {
+ if (magic != bswap16(AR_EEPROM_MAGIC)) {
+ DPRINTF(("invalid ROM magic 0x%x != 0x%x\n",
+ magic, AR_EEPROM_MAGIC));
+ return (EIO);
+ }
+ DPRINTF(("non-native ROM endianness\n"));
+ need_swap = 1;
+ }
+
+ /* Allocate space to store ROM in host memory. */
+ sc->eep = malloc(sc->eep_size, M_DEVBUF, M_NOWAIT);
+ if (sc->eep == NULL)
+ return (ENOMEM);
+
+ /* Read entire ROM and compute checksum. */
+ sum = 0;
+ eep = sc->eep;
+ end = sc->eep_base + sc->eep_size / sizeof(uint16_t);
+ for (addr = sc->eep_base; addr < end; addr++, eep++) {
+ if ((error = ar5008_read_eep_word(sc, addr, eep)) != 0) {
+ DPRINTF(("could not read ROM at 0x%x\n", addr));
+ return (error);
+ }
+ if (need_swap)
+ *eep = bswap16(*eep);
+ sum ^= *eep;
+ }
+ if (sum != 0xffff) {
+ device_printf(sc->sc_dev, "bad ROM checksum 0x%04x\n", sum);
+ return (EIO);
+ }
+ if (need_swap)
+ ar5008_swap_rom(sc);
+
+ return (0);
+}
+
+void
+ar5008_swap_rom(struct athn_softc *sc)
+{
+ struct ar_base_eep_header *base = sc->eep;
+
+ /* Swap common fields first. */
+ base->length = bswap16(base->length);
+ base->version = bswap16(base->version);
+ base->regDmn[0] = bswap16(base->regDmn[0]);
+ base->regDmn[1] = bswap16(base->regDmn[1]);
+ base->rfSilent = bswap16(base->rfSilent);
+ base->blueToothOptions = bswap16(base->blueToothOptions);
+ base->deviceCap = bswap16(base->deviceCap);
+
+ /* Swap device-dependent fields. */
+ sc->ops.swap_rom(sc);
+#if 0
+ printf("%s unimplemented\n", __func__);
+#endif
+}
+
+/*
+ * Access to General Purpose Input/Output ports.
+ */
+int
+ar5008_gpio_read(struct athn_softc *sc, int pin)
+{
+ KASSERT(pin < sc->ngpiopins, ("ar5008_gpio_read"));
+ if ((sc->flags & ATHN_FLAG_USB) && !AR_SREV_9271(sc))
+ return (!((AR_READ(sc, AR7010_GPIO_IN) >> pin) & 1));
+ return ((AR_READ(sc, AR_GPIO_IN_OUT) >> (sc->ngpiopins + pin)) & 1);
+}
+
+void
+ar5008_gpio_write(struct athn_softc *sc, int pin, int set)
+{
+
+ uint32_t reg;
+
+ KASSERT(pin < sc->ngpiopins, ("ar5008_gpio_write"));
+
+ if (sc->flags & ATHN_FLAG_USB)
+ set = !set; /* AR9271/AR7010 is reversed. */
+
+ if ((sc->flags & ATHN_FLAG_USB) && !AR_SREV_9271(sc)) {
+ /* Special case for AR7010. */
+ reg = AR_READ(sc, AR7010_GPIO_OUT);
+ if (set)
+ reg |= 1 << pin;
+ else
+ reg &= ~(1 << pin);
+ AR_WRITE(sc, AR7010_GPIO_OUT, reg);
+ } else {
+ reg = AR_READ(sc, AR_GPIO_IN_OUT);
+ if (set)
+ reg |= 1 << pin;
+ else
+ reg &= ~(1 << pin);
+ AR_WRITE(sc, AR_GPIO_IN_OUT, reg);
+ }
+ AR_WRITE_BARRIER(sc);
+#if 0
+#endif
+}
+
+void
+ar5008_gpio_config_input(struct athn_softc *sc, int pin)
+{
+ uint32_t reg;
+
+ if ((sc->flags & ATHN_FLAG_USB) && !AR_SREV_9271(sc)) {
+ /* Special case for AR7010. */
+ AR_SETBITS(sc, AR7010_GPIO_OE, 1 << pin);
+ } else {
+ reg = AR_READ(sc, AR_GPIO_OE_OUT);
+ reg &= ~(AR_GPIO_OE_OUT_DRV_M << (pin * 2));
+ reg |= AR_GPIO_OE_OUT_DRV_NO << (pin * 2);
+ AR_WRITE(sc, AR_GPIO_OE_OUT, reg);
+ }
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_gpio_config_output(struct athn_softc *sc, int pin, int type)
+{
+ uint32_t reg;
+ int mux, off;
+
+ if ((sc->flags & ATHN_FLAG_USB) && !AR_SREV_9271(sc)) {
+ /* Special case for AR7010. */
+ AR_CLRBITS(sc, AR7010_GPIO_OE, 1 << pin);
+ AR_WRITE_BARRIER(sc);
+ return;
+ }
+ mux = pin / 6;
+ off = pin % 6;
+
+ reg = AR_READ(sc, AR_GPIO_OUTPUT_MUX(mux));
+ if (!AR_SREV_9280_20_OR_LATER(sc) && mux == 0)
+ reg = (reg & ~0x1f0) | (reg & 0x1f0) << 1;
+ reg &= ~(0x1f << (off * 5));
+ reg |= (type & 0x1f) << (off * 5);
+ AR_WRITE(sc, AR_GPIO_OUTPUT_MUX(mux), reg);
+
+ reg = AR_READ(sc, AR_GPIO_OE_OUT);
+ reg &= ~(AR_GPIO_OE_OUT_DRV_M << (pin * 2));
+ reg |= AR_GPIO_OE_OUT_DRV_ALL << (pin * 2);
+ AR_WRITE(sc, AR_GPIO_OE_OUT, reg);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_rfsilent_init(struct athn_softc *sc)
+{
+ uint32_t reg;
+
+ /* Configure hardware radio switch. */
+ AR_SETBITS(sc, AR_GPIO_INPUT_EN_VAL, AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
+ reg = AR_READ(sc, AR_GPIO_INPUT_MUX2);
+ reg = RW(reg, AR_GPIO_INPUT_MUX2_RFSILENT, 0);
+ AR_WRITE(sc, AR_GPIO_INPUT_MUX2, reg);
+ ar5008_gpio_config_input(sc, sc->rfsilent_pin);
+ AR_SETBITS(sc, AR_PHY_TEST, AR_PHY_TEST_RFSILENT_BB);
+ if (!(sc->flags & ATHN_FLAG_RFSILENT_REVERSED)) {
+ AR_SETBITS(sc, AR_GPIO_INTR_POL,
+ AR_GPIO_INTR_POL_PIN(sc->rfsilent_pin));
+ }
+ AR_WRITE_BARRIER(sc);
+}
+
+int
+ar5008_dma_alloc(struct athn_softc *sc)
+{
+ int error;
+
+ error = ar5008_tx_alloc(sc);
+ if (error != 0)
+ return (error);
+
+ error = ar5008_rx_alloc(sc);
+ if (error != 0)
+ return (error);
+
+ return (0);
+}
+
+void
+ar5008_dma_free(struct athn_softc *sc)
+{
+ ar5008_tx_free(sc);
+ ar5008_rx_free(sc);
+}
+
+int
+ar5008_tx_alloc(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ struct athn_tx_buf *bf;
+ bus_size_t size;
+ int error, nsegs, i;
+
+ /*
+ * Allocate a pool of Tx descriptors shared between all Tx queues.
+ */
+ size = ATHN_NTXBUFS * AR5008_MAX_SCATTER * sizeof(struct ar_tx_desc);
+
+ error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
+ BUS_DMA_NOWAIT, &sc->map);
+ if (error != 0)
+ goto fail;
+
+ error = bus_dmamem_alloc(sc->sc_dmat, size, 4, 0, &sc->seg, 1,
+ &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
+ if (error != 0)
+ goto fail;
+
+ error = bus_dmamem_map(sc->sc_dmat, &sc->seg, 1, size,
+ (caddr_t *)&sc->descs, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
+ if (error != 0)
+ goto fail;
+
+ error = bus_dmamap_load_raw(sc->sc_dmat, sc->map, &sc->seg, 1, size,
+ BUS_DMA_NOWAIT);
+ if (error != 0)
+ goto fail;
+
+ SIMPLEQ_INIT(&sc->txbufs);
+ for (i = 0; i < ATHN_NTXBUFS; i++) {
+ bf = &sc->txpool[i];
+
+ error = bus_dmamap_create(sc->sc_dmat, ATHN_TXBUFSZ,
+ AR5008_MAX_SCATTER, ATHN_TXBUFSZ, 0, BUS_DMA_NOWAIT,
+ &bf->bf_map);
+ if (error != 0) {
+ printf(": could not create Tx buf DMA map\n");
+ //,
+ sc->sc_dev.dv_xname);
+// printf("%s: could not create Tx buf DMA map\n",
+// sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ bf->bf_descs =
+ &((struct ar_tx_desc *)sc->descs)[i * AR5008_MAX_SCATTER];
+ bf->bf_daddr = sc->map->dm_segs[0].ds_addr +
+ i * AR5008_MAX_SCATTER * sizeof(struct ar_tx_desc);
+
+ SIMPLEQ_INSERT_TAIL(&sc->txbufs, bf, bf_list);
+ }
+ return (0);
+ fail:
+ ar5008_tx_free(sc);
+ return (error);
+#endif
+}
+
+void
+ar5008_tx_free(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ struct athn_tx_buf *bf;
+ int i;
+
+ for (i = 0; i < ATHN_NTXBUFS; i++) {
+ bf = &sc->txpool[i];
+
+ if (bf->bf_map != NULL)
+ bus_dmamap_destroy(sc->sc_dmat, bf->bf_map);
+ }
+ /* Free Tx descriptors. */
+ if (sc->map != NULL) {
+ if (sc->descs != NULL) {
+ bus_dmamap_unload(sc->sc_dmat, sc->map);
+ bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->descs,
+ ATHN_NTXBUFS * AR5008_MAX_SCATTER *
+ sizeof(struct ar_tx_desc));
+ bus_dmamem_free(sc->sc_dmat, &sc->seg, 1);
+ }
+ bus_dmamap_destroy(sc->sc_dmat, sc->map);
+ }
+#endif
+}
+
+int
+ar5008_rx_alloc(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ struct athn_rxq *rxq = &sc->rxq[0];
+ struct athn_rx_buf *bf;
+ struct ar_rx_desc *ds;
+ bus_size_t size;
+ int error, nsegs, i;
+
+ rxq->bf = mallocarray(ATHN_NRXBUFS, sizeof(*bf), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (rxq->bf == NULL)
+ return (ENOMEM);
+
+ size = ATHN_NRXBUFS * sizeof(struct ar_rx_desc);
+
+ error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
+ BUS_DMA_NOWAIT, &rxq->map);
+ if (error != 0)
+ goto fail;
+
+ error = bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, &rxq->seg, 1,
+ &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
+ if (error != 0)
+ goto fail;
+
+ error = bus_dmamem_map(sc->sc_dmat, &rxq->seg, 1, size,
+ (caddr_t *)&rxq->descs, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
+ if (error != 0)
+ goto fail;
+
+ error = bus_dmamap_load_raw(sc->sc_dmat, rxq->map, &rxq->seg, 1,
+ size, BUS_DMA_NOWAIT);
+ if (error != 0)
+ goto fail;
+
+ for (i = 0; i < ATHN_NRXBUFS; i++) {
+ bf = &rxq->bf[i];
+ ds = &((struct ar_rx_desc *)rxq->descs)[i];
+
+ error = bus_dmamap_create(sc->sc_dmat, ATHN_RXBUFSZ, 1,
+ ATHN_RXBUFSZ, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
+ &bf->bf_map);
+ if (error != 0) {
+ printf(": could not create Rx buf DMA map\n");
+// printf("%s: could not create Rx buf DMA map\n",
+// sc->sc_dev.dv_xname);
+ goto fail;
+ }
+ /*
+ * Assumes MCLGETL returns cache-line-size aligned buffers.
+ */
+ bf->bf_m = MCLGETL(NULL, M_DONTWAIT, ATHN_RXBUFSZ);
+ if (bf->bf_m == NULL) {
+ printf(": could not allocate Rx mbuf\n");
+// printf("%s: could not allocate Rx mbuf\n",
+// sc->sc_dev.dv_xname);
+ error = ENOBUFS;
+ goto fail;
+ }
+
+ error = bus_dmamap_load(sc->sc_dmat, bf->bf_map,
+ mtod(bf->bf_m, void *), ATHN_RXBUFSZ, NULL,
+ BUS_DMA_NOWAIT | BUS_DMA_READ);
+ if (error != 0) {
+ printf(": could not DMA map Rx buffer\n");
+// printf("%s: could not DMA map Rx buffer\n",
+// sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, ATHN_RXBUFSZ,
+ BUS_DMASYNC_PREREAD);
+
+ bf->bf_desc = ds;
+ bf->bf_daddr = rxq->map->dm_segs[0].ds_addr +
+ i * sizeof(struct ar_rx_desc);
+ }
+ return (0);
+ fail:
+ ar5008_rx_free(sc);
+ return (error);
+#endif
+}
+
+void
+ar5008_rx_free(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ struct athn_rxq *rxq = &sc->rxq[0];
+ struct athn_rx_buf *bf;
+ int i;
+
+ if (rxq->bf == NULL)
+ return;
+ for (i = 0; i < ATHN_NRXBUFS; i++) {
+ bf = &rxq->bf[i];
+
+ if (bf->bf_map != NULL)
+ bus_dmamap_destroy(sc->sc_dmat, bf->bf_map);
+ m_freem(bf->bf_m);
+ }
+ free(rxq->bf, M_DEVBUF, 0);
+
+ /* Free Rx descriptors. */
+ if (rxq->map != NULL) {
+ if (rxq->descs != NULL) {
+ bus_dmamap_unload(sc->sc_dmat, rxq->map);
+ bus_dmamem_unmap(sc->sc_dmat, (caddr_t)rxq->descs,
+ ATHN_NRXBUFS * sizeof(struct ar_rx_desc));
+ bus_dmamem_free(sc->sc_dmat, &rxq->seg, 1);
+ }
+ bus_dmamap_destroy(sc->sc_dmat, rxq->map);
+ }
+#endif
+}
+
+void
+ar5008_rx_enable(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ struct athn_rxq *rxq = &sc->rxq[0];
+ struct athn_rx_buf *bf;
+ struct ar_rx_desc *ds;
+ int i;
+
+ /* Setup and link Rx descriptors. */
+ SIMPLEQ_INIT(&rxq->head);
+ rxq->lastds = NULL;
+ for (i = 0; i < ATHN_NRXBUFS; i++) {
+ bf = &rxq->bf[i];
+ ds = bf->bf_desc;
+
+ memset(ds, 0, sizeof(*ds));
+ ds->ds_data = bf->bf_map->dm_segs[0].ds_addr;
+ ds->ds_ctl1 = SM(AR_RXC1_BUF_LEN, ATHN_RXBUFSZ);
+
+ if (rxq->lastds != NULL) {
+ ((struct ar_rx_desc *)rxq->lastds)->ds_link =
+ bf->bf_daddr;
+ }
+ SIMPLEQ_INSERT_TAIL(&rxq->head, bf, bf_list);
+ rxq->lastds = ds;
+ }
+ bus_dmamap_sync(sc->sc_dmat, rxq->map, 0, rxq->map->dm_mapsize,
+ BUS_DMASYNC_PREREAD);
+
+ /* Enable Rx. */
+ AR_WRITE(sc, AR_RXDP, SIMPLEQ_FIRST(&rxq->head)->bf_daddr);
+ AR_WRITE(sc, AR_CR, AR_CR_RXE);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+#if 0
+#if NBPFILTER > 0
+void
+ar5008_rx_radiotap(struct athn_softc *sc, struct mbuf *m,
+ struct ar_rx_desc *ds)
+{
+#define IEEE80211_RADIOTAP_F_SHORTGI 0x80 /* XXX from FBSD */
+
+ struct athn_rx_radiotap_header *tap = &sc->sc_rxtap;
+ struct ieee80211com *ic = &sc->sc_ic;
+ uint64_t tsf;
+ uint32_t tstamp;
+ uint8_t rate;
+
+ /* Extend the 15-bit timestamp from Rx descriptor to 64-bit TSF. */
+ tstamp = ds->ds_status2;
+ tsf = AR_READ(sc, AR_TSF_U32);
+ tsf = tsf << 32 | AR_READ(sc, AR_TSF_L32);
+ if ((tsf & 0x7fff) < tstamp)
+ tsf -= 0x8000;
+ tsf = (tsf & ~0x7fff) | tstamp;
+
+ tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
+ tap->wr_tsft = htole64(tsf);
+ tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
+ tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
+ tap->wr_dbm_antsignal = MS(ds->ds_status4, AR_RXS4_RSSI_COMBINED);
+ /* XXX noise. */
+ tap->wr_antenna = MS(ds->ds_status3, AR_RXS3_ANTENNA);
+ tap->wr_rate = 0; /* In case it can't be found below. */
+ if (AR_SREV_5416_20_OR_LATER(sc))
+ rate = MS(ds->ds_status0, AR_RXS0_RATE);
+ else
+ rate = MS(ds->ds_status3, AR_RXS3_RATE);
+ if (rate & 0x80) { /* HT. */
+ /* Bit 7 set means HT MCS instead of rate. */
+ tap->wr_rate = rate;
+ if (!(ds->ds_status3 & AR_RXS3_GI))
+ tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI;
+
+ } else if (rate & 0x10) { /* CCK. */
+ if (rate & 0x04)
+ tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+ switch (rate & ~0x14) {
+ case 0xb: tap->wr_rate = 2; break;
+ case 0xa: tap->wr_rate = 4; break;
+ case 0x9: tap->wr_rate = 11; break;
+ case 0x8: tap->wr_rate = 22; break;
+ }
+ } else { /* OFDM. */
+ switch (rate) {
+ case 0xb: tap->wr_rate = 12; break;
+ case 0xf: tap->wr_rate = 18; break;
+ case 0xa: tap->wr_rate = 24; break;
+ case 0xe: tap->wr_rate = 36; break;
+ case 0x9: tap->wr_rate = 48; break;
+ case 0xd: tap->wr_rate = 72; break;
+ case 0x8: tap->wr_rate = 96; break;
+ case 0xc: tap->wr_rate = 108; break;
+ }
+ }
+ bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_DIRECTION_IN);
+}
+#endif
+#endif // This is the FreeBSD endif
+
+int
+ar5008_ccmp_decap(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_key *k;
+ struct ieee80211_frame *wh;
+ struct ieee80211_rx_ba *ba;
+ uint64_t pn, *prsc;
+ u_int8_t *ivp;
+ uint8_t tid;
+ int hdrlen, hasqos;
+ uintptr_t entry;
+
+ wh = mtod(m, struct ieee80211_frame *);
+ hdrlen = ieee80211_get_hdrlen(wh);
+ ivp = mtod(m, u_int8_t *) + hdrlen;
+
+ /* find key for decryption */
+ k = ieee80211_get_rxkey(ic, m, ni);
+ if (k == NULL || k->k_cipher != IEEE80211_CIPHER_CCMP)
+ return 1;
+
+ /* Sanity checks to ensure this is really a key we installed. */
+ entry = (uintptr_t)k->k_priv;
+ if (k->k_flags & IEEE80211_KEY_GROUP) {
+ if (k->k_id >= IEEE80211_WEP_NKID ||
+ entry != k->k_id)
+ return 1;
+ } else {
+#ifndef IEEE80211_STA_ONLY
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+ if (entry != IEEE80211_WEP_NKID +
+ IEEE80211_AID(ni->ni_associd))
+ return 1;
+ } else
+#endif
+ if (entry != IEEE80211_WEP_NKID)
+ return 1;
+ }
+
+ /* Check that ExtIV bit is set. */
+ if (!(ivp[3] & IEEE80211_WEP_EXTIV))
+ return 1;
+
+ hasqos = ieee80211_has_qos(wh);
+ tid = hasqos ? ieee80211_get_qos(wh) & IEEE80211_QOS_TID : 0;
+ ba = hasqos ? &ni->ni_rx_ba[tid] : NULL;
+ prsc = &k->k_rsc[tid];
+
+ /* Extract the 48-bit PN from the CCMP header. */
+ pn = (uint64_t)ivp[0] |
+ (uint64_t)ivp[1] << 8 |
+ (uint64_t)ivp[4] << 16 |
+ (uint64_t)ivp[5] << 24 |
+ (uint64_t)ivp[6] << 32 |
+ (uint64_t)ivp[7] << 40;
+ if (pn <= *prsc) {
+ ic->ic_stats.is_ccmp_replays++;
+ return 1;
+ }
+ /* Last seen packet number is updated in ieee80211_inputm(). */
+
+ /* Strip MIC. IV will be stripped by ieee80211_inputm(). */
+ m_adj(m, -IEEE80211_CCMP_MICLEN);
+ return 0;
+#endif
+}
+
+static __inline int
+//ar5008_rx_process(struct athn_softc *sc, struct mbuf_list *ml)
+ar5008_rx_process(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+ struct athn_rxq *rxq = &sc->rxq[0];
+ struct athn_rx_buf *bf, *nbf;
+ struct ar_rx_desc *ds;
+ struct ieee80211_frame *wh;
+ struct ieee80211_rxinfo rxi;
+ struct ieee80211_node *ni;
+ struct mbuf *m, *m1;
+ int error, len, michael_mic_failure = 0;
+
+ bf = SIMPLEQ_FIRST(&rxq->head);
+ if (__predict_false(bf == NULL)) { /* Should not happen. */
+ printf(": Rx queue is empty!\n"); //, sc->sc_dev.dv_xname);
+// printf("%s: Rx queue is empty!\n", sc->sc_dev.dv_xname);
+ return (ENOENT);
+ }
+ ds = bf->bf_desc;
+
+ if (!(ds->ds_status8 & AR_RXS8_DONE)) {
+ /*
+ * On some parts, the status words can get corrupted
+ * (including the "done" bit), so we check the next
+ * descriptor "done" bit. If it is set, it is a good
+ * indication that the status words are corrupted, so
+ * we skip this descriptor and drop the frame.
+ */
+ nbf = SIMPLEQ_NEXT(bf, bf_list);
+ if (nbf != NULL &&
+ (((struct ar_rx_desc *)nbf->bf_desc)->ds_status8 &
+ AR_RXS8_DONE)) {
+ DPRINTF(("corrupted descriptor status=0x%x\n",
+ ds->ds_status8));
+ /* HW will not "move" RXDP in this case, so do it. */
+ AR_WRITE(sc, AR_RXDP, nbf->bf_daddr);
+ AR_WRITE_BARRIER(sc);
+ ifp->if_ierrors++;
+ goto skip;
+ }
+ return (EBUSY);
+ }
+
+ if (__predict_false(ds->ds_status1 & AR_RXS1_MORE)) {
+ /* Drop frames that span multiple Rx descriptors. */
+ DPRINTF(("dropping split frame\n"));
+ ifp->if_ierrors++;
+ goto skip;
+ }
+ if (!(ds->ds_status8 & AR_RXS8_FRAME_OK)) {
+ if (ds->ds_status8 & AR_RXS8_CRC_ERR)
+ DPRINTFN(6, ("CRC error\n"));
+ else if (ds->ds_status8 & AR_RXS8_PHY_ERR)
+ DPRINTFN(6, ("PHY error=0x%x\n",
+ MS(ds->ds_status8, AR_RXS8_PHY_ERR_CODE)));
+ else if (ds->ds_status8 & (AR_RXS8_DECRYPT_CRC_ERR |
+ AR_RXS8_KEY_MISS | AR_RXS8_DECRYPT_BUSY_ERR)) {
+ DPRINTFN(6, ("Decryption CRC error\n"));
+ ic->ic_stats.is_ccmp_dec_errs++;
+ } else if (ds->ds_status8 & AR_RXS8_MICHAEL_ERR) {
+ DPRINTFN(2, ("Michael MIC failure\n"));
+ michael_mic_failure = 1;
+ }
+ if (!michael_mic_failure) {
+ ifp->if_ierrors++;
+ goto skip;
+ }
+ } else {
+ if (ds->ds_status8 & (AR_RXS8_CRC_ERR | AR_RXS8_PHY_ERR |
+ AR_RXS8_DECRYPT_CRC_ERR | AR_RXS8_MICHAEL_ERR)) {
+ ifp->if_ierrors++;
+ goto skip;
+ }
+ }
+
+ len = MS(ds->ds_status1, AR_RXS1_DATA_LEN);
+ if (__predict_false(len < IEEE80211_MIN_LEN || len > ATHN_RXBUFSZ)) {
+ DPRINTF(("corrupted descriptor length=%d\n", len));
+ ifp->if_ierrors++;
+ goto skip;
+ }
+
+ /* Allocate a new Rx buffer. */
+ m1 = MCLGETL(NULL, M_DONTWAIT, ATHN_RXBUFSZ);
+ if (__predict_false(m1 == NULL)) {
+ ic->ic_stats.is_rx_nombuf++;
+ ifp->if_ierrors++;
+ goto skip;
+ }
+
+ /* Sync and unmap the old Rx buffer. */
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, ATHN_RXBUFSZ,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->sc_dmat, bf->bf_map);
+
+ /* Map the new Rx buffer. */
+ error = bus_dmamap_load(sc->sc_dmat, bf->bf_map, mtod(m1, void *),
+ ATHN_RXBUFSZ, NULL, BUS_DMA_NOWAIT | BUS_DMA_READ);
+ if (__predict_false(error != 0)) {
+ m_freem(m1);
+
+ /* Remap the old Rx buffer or panic. */
+ error = bus_dmamap_load(sc->sc_dmat, bf->bf_map,
+ mtod(bf->bf_m, void *), ATHN_RXBUFSZ, NULL,
+ BUS_DMA_NOWAIT | BUS_DMA_READ);
+ KASSERT(error != 0, ("ar5008_rx_process"));
+ ifp->if_ierrors++;
+ goto skip;
+ }
+
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, ATHN_RXBUFSZ,
+ BUS_DMASYNC_PREREAD);
+
+ /* Write physical address of new Rx buffer. */
+ ds->ds_data = bf->bf_map->dm_segs[0].ds_addr;
+
+ m = bf->bf_m;
+ bf->bf_m = m1;
+
+ /* Finalize mbuf. */
+ m->m_pkthdr.len = m->m_len = len;
+
+ wh = mtod(m, struct ieee80211_frame *);
+
+ if (michael_mic_failure) {
+ /*
+ * Check that it is not a control frame
+ * (invalid MIC failures on valid ctl frames).
+ * Validate the transmitter's address to avoid passing
+ * corrupt frames with bogus addresses to net80211.
+ */
+ if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) {
+ switch (ic->ic_opmode) {
+#ifndef IEEE80211_STA_ONLY
+ case IEEE80211_M_HOSTAP:
+ if (ieee80211_find_node(ic, wh->i_addr2))
+ michael_mic_failure = 0;
+ break;
+#endif
+ case IEEE80211_M_STA:
+ if (IEEE80211_ADDR_EQ(wh->i_addr2,
+ ic->ic_bss->ni_macaddr))
+ michael_mic_failure = 0;
+ break;
+ case IEEE80211_M_MONITOR:
+ michael_mic_failure = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (michael_mic_failure) {
+ /* Report Michael MIC failures to net80211. */
+ if ((ic->ic_rsnciphers & IEEE80211_CIPHER_TKIP) ||
+ ic->ic_rsngroupcipher == IEEE80211_CIPHER_TKIP) {
+ ic->ic_stats.is_rx_locmicfail++;
+ ieee80211_michael_mic_failure(ic, 0);
+ }
+ ifp->if_ierrors++;
+ m_freem(m);
+ goto skip;
+ }
+ }
+
+ /* Grab a reference to the source node. */
+ ni = ieee80211_find_rxnode(ic, wh);
+
+ /* Remove any HW padding after the 802.11 header. */
+ if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) {
+ u_int hdrlen = ieee80211_get_hdrlen(wh);
+ if (hdrlen & 3) {
+ memmove((caddr_t)wh + 2, wh, hdrlen);
+ m_adj(m, 2);
+ }
+ wh = mtod(m, struct ieee80211_frame *);
+ }
+#if NBPFILTER > 0
+ if (__predict_false(sc->sc_drvbpf != NULL))
+ ar5008_rx_radiotap(sc, m, ds);
+#endif
+ /* Trim 802.11 FCS after radiotap. */
+ m_adj(m, -IEEE80211_CRC_LEN);
+
+ /* Send the frame to the 802.11 layer. */
+ memset(&rxi, 0, sizeof(rxi));
+ rxi.rxi_rssi = MS(ds->ds_status4, AR_RXS4_RSSI_COMBINED);
+ rxi.rxi_rssi += AR_DEFAULT_NOISE_FLOOR;
+ rxi.rxi_tstamp = ds->ds_status2;
+ if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL) &&
+ (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
+ (ic->ic_flags & IEEE80211_F_RSNON) &&
+ (ni->ni_flags & IEEE80211_NODE_RXPROT) &&
+ ((!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+ ni->ni_rsncipher == IEEE80211_CIPHER_CCMP) ||
+ (IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+ ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP))) {
+ if (ar5008_ccmp_decap(sc, m, ni) != 0) {
+ ifp->if_ierrors++;
+ ieee80211_release_node(ic, ni);
+ m_freem(m);
+ goto skip;
+ }
+ rxi.rxi_flags |= IEEE80211_RXI_HWDEC;
+ }
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
+
+ /* Node is no longer needed. */
+ ieee80211_release_node(ic, ni);
+
+ skip:
+ /* Unlink this descriptor from head. */
+ SIMPLEQ_REMOVE_HEAD(&rxq->head, bf_list);
+ memset(&ds->ds_status0, 0, 36); /* XXX Really needed? */
+ ds->ds_status8 &= ~AR_RXS8_DONE;
+ ds->ds_link = 0;
+
+ /* Re-use this descriptor and link it to tail. */
+ if (__predict_true(!SIMPLEQ_EMPTY(&rxq->head)))
+ ((struct ar_rx_desc *)rxq->lastds)->ds_link = bf->bf_daddr;
+ else
+ AR_WRITE(sc, AR_RXDP, bf->bf_daddr);
+ SIMPLEQ_INSERT_TAIL(&rxq->head, bf, bf_list);
+ rxq->lastds = ds;
+
+ /* Re-enable Rx. */
+ AR_WRITE(sc, AR_CR, AR_CR_RXE);
+ AR_WRITE_BARRIER(sc);
+ return (0);
+#endif
+}
+
+void
+ar5008_rx_intr(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+
+ while (ar5008_rx_process(sc, &ml) == 0);
+
+ if_input(ifp, &ml);
+#endif
+}
+
+int
+ar5008_tx_process(struct athn_softc *sc, int qid)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+ struct athn_txq *txq = &sc->txq[qid];
+ struct athn_node *an;
+ struct ieee80211_node *ni;
+ struct athn_tx_buf *bf;
+ struct ar_tx_desc *ds;
+ uint8_t failcnt;
+ int txfail = 0, rtscts;
+
+ bf = SIMPLEQ_FIRST(&txq->head);
+ if (bf == NULL)
+ return (ENOENT);
+ /* Get descriptor of last DMA segment. */
+ ds = &((struct ar_tx_desc *)bf->bf_descs)[bf->bf_map->dm_nsegs - 1];
+
+ if (!(ds->ds_status9 & AR_TXS9_DONE))
+ return (EBUSY);
+
+ SIMPLEQ_REMOVE_HEAD(&txq->head, bf_list);
+
+ sc->sc_tx_timer = 0;
+
+ /* These status bits are valid if “FRM_XMIT_OK” is clear. */
+ if ((ds->ds_status1 & AR_TXS1_FRM_XMIT_OK) == 0) {
+ txfail = (ds->ds_status1 & AR_TXS1_EXCESSIVE_RETRIES);
+ if (txfail)
+ ifp->if_oerrors++;
+ if (ds->ds_status1 & AR_TXS1_UNDERRUN)
+ athn_inc_tx_trigger_level(sc);
+ }
+
+ an = (struct athn_node *)bf->bf_ni;
+ ni = (struct ieee80211_node *)bf->bf_ni;
+
+ /*
+ * NB: the data fail count contains the number of un-acked tries
+ * for the final series used. We must add the number of tries for
+ * each series that was fully processed to punish transmit rates in
+ * the earlier series which did not perform well.
+ */
+ failcnt = MS(ds->ds_status1, AR_TXS1_DATA_FAIL_CNT);
+ /* Assume two tries per series, as per AR_TXC2_XMIT_DATA_TRIESx. */
+ failcnt += MS(ds->ds_status9, AR_TXS9_FINAL_IDX) * 2;
+
+ rtscts = (ds->ds_ctl0 & (AR_TXC0_RTS_ENABLE | AR_TXC0_CTS_ENABLE));
+
+ /* Update rate control statistics. */
+ if ((ni->ni_flags & IEEE80211_NODE_HT) && ic->ic_fixed_mcs == -1) {
+ const struct ieee80211_ht_rateset *rs =
+ ieee80211_ra_get_ht_rateset(bf->bf_txmcs, 0 /* chan40 */,
+ ieee80211_node_supports_ht_sgi20(ni));
+ unsigned int retries = 0, i;
+ int mcs = bf->bf_txmcs;
+
+ /* With RTS/CTS each Tx series used the same MCS. */
+ if (rtscts) {
+ retries = failcnt;
+ } else {
+ for (i = 0; i < failcnt; i++) {
+ if (mcs > rs->min_mcs) {
+ ieee80211_ra_add_stats_ht(&an->rn,
+ ic, ni, mcs, 1, 1);
+ if (i % 2) /* two tries per series */
+ mcs--;
+ } else
+ retries++;
+ }
+ }
+
+ if (txfail && retries == 0) {
+ ieee80211_ra_add_stats_ht(&an->rn, ic, ni,
+ mcs, 1, 1);
+ } else {
+ ieee80211_ra_add_stats_ht(&an->rn, ic, ni,
+ mcs, retries + 1, retries);
+ }
+ if (ic->ic_state == IEEE80211_S_RUN) {
+#ifndef IEEE80211_STA_ONLY
+ if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
+ ni->ni_state == IEEE80211_STA_ASSOC)
+#endif
+ ieee80211_ra_choose(&an->rn, ic, ni);
+ }
+ } else if (ic->ic_fixed_rate == -1) {
+ an->amn.amn_txcnt++;
+ if (failcnt > 0)
+ an->amn.amn_retrycnt++;
+ }
+ DPRINTFN(5, ("Tx done qid=%d status1=%d fail count=%d\n",
+ qid, ds->ds_status1, failcnt));
+
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->sc_dmat, bf->bf_map);
+
+ m_freem(bf->bf_m);
+ bf->bf_m = NULL;
+ ieee80211_release_node(ic, bf->bf_ni);
+ bf->bf_ni = NULL;
+
+ /* Link Tx buffer back to global free list. */
+ SIMPLEQ_INSERT_TAIL(&sc->txbufs, bf, bf_list);
+ return (0);
+#endif
+}
+
+void
+ar5008_tx_intr(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+ uint16_t mask = 0;
+ uint32_t reg;
+ int qid;
+
+ reg = AR_READ(sc, AR_ISR_S0_S);
+ mask |= MS(reg, AR_ISR_S0_QCU_TXOK);
+ mask |= MS(reg, AR_ISR_S0_QCU_TXDESC);
+
+ reg = AR_READ(sc, AR_ISR_S1_S);
+ mask |= MS(reg, AR_ISR_S1_QCU_TXERR);
+ mask |= MS(reg, AR_ISR_S1_QCU_TXEOL);
+
+ DPRINTFN(4, ("Tx interrupt mask=0x%x\n", mask));
+ for (qid = 0; mask != 0; mask >>= 1, qid++) {
+ if (mask & 1)
+ while (ar5008_tx_process(sc, qid) == 0);
+ }
+ if (!SIMPLEQ_EMPTY(&sc->txbufs)) {
+ ifq_clr_oactive(&ifp->if_snd);
+ ifp->if_start(ifp);
+ }
+#endif
+}
+
+#ifndef IEEE80211_STA_ONLY
+/*
+ * Process Software Beacon Alert interrupts.
+ */
+int
+ar5008_swba_intr(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+ struct ieee80211_node *ni = ic->ic_bss;
+ struct athn_tx_buf *bf = sc->bcnbuf;
+ struct ieee80211_frame *wh;
+ struct ar_tx_desc *ds;
+ struct mbuf *m;
+ uint8_t ridx, hwrate;
+ int error, totlen;
+
+ if (ic->ic_tim_mcast_pending &&
+ mq_empty(&ni->ni_savedq) &&
+ SIMPLEQ_EMPTY(&sc->txq[ATHN_QID_CAB].head))
+ ic->ic_tim_mcast_pending = 0;
+
+ if (ic->ic_dtim_count == 0)
+ ic->ic_dtim_count = ic->ic_dtim_period - 1;
+ else
+ ic->ic_dtim_count--;
+
+ /* Make sure previous beacon has been sent. */
+ if (athn_tx_pending(sc, ATHN_QID_BEACON)) {
+ DPRINTF(("beacon stuck\n"));
+ return (EBUSY);
+ }
+ /* Get new beacon. */
+ m = ieee80211_beacon_alloc(ic, ic->ic_bss);
+ if (__predict_false(m == NULL))
+ return (ENOBUFS);
+ /* Assign sequence number. */
+ wh = mtod(m, struct ieee80211_frame *);
+ *(uint16_t *)&wh->i_seq[0] =
+ htole16(ic->ic_bss->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
+ ic->ic_bss->ni_txseq++;
+
+ /* Unmap and free old beacon if any. */
+ if (__predict_true(bf->bf_m != NULL)) {
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0,
+ bf->bf_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->sc_dmat, bf->bf_map);
+ m_freem(bf->bf_m);
+ bf->bf_m = NULL;
+ }
+ /* DMA map new beacon. */
+ error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m,
+ BUS_DMA_NOWAIT | BUS_DMA_WRITE);
+ if (__predict_false(error != 0)) {
+ m_freem(m);
+ return (error);
+ }
+ bf->bf_m = m;
+
+ /* Setup Tx descriptor (simplified ar5008_tx()). */
+ ds = bf->bf_descs;
+ memset(ds, 0, sizeof(*ds));
+
+ totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
+ ds->ds_ctl0 = SM(AR_TXC0_FRAME_LEN, totlen);
+ ds->ds_ctl0 |= SM(AR_TXC0_XMIT_POWER, AR_MAX_RATE_POWER);
+ ds->ds_ctl1 = SM(AR_TXC1_FRAME_TYPE, AR_FRAME_TYPE_BEACON);
+ ds->ds_ctl1 |= AR_TXC1_NO_ACK;
+ ds->ds_ctl6 = SM(AR_TXC6_ENCR_TYPE, AR_ENCR_TYPE_CLEAR);
+
+ /* Write number of tries. */
+ ds->ds_ctl2 = SM(AR_TXC2_XMIT_DATA_TRIES0, 1);
+
+ /* Write Tx rate. */
+ ridx = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ?
+ ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK1;
+ hwrate = athn_rates[ridx].hwrate;
+ ds->ds_ctl3 = SM(AR_TXC3_XMIT_RATE0, hwrate);
+
+ /* Write Tx chains. */
+ ds->ds_ctl7 = SM(AR_TXC7_CHAIN_SEL0, sc->txchainmask);
+
+ ds->ds_data = bf->bf_map->dm_segs[0].ds_addr;
+ /* Segment length must be a multiple of 4. */
+ ds->ds_ctl1 |= SM(AR_TXC1_BUF_LEN,
+ (bf->bf_map->dm_segs[0].ds_len + 3) & ~3);
+
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize,
+ BUS_DMASYNC_PREWRITE);
+
+ /* Stop Tx DMA before putting the new beacon on the queue. */
+ athn_stop_tx_dma(sc, ATHN_QID_BEACON);
+
+ AR_WRITE(sc, AR_QTXDP(ATHN_QID_BEACON), bf->bf_daddr);
+
+ for(;;) {
+ if (SIMPLEQ_EMPTY(&sc->txbufs))
+ break;
+
+ m = mq_dequeue(&ni->ni_savedq);
+ if (m == NULL)
+ break;
+ if (!mq_empty(&ni->ni_savedq)) {
+ /* more queued frames, set the more data bit */
+ wh = mtod(m, struct ieee80211_frame *);
+ wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
+ }
+
+ if (sc->ops.tx(sc, m, ni, ATHN_TXFLAG_CAB) != 0) {
+ ieee80211_release_node(ic, ni);
+ ifp->if_oerrors++;
+ break;
+ }
+ }
+
+ /* Kick Tx. */
+ AR_WRITE(sc, AR_Q_TXE, 1 << ATHN_QID_BEACON);
+ AR_WRITE_BARRIER(sc);
+ return (0);
+#endif
+}
+#endif
+
+int
+ar5008_intr(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ uint32_t intr, intr2, intr5, sync;
+
+ /* Get pending interrupts. */
+ intr = AR_READ(sc, AR_INTR_ASYNC_CAUSE);
+ if (!(intr & AR_INTR_MAC_IRQ) || intr == AR_INTR_SPURIOUS) {
+ intr = AR_READ(sc, AR_INTR_SYNC_CAUSE);
+ if (intr == AR_INTR_SPURIOUS || (intr & sc->isync) == 0)
+ return (0); /* Not for us. */
+ }
+
+ if ((AR_READ(sc, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) &&
+ (AR_READ(sc, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_ON)
+ intr = AR_READ(sc, AR_ISR);
+ else
+ intr = 0;
+ sync = AR_READ(sc, AR_INTR_SYNC_CAUSE) & sc->isync;
+ if (intr == 0 && sync == 0)
+ return (0); /* Not for us. */
+
+ if (intr != 0) {
+ if (intr & AR_ISR_BCNMISC) {
+ intr2 = AR_READ(sc, AR_ISR_S2);
+ if (intr2 & AR_ISR_S2_TIM)
+ /* TBD */;
+ if (intr2 & AR_ISR_S2_TSFOOR)
+ /* TBD */;
+ }
+ intr = AR_READ(sc, AR_ISR_RAC);
+ if (intr == AR_INTR_SPURIOUS)
+ return (1);
+
+#ifndef IEEE80211_STA_ONLY
+ if (intr & AR_ISR_SWBA)
+ ar5008_swba_intr(sc);
+#endif
+ if (intr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
+ ar5008_rx_intr(sc);
+ if (intr & (AR_ISR_RXOK | AR_ISR_RXERR | AR_ISR_RXORN))
+ ar5008_rx_intr(sc);
+
+ if (intr & (AR_ISR_TXOK | AR_ISR_TXDESC |
+ AR_ISR_TXERR | AR_ISR_TXEOL))
+ ar5008_tx_intr(sc);
+
+ intr5 = AR_READ(sc, AR_ISR_S5_S);
+ if (intr & AR_ISR_GENTMR) {
+ if (intr5 & AR_ISR_GENTMR) {
+ DPRINTF(("GENTMR trigger=%d thresh=%d\n",
+ MS(intr5, AR_ISR_S5_GENTIMER_TRIG),
+ MS(intr5, AR_ISR_S5_GENTIMER_THRESH)));
+ }
+ }
+
+ if (intr5 & AR_ISR_S5_TIM_TIMER)
+ /* TBD */;
+ }
+ if (sync != 0) {
+ if (sync & (AR_INTR_SYNC_HOST1_FATAL |
+ AR_INTR_SYNC_HOST1_PERR))
+ /* TBD */;
+
+ if (sync & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
+ AR_WRITE(sc, AR_RC, AR_RC_HOSTIF);
+ AR_WRITE(sc, AR_RC, 0);
+ }
+
+ if ((sc->flags & ATHN_FLAG_RFSILENT) &&
+ (sync & AR_INTR_SYNC_GPIO_PIN(sc->rfsilent_pin))) {
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+// printf("%s: radio switch turned off\n",
+// sc->sc_dev.dv_xname);
+ printf(": radio switch turned off\n");
+ /* Turn the interface down. */
+ athn_stop(ifp, 1);
+ return (1);
+ }
+
+ AR_WRITE(sc, AR_INTR_SYNC_CAUSE, sync);
+ (void)AR_READ(sc, AR_INTR_SYNC_CAUSE);
+ }
+ return (1);
+#endif
+}
+
+int
+ar5008_ccmp_encap(struct mbuf *m, u_int hdrlen, struct ieee80211_key *k)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ struct mbuf *n;
+ uint8_t *ivp;
+ int off;
+
+ /* Insert IV for CCMP hardware encryption. */
+ n = m_makespace(m, hdrlen, IEEE80211_CCMP_HDRLEN, &off);
+ if (n == NULL) {
+ m_freem(m);
+ return (ENOBUFS);
+ }
+ ivp = mtod(n, uint8_t *) + off;
+ k->k_tsc++;
+ ivp[0] = k->k_tsc;
+ ivp[1] = k->k_tsc >> 8;
+ ivp[2] = 0;
+ ivp[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV;
+ ivp[4] = k->k_tsc >> 16;
+ ivp[5] = k->k_tsc >> 24;
+ ivp[6] = k->k_tsc >> 32;
+ ivp[7] = k->k_tsc >> 40;
+
+ return 0;
+#endif
+}
+
+int
+ar5008_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
+ int txflags)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_key *k = NULL;
+ struct ieee80211_frame *wh;
+ struct athn_series series[4];
+ struct ar_tx_desc *ds, *lastds;
+ struct athn_txq *txq;
+ struct athn_tx_buf *bf;
+ struct athn_node *an = (void *)ni;
+ uintptr_t entry;
+ uint16_t qos;
+ uint8_t txpower, type, encrtype, tid, ridx[4];
+ int i, error, totlen, hasqos, qid;
+
+ /* Grab a Tx buffer from our global free list. */
+ bf = SIMPLEQ_FIRST(&sc->txbufs);
+ KASSERT(bf != NULL, ("ar5008_tx"));
+
+ /* Map 802.11 frame type to hardware frame type. */
+ wh = mtod(m, struct ieee80211_frame *);
+ if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
+ IEEE80211_FC0_TYPE_MGT) {
+ /* NB: Beacons do not use ar5008_tx(). */
+ if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
+ IEEE80211_FC0_SUBTYPE_PROBE_RESP)
+ type = AR_FRAME_TYPE_PROBE_RESP;
+ else if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
+ IEEE80211_FC0_SUBTYPE_ATIM)
+ type = AR_FRAME_TYPE_ATIM;
+ else
+ type = AR_FRAME_TYPE_NORMAL;
+ } else if ((wh->i_fc[0] &
+ (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
+ (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) {
+ type = AR_FRAME_TYPE_PSPOLL;
+ } else
+ type = AR_FRAME_TYPE_NORMAL;
+
+ if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
+ k = ieee80211_get_txkey(ic, wh, ni);
+ if (k->k_cipher == IEEE80211_CIPHER_CCMP) {
+ u_int hdrlen = ieee80211_get_hdrlen(wh);
+ if (ar5008_ccmp_encap(m, hdrlen, k) != 0)
+ return (ENOBUFS);
+ } else {
+ if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
+ return (ENOBUFS);
+ k = NULL; /* skip hardware crypto further below */
+ }
+ wh = mtod(m, struct ieee80211_frame *);
+ }
+
+ /* XXX 2-byte padding for QoS and 4-addr headers. */
+
+ /* Select the HW Tx queue to use for this frame. */
+ if ((hasqos = ieee80211_has_qos(wh))) {
+ qos = ieee80211_get_qos(wh);
+ tid = qos & IEEE80211_QOS_TID;
+ qid = athn_ac2qid[ieee80211_up_to_ac(ic, tid)];
+ } else if (type == AR_FRAME_TYPE_PSPOLL) {
+ qid = ATHN_QID_PSPOLL;
+ } else if (txflags & ATHN_TXFLAG_CAB) {
+ qid = ATHN_QID_CAB;
+ } else
+ qid = ATHN_QID_AC_BE;
+ txq = &sc->txq[qid];
+
+ /* Select the transmit rates to use for this frame. */
+ if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
+ (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
+ IEEE80211_FC0_TYPE_DATA) {
+ /* Use lowest rate for all tries. */
+ ridx[0] = ridx[1] = ridx[2] = ridx[3] =
+ (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ?
+ ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK1);
+ } else if ((ni->ni_flags & IEEE80211_NODE_HT) &&
+ ic->ic_fixed_mcs != -1) {
+ /* Use same fixed rate for all tries. */
+ ridx[0] = ridx[1] = ridx[2] = ridx[3] =
+ ATHN_RIDX_MCS0 + ic->ic_fixed_mcs;
+ } else if (ic->ic_fixed_rate != -1) {
+ /* Use same fixed rate for all tries. */
+ ridx[0] = ridx[1] = ridx[2] = ridx[3] =
+ sc->fixed_ridx;
+ } else {
+ /* Use fallback table of the node. */
+ int txrate;
+
+ if (ni->ni_flags & IEEE80211_NODE_HT)
+ txrate = ATHN_NUM_LEGACY_RATES + ni->ni_txmcs;
+ else
+ txrate = ni->ni_txrate;
+ for (i = 0; i < 4; i++) {
+ ridx[i] = an->ridx[txrate];
+ txrate = an->fallback[txrate];
+ }
+ }
+
+#if NBPFILTER > 0
+ if (__predict_false(sc->sc_drvbpf != NULL)) {
+ struct athn_tx_radiotap_header *tap = &sc->sc_txtap;
+
+ tap->wt_flags = 0;
+ /* Use initial transmit rate. */
+ if (athn_rates[ridx[0]].hwrate & 0x80) /* MCS */
+ tap->wt_rate = athn_rates[ridx[0]].hwrate;
+ else
+ tap->wt_rate = athn_rates[ridx[0]].rate;
+ tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
+ tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
+ if (athn_rates[ridx[0]].phy == IEEE80211_T_DS &&
+ ridx[0] != ATHN_RIDX_CCK1 &&
+ (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
+ tap->wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+ bpf_mtap_hdr(sc->sc_drvbpf, tap, sc->sc_txtap_len, m,
+ BPF_DIRECTION_OUT);
+ }
+#endif
+
+ /* DMA map mbuf. */
+ error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m,
+ BUS_DMA_NOWAIT | BUS_DMA_WRITE);
+ if (__predict_false(error != 0)) {
+ if (error != EFBIG) {
+ printf(": can't map mbuf (error %d)\n", error);
+// printf("%s: can't map mbuf (error %d)\n",
+// sc->sc_dev.dv_xname, error);
+ m_freem(m);
+ return (error);
+ }
+ /*
+ * DMA mapping requires too many DMA segments; linearize
+ * mbuf in kernel virtual address space and retry.
+ */
+ if (m_defrag(m, M_DONTWAIT) != 0) {
+ m_freem(m);
+ return (ENOBUFS);
+ }
+
+ error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_map, m,
+ BUS_DMA_NOWAIT | BUS_DMA_WRITE);
+ if (error != 0) {
+ printf(": can't map mbuf (error %d)\n", error);
+// printf("%s: can't map mbuf (error %d)\n",
+// sc->sc_dev.dv_xname, error);
+ m_freem(m);
+ return (error);
+ }
+ }
+ bf->bf_m = m;
+ bf->bf_ni = ni;
+ bf->bf_txmcs = ni->ni_txmcs;
+ bf->bf_txflags = txflags;
+
+ wh = mtod(m, struct ieee80211_frame *);
+
+ totlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
+
+ /* Clear all Tx descriptors that we will use. */
+ memset(bf->bf_descs, 0, bf->bf_map->dm_nsegs * sizeof(*ds));
+
+ /* Setup first Tx descriptor. */
+ ds = bf->bf_descs;
+
+ ds->ds_ctl0 = AR_TXC0_INTR_REQ | AR_TXC0_CLR_DEST_MASK;
+ txpower = AR_MAX_RATE_POWER; /* Get from per-rate registers. */
+ ds->ds_ctl0 |= SM(AR_TXC0_XMIT_POWER, txpower);
+
+ ds->ds_ctl1 = SM(AR_TXC1_FRAME_TYPE, type);
+
+ if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
+ (hasqos && (qos & IEEE80211_QOS_ACK_POLICY_MASK) ==
+ IEEE80211_QOS_ACK_POLICY_NOACK))
+ ds->ds_ctl1 |= AR_TXC1_NO_ACK;
+
+ if (k != NULL) {
+ /* Map 802.11 cipher to hardware encryption type. */
+ if (k->k_cipher == IEEE80211_CIPHER_CCMP) {
+ encrtype = AR_ENCR_TYPE_AES;
+ totlen += IEEE80211_CCMP_MICLEN;
+ } else
+ panic("unsupported cipher");
+ /*
+ * NB: The key cache entry index is stored in the key
+ * private field when the key is installed.
+ */
+ entry = (uintptr_t)k->k_priv;
+ ds->ds_ctl1 |= SM(AR_TXC1_DEST_IDX, entry);
+ ds->ds_ctl0 |= AR_TXC0_DEST_IDX_VALID;
+ } else
+ encrtype = AR_ENCR_TYPE_CLEAR;
+ ds->ds_ctl6 = SM(AR_TXC6_ENCR_TYPE, encrtype);
+
+ /* Check if frame must be protected using RTS/CTS or CTS-to-self. */
+ if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+ (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
+ IEEE80211_FC0_TYPE_DATA) {
+ enum ieee80211_htprot htprot;
+
+ htprot = (ic->ic_bss->ni_htop1 & IEEE80211_HTOP1_PROT_MASK);
+
+ /* NB: Group frames are sent using CCK in 802.11b/g. */
+ if (totlen > ic->ic_rtsthreshold) {
+ ds->ds_ctl0 |= AR_TXC0_RTS_ENABLE;
+ } else if (((ic->ic_flags & IEEE80211_F_USEPROT) &&
+ athn_rates[ridx[0]].phy == IEEE80211_T_OFDM) ||
+ ((ni->ni_flags & IEEE80211_NODE_HT) &&
+ htprot != IEEE80211_HTPROT_NONE)) {
+ if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
+ ds->ds_ctl0 |= AR_TXC0_RTS_ENABLE;
+ else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
+ ds->ds_ctl0 |= AR_TXC0_CTS_ENABLE;
+ }
+ }
+ /*
+ * Disable multi-rate retries when protection is used.
+ * The RTS/CTS frame's duration field is fixed and won't be
+ * updated by hardware when the data rate changes.
+ */
+ if (ds->ds_ctl0 & (AR_TXC0_RTS_ENABLE | AR_TXC0_CTS_ENABLE)) {
+ ridx[1] = ridx[2] = ridx[3] = ridx[0];
+ }
+ /* Setup multi-rate retries. */
+ for (i = 0; i < 4; i++) {
+ series[i].hwrate = athn_rates[ridx[i]].hwrate;
+ if (athn_rates[ridx[i]].phy == IEEE80211_T_DS &&
+ ridx[i] != ATHN_RIDX_CCK1 &&
+ (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
+ series[i].hwrate |= 0x04;
+ /* Compute duration for each series. */
+ series[i].dur = athn_txtime(sc, totlen, ridx[i], ic->ic_flags);
+ if (!(ds->ds_ctl1 & AR_TXC1_NO_ACK)) {
+ /* Account for ACK duration. */
+ series[i].dur += athn_txtime(sc, IEEE80211_ACK_LEN,
+ athn_rates[ridx[i]].rspridx, ic->ic_flags);
+ }
+ }
+
+ /* Write number of tries for each series. */
+ ds->ds_ctl2 =
+ SM(AR_TXC2_XMIT_DATA_TRIES0, 2) |
+ SM(AR_TXC2_XMIT_DATA_TRIES1, 2) |
+ SM(AR_TXC2_XMIT_DATA_TRIES2, 2) |
+ SM(AR_TXC2_XMIT_DATA_TRIES3, 4);
+
+ /* Tell HW to update duration field in 802.11 header. */
+ if (type != AR_FRAME_TYPE_PSPOLL)
+ ds->ds_ctl2 |= AR_TXC2_DUR_UPDATE_ENA;
+
+ /* Write Tx rate for each series. */
+ ds->ds_ctl3 =
+ SM(AR_TXC3_XMIT_RATE0, series[0].hwrate) |
+ SM(AR_TXC3_XMIT_RATE1, series[1].hwrate) |
+ SM(AR_TXC3_XMIT_RATE2, series[2].hwrate) |
+ SM(AR_TXC3_XMIT_RATE3, series[3].hwrate);
+
+ /* Write duration for each series. */
+ ds->ds_ctl4 =
+ SM(AR_TXC4_PACKET_DUR0, series[0].dur) |
+ SM(AR_TXC4_PACKET_DUR1, series[1].dur);
+ ds->ds_ctl5 =
+ SM(AR_TXC5_PACKET_DUR2, series[2].dur) |
+ SM(AR_TXC5_PACKET_DUR3, series[3].dur);
+
+ /* Use the same Tx chains for all tries. */
+ ds->ds_ctl7 =
+ SM(AR_TXC7_CHAIN_SEL0, sc->txchainmask) |
+ SM(AR_TXC7_CHAIN_SEL1, sc->txchainmask) |
+ SM(AR_TXC7_CHAIN_SEL2, sc->txchainmask) |
+ SM(AR_TXC7_CHAIN_SEL3, sc->txchainmask);
+#ifdef notyet
+ /* Use the same short GI setting for all tries. */
+ if (ni->ni_htcaps & IEEE80211_HTCAP_SGI20)
+ ds->ds_ctl7 |= AR_TXC7_GI0123;
+ /* Use the same channel width for all tries. */
+ if (ic->ic_flags & IEEE80211_F_CBW40)
+ ds->ds_ctl7 |= AR_TXC7_2040_0123;
+#endif
+
+ /* Set Tx power for series 1 - 3 */
+ ds->ds_ctl9 = SM(AR_TXC9_XMIT_POWER1, txpower);
+ ds->ds_ctl10 = SM(AR_TXC10_XMIT_POWER2, txpower);
+ ds->ds_ctl11 = SM(AR_TXC11_XMIT_POWER3, txpower);
+
+ if (ds->ds_ctl0 & (AR_TXC0_RTS_ENABLE | AR_TXC0_CTS_ENABLE)) {
+ uint8_t protridx, hwrate;
+ uint16_t dur = 0;
+
+ /* Use the same protection mode for all tries. */
+ if (ds->ds_ctl0 & AR_TXC0_RTS_ENABLE) {
+ ds->ds_ctl4 |= AR_TXC4_RTSCTS_QUAL01;
+ ds->ds_ctl5 |= AR_TXC5_RTSCTS_QUAL23;
+ }
+ /* Select protection rate (suboptimal but ok). */
+ protridx = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ?
+ ATHN_RIDX_OFDM6 : ATHN_RIDX_CCK2;
+ if (ds->ds_ctl0 & AR_TXC0_RTS_ENABLE) {
+ /* Account for CTS duration. */
+ dur += athn_txtime(sc, IEEE80211_ACK_LEN,
+ athn_rates[protridx].rspridx, ic->ic_flags);
+ }
+ dur += athn_txtime(sc, totlen, ridx[0], ic->ic_flags);
+ if (!(ds->ds_ctl1 & AR_TXC1_NO_ACK)) {
+ /* Account for ACK duration. */
+ dur += athn_txtime(sc, IEEE80211_ACK_LEN,
+ athn_rates[ridx[0]].rspridx, ic->ic_flags);
+ }
+ /* Write protection frame duration and rate. */
+ ds->ds_ctl2 |= SM(AR_TXC2_BURST_DUR, dur);
+ hwrate = athn_rates[protridx].hwrate;
+ if (protridx == ATHN_RIDX_CCK2 &&
+ (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
+ hwrate |= 0x04;
+ ds->ds_ctl7 |= SM(AR_TXC7_RTSCTS_RATE, hwrate);
+ }
+
+ /* Finalize first Tx descriptor and fill others (if any). */
+ ds->ds_ctl0 |= SM(AR_TXC0_FRAME_LEN, totlen);
+
+ for (i = 0; i < bf->bf_map->dm_nsegs; i++, ds++) {
+ ds->ds_data = bf->bf_map->dm_segs[i].ds_addr;
+ ds->ds_ctl1 |= SM(AR_TXC1_BUF_LEN,
+ bf->bf_map->dm_segs[i].ds_len);
+
+ if (i != bf->bf_map->dm_nsegs - 1)
+ ds->ds_ctl1 |= AR_TXC1_MORE;
+ ds->ds_link = 0;
+
+ /* Chain Tx descriptor. */
+ if (i != 0)
+ lastds->ds_link = bf->bf_daddr + i * sizeof(*ds);
+ lastds = ds;
+ }
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_map, 0, bf->bf_map->dm_mapsize,
+ BUS_DMASYNC_PREWRITE);
+
+ if (!SIMPLEQ_EMPTY(&txq->head))
+ ((struct ar_tx_desc *)txq->lastds)->ds_link = bf->bf_daddr;
+ else
+ AR_WRITE(sc, AR_QTXDP(qid), bf->bf_daddr);
+ txq->lastds = lastds;
+ SIMPLEQ_REMOVE_HEAD(&sc->txbufs, bf_list);
+ SIMPLEQ_INSERT_TAIL(&txq->head, bf, bf_list);
+
+ ds = bf->bf_descs;
+ DPRINTFN(6, ("Tx qid=%d nsegs=%d ctl0=0x%x ctl1=0x%x ctl3=0x%x\n",
+ qid, bf->bf_map->dm_nsegs, ds->ds_ctl0, ds->ds_ctl1, ds->ds_ctl3));
+
+ /* Kick Tx. */
+ AR_WRITE(sc, AR_Q_TXE, 1 << qid);
+ AR_WRITE_BARRIER(sc);
+ return (0);
+#endif
+}
+
+void
+ar5008_set_rf_mode(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ uint32_t reg;
+
+ printf("Running ar5008_set_rf_mode %p %p\n", sc, c);
+
+ reg = IEEE80211_IS_CHAN_2GHZ(c) ?
+ AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
+ if (!AR_SREV_9280_10_OR_LATER(sc)) {
+ reg |= IEEE80211_IS_CHAN_2GHZ(c) ?
+ AR_PHY_MODE_RF2GHZ : AR_PHY_MODE_RF5GHZ;
+ } else if (IEEE80211_IS_CHAN_5GHZ(c) &&
+ (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)) {
+ reg |= AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE;
+ }
+ AR_WRITE(sc, AR_PHY_MODE, reg);
+ AR_WRITE_BARRIER(sc);
+
+ printf("Returning ar5008_set_rf_mode\n");
+}
+
+static __inline uint32_t
+ar5008_synth_delay(struct athn_softc *sc)
+{
+ uint32_t delay;
+
+ delay = MS(AR_READ(sc, AR_PHY_RX_DELAY), AR_PHY_RX_DELAY_DELAY);
+ if (sc->sc_ic.ic_curmode == IEEE80211_MODE_11B)
+ delay = (delay * 4) / 22;
+ else
+ delay = delay / 10; /* in 100ns steps */
+ return (delay);
+}
+
+int
+ar5008_rf_bus_request(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ int ntries;
+
+ /* Request RF Bus grant. */
+ AR_WRITE(sc, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
+ for (ntries = 0; ntries < 10000; ntries++) {
+ if (AR_READ(sc, AR_PHY_RFBUS_GRANT) & AR_PHY_RFBUS_GRANT_EN)
+ return (0);
+ DELAY(10);
+ }
+ DPRINTF(("could not kill baseband Rx"));
+ return (ETIMEDOUT);
+#endif
+}
+
+void
+ar5008_rf_bus_release(struct athn_softc *sc)
+{
+ /* Wait for the synthesizer to settle. */
+ DELAY(AR_BASE_PHY_ACTIVE_DELAY + ar5008_synth_delay(sc));
+
+ /* Release the RF Bus grant. */
+ AR_WRITE(sc, AR_PHY_RFBUS_REQ, 0);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_set_phy(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ uint32_t phy;
+
+ if (AR_SREV_9285_10_OR_LATER(sc))
+ phy = AR_READ(sc, AR_PHY_TURBO) & AR_PHY_FC_ENABLE_DAC_FIFO;
+ else
+ phy = 0;
+ phy |= AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 |
+ AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
+ if (extc != NULL) {
+ phy |= AR_PHY_FC_DYN2040_EN;
+ if (extc > c) /* XXX */
+ phy |= AR_PHY_FC_DYN2040_PRI_CH;
+ }
+ AR_WRITE(sc, AR_PHY_TURBO, phy);
+
+ AR_WRITE(sc, AR_2040_MODE,
+ (extc != NULL) ? AR_2040_JOINED_RX_CLEAR : 0);
+
+ /* Set global transmit timeout. */
+ AR_WRITE(sc, AR_GTXTO, SM(AR_GTXTO_TIMEOUT_LIMIT, 25));
+ /* Set carrier sense timeout. */
+ AR_WRITE(sc, AR_CST, SM(AR_CST_TIMEOUT_LIMIT, 15));
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+ar5008_set_delta_slope(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ uint32_t coeff, exp, man, reg;
+
+ /* Set Delta Slope (exponent and mantissa). */
+ coeff = (100 << 24) / c->ic_freq;
+ athn_get_delta_slope(coeff, &exp, &man);
+ DPRINTFN(5, ("delta slope coeff exp=%u man=%u\n", exp, man));
+
+ reg = AR_READ(sc, AR_PHY_TIMING3);
+ reg = RW(reg, AR_PHY_TIMING3_DSC_EXP, exp);
+ reg = RW(reg, AR_PHY_TIMING3_DSC_MAN, man);
+ AR_WRITE(sc, AR_PHY_TIMING3, reg);
+
+ /* For Short GI, coeff is 9/10 that of normal coeff. */
+ coeff = (9 * coeff) / 10;
+ athn_get_delta_slope(coeff, &exp, &man);
+ DPRINTFN(5, ("delta slope coeff exp=%u man=%u\n", exp, man));
+
+ reg = AR_READ(sc, AR_PHY_HALFGI);
+ reg = RW(reg, AR_PHY_HALFGI_DSC_EXP, exp);
+ reg = RW(reg, AR_PHY_HALFGI_DSC_MAN, man);
+ AR_WRITE(sc, AR_PHY_HALFGI, reg);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_enable_antenna_diversity(struct athn_softc *sc)
+{
+ AR_SETBITS(sc, AR_PHY_CCK_DETECT,
+ AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_init_baseband(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ uint32_t synth_delay;
+
+ synth_delay = ar5008_synth_delay(sc);
+ /* Activate the PHY (includes baseband activate and synthesizer on). */
+ AR_WRITE(sc, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+ AR_WRITE_BARRIER(sc);
+ DELAY(AR_BASE_PHY_ACTIVE_DELAY + synth_delay);
+#endif
+}
+
+void
+ar5008_disable_phy(struct athn_softc *sc)
+{
+ AR_WRITE(sc, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_init_chains(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ if (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5)
+ AR_SETBITS(sc, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
+
+ /* Setup chain masks. */
+ if (sc->mac_ver <= AR_SREV_VERSION_9160 &&
+ (sc->rxchainmask == 0x3 || sc->rxchainmask == 0x5)) {
+ AR_WRITE(sc, AR_PHY_RX_CHAINMASK, 0x7);
+ AR_WRITE(sc, AR_PHY_CAL_CHAINMASK, 0x7);
+ } else {
+ AR_WRITE(sc, AR_PHY_RX_CHAINMASK, sc->rxchainmask);
+ AR_WRITE(sc, AR_PHY_CAL_CHAINMASK, sc->rxchainmask);
+ }
+ AR_WRITE(sc, AR_SELFGEN_MASK, sc->txchainmask);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+ar5008_set_rxchains(struct athn_softc *sc)
+{
+ if (sc->rxchainmask == 0x3 || sc->rxchainmask == 0x5) {
+ AR_WRITE(sc, AR_PHY_RX_CHAINMASK, sc->rxchainmask);
+ AR_WRITE(sc, AR_PHY_CAL_CHAINMASK, sc->rxchainmask);
+ AR_WRITE_BARRIER(sc);
+ }
+}
+
+void
+ar5008_read_noisefloor(struct athn_softc *sc, int16_t *nf, int16_t *nf_ext)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+/* Sign-extends 9-bit value (assumes upper bits are zeroes). */
+#define SIGN_EXT(v) (((v) ^ 0x100) - 0x100)
+ uint32_t reg;
+ int i;
+
+ for (i = 0; i < sc->nrxchains; i++) {
+ reg = AR_READ(sc, AR_PHY_CCA(i));
+ if (AR_SREV_9280_10_OR_LATER(sc))
+ nf[i] = MS(reg, AR9280_PHY_MINCCA_PWR);
+ else
+ nf[i] = MS(reg, AR_PHY_MINCCA_PWR);
+ nf[i] = SIGN_EXT(nf[i]);
+
+ reg = AR_READ(sc, AR_PHY_EXT_CCA(i));
+ if (AR_SREV_9280_10_OR_LATER(sc))
+ nf_ext[i] = MS(reg, AR9280_PHY_EXT_MINCCA_PWR);
+ else
+ nf_ext[i] = MS(reg, AR_PHY_EXT_MINCCA_PWR);
+ nf_ext[i] = SIGN_EXT(nf_ext[i]);
+ }
+#undef SIGN_EXT
+#endif // This is the FreeBSD addition endif
+}
+
+void
+ar5008_write_noisefloor(struct athn_softc *sc, int16_t *nf, int16_t *nf_ext)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ uint32_t reg;
+ int i;
+
+ for (i = 0; i < sc->nrxchains; i++) {
+ reg = AR_READ(sc, AR_PHY_CCA(i));
+ reg = RW(reg, AR_PHY_MAXCCA_PWR, nf[i]);
+ AR_WRITE(sc, AR_PHY_CCA(i), reg);
+
+ reg = AR_READ(sc, AR_PHY_EXT_CCA(i));
+ reg = RW(reg, AR_PHY_EXT_MAXCCA_PWR, nf_ext[i]);
+ AR_WRITE(sc, AR_PHY_EXT_CCA(i), reg);
+ }
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+int
+ar5008_get_noisefloor(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+ return 0;
+#if 0
+ int16_t nf[AR_MAX_CHAINS], nf_ext[AR_MAX_CHAINS];
+ int i;
+
+ if (AR_READ(sc, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
+ /* Noisefloor calibration not finished. */
+ return 0;
+ }
+ /* Noisefloor calibration is finished. */
+ ar5008_read_noisefloor(sc, nf, nf_ext);
+
+ /* Update noisefloor history. */
+ for (i = 0; i < sc->nrxchains; i++) {
+ sc->nf_hist[sc->nf_hist_cur].nf[i] = nf[i];
+ sc->nf_hist[sc->nf_hist_cur].nf_ext[i] = nf_ext[i];
+ }
+ if (++sc->nf_hist_cur >= ATHN_NF_CAL_HIST_MAX)
+ sc->nf_hist_cur = 0;
+ return 1;
+#endif
+}
+
+void
+ar5008_bb_load_noisefloor(struct athn_softc *sc)
+{
+ int16_t nf[AR_MAX_CHAINS], nf_ext[AR_MAX_CHAINS];
+ int i, ntries;
+
+ /* Write filtered noisefloor values. */
+ for (i = 0; i < sc->nrxchains; i++) {
+ nf[i] = sc->nf_priv[i] * 2;
+ nf_ext[i] = sc->nf_ext_priv[i] * 2;
+ }
+ ar5008_write_noisefloor(sc, nf, nf_ext);
+
+ /* Load filtered noisefloor values into baseband. */
+ AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
+ AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+ /* Wait for load to complete. */
+ for (ntries = 0; ntries < 1000; ntries++) {
+ if (!(AR_READ(sc, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF))
+ break;
+ DELAY(50);
+ }
+ if (ntries == 1000) {
+ DPRINTF(("failed to load noisefloor values\n"));
+ return;
+ }
+
+ /*
+ * Restore noisefloor values to initial (max) values. These will
+ * be used as initial values during the next NF calibration.
+ */
+ for (i = 0; i < AR_MAX_CHAINS; i++)
+ nf[i] = nf_ext[i] = AR_DEFAULT_NOISE_FLOOR;
+ ar5008_write_noisefloor(sc, nf, nf_ext);
+}
+
+void
+ar5008_apply_noisefloor(struct athn_softc *sc)
+{
+ uint32_t agc_nfcal;
+
+ agc_nfcal = AR_READ(sc, AR_PHY_AGC_CONTROL) &
+ (AR_PHY_AGC_CONTROL_NF | AR_PHY_AGC_CONTROL_ENABLE_NF |
+ AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+
+ if (agc_nfcal & AR_PHY_AGC_CONTROL_NF) {
+ /* Pause running NF calibration while values are updated. */
+ AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+ AR_WRITE_BARRIER(sc);
+ }
+
+ ar5008_bb_load_noisefloor(sc);
+
+ if (agc_nfcal & AR_PHY_AGC_CONTROL_NF) {
+ /* Restart interrupted NF calibration. */
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, agc_nfcal);
+ AR_WRITE_BARRIER(sc);
+ }
+}
+
+void
+ar5008_do_noisefloor_calib(struct athn_softc *sc)
+{
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_init_noisefloor_calib(struct athn_softc *sc)
+{
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_do_calib(struct athn_softc *sc)
+{
+ uint32_t mode, reg;
+ int log;
+
+ reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0);
+ log = AR_SREV_9280_10_OR_LATER(sc) ? 10 : 2;
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, log);
+ AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0, reg);
+
+ if (sc->cur_calib_mask & ATHN_CAL_ADC_GAIN)
+ mode = AR_PHY_CALMODE_ADC_GAIN;
+ else if (sc->cur_calib_mask & ATHN_CAL_ADC_DC)
+ mode = AR_PHY_CALMODE_ADC_DC_PER;
+ else /* ATHN_CAL_IQ */
+ mode = AR_PHY_CALMODE_IQ;
+ AR_WRITE(sc, AR_PHY_CALMODE, mode);
+
+ DPRINTF(("starting calibration mode=0x%x\n", mode));
+ AR_SETBITS(sc, AR_PHY_TIMING_CTRL4_0, AR_PHY_TIMING_CTRL4_DO_CAL);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_next_calib(struct athn_softc *sc)
+{
+ /* Check if we have any calibration in progress. */
+ if (sc->cur_calib_mask != 0) {
+ if (!(AR_READ(sc, AR_PHY_TIMING_CTRL4_0) &
+ AR_PHY_TIMING_CTRL4_DO_CAL)) {
+ /* Calibration completed for current sample. */
+ if (sc->cur_calib_mask & ATHN_CAL_ADC_GAIN)
+ ar5008_calib_adc_gain(sc);
+ else if (sc->cur_calib_mask & ATHN_CAL_ADC_DC)
+ ar5008_calib_adc_dc_off(sc);
+ else /* ATHN_CAL_IQ */
+ ar5008_calib_iq(sc);
+ }
+ }
+}
+
+void
+ar5008_calib_iq(struct athn_softc *sc)
+{
+ struct athn_iq_cal *cal;
+ uint32_t reg, i_coff_denom, q_coff_denom;
+ int32_t i_coff, q_coff;
+ int i, iq_corr_neg;
+
+ for (i = 0; i < AR_MAX_CHAINS; i++) {
+ cal = &sc->calib.iq[i];
+
+ /* Accumulate IQ calibration measures (clear on read). */
+ cal->pwr_meas_i += AR_READ(sc, AR_PHY_CAL_MEAS_0(i));
+ cal->pwr_meas_q += AR_READ(sc, AR_PHY_CAL_MEAS_1(i));
+ cal->iq_corr_meas +=
+ (int32_t)AR_READ(sc, AR_PHY_CAL_MEAS_2(i));
+ }
+ if (!AR_SREV_9280_10_OR_LATER(sc) &&
+ ++sc->calib.nsamples < AR_CAL_SAMPLES) {
+ /* Not enough samples accumulated, continue. */
+ ar5008_do_calib(sc);
+ return;
+ }
+
+ for (i = 0; i < sc->nrxchains; i++) {
+ cal = &sc->calib.iq[i];
+
+ if (cal->pwr_meas_q == 0)
+ continue;
+
+ if ((iq_corr_neg = cal->iq_corr_meas < 0))
+ cal->iq_corr_meas = -cal->iq_corr_meas;
+
+ i_coff_denom =
+ (cal->pwr_meas_i / 2 + cal->pwr_meas_q / 2) / 128;
+ q_coff_denom = cal->pwr_meas_q / 64;
+
+ if (i_coff_denom == 0 || q_coff_denom == 0)
+ continue; /* Prevents division by zero. */
+
+ i_coff = cal->iq_corr_meas / i_coff_denom;
+ q_coff = (cal->pwr_meas_i / q_coff_denom) - 64;
+
+ /* Negate i_coff if iq_corr_meas is positive. */
+ if (!iq_corr_neg)
+ i_coff = 0x40 - (i_coff & 0x3f);
+ if (q_coff > 15)
+ q_coff = 15;
+ else if (q_coff <= -16)
+ q_coff = -16; /* XXX Linux has a bug here? */
+
+ DPRINTFN(2, ("IQ calibration for chain %d\n", i));
+ reg = AR_READ(sc, AR_PHY_TIMING_CTRL4(i));
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, i_coff);
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, q_coff);
+ AR_WRITE(sc, AR_PHY_TIMING_CTRL4(i), reg);
+ }
+
+ /* Apply new settings. */
+ AR_SETBITS(sc, AR_PHY_TIMING_CTRL4_0,
+ AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
+ AR_WRITE_BARRIER(sc);
+
+ /* IQ calibration done. */
+ sc->cur_calib_mask &= ~ATHN_CAL_IQ;
+ memset(&sc->calib, 0, sizeof(sc->calib));
+}
+
+void
+ar5008_calib_adc_gain(struct athn_softc *sc)
+{
+ struct athn_adc_cal *cal;
+ uint32_t reg, gain_mismatch_i, gain_mismatch_q;
+ int i;
+
+ for (i = 0; i < AR_MAX_CHAINS; i++) {
+ cal = &sc->calib.adc_gain[i];
+
+ /* Accumulate ADC gain measures (clear on read). */
+ cal->pwr_meas_odd_i += AR_READ(sc, AR_PHY_CAL_MEAS_0(i));
+ cal->pwr_meas_even_i += AR_READ(sc, AR_PHY_CAL_MEAS_1(i));
+ cal->pwr_meas_odd_q += AR_READ(sc, AR_PHY_CAL_MEAS_2(i));
+ cal->pwr_meas_even_q += AR_READ(sc, AR_PHY_CAL_MEAS_3(i));
+ }
+ if (!AR_SREV_9280_10_OR_LATER(sc) &&
+ ++sc->calib.nsamples < AR_CAL_SAMPLES) {
+ /* Not enough samples accumulated, continue. */
+ ar5008_do_calib(sc);
+ return;
+ }
+
+ for (i = 0; i < sc->nrxchains; i++) {
+ cal = &sc->calib.adc_gain[i];
+
+ if (cal->pwr_meas_odd_i == 0 || cal->pwr_meas_even_q == 0)
+ continue; /* Prevents division by zero. */
+
+ gain_mismatch_i =
+ (cal->pwr_meas_even_i * 32) / cal->pwr_meas_odd_i;
+ gain_mismatch_q =
+ (cal->pwr_meas_odd_q * 32) / cal->pwr_meas_even_q;
+
+ DPRINTFN(2, ("ADC gain calibration for chain %d\n", i));
+ reg = AR_READ(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+ reg = RW(reg, AR_PHY_NEW_ADC_DC_GAIN_IGAIN, gain_mismatch_i);
+ reg = RW(reg, AR_PHY_NEW_ADC_DC_GAIN_QGAIN, gain_mismatch_q);
+ AR_WRITE(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), reg);
+ }
+
+ /* Apply new settings. */
+ AR_SETBITS(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+ AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
+ AR_WRITE_BARRIER(sc);
+
+ /* ADC gain calibration done. */
+ sc->cur_calib_mask &= ~ATHN_CAL_ADC_GAIN;
+ memset(&sc->calib, 0, sizeof(sc->calib));
+}
+
+void
+ar5008_calib_adc_dc_off(struct athn_softc *sc)
+{
+ struct athn_adc_cal *cal;
+ int32_t dc_offset_mismatch_i, dc_offset_mismatch_q;
+ uint32_t reg;
+ int count, i;
+
+ for (i = 0; i < AR_MAX_CHAINS; i++) {
+ cal = &sc->calib.adc_dc_offset[i];
+
+ /* Accumulate ADC DC offset measures (clear on read). */
+ cal->pwr_meas_odd_i += AR_READ(sc, AR_PHY_CAL_MEAS_0(i));
+ cal->pwr_meas_even_i += AR_READ(sc, AR_PHY_CAL_MEAS_1(i));
+ cal->pwr_meas_odd_q += AR_READ(sc, AR_PHY_CAL_MEAS_2(i));
+ cal->pwr_meas_even_q += AR_READ(sc, AR_PHY_CAL_MEAS_3(i));
+ }
+ if (!AR_SREV_9280_10_OR_LATER(sc) &&
+ ++sc->calib.nsamples < AR_CAL_SAMPLES) {
+ /* Not enough samples accumulated, continue. */
+ ar5008_do_calib(sc);
+ return;
+ }
+
+ if (AR_SREV_9280_10_OR_LATER(sc))
+ count = (1 << (10 + 5));
+ else
+ count = (1 << ( 2 + 5)) * AR_CAL_SAMPLES;
+ for (i = 0; i < sc->nrxchains; i++) {
+ cal = &sc->calib.adc_dc_offset[i];
+
+ dc_offset_mismatch_i =
+ (cal->pwr_meas_even_i - cal->pwr_meas_odd_i * 2) / count;
+ dc_offset_mismatch_q =
+ (cal->pwr_meas_odd_q - cal->pwr_meas_even_q * 2) / count;
+
+ DPRINTFN(2, ("ADC DC offset calibration for chain %d\n", i));
+ reg = AR_READ(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+ reg = RW(reg, AR_PHY_NEW_ADC_DC_GAIN_QDC,
+ dc_offset_mismatch_q);
+ reg = RW(reg, AR_PHY_NEW_ADC_DC_GAIN_IDC,
+ dc_offset_mismatch_i);
+ AR_WRITE(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), reg);
+ }
+
+ /* Apply new settings. */
+ AR_SETBITS(sc, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+ AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
+ AR_WRITE_BARRIER(sc);
+
+ /* ADC DC offset calibration done. */
+ sc->cur_calib_mask &= ~ATHN_CAL_ADC_DC;
+ memset(&sc->calib, 0, sizeof(sc->calib));
+}
+
+void
+ar5008_write_txpower(struct athn_softc *sc, int16_t power[ATHN_POWER_COUNT])
+{
+ AR_WRITE(sc, AR_PHY_POWER_TX_RATE1,
+ (power[ATHN_POWER_OFDM18 ] & 0x3f) << 24 |
+ (power[ATHN_POWER_OFDM12 ] & 0x3f) << 16 |
+ (power[ATHN_POWER_OFDM9 ] & 0x3f) << 8 |
+ (power[ATHN_POWER_OFDM6 ] & 0x3f));
+ AR_WRITE(sc, AR_PHY_POWER_TX_RATE2,
+ (power[ATHN_POWER_OFDM54 ] & 0x3f) << 24 |
+ (power[ATHN_POWER_OFDM48 ] & 0x3f) << 16 |
+ (power[ATHN_POWER_OFDM36 ] & 0x3f) << 8 |
+ (power[ATHN_POWER_OFDM24 ] & 0x3f));
+ AR_WRITE(sc, AR_PHY_POWER_TX_RATE3,
+ (power[ATHN_POWER_CCK2_SP ] & 0x3f) << 24 |
+ (power[ATHN_POWER_CCK2_LP ] & 0x3f) << 16 |
+ (power[ATHN_POWER_XR ] & 0x3f) << 8 |
+ (power[ATHN_POWER_CCK1_LP ] & 0x3f));
+ AR_WRITE(sc, AR_PHY_POWER_TX_RATE4,
+ (power[ATHN_POWER_CCK11_SP] & 0x3f) << 24 |
+ (power[ATHN_POWER_CCK11_LP] & 0x3f) << 16 |
+ (power[ATHN_POWER_CCK55_SP] & 0x3f) << 8 |
+ (power[ATHN_POWER_CCK55_LP] & 0x3f));
+ AR_WRITE(sc, AR_PHY_POWER_TX_RATE5,
+ (power[ATHN_POWER_HT20(3) ] & 0x3f) << 24 |
+ (power[ATHN_POWER_HT20(2) ] & 0x3f) << 16 |
+ (power[ATHN_POWER_HT20(1) ] & 0x3f) << 8 |
+ (power[ATHN_POWER_HT20(0) ] & 0x3f));
+ AR_WRITE(sc, AR_PHY_POWER_TX_RATE6,
+ (power[ATHN_POWER_HT20(7) ] & 0x3f) << 24 |
+ (power[ATHN_POWER_HT20(6) ] & 0x3f) << 16 |
+ (power[ATHN_POWER_HT20(5) ] & 0x3f) << 8 |
+ (power[ATHN_POWER_HT20(4) ] & 0x3f));
+ AR_WRITE(sc, AR_PHY_POWER_TX_RATE7,
+ (power[ATHN_POWER_HT40(3) ] & 0x3f) << 24 |
+ (power[ATHN_POWER_HT40(2) ] & 0x3f) << 16 |
+ (power[ATHN_POWER_HT40(1) ] & 0x3f) << 8 |
+ (power[ATHN_POWER_HT40(0) ] & 0x3f));
+ AR_WRITE(sc, AR_PHY_POWER_TX_RATE8,
+ (power[ATHN_POWER_HT40(7) ] & 0x3f) << 24 |
+ (power[ATHN_POWER_HT40(6) ] & 0x3f) << 16 |
+ (power[ATHN_POWER_HT40(5) ] & 0x3f) << 8 |
+ (power[ATHN_POWER_HT40(4) ] & 0x3f));
+ AR_WRITE(sc, AR_PHY_POWER_TX_RATE9,
+ (power[ATHN_POWER_OFDM_EXT] & 0x3f) << 24 |
+ (power[ATHN_POWER_CCK_EXT ] & 0x3f) << 16 |
+ (power[ATHN_POWER_OFDM_DUP] & 0x3f) << 8 |
+ (power[ATHN_POWER_CCK_DUP ] & 0x3f));
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_set_viterbi_mask(struct athn_softc *sc, int bin)
+{
+ uint32_t mask[4], reg;
+ uint8_t m[62], p[62]; /* XXX use bit arrays? */
+ int i, bit, cur;
+
+ /* Compute pilot mask. */
+ cur = -6000;
+ for (i = 0; i < 4; i++) {
+ mask[i] = 0;
+ for (bit = 0; bit < 30; bit++) {
+ if (abs(cur - bin) < 100)
+ mask[i] |= 1 << bit;
+ cur += 100;
+ }
+ if (cur == 0) /* Skip entry "0". */
+ cur = 100;
+ }
+ /* Write entries from -6000 to -3100. */
+ AR_WRITE(sc, AR_PHY_TIMING7, mask[0]);
+ AR_WRITE(sc, AR_PHY_TIMING9, mask[0]);
+ /* Write entries from -3000 to -100. */
+ AR_WRITE(sc, AR_PHY_TIMING8, mask[1]);
+ AR_WRITE(sc, AR_PHY_TIMING10, mask[1]);
+ /* Write entries from 100 to 3000. */
+ AR_WRITE(sc, AR_PHY_PILOT_MASK_01_30, mask[2]);
+ AR_WRITE(sc, AR_PHY_CHANNEL_MASK_01_30, mask[2]);
+ /* Write entries from 3100 to 6000. */
+ AR_WRITE(sc, AR_PHY_PILOT_MASK_31_60, mask[3]);
+ AR_WRITE(sc, AR_PHY_CHANNEL_MASK_31_60, mask[3]);
+
+ /* Compute viterbi mask. */
+ for (cur = 6100; cur >= 0; cur -= 100)
+ p[+cur / 100] = abs(cur - bin) < 75;
+ for (cur = -100; cur >= -6100; cur -= 100)
+ m[-cur / 100] = abs(cur - bin) < 75;
+
+ /* Write viterbi mask (XXX needs to be reworked). */
+ reg =
+ m[46] << 30 | m[47] << 28 | m[48] << 26 | m[49] << 24 |
+ m[50] << 22 | m[51] << 20 | m[52] << 18 | m[53] << 16 |
+ m[54] << 14 | m[55] << 12 | m[56] << 10 | m[57] << 8 |
+ m[58] << 6 | m[59] << 4 | m[60] << 2 | m[61] << 0;
+ AR_WRITE(sc, AR_PHY_BIN_MASK_1, reg);
+ AR_WRITE(sc, AR_PHY_VIT_MASK2_M_46_61, reg);
+
+ /* XXX m[48] should be m[38] ? */
+ reg = m[31] << 28 | m[32] << 26 | m[33] << 24 |
+ m[34] << 22 | m[35] << 20 | m[36] << 18 | m[37] << 16 |
+ m[48] << 14 | m[39] << 12 | m[40] << 10 | m[41] << 8 |
+ m[42] << 6 | m[43] << 4 | m[44] << 2 | m[45] << 0;
+ AR_WRITE(sc, AR_PHY_BIN_MASK_2, reg);
+ AR_WRITE(sc, AR_PHY_VIT_MASK2_M_31_45, reg);
+
+ /* XXX This one is weird too. */
+ reg =
+ m[16] << 30 | m[16] << 28 | m[18] << 26 | m[18] << 24 |
+ m[20] << 22 | m[20] << 20 | m[22] << 18 | m[22] << 16 |
+ m[24] << 14 | m[24] << 12 | m[25] << 10 | m[26] << 8 |
+ m[27] << 6 | m[28] << 4 | m[29] << 2 | m[30] << 0;
+ AR_WRITE(sc, AR_PHY_BIN_MASK_3, reg);
+ AR_WRITE(sc, AR_PHY_VIT_MASK2_M_16_30, reg);
+
+ reg =
+ m[ 0] << 30 | m[ 1] << 28 | m[ 2] << 26 | m[ 3] << 24 |
+ m[ 4] << 22 | m[ 5] << 20 | m[ 6] << 18 | m[ 7] << 16 |
+ m[ 8] << 14 | m[ 9] << 12 | m[10] << 10 | m[11] << 8 |
+ m[12] << 6 | m[13] << 4 | m[14] << 2 | m[15] << 0;
+ AR_WRITE(sc, AR_PHY_MASK_CTL, reg);
+ AR_WRITE(sc, AR_PHY_VIT_MASK2_M_00_15, reg);
+
+ reg = p[15] << 28 | p[14] << 26 | p[13] << 24 |
+ p[12] << 22 | p[11] << 20 | p[10] << 18 | p[ 9] << 16 |
+ p[ 8] << 14 | p[ 7] << 12 | p[ 6] << 10 | p[ 5] << 8 |
+ p[ 4] << 6 | p[ 3] << 4 | p[ 2] << 2 | p[ 1] << 0;
+ AR_WRITE(sc, AR_PHY_BIN_MASK2_1, reg);
+ AR_WRITE(sc, AR_PHY_VIT_MASK2_P_15_01, reg);
+
+ reg = p[30] << 28 | p[29] << 26 | p[28] << 24 |
+ p[27] << 22 | p[26] << 20 | p[25] << 18 | p[24] << 16 |
+ p[23] << 14 | p[22] << 12 | p[21] << 10 | p[20] << 8 |
+ p[19] << 6 | p[18] << 4 | p[17] << 2 | p[16] << 0;
+ AR_WRITE(sc, AR_PHY_BIN_MASK2_2, reg);
+ AR_WRITE(sc, AR_PHY_VIT_MASK2_P_30_16, reg);
+
+ reg = p[45] << 28 | p[44] << 26 | p[43] << 24 |
+ p[42] << 22 | p[41] << 20 | p[40] << 18 | p[39] << 16 |
+ p[38] << 14 | p[37] << 12 | p[36] << 10 | p[35] << 8 |
+ p[34] << 6 | p[33] << 4 | p[32] << 2 | p[31] << 0;
+ AR_WRITE(sc, AR_PHY_BIN_MASK2_3, reg);
+ AR_WRITE(sc, AR_PHY_VIT_MASK2_P_45_31, reg);
+
+ reg =
+ p[61] << 30 | p[60] << 28 | p[59] << 26 | p[58] << 24 |
+ p[57] << 22 | p[56] << 20 | p[55] << 18 | p[54] << 16 |
+ p[53] << 14 | p[52] << 12 | p[51] << 10 | p[50] << 8 |
+ p[49] << 6 | p[48] << 4 | p[47] << 2 | p[46] << 0;
+ AR_WRITE(sc, AR_PHY_BIN_MASK2_4, reg);
+ AR_WRITE(sc, AR_PHY_VIT_MASK2_P_61_46, reg);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_hw_init(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ struct athn_ops *ops = &sc->ops;
+ const struct athn_ini *ini = sc->ini;
+ const uint32_t *pvals;
+ uint32_t reg;
+ int i;
+
+ AR_WRITE(sc, AR_PHY(0), 0x00000007);
+ AR_WRITE(sc, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+
+ if (!AR_SINGLE_CHIP(sc))
+ ar5416_reset_addac(sc, c);
+
+ AR_WRITE(sc, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
+
+ /* First initialization step (depends on channel band/bandwidth). */
+ if (extc != NULL) {
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ pvals = ini->vals_2g40;
+ else
+ pvals = ini->vals_5g40;
+ } else {
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ pvals = ini->vals_2g20;
+ else
+ pvals = ini->vals_5g20;
+ }
+
+ DPRINTFN(4, ("writing modal init vals\n"));
+ for (i = 0; i < ini->nregs; i++) {
+ uint32_t val = pvals[i];
+
+ /* Fix AR_AN_TOP2 initialization value if required. */
+ if (ini->regs[i] == AR_AN_TOP2 &&
+ (sc->flags & ATHN_FLAG_AN_TOP2_FIXUP))
+ val &= ~AR_AN_TOP2_PWDCLKIND;
+ AR_WRITE(sc, ini->regs[i], val);
+ if (AR_IS_ANALOG_REG(ini->regs[i])) {
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+ }
+ if ((i & 0x1f) == 0)
+ DELAY(1);
+ }
+ AR_WRITE_BARRIER(sc);
+
+ if (sc->rx_gain != NULL)
+ ar9280_reset_rx_gain(sc, c);
+ if (sc->tx_gain != NULL)
+ ar9280_reset_tx_gain(sc, c);
+
+ if (AR_SREV_9271_10(sc)) {
+ AR_WRITE(sc, AR_PHY(68), 0x30002311);
+ AR_WRITE(sc, AR_PHY_RF_CTL3, 0x0a020001);
+ }
+ AR_WRITE_BARRIER(sc);
+
+ printf("ar5008_hw_init working through...\n");
+ if (1)
+ return;
+ /* Second initialization step (common to all channels). */
+ DPRINTFN(4, ("writing common init vals\n"));
+ for (i = 0; i < ini->ncmregs; i++) {
+ AR_WRITE(sc, ini->cmregs[i], ini->cmvals[i]);
+ if (AR_IS_ANALOG_REG(ini->cmregs[i])) {
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+ }
+ if ((i & 0x1f) == 0)
+ DELAY(1);
+ }
+ AR_WRITE_BARRIER(sc);
+
+ if (!AR_SINGLE_CHIP(sc))
+ ar5416_reset_bb_gain(sc, c);
+
+ if (IEEE80211_IS_CHAN_5GHZ(c) &&
+ (sc->flags & ATHN_FLAG_FAST_PLL_CLOCK)) {
+ /* Update modal values for fast PLL clock. */
+ if (extc != NULL)
+ pvals = ini->fastvals_5g40;
+ else
+ pvals = ini->fastvals_5g20;
+ DPRINTFN(4, ("writing fast pll clock init vals\n"));
+ for (i = 0; i < ini->nfastregs; i++) {
+ AR_WRITE(sc, ini->fastregs[i], pvals[i]);
+ if (AR_IS_ANALOG_REG(ini->fastregs[i])) {
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+ }
+ if ((i & 0x1f) == 0)
+ DELAY(1);
+ }
+ }
+
+ /*
+ * Set the RX_ABORT and RX_DIS bits to prevent frames with corrupted
+ * descriptor status.
+ */
+ AR_SETBITS(sc, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
+
+ /* Hardware workarounds for occasional Rx data corruption. */
+ if (AR_SREV_9280_10_OR_LATER(sc)) {
+ reg = AR_READ(sc, AR_PCU_MISC_MODE2);
+ if (!AR_SREV_9271(sc))
+ reg &= ~AR_PCU_MISC_MODE2_HWWAR1;
+ if (AR_SREV_9287_10_OR_LATER(sc))
+ reg &= ~AR_PCU_MISC_MODE2_HWWAR2;
+ AR_WRITE(sc, AR_PCU_MISC_MODE2, reg);
+
+ } else if (AR_SREV_5416_20_OR_LATER(sc)) {
+ /* Disable baseband clock gating. */
+ AR_WRITE(sc, AR_PHY(651), 0x11);
+
+ if (AR_SREV_9160(sc)) {
+ /* Disable RIFS search to fix baseband hang. */
+ AR_CLRBITS(sc, AR_PHY_HEAVY_CLIP_FACTOR_RIFS,
+ AR_PHY_RIFS_INIT_DELAY_M);
+ }
+ }
+ AR_WRITE_BARRIER(sc);
+
+ ar5008_set_phy(sc, c, extc);
+ ar5008_init_chains(sc);
+
+ if (sc->flags & ATHN_FLAG_OLPC) {
+ sc->olpc_ticks = ticks;
+ ops->olpc_init(sc);
+ }
+
+ ops->set_txpower(sc, c, extc);
+
+ if (!AR_SINGLE_CHIP(sc))
+ ar5416_rf_reset(sc, c);
+}
+
+uint8_t
+ar5008_get_vpd(uint8_t pwr, const uint8_t *pwrPdg, const uint8_t *vpdPdg,
+ int nicepts)
+{
+ uint8_t vpd;
+ int i, lo, hi;
+
+ for (i = 0; i < nicepts; i++)
+ if (pwrPdg[i] > pwr)
+ break;
+ hi = i;
+ lo = hi - 1;
+ if (lo == -1)
+ lo = hi;
+ else if (hi == nicepts)
+ hi = lo;
+
+ vpd = athn_interpolate(pwr, pwrPdg[lo], vpdPdg[lo],
+ pwrPdg[hi], vpdPdg[hi]);
+ return (vpd);
+}
+
+void
+ar5008_get_pdadcs(struct athn_softc *sc, uint8_t fbin,
+ struct athn_pier *lopier, struct athn_pier *hipier, int nxpdgains,
+ int nicepts, uint8_t overlap, uint8_t *boundaries, uint8_t *pdadcs)
+{
+#define DB(x) ((x) / 2) /* Convert half dB to dB. */
+ uint8_t minpwr[AR_PD_GAINS_IN_MASK], maxpwr[AR_PD_GAINS_IN_MASK];
+ uint8_t vpd[AR_MAX_PWR_RANGE_IN_HALF_DB], pwr;
+ uint8_t lovpd, hivpd, boundary;
+ int16_t ss, delta, vpdstep, val;
+ int i, j, npdadcs, nvpds, maxidx, tgtidx;
+
+ /* Compute min and max power in half dB for each pdGain. */
+ for (i = 0; i < nxpdgains; i++) {
+ minpwr[i] = MAX(lopier->pwr[i][0], hipier->pwr[i][0]);
+ maxpwr[i] = MIN(lopier->pwr[i][nicepts - 1],
+ hipier->pwr[i][nicepts - 1]);
+ }
+
+ /* Fill phase domain analog-to-digital converter (PDADC) table. */
+ npdadcs = 0;
+ for (i = 0; i < nxpdgains; i++) {
+ if (i != nxpdgains - 1)
+ boundaries[i] = DB(maxpwr[i] + minpwr[i + 1]) / 2;
+ else
+ boundaries[i] = DB(maxpwr[i]);
+ if (boundaries[i] > AR_MAX_RATE_POWER)
+ boundaries[i] = AR_MAX_RATE_POWER;
+
+ if (i == 0 && !AR_SREV_5416_20_OR_LATER(sc)) {
+ /* Fix the gain delta (AR5416 1.0 only). */
+ delta = boundaries[0] - 23;
+ boundaries[0] = 23;
+ } else
+ delta = 0;
+
+ /* Find starting index for this pdGain. */
+ if (i != 0) {
+ ss = boundaries[i - 1] - DB(minpwr[i]) -
+ overlap + 1 + delta;
+ } else if (AR_SREV_9280_10_OR_LATER(sc)) {
+ ss = -DB(minpwr[i]);
+ } else
+ ss = 0;
+
+ /* Compute Vpd table for this pdGain. */
+ nvpds = DB(maxpwr[i] - minpwr[i]) + 1;
+ memset(vpd, 0, sizeof(vpd));
+ pwr = minpwr[i];
+ for (j = 0; j < nvpds; j++) {
+ /* Get lower and higher Vpd. */
+ lovpd = ar5008_get_vpd(pwr, lopier->pwr[i],
+ lopier->vpd[i], nicepts);
+ hivpd = ar5008_get_vpd(pwr, hipier->pwr[i],
+ hipier->vpd[i], nicepts);
+
+ /* Interpolate the final Vpd. */
+ vpd[j] = athn_interpolate(fbin,
+ lopier->fbin, lovpd, hipier->fbin, hivpd);
+
+ pwr += 2; /* In half dB. */
+ }
+
+ /* Extrapolate data for ss < 0. */
+ if (vpd[1] > vpd[0])
+ vpdstep = vpd[1] - vpd[0];
+ else
+ vpdstep = 1;
+ while (ss < 0 && npdadcs < AR_NUM_PDADC_VALUES - 1) {
+ val = vpd[0] + ss * vpdstep;
+ pdadcs[npdadcs++] = MAX(val, 0);
+ ss++;
+ }
+
+ tgtidx = boundaries[i] + overlap - DB(minpwr[i]);
+ maxidx = MIN(tgtidx, nvpds);
+ while (ss < maxidx && npdadcs < AR_NUM_PDADC_VALUES - 1)
+ pdadcs[npdadcs++] = vpd[ss++];
+
+ if (tgtidx < maxidx)
+ continue;
+
+ /* Extrapolate data for maxidx <= ss <= tgtidx. */
+ if (vpd[nvpds - 1] > vpd[nvpds - 2])
+ vpdstep = vpd[nvpds - 1] - vpd[nvpds - 2];
+ else
+ vpdstep = 1;
+ while (ss <= tgtidx && npdadcs < AR_NUM_PDADC_VALUES - 1) {
+ val = vpd[nvpds - 1] + (ss - maxidx + 1) * vpdstep;
+ pdadcs[npdadcs++] = MIN(val, 255);
+ ss++;
+ }
+ }
+
+ /* Fill remaining PDADC and boundaries entries. */
+ if (AR_SREV_9285(sc))
+ boundary = AR9285_PD_GAIN_BOUNDARY_DEFAULT;
+ else /* Fill with latest. */
+ boundary = boundaries[nxpdgains - 1];
+
+ for (; nxpdgains < AR_PD_GAINS_IN_MASK; nxpdgains++)
+ boundaries[nxpdgains] = boundary;
+
+ for (; npdadcs < AR_NUM_PDADC_VALUES; npdadcs++)
+ pdadcs[npdadcs] = pdadcs[npdadcs - 1];
+#undef DB
+}
+
+void
+ar5008_get_lg_tpow(struct athn_softc *sc, struct ieee80211_channel *c,
+ uint8_t ctl, const struct ar_cal_target_power_leg *tgt, int nchans,
+ uint8_t tpow[4])
+{
+ uint8_t fbin;
+ int i, lo, hi;
+
+ /* Find interval (lower and upper indices). */
+ fbin = athn_chan2fbin(c);
+ for (i = 0; i < nchans; i++) {
+ if (tgt[i].bChannel == AR_BCHAN_UNUSED ||
+ tgt[i].bChannel > fbin)
+ break;
+ }
+ hi = i;
+ lo = hi - 1;
+ if (lo == -1)
+ lo = hi;
+ else if (hi == nchans || tgt[hi].bChannel == AR_BCHAN_UNUSED)
+ hi = lo;
+
+ /* Interpolate values. */
+ for (i = 0; i < 4; i++) {
+ tpow[i] = athn_interpolate(fbin,
+ tgt[lo].bChannel, tgt[lo].tPow2x[i],
+ tgt[hi].bChannel, tgt[hi].tPow2x[i]);
+ }
+ /* XXX Apply conformance testing limit. */
+}
+
+void
+ar5008_get_ht_tpow(struct athn_softc *sc, struct ieee80211_channel *c,
+ uint8_t ctl, const struct ar_cal_target_power_ht *tgt, int nchans,
+ uint8_t tpow[8])
+{
+ uint8_t fbin;
+ int i, lo, hi;
+
+ /* Find interval (lower and upper indices). */
+ fbin = athn_chan2fbin(c);
+ for (i = 0; i < nchans; i++) {
+ if (tgt[i].bChannel == AR_BCHAN_UNUSED ||
+ tgt[i].bChannel > fbin)
+ break;
+ }
+ hi = i;
+ lo = hi - 1;
+ if (lo == -1)
+ lo = hi;
+ else if (hi == nchans || tgt[hi].bChannel == AR_BCHAN_UNUSED)
+ hi = lo;
+
+ /* Interpolate values. */
+ for (i = 0; i < 8; i++) {
+ tpow[i] = athn_interpolate(fbin,
+ tgt[lo].bChannel, tgt[lo].tPow2x[i],
+ tgt[hi].bChannel, tgt[hi].tPow2x[i]);
+ }
+ /* XXX Apply conformance testing limit. */
+}
+
+/*
+ * Adaptive noise immunity.
+ */
+void
+ar5008_set_noise_immunity_level(struct athn_softc *sc, int level)
+{
+ int high = level == 4;
+ uint32_t reg;
+
+ reg = AR_READ(sc, AR_PHY_DESIRED_SZ);
+ reg = RW(reg, AR_PHY_DESIRED_SZ_TOT_DES, high ? -62 : -55);
+ AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg);
+
+ reg = AR_READ(sc, AR_PHY_AGC_CTL1);
+ reg = RW(reg, AR_PHY_AGC_CTL1_COARSE_LOW, high ? -70 : -64);
+ reg = RW(reg, AR_PHY_AGC_CTL1_COARSE_HIGH, high ? -12 : -14);
+ AR_WRITE(sc, AR_PHY_AGC_CTL1, reg);
+
+ reg = AR_READ(sc, AR_PHY_FIND_SIG);
+ reg = RW(reg, AR_PHY_FIND_SIG_FIRPWR, high ? -80 : -78);
+ AR_WRITE(sc, AR_PHY_FIND_SIG, reg);
+
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_enable_ofdm_weak_signal(struct athn_softc *sc)
+{
+ uint32_t reg;
+
+ reg = AR_READ(sc, AR_PHY_SFCORR_LOW);
+ reg = RW(reg, AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 50);
+ reg = RW(reg, AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 40);
+ reg = RW(reg, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 48);
+ AR_WRITE(sc, AR_PHY_SFCORR_LOW, reg);
+
+ reg = AR_READ(sc, AR_PHY_SFCORR);
+ reg = RW(reg, AR_PHY_SFCORR_M1_THRESH, 77);
+ reg = RW(reg, AR_PHY_SFCORR_M2_THRESH, 64);
+ reg = RW(reg, AR_PHY_SFCORR_M2COUNT_THR, 16);
+ AR_WRITE(sc, AR_PHY_SFCORR, reg);
+
+ reg = AR_READ(sc, AR_PHY_SFCORR_EXT);
+ reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH_LOW, 50);
+ reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH_LOW, 40);
+ reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH, 77);
+ reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH, 64);
+ AR_WRITE(sc, AR_PHY_SFCORR_EXT, reg);
+
+ AR_SETBITS(sc, AR_PHY_SFCORR_LOW,
+ AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_disable_ofdm_weak_signal(struct athn_softc *sc)
+{
+ uint32_t reg;
+
+ reg = AR_READ(sc, AR_PHY_SFCORR_LOW);
+ reg = RW(reg, AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 127);
+ reg = RW(reg, AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 127);
+ reg = RW(reg, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 63);
+ AR_WRITE(sc, AR_PHY_SFCORR_LOW, reg);
+
+ reg = AR_READ(sc, AR_PHY_SFCORR);
+ reg = RW(reg, AR_PHY_SFCORR_M1_THRESH, 127);
+ reg = RW(reg, AR_PHY_SFCORR_M2_THRESH, 127);
+ reg = RW(reg, AR_PHY_SFCORR_M2COUNT_THR, 31);
+ AR_WRITE(sc, AR_PHY_SFCORR, reg);
+
+ reg = AR_READ(sc, AR_PHY_SFCORR_EXT);
+ reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH_LOW, 127);
+ reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH_LOW, 127);
+ reg = RW(reg, AR_PHY_SFCORR_EXT_M1_THRESH, 127);
+ reg = RW(reg, AR_PHY_SFCORR_EXT_M2_THRESH, 127);
+ AR_WRITE(sc, AR_PHY_SFCORR_EXT, reg);
+
+ AR_CLRBITS(sc, AR_PHY_SFCORR_LOW,
+ AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_set_cck_weak_signal(struct athn_softc *sc, int high)
+{
+ uint32_t reg;
+
+ reg = AR_READ(sc, AR_PHY_CCK_DETECT);
+ reg = RW(reg, AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, high ? 6 : 8);
+ AR_WRITE(sc, AR_PHY_CCK_DETECT, reg);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_set_firstep_level(struct athn_softc *sc, int level)
+{
+ uint32_t reg;
+
+ reg = AR_READ(sc, AR_PHY_FIND_SIG);
+ reg = RW(reg, AR_PHY_FIND_SIG_FIRSTEP, level * 4);
+ AR_WRITE(sc, AR_PHY_FIND_SIG, reg);
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar5008_set_spur_immunity_level(struct athn_softc *sc, int level)
+{
+ uint32_t reg;
+
+ reg = AR_READ(sc, AR_PHY_TIMING5);
+ reg = RW(reg, AR_PHY_TIMING5_CYCPWR_THR1, (level + 1) * 2);
+ AR_WRITE(sc, AR_PHY_TIMING5, reg);
+ AR_WRITE_BARRIER(sc);
+}
diff --git a/sys/dev/athn/ic/ar5008reg.h b/sys/dev/athn/ic/ar5008reg.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar5008reg.h
@@ -0,0 +1,1038 @@
+/* $OpenBSD: ar5008reg.h,v 1.7 2020/04/27 08:21:34 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * MAC registers.
+ */
+#define AR_ISR_S2_S 0x00cc
+#define AR_ISR_S3_S 0x00d0
+#define AR_ISR_S4_S 0x00d4
+#define AR_ISR_S5_S 0x00d8
+#define AR_GPIO_IN_OUT 0x4048
+#define AR_GPIO_OE_OUT 0x404c
+#define AR_GPIO_INTR_POL 0x4050
+#define AR_GPIO_INPUT_EN_VAL 0x4054
+#define AR_GPIO_INPUT_MUX1 0x4058
+#define AR_GPIO_INPUT_MUX2 0x405c
+#define AR_GPIO_OUTPUT_MUX(i) (0x4060 + (i) * 4)
+#define AR_INPUT_STATE 0x406c
+#define AR_EEPROM_STATUS_DATA 0x407c
+#define AR_OBS 0x4080
+#define AR_GPIO_PDPU 0x4088
+#define AR_PCIE_MSI 0x4094
+
+/*
+ * Analog registers.
+ */
+#define AR_IS_ANALOG_REG(reg) ((reg) >= 0x7800 && (reg) <= 0x78b4)
+#define AR_AN_RF2G1_CH0 0x7810
+#define AR_AN_RF5G1_CH0 0x7818
+#define AR_AN_RF2G1_CH1 0x7834
+#define AR_AN_RF5G1_CH1 0x783c
+#define AR_AN_SYNTH9 0x7868
+#define AR_AN_TOP1 0x7890
+#define AR_AN_TOP2 0x7894
+
+/*
+ * PHY registers.
+ */
+#define AR_PHY_BASE 0x9800
+#define AR_PHY(i) (AR_PHY_BASE + (i) * 4)
+#define AR_PHY_TEST 0x9800
+#define AR_PHY_TURBO 0x9804
+#define AR_PHY_TEST2 0x9808
+#define AR_PHY_TIMING2 0x9810
+#define AR_PHY_TIMING3 0x9814
+#define AR_PHY_CHIP_ID 0x9818
+#define AR_PHY_ACTIVE 0x981c
+#define AR_PHY_RF_CTL2 0x9824
+#define AR_PHY_RF_CTL3 0x9828
+#define AR_PHY_ADC_CTL 0x982c
+#define AR_PHY_ADC_SERIAL_CTL 0x9830
+#define AR_PHY_RF_CTL4 0x9834
+#define AR_PHY_TSTDAC_CONST 0x983c
+#define AR_PHY_SETTLING 0x9844
+#define AR_PHY_RXGAIN 0x9848
+#define AR_PHY_DESIRED_SZ 0x9850
+#define AR_PHY_FIND_SIG 0x9858
+#define AR_PHY_AGC_CTL1 0x985c
+#define AR_PHY_AGC_CONTROL 0x9860
+#define AR_PHY_CCA(i) (0x9864 + (i) * 0x1000)
+#define AR_PHY_SFCORR 0x9868
+#define AR_PHY_SFCORR_LOW 0x986c
+#define AR_PHY_SLEEP_CTR_CONTROL 0x9870
+#define AR_PHY_SLEEP_CTR_LIMIT 0x9874
+#define AR_PHY_SLEEP_SCAL 0x9878
+#define AR_PHY_PLL_CTL 0x987c
+#define AR_PHY_BIN_MASK_1 0x9900
+#define AR_PHY_BIN_MASK_2 0x9904
+#define AR_PHY_BIN_MASK_3 0x9908
+#define AR_PHY_MASK_CTL 0x990c
+#define AR_PHY_RX_DELAY 0x9914
+#define AR_PHY_SEARCH_START_DELAY 0x9918
+#define AR_PHY_TIMING_CTRL4_0 0x9920
+#define AR_PHY_TIMING_CTRL4(i) (0x9920 + (i) * 0x1000)
+#define AR_PHY_TIMING5 0x9924
+#define AR_PHY_POWER_TX_RATE1 0x9934
+#define AR_PHY_POWER_TX_RATE2 0x9938
+#define AR_PHY_POWER_TX_RATE_MAX 0x993c
+#define AR_PHY_RADAR_EXT 0x9940
+#define AR_PHY_FRAME_CTL 0x9944
+#define AR_PHY_SPUR_REG 0x994c
+#define AR_PHY_RADAR_0 0x9954
+#define AR_PHY_RADAR_1 0x9958
+#define AR_PHY_SWITCH_CHAIN_0 0x9960
+#define AR_PHY_SWITCH_COM 0x9964
+#define AR_PHY_SIGMA_DELTA 0x996c
+#define AR_PHY_RESTART 0x9970
+#define AR_PHY_RFBUS_REQ 0x997c
+#define AR_PHY_TIMING7 0x9980
+#define AR_PHY_TIMING8 0x9984
+#define AR_PHY_BIN_MASK2_1 0x9988
+#define AR_PHY_BIN_MASK2_2 0x998c
+#define AR_PHY_BIN_MASK2_3 0x9990
+#define AR_PHY_BIN_MASK2_4 0x9994
+#define AR_PHY_TIMING9 0x9998
+#define AR_PHY_TIMING10 0x999c
+#define AR_PHY_TIMING11 0x99a0
+#define AR_PHY_RX_CHAINMASK 0x99a4
+#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
+#define AR_PHY_NEW_ADC_DC_GAIN_CORR(i) (0x99b4 + (i) * 0x1000)
+#define AR_PHY_EXT_CCA0 0x99b8
+#define AR_PHY_EXT_CCA(i) (0x99bc + (i) * 0x1000)
+#define AR_PHY_SFCORR_EXT 0x99c0
+#define AR_PHY_HALFGI 0x99d0
+#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
+#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
+#define AR_PHY_CHAN_INFO_MEMORY 0x99dc
+#define AR_PHY_HEAVY_CLIP_ENABLE 0x99e0
+#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99ec
+#define AR_PHY_CALMODE 0x99f0
+#define AR_PHY_REFCLKDLY 0x99f4
+#define AR_PHY_REFCLKPD 0x99f8
+#define AR_PHY_BB_RFGAIN(i) (0x9a00 + (i) * 4)
+#define AR_PHY_CAL_MEAS_0(i) (0x9c10 + (i) * 0x1000)
+#define AR_PHY_CAL_MEAS_1(i) (0x9c14 + (i) * 0x1000)
+#define AR_PHY_CAL_MEAS_2(i) (0x9c18 + (i) * 0x1000)
+#define AR_PHY_CAL_MEAS_3(i) (0x9c1c + (i) * 0x1000)
+#define AR_PHY_CURRENT_RSSI 0x9c1c
+#define AR_PHY_RFBUS_GRANT 0x9c20
+#define AR9280_PHY_CURRENT_RSSI 0x9c3c
+#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9cf4
+#define AR_PHY_CHAN_INFO_GAIN 0x9cfc
+#define AR_PHY_MODE 0xa200
+#define AR_PHY_CCK_TX_CTRL 0xa204
+#define AR_PHY_CCK_DETECT 0xa208
+#define AR_PHY_GAIN_2GHZ 0xa20c
+#define AR_PHY_CCK_RXCTRL4 0xa21c
+#define AR_PHY_DAG_CTRLCCK 0xa228
+#define AR_PHY_FORCE_CLKEN_CCK 0xa22c
+#define AR_PHY_POWER_TX_RATE3 0xa234
+#define AR_PHY_POWER_TX_RATE4 0xa238
+#define AR_PHY_SCRM_SEQ_XR 0xa23c
+#define AR_PHY_HEADER_DETECT_XR 0xa240
+#define AR_PHY_CHIRP_DETECTED_XR 0xa244
+#define AR_PHY_BLUETOOTH 0xa254
+#define AR_PHY_TPCRG1 0xa258
+#define AR_PHY_TX_PWRCTRL4 0xa264
+#define AR_PHY_ANALOG_SWAP 0xa268
+#define AR_PHY_TPCRG5 0xa26c
+#define AR_PHY_TX_PWRCTRL6_0 0xa270
+#define AR_PHY_TX_PWRCTRL7 0xa274
+#define AR_PHY_TX_PWRCTRL9 0xa27c
+#define AR_PHY_PDADC_TBL_BASE 0xa280
+#define AR_PHY_TX_GAIN_TBL(i) (0xa300 + (i) * 4)
+#define AR_PHY_CL_CAL_CTL 0xa358
+#define AR_PHY_CLC_TBL(i) (0xa35c + (i) * 4)
+#define AR_PHY_POWER_TX_RATE5 0xa38c
+#define AR_PHY_POWER_TX_RATE6 0xa390
+#define AR_PHY_CH0_TX_PWRCTRL11 0xa398
+#define AR_PHY_CAL_CHAINMASK 0xa39c
+#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
+#define AR_PHY_VIT_MASK2_M_31_45 0xa3a4
+#define AR_PHY_VIT_MASK2_M_16_30 0xa3a8
+#define AR_PHY_VIT_MASK2_M_00_15 0xa3ac
+#define AR_PHY_PILOT_MASK_01_30 0xa3b0
+#define AR_PHY_PILOT_MASK_31_60 0xa3b4
+#define AR_PHY_VIT_MASK2_P_15_01 0xa3b8
+#define AR_PHY_VIT_MASK2_P_30_16 0xa3bc
+#define AR_PHY_VIT_MASK2_P_45_31 0xa3c0
+#define AR_PHY_VIT_MASK2_P_61_46 0xa3c4
+#define AR_PHY_POWER_TX_SUB 0xa3c8
+#define AR_PHY_POWER_TX_RATE7 0xa3cc
+#define AR_PHY_POWER_TX_RATE8 0xa3d0
+#define AR_PHY_POWER_TX_RATE9 0xa3d4
+#define AR_PHY_XPA_CFG 0xa3d8
+#define AR_PHY_TX_PWRCTRL6_1 0xb270
+#define AR_PHY_CH1_TX_PWRCTRL11 0xb398
+
+/*
+ * AR7010 registers.
+ */
+#define AR7010_GPIO_OE 0x52000
+#define AR7010_GPIO_IN 0x52004
+#define AR7010_GPIO_OUT 0x52008
+
+
+/* Bits for AR_AN_RF2G1_CH0. */
+#define AR_AN_RF2G1_CH0_OB_M 0x03800000
+#define AR_AN_RF2G1_CH0_OB_S 23
+#define AR_AN_RF2G1_CH0_DB_M 0x1c000000
+#define AR_AN_RF2G1_CH0_DB_S 26
+
+/* Bits for AR_AN_RF5G1_CH0. */
+#define AR_AN_RF5G1_CH0_OB5_M 0x00070000
+#define AR_AN_RF5G1_CH0_OB5_S 16
+#define AR_AN_RF5G1_CH0_DB5_M 0x00380000
+#define AR_AN_RF5G1_CH0_DB5_S 19
+
+/* Bits for AR_AN_RF2G1_CH1. */
+#define AR_AN_RF2G1_CH1_OB_M 0x03800000
+#define AR_AN_RF2G1_CH1_OB_S 23
+#define AR_AN_RF2G1_CH1_DB_M 0x1c000000
+#define AR_AN_RF2G1_CH1_DB_S 26
+
+/* Bits for AR_AN_RF5G1_CH1. */
+#define AR_AN_RF5G1_CH1_OB5_M 0x00070000
+#define AR_AN_RF5G1_CH1_OB5_S 16
+#define AR_AN_RF5G1_CH1_DB5_M 0x00380000
+#define AR_AN_RF5G1_CH1_DB5_S 19
+
+/* Bits for AR_AN_SYNTH9. */
+#define AR_AN_SYNTH9_REFDIVA_M 0xf8000000
+#define AR_AN_SYNTH9_REFDIVA_S 27
+
+/* Bits for AR_AN_TOP1. */
+#define AR_AN_TOP1_DACLPMODE 0x00040000
+
+/* Bits for AR_AN_TOP2. */
+#define AR_AN_TOP2_XPABIAS_LVL_M 0xc0000000
+#define AR_AN_TOP2_XPABIAS_LVL_S 30
+#define AR_AN_TOP2_LOCALBIAS 0x00200000
+#define AR_AN_TOP2_PWDCLKIND 0x00400000
+
+/* Bits for AR_PHY_TEST. */
+#define AR_PHY_TEST_RFSILENT_BB 0x00002000
+#define AR_PHY_TEST_AGC_CLR 0x10000000
+
+/* Bits for AR_PHY_TURBO. */
+#define AR_PHY_FC_TURBO_MODE 0x00000001
+#define AR_PHY_FC_TURBO_SHORT 0x00000002
+#define AR_PHY_FC_DYN2040_EN 0x00000004
+#define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008
+#define AR_PHY_FC_DYN2040_PRI_CH 0x00000010
+#define AR_PHY_FC_DYN2040_EXT_CH 0x00000020
+#define AR_PHY_FC_HT_EN 0x00000040
+#define AR_PHY_FC_SHORT_GI_40 0x00000080
+#define AR_PHY_FC_WALSH 0x00000100
+#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200
+#define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800
+
+/* Bits for AR_PHY_TIMING3. */
+#define AR_PHY_TIMING3_DSC_MAN_M 0xfffe0000
+#define AR_PHY_TIMING3_DSC_MAN_S 17
+#define AR_PHY_TIMING3_DSC_EXP_M 0x0001e000
+#define AR_PHY_TIMING3_DSC_EXP_S 13
+
+/* Bits for AR_PHY_CHIP_ID. */
+#define AR_PHY_CHIP_ID_REV_0 0x00000080
+#define AR_PHY_CHIP_ID_REV_1 0x00000081
+#define AR_PHY_CHIP_ID_9160_REV_0 0x000000b0
+
+/* Bits for AR_PHY_ACTIVE. */
+#define AR_PHY_ACTIVE_EN 0x00000001
+#define AR_PHY_ACTIVE_DIS 0x00000000
+
+/* Bits for AR_PHY_RF_CTL2. */
+#define AR_PHY_TX_END_DATA_START_M 0x000000ff
+#define AR_PHY_TX_END_DATA_START_S 0
+#define AR_PHY_TX_END_PA_ON_M 0x0000ff00
+#define AR_PHY_TX_END_PA_ON_S 8
+
+/* Bits for AR_PHY_RF_CTL3. */
+#define AR_PHY_TX_END_TO_A2_RX_ON_M 0x00ff0000
+#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
+
+/* Bits for AR_PHY_ADC_CTL. */
+#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_M 0x00000003
+#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0
+#define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000
+#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000
+#define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000
+#define AR_PHY_ADC_CTL_ON_INBUFGAIN_M 0x00030000
+#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16
+
+/* Bits for AR_PHY_ADC_SERIAL_CTL. */
+#define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000
+#define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001
+
+/* Bits for AR_PHY_RF_CTL4. */
+#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_M 0xff000000
+#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24
+#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_M 0x00ff0000
+#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16
+#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_M 0x0000ff00
+#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8
+#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_M 0x000000ff
+#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
+
+/* Bits for AR_PHY_SETTLING. */
+#define AR_PHY_SETTLING_SWITCH_M 0x00003f80
+#define AR_PHY_SETTLING_SWITCH_S 7
+
+/* Bits for AR_PHY_RXGAIN. */
+#define AR_PHY_RXGAIN_TXRX_ATTEN_M 0x0003f000
+#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
+#define AR_PHY_RXGAIN_TXRX_RF_MAX_M 0x007c0000
+#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN_M 0x00003f80
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN_M 0x001fc000
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
+
+/* Bits for AR_PHY_DESIRED_SZ. */
+#define AR_PHY_DESIRED_SZ_ADC_M 0x000000ff
+#define AR_PHY_DESIRED_SZ_ADC_S 0
+#define AR_PHY_DESIRED_SZ_PGA_M 0x0000ff00
+#define AR_PHY_DESIRED_SZ_PGA_S 8
+#define AR_PHY_DESIRED_SZ_TOT_DES_M 0x0ff00000
+#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
+
+/* Bits for AR_PHY_FIND_SIG. */
+#define AR_PHY_FIND_SIG_FIRSTEP_M 0x0003f000
+#define AR_PHY_FIND_SIG_FIRSTEP_S 12
+#define AR_PHY_FIND_SIG_FIRPWR_M 0x03fc0000
+#define AR_PHY_FIND_SIG_FIRPWR_S 18
+
+/* Bits for AR_PHY_AGC_CTL1. */
+#define AR_PHY_AGC_CTL1_COARSE_LOW_M 0x00007f80
+#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7
+#define AR_PHY_AGC_CTL1_COARSE_HIGH_M 0x003f8000
+#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15
+
+/* Bits for AR_PHY_AGC_CONTROL. */
+#define AR_PHY_AGC_CONTROL_CAL 0x00000001
+#define AR_PHY_AGC_CONTROL_NF 0x00000002
+#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000
+#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000
+#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
+
+/* Bits for AR_PHY_CCA. */
+#define AR_PHY_MAXCCA_PWR_M 0x000001ff
+#define AR_PHY_MAXCCA_PWR_S 0
+#define AR_PHY_CCA_THRESH62_M 0x0007f000
+#define AR_PHY_CCA_THRESH62_S 12
+#define AR_PHY_MINCCA_PWR_M 0x0ff80000
+#define AR_PHY_MINCCA_PWR_S 19
+#define AR9280_PHY_CCA_THRESH62_M 0x000ff000
+#define AR9280_PHY_CCA_THRESH62_S 12
+#define AR9280_PHY_MINCCA_PWR_M 0x1ff00000
+#define AR9280_PHY_MINCCA_PWR_S 20
+
+/* Bits for AR_PHY_SFCORR_LOW. */
+#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_M 0x00003f00
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_M 0x001fc000
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_M 0x0fe00000
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
+
+/* Bits for AR_PHY_SFCORR. */
+#define AR_PHY_SFCORR_M2COUNT_THR_M 0x0000001f
+#define AR_PHY_SFCORR_M2COUNT_THR_S 0
+#define AR_PHY_SFCORR_M1_THRESH_M 0x00fe0000
+#define AR_PHY_SFCORR_M1_THRESH_S 17
+#define AR_PHY_SFCORR_M2_THRESH_M 0x7f000000
+#define AR_PHY_SFCORR_M2_THRESH_S 24
+
+/* Bits for AR_PHY_RX_DELAY. */
+#define AR_PHY_RX_DELAY_DELAY_M 0x00003fff
+#define AR_PHY_RX_DELAY_DELAY_S 0
+
+/* Bits for AR_PHY_TIMING_CTRL4_0. */
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_M 0x0000001f
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_M 0x000007e0
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5
+#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x00000800
+#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_M 0x0000f000
+#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12
+#define AR_PHY_TIMING_CTRL4_DO_CAL 0x00010000
+#define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000
+#define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000
+#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000
+#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000
+
+/* Bits for AR_PHY_TIMING5. */
+#define AR_PHY_TIMING5_CYCPWR_THR1_M 0x000000fe
+#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
+
+/* Bits for AR_PHY_POWER_TX_RATE_MAX. */
+#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
+
+/* Bits for AR_PHY_FRAME_CTL. */
+#define AR_PHY_FRAME_CTL_TX_CLIP_M 0x00000038
+#define AR_PHY_FRAME_CTL_TX_CLIP_S 3
+
+/* Bits for AR_PHY_TXPWRADJ. */
+#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_M 0x00000fc0
+#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6
+#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_M 0x00fc0000
+#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
+
+/* Bits for AR_PHY_RADAR_EXT. */
+#define AR_PHY_RADAR_EXT_ENA 0x00004000
+
+/* Bits for AR_PHY_RADAR_0. */
+#define AR_PHY_RADAR_0_ENA 0x00000001
+#define AR_PHY_RADAR_0_INBAND_M 0x0000003e
+#define AR_PHY_RADAR_0_INBAND_S 1
+#define AR_PHY_RADAR_0_PRSSI_M 0x00000fc0
+#define AR_PHY_RADAR_0_PRSSI_S 6
+#define AR_PHY_RADAR_0_HEIGHT_M 0x0003f000
+#define AR_PHY_RADAR_0_HEIGHT_S 12
+#define AR_PHY_RADAR_0_RRSSI_M 0x00fc0000
+#define AR_PHY_RADAR_0_RRSSI_S 18
+#define AR_PHY_RADAR_0_FIRPWR_M 0x7f000000
+#define AR_PHY_RADAR_0_FIRPWR_S 24
+#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
+
+/* Bits for AR_PHY_RADAR_1. */
+#define AR_PHY_RADAR_1_MAXLEN_M 0x000000ff
+#define AR_PHY_RADAR_1_MAXLEN_S 0
+#define AR_PHY_RADAR_1_RELSTEP_THRESH_M 0x00001f00
+#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
+#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
+#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
+#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
+#define AR_PHY_RADAR_1_RELPWR_THRESH_M 0x003f0000
+#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
+#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
+#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
+
+/* Bits for AR_PHY_SIGMA_DELTA. */
+#define AR_PHY_SIGMA_DELTA_ADC_SEL_M 0x00000003
+#define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0
+#define AR_PHY_SIGMA_DELTA_FILT2_M 0x000000f8
+#define AR_PHY_SIGMA_DELTA_FILT2_S 3
+#define AR_PHY_SIGMA_DELTA_FILT1_M 0x00001f00
+#define AR_PHY_SIGMA_DELTA_FILT1_S 8
+#define AR_PHY_SIGMA_DELTA_ADC_CLIP_M 0x01ffe000
+#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
+
+/* Bits for AR_PHY_RESTART. */
+#define AR_PHY_RESTART_DIV_GC_M 0x001c0000
+#define AR_PHY_RESTART_DIV_GC_S 18
+
+/* Bits for AR_PHY_RFBUS_REQ. */
+#define AR_PHY_RFBUS_REQ_EN 0x00000001
+
+/* Bits for AR_PHY_TIMING11. */
+#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_M 0x000fffff
+#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
+#define AR_PHY_TIMING11_SPUR_FREQ_SD_M 0x3ff00000
+#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
+#define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
+#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
+
+/* Bits for AR_PHY_NEW_ADC_DC_GAIN_CORR(). */
+#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
+#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
+
+/* Bits for AR_PHY_EXT_CCA0. */
+#define AR_PHY_EXT_CCA0_THRESH62_M 0x000000ff
+#define AR_PHY_EXT_CCA0_THRESH62_S 0
+
+/* Bits for AR_PHY_EXT_CCA. */
+#define AR_PHY_EXT_MAXCCA_PWR_M 0x000001ff
+#define AR_PHY_EXT_MAXCCA_PWR_S 0
+#define AR_PHY_EXT_CCA_CYCPWR_THR1_M 0x0000fe00
+#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9
+#define AR_PHY_EXT_CCA_THRESH62_M 0x007f0000
+#define AR_PHY_EXT_CCA_THRESH62_S 16
+#define AR_PHY_EXT_MINCCA_PWR_M 0xff800000
+#define AR_PHY_EXT_MINCCA_PWR_S 23
+#define AR9280_PHY_EXT_MINCCA_PWR_M 0x01ff0000
+#define AR9280_PHY_EXT_MINCCA_PWR_S 16
+
+/* Bits for AR_PHY_SFCORR_EXT. */
+#define AR_PHY_SFCORR_EXT_M1_THRESH_M 0x0000007f
+#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
+#define AR_PHY_SFCORR_EXT_M2_THRESH_M 0x00003f80
+#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_M 0x001fc000
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_M 0x0fe00000
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
+#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_M 0xf0000000
+#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
+
+/* Bits for AR_PHY_HALFGI. */
+#define AR_PHY_HALFGI_DSC_EXP_M 0x0000000f
+#define AR_PHY_HALFGI_DSC_EXP_S 0
+#define AR_PHY_HALFGI_DSC_MAN_M 0x0007fff0
+#define AR_PHY_HALFGI_DSC_MAN_S 4
+
+/* Bits for AR_PHY_CHAN_INFO_MEMORY. */
+#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x00000001
+
+/* Bits for AR_PHY_HEAVY_CLIP_FACTOR_RIFS. */
+#define AR_PHY_RIFS_INIT_DELAY_M 0x03ff0000
+#define AR_PHY_RIFS_INIT_DELAY_S 16
+
+/* Bits for AR_PHY_CALMODE. */
+#define AR_PHY_CALMODE_IQ 0x00000000
+#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
+#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
+#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
+
+/* Bits for AR_PHY_RFBUS_GRANT. */
+#define AR_PHY_RFBUS_GRANT_EN 0x00000001
+
+/* Bits for AR_PHY_CHAN_INFO_GAIN_DIFF. */
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
+
+/* Bits for AR_PHY_MODE. */
+#define AR_PHY_MODE_ASYNCFIFO 0x00000080
+#define AR_PHY_MODE_AR2133 0x00000008
+#define AR_PHY_MODE_AR5111 0x00000000
+#define AR_PHY_MODE_AR5112 0x00000008
+#define AR_PHY_MODE_DYNAMIC 0x00000004
+#define AR_PHY_MODE_RF2GHZ 0x00000002
+#define AR_PHY_MODE_RF5GHZ 0x00000000
+#define AR_PHY_MODE_CCK 0x00000001
+#define AR_PHY_MODE_OFDM 0x00000000
+#define AR_PHY_MODE_DYN_CCK_DISABLE 0x00000100
+
+/* Bits for AR_PHY_CCK_TX_CTRL. */
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_M 0x0000000c
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2
+#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
+
+/* Bits for AR_PHY_CCK_DETECT. */
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_M 0x0000003f
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_M 0x00001fc0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x00002000
+
+/* Bits for AR_PHY_GAIN_2GHZ. */
+#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_M 0x0000003f
+#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0
+#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_M 0x0000001f
+#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0
+#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_M 0x00000fc0
+#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6
+#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_M 0x00003c00
+#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10
+#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_M 0x0001f000
+#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12
+#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_M 0x003e0000
+#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17
+#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_M 0x00fc0000
+#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
+
+/* Bit for AR_PHY_CCK_RXCTRL4. */
+#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_M 0x01f80000
+#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
+
+/* Bits for AR_PHY_DAG_CTRLCCK. */
+#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR_M 0x0001fc00
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
+
+/* Bits for AR_PHY_FORCE_CLKEN_CCK. */
+#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040
+
+/* Bits for AR_PHY_TPCRG1. */
+#define AR_PHY_TPCRG1_NUM_PD_GAIN_M 0x0000c000
+#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
+#define AR_PHY_TPCRG1_PD_GAIN_1_M 0x00030000
+#define AR_PHY_TPCRG1_PD_GAIN_1_S 16
+#define AR_PHY_TPCRG1_PD_GAIN_2_M 0x000c0000
+#define AR_PHY_TPCRG1_PD_GAIN_2_S 18
+#define AR_PHY_TPCRG1_PD_GAIN_3_M 0x00300000
+#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
+
+/* Bits for AR_PHY_TX_PWRCTRL4. */
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_M 0x000001fe
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1
+
+/* Bits for AR_PHY_TX_PWRCTRL6_[01]. */
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_M 0x03000000
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24
+
+/* Bits for AR_PHY_TX_PWRCTRL7. */
+#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_M 0x0007e000
+#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S 13
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_M 0x01f80000
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
+
+/* Bits for AR_PHY_TX_PWRCTRL9. */
+#define AR_PHY_TX_DESIRED_SCALE_CCK_M 0x00007c00
+#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 /* XXX should be 9? */
+#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
+
+/* Bits for AR_PHY_TX_GAIN_TBL. */
+#define AR_PHY_TX_GAIN_CLC_M 0x0000001e
+#define AR_PHY_TX_GAIN_CLC_S 1
+#define AR_PHY_TX_GAIN_M 0x0007f000
+#define AR_PHY_TX_GAIN_S 12
+
+/* Bits for AR_PHY_SPUR_REG. */
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_M 0x0000007f
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
+#define AR_SPUR_RSSI_THRESH 40
+#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x00000100
+#define AR_PHY_SPUR_REG_MASK_RATE_SELECT 0x0001fe00
+#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x00020000
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL 0x03fc0000
+
+/* Bits for AR_PHY_ANALOG_SWAP. */
+#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
+
+/* Bits for AR_PHY_TPCRG5. */
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_M 0x0000000f
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_M 0x000003f0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_M 0x0000fc00
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_M 0x003f0000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_M 0x0fc00000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
+
+/* Bits for AR_PHY_CL_CAL_CTL. */
+#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
+#define AR_PHY_CL_CAL_ENABLE 0x00000002
+
+/* Bits for AR_PHY_CLC_TBL. */
+#define AR_PHY_CLC_Q0_M 0x0000ffd0
+#define AR_PHY_CLC_Q0_S 5
+#define AR_PHY_CLC_I0_M 0x07ff0000
+#define AR_PHY_CLC_I0_S 16
+
+/* Bits for AR_PHY_XPA_CFG. */
+#define AR_PHY_FORCE_XPA_CFG 0x000000001
+
+/* Bits for AR_PHY_CH[01]_TX_PWRCTRL11. */
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_M 0x0000fc00
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
+#define AR_PHY_TX_PWRCTRL_OLPC_PWR_M 0x00ff0000
+#define AR_PHY_TX_PWRCTRL_OLPC_PWR_S 16
+
+/* Bits for AR_PHY_NEW_ADC_DC_GAIN_CORR. */
+#define AR_PHY_NEW_ADC_DC_GAIN_QGAIN_M 0x0000003f
+#define AR_PHY_NEW_ADC_DC_GAIN_QGAIN_S 0
+#define AR_PHY_NEW_ADC_DC_GAIN_IGAIN_M 0x00000fc0
+#define AR_PHY_NEW_ADC_DC_GAIN_IGAIN_S 6
+#define AR_PHY_NEW_ADC_DC_GAIN_QDC_M 0x001ff000
+#define AR_PHY_NEW_ADC_DC_GAIN_QDC_S 12
+#define AR_PHY_NEW_ADC_DC_GAIN_IDC_M 0x3fe00000
+#define AR_PHY_NEW_ADC_DC_GAIN_IDC_S 21
+
+/* Bits for AR_PHY(0x37). */
+#define AR5416_BMODE_SYNTH 0x00000002
+#define AR5416_AMODE_REFSEL_M 0x0000000c
+#define AR5416_AMODE_REFSEL_S 2
+
+
+#define AR5008_MAX_SCATTER 16 /* NB: not a hardware limit. */
+
+/*
+ * Tx DMA descriptor.
+ */
+struct ar_tx_desc {
+ uint32_t ds_link;
+ uint32_t ds_data;
+ uint32_t ds_ctl0;
+ uint32_t ds_ctl1;
+ uint32_t ds_ctl2;
+ uint32_t ds_ctl3;
+ uint32_t ds_ctl4;
+ uint32_t ds_ctl5;
+ uint32_t ds_ctl6;
+ uint32_t ds_ctl7;
+ uint32_t ds_ctl8;
+ uint32_t ds_ctl9;
+ uint32_t ds_ctl10;
+ uint32_t ds_ctl11;
+ uint32_t ds_status0;
+ uint32_t ds_status1;
+ uint32_t ds_tstamp;
+ uint32_t ds_ba_bitmap_lo;
+ uint32_t ds_ba_bitmap_hi;
+ uint32_t ds_evm0;
+ uint32_t ds_evm1;
+ uint32_t ds_evm2;
+ uint32_t ds_status8;
+ uint32_t ds_status9;
+ /*
+ * Padding to make Tx descriptors 128 bytes such that they will
+ * not cross a 4KB boundary.
+ */
+ uint32_t pad[8];
+} __packed __attribute__((aligned(4)));
+
+/* Bits for ds_ctl0. */
+#define AR_TXC0_FRAME_LEN_M 0x00000fff
+#define AR_TXC0_FRAME_LEN_S 0
+#define AR_TXC0_VIRT_MORE_FRAG 0x00001000
+#define AR_TXC0_XMIT_POWER_M 0x003f0000
+#define AR_TXC0_XMIT_POWER_S 16
+#define AR_TXC0_RTS_ENABLE 0x00400000
+#define AR_TXC0_VEOL 0x00800000
+#define AR_TXC0_CLR_DEST_MASK 0x01000000
+#define AR_TXC0_INTR_REQ 0x20000000
+#define AR_TXC0_DEST_IDX_VALID 0x40000000
+#define AR_TXC0_CTS_ENABLE 0x80000000
+
+/* Bits for ds_ctl1. */
+#define AR_TXC1_BUF_LEN_M 0x00000fff
+#define AR_TXC1_BUF_LEN_S 0
+#define AR_TXC1_MORE 0x00001000
+#define AR_TXC1_DEST_IDX_M 0x000fe000
+#define AR_TXC1_DEST_IDX_S 13
+#define AR_TXC1_FRAME_TYPE_M 0x00f00000
+#define AR_TXC1_FRAME_TYPE_S 20
+#define AR_FRAME_TYPE_NORMAL 0
+#define AR_FRAME_TYPE_ATIM 1
+#define AR_FRAME_TYPE_PSPOLL 2
+#define AR_FRAME_TYPE_BEACON 3
+#define AR_FRAME_TYPE_PROBE_RESP 4
+#define AR_TXC1_NO_ACK 0x01000000
+#define AR_TXC1_INSERT_TS 0x02000000
+#define AR_TXC1_EXT_ONLY 0x08000000
+#define AR_TXC1_EXT_AND_CTL 0x10000000
+#define AR_TXC1_MORE_AGGR 0x20000000
+#define AR_TXC1_IS_AGGR 0x40000000
+
+/* Bits for ds_ctl2. */
+#define AR_TXC2_BURST_DUR_M 0x00007fff
+#define AR_TXC2_BURST_DUR_S 0
+#define AR_TXC2_DUR_UPDATE_ENA 0x00008000
+#define AR_TXC2_XMIT_DATA_TRIES0_M 0x000f0000
+#define AR_TXC2_XMIT_DATA_TRIES0_S 16
+#define AR_TXC2_XMIT_DATA_TRIES1_M 0x00f00000
+#define AR_TXC2_XMIT_DATA_TRIES1_S 20
+#define AR_TXC2_XMIT_DATA_TRIES2_M 0x0f000000
+#define AR_TXC2_XMIT_DATA_TRIES2_S 24
+#define AR_TXC2_XMIT_DATA_TRIES3_M 0xf0000000
+#define AR_TXC2_XMIT_DATA_TRIES3_S 28
+
+/* Bits for ds_ctl3. */
+#define AR_TXC3_XMIT_RATE0_M 0x000000ff
+#define AR_TXC3_XMIT_RATE0_S 0
+#define AR_TXC3_XMIT_RATE1_M 0x0000ff00
+#define AR_TXC3_XMIT_RATE1_S 8
+#define AR_TXC3_XMIT_RATE2_M 0x00ff0000
+#define AR_TXC3_XMIT_RATE2_S 16
+#define AR_TXC3_XMIT_RATE3_M 0xff000000
+#define AR_TXC3_XMIT_RATE3_S 24
+
+/* Bits for ds_ctl4. */
+#define AR_TXC4_PACKET_DUR0_M 0x00007fff
+#define AR_TXC4_PACKET_DUR0_S 0
+#define AR_TXC4_RTSCTS_QUAL0 0x00008000
+#define AR_TXC4_PACKET_DUR1_M 0x7fff0000
+#define AR_TXC4_PACKET_DUR1_S 16
+#define AR_TXC4_RTSCTS_QUAL1 0x80000000
+/* Shortcut. */
+#define AR_TXC4_RTSCTS_QUAL01 \
+ (AR_TXC4_RTSCTS_QUAL0 | AR_TXC4_RTSCTS_QUAL1)
+
+/* Bits for ds_ctl5. */
+#define AR_TXC5_PACKET_DUR2_M 0x00007fff
+#define AR_TXC5_PACKET_DUR2_S 0
+#define AR_TXC5_RTSCTS_QUAL2 0x00008000
+#define AR_TXC5_PACKET_DUR3_M 0x7fff0000
+#define AR_TXC5_PACKET_DUR3_S 16
+#define AR_TXC5_RTSCTS_QUAL3 0x80000000
+/* Shortcut. */
+#define AR_TXC5_RTSCTS_QUAL23 \
+ (AR_TXC5_RTSCTS_QUAL2 | AR_TXC5_RTSCTS_QUAL3)
+
+/* Bits for ds_ctl6. */
+#define AR_TXC6_AGGR_LEN_M 0x0000ffff
+#define AR_TXC6_AGGR_LEN_S 0
+#define AR_TXC6_PAD_DELIM_M 0x03fc0000
+#define AR_TXC6_PAD_DELIM_S 18
+#define AR_TXC6_ENCR_TYPE_M 0x0c000000
+#define AR_TXC6_ENCR_TYPE_S 26
+#define AR_ENCR_TYPE_CLEAR 0
+#define AR_ENCR_TYPE_WEP 1
+#define AR_ENCR_TYPE_AES 2
+#define AR_ENCR_TYPE_TKIP 3
+
+/* Bits for ds_ctl7. */
+#define AR_TXC7_2040_0 0x00000001
+#define AR_TXC7_GI0 0x00000002
+#define AR_TXC7_CHAIN_SEL0_M 0x0000001c
+#define AR_TXC7_CHAIN_SEL0_S 2
+#define AR_TXC7_2040_1 0x00000020
+#define AR_TXC7_GI1 0x00000040
+#define AR_TXC7_CHAIN_SEL1_M 0x00000380
+#define AR_TXC7_CHAIN_SEL1_S 7
+#define AR_TXC7_2040_2 0x00000400
+#define AR_TXC7_GI2 0x00000800
+#define AR_TXC7_CHAIN_SEL2_M 0x00007000
+#define AR_TXC7_CHAIN_SEL2_S 12
+#define AR_TXC7_2040_3 0x00008000
+#define AR_TXC7_GI3 0x00010000
+#define AR_TXC7_CHAIN_SEL3_M 0x000e0000
+#define AR_TXC7_CHAIN_SEL3_S 17
+#define AR_TXC7_RTSCTS_RATE_M 0x0ff00000
+#define AR_TXC7_RTSCTS_RATE_S 20
+/* Shortcuts. */
+#define AR_TXC7_2040_0123 \
+ (AR_TXC7_2040_0 | AR_TXC7_2040_1 | AR_TXC7_2040_2 | AR_TXC7_2040_3)
+#define AR_TXC7_GI0123 \
+ (AR_TXC7_GI0 | AR_TXC7_GI1 | AR_TXC7_GI2 | AR_TXC7_GI3)
+
+/* Bits for ds_ctl9. */
+#define AR_TXC9_XMIT_POWER1_M 0x3f000000
+#define AR_TXC9_XMIT_POWER1_S 24
+
+/* Bits for ds_ctl10. */
+#define AR_TXC10_XMIT_POWER2_M 0x3f000000
+#define AR_TXC10_XMIT_POWER2_S 24
+
+/* Bits for ds_ctl11. */
+#define AR_TXC11_XMIT_POWER3_M 0x3f000000
+#define AR_TXC11_XMIT_POWER3_S 24
+
+/* Bits for ds_status0. */
+#define AR_TXS0_RSSI_ANT0(i) (((x) >> ((i) * 8)) & 0xff)
+#define AR_TXS0_BA_STATUS 0x40000000
+
+/* Bits for ds_status1. */
+#define AR_TXS1_FRM_XMIT_OK 0x00000001
+#define AR_TXS1_EXCESSIVE_RETRIES 0x00000002
+#define AR_TXS1_FIFO_UNDERRUN 0x00000004
+#define AR_TXS1_FILTERED 0x00000008
+#define AR_TXS1_RTS_FAIL_CNT_M 0x000000f0
+#define AR_TXS1_RTS_FAIL_CNT_S 4
+#define AR_TXS1_DATA_FAIL_CNT_M 0x00000f00
+#define AR_TXS1_DATA_FAIL_CNT_S 8
+#define AR_TXS1_VIRT_RETRY_CNT_M 0x0000f000
+#define AR_TXS1_VIRT_RETRY_CNT_S 12
+#define AR_TXS1_TX_DELIM_UNDERRUN 0x00010000
+#define AR_TXS1_TX_DATA_UNDERRUN 0x00020000
+#define AR_TXS1_DESC_CFG_ERR 0x00040000
+#define AR_TXS1_TX_TIMER_EXPIRED 0x00080000
+/* Shortcut. */
+#define AR_TXS1_UNDERRUN \
+ (AR_TXS1_FIFO_UNDERRUN | \
+ AR_TXS1_TX_DELIM_UNDERRUN | \
+ AR_TXS1_TX_DATA_UNDERRUN)
+
+/* Bits for ds_status9. */
+#define AR_TXS9_DONE 0x00000001
+#define AR_TXS9_SEQNUM_M 0x00001ffe
+#define AR_TXS9_SEQNUM_S 1
+#define AR_TXS9_TXOP_EXCEEDED 0x00020000
+#define AR_TXS9_FINAL_IDX_M 0x00600000
+#define AR_TXS9_FINAL_IDX_S 21
+#define AR_TXS9_POWER_MGMT 0x02000000
+
+/*
+ * Rx DMA descriptor.
+ */
+struct ar_rx_desc {
+ uint32_t ds_link;
+ uint32_t ds_data;
+ uint32_t ds_ctl0;
+ uint32_t ds_ctl1;
+ uint32_t ds_status0;
+ uint32_t ds_status1;
+ uint32_t ds_status2;
+ uint32_t ds_status3;
+ uint32_t ds_status4;
+ uint32_t ds_status5;
+ uint32_t ds_status6;
+ uint32_t ds_status7;
+ uint32_t ds_status8;
+ /*
+ * Padding to make Rx descriptors 64 bytes such that they will
+ * not cross a 4KB boundary.
+ */
+ uint32_t pad[3];
+} __packed __attribute__((aligned(4)));
+
+/* Bits for ds_ctl1. */
+#define AR_RXC1_BUF_LEN_M 0x00000fff
+#define AR_RXC1_BUF_LEN_S 0
+#define AR_RXC1_INTR_REQ 0x00002000
+
+/* Bits for ds_status0. */
+#define AR_RXS0_RSSI_ANT00(x) (((x) >> 0) & 0xff)
+#define AR_RXS0_RSSI_ANT01(x) (((x) >> 8) & 0xff)
+#define AR_RXS0_RSSI_ANT02(x) (((x) >> 16) & 0xff)
+#define AR_RXS0_RATE_M 0xff000000
+#define AR_RXS0_RATE_S 24
+
+/* Bits for ds_status1. */
+#define AR_RXS1_DATA_LEN_M 0x00000fff
+#define AR_RXS1_DATA_LEN_S 0
+#define AR_RXS1_MORE 0x00001000
+
+/* Bits for ds_status3. */
+#define AR_RXS3_GI 0x00000001
+#define AR_RXS3_2040 0x00000002
+#define AR_RXS3_PARALLEL_40 0x00000004
+#define AR_RXS3_ANTENNA_M 0xffffff00
+#define AR_RXS3_ANTENNA_S 8
+#define AR_RXS3_RATE_M 0x000003fc
+#define AR_RXS3_RATE_S 2
+
+/* Bits for ds_status4. */
+#define AR_RXS0_RSSI_ANT10(x) (((x) >> 0) & 0xff)
+#define AR_RXS0_RSSI_ANT11(x) (((x) >> 8) & 0xff)
+#define AR_RXS0_RSSI_ANT12(x) (((x) >> 16) & 0xff)
+#define AR_RXS4_RSSI_COMBINED_M 0xff000000
+#define AR_RXS4_RSSI_COMBINED_S 24
+
+/* Bits for ds_status8. */
+#define AR_RXS8_DONE 0x00000001
+#define AR_RXS8_FRAME_OK 0x00000002
+#define AR_RXS8_CRC_ERR 0x00000004
+#define AR_RXS8_DECRYPT_CRC_ERR 0x00000008
+#define AR_RXS8_PHY_ERR 0x00000010
+#define AR_RXS8_MICHAEL_ERR 0x00000020
+#define AR_RXS8_PRE_DELIM_CRC_ERR 0x00000040
+#define AR_RXS8_PHY_ERR_CODE_M 0x0000ff00
+#define AR_RXS8_PHY_ERR_CODE_S 8
+#define AR_RXS8_KEY_IDX_VALID 0x00000100
+#define AR_RXS8_KEY_IDX_M 0x0000fe00
+#define AR_RXS8_KEY_IDX_S 9
+#define AR_RXS8_POST_DELIM_CRC_ERR 0x00040000
+#define AR_RXS8_DECRYPT_BUSY_ERR 0x40000000
+#define AR_RXS8_KEY_MISS 0x80000000
+
+#define AR_MAX_PWR_RANGE_IN_HALF_DB 64
+#define AR9285_PD_GAIN_BOUNDARY_DEFAULT 58
+
+/*
+ * AR5008 family common ROM header.
+ */
+#define AR_EEPROM_MAGIC_OFFSET 0x0000
+#if BYTE_ORDER == BIG_ENDIAN
+#define AR_EEPROM_MAGIC 0x5aa5
+#else
+#define AR_EEPROM_MAGIC 0xa55a
+#endif
+
+#define AR_NO_SPUR 0x8000
+#define AR_NUM_PDADC_VALUES 128
+
+struct ar_base_eep_header {
+ uint16_t length;
+ uint16_t checksum;
+ uint16_t version;
+#define AR_EEP_VER 0xe
+#define AR_EEP_VER_MINOR_MASK 0x0fff
+#define AR_EEP_MINOR_VER_2 2
+#define AR_EEP_MINOR_VER_3 3
+#define AR_EEP_MINOR_VER_7 7
+#define AR_EEP_MINOR_VER_9 9
+#define AR_EEP_MINOR_VER_10 10
+#define AR_EEP_MINOR_VER_16 16
+#define AR_EEP_MINOR_VER_17 17
+#define AR_EEP_MINOR_VER_19 19
+#define AR_EEP_MINOR_VER_20 20
+#define AR_EEP_MINOR_VER_21 21
+#define AR_EEP_MINOR_VER_22 22
+
+ uint8_t opCapFlags;
+#define AR_OPFLAGS_11A 0x01
+#define AR_OPFLAGS_11G 0x02
+/* NB: If set, 11n is _disabled_ in the corresponding mode: */
+#define AR_OPFLAGS_11N_5G40 0x04
+#define AR_OPFLAGS_11N_2G40 0x08
+#define AR_OPFLAGS_11N_5G20 0x10
+#define AR_OPFLAGS_11N_2G20 0x20
+
+ uint8_t eepMisc;
+ uint16_t regDmn[2];
+ uint8_t macAddr[6];
+ uint8_t rxMask;
+ uint8_t txMask;
+ uint16_t rfSilent;
+#define AR_EEP_RFSILENT_ENABLED 0x0001
+#define AR_EEP_RFSILENT_GPIO_SEL_M 0x001c
+#define AR_EEP_RFSILENT_GPIO_SEL_S 2
+#define AR_EEP_RFSILENT_POLARITY 0x0002
+
+ uint16_t blueToothOptions;
+ uint16_t deviceCap;
+#define AR_EEP_DEVCAP_COMPRESS_DIS 0x0001
+#define AR_EEP_DEVCAP_AES_DIS 0x0002
+#define AR_EEP_DEVCAP_FASTFRAME_DIS 0x0004
+#define AR_EEP_DEVCAP_BURST_DIS 0x0008
+#define AR_EEP_DEVCAP_MAXQCU_M 0x01f0
+#define AR_EEP_DEVCAP_MAXQCU_S 4
+#define AR_EEP_DEVCAP_HEAVY_CLIP_EN 0x0200
+#define AR_EEP_DEVCAP_KC_ENTRIES_M 0xf000
+#define AR_EEP_DEVCAP_KC_ENTRIES_S 12
+
+ uint32_t binBuildNumber;
+ uint8_t deviceType;
+} __packed;
+
+#define AR_EEP_TXGAIN_ORIGINAL 0
+#define AR_EEP_TXGAIN_HIGH_POWER 1
+
+#define AR_EEPROM_MODAL_SPURS 5
+
+struct ar_spur_chan {
+ uint16_t spurChan;
+ uint8_t spurRangeLow;
+ uint8_t spurRangeHigh;
+} __packed;
+
+struct ar_cal_data_per_freq_olpc {
+ uint8_t pwrPdg[2][5];
+ uint8_t vpdPdg[2][5];
+ uint8_t pcdac[2][5];
+ uint8_t empty[2][5];
+} __packed;
+
+struct ar_cal_target_power_leg {
+ uint8_t bChannel;
+ uint8_t tPow2x[4];
+} __packed;
+
+struct ar_cal_target_power_ht {
+ uint8_t bChannel;
+ uint8_t tPow2x[8];
+} __packed;
+
+struct ar_cal_ctl_edges {
+ uint8_t bChannel;
+ uint8_t tPowerFlag;
+#define AR_CAL_CTL_EDGES_POWER_M 0x3f
+#define AR_CAL_CTL_EDGES_POWER_S 0
+#define AR_CAL_CTL_EDGES_FLAG_M 0xc0
+#define AR_CAL_CTL_EDGES_FLAG_S 6
+} __packed;
+
diff --git a/sys/dev/athn/ic/ar5416.c b/sys/dev/athn/ic/ar5416.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar5416.c
@@ -0,0 +1,963 @@
+/* $OpenBSD: ar5416.c,v 1.23 2022/01/09 05:42:38 jsg Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Driver for Atheros 802.11a/g/n chipsets.
+ * Routines for AR5416, AR5418 and AR9160 chipsets.
+ */
+
+//#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+//#include <sys/timeout.h>
+#include <sys/conf.h>
+//#include <sys/device.h>
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+//#include <machine/intr.h>
+
+//#if NBPFILTER > 0
+//#include <net/bpf.h>
+//#endif
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+//#include <net80211/ieee80211_ra.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/athn/athnreg.h>
+#include <dev/athn/athnvar.h>
+
+#include <dev/athn/ic/ar5008reg.h>
+#include <dev/athn/ic/ar5416reg.h>
+
+int ar5416_attach(struct athn_softc *);
+void ar5416_setup(struct athn_softc *);
+void ar5416_swap_rom(struct athn_softc *);
+const struct ar_spur_chan *
+ ar5416_get_spur_chans(struct athn_softc *, int);
+int ar5416_set_synth(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+uint8_t ar5416_reverse_bits(uint8_t, int);
+uint8_t ar5416_get_rf_rev(struct athn_softc *);
+void ar5416_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+int ar5416_init_calib(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar5416_set_power_calib(struct athn_softc *,
+ struct ieee80211_channel *);
+void ar5416_set_txpower(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar5416_spur_mitigate(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar5416_rw_rfbits(uint32_t *, int, int, uint32_t, int);
+void ar5416_rw_bank6tpc(struct athn_softc *, struct ieee80211_channel *,
+ uint32_t *);
+void ar5416_rf_reset(struct athn_softc *, struct ieee80211_channel *);
+void ar5416_reset_bb_gain(struct athn_softc *, struct ieee80211_channel *);
+void ar5416_force_bias(struct athn_softc *, struct ieee80211_channel *);
+void ar9160_rw_addac(struct athn_softc *, struct ieee80211_channel *,
+ uint32_t *);
+void ar5416_reset_addac(struct athn_softc *, struct ieee80211_channel *);
+void ar5416_get_pdadcs(struct athn_softc *, struct ieee80211_channel *,
+ int, int, uint8_t, uint8_t *, uint8_t *);
+
+/* Extern functions. */
+uint8_t athn_chan2fbin(struct ieee80211_channel *);
+void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *);
+int ar5008_attach(struct athn_softc *);
+void ar5008_write_txpower(struct athn_softc *, int16_t power[]);
+void ar5008_get_pdadcs(struct athn_softc *, uint8_t, struct athn_pier *,
+ struct athn_pier *, int, int, uint8_t, uint8_t *, uint8_t *);
+void ar5008_set_viterbi_mask(struct athn_softc *, int);
+void ar5008_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *,
+ uint8_t, const struct ar_cal_target_power_leg *, int, uint8_t[]);
+void ar5008_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *,
+ uint8_t, const struct ar_cal_target_power_ht *, int, uint8_t[]);
+void ar9280_olpc_get_pdadcs(struct athn_softc *, struct ieee80211_channel *,
+ int, uint8_t *, uint8_t *, uint8_t *);
+
+
+int
+ar5416_attach(struct athn_softc *sc)
+{
+ sc->eep_base = AR5416_EEP_START_LOC;
+ sc->eep_size = sizeof(struct ar5416_eeprom);
+ sc->ngpiopins = 14;
+ sc->led_pin = 1;
+ sc->workaround = AR5416_WA_DEFAULT;
+ sc->ops.setup = ar5416_setup;
+ sc->ops.swap_rom = ar5416_swap_rom;
+ sc->ops.init_from_rom = ar5416_init_from_rom;
+ sc->ops.set_txpower = ar5416_set_txpower;
+ sc->ops.set_synth = ar5416_set_synth;
+ sc->ops.spur_mitigate = ar5416_spur_mitigate;
+ sc->ops.get_spur_chans = ar5416_get_spur_chans;
+ sc->cca_min_2g = AR5416_PHY_CCA_MIN_GOOD_VAL_2GHZ;
+ sc->cca_max_2g = AR5416_PHY_CCA_MAX_GOOD_VAL_2GHZ;
+ sc->cca_min_5g = AR5416_PHY_CCA_MIN_GOOD_VAL_5GHZ;
+ sc->cca_max_5g = AR5416_PHY_CCA_MAX_GOOD_VAL_5GHZ;
+ if (AR_SREV_9160_10_OR_LATER(sc))
+ sc->ini = &ar9160_ini;
+ else
+ sc->ini = &ar5416_ini;
+ sc->serdes = &ar5416_serdes;
+
+ return (ar5008_attach(sc));
+}
+
+void
+ar5416_setup(struct athn_softc *sc)
+{
+ /* Select ADDAC programming. */
+ if (AR_SREV_9160_11(sc))
+ sc->addac = &ar9160_1_1_addac;
+ else if (AR_SREV_9160_10_OR_LATER(sc))
+ sc->addac = &ar9160_1_0_addac;
+ else if (AR_SREV_5416_22_OR_LATER(sc))
+ sc->addac = &ar5416_2_2_addac;
+ else
+ sc->addac = &ar5416_2_1_addac;
+}
+
+void
+ar5416_swap_rom(struct athn_softc *sc)
+{
+ printf("%s unimplemented\n", __func__);
+#if 0
+ struct ar5416_eeprom *eep = sc->eep;
+ struct ar5416_modal_eep_header *modal;
+ int i, j;
+
+ for (i = 0; i < 2; i++) { /* Dual-band. */
+ modal = &eep->modalHeader[i];
+
+ modal->antCtrlCommon = swap32(modal->antCtrlCommon);
+ for (j = 0; j < AR5416_MAX_CHAINS; j++) {
+ modal->antCtrlChain[j] =
+ swap32(modal->antCtrlChain[j]);
+ }
+ for (j = 0; j < AR_EEPROM_MODAL_SPURS; j++) {
+ modal->spurChans[j].spurChan =
+ swap16(modal->spurChans[j].spurChan);
+ }
+ }
+#endif
+}
+
+const struct ar_spur_chan *
+ar5416_get_spur_chans(struct athn_softc *sc, int is2ghz)
+{
+ const struct ar5416_eeprom *eep = sc->eep;
+
+ return (eep->modalHeader[is2ghz].spurChans);
+}
+
+int
+ar5416_set_synth(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ uint32_t phy, reg;
+ uint32_t freq = c->ic_freq;
+ uint8_t chansel;
+
+ phy = 0;
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ if (((freq - 2192) % 5) == 0) {
+ chansel = ((freq - 672) * 2 - 3040) / 10;
+ } else if (((freq - 2224) % 5) == 0) {
+ chansel = ((freq - 704) * 2 - 3040) / 10;
+ phy |= AR5416_BMODE_SYNTH;
+ } else
+ return (EINVAL);
+ chansel <<= 2;
+
+ reg = AR_READ(sc, AR_PHY_CCK_TX_CTRL);
+ if (freq == 2484) /* Channel 14. */
+ reg |= AR_PHY_CCK_TX_CTRL_JAPAN;
+ else
+ reg &= ~AR_PHY_CCK_TX_CTRL_JAPAN;
+ AR_WRITE(sc, AR_PHY_CCK_TX_CTRL, reg);
+
+ /* Fix for orientation sensitivity issue. */
+ if (AR_SREV_5416(sc))
+ ar5416_force_bias(sc, c);
+ } else {
+ if (freq >= 5120 && (freq % 20) == 0) {
+ chansel = (freq - 4800) / 20;
+ chansel <<= 2;
+ phy |= SM(AR5416_AMODE_REFSEL, 2);
+ } else if ((freq % 10) == 0) {
+ chansel = (freq - 4800) / 10;
+ chansel <<= 1;
+ if (AR_SREV_9160_10_OR_LATER(sc))
+ phy |= SM(AR5416_AMODE_REFSEL, 1);
+ else
+ phy |= SM(AR5416_AMODE_REFSEL, 2);
+ } else if ((freq % 5) == 0) {
+ chansel = (freq - 4800) / 5;
+ phy |= SM(AR5416_AMODE_REFSEL, 2);
+ } else
+ return (EINVAL);
+ }
+ chansel = ar5416_reverse_bits(chansel, 8);
+ phy |= chansel << 8 | 1 << 5 | 1;
+ DPRINTFN(4, ("AR_PHY(0x37)=0x%08x\n", phy));
+ AR_WRITE(sc, AR_PHY(0x37), phy);
+ return (0);
+}
+
+void
+ar5416_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ static const uint32_t chainoffset[] = { 0x0000, 0x2000, 0x1000 };
+ const struct ar5416_eeprom *eep = sc->eep;
+ const struct ar5416_modal_eep_header *modal;
+ uint32_t reg, offset;
+ uint8_t txRxAtten;
+ int i;
+
+ modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)];
+
+ AR_WRITE(sc, AR_PHY_SWITCH_COM, modal->antCtrlCommon);
+
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+ if (AR_SREV_5416_20_OR_LATER(sc) &&
+ (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5))
+ offset = chainoffset[i];
+ else
+ offset = i * 0x1000;
+
+ AR_WRITE(sc, AR_PHY_SWITCH_CHAIN_0 + offset,
+ modal->antCtrlChain[i]);
+
+ reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0 + offset);
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
+ modal->iqCalICh[i]);
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
+ modal->iqCalQCh[i]);
+ AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0 + offset, reg);
+
+ if (i > 0 && !AR_SREV_5416_20_OR_LATER(sc))
+ continue;
+
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_3) {
+ reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_BSW_MARGIN,
+ modal->bswMargin[i]);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_BSW_ATTEN,
+ modal->bswAtten[i]);
+ AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg);
+ }
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_3)
+ txRxAtten = modal->txRxAttenCh[i];
+ else /* Workaround for ROM versions < 14.3. */
+ txRxAtten = IEEE80211_IS_CHAN_2GHZ(c) ? 23 : 44;
+ reg = AR_READ(sc, AR_PHY_RXGAIN + offset);
+ reg = RW(reg, AR_PHY_RXGAIN_TXRX_ATTEN, txRxAtten);
+ AR_WRITE(sc, AR_PHY_RXGAIN + offset, reg);
+
+ reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_RXTX_MARGIN,
+ modal->rxTxMarginCh[i]);
+ AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg);
+ }
+ reg = AR_READ(sc, AR_PHY_SETTLING);
+ reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling);
+ AR_WRITE(sc, AR_PHY_SETTLING, reg);
+
+ reg = AR_READ(sc, AR_PHY_DESIRED_SZ);
+ reg = RW(reg, AR_PHY_DESIRED_SZ_ADC, modal->adcDesiredSize);
+ reg = RW(reg, AR_PHY_DESIRED_SZ_PGA, modal->pgaDesiredSize);
+ AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg);
+
+ reg = SM(AR_PHY_RF_CTL4_TX_END_XPAA_OFF, modal->txEndToXpaOff);
+ reg |= SM(AR_PHY_RF_CTL4_TX_END_XPAB_OFF, modal->txEndToXpaOff);
+ reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAA_ON, modal->txFrameToXpaOn);
+ reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAB_ON, modal->txFrameToXpaOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL4, reg);
+
+ reg = AR_READ(sc, AR_PHY_RF_CTL3);
+ reg = RW(reg, AR_PHY_TX_END_TO_A2_RX_ON, modal->txEndToRxOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL3, reg);
+
+ reg = AR_READ(sc, AR_PHY_CCA(0));
+ reg = RW(reg, AR_PHY_CCA_THRESH62, modal->thresh62);
+ AR_WRITE(sc, AR_PHY_CCA(0), reg);
+
+ reg = AR_READ(sc, AR_PHY_EXT_CCA(0));
+ reg = RW(reg, AR_PHY_EXT_CCA_THRESH62, modal->thresh62);
+ AR_WRITE(sc, AR_PHY_EXT_CCA(0), reg);
+
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_2) {
+ reg = AR_READ(sc, AR_PHY_RF_CTL2);
+ reg = RW(reg, AR_PHY_TX_END_DATA_START,
+ modal->txFrameToDataStart);
+ reg = RW(reg, AR_PHY_TX_END_PA_ON, modal->txFrameToPaOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL2, reg);
+ }
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_3 && extc != NULL) {
+ /* Overwrite switch settling with HT-40 value. */
+ reg = AR_READ(sc, AR_PHY_SETTLING);
+ reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->swSettleHt40);
+ AR_WRITE(sc, AR_PHY_SETTLING, reg);
+ }
+}
+
+int
+ar5416_init_calib(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ int ntries;
+
+ if (AR_SREV_9280_10_OR_LATER(sc)) {
+ /* XXX Linux tests AR9287?! */
+ AR_CLRBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_FLTR_CAL);
+ }
+ /* Calibrate the AGC. */
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+ /* Poll for offset calibration completion. */
+ for (ntries = 0; ntries < 10000; ntries++) {
+ if (!(AR_READ(sc, AR_PHY_AGC_CONTROL) &
+ AR_PHY_AGC_CONTROL_CAL))
+ break;
+ DELAY(10);
+ }
+ if (ntries == 10000)
+ return (ETIMEDOUT);
+ if (AR_SREV_9280_10_OR_LATER(sc)) {
+ AR_SETBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ AR_CLRBITS(sc, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_FLTR_CAL);
+ }
+ return (0);
+}
+
+void
+ar5416_get_pdadcs(struct athn_softc *sc, struct ieee80211_channel *c,
+ int chain, int nxpdgains, uint8_t overlap, uint8_t *boundaries,
+ uint8_t *pdadcs)
+{
+ const struct ar5416_eeprom *eep = sc->eep;
+ const struct ar5416_cal_data_per_freq *pierdata;
+ const uint8_t *pierfreq;
+ struct athn_pier lopier, hipier;
+ int16_t delta;
+ uint8_t fbin, pwroff;
+ int i, lo, hi, npiers;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ pierfreq = eep->calFreqPier2G;
+ pierdata = eep->calPierData2G[chain];
+ npiers = AR5416_NUM_2G_CAL_PIERS;
+ } else {
+ pierfreq = eep->calFreqPier5G;
+ pierdata = eep->calPierData5G[chain];
+ npiers = AR5416_NUM_5G_CAL_PIERS;
+ }
+ /* Find channel in ROM pier table. */
+ fbin = athn_chan2fbin(c);
+ athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi);
+
+ lopier.fbin = pierfreq[lo];
+ hipier.fbin = pierfreq[hi];
+ for (i = 0; i < nxpdgains; i++) {
+ lopier.pwr[i] = pierdata[lo].pwrPdg[i];
+ lopier.vpd[i] = pierdata[lo].vpdPdg[i];
+ hipier.pwr[i] = pierdata[lo].pwrPdg[i];
+ hipier.vpd[i] = pierdata[lo].vpdPdg[i];
+ }
+ ar5008_get_pdadcs(sc, fbin, &lopier, &hipier, nxpdgains,
+ AR5416_PD_GAIN_ICEPTS, overlap, boundaries, pdadcs);
+
+ if (!AR_SREV_9280_20_OR_LATER(sc))
+ return;
+
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_21)
+ pwroff = eep->baseEepHeader.pwrTableOffset;
+ else
+ pwroff = AR_PWR_TABLE_OFFSET_DB;
+ delta = (pwroff - AR_PWR_TABLE_OFFSET_DB) * 2; /* In half dB. */
+
+ /* Change the original gain boundaries setting. */
+ for (i = 0; i < nxpdgains; i++) {
+ /* XXX Possible overflows? */
+ boundaries[i] -= delta;
+ if (boundaries[i] > AR_MAX_RATE_POWER - overlap)
+ boundaries[i] = AR_MAX_RATE_POWER - overlap;
+ }
+ if (delta != 0) {
+ /* Shift the PDADC table to start at the new offset. */
+ for (i = 0; i < AR_NUM_PDADC_VALUES; i++)
+ pdadcs[i] = pdadcs[MIN(i + delta,
+ AR_NUM_PDADC_VALUES - 1)];
+ }
+}
+
+void
+ar5416_set_power_calib(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ static const uint32_t chainoffset[] = { 0x0000, 0x2000, 0x1000 };
+ const struct ar5416_eeprom *eep = sc->eep;
+ const struct ar5416_modal_eep_header *modal;
+ uint8_t boundaries[AR_PD_GAINS_IN_MASK];
+ uint8_t pdadcs[AR_NUM_PDADC_VALUES];
+ uint8_t xpdgains[AR5416_NUM_PD_GAINS];
+ uint8_t overlap, txgain;
+ uint32_t reg, offset;
+ int i, j, nxpdgains;
+
+ modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)];
+
+ if (sc->eep_rev < AR_EEP_MINOR_VER_2) {
+ overlap = MS(AR_READ(sc, AR_PHY_TPCRG5),
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP);
+ } else
+ overlap = modal->pdGainOverlap;
+
+ if ((sc->flags & ATHN_FLAG_OLPC) && IEEE80211_IS_CHAN_2GHZ(c)) {
+ /* XXX not here. */
+ sc->pdadc =
+ ((const struct ar_cal_data_per_freq_olpc *)
+ eep->calPierData2G[0])->vpdPdg[0][0];
+ }
+
+ nxpdgains = 0;
+ memset(xpdgains, 0, sizeof(xpdgains));
+ for (i = AR5416_PD_GAINS_IN_MASK - 1; i >= 0; i--) {
+ if (nxpdgains >= AR5416_NUM_PD_GAINS)
+ break; /* Can't happen. */
+ if (modal->xpdGain & (1 << i))
+ xpdgains[nxpdgains++] = i;
+ }
+ reg = AR_READ(sc, AR_PHY_TPCRG1);
+ reg = RW(reg, AR_PHY_TPCRG1_NUM_PD_GAIN, nxpdgains - 1);
+ reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_1, xpdgains[0]);
+ reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_2, xpdgains[1]);
+ reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_3, xpdgains[2]);
+ AR_WRITE(sc, AR_PHY_TPCRG1, reg);
+
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+ if (!(sc->txchainmask & (1 << i)))
+ continue;
+
+ if (AR_SREV_5416_20_OR_LATER(sc) &&
+ (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5))
+ offset = chainoffset[i];
+ else
+ offset = i * 0x1000;
+
+ if (sc->flags & ATHN_FLAG_OLPC) {
+ ar9280_olpc_get_pdadcs(sc, c, i, boundaries,
+ pdadcs, &txgain);
+
+ reg = AR_READ(sc, AR_PHY_TX_PWRCTRL6_0);
+ reg = RW(reg, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+ AR_WRITE(sc, AR_PHY_TX_PWRCTRL6_0, reg);
+
+ reg = AR_READ(sc, AR_PHY_TX_PWRCTRL6_1);
+ reg = RW(reg, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+ AR_WRITE(sc, AR_PHY_TX_PWRCTRL6_1, reg);
+
+ reg = AR_READ(sc, AR_PHY_TX_PWRCTRL7);
+ reg = RW(reg, AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, txgain);
+ AR_WRITE(sc, AR_PHY_TX_PWRCTRL7, reg);
+
+ overlap = 6;
+ } else {
+ ar5416_get_pdadcs(sc, c, i, nxpdgains, overlap,
+ boundaries, pdadcs);
+ }
+ /* Write boundaries. */
+ if (i == 0 || AR_SREV_5416_20_OR_LATER(sc)) {
+ reg = SM(AR_PHY_TPCRG5_PD_GAIN_OVERLAP,
+ overlap);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1,
+ boundaries[0]);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2,
+ boundaries[1]);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3,
+ boundaries[2]);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4,
+ boundaries[3]);
+ AR_WRITE(sc, AR_PHY_TPCRG5 + offset, reg);
+ }
+ /* Write PDADC values. */
+ for (j = 0; j < AR_NUM_PDADC_VALUES; j += 4) {
+ AR_WRITE(sc, AR_PHY_PDADC_TBL_BASE + offset + j,
+ pdadcs[j + 0] << 0 |
+ pdadcs[j + 1] << 8 |
+ pdadcs[j + 2] << 16 |
+ pdadcs[j + 3] << 24);
+ }
+ }
+}
+
+void
+ar5416_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ const struct ar5416_eeprom *eep = sc->eep;
+ const struct ar5416_modal_eep_header *modal;
+ uint8_t tpow_cck[4], tpow_ofdm[4];
+ uint8_t tpow_cck_ext[4], tpow_ofdm_ext[4];
+ uint8_t tpow_ht20[8], tpow_ht40[8];
+ uint8_t ht40inc;
+ int16_t pwr = 0, pwroff, max_ant_gain, power[ATHN_POWER_COUNT];
+ uint8_t cckinc;
+ int i;
+
+ ar5416_set_power_calib(sc, c);
+
+ modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)];
+
+ /* Compute transmit power reduction due to antenna gain. */
+ max_ant_gain = MAX(modal->antennaGainCh[0], modal->antennaGainCh[1]);
+ max_ant_gain = MAX(modal->antennaGainCh[2], max_ant_gain);
+ /* XXX */
+
+ /*
+ * Reduce scaled power by number of active chains to get per-chain
+ * transmit power level.
+ */
+ if (sc->ntxchains == 2)
+ pwr -= AR_PWR_DECREASE_FOR_2_CHAIN;
+ else if (sc->ntxchains == 3)
+ pwr -= AR_PWR_DECREASE_FOR_3_CHAIN;
+ if (pwr < 0)
+ pwr = 0;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ /* Get CCK target powers. */
+ ar5008_get_lg_tpow(sc, c, AR_CTL_11B, eep->calTargetPowerCck,
+ AR5416_NUM_2G_CCK_TARGET_POWERS, tpow_cck);
+
+ /* Get OFDM target powers. */
+ ar5008_get_lg_tpow(sc, c, AR_CTL_11G, eep->calTargetPower2G,
+ AR5416_NUM_2G_20_TARGET_POWERS, tpow_ofdm);
+
+ /* Get HT-20 target powers. */
+ ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT20,
+ eep->calTargetPower2GHT20, AR5416_NUM_2G_20_TARGET_POWERS,
+ tpow_ht20);
+
+ if (extc != NULL) {
+ /* Get HT-40 target powers. */
+ ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT40,
+ eep->calTargetPower2GHT40,
+ AR5416_NUM_2G_40_TARGET_POWERS, tpow_ht40);
+
+ /* Get secondary channel CCK target powers. */
+ ar5008_get_lg_tpow(sc, extc, AR_CTL_11B,
+ eep->calTargetPowerCck,
+ AR5416_NUM_2G_CCK_TARGET_POWERS, tpow_cck_ext);
+
+ /* Get secondary channel OFDM target powers. */
+ ar5008_get_lg_tpow(sc, extc, AR_CTL_11G,
+ eep->calTargetPower2G,
+ AR5416_NUM_2G_20_TARGET_POWERS, tpow_ofdm_ext);
+ }
+ } else {
+ /* Get OFDM target powers. */
+ ar5008_get_lg_tpow(sc, c, AR_CTL_11A, eep->calTargetPower5G,
+ AR5416_NUM_5G_20_TARGET_POWERS, tpow_ofdm);
+
+ /* Get HT-20 target powers. */
+ ar5008_get_ht_tpow(sc, c, AR_CTL_5GHT20,
+ eep->calTargetPower5GHT20, AR5416_NUM_5G_20_TARGET_POWERS,
+ tpow_ht20);
+
+ if (extc != NULL) {
+ /* Get HT-40 target powers. */
+ ar5008_get_ht_tpow(sc, c, AR_CTL_5GHT40,
+ eep->calTargetPower5GHT40,
+ AR5416_NUM_5G_40_TARGET_POWERS, tpow_ht40);
+
+ /* Get secondary channel OFDM target powers. */
+ ar5008_get_lg_tpow(sc, extc, AR_CTL_11A,
+ eep->calTargetPower5G,
+ AR5416_NUM_5G_20_TARGET_POWERS, tpow_ofdm_ext);
+ }
+ }
+
+ /* Compute CCK/OFDM delta. */
+ cckinc = (sc->flags & ATHN_FLAG_OLPC) ? -2 : 0;
+
+ memset(power, 0, sizeof(power));
+ /* Shuffle target powers across transmit rates. */
+ power[ATHN_POWER_OFDM6 ] =
+ power[ATHN_POWER_OFDM9 ] =
+ power[ATHN_POWER_OFDM12] =
+ power[ATHN_POWER_OFDM18] =
+ power[ATHN_POWER_OFDM24] = tpow_ofdm[0];
+ power[ATHN_POWER_OFDM36] = tpow_ofdm[1];
+ power[ATHN_POWER_OFDM48] = tpow_ofdm[2];
+ power[ATHN_POWER_OFDM54] = tpow_ofdm[3];
+ power[ATHN_POWER_XR ] = tpow_ofdm[0];
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ power[ATHN_POWER_CCK1_LP ] = tpow_cck[0] + cckinc;
+ power[ATHN_POWER_CCK2_LP ] =
+ power[ATHN_POWER_CCK2_SP ] = tpow_cck[1] + cckinc;
+ power[ATHN_POWER_CCK55_LP] =
+ power[ATHN_POWER_CCK55_SP] = tpow_cck[2] + cckinc;
+ power[ATHN_POWER_CCK11_LP] =
+ power[ATHN_POWER_CCK11_SP] = tpow_cck[3] + cckinc;
+ }
+ for (i = 0; i < nitems(tpow_ht20); i++)
+ power[ATHN_POWER_HT20(i)] = tpow_ht20[i];
+ if (extc != NULL) {
+ /* Correct PAR difference between HT40 and HT20/Legacy. */
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_2)
+ ht40inc = modal->ht40PowerIncForPdadc;
+ else
+ ht40inc = AR_HT40_POWER_INC_FOR_PDADC;
+ for (i = 0; i < nitems(tpow_ht40); i++)
+ power[ATHN_POWER_HT40(i)] = tpow_ht40[i] + ht40inc;
+ power[ATHN_POWER_OFDM_DUP] = tpow_ht40[0];
+ power[ATHN_POWER_CCK_DUP ] = tpow_ht40[0] + cckinc;
+ power[ATHN_POWER_OFDM_EXT] = tpow_ofdm_ext[0];
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ power[ATHN_POWER_CCK_EXT] = tpow_cck_ext[0] + cckinc;
+ }
+
+ if (AR_SREV_9280_10_OR_LATER(sc)) {
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_21)
+ pwroff = eep->baseEepHeader.pwrTableOffset;
+ else
+ pwroff = AR_PWR_TABLE_OFFSET_DB;
+ for (i = 0; i < ATHN_POWER_COUNT; i++)
+ power[i] -= pwroff * 2; /* In half dB. */
+ }
+ for (i = 0; i < ATHN_POWER_COUNT; i++) {
+ if (power[i] > AR_MAX_RATE_POWER)
+ power[i] = AR_MAX_RATE_POWER;
+ }
+
+ /* Write transmit power values to hardware. */
+ ar5008_write_txpower(sc, power);
+
+ /*
+ * Write transmit power subtraction for dynamic chain changing
+ * and per-packet transmit power.
+ */
+ AR_WRITE(sc, AR_PHY_POWER_TX_SUB,
+ (modal->pwrDecreaseFor3Chain & 0x3f) << 6 |
+ (modal->pwrDecreaseFor2Chain & 0x3f));
+}
+
+void
+ar5416_spur_mitigate(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ const struct ar_spur_chan *spurchans;
+ int i, spur, bin, spur_delta_phase, spur_freq_sd;
+
+ spurchans = sc->ops.get_spur_chans(sc, IEEE80211_IS_CHAN_2GHZ(c));
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+ spur = spurchans[i].spurChan;
+ if (spur == AR_NO_SPUR)
+ return; /* XXX disable if it was enabled! */
+ spur -= c->ic_freq * 10;
+ /* Verify range +/-9.5MHz */
+ if (abs(spur) < 95)
+ break;
+ }
+ if (i == AR_EEPROM_MODAL_SPURS)
+ return; /* XXX disable if it was enabled! */
+ DPRINTFN(2, ("enabling spur mitigation\n"));
+
+ AR_SETBITS(sc, AR_PHY_TIMING_CTRL4_0,
+ AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+ AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+ AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+ AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+
+ AR_WRITE(sc, AR_PHY_SPUR_REG,
+ AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+ AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+ AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+ AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+ SM(AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, AR_SPUR_RSSI_THRESH));
+
+ spur_delta_phase = (spur * 524288) / 100;
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ spur_freq_sd = (spur * 2048) / 440;
+ else
+ spur_freq_sd = (spur * 2048) / 400;
+
+ AR_WRITE(sc, AR_PHY_TIMING11,
+ AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+ SM(AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd) |
+ SM(AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase));
+
+ bin = spur * 32;
+ ar5008_set_viterbi_mask(sc, bin);
+}
+
+uint8_t
+ar5416_reverse_bits(uint8_t v, int nbits)
+{
+ KASSERT(nbits <= 8, ("ar5416_reverse_bits"));
+ v = ((v >> 1) & 0x55) | ((v & 0x55) << 1);
+ v = ((v >> 2) & 0x33) | ((v & 0x33) << 2);
+ v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4);
+ return (v >> (8 - nbits));
+}
+
+uint8_t
+ar5416_get_rf_rev(struct athn_softc *sc)
+{
+ uint8_t rev, reg;
+ int i;
+
+ /* Allow access to analog chips. */
+ AR_WRITE(sc, AR_PHY(0), 0x00000007);
+
+ AR_WRITE(sc, AR_PHY(0x36), 0x00007058);
+ for (i = 0; i < 8; i++)
+ AR_WRITE(sc, AR_PHY(0x20), 0x00010000);
+ reg = (AR_READ(sc, AR_PHY(256)) >> 24) & 0xff;
+ reg = (reg & 0xf0) >> 4 | (reg & 0x0f) << 4;
+
+ rev = ar5416_reverse_bits(reg, 8);
+ if ((rev & AR_RADIO_SREV_MAJOR) == 0)
+ rev = AR_RAD5133_SREV_MAJOR;
+ return (rev);
+}
+
+/*
+ * Replace bits "off" to "off+nbits-1" in column "col" with the specified
+ * value.
+ */
+void
+ar5416_rw_rfbits(uint32_t *buf, int col, int off, uint32_t val, int nbits)
+{
+ int idx, bit;
+
+ KASSERT(off >= 1 && col < 4 && nbits <= 32, ("ar5416_rw_rfbits"));
+
+ off--; /* Starts at 1. */
+ while (nbits-- > 0) {
+ idx = off / 8;
+ bit = off % 8;
+ buf[idx] &= ~(1 << (bit + col * 8));
+ buf[idx] |= ((val >> nbits) & 1) << (bit + col * 8);
+ off++;
+ }
+}
+
+/*
+ * Overwrite db and ob based on ROM settings.
+ */
+void
+ar5416_rw_bank6tpc(struct athn_softc *sc, struct ieee80211_channel *c,
+ uint32_t *rwbank6tpc)
+{
+ const struct ar5416_eeprom *eep = sc->eep;
+ const struct ar5416_modal_eep_header *modal;
+
+ if (IEEE80211_IS_CHAN_5GHZ(c)) {
+ modal = &eep->modalHeader[0];
+ /* 5GHz db in column 0, bits [200-202]. */
+ ar5416_rw_rfbits(rwbank6tpc, 0, 200, modal->db, 3);
+ /* 5GHz ob in column 0, bits [203-205]. */
+ ar5416_rw_rfbits(rwbank6tpc, 0, 203, modal->ob, 3);
+ } else {
+ modal = &eep->modalHeader[1];
+ /* 2GHz db in column 0, bits [194-196]. */
+ ar5416_rw_rfbits(rwbank6tpc, 0, 194, modal->db, 3);
+ /* 2GHz ob in column 0, bits [197-199]. */
+ ar5416_rw_rfbits(rwbank6tpc, 0, 197, modal->ob, 3);
+ }
+}
+
+/*
+ * Program analog RF.
+ */
+void
+ar5416_rf_reset(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ const uint32_t *bank6tpc;
+ int i;
+
+ /* Bank 0. */
+ AR_WRITE(sc, 0x98b0, 0x1e5795e5);
+ AR_WRITE(sc, 0x98e0, 0x02008020);
+
+ /* Bank 1. */
+ AR_WRITE(sc, 0x98b0, 0x02108421);
+ AR_WRITE(sc, 0x98ec, 0x00000008);
+
+ /* Bank 2. */
+ AR_WRITE(sc, 0x98b0, 0x0e73ff17);
+ AR_WRITE(sc, 0x98e0, 0x00000420);
+
+ /* Bank 3. */
+ if (IEEE80211_IS_CHAN_5GHZ(c))
+ AR_WRITE(sc, 0x98f0, 0x01400018);
+ else
+ AR_WRITE(sc, 0x98f0, 0x01c00018);
+
+ /* Select the Bank 6 TPC values to use. */
+ if (AR_SREV_9160_10_OR_LATER(sc))
+ bank6tpc = ar9160_bank6tpc_vals;
+ else
+ bank6tpc = ar5416_bank6tpc_vals;
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_2) {
+ uint32_t *rwbank6tpc = sc->rwbuf;
+
+ /* Copy values from .rodata to writable buffer. */
+ memcpy(rwbank6tpc, bank6tpc, 32 * sizeof(uint32_t));
+ ar5416_rw_bank6tpc(sc, c, rwbank6tpc);
+ bank6tpc = rwbank6tpc;
+ }
+ /* Bank 6 TPC. */
+ for (i = 0; i < 32; i++)
+ AR_WRITE(sc, 0x989c, bank6tpc[i]);
+ if (IEEE80211_IS_CHAN_5GHZ(c))
+ AR_WRITE(sc, 0x98d0, 0x0000000f);
+ else
+ AR_WRITE(sc, 0x98d0, 0x0010000f);
+
+ /* Bank 7. */
+ AR_WRITE(sc, 0x989c, 0x00000500);
+ AR_WRITE(sc, 0x989c, 0x00000800);
+ AR_WRITE(sc, 0x98cc, 0x0000000e);
+}
+
+void
+ar5416_reset_bb_gain(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ const uint32_t *pvals;
+ int i;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ pvals = ar5416_bb_rfgain_vals_2g;
+ else
+ pvals = ar5416_bb_rfgain_vals_5g;
+ for (i = 0; i < 64; i++)
+ AR_WRITE(sc, AR_PHY_BB_RFGAIN(i), pvals[i]);
+}
+
+/*
+ * Fix orientation sensitivity issue on AR5416/2GHz by increasing
+ * rf_pwd_icsyndiv.
+ */
+void
+ar5416_force_bias(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ uint32_t *rwbank6 = sc->rwbuf;
+ uint8_t bias;
+ int i;
+
+ KASSERT(IEEE80211_IS_CHAN_2GHZ(c), ("ar5416_force_bias"));
+
+ /* Copy values from .rodata to writable buffer. */
+ memcpy(rwbank6, ar5416_bank6_vals, sizeof(ar5416_bank6_vals));
+
+ if (c->ic_freq < 2412)
+ bias = 0;
+ else if (c->ic_freq < 2422)
+ bias = 1;
+ else
+ bias = 2;
+ ar5416_reverse_bits(bias, 3);
+
+ /* Overwrite "rf_pwd_icsyndiv" (column 3, bits [181-183].) */
+ ar5416_rw_rfbits(rwbank6, 3, 181, bias, 3);
+
+ /* Write Bank 6. */
+ for (i = 0; i < 32; i++)
+ AR_WRITE(sc, 0x989c, rwbank6[i]);
+ AR_WRITE(sc, 0x98d0, 0x0010000f);
+}
+
+/*
+ * Overwrite XPA bias level based on ROM setting.
+ */
+void
+ar9160_rw_addac(struct athn_softc *sc, struct ieee80211_channel *c,
+ uint32_t *addac)
+{
+ struct ar5416_eeprom *eep = sc->eep;
+ struct ar5416_modal_eep_header *modal;
+ uint8_t fbin, bias;
+ int i;
+
+ /* XXX xpaBiasLvlFreq values have not been endian-swapped? */
+
+ /* Get the XPA bias level to use for the specified channel. */
+ modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)];
+ if (modal->xpaBiasLvl == 0xff) {
+ bias = modal->xpaBiasLvlFreq[0] >> 14;
+ fbin = athn_chan2fbin(c);
+ for (i = 1; i < 3; i++) {
+ if (modal->xpaBiasLvlFreq[i] == 0)
+ break;
+ if ((modal->xpaBiasLvlFreq[i] & 0xff) < fbin)
+ break;
+ bias = modal->xpaBiasLvlFreq[i] >> 14;
+ }
+ } else
+ bias = modal->xpaBiasLvl & 0x3;
+
+ bias = ar5416_reverse_bits(bias, 2); /* Put in host bit-order. */
+ DPRINTFN(4, ("bias level=%d\n", bias));
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ ar5416_rw_rfbits(addac, 0, 60, bias, 2);
+ else
+ ar5416_rw_rfbits(addac, 0, 55, bias, 2);
+}
+
+void
+ar5416_reset_addac(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ const struct athn_addac *addac = sc->addac;
+ const uint32_t *pvals;
+ int i;
+
+ if (AR_SREV_9160(sc) && sc->eep_rev >= AR_EEP_MINOR_VER_7) {
+ uint32_t *rwaddac = sc->rwbuf;
+
+ /* Copy values from .rodata to writable buffer. */
+ memcpy(rwaddac, addac->vals, addac->nvals * sizeof(uint32_t));
+ ar9160_rw_addac(sc, c, rwaddac);
+ pvals = rwaddac;
+ } else
+ pvals = addac->vals;
+ for (i = 0; i < addac->nvals; i++)
+ AR_WRITE(sc, 0x989c, pvals[i]);
+ AR_WRITE(sc, 0x98cc, 0); /* Finalize. */
+}
diff --git a/sys/dev/athn/ic/ar5416reg.h b/sys/dev/athn/ic/ar5416reg.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar5416reg.h
@@ -0,0 +1,844 @@
+/* $OpenBSD: ar5416reg.h,v 1.7 2019/02/01 16:15:07 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <dev/athn/athnreg.h>
+#include <dev/athn/athnvar.h>
+
+#define AR5416_MAX_CHAINS 3
+
+#define AR5416_PHY_CCA_MIN_GOOD_VAL_2GHZ (-100)
+#define AR5416_PHY_CCA_MIN_GOOD_VAL_5GHZ (-110)
+#define AR5416_PHY_CCA_MAX_GOOD_VAL_2GHZ (-80)
+#define AR5416_PHY_CCA_MAX_GOOD_VAL_5GHZ (-90)
+
+/*
+ * ROM layout used by AR5416, AR9160 and AR9280.
+ */
+#define AR5416_EEP_START_LOC 256
+#define AR5416_NUM_5G_CAL_PIERS 8
+#define AR5416_NUM_2G_CAL_PIERS 4
+#define AR5416_NUM_5G_20_TARGET_POWERS 8
+#define AR5416_NUM_5G_40_TARGET_POWERS 8
+#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_NUM_2G_20_TARGET_POWERS 4
+#define AR5416_NUM_2G_40_TARGET_POWERS 4
+#define AR5416_NUM_CTLS 24
+#define AR5416_NUM_BAND_EDGES 8
+#define AR5416_NUM_PD_GAINS 4
+#define AR5416_PD_GAINS_IN_MASK 4
+#define AR5416_PD_GAIN_ICEPTS 5
+
+struct ar5416_base_eep_header {
+ uint16_t length;
+ uint16_t checksum;
+ uint16_t version;
+ uint8_t opCapFlags;
+ uint8_t eepMisc;
+ uint16_t regDmn[2];
+ uint8_t macAddr[6];
+ uint8_t rxMask;
+ uint8_t txMask;
+ uint16_t rfSilent;
+ uint16_t blueToothOptions;
+ uint16_t deviceCap;
+ uint32_t binBuildNumber;
+ uint8_t deviceType;
+ /* End of common header. */
+ uint8_t pwdclkind;
+ uint8_t fastClk5g;
+ uint8_t divChain;
+ uint8_t rxGainType;
+#define AR5416_EEP_RXGAIN_23DB_BACKOFF 0
+#define AR5416_EEP_RXGAIN_13DB_BACKOFF 1
+#define AR5416_EEP_RXGAIN_ORIG 2
+
+ uint8_t dacHiPwrMode_5G;
+ uint8_t openLoopPwrCntl;
+ uint8_t dacLpMode;
+ uint8_t txGainType;
+ uint8_t rcChainMask;
+ uint8_t desiredScaleCCK;
+ uint8_t pwrTableOffset;
+ uint8_t frac_n_5g;
+ uint8_t futureBase[21];
+} __packed;
+
+struct ar5416_modal_eep_header {
+ uint32_t antCtrlChain[AR5416_MAX_CHAINS];
+ uint32_t antCtrlCommon;
+ uint8_t antennaGainCh[AR5416_MAX_CHAINS];
+ uint8_t switchSettling;
+ uint8_t txRxAttenCh[AR5416_MAX_CHAINS];
+ uint8_t rxTxMarginCh[AR5416_MAX_CHAINS];
+ uint8_t adcDesiredSize;
+ uint8_t pgaDesiredSize;
+ uint8_t xlnaGainCh[AR5416_MAX_CHAINS];
+ uint8_t txEndToXpaOff;
+ uint8_t txEndToRxOn;
+ uint8_t txFrameToXpaOn;
+ uint8_t thresh62;
+ uint8_t noiseFloorThreshCh[AR5416_MAX_CHAINS];
+ uint8_t xpdGain;
+ uint8_t xpd;
+ uint8_t iqCalICh[AR5416_MAX_CHAINS];
+ uint8_t iqCalQCh[AR5416_MAX_CHAINS];
+ uint8_t pdGainOverlap;
+ uint8_t ob;
+ uint8_t db;
+ uint8_t xpaBiasLvl;
+ uint8_t pwrDecreaseFor2Chain;
+ uint8_t pwrDecreaseFor3Chain;
+ uint8_t txFrameToDataStart;
+ uint8_t txFrameToPaOn;
+ uint8_t ht40PowerIncForPdadc;
+ uint8_t bswAtten[AR5416_MAX_CHAINS];
+ uint8_t bswMargin[AR5416_MAX_CHAINS];
+ uint8_t swSettleHt40;
+ uint8_t xatten2Db[AR5416_MAX_CHAINS];
+ uint8_t xatten2Margin[AR5416_MAX_CHAINS];
+ uint8_t ob_ch1;
+ uint8_t db_ch1;
+ uint8_t flagBits;
+#define AR5416_EEP_FLAG_USEANT1 0x01
+#define AR5416_EEP_FLAG_FORCEXPAON 0x02
+#define AR5416_EEP_FLAG_LOCALBIAS 0x04
+#define AR5416_EEP_FLAG_FEMBANDSELECT 0x08
+#define AR5416_EEP_FLAG_XLNABUFIN 0x10
+#define AR5416_EEP_FLAG_XLNAISEL_M 0x60
+#define AR5416_EEP_FLAG_XLNAISEL_S 5
+#define AR5416_EEP_FLAG_XLNABUFMODE 0x80
+
+ uint8_t miscBits;
+#define AR5416_EEP_MISC_TX_DAC_SCALE_CCK_M 0x03
+#define AR5416_EEP_MISC_TX_DAC_SCALE_CCK_S 0
+#define AR5416_EEP_MISC_TX_CLIP_M 0xfc
+#define AR5416_EEP_MISC_TX_CLIP_S 2
+
+ uint16_t xpaBiasLvlFreq[3];
+ uint8_t futureModal[6];
+ struct ar_spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
+} __packed;
+
+struct ar5416_cal_data_per_freq {
+ uint8_t pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+ uint8_t vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+struct ar5416_cal_ctl_data {
+ struct ar_cal_ctl_edges
+ ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+struct ar5416_eeprom {
+ struct ar5416_base_eep_header baseEepHeader;
+ uint8_t custData[64];
+ struct ar5416_modal_eep_header modalHeader[2];
+ uint8_t calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
+ uint8_t calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
+ struct ar5416_cal_data_per_freq
+ calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
+ struct ar5416_cal_data_per_freq
+ calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+ struct ar_cal_target_power_leg
+ calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
+ struct ar_cal_target_power_leg
+ calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
+ struct ar_cal_target_power_leg
+ calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
+ uint8_t ctlIndex[AR5416_NUM_CTLS];
+ struct ar5416_cal_ctl_data ctlData[AR5416_NUM_CTLS];
+ uint8_t padding;
+} __packed;
+
+/* Macro to "pack" registers to 16-bit to save some .rodata space. */
+#define P(x) (x)
+
+/*
+ * AR5416 initialization values.
+ */
+static const uint16_t ar5416_regs[] = {
+ P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014),
+ P(0x0801c), P(0x08120), P(0x081d0), P(0x09804), P(0x09820),
+ P(0x09824), P(0x09828), P(0x09834), P(0x09838), P(0x09844),
+ P(0x09848), P(0x0a848), P(0x0b848), P(0x09850), P(0x09858),
+ P(0x0985c), P(0x09860), P(0x09864), P(0x09868), P(0x0986c),
+ P(0x09914), P(0x09918), P(0x09924), P(0x09944), P(0x09960),
+ P(0x0a960), P(0x0b960), P(0x09964), P(0x099bc), P(0x099c0),
+ P(0x099c4), P(0x099c8), P(0x099cc), P(0x099d0), P(0x099d4),
+ P(0x099d8), P(0x0a204), P(0x0a208), P(0x0a20c), P(0x0b20c),
+ P(0x0c20c), P(0x0a21c), P(0x0a230), P(0x0a274), P(0x0a300),
+ P(0x0a304), P(0x0a308), P(0x0a30c), P(0x0a310), P(0x0a314),
+ P(0x0a318), P(0x0a31c), P(0x0a320), P(0x0a324), P(0x0a328),
+ P(0x0a32c), P(0x0a330), P(0x0a334)
+};
+
+static const uint32_t ar5416_vals_5g20[] = {
+ 0x00000230, 0x00000168, 0x00000e60, 0x0000a000, 0x03e803e8,
+ 0x128d93a7, 0x08f04800, 0x00003210, 0x00000300, 0x02020200,
+ 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x1372161e,
+ 0x001a6a65, 0x001a6a65, 0x001a6a65, 0x6c48b4e0, 0x7ec82d2e,
+ 0x31395d5e, 0x00049d18, 0x0001ce00, 0x409a4190, 0x050cb081,
+ 0x000007d0, 0x000001b8, 0xd0058a0b, 0xffb81020, 0x00000900,
+ 0x00000900, 0x00000900, 0x00000000, 0x001a0a00, 0x038919be,
+ 0x06336f77, 0x6af6532c, 0x08f186c8, 0x00046384, 0x00000000,
+ 0x00000000, 0x00000880, 0xd6be4788, 0x002ec1e0, 0x002ec1e0,
+ 0x002ec1e0, 0x1883800a, 0x00000000, 0x0a1a9caa, 0x18010000,
+ 0x30032602, 0x48073e06, 0x560b4c0a, 0x641a600f, 0x7a4f6e1b,
+ 0x8c5b7e5a, 0x9d0f96cf, 0xb51fa69f, 0xcb3fbd07, 0x0000d7bf,
+ 0x00000000, 0x00000000, 0x00000000
+};
+
+static const uint32_t ar5416_vals_5g40[] = {
+ 0x00000460, 0x000002d0, 0x00001cc0, 0x00014000, 0x07d007d0,
+ 0x128d93cf, 0x08f04800, 0x00003210, 0x000003c4, 0x02020200,
+ 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x1372161e,
+ 0x001a6a65, 0x001a6a65, 0x001a6a65, 0x6d48b4e0, 0x7ec82d2e,
+ 0x3139605e, 0x00049d18, 0x0001ce00, 0x409a4190, 0x050cb081,
+ 0x00000fa0, 0x00000370, 0xd0058a0b, 0xffb81020, 0x00000900,
+ 0x00000900, 0x00000900, 0x00000000, 0x001a0a00, 0x038919be,
+ 0x06336f77, 0x6af6532c, 0x08f186c8, 0x00046384, 0x00000000,
+ 0x00000000, 0x00000880, 0xd6be4788, 0x002ec1e0, 0x002ec1e0,
+ 0x002ec1e0, 0x1883800a, 0x00000000, 0x0a1a9caa, 0x18010000,
+ 0x30032602, 0x48073e06, 0x560b4c0a, 0x641a600f, 0x7a4f6e1b,
+ 0x8c5b7e5a, 0x9d0f96cf, 0xb51fa69f, 0xcb3fbcbf, 0x0000d7bf,
+ 0x00000000, 0x00000000, 0x00000000
+};
+
+static const uint32_t ar5416_vals_2g40[] = {
+ 0x000002c0, 0x00000318, 0x00007c70, 0x00016000, 0x10801600,
+ 0x12e013d7, 0x08f04810, 0x0000320a, 0x000003c4, 0x02020200,
+ 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x137216a0,
+ 0x00197a68, 0x00197a68, 0x00197a68, 0x6d48b0de, 0x7ec82d2e,
+ 0x3139605e, 0x00049d18, 0x0001ce00, 0x409a4190, 0x050cb081,
+ 0x00001130, 0x00000268, 0xd0058a0b, 0xffb81020, 0x00012d80,
+ 0x00012d80, 0x00012d80, 0x00001120, 0x001a0a00, 0x038919be,
+ 0x06336f77, 0x6af6532c, 0x08f186c8, 0x00046384, 0x00000000,
+ 0x00000000, 0x00000880, 0xd03e4788, 0x002ac120, 0x002ac120,
+ 0x002ac120, 0x1883800a, 0x00000210, 0x0a1a7caa, 0x18010000,
+ 0x2e032402, 0x4a0a3c06, 0x621a540b, 0x764f6c1b, 0x845b7a5a,
+ 0x950f8ccf, 0xa5cf9b4f, 0xbddfaf1f, 0xd1ffc93f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000
+};
+
+static const uint32_t ar5416_vals_2g20[] = {
+ 0x00000160, 0x0000018c, 0x00003e38, 0x0000b000, 0x08400b00,
+ 0x12e013ab, 0x08f04810, 0x0000320a, 0x00000300, 0x02020200,
+ 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x137216a0,
+ 0x00197a68, 0x00197a68, 0x00197a68, 0x6c48b0de, 0x7ec82d2e,
+ 0x31395d5e, 0x00049d18, 0x0001ce00, 0x409a4190, 0x050cb081,
+ 0x00000898, 0x00000134, 0xd0058a0b, 0xffb81020, 0x00012d80,
+ 0x00012d80, 0x00012d80, 0x00001120, 0x001a0a00, 0x038919be,
+ 0x06336f77, 0x6af6532c, 0x08f186c8, 0x00046384, 0x00000000,
+ 0x00000000, 0x00000880, 0xd03e4788, 0x002ac120, 0x002ac120,
+ 0x002ac120, 0x1883800a, 0x00000108, 0x0a1a7caa, 0x18010000,
+ 0x2e032402, 0x4a0a3c06, 0x621a540b, 0x764f6c1b, 0x845b7a5a,
+ 0x950f8ccf, 0xa5cf9b4f, 0xbddfaf1f, 0xd1ffc93f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000
+};
+
+static const uint16_t ar5416_cm_regs[] = {
+ P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044),
+ P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800),
+ P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814),
+ P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040),
+ P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054),
+ P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230),
+ P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8),
+ P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238),
+ P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378),
+ P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8),
+ P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8),
+ P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738),
+ P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c),
+ P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc),
+ P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc),
+ P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c),
+ P(0x0147c), P(0x04030), P(0x0403c), P(0x07010), P(0x07038),
+ P(0x08004), P(0x08008), P(0x0800c), P(0x08018), P(0x08020),
+ P(0x08038), P(0x0803c), P(0x08048), P(0x08054), P(0x08058),
+ P(0x0805c), P(0x08060), P(0x08064), P(0x080c0), P(0x080c4),
+ P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4), P(0x080d8),
+ P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec), P(0x080f0),
+ P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100), P(0x08104),
+ P(0x08108), P(0x0810c), P(0x08110), P(0x08118), P(0x0811c),
+ P(0x08124), P(0x08128), P(0x0812c), P(0x08130), P(0x08134),
+ P(0x08138), P(0x0813c), P(0x08144), P(0x08168), P(0x0816c),
+ P(0x08170), P(0x08174), P(0x08178), P(0x0817c), P(0x081c4),
+ P(0x081ec), P(0x081f0), P(0x081f4), P(0x081f8), P(0x081fc),
+ P(0x08200), P(0x08204), P(0x08208), P(0x0820c), P(0x08210),
+ P(0x08214), P(0x08218), P(0x0821c), P(0x08220), P(0x08224),
+ P(0x08228), P(0x0822c), P(0x08230), P(0x08234), P(0x08238),
+ P(0x0823c), P(0x08240), P(0x08244), P(0x08248), P(0x0824c),
+ P(0x08250), P(0x08254), P(0x08258), P(0x0825c), P(0x08260),
+ P(0x08264), P(0x08270), P(0x08274), P(0x08278), P(0x0827c),
+ P(0x08284), P(0x08288), P(0x0828c), P(0x08294), P(0x08298),
+ P(0x08300), P(0x08304), P(0x08308), P(0x0830c), P(0x08310),
+ P(0x08314), P(0x08318), P(0x08328), P(0x0832c), P(0x08330),
+ P(0x08334), P(0x08338), P(0x0833c), P(0x08340), P(0x09808),
+ P(0x0980c), P(0x09810), P(0x09814), P(0x0981c), P(0x0982c),
+ P(0x09830), P(0x0983c), P(0x09840), P(0x0984c), P(0x09854),
+ P(0x09900), P(0x09904), P(0x09908), P(0x0990c), P(0x0991c),
+ P(0x09920), P(0x0a920), P(0x0b920), P(0x09928), P(0x0992c),
+ P(0x09934), P(0x09938), P(0x0993c), P(0x09948), P(0x0994c),
+ P(0x09954), P(0x09958), P(0x0c95c), P(0x0c968), P(0x09970),
+ P(0x09974), P(0x09978), P(0x0997c), P(0x09980), P(0x09984),
+ P(0x09988), P(0x0998c), P(0x09990), P(0x09994), P(0x09998),
+ P(0x0999c), P(0x099a0), P(0x099a4), P(0x099a8), P(0x099ac),
+ P(0x099b0), P(0x099dc), P(0x099e0), P(0x099e4), P(0x099e8),
+ P(0x099ec), P(0x099fc), P(0x09b00), P(0x09b04), P(0x09b08),
+ P(0x09b0c), P(0x09b10), P(0x09b14), P(0x09b18), P(0x09b1c),
+ P(0x09b20), P(0x09b24), P(0x09b28), P(0x09b2c), P(0x09b30),
+ P(0x09b34), P(0x09b38), P(0x09b3c), P(0x09b40), P(0x09b44),
+ P(0x09b48), P(0x09b4c), P(0x09b50), P(0x09b54), P(0x09b58),
+ P(0x09b5c), P(0x09b60), P(0x09b64), P(0x09b68), P(0x09b6c),
+ P(0x09b70), P(0x09b74), P(0x09b78), P(0x09b7c), P(0x09b80),
+ P(0x09b84), P(0x09b88), P(0x09b8c), P(0x09b90), P(0x09b94),
+ P(0x09b98), P(0x09b9c), P(0x09ba0), P(0x09ba4), P(0x09ba8),
+ P(0x09bac), P(0x09bb0), P(0x09bb4), P(0x09bb8), P(0x09bbc),
+ P(0x09bc0), P(0x09bc4), P(0x09bc8), P(0x09bcc), P(0x09bd0),
+ P(0x09bd4), P(0x09bd8), P(0x09bdc), P(0x09be0), P(0x09be4),
+ P(0x09be8), P(0x09bec), P(0x09bf0), P(0x09bf4), P(0x09bf8),
+ P(0x09bfc), P(0x0a210), P(0x0a214), P(0x0a218), P(0x0a220),
+ P(0x0a224), P(0x0a228), P(0x0a22c), P(0x0a234), P(0x0a238),
+ P(0x0a23c), P(0x0a240), P(0x0a244), P(0x0a248), P(0x0a24c),
+ P(0x0a250), P(0x0a254), P(0x0a258), P(0x0a25c), P(0x0a260),
+ P(0x0a268), P(0x0a26c), P(0x0b26c), P(0x0c26c), P(0x0d270),
+ P(0x0a278), P(0x0a27c), P(0x0a338), P(0x0a33c), P(0x0a340),
+ P(0x0a344), P(0x0a348), P(0x0a34c), P(0x0a350), P(0x0a354),
+ P(0x0a358), P(0x0d35c), P(0x0d360), P(0x0d364), P(0x0d368),
+ P(0x0d36c), P(0x0d370), P(0x0d374), P(0x0d378), P(0x0d37c),
+ P(0x0d380), P(0x0d384), P(0x0a388), P(0x0a38c), P(0x0a390),
+ P(0x0a394), P(0x0a398), P(0x0a39c), P(0x0a3a0), P(0x0a3a4),
+ P(0x0a3a8), P(0x0a3ac), P(0x0a3b0), P(0x0a3b4), P(0x0a3b8),
+ P(0x0a3bc), P(0x0a3c0), P(0x0a3c4), P(0x0a3c8), P(0x0a3cc),
+ P(0x0a3d0), P(0x0a3d4), P(0x0a3dc), P(0x0a3e0)
+};
+
+static const uint32_t ar5416_cm_vals[] = {
+ 0x00000000, 0x00020015, 0x00000005, 0x00000000, 0x00000008,
+ 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x000004c2,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000700, 0x00000000,
+ 0x00000000, 0x00000000, 0x40000000, 0x00000000, 0x00000000,
+ 0x000fc78f, 0x0000000f, 0x00000000, 0x2a82301a, 0x05dc01e0,
+ 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000, 0x00400000,
+ 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00000001,
+ 0x00000052, 0x00000000, 0x00000168, 0x000100aa, 0x00003210,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000,
+ 0x32143320, 0xfaa4fa50, 0x00000100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00100000, 0x0010f400, 0x00000100, 0x0001e800,
+ 0x00000000, 0x00000000, 0x00000000, 0x400000ff, 0x00080922,
+ 0x88000010, 0x00000000, 0x40000000, 0x003e4180, 0x00000000,
+ 0x0000002c, 0x0000002c, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000302,
+ 0x00000e00, 0x00070000, 0x00000000, 0x000107ff, 0x00000000,
+ 0xad848e19, 0x7d14e000, 0x9c0a9f6b, 0x00000000, 0x0000a000,
+ 0x00000000, 0x00200400, 0x206a002e, 0x1284233c, 0x00000859,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000fff,
+ 0x05100000, 0x05100000, 0x05100000, 0x00000001, 0x00000004,
+ 0x1e1f2022, 0x0a0b0c0d, 0x00000000, 0x9280b212, 0x00020028,
+ 0x5d50e188, 0x00081fff, 0x004b6a8e, 0x000003ce, 0x190fb515,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x001fff00, 0x00000000,
+ 0x03051000, 0x00000000, 0x00000200, 0xaaaaaaaa, 0x3c466478,
+ 0x000000aa, 0x00001042, 0x00000000, 0x00000001, 0x00000002,
+ 0x00000003, 0x00000004, 0x00000005, 0x00000008, 0x00000009,
+ 0x0000000a, 0x0000000b, 0x0000000c, 0x0000000d, 0x00000010,
+ 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015,
+ 0x00000018, 0x00000019, 0x0000001a, 0x0000001b, 0x0000001c,
+ 0x0000001d, 0x00000020, 0x00000021, 0x00000022, 0x00000023,
+ 0x00000024, 0x00000025, 0x00000028, 0x00000029, 0x0000002a,
+ 0x0000002b, 0x0000002c, 0x0000002d, 0x00000030, 0x00000031,
+ 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000035,
+ 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
+ 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
+ 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
+ 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000010,
+ 0x0000001a, 0x40806333, 0x00106c10, 0x009c4060, 0x018830c6,
+ 0x00000400, 0x00000bb5, 0x00000011, 0x20202020, 0x20202020,
+ 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, 0x00000001,
+ 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01, 0xdfa91f01,
+ 0x00000000, 0x0e79e5c6, 0x0e79e5c6, 0x0e79e5c6, 0x00820820,
+ 0x1ce739ce, 0x051701ce, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff,
+ 0x79a8aa1f, 0x07ffffef, 0x0fffffe7, 0x17ffffe5, 0x1fffffe4,
+ 0x37ffffe3, 0x3fffffe3, 0x57ffffe3, 0x5fffffe2, 0x7fffffe2,
+ 0x7f3c7bba, 0xf3307ff0, 0x08000000, 0x20202020, 0x20202020,
+ 0x1ce739ce, 0x000001ce, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000246, 0x20202020,
+ 0x20202020, 0x20202020, 0x1ce739ce, 0x000001ce
+};
+
+static const struct athn_ini ar5416_ini = {
+ nitems(ar5416_regs),
+ ar5416_regs,
+ ar5416_vals_5g20,
+ ar5416_vals_5g40,
+ ar5416_vals_2g40,
+ ar5416_vals_2g20,
+ nitems(ar5416_cm_regs),
+ ar5416_cm_regs,
+ ar5416_cm_vals
+};
+
+/*
+ * AR9160 initialization values.
+ */
+static const uint16_t ar9160_regs[] = {
+ P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014),
+ P(0x0801c), P(0x08120), P(0x081d0), P(0x09804), P(0x09820),
+ P(0x09824), P(0x09828), P(0x09834), P(0x09838), P(0x09844),
+ P(0x09848), P(0x0a848), P(0x0b848), P(0x09850), P(0x09858),
+ P(0x0985c), P(0x09860), P(0x09864), P(0x09868), P(0x0986c),
+ P(0x09914), P(0x09918), P(0x09924), P(0x09944), P(0x09960),
+ P(0x0a960), P(0x0b960), P(0x09964), P(0x0c968), P(0x099bc),
+ P(0x099c0), P(0x099c4), P(0x099c8), P(0x099cc), P(0x099d0),
+ P(0x099d4), P(0x099d8), P(0x0a204), P(0x0a208), P(0x0a20c),
+ P(0x0b20c), P(0x0c20c), P(0x0a21c), P(0x0a230), P(0x0a274),
+ P(0x0a300), P(0x0a304), P(0x0a308), P(0x0a30c), P(0x0a310),
+ P(0x0a314), P(0x0a318), P(0x0a31c), P(0x0a320), P(0x0a324),
+ P(0x0a328), P(0x0a32c), P(0x0a330), P(0x0a334)
+};
+
+static const uint32_t ar9160_vals_5g20[] = {
+ 0x00000230, 0x00000168, 0x00000e60, 0x0000a000, 0x03e803e8,
+ 0x128d93a7, 0x08f04800, 0x00003210, 0x00000300, 0x02020200,
+ 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x0372161e,
+ 0x001a6a65, 0x001a6a65, 0x001a6a65, 0x6c48b4e2, 0x7ec82d2e,
+ 0x31395d5e, 0x00048d18, 0x0001ce00, 0x409a40d0, 0x050cb081,
+ 0x000007d0, 0x0000000a, 0xd00a8a07, 0xffb81020, 0x00009b40,
+ 0x00009b40, 0x00009b40, 0x00001120, 0x000003b5, 0x001a0600,
+ 0x038919be, 0x06336f77, 0x6af65329, 0x08f186c8, 0x00046384,
+ 0x00000000, 0x00000000, 0x00000880, 0xd6be4788, 0x002fc160,
+ 0x002fc160, 0x002fc160, 0x1883800a, 0x00000000, 0x0a1a9caa,
+ 0x18010000, 0x30032602, 0x48073e06, 0x560b4c0a, 0x641a600f,
+ 0x7a4f6e1b, 0x8c5b7e5a, 0x9d0f96cf, 0xb51fa69f, 0xcb3fbd07,
+ 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000
+};
+
+static const uint32_t ar9160_vals_5g40[] = {
+ 0x00000460, 0x000002d0, 0x00001cc0, 0x00014000, 0x07d007d0,
+ 0x128d93cf, 0x08f04800, 0x00003210, 0x000003c4, 0x02020200,
+ 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x0372161e,
+ 0x001a6a65, 0x001a6a65, 0x001a6a65, 0x6d48b4e2, 0x7ec82d2e,
+ 0x3139605e, 0x00048d18, 0x0001ce00, 0x409a40d0, 0x050cb081,
+ 0x00000fa0, 0x00000014, 0xd00a8a07, 0xffb81020, 0x00009b40,
+ 0x00009b40, 0x00009b40, 0x00001120, 0x000003b5, 0x001a0600,
+ 0x038919be, 0x06336f77, 0x6af65329, 0x08f186c8, 0x00046384,
+ 0x00000000, 0x00000000, 0x00000880, 0xd6be4788, 0x002fc160,
+ 0x002fc160, 0x002fc160, 0x1883800a, 0x00000000, 0x0a1a9caa,
+ 0x18010000, 0x30032602, 0x48073e06, 0x560b4c0a, 0x641a600f,
+ 0x7a4f6e1b, 0x8c5b7e5a, 0x9d0f96cf, 0xb51fa69f, 0xcb3fbcbf,
+ 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000
+};
+
+static const uint32_t ar9160_vals_2g40[] = {
+ 0x000002c0, 0x00000318, 0x00007c70, 0x00016000, 0x10801600,
+ 0x12e013d7, 0x08f04810, 0x0000320a, 0x000003c4, 0x02020200,
+ 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x037216a0,
+ 0x00197a68, 0x00197a68, 0x00197a68, 0x6d48b0e2, 0x7ec82d2e,
+ 0x3139605e, 0x00048d20, 0x0001ce00, 0x409a40d0, 0x050cb081,
+ 0x00001130, 0x00000016, 0xd00a8a0d, 0xffb81020, 0x00009b40,
+ 0x00009b40, 0x00009b40, 0x00001120, 0x000003ce, 0x001a0c00,
+ 0x038919be, 0x06336f77, 0x6af65329, 0x08f186c8, 0x00046384,
+ 0x00000000, 0x00000000, 0x00000880, 0xd03e4788, 0x002ac120,
+ 0x002ac120, 0x002ac120, 0x1883800a, 0x00000210, 0x0a1a7caa,
+ 0x18010000, 0x2e032402, 0x4a0a3c06, 0x621a540b, 0x764f6c1b,
+ 0x845b7a5a, 0x950f8ccf, 0xa5cf9b4f, 0xbddfaf1f, 0xd1ffc93f,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+static const uint32_t ar9160_vals_2g20[] = {
+ 0x00000160, 0x0000018c, 0x00003e38, 0x0000b000, 0x08400b00,
+ 0x12e013ab, 0x08f04810, 0x0000320a, 0x00000300, 0x02020200,
+ 0x00000e0e, 0x0a020001, 0x00000e0e, 0x00000007, 0x037216a0,
+ 0x00197a68, 0x00197a68, 0x00197a68, 0x6c48b0e2, 0x7ec82d2e,
+ 0x31395d5e, 0x00048d20, 0x0001ce00, 0x409a40d0, 0x050cb081,
+ 0x00000898, 0x0000000b, 0xd00a8a0d, 0xffb81020, 0x00009b40,
+ 0x00009b40, 0x00009b40, 0x00001120, 0x000003ce, 0x001a0c00,
+ 0x038919be, 0x06336f77, 0x6af65329, 0x08f186c8, 0x00046384,
+ 0x00000000, 0x00000000, 0x00000880, 0xd03e4788, 0x002ac120,
+ 0x002ac120, 0x002ac120, 0x1883800a, 0x00000108, 0x0a1a7caa,
+ 0x18010000, 0x2e032402, 0x4a0a3c06, 0x621a540b, 0x764f6c1b,
+ 0x845b7a5a, 0x950f8ccf, 0xa5cf9b4f, 0xbddfaf1f, 0xd1ffc93f,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+static const uint16_t ar9160_cm_regs[] = {
+ P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044),
+ P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800),
+ P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814),
+ P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040),
+ P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054),
+ P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230),
+ P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8),
+ P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238),
+ P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378),
+ P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8),
+ P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8),
+ P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738),
+ P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c),
+ P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc),
+ P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc),
+ P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c),
+ P(0x0147c), P(0x04030), P(0x0403c), P(0x07010), P(0x07038),
+ P(0x08004), P(0x08008), P(0x0800c), P(0x08018), P(0x08020),
+ P(0x08038), P(0x0803c), P(0x08048), P(0x08054), P(0x08058),
+ P(0x0805c), P(0x08060), P(0x08064), P(0x080c0), P(0x080c4),
+ P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4), P(0x080d8),
+ P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec), P(0x080f0),
+ P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100), P(0x08104),
+ P(0x08108), P(0x0810c), P(0x08110), P(0x08118), P(0x0811c),
+ P(0x08124), P(0x08128), P(0x0812c), P(0x08130), P(0x08134),
+ P(0x08138), P(0x0813c), P(0x08144), P(0x08168), P(0x0816c),
+ P(0x08170), P(0x08174), P(0x08178), P(0x0817c), P(0x081c4),
+ P(0x081ec), P(0x081f0), P(0x081f4), P(0x081f8), P(0x081fc),
+ P(0x08200), P(0x08204), P(0x08208), P(0x0820c), P(0x08210),
+ P(0x08214), P(0x08218), P(0x0821c), P(0x08220), P(0x08224),
+ P(0x08228), P(0x0822c), P(0x08230), P(0x08234), P(0x08238),
+ P(0x0823c), P(0x08240), P(0x08244), P(0x08248), P(0x0824c),
+ P(0x08250), P(0x08254), P(0x08258), P(0x0825c), P(0x08260),
+ P(0x08264), P(0x08270), P(0x08274), P(0x08278), P(0x0827c),
+ P(0x08284), P(0x08288), P(0x0828c), P(0x08294), P(0x08298),
+ P(0x08300), P(0x08304), P(0x08308), P(0x0830c), P(0x08310),
+ P(0x08314), P(0x08318), P(0x08328), P(0x0832c), P(0x08330),
+ P(0x08334), P(0x08338), P(0x0833c), P(0x08340), P(0x09808),
+ P(0x0980c), P(0x09810), P(0x09814), P(0x0981c), P(0x0982c),
+ P(0x09830), P(0x0983c), P(0x09840), P(0x0984c), P(0x09854),
+ P(0x09900), P(0x09904), P(0x09908), P(0x0990c), P(0x0991c),
+ P(0x09920), P(0x0a920), P(0x0b920), P(0x09928), P(0x0992c),
+ P(0x09934), P(0x09938), P(0x0993c), P(0x09948), P(0x0994c),
+ P(0x09954), P(0x09958), P(0x09940), P(0x0c95c), P(0x09970),
+ P(0x09974), P(0x09978), P(0x0997c), P(0x09980), P(0x09984),
+ P(0x09988), P(0x0998c), P(0x09990), P(0x09994), P(0x09998),
+ P(0x0999c), P(0x099a0), P(0x099a4), P(0x099a8), P(0x099ac),
+ P(0x099b0), P(0x099dc), P(0x099e0), P(0x099e4), P(0x099e8),
+ P(0x099ec), P(0x099fc), P(0x09b00), P(0x09b04), P(0x09b08),
+ P(0x09b0c), P(0x09b10), P(0x09b14), P(0x09b18), P(0x09b1c),
+ P(0x09b20), P(0x09b24), P(0x09b28), P(0x09b2c), P(0x09b30),
+ P(0x09b34), P(0x09b38), P(0x09b3c), P(0x09b40), P(0x09b44),
+ P(0x09b48), P(0x09b4c), P(0x09b50), P(0x09b54), P(0x09b58),
+ P(0x09b5c), P(0x09b60), P(0x09b64), P(0x09b68), P(0x09b6c),
+ P(0x09b70), P(0x09b74), P(0x09b78), P(0x09b7c), P(0x09b80),
+ P(0x09b84), P(0x09b88), P(0x09b8c), P(0x09b90), P(0x09b94),
+ P(0x09b98), P(0x09b9c), P(0x09ba0), P(0x09ba4), P(0x09ba8),
+ P(0x09bac), P(0x09bb0), P(0x09bb4), P(0x09bb8), P(0x09bbc),
+ P(0x09bc0), P(0x09bc4), P(0x09bc8), P(0x09bcc), P(0x09bd0),
+ P(0x09bd4), P(0x09bd8), P(0x09bdc), P(0x09be0), P(0x09be4),
+ P(0x09be8), P(0x09bec), P(0x09bf0), P(0x09bf4), P(0x09bf8),
+ P(0x09bfc), P(0x0a210), P(0x0a214), P(0x0a218), P(0x0a220),
+ P(0x0a224), P(0x0a228), P(0x0a22c), P(0x0a234), P(0x0a238),
+ P(0x0a23c), P(0x0a240), P(0x0a244), P(0x0a248), P(0x0a24c),
+ P(0x0a250), P(0x0a254), P(0x0a258), P(0x0a25c), P(0x0a260),
+ P(0x0a268), P(0x0a26c), P(0x0b26c), P(0x0c26c), P(0x0d270),
+ P(0x0a278), P(0x0a27c), P(0x0a338), P(0x0a33c), P(0x0a340),
+ P(0x0a344), P(0x0a348), P(0x0a34c), P(0x0a350), P(0x0a354),
+ P(0x0a358), P(0x0d35c), P(0x0d360), P(0x0d364), P(0x0d368),
+ P(0x0d36c), P(0x0d370), P(0x0d374), P(0x0d378), P(0x0d37c),
+ P(0x0d380), P(0x0d384), P(0x0a388), P(0x0a38c), P(0x0a390),
+ P(0x0a394), P(0x0a398), P(0x0a39c), P(0x0a3a0), P(0x0a3a4),
+ P(0x0a3a8), P(0x0a3ac), P(0x0a3b0), P(0x0a3b4), P(0x0a3b8),
+ P(0x0a3bc), P(0x0a3c0), P(0x0a3c4), P(0x0a3c8), P(0x0a3cc),
+ P(0x0a3d0), P(0x0a3d4), P(0x0a3dc), P(0x0a3e0)
+};
+
+static const uint32_t ar9160_cm_vals[] = {
+ 0x00000000, 0x00020015, 0x00000005, 0x00000000, 0x00000008,
+ 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000002, 0x00000002, 0x00000020, 0x000004c2,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000700, 0x00000000,
+ 0x00000000, 0x00000000, 0x40000000, 0x00000000, 0x00000000,
+ 0x000fc78f, 0x0000000f, 0x00000000, 0x2a82301a, 0x05dc01e0,
+ 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000, 0x00400000,
+ 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00000001,
+ 0x00000052, 0x00000000, 0x00000168, 0x000100aa, 0x00003210,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000,
+ 0x32143320, 0xfaa4fa50, 0x00000100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00100000, 0x0010f400, 0x00000100, 0x0001e800,
+ 0x00000000, 0x00000000, 0x00000000, 0x400000ff, 0x00080922,
+ 0x88a00010, 0x00000000, 0x40000000, 0x003e4180, 0x00000000,
+ 0x0000002c, 0x0000002c, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000302,
+ 0x00000e00, 0x00ff0000, 0x00000000, 0x000107ff, 0x00000000,
+ 0xad848e19, 0x7d14e000, 0x9c0a9f6b, 0x00000000, 0x0000a000,
+ 0x00000000, 0x00200400, 0x206a01ae, 0x1284233c, 0x00000859,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000fff,
+ 0x05100000, 0x05100000, 0x05100000, 0x00000001, 0x00000004,
+ 0x1e1f2022, 0x0a0b0c0d, 0x00000000, 0x9280b212, 0x00020028,
+ 0x5f3ca3de, 0x2108ecff, 0x00750604, 0x004b6a8e, 0x190fb515,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x201fff00, 0x006f0000,
+ 0x03051000, 0x00000000, 0x00000200, 0xaaaaaaaa, 0x3c466478,
+ 0x0cc80caa, 0x00001042, 0x00000000, 0x00000001, 0x00000002,
+ 0x00000003, 0x00000004, 0x00000005, 0x00000008, 0x00000009,
+ 0x0000000a, 0x0000000b, 0x0000000c, 0x0000000d, 0x00000010,
+ 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015,
+ 0x00000018, 0x00000019, 0x0000001a, 0x0000001b, 0x0000001c,
+ 0x0000001d, 0x00000020, 0x00000021, 0x00000022, 0x00000023,
+ 0x00000024, 0x00000025, 0x00000028, 0x00000029, 0x0000002a,
+ 0x0000002b, 0x0000002c, 0x0000002d, 0x00000030, 0x00000031,
+ 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000035,
+ 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
+ 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
+ 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
+ 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000010,
+ 0x0000001a, 0x40806333, 0x00106c10, 0x009c4060, 0x018830c6,
+ 0x00000400, 0x001a0bb5, 0x00000000, 0x20202020, 0x20202020,
+ 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc, 0x00000001,
+ 0x0000e000, 0x00000000, 0x0cc75380, 0x0f0f0f01, 0xdfa91f01,
+ 0x00000001, 0x0e79e5c6, 0x0e79e5c6, 0x0e79e5c6, 0x00820820,
+ 0x1ce739ce, 0x050701ce, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff,
+ 0x79bfaa03, 0x07ffffef, 0x0fffffe7, 0x17ffffe5, 0x1fffffe4,
+ 0x37ffffe3, 0x3fffffe3, 0x57ffffe3, 0x5fffffe2, 0x7fffffe2,
+ 0x7f3c7bba, 0xf3307ff0, 0x0c000000, 0x20202020, 0x20202020,
+ 0x1ce739ce, 0x000001ce, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000246, 0x20202020,
+ 0x20202020, 0x20202020, 0x1ce739ce, 0x000001ce
+};
+
+static const struct athn_ini ar9160_ini = {
+ nitems(ar9160_regs),
+ ar9160_regs,
+ ar9160_vals_5g20,
+ ar9160_vals_5g40,
+ ar9160_vals_2g40,
+ ar9160_vals_2g20,
+ nitems(ar9160_cm_regs),
+ ar9160_cm_regs,
+ ar9160_cm_vals
+};
+
+/*
+ * BB/RF Gains common to AR5416 and AR9160.
+ */
+static const uint32_t ar5416_bb_rfgain_vals_5g[] = {
+ 0x00000000, 0x00000040, 0x00000080, 0x000001a1, 0x000001e1,
+ 0x00000021, 0x00000061, 0x00000168, 0x000001a8, 0x000001e8,
+ 0x00000028, 0x00000068, 0x00000189, 0x000001c9, 0x00000009,
+ 0x00000049, 0x00000089, 0x00000170, 0x000001b0, 0x000001f0,
+ 0x00000030, 0x00000070, 0x00000191, 0x000001d1, 0x00000011,
+ 0x00000051, 0x00000091, 0x000001b8, 0x000001f8, 0x00000038,
+ 0x00000078, 0x00000199, 0x000001d9, 0x00000019, 0x00000059,
+ 0x00000099, 0x000000d9, 0x000000f9, 0x000000f9, 0x000000f9,
+ 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
+ 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
+ 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
+ 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
+ 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9
+};
+
+static const uint32_t ar5416_bb_rfgain_vals_2g[] = {
+ 0x00000000, 0x00000040, 0x00000080, 0x00000141, 0x00000181,
+ 0x000001c1, 0x00000001, 0x00000041, 0x000001a8, 0x000001e8,
+ 0x00000028, 0x00000068, 0x000000a8, 0x00000169, 0x000001a9,
+ 0x000001e9, 0x00000029, 0x00000069, 0x00000190, 0x000001d0,
+ 0x00000010, 0x00000050, 0x00000090, 0x00000151, 0x00000191,
+ 0x000001d1, 0x00000011, 0x00000051, 0x00000198, 0x000001d8,
+ 0x00000018, 0x00000058, 0x00000098, 0x00000159, 0x00000199,
+ 0x000001d9, 0x00000019, 0x00000059, 0x00000099, 0x000000d9,
+ 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
+ 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
+ 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
+ 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
+ 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9
+};
+
+static const uint32_t ar5416_2_1_addac_vals[] = {
+ 0x00000000, 0x00000003, 0x00000000, 0x0000000c, 0x00000000,
+ 0x00000030, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000060, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000
+};
+
+static const struct athn_addac ar5416_2_1_addac = {
+ nitems(ar5416_2_1_addac_vals),
+ ar5416_2_1_addac_vals
+};
+
+static const uint32_t ar5416_2_2_addac_vals[] = {
+ 0x00000000, 0x00000003, 0x00000000, 0x0000000c, 0x00000000,
+ 0x00000030, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000060, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000058, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000
+};
+
+static const struct athn_addac ar5416_2_2_addac = {
+ nitems(ar5416_2_2_addac_vals),
+ ar5416_2_2_addac_vals
+};
+
+static const uint32_t ar9160_1_0_addac_vals[] = {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x000000c0, 0x00000018, 0x00000004, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x000000c0, 0x00000019, 0x00000004, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000004, 0x00000003, 0x00000008,
+ 0x00000000
+};
+
+static const struct athn_addac ar9160_1_0_addac = {
+ nitems(ar9160_1_0_addac_vals),
+ ar9160_1_0_addac_vals
+};
+
+static const uint32_t ar9160_1_1_addac_vals[] = {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x000000c0, 0x00000018, 0x00000004, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x000000c0, 0x00000019, 0x00000004, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000
+};
+
+static const struct athn_addac ar9160_1_1_addac = {
+ nitems(ar9160_1_1_addac_vals),
+ ar9160_1_1_addac_vals
+};
+
+static const uint32_t ar5416_bank6tpc_vals[] = {
+ 0x00000000, 0x00000000, 0x00000000, 0x00e00000, 0x005e0000,
+ 0x00120000, 0x00620000, 0x00020000, 0x00ff0000, 0x00ff0000,
+ 0x00ff0000, 0x40ff0000, 0x005f0000, 0x00870000, 0x00f90000,
+ 0x007b0000, 0x00ff0000, 0x00f50000, 0x00dc0000, 0x00110000,
+ 0x006100a8, 0x00423022, 0x201400df, 0x00c40002, 0x003000f2,
+ 0x00440016, 0x00410040, 0x0001805e, 0x0000c0ab, 0x000000e1,
+ 0x00007081, 0x000000d4
+};
+
+static const uint32_t ar9160_bank6tpc_vals[] = {
+ 0x00000000, 0x00000000, 0x00000000, 0x00e00000, 0x005e0000,
+ 0x00120000, 0x00620000, 0x00020000, 0x00ff0000, 0x00ff0000,
+ 0x00ff0000, 0x40ff0000, 0x005f0000, 0x00870000, 0x00f90000,
+ 0x007b0000, 0x00ff0000, 0x00f50000, 0x00dc0000, 0x00110000,
+ 0x006100a8, 0x00423022, 0x2014008f, 0x00c40002, 0x003000f2,
+ 0x00440016, 0x00410040, 0x0001805e, 0x0000c0ab, 0x000000e1,
+ 0x00007080, 0x000000d4
+};
+
+static const uint32_t ar5416_bank6_vals[] = {
+ 0x00000000, 0x00000000, 0x00000000, 0x00e00000, 0x005e0000,
+ 0x00120000, 0x00620000, 0x00020000, 0x00ff0000, 0x00ff0000,
+ 0x00ff0000, 0x40ff0000, 0x005f0000, 0x00870000, 0x00f90000,
+ 0x007b0000, 0x00ff0000, 0x00f50000, 0x00dc0000, 0x00110000,
+ 0x006100a8, 0x004210a2, 0x0014008f, 0x00c40003, 0x003000f2,
+ 0x00440016, 0x00410040, 0x0001805e, 0x0000c0ab, 0x000000f1,
+ 0x00002081, 0x000000d4
+};
+
+/*
+ * Serializer/Deserializer programming.
+ */
+
+static const uint32_t ar5416_serdes_regs[] = {
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES2
+};
+
+static const uint32_t ar5416_serdes_vals[] = {
+ 0x9248fc00,
+ 0x24924924,
+ /* RX shut off when elecidle is asserted. */
+ 0x28000039,
+ 0x53160824,
+ 0xe5980579,
+ 0x001defff,
+ 0x1aaabe40,
+ 0xbe105554,
+ 0x000e3007,
+ 0x00000000
+};
+
+static const struct athn_serdes ar5416_serdes = {
+ nitems(ar5416_serdes_vals),
+ ar5416_serdes_regs,
+ ar5416_serdes_vals,
+};
diff --git a/sys/dev/athn/ic/ar9003reg.h b/sys/dev/athn/ic/ar9003reg.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar9003reg.h
@@ -0,0 +1,1200 @@
+/* $OpenBSD: ar9003reg.h,v 1.9 2017/05/19 11:42:48 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * MAC registers.
+ */
+#define AR_ISR_S2_S 0x00d0
+#define AR_ISR_S3_S 0x00d4
+#define AR_ISR_S4_S 0x00d8
+#define AR_ISR_S5_S 0x00dc
+#define AR_GPIO_IN_OUT 0x4048
+#define AR_GPIO_IN 0x404c
+#define AR9300_GPIO_IN_VAL 0x0001FFFF
+#define AR_GPIO_OE_OUT 0x4050
+#define AR_GPIO_INTR_POL 0x4058
+#define AR_GPIO_INPUT_EN_VAL 0x405c
+#define AR_GPIO_INPUT_MUX1 0x4060
+#define AR_GPIO_INPUT_MUX2 0x4064
+#define AR_GPIO_OUTPUT_MUX(i) (0x4068 + (i) * 4)
+#define AR_INPUT_STATE 0x4074
+#define AR_EEPROM_STATUS_DATA 0x4084
+#define AR_OBS 0x4088
+#define AR_GPIO_PDPU 0x4090
+#define AR_PCIE_MSI 0x40a4
+#define AR_ENT_OTP 0x40d8
+
+/* Bits for AR_ENT_OTP. */
+#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
+#define AR_ENT_OTP_MPSD 0x00800000
+
+/*
+ * PHY registers.
+ */
+#define AR_PHY_TIMING1 0x09800
+#define AR_PHY_TIMING2 0x09804
+#define AR_PHY_TIMING3 0x09808
+#define AR_PHY_TIMING4 0x0980c
+#define AR_PHY_TIMING5 0x09810
+#define AR_PHY_TIMING6 0x09814
+#define AR_PHY_TIMING11 0x09818
+#define AR_PHY_SPUR_REG 0x0981c
+#define AR_PHY_FIND_SIG_LOW 0x09820
+#define AR_PHY_SFCORR 0x09824
+#define AR_PHY_SFCORR_LOW 0x09828
+#define AR_PHY_SFCORR_EXT 0x0982c
+#define AR_PHY_EXT_CCA(i) (0x09830 + (i) * 0x1000)
+#define AR_PHY_RADAR_0 0x09834
+#define AR_PHY_RADAR_1 0x09838
+#define AR_PHY_RADAR_EXT 0x0983c
+#define AR_PHY_MULTICHAIN_CTRL 0x09880
+#define AR_PHY_PERCHAIN_CSD 0x09884
+#define AR_PHY_TX_CRC 0x098a0
+#define AR_PHY_TST_DAC_CONST 0x098a4
+#define AR_PHY_SPUR_REPORT_0 0x098a8
+#define AR_PHY_TX_IQCAL_CONTROL_3 0x098b0
+#define AR_PHY_IQ_ADC_MEAS_0_B(i) (0x098c0 + (i) * 0x1000)
+#define AR_PHY_IQ_ADC_MEAS_1_B(i) (0x098c4 + (i) * 0x1000)
+#define AR_PHY_IQ_ADC_MEAS_2_B(i) (0x098c8 + (i) * 0x1000)
+#define AR_PHY_IQ_ADC_MEAS_3_B(i) (0x098cc + (i) * 0x1000)
+#define AR_PHY_TX_PHASE_RAMP_0 0x098d0
+#define AR_PHY_ADC_DC_GAIN_CORR(i) (0x098d4 + (i) * 0x1000)
+#define AR_PHY_RX_IQCAL_CORR_B(i) (0x098dc + (i) * 0x1000)
+#define AR_PHY_PAPRD_AM2AM 0x098e4
+#define AR_PHY_PAPRD_AM2PM 0x098e8
+#define AR_PHY_PAPRD_HT40 0x098ec
+#define AR_PHY_PAPRD_CTRL0_B(i) (0x098f0 + (i) * 0x1000)
+#define AR_PHY_PAPRD_CTRL1_B(i) (0x098f4 + (i) * 0x1000)
+#define AR_PHY_PA_GAIN123_B(i) (0x098f8 + (i) * 0x1000)
+#define AR_PHY_PAPRD_PRE_POST_SCALE_B0(i) \
+ (0x09900 + (i) * 4)
+#define AR_PHY_PAPRD_MEM_TAB_B(i, j) (0x09920 + (i) * 0x1000 + (j) * 4)
+#define AR_PHY_CHAN_INFO_TAB(i, j) (0x09b00 + (i) * 0x1000 + (j) * 4)
+#define AR_PHY_TIMING_3A 0x09c00
+#define AR_PHY_LDPC_CNTL1 0x09c04
+#define AR_PHY_LDPC_CNTL2 0x09c08
+#define AR_PHY_PILOT_SPUR_MASK 0x09c0c
+#define AR_PHY_CHAN_SPUR_MASK 0x09c10
+#define AR_PHY_SGI_DELTA 0x09c14
+#define AR_PHY_ML_CNTL_1 0x09c18
+#define AR_PHY_ML_CNTL_2 0x09c1c
+#define AR_PHY_TST_ADC 0x09c20
+#define AR_PHY_SETTLING 0x09e00
+#define AR_PHY_RXGAIN(i) (0x09e04 + (i) * 0x1000)
+#define AR_PHY_GAINS_MINOFF0 0x09e08
+#define AR_PHY_DESIRED_SZ 0x09e0c
+#define AR_PHY_FIND_SIG 0x09e10
+#define AR_PHY_AGC 0x09e14
+#define AR_PHY_EXT_ATTEN_CTL(i) (0x09e18 + (i) * 0x1000)
+#define AR_PHY_CCA(i) (0x09e1c + (i) * 0x1000)
+#define AR_PHY_CCA_CTRL(i) (0x09e20 + (i) * 0x1000)
+#define AR_PHY_RESTART 0x09e24
+#define AR_PHY_MC_GAIN_CTRL 0x09e28
+#define AR_PHY_EXTCHN_PWRTHR1 0x09e2c
+#define AR_PHY_EXT_CHN_WIN 0x09e30
+#define AR_PHY_20_40_DET_THR 0x09e34
+#define AR_PHY_RIFS_SRCH 0x09e38
+#define AR_PHY_PEAK_DET_CTRL_1 0x09e3c
+#define AR_PHY_PEAK_DET_CTRL_2 0x09e40
+#define AR_PHY_RX_GAIN_BOUNDS_1 0x09e44
+#define AR_PHY_RX_GAIN_BOUNDS_2 0x09e48
+#define AR_PHY_RSSI(i) (0x09f80 + (i) * 0x1000)
+#define AR_PHY_SPUR_CCK_REP0 0x09f84
+#define AR_PHY_CCK_DETECT 0x09fc0
+#define AR_PHY_DAG_CTRLCCK 0x09fc4
+#define AR_PHY_IQCORR_CTRL_CCK 0x09fc8
+#define AR_PHY_CCK_SPUR_MIT 0x09fcc
+#define AR_PHY_RX_OCGAIN 0x0a000
+#define AR_PHY_D2_CHIP_ID 0x0a200
+#define AR_PHY_GEN_CTRL 0x0a204
+#define AR_PHY_MODE 0x0a208
+#define AR_PHY_ACTIVE 0x0a20c
+#define AR_PHY_SPUR_MASK_A 0x0a220
+#define AR_PHY_SPUR_MASK_B 0x0a224
+#define AR_PHY_SPECTRAL_SCAN 0x0a228
+#define AR_PHY_RADAR_BW_FILTER 0x0a22c
+#define AR_PHY_SEARCH_START_DELAY 0x0a230
+#define AR_PHY_MAX_RX_LEN 0x0a234
+#define AR_PHY_FRAME_CTL 0x0a238
+#define AR_PHY_RFBUS_REQ 0x0a23c
+#define AR_PHY_RFBUS_GRANT 0x0a240
+#define AR_PHY_RIFS 0x0a244
+#define AR_PHY_RX_CLR_DELAY 0x0a250
+#define AR_PHY_RX_DELAY 0x0a254
+#define AR_PHY_XPA_TIMING_CTL 0x0a264
+#define AR_PHY_MISC_PA_CTL 0x0a280
+#define AR_PHY_SWITCH_CHAIN(i) (0x0a284 + (i) * 0x1000)
+#define AR_PHY_SWITCH_COM 0x0a288
+#define AR_PHY_SWITCH_COM_2 0x0a28c
+#define AR_PHY_RX_CHAINMASK 0x0a2a0
+#define AR_PHY_CAL_CHAINMASK 0x0a2c0
+#define AR_PHY_AGC_CONTROL 0x0a2c4
+#define AR_PHY_CALMODE 0x0a2c8
+#define AR_PHY_FCAL_1 0x0a2cc
+#define AR_PHY_FCAL_2_0 0x0a2d0
+#define AR_PHY_DFT_TONE_CTL_0 0x0a2d4
+#define AR_PHY_CL_CAL_CTL 0x0a2d8
+#define AR_PHY_CL_TAB_0 0x0a300
+#define AR_PHY_SYNTH_CONTROL 0x0a340
+#define AR_PHY_ADDAC_CLK_SEL 0x0a344
+#define AR_PHY_PLL_CTL 0x0a348
+#define AR_PHY_ANALOG_SWAP 0x0a34c
+#define AR_PHY_ADDAC_PARA_CTL 0x0a350
+#define AR_PHY_XPA_CFG 0x0a358
+#define AR_PHY_TEST 0x0a360
+#define AR_PHY_TEST_CTL_STATUS 0x0a364
+#define AR_PHY_TSTDAC 0x0a368
+#define AR_PHY_CHAN_STATUS 0x0a36c
+#define AR_PHY_CHAN_INFO_MEMORY 0x0a370
+#define AR_PHY_CHNINFO_NOISEPWR 0x0a374
+#define AR_PHY_CHNINFO_GAINDIFF 0x0a378
+#define AR_PHY_CHNINFO_FINETIM 0x0a37c
+#define AR_PHY_CHAN_INFO_GAIN_0 0x0a380
+#define AR_PHY_SCRAMBLER_SEED 0x0a390
+#define AR_PHY_CCK_TX_CTRL 0x0a394
+#define AR_PHY_HEAVYCLIP_CTL 0x0a3a4
+#define AR_PHY_HEAVYCLIP_20 0x0a3a8
+#define AR_PHY_HEAVYCLIP_40 0x0a3ac
+#define AR_PHY_ILLEGAL_TXRATE 0x0a3b0
+#define AR_PHY_PWRTX_RATE1 0x0a3c0
+#define AR_PHY_PWRTX_RATE2 0x0a3c4
+#define AR_PHY_PWRTX_RATE3 0x0a3c8
+#define AR_PHY_PWRTX_RATE4 0x0a3cc
+#define AR_PHY_PWRTX_RATE5 0x0a3d0
+#define AR_PHY_PWRTX_RATE6 0x0a3d4
+#define AR_PHY_PWRTX_RATE7 0x0a3d8
+#define AR_PHY_PWRTX_RATE8 0x0a3dc
+#define AR_PHY_PWRTX_RATE10 0x0a3e4
+#define AR_PHY_PWRTX_RATE11 0x0a3e8
+#define AR_PHY_PWRTX_RATE12 0x0a3ec
+#define AR_PHY_PWRTX_MAX 0x0a3f0
+#define AR_PHY_POWER_TX_SUB 0x0a3f4
+#define AR_PHY_TPC_1 0x0a3f8
+#define AR_PHY_TPC_4_B(i) (0x0a404 + (i) * 0x1000)
+#define AR_PHY_TPC_5_B(i) (0x0a408 + (i) * 0x1000)
+#define AR_PHY_TPC_6_B(i) (0x0a40c + (i) * 0x1000)
+#define AR_PHY_TPC_11_B(i) (0x0a420 + (i) * 0x1000)
+#define AR_PHY_TPC_12 0x0a424
+#define AR_PHY_TPC_18 0x0a43c
+#define AR_PHY_TPC_19 0x0a440
+#define AR_PHY_BB_THERM_ADC_1 0x0a448
+#define AR_PHY_BB_THERM_ADC_4 0x0a454
+#define AR_PHY_TX_FORCED_GAIN 0x0a458
+#define AR_PHY_PDADC_TAB(i) (0x0a480 + (i) * 0x1000)
+#define AR_PHY_TXGAIN_TABLE(i) (0x0a500 + (i) * 4)
+#define AR_PHY_TX_IQCAL_CONTROL_1 0x0a648
+#define AR_PHY_TX_IQCAL_START 0x0a640
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B(i) \
+ (0x0a650 + (i) * 0x1000)
+#define AR_PHY_TX_IQCAL_STATUS_B(i) (0x0a68c + (i) * 0x1000)
+#define AR_PHY_PAPRD_TRAINER_CNTL1 0x0a690
+#define AR_PHY_PAPRD_TRAINER_CNTL2 0x0a694
+#define AR_PHY_PAPRD_TRAINER_CNTL3 0x0a698
+#define AR_PHY_PAPRD_TRAINER_CNTL4 0x0a69c
+#define AR_PHY_PAPRD_TRAINER_STAT1 0x0a6a0
+#define AR_PHY_PAPRD_TRAINER_STAT2 0x0a6a4
+#define AR_PHY_PAPRD_TRAINER_STAT3 0x0a6a8
+#define AR_PHY_PANIC_WD_STATUS 0x0a7c0
+#define AR_PHY_PANIC_WD_CTL_1 0x0a7c4
+#define AR_PHY_PANIC_WD_CTL_2 0x0a7c8
+#define AR_PHY_BT_CTL 0x0a7cc
+#define AR_PHY_ONLY_WARMRESET 0x0a7d0
+#define AR_PHY_ONLY_CTL 0x0a7d4
+#define AR_PHY_ECO_CTRL 0x0a7dc
+
+/*
+ * Analog registers.
+ */
+#define AR_IS_ANALOG_REG(reg) ((reg) >= 0x16000 && (reg) <= 0x17000)
+#define AR_PHY_65NM_CH0_SYNTH4 0x1608c
+#define AR_PHY_65NM_CH0_SYNTH7 0x16098
+#define AR_PHY_65NM_CH0_BIAS1 0x160c0
+#define AR_PHY_65NM_CH0_BIAS2 0x160c4
+#define AR_PHY_65NM_CH0_BIAS4 0x160cc
+#define AR_PHY_65NM_CH0_RXTX1 0x16100
+#define AR_PHY_65NM_CH0_RXTX2 0x16104
+#define AR_PHY_65NM_CH0_RXTX4 0x1610c
+#define AR9485_PHY_65NM_CH0_TOP2 0x16284
+#define AR_PHY_65NM_CH0_TOP 0x16288
+#define AR_PHY_65NM_CH0_THERM 0x16290
+#define AR9485_PHY_CH0_XTAL 0x16290
+#define AR_PHY_65NM_CH1_RXTX1 0x16500
+#define AR_PHY_65NM_CH1_RXTX2 0x16504
+#define AR_PHY_65NM_CH2_RXTX1 0x16900
+#define AR_PHY_65NM_CH2_RXTX2 0x16904
+#define AR_PHY_PMU1 0x16c40
+#define AR_PHY_PMU2 0x16c44
+
+
+/* Bits for AR_PHY_TIMING2. */
+#define AR_PHY_TIMING2_FORCE_PPM_VAL_M 0x00000fff
+#define AR_PHY_TIMING2_FORCE_PPM_VAL_S 0
+#define AR_PHY_TIMING2_USE_FORCE_PPM 0x00001000
+
+/* Bits for AR_PHY_TIMING3. */
+#define AR_PHY_TIMING3_DSC_EXP_M 0x0001e000
+#define AR_PHY_TIMING3_DSC_EXP_S 13
+#define AR_PHY_TIMING3_DSC_MAN_M 0xfffe0000
+#define AR_PHY_TIMING3_DSC_MAN_S 17
+
+/* Bits for AR_PHY_TIMING4. */
+#define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX_M 0x0000f000
+#define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX_S 12
+#define AR_PHY_TIMING4_DO_CAL 0x00010000
+#define AR_PHY_TIMING4_ENABLE_PILOT_MASK 0x10000000
+#define AR_PHY_TIMING4_ENABLE_CHAN_MASK 0x20000000
+#define AR_PHY_TIMING4_ENABLE_SPUR_FILTER 0x40000000
+#define AR_PHY_TIMING4_ENABLE_SPUR_RSSI 0x80000000
+
+/* Bits for AR_PHY_TIMING5. */
+#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE 0x00000001
+#define AR_PHY_TIMING5_CYCPWR_THR1_M 0x000000fe
+#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
+#define AR_PHY_TIMING5_RSSI_THR1A_ENA 0x00008000
+#define AR_PHY_TIMING5_CYCPWR_THR1A_M 0x007f0000
+#define AR_PHY_TIMING5_CYCPWR_THR1A_S 16
+#define AR_PHY_TIMING5_RSSI_THR1A_M 0x007f0000
+#define AR_PHY_TIMING5_RSSI_THR1A_S 16
+
+/* Bits for AR_PHY_TIMING11. */
+#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_M 0x000fffff
+#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
+#define AR_PHY_TIMING11_SPUR_FREQ_SD_M 0x3ff00000
+#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
+#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC 0x40000000
+#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR 0x80000000
+
+/* Bits for AR_PHY_SPUR_REG. */
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_M 0x000000ff
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
+#define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI 0x00000100
+#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x00020000
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_M 0x03fc0000
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
+#define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT 0x04000000
+
+/* Bits for AR_PHY_FIND_SIG_LOW. */
+#define AR_PHY_FIND_SIG_LOW_RELSTEP_M 0x0000001f
+#define AR_PHY_FIND_SIG_LOW_RELSTEP_S 0
+#define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW_M 0x00000fc0
+#define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW_S 6
+#define AR_PHY_FIND_SIG_LOW_FIRPWR_M 0x0007f000
+#define AR_PHY_FIND_SIG_LOW_FIRPWR_S 12
+
+/* Bits for AR_PHY_SFCORR. */
+#define AR_PHY_SFCORR_M2COUNT_THR_M 0x0000001f
+#define AR_PHY_SFCORR_M2COUNT_THR_S 0
+#define AR_PHY_SFCORR_M1_THRESH_M 0x00fe0000
+#define AR_PHY_SFCORR_M1_THRESH_S 17
+#define AR_PHY_SFCORR_M2_THRESH_M 0x7f000000
+#define AR_PHY_SFCORR_M2_THRESH_S 24
+
+/* Bits for AR_PHY_SFCORR_LOW. */
+#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_M 0x00003f00
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_M 0x001fc000
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_M 0x0fe00000
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
+
+/* Bits for AR_PHY_SFCORR_EXT. */
+#define AR_PHY_SFCORR_EXT_M1_THRESH_M 0x0000007f
+#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
+#define AR_PHY_SFCORR_EXT_M2_THRESH_M 0x00003f80
+#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_M 0x001fc000
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_M 0x0fe00000
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
+#define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD 0x10000000
+
+/* Bits for AR_PHY_RADAR_0. */
+#define AR_PHY_RADAR_0_ENA 0x00000001
+#define AR_PHY_RADAR_0_INBAND_M 0x0000003e
+#define AR_PHY_RADAR_0_INBAND_S 1
+#define AR_PHY_RADAR_0_PRSSI_M 0x00000fc0
+#define AR_PHY_RADAR_0_PRSSI_S 6
+#define AR_PHY_RADAR_0_HEIGHT_M 0x0003f000
+#define AR_PHY_RADAR_0_HEIGHT_S 12
+#define AR_PHY_RADAR_0_RRSSI_M 0x00fc0000
+#define AR_PHY_RADAR_0_RRSSI_S 18
+#define AR_PHY_RADAR_0_FIRPWR_M 0x7f000000
+#define AR_PHY_RADAR_0_FIRPWR_S 24
+#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
+
+/* Bits for AR_PHY_RADAR_1. */
+#define AR_PHY_RADAR_1_MAXLEN_M 0x000000ff
+#define AR_PHY_RADAR_1_MAXLEN_S 0
+#define AR_PHY_RADAR_1_RELSTEP_THRESH_M 0x00001f00
+#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
+#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
+#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
+#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
+#define AR_PHY_RADAR_1_RELPWR_THRESH_M 0x003f0000
+#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
+#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
+#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
+
+/* Bits for AR_PHY_RADAR_EXT. */
+#define AR_PHY_RADAR_EXT_ENA 0x00004000
+#define AR_PHY_RADAR_DC_PWR_THRESH_M 0x007f8000
+#define AR_PHY_RADAR_DC_PWR_THRESH_S 15
+#define AR_PHY_RADAR_LB_DC_CAP_M 0x7f800000
+#define AR_PHY_RADAR_LB_DC_CAP_S 23
+
+/* Bits for AR_PHY_TX_IQCAL_CONTROL_3. */
+#define AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN 0x80000000
+
+/* Bits for AR_PHY_RX_IQCAL_CORR_B(0). */
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF_M 0x0000007f
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF_S 0
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF_M 0x00003f80
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF_S 7
+#define AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE 0x00004000
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF_M 0x003f8000
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF_S 15
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF_M 0x1fc00000
+#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF_S 22
+#define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN 0x20000000
+
+/* Bits for AR_PHY_PAPRD_AM2AM. */
+#define AR_PHY_PAPRD_AM2AM_MASK_M 0x01ffffff
+#define AR_PHY_PAPRD_AM2AM_MASK_S 0
+
+/* Bits for AR_PHY_PAPRD_AM2PM. */
+#define AR_PHY_PAPRD_AM2PM_MASK_M 0x01ffffff
+#define AR_PHY_PAPRD_AM2PM_MASK_S 0
+
+/* Bits for AR_PHY_PAPRD_HT40. */
+#define AR_PHY_PAPRD_HT40_MASK_M 0x01ffffff
+#define AR_PHY_PAPRD_HT40_MASK_S 0
+
+/* Bits for AR_PHY_PAPRD_CTRL0_B(i). */
+#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE 0x00000001
+#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE 0x00000002
+#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH_M 0xf8000000
+#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH_S 27
+
+/* Bits for AR_PHY_PAPRD_CTRL1_B(i). */
+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA 0x00000001
+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENA 0x00000002
+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENA 0x00000004
+#define AR_PHY_PAPRD_CTRL1_POWER_AT_AM2AM_CAL_M 0x000001f8
+#define AR_PHY_PAPRD_CTRL1_POWER_AT_AM2AM_CAL_S 3
+#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_M 0x0001fe00
+#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_S 9
+#define AR_PHY_PAPRD_CTRL1_MAG_SCALE_FACT_M 0x0ffe0000
+#define AR_PHY_PAPRD_CTRL1_MAG_SCALE_FACT_S 17
+
+/* Bits for AR_PHY_PA_GAIN123_B(i). */
+#define AR_PHY_PA_GAIN123_PA_GAIN1_M 0x000003ff
+#define AR_PHY_PA_GAIN123_PA_GAIN1_S 0
+
+/* Bits for AR_PHY_PAPRD_PRE_POST_SCALE_B0(i). */
+#define AR_PHY_PAPRD_PRE_POST_SCALING_M 0x0003ffff
+#define AR_PHY_PAPRD_PRE_POST_SCALING_S 0
+
+/* Bits for AR_PHY_PAPRD_MEM_TAB_B(i). */
+#define AR_PHY_PAPRD_ANGLE_M 0x000007ff
+#define AR_PHY_PAPRD_ANGLE_S 0
+#define AR_PHY_PAPRD_PA_IN_M 0x003ff800
+#define AR_PHY_PAPRD_PA_IN_S 11
+
+/* Bits for AR_PHY_PILOT_SPUR_MASK. */
+#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_M 0x0000001f
+#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_S 0
+#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_M 0x00000fe0
+#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_S 5
+
+/* Bits for AR_PHY_CHAN_SPUR_MASK. */
+#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A_M 0x0000001f
+#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A_S 0
+#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_M 0x00000fe0
+#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_S 5
+
+/* Bits for AR_PHY_SGI_DELTA. */
+#define AR_PHY_SGI_DSC_EXP_M 0x0000000f
+#define AR_PHY_SGI_DSC_EXP_S 0
+#define AR_PHY_SGI_DSC_MAN_M 0x0007fff0
+#define AR_PHY_SGI_DSC_MAN_S 4
+
+/* Bits for AR_PHY_SETTLING. */
+#define AR_PHY_SETTLING_SWITCH_M 0x00003f80
+#define AR_PHY_SETTLING_SWITCH_S 7
+
+/* Bits for AR_PHY_RXGAIN(i). */
+#define AR_PHY_RXGAIN_TXRX_ATTEN_M 0x0003f000
+#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
+#define AR_PHY_RXGAIN_TXRX_RF_MAX_M 0x007c0000
+#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
+
+/* Bits for AR_PHY_DESIRED_SZ. */
+#define AR_PHY_DESIRED_SZ_ADC_M 0x000000ff
+#define AR_PHY_DESIRED_SZ_ADC_S 0
+#define AR_PHY_DESIRED_SZ_PGA_M 0x0000ff00
+#define AR_PHY_DESIRED_SZ_PGA_S 8
+#define AR_PHY_DESIRED_SZ_TOT_DES_M 0x0ff00000
+#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
+
+/* Bits for AR_PHY_FIND_SIG. */
+#define AR_PHY_FIND_SIG_RELSTEP_M 0x0000001f
+#define AR_PHY_FIND_SIG_RELSTEP_S 0
+#define AR_PHY_FIND_SIG_RELPWR_M 0x000007c0
+#define AR_PHY_FIND_SIG_RELPWR_S 6
+#define AR_PHY_FIND_SIG_FIRSTEP_M 0x0003f000
+#define AR_PHY_FIND_SIG_FIRSTEP_S 12
+#define AR_PHY_FIND_SIG_FIRPWR_M 0x03fc0000
+#define AR_PHY_FIND_SIG_FIRPWR_S 18
+
+/* Bits for AR_PHY_AGC. */
+#define AR_PHY_AGC_COARSE_PWR_CONST_M 0x0000007f
+#define AR_PHY_AGC_COARSE_PWR_CONST_S 0
+#define AR_PHY_AGC_COARSE_LOW_M 0x00007f80
+#define AR_PHY_AGC_COARSE_LOW_S 7
+#define AR_PHY_AGC_COARSE_HIGH_M 0x003f8000
+#define AR_PHY_AGC_COARSE_HIGH_S 15
+
+/* Bits for AR_PHY_EXT_ATTEN_CTL(i). */
+#define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN_M 0x0000001f
+#define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN_S 0
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB_M 0x0000003f
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB_S 0
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB_M 0x00000fc0
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB_S 6
+#define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN_M 0x00003c00
+#define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN_S 10
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN_M 0x0001f000
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN_S 12
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN_M 0x003e0000
+#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN_S 17
+#define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN_M 0x00fc0000
+#define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN_S 18
+
+/* Bits for AR_PHY_CCA(i). */
+#define AR_PHY_MAXCCA_PWR_M 0x000001ff
+#define AR_PHY_MAXCCA_PWR_S 0
+#define AR_PHY_MINCCA_PWR_M 0x1ff00000
+#define AR_PHY_MINCCA_PWR_S 20
+
+/* Bits for AR_PHY_EXT_CCA(i). */
+#define AR_PHY_EXT_MAXCCA_PWR_M 0x000001ff
+#define AR_PHY_EXT_MAXCCA_PWR_S 0
+#define AR_PHY_EXT_MINCCA_PWR_M 0x01ff0000
+#define AR_PHY_EXT_MINCCA_PWR_S 16
+
+/* Bits for AR_PHY_RESTART. */
+#define AR_PHY_RESTART_ENA 0x00000001
+#define AR_PHY_RESTART_DIV_GC_M 0x001c0000
+#define AR_PHY_RESTART_DIV_GC_S 18
+
+/* Bits for AR_PHY_MC_GAIN_CTRL. */
+#define AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV 0x01000000
+#define AR_PHY_MC_GAIN_CTRL_ANT_DIV_CTRL_ALL_M 0x7e000000
+#define AR_PHY_MC_GAIN_CTRL_ANT_DIV_CTRL_ALL_S 25
+
+/* Bits for AR_PHY_CCK_DETECT. */
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_M 0x0000003f
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_M 0x00001fc0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x00002000
+
+/* Bits for AR_PHY_DAG_CTRLCCK. */
+#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR_M 0x0001fc00
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
+
+/* Bits for AR_PHY_CCK_SPUR_MIT. */
+#define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT 0x00000001
+#define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR_M 0x000001fe
+#define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR_S 1
+#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ_M 0x1ffffe00
+#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ_S 9
+#define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE_M 0x60000000
+#define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE_S 29
+
+/* Bits for AR_PHY_GEN_CTRL. */
+#define AR_PHY_GC_TURBO_MODE 0x00000001
+#define AR_PHY_GC_TURBO_SHORT 0x00000002
+#define AR_PHY_GC_DYN2040_EN 0x00000004
+#define AR_PHY_GC_DYN2040_PRI_ONLY 0x00000008
+#define AR_PHY_GC_DYN2040_PRI_CH 0x00000010
+#define AR_PHY_GC_DYN2040_EXT_CH 0x00000020
+#define AR_PHY_GC_HT_EN 0x00000040
+#define AR_PHY_GC_SHORT_GI_40 0x00000080
+#define AR_PHY_GC_WALSH 0x00000100
+#define AR_PHY_GC_SINGLE_HT_LTF1 0x00000200
+#define AR_PHY_GC_GF_DETECT_EN 0x00000400
+#define AR_PHY_GC_ENABLE_DAC_FIFO 0x00000800
+
+/* Bits for AR_PHY_MODE. */
+#define AR_PHY_MODE_OFDM 0x00000000
+#define AR_PHY_MODE_CCK 0x00000001
+#define AR_PHY_MODE_DYNAMIC 0x00000004
+#define AR_PHY_MODE_HALF 0x00000020
+#define AR_PHY_MODE_QUARTER 0x00000040
+#define AR_PHY_MODE_DYN_CCK_DISABLE 0x00000100
+#define AR_PHY_MODE_SVD_HALF 0x00000200
+
+/* Bits for AR_PHY_ACTIVE. */
+#define AR_PHY_ACTIVE_DIS 0x00000000
+#define AR_PHY_ACTIVE_EN 0x00000001
+
+/* Bits for AR_PHY_SPUR_MASK_A. */
+#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A_M 0x000003ff
+#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A_S 0
+#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_M 0x0001fc00
+#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S 10
+
+/* Bits for AR_PHY_SPECTRAL_SCAN. */
+#define AR_PHY_SPECTRAL_SCAN_ENABLE 0x00000001
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_M 0x000000f0
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4
+#define AR_PHY_SPECTRAL_SCAN_PERIOD_M 0x0000ff00
+#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8
+#define AR_PHY_SPECTRAL_SCAN_COUNT_M 0x00ff0000
+#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000
+
+/* Bits for AR_PHY_RFBUS_REQ. */
+#define AR_PHY_RFBUS_REQ_EN 0x00000001
+
+/* Bits for AR_PHY_RFBUS_GRANT. */
+#define AR_PHY_RFBUS_GRANT_EN 0x00000001
+
+/* Bits for AR_PHY_RIFS. */
+#define AR_PHY_RIFS_INIT_DELAY 0x3ff0000
+
+/* Bits for AR_PHY_RX_DELAY. */
+#define AR_PHY_RX_DELAY_DELAY_M 0x00003fff
+#define AR_PHY_RX_DELAY_DELAY_S 0
+
+/* Bits for AR_PHY_XPA_TIMING_CTL. */
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON_M 0x000000ff
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON_S 0
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON_M 0x0000ff00
+#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON_S 8
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF_M 0x00ff0000
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF_S 16
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF_M 0xff000000
+#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF_S 24
+
+/* Bits for AR_PHY_SWITCH_CHAIN. */
+#define AR_SWITCH_TABLE_ALL_M 0x00000fff
+#define AR_SWITCH_TABLE_ALL_S 0
+
+/* Bits for AR_PHY_SWITCH_COM. */
+#define AR_SWITCH_TABLE_COM_ALL_M 0x0000ffff
+#define AR_SWITCH_TABLE_COM_ALL_S 0
+
+/* Bits for AR_SWITCH_TABLE_COM_2. */
+#define AR_SWITCH_TABLE_COM_2_ALL_M 0x00ffffff
+#define AR_SWITCH_TABLE_COM_2_ALL_S 0
+
+/* Bits for AR_PHY_AGC_CONTROL. */
+#define AR_PHY_AGC_CONTROL_CAL 0x00000001
+#define AR_PHY_AGC_CONTROL_NF 0x00000002
+#define AR_PHY_AGC_CONTROL_YCOK_MAX_M 0x000003c0
+#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6
+#define AR_PHY_AGC_CONTROL_OFFSET_CAL 0x00000800
+#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000
+#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000
+#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
+#define AR_PHY_AGC_CONTROL_EXT_NF_PWR_MEAS 0x00040000
+#define AR_PHY_AGC_CONTROL_CLC_SUCCESS 0x00080000
+
+/* Bits for AR_PHY_CALMODE. */
+#define AR_PHY_CALMODE_IQ 0x00000000
+#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
+#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
+#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
+
+/* Bits for AR_PHY_FCAL_2_0. */
+#define AR_PHY_FCAL20_CAP_STATUS_0_M 0x01f00000
+#define AR_PHY_FCAL20_CAP_STATUS_0_S 20
+
+/* Bits for AR_PHY_SYNTH_CONTROL. */
+#define AR9380_BMODE 0x20000000
+
+/* Bits for AR_PHY_ANALOG_SWAP. */
+#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
+
+/* Bits for AR_PHY_ADDAC_PARA_CTL. */
+#define AR_PHY_ADDAC_PARACTL_OFF_PWDADC 0x00008000
+
+/* Bits for AR_PHY_TEST. */
+#define AR_PHY_TEST_RFSILENT_BB 0x00002000
+#define AR_PHY_TEST_BBB_OBS_SEL_M 0x00780000
+#define AR_PHY_TEST_BBB_OBS_SEL_S 19
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5 0x00800000
+#define AR_PHY_TEST_CHAIN_SEL_M 0xc0000000
+#define AR_PHY_TEST_CHAIN_SEL_S 30
+
+/* Bits for AR_PHY_TEST_CTL_STATUS. */
+#define AR_PHY_TEST_CTL_TSTDAC_EN 0x00000001
+#define AR_PHY_TEST_CTL_TX_OBS_SEL_M 0x0000001c
+#define AR_PHY_TEST_CTL_TX_OBS_SEL_S 2
+#define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL_M 0x00000060
+#define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL_S 5
+#define AR_PHY_TEST_CTL_TSTADC_EN 0x00000100
+#define AR_PHY_TEST_CTL_RX_OBS_SEL_M 0x00003c00
+#define AR_PHY_TEST_CTL_RX_OBS_SEL_S 10
+
+/* Bits for AR_PHY_CHAN_INFO_MEMORY. */
+#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x00000001
+#define AR_PHY_CHAN_INFO_TAB_S2_READ 0x00000008
+
+/* Bits for AR_PHY_CHAN_INFO_GAIN_0. */
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_MASK 0x00000fff
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
+
+/* Bits for AR_PHY_CCK_TX_CTRL. */
+#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
+
+/* Bits for AR_PHY_PWRTX_RATE5. */
+#define AR_PHY_PWRTX_RATE5_POWERTXHT20_0_M 0x0000003f
+#define AR_PHY_PWRTX_RATE5_POWERTXHT20_0_S 0
+
+/* Bits for AR_PHY_PWRTX_MAX. */
+#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
+
+/* Bits for AR_PHY_TPC_1. */
+#define AR_PHY_TPC_1_FORCE_DAC_GAIN 0x00000001
+#define AR_PHY_TPC_1_FORCED_DAC_GAIN_M 0x0000003e
+#define AR_PHY_TPC_1_FORCED_DAC_GAIN_S 1
+
+/* Bits for AR_PHY_TPC_5_B(i). */
+#define AR_PHY_TPC_5_PD_GAIN_OVERLAP_M 0x0000000f
+#define AR_PHY_TPC_5_PD_GAIN_OVERLAP_S 0
+#define AR_PHY_TPC_5_PD_GAIN_BOUNDARY_1_M 0x000003f0
+#define AR_PHY_TPC_5_PD_GAIN_BOUNDARY_1_S 4
+#define AR_PHY_TPC_5_PD_GAIN_BOUNDARY_2_M 0x0000fc00
+#define AR_PHY_TPC_5_PD_GAIN_BOUNDARY_2_S 10
+#define AR_PHY_TPC_5_PD_GAIN_BOUNDARY_3_M 0x003f0000
+#define AR_PHY_TPC_5_PD_GAIN_BOUNDARY_3_S 16
+#define AR_PHY_TPC_5_PD_GAIN_BOUNDARY_4_M 0x0fc00000
+#define AR_PHY_TPC_5_PD_GAIN_BOUNDARY_4_S 22
+
+/* Bits for AR_PHY_TPC_6_B(i). */
+#define AR_PHY_TPC_6_ERROR_EST_MODE_M 0x03000000
+#define AR_PHY_TPC_6_ERROR_EST_MODE_S 24
+
+/* Bits for AR_PHY_TPC_11_B(i). */
+#define AR_PHY_TPC_11_OLPC_GAIN_DELTA_M 0x00ff0000
+#define AR_PHY_TPC_11_OLPC_GAIN_DELTA_S 16
+#define AR_PHY_TPC_11_OLPC_GAIN_DELTA_PAL_ON_M 0xff000000
+#define AR_PHY_TPC_11_OLPC_GAIN_DELTA_PAL_ON_S 24
+
+/* Bits for AR_PHY_TPC_12. */
+#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5_M 0x3e000000
+#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5_S 25
+
+/* Bits for AR_PHY_TPC_18. */
+#define AR_PHY_TPC_18_THERM_CAL_M 0x000000ff
+#define AR_PHY_TPC_18_THERM_CAL_S 0
+#define AR_PHY_TPC_18_VOLT_CAL_M 0x0000ff00
+#define AR_PHY_TPC_18_VOLT_CAL_S 8
+
+/* Bits for AR_PHY_TPC_19. */
+#define AR_PHY_TPC_19_ALPHA_THERM_M 0x000000ff
+#define AR_PHY_TPC_19_ALPHA_THERM_S 0
+#define AR_PHY_TPC_19_ALPHA_VOLT_M 0x001f0000
+#define AR_PHY_TPC_19_ALPHA_VOLT_S 16
+
+/* Bits for AR_PHY_BB_THERM_ADC_1. */
+#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_M 0x000000ff
+#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0
+
+/* Bits for AR_PHY_BB_THERM_ADC_4. */
+#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_M 0x000000ff
+#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_S 0
+#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_M 0x0000ff00
+#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_S 8
+
+/* Bits for AR_PHY_TX_FORCED_GAIN. */
+#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN 0x00000001
+#define AR_PHY_TX_FORCED_GAIN_TXBB1DBGAIN_M 0x0000000e
+#define AR_PHY_TX_FORCED_GAIN_TXBB1DBGAIN_S 1
+#define AR_PHY_TX_FORCED_GAIN_TXBB6DBGAIN_M 0x00000030
+#define AR_PHY_TX_FORCED_GAIN_TXBB6DBGAIN_S 4
+#define AR_PHY_TX_FORCED_GAIN_TXMXRGAIN_M 0x000003c0
+#define AR_PHY_TX_FORCED_GAIN_TXMXRGAIN_S 6
+#define AR_PHY_TX_FORCED_GAIN_PADRVGNA_M 0x00003c00
+#define AR_PHY_TX_FORCED_GAIN_PADRVGNA_S 10
+#define AR_PHY_TX_FORCED_GAIN_PADRVGNB_M 0x0003c000
+#define AR_PHY_TX_FORCED_GAIN_PADRVGNB_S 14
+#define AR_PHY_TX_FORCED_GAIN_PADRVGNC_M 0x003c0000
+#define AR_PHY_TX_FORCED_GAIN_PADRVGNC_S 18
+#define AR_PHY_TX_FORCED_GAIN_PADRVGND_M 0x00c00000
+#define AR_PHY_TX_FORCED_GAIN_PADRVGND_S 22
+#define AR_PHY_TX_FORCED_GAIN_ENABLE_PAL 0x01000000
+
+/* Bits for AR_PHY_TXGAIN_TABLE(i). */
+#define AR_PHY_TXGAIN_TXBB1DBGAIN_M 0x00000007
+#define AR_PHY_TXGAIN_TXBB1DBGAIN_S 0
+#define AR_PHY_TXGAIN_TXBB6DBGAIN_M 0x00000018
+#define AR_PHY_TXGAIN_TXBB6DBGAIN_S 3
+#define AR_PHY_TXGAIN_TXMXRGAIN_M 0x000001e0
+#define AR_PHY_TXGAIN_TXMXRGAIN_S 5
+#define AR_PHY_TXGAIN_PADRVGNA_M 0x00001e00
+#define AR_PHY_TXGAIN_PADRVGNA_S 9
+#define AR_PHY_TXGAIN_PADRVGNB_M 0x0001e000
+#define AR_PHY_TXGAIN_PADRVGNB_S 13
+#define AR_PHY_TXGAIN_PADRVGNC_M 0x001e0000
+#define AR_PHY_TXGAIN_PADRVGNC_S 17
+#define AR_PHY_TXGAIN_PADRVGND_M 0x00600000
+#define AR_PHY_TXGAIN_PADRVGND_S 21
+#define AR_PHY_TXGAIN_INDEX_M 0xff000000
+#define AR_PHY_TXGAIN_INDEX_S 24
+
+/* Bits for AR_PHY_TX_IQCAL_CONTROL_1. */
+#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_M 0x01fc0000
+#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
+
+/* Bits for AR_PHY_TX_IQCAL_START. */
+#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
+
+/* Bits for AR_PHY_TX_IQCAL_CORR_COEFF_01_B(i). */
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_M 0x00003fff
+#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0
+
+/* Bits for AR_PHY_TX_IQCAL_STATUS_B(i). */
+#define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001
+
+/* Bits for AR_PHY_PAPRD_TRAINER_CNTL1. */
+#define AR_PHY_PAPRD_TRAINER_CNTL1_TRAIN_ENABLE 0x00000001
+#define AR_PHY_PAPRD_TRAINER_CNTL1_AGC2_SETTLING_M 0x0000007e
+#define AR_PHY_PAPRD_TRAINER_CNTL1_AGC2_SETTLING_S 1
+#define AR_PHY_PAPRD_TRAINER_CNTL1_IQCORR_ENABLE 0x00000100
+#define AR_PHY_PAPRD_TRAINER_CNTL1_RX_BB_GAIN_FORCE 0x00000200
+#define AR_PHY_PAPRD_TRAINER_CNTL1_TX_GAIN_FORCE 0x00000400
+#define AR_PHY_PAPRD_TRAINER_CNTL1_LB_ENABLE 0x00000800
+#define AR_PHY_PAPRD_TRAINER_CNTL1_LB_SKIP_M 0x0003f000
+#define AR_PHY_PAPRD_TRAINER_CNTL1_LB_SKIP_S 12
+
+/* Bits for AR_PHY_PAPRD_TRAINER_CNTL3. */
+#define AR_PHY_PAPRD_TRAINER_CNTL3_ADC_DESIRED_SIZE_M 0x0000003f
+#define AR_PHY_PAPRD_TRAINER_CNTL3_ADC_DESIRED_SIZE_S 0
+#define AR_PHY_PAPRD_TRAINER_CNTL3_QUICK_DROP_M 0x00000fc0
+#define AR_PHY_PAPRD_TRAINER_CNTL3_QUICK_DROP_S 6
+#define AR_PHY_PAPRD_TRAINER_CNTL3_MIN_LOOPBACK_DEL_M 0x0001f000
+#define AR_PHY_PAPRD_TRAINER_CNTL3_MIN_LOOPBACK_DEL_S 12
+#define AR_PHY_PAPRD_TRAINER_CNTL3_NUM_CORR_STAGES_M 0x000e0000
+#define AR_PHY_PAPRD_TRAINER_CNTL3_NUM_CORR_STAGES_S 17
+#define AR_PHY_PAPRD_TRAINER_CNTL3_COARSE_CORR_LEN_M 0x00f00000
+#define AR_PHY_PAPRD_TRAINER_CNTL3_COARSE_CORR_LEN_S 20
+#define AR_PHY_PAPRD_TRAINER_CNTL3_FINE_CORR_LEN_M 0x0f000000
+#define AR_PHY_PAPRD_TRAINER_CNTL3_FINE_CORR_LEN_S 24
+#define AR_PHY_PAPRD_TRAINER_CNTL3_BBTXMIX_DISABLE 0x20000000
+
+/* Bits for AR_PHY_PAPRD_TRAINER_CNTL4. */
+#define AR_PHY_PAPRD_TRAINER_CNTL4_MIN_CORR_M 0x00000fff
+#define AR_PHY_PAPRD_TRAINER_CNTL4_MIN_CORR_S 0
+#define AR_PHY_PAPRD_TRAINER_CNTL4_SAFETY_DELTA_M 0x0000f000
+#define AR_PHY_PAPRD_TRAINER_CNTL4_SAFETY_DELTA_S 12
+#define AR_PHY_PAPRD_TRAINER_CNTL4_NUM_TRAIN_SAMPLES_M 0x03ff0000
+#define AR_PHY_PAPRD_TRAINER_CNTL4_NUM_TRAIN_SAMPLES_S 16
+
+/* Bits for AR_PHY_PAPRD_TRAINER_STAT1. */
+#define AR_PHY_PAPRD_TRAINER_STAT1_TRAIN_DONE 0x00000001
+#define AR_PHY_PAPRD_TRAINER_STAT1_TRAIN_INCOMPLETE 0x00000002
+#define AR_PHY_PAPRD_TRAINER_STAT1_CORR_ERR 0x00000004
+#define AR_PHY_PAPRD_TRAINER_STAT1_TRAIN_ACTIVE 0x00000008
+#define AR_PHY_PAPRD_TRAINER_STAT1_RX_GAIN_IDX_M 0x000001f0
+#define AR_PHY_PAPRD_TRAINER_STAT1_RX_GAIN_IDX_S 4
+#define AR_PHY_PAPRD_TRAINER_STAT1_AGC2_PWR_M 0x0001fe00
+#define AR_PHY_PAPRD_TRAINER_STAT1_AGC2_PWR_S 9
+
+/* Bits for AR_PHY_PAPRD_TRAINER_STAT2. */
+#define AR_PHY_PAPRD_TRAINER_STAT2_FINE_VAL_M 0x0000ffff
+#define AR_PHY_PAPRD_TRAINER_STAT2_FINE_VAL_S 0
+#define AR_PHY_PAPRD_TRAINER_STAT2_COARSE_IDX_M 0x001f0000
+#define AR_PHY_PAPRD_TRAINER_STAT2_COARSE_IDX_S 16
+#define AR_PHY_PAPRD_TRAINER_STAT2_FINE_IDX_M 0x00600000
+#define AR_PHY_PAPRD_TRAINER_STAT2_FINE_IDX_S 21
+
+/* Bits for AR_PHY_PAPRD_TRAINER_STAT3. */
+#define AR_PHY_PAPRD_TRAINER_STAT3_TRAIN_SAMPLES_CNT_M 0x000fffff
+#define AR_PHY_PAPRD_TRAINER_STAT3_TRAIN_SAMPLES_CNT_S 0
+
+/* Bits for AR_PHY_65NM_CH0_SYNTH4. */
+#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002
+
+/* Bits for AR_PHY_65NM_CH0_SYNTH7. */
+#define AR9380_FRACMODE 0x40000000
+#define AR9380_LOAD_SYNTH 0x80000000
+
+/* Bits for AR_PHY_65NM_CH0_BIAS1. */
+#define AR_PHY_65NM_CH0_BIAS1_0_M 0x000001c0
+#define AR_PHY_65NM_CH0_BIAS1_0_S 6
+#define AR_PHY_65NM_CH0_BIAS1_1_M 0x00000e00
+#define AR_PHY_65NM_CH0_BIAS1_1_S 9
+#define AR_PHY_65NM_CH0_BIAS1_2_M 0x00007000
+#define AR_PHY_65NM_CH0_BIAS1_2_S 12
+#define AR_PHY_65NM_CH0_BIAS1_3_M 0x00038000
+#define AR_PHY_65NM_CH0_BIAS1_3_S 15
+#define AR_PHY_65NM_CH0_BIAS1_4_M 0x001c0000
+#define AR_PHY_65NM_CH0_BIAS1_4_S 18
+#define AR_PHY_65NM_CH0_BIAS1_5_M 0x00e00000
+#define AR_PHY_65NM_CH0_BIAS1_5_S 21
+
+/* Bits for AR_PHY_65NM_CH0_BIAS2. */
+#define AR_PHY_65NM_CH0_BIAS2_0_M 0x000000e0
+#define AR_PHY_65NM_CH0_BIAS2_0_S 5
+#define AR_PHY_65NM_CH0_BIAS2_1_M 0x00000700
+#define AR_PHY_65NM_CH0_BIAS2_1_S 8
+#define AR_PHY_65NM_CH0_BIAS2_2_M 0x00003800
+#define AR_PHY_65NM_CH0_BIAS2_2_S 11
+#define AR_PHY_65NM_CH0_BIAS2_3_M 0x0001c000
+#define AR_PHY_65NM_CH0_BIAS2_3_S 14
+#define AR_PHY_65NM_CH0_BIAS2_4_M 0x000e0000
+#define AR_PHY_65NM_CH0_BIAS2_4_S 17
+#define AR_PHY_65NM_CH0_BIAS2_5_M 0x00700000
+#define AR_PHY_65NM_CH0_BIAS2_5_S 20
+#define AR_PHY_65NM_CH0_BIAS2_6_M 0x03800000
+#define AR_PHY_65NM_CH0_BIAS2_6_S 23
+#define AR_PHY_65NM_CH0_BIAS2_7_M 0x1c000000
+#define AR_PHY_65NM_CH0_BIAS2_7_S 26
+#define AR_PHY_65NM_CH0_BIAS2_8_M 0xe0000000
+#define AR_PHY_65NM_CH0_BIAS2_8_S 29
+
+/* Bits for AR_PHY_65NM_CH0_BIAS4. */
+#define AR_PHY_65NM_CH0_BIAS4_0_M 0x03800000
+#define AR_PHY_65NM_CH0_BIAS4_0_S 23
+#define AR_PHY_65NM_CH0_BIAS4_1_M 0x1c000000
+#define AR_PHY_65NM_CH0_BIAS4_1_S 26
+#define AR_PHY_65NM_CH0_BIAS4_2_M 0xe0000000
+#define AR_PHY_65NM_CH0_BIAS4_2_S 29
+
+/* Bits for AR_PHY_65NM_CH0_RXTX4. */
+#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000
+
+/* Bits for AR9485_PHY_65NM_CH0_TOP2. */
+#define AR9485_PHY_65NM_CH0_TOP2_XPABIASLVL_M 0x0000f000
+#define AR9485_PHY_65NM_CH0_TOP2_XPABIASLVL_S 12
+
+/* Bits for AR_PHY_65NM_CH0_TOP. */
+#define AR_PHY_65NM_CH0_TOP_XPABIASLVL_M 0x00000300
+#define AR_PHY_65NM_CH0_TOP_XPABIASLVL_S 8
+
+/* Bits for AR_PHY_65NM_CH0_THERM. */
+#define AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB_M 0x00000003
+#define AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB_S 0
+#define AR_PHY_65NM_CH0_THERM_XPASHORT2GND 0x00000004
+#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_M 0x0000ff00
+#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8
+#define AR_PHY_65NM_CH0_THERM_START 0x20000000
+#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
+
+/* Bits for AR9485_PHY_CH0_XTAL. */
+#define AR9485_PHY_CH0_XTAL_CAPINDAC_M 0x7f000000
+#define AR9485_PHY_CH0_XTAL_CAPINDAC_S 24
+#define AR9485_PHY_CH0_XTAL_CAPOUTDAC_M 0x00fe0000
+#define AR9485_PHY_CH0_XTAL_CAPOUTDAC_S 17
+
+/* Bits for AR_PHY_PMU1. */
+#define AR_PHY_PMU1_PWD 0x00000001
+
+/* Bits for AR_PHY_PMU2. */
+#define AR_PHY_PMU2_PGM 0x00200000
+
+/*
+ * OTP registers.
+ */
+#define AR_OTP_BASE(i) (0x14000 + (i) * 4)
+#define AR_OTP_STATUS 0x15f18
+#define AR_OTP_READ_DATA 0x15f1c
+
+/* Bits for AR_OTP_STATUS. */
+#define AR_OTP_STATUS_TYPE_M 0x00000007
+#define AR_OTP_STATUS_TYPE_S 0
+#define AR_OTP_STATUS_SM_BUSY 0x1
+#define AR_OTP_STATUS_ACCESS_BUSY 0x2
+#define AR_OTP_STATUS_VALID 0x4
+
+
+#define AR9003_MAX_CHAINS 3
+
+#define AR9003_TX_QDEPTH 8
+#define AR9003_RX_LP_QDEPTH 128
+#define AR9003_RX_HP_QDEPTH 16
+
+#define AR9003_NTXSTATUS 64
+
+/* Maximum number of DMA segments per Tx descriptor. */
+#define AR9003_MAX_SCATTER 4
+
+/*
+ * Tx DMA descriptor.
+ */
+struct ar_tx_desc {
+ uint32_t ds_info;
+ uint32_t ds_link;
+ struct {
+ uint32_t ds_data;
+ uint32_t ds_ctl;
+ } __packed ds_segs[AR9003_MAX_SCATTER];
+ uint32_t ds_ctl10;
+ uint32_t ds_ctl11;
+ uint32_t ds_ctl12;
+ uint32_t ds_ctl13;
+ uint32_t ds_ctl14;
+ uint32_t ds_ctl15;
+ uint32_t ds_ctl16;
+ uint32_t ds_ctl17;
+ uint32_t ds_ctl18;
+ uint32_t ds_ctl19;
+ uint32_t ds_ctl20;
+ uint32_t ds_ctl21;
+ uint32_t ds_ctl22;
+ /*
+ * Padding to make Tx descriptors 128 bytes such that they will
+ * not cross a 4KB boundary.
+ */
+ uint32_t pad[9];
+} __packed __attribute__((aligned(4)));
+
+/* Bits for ds_info. */
+#define AR_TXI_DESC_NDWORDS_M 0x000000ff
+#define AR_TXI_DESC_NDWORDS_S 0
+#define AR_TXI_QCU_NUM_M 0x00000f00
+#define AR_TXI_QCU_NUM_S 8
+#define AR_TXI_CTRL_STAT 0x00004000
+#define AR_TXI_DESC_TX 0x00008000
+#define AR_TXI_DESC_ID_M 0xffff0000
+#define AR_TXI_DESC_ID_S 16
+#define AR_VENDOR_ATHEROS 0x168c /* NB: PCI_VENDOR_ATHEROS */
+
+/* Bits for ds_ctl. */
+#define AR_TXC_BUF_LEN_M 0x0fff0000
+#define AR_TXC_BUF_LEN_S 16
+
+/* Bits for ds_ctl10. */
+#define AR_TXC10_PTR_CHK_SUM_M 0x0000ffff
+#define AR_TXC10_PTR_CHK_SUM_S 0
+
+/* Bits for ds_ctl11. */
+#define AR_TXC11_FRAME_LEN_M 0x00000fff
+#define AR_TXC11_FRAME_LEN_S 0
+#define AR_TXC11_XMIT_POWER_M 0x003f0000
+#define AR_TXC11_XMIT_POWER_S 16
+#define AR_TXC11_RTS_ENABLE 0x00400000
+#define AR_TXC11_CLR_DEST_MASK 0x01000000
+#define AR_TXC11_DEST_IDX_VALID 0x40000000
+#define AR_TXC11_CTS_ENABLE 0x80000000
+
+/* Bits for ds_ctl12. */
+#define AR_TXC12_PAPRD_CHAIN_MASK_M 0x00000e00
+#define AR_TXC12_PAPRD_CHAIN_MASK_S 9
+#define AR_TXC12_DEST_IDX_M 0x000fe000
+#define AR_TXC12_DEST_IDX_S 13
+#define AR_TXC12_FRAME_TYPE_M 0x00f00000
+#define AR_TXC12_FRAME_TYPE_S 20
+#define AR_FRAME_TYPE_NORMAL 0
+#define AR_FRAME_TYPE_ATIM 1
+#define AR_FRAME_TYPE_PSPOLL 2
+#define AR_FRAME_TYPE_BEACON 3
+#define AR_FRAME_TYPE_PROBE_RESP 4
+#define AR_TXC12_NO_ACK 0x01000000
+
+/* Bits for ds_ctl13. */
+#define AR_TXC13_BURST_DUR_M 0x00007fff
+#define AR_TXC13_BURST_DUR_S 0
+#define AR_TXC13_DUR_UPDATE_ENA 0x00008000
+#define AR_TXC13_XMIT_DATA_TRIES0_M 0x000f0000
+#define AR_TXC13_XMIT_DATA_TRIES0_S 16
+#define AR_TXC13_XMIT_DATA_TRIES1_M 0x00f00000
+#define AR_TXC13_XMIT_DATA_TRIES1_S 20
+#define AR_TXC13_XMIT_DATA_TRIES2_M 0x0f000000
+#define AR_TXC13_XMIT_DATA_TRIES2_S 24
+#define AR_TXC13_XMIT_DATA_TRIES3_M 0xf0000000
+#define AR_TXC13_XMIT_DATA_TRIES3_S 28
+
+/* Bits for ds_ctl14. */
+#define AR_TXC14_XMIT_RATE0_M 0x000000ff
+#define AR_TXC14_XMIT_RATE0_S 0
+#define AR_TXC14_XMIT_RATE1_M 0x0000ff00
+#define AR_TXC14_XMIT_RATE1_S 8
+#define AR_TXC14_XMIT_RATE2_M 0x00ff0000
+#define AR_TXC14_XMIT_RATE2_S 16
+#define AR_TXC14_XMIT_RATE3_M 0xff000000
+#define AR_TXC14_XMIT_RATE3_S 24
+
+/* Bits for ds_ctl15. */
+#define AR_TXC15_PACKET_DUR0_M 0x00007fff
+#define AR_TXC15_PACKET_DUR0_S 0
+#define AR_TXC15_RTSCTS_QUAL0 0x00008000
+#define AR_TXC15_PACKET_DUR1_M 0x7fff0000
+#define AR_TXC15_PACKET_DUR1_S 16
+#define AR_TXC15_RTSCTS_QUAL1 0x80000000
+/* Shortcut. */
+#define AR_TXC15_RTSCTS_QUAL01 \
+ (AR_TXC15_RTSCTS_QUAL0 | AR_TXC15_RTSCTS_QUAL1)
+
+/* Bits for ds_ctl16. */
+#define AR_TXC16_PACKET_DUR2_M 0x00007fff
+#define AR_TXC16_PACKET_DUR2_S 0
+#define AR_TXC16_RTSCTS_QUAL2 0x00008000
+#define AR_TXC16_PACKET_DUR3_M 0x7fff0000
+#define AR_TXC16_PACKET_DUR3_S 16
+#define AR_TXC16_RTSCTS_QUAL3 0x80000000
+/* Shortcut. */
+#define AR_TXC16_RTSCTS_QUAL23 \
+ (AR_TXC16_RTSCTS_QUAL2 | AR_TXC16_RTSCTS_QUAL3)
+
+/* Bits for ds_ctl17. */
+#define AR_TXC17_ENCR_TYPE_M 0x0c000000
+#define AR_TXC17_ENCR_TYPE_S 26
+#define AR_ENCR_TYPE_CLEAR 0
+#define AR_ENCR_TYPE_WEP 1
+#define AR_ENCR_TYPE_AES 2
+#define AR_ENCR_TYPE_TKIP 3
+
+/* Bits for ds_ctl18. */
+#define AR_TXC18_2040_0 0x00000001
+#define AR_TXC18_GI0 0x00000002
+#define AR_TXC18_CHAIN_SEL0_M 0x0000001c
+#define AR_TXC18_CHAIN_SEL0_S 2
+#define AR_TXC18_2040_1 0x00000020
+#define AR_TXC18_GI1 0x00000040
+#define AR_TXC18_CHAIN_SEL1_M 0x00000380
+#define AR_TXC18_CHAIN_SEL1_S 7
+#define AR_TXC18_2040_2 0x00000400
+#define AR_TXC18_GI2 0x00000800
+#define AR_TXC18_CHAIN_SEL2_M 0x00007000
+#define AR_TXC18_CHAIN_SEL2_S 12
+#define AR_TXC18_2040_3 0x00008000
+#define AR_TXC18_GI3 0x00010000
+#define AR_TXC18_CHAIN_SEL3_M 0x000e0000
+#define AR_TXC18_CHAIN_SEL3_S 17
+#define AR_TXC18_RTSCTS_RATE_M 0x0ff00000
+#define AR_TXC18_RTSCTS_RATE_S 20
+/* Shortcuts. */
+#define AR_TXC18_2040_0123 \
+ (AR_TXC18_2040_0 | AR_TXC18_2040_1 | AR_TXC18_2040_2 | AR_TXC18_2040_3)
+#define AR_TXC18_GI0123 \
+ (AR_TXC18_GI0 | AR_TXC18_GI1 | AR_TXC18_GI2 | AR_TXC18_GI3)
+
+/* Bits for ds_ctl19. */
+#define AR_TXC19_NOT_SOUNDING 0x20000000
+
+
+/*
+ * Tx status DMA descriptor.
+ */
+struct ar_tx_status {
+ uint32_t ds_info;
+ uint32_t ds_status1;
+ uint32_t ds_status2;
+ uint32_t ds_status3;
+ uint32_t ds_status4;
+ uint32_t ds_status5;
+ uint32_t ds_status6;
+ uint32_t ds_status7;
+ uint32_t ds_status8;
+} __packed __attribute__((aligned(4)));
+
+/* Bits for ds_status3. */
+#define AR_TXS3_EXCESSIVE_RETRIES 0x00000002
+#define AR_TXS3_FIFO_UNDERRUN 0x00000004
+#define AR_TXS3_RTS_FAIL_CNT_M 0x000000f0
+#define AR_TXS3_RTS_FAIL_CNT_S 4
+#define AR_TXS3_DATA_FAIL_CNT_M 0x00000f00
+#define AR_TXS3_DATA_FAIL_CNT_S 8
+#define AR_TXS3_TX_DELIM_UNDERRUN 0x00010000
+#define AR_TXS3_TX_DATA_UNDERRUN 0x00020000
+/* Shortcut. */
+#define AR_TXS3_UNDERRUN \
+ (AR_TXS3_FIFO_UNDERRUN | \
+ AR_TXS3_TX_DELIM_UNDERRUN | \
+ AR_TXS3_TX_DATA_UNDERRUN)
+
+/* Bits for ds_status8. */
+#define AR_TXS8_DONE 0x00000001
+#define AR_TXS8_FINAL_IDX_M 0x00600000
+#define AR_TXS8_FINAL_IDX_S 21
+
+/*
+ * Rx status DMA descriptor.
+ */
+struct ar_rx_status {
+ uint32_t ds_info;
+ uint32_t ds_status1;
+ uint32_t ds_status2;
+ uint32_t ds_status3;
+ uint32_t ds_status4;
+ uint32_t ds_status5;
+ uint32_t ds_status6;
+ uint32_t ds_status7;
+ uint32_t ds_status8;
+ uint32_t ds_status9;
+ uint32_t ds_status10;
+ uint32_t ds_status11;
+} __packed __attribute__((aligned(4)));
+
+/* Bits for ds_info. */
+#define AR_RXI_CTRL_STAT 0x00004000
+#define AR_RXI_DESC_TX 0x00008000
+#define AR_RXI_DESC_ID_M 0xffff0000
+#define AR_RXI_DESC_ID_S 16
+
+/* Bits for ds_status1. */
+#define AR_RXS1_RATE_M 0x000003fc
+#define AR_RXS1_RATE_S 2
+
+/* Bits for ds_status2. */
+#define AR_RXS2_DATA_LEN_M 0x00000fff
+#define AR_RXS2_DATA_LEN_S 0
+
+/* Bits for ds_status4. */
+#define AR_RXS4_GI 0x00000001
+#define AR_RXS4_ANTENNA_M 0xffffff00
+#define AR_RXS4_ANTENNA_S 8
+
+/* Bits for ds_status5. */
+#define AR_RXS5_RSSI_COMBINED_M 0xff000000
+#define AR_RXS5_RSSI_COMBINED_S 24
+
+/* Bits for ds_status11. */
+#define AR_RXS11_DONE 0x00000001
+#define AR_RXS11_FRAME_OK 0x00000002
+#define AR_RXS11_CRC_ERR 0x00000004
+#define AR_RXS11_DECRYPT_CRC_ERR 0x00000008
+#define AR_RXS11_PHY_ERR 0x00000010
+#define AR_RXS11_PHY_ERR_CODE_M 0x0000ff00
+#define AR_RXS11_PHY_ERR_CODE_S 8
+#define AR_RXS11_MICHAEL_ERR 0x00000020
+
+/*
+ * AR9003 family common ROM structures.
+ */
+#define AR_EEP_COMPRESS_NONE 0
+#define AR_EEP_COMPRESS_LZMA 1
+#define AR_EEP_COMPRESS_PAIRS 2
+#define AR_EEP_COMPRESS_BLOCK 3
+
+struct ar_cal_target_power_leg {
+ uint8_t tPow2x[4];
+} __packed;
+
+struct ar_cal_target_power_ht {
+ uint8_t tPow2x[14];
+} __packed;
diff --git a/sys/dev/athn/ic/ar9280.c b/sys/dev/athn/ic/ar9280.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar9280.c
@@ -0,0 +1,614 @@
+/* $OpenBSD: ar9280.c,v 1.28 2021/04/15 18:25:43 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Driver for Atheros 802.11a/g/n chipsets.
+ * Routines for AR9220, AR9223, AR9280 and AR9281 chipsets.
+ */
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <dev/athn/athnreg.h>
+#include <dev/athn/athnvar.h>
+
+#include <dev/athn/ic/ar5008reg.h>
+#include <dev/athn/ic/ar5416reg.h> /* We share the ROM layout. */
+#include <dev/athn/ic/ar9280reg.h>
+
+
+
+int ar9280_attach(struct athn_softc *);
+void ar9280_setup(struct athn_softc *);
+int ar9280_set_synth(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9280_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9280_spur_mitigate(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9280_olpc_get_pdadcs(struct athn_softc *,
+ struct ieee80211_channel *, int, uint8_t *, uint8_t *, uint8_t *);
+void ar9280_reset_rx_gain(struct athn_softc *, struct ieee80211_channel *);
+void ar9280_reset_tx_gain(struct athn_softc *, struct ieee80211_channel *);
+void ar9280_olpc_init(struct athn_softc *);
+void ar9280_olpc_temp_compensation(struct athn_softc *);
+
+/* Extern functions. */
+uint8_t athn_chan2fbin(struct ieee80211_channel *);
+void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *);
+int ar5008_attach(struct athn_softc *);
+void ar5008_set_viterbi_mask(struct athn_softc *, int);
+void ar5416_swap_rom(struct athn_softc *);
+void ar5416_set_txpower(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+const struct ar_spur_chan *
+ ar5416_get_spur_chans(struct athn_softc *, int);
+
+
+int
+ar9280_attach(struct athn_softc *sc)
+{
+ sc->eep_base = AR5416_EEP_START_LOC;
+ sc->eep_size = sizeof(struct ar5416_eeprom);
+ sc->ngpiopins = (sc->flags & ATHN_FLAG_USB) ? 16 : 10;
+ sc->led_pin = 1;
+ sc->workaround = AR9280_WA_DEFAULT;
+ sc->ops.setup = ar9280_setup;
+ sc->ops.swap_rom = ar5416_swap_rom;
+ sc->ops.init_from_rom = ar9280_init_from_rom;
+ sc->ops.set_txpower = ar5416_set_txpower;
+ sc->ops.set_synth = ar9280_set_synth;
+ sc->ops.spur_mitigate = ar9280_spur_mitigate;
+ sc->ops.get_spur_chans = ar5416_get_spur_chans;
+ sc->ops.olpc_init = ar9280_olpc_init;
+ sc->ops.olpc_temp_compensation = ar9280_olpc_temp_compensation;
+ sc->cca_min_2g = AR9280_PHY_CCA_MIN_GOOD_VAL_2GHZ;
+ sc->cca_max_2g = AR9280_PHY_CCA_MAX_GOOD_VAL_2GHZ;
+ sc->cca_min_5g = AR9280_PHY_CCA_MIN_GOOD_VAL_5GHZ;
+ sc->cca_max_5g = AR9280_PHY_CCA_MAX_GOOD_VAL_5GHZ;
+ sc->ini = &ar9280_2_0_ini;
+ sc->serdes = &ar9280_2_0_serdes;
+
+ return (ar5008_attach(sc));
+}
+
+void
+ar9280_setup(struct athn_softc *sc)
+{
+ const struct ar5416_eeprom *eep = sc->eep;
+ uint8_t type;
+
+ /* Determine if open loop power control should be used. */
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_19 &&
+ eep->baseEepHeader.openLoopPwrCntl)
+ sc->flags |= ATHN_FLAG_OLPC;
+
+ /* Determine if fast PLL clock is supported. */
+ if (AR_SREV_9280_20(sc) &&
+ (sc->eep_rev <= AR_EEP_MINOR_VER_16 ||
+ eep->baseEepHeader.fastClk5g))
+ sc->flags |= ATHN_FLAG_FAST_PLL_CLOCK;
+
+ /*
+ * Determine if initialization value for AR_AN_TOP2 must be fixed.
+ * This is required for some AR9220 devices such as Ubiquiti SR71-12.
+ */
+ if (AR_SREV_9280_20(sc) &&
+ sc->eep_rev > AR_EEP_MINOR_VER_10 &&
+ !eep->baseEepHeader.pwdclkind) {
+ DPRINTF(("AR_AN_TOP2 fixup required\n"));
+ sc->flags |= ATHN_FLAG_AN_TOP2_FIXUP;
+ }
+
+ if (AR_SREV_9280_20(sc)) {
+ /* Check if we have a valid rxGainType field in ROM. */
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_17) {
+ /* Select initialization values based on ROM. */
+ type = eep->baseEepHeader.rxGainType;
+ DPRINTF(("Rx gain type=0x%x\n", type));
+ if (type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
+ sc->rx_gain = &ar9280_2_0_rx_gain_23db_backoff;
+ else if (type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
+ sc->rx_gain = &ar9280_2_0_rx_gain_13db_backoff;
+ else
+ sc->rx_gain = &ar9280_2_0_rx_gain;
+ } else
+ sc->rx_gain = &ar9280_2_0_rx_gain;
+
+ /* Check if we have a valid txGainType field in ROM. */
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_19) {
+ /* Select initialization values based on ROM. */
+ type = eep->baseEepHeader.txGainType;
+ DPRINTF(("Tx gain type=0x%x\n", type));
+ if (type == AR_EEP_TXGAIN_HIGH_POWER)
+ sc->tx_gain = &ar9280_2_0_tx_gain_high_power;
+ else
+ sc->tx_gain = &ar9280_2_0_tx_gain;
+ } else
+ sc->tx_gain = &ar9280_2_0_tx_gain;
+ }
+}
+
+int
+ar9280_set_synth(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ uint32_t phy, reg, ndiv = 0;
+ uint32_t freq = c->ic_freq;
+
+ phy = AR_READ(sc, AR9280_PHY_SYNTH_CONTROL) & ~0x3fffffff;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ phy |= (freq << 16) / 15;
+ phy |= AR9280_BMODE | AR9280_FRACMODE;
+
+ if (AR_SREV_9287_11_OR_LATER(sc)) {
+ /* NB: Magic values from the Linux driver. */
+ if (freq == 2484) { /* Channel 14. */
+ /* Japanese regulatory requirements. */
+ AR_WRITE(sc, AR_PHY(637), 0x00000000);
+ AR_WRITE(sc, AR_PHY(638), 0xefff0301);
+ AR_WRITE(sc, AR_PHY(639), 0xca9228ee);
+ } else {
+ AR_WRITE(sc, AR_PHY(637), 0x00fffeff);
+ AR_WRITE(sc, AR_PHY(638), 0x00f5f9ff);
+ AR_WRITE(sc, AR_PHY(639), 0xb79f6427);
+ }
+ } else {
+ reg = AR_READ(sc, AR_PHY_CCK_TX_CTRL);
+ if (freq == 2484) /* Channel 14. */
+ reg |= AR_PHY_CCK_TX_CTRL_JAPAN;
+ else
+ reg &= ~AR_PHY_CCK_TX_CTRL_JAPAN;
+ AR_WRITE(sc, AR_PHY_CCK_TX_CTRL, reg);
+ }
+ } else {
+ if (AR_SREV_9285_10_OR_LATER(sc) ||
+ sc->eep_rev < AR_EEP_MINOR_VER_22 ||
+ !((struct ar5416_base_eep_header *)sc->eep)->frac_n_5g) {
+ if ((freq % 20) == 0) {
+ ndiv = (freq * 3) / 60;
+ phy |= SM(AR9280_AMODE_REFSEL, 3);
+ } else if ((freq % 10) == 0) {
+ ndiv = (freq * 6) / 60;
+ phy |= SM(AR9280_AMODE_REFSEL, 2);
+ }
+ }
+ if (ndiv != 0) {
+ phy |= (ndiv & 0x1ff) << 17;
+ phy |= (ndiv & ~0x1ff) * 2;
+ } else {
+ phy |= (freq << 15) / 15;
+ phy |= AR9280_FRACMODE;
+
+ reg = AR_READ(sc, AR_AN_SYNTH9);
+ reg = RW(reg, AR_AN_SYNTH9_REFDIVA, 1);
+ AR_WRITE(sc, AR_AN_SYNTH9, reg);
+ }
+ }
+ AR_WRITE_BARRIER(sc);
+ DPRINTFN(4, ("AR9280_PHY_SYNTH_CONTROL=0x%08x\n", phy));
+ AR_WRITE(sc, AR9280_PHY_SYNTH_CONTROL, phy);
+ AR_WRITE_BARRIER(sc);
+ return (0);
+}
+
+void
+ar9280_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ static const uint32_t chainoffset[] = { 0x0000, 0x2000, 0x1000 };
+ const struct ar5416_eeprom *eep = sc->eep;
+ const struct ar5416_modal_eep_header *modal;
+ uint32_t reg, offset;
+ uint8_t txRxAtten;
+ int i;
+
+ modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)];
+
+ AR_WRITE(sc, AR_PHY_SWITCH_COM, modal->antCtrlCommon);
+
+ for (i = 0; i < AR9280_MAX_CHAINS; i++) {
+ if (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5)
+ offset = chainoffset[i];
+ else
+ offset = i * 0x1000;
+
+ AR_WRITE(sc, AR_PHY_SWITCH_CHAIN_0 + offset,
+ modal->antCtrlChain[i]);
+
+ reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0 + offset);
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
+ modal->iqCalICh[i]);
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
+ modal->iqCalQCh[i]);
+ AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0 + offset, reg);
+
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_3) {
+ reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+ modal->bswMargin[i]);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+ modal->bswAtten[i]);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+ modal->xatten2Margin[i]);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+ modal->xatten2Db[i]);
+ AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg);
+ }
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_3)
+ txRxAtten = modal->txRxAttenCh[i];
+ else /* Workaround for ROM versions < 14.3. */
+ txRxAtten = IEEE80211_IS_CHAN_2GHZ(c) ? 23 : 44;
+ reg = AR_READ(sc, AR_PHY_RXGAIN + offset);
+ reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_ATTEN,
+ txRxAtten);
+ reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_MARGIN,
+ modal->rxTxMarginCh[i]);
+ AR_WRITE(sc, AR_PHY_RXGAIN + offset, reg);
+ }
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ reg = AR_READ(sc, AR_AN_RF2G1_CH0);
+ reg = RW(reg, AR_AN_RF2G1_CH0_OB, modal->ob);
+ reg = RW(reg, AR_AN_RF2G1_CH0_DB, modal->db);
+ AR_WRITE(sc, AR_AN_RF2G1_CH0, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+
+ reg = AR_READ(sc, AR_AN_RF2G1_CH1);
+ reg = RW(reg, AR_AN_RF2G1_CH1_OB, modal->ob_ch1);
+ reg = RW(reg, AR_AN_RF2G1_CH1_DB, modal->db_ch1);
+ AR_WRITE(sc, AR_AN_RF2G1_CH1, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+ } else {
+ reg = AR_READ(sc, AR_AN_RF5G1_CH0);
+ reg = RW(reg, AR_AN_RF5G1_CH0_OB5, modal->ob);
+ reg = RW(reg, AR_AN_RF5G1_CH0_DB5, modal->db);
+ AR_WRITE(sc, AR_AN_RF5G1_CH0, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+
+ reg = AR_READ(sc, AR_AN_RF5G1_CH1);
+ reg = RW(reg, AR_AN_RF5G1_CH1_OB5, modal->ob_ch1);
+ reg = RW(reg, AR_AN_RF5G1_CH1_DB5, modal->db_ch1);
+ AR_WRITE(sc, AR_AN_RF5G1_CH1, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+ }
+ reg = AR_READ(sc, AR_AN_TOP2);
+ if ((sc->flags & ATHN_FLAG_USB) && IEEE80211_IS_CHAN_5GHZ(c)) {
+ /*
+ * Hardcode the output voltage of x-PA bias LDO to the
+ * lowest value for UB94 such that the card doesn't get
+ * too hot.
+ */
+ reg = RW(reg, AR_AN_TOP2_XPABIAS_LVL, 0);
+ } else
+ reg = RW(reg, AR_AN_TOP2_XPABIAS_LVL, modal->xpaBiasLvl);
+ if (modal->flagBits & AR5416_EEP_FLAG_LOCALBIAS)
+ reg |= AR_AN_TOP2_LOCALBIAS;
+ else
+ reg &= ~AR_AN_TOP2_LOCALBIAS;
+ AR_WRITE(sc, AR_AN_TOP2, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+
+ reg = AR_READ(sc, AR_PHY_XPA_CFG);
+ if (modal->flagBits & AR5416_EEP_FLAG_FORCEXPAON)
+ reg |= AR_PHY_FORCE_XPA_CFG;
+ else
+ reg &= ~AR_PHY_FORCE_XPA_CFG;
+ AR_WRITE(sc, AR_PHY_XPA_CFG, reg);
+
+ reg = AR_READ(sc, AR_PHY_SETTLING);
+ reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling);
+ AR_WRITE(sc, AR_PHY_SETTLING, reg);
+
+ reg = AR_READ(sc, AR_PHY_DESIRED_SZ);
+ reg = RW(reg, AR_PHY_DESIRED_SZ_ADC, modal->adcDesiredSize);
+ AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg);
+
+ reg = SM(AR_PHY_RF_CTL4_TX_END_XPAA_OFF, modal->txEndToXpaOff);
+ reg |= SM(AR_PHY_RF_CTL4_TX_END_XPAB_OFF, modal->txEndToXpaOff);
+ reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAA_ON, modal->txFrameToXpaOn);
+ reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAB_ON, modal->txFrameToXpaOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL4, reg);
+
+ reg = AR_READ(sc, AR_PHY_RF_CTL3);
+ reg = RW(reg, AR_PHY_TX_END_TO_A2_RX_ON, modal->txEndToRxOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL3, reg);
+
+ reg = AR_READ(sc, AR_PHY_CCA(0));
+ reg = RW(reg, AR9280_PHY_CCA_THRESH62, modal->thresh62);
+ AR_WRITE(sc, AR_PHY_CCA(0), reg);
+
+ reg = AR_READ(sc, AR_PHY_EXT_CCA0);
+ reg = RW(reg, AR_PHY_EXT_CCA0_THRESH62, modal->thresh62);
+ AR_WRITE(sc, AR_PHY_EXT_CCA0, reg);
+
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_2) {
+ reg = AR_READ(sc, AR_PHY_RF_CTL2);
+ reg = RW(reg, AR_PHY_TX_END_DATA_START,
+ modal->txFrameToDataStart);
+ reg = RW(reg, AR_PHY_TX_END_PA_ON, modal->txFrameToPaOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL2, reg);
+ }
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_3 && extc != NULL) {
+ /* Overwrite switch settling with HT-40 value. */
+ reg = AR_READ(sc, AR_PHY_SETTLING);
+ reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->swSettleHt40);
+ AR_WRITE(sc, AR_PHY_SETTLING, reg);
+ }
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_19) {
+ reg = AR_READ(sc, AR_PHY_CCK_TX_CTRL);
+ reg = RW(reg, AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
+ MS(modal->miscBits, AR5416_EEP_MISC_TX_DAC_SCALE_CCK));
+ AR_WRITE(sc, AR_PHY_CCK_TX_CTRL, reg);
+ }
+ if (AR_SREV_9280_20(sc) &&
+ sc->eep_rev >= AR_EEP_MINOR_VER_20) {
+ reg = AR_READ(sc, AR_AN_TOP1);
+ if (eep->baseEepHeader.dacLpMode &&
+ (IEEE80211_IS_CHAN_2GHZ(c) ||
+ !eep->baseEepHeader.dacHiPwrMode_5G))
+ reg |= AR_AN_TOP1_DACLPMODE;
+ else
+ reg &= ~AR_AN_TOP1_DACLPMODE;
+ AR_WRITE(sc, AR_AN_TOP1, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+
+ reg = AR_READ(sc, AR_PHY_FRAME_CTL);
+ reg = RW(reg, AR_PHY_FRAME_CTL_TX_CLIP,
+ MS(modal->miscBits, AR5416_EEP_MISC_TX_CLIP));
+ AR_WRITE(sc, AR_PHY_FRAME_CTL, reg);
+
+ reg = AR_READ(sc, AR_PHY_TX_PWRCTRL9);
+ reg = RW(reg, AR_PHY_TX_DESIRED_SCALE_CCK,
+ eep->baseEepHeader.desiredScaleCCK);
+ AR_WRITE(sc, AR_PHY_TX_PWRCTRL9, reg);
+ }
+ AR_WRITE_BARRIER(sc);
+}
+
+void
+ar9280_olpc_get_pdadcs(struct athn_softc *sc, struct ieee80211_channel *c,
+ int chain, uint8_t *boundaries, uint8_t *pdadcs, uint8_t *txgain)
+{
+ const struct ar5416_eeprom *eep = sc->eep;
+ const struct ar_cal_data_per_freq_olpc *pierdata;
+ const uint8_t *pierfreq;
+ uint8_t fbin, pcdac, pwr, idx;
+ int i, lo, hi, npiers;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ pierfreq = eep->calFreqPier2G;
+ pierdata = (const struct ar_cal_data_per_freq_olpc *)
+ eep->calPierData2G[chain];
+ npiers = AR5416_NUM_2G_CAL_PIERS;
+ } else {
+ pierfreq = eep->calFreqPier5G;
+ pierdata = (const struct ar_cal_data_per_freq_olpc *)
+ eep->calPierData5G[chain];
+ npiers = AR5416_NUM_5G_CAL_PIERS;
+ }
+ /* Find channel in ROM pier table. */
+ fbin = athn_chan2fbin(c);
+ athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi);
+
+ /* Get average. */
+ pwr = (pierdata[lo].pwrPdg[0][0] + pierdata[hi].pwrPdg[0][0]) / 2;
+ pwr /= 2; /* Convert to dB. */
+
+ /* Find power control digital-to-analog converter (PCDAC) value. */
+ pcdac = pierdata[hi].pcdac[0][0];
+ for (idx = 0; idx < AR9280_TX_GAIN_TABLE_SIZE - 1; idx++)
+ if (pcdac <= sc->tx_gain_tbl[idx])
+ break;
+ *txgain = idx;
+
+ DPRINTFN(3, ("fbin=%d lo=%d hi=%d pwr=%d pcdac=%d txgain=%d\n",
+ fbin, lo, hi, pwr, pcdac, idx));
+
+ /* Fill phase domain analog-to-digital converter (PDADC) table. */
+ for (i = 0; i < AR_NUM_PDADC_VALUES; i++)
+ pdadcs[i] = (i < pwr) ? 0x00 : 0xff;
+
+ for (i = 0; i < AR_PD_GAINS_IN_MASK; i++)
+ boundaries[i] = AR9280_PD_GAIN_BOUNDARY_DEFAULT;
+}
+
+void
+ar9280_spur_mitigate(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ const struct ar_spur_chan *spurchans;
+ int spur, bin, spur_delta_phase, spur_freq_sd, spur_subchannel_sd;
+ int spur_off, range, i;
+
+ /* NB: Always clear. */
+ AR_CLRBITS(sc, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+
+ range = (extc != NULL) ? 19 : 10;
+
+ spurchans = sc->ops.get_spur_chans(sc, IEEE80211_IS_CHAN_2GHZ(c));
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+ spur = spurchans[i].spurChan;
+ if (spur == AR_NO_SPUR)
+ return; /* XXX disable if it was enabled! */
+ spur /= 10;
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ spur += AR_BASE_FREQ_2GHZ;
+ else
+ spur += AR_BASE_FREQ_5GHZ;
+ spur -= c->ic_freq;
+ if (abs(spur) < range)
+ break;
+ }
+ if (i == AR_EEPROM_MODAL_SPURS)
+ return; /* XXX disable if it was enabled! */
+ DPRINTFN(2, ("enabling spur mitigation\n"));
+
+ AR_SETBITS(sc, AR_PHY_TIMING_CTRL4_0,
+ AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+ AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+ AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+ AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+
+ AR_WRITE(sc, AR_PHY_SPUR_REG,
+ AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+ AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+ AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+ AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+ SM(AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, AR_SPUR_RSSI_THRESH));
+
+ if (extc != NULL) {
+ spur_delta_phase = (spur * 262144) / 10;
+ if (spur < 0) {
+ spur_subchannel_sd = 1;
+ spur_off = spur + 10;
+ } else {
+ spur_subchannel_sd = 0;
+ spur_off = spur - 10;
+ }
+ } else {
+ spur_delta_phase = (spur * 524288) / 10;
+ spur_subchannel_sd = 0;
+ spur_off = spur;
+ }
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ spur_freq_sd = (spur_off * 2048) / 44;
+ else
+ spur_freq_sd = (spur_off * 2048) / 40;
+
+ AR_WRITE(sc, AR_PHY_TIMING11,
+ AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+ SM(AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd) |
+ SM(AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase));
+
+ AR_WRITE(sc, AR_PHY_SFCORR_EXT,
+ SM(AR_PHY_SFCORR_SPUR_SUBCHNL_SD, spur_subchannel_sd));
+ AR_WRITE_BARRIER(sc);
+
+ bin = spur * 320;
+ ar5008_set_viterbi_mask(sc, bin);
+}
+
+void
+ar9280_reset_rx_gain(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ const struct athn_gain *prog = sc->rx_gain;
+ const uint32_t *pvals;
+ int i;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ pvals = prog->vals_2g;
+ else
+ pvals = prog->vals_5g;
+ for (i = 0; i < prog->nregs; i++)
+ AR_WRITE(sc, prog->regs[i], pvals[i]);
+}
+
+void
+ar9280_reset_tx_gain(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ const struct athn_gain *prog = sc->tx_gain;
+ const uint32_t *pvals;
+ int i;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ pvals = prog->vals_2g;
+ else
+ pvals = prog->vals_5g;
+ for (i = 0; i < prog->nregs; i++)
+ AR_WRITE(sc, prog->regs[i], pvals[i]);
+}
+
+void
+ar9280_olpc_init(struct athn_softc *sc)
+{
+ uint32_t reg;
+ int i;
+
+ /* Save original Tx gain values. */
+ for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+ reg = AR_READ(sc, AR_PHY_TX_GAIN_TBL(i));
+ sc->tx_gain_tbl[i] = MS(reg, AR_PHY_TX_GAIN);
+ }
+ /* Initial Tx gain temperature compensation. */
+ sc->tcomp = 0;
+}
+
+void
+ar9280_olpc_temp_compensation(struct athn_softc *sc)
+{
+ const struct ar5416_eeprom *eep = sc->eep;
+ int8_t pdadc, txgain, tcomp;
+ uint32_t reg;
+ int i;
+
+ reg = AR_READ(sc, AR_PHY_TX_PWRCTRL4);
+ pdadc = MS(reg, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+ DPRINTFN(3, ("PD Avg Out=%d\n", pdadc));
+
+ if (sc->pdadc == 0 || pdadc == 0)
+ return; /* No frames transmitted yet. */
+
+ /* Compute Tx gain temperature compensation. */
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_20 &&
+ eep->baseEepHeader.dacHiPwrMode_5G)
+ tcomp = (pdadc - sc->pdadc + 4) / 8;
+ else
+ tcomp = (pdadc - sc->pdadc + 5) / 10;
+ DPRINTFN(3, ("OLPC temp compensation=%d\n", tcomp));
+
+ if (tcomp == sc->tcomp)
+ return; /* Don't rewrite the same values. */
+ sc->tcomp = tcomp;
+
+ /* Adjust Tx gain values. */
+ for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+ txgain = sc->tx_gain_tbl[i] - tcomp;
+ if (txgain < 0)
+ txgain = 0;
+ reg = AR_READ(sc, AR_PHY_TX_GAIN_TBL(i));
+ reg = RW(reg, AR_PHY_TX_GAIN, txgain);
+ AR_WRITE(sc, AR_PHY_TX_GAIN_TBL(i), reg);
+ }
+ AR_WRITE_BARRIER(sc);
+}
diff --git a/sys/dev/athn/ic/ar9280reg.h b/sys/dev/athn/ic/ar9280reg.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar9280reg.h
@@ -0,0 +1,624 @@
+/* $OpenBSD: ar9280reg.h,v 1.8 2019/02/01 16:15:07 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#include <dev/athn/athnreg.h>
+#include <dev/athn/athnvar.h>
+
+#define AR9280_MAX_CHAINS 2
+
+#define AR9280_PD_GAIN_BOUNDARY_DEFAULT 56
+
+#define AR9280_PHY_CCA_MIN_GOOD_VAL_2GHZ (-127)
+#define AR9280_PHY_CCA_MIN_GOOD_VAL_5GHZ (-122)
+#define AR9280_PHY_CCA_MAX_GOOD_VAL_2GHZ (-97)
+#define AR9280_PHY_CCA_MAX_GOOD_VAL_5GHZ (-102)
+
+#define AR9280_PHY_SYNTH_CONTROL 0x9874
+
+/* Bits for AR9280_PHY_SYNTH_CONTROL. */
+#define AR9280_BMODE 0x20000000
+#define AR9280_FRACMODE 0x10000000
+#define AR9280_AMODE_REFSEL_M 0x0c000000
+#define AR9280_AMODE_REFSEL_S 26
+
+/*
+ * NB: The AR9280 uses the same ROM layout than the AR5416.
+ */
+
+/* Macro to "pack" registers to 16-bit to save some .rodata space. */
+#define P(x) (x)
+
+/*
+ * AR9280 2.0 initialization values.
+ */
+static const uint16_t ar9280_2_0_regs[] = {
+ P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014),
+ P(0x0801c), P(0x08120), P(0x081d0), P(0x08318), P(0x09804),
+ P(0x09820), P(0x09824), P(0x09828), P(0x09834), P(0x09838),
+ P(0x09840), P(0x09844), P(0x09850), P(0x09858), P(0x0985c),
+ P(0x09860), P(0x09864), P(0x09868), P(0x0986c), P(0x09914),
+ P(0x09918), P(0x09924), P(0x09944), P(0x09960), P(0x0a960),
+ P(0x09964), P(0x0c968), P(0x099b8), P(0x099bc), P(0x099c0),
+ P(0x0a204), P(0x0a20c), P(0x0b20c), P(0x0a21c), P(0x0a230),
+ P(0x0a23c), P(0x0a250), P(0x0a358), P(0x0a388), P(0x0a3d8),
+ P(0x07894)
+};
+
+static const uint32_t ar9280_2_0_vals_5g20[] = {
+ 0x00000230, 0x00000168, 0x00000e60, 0x00000000, 0x03e803e8,
+ 0x128d8027, 0x08f04800, 0x00003210, 0x00003e80, 0x00000300,
+ 0x02020200, 0x01000e0e, 0x0a020001, 0x00000e0e, 0x00000007,
+ 0x206a022e, 0x0372161e, 0x6c4000e2, 0x7ec88d2e, 0x31395d5e,
+ 0x00048d18, 0x0001ce00, 0x5ac640d0, 0x06903081, 0x000007d0,
+ 0x0000000a, 0xd00a8a0b, 0xffbc1010, 0x00000010, 0x00000010,
+ 0x00000210, 0x000003b5, 0x0000001c, 0x00000a00, 0x05eea6d4,
+ 0x00000444, 0x00000014, 0x00000014, 0x1883800a, 0x00000000,
+ 0x13c88000, 0x001ff000, 0x7999aa02, 0x0c000000, 0x00000000,
+ 0x5a508000
+};
+
+static const uint32_t ar9280_2_0_vals_5g40[] = {
+ 0x00000460, 0x000002d0, 0x00001cc0, 0x00000000, 0x07d007d0,
+ 0x128d804f, 0x08f04800, 0x00003210, 0x00007d00, 0x000003c4,
+ 0x02020200, 0x01000e0e, 0x0a020001, 0x00000e0e, 0x00000007,
+ 0x206a022e, 0x0372161e, 0x6d4000e2, 0x7ec88d2e, 0x3139605e,
+ 0x00048d18, 0x0001ce00, 0x5ac640d0, 0x06903081, 0x00000fa0,
+ 0x00000014, 0xd00a8a0b, 0xffbc1010, 0x00000010, 0x00000010,
+ 0x00000210, 0x000003b5, 0x0000001c, 0x00000a00, 0x05eea6d4,
+ 0x00000444, 0x00000014, 0x00000014, 0x1883800a, 0x00000000,
+ 0x13c88000, 0x001ff000, 0x7999aa02, 0x0c000000, 0x00000000,
+ 0x5a508000
+};
+
+static const uint32_t ar9280_2_0_vals_2g40[] = {
+ 0x000002c0, 0x00000318, 0x00007c70, 0x00000000, 0x10801600,
+ 0x12e00057, 0x08f04810, 0x0000320a, 0x00006880, 0x000003c4,
+ 0x02020200, 0x01000e0e, 0x0a020001, 0x00000e0e, 0x00000007,
+ 0x206a012e, 0x037216a0, 0x6d4000e2, 0x7ec84d2e, 0x3139605e,
+ 0x00048d20, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x00001130,
+ 0x00000268, 0xd00a8a0d, 0xffbc1010, 0x00000010, 0x00000010,
+ 0x00000210, 0x000003ce, 0x0000001c, 0x00000c00, 0x05eea6d4,
+ 0x00000444, 0x0001f019, 0x0001f019, 0x1883800a, 0x00000210,
+ 0x13c88001, 0x0004a000, 0x7999aa0e, 0x08000000, 0x00000000,
+ 0x5a508000
+};
+
+static const uint32_t ar9280_2_0_vals_2g20[] = {
+ 0x00000160, 0x0000018c, 0x00003e38, 0x00000000, 0x08400b00,
+ 0x12e0002b, 0x08f04810, 0x0000320a, 0x00003440, 0x00000300,
+ 0x02020200, 0x01000e0e, 0x0a020001, 0x00000e0e, 0x00000007,
+ 0x206a012e, 0x037216a0, 0x6c4000e2, 0x7ec84d2e, 0x31395d5e,
+ 0x00048d20, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x00000898,
+ 0x0000000b, 0xd00a8a0d, 0xffbc1010, 0x00000010, 0x00000010,
+ 0x00000210, 0x000003ce, 0x0000001c, 0x00000c00, 0x05eea6d4,
+ 0x00000444, 0x0001f019, 0x0001f019, 0x1883800a, 0x00000108,
+ 0x13c88000, 0x0004a000, 0x7999aa0e, 0x0c000000, 0x00000000,
+ 0x5a508000
+};
+
+static const uint16_t ar9280_2_0_cm_regs[] = {
+ P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044),
+ P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800),
+ P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814),
+ P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040),
+ P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054),
+ P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230),
+ P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8),
+ P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238),
+ P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378),
+ P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8),
+ P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8),
+ P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738),
+ P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c),
+ P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc),
+ P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc),
+ P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c),
+ P(0x0147c), P(0x04030), P(0x0403c), P(0x04024), P(0x04060),
+ P(0x04064), P(0x07010), P(0x07034), P(0x07038), P(0x08004),
+ P(0x08008), P(0x0800c), P(0x08018), P(0x08020), P(0x08038),
+ P(0x0803c), P(0x08048), P(0x08054), P(0x08058), P(0x0805c),
+ P(0x08060), P(0x08064), P(0x08070), P(0x080c0), P(0x080c4),
+ P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4), P(0x080d8),
+ P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec), P(0x080f0),
+ P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100), P(0x08104),
+ P(0x08108), P(0x0810c), P(0x08110), P(0x08118), P(0x0811c),
+ P(0x08124), P(0x08128), P(0x0812c), P(0x08130), P(0x08134),
+ P(0x08138), P(0x0813c), P(0x08144), P(0x08168), P(0x0816c),
+ P(0x08170), P(0x08174), P(0x08178), P(0x0817c), P(0x081c0),
+ P(0x081ec), P(0x081f0), P(0x081f4), P(0x081f8), P(0x081fc),
+ P(0x08200), P(0x08204), P(0x08208), P(0x0820c), P(0x08210),
+ P(0x08214), P(0x08218), P(0x0821c), P(0x08220), P(0x08224),
+ P(0x08228), P(0x0822c), P(0x08230), P(0x08234), P(0x08238),
+ P(0x0823c), P(0x08240), P(0x08244), P(0x08248), P(0x0824c),
+ P(0x08250), P(0x08254), P(0x08258), P(0x0825c), P(0x08260),
+ P(0x08264), P(0x08270), P(0x08274), P(0x08278), P(0x0827c),
+ P(0x08284), P(0x08288), P(0x0828c), P(0x08294), P(0x08298),
+ P(0x0829c), P(0x08300), P(0x08314), P(0x08328), P(0x0832c),
+ P(0x08330), P(0x08334), P(0x08338), P(0x0833c), P(0x08340),
+ P(0x08344), P(0x09808), P(0x0980c), P(0x09810), P(0x09814),
+ P(0x0981c), P(0x0982c), P(0x09830), P(0x0983c), P(0x0984c),
+ P(0x0a84c), P(0x09854), P(0x09900), P(0x09904), P(0x09908),
+ P(0x0990c), P(0x09910), P(0x0991c), P(0x09920), P(0x0a920),
+ P(0x09928), P(0x0992c), P(0x09934), P(0x09938), P(0x0993c),
+ P(0x09948), P(0x0994c), P(0x09954), P(0x09958), P(0x09940),
+ P(0x0c95c), P(0x09970), P(0x09974), P(0x09978), P(0x0997c),
+ P(0x09980), P(0x09984), P(0x09988), P(0x0998c), P(0x09990),
+ P(0x09994), P(0x09998), P(0x0999c), P(0x099a0), P(0x099a4),
+ P(0x099a8), P(0x099ac), P(0x099b0), P(0x099b4), P(0x099c4),
+ P(0x099c8), P(0x099cc), P(0x099d0), P(0x099d4), P(0x099d8),
+ P(0x099dc), P(0x099e0), P(0x099e4), P(0x099e8), P(0x099ec),
+ P(0x099f0), P(0x099fc), P(0x0a208), P(0x0a210), P(0x0a214),
+ P(0x0a218), P(0x0a220), P(0x0a224), P(0x0a228), P(0x0a22c),
+ P(0x0a234), P(0x0a238), P(0x0a240), P(0x0a244), P(0x0a248),
+ P(0x0a24c), P(0x0a254), P(0x0a258), P(0x0a25c), P(0x0a260),
+ P(0x0a268), P(0x0a26c), P(0x0b26c), P(0x0d270), P(0x0a278),
+ P(0x0d35c), P(0x0d360), P(0x0d364), P(0x0d368), P(0x0d36c),
+ P(0x0d370), P(0x0d374), P(0x0d378), P(0x0d37c), P(0x0d380),
+ P(0x0d384), P(0x0a38c), P(0x0a390), P(0x0a394), P(0x0a398),
+ P(0x0a39c), P(0x0a3a0), P(0x0a3a4), P(0x0a3a8), P(0x0a3ac),
+ P(0x0a3b0), P(0x0a3b4), P(0x0a3b8), P(0x0a3bc), P(0x0a3c0),
+ P(0x0a3c4), P(0x0a3c8), P(0x0a3cc), P(0x0a3d0), P(0x0a3d4),
+ P(0x0a3dc), P(0x0a3e0), P(0x0a3e4), P(0x0a3e8), P(0x07800),
+ P(0x07804), P(0x07808), P(0x0780c), P(0x07810), P(0x07818),
+ P(0x07824), P(0x07828), P(0x0782c), P(0x07830), P(0x07834),
+ P(0x0783c), P(0x07848), P(0x0784c), P(0x07850), P(0x07854),
+ P(0x07858), P(0x07860), P(0x07864), P(0x07868), P(0x0786c),
+ P(0x07870), P(0x07874), P(0x07878), P(0x0787c), P(0x07880),
+ P(0x07884), P(0x07888), P(0x0788c), P(0x07890), P(0x07898)
+};
+
+static const uint32_t ar9280_2_0_cm_vals[] = {
+ 0x00000000, 0x00020015, 0x00000005, 0x00000000, 0x00000008,
+ 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000002, 0x00000002, 0x0000001f, 0x00000000,
+ 0x00000000, 0x00000033, 0x00000002, 0x000004c2, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000700, 0x00000000, 0x00000000,
+ 0x00000000, 0x40000000, 0x00000000, 0x00000000, 0x000fc78f,
+ 0x0000000f, 0x00000000, 0x00000000, 0x2a80001a, 0x05dc01e0,
+ 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000, 0x00400000,
+ 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00000001,
+ 0x00000052, 0x00000000, 0x00000168, 0x000100aa, 0x00003210,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000,
+ 0x32143320, 0xfaa4fa50, 0x00000100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00100000, 0x0010f400, 0x00000100, 0x0001e800,
+ 0x00000000, 0x00000000, 0x00000000, 0x400000ff, 0x00080922,
+ 0x88a00010, 0x00000000, 0x40000000, 0x003e4180, 0x00000000,
+ 0x0000002c, 0x0000002c, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00000007,
+ 0x00000302, 0x00000e00, 0x00ff0000, 0x00000000, 0x000107ff,
+ 0x00481043, 0x00000000, 0xafa68e30, 0xfd14e000, 0x9c0a9f6b,
+ 0x00000000, 0x0000a000, 0x00000000, 0x00200400, 0x0040233c,
+ 0x0040233c, 0x00000044, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x01002310, 0x10000fff, 0x04900000, 0x04900000,
+ 0x00000001, 0x00000004, 0x1e1f2022, 0x0a0b0c0d, 0x00000000,
+ 0x9280c00a, 0x00020028, 0x5f3ca3de, 0x2108ecff, 0x14750604,
+ 0x004b6a8e, 0x190fb514, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+ 0x201fff00, 0x006f0000, 0x03051000, 0x00000820, 0x06336f77,
+ 0x6af6532f, 0x08f186c8, 0x00046384, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xaaaaaaaa, 0x3c466478, 0x0cc80caa,
+ 0x00000000, 0x00001042, 0x803e4788, 0x4080a333, 0x40206c10,
+ 0x009c4060, 0x01834061, 0x00000400, 0x000003b5, 0x233f7180,
+ 0x20202020, 0x20202020, 0x38490a20, 0x00007bb6, 0x0fff3ffc,
+ 0x00000000, 0x00000000, 0x0cdbd380, 0x0f0f0f01, 0xdfa91f01,
+ 0x00000000, 0x0e79e5c6, 0x0e79e5c6, 0x00820820, 0x1ce739ce,
+ 0x07ffffef, 0x0fffffe7, 0x17ffffe5, 0x1fffffe4, 0x37ffffe3,
+ 0x3fffffe3, 0x57ffffe3, 0x5fffffe2, 0x7fffffe2, 0x7f3c7bba,
+ 0xf3307ff0, 0x20202020, 0x20202020, 0x1ce739ce, 0x000001ce,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000246, 0x20202020, 0x20202020, 0x20202020,
+ 0x1ce739ce, 0x000001ce, 0x00000000, 0x18c43433, 0x00040000,
+ 0xdb005012, 0x04924914, 0x21084210, 0x6d801300, 0x07e41000,
+ 0x00040000, 0xdb005012, 0x04924914, 0x21084210, 0x6d801300,
+ 0x07e40000, 0x00100000, 0x773f0567, 0x54214514, 0x12035828,
+ 0x9259269a, 0x52802000, 0x0a8e370e, 0xc0102850, 0x812d4000,
+ 0x807ec400, 0x001b6db0, 0x00376b63, 0x06db6db6, 0x006d8000,
+ 0xffeffffe, 0xffeffffe, 0x00010000, 0x02060aeb, 0x2a850160
+};
+
+static const uint16_t ar9280_2_0_fast_clock_regs[] = {
+ P(0x01030), P(0x01070), P(0x010b0), P(0x08014), P(0x0801c),
+ P(0x08318), P(0x09820), P(0x09824), P(0x09828), P(0x09834),
+ P(0x09844), P(0x09914), P(0x09918)
+};
+
+static const uint32_t ar9280_2_0_fast_clock_vals_5g20[] = {
+ 0x00000268, 0x0000018c, 0x00000fd0, 0x044c044c, 0x148ec02b,
+ 0x000044c0, 0x02020200, 0x01000f0f, 0x0b020001, 0x00000f0f,
+ 0x03721821, 0x00000898, 0x0000000b
+};
+
+static const uint32_t ar9280_2_0_fast_clock_vals_5g40[] = {
+ 0x000004d0, 0x00000318, 0x00001fa0, 0x08980898, 0x148ec057,
+ 0x00008980, 0x02020200, 0x01000f0f, 0x0b020001, 0x00000f0f,
+ 0x03721821, 0x00001130, 0x00000016
+};
+
+static const struct athn_ini ar9280_2_0_ini = {
+ nitems(ar9280_2_0_regs),
+ ar9280_2_0_regs,
+ ar9280_2_0_vals_5g20,
+ ar9280_2_0_vals_5g40,
+ ar9280_2_0_vals_2g40,
+ ar9280_2_0_vals_2g20,
+ nitems(ar9280_2_0_cm_regs),
+ ar9280_2_0_cm_regs,
+ ar9280_2_0_cm_vals,
+ nitems(ar9280_2_0_fast_clock_regs),
+ ar9280_2_0_fast_clock_regs,
+ ar9280_2_0_fast_clock_vals_5g20,
+ ar9280_2_0_fast_clock_vals_5g40
+};
+
+/*
+ * AR9280 2.0 Tx gains.
+ */
+static const uint16_t ar9280_2_0_tx_gain_regs[] = {
+ P(0x0a274), P(0x0a27c), P(0x0a300), P(0x0a304), P(0x0a308),
+ P(0x0a30c), P(0x0a310), P(0x0a314), P(0x0a318), P(0x0a31c),
+ P(0x0a320), P(0x0a324), P(0x0a328), P(0x0a32c), P(0x0a330),
+ P(0x0a334), P(0x0a338), P(0x0a33c), P(0x0a340), P(0x0a344),
+ P(0x0a348), P(0x0a34c), P(0x0a350), P(0x0a354), P(0x0a3ec),
+ P(0x07814), P(0x07838), P(0x0781c), P(0x07840), P(0x07820),
+ P(0x07844)
+};
+
+static const uint32_t ar9280_2_0_tx_gain_vals_5g[] = {
+ 0x0a19c652, 0x050701ce, 0x00000000, 0x00003002, 0x00006004,
+ 0x0000a006, 0x0000e012, 0x00011014, 0x0001504a, 0x0001904c,
+ 0x0001c04e, 0x00020092, 0x0002410a, 0x0002710c, 0x0002b18b,
+ 0x0002e1cc, 0x000321ec, 0x000321ec, 0x000321ec, 0x000321ec,
+ 0x000321ec, 0x000321ec, 0x000321ec, 0x000321ec, 0x00f70081,
+ 0x0019beff, 0x0019beff, 0x00392000, 0x00392000, 0x92592480,
+ 0x92592480
+};
+
+static const uint32_t ar9280_2_0_tx_gain_vals_2g[] = {
+ 0x0a1aa652, 0x050701ce, 0x00000000, 0x00003002, 0x00008009,
+ 0x0000b00b, 0x0000e012, 0x00012048, 0x0001604a, 0x0001a211,
+ 0x0001e213, 0x0002121b, 0x00024412, 0x00028414, 0x0002b44a,
+ 0x00030649, 0x0003364b, 0x00038a49, 0x0003be48, 0x0003ee4a,
+ 0x00042e88, 0x00046e8a, 0x00049ec9, 0x0004bf42, 0x00f70081,
+ 0x0019beff, 0x0019beff, 0x00392000, 0x00392000, 0x92592480,
+ 0x92592480
+};
+
+static const struct athn_gain ar9280_2_0_tx_gain = {
+ nitems(ar9280_2_0_tx_gain_regs),
+ ar9280_2_0_tx_gain_regs,
+ ar9280_2_0_tx_gain_vals_5g,
+ ar9280_2_0_tx_gain_vals_2g
+};
+
+static const uint32_t ar9280_2_0_tx_gain_high_power_vals_5g[] = {
+ 0x0a19e652, 0x050739ce, 0x00000000, 0x00003002, 0x00006004,
+ 0x0000a006, 0x0000e012, 0x00011014, 0x0001504a, 0x0001904c,
+ 0x0001c04e, 0x00021092, 0x0002510a, 0x0002910c, 0x0002c18b,
+ 0x0002f1cc, 0x000321eb, 0x000341ec, 0x000341ec, 0x000341ec,
+ 0x000341ec, 0x000341ec, 0x000341ec, 0x000341ec, 0x00f70081,
+ 0x00198eff, 0x00198eff, 0x00172000, 0x00172000, 0xf258a480,
+ 0xf258a480
+};
+
+static const uint32_t ar9280_2_0_tx_gain_high_power_vals_2g[] = {
+ 0x0a1aa652, 0x050739ce, 0x00000000, 0x00004002, 0x00007008,
+ 0x0000c010, 0x00010012, 0x00013014, 0x0001820a, 0x0001b211,
+ 0x0001e213, 0x00022411, 0x00025413, 0x00029811, 0x0002c813,
+ 0x00030a14, 0x00035a50, 0x00039c4c, 0x0003de8a, 0x00042e92,
+ 0x00046ed2, 0x0004bed5, 0x0004ff54, 0x00055fd5, 0x00f70081,
+ 0x00198eff, 0x00198eff, 0x00172000, 0x00172000, 0xf258a480,
+ 0xf258a480
+};
+
+static const struct athn_gain ar9280_2_0_tx_gain_high_power = {
+ nitems(ar9280_2_0_tx_gain_regs),
+ ar9280_2_0_tx_gain_regs,
+ ar9280_2_0_tx_gain_high_power_vals_5g,
+ ar9280_2_0_tx_gain_high_power_vals_2g
+};
+
+/*
+ * AR9280 2.0 Rx gains.
+ */
+static const uint16_t ar9280_2_0_rx_gain_regs[] = {
+ P(0x09a00), P(0x09a04), P(0x09a08), P(0x09a0c), P(0x09a10),
+ P(0x09a14), P(0x09a18), P(0x09a1c), P(0x09a20), P(0x09a24),
+ P(0x09a28), P(0x09a2c), P(0x09a30), P(0x09a34), P(0x09a38),
+ P(0x09a3c), P(0x09a40), P(0x09a44), P(0x09a48), P(0x09a4c),
+ P(0x09a50), P(0x09a54), P(0x09a58), P(0x09a5c), P(0x09a60),
+ P(0x09a64), P(0x09a68), P(0x09a6c), P(0x09a70), P(0x09a74),
+ P(0x09a78), P(0x09a7c), P(0x09a80), P(0x09a84), P(0x09a88),
+ P(0x09a8c), P(0x09a90), P(0x09a94), P(0x09a98), P(0x09a9c),
+ P(0x09aa0), P(0x09aa4), P(0x09aa8), P(0x09aac), P(0x09ab0),
+ P(0x09ab4), P(0x09ab8), P(0x09abc), P(0x09ac0), P(0x09ac4),
+ P(0x09ac8), P(0x09acc), P(0x09ad0), P(0x09ad4), P(0x09ad8),
+ P(0x09adc), P(0x09ae0), P(0x09ae4), P(0x09ae8), P(0x09aec),
+ P(0x09af0), P(0x09af4), P(0x09af8), P(0x09afc), P(0x09b00),
+ P(0x09b04), P(0x09b08), P(0x09b0c), P(0x09b10), P(0x09b14),
+ P(0x09b18), P(0x09b1c), P(0x09b20), P(0x09b24), P(0x09b28),
+ P(0x09b2c), P(0x09b30), P(0x09b34), P(0x09b38), P(0x09b3c),
+ P(0x09b40), P(0x09b44), P(0x09b48), P(0x09b4c), P(0x09b50),
+ P(0x09b54), P(0x09b58), P(0x09b5c), P(0x09b60), P(0x09b64),
+ P(0x09b68), P(0x09b6c), P(0x09b70), P(0x09b74), P(0x09b78),
+ P(0x09b7c), P(0x09b80), P(0x09b84), P(0x09b88), P(0x09b8c),
+ P(0x09b90), P(0x09b94), P(0x09b98), P(0x09b9c), P(0x09ba0),
+ P(0x09ba4), P(0x09ba8), P(0x09bac), P(0x09bb0), P(0x09bb4),
+ P(0x09bb8), P(0x09bbc), P(0x09bc0), P(0x09bc4), P(0x09bc8),
+ P(0x09bcc), P(0x09bd0), P(0x09bd4), P(0x09bd8), P(0x09bdc),
+ P(0x09be0), P(0x09be4), P(0x09be8), P(0x09bec), P(0x09bf0),
+ P(0x09bf4), P(0x09bf8), P(0x09bfc), P(0x09848), P(0x0a848)
+};
+
+static const uint32_t ar9280_2_0_rx_gain_vals_5g[] = {
+ 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194,
+ 0x00008200, 0x00008204, 0x00008208, 0x0000820c, 0x00008210,
+ 0x00008214, 0x00008280, 0x00008284, 0x00008288, 0x0000828c,
+ 0x00008290, 0x00008300, 0x00008304, 0x00008308, 0x0000830c,
+ 0x00008310, 0x00008314, 0x00008380, 0x00008384, 0x00008388,
+ 0x0000838c, 0x00008390, 0x00008394, 0x0000a380, 0x0000a384,
+ 0x0000a388, 0x0000a38c, 0x0000a390, 0x0000a394, 0x0000a780,
+ 0x0000a784, 0x0000a788, 0x0000a78c, 0x0000a790, 0x0000a794,
+ 0x0000ab84, 0x0000ab88, 0x0000ab8c, 0x0000ab90, 0x0000ab94,
+ 0x0000af80, 0x0000af84, 0x0000af88, 0x0000af8c, 0x0000af90,
+ 0x0000af94, 0x0000b380, 0x0000b384, 0x0000b388, 0x0000b38c,
+ 0x0000b390, 0x0000b394, 0x0000b398, 0x0000b780, 0x0000b784,
+ 0x0000b788, 0x0000b78c, 0x0000b790, 0x0000b794, 0x0000b798,
+ 0x0000d784, 0x0000d788, 0x0000d78c, 0x0000d790, 0x0000f780,
+ 0x0000f784, 0x0000f788, 0x0000f78c, 0x0000f790, 0x0000f794,
+ 0x0000f7a4, 0x0000f7a8, 0x0000f7ac, 0x0000f7b0, 0x0000f7b4,
+ 0x0000f7a1, 0x0000f7a5, 0x0000f7a9, 0x0000f7ad, 0x0000f7b1,
+ 0x0000f7b5, 0x0000f7c5, 0x0000f7c9, 0x0000f7cd, 0x0000f7d1,
+ 0x0000f7d5, 0x0000f7c2, 0x0000f7c6, 0x0000f7ca, 0x0000f7ce,
+ 0x0000f7d2, 0x0000f7d6, 0x0000f7c3, 0x0000f7c7, 0x0000f7cb,
+ 0x0000f7d3, 0x0000f7d7, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x00001066, 0x00001066
+};
+
+static const uint32_t ar9280_2_0_rx_gain_vals_2g[] = {
+ 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000,
+ 0x00008000, 0x00008004, 0x00008008, 0x0000800c, 0x00008080,
+ 0x00008084, 0x00008088, 0x0000808c, 0x00008100, 0x00008104,
+ 0x00008108, 0x0000810c, 0x00008110, 0x00008114, 0x00008180,
+ 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194,
+ 0x000081a0, 0x0000820c, 0x000081a8, 0x00008284, 0x00008288,
+ 0x00008224, 0x00008290, 0x00008300, 0x00008304, 0x00008308,
+ 0x0000830c, 0x00008380, 0x00008384, 0x00008700, 0x00008704,
+ 0x00008708, 0x0000870c, 0x00008780, 0x00008784, 0x00008b00,
+ 0x00008b04, 0x00008b08, 0x00008b0c, 0x00008b80, 0x00008b84,
+ 0x00008b88, 0x00008b8c, 0x00008b90, 0x00008f80, 0x00008f84,
+ 0x00008f88, 0x00008f8c, 0x00008f90, 0x0000930c, 0x00009310,
+ 0x00009384, 0x00009388, 0x00009324, 0x00009704, 0x000096a4,
+ 0x000096a8, 0x00009710, 0x00009714, 0x00009720, 0x00009724,
+ 0x00009728, 0x0000972c, 0x000097a0, 0x000097a4, 0x000097a8,
+ 0x000097b0, 0x000097b4, 0x000097b8, 0x000097a5, 0x000097a9,
+ 0x000097ad, 0x000097b1, 0x000097b5, 0x000097b9, 0x000097c5,
+ 0x000097c9, 0x000097d1, 0x000097d5, 0x000097d9, 0x000097c6,
+ 0x000097ca, 0x000097ce, 0x000097d2, 0x000097d6, 0x000097c3,
+ 0x000097c7, 0x000097cb, 0x000097cf, 0x000097d7, 0x000097db,
+ 0x000097db, 0x000097db, 0x000097db, 0x000097db, 0x000097db,
+ 0x000097db, 0x000097db, 0x000097db, 0x000097db, 0x000097db,
+ 0x000097db, 0x000097db, 0x000097db, 0x000097db, 0x000097db,
+ 0x000097db, 0x000097db, 0x000097db, 0x000097db, 0x000097db,
+ 0x000097db, 0x000097db, 0x000097db, 0x000097db, 0x000097db,
+ 0x000097db, 0x000097db, 0x000097db, 0x00001063, 0x00001063
+};
+
+static const struct athn_gain ar9280_2_0_rx_gain = {
+ nitems(ar9280_2_0_rx_gain_regs),
+ ar9280_2_0_rx_gain_regs,
+ ar9280_2_0_rx_gain_vals_5g,
+ ar9280_2_0_rx_gain_vals_2g
+};
+
+static const uint32_t ar9280_2_0_rx_gain_13db_backoff_vals_5g[] = {
+ 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194,
+ 0x00008200, 0x00008204, 0x00008208, 0x0000820c, 0x00008210,
+ 0x00008214, 0x00008280, 0x00008284, 0x00008288, 0x0000828c,
+ 0x00008290, 0x00008300, 0x00008304, 0x00008308, 0x0000830c,
+ 0x00008310, 0x00008314, 0x00008380, 0x00008384, 0x00008388,
+ 0x0000838c, 0x00008390, 0x00008394, 0x0000a380, 0x0000a384,
+ 0x0000a388, 0x0000a38c, 0x0000a390, 0x0000a394, 0x0000a780,
+ 0x0000a784, 0x0000a788, 0x0000a78c, 0x0000a790, 0x0000a794,
+ 0x0000ab84, 0x0000ab88, 0x0000ab8c, 0x0000ab90, 0x0000ab94,
+ 0x0000af80, 0x0000af84, 0x0000af88, 0x0000af8c, 0x0000af90,
+ 0x0000af94, 0x0000b380, 0x0000b384, 0x0000b388, 0x0000b38c,
+ 0x0000b390, 0x0000b394, 0x0000b398, 0x0000b780, 0x0000b784,
+ 0x0000b788, 0x0000b78c, 0x0000b790, 0x0000b794, 0x0000b798,
+ 0x0000d784, 0x0000d788, 0x0000d78c, 0x0000d790, 0x0000f780,
+ 0x0000f784, 0x0000f788, 0x0000f78c, 0x0000f790, 0x0000f794,
+ 0x0000f7a4, 0x0000f7a8, 0x0000f7ac, 0x0000f7b0, 0x0000f7b4,
+ 0x0000f7a1, 0x0000f7a5, 0x0000f7a9, 0x0000f7ad, 0x0000f7b1,
+ 0x0000f7b5, 0x0000f7c5, 0x0000f7c9, 0x0000f7cd, 0x0000f7d1,
+ 0x0000f7d5, 0x0000f7c2, 0x0000f7c6, 0x0000f7ca, 0x0000f7ce,
+ 0x0000f7d2, 0x0000f7d6, 0x0000f7c3, 0x0000f7c7, 0x0000f7cb,
+ 0x0000f7d3, 0x0000f7d7, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x00001066, 0x00001066
+};
+
+static const uint32_t ar9280_2_0_rx_gain_13db_backoff_vals_2g[] = {
+ 0x00000290, 0x00000300, 0x00000304, 0x00000308, 0x0000030c,
+ 0x00008000, 0x00008004, 0x00008008, 0x0000800c, 0x00008080,
+ 0x00008084, 0x00008088, 0x0000808c, 0x00008100, 0x00008104,
+ 0x00008108, 0x0000810c, 0x00008110, 0x00008114, 0x00008180,
+ 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194,
+ 0x000081a0, 0x0000820c, 0x000081a8, 0x00008284, 0x00008288,
+ 0x00008224, 0x00008290, 0x00008300, 0x00008304, 0x00008308,
+ 0x0000830c, 0x00008380, 0x00008384, 0x00008700, 0x00008704,
+ 0x00008708, 0x0000870c, 0x00008780, 0x00008784, 0x00008b00,
+ 0x00008b04, 0x00008b08, 0x00008b0c, 0x00008b80, 0x00008b84,
+ 0x00008b88, 0x00008b8c, 0x00008b90, 0x00008f80, 0x00008f84,
+ 0x00008f88, 0x00008f8c, 0x00008f90, 0x00009310, 0x00009314,
+ 0x00009320, 0x00009324, 0x00009328, 0x0000932c, 0x00009330,
+ 0x00009334, 0x00009321, 0x00009325, 0x00009329, 0x0000932d,
+ 0x00009331, 0x00009335, 0x00009322, 0x00009326, 0x0000932a,
+ 0x0000932e, 0x00009332, 0x00009336, 0x00009323, 0x00009327,
+ 0x0000932b, 0x0000932f, 0x00009333, 0x00009337, 0x00009343,
+ 0x00009347, 0x0000934b, 0x0000934f, 0x00009353, 0x00009357,
+ 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b,
+ 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b,
+ 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b,
+ 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b,
+ 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b,
+ 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b,
+ 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b, 0x0000935b,
+ 0x0000935b, 0x0000935b, 0x0000935b, 0x0000105a, 0x0000105a
+};
+
+static const struct athn_gain ar9280_2_0_rx_gain_13db_backoff = {
+ nitems(ar9280_2_0_rx_gain_regs),
+ ar9280_2_0_rx_gain_regs,
+ ar9280_2_0_rx_gain_13db_backoff_vals_5g,
+ ar9280_2_0_rx_gain_13db_backoff_vals_2g
+};
+
+static const uint32_t ar9280_2_0_rx_gain_23db_backoff_vals_5g[] = {
+ 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194,
+ 0x00008200, 0x00008204, 0x00008208, 0x0000820c, 0x00008210,
+ 0x00008214, 0x00008280, 0x00008284, 0x00008288, 0x0000828c,
+ 0x00008290, 0x00008300, 0x00008304, 0x00008308, 0x0000830c,
+ 0x00008310, 0x00008314, 0x00008380, 0x00008384, 0x00008388,
+ 0x0000838c, 0x00008390, 0x00008394, 0x0000a380, 0x0000a384,
+ 0x0000a388, 0x0000a38c, 0x0000a390, 0x0000a394, 0x0000a780,
+ 0x0000a784, 0x0000a788, 0x0000a78c, 0x0000a790, 0x0000a794,
+ 0x0000ab84, 0x0000ab88, 0x0000ab8c, 0x0000ab90, 0x0000ab94,
+ 0x0000af80, 0x0000af84, 0x0000af88, 0x0000af8c, 0x0000af90,
+ 0x0000af94, 0x0000b380, 0x0000b384, 0x0000b388, 0x0000b38c,
+ 0x0000b390, 0x0000b394, 0x0000b398, 0x0000b780, 0x0000b784,
+ 0x0000b788, 0x0000b78c, 0x0000b790, 0x0000b794, 0x0000b798,
+ 0x0000d784, 0x0000d788, 0x0000d78c, 0x0000d790, 0x0000f780,
+ 0x0000f784, 0x0000f788, 0x0000f78c, 0x0000f790, 0x0000f794,
+ 0x0000f7a4, 0x0000f7a8, 0x0000f7ac, 0x0000f7b0, 0x0000f7b4,
+ 0x0000f7a1, 0x0000f7a5, 0x0000f7a9, 0x0000f7ad, 0x0000f7b1,
+ 0x0000f7b5, 0x0000f7c5, 0x0000f7c9, 0x0000f7cd, 0x0000f7d1,
+ 0x0000f7d5, 0x0000f7c2, 0x0000f7c6, 0x0000f7ca, 0x0000f7ce,
+ 0x0000f7d2, 0x0000f7d6, 0x0000f7c3, 0x0000f7c7, 0x0000f7cb,
+ 0x0000f7d3, 0x0000f7d7, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x0000f7db,
+ 0x0000f7db, 0x0000f7db, 0x0000f7db, 0x00001066, 0x00001066
+};
+
+static const uint32_t ar9280_2_0_rx_gain_23db_backoff_vals_2g[] = {
+ 0x00000290, 0x00000300, 0x00000304, 0x00000308, 0x0000030c,
+ 0x00008000, 0x00008004, 0x00008008, 0x0000800c, 0x00008080,
+ 0x00008084, 0x00008088, 0x0000808c, 0x00008100, 0x00008104,
+ 0x00008108, 0x0000810c, 0x00008110, 0x00008114, 0x00008180,
+ 0x00008184, 0x00008188, 0x0000818c, 0x00008190, 0x00008194,
+ 0x000081a0, 0x0000820c, 0x000081a8, 0x00008284, 0x00008288,
+ 0x00008224, 0x00008290, 0x00008300, 0x00008304, 0x00008308,
+ 0x0000830c, 0x00008380, 0x00008384, 0x00008700, 0x00008704,
+ 0x00008708, 0x0000870c, 0x00008780, 0x00008784, 0x00008b00,
+ 0x00008b04, 0x00008b08, 0x00008b0c, 0x00008b10, 0x00008b80,
+ 0x00008b84, 0x00008b88, 0x00008b8c, 0x00008b90, 0x00008b94,
+ 0x00008b98, 0x00008ba4, 0x00008ba8, 0x00008bac, 0x00008bb0,
+ 0x00008bb4, 0x00008ba1, 0x00008ba5, 0x00008ba9, 0x00008bad,
+ 0x00008bb1, 0x00008bb5, 0x00008ba2, 0x00008ba6, 0x00008baa,
+ 0x00008bae, 0x00008bb2, 0x00008bb6, 0x00008ba3, 0x00008ba7,
+ 0x00008bab, 0x00008baf, 0x00008bb3, 0x00008bb7, 0x00008bc3,
+ 0x00008bc7, 0x00008bcb, 0x00008bcf, 0x00008bd3, 0x00008bd7,
+ 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb,
+ 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb,
+ 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb,
+ 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb,
+ 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb,
+ 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb,
+ 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb,
+ 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00008bdb,
+ 0x00008bdb, 0x00008bdb, 0x00008bdb, 0x00001055, 0x00001055
+};
+
+static const struct athn_gain ar9280_2_0_rx_gain_23db_backoff = {
+ nitems(ar9280_2_0_rx_gain_regs),
+ ar9280_2_0_rx_gain_regs,
+ ar9280_2_0_rx_gain_23db_backoff_vals_5g,
+ ar9280_2_0_rx_gain_23db_backoff_vals_2g
+};
+
+/*
+ * Serializer/Deserializer programming.
+ */
+
+static const uint32_t ar9280_2_0_serdes_regs[] = {
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES2,
+};
+
+static const uint32_t ar9280_2_0_serdes_vals[] = {
+ 0x9248fd00,
+ 0x24924924,
+ 0xa8000019,
+ 0x13160820,
+ 0xe5980560,
+#ifdef ATHN_PCIE_CLKREQ
+ 0xc01dcffc,
+#else
+ 0xc01dcffd,
+#endif
+ 0x1aaabe41,
+ 0xbe105554,
+ 0x00043007,
+ 0x00000000
+};
+
+static const struct athn_serdes ar9280_2_0_serdes = {
+ nitems(ar9280_2_0_serdes_vals),
+ ar9280_2_0_serdes_regs,
+ ar9280_2_0_serdes_vals
+};
diff --git a/sys/dev/athn/ic/ar9285.c b/sys/dev/athn/ic/ar9285.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar9285.c
@@ -0,0 +1,958 @@
+/* $OpenBSD: ar9285.c,v 1.30 2022/01/09 05:42:38 jsg Exp $ */
+
+/*-
+ * Copyright (c) 2022 Farhan Khan <farhan@farhan.codes>
+ * Copyright (c) 2009-2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Driver for Atheros 802.11a/g/n chipsets.
+ * Routines for AR9285 and AR9271 chipsets.
+ */
+
+#include "opt_wlan.h"
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <dev/athn/ic/ar9280reg.h>
+
+#if 0
+#include "athn_usb.h"
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/timeout.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ra.h>
+#include <net80211/ieee80211_radiotap.h>
+#endif
+
+#include <dev/athn/athnreg.h>
+#include <dev/athn/athnvar.h>
+#include <dev/athn/ic/ar5008reg.h>
+#include <dev/athn/ic/ar9285reg.h>
+
+#if 0
+#include <dev/ic/ar5008reg.h>
+#include <dev/ic/ar9280reg.h>
+#include <dev/ic/ar9285reg.h>
+#endif
+
+int ar9285_attach(struct athn_softc *);
+void ar9285_setup(struct athn_softc *);
+void ar9285_swap_rom(struct athn_softc *);
+const struct ar_spur_chan *ar9285_get_spur_chans(struct athn_softc *, int);
+
+void ar9285_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9285_pa_calib(struct athn_softc *);
+void ar9271_pa_calib(struct athn_softc *);
+int ar9285_cl_cal(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9271_load_ani(struct athn_softc *);
+int ar9285_init_calib(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9285_get_pdadcs(struct athn_softc *, struct ieee80211_channel *,
+ int, uint8_t, uint8_t *, uint8_t *);
+void ar9285_set_power_calib(struct athn_softc *,
+ struct ieee80211_channel *);
+void ar9285_set_txpower(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+
+/* Extern functions. */
+#if 0
+uint8_t athn_chan2fbin(struct ieee80211_channel *);
+void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *);
+#endif
+int ar5008_attach(struct athn_softc *);
+#if 0
+void ar5008_write_txpower(struct athn_softc *, int16_t power[]);
+void ar5008_get_pdadcs(struct athn_softc *, uint8_t, struct athn_pier *,
+ struct athn_pier *, int, int, uint8_t, uint8_t *, uint8_t *);
+void ar5008_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *,
+ uint8_t, const struct ar_cal_target_power_leg *, int, uint8_t[]);
+void ar5008_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *,
+ uint8_t, const struct ar_cal_target_power_ht *, int, uint8_t[]);
+#endif
+int ar9280_set_synth(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9280_spur_mitigate(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+
+
+int
+ar9285_attach(struct athn_softc *sc)
+{
+ sc->eep_base = AR9285_EEP_START_LOC;
+ sc->eep_size = sizeof(struct ar9285_eeprom);
+ sc->ngpiopins = (sc->flags & ATHN_FLAG_USB) ? 16 : 12;
+ sc->led_pin = (sc->flags & ATHN_FLAG_USB) ? 15 : 1;
+ sc->workaround = AR9285_WA_DEFAULT;
+ sc->ops.setup = ar9285_setup;
+ sc->ops.swap_rom = ar9285_swap_rom;
+ sc->ops.init_from_rom = ar9285_init_from_rom;
+ sc->ops.set_txpower = ar9285_set_txpower;
+ sc->ops.set_synth = ar9280_set_synth;
+ sc->ops.spur_mitigate = ar9280_spur_mitigate;
+ sc->ops.get_spur_chans = ar9285_get_spur_chans;
+//#if NATHN_USB > 0
+ if (AR_SREV_9271(sc)) {
+ printf("Condition 1 %s:%s\n", __FILE__, __func__);
+ sc->cca_min_2g = AR9271_PHY_CCA_MIN_GOOD_VAL_2GHZ;
+ sc->cca_max_2g = AR9271_PHY_CCA_MAX_GOOD_VAL_2GHZ;
+ } else
+//#endif
+ {
+ printf("Condition 2 %s:%s\n", __FILE__, __func__);
+ sc->cca_min_2g = AR9285_PHY_CCA_MIN_GOOD_VAL_2GHZ;
+ sc->cca_max_2g = AR9285_PHY_CCA_MAX_GOOD_VAL_2GHZ;
+ }
+//#if NATHN_USB > 0
+ if (AR_SREV_9271(sc)) {
+ sc->ini = &ar9271_ini;
+ }
+ else {
+//#endif
+ sc->ini = &ar9285_1_2_ini;
+ }
+ sc->serdes = &ar9280_2_0_serdes;
+
+ return (ar5008_attach(sc));
+}
+
+void
+ar9285_setup(struct athn_softc *sc)
+{
+printf("Entering: %s\n", __func__);
+ const struct ar9285_eeprom *eep = sc->eep;
+ uint8_t type;
+
+ /* Select initialization values based on ROM. */
+ type = eep->baseEepHeader.txGainType;
+// DPRINTF(("Tx gain type=0x%x\n", type));
+//#if NATHN_USB > 0
+ if (AR_SREV_9271(sc)) {
+ if (type == AR_EEP_TXGAIN_HIGH_POWER)
+ sc->tx_gain = &ar9271_tx_gain_high_power;
+ else
+ sc->tx_gain = &ar9271_tx_gain;
+ } else
+//#endif /* NATHN_USB */
+ if ((AR_READ(sc, AR_AN_SYNTH9) & 0x7) == 0x1) { /* XE rev. */
+ if (type == AR_EEP_TXGAIN_HIGH_POWER)
+ sc->tx_gain = &ar9285_2_0_tx_gain_high_power;
+ else
+ sc->tx_gain = &ar9285_2_0_tx_gain;
+ } else {
+ if (type == AR_EEP_TXGAIN_HIGH_POWER)
+ sc->tx_gain = &ar9285_1_2_tx_gain_high_power;
+ else
+ sc->tx_gain = &ar9285_1_2_tx_gain;
+ }
+printf("Exiting: %s\n", __func__);
+}
+
+void
+ar9285_swap_rom(struct athn_softc *sc)
+{
+ printf("Unimplemented: %s\n", __func__);
+#if 0
+ struct ar9285_eeprom *eep = sc->eep;
+ int i;
+
+ eep->modalHeader.antCtrlCommon =
+ swap32(eep->modalHeader.antCtrlCommon);
+ eep->modalHeader.antCtrlChain =
+ swap32(eep->modalHeader.antCtrlChain);
+
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+ eep->modalHeader.spurChans[i].spurChan =
+ swap16(eep->modalHeader.spurChans[i].spurChan);
+ }
+#endif
+}
+
+const struct ar_spur_chan *
+ar9285_get_spur_chans(struct athn_softc *sc, int is2ghz)
+{
+ const struct ar9285_eeprom *eep = sc->eep;
+
+ KASSERT(is2ghz, ("is2ghz assertion error"));
+ return (eep->modalHeader.spurChans);
+}
+
+void
+ar9285_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ const struct ar9285_eeprom *eep = sc->eep;
+ const struct ar9285_modal_eep_header *modal = &eep->modalHeader;
+ uint32_t reg, offset = 0x1000;
+ uint8_t ob[5], db1[5], db2[5];
+ uint8_t txRxAtten;
+
+ printf("Start of ar9285_init_from_rom\n");
+ AR_WRITE(sc, AR_PHY_SWITCH_COM, modal->antCtrlCommon);
+ AR_WRITE(sc, AR_PHY_SWITCH_CHAIN_0, modal->antCtrlChain);
+
+ reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0);
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, modal->iqCalI);
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, modal->iqCalQ);
+ AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0, reg);
+
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_3) {
+ reg = AR_READ(sc, AR_PHY_GAIN_2GHZ);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+ modal->bswMargin);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+ modal->bswAtten);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+ modal->xatten2Margin);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+ modal->xatten2Db);
+ AR_WRITE(sc, AR_PHY_GAIN_2GHZ, reg);
+
+ /* Duplicate values of chain 0 for chain 1. */
+ reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+ modal->bswMargin);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+ modal->bswAtten);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+ modal->xatten2Margin);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+ modal->xatten2Db);
+ AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg);
+ }
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_3)
+ txRxAtten = modal->txRxAtten;
+ else /* Workaround for ROM versions < 14.3. */
+ txRxAtten = 23;
+ reg = AR_READ(sc, AR_PHY_RXGAIN);
+ reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAtten);
+ reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_MARGIN, modal->rxTxMargin);
+ AR_WRITE(sc, AR_PHY_RXGAIN, reg);
+
+ /* Duplicate values of chain 0 for chain 1. */
+ reg = AR_READ(sc, AR_PHY_RXGAIN + offset);
+ reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAtten);
+ reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_MARGIN, modal->rxTxMargin);
+ AR_WRITE(sc, AR_PHY_RXGAIN + offset, reg);
+
+ if (modal->version >= 3) {
+ /* Setup antenna diversity from ROM. */
+ reg = AR_READ(sc, AR_PHY_MULTICHAIN_GAIN_CTL);
+ reg = RW(reg, AR9285_PHY_ANT_DIV_CTL_ALL, 0);
+ reg = RW(reg, AR9285_PHY_ANT_DIV_CTL,
+ (modal->ob_234 >> 12) & 0x1);
+ reg = RW(reg, AR9285_PHY_ANT_DIV_ALT_LNACONF,
+ (modal->db1_234 >> 12) & 0x3);
+ reg = RW(reg, AR9285_PHY_ANT_DIV_MAIN_LNACONF,
+ (modal->db1_234 >> 14) & 0x3);
+ reg = RW(reg, AR9285_PHY_ANT_DIV_ALT_GAINTB,
+ (modal->ob_234 >> 13) & 0x1);
+ reg = RW(reg, AR9285_PHY_ANT_DIV_MAIN_GAINTB,
+ (modal->ob_234 >> 14) & 0x1);
+ AR_WRITE(sc, AR_PHY_MULTICHAIN_GAIN_CTL, reg);
+ reg = AR_READ(sc, AR_PHY_MULTICHAIN_GAIN_CTL); /* Flush. */
+
+ reg = AR_READ(sc, AR_PHY_CCK_DETECT);
+ if (modal->ob_234 & (1 << 15))
+ reg |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+ else
+ reg &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+ AR_WRITE(sc, AR_PHY_CCK_DETECT, reg);
+ reg = AR_READ(sc, AR_PHY_CCK_DETECT); /* Flush. */
+ }
+ if (modal->version >= 2) {
+ ob [0] = (modal->ob_01 >> 0) & 0xf;
+ ob [1] = (modal->ob_01 >> 4) & 0xf;
+ ob [2] = (modal->ob_234 >> 0) & 0xf;
+ ob [3] = (modal->ob_234 >> 4) & 0xf;
+ ob [4] = (modal->ob_234 >> 8) & 0xf;
+
+ db1[0] = (modal->db1_01 >> 0) & 0xf;
+ db1[1] = (modal->db1_01 >> 4) & 0xf;
+ db1[2] = (modal->db1_234 >> 0) & 0xf;
+ db1[3] = (modal->db1_234 >> 4) & 0xf;
+ db1[4] = (modal->db1_234 >> 8) & 0xf;
+
+ db2[0] = (modal->db2_01 >> 0) & 0xf;
+ db2[1] = (modal->db2_01 >> 4) & 0xf;
+ db2[2] = (modal->db2_234 >> 0) & 0xf;
+ db2[3] = (modal->db2_234 >> 4) & 0xf;
+ db2[4] = (modal->db2_234 >> 8) & 0xf;
+
+ } else if (modal->version == 1) {
+ ob [0] = (modal->ob_01 >> 0) & 0xf;
+ ob [1] = (modal->ob_01 >> 4) & 0xf;
+ /* Field ob_234 does not exist, use ob_01. */
+ ob [2] = ob [3] = ob [4] = ob [1];
+
+ db1[0] = (modal->db1_01 >> 0) & 0xf;
+ db1[1] = (modal->db1_01 >> 4) & 0xf;
+ /* Field db1_234 does not exist, use db1_01. */
+ db1[2] = db1[3] = db1[4] = db1[1];
+
+ db2[0] = (modal->db2_01 >> 0) & 0xf;
+ db2[1] = (modal->db2_01 >> 4) & 0xf;
+ /* Field db2_234 does not exist, use db2_01. */
+ db2[2] = db2[3] = db2[4] = db2[1];
+
+ } else {
+ ob [0] = modal->ob_01;
+ ob [1] = ob [2] = ob [3] = ob [4] = ob [0];
+
+ db1[0] = modal->db1_01;
+ db1[1] = db1[2] = db1[3] = db1[4] = db1[0];
+
+ /* Field db2_01 does not exist, use db1_01. */
+ db2[0] = modal->db1_01;
+ db2[1] = db2[2] = db2[3] = db2[4] = db2[0];
+ }
+printf("Set a flag to only do this if USB\n");
+//#if NATHN_USB > 0
+ if (AR_SREV_9271(sc)) {
+ reg = AR_READ(sc, AR9285_AN_RF2G3);
+ reg = RW(reg, AR9271_AN_RF2G3_OB_CCK, ob [0]);
+ reg = RW(reg, AR9271_AN_RF2G3_OB_PSK, ob [1]);
+ reg = RW(reg, AR9271_AN_RF2G3_OB_QAM, ob [2]);
+ reg = RW(reg, AR9271_AN_RF2G3_DB1, db1[0]);
+ AR_WRITE(sc, AR9285_AN_RF2G3, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+ reg = AR_READ(sc, AR9285_AN_RF2G4);
+ reg = RW(reg, AR9271_AN_RF2G4_DB2, db2[0]);
+ AR_WRITE(sc, AR9285_AN_RF2G4, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+ } else
+//#endif /* ATHN_USB */
+ {
+ reg = AR_READ(sc, AR9285_AN_RF2G3);
+ reg = RW(reg, AR9285_AN_RF2G3_OB_0, ob [0]);
+ reg = RW(reg, AR9285_AN_RF2G3_OB_1, ob [1]);
+ reg = RW(reg, AR9285_AN_RF2G3_OB_2, ob [2]);
+ reg = RW(reg, AR9285_AN_RF2G3_OB_3, ob [3]);
+ reg = RW(reg, AR9285_AN_RF2G3_OB_4, ob [4]);
+ reg = RW(reg, AR9285_AN_RF2G3_DB1_0, db1[0]);
+ reg = RW(reg, AR9285_AN_RF2G3_DB1_1, db1[1]);
+ reg = RW(reg, AR9285_AN_RF2G3_DB1_2, db1[2]);
+ AR_WRITE(sc, AR9285_AN_RF2G3, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+ reg = AR_READ(sc, AR9285_AN_RF2G4);
+ reg = RW(reg, AR9285_AN_RF2G4_DB1_3, db1[3]);
+ reg = RW(reg, AR9285_AN_RF2G4_DB1_4, db1[4]);
+ reg = RW(reg, AR9285_AN_RF2G4_DB2_0, db2[0]);
+ reg = RW(reg, AR9285_AN_RF2G4_DB2_1, db2[1]);
+ reg = RW(reg, AR9285_AN_RF2G4_DB2_2, db2[2]);
+ reg = RW(reg, AR9285_AN_RF2G4_DB2_3, db2[3]);
+ reg = RW(reg, AR9285_AN_RF2G4_DB2_4, db2[4]);
+ AR_WRITE(sc, AR9285_AN_RF2G4, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+ }
+
+ reg = AR_READ(sc, AR_PHY_SETTLING);
+ reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling);
+ AR_WRITE(sc, AR_PHY_SETTLING, reg);
+
+ reg = AR_READ(sc, AR_PHY_DESIRED_SZ);
+ reg = RW(reg, AR_PHY_DESIRED_SZ_ADC, modal->adcDesiredSize);
+ AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg);
+
+ reg = SM(AR_PHY_RF_CTL4_TX_END_XPAA_OFF, modal->txEndToXpaOff);
+ reg |= SM(AR_PHY_RF_CTL4_TX_END_XPAB_OFF, modal->txEndToXpaOff);
+ reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAA_ON, modal->txFrameToXpaOn);
+ reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAB_ON, modal->txFrameToXpaOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL4, reg);
+
+ reg = AR_READ(sc, AR_PHY_RF_CTL3);
+ reg = RW(reg, AR_PHY_TX_END_TO_A2_RX_ON, modal->txEndToRxOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL3, reg);
+
+ reg = AR_READ(sc, AR_PHY_CCA(0));
+ reg = RW(reg, AR9280_PHY_CCA_THRESH62, modal->thresh62);
+ AR_WRITE(sc, AR_PHY_CCA(0), reg);
+
+ reg = AR_READ(sc, AR_PHY_EXT_CCA0);
+ reg = RW(reg, AR_PHY_EXT_CCA0_THRESH62, modal->thresh62);
+ AR_WRITE(sc, AR_PHY_EXT_CCA0, reg);
+
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_2) {
+ reg = AR_READ(sc, AR_PHY_RF_CTL2);
+ reg = RW(reg, AR_PHY_TX_END_PA_ON,
+ modal->txFrameToPaOn);
+ reg = RW(reg, AR_PHY_TX_END_DATA_START,
+ modal->txFrameToDataStart);
+ AR_WRITE(sc, AR_PHY_RF_CTL2, reg);
+ }
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_3 && extc != NULL) {
+ reg = AR_READ(sc, AR_PHY_SETTLING);
+ reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->swSettleHt40);
+ AR_WRITE(sc, AR_PHY_SETTLING, reg);
+ }
+ AR_WRITE_BARRIER(sc);
+ printf("End of ar9285_init_from_rom\n");
+}
+
+void
+ar9285_pa_calib(struct athn_softc *sc)
+{
+ printf("Unimplemented: %s\n", __func__);
+#if 0
+ /* List of registers that need to be saved/restored. */
+ static const uint16_t regs[] = {
+ AR9285_AN_TOP3,
+ AR9285_AN_RXTXBB1,
+ AR9285_AN_RF2G1,
+ AR9285_AN_RF2G2,
+ AR9285_AN_TOP2,
+ AR9285_AN_RF2G8,
+ AR9285_AN_RF2G7
+ };
+ uint32_t svg[7], reg, ccomp_svg;
+ int i;
+
+ /* No PA calibration needed for high power solutions. */
+ if (AR_SREV_9285(sc) &&
+ ((struct ar9285_base_eep_header *)sc->eep)->txGainType ==
+ AR_EEP_TXGAIN_HIGH_POWER) /* XXX AR9287? */
+ return;
+
+ /* Save registers. */
+ for (i = 0; i < nitems(regs); i++)
+ svg[i] = AR_READ(sc, regs[i]);
+
+ AR_CLRBITS(sc, AR9285_AN_RF2G6, 1);
+ AR_SETBITS(sc, AR_PHY(2), 1 << 27);
+
+ AR_SETBITS(sc, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC);
+ AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1);
+ AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I);
+ AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF);
+ AR_CLRBITS(sc, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL);
+ AR_CLRBITS(sc, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB);
+ AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL);
+ /* Power down PA drivers. */
+ AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1);
+ AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2);
+ AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT);
+
+ reg = AR_READ(sc, AR9285_AN_RF2G8);
+ reg = RW(reg, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
+ AR_WRITE(sc, AR9285_AN_RF2G8, reg);
+
+ reg = AR_READ(sc, AR9285_AN_RF2G7);
+ reg = RW(reg, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
+ AR_WRITE(sc, AR9285_AN_RF2G7, reg);
+
+ reg = AR_READ(sc, AR9285_AN_RF2G6);
+ /* Save compensation capacitor value. */
+ ccomp_svg = MS(reg, AR9285_AN_RF2G6_CCOMP);
+ /* Program compensation capacitor for dynamic PA. */
+ reg = RW(reg, AR9285_AN_RF2G6_CCOMP, 0xf);
+ AR_WRITE(sc, AR9285_AN_RF2G6, reg);
+
+ AR_WRITE(sc, AR9285_AN_TOP2, AR9285_AN_TOP2_DEFAULT);
+ AR_WRITE_BARRIER(sc);
+ DELAY(30);
+
+ /* Clear offsets 6-1. */
+ AR_CLRBITS(sc, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS_6_1);
+ /* Clear offset 0. */
+ AR_CLRBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP);
+ /* Set offsets 6-1. */
+ for (i = 6; i >= 1; i--) {
+ AR_SETBITS(sc, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS(i));
+ AR_WRITE_BARRIER(sc);
+ DELAY(1);
+ if (AR_READ(sc, AR9285_AN_RF2G9) & AR9285_AN_RXTXBB1_SPARE9) {
+ AR_SETBITS(sc, AR9285_AN_RF2G6,
+ AR9285_AN_RF2G6_OFFS(i));
+ } else {
+ AR_CLRBITS(sc, AR9285_AN_RF2G6,
+ AR9285_AN_RF2G6_OFFS(i));
+ }
+ }
+ /* Set offset 0. */
+ AR_SETBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP);
+ AR_WRITE_BARRIER(sc);
+ DELAY(1);
+ if (AR_READ(sc, AR9285_AN_RF2G9) & AR9285_AN_RXTXBB1_SPARE9)
+ AR_SETBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP);
+ else
+ AR_CLRBITS(sc, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP);
+
+ AR_WRITE_BARRIER(sc);
+
+ AR_SETBITS(sc, AR9285_AN_RF2G6, 1);
+ AR_CLRBITS(sc, AR_PHY(2), 1 << 27);
+
+ /* Restore registers. */
+ for (i = 0; i < nitems(regs); i++)
+ AR_WRITE(sc, regs[i], svg[i]);
+
+ /* Restore compensation capacitor value. */
+ reg = AR_READ(sc, AR9285_AN_RF2G6);
+ reg = RW(reg, AR9285_AN_RF2G6_CCOMP, ccomp_svg);
+ AR_WRITE(sc, AR9285_AN_RF2G6, reg);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+ar9271_pa_calib(struct athn_softc *sc)
+{
+ printf("Unimplemented: %s\n", __func__);
+#if 0
+#if NATHN_USB > 0
+ /* List of registers that need to be saved/restored. */
+ static const uint16_t regs[] = {
+ AR9285_AN_TOP3,
+ AR9285_AN_RXTXBB1,
+ AR9285_AN_RF2G1,
+ AR9285_AN_RF2G2,
+ AR9285_AN_TOP2,
+ AR9285_AN_RF2G8,
+ AR9285_AN_RF2G7
+ };
+ uint32_t svg[7], reg, rf2g3_svg;
+ int i;
+
+ /* Save registers. */
+ for (i = 0; i < nitems(regs); i++)
+ svg[i] = AR_READ(sc, regs[i]);
+
+ AR_CLRBITS(sc, AR9285_AN_RF2G6, 1);
+ AR_SETBITS(sc, AR_PHY(2), 1 << 27);
+
+ AR_SETBITS(sc, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC);
+ AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1);
+ AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I);
+ AR_SETBITS(sc, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF);
+ AR_CLRBITS(sc, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL);
+ AR_CLRBITS(sc, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB);
+ AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL);
+ /* Power down PA drivers. */
+ AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1);
+ AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2);
+ AR_CLRBITS(sc, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT);
+
+ reg = AR_READ(sc, AR9285_AN_RF2G8);
+ reg = RW(reg, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
+ AR_WRITE(sc, AR9285_AN_RF2G8, reg);
+
+ reg = AR_READ(sc, AR9285_AN_RF2G7);
+ reg = RW(reg, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
+ AR_WRITE(sc, AR9285_AN_RF2G7, reg);
+
+ /* Save compensation capacitor value. */
+ reg = rf2g3_svg = AR_READ(sc, AR9285_AN_RF2G3);
+ /* Program compensation capacitor for dynamic PA. */
+ reg = RW(reg, AR9271_AN_RF2G3_CCOMP, 0xfff);
+ AR_WRITE(sc, AR9285_AN_RF2G3, reg);
+
+ AR_WRITE(sc, AR9285_AN_TOP2, AR9285_AN_TOP2_DEFAULT);
+ AR_WRITE_BARRIER(sc);
+ DELAY(30);
+
+ /* Clear offsets 6-0. */
+ AR_CLRBITS(sc, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS_6_0);
+ /* Set offsets 6-1. */
+ for (i = 6; i >= 1; i--) {
+ reg = AR_READ(sc, AR9285_AN_RF2G6);
+ reg |= AR9271_AN_RF2G6_OFFS(i);
+ AR_WRITE(sc, AR9285_AN_RF2G6, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(1);
+ if (!(AR_READ(sc, AR9285_AN_RF2G9) & AR9285_AN_RXTXBB1_SPARE9))
+ reg &= ~AR9271_AN_RF2G6_OFFS(i);
+ AR_WRITE(sc, AR9285_AN_RF2G6, reg);
+ }
+ AR_WRITE_BARRIER(sc);
+
+ AR_SETBITS(sc, AR9285_AN_RF2G6, 1);
+ AR_CLRBITS(sc, AR_PHY(2), 1 << 27);
+
+ /* Restore registers. */
+ for (i = 0; i < nitems(regs); i++)
+ AR_WRITE(sc, regs[i], svg[i]);
+
+ /* Restore compensation capacitor value. */
+ AR_WRITE(sc, AR9285_AN_RF2G3, rf2g3_svg);
+ AR_WRITE_BARRIER(sc);
+#endif /* NATHN_USB */
+#endif // Terminating for FreeBSD usage
+}
+
+/*
+ * Carrier Leakage Calibration.
+ */
+int
+ar9285_cl_cal(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("Unimplemented: %s\n", __func__);
+ return 0;
+#if 0
+ int ntries;
+
+ AR_SETBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ if (0 && extc == NULL) { /* XXX IS_CHAN_HT20!! */
+ AR_SETBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+ AR_SETBITS(sc, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+ AR_CLRBITS(sc, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_FLTR_CAL);
+ AR_CLRBITS(sc, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+ for (ntries = 0; ntries < 10000; ntries++) {
+ if (!(AR_READ(sc, AR_PHY_AGC_CONTROL) &
+ AR_PHY_AGC_CONTROL_CAL))
+ break;
+ DELAY(10);
+ }
+ if (ntries == 10000)
+ return (ETIMEDOUT);
+ AR_CLRBITS(sc, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+ AR_CLRBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+ AR_CLRBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ }
+ AR_CLRBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ AR_SETBITS(sc, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+ AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+ for (ntries = 0; ntries < 10000; ntries++) {
+ if (!(AR_READ(sc, AR_PHY_AGC_CONTROL) &
+ AR_PHY_AGC_CONTROL_CAL))
+ break;
+ DELAY(10);
+ }
+ if (ntries == 10000)
+ return (ETIMEDOUT);
+ AR_SETBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ AR_CLRBITS(sc, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ AR_WRITE_BARRIER(sc);
+ return (0);
+#endif
+}
+
+void
+ar9271_load_ani(struct athn_softc *sc)
+{
+ printf("Unimplemented: %s\n", __func__);
+#if 0
+#if NATHN_USB > 0
+ /* Write ANI registers. */
+ AR_WRITE(sc, AR_PHY_DESIRED_SZ, 0x6d4000e2);
+ AR_WRITE(sc, AR_PHY_AGC_CTL1, 0x3139605e);
+ AR_WRITE(sc, AR_PHY_FIND_SIG, 0x7ec84d2e);
+ AR_WRITE(sc, AR_PHY_SFCORR_LOW, 0x06903881);
+ AR_WRITE(sc, AR_PHY_SFCORR, 0x5ac640d0);
+ AR_WRITE(sc, AR_PHY_CCK_DETECT, 0x803e68c8);
+ AR_WRITE(sc, AR_PHY_TIMING5, 0xd00a8007);
+ AR_WRITE(sc, AR_PHY_SFCORR_EXT, 0x05eea6d4);
+ AR_WRITE_BARRIER(sc);
+#endif /* NATHN_USB */
+#endif
+}
+
+int
+ar9285_init_calib(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("Unimplemented: %s\n", __func__);
+ return 0;
+#if 0
+ uint32_t reg, mask, clcgain, rf2g5_svg;
+ int i, maxgain, nclcs, thresh, error;
+
+ /* Do carrier leakage calibration. */
+ if ((error = ar9285_cl_cal(sc, c, extc)) != 0)
+ return (error);
+
+ /* Workaround for high temperature is not applicable on AR9271. */
+ if (AR_SREV_9271(sc))
+ return (0);
+
+ mask = 0;
+ nclcs = 0;
+ reg = AR_READ(sc, AR_PHY_TX_PWRCTRL7);
+ maxgain = MS(reg, AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
+ for (i = 0; i <= maxgain; i++) {
+ reg = AR_READ(sc, AR_PHY_TX_GAIN_TBL(i));
+ clcgain = MS(reg, AR_PHY_TX_GAIN_CLC);
+ /* NB: clcgain <= 0xf. */
+ if (!(mask & (1 << clcgain))) {
+ mask |= 1 << clcgain;
+ nclcs++;
+ }
+ }
+ thresh = 0;
+ for (i = 0; i < nclcs; i++) {
+ reg = AR_READ(sc, AR_PHY_CLC_TBL(i));
+ if (MS(reg, AR_PHY_CLC_I0) == 0)
+ thresh++;
+ if (MS(reg, AR_PHY_CLC_Q0) == 0)
+ thresh++;
+ }
+ if (thresh <= AR9285_CL_CAL_REDO_THRESH)
+ return (0); /* No need to redo. */
+
+ /* Threshold reached, redo carrier leakage calibration. */
+ DPRINTFN(2, ("CLC threshold=%d\n", thresh));
+ rf2g5_svg = reg = AR_READ(sc, AR9285_AN_RF2G5);
+ if ((AR_READ(sc, AR_AN_SYNTH9) & 0x7) == 0x1) /* XE rev. */
+ reg = RW(reg, AR9285_AN_RF2G5_IC50TX, 0x5);
+ else
+ reg = RW(reg, AR9285_AN_RF2G5_IC50TX, 0x4);
+ AR_WRITE(sc, AR9285_AN_RF2G5, reg);
+ AR_WRITE_BARRIER(sc);
+ error = ar9285_cl_cal(sc, c, extc);
+ AR_WRITE(sc, AR9285_AN_RF2G5, rf2g5_svg);
+ AR_WRITE_BARRIER(sc);
+ return (error);
+#endif
+}
+
+void
+ar9285_get_pdadcs(struct athn_softc *sc, struct ieee80211_channel *c,
+ int nxpdgains, uint8_t overlap, uint8_t *boundaries, uint8_t *pdadcs)
+{
+ printf("Unimplemented: %s\n", __func__);
+#if 0
+ const struct ar9285_eeprom *eep = sc->eep;
+ const struct ar9285_cal_data_per_freq *pierdata;
+ const uint8_t *pierfreq;
+ struct athn_pier lopier, hipier;
+ uint8_t fbin;
+ int i, lo, hi, npiers;
+
+ pierfreq = eep->calFreqPier2G;
+ pierdata = eep->calPierData2G;
+ npiers = AR9285_NUM_2G_CAL_PIERS;
+
+ /* Find channel in ROM pier table. */
+ fbin = athn_chan2fbin(c);
+ athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi);
+
+ lopier.fbin = pierfreq[lo];
+ hipier.fbin = pierfreq[hi];
+ for (i = 0; i < nxpdgains; i++) {
+ lopier.pwr[i] = pierdata[lo].pwrPdg[i];
+ lopier.vpd[i] = pierdata[lo].vpdPdg[i];
+ hipier.pwr[i] = pierdata[lo].pwrPdg[i];
+ hipier.vpd[i] = pierdata[lo].vpdPdg[i];
+ }
+ ar5008_get_pdadcs(sc, fbin, &lopier, &hipier, nxpdgains,
+ AR9285_PD_GAIN_ICEPTS, overlap, boundaries, pdadcs);
+#endif
+}
+
+void
+ar9285_set_power_calib(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ printf("Unimplemented: %s\n", __func__);
+#if 0
+ const struct ar9285_eeprom *eep = sc->eep;
+ uint8_t boundaries[AR_PD_GAINS_IN_MASK];
+ uint8_t pdadcs[AR_NUM_PDADC_VALUES];
+ uint8_t xpdgains[AR9285_NUM_PD_GAINS];
+ uint8_t overlap;
+ uint32_t reg;
+ int i, nxpdgains;
+
+ if (sc->eep_rev < AR_EEP_MINOR_VER_2) {
+ overlap = MS(AR_READ(sc, AR_PHY_TPCRG5),
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP);
+ } else
+ overlap = eep->modalHeader.pdGainOverlap;
+
+ nxpdgains = 0;
+ memset(xpdgains, 0, sizeof(xpdgains));
+ for (i = AR9285_PD_GAINS_IN_MASK - 1; i >= 0; i--) {
+ if (nxpdgains >= AR9285_NUM_PD_GAINS)
+ break;
+ if (eep->modalHeader.xpdGain & (1 << i))
+ xpdgains[nxpdgains++] = i;
+ }
+ reg = AR_READ(sc, AR_PHY_TPCRG1);
+ reg = RW(reg, AR_PHY_TPCRG1_NUM_PD_GAIN, nxpdgains - 1);
+ reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_1, xpdgains[0]);
+ reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_2, xpdgains[1]);
+ AR_WRITE(sc, AR_PHY_TPCRG1, reg);
+
+ /* NB: No open loop power control for AR9285. */
+ ar9285_get_pdadcs(sc, c, nxpdgains, overlap, boundaries, pdadcs);
+
+ /* Write boundaries. */
+ reg = SM(AR_PHY_TPCRG5_PD_GAIN_OVERLAP, overlap);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1, boundaries[0]);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2, boundaries[1]);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3, boundaries[2]);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4, boundaries[3]);
+ AR_WRITE(sc, AR_PHY_TPCRG5, reg);
+
+ /* Write PDADC values. */
+ for (i = 0; i < AR_NUM_PDADC_VALUES; i += 4) {
+ AR_WRITE(sc, AR_PHY_PDADC_TBL_BASE + i,
+ pdadcs[i + 0] << 0 |
+ pdadcs[i + 1] << 8 |
+ pdadcs[i + 2] << 16 |
+ pdadcs[i + 3] << 24);
+ }
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+ar9285_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("Unimplemented: %s\n", __func__);
+#if 0
+ const struct ar9285_eeprom *eep = sc->eep;
+ const struct ar9285_modal_eep_header *modal = &eep->modalHeader;
+ uint8_t tpow_cck[4], tpow_ofdm[4];
+ uint8_t tpow_cck_ext[4], tpow_ofdm_ext[4];
+ uint8_t tpow_ht20[8], tpow_ht40[8];
+ uint8_t ht40inc;
+ int16_t max_ant_gain, power[ATHN_POWER_COUNT];
+ int i;
+
+ ar9285_set_power_calib(sc, c);
+
+ /* Compute transmit power reduction due to antenna gain. */
+ max_ant_gain = modal->antennaGain;
+ /* XXX */
+
+ /* Get CCK target powers. */
+ ar5008_get_lg_tpow(sc, c, AR_CTL_11B, eep->calTargetPowerCck,
+ AR9285_NUM_2G_CCK_TARGET_POWERS, tpow_cck);
+
+ /* Get OFDM target powers. */
+ ar5008_get_lg_tpow(sc, c, AR_CTL_11G, eep->calTargetPower2G,
+ AR9285_NUM_2G_20_TARGET_POWERS, tpow_ofdm);
+
+ /* Get HT-20 target powers. */
+ ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT20, eep->calTargetPower2GHT20,
+ AR9285_NUM_2G_20_TARGET_POWERS, tpow_ht20);
+
+ if (extc != NULL) {
+ /* Get HT-40 target powers. */
+ ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT40,
+ eep->calTargetPower2GHT40, AR9285_NUM_2G_40_TARGET_POWERS,
+ tpow_ht40);
+
+ /* Get secondary channel CCK target powers. */
+ ar5008_get_lg_tpow(sc, extc, AR_CTL_11B,
+ eep->calTargetPowerCck, AR9285_NUM_2G_CCK_TARGET_POWERS,
+ tpow_cck_ext);
+
+ /* Get secondary channel OFDM target powers. */
+ ar5008_get_lg_tpow(sc, extc, AR_CTL_11G,
+ eep->calTargetPower2G, AR9285_NUM_2G_20_TARGET_POWERS,
+ tpow_ofdm_ext);
+ }
+
+ memset(power, 0, sizeof(power));
+ /* Shuffle target powers across transmit rates. */
+ power[ATHN_POWER_OFDM6 ] =
+ power[ATHN_POWER_OFDM9 ] =
+ power[ATHN_POWER_OFDM12 ] =
+ power[ATHN_POWER_OFDM18 ] =
+ power[ATHN_POWER_OFDM24 ] = tpow_ofdm[0];
+ power[ATHN_POWER_OFDM36 ] = tpow_ofdm[1];
+ power[ATHN_POWER_OFDM48 ] = tpow_ofdm[2];
+ power[ATHN_POWER_OFDM54 ] = tpow_ofdm[3];
+ power[ATHN_POWER_XR ] = tpow_ofdm[0];
+ power[ATHN_POWER_CCK1_LP ] = tpow_cck[0];
+ power[ATHN_POWER_CCK2_LP ] =
+ power[ATHN_POWER_CCK2_SP ] = tpow_cck[1];
+ power[ATHN_POWER_CCK55_LP] =
+ power[ATHN_POWER_CCK55_SP] = tpow_cck[2];
+ power[ATHN_POWER_CCK11_LP] =
+ power[ATHN_POWER_CCK11_SP] = tpow_cck[3];
+ for (i = 0; i < nitems(tpow_ht20); i++)
+ power[ATHN_POWER_HT20(i)] = tpow_ht20[i];
+ if (extc != NULL) {
+ /* Correct PAR difference between HT40 and HT20/Legacy. */
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_2)
+ ht40inc = modal->ht40PowerIncForPdadc;
+ else
+ ht40inc = AR_HT40_POWER_INC_FOR_PDADC;
+ for (i = 0; i < nitems(tpow_ht40); i++)
+ power[ATHN_POWER_HT40(i)] = tpow_ht40[i] + ht40inc;
+ power[ATHN_POWER_OFDM_DUP] = tpow_ht40[0];
+ power[ATHN_POWER_CCK_DUP ] = tpow_ht40[0];
+ power[ATHN_POWER_OFDM_EXT] = tpow_ofdm_ext[0];
+ power[ATHN_POWER_CCK_EXT ] = tpow_cck_ext[0];
+ }
+
+ for (i = 0; i < ATHN_POWER_COUNT; i++) {
+ power[i] -= AR_PWR_TABLE_OFFSET_DB * 2; /* In half dB. */
+ if (power[i] > AR_MAX_RATE_POWER)
+ power[i] = AR_MAX_RATE_POWER;
+ }
+
+ /* Commit transmit power values to hardware. */
+ ar5008_write_txpower(sc, power);
+#endif
+}
diff --git a/sys/dev/athn/ic/ar9285reg.h b/sys/dev/athn/ic/ar9285reg.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar9285reg.h
@@ -0,0 +1,1082 @@
+/* $OpenBSD: ar9285reg.h,v 1.9 2019/02/01 16:15:07 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define AR9285_MAX_CHAINS 1
+
+#define AR9285_PHY_CCA_MIN_GOOD_VAL_2GHZ (-127)
+#define AR9285_PHY_CCA_MAX_GOOD_VAL_2GHZ (-108)
+#define AR9271_PHY_CCA_MIN_GOOD_VAL_2GHZ (-127)
+#define AR9271_PHY_CCA_MAX_GOOD_VAL_2GHZ (-116)
+
+#define AR9285_CL_CAL_REDO_THRESH 1
+
+/*
+ * Analog registers.
+ */
+#define AR9285_AN_RF2G1 0x7820
+#define AR9285_AN_RF2G2 0x7824
+#define AR9285_AN_RF2G3 0x7828
+#define AR9285_AN_RF2G4 0x782c
+#define AR9285_AN_RF2G5 0x7830
+#define AR9285_AN_RF2G6 0x7834
+#define AR9285_AN_RF2G7 0x7838
+#define AR9285_AN_RF2G8 0x783c
+#define AR9285_AN_RF2G9 0x7840
+#define AR9285_AN_RXTXBB1 0x7854
+#define AR9285_AN_TOP2 0x7868
+#define AR9285_AN_TOP3 0x786c
+#define AR9285_AN_TOP4 0x7870
+
+/* Bits for AR9285_AN_RF2G1. */
+#define AR9285_AN_RF2G1_ENPACAL 0x00000800
+#define AR9285_AN_RF2G1_PDPAOUT 0x00800000
+#define AR9285_AN_RF2G1_PDPADRV2 0x01000000
+#define AR9285_AN_RF2G1_PDPADRV1 0x02000000
+
+/* Bits for AR9285_AN_RF2G2. */
+#define AR9285_AN_RF2G2_OFFCAL 0x00001000
+
+/* Bits for AR9285_AN_RF2G3. */
+#define AR9285_AN_RF2G3_DB1_2_M 0x00000007
+#define AR9285_AN_RF2G3_DB1_2_S 0
+#define AR9285_AN_RF2G3_DB1_1_M 0x00000038
+#define AR9285_AN_RF2G3_DB1_1_S 3
+#define AR9285_AN_RF2G3_DB1_0_M 0x000001c0
+#define AR9285_AN_RF2G3_DB1_0_S 6
+#define AR9285_AN_RF2G3_OB_4_M 0x00000e00
+#define AR9285_AN_RF2G3_OB_4_S 9
+#define AR9285_AN_RF2G3_OB_3_M 0x00007000
+#define AR9285_AN_RF2G3_OB_3_S 12
+#define AR9285_AN_RF2G3_OB_2_M 0x00038000
+#define AR9285_AN_RF2G3_OB_2_S 15
+#define AR9285_AN_RF2G3_OB_1_M 0x001c0000
+#define AR9285_AN_RF2G3_OB_1_S 18
+#define AR9285_AN_RF2G3_OB_0_M 0x00e00000
+#define AR9285_AN_RF2G3_OB_0_S 21
+#define AR9285_AN_RF2G3_PDVCCOMP 0x02000000
+#define AR9271_AN_RF2G3_CCOMP_M 0x00000fff
+#define AR9271_AN_RF2G3_CCOMP_S 0
+#define AR9271_AN_RF2G3_OB_QAM_M 0x00007000
+#define AR9271_AN_RF2G3_OB_QAM_S 12
+#define AR9271_AN_RF2G3_OB_PSK_M 0x00038000
+#define AR9271_AN_RF2G3_OB_PSK_S 15
+#define AR9271_AN_RF2G3_OB_CCK_M 0x001c0000
+#define AR9271_AN_RF2G3_OB_CCK_S 18
+#define AR9271_AN_RF2G3_DB1_M 0x00e00000
+#define AR9271_AN_RF2G3_DB1_S 21
+
+/* Bits for AR9285_AN_RF2G4. */
+#define AR9285_AN_RF2G4_DB2_4_M 0x00003800
+#define AR9285_AN_RF2G4_DB2_4_S 11
+#define AR9285_AN_RF2G4_DB2_3_M 0x0001c000
+#define AR9285_AN_RF2G4_DB2_3_S 14
+#define AR9285_AN_RF2G4_DB2_2_M 0x000e0000
+#define AR9285_AN_RF2G4_DB2_2_S 17
+#define AR9285_AN_RF2G4_DB2_1_M 0x00700000
+#define AR9285_AN_RF2G4_DB2_1_S 20
+#define AR9285_AN_RF2G4_DB2_0_M 0x03800000
+#define AR9285_AN_RF2G4_DB2_0_S 23
+#define AR9285_AN_RF2G4_DB1_4_M 0x1c000000
+#define AR9285_AN_RF2G4_DB1_4_S 26
+#define AR9285_AN_RF2G4_DB1_3_M 0xe0000000
+#define AR9285_AN_RF2G4_DB1_3_S 29
+#define AR9271_AN_RF2G4_DB2_M 0xe0000000
+#define AR9271_AN_RF2G4_DB2_S 29
+
+/* Bits for AR9285_AN_RF2G5. */
+#define AR9285_AN_RF2G5_IC50TX_M 0x00000700
+#define AR9285_AN_RF2G5_IC50TX_S 8
+
+/* Bits for AR9285_AN_RF2G6. */
+#define AR9285_AN_RF2G6_CCOMP_M 0x00007800
+#define AR9285_AN_RF2G6_CCOMP_S 11
+#define AR9285_AN_RF2G6_OFFS_6_1 0x03f00000
+#define AR9285_AN_RF2G6_OFFS(i) (1 << (19 + (i)))
+#define AR9271_AN_RF2G6_OFFS_6_0 0x07f00000
+#define AR9271_AN_RF2G6_OFFS(i) (1 << (20 + (i)))
+
+/* Bits for AR9285_AN_RF2G7. */
+#define AR9285_AN_RF2G7_PWDDB 0x00000002
+#define AR9285_AN_RF2G7_PADRVGN2TAB0_M 0xe0000000
+#define AR9285_AN_RF2G7_PADRVGN2TAB0_S 29
+
+/* Bits for AR9285_AN_RF2G8. */
+#define AR9285_AN_RF2G8_PADRVGN2TAB0_M 0x0001c000
+#define AR9285_AN_RF2G8_PADRVGN2TAB0_S 14
+
+/* Bits for AR9285_AN_RXTXBB1. */
+#define AR9285_AN_RXTXBB1_SPARE9 0x00000001
+#define AR9285_AN_RXTXBB1_PDRXTXBB1 0x00000020
+#define AR9285_AN_RXTXBB1_PDV2I 0x00000080
+#define AR9285_AN_RXTXBB1_PDDACIF 0x00000100
+
+/* Bits for AR9285_AN_TOP2. */
+#define AR9285_AN_TOP2_DEFAULT 0xca0358a0 /* XXX magic */
+
+/* Bits for AR9285_AN_TOP3. */
+#define AR9285_AN_TOP3_XPABIAS_LVL_M 0x0000000c
+#define AR9285_AN_TOP3_XPABIAS_LVL_S 2
+#define AR9285_AN_TOP3_PWDDAC 0x00800000
+
+/* Bits for AR9285_AN_TOP4. */
+#define AR9285_AN_TOP4_DEFAULT 0x10142c00 /* XXX magic */
+#define AR9285_AN_TOP4_UNLOCKED 0x10142c14 /* XXX magic */
+
+/* Bits for AR_PHY_MULTICHAIN_GAIN_CTL. */
+#define AR9285_PHY_ANT_DIV_CTL_ALL_M 0x7f000000
+#define AR9285_PHY_ANT_DIV_CTL_ALL_S 24
+#define AR9285_PHY_ANT_DIV_CTL_M 0x01000000
+#define AR9285_PHY_ANT_DIV_CTL_S 24
+#define AR9285_PHY_ANT_DIV_ALT_LNACONF_M 0x06000000
+#define AR9285_PHY_ANT_DIV_ALT_LNACONF_S 25
+#define AR9285_PHY_ANT_DIV_MAIN_LNACONF_M 0x18000000
+#define AR9285_PHY_ANT_DIV_MAIN_LNACONF_S 27
+#define AR9285_PHY_ANT_DIV_ALT_GAINTB_M 0x20000000
+#define AR9285_PHY_ANT_DIV_ALT_GAINTB_S 29
+#define AR9285_PHY_ANT_DIV_MAIN_GAINTB_M 0x40000000
+#define AR9285_PHY_ANT_DIV_MAIN_GAINTB_S 30
+
+/*
+ * ROM layout used by AR9285 (single-stream, 2GHz only).
+ */
+#define AR9285_EEP_START_LOC 64
+#define AR9285_NUM_2G_CAL_PIERS 3
+#define AR9285_NUM_2G_CCK_TARGET_POWERS 3
+#define AR9285_NUM_2G_20_TARGET_POWERS 3
+#define AR9285_NUM_2G_40_TARGET_POWERS 3
+#define AR9285_NUM_CTLS 12
+#define AR9285_NUM_BAND_EDGES 4
+#define AR9285_NUM_PD_GAINS 2
+#define AR9285_PD_GAINS_IN_MASK 4
+#define AR9285_PD_GAIN_ICEPTS 5
+
+struct ar9285_base_eep_header {
+ uint16_t length;
+ uint16_t checksum;
+ uint16_t version;
+ uint8_t opCapFlags;
+ uint8_t eepMisc;
+ uint16_t regDmn[2];
+ uint8_t macAddr[6];
+ uint8_t rxMask;
+ uint8_t txMask;
+ uint16_t rfSilent;
+ uint16_t blueToothOptions;
+ uint16_t deviceCap;
+ uint32_t binBuildNumber;
+ uint8_t deviceType;
+ /* End of common header. */
+ uint8_t txGainType;
+} __packed;
+
+struct ar9285_modal_eep_header {
+ uint32_t antCtrlChain;
+ uint32_t antCtrlCommon;
+ uint8_t antennaGain;
+ uint8_t switchSettling;
+ uint8_t txRxAtten;
+ uint8_t rxTxMargin;
+ uint8_t adcDesiredSize;
+ uint8_t pgaDesiredSize;
+ uint8_t xlnaGain;
+ uint8_t txEndToXpaOff;
+ uint8_t txEndToRxOn;
+ uint8_t txFrameToXpaOn;
+ uint8_t thresh62;
+ uint8_t noiseFloorThresh;
+ uint8_t xpdGain;
+ uint8_t xpd;
+ uint8_t iqCalI;
+ uint8_t iqCalQ;
+ uint8_t pdGainOverlap;
+ uint8_t ob_01;
+ uint8_t db1_01;
+ uint8_t xpaBiasLvl;
+ uint8_t txFrameToDataStart;
+ uint8_t txFrameToPaOn;
+ uint8_t ht40PowerIncForPdadc;
+ uint8_t bswAtten;
+ uint8_t bswMargin;
+ uint8_t swSettleHt40;
+ uint8_t xatten2Db;
+ uint8_t xatten2Margin;
+ uint8_t db2_01;
+ uint8_t version;
+ uint16_t ob_234;
+ uint16_t db1_234;
+ uint16_t db2_234;
+ uint8_t futureModal[4];
+ struct ar_spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
+} __packed;
+
+struct ar9285_cal_data_per_freq {
+ uint8_t pwrPdg[AR9285_NUM_PD_GAINS][AR9285_PD_GAIN_ICEPTS];
+ uint8_t vpdPdg[AR9285_NUM_PD_GAINS][AR9285_PD_GAIN_ICEPTS];
+} __packed;
+
+struct ar9285_cal_ctl_data {
+ struct ar_cal_ctl_edges ctlEdges[AR9285_NUM_BAND_EDGES];
+} __packed;
+
+struct ar9285_eeprom {
+ struct ar9285_base_eep_header baseEepHeader;
+ uint8_t custData[20];
+ struct ar9285_modal_eep_header modalHeader;
+ uint8_t calFreqPier2G[AR9285_NUM_2G_CAL_PIERS];
+ struct ar9285_cal_data_per_freq
+ calPierData2G[AR9285_NUM_2G_CAL_PIERS];
+ struct ar_cal_target_power_leg
+ calTargetPowerCck[AR9285_NUM_2G_CCK_TARGET_POWERS];
+ struct ar_cal_target_power_leg
+ calTargetPower2G[AR9285_NUM_2G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower2GHT20[AR9285_NUM_2G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower2GHT40[AR9285_NUM_2G_40_TARGET_POWERS];
+ uint8_t ctlIndex[AR9285_NUM_CTLS];
+ struct ar9285_cal_ctl_data ctlData[AR9285_NUM_CTLS];
+ uint8_t padding;
+} __packed;
+
+/* Macro to "pack" registers to 16-bit to save some .rodata space. */
+#define P(x) (x)
+
+/*
+ * AR9285 1.2 initialization values.
+ */
+static const uint16_t ar9285_1_2_regs[] = {
+ P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014),
+ P(0x0801c), P(0x08318), P(0x09804), P(0x09820), P(0x09824),
+ P(0x09828), P(0x09834), P(0x09838), P(0x09840), P(0x09844),
+ P(0x09848), P(0x0a848), P(0x09850), P(0x09858), P(0x0985c),
+ P(0x09860), P(0x09864), P(0x09868), P(0x0986c), P(0x09914),
+ P(0x09918), P(0x09924), P(0x09944), P(0x09960), P(0x09964),
+ P(0x099b8), P(0x099bc), P(0x099c0), P(0x099c4), P(0x099c8),
+ P(0x099cc), P(0x099d0), P(0x099d4), P(0x099d8), P(0x09a00),
+ P(0x09a04), P(0x09a08), P(0x09a0c), P(0x09a10), P(0x09a14),
+ P(0x09a18), P(0x09a1c), P(0x09a20), P(0x09a24), P(0x09a28),
+ P(0x09a2c), P(0x09a30), P(0x09a34), P(0x09a38), P(0x09a3c),
+ P(0x09a40), P(0x09a44), P(0x09a48), P(0x09a4c), P(0x09a50),
+ P(0x09a54), P(0x09a58), P(0x09a5c), P(0x09a60), P(0x09a64),
+ P(0x09a68), P(0x09a6c), P(0x09a70), P(0x09a74), P(0x09a78),
+ P(0x09a7c), P(0x09a80), P(0x09a84), P(0x09a88), P(0x09a8c),
+ P(0x09a90), P(0x09a94), P(0x09a98), P(0x09a9c), P(0x09aa0),
+ P(0x09aa4), P(0x09aa8), P(0x09aac), P(0x09ab0), P(0x09ab4),
+ P(0x09ab8), P(0x09abc), P(0x09ac0), P(0x09ac4), P(0x09ac8),
+ P(0x09acc), P(0x09ad0), P(0x09ad4), P(0x09ad8), P(0x09adc),
+ P(0x09ae0), P(0x09ae4), P(0x09ae8), P(0x09aec), P(0x09af0),
+ P(0x09af4), P(0x09af8), P(0x09afc), P(0x09b00), P(0x09b04),
+ P(0x09b08), P(0x09b0c), P(0x09b10), P(0x09b14), P(0x09b18),
+ P(0x09b1c), P(0x09b20), P(0x09b24), P(0x09b28), P(0x09b2c),
+ P(0x09b30), P(0x09b34), P(0x09b38), P(0x09b3c), P(0x09b40),
+ P(0x09b44), P(0x09b48), P(0x09b4c), P(0x09b50), P(0x09b54),
+ P(0x09b58), P(0x09b5c), P(0x09b60), P(0x09b64), P(0x09b68),
+ P(0x09b6c), P(0x09b70), P(0x09b74), P(0x09b78), P(0x09b7c),
+ P(0x09b80), P(0x09b84), P(0x09b88), P(0x09b8c), P(0x09b90),
+ P(0x09b94), P(0x09b98), P(0x09b9c), P(0x09ba0), P(0x09ba4),
+ P(0x09ba8), P(0x09bac), P(0x09bb0), P(0x09bb4), P(0x09bb8),
+ P(0x09bbc), P(0x09bc0), P(0x09bc4), P(0x09bc8), P(0x09bcc),
+ P(0x09bd0), P(0x09bd4), P(0x09bd8), P(0x09bdc), P(0x09be0),
+ P(0x09be4), P(0x09be8), P(0x09bec), P(0x09bf0), P(0x09bf4),
+ P(0x09bf8), P(0x09bfc), P(0x0aa00), P(0x0aa04), P(0x0aa08),
+ P(0x0aa0c), P(0x0aa10), P(0x0aa14), P(0x0aa18), P(0x0aa1c),
+ P(0x0aa20), P(0x0aa24), P(0x0aa28), P(0x0aa2c), P(0x0aa30),
+ P(0x0aa34), P(0x0aa38), P(0x0aa3c), P(0x0aa40), P(0x0aa44),
+ P(0x0aa48), P(0x0aa4c), P(0x0aa50), P(0x0aa54), P(0x0aa58),
+ P(0x0aa5c), P(0x0aa60), P(0x0aa64), P(0x0aa68), P(0x0aa6c),
+ P(0x0aa70), P(0x0aa74), P(0x0aa78), P(0x0aa7c), P(0x0aa80),
+ P(0x0aa84), P(0x0aa88), P(0x0aa8c), P(0x0aa90), P(0x0aa94),
+ P(0x0aa98), P(0x0aa9c), P(0x0aaa0), P(0x0aaa4), P(0x0aaa8),
+ P(0x0aaac), P(0x0aab0), P(0x0aab4), P(0x0aab8), P(0x0aabc),
+ P(0x0aac0), P(0x0aac4), P(0x0aac8), P(0x0aacc), P(0x0aad0),
+ P(0x0aad4), P(0x0aad8), P(0x0aadc), P(0x0aae0), P(0x0aae4),
+ P(0x0aae8), P(0x0aaec), P(0x0aaf0), P(0x0aaf4), P(0x0aaf8),
+ P(0x0aafc), P(0x0ab00), P(0x0ab04), P(0x0ab08), P(0x0ab0c),
+ P(0x0ab10), P(0x0ab14), P(0x0ab18), P(0x0ab1c), P(0x0ab20),
+ P(0x0ab24), P(0x0ab28), P(0x0ab2c), P(0x0ab30), P(0x0ab34),
+ P(0x0ab38), P(0x0ab3c), P(0x0ab40), P(0x0ab44), P(0x0ab48),
+ P(0x0ab4c), P(0x0ab50), P(0x0ab54), P(0x0ab58), P(0x0ab5c),
+ P(0x0ab60), P(0x0ab64), P(0x0ab68), P(0x0ab6c), P(0x0ab70),
+ P(0x0ab74), P(0x0ab78), P(0x0ab7c), P(0x0ab80), P(0x0ab84),
+ P(0x0ab88), P(0x0ab8c), P(0x0ab90), P(0x0ab94), P(0x0ab98),
+ P(0x0ab9c), P(0x0aba0), P(0x0aba4), P(0x0aba8), P(0x0abac),
+ P(0x0abb0), P(0x0abb4), P(0x0abb8), P(0x0abbc), P(0x0abc0),
+ P(0x0abc4), P(0x0abc8), P(0x0abcc), P(0x0abd0), P(0x0abd4),
+ P(0x0abd8), P(0x0abdc), P(0x0abe0), P(0x0abe4), P(0x0abe8),
+ P(0x0abec), P(0x0abf0), P(0x0abf4), P(0x0abf8), P(0x0abfc),
+ P(0x0a204), P(0x0a20c), P(0x0b20c), P(0x0a21c), P(0x0a230),
+ P(0x0a250), P(0x0a358)
+};
+
+static const uint32_t ar9285_1_2_vals_2g40[] = {
+ 0x000002c0, 0x00000318, 0x00007c70, 0x00000000, 0x10801600,
+ 0x12e00057, 0x00006880, 0x000003c4, 0x02020200, 0x01000e0e,
+ 0x0a020001, 0x00000e0e, 0x00000007, 0x206a012e, 0x03721620,
+ 0x00001053, 0x00001053, 0x6d4000e2, 0x7ec84d2e, 0x3137605e,
+ 0x00058d20, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x00001130,
+ 0x00000016, 0xd00a800d, 0xffbc1020, 0x00000000, 0x00000000,
+ 0x0000421c, 0x00000c00, 0x05eea6d4, 0x06336f77, 0x6af6532f,
+ 0x08f186c8, 0x00046384, 0x00000000, 0x00000000, 0x00058084,
+ 0x00058088, 0x0005808c, 0x00058100, 0x00058104, 0x00058108,
+ 0x0005810c, 0x00058110, 0x00058114, 0x00058180, 0x00058184,
+ 0x00058188, 0x0005818c, 0x00058190, 0x00058194, 0x000581a0,
+ 0x0005820c, 0x000581a8, 0x00058284, 0x00058288, 0x00058224,
+ 0x00058290, 0x00058300, 0x00058304, 0x00058308, 0x0005830c,
+ 0x00058380, 0x00058384, 0x00068700, 0x00068704, 0x00068708,
+ 0x0006870c, 0x00068780, 0x00068784, 0x00078b00, 0x00078b04,
+ 0x00078b08, 0x00078b0c, 0x00078b80, 0x00078b84, 0x00078b88,
+ 0x00078b8c, 0x00078b90, 0x000caf80, 0x000caf84, 0x000caf88,
+ 0x000caf8c, 0x000caf90, 0x000db30c, 0x000db310, 0x000db384,
+ 0x000db388, 0x000db324, 0x000eb704, 0x000eb6a4, 0x000eb6a8,
+ 0x000eb710, 0x000eb714, 0x000eb720, 0x000eb724, 0x000eb728,
+ 0x000eb72c, 0x000eb7a0, 0x000eb7a4, 0x000eb7a8, 0x000eb7b0,
+ 0x000eb7b4, 0x000eb7b8, 0x000eb7a5, 0x000eb7a9, 0x000eb7ad,
+ 0x000eb7b1, 0x000eb7b5, 0x000eb7b9, 0x000eb7c5, 0x000eb7c9,
+ 0x000eb7d1, 0x000eb7d5, 0x000eb7d9, 0x000eb7c6, 0x000eb7ca,
+ 0x000eb7ce, 0x000eb7d2, 0x000eb7d6, 0x000eb7c3, 0x000eb7c7,
+ 0x000eb7cb, 0x000eb7cf, 0x000eb7d7, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x00058084, 0x00058088, 0x0005808c,
+ 0x00058100, 0x00058104, 0x00058108, 0x0005810c, 0x00058110,
+ 0x00058114, 0x00058180, 0x00058184, 0x00058188, 0x0005818c,
+ 0x00058190, 0x00058194, 0x000581a0, 0x0005820c, 0x000581a8,
+ 0x00058284, 0x00058288, 0x00058224, 0x00058290, 0x00058300,
+ 0x00058304, 0x00058308, 0x0005830c, 0x00058380, 0x00058384,
+ 0x00068700, 0x00068704, 0x00068708, 0x0006870c, 0x00068780,
+ 0x00068784, 0x00078b00, 0x00078b04, 0x00078b08, 0x00078b0c,
+ 0x00078b80, 0x00078b84, 0x00078b88, 0x00078b8c, 0x00078b90,
+ 0x000caf80, 0x000caf84, 0x000caf88, 0x000caf8c, 0x000caf90,
+ 0x000db30c, 0x000db310, 0x000db384, 0x000db388, 0x000db324,
+ 0x000eb704, 0x000eb6a4, 0x000eb6a8, 0x000eb710, 0x000eb714,
+ 0x000eb720, 0x000eb724, 0x000eb728, 0x000eb72c, 0x000eb7a0,
+ 0x000eb7a4, 0x000eb7a8, 0x000eb7b0, 0x000eb7b4, 0x000eb7b8,
+ 0x000eb7a5, 0x000eb7a9, 0x000eb7ad, 0x000eb7b1, 0x000eb7b5,
+ 0x000eb7b9, 0x000eb7c5, 0x000eb7c9, 0x000eb7d1, 0x000eb7d5,
+ 0x000eb7d9, 0x000eb7c6, 0x000eb7ca, 0x000eb7ce, 0x000eb7d2,
+ 0x000eb7d6, 0x000eb7c3, 0x000eb7c7, 0x000eb7cb, 0x000eb7cf,
+ 0x000eb7d7, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x00000004, 0x0001f000, 0x0001f000, 0x1883800a, 0x00000210,
+ 0x0004a000, 0x7999aa0e
+};
+
+static const uint32_t ar9285_1_2_vals_2g20[] = {
+ 0x00000160, 0x0000018c, 0x00003e38, 0x00000000, 0x08400b00,
+ 0x12e0002b, 0x00003440, 0x00000300, 0x02020200, 0x01000e0e,
+ 0x0a020001, 0x00000e0e, 0x00000007, 0x206a012e, 0x03721620,
+ 0x00001053, 0x00001053, 0x6d4000e2, 0x7ec84d2e, 0x3137605e,
+ 0x00058d20, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x00000898,
+ 0x0000000b, 0xd00a800d, 0xffbc1020, 0x00000000, 0x00000000,
+ 0x0000421c, 0x00000c00, 0x05eea6d4, 0x06336f77, 0x6af6532f,
+ 0x08f186c8, 0x00046384, 0x00000000, 0x00000000, 0x00058084,
+ 0x00058088, 0x0005808c, 0x00058100, 0x00058104, 0x00058108,
+ 0x0005810c, 0x00058110, 0x00058114, 0x00058180, 0x00058184,
+ 0x00058188, 0x0005818c, 0x00058190, 0x00058194, 0x000581a0,
+ 0x0005820c, 0x000581a8, 0x00058284, 0x00058288, 0x00058224,
+ 0x00058290, 0x00058300, 0x00058304, 0x00058308, 0x0005830c,
+ 0x00058380, 0x00058384, 0x00068700, 0x00068704, 0x00068708,
+ 0x0006870c, 0x00068780, 0x00068784, 0x00078b00, 0x00078b04,
+ 0x00078b08, 0x00078b0c, 0x00078b80, 0x00078b84, 0x00078b88,
+ 0x00078b8c, 0x00078b90, 0x000caf80, 0x000caf84, 0x000caf88,
+ 0x000caf8c, 0x000caf90, 0x000db30c, 0x000db310, 0x000db384,
+ 0x000db388, 0x000db324, 0x000eb704, 0x000eb6a4, 0x000eb6a8,
+ 0x000eb710, 0x000eb714, 0x000eb720, 0x000eb724, 0x000eb728,
+ 0x000eb72c, 0x000eb7a0, 0x000eb7a4, 0x000eb7a8, 0x000eb7b0,
+ 0x000eb7b4, 0x000eb7b8, 0x000eb7a5, 0x000eb7a9, 0x000eb7ad,
+ 0x000eb7b1, 0x000eb7b5, 0x000eb7b9, 0x000eb7c5, 0x000eb7c9,
+ 0x000eb7d1, 0x000eb7d5, 0x000eb7d9, 0x000eb7c6, 0x000eb7ca,
+ 0x000eb7ce, 0x000eb7d2, 0x000eb7d6, 0x000eb7c3, 0x000eb7c7,
+ 0x000eb7cb, 0x000eb7cf, 0x000eb7d7, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x00058084, 0x00058088, 0x0005808c,
+ 0x00058100, 0x00058104, 0x00058108, 0x0005810c, 0x00058110,
+ 0x00058114, 0x00058180, 0x00058184, 0x00058188, 0x0005818c,
+ 0x00058190, 0x00058194, 0x000581a0, 0x0005820c, 0x000581a8,
+ 0x00058284, 0x00058288, 0x00058224, 0x00058290, 0x00058300,
+ 0x00058304, 0x00058308, 0x0005830c, 0x00058380, 0x00058384,
+ 0x00068700, 0x00068704, 0x00068708, 0x0006870c, 0x00068780,
+ 0x00068784, 0x00078b00, 0x00078b04, 0x00078b08, 0x00078b0c,
+ 0x00078b80, 0x00078b84, 0x00078b88, 0x00078b8c, 0x00078b90,
+ 0x000caf80, 0x000caf84, 0x000caf88, 0x000caf8c, 0x000caf90,
+ 0x000db30c, 0x000db310, 0x000db384, 0x000db388, 0x000db324,
+ 0x000eb704, 0x000eb6a4, 0x000eb6a8, 0x000eb710, 0x000eb714,
+ 0x000eb720, 0x000eb724, 0x000eb728, 0x000eb72c, 0x000eb7a0,
+ 0x000eb7a4, 0x000eb7a8, 0x000eb7b0, 0x000eb7b4, 0x000eb7b8,
+ 0x000eb7a5, 0x000eb7a9, 0x000eb7ad, 0x000eb7b1, 0x000eb7b5,
+ 0x000eb7b9, 0x000eb7c5, 0x000eb7c9, 0x000eb7d1, 0x000eb7d5,
+ 0x000eb7d9, 0x000eb7c6, 0x000eb7ca, 0x000eb7ce, 0x000eb7d2,
+ 0x000eb7d6, 0x000eb7c3, 0x000eb7c7, 0x000eb7cb, 0x000eb7cf,
+ 0x000eb7d7, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x00000004, 0x0001f000, 0x0001f000, 0x1883800a, 0x00000108,
+ 0x0004a000, 0x7999aa0e
+};
+
+static const uint16_t ar9285_1_2_cm_regs[] = {
+ P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044),
+ P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800),
+ P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814),
+ P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040),
+ P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054),
+ P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230),
+ P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8),
+ P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238),
+ P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378),
+ P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8),
+ P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8),
+ P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738),
+ P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c),
+ P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc),
+ P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc),
+ P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c),
+ P(0x0147c), P(0x04030), P(0x0403c), P(0x04024), P(0x04060),
+ P(0x04064), P(0x07010), P(0x07034), P(0x07038), P(0x08004),
+ P(0x08008), P(0x0800c), P(0x08018), P(0x08020), P(0x08038),
+ P(0x0803c), P(0x08048), P(0x08054), P(0x08058), P(0x0805c),
+ P(0x08060), P(0x08064), P(0x08070), P(0x080c0), P(0x080c4),
+ P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4), P(0x080d8),
+ P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec), P(0x080f0),
+ P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100), P(0x08104),
+ P(0x08108), P(0x0810c), P(0x08110), P(0x08118), P(0x0811c),
+ P(0x08120), P(0x08124), P(0x08128), P(0x0812c), P(0x08130),
+ P(0x08134), P(0x08138), P(0x0813c), P(0x08144), P(0x08168),
+ P(0x0816c), P(0x08170), P(0x08174), P(0x08178), P(0x0817c),
+ P(0x081c0), P(0x081d0), P(0x081ec), P(0x081f0), P(0x081f4),
+ P(0x081f8), P(0x081fc), P(0x08200), P(0x08204), P(0x08208),
+ P(0x0820c), P(0x08210), P(0x08214), P(0x08218), P(0x0821c),
+ P(0x08220), P(0x08224), P(0x08228), P(0x0822c), P(0x08230),
+ P(0x08234), P(0x08238), P(0x0823c), P(0x08240), P(0x08244),
+ P(0x08248), P(0x0824c), P(0x08250), P(0x08254), P(0x08258),
+ P(0x0825c), P(0x08260), P(0x08264), P(0x08270), P(0x08274),
+ P(0x08278), P(0x0827c), P(0x08284), P(0x08288), P(0x0828c),
+ P(0x08294), P(0x08298), P(0x0829c), P(0x08300), P(0x08314),
+ P(0x08328), P(0x0832c), P(0x08330), P(0x08334), P(0x08338),
+ P(0x0833c), P(0x08340), P(0x08344), P(0x09808), P(0x0980c),
+ P(0x09810), P(0x09814), P(0x0981c), P(0x0982c), P(0x09830),
+ P(0x0983c), P(0x0984c), P(0x09854), P(0x09900), P(0x09904),
+ P(0x09908), P(0x0990c), P(0x09910), P(0x0991c), P(0x09920),
+ P(0x09928), P(0x0992c), P(0x09934), P(0x09938), P(0x0993c),
+ P(0x09940), P(0x09948), P(0x0994c), P(0x09954), P(0x09958),
+ P(0x09968), P(0x09970), P(0x09974), P(0x09978), P(0x0997c),
+ P(0x09980), P(0x09984), P(0x09988), P(0x0998c), P(0x09990),
+ P(0x09994), P(0x09998), P(0x0999c), P(0x099a0), P(0x099a4),
+ P(0x099a8), P(0x099ac), P(0x099b0), P(0x099b4), P(0x099dc),
+ P(0x099e0), P(0x099e4), P(0x099e8), P(0x099ec), P(0x099f0),
+ P(0x0a208), P(0x0a210), P(0x0a214), P(0x0a218), P(0x0a220),
+ P(0x0a224), P(0x0a228), P(0x0a22c), P(0x0a234), P(0x0a238),
+ P(0x0a244), P(0x0a248), P(0x0a24c), P(0x0a254), P(0x0a258),
+ P(0x0a25c), P(0x0a260), P(0x0a268), P(0x0a26c), P(0x0d270),
+ P(0x0d35c), P(0x0d360), P(0x0d364), P(0x0d368), P(0x0d36c),
+ P(0x0d370), P(0x0d374), P(0x0d378), P(0x0d37c), P(0x0d380),
+ P(0x0d384), P(0x0a388), P(0x0a38c), P(0x0a390), P(0x0a39c),
+ P(0x0a3a0), P(0x0a3a4), P(0x0a3a8), P(0x0a3ac), P(0x0a3b0),
+ P(0x0a3b4), P(0x0a3b8), P(0x0a3bc), P(0x0a3c0), P(0x0a3c4),
+ P(0x0a3cc), P(0x0a3d0), P(0x0a3d4), P(0x0a3e4), P(0x0a3e8),
+ P(0x0a3ec), P(0x07800), P(0x07804), P(0x07808), P(0x0780c),
+ P(0x07810), P(0x0781c), P(0x07824), P(0x0782c), P(0x07834),
+ P(0x07844), P(0x07848), P(0x0784c), P(0x07850), P(0x07854),
+ P(0x07858), P(0x0785c), P(0x07860), P(0x07864), P(0x07868),
+ P(0x07870)
+};
+
+static const uint32_t ar9285_1_2_cm_vals[] = {
+ 0x00000000, 0x00020045, 0x00000005, 0x00000000, 0x00000008,
+ 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000002, 0x00000002, 0x0000001f, 0x00000000,
+ 0x00000000, 0x00000031, 0x00000002, 0x000004c2, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000700, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000fc78f,
+ 0x0000000f, 0x00000000, 0x00000000, 0x2a80001a, 0x05dc01e0,
+ 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000, 0x00400000,
+ 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00000001,
+ 0x00000052, 0x00000000, 0x00000168, 0x000100aa, 0x00003210,
+ 0x08f04810, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000,
+ 0x00000000, 0x32143320, 0xfaa4fa50, 0x00000100, 0x00000000,
+ 0x00000000, 0x0000320a, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00100000, 0x0010f400,
+ 0x00000100, 0x0001e800, 0x00000000, 0x00000000, 0x00000000,
+ 0x400000ff, 0x00080922, 0x88a00010, 0x00000000, 0x40000000,
+ 0x003e4180, 0x00000000, 0x0000002c, 0x0000002c, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000302, 0x00000e00, 0x00ff0000,
+ 0x00000000, 0x00010380, 0x00481043, 0x00000000, 0xafe68e30,
+ 0xfd14e000, 0x9c0a9f6b, 0x00000000, 0x0000a000, 0x00000000,
+ 0x00200400, 0x0040233c, 0x00000044, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x01002310, 0x10000fff, 0x04900000,
+ 0x00000001, 0x00000004, 0x1e1f2022, 0x0a0b0c0d, 0x00000000,
+ 0x14750604, 0x9280c00a, 0x00020028, 0x5f3ca3de, 0x2108ecff,
+ 0x000003ce, 0x192bb514, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+ 0x201fff00, 0x2def0400, 0x03051000, 0x00000820, 0x00000000,
+ 0x00000000, 0xaaaaaaaa, 0x3c466478, 0x0cc80caa, 0x00000000,
+ 0x803e68c8, 0x4080a333, 0x00206c10, 0x009c4060, 0x01834061,
+ 0x00000400, 0x000003b5, 0x00000000, 0x20202020, 0x20202020,
+ 0x00000000, 0xfffffffc, 0x00000000, 0x00000000, 0x0ccb5380,
+ 0x15151501, 0xdfa90f01, 0x00000000, 0x0ebae9e6, 0x0d820820,
+ 0x07ffffef, 0x0fffffe7, 0x17ffffe5, 0x1fffffe4, 0x37ffffe3,
+ 0x3fffffe3, 0x57ffffe3, 0x5fffffe2, 0x7fffffe2, 0x7f3c7bba,
+ 0xf3307ff0, 0x0c000000, 0x20202020, 0x20202020, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x20202020, 0x20202020, 0x20202020, 0x00000000, 0x18c43433,
+ 0x00f70081, 0x00140000, 0x0e4548d8, 0x54214514, 0x02025830,
+ 0x71c0d388, 0x00000000, 0x00d86fff, 0x6e36d97b, 0x71400087,
+ 0x000c0db6, 0x6db6246f, 0x6d9b66db, 0x6d8c6dba, 0x00040000,
+ 0xdb003012, 0x04924914, 0x21084210, 0xf7d7ffde, 0xc2034080,
+ 0x10142c00
+};
+
+static const struct athn_ini ar9285_1_2_ini = {
+ nitems(ar9285_1_2_regs),
+ ar9285_1_2_regs,
+ NULL, /* 2GHz only. */
+ NULL, /* 2GHz only. */
+ ar9285_1_2_vals_2g40,
+ ar9285_1_2_vals_2g20,
+ nitems(ar9285_1_2_cm_regs),
+ ar9285_1_2_cm_regs,
+ ar9285_1_2_cm_vals
+};
+
+//#if NATHN_USB > 0
+/*
+ * AR9271 programming.
+ */
+static const uint16_t ar9271_regs[] = {
+ P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014),
+ P(0x0801c), P(0x08318), P(0x09804), P(0x09820), P(0x09824),
+ P(0x09828), P(0x09834), P(0x09838), P(0x09840), P(0x09844),
+ P(0x09848), P(0x0a848), P(0x09850), P(0x09858), P(0x0985c),
+ P(0x09860), P(0x09864), P(0x09868), P(0x0986c), P(0x09910),
+ P(0x09914), P(0x09918), P(0x09924), P(0x09944), P(0x09960),
+ P(0x09964), P(0x099b8), P(0x099bc), P(0x099c0), P(0x099c4),
+ P(0x099c8), P(0x099cc), P(0x099d0), P(0x099d4), P(0x099d8),
+ P(0x09a00), P(0x09a04), P(0x09a08), P(0x09a0c), P(0x09a10),
+ P(0x09a14), P(0x09a18), P(0x09a1c), P(0x09a20), P(0x09a24),
+ P(0x09a28), P(0x09a2c), P(0x09a30), P(0x09a34), P(0x09a38),
+ P(0x09a3c), P(0x09a40), P(0x09a44), P(0x09a48), P(0x09a4c),
+ P(0x09a50), P(0x09a54), P(0x09a58), P(0x09a5c), P(0x09a60),
+ P(0x09a64), P(0x09a68), P(0x09a6c), P(0x09a70), P(0x09a74),
+ P(0x09a78), P(0x09a7c), P(0x09a80), P(0x09a84), P(0x09a88),
+ P(0x09a8c), P(0x09a90), P(0x09a94), P(0x09a98), P(0x09a9c),
+ P(0x09aa0), P(0x09aa4), P(0x09aa8), P(0x09aac), P(0x09ab0),
+ P(0x09ab4), P(0x09ab8), P(0x09abc), P(0x09ac0), P(0x09ac4),
+ P(0x09ac8), P(0x09acc), P(0x09ad0), P(0x09ad4), P(0x09ad8),
+ P(0x09adc), P(0x09ae0), P(0x09ae4), P(0x09ae8), P(0x09aec),
+ P(0x09af0), P(0x09af4), P(0x09af8), P(0x09afc), P(0x09b00),
+ P(0x09b04), P(0x09b08), P(0x09b0c), P(0x09b10), P(0x09b14),
+ P(0x09b18), P(0x09b1c), P(0x09b20), P(0x09b24), P(0x09b28),
+ P(0x09b2c), P(0x09b30), P(0x09b34), P(0x09b38), P(0x09b3c),
+ P(0x09b40), P(0x09b44), P(0x09b48), P(0x09b4c), P(0x09b50),
+ P(0x09b54), P(0x09b58), P(0x09b5c), P(0x09b60), P(0x09b64),
+ P(0x09b68), P(0x09b6c), P(0x09b70), P(0x09b74), P(0x09b78),
+ P(0x09b7c), P(0x09b80), P(0x09b84), P(0x09b88), P(0x09b8c),
+ P(0x09b90), P(0x09b94), P(0x09b98), P(0x09b9c), P(0x09ba0),
+ P(0x09ba4), P(0x09ba8), P(0x09bac), P(0x09bb0), P(0x09bb4),
+ P(0x09bb8), P(0x09bbc), P(0x09bc0), P(0x09bc4), P(0x09bc8),
+ P(0x09bcc), P(0x09bd0), P(0x09bd4), P(0x09bd8), P(0x09bdc),
+ P(0x09be0), P(0x09be4), P(0x09be8), P(0x09bec), P(0x09bf0),
+ P(0x09bf4), P(0x09bf8), P(0x09bfc), P(0x0aa00), P(0x0aa04),
+ P(0x0aa08), P(0x0aa0c), P(0x0aa10), P(0x0aa14), P(0x0aa18),
+ P(0x0aa1c), P(0x0aa20), P(0x0aa24), P(0x0aa28), P(0x0aa2c),
+ P(0x0aa30), P(0x0aa34), P(0x0aa38), P(0x0aa3c), P(0x0aa40),
+ P(0x0aa44), P(0x0aa48), P(0x0aa4c), P(0x0aa50), P(0x0aa54),
+ P(0x0aa58), P(0x0aa5c), P(0x0aa60), P(0x0aa64), P(0x0aa68),
+ P(0x0aa6c), P(0x0aa70), P(0x0aa74), P(0x0aa78), P(0x0aa7c),
+ P(0x0aa80), P(0x0aa84), P(0x0aa88), P(0x0aa8c), P(0x0aa90),
+ P(0x0aa94), P(0x0aa98), P(0x0aa9c), P(0x0aaa0), P(0x0aaa4),
+ P(0x0aaa8), P(0x0aaac), P(0x0aab0), P(0x0aab4), P(0x0aab8),
+ P(0x0aabc), P(0x0aac0), P(0x0aac4), P(0x0aac8), P(0x0aacc),
+ P(0x0aad0), P(0x0aad4), P(0x0aad8), P(0x0aadc), P(0x0aae0),
+ P(0x0aae4), P(0x0aae8), P(0x0aaec), P(0x0aaf0), P(0x0aaf4),
+ P(0x0aaf8), P(0x0aafc), P(0x0ab00), P(0x0ab04), P(0x0ab08),
+ P(0x0ab0c), P(0x0ab10), P(0x0ab14), P(0x0ab18), P(0x0ab1c),
+ P(0x0ab20), P(0x0ab24), P(0x0ab28), P(0x0ab2c), P(0x0ab30),
+ P(0x0ab34), P(0x0ab38), P(0x0ab3c), P(0x0ab40), P(0x0ab44),
+ P(0x0ab48), P(0x0ab4c), P(0x0ab50), P(0x0ab54), P(0x0ab58),
+ P(0x0ab5c), P(0x0ab60), P(0x0ab64), P(0x0ab68), P(0x0ab6c),
+ P(0x0ab70), P(0x0ab74), P(0x0ab78), P(0x0ab7c), P(0x0ab80),
+ P(0x0ab84), P(0x0ab88), P(0x0ab8c), P(0x0ab90), P(0x0ab94),
+ P(0x0ab98), P(0x0ab9c), P(0x0aba0), P(0x0aba4), P(0x0aba8),
+ P(0x0abac), P(0x0abb0), P(0x0abb4), P(0x0abb8), P(0x0abbc),
+ P(0x0abc0), P(0x0abc4), P(0x0abc8), P(0x0abcc), P(0x0abd0),
+ P(0x0abd4), P(0x0abd8), P(0x0abdc), P(0x0abe0), P(0x0abe4),
+ P(0x0abe8), P(0x0abec), P(0x0abf0), P(0x0abf4), P(0x0abf8),
+ P(0x0abfc), P(0x0a204), P(0x0a20c), P(0x0b20c), P(0x0a21c),
+ P(0x0a230), P(0x0a250), P(0x0a358)
+};
+
+static const uint32_t ar9271_vals_2g40[] = {
+ 0x000002c0, 0x00000318, 0x00007c70, 0x00000000, 0x10801600,
+ 0x12e00057, 0x00006880, 0x000003c4, 0x02020200, 0x01000e0e,
+ 0x3a020001, 0x00000e0e, 0x00000007, 0x206a012e, 0x03721620,
+ 0x00001053, 0x00001053, 0x6d4000e2, 0x7ec84d2e, 0x3137605e,
+ 0x00058d18, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x30002310,
+ 0x00001130, 0x00000016, 0xd00a800d, 0xffbc1020, 0x00000000,
+ 0x00000000, 0x0000421c, 0x00000c00, 0x05eea6d4, 0x06336f77,
+ 0x6af6532f, 0x08f186c8, 0x00046384, 0x00000000, 0x00000000,
+ 0x00058084, 0x00058088, 0x0005808c, 0x00058100, 0x00058104,
+ 0x00058108, 0x0005810c, 0x00058110, 0x00058114, 0x00058180,
+ 0x00058184, 0x00058188, 0x0005818c, 0x00058190, 0x00058194,
+ 0x000581a0, 0x0005820c, 0x000581a8, 0x00058284, 0x00058288,
+ 0x00058224, 0x00058290, 0x00058300, 0x00058304, 0x00058308,
+ 0x0005830c, 0x00058380, 0x00058384, 0x00068700, 0x00068704,
+ 0x00068708, 0x0006870c, 0x00068780, 0x00068784, 0x00078b00,
+ 0x00078b04, 0x00078b08, 0x00078b0c, 0x00078b80, 0x00078b84,
+ 0x00078b88, 0x00078b8c, 0x00078b90, 0x000caf80, 0x000caf84,
+ 0x000caf88, 0x000caf8c, 0x000caf90, 0x000db30c, 0x000db310,
+ 0x000db384, 0x000db388, 0x000db324, 0x000eb704, 0x000eb6a4,
+ 0x000eb6a8, 0x000eb710, 0x000eb714, 0x000eb720, 0x000eb724,
+ 0x000eb728, 0x000eb72c, 0x000eb7a0, 0x000eb7a4, 0x000eb7a8,
+ 0x000eb7b0, 0x000eb7b4, 0x000eb7b8, 0x000eb7a5, 0x000eb7a9,
+ 0x000eb7ad, 0x000eb7b1, 0x000eb7b5, 0x000eb7b9, 0x000eb7c5,
+ 0x000eb7c9, 0x000eb7d1, 0x000eb7d5, 0x000eb7d9, 0x000eb7c6,
+ 0x000eb7ca, 0x000eb7ce, 0x000eb7d2, 0x000eb7d6, 0x000eb7c3,
+ 0x000eb7c7, 0x000eb7cb, 0x000eb7cf, 0x000eb7d7, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x00058084, 0x00058088,
+ 0x0005808c, 0x00058100, 0x00058104, 0x00058108, 0x0005810c,
+ 0x00058110, 0x00058114, 0x00058180, 0x00058184, 0x00058188,
+ 0x0005818c, 0x00058190, 0x00058194, 0x000581a0, 0x0005820c,
+ 0x000581a8, 0x00058284, 0x00058288, 0x00058224, 0x00058290,
+ 0x00058300, 0x00058304, 0x00058308, 0x0005830c, 0x00058380,
+ 0x00058384, 0x00068700, 0x00068704, 0x00068708, 0x0006870c,
+ 0x00068780, 0x00068784, 0x00078b00, 0x00078b04, 0x00078b08,
+ 0x00078b0c, 0x00078b80, 0x00078b84, 0x00078b88, 0x00078b8c,
+ 0x00078b90, 0x000caf80, 0x000caf84, 0x000caf88, 0x000caf8c,
+ 0x000caf90, 0x000db30c, 0x000db310, 0x000db384, 0x000db388,
+ 0x000db324, 0x000eb704, 0x000eb6a4, 0x000eb6a8, 0x000eb710,
+ 0x000eb714, 0x000eb720, 0x000eb724, 0x000eb728, 0x000eb72c,
+ 0x000eb7a0, 0x000eb7a4, 0x000eb7a8, 0x000eb7b0, 0x000eb7b4,
+ 0x000eb7b8, 0x000eb7a5, 0x000eb7a9, 0x000eb7ad, 0x000eb7b1,
+ 0x000eb7b5, 0x000eb7b9, 0x000eb7c5, 0x000eb7c9, 0x000eb7d1,
+ 0x000eb7d5, 0x000eb7d9, 0x000eb7c6, 0x000eb7ca, 0x000eb7ce,
+ 0x000eb7d2, 0x000eb7d6, 0x000eb7c3, 0x000eb7c7, 0x000eb7cb,
+ 0x000eb7cf, 0x000eb7d7, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x00000004, 0x0001f000, 0x0001f000, 0x1883800a,
+ 0x00000210, 0x0004a000, 0x7999aa0e
+};
+
+static const uint32_t ar9271_vals_2g20[] = {
+ 0x00000160, 0x0000018c, 0x00003e38, 0x00000000, 0x08400b00,
+ 0x12e0002b, 0x00003440, 0x00000300, 0x02020200, 0x01000e0e,
+ 0x3a020001, 0x00000e0e, 0x00000007, 0x206a012e, 0x03721620,
+ 0x00001053, 0x00001053, 0x6d4000e2, 0x7ec84d2e, 0x3137605e,
+ 0x00058d18, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x30002310,
+ 0x00000898, 0x0000000b, 0xd00a800d, 0xffbc1020, 0x00000000,
+ 0x00000000, 0x0000421c, 0x00000c00, 0x05eea6d4, 0x06336f77,
+ 0x6af6532f, 0x08f186c8, 0x00046384, 0x00000000, 0x00000000,
+ 0x00058084, 0x00058088, 0x0005808c, 0x00058100, 0x00058104,
+ 0x00058108, 0x0005810c, 0x00058110, 0x00058114, 0x00058180,
+ 0x00058184, 0x00058188, 0x0005818c, 0x00058190, 0x00058194,
+ 0x000581a0, 0x0005820c, 0x000581a8, 0x00058284, 0x00058288,
+ 0x00058224, 0x00058290, 0x00058300, 0x00058304, 0x00058308,
+ 0x0005830c, 0x00058380, 0x00058384, 0x00068700, 0x00068704,
+ 0x00068708, 0x0006870c, 0x00068780, 0x00068784, 0x00078b00,
+ 0x00078b04, 0x00078b08, 0x00078b0c, 0x00078b80, 0x00078b84,
+ 0x00078b88, 0x00078b8c, 0x00078b90, 0x000caf80, 0x000caf84,
+ 0x000caf88, 0x000caf8c, 0x000caf90, 0x000db30c, 0x000db310,
+ 0x000db384, 0x000db388, 0x000db324, 0x000eb704, 0x000eb6a4,
+ 0x000eb6a8, 0x000eb710, 0x000eb714, 0x000eb720, 0x000eb724,
+ 0x000eb728, 0x000eb72c, 0x000eb7a0, 0x000eb7a4, 0x000eb7a8,
+ 0x000eb7b0, 0x000eb7b4, 0x000eb7b8, 0x000eb7a5, 0x000eb7a9,
+ 0x000eb7ad, 0x000eb7b1, 0x000eb7b5, 0x000eb7b9, 0x000eb7c5,
+ 0x000eb7c9, 0x000eb7d1, 0x000eb7d5, 0x000eb7d9, 0x000eb7c6,
+ 0x000eb7ca, 0x000eb7ce, 0x000eb7d2, 0x000eb7d6, 0x000eb7c3,
+ 0x000eb7c7, 0x000eb7cb, 0x000eb7cf, 0x000eb7d7, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x00058084, 0x00058088,
+ 0x0005808c, 0x00058100, 0x00058104, 0x00058108, 0x0005810c,
+ 0x00058110, 0x00058114, 0x00058180, 0x00058184, 0x00058188,
+ 0x0005818c, 0x00058190, 0x00058194, 0x000581a0, 0x0005820c,
+ 0x000581a8, 0x00058284, 0x00058288, 0x00058224, 0x00058290,
+ 0x00058300, 0x00058304, 0x00058308, 0x0005830c, 0x00058380,
+ 0x00058384, 0x00068700, 0x00068704, 0x00068708, 0x0006870c,
+ 0x00068780, 0x00068784, 0x00078b00, 0x00078b04, 0x00078b08,
+ 0x00078b0c, 0x00078b80, 0x00078b84, 0x00078b88, 0x00078b8c,
+ 0x00078b90, 0x000caf80, 0x000caf84, 0x000caf88, 0x000caf8c,
+ 0x000caf90, 0x000db30c, 0x000db310, 0x000db384, 0x000db388,
+ 0x000db324, 0x000eb704, 0x000eb6a4, 0x000eb6a8, 0x000eb710,
+ 0x000eb714, 0x000eb720, 0x000eb724, 0x000eb728, 0x000eb72c,
+ 0x000eb7a0, 0x000eb7a4, 0x000eb7a8, 0x000eb7b0, 0x000eb7b4,
+ 0x000eb7b8, 0x000eb7a5, 0x000eb7a9, 0x000eb7ad, 0x000eb7b1,
+ 0x000eb7b5, 0x000eb7b9, 0x000eb7c5, 0x000eb7c9, 0x000eb7d1,
+ 0x000eb7d5, 0x000eb7d9, 0x000eb7c6, 0x000eb7ca, 0x000eb7ce,
+ 0x000eb7d2, 0x000eb7d6, 0x000eb7c3, 0x000eb7c7, 0x000eb7cb,
+ 0x000eb7cf, 0x000eb7d7, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db, 0x000eb7db,
+ 0x000eb7db, 0x00000004, 0x0001f000, 0x0001f000, 0x1883800a,
+ 0x00000108, 0x0004a000, 0x7999aa0e
+};
+
+static const uint16_t ar9271_cm_regs[] = {
+ P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044),
+ P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800),
+ P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814),
+ P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040),
+ P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054),
+ P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230),
+ P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8),
+ P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238),
+ P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378),
+ P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8),
+ P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8),
+ P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738),
+ P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c),
+ P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc),
+ P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc),
+ P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c),
+ P(0x0147c), P(0x04030), P(0x0403c), P(0x04024), P(0x04060),
+ P(0x04064), P(0x08004), P(0x08008), P(0x0800c), P(0x08018),
+ P(0x08020), P(0x08038), P(0x0803c), P(0x08048), P(0x08054),
+ P(0x08058), P(0x0805c), P(0x08060), P(0x08064), P(0x08070),
+ P(0x080b0), P(0x080b4), P(0x080b8), P(0x080bc), P(0x080c0),
+ P(0x080c4), P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4),
+ P(0x080d8), P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec),
+ P(0x080f0), P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100),
+ P(0x08104), P(0x08108), P(0x0810c), P(0x08110), P(0x08118),
+ P(0x0811c), P(0x08120), P(0x08124), P(0x08128), P(0x0812c),
+ P(0x08130), P(0x08134), P(0x08138), P(0x0813c), P(0x08144),
+ P(0x08168), P(0x0816c), P(0x08170), P(0x08174), P(0x08178),
+ P(0x0817c), P(0x081c0), P(0x081d0), P(0x081ec), P(0x081f0),
+ P(0x081f4), P(0x081f8), P(0x081fc), P(0x08200), P(0x08204),
+ P(0x08208), P(0x0820c), P(0x08210), P(0x08214), P(0x08218),
+ P(0x0821c), P(0x08220), P(0x08224), P(0x08228), P(0x0822c),
+ P(0x08230), P(0x08234), P(0x08238), P(0x0823c), P(0x08240),
+ P(0x08244), P(0x08248), P(0x0824c), P(0x08250), P(0x08254),
+ P(0x08258), P(0x0825c), P(0x08260), P(0x08264), P(0x08270),
+ P(0x08274), P(0x08278), P(0x0827c), P(0x08284), P(0x08288),
+ P(0x0828c), P(0x08294), P(0x08298), P(0x0829c), P(0x08300),
+ P(0x08314), P(0x08328), P(0x0832c), P(0x08330), P(0x08334),
+ P(0x08338), P(0x0833c), P(0x08340), P(0x08344), P(0x07010),
+ P(0x07034), P(0x07038), P(0x07800), P(0x07804), P(0x07808),
+ P(0x0780c), P(0x07810), P(0x07814), P(0x0781c), P(0x07828),
+ P(0x0782c), P(0x07830), P(0x07834), P(0x0783c), P(0x07840),
+ P(0x07844), P(0x07848), P(0x0784c), P(0x07850), P(0x07854),
+ P(0x07858), P(0x0785c), P(0x07860), P(0x07864), P(0x07868),
+ P(0x07870), P(0x09808), P(0x0980c), P(0x09810), P(0x09814),
+ P(0x0981c), P(0x0982c), P(0x09830), P(0x0983c), P(0x0984c),
+ P(0x09854), P(0x09900), P(0x09904), P(0x09908), P(0x0990c),
+ P(0x0991c), P(0x09920), P(0x09928), P(0x0992c), P(0x09934),
+ P(0x09938), P(0x0993c), P(0x09940), P(0x09948), P(0x0994c),
+ P(0x09954), P(0x09958), P(0x09968), P(0x09970), P(0x09974),
+ P(0x09978), P(0x0997c), P(0x09980), P(0x09984), P(0x09988),
+ P(0x0998c), P(0x09990), P(0x09994), P(0x09998), P(0x0999c),
+ P(0x099a0), P(0x099a4), P(0x099a8), P(0x099ac), P(0x099b0),
+ P(0x099b4), P(0x099dc), P(0x099e0), P(0x099e4), P(0x099e8),
+ P(0x099ec), P(0x099f0), P(0x0a208), P(0x0a210), P(0x0a214),
+ P(0x0a218), P(0x0a220), P(0x0a224), P(0x0a228), P(0x0a22c),
+ P(0x0a234), P(0x0a238), P(0x0a244), P(0x0a248), P(0x0a24c),
+ P(0x0a254), P(0x0a258), P(0x0a25c), P(0x0a260), P(0x0a268),
+ P(0x0a26c), P(0x0a388), P(0x0a38c), P(0x0a390), P(0x0a39c),
+ P(0x0a3a0), P(0x0a3a4), P(0x0a3a8), P(0x0a3ac), P(0x0a3b0),
+ P(0x0a3b4), P(0x0a3b8), P(0x0a3bc), P(0x0a3c0), P(0x0a3c4),
+ P(0x0a3cc), P(0x0a3d0), P(0x0a3d4), P(0x0a3e4), P(0x0a3e8),
+ P(0x0a3ec), P(0x0a3f0), P(0x0a3f4), P(0x0d270), P(0x0d35c),
+ P(0x0d360), P(0x0d364), P(0x0d368), P(0x0d36c), P(0x0d370),
+ P(0x0d374), P(0x0d378), P(0x0d37c), P(0x0d380), P(0x0d384)
+};
+
+static const uint32_t ar9271_cm_vals[] = {
+ 0x00000000, 0x00020045, 0x00000005, 0x00000000, 0x00000008,
+ 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000002, 0x00000002, 0x0000001f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000700,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x000fc78f, 0x0000000f, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2a80001a,
+ 0x05dc01e0, 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000,
+ 0x00400000, 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00020000, 0x00020000,
+ 0x00000001, 0x00000052, 0x00000000, 0x00000168, 0x000100aa,
+ 0x00003210, 0x08f04810, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x32143320, 0xfaa4fa50, 0x00000100,
+ 0x00000000, 0x00000000, 0x0000320a, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00100000,
+ 0x0010f400, 0x00000100, 0x0001e800, 0x00000000, 0x00000000,
+ 0x00000000, 0x400000ff, 0x00080922, 0x88a00010, 0x00000000,
+ 0x40000000, 0x003e4180, 0x00000000, 0x0000002c, 0x0000002c,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000302, 0x00000e00,
+ 0x00ff0000, 0x00000000, 0x00010380, 0x00581043, 0x00000030,
+ 0x00000002, 0x000004c2, 0x00140000, 0x0e4548d8, 0x54214514,
+ 0x02025820, 0x71c0d388, 0x924934a8, 0x00000000, 0x66964300,
+ 0x8db6d961, 0x8db6d96c, 0x6140008b, 0x72ee0a72, 0xbbfffffc,
+ 0x000c0db6, 0x6db6246f, 0x6d9b66db, 0x6d8c6dba, 0x00040000,
+ 0xdb003012, 0x04924914, 0x21084210, 0xf7d7ffde, 0xc2034080,
+ 0x10142c00, 0x00000000, 0xafe68e30, 0xfd14e000, 0x9c0a9f6b,
+ 0x00000000, 0x0000a000, 0x00000000, 0x00200400, 0x0040233c,
+ 0x00000044, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x10000fff, 0x04900000, 0x00000001, 0x00000004, 0x1e1f2022,
+ 0x0a0b0c0d, 0x00000000, 0x14750604, 0x9280c00a, 0x00020028,
+ 0x5f3ca3de, 0x0108ecff, 0x000003ce, 0x192bb514, 0x00000000,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x201fff00, 0x2def0400, 0x03051000,
+ 0x00000820, 0x00000000, 0x00000000, 0xaaaaaaaa, 0x3c466478,
+ 0x0cc80caa, 0x00000000, 0x803e68c8, 0x4080a333, 0x00206c10,
+ 0x009c4060, 0x01834061, 0x00000400, 0x000003b5, 0x00000000,
+ 0x20202020, 0x20202020, 0x00000000, 0xfffffffc, 0x00000000,
+ 0x00000000, 0x0ccb5380, 0x15151501, 0xdfa90f01, 0x00000000,
+ 0x0ebae9e6, 0x0c000000, 0x20202020, 0x20202020, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x20202020, 0x20202020, 0x20202020, 0x00000000, 0x18c43433,
+ 0x00f70081, 0x01036a2f, 0x00000000, 0x0d820820, 0x07ffffef,
+ 0x0fffffe7, 0x17ffffe5, 0x1fffffe4, 0x37ffffe3, 0x3fffffe3,
+ 0x57ffffe3, 0x5fffffe2, 0x7fffffe2, 0x7f3c7bba, 0xf3307ff0
+};
+
+static const struct athn_ini ar9271_ini = {
+ nitems(ar9271_regs),
+ ar9271_regs,
+ NULL, /* 2GHz only. */
+ NULL, /* 2GHz only. */
+ ar9271_vals_2g40,
+ ar9271_vals_2g20,
+ nitems(ar9271_cm_regs),
+ ar9271_cm_regs,
+ ar9271_cm_vals
+};
+//#endif /* NATHN_USB */
+
+/*
+ * AR9285 1.2 Tx gains.
+ */
+static const uint16_t ar9285_1_2_tx_gain_regs[] = {
+ P(0x0a300), P(0x0a304), P(0x0a308), P(0x0a30c), P(0x0a310),
+ P(0x0a314), P(0x0a318), P(0x0a31c), P(0x0a320), P(0x0a324),
+ P(0x0a328), P(0x0a32c), P(0x0a330), P(0x0a334), P(0x0a338),
+ P(0x0a33c), P(0x0a340), P(0x0a344), P(0x0a348), P(0x0a34c),
+ P(0x0a350), P(0x0a354), P(0x07814), P(0x07828), P(0x07830),
+ P(0x07838), P(0x0783c), P(0x07840), P(0x0786c), P(0x07820),
+ P(0x0a274), P(0x0a278), P(0x0a27c), P(0x0a394), P(0x0a398),
+ P(0x0a3dc), P(0x0a3e0)
+};
+
+static const uint32_t ar9285_1_2_tx_gain_vals_2g[] = {
+ 0x00000000, 0x00009200, 0x00010208, 0x00019608, 0x00022618,
+ 0x0002a6c9, 0x00031710, 0x00035718, 0x00038758, 0x0003c75a,
+ 0x0004075c, 0x0004475e, 0x0004679f, 0x000487df, 0x0003891e,
+ 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
+ 0x0003e9df, 0x0003e9df, 0x924934a8, 0x26d2491b, 0xedb6d96e,
+ 0xfac68801, 0x0001fffe, 0xffeb1a20, 0x48609eb4, 0x00000c04,
+ 0x0a21a652, 0x39ce739c, 0x050e039c, 0x39ce739c, 0x0000039c,
+ 0x39ce739c, 0x0000039c
+};
+
+static const struct athn_gain ar9285_1_2_tx_gain = {
+ nitems(ar9285_1_2_tx_gain_regs),
+ ar9285_1_2_tx_gain_regs,
+ NULL, /* 2GHz only. */
+ ar9285_1_2_tx_gain_vals_2g
+};
+
+static const uint32_t ar9285_1_2_tx_gain_high_power_vals_2g[] = {
+ 0x00000000, 0x00006200, 0x00008201, 0x0000b240, 0x0000d241,
+ 0x0000f600, 0x00012800, 0x00016802, 0x0001b805, 0x00021a80,
+ 0x00028b00, 0x0002ab40, 0x0002cd80, 0x00033d82, 0x0003891e,
+ 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
+ 0x0003e9df, 0x0003e9df, 0x924934a8, 0x26d2491b, 0xedb6d96e,
+ 0xfac68803, 0x0001fffe, 0xffeb1a20, 0x08609ebe, 0x00000c00,
+ 0x0a216652, 0x0e739ce7, 0x050380e7, 0x0e739ce7, 0x000000e7,
+ 0x0e739ce7, 0x000000e7
+};
+
+static const struct athn_gain ar9285_1_2_tx_gain_high_power = {
+ nitems(ar9285_1_2_tx_gain_regs),
+ ar9285_1_2_tx_gain_regs,
+ NULL, /* 2GHz only. */
+ ar9285_1_2_tx_gain_high_power_vals_2g
+};
+
+/*
+ * AR9285 XE 2.0 Tx gains.
+ */
+static const uint32_t ar9285_2_0_tx_gain_vals_2g[] = {
+ 0x00000000, 0x00009200, 0x00010208, 0x00019608, 0x00022618,
+ 0x0002a6c9, 0x00031710, 0x00035718, 0x00038758, 0x0003c75a,
+ 0x0004075c, 0x0004475e, 0x0004679f, 0x000487df, 0x0003891e,
+ 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
+ 0x0003e9df, 0x0003e9df, 0x92497ca8, 0x2ad2491b, 0xedb6da6e,
+ 0xdac71441, 0x2481f6fe, 0xba5f638c, 0x48609eb4, 0x00000c04,
+ 0x0a21a652, 0x39ce739c, 0x050e039c, 0x39ce739c, 0x0000039c,
+ 0x39ce739c, 0x0000039c
+};
+
+static const struct athn_gain ar9285_2_0_tx_gain = {
+ nitems(ar9285_1_2_tx_gain_regs),
+ ar9285_1_2_tx_gain_regs,
+ NULL, /* 2GHz only. */
+ ar9285_2_0_tx_gain_vals_2g
+};
+
+static const uint32_t ar9285_2_0_tx_gain_high_power_vals_2g[] = {
+ 0x00000000, 0x00006200, 0x00008201, 0x0000b240, 0x0000d241,
+ 0x0000f600, 0x00012800, 0x00016802, 0x0001b805, 0x00021a80,
+ 0x00028b00, 0x0002ab40, 0x0002cd80, 0x00033d82, 0x0003891e,
+ 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
+ 0x0003e9df, 0x0003e9df, 0x92497ca8, 0x2ad2491b, 0xedb6da6e,
+ 0xdac71443, 0x2481f6fe, 0xba5f638c, 0x08609ebe, 0x00000c00,
+ 0x0a216652, 0x0e739ce7, 0x050380e7, 0x0e739ce7, 0x000000e7,
+ 0x0e739ce7, 0x000000e7
+};
+
+static const struct athn_gain ar9285_2_0_tx_gain_high_power = {
+ nitems(ar9285_1_2_tx_gain_regs),
+ ar9285_1_2_tx_gain_regs,
+ NULL, /* 2GHz only. */
+ ar9285_2_0_tx_gain_high_power_vals_2g
+};
+
+//#if NATHN_USB > 0
+/*
+ * AR9271 Tx gains.
+ */
+static const uint16_t ar9271_tx_gain_regs[] = {
+ P(0x0a300), P(0x0a304), P(0x0a308), P(0x0a30c), P(0x0a310),
+ P(0x0a314), P(0x0a318), P(0x0a31c), P(0x0a320), P(0x0a324),
+ P(0x0a328), P(0x0a32c), P(0x0a330), P(0x0a334), P(0x0a338),
+ P(0x0a33c), P(0x0a340), P(0x0a344), P(0x0a348), P(0x0a34c),
+ P(0x0a350), P(0x0a354), P(0x07838), P(0x07824), P(0x0786c),
+ P(0x07820), P(0x0a274), P(0x0a278), P(0x0a27c), P(0x0a394),
+ P(0x0a398), P(0x0a3dc), P(0x0a3e0)
+};
+
+static const uint32_t ar9271_tx_gain_vals_2g[] = {
+ 0x00000000, 0x00009200, 0x00010208, 0x00019608, 0x0001e610,
+ 0x0002d6d0, 0x00039758, 0x0003b759, 0x0003d75a, 0x0004175c,
+ 0x0004575e, 0x0004979f, 0x0004d7df, 0x000368de, 0x0003891e,
+ 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
+ 0x0003e9df, 0x0003e9df, 0x00000029, 0x00d8abff, 0x48609eb4,
+ 0x00000c04, 0x0a218652, 0x3bdef7bd, 0x050e83bd, 0x3bdef7bd,
+ 0x000003bd, 0x3bdef7bd, 0x000003bd
+};
+
+static const struct athn_gain ar9271_tx_gain = {
+ nitems(ar9271_tx_gain_regs),
+ ar9271_tx_gain_regs,
+ NULL, /* 2GHz only. */
+ ar9271_tx_gain_vals_2g
+};
+
+static const uint32_t ar9271_tx_gain_high_power_vals_2g[] = {
+ 0x00010000, 0x00016200, 0x00018201, 0x0001b240, 0x0001d241,
+ 0x0001f600, 0x00022800, 0x00026802, 0x0002b805, 0x0002ea41,
+ 0x00038b00, 0x0003ab40, 0x0003cd80, 0x000368de, 0x0003891e,
+ 0x0003a95e, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
+ 0x0003e9df, 0x0003e9df, 0x0000002b, 0x00d8a7ff, 0x08609eba,
+ 0x00000c00, 0x0a214652, 0x0e739ce7, 0x05018063, 0x06318c63,
+ 0x00000063, 0x06318c63, 0x00000063
+};
+
+static const struct athn_gain ar9271_tx_gain_high_power = {
+ nitems(ar9271_tx_gain_regs),
+ ar9271_tx_gain_regs,
+ NULL, /* 2GHz only. */
+ ar9271_tx_gain_high_power_vals_2g
+};
+//#endif /* NATHN_USB */
diff --git a/sys/dev/athn/ic/ar9287.c b/sys/dev/athn/ic/ar9287.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar9287.c
@@ -0,0 +1,669 @@
+/* $OpenBSD: ar9287.c,v 1.30 2022/01/09 05:42:38 jsg Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Driver for Atheros 802.11a/g/n chipsets.
+ * Routines for AR9227 and AR9287 chipsets.
+ */
+
+//#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+//#include <sys/timeout.h>
+#include <sys/conf.h>
+//#include <sys/device.h>
+//#include <sys/endian.h>
+
+#include <machine/bus.h>
+//#include <machine/intr.h>
+
+//#if NBPFILTER > 0
+//#include <net/bpf.h>
+//#endif
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+//#include <net80211/ieee80211_ra.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/athn/athnreg.h>
+#include <dev/athn/athnvar.h>
+
+#include <dev/athn/ic/ar5008reg.h>
+#include <dev/athn/ic/ar9280reg.h>
+#include <dev/athn/ic/ar9287reg.h>
+
+int ar9287_attach(struct athn_softc *);
+void ar9287_setup(struct athn_softc *);
+void ar9287_swap_rom(struct athn_softc *);
+const struct ar_spur_chan *ar9287_get_spur_chans(struct athn_softc *, int);
+void ar9287_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9287_get_pdadcs(struct athn_softc *, struct ieee80211_channel *,
+ int, int, uint8_t, uint8_t *, uint8_t *);
+void ar9287_olpc_get_pdgain(struct athn_softc *, struct ieee80211_channel *,
+ int, int8_t *);
+void ar9287_set_power_calib(struct athn_softc *,
+ struct ieee80211_channel *);
+void ar9287_set_txpower(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9287_olpc_init(struct athn_softc *);
+void ar9287_olpc_temp_compensation(struct athn_softc *);
+void ar9287_1_3_enable_async_fifo(struct athn_softc *);
+void ar9287_1_3_setup_async_fifo(struct athn_softc *);
+
+/* Extern functions. */
+uint8_t athn_chan2fbin(struct ieee80211_channel *);
+void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *);
+int ar5008_attach(struct athn_softc *);
+void ar5008_write_txpower(struct athn_softc *, int16_t power[]);
+void ar5008_get_pdadcs(struct athn_softc *, uint8_t, struct athn_pier *,
+ struct athn_pier *, int, int, uint8_t, uint8_t *, uint8_t *);
+void ar5008_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *,
+ uint8_t, const struct ar_cal_target_power_leg *, int, uint8_t[]);
+void ar5008_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *,
+ uint8_t, const struct ar_cal_target_power_ht *, int, uint8_t[]);
+int ar9280_set_synth(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9280_spur_mitigate(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+
+
+int
+ar9287_attach(struct athn_softc *sc)
+{
+ printf("%s Unimplemented...\n", __func__);
+ return 0;
+#if 0
+ sc->eep_base = (sc->flags & ATHN_FLAG_USB) ?
+ AR9287_HTC_EEP_START_LOC : AR9287_EEP_START_LOC;
+ sc->eep_size = sizeof(struct ar9287_eeprom);
+ sc->ngpiopins = (sc->flags & ATHN_FLAG_USB) ? 16 : 11;
+ sc->led_pin = (sc->flags & ATHN_FLAG_USB) ? 10 : 8;
+ sc->workaround = AR9285_WA_DEFAULT;
+ sc->ops.setup = ar9287_setup;
+ sc->ops.swap_rom = ar9287_swap_rom;
+ sc->ops.init_from_rom = ar9287_init_from_rom;
+ sc->ops.set_txpower = ar9287_set_txpower;
+ sc->ops.set_synth = ar9280_set_synth;
+ sc->ops.spur_mitigate = ar9280_spur_mitigate;
+ sc->ops.get_spur_chans = ar9287_get_spur_chans;
+ sc->ops.olpc_init = ar9287_olpc_init;
+ sc->ops.olpc_temp_compensation = ar9287_olpc_temp_compensation;
+ sc->cca_min_2g = AR9287_PHY_CCA_MIN_GOOD_VAL_2GHZ;
+ sc->cca_max_2g = AR9287_PHY_CCA_MAX_GOOD_VAL_2GHZ;
+ sc->ini = &ar9287_1_1_ini;
+ sc->serdes = &ar9280_2_0_serdes;
+
+ return (ar5008_attach(sc));
+#endif
+}
+
+void
+ar9287_setup(struct athn_softc *sc)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ const struct ar9287_eeprom *eep = sc->eep;
+
+ /* Determine if open loop power control should be used. */
+ if (eep->baseEepHeader.openLoopPwrCntl)
+ sc->flags |= ATHN_FLAG_OLPC;
+
+ sc->rx_gain = &ar9287_1_1_rx_gain;
+ sc->tx_gain = &ar9287_1_1_tx_gain;
+#endif
+}
+
+void
+ar9287_swap_rom(struct athn_softc *sc)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ struct ar9287_eeprom *eep = sc->eep;
+ int i;
+
+ eep->modalHeader.antCtrlCommon =
+ swap32(eep->modalHeader.antCtrlCommon);
+
+ for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+ eep->modalHeader.antCtrlChain[i] =
+ swap32(eep->modalHeader.antCtrlChain[i]);
+ }
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+ eep->modalHeader.spurChans[i].spurChan =
+ swap16(eep->modalHeader.spurChans[i].spurChan);
+ }
+#endif
+}
+
+const struct ar_spur_chan *
+ar9287_get_spur_chans(struct athn_softc *sc, int is2ghz)
+{
+ printf("%s Unimplemented...\n", __func__);
+ return NULL;
+#if 0
+ const struct ar9287_eeprom *eep = sc->eep;
+
+ KASSERT(is2ghz);
+ return (eep->modalHeader.spurChans);
+#endif
+}
+
+void
+ar9287_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ const struct ar9287_eeprom *eep = sc->eep;
+ const struct ar9287_modal_eep_header *modal = &eep->modalHeader;
+ uint32_t reg, offset;
+ int i;
+
+ AR_WRITE(sc, AR_PHY_SWITCH_COM, modal->antCtrlCommon);
+
+ for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+ offset = i * 0x1000;
+
+ AR_WRITE(sc, AR_PHY_SWITCH_CHAIN_0 + offset,
+ modal->antCtrlChain[i]);
+
+ reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0 + offset);
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
+ modal->iqCalICh[i]);
+ reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
+ modal->iqCalQCh[i]);
+ AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0 + offset, reg);
+
+ reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+ modal->bswMargin[i]);
+ reg = RW(reg, AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+ modal->bswAtten[i]);
+ AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg);
+
+ reg = AR_READ(sc, AR_PHY_RXGAIN + offset);
+ reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_MARGIN,
+ modal->rxTxMarginCh[i]);
+ reg = RW(reg, AR9280_PHY_RXGAIN_TXRX_ATTEN,
+ modal->txRxAttenCh[i]);
+ AR_WRITE(sc, AR_PHY_RXGAIN + offset, reg);
+ }
+
+ reg = AR_READ(sc, AR_PHY_SETTLING);
+ if (extc != NULL)
+ reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->swSettleHt40);
+ else
+ reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling);
+ AR_WRITE(sc, AR_PHY_SETTLING, reg);
+
+ reg = AR_READ(sc, AR_PHY_DESIRED_SZ);
+ reg = RW(reg, AR_PHY_DESIRED_SZ_ADC, modal->adcDesiredSize);
+ AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg);
+
+ reg = SM(AR_PHY_RF_CTL4_TX_END_XPAA_OFF, modal->txEndToXpaOff);
+ reg |= SM(AR_PHY_RF_CTL4_TX_END_XPAB_OFF, modal->txEndToXpaOff);
+ reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAA_ON, modal->txFrameToXpaOn);
+ reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAB_ON, modal->txFrameToXpaOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL4, reg);
+
+ reg = AR_READ(sc, AR_PHY_RF_CTL3);
+ reg = RW(reg, AR_PHY_TX_END_TO_A2_RX_ON, modal->txEndToRxOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL3, reg);
+
+ reg = AR_READ(sc, AR_PHY_CCA(0));
+ reg = RW(reg, AR9280_PHY_CCA_THRESH62, modal->thresh62);
+ AR_WRITE(sc, AR_PHY_CCA(0), reg);
+
+ reg = AR_READ(sc, AR_PHY_EXT_CCA0);
+ reg = RW(reg, AR_PHY_EXT_CCA0_THRESH62, modal->thresh62);
+ AR_WRITE(sc, AR_PHY_EXT_CCA0, reg);
+
+ reg = AR_READ(sc, AR9287_AN_RF2G3_CH0);
+ reg = RW(reg, AR9287_AN_RF2G3_DB1, modal->db1);
+ reg = RW(reg, AR9287_AN_RF2G3_DB2, modal->db2);
+ reg = RW(reg, AR9287_AN_RF2G3_OB_CCK, modal->ob_cck);
+ reg = RW(reg, AR9287_AN_RF2G3_OB_PSK, modal->ob_psk);
+ reg = RW(reg, AR9287_AN_RF2G3_OB_QAM, modal->ob_qam);
+ reg = RW(reg, AR9287_AN_RF2G3_OB_PAL_OFF, modal->ob_pal_off);
+ AR_WRITE(sc, AR9287_AN_RF2G3_CH0, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+
+ reg = AR_READ(sc, AR9287_AN_RF2G3_CH1);
+ reg = RW(reg, AR9287_AN_RF2G3_DB1, modal->db1);
+ reg = RW(reg, AR9287_AN_RF2G3_DB2, modal->db2);
+ reg = RW(reg, AR9287_AN_RF2G3_OB_CCK, modal->ob_cck);
+ reg = RW(reg, AR9287_AN_RF2G3_OB_PSK, modal->ob_psk);
+ reg = RW(reg, AR9287_AN_RF2G3_OB_QAM, modal->ob_qam);
+ reg = RW(reg, AR9287_AN_RF2G3_OB_PAL_OFF, modal->ob_pal_off);
+ AR_WRITE(sc, AR9287_AN_RF2G3_CH1, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+
+ reg = AR_READ(sc, AR_PHY_RF_CTL2);
+ reg = RW(reg, AR_PHY_TX_END_DATA_START, modal->txFrameToDataStart);
+ reg = RW(reg, AR_PHY_TX_END_PA_ON, modal->txFrameToPaOn);
+ AR_WRITE(sc, AR_PHY_RF_CTL2, reg);
+
+ reg = AR_READ(sc, AR9287_AN_TOP2);
+ reg = RW(reg, AR9287_AN_TOP2_XPABIAS_LVL, modal->xpaBiasLvl);
+ AR_WRITE(sc, AR9287_AN_TOP2, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+#endif
+}
+
+void
+ar9287_get_pdadcs(struct athn_softc *sc, struct ieee80211_channel *c,
+ int chain, int nxpdgains, uint8_t overlap, uint8_t *boundaries,
+ uint8_t *pdadcs)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ const struct ar9287_eeprom *eep = sc->eep;
+ const struct ar9287_cal_data_per_freq *pierdata;
+ const uint8_t *pierfreq;
+ struct athn_pier lopier, hipier;
+ int16_t delta;
+ uint8_t fbin;
+ int i, lo, hi, npiers;
+
+ pierfreq = eep->calFreqPier2G;
+ pierdata = (const struct ar9287_cal_data_per_freq *)
+ eep->calPierData2G[chain];
+ npiers = AR9287_NUM_2G_CAL_PIERS;
+
+ /* Find channel in ROM pier table. */
+ fbin = athn_chan2fbin(c);
+ athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi);
+
+ lopier.fbin = pierfreq[lo];
+ hipier.fbin = pierfreq[hi];
+ for (i = 0; i < nxpdgains; i++) {
+ lopier.pwr[i] = pierdata[lo].pwrPdg[i];
+ lopier.vpd[i] = pierdata[lo].vpdPdg[i];
+ hipier.pwr[i] = pierdata[lo].pwrPdg[i];
+ hipier.vpd[i] = pierdata[lo].vpdPdg[i];
+ }
+ ar5008_get_pdadcs(sc, fbin, &lopier, &hipier, nxpdgains,
+ AR9287_PD_GAIN_ICEPTS, overlap, boundaries, pdadcs);
+
+ delta = (eep->baseEepHeader.pwrTableOffset -
+ AR_PWR_TABLE_OFFSET_DB) * 2; /* In half dB. */
+ if (delta != 0) {
+ /* Shift the PDADC table to start at the new offset. */
+ /* XXX Our padding value differs from Linux. */
+ for (i = 0; i < AR_NUM_PDADC_VALUES; i++)
+ pdadcs[i] = pdadcs[MIN(i + delta,
+ AR_NUM_PDADC_VALUES - 1)];
+ }
+#endif
+}
+
+void
+ar9287_olpc_get_pdgain(struct athn_softc *sc, struct ieee80211_channel *c,
+ int chain, int8_t *pwr)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ const struct ar9287_eeprom *eep = sc->eep;
+ const struct ar_cal_data_per_freq_olpc *pierdata;
+ const uint8_t *pierfreq;
+ uint8_t fbin;
+ int lo, hi, npiers;
+
+ pierfreq = eep->calFreqPier2G;
+ pierdata = (const struct ar_cal_data_per_freq_olpc *)
+ eep->calPierData2G[chain];
+ npiers = AR9287_NUM_2G_CAL_PIERS;
+
+ /* Find channel in ROM pier table. */
+ fbin = athn_chan2fbin(c);
+ athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi);
+
+#if 0
+ *pwr = athn_interpolate(fbin,
+ pierfreq[lo], pierdata[lo].pwrPdg[0][0],
+ pierfreq[hi], pierdata[hi].pwrPdg[0][0]);
+#else
+ *pwr = (pierdata[lo].pwrPdg[0][0] + pierdata[hi].pwrPdg[0][0]) / 2;
+#endif
+#endif // FreeBSD endif
+}
+
+void
+ar9287_set_power_calib(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ const struct ar9287_eeprom *eep = sc->eep;
+ uint8_t boundaries[AR_PD_GAINS_IN_MASK];
+ uint8_t pdadcs[AR_NUM_PDADC_VALUES];
+ uint8_t xpdgains[AR9287_NUM_PD_GAINS];
+ int8_t txpower;
+ uint8_t overlap;
+ uint32_t reg, offset;
+ int i, j, nxpdgains;
+
+ if (sc->eep_rev < AR_EEP_MINOR_VER_2) {
+ overlap = MS(AR_READ(sc, AR_PHY_TPCRG5),
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP);
+ } else
+ overlap = eep->modalHeader.pdGainOverlap;
+
+ if (sc->flags & ATHN_FLAG_OLPC) {
+ /* XXX not here. */
+ sc->pdadc =
+ ((const struct ar_cal_data_per_freq_olpc *)
+ eep->calPierData2G[0])->vpdPdg[0][0];
+ }
+
+ nxpdgains = 0;
+ memset(xpdgains, 0, sizeof(xpdgains));
+ for (i = AR9287_PD_GAINS_IN_MASK - 1; i >= 0; i--) {
+ if (nxpdgains >= AR9287_NUM_PD_GAINS)
+ break; /* Can't happen. */
+ if (eep->modalHeader.xpdGain & (1 << i))
+ xpdgains[nxpdgains++] = i;
+ }
+ reg = AR_READ(sc, AR_PHY_TPCRG1);
+ reg = RW(reg, AR_PHY_TPCRG1_NUM_PD_GAIN, nxpdgains - 1);
+ reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_1, xpdgains[0]);
+ reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_2, xpdgains[1]);
+ AR_WRITE(sc, AR_PHY_TPCRG1, reg);
+ AR_WRITE_BARRIER(sc);
+
+ for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+ if (!(sc->txchainmask & (1 << i)))
+ continue;
+
+ offset = i * 0x1000;
+
+ if (sc->flags & ATHN_FLAG_OLPC) {
+ ar9287_olpc_get_pdgain(sc, c, i, &txpower);
+
+ reg = AR_READ(sc, AR_PHY_TX_PWRCTRL6_0);
+ reg = RW(reg, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+ AR_WRITE(sc, AR_PHY_TX_PWRCTRL6_0, reg);
+
+ reg = AR_READ(sc, AR_PHY_TX_PWRCTRL6_1);
+ reg = RW(reg, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+ AR_WRITE(sc, AR_PHY_TX_PWRCTRL6_1, reg);
+
+ /* NB: txpower is in half dB. */
+ reg = AR_READ(sc, AR_PHY_CH0_TX_PWRCTRL11 + offset);
+ reg = RW(reg, AR_PHY_TX_PWRCTRL_OLPC_PWR, txpower);
+ AR_WRITE(sc, AR_PHY_CH0_TX_PWRCTRL11 + offset, reg);
+
+ AR_WRITE_BARRIER(sc);
+ continue; /* That's it for open loop mode. */
+ }
+
+ /* Closed loop power control. */
+ ar9287_get_pdadcs(sc, c, i, nxpdgains, overlap,
+ boundaries, pdadcs);
+
+ /* Write boundaries. */
+ if (i == 0) {
+ reg = SM(AR_PHY_TPCRG5_PD_GAIN_OVERLAP,
+ overlap);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1,
+ boundaries[0]);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2,
+ boundaries[1]);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3,
+ boundaries[2]);
+ reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4,
+ boundaries[3]);
+ AR_WRITE(sc, AR_PHY_TPCRG5 + offset, reg);
+ }
+ /* Write PDADC values. */
+ for (j = 0; j < AR_NUM_PDADC_VALUES; j += 4) {
+ AR_WRITE(sc, AR_PHY_PDADC_TBL_BASE + offset + j,
+ pdadcs[j + 0] << 0 |
+ pdadcs[j + 1] << 8 |
+ pdadcs[j + 2] << 16 |
+ pdadcs[j + 3] << 24);
+ }
+ AR_WRITE_BARRIER(sc);
+ }
+#endif
+}
+
+void
+ar9287_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ const struct ar9287_eeprom *eep = sc->eep;
+ const struct ar9287_modal_eep_header *modal = &eep->modalHeader;
+ uint8_t tpow_cck[4], tpow_ofdm[4];
+ uint8_t tpow_cck_ext[4], tpow_ofdm_ext[4];
+ uint8_t tpow_ht20[8], tpow_ht40[8];
+ uint8_t ht40inc;
+ int16_t pwr = 0, max_ant_gain, power[ATHN_POWER_COUNT];
+ int i;
+
+ ar9287_set_power_calib(sc, c);
+
+ /* Compute transmit power reduction due to antenna gain. */
+ max_ant_gain = MAX(modal->antennaGainCh[0], modal->antennaGainCh[1]);
+ /* XXX */
+
+ /*
+ * Reduce scaled power by number of active chains to get per-chain
+ * transmit power level.
+ */
+ if (sc->ntxchains == 2)
+ pwr -= AR_PWR_DECREASE_FOR_2_CHAIN;
+ if (pwr < 0)
+ pwr = 0;
+
+ /* Get CCK target powers. */
+ ar5008_get_lg_tpow(sc, c, AR_CTL_11B, eep->calTargetPowerCck,
+ AR9287_NUM_2G_CCK_TARGET_POWERS, tpow_cck);
+
+ /* Get OFDM target powers. */
+ ar5008_get_lg_tpow(sc, c, AR_CTL_11G, eep->calTargetPower2G,
+ AR9287_NUM_2G_20_TARGET_POWERS, tpow_ofdm);
+
+ /* Get HT-20 target powers. */
+ ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT20, eep->calTargetPower2GHT20,
+ AR9287_NUM_2G_20_TARGET_POWERS, tpow_ht20);
+
+ if (extc != NULL) {
+ /* Get HT-40 target powers. */
+ ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT40,
+ eep->calTargetPower2GHT40, AR9287_NUM_2G_40_TARGET_POWERS,
+ tpow_ht40);
+
+ /* Get secondary channel CCK target powers. */
+ ar5008_get_lg_tpow(sc, extc, AR_CTL_11B,
+ eep->calTargetPowerCck, AR9287_NUM_2G_CCK_TARGET_POWERS,
+ tpow_cck_ext);
+
+ /* Get secondary channel OFDM target powers. */
+ ar5008_get_lg_tpow(sc, extc, AR_CTL_11G,
+ eep->calTargetPower2G, AR9287_NUM_2G_20_TARGET_POWERS,
+ tpow_ofdm_ext);
+ }
+
+ memset(power, 0, sizeof(power));
+ /* Shuffle target powers across transmit rates. */
+ power[ATHN_POWER_OFDM6 ] =
+ power[ATHN_POWER_OFDM9 ] =
+ power[ATHN_POWER_OFDM12 ] =
+ power[ATHN_POWER_OFDM18 ] =
+ power[ATHN_POWER_OFDM24 ] = tpow_ofdm[0];
+ power[ATHN_POWER_OFDM36 ] = tpow_ofdm[1];
+ power[ATHN_POWER_OFDM48 ] = tpow_ofdm[2];
+ power[ATHN_POWER_OFDM54 ] = tpow_ofdm[3];
+ power[ATHN_POWER_XR ] = tpow_ofdm[0];
+ power[ATHN_POWER_CCK1_LP ] = tpow_cck[0];
+ power[ATHN_POWER_CCK2_LP ] =
+ power[ATHN_POWER_CCK2_SP ] = tpow_cck[1];
+ power[ATHN_POWER_CCK55_LP] =
+ power[ATHN_POWER_CCK55_SP] = tpow_cck[2];
+ power[ATHN_POWER_CCK11_LP] =
+ power[ATHN_POWER_CCK11_SP] = tpow_cck[3];
+ for (i = 0; i < nitems(tpow_ht20); i++)
+ power[ATHN_POWER_HT20(i)] = tpow_ht20[i];
+ if (extc != NULL) {
+ /* Correct PAR difference between HT40 and HT20/Legacy. */
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_2)
+ ht40inc = modal->ht40PowerIncForPdadc;
+ else
+ ht40inc = AR_HT40_POWER_INC_FOR_PDADC;
+ for (i = 0; i < nitems(tpow_ht40); i++)
+ power[ATHN_POWER_HT40(i)] = tpow_ht40[i] + ht40inc;
+ power[ATHN_POWER_OFDM_DUP] = tpow_ht40[0];
+ power[ATHN_POWER_CCK_DUP ] = tpow_ht40[0];
+ power[ATHN_POWER_OFDM_EXT] = tpow_ofdm_ext[0];
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ power[ATHN_POWER_CCK_EXT] = tpow_cck_ext[0];
+ }
+
+ for (i = 0; i < ATHN_POWER_COUNT; i++) {
+ power[i] -= AR_PWR_TABLE_OFFSET_DB * 2; /* In half dB. */
+ if (power[i] > AR_MAX_RATE_POWER)
+ power[i] = AR_MAX_RATE_POWER;
+ }
+ /* Commit transmit power values to hardware. */
+ ar5008_write_txpower(sc, power);
+#endif
+}
+
+void
+ar9287_olpc_init(struct athn_softc *sc)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ uint32_t reg;
+
+ AR_SETBITS(sc, AR_PHY_TX_PWRCTRL9, AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
+
+ reg = AR_READ(sc, AR9287_AN_TXPC0);
+ reg = RW(reg, AR9287_AN_TXPC0_TXPCMODE,
+ AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
+ AR_WRITE(sc, AR9287_AN_TXPC0, reg);
+ AR_WRITE_BARRIER(sc);
+ DELAY(100);
+#endif
+}
+
+void
+ar9287_olpc_temp_compensation(struct athn_softc *sc)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ const struct ar9287_eeprom *eep = sc->eep;
+ int8_t pdadc, slope, tcomp;
+ uint32_t reg;
+
+ reg = AR_READ(sc, AR_PHY_TX_PWRCTRL4);
+ pdadc = MS(reg, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+ DPRINTFN(3, ("PD Avg Out=%d\n", pdadc));
+
+ if (sc->pdadc == 0 || pdadc == 0)
+ return; /* No frames transmitted yet. */
+
+ /* Compute Tx gain temperature compensation. */
+ if (sc->eep_rev >= AR_EEP_MINOR_VER_2)
+ slope = eep->baseEepHeader.tempSensSlope;
+ else
+ slope = 0;
+ if (slope != 0) /* Prevents division by zero. */
+ tcomp = ((pdadc - sc->pdadc) * 4) / slope;
+ else
+ tcomp = 0;
+ DPRINTFN(3, ("OLPC temp compensation=%d\n", tcomp));
+
+ /* Write compensation value for both Tx chains. */
+ reg = AR_READ(sc, AR_PHY_CH0_TX_PWRCTRL11);
+ reg = RW(reg, AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, tcomp);
+ AR_WRITE(sc, AR_PHY_CH0_TX_PWRCTRL11, reg);
+
+ reg = AR_READ(sc, AR_PHY_CH1_TX_PWRCTRL11);
+ reg = RW(reg, AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, tcomp);
+ AR_WRITE(sc, AR_PHY_CH1_TX_PWRCTRL11, reg);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+ar9287_1_3_enable_async_fifo(struct athn_softc *sc)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ /* Enable ASYNC FIFO. */
+ AR_SETBITS(sc, AR_MAC_PCU_ASYNC_FIFO_REG3,
+ AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
+ AR_SETBITS(sc, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
+ AR_CLRBITS(sc, AR_MAC_PCU_ASYNC_FIFO_REG3,
+ AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+ AR_SETBITS(sc, AR_MAC_PCU_ASYNC_FIFO_REG3,
+ AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+ar9287_1_3_setup_async_fifo(struct athn_softc *sc)
+{
+ printf("%s Unimplemented...\n", __func__);
+#if 0
+ uint32_t reg;
+
+ /*
+ * MAC runs at 117MHz (instead of 88/44MHz) when ASYNC FIFO is
+ * enabled, so the following counters have to be changed.
+ */
+ AR_WRITE(sc, AR_D_GBL_IFS_SIFS, AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
+ AR_WRITE(sc, AR_D_GBL_IFS_SLOT, AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
+ AR_WRITE(sc, AR_D_GBL_IFS_EIFS, AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
+
+ AR_WRITE(sc, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
+ AR_WRITE(sc, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
+
+ AR_SETBITS(sc, AR_MAC_PCU_LOGIC_ANALYZER,
+ AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
+
+ reg = AR_READ(sc, AR_AHB_MODE);
+ reg = RW(reg, AR_AHB_CUSTOM_BURST, AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
+ AR_WRITE(sc, AR_AHB_MODE, reg);
+
+ AR_SETBITS(sc, AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
diff --git a/sys/dev/athn/ic/ar9287reg.h b/sys/dev/athn/ic/ar9287reg.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar9287reg.h
@@ -0,0 +1,531 @@
+/* $OpenBSD: ar9287reg.h,v 1.6 2019/03/29 11:04:40 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define AR9287_MAX_CHAINS 2
+
+#define AR9287_PHY_CCA_MIN_GOOD_VAL_2GHZ (-127)
+#define AR9287_PHY_CCA_MAX_GOOD_VAL_2GHZ (-97)
+
+/*
+ * Analog registers.
+ */
+#define AR9287_AN_RF2G3_CH0 0x7808
+#define AR9287_AN_RF2G3_CH1 0x785c
+#define AR9287_AN_TXPC0 0x7898
+#define AR9287_AN_TOP2 0x78b4
+
+/* Bits for AR9287_AN_RF2G3_CH[01]. */
+#define AR9287_AN_RF2G3_OB_PAL_OFF_M 0x0001c000
+#define AR9287_AN_RF2G3_OB_PAL_OFF_S 14
+#define AR9287_AN_RF2G3_OB_QAM_M 0x000e0000
+#define AR9287_AN_RF2G3_OB_QAM_S 17
+#define AR9287_AN_RF2G3_OB_PSK_M 0x00700000
+#define AR9287_AN_RF2G3_OB_PSK_S 20
+#define AR9287_AN_RF2G3_OB_CCK_M 0x03800000
+#define AR9287_AN_RF2G3_OB_CCK_S 23
+#define AR9287_AN_RF2G3_DB2_M 0x1c000000
+#define AR9287_AN_RF2G3_DB2_S 26
+#define AR9287_AN_RF2G3_DB1_M 0xe0000000
+#define AR9287_AN_RF2G3_DB1_S 29
+
+/* Bits for AR9287_AN_TXPC0. */
+#define AR9287_AN_TXPC0_TXPCMODE_M 0x0000c000
+#define AR9287_AN_TXPC0_TXPCMODE_S 14
+#define AR9287_AN_TXPC0_TXPCMODE_NORMAL 0
+#define AR9287_AN_TXPC0_TXPCMODE_TEST 1
+#define AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE 2
+#define AR9287_AN_TXPC0_TXPCMODE_ATBTEST 3
+
+/* Bits for AR9287_AN_TOP2. */
+#define AR9287_AN_TOP2_XPABIAS_LVL_M 0xc0000000
+#define AR9287_AN_TOP2_XPABIAS_LVL_S 30
+
+/*
+ * ROM layout used by AR9287 (2GHz only).
+ */
+#define AR9287_EEP_START_LOC 128
+#define AR9287_HTC_EEP_START_LOC 256
+#define AR9287_NUM_2G_CAL_PIERS 3
+#define AR9287_NUM_2G_CCK_TARGET_POWERS 3
+#define AR9287_NUM_2G_20_TARGET_POWERS 3
+#define AR9287_NUM_2G_40_TARGET_POWERS 3
+#define AR9287_NUM_CTLS 12
+#define AR9287_NUM_BAND_EDGES 4
+#define AR9287_NUM_PD_GAINS 4
+#define AR9287_PD_GAINS_IN_MASK 4
+#define AR9287_PD_GAIN_ICEPTS 1
+#define AR9287_MAX_RATE_POWER 63
+#define AR9287_NUM_RATES 16
+
+struct ar9287_base_eep_header {
+ uint16_t length;
+ uint16_t checksum;
+ uint16_t version;
+ uint8_t opCapFlags;
+ uint8_t eepMisc;
+#define AR9287_EEPMISC_BIG_ENDIAN 0x01
+#define AR9287_EEPMISC_WOW 0x02
+
+ uint16_t regDmn[2];
+ uint8_t macAddr[6];
+ uint8_t rxMask;
+ uint8_t txMask;
+ uint16_t rfSilent;
+ uint16_t blueToothOptions;
+ uint16_t deviceCap;
+ uint32_t binBuildNumber;
+ uint8_t deviceType;
+ /* End of common header. */
+ uint8_t openLoopPwrCntl;
+ int8_t pwrTableOffset;
+ int8_t tempSensSlope;
+ int8_t tempSensSlopePalOn;
+ uint8_t futureBase[29];
+} __packed;
+
+struct ar9287_modal_eep_header {
+ uint32_t antCtrlChain[AR9287_MAX_CHAINS];
+ uint32_t antCtrlCommon;
+ int8_t antennaGainCh[AR9287_MAX_CHAINS];
+ uint8_t switchSettling;
+ uint8_t txRxAttenCh[AR9287_MAX_CHAINS];
+ uint8_t rxTxMarginCh[AR9287_MAX_CHAINS];
+ int8_t adcDesiredSize;
+ uint8_t txEndToXpaOff;
+ uint8_t txEndToRxOn;
+ uint8_t txFrameToXpaOn;
+ uint8_t thresh62;
+ int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS];
+ uint8_t xpdGain;
+ uint8_t xpd;
+ int8_t iqCalICh[AR9287_MAX_CHAINS];
+ int8_t iqCalQCh[AR9287_MAX_CHAINS];
+ uint8_t pdGainOverlap;
+ uint8_t xpaBiasLvl;
+ uint8_t txFrameToDataStart;
+ uint8_t txFrameToPaOn;
+ uint8_t ht40PowerIncForPdadc;
+ uint8_t bswAtten[AR9287_MAX_CHAINS];
+ uint8_t bswMargin[AR9287_MAX_CHAINS];
+ uint8_t swSettleHt40;
+ uint8_t version;
+ uint8_t db1;
+ uint8_t db2;
+ uint8_t ob_cck;
+ uint8_t ob_psk;
+ uint8_t ob_qam;
+ uint8_t ob_pal_off;
+ uint8_t futureModal[30];
+ struct ar_spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
+} __packed;
+
+struct ar9287_cal_data_per_freq {
+ uint8_t pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
+ uint8_t vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
+} __packed;
+
+union ar9287_cal_data_per_freq_u {
+ struct ar_cal_data_per_freq_olpc calDataOpen;
+ struct ar9287_cal_data_per_freq calDataClose;
+} __packed;
+
+struct ar9287_cal_ctl_data {
+ struct ar_cal_ctl_edges
+ ctlEdges[AR9287_MAX_CHAINS][AR9287_NUM_BAND_EDGES];
+} __packed;
+
+struct ar9287_eeprom {
+ struct ar9287_base_eep_header baseEepHeader;
+ uint8_t custData[32];
+ struct ar9287_modal_eep_header modalHeader;
+ uint8_t calFreqPier2G[AR9287_NUM_2G_CAL_PIERS];
+ union ar9287_cal_data_per_freq_u
+ calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS];
+ struct ar_cal_target_power_leg
+ calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS];
+ struct ar_cal_target_power_leg
+ calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS];
+ uint8_t ctlIndex[AR9287_NUM_CTLS];
+ struct ar9287_cal_ctl_data ctlData[AR9287_NUM_CTLS];
+ uint8_t padding;
+} __packed;
+
+/* Macro to "pack" registers to 16-bit to save some .rodata space. */
+#define P(x) (x)
+
+/*
+ * AR9287 1.1 initialization values.
+ */
+static const uint16_t ar9287_1_1_regs[] = {
+ P(0x01030), P(0x01070), P(0x010b0), P(0x010f0), P(0x08014),
+ P(0x0801c), P(0x08120), P(0x081d0), P(0x08318), P(0x09804),
+ P(0x09820), P(0x09824), P(0x09828), P(0x09834), P(0x09838),
+ P(0x09840), P(0x09844), P(0x09850), P(0x09858), P(0x0985c),
+ P(0x09860), P(0x09864), P(0x09868), P(0x0986c), P(0x09914),
+ P(0x09918), P(0x09924), P(0x09944), P(0x09960), P(0x0a960),
+ P(0x09964), P(0x0c968), P(0x099b8), P(0x099bc), P(0x099c0),
+ P(0x0a204), P(0x0a20c), P(0x0b20c), P(0x0a21c), P(0x0a230),
+ P(0x0a250), P(0x0a358), P(0x0a3d8)
+};
+
+static const uint32_t ar9287_1_1_vals_2g40[] = {
+ 0x000002c0, 0x00000318, 0x00007c70, 0x00000000, 0x10801600,
+ 0x12e00057, 0x08f04810, 0x0000320a, 0x00006880, 0x000003c4,
+ 0x02020200, 0x01000e0e, 0x3a020001, 0x00000e0e, 0x00000007,
+ 0x206a012e, 0x037216a0, 0x6d4000e2, 0x7ec84d2e, 0x3139605e,
+ 0x00058d20, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x00001130,
+ 0x00000016, 0xd00a8a0d, 0xefbc1010, 0x00000010, 0x00000010,
+ 0x00000210, 0x000003ce, 0x0000001c, 0x00000c00, 0x05eea6d4,
+ 0x00000444, 0x00000000, 0x00000000, 0x1883800a, 0x00000210,
+ 0x0004a000, 0x7999aa0e, 0x00000000
+};
+
+static const uint32_t ar9287_1_1_vals_2g20[] = {
+ 0x00000160, 0x0000018c, 0x00003e38, 0x00000000, 0x08400b00,
+ 0x12e0002b, 0x08f04810, 0x0000320a, 0x00003440, 0x00000300,
+ 0x02020200, 0x01000e0e, 0x3a020001, 0x00000e0e, 0x00000007,
+ 0x206a012e, 0x037216a0, 0x6c4000e2, 0x7ec84d2e, 0x31395d5e,
+ 0x00058d20, 0x0001ce00, 0x5ac640d0, 0x06903881, 0x00000898,
+ 0x0000000b, 0xd00a8a0d, 0xefbc1010, 0x00000010, 0x00000010,
+ 0x00000210, 0x000003ce, 0x0000001c, 0x00000c00, 0x05eea6d4,
+ 0x00000444, 0x00000000, 0x00000000, 0x1883800a, 0x00000108,
+ 0x0004a000, 0x7999aa0e, 0x00000000
+};
+
+static const uint16_t ar9287_1_1_cm_regs[] = {
+ P(0x0000c), P(0x00030), P(0x00034), P(0x00040), P(0x00044),
+ P(0x00048), P(0x0004c), P(0x00050), P(0x00054), P(0x00800),
+ P(0x00804), P(0x00808), P(0x0080c), P(0x00810), P(0x00814),
+ P(0x00818), P(0x0081c), P(0x00820), P(0x00824), P(0x01040),
+ P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054),
+ P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x01230),
+ P(0x01270), P(0x01038), P(0x01078), P(0x010b8), P(0x010f8),
+ P(0x01138), P(0x01178), P(0x011b8), P(0x011f8), P(0x01238),
+ P(0x01278), P(0x012b8), P(0x012f8), P(0x01338), P(0x01378),
+ P(0x013b8), P(0x013f8), P(0x01438), P(0x01478), P(0x014b8),
+ P(0x014f8), P(0x01538), P(0x01578), P(0x015b8), P(0x015f8),
+ P(0x01638), P(0x01678), P(0x016b8), P(0x016f8), P(0x01738),
+ P(0x01778), P(0x017b8), P(0x017f8), P(0x0103c), P(0x0107c),
+ P(0x010bc), P(0x010fc), P(0x0113c), P(0x0117c), P(0x011bc),
+ P(0x011fc), P(0x0123c), P(0x0127c), P(0x012bc), P(0x012fc),
+ P(0x0133c), P(0x0137c), P(0x013bc), P(0x013fc), P(0x0143c),
+ P(0x0147c), P(0x04030), P(0x0403c), P(0x04024), P(0x04060),
+ P(0x04064), P(0x07010), P(0x07020), P(0x07034), P(0x07038),
+ P(0x08004), P(0x08008), P(0x0800c), P(0x08018), P(0x08020),
+ P(0x08038), P(0x0803c), P(0x08048), P(0x08054), P(0x08058),
+ P(0x0805c), P(0x08060), P(0x08064), P(0x08070), P(0x080c0),
+ P(0x080c4), P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4),
+ P(0x080d8), P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec),
+ P(0x080f0), P(0x080f4), P(0x080f8), P(0x080fc), P(0x08100),
+ P(0x08104), P(0x08108), P(0x0810c), P(0x08110), P(0x08118),
+ P(0x0811c), P(0x08124), P(0x08128), P(0x0812c), P(0x08130),
+ P(0x08134), P(0x08138), P(0x0813c), P(0x08144), P(0x08168),
+ P(0x0816c), P(0x08170), P(0x08174), P(0x08178), P(0x0817c),
+ P(0x081c0), P(0x081c4), P(0x081d4), P(0x081ec), P(0x081f0),
+ P(0x081f4), P(0x081f8), P(0x081fc), P(0x08200), P(0x08204),
+ P(0x08208), P(0x0820c), P(0x08210), P(0x08214), P(0x08218),
+ P(0x0821c), P(0x08220), P(0x08224), P(0x08228), P(0x0822c),
+ P(0x08230), P(0x08234), P(0x08238), P(0x0823c), P(0x08240),
+ P(0x08244), P(0x08248), P(0x0824c), P(0x08250), P(0x08254),
+ P(0x08258), P(0x0825c), P(0x08260), P(0x08264), P(0x08270),
+ P(0x08274), P(0x08278), P(0x0827c), P(0x08284), P(0x08288),
+ P(0x0828c), P(0x08294), P(0x08298), P(0x0829c), P(0x08300),
+ P(0x08314), P(0x08328), P(0x0832c), P(0x08330), P(0x08334),
+ P(0x08338), P(0x0833c), P(0x08340), P(0x08344), P(0x08360),
+ P(0x08364), P(0x08368), P(0x08370), P(0x08374), P(0x08378),
+ P(0x0837c), P(0x08380), P(0x08384), P(0x08390), P(0x08394),
+ P(0x08398), P(0x0839c), P(0x083a0), P(0x09808), P(0x0980c),
+ P(0x09810), P(0x09814), P(0x0981c), P(0x0982c), P(0x09830),
+ P(0x0983c), P(0x0984c), P(0x0a84c), P(0x09854), P(0x09900),
+ P(0x09904), P(0x09908), P(0x0990c), P(0x09910), P(0x0991c),
+ P(0x09920), P(0x0a920), P(0x09928), P(0x0992c), P(0x09930),
+ P(0x0a930), P(0x09934), P(0x09938), P(0x0993c), P(0x09948),
+ P(0x0994c), P(0x09954), P(0x09958), P(0x09940), P(0x0c95c),
+ P(0x09970), P(0x09974), P(0x09978), P(0x0997c), P(0x099a0),
+ P(0x099a4), P(0x099a8), P(0x099ac), P(0x099b0), P(0x099b4),
+ P(0x099c4), P(0x099c8), P(0x099cc), P(0x099d0), P(0x099dc),
+ P(0x099e0), P(0x099e4), P(0x099e8), P(0x099ec), P(0x099f0),
+ P(0x099fc), P(0x0a208), P(0x0a210), P(0x0a214), P(0x0a218),
+ P(0x0a220), P(0x0a224), P(0x0a228), P(0x0a22c), P(0x0a234),
+ P(0x0a238), P(0x0a23c), P(0x0a240), P(0x0a244), P(0x0a248),
+ P(0x0a24c), P(0x0a254), P(0x0a258), P(0x0a25c), P(0x0a260),
+ P(0x0a264), P(0x0b264), P(0x0a268), P(0x0a26c), P(0x0b26c),
+ P(0x0d270), P(0x0a278), P(0x0a27c), P(0x0d35c), P(0x0d360),
+ P(0x0d364), P(0x0d368), P(0x0d36c), P(0x0d370), P(0x0d374),
+ P(0x0d378), P(0x0d37c), P(0x0d380), P(0x0d384), P(0x0a388),
+ P(0x0a38c), P(0x0a390), P(0x0a394), P(0x0a398), P(0x0b398),
+ P(0x0a39c), P(0x0a3c8), P(0x0a3cc), P(0x0a3d0), P(0x0a3d4),
+ P(0x0a3dc), P(0x0a3e0), P(0x0a3e4), P(0x0a3e8), P(0x0a3ec),
+ P(0x0a3f0), P(0x0a3f4), P(0x0b3f4), P(0x0a7d8), P(0x07800),
+ P(0x07804), P(0x07808), P(0x0780c), P(0x07810), P(0x07814),
+ P(0x07818), P(0x0781c), P(0x07820), P(0x07824), P(0x07828),
+ P(0x0782c), P(0x07830), P(0x07834), P(0x07838), P(0x0783c),
+ P(0x07840), P(0x07844), P(0x07848), P(0x07850), P(0x07854),
+ P(0x07858), P(0x0785c), P(0x07860), P(0x07864), P(0x07868),
+ P(0x0786c), P(0x07870), P(0x07874), P(0x07878), P(0x0787c),
+ P(0x07880), P(0x07884), P(0x07888), P(0x0788c), P(0x07890),
+ P(0x07894), P(0x07898), P(0x0789c), P(0x078a0), P(0x078a4),
+ P(0x078a8), P(0x078ac), P(0x078b0), P(0x078b4), P(0x078b8)
+};
+
+static const uint32_t ar9287_1_1_cm_vals[] = {
+ 0x00000000, 0x00020015, 0x00000005, 0x00000000, 0x00000008,
+ 0x00000008, 0x00000010, 0x00000000, 0x0000001f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000002, 0x00000002, 0x0000001f, 0x00000000,
+ 0x00000000, 0x00000033, 0x00000000, 0x00000002, 0x000004c2,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000700, 0x00000000,
+ 0x00000000, 0x00000000, 0x40000000, 0x00000000, 0x00000000,
+ 0x000fc78f, 0x0000000f, 0x00000000, 0x00000000, 0x2a80001a,
+ 0x05dc01e0, 0x1f402710, 0x01f40000, 0x00001e00, 0x00000000,
+ 0x00400000, 0xffffffff, 0x0000ffff, 0x003f3f3f, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00020000, 0x00020000,
+ 0x00000001, 0x00000052, 0x00000000, 0x00000168, 0x000100aa,
+ 0x00003210, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000,
+ 0x00000000, 0x18487320, 0xfaa4fa50, 0x00000100, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00100000,
+ 0x0010f400, 0x00000100, 0x0001e800, 0x00000000, 0x00000000,
+ 0x00000000, 0x400000ff, 0x00080922, 0x88a00010, 0x00000000,
+ 0x40000000, 0x003e4180, 0x00000000, 0x0000002c, 0x0000002c,
+ 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000040,
+ 0x00000000, 0x00000000, 0x00000007, 0x00000302, 0x00000e00,
+ 0x00ff0000, 0x00000000, 0x000107ff, 0x01c81043, 0xffffffff,
+ 0xffffffff, 0x00000000, 0x00000000, 0x000000ff, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x0fffffff, 0x0fffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xafe68e30,
+ 0xfd14e000, 0x9c0a9f6b, 0x00000000, 0x0000a000, 0x00000000,
+ 0x00200400, 0x0040233c, 0x0040233c, 0x00000044, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x10002310, 0x10000fff,
+ 0x04900000, 0x04900000, 0x00000001, 0x00000004, 0x00000000,
+ 0x00000000, 0x1e1f2022, 0x0a0b0c0d, 0x00000000, 0x9280c00a,
+ 0x00020028, 0x5f3ca3de, 0x0108ecff, 0x14750604, 0x004b6a8e,
+ 0x990bb514, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000001, 0x201fff00, 0x0c6f0000, 0x03051000, 0x00000820,
+ 0x06336f77, 0x6af6532f, 0x08f186c8, 0x00046384, 0x00000000,
+ 0x00000000, 0xaaaaaaaa, 0x3c466478, 0x0cc80caa, 0x00000000,
+ 0x00001042, 0x803e4788, 0x4080a333, 0x40206c10, 0x009c4060,
+ 0x01834061, 0x00000400, 0x000003b5, 0x233f7180, 0x20202020,
+ 0x20202020, 0x13c889af, 0x38490a20, 0x00000000, 0xfffffffc,
+ 0x00000000, 0x00000000, 0x0cdbd380, 0x0f0f0f01, 0xdfa91f01,
+ 0x00418a11, 0x00418a11, 0x00000000, 0x0e79e5c6, 0x0e79e5c6,
+ 0x00820820, 0x1ce739ce, 0x050701ce, 0x07ffffef, 0x0fffffe7,
+ 0x17ffffe5, 0x1fffffe4, 0x37ffffe3, 0x3fffffe3, 0x57ffffe3,
+ 0x5fffffe2, 0x7fffffe2, 0x7f3c7bba, 0xf3307ff0, 0x0c000000,
+ 0x20202020, 0x20202020, 0x1ce739ce, 0x000001ce, 0x000001ce,
+ 0x00000001, 0x00000246, 0x20202020, 0x20202020, 0x20202020,
+ 0x1ce739ce, 0x000001ce, 0x00000000, 0x18c43433, 0x00f70081,
+ 0x01036a1e, 0x00000000, 0x00000000, 0x000003f1, 0x00000800,
+ 0x6c35ffd2, 0x6db6c000, 0x6db6cb30, 0x6db6cb6c, 0x0501e200,
+ 0x0094128d, 0x976ee392, 0xf75ff6fc, 0x00040000, 0xdb003012,
+ 0x04924914, 0x21084210, 0x00140000, 0x0e4548d8, 0x54214514,
+ 0x02025830, 0x71c0d388, 0x934934a8, 0x00000000, 0x00000800,
+ 0x6c35ffd2, 0x6db6c000, 0x6db6cb30, 0x6db6cb6c, 0x0501e200,
+ 0x0094128d, 0x976ee392, 0xf75ff6fc, 0x00040000, 0xdb003012,
+ 0x04924914, 0x21084210, 0x001b6db0, 0x00376b63, 0x06db6db6,
+ 0x006d8000, 0x48100000, 0x00000000, 0x08000000, 0x0007ffd8,
+ 0x0007ffd8, 0x001c0020, 0x00060aeb, 0x40008080, 0x2a850160
+};
+
+static const struct athn_ini ar9287_1_1_ini = {
+ nitems(ar9287_1_1_regs),
+ ar9287_1_1_regs,
+ NULL, /* 2GHz only. */
+ NULL, /* 2GHz only. */
+ ar9287_1_1_vals_2g40,
+ ar9287_1_1_vals_2g20,
+ nitems(ar9287_1_1_cm_regs),
+ ar9287_1_1_cm_regs,
+ ar9287_1_1_cm_vals
+};
+
+/*
+ * AR9287 1.1 Tx gains.
+ */
+static const uint16_t ar9287_1_1_tx_gain_regs[] = {
+ P(0x0a300), P(0x0a304), P(0x0a308), P(0x0a30c), P(0x0a310),
+ P(0x0a314), P(0x0a318), P(0x0a31c), P(0x0a320), P(0x0a324),
+ P(0x0a328), P(0x0a32c), P(0x0a330), P(0x0a334), P(0x0a338),
+ P(0x0a33c), P(0x0a340), P(0x0a344), P(0x0a348), P(0x0a34c),
+ P(0x0a350), P(0x0a354), P(0x0a780), P(0x0a784), P(0x0a788),
+ P(0x0a78c), P(0x0a790), P(0x0a794), P(0x0a798), P(0x0a79c),
+ P(0x0a7a0), P(0x0a7a4), P(0x0a7a8), P(0x0a7ac), P(0x0a7b0),
+ P(0x0a7b4), P(0x0a7b8), P(0x0a7bc), P(0x0a7c0), P(0x0a7c4),
+ P(0x0a7c8), P(0x0a7cc), P(0x0a7d0), P(0x0a7d4), P(0x0a274)
+};
+
+static const uint32_t ar9287_1_1_tx_gain_vals_2g[] = {
+ 0x00000000, 0x00004002, 0x00008004, 0x0000c00a, 0x0001000c,
+ 0x0001420b, 0x0001824a, 0x0001c44a, 0x0002064a, 0x0002484a,
+ 0x00028a4a, 0x0002cc4a, 0x00030e4a, 0x00034e8a, 0x00038e8c,
+ 0x0003cecc, 0x00040ed4, 0x00044edc, 0x00048ede, 0x0004cf1e,
+ 0x00050f5e, 0x00054f9e, 0x00000062, 0x00004064, 0x000080a4,
+ 0x0000c0aa, 0x000100ac, 0x000140b4, 0x000180f4, 0x0001c134,
+ 0x00020174, 0x0002417c, 0x0002817e, 0x0002c1be, 0x000301fe,
+ 0x000301fe, 0x000301fe, 0x000301fe, 0x000301fe, 0x000301fe,
+ 0x000301fe, 0x000301fe, 0x000301fe, 0x000301fe, 0x0a1aa000
+};
+
+static const struct athn_gain ar9287_1_1_tx_gain = {
+ nitems(ar9287_1_1_tx_gain_regs),
+ ar9287_1_1_tx_gain_regs,
+ NULL, /* 2GHz only. */
+ ar9287_1_1_tx_gain_vals_2g
+};
+
+/*
+ * AR9287 1.1 Rx gains.
+ */
+static const uint16_t ar9287_1_1_rx_gain_regs[] = {
+ P(0x09a00), P(0x09a04), P(0x09a08), P(0x09a0c), P(0x09a10),
+ P(0x09a14), P(0x09a18), P(0x09a1c), P(0x09a20), P(0x09a24),
+ P(0x09a28), P(0x09a2c), P(0x09a30), P(0x09a34), P(0x09a38),
+ P(0x09a3c), P(0x09a40), P(0x09a44), P(0x09a48), P(0x09a4c),
+ P(0x09a50), P(0x09a54), P(0x09a58), P(0x09a5c), P(0x09a60),
+ P(0x09a64), P(0x09a68), P(0x09a6c), P(0x09a70), P(0x09a74),
+ P(0x09a78), P(0x09a7c), P(0x09a80), P(0x09a84), P(0x09a88),
+ P(0x09a8c), P(0x09a90), P(0x09a94), P(0x09a98), P(0x09a9c),
+ P(0x09aa0), P(0x09aa4), P(0x09aa8), P(0x09aac), P(0x09ab0),
+ P(0x09ab4), P(0x09ab8), P(0x09abc), P(0x09ac0), P(0x09ac4),
+ P(0x09ac8), P(0x09acc), P(0x09ad0), P(0x09ad4), P(0x09ad8),
+ P(0x09adc), P(0x09ae0), P(0x09ae4), P(0x09ae8), P(0x09aec),
+ P(0x09af0), P(0x09af4), P(0x09af8), P(0x09afc), P(0x09b00),
+ P(0x09b04), P(0x09b08), P(0x09b0c), P(0x09b10), P(0x09b14),
+ P(0x09b18), P(0x09b1c), P(0x09b20), P(0x09b24), P(0x09b28),
+ P(0x09b2c), P(0x09b30), P(0x09b34), P(0x09b38), P(0x09b3c),
+ P(0x09b40), P(0x09b44), P(0x09b48), P(0x09b4c), P(0x09b50),
+ P(0x09b54), P(0x09b58), P(0x09b5c), P(0x09b60), P(0x09b64),
+ P(0x09b68), P(0x09b6c), P(0x09b70), P(0x09b74), P(0x09b78),
+ P(0x09b7c), P(0x09b80), P(0x09b84), P(0x09b88), P(0x09b8c),
+ P(0x09b90), P(0x09b94), P(0x09b98), P(0x09b9c), P(0x09ba0),
+ P(0x09ba4), P(0x09ba8), P(0x09bac), P(0x09bb0), P(0x09bb4),
+ P(0x09bb8), P(0x09bbc), P(0x09bc0), P(0x09bc4), P(0x09bc8),
+ P(0x09bcc), P(0x09bd0), P(0x09bd4), P(0x09bd8), P(0x09bdc),
+ P(0x09be0), P(0x09be4), P(0x09be8), P(0x09bec), P(0x09bf0),
+ P(0x09bf4), P(0x09bf8), P(0x09bfc), P(0x0aa00), P(0x0aa04),
+ P(0x0aa08), P(0x0aa0c), P(0x0aa10), P(0x0aa14), P(0x0aa18),
+ P(0x0aa1c), P(0x0aa20), P(0x0aa24), P(0x0aa28), P(0x0aa2c),
+ P(0x0aa30), P(0x0aa34), P(0x0aa38), P(0x0aa3c), P(0x0aa40),
+ P(0x0aa44), P(0x0aa48), P(0x0aa4c), P(0x0aa50), P(0x0aa54),
+ P(0x0aa58), P(0x0aa5c), P(0x0aa60), P(0x0aa64), P(0x0aa68),
+ P(0x0aa6c), P(0x0aa70), P(0x0aa74), P(0x0aa78), P(0x0aa7c),
+ P(0x0aa80), P(0x0aa84), P(0x0aa88), P(0x0aa8c), P(0x0aa90),
+ P(0x0aa94), P(0x0aa98), P(0x0aa9c), P(0x0aaa0), P(0x0aaa4),
+ P(0x0aaa8), P(0x0aaac), P(0x0aab0), P(0x0aab4), P(0x0aab8),
+ P(0x0aabc), P(0x0aac0), P(0x0aac4), P(0x0aac8), P(0x0aacc),
+ P(0x0aad0), P(0x0aad4), P(0x0aad8), P(0x0aadc), P(0x0aae0),
+ P(0x0aae4), P(0x0aae8), P(0x0aaec), P(0x0aaf0), P(0x0aaf4),
+ P(0x0aaf8), P(0x0aafc), P(0x0ab00), P(0x0ab04), P(0x0ab08),
+ P(0x0ab0c), P(0x0ab10), P(0x0ab14), P(0x0ab18), P(0x0ab1c),
+ P(0x0ab20), P(0x0ab24), P(0x0ab28), P(0x0ab2c), P(0x0ab30),
+ P(0x0ab34), P(0x0ab38), P(0x0ab3c), P(0x0ab40), P(0x0ab44),
+ P(0x0ab48), P(0x0ab4c), P(0x0ab50), P(0x0ab54), P(0x0ab58),
+ P(0x0ab5c), P(0x0ab60), P(0x0ab64), P(0x0ab68), P(0x0ab6c),
+ P(0x0ab70), P(0x0ab74), P(0x0ab78), P(0x0ab7c), P(0x0ab80),
+ P(0x0ab84), P(0x0ab88), P(0x0ab8c), P(0x0ab90), P(0x0ab94),
+ P(0x0ab98), P(0x0ab9c), P(0x0aba0), P(0x0aba4), P(0x0aba8),
+ P(0x0abac), P(0x0abb0), P(0x0abb4), P(0x0abb8), P(0x0abbc),
+ P(0x0abc0), P(0x0abc4), P(0x0abc8), P(0x0abcc), P(0x0abd0),
+ P(0x0abd4), P(0x0abd8), P(0x0abdc), P(0x0abe0), P(0x0abe4),
+ P(0x0abe8), P(0x0abec), P(0x0abf0), P(0x0abf4), P(0x0abf8),
+ P(0x0abfc), P(0x09848), P(0x0a848)
+};
+
+static const uint32_t ar9287_1_1_rx_gain_vals_2g[] = {
+ 0x0000a120, 0x0000a124, 0x0000a128, 0x0000a12c, 0x0000a130,
+ 0x0000a194, 0x0000a198, 0x0000a20c, 0x0000a210, 0x0000a284,
+ 0x0000a288, 0x0000a28c, 0x0000a290, 0x0000a294, 0x0000a2a0,
+ 0x0000a2a4, 0x0000a2a8, 0x0000a2ac, 0x0000a2b0, 0x0000a2b4,
+ 0x0000a2b8, 0x0000a2c4, 0x0000a708, 0x0000a70c, 0x0000a710,
+ 0x0000ab04, 0x0000ab08, 0x0000ab0c, 0x0000ab10, 0x0000ab14,
+ 0x0000ab18, 0x0000ab8c, 0x0000ab90, 0x0000ab94, 0x0000ab98,
+ 0x0000aba4, 0x0000aba8, 0x0000cb04, 0x0000cb08, 0x0000cb0c,
+ 0x0000cb10, 0x0000cb14, 0x0000cb18, 0x0000cb8c, 0x0000cb90,
+ 0x0000cf18, 0x0000cf24, 0x0000cf28, 0x0000d314, 0x0000d318,
+ 0x0000d38c, 0x0000d390, 0x0000d394, 0x0000d398, 0x0000d3a4,
+ 0x0000d3a8, 0x0000d3ac, 0x0000d3b0, 0x0000f380, 0x0000f384,
+ 0x0000f388, 0x0000f710, 0x0000f714, 0x0000f718, 0x0000fb10,
+ 0x0000fb14, 0x0000fb18, 0x0000fb8c, 0x0000fb90, 0x0000fb94,
+ 0x0000ff8c, 0x0000ff90, 0x0000ff94, 0x0000ffa0, 0x0000ffa4,
+ 0x0000ffa8, 0x0000ffac, 0x0000ffb0, 0x0000ffb4, 0x0000ffa1,
+ 0x0000ffa5, 0x0000ffa9, 0x0000ffad, 0x0000ffb1, 0x0000ffb5,
+ 0x0000ffb9, 0x0000ffc5, 0x0000ffc9, 0x0000ffcd, 0x0000ffd1,
+ 0x0000ffd5, 0x0000ffc2, 0x0000ffc6, 0x0000ffca, 0x0000ffce,
+ 0x0000ffd2, 0x0000ffd6, 0x0000ffda, 0x0000ffc7, 0x0000ffcb,
+ 0x0000ffcf, 0x0000ffd3, 0x0000ffd7, 0x0000ffdb, 0x0000ffdb,
+ 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb,
+ 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb,
+ 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb,
+ 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb,
+ 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000a120, 0x0000a124,
+ 0x0000a128, 0x0000a12c, 0x0000a130, 0x0000a194, 0x0000a198,
+ 0x0000a20c, 0x0000a210, 0x0000a284, 0x0000a288, 0x0000a28c,
+ 0x0000a290, 0x0000a294, 0x0000a2a0, 0x0000a2a4, 0x0000a2a8,
+ 0x0000a2ac, 0x0000a2b0, 0x0000a2b4, 0x0000a2b8, 0x0000a2c4,
+ 0x0000a708, 0x0000a70c, 0x0000a710, 0x0000ab04, 0x0000ab08,
+ 0x0000ab0c, 0x0000ab10, 0x0000ab14, 0x0000ab18, 0x0000ab8c,
+ 0x0000ab90, 0x0000ab94, 0x0000ab98, 0x0000aba4, 0x0000aba8,
+ 0x0000cb04, 0x0000cb08, 0x0000cb0c, 0x0000cb10, 0x0000cb14,
+ 0x0000cb18, 0x0000cb8c, 0x0000cb90, 0x0000cf18, 0x0000cf24,
+ 0x0000cf28, 0x0000d314, 0x0000d318, 0x0000d38c, 0x0000d390,
+ 0x0000d394, 0x0000d398, 0x0000d3a4, 0x0000d3a8, 0x0000d3ac,
+ 0x0000d3b0, 0x0000f380, 0x0000f384, 0x0000f388, 0x0000f710,
+ 0x0000f714, 0x0000f718, 0x0000fb10, 0x0000fb14, 0x0000fb18,
+ 0x0000fb8c, 0x0000fb90, 0x0000fb94, 0x0000ff8c, 0x0000ff90,
+ 0x0000ff94, 0x0000ffa0, 0x0000ffa4, 0x0000ffa8, 0x0000ffac,
+ 0x0000ffb0, 0x0000ffb4, 0x0000ffa1, 0x0000ffa5, 0x0000ffa9,
+ 0x0000ffad, 0x0000ffb1, 0x0000ffb5, 0x0000ffb9, 0x0000ffc5,
+ 0x0000ffc9, 0x0000ffcd, 0x0000ffd1, 0x0000ffd5, 0x0000ffc2,
+ 0x0000ffc6, 0x0000ffca, 0x0000ffce, 0x0000ffd2, 0x0000ffd6,
+ 0x0000ffda, 0x0000ffc7, 0x0000ffcb, 0x0000ffcf, 0x0000ffd3,
+ 0x0000ffd7, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb,
+ 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb,
+ 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb,
+ 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb,
+ 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb,
+ 0x0000ffdb, 0x00001067, 0x00001067
+};
+
+static const struct athn_gain ar9287_1_1_rx_gain = {
+ nitems(ar9287_1_1_rx_gain_regs),
+ ar9287_1_1_rx_gain_regs,
+ NULL, /* 2GHz only. */
+ ar9287_1_1_rx_gain_vals_2g
+};
diff --git a/sys/dev/athn/ic/ar9380.c b/sys/dev/athn/ic/ar9380.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar9380.c
@@ -0,0 +1,940 @@
+/* $OpenBSD: ar9380.c,v 1.28 2022/01/09 05:42:38 jsg Exp $ */
+
+/*-
+ * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Driver for Atheros 802.11a/g/n chipsets.
+ * Routines for AR9380 and AR9485 chipsets.
+ */
+
+//#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/conf.h>
+//#include <sys/device.h>
+//#include <sys/endian.h>
+
+#include <machine/bus.h>
+
+//#if NBPFILTER > 0
+//#include <net/bpf.h>
+//#endif
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
+//#include <net80211/ieee80211_ra.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/athn/athnreg.h>
+#include <dev/athn/athnvar.h>
+
+#include <dev/athn/ic/ar9003reg.h>
+#include <dev/athn/ic/ar9380reg.h>
+
+int ar9380_attach(struct athn_softc *);
+void ar9380_setup(struct athn_softc *);
+const uint8_t *ar9380_get_rom_template(struct athn_softc *, uint8_t);
+void ar9380_swap_rom(struct athn_softc *);
+int ar9380_set_synth(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9380_get_paprd_masks(struct athn_softc *, struct ieee80211_channel *,
+ uint32_t *, uint32_t *);
+void ar9380_init_from_rom(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9380_init_swreg(struct athn_softc *);
+int ar9485_pmu_write(struct athn_softc *, uint32_t, uint32_t);
+void ar9485_init_swreg(struct athn_softc *);
+void ar9380_spur_mitigate_cck(struct athn_softc *,
+ struct ieee80211_channel *, struct ieee80211_channel *);
+void ar9380_spur_mitigate_ofdm(struct athn_softc *,
+ struct ieee80211_channel *, struct ieee80211_channel *);
+void ar9380_spur_mitigate(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9380_set_txpower(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+void ar9380_get_correction(struct athn_softc *, struct ieee80211_channel *,
+ int, int *, int *);
+void ar9380_set_correction(struct athn_softc *, struct ieee80211_channel *);
+
+/* Extern functions. */
+int athn_interpolate(int, int, int, int, int);
+uint8_t athn_chan2fbin(struct ieee80211_channel *);
+void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *);
+int ar9003_attach(struct athn_softc *);
+void ar9003_write_txpower(struct athn_softc *, int16_t power[]);
+void ar9003_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *,
+ uint8_t, const uint8_t *, const struct ar_cal_target_power_leg *,
+ int, uint8_t[]);
+void ar9003_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *,
+ uint8_t, const uint8_t *, const struct ar_cal_target_power_ht *,
+ int, uint8_t[]);
+
+
+int
+ar9380_attach(struct athn_softc *sc)
+{
+ printf("Unimplemented %s\n", __func__);
+ return 0;
+#if 0
+ sc->ngpiopins = 17;
+ sc->ops.setup = ar9380_setup;
+ sc->ops.get_rom_template = ar9380_get_rom_template;
+ sc->ops.swap_rom = ar9380_swap_rom;
+ sc->ops.init_from_rom = ar9380_init_from_rom;
+ sc->ops.set_txpower = ar9380_set_txpower;
+ sc->ops.set_synth = ar9380_set_synth;
+ sc->ops.spur_mitigate = ar9380_spur_mitigate;
+ sc->ops.get_paprd_masks = ar9380_get_paprd_masks;
+ sc->cca_min_2g = AR9380_PHY_CCA_MIN_GOOD_VAL_2GHZ;
+ sc->cca_max_2g = AR9380_PHY_CCA_MAX_GOOD_VAL_2GHZ;
+ sc->cca_min_5g = AR9380_PHY_CCA_MIN_GOOD_VAL_5GHZ;
+ sc->cca_max_5g = AR9380_PHY_CCA_MAX_GOOD_VAL_5GHZ;
+ if (AR_SREV_9485(sc)) {
+ sc->ini = &ar9485_1_1_ini;
+ sc->serdes = &ar9485_1_1_serdes;
+ } else {
+ sc->ini = &ar9380_2_2_ini;
+ sc->serdes = &ar9380_2_2_serdes;
+ }
+
+ return (ar9003_attach(sc));
+#endif
+}
+
+void
+ar9380_setup(struct athn_softc *sc)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ar9380_eeprom *eep = sc->eep;
+ struct ar9380_base_eep_hdr *base = &eep->baseEepHeader;
+ uint8_t type;
+
+ if (base->opFlags & AR_OPFLAGS_11A)
+ sc->flags |= ATHN_FLAG_11A;
+ if (base->opFlags & AR_OPFLAGS_11G)
+ sc->flags |= ATHN_FLAG_11G;
+ if (base->opFlags & AR_OPFLAGS_11N)
+ sc->flags |= ATHN_FLAG_11N;
+
+ IEEE80211_ADDR_COPY(ic->ic_myaddr, eep->macAddr);
+ sc->led_pin = base->wlanLedGpio;
+
+ /* Check if we have a hardware radio switch. */
+ if (base->rfSilent & AR_EEP_RFSILENT_ENABLED) {
+ sc->flags |= ATHN_FLAG_RFSILENT;
+ /* Get GPIO pin used by hardware radio switch. */
+ sc->rfsilent_pin = MS(base->rfSilent,
+ AR_EEP_RFSILENT_GPIO_SEL);
+ /* Get polarity of hardware radio switch. */
+ if (base->rfSilent & AR_EEP_RFSILENT_POLARITY)
+ sc->flags |= ATHN_FLAG_RFSILENT_REVERSED;
+ }
+
+ /* Set the number of HW key cache entries. */
+ sc->kc_entries = AR_KEYTABLE_SIZE;
+
+ sc->txchainmask = MS(base->txrxMask, AR_EEP_TX_MASK);
+ sc->rxchainmask = MS(base->txrxMask, AR_EEP_RX_MASK);
+
+ /* Fast PLL clock is always supported. */
+ sc->flags |= ATHN_FLAG_FAST_PLL_CLOCK;
+
+ /* Enable PA predistortion if supported. */
+ if (base->featureEnable & AR_EEP_PAPRD)
+ sc->flags |= ATHN_FLAG_PAPRD;
+ /*
+ * Some 3-stream chips may exceed the PCIe power requirements,
+ * requiring to reduce the number of Tx chains in some cases.
+ */
+ if ((base->miscConfiguration & AR_EEP_CHAIN_MASK_REDUCE) &&
+ sc->txchainmask == 0x7)
+ sc->flags |= ATHN_FLAG_3TREDUCE_CHAIN;
+
+ /* Select initialization values based on ROM. */
+ type = MS(eep->baseEepHeader.txrxgain, AR_EEP_RX_GAIN);
+ if (!AR_SREV_9485(sc)) {
+ if (type == AR_EEP_RX_GAIN_WO_XLNA)
+ sc->rx_gain = &ar9380_2_2_rx_gain_wo_xlna;
+ else
+ sc->rx_gain = &ar9380_2_2_rx_gain;
+ } else
+ sc->rx_gain = &ar9485_1_1_rx_gain;
+
+ /* Select initialization values based on ROM. */
+ type = MS(eep->baseEepHeader.txrxgain, AR_EEP_TX_GAIN);
+ if (!AR_SREV_9485(sc)) {
+ if (type == AR_EEP_TX_GAIN_HIGH_OB_DB)
+ sc->tx_gain = &ar9380_2_2_tx_gain_high_ob_db;
+ else if (type == AR_EEP_TX_GAIN_LOW_OB_DB)
+ sc->tx_gain = &ar9380_2_2_tx_gain_low_ob_db;
+ else if (type == AR_EEP_TX_GAIN_HIGH_POWER)
+ sc->tx_gain = &ar9380_2_2_tx_gain_high_power;
+ else
+ sc->tx_gain = &ar9380_2_2_tx_gain;
+ } else
+ sc->tx_gain = &ar9485_1_1_tx_gain;
+#endif
+}
+
+const uint8_t *
+ar9380_get_rom_template(struct athn_softc *sc, uint8_t ref)
+{
+ printf("Unimplemented %s\n", __func__);
+ return NULL;
+#if 0
+ int i;
+
+ /* Retrieve template ROM image for given reference. */
+ for (i = 0; i < nitems(ar9380_rom_templates); i++)
+ if (ar9380_rom_templates[i][1] == ref)
+ return (ar9380_rom_templates[i]);
+ return (NULL);
+#endif
+}
+
+void
+ar9380_swap_rom(struct athn_softc *sc)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+#if BYTE_ORDER == BIG_ENDIAN
+ struct ar9380_eeprom *eep = sc->eep;
+ struct ar9380_base_eep_hdr *base = &eep->baseEepHeader;
+ struct ar9380_modal_eep_header *modal;
+ int i;
+
+ base->regDmn[0] = swap16(base->regDmn[0]);
+ base->regDmn[1] = swap16(base->regDmn[1]);
+ base->swreg = swap32(base->swreg);
+
+ modal = &eep->modalHeader2G;
+ modal->antCtrlCommon = swap32(modal->antCtrlCommon);
+ modal->antCtrlCommon2 = swap32(modal->antCtrlCommon2);
+ modal->papdRateMaskHt20 = swap32(modal->papdRateMaskHt20);
+ modal->papdRateMaskHt40 = swap32(modal->papdRateMaskHt40);
+ for (i = 0; i < AR9380_MAX_CHAINS; i++)
+ modal->antCtrlChain[i] = swap16(modal->antCtrlChain[i]);
+
+ modal = &eep->modalHeader5G;
+ modal->antCtrlCommon = swap32(modal->antCtrlCommon);
+ modal->antCtrlCommon2 = swap32(modal->antCtrlCommon2);
+ modal->papdRateMaskHt20 = swap32(modal->papdRateMaskHt20);
+ modal->papdRateMaskHt40 = swap32(modal->papdRateMaskHt40);
+ for (i = 0; i < AR9380_MAX_CHAINS; i++)
+ modal->antCtrlChain[i] = swap16(modal->antCtrlChain[i]);
+#endif
+#endif // FreeBSD endif
+}
+
+void
+ar9380_get_paprd_masks(struct athn_softc *sc, struct ieee80211_channel *c,
+ uint32_t *ht20mask, uint32_t *ht40mask)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ const struct ar9380_eeprom *eep = sc->eep;
+ const struct ar9380_modal_eep_header *modal;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ modal = &eep->modalHeader2G;
+ else
+ modal = &eep->modalHeader5G;
+ *ht20mask = modal->papdRateMaskHt20;
+ *ht40mask = modal->papdRateMaskHt40;
+#endif
+}
+
+int
+ar9380_set_synth(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("Unimplemented %s\n", __func__);
+ return 0;
+#if 0
+ uint32_t freq = c->ic_freq;
+ uint32_t chansel, phy;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ if (AR_SREV_9485(sc))
+ chansel = ((freq << 16) - 215) / 15;
+ else
+ chansel = (freq << 16) / 15;
+ AR_WRITE(sc, AR_PHY_SYNTH_CONTROL, AR9380_BMODE);
+ } else {
+ chansel = (freq << 15) / 15;
+ chansel >>= 1;
+ AR_WRITE(sc, AR_PHY_SYNTH_CONTROL, 0);
+ }
+
+ /* Enable Long Shift Select for synthesizer. */
+ AR_SETBITS(sc, AR_PHY_65NM_CH0_SYNTH4,
+ AR_PHY_SYNTH4_LONG_SHIFT_SELECT);
+ AR_WRITE_BARRIER(sc);
+
+ /* Program synthesizer. */
+ phy = (chansel << 2) | AR9380_FRACMODE;
+ DPRINTFN(4, ("AR_PHY_65NM_CH0_SYNTH7=0x%08x\n", phy));
+ AR_WRITE(sc, AR_PHY_65NM_CH0_SYNTH7, phy);
+ AR_WRITE_BARRIER(sc);
+ /* Toggle Load Synth Channel bit. */
+ AR_WRITE(sc, AR_PHY_65NM_CH0_SYNTH7, phy | AR9380_LOAD_SYNTH);
+ AR_WRITE_BARRIER(sc);
+ return (0);
+#endif
+}
+
+void
+ar9380_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ const struct ar9380_eeprom *eep = sc->eep;
+ const struct ar9380_modal_eep_header *modal;
+ uint8_t db, margin, ant_div_ctrl;
+ uint32_t reg;
+ int i, maxchains;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ modal = &eep->modalHeader2G;
+ else
+ modal = &eep->modalHeader5G;
+
+ /* Apply XPA bias level. */
+ if (AR_SREV_9485(sc)) {
+ reg = AR_READ(sc, AR9485_PHY_65NM_CH0_TOP2);
+ reg = RW(reg, AR9485_PHY_65NM_CH0_TOP2_XPABIASLVL,
+ modal->xpaBiasLvl);
+ AR_WRITE(sc, AR9485_PHY_65NM_CH0_TOP2, reg);
+ } else {
+ reg = AR_READ(sc, AR_PHY_65NM_CH0_TOP);
+ reg = RW(reg, AR_PHY_65NM_CH0_TOP_XPABIASLVL,
+ modal->xpaBiasLvl & 0x3);
+ AR_WRITE(sc, AR_PHY_65NM_CH0_TOP, reg);
+ reg = AR_READ(sc, AR_PHY_65NM_CH0_THERM);
+ reg = RW(reg, AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB,
+ modal->xpaBiasLvl >> 2);
+ reg |= AR_PHY_65NM_CH0_THERM_XPASHORT2GND;
+ AR_WRITE(sc, AR_PHY_65NM_CH0_THERM, reg);
+ }
+
+ /* Apply antenna control. */
+ reg = AR_READ(sc, AR_PHY_SWITCH_COM);
+ reg = RW(reg, AR_SWITCH_TABLE_COM_ALL, modal->antCtrlCommon);
+ AR_WRITE(sc, AR_PHY_SWITCH_COM, reg);
+ reg = AR_READ(sc, AR_PHY_SWITCH_COM_2);
+ reg = RW(reg, AR_SWITCH_TABLE_COM_2_ALL, modal->antCtrlCommon2);
+ AR_WRITE(sc, AR_PHY_SWITCH_COM_2, reg);
+
+ maxchains = AR_SREV_9485(sc) ? 1 : AR9380_MAX_CHAINS;
+ for (i = 0; i < maxchains; i++) {
+ reg = AR_READ(sc, AR_PHY_SWITCH_CHAIN(i));
+ reg = RW(reg, AR_SWITCH_TABLE_ALL, modal->antCtrlChain[i]);
+ AR_WRITE(sc, AR_PHY_SWITCH_CHAIN(i), reg);
+ }
+
+ if (AR_SREV_9485(sc)) {
+ ant_div_ctrl = eep->base_ext1.ant_div_control;
+ reg = AR_READ(sc, AR_PHY_MC_GAIN_CTRL);
+ reg = RW(reg, AR_PHY_MC_GAIN_CTRL_ANT_DIV_CTRL_ALL,
+ MS(ant_div_ctrl, AR_EEP_ANT_DIV_CTRL_ALL));
+ if (ant_div_ctrl & AR_EEP_ANT_DIV_CTRL_ANT_DIV)
+ reg |= AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV;
+ else
+ reg &= ~AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV;
+ AR_WRITE(sc, AR_PHY_MC_GAIN_CTRL, reg);
+ reg = AR_READ(sc, AR_PHY_CCK_DETECT);
+ if (ant_div_ctrl & AR_EEP_ANT_DIV_CTRL_FAST_DIV)
+ reg |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+ else
+ reg &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+ AR_WRITE(sc, AR_PHY_CCK_DETECT, reg);
+ }
+
+ if (eep->baseEepHeader.miscConfiguration & AR_EEP_DRIVE_STRENGTH) {
+ /* Apply drive strength. */
+ reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS1);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_0, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_1, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_2, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_3, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_4, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_5, 5);
+ AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS1, reg);
+
+ reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS2);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_0, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_1, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_2, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_3, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_4, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_5, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_6, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_7, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_8, 5);
+ AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS2, reg);
+
+ reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS4);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_0, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_1, 5);
+ reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_2, 5);
+ AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS4, reg);
+ }
+
+ /* Apply attenuation settings. */
+ maxchains = AR_SREV_9485(sc) ? 1 : AR9380_MAX_CHAINS;
+ for (i = 0; i < maxchains; i++) {
+ if (IEEE80211_IS_CHAN_5GHZ(c) &&
+ eep->base_ext2.xatten1DBLow[i] != 0) {
+ if (c->ic_freq <= 5500) {
+ db = athn_interpolate(c->ic_freq,
+ 5180, eep->base_ext2.xatten1DBLow[i],
+ 5500, modal->xatten1DB[i]);
+ } else {
+ db = athn_interpolate(c->ic_freq,
+ 5500, modal->xatten1DB[i],
+ 5785, eep->base_ext2.xatten1DBHigh[i]);
+ }
+ } else
+ db = modal->xatten1DB[i];
+ if (IEEE80211_IS_CHAN_5GHZ(c) &&
+ eep->base_ext2.xatten1MarginLow[i] != 0) {
+ if (c->ic_freq <= 5500) {
+ margin = athn_interpolate(c->ic_freq,
+ 5180, eep->base_ext2.xatten1MarginLow[i],
+ 5500, modal->xatten1Margin[i]);
+ } else {
+ margin = athn_interpolate(c->ic_freq,
+ 5500, modal->xatten1Margin[i],
+ 5785, eep->base_ext2.xatten1MarginHigh[i]);
+ }
+ } else
+ margin = modal->xatten1Margin[i];
+ reg = AR_READ(sc, AR_PHY_EXT_ATTEN_CTL(i));
+ reg = RW(reg, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, db);
+ reg = RW(reg, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, margin);
+ AR_WRITE(sc, AR_PHY_EXT_ATTEN_CTL(i), reg);
+ }
+
+ /* Initialize switching regulator. */
+ if (AR_SREV_9485(sc))
+ ar9485_init_swreg(sc);
+ else
+ ar9380_init_swreg(sc);
+
+ /* Apply tuning capabilities. */
+ if (AR_SREV_9485(sc) &&
+ (eep->baseEepHeader.featureEnable & AR_EEP_TUNING_CAPS)) {
+ reg = AR_READ(sc, AR9485_PHY_CH0_XTAL);
+ reg = RW(reg, AR9485_PHY_CH0_XTAL_CAPINDAC,
+ eep->baseEepHeader.params_for_tuning_caps[0]);
+ reg = RW(reg, AR9485_PHY_CH0_XTAL_CAPOUTDAC,
+ eep->baseEepHeader.params_for_tuning_caps[0]);
+ AR_WRITE(sc, AR9485_PHY_CH0_XTAL, reg);
+ }
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+ar9380_init_swreg(struct athn_softc *sc)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ const struct ar9380_eeprom *eep = sc->eep;
+
+ if (eep->baseEepHeader.featureEnable & AR_EEP_INTERNAL_REGULATOR) {
+ /* Internal regulator is ON. */
+ AR_CLRBITS(sc, AR_RTC_REG_CONTROL1,
+ AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
+ AR_WRITE(sc, AR_RTC_REG_CONTROL0, eep->baseEepHeader.swreg);
+ AR_SETBITS(sc, AR_RTC_REG_CONTROL1,
+ AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
+ } else
+ AR_SETBITS(sc, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_SWREG_PRD);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+int
+ar9485_pmu_write(struct athn_softc *sc, uint32_t addr, uint32_t val)
+{
+ printf("Unimplemented %s\n", __func__);
+ return 0;
+#if 0
+ int ntries;
+
+ AR_WRITE(sc, addr, val);
+ /* Wait for write to complete. */
+ for (ntries = 0; ntries < 100; ntries++) {
+ if (AR_READ(sc, addr) == val)
+ return (0);
+ AR_WRITE(sc, addr, val); /* Insist. */
+ AR_WRITE_BARRIER(sc);
+ DELAY(10);
+ }
+ return (ETIMEDOUT);
+#endif
+}
+
+#define ar9486_pmu_read AR_READ
+
+void
+ar9485_init_swreg(struct athn_softc *sc)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ const struct ar9380_eeprom *eep = sc->eep;
+ uint32_t reg;
+
+ ar9485_pmu_write(sc, AR_PHY_PMU2,
+ ar9486_pmu_read(sc, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM);
+
+ if (eep->baseEepHeader.featureEnable & AR_EEP_INTERNAL_REGULATOR) {
+ ar9485_pmu_write(sc, AR_PHY_PMU1, 0x131dc17a);
+
+ reg = ar9486_pmu_read(sc, AR_PHY_PMU2);
+ reg = (reg & ~0xffc00000) | 0x10000000;
+ ar9485_pmu_write(sc, AR_PHY_PMU2, reg);
+ } else {
+ ar9485_pmu_write(sc, AR_PHY_PMU1,
+ ar9486_pmu_read(sc, AR_PHY_PMU1) | AR_PHY_PMU1_PWD);
+ }
+
+ ar9485_pmu_write(sc, AR_PHY_PMU2,
+ ar9486_pmu_read(sc, AR_PHY_PMU2) | AR_PHY_PMU2_PGM);
+#endif
+}
+
+void
+ar9380_spur_mitigate_cck(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ /* NB: It is safe to call this function for 5GHz channels. */
+ static const int16_t freqs[] = { 2420, 2440, 2464, 2480 };
+ int i, spur, freq;
+ uint32_t reg;
+
+ for (i = 0; i < nitems(freqs); i++) {
+ spur = freqs[i] - c->ic_freq;
+ if (abs(spur) < 10) /* +/- 10MHz range. */
+ break;
+ }
+ if (i == nitems(freqs)) {
+ /* Disable CCK spur mitigation. */
+ reg = AR_READ(sc, AR_PHY_AGC_CONTROL);
+ reg = RW(reg, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5);
+ AR_WRITE(sc, AR_PHY_AGC_CONTROL, reg);
+ reg = AR_READ(sc, AR_PHY_CCK_SPUR_MIT);
+ reg = RW(reg, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0);
+ reg &= ~AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT;
+ AR_WRITE(sc, AR_PHY_CCK_SPUR_MIT, reg);
+ AR_WRITE_BARRIER(sc);
+ return;
+ }
+ freq = (spur * 524288) / 11;
+
+ reg = AR_READ(sc, AR_PHY_AGC_CONTROL);
+ reg = RW(reg, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7);
+ AR_WRITE(sc, AR_PHY_AGC_CONTROL, reg);
+
+ reg = AR_READ(sc, AR_PHY_CCK_SPUR_MIT);
+ reg = RW(reg, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, freq);
+ reg = RW(reg, AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f);
+ reg = RW(reg, AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE, 0x2);
+ reg |= AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT;
+ AR_WRITE(sc, AR_PHY_CCK_SPUR_MIT, reg);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+ar9380_spur_mitigate_ofdm(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ const struct ar9380_eeprom *eep = sc->eep;
+ const uint8_t *spurchans;
+ uint32_t reg;
+ int idx, spur_delta_phase, spur_off, range, i;
+ int freq, spur, spur_freq_sd, spur_subchannel_sd;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ spurchans = eep->modalHeader2G.spurChans;
+ else
+ spurchans = eep->modalHeader5G.spurChans;
+ if (spurchans[0] == 0)
+ return;
+
+ /* Disable OFDM spur mitigation. */
+ AR_CLRBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER);
+
+ reg = AR_READ(sc, AR_PHY_TIMING11);
+ reg = RW(reg, AR_PHY_TIMING11_SPUR_FREQ_SD, 0);
+ reg = RW(reg, AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0);
+ reg &= ~AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC;
+ reg &= ~AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR;
+ AR_WRITE(sc, AR_PHY_TIMING11, reg);
+
+ AR_CLRBITS(sc, AR_PHY_SFCORR_EXT,
+ AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD);
+
+ AR_CLRBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI);
+
+ reg = AR_READ(sc, AR_PHY_SPUR_REG);
+ reg = RW(reg, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0);
+ reg &= ~AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI;
+ reg &= ~AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT;
+ reg &= ~AR_PHY_SPUR_REG_ENABLE_MASK_PPM;
+ AR_WRITE(sc, AR_PHY_SPUR_REG, reg);
+ AR_WRITE_BARRIER(sc);
+
+ freq = c->ic_freq;
+ if (extc != NULL) {
+ range = 19; /* +/- 19MHz range. */
+ if (AR_READ(sc, AR_PHY_GEN_CTRL) & AR_PHY_GC_DYN2040_PRI_CH)
+ freq += 10;
+ else
+ freq -= 10;
+ } else
+ range = 10; /* +/- 10MHz range. */
+ for (i = 0; i < AR9380_EEPROM_MODAL_SPURS; i++) {
+ spur = spurchans[i];
+ if (spur == 0)
+ return;
+ /* Convert to frequency. */
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ spur = 2300 + spur;
+ else
+ spur = 4900 + (spur * 5);
+ spur -= freq;
+ if (abs(spur) < range)
+ break;
+ }
+ if (i == AR9380_EEPROM_MODAL_SPURS)
+ return;
+
+ /* Enable OFDM spur mitigation. */
+ if (extc != NULL) {
+ spur_delta_phase = (spur * 131072) / 5;
+ reg = AR_READ(sc, AR_PHY_GEN_CTRL);
+ if (spur < 0) {
+ spur_subchannel_sd =
+ (reg & AR_PHY_GC_DYN2040_PRI_CH) == 0;
+ spur_off = spur + 10;
+ } else {
+ spur_subchannel_sd =
+ (reg & AR_PHY_GC_DYN2040_PRI_CH) != 0;
+ spur_off = spur - 10;
+ }
+ } else {
+ spur_delta_phase = (spur * 262144) / 5;
+ spur_subchannel_sd = 0;
+ spur_off = spur;
+ }
+ spur_freq_sd = (spur_off * 512) / 11;
+
+ AR_SETBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER);
+
+ reg = AR_READ(sc, AR_PHY_TIMING11);
+ reg = RW(reg, AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd);
+ reg = RW(reg, AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase);
+ reg |= AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC;
+ reg |= AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR;
+ AR_WRITE(sc, AR_PHY_TIMING11, reg);
+
+ reg = AR_READ(sc, AR_PHY_SFCORR_EXT);
+ if (spur_subchannel_sd)
+ reg |= AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD;
+ else
+ reg &= ~AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD;
+ AR_WRITE(sc, AR_PHY_SFCORR_EXT, reg);
+
+ AR_SETBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI);
+
+ reg = AR_READ(sc, AR_PHY_SPUR_REG);
+ reg = RW(reg, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
+ reg = RW(reg, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34);
+ reg |= AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI;
+ if (AR_READ(sc, AR_PHY_MODE) & AR_PHY_MODE_DYNAMIC)
+ reg |= AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT;
+ reg |= AR_PHY_SPUR_REG_ENABLE_MASK_PPM;
+ AR_WRITE(sc, AR_PHY_SPUR_REG, reg);
+
+ idx = (spur * 16) / 5;
+ if (idx < 0)
+ idx--;
+
+ /* Write pilot mask. */
+ AR_SETBITS(sc, AR_PHY_TIMING4,
+ AR_PHY_TIMING4_ENABLE_PILOT_MASK |
+ AR_PHY_TIMING4_ENABLE_CHAN_MASK);
+
+ reg = AR_READ(sc, AR_PHY_PILOT_SPUR_MASK);
+ reg = RW(reg, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, idx);
+ reg = RW(reg, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0x0c);
+ AR_WRITE(sc, AR_PHY_PILOT_SPUR_MASK, reg);
+
+ reg = AR_READ(sc, AR_PHY_SPUR_MASK_A);
+ reg = RW(reg, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, idx);
+ reg = RW(reg, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
+ AR_WRITE(sc, AR_PHY_SPUR_MASK_A, reg);
+
+ reg = AR_READ(sc, AR_PHY_CHAN_SPUR_MASK);
+ reg = RW(reg, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, idx);
+ reg = RW(reg, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0x0c);
+ AR_WRITE(sc, AR_PHY_CHAN_SPUR_MASK, reg);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+void
+ar9380_spur_mitigate(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ /* NB: We call spur_mitigate_cck for 5GHz too, just to disable it. */
+ ar9380_spur_mitigate_cck(sc, c, extc);
+ ar9380_spur_mitigate_ofdm(sc, c, extc);
+#endif
+}
+
+void
+ar9380_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ const struct ar9380_eeprom *eep = sc->eep;
+ uint8_t tpow_cck[4], tpow_ofdm[4];
+ uint8_t tpow_ht20[14], tpow_ht40[14];
+ int16_t power[ATHN_POWER_COUNT];
+
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ /* Get CCK target powers. */
+ ar9003_get_lg_tpow(sc, c, AR_CTL_11B,
+ eep->calTargetFbinCck, eep->calTargetPowerCck,
+ AR9380_NUM_2G_CCK_TARGET_POWERS, tpow_cck);
+
+ /* Get OFDM target powers. */
+ ar9003_get_lg_tpow(sc, c, AR_CTL_11G,
+ eep->calTargetFbin2G, eep->calTargetPower2G,
+ AR9380_NUM_2G_20_TARGET_POWERS, tpow_ofdm);
+
+ /* Get HT-20 target powers. */
+ ar9003_get_ht_tpow(sc, c, AR_CTL_2GHT20,
+ eep->calTargetFbin2GHT20, eep->calTargetPower2GHT20,
+ AR9380_NUM_2G_20_TARGET_POWERS, tpow_ht20);
+
+ if (extc != NULL) {
+ /* Get HT-40 target powers. */
+ ar9003_get_ht_tpow(sc, c, AR_CTL_2GHT40,
+ eep->calTargetFbin2GHT40,
+ eep->calTargetPower2GHT40,
+ AR9380_NUM_2G_40_TARGET_POWERS, tpow_ht40);
+ }
+ } else {
+ /* Get OFDM target powers. */
+ ar9003_get_lg_tpow(sc, c, AR_CTL_11A,
+ eep->calTargetFbin5G, eep->calTargetPower5G,
+ AR9380_NUM_5G_20_TARGET_POWERS, tpow_ofdm);
+
+ /* Get HT-20 target powers. */
+ ar9003_get_ht_tpow(sc, c, AR_CTL_5GHT20,
+ eep->calTargetFbin5GHT20, eep->calTargetPower5GHT20,
+ AR9380_NUM_5G_20_TARGET_POWERS, tpow_ht20);
+
+ if (extc != NULL) {
+ /* Get HT-40 target powers. */
+ ar9003_get_ht_tpow(sc, c, AR_CTL_5GHT40,
+ eep->calTargetFbin5GHT40,
+ eep->calTargetPower5GHT40,
+ AR9380_NUM_5G_40_TARGET_POWERS, tpow_ht40);
+ }
+ }
+
+ memset(power, 0, sizeof(power));
+ /* Shuffle target powers across transmit rates. */
+ power[ATHN_POWER_OFDM6 ] =
+ power[ATHN_POWER_OFDM9 ] =
+ power[ATHN_POWER_OFDM12] =
+ power[ATHN_POWER_OFDM18] =
+ power[ATHN_POWER_OFDM24] = tpow_ofdm[0];
+ power[ATHN_POWER_OFDM36] = tpow_ofdm[1];
+ power[ATHN_POWER_OFDM48] = tpow_ofdm[2];
+ power[ATHN_POWER_OFDM54] = tpow_ofdm[3];
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ power[ATHN_POWER_CCK1_LP ] =
+ power[ATHN_POWER_CCK2_LP ] =
+ power[ATHN_POWER_CCK2_SP ] =
+ power[ATHN_POWER_CCK55_LP] = tpow_cck[0];
+ power[ATHN_POWER_CCK55_SP] = tpow_cck[1];
+ power[ATHN_POWER_CCK11_LP] = tpow_cck[2];
+ power[ATHN_POWER_CCK11_SP] = tpow_cck[3];
+ }
+ /* Next entry covers MCS0, MCS8 and MCS16. */
+ power[ATHN_POWER_HT20( 0)] = tpow_ht20[ 0];
+ /* Next entry covers MCS1-3, MCS9-11 and MCS17-19. */
+ power[ATHN_POWER_HT20( 1)] = tpow_ht20[ 1];
+ power[ATHN_POWER_HT20( 4)] = tpow_ht20[ 2];
+ power[ATHN_POWER_HT20( 5)] = tpow_ht20[ 3];
+ power[ATHN_POWER_HT20( 6)] = tpow_ht20[ 4];
+ power[ATHN_POWER_HT20( 7)] = tpow_ht20[ 5];
+ power[ATHN_POWER_HT20(12)] = tpow_ht20[ 6];
+ power[ATHN_POWER_HT20(13)] = tpow_ht20[ 7];
+ power[ATHN_POWER_HT20(14)] = tpow_ht20[ 8];
+ power[ATHN_POWER_HT20(15)] = tpow_ht20[ 9];
+ power[ATHN_POWER_HT20(20)] = tpow_ht20[10];
+ power[ATHN_POWER_HT20(21)] = tpow_ht20[11];
+ power[ATHN_POWER_HT20(22)] = tpow_ht20[12];
+ power[ATHN_POWER_HT20(23)] = tpow_ht20[13];
+ if (extc != NULL) {
+ /* Next entry covers MCS0, MCS8 and MCS16. */
+ power[ATHN_POWER_HT40( 0)] = tpow_ht40[ 0];
+ /* Next entry covers MCS1-3, MCS9-11 and MCS17-19. */
+ power[ATHN_POWER_HT40( 1)] = tpow_ht40[ 1];
+ power[ATHN_POWER_HT40( 4)] = tpow_ht40[ 2];
+ power[ATHN_POWER_HT40( 5)] = tpow_ht40[ 3];
+ power[ATHN_POWER_HT40( 6)] = tpow_ht40[ 4];
+ power[ATHN_POWER_HT40( 7)] = tpow_ht40[ 5];
+ power[ATHN_POWER_HT40(12)] = tpow_ht40[ 6];
+ power[ATHN_POWER_HT40(13)] = tpow_ht40[ 7];
+ power[ATHN_POWER_HT40(14)] = tpow_ht40[ 8];
+ power[ATHN_POWER_HT40(15)] = tpow_ht40[ 9];
+ power[ATHN_POWER_HT40(20)] = tpow_ht40[10];
+ power[ATHN_POWER_HT40(21)] = tpow_ht40[11];
+ power[ATHN_POWER_HT40(22)] = tpow_ht40[12];
+ power[ATHN_POWER_HT40(23)] = tpow_ht40[13];
+ }
+
+ /* Write transmit power values to hardware. */
+ ar9003_write_txpower(sc, power);
+
+ /* Apply transmit power correction. */
+ ar9380_set_correction(sc, c);
+#endif
+}
+
+void
+ar9380_get_correction(struct athn_softc *sc, struct ieee80211_channel *c,
+ int chain, int *corr, int *temp)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ const struct ar9380_eeprom *eep = sc->eep;
+ const struct ar9380_cal_data_per_freq_op_loop *pierdata;
+ const uint8_t *pierfreq;
+ uint8_t fbin;
+ int lo, hi, npiers;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c)) {
+ pierfreq = eep->calFreqPier2G;
+ pierdata = eep->calPierData2G[chain];
+ npiers = AR9380_NUM_2G_CAL_PIERS;
+ } else {
+ pierfreq = eep->calFreqPier5G;
+ pierdata = eep->calPierData5G[chain];
+ npiers = AR9380_NUM_5G_CAL_PIERS;
+ }
+ /* Find channel in ROM pier table. */
+ fbin = athn_chan2fbin(c);
+ athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi);
+
+ *corr = athn_interpolate(fbin,
+ pierfreq[lo], pierdata[lo].refPower,
+ pierfreq[hi], pierdata[hi].refPower);
+ *temp = athn_interpolate(fbin,
+ pierfreq[lo], pierdata[lo].tempMeas,
+ pierfreq[hi], pierdata[hi].tempMeas);
+#endif
+}
+
+void
+ar9380_set_correction(struct athn_softc *sc, struct ieee80211_channel *c)
+{
+ printf("Unimplemented %s\n", __func__);
+#if 0
+ const struct ar9380_eeprom *eep = sc->eep;
+ const struct ar9380_modal_eep_header *modal;
+ uint32_t reg;
+ int8_t slope;
+ int i, corr, temp, temp0;
+
+ if (IEEE80211_IS_CHAN_2GHZ(c))
+ modal = &eep->modalHeader2G;
+ else
+ modal = &eep->modalHeader5G;
+
+ for (i = 0; i < AR9380_MAX_CHAINS; i++) {
+ ar9380_get_correction(sc, c, i, &corr, &temp);
+ if (i == 0)
+ temp0 = temp;
+
+ reg = AR_READ(sc, AR_PHY_TPC_11_B(i));
+ reg = RW(reg, AR_PHY_TPC_11_OLPC_GAIN_DELTA, corr);
+ AR_WRITE(sc, AR_PHY_TPC_11_B(i), reg);
+
+ /* Enable open loop power control. */
+ reg = AR_READ(sc, AR_PHY_TPC_6_B(i));
+ reg = RW(reg, AR_PHY_TPC_6_ERROR_EST_MODE, 3);
+ AR_WRITE(sc, AR_PHY_TPC_6_B(i), reg);
+ }
+
+ /* Enable temperature compensation. */
+ if (IEEE80211_IS_CHAN_5GHZ(c) &&
+ eep->base_ext2.tempSlopeLow != 0) {
+ if (c->ic_freq <= 5500) {
+ slope = athn_interpolate(c->ic_freq,
+ 5180, eep->base_ext2.tempSlopeLow,
+ 5500, modal->tempSlope);
+ } else {
+ slope = athn_interpolate(c->ic_freq,
+ 5500, modal->tempSlope,
+ 5785, eep->base_ext2.tempSlopeHigh);
+ }
+ } else
+ slope = modal->tempSlope;
+
+ reg = AR_READ(sc, AR_PHY_TPC_19);
+ reg = RW(reg, AR_PHY_TPC_19_ALPHA_THERM, slope);
+ AR_WRITE(sc, AR_PHY_TPC_19, reg);
+
+ reg = AR_READ(sc, AR_PHY_TPC_18);
+ reg = RW(reg, AR_PHY_TPC_18_THERM_CAL, temp0);
+ AR_WRITE(sc, AR_PHY_TPC_18, reg);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
diff --git a/sys/dev/athn/ic/ar9380reg.h b/sys/dev/athn/ic/ar9380reg.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/ic/ar9380reg.h
@@ -0,0 +1,1910 @@
+/* $OpenBSD: ar9380reg.h,v 1.21 2016/01/05 18:41:15 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2010 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define AR9380_MAX_CHAINS 3
+
+#define AR9380_PHY_CCA_NOM_VAL_2GHZ (-110)
+#define AR9380_PHY_CCA_NOM_VAL_5GHZ (-115)
+#define AR9380_PHY_CCA_MIN_GOOD_VAL_2GHZ (-125)
+#define AR9380_PHY_CCA_MIN_GOOD_VAL_5GHZ (-125)
+#define AR9380_PHY_CCA_MAX_GOOD_VAL_2GHZ ( -95)
+#define AR9380_PHY_CCA_MAX_GOOD_VAL_5GHZ (-100)
+
+/*
+ * ROM layout used by AR9380.
+ */
+#define AR9380_NUM_5G_CAL_PIERS 8
+#define AR9380_NUM_2G_CAL_PIERS 3
+#define AR9380_NUM_5G_20_TARGET_POWERS 8
+#define AR9380_NUM_5G_40_TARGET_POWERS 8
+#define AR9380_NUM_2G_CCK_TARGET_POWERS 2
+#define AR9380_NUM_2G_20_TARGET_POWERS 3
+#define AR9380_NUM_2G_40_TARGET_POWERS 3
+#define AR9380_NUM_CTLS_5G 9
+#define AR9380_NUM_CTLS_2G 12
+#define AR9380_NUM_BAND_EDGES_5G 8
+#define AR9380_NUM_BAND_EDGES_2G 4
+#define AR9380_NUM_PD_GAINS 4
+#define AR9380_PD_GAINS_IN_MASK 4
+#define AR9380_PD_GAIN_ICEPTS 5
+#define AR9380_EEPROM_MODAL_SPURS 5
+#define AR9380_CUSTOMER_DATA_SIZE 20
+
+struct ar9380_cal_ctl_data_2g {
+ uint8_t ctlEdges[AR9380_NUM_BAND_EDGES_2G];
+} __packed;
+
+struct ar9380_cal_ctl_data_5g {
+ uint8_t ctlEdges[AR9380_NUM_BAND_EDGES_5G];
+} __packed;
+
+struct ar9380_base_eep_hdr {
+ uint16_t regDmn[2];
+ uint8_t txrxMask;
+#define AR_EEP_TX_MASK_M 0xf0
+#define AR_EEP_TX_MASK_S 4
+#define AR_EEP_RX_MASK_M 0x0f
+#define AR_EEP_RX_MASK_S 0
+
+ uint8_t opFlags;
+#define AR_OPFLAGS_11A 0x01
+#define AR_OPFLAGS_11G 0x02
+#define AR_OPFLAGS_11N_5G40 0x04
+#define AR_OPFLAGS_11N_2G40 0x08
+#define AR_OPFLAGS_11N_5G20 0x10
+#define AR_OPFLAGS_11N_2G20 0x20
+/* Shortcut. */
+#define AR_OPFLAGS_11N 0x3c
+
+ uint8_t eepMisc;
+ uint8_t rfSilent;
+#define AR_EEP_RFSILENT_ENABLED 0x0001
+#define AR_EEP_RFSILENT_GPIO_SEL_M 0x001c
+#define AR_EEP_RFSILENT_GPIO_SEL_S 2
+#define AR_EEP_RFSILENT_POLARITY 0x0002
+
+ uint8_t blueToothOptions;
+ uint8_t deviceCap;
+ uint8_t deviceType;
+ int8_t pwrTableOffset;
+ uint8_t params_for_tuning_caps[2];
+ uint8_t featureEnable;
+#define AR_EEP_TX_TEMP_COMP_EN 0x01
+#define AR_EEP_TX_VOLT_COMP_EN 0x02
+#define AR_EEP_FAST_CLOCK_EN 0x04
+#define AR_EEP_DOUBLING_EN 0x08
+#define AR_EEP_INTERNAL_REGULATOR 0x10
+#define AR_EEP_PAPRD 0x20
+#define AR_EEP_TUNING_CAPS 0x40
+
+ uint8_t miscConfiguration;
+#define AR_EEP_DRIVE_STRENGTH 0x01
+#define AR_EEP_CHAIN_MASK_REDUCE 0x08
+
+ uint8_t eepromWriteEnableGpio;
+ uint8_t wlanDisableGpio;
+ uint8_t wlanLedGpio;
+ uint8_t rxBandSelectGpio;
+ uint8_t txrxgain;
+#define AR_EEP_TX_GAIN_M 0xf0
+#define AR_EEP_TX_GAIN_S 4
+#define AR_EEP_TX_GAIN_HIGH_OB_DB 1
+#define AR_EEP_TX_GAIN_LOW_OB_DB 2
+#define AR_EEP_TX_GAIN_HIGH_POWER 3
+#define AR_EEP_RX_GAIN_M 0x0f
+#define AR_EEP_RX_GAIN_S 0
+#define AR_EEP_RX_GAIN_WO_XLNA 1
+
+ uint32_t swreg;
+} __packed;
+
+struct ar9380_modal_eep_header {
+ uint32_t antCtrlCommon;
+ uint32_t antCtrlCommon2;
+ uint16_t antCtrlChain[AR9380_MAX_CHAINS];
+ uint8_t xatten1DB[AR9380_MAX_CHAINS];
+ uint8_t xatten1Margin[AR9380_MAX_CHAINS];
+ int8_t tempSlope;
+ int8_t voltSlope;
+ uint8_t spurChans[AR9380_EEPROM_MODAL_SPURS];
+ int8_t noiseFloorThreshCh[AR9380_MAX_CHAINS];
+ uint8_t ob[AR9380_MAX_CHAINS];
+ uint8_t db_stage2[AR9380_MAX_CHAINS];
+ uint8_t db_stage3[AR9380_MAX_CHAINS];
+ uint8_t db_stage4[AR9380_MAX_CHAINS];
+ uint8_t xpaBiasLvl;
+ uint8_t txFrameToDataStart;
+ uint8_t txFrameToPaOn;
+ uint8_t txClip;
+ int8_t antennaGain;
+ uint8_t switchSettling;
+ int8_t adcDesiredSize;
+ uint8_t txEndToXpaOff;
+ uint8_t txEndToRxOn;
+ uint8_t txFrameToXpaOn;
+ uint8_t thresh62;
+ uint32_t papdRateMaskHt20;
+ uint32_t papdRateMaskHt40;
+ uint8_t futureModal[10];
+} __packed;
+
+struct ar9380_cal_data_per_freq_op_loop {
+ int8_t refPower;
+ uint8_t voltMeas;
+ uint8_t tempMeas;
+ int8_t rxNoisefloorCal;
+ int8_t rxNoisefloorPower;
+ uint8_t rxTempMeas;
+} __packed;
+
+struct ar9380_base_extension_1 {
+ uint8_t ant_div_control;
+#define AR_EEP_ANT_DIV_CTRL_ALL_M 0x3f
+#define AR_EEP_ANT_DIV_CTRL_ALL_S 0
+#define AR_EEP_ANT_DIV_CTRL_ANT_DIV 0x40
+#define AR_EEP_ANT_DIV_CTRL_FAST_DIV 0x80
+
+ uint8_t future[13];
+} __packed;
+
+struct ar9380_base_extension_2 {
+ int8_t tempSlopeLow;
+ int8_t tempSlopeHigh;
+ uint8_t xatten1DBLow[AR9380_MAX_CHAINS];
+ uint8_t xatten1MarginLow[AR9380_MAX_CHAINS];
+ uint8_t xatten1DBHigh[AR9380_MAX_CHAINS];
+ uint8_t xatten1MarginHigh[AR9380_MAX_CHAINS];
+} __packed;
+
+struct ar9380_eeprom {
+ uint8_t eepromVersion;
+ uint8_t templateVersion;
+ uint8_t macAddr[6];
+ uint8_t custData[AR9380_CUSTOMER_DATA_SIZE];
+ struct ar9380_base_eep_hdr baseEepHeader;
+ struct ar9380_modal_eep_header modalHeader2G;
+ struct ar9380_base_extension_1 base_ext1;
+ uint8_t calFreqPier2G[AR9380_NUM_2G_CAL_PIERS];
+ struct ar9380_cal_data_per_freq_op_loop
+ calPierData2G[AR9380_MAX_CHAINS][AR9380_NUM_2G_CAL_PIERS];
+ uint8_t calTargetFbinCck[AR9380_NUM_2G_CCK_TARGET_POWERS];
+ uint8_t calTargetFbin2G[AR9380_NUM_2G_20_TARGET_POWERS];
+ uint8_t calTargetFbin2GHT20[AR9380_NUM_2G_20_TARGET_POWERS];
+ uint8_t calTargetFbin2GHT40[AR9380_NUM_2G_40_TARGET_POWERS];
+ struct ar_cal_target_power_leg
+ calTargetPowerCck[AR9380_NUM_2G_CCK_TARGET_POWERS];
+ struct ar_cal_target_power_leg
+ calTargetPower2G[AR9380_NUM_2G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower2GHT20[AR9380_NUM_2G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower2GHT40[AR9380_NUM_2G_40_TARGET_POWERS];
+ uint8_t ctlIndex_2G[AR9380_NUM_CTLS_2G];
+ uint8_t ctl_freqbin_2G[AR9380_NUM_CTLS_2G][AR9380_NUM_BAND_EDGES_2G];
+ struct ar9380_cal_ctl_data_2g ctlPowerData_2G[AR9380_NUM_CTLS_2G];
+ struct ar9380_modal_eep_header modalHeader5G;
+ struct ar9380_base_extension_2 base_ext2;
+ uint8_t calFreqPier5G[AR9380_NUM_5G_CAL_PIERS];
+ struct ar9380_cal_data_per_freq_op_loop
+ calPierData5G[AR9380_MAX_CHAINS][AR9380_NUM_5G_CAL_PIERS];
+ uint8_t calTargetFbin5G[AR9380_NUM_5G_20_TARGET_POWERS];
+ uint8_t calTargetFbin5GHT20[AR9380_NUM_5G_20_TARGET_POWERS];
+ uint8_t calTargetFbin5GHT40[AR9380_NUM_5G_40_TARGET_POWERS];
+ struct ar_cal_target_power_leg
+ calTargetPower5G[AR9380_NUM_5G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower5GHT20[AR9380_NUM_5G_20_TARGET_POWERS];
+ struct ar_cal_target_power_ht
+ calTargetPower5GHT40[AR9380_NUM_5G_40_TARGET_POWERS];
+ uint8_t ctlIndex_5G[AR9380_NUM_CTLS_5G];
+ uint8_t ctl_freqbin_5G[AR9380_NUM_CTLS_5G][AR9380_NUM_BAND_EDGES_5G];
+ struct ar9380_cal_ctl_data_5g ctlPowerData_5G[AR9380_NUM_CTLS_5G];
+} __packed;
+
+/*
+ * ROM templates (little endian).
+ */
+static const uint8_t ar9380_def_rom[] = {
+ 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x08, 0xff, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x22, 0x22, 0x02,
+ 0x00, 0x50, 0x01, 0x50, 0x01, 0x50, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x03, 0x00,
+ 0x2c, 0xe2, 0x00, 0x02, 0x0e, 0x1c, 0xe0, 0xe0, 0xf0, 0x0c,
+ 0xe0, 0xe0, 0xf0, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x89,
+ 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xb8, 0x70, 0x89, 0xac,
+ 0x70, 0x89, 0xac, 0x70, 0x89, 0xac, 0x24, 0x24, 0x24, 0x24,
+ 0x24, 0x24, 0x24, 0x24, 0x20, 0x20, 0x1c, 0x18, 0x20, 0x20,
+ 0x1c, 0x18, 0x20, 0x20, 0x1c, 0x18, 0x20, 0x20, 0x20, 0x20,
+ 0x1c, 0x14, 0x20, 0x20, 0x1c, 0x14, 0x20, 0x20, 0x1c, 0x14,
+ 0x20, 0x20, 0x20, 0x20, 0x1c, 0x14, 0x20, 0x20, 0x1c, 0x14,
+ 0x20, 0x20, 0x1c, 0x14, 0x20, 0x20, 0x20, 0x20, 0x1c, 0x14,
+ 0x20, 0x20, 0x1c, 0x14, 0x20, 0x20, 0x1c, 0x14, 0x20, 0x20,
+ 0x20, 0x20, 0x1c, 0x14, 0x20, 0x20, 0x1c, 0x14, 0x20, 0x20,
+ 0x1c, 0x14, 0x20, 0x20, 0x20, 0x20, 0x1c, 0x14, 0x20, 0x20,
+ 0x1c, 0x14, 0x20, 0x20, 0x1c, 0x14, 0x20, 0x20, 0x20, 0x20,
+ 0x1c, 0x14, 0x20, 0x20, 0x1c, 0x14, 0x20, 0x20, 0x1c, 0x14,
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, 0x45, 0x47, 0x31, 0x32,
+ 0x35, 0x37, 0x70, 0x75, 0x9d, 0xa2, 0x70, 0x75, 0xa2, 0xff,
+ 0x70, 0x75, 0xa2, 0xff, 0x7a, 0x7f, 0x93, 0x98, 0x70, 0x75,
+ 0xac, 0xb8, 0x70, 0x75, 0xac, 0x00, 0x70, 0x75, 0xac, 0x00,
+ 0x7a, 0x7f, 0x93, 0xa2, 0x70, 0x75, 0xac, 0x00, 0x70, 0x75,
+ 0xac, 0x00, 0x70, 0x75, 0xac, 0x00, 0x7a, 0x7f, 0x93, 0xa2,
+ 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c, 0x7c, 0x3c,
+ 0x3c, 0x7c, 0x7c, 0x3c, 0x00, 0x00, 0x3c, 0x7c, 0x3c, 0x3c,
+ 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x3c, 0x3c, 0x7c,
+ 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c,
+ 0x3c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x10, 0x01,
+ 0x00, 0x00, 0x22, 0x22, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x00, 0x0e, 0x0e, 0x03, 0x00, 0x2d, 0xe2, 0x00, 0x02, 0x0e,
+ 0x1c, 0x80, 0xc0, 0x80, 0x0c, 0x80, 0xc0, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x54, 0x68, 0x78, 0x8c, 0xa0, 0xb9,
+ 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x54, 0x68, 0x78, 0x8c,
+ 0xa0, 0xb9, 0xcd, 0x4c, 0x58, 0x68, 0x8c, 0xb4, 0xbd, 0xb9,
+ 0xcd, 0x4c, 0x58, 0x68, 0x8c, 0xb4, 0xbd, 0xb9, 0xcd, 0x14,
+ 0x14, 0x14, 0x0a, 0x14, 0x14, 0x14, 0x0a, 0x14, 0x14, 0x14,
+ 0x0a, 0x14, 0x14, 0x14, 0x0a, 0x14, 0x14, 0x14, 0x0a, 0x14,
+ 0x14, 0x14, 0x0a, 0x14, 0x14, 0x14, 0x0a, 0x14, 0x14, 0x14,
+ 0x0a, 0x14, 0x14, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00,
+ 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x14, 0x14, 0x0a, 0x0a, 0x00,
+ 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x14,
+ 0x14, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x0a,
+ 0x0a, 0x00, 0x00, 0x14, 0x14, 0x0a, 0x0a, 0x00, 0x00, 0x0a,
+ 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x14, 0x14, 0x0a,
+ 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00,
+ 0x00, 0x14, 0x14, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00,
+ 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x14, 0x14, 0x0a, 0x0a, 0x00,
+ 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x14,
+ 0x14, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x0a,
+ 0x0a, 0x00, 0x00, 0x14, 0x14, 0x0a, 0x0a, 0x00, 0x00, 0x0a,
+ 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x14, 0x14, 0x0a,
+ 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00,
+ 0x00, 0x14, 0x14, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00,
+ 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x14, 0x14, 0x0a, 0x0a, 0x00,
+ 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x14,
+ 0x14, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x0a,
+ 0x0a, 0x00, 0x00, 0x14, 0x14, 0x0a, 0x0a, 0x00, 0x00, 0x0a,
+ 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x14, 0x14, 0x0a,
+ 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00,
+ 0x00, 0x14, 0x14, 0x0a, 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00,
+ 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38, 0x4c, 0x5c, 0x60, 0x8c, 0xa0, 0xb4,
+ 0xbd, 0xcd, 0x4c, 0x5c, 0x60, 0x8c, 0x90, 0xb4, 0xbd, 0xcd,
+ 0x4e, 0x56, 0x5e, 0x66, 0x8e, 0x96, 0xae, 0xbf, 0x4c, 0x50,
+ 0x5c, 0x68, 0x8c, 0xb4, 0xff, 0xff, 0x4c, 0x5c, 0x8c, 0xb4,
+ 0xff, 0xff, 0xff, 0xff, 0x4e, 0x5e, 0x66, 0x8e, 0x9e, 0xae,
+ 0xff, 0xff, 0x4c, 0x50, 0x54, 0x5c, 0x8c, 0xa0, 0xb4, 0xbd,
+ 0x4c, 0x5c, 0x68, 0x8c, 0x98, 0xb4, 0xbd, 0xcd, 0x4e, 0x56,
+ 0x5e, 0x8e, 0x96, 0xae, 0xbf, 0xc7, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x3c, 0x7c, 0x7c, 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c,
+ 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c
+};
+
+static const uint8_t ar9380_def_rom_h112[] = {
+ 0x02, 0x03, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x00, 0x68, 0x31,
+ 0x31, 0x32, 0x2d, 0x32, 0x34, 0x31, 0x2d, 0x66, 0x30, 0x30,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x08, 0xff, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x44, 0x44, 0x04,
+ 0x00, 0x50, 0x01, 0x50, 0x01, 0x50, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x19, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x03, 0x00,
+ 0x2c, 0xe2, 0x00, 0x02, 0x0e, 0x1c, 0x80, 0xc0, 0x80, 0x00,
+ 0x80, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x89,
+ 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xb8, 0x70, 0x89, 0xac,
+ 0x70, 0x89, 0xac, 0x70, 0x89, 0xac, 0x22, 0x22, 0x22, 0x22,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x20, 0x20, 0x22, 0x22,
+ 0x20, 0x20, 0x22, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x1e, 0x20, 0x20, 0x1e, 0x1c, 0x1c, 0x1c, 0x1c, 0x18,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x1e, 0x20, 0x20, 0x1e, 0x1c,
+ 0x1c, 0x1c, 0x1c, 0x18, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1e,
+ 0x20, 0x20, 0x1e, 0x1c, 0x1c, 0x1c, 0x1c, 0x18, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1c, 0x1e, 0x1e, 0x1c, 0x1a, 0x1a, 0x1a,
+ 0x1a, 0x16, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1c, 0x1e, 0x1e,
+ 0x1c, 0x1a, 0x1a, 0x1a, 0x1a, 0x16, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1c, 0x1e, 0x1e, 0x1c, 0x1a, 0x1a, 0x1a, 0x1a, 0x16,
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, 0x45, 0x47, 0x31, 0x32,
+ 0x35, 0x37, 0x70, 0x75, 0x9d, 0xa2, 0x70, 0x75, 0xa2, 0xff,
+ 0x70, 0x75, 0xa2, 0xff, 0x7a, 0x7f, 0x93, 0x98, 0x70, 0x75,
+ 0xac, 0xb8, 0x70, 0x75, 0xac, 0x00, 0x70, 0x75, 0xac, 0x00,
+ 0x7a, 0x7f, 0x93, 0xa2, 0x70, 0x75, 0xac, 0x00, 0x70, 0x75,
+ 0xac, 0x00, 0x70, 0x75, 0xac, 0x00, 0x7a, 0x7f, 0x93, 0xa2,
+ 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c, 0x7c, 0x3c,
+ 0x3c, 0x7c, 0x7c, 0x3c, 0x00, 0x00, 0x3c, 0x7c, 0x3c, 0x3c,
+ 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x3c, 0x3c, 0x7c,
+ 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c,
+ 0x3c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x20, 0x02,
+ 0x00, 0x00, 0x44, 0x44, 0x04, 0x00, 0x50, 0x01, 0x50, 0x01,
+ 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x00, 0x0e, 0x0e, 0x03, 0x00, 0x2d, 0xe2, 0x00, 0x02, 0x0e,
+ 0x1c, 0xe0, 0xe0, 0xf0, 0x0c, 0xe0, 0xe0, 0xf0, 0x6c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x54, 0x68, 0x78, 0x8c, 0xa0, 0xb4,
+ 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x58, 0x68, 0x78, 0x8c,
+ 0xa0, 0xb4, 0xcd, 0x4c, 0x58, 0x68, 0x78, 0x8c, 0xb4, 0xbd,
+ 0xcd, 0x4c, 0x58, 0x68, 0x78, 0x8c, 0xb4, 0xbd, 0xcd, 0x1e,
+ 0x1e, 0x1c, 0x18, 0x1e, 0x1e, 0x1c, 0x18, 0x1e, 0x1e, 0x1c,
+ 0x18, 0x1e, 0x1e, 0x1c, 0x18, 0x1e, 0x1e, 0x1c, 0x18, 0x1e,
+ 0x1e, 0x1c, 0x18, 0x1e, 0x1e, 0x1c, 0x18, 0x1e, 0x1e, 0x1c,
+ 0x18, 0x1e, 0x1e, 0x1e, 0x1c, 0x18, 0x14, 0x1e, 0x1c, 0x18,
+ 0x14, 0x14, 0x14, 0x14, 0x10, 0x1e, 0x1e, 0x1e, 0x1c, 0x18,
+ 0x14, 0x1e, 0x1c, 0x18, 0x14, 0x14, 0x14, 0x14, 0x10, 0x1e,
+ 0x1e, 0x1e, 0x1a, 0x16, 0x12, 0x1e, 0x1a, 0x16, 0x12, 0x12,
+ 0x12, 0x12, 0x10, 0x1e, 0x1e, 0x1e, 0x1a, 0x16, 0x12, 0x1e,
+ 0x1a, 0x16, 0x12, 0x12, 0x12, 0x12, 0x10, 0x1e, 0x1e, 0x1e,
+ 0x18, 0x14, 0x10, 0x1e, 0x18, 0x14, 0x10, 0x10, 0x10, 0x10,
+ 0x0e, 0x1e, 0x1e, 0x1e, 0x18, 0x14, 0x10, 0x1e, 0x18, 0x14,
+ 0x10, 0x10, 0x10, 0x10, 0x0e, 0x1e, 0x1e, 0x1e, 0x16, 0x12,
+ 0x0e, 0x1e, 0x16, 0x12, 0x0e, 0x0e, 0x0e, 0x0e, 0x0c, 0x1e,
+ 0x1e, 0x1e, 0x16, 0x12, 0x0e, 0x1e, 0x16, 0x12, 0x0e, 0x0e,
+ 0x0e, 0x0e, 0x0c, 0x1c, 0x1c, 0x1c, 0x1a, 0x16, 0x12, 0x1c,
+ 0x1a, 0x16, 0x12, 0x12, 0x12, 0x12, 0x0e, 0x1c, 0x1c, 0x1c,
+ 0x1a, 0x16, 0x12, 0x1c, 0x1a, 0x16, 0x12, 0x12, 0x12, 0x12,
+ 0x0e, 0x1c, 0x1c, 0x1c, 0x18, 0x14, 0x10, 0x1c, 0x18, 0x14,
+ 0x10, 0x10, 0x10, 0x10, 0x0c, 0x1c, 0x1c, 0x1c, 0x18, 0x14,
+ 0x10, 0x1c, 0x18, 0x14, 0x10, 0x10, 0x10, 0x10, 0x0c, 0x1c,
+ 0x1c, 0x1c, 0x16, 0x12, 0x0e, 0x1c, 0x16, 0x12, 0x0e, 0x0e,
+ 0x0e, 0x0e, 0x0a, 0x1c, 0x1c, 0x1c, 0x16, 0x12, 0x0e, 0x1c,
+ 0x16, 0x12, 0x0e, 0x0e, 0x0e, 0x0e, 0x0a, 0x1c, 0x1c, 0x1c,
+ 0x14, 0x10, 0x0c, 0x1c, 0x14, 0x10, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x08, 0x1c, 0x1c, 0x1c, 0x14, 0x10, 0x0c, 0x1c, 0x14, 0x10,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x08, 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38, 0x4c, 0x5c, 0x60, 0x8c, 0xa0, 0xb4,
+ 0xbd, 0xcd, 0x4c, 0x5c, 0x60, 0x8c, 0x90, 0xb4, 0xbd, 0xcd,
+ 0x4e, 0x56, 0x5e, 0x66, 0x8e, 0x96, 0xae, 0xbf, 0x4c, 0x50,
+ 0x5c, 0x68, 0x8c, 0xb4, 0xff, 0xff, 0x4c, 0x5c, 0x8c, 0xb4,
+ 0xff, 0xff, 0xff, 0xff, 0x4e, 0x5e, 0x66, 0x8e, 0x9e, 0xae,
+ 0xff, 0xff, 0x4c, 0x50, 0x54, 0x5c, 0x8c, 0xa0, 0xb4, 0xbd,
+ 0x4c, 0x5c, 0x68, 0x8c, 0x98, 0xb4, 0xbd, 0xcd, 0x4e, 0x56,
+ 0x5e, 0x8e, 0x96, 0xae, 0xbf, 0xc7, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x3c, 0x7c, 0x7c, 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c,
+ 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c
+};
+
+static const uint8_t ar9380_def_rom_h116[] = {
+ 0x02, 0x04, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x00, 0x68, 0x31,
+ 0x31, 0x36, 0x2d, 0x30, 0x34, 0x31, 0x2d, 0x66, 0x30, 0x30,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x08, 0xff, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x44, 0x44, 0x04,
+ 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x1f, 0x1f, 0x1f,
+ 0x12, 0x12, 0x12, 0x19, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x03, 0x00,
+ 0x2c, 0xe2, 0x00, 0x02, 0x0e, 0x1c, 0x80, 0xc0, 0x80, 0x0c,
+ 0x80, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x89,
+ 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xac, 0x70, 0x89, 0xac,
+ 0x70, 0x89, 0xac, 0x70, 0x89, 0xac, 0x22, 0x22, 0x22, 0x22,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x20, 0x20, 0x22, 0x22,
+ 0x20, 0x20, 0x22, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x1e, 0x20, 0x20, 0x1e, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x1e, 0x20, 0x20, 0x1e, 0x1c,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1e,
+ 0x20, 0x20, 0x1e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1c, 0x1e, 0x1e, 0x1c, 0x1a, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1c, 0x1e, 0x1e,
+ 0x1c, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1c, 0x1e, 0x1e, 0x1c, 0x1a, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, 0x45, 0x47, 0x31, 0x32,
+ 0x35, 0x37, 0x70, 0x75, 0x9d, 0xa2, 0x70, 0x75, 0xa2, 0xff,
+ 0x70, 0x75, 0xa2, 0xff, 0x7a, 0x7f, 0x93, 0x98, 0x70, 0x75,
+ 0xac, 0xb8, 0x70, 0x75, 0xac, 0x00, 0x70, 0x75, 0xac, 0x00,
+ 0x7a, 0x7f, 0x93, 0xa2, 0x70, 0x75, 0xac, 0x00, 0x70, 0x75,
+ 0xac, 0x00, 0x70, 0x75, 0xac, 0x00, 0x7a, 0x7f, 0x93, 0xa2,
+ 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c, 0x7c, 0x3c,
+ 0x3c, 0x7c, 0x7c, 0x3c, 0x00, 0x00, 0x3c, 0x7c, 0x3c, 0x3c,
+ 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x3c, 0x3c, 0x7c,
+ 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c,
+ 0x3c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x20, 0x02,
+ 0x00, 0x00, 0x44, 0x44, 0x04, 0x00, 0x50, 0x01, 0x50, 0x01,
+ 0x50, 0x01, 0x19, 0x19, 0x19, 0x14, 0x14, 0x14, 0x46, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x00, 0x0e, 0x0e, 0x03, 0x00, 0x2d, 0xe2, 0x00, 0x02, 0x0e,
+ 0x1c, 0xe0, 0xe0, 0xf0, 0x0c, 0xe0, 0xe0, 0xf0, 0x6c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23,
+ 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x54, 0x68, 0x78, 0x8c, 0xa0, 0xb4,
+ 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x58, 0x68, 0x78, 0x8c,
+ 0xa0, 0xb4, 0xcd, 0x4c, 0x58, 0x68, 0x78, 0x8c, 0xb4, 0xbd,
+ 0xcd, 0x4c, 0x58, 0x68, 0x78, 0x8c, 0xb4, 0xbd, 0xcd, 0x1e,
+ 0x1e, 0x1c, 0x18, 0x1e, 0x1e, 0x1c, 0x18, 0x1e, 0x1e, 0x1c,
+ 0x18, 0x1e, 0x1e, 0x1c, 0x18, 0x1e, 0x1e, 0x1c, 0x18, 0x1e,
+ 0x1e, 0x1c, 0x18, 0x1e, 0x1e, 0x1c, 0x18, 0x1e, 0x1e, 0x1c,
+ 0x18, 0x1e, 0x1e, 0x1e, 0x1c, 0x18, 0x14, 0x1e, 0x1c, 0x18,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1c, 0x18,
+ 0x14, 0x1e, 0x1c, 0x18, 0x14, 0x00, 0x00, 0x00, 0x00, 0x1e,
+ 0x1e, 0x1e, 0x1a, 0x16, 0x12, 0x1e, 0x1a, 0x16, 0x12, 0x00,
+ 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1a, 0x16, 0x12, 0x1e,
+ 0x1a, 0x16, 0x12, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x1e,
+ 0x18, 0x14, 0x10, 0x1e, 0x18, 0x14, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x1e, 0x1e, 0x1e, 0x18, 0x14, 0x10, 0x1e, 0x18, 0x14,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x16, 0x12,
+ 0x0e, 0x1e, 0x16, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x1e,
+ 0x1e, 0x1e, 0x16, 0x12, 0x0e, 0x1e, 0x16, 0x12, 0x0e, 0x00,
+ 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1a, 0x16, 0x12, 0x1c,
+ 0x1a, 0x16, 0x12, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x1c,
+ 0x1a, 0x16, 0x12, 0x1c, 0x1a, 0x16, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x1c, 0x1c, 0x1c, 0x18, 0x14, 0x10, 0x1c, 0x18, 0x14,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x18, 0x14,
+ 0x10, 0x1c, 0x18, 0x14, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1c,
+ 0x1c, 0x1c, 0x16, 0x12, 0x0e, 0x1c, 0x16, 0x12, 0x0e, 0x00,
+ 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x16, 0x12, 0x0e, 0x1c,
+ 0x16, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x1c,
+ 0x14, 0x10, 0x0c, 0x1c, 0x14, 0x10, 0x0c, 0x00, 0x00, 0x00,
+ 0x00, 0x1c, 0x1c, 0x1c, 0x14, 0x10, 0x0c, 0x1c, 0x14, 0x10,
+ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38, 0x4c, 0x5c, 0x60, 0x8c, 0xa0, 0xb4,
+ 0xbd, 0xcd, 0x4c, 0x5c, 0x60, 0x8c, 0x90, 0xb4, 0xbd, 0xcd,
+ 0x4e, 0x56, 0x5e, 0x66, 0x8e, 0x96, 0xae, 0xbf, 0x4c, 0x50,
+ 0x5c, 0x68, 0x8c, 0xb4, 0xff, 0xff, 0x4c, 0x5c, 0x8c, 0xb4,
+ 0xff, 0xff, 0xff, 0xff, 0x4e, 0x5e, 0x66, 0x8e, 0x9e, 0xae,
+ 0xff, 0xff, 0x4c, 0x50, 0x54, 0x5c, 0x8c, 0xa0, 0xb4, 0xbd,
+ 0x4c, 0x5c, 0x68, 0x8c, 0x98, 0xb4, 0xbd, 0xcd, 0x4e, 0x56,
+ 0x5e, 0x8e, 0x96, 0xae, 0xbf, 0xc7, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x3c, 0x7c, 0x7c, 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c,
+ 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c
+};
+
+static const uint8_t ar9380_def_rom_x112[] = {
+ 0x02, 0x05, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x00, 0x78, 0x31,
+ 0x31, 0x32, 0x2d, 0x30, 0x34, 0x31, 0x2d, 0x66, 0x30, 0x30,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x08, 0xff, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x22, 0x22, 0x02,
+ 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x1b, 0x1b, 0x1b,
+ 0x15, 0x15, 0x15, 0x32, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x03, 0x00,
+ 0x2c, 0xe2, 0x00, 0x02, 0x0e, 0x1c, 0x80, 0xc0, 0x80, 0x0c,
+ 0x80, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x89,
+ 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xac, 0x70, 0x89, 0xac,
+ 0x70, 0x89, 0xac, 0x70, 0x89, 0xac, 0x26, 0x26, 0x26, 0x26,
+ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x24, 0x22, 0x26, 0x26,
+ 0x24, 0x22, 0x26, 0x26, 0x22, 0x20, 0x24, 0x24, 0x24, 0x24,
+ 0x24, 0x22, 0x22, 0x20, 0x1e, 0x1c, 0x1c, 0x1c, 0x1c, 0x1a,
+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x22, 0x24, 0x22, 0x20, 0x1e,
+ 0x1e, 0x1e, 0x1c, 0x1a, 0x24, 0x24, 0x24, 0x24, 0x24, 0x22,
+ 0x22, 0x20, 0x1e, 0x1c, 0x1c, 0x1c, 0x1c, 0x1a, 0x24, 0x24,
+ 0x24, 0x24, 0x22, 0x20, 0x20, 0x1e, 0x1c, 0x1a, 0x1a, 0x1a,
+ 0x1a, 0x18, 0x24, 0x24, 0x24, 0x24, 0x22, 0x20, 0x22, 0x20,
+ 0x1e, 0x1c, 0x1c, 0x1c, 0x1c, 0x18, 0x24, 0x24, 0x24, 0x24,
+ 0x22, 0x20, 0x20, 0x1e, 0x1c, 0x1a, 0x1a, 0x1a, 0x1a, 0x18,
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, 0x45, 0x47, 0x31, 0x32,
+ 0x35, 0x37, 0x70, 0x75, 0x9d, 0xa2, 0x70, 0x75, 0xa2, 0xff,
+ 0x70, 0x75, 0xa2, 0xff, 0x7a, 0x7f, 0x93, 0x98, 0x70, 0x75,
+ 0xac, 0xb8, 0x70, 0x75, 0xac, 0x00, 0x70, 0x75, 0xac, 0x00,
+ 0x7a, 0x7f, 0x93, 0xa2, 0x70, 0x75, 0xac, 0x00, 0x70, 0x75,
+ 0xac, 0x00, 0x70, 0x75, 0xac, 0x00, 0x7a, 0x7f, 0x93, 0xa2,
+ 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c, 0x7c, 0x3c,
+ 0x3c, 0x7c, 0x7c, 0x3c, 0x00, 0x00, 0x3c, 0x7c, 0x3c, 0x3c,
+ 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x3c, 0x3c, 0x7c,
+ 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c,
+ 0x3c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x10, 0x01,
+ 0x00, 0x00, 0x22, 0x22, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x13, 0x19, 0x17, 0x19, 0x19, 0x19, 0x46, 0x0f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x00, 0x0e, 0x0e, 0x03, 0x00, 0x2d, 0xe2, 0x00, 0x02, 0x0e,
+ 0x1c, 0xe0, 0xe0, 0xf0, 0x0c, 0xe0, 0xe0, 0xf0, 0x6c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x69, 0x10, 0x14, 0x10, 0x19, 0x19, 0x19, 0x1d, 0x20, 0x24,
+ 0x10, 0x10, 0x10, 0x4c, 0x54, 0x68, 0x78, 0x8c, 0xa0, 0xb4,
+ 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x54, 0x68, 0x78, 0x8c,
+ 0xa0, 0xb9, 0xcd, 0x4c, 0x54, 0x68, 0x78, 0x8c, 0xa0, 0xb9,
+ 0xcd, 0x4c, 0x54, 0x68, 0x78, 0x8c, 0xa0, 0xb9, 0xcd, 0x20,
+ 0x20, 0x1c, 0x1a, 0x20, 0x20, 0x1c, 0x1a, 0x20, 0x20, 0x1c,
+ 0x1a, 0x20, 0x20, 0x1a, 0x18, 0x20, 0x20, 0x1a, 0x18, 0x20,
+ 0x20, 0x18, 0x16, 0x1e, 0x1e, 0x18, 0x16, 0x1e, 0x1e, 0x18,
+ 0x16, 0x20, 0x20, 0x20, 0x20, 0x1c, 0x1a, 0x20, 0x1c, 0x1a,
+ 0x18, 0x18, 0x18, 0x16, 0x16, 0x20, 0x20, 0x20, 0x20, 0x1c,
+ 0x1a, 0x20, 0x1c, 0x1a, 0x18, 0x18, 0x18, 0x16, 0x16, 0x20,
+ 0x20, 0x20, 0x20, 0x1c, 0x1a, 0x20, 0x1c, 0x1a, 0x18, 0x18,
+ 0x18, 0x16, 0x16, 0x20, 0x20, 0x20, 0x20, 0x1c, 0x1a, 0x20,
+ 0x1a, 0x18, 0x16, 0x16, 0x16, 0x14, 0x14, 0x20, 0x20, 0x20,
+ 0x20, 0x1c, 0x1a, 0x20, 0x1a, 0x18, 0x16, 0x14, 0x12, 0x10,
+ 0x10, 0x20, 0x20, 0x20, 0x20, 0x1c, 0x1a, 0x20, 0x18, 0x14,
+ 0x10, 0x12, 0x10, 0x0e, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1c,
+ 0x1a, 0x1e, 0x18, 0x14, 0x10, 0x12, 0x10, 0x0e, 0x0e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1c, 0x1a, 0x1e, 0x18, 0x14, 0x10, 0x12,
+ 0x10, 0x0e, 0x0e, 0x20, 0x20, 0x20, 0x1e, 0x1c, 0x1a, 0x1e,
+ 0x1c, 0x1a, 0x18, 0x18, 0x18, 0x16, 0x16, 0x20, 0x20, 0x20,
+ 0x1e, 0x1c, 0x1a, 0x1e, 0x1c, 0x1a, 0x18, 0x18, 0x18, 0x16,
+ 0x16, 0x20, 0x20, 0x20, 0x1e, 0x1c, 0x1a, 0x1e, 0x1c, 0x1a,
+ 0x18, 0x18, 0x18, 0x16, 0x16, 0x20, 0x20, 0x20, 0x1e, 0x1c,
+ 0x1a, 0x1e, 0x1a, 0x18, 0x16, 0x16, 0x16, 0x14, 0x14, 0x20,
+ 0x20, 0x20, 0x1e, 0x1c, 0x1a, 0x1e, 0x1a, 0x18, 0x16, 0x14,
+ 0x12, 0x10, 0x10, 0x20, 0x20, 0x20, 0x1e, 0x1c, 0x1a, 0x1e,
+ 0x16, 0x14, 0x10, 0x12, 0x10, 0x0e, 0x0e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1c, 0x1a, 0x1e, 0x16, 0x14, 0x10, 0x12, 0x10, 0x0e,
+ 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1c, 0x1a, 0x1e, 0x16, 0x14,
+ 0x10, 0x12, 0x10, 0x0e, 0x0e, 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38, 0x4c, 0x5c, 0x60, 0x8c, 0xa0, 0xb4,
+ 0xbd, 0xcd, 0x4c, 0x5c, 0x60, 0x8c, 0x90, 0xb4, 0xbd, 0xcd,
+ 0x4e, 0x56, 0x5e, 0x66, 0x8e, 0x96, 0xae, 0xbf, 0x4c, 0x50,
+ 0x5c, 0x68, 0x8c, 0xb4, 0xff, 0xff, 0x4c, 0x5c, 0x8c, 0xb4,
+ 0xff, 0xff, 0xff, 0xff, 0x4e, 0x5e, 0x66, 0x8e, 0x9e, 0xae,
+ 0xff, 0xff, 0x4c, 0x50, 0x54, 0x5c, 0x8c, 0xa0, 0xb4, 0xbd,
+ 0x4c, 0x5c, 0x68, 0x8c, 0x98, 0xb4, 0xbd, 0xcd, 0x4e, 0x56,
+ 0x5e, 0x8e, 0x96, 0xae, 0xbf, 0xc7, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x3c, 0x7c, 0x7c, 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c,
+ 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c
+};
+
+static const uint8_t ar9380_def_rom_x113[] = {
+ 0x02, 0x06, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x00, 0x78, 0x31,
+ 0x31, 0x33, 0x2d, 0x30, 0x32, 0x33, 0x2d, 0x66, 0x30, 0x30,
+ 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x08, 0xff, 0x21, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x44, 0x44, 0x04,
+ 0x00, 0x50, 0x01, 0x50, 0x01, 0x50, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x19, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x03, 0x00,
+ 0x2c, 0xe2, 0x00, 0x02, 0x0e, 0x1c, 0x80, 0xc0, 0x80, 0x0c,
+ 0x80, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x89,
+ 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xac, 0x70, 0x89, 0xac,
+ 0x70, 0x89, 0xac, 0x70, 0x89, 0xac, 0x22, 0x22, 0x22, 0x22,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x20, 0x20, 0x22, 0x22,
+ 0x20, 0x20, 0x22, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x1c, 0x20, 0x20, 0x1e, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x1c, 0x20, 0x20, 0x1e, 0x1c,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1c,
+ 0x20, 0x20, 0x1e, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1c, 0x1e, 0x1e, 0x1c, 0x1a, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1c, 0x1e, 0x1e,
+ 0x1c, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1c, 0x1e, 0x1e, 0x1c, 0x1a, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, 0x45, 0x47, 0x31, 0x32,
+ 0x35, 0x37, 0x70, 0x75, 0x9d, 0xa2, 0x70, 0x75, 0xa2, 0xff,
+ 0x70, 0x75, 0xa2, 0xff, 0x7a, 0x7f, 0x93, 0x98, 0x70, 0x75,
+ 0xac, 0xb8, 0x70, 0x75, 0xac, 0x00, 0x70, 0x75, 0xac, 0x00,
+ 0x7a, 0x7f, 0x93, 0xa2, 0x70, 0x75, 0xac, 0x00, 0x70, 0x75,
+ 0xac, 0x00, 0x70, 0x75, 0xac, 0x00, 0x7a, 0x7f, 0x93, 0xa2,
+ 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c, 0x7c, 0x3c,
+ 0x3c, 0x7c, 0x7c, 0x3c, 0x00, 0x00, 0x3c, 0x7c, 0x3c, 0x3c,
+ 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x3c, 0x3c, 0x7c,
+ 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x3c, 0x3c,
+ 0x3c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x20, 0x02,
+ 0x00, 0x00, 0x11, 0x11, 0x01, 0x00, 0x50, 0x01, 0x50, 0x01,
+ 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00,
+ 0x8c, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x00, 0x0e, 0x0e, 0x03, 0x00, 0x2d, 0xe2, 0x00, 0x02, 0x0e,
+ 0x1c, 0xe0, 0xe0, 0xf0, 0x0c, 0xe0, 0xe0, 0xf0, 0x6c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x58, 0x68, 0x78, 0x8c, 0xa0, 0xbd,
+ 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x54, 0x68, 0x78, 0x8c,
+ 0xa0, 0xbd, 0xc5, 0x4c, 0x58, 0x68, 0x78, 0x8c, 0xb4, 0xbd,
+ 0xcd, 0x4e, 0x56, 0x68, 0x7a, 0x8e, 0xae, 0xbf, 0xcd, 0x2a,
+ 0x28, 0x28, 0x22, 0x2a, 0x28, 0x28, 0x22, 0x2a, 0x28, 0x28,
+ 0x22, 0x2a, 0x28, 0x28, 0x22, 0x2a, 0x28, 0x28, 0x22, 0x2a,
+ 0x28, 0x28, 0x22, 0x2a, 0x28, 0x28, 0x22, 0x2a, 0x28, 0x28,
+ 0x22, 0x28, 0x28, 0x28, 0x28, 0x20, 0x1c, 0x28, 0x28, 0x20,
+ 0x1c, 0x28, 0x28, 0x20, 0x14, 0x28, 0x28, 0x28, 0x28, 0x20,
+ 0x1c, 0x28, 0x28, 0x20, 0x1c, 0x28, 0x28, 0x20, 0x14, 0x28,
+ 0x28, 0x28, 0x28, 0x20, 0x1c, 0x28, 0x28, 0x20, 0x1c, 0x28,
+ 0x28, 0x20, 0x14, 0x28, 0x28, 0x28, 0x28, 0x20, 0x1c, 0x28,
+ 0x28, 0x20, 0x1c, 0x28, 0x28, 0x20, 0x14, 0x28, 0x28, 0x28,
+ 0x28, 0x20, 0x1c, 0x28, 0x28, 0x20, 0x1c, 0x28, 0x28, 0x20,
+ 0x14, 0x28, 0x28, 0x28, 0x28, 0x20, 0x1c, 0x28, 0x28, 0x20,
+ 0x1c, 0x28, 0x28, 0x20, 0x14, 0x26, 0x26, 0x26, 0x26, 0x20,
+ 0x1c, 0x26, 0x26, 0x20, 0x1c, 0x26, 0x26, 0x20, 0x1a, 0x24,
+ 0x24, 0x24, 0x24, 0x20, 0x1c, 0x24, 0x24, 0x20, 0x1c, 0x24,
+ 0x24, 0x20, 0x1a, 0x28, 0x28, 0x28, 0x26, 0x1e, 0x1a, 0x28,
+ 0x28, 0x1e, 0x1a, 0x28, 0x28, 0x1e, 0x18, 0x28, 0x28, 0x28,
+ 0x26, 0x1e, 0x1a, 0x28, 0x28, 0x1e, 0x1a, 0x28, 0x28, 0x1e,
+ 0x18, 0x28, 0x28, 0x28, 0x26, 0x1e, 0x1a, 0x28, 0x28, 0x1e,
+ 0x1a, 0x28, 0x28, 0x1e, 0x18, 0x28, 0x28, 0x28, 0x26, 0x1e,
+ 0x1a, 0x28, 0x28, 0x1e, 0x1a, 0x28, 0x28, 0x1e, 0x18, 0x28,
+ 0x28, 0x28, 0x26, 0x1e, 0x1a, 0x28, 0x28, 0x1e, 0x1a, 0x28,
+ 0x28, 0x1e, 0x18, 0x28, 0x28, 0x28, 0x26, 0x1e, 0x1a, 0x28,
+ 0x28, 0x1e, 0x1a, 0x28, 0x28, 0x1e, 0x18, 0x24, 0x24, 0x24,
+ 0x24, 0x1e, 0x1a, 0x24, 0x24, 0x1e, 0x1a, 0x24, 0x24, 0x1e,
+ 0x18, 0x22, 0x22, 0x22, 0x22, 0x1e, 0x1a, 0x22, 0x22, 0x1e,
+ 0x1a, 0x22, 0x22, 0x1e, 0x18, 0x10, 0x16, 0x18, 0x40, 0x46,
+ 0x48, 0x30, 0x36, 0x38, 0x4c, 0x5c, 0x60, 0x8c, 0xa0, 0xb4,
+ 0xbd, 0xcd, 0x4c, 0x5c, 0x60, 0x8c, 0x90, 0xb4, 0xbd, 0xcd,
+ 0x4e, 0x56, 0x5e, 0x66, 0x8e, 0x96, 0xae, 0xbf, 0x4c, 0x50,
+ 0x5c, 0x68, 0x8c, 0xb4, 0xff, 0xff, 0x4c, 0x5c, 0x8c, 0xb4,
+ 0xff, 0xff, 0xff, 0xff, 0x4e, 0x5e, 0x66, 0x8e, 0x9e, 0xae,
+ 0xff, 0xff, 0x4c, 0x50, 0x54, 0x5c, 0x8c, 0xa0, 0xb4, 0xbd,
+ 0x4c, 0x5c, 0x68, 0x8c, 0x98, 0xb4, 0xbd, 0xcd, 0x4e, 0x56,
+ 0x5e, 0x8e, 0x96, 0xae, 0xbf, 0xc7, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x3c, 0x7c, 0x7c, 0x3c, 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c,
+ 0x7c, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x7c
+};
+
+static const uint8_t *ar9380_rom_templates[] = {
+ ar9380_def_rom,
+ ar9380_def_rom_h112,
+ ar9380_def_rom_h116,
+ ar9380_def_rom_x112,
+ ar9380_def_rom_x113
+};
+
+/* Macro to "pack" registers to 16-bit to save some .rodata space. */
+#define P(x) ((x) >> 2)
+
+/*
+ * AR9380 2.2 programming.
+ */
+static const uint16_t ar9380_2_2_regs[] = {
+ P(0x07010), P(0x01030), P(0x01070), P(0x010b0), P(0x08014),
+ P(0x0801c), P(0x08120), P(0x081d0), P(0x08318), P(0x1609c),
+ P(0x160ac), P(0x160b0), P(0x1610c), P(0x16140), P(0x1650c),
+ P(0x16540), P(0x1690c), P(0x16940), P(0x09810), P(0x09820),
+ P(0x09824), P(0x09828), P(0x0982c), P(0x09830), P(0x09c00),
+ P(0x09e00), P(0x09e04), P(0x09e0c), P(0x09e10), P(0x09e14),
+ P(0x09e18), P(0x09e1c), P(0x09e20), P(0x09e2c), P(0x09e3c),
+ P(0x09e44), P(0x09e48), P(0x09fc8), P(0x0a204), P(0x0a208),
+ P(0x0a22c), P(0x0a230), P(0x0a234), P(0x0a238), P(0x0a250),
+ P(0x0a254), P(0x0a258), P(0x0a25c), P(0x0a260), P(0x0a264),
+ P(0x0a280), P(0x0a284), P(0x0a288), P(0x0a28c), P(0x0a2c4),
+ P(0x0a2d0), P(0x0a2d8), P(0x0a358), P(0x0a830), P(0x0ae04),
+ P(0x0ae18), P(0x0ae1c), P(0x0ae20), P(0x0b284), P(0x0b830),
+ P(0x0be04), P(0x0be18), P(0x0be1c), P(0x0be20), P(0x0c284)
+};
+
+static const uint32_t ar9380_2_2_vals_5g20[] = {
+ 0x00000023, 0x00000230, 0x00000168, 0x00000e60, 0x03e803e8,
+ 0x128d8027, 0x08f04800, 0x00003210, 0x00003e80, 0x0dd08f29,
+ 0xa4653c00, 0x03284f3e, 0x08000000, 0x10804008, 0x08000000,
+ 0x10804008, 0x08000000, 0x10804008, 0xd00a8005, 0x206a022e,
+ 0x5ac640d0, 0x06903081, 0x05eea6d4, 0x0000059c, 0x000000c4,
+ 0x0372111a, 0x001c2020, 0x6c4000e2, 0x7ec88d2e, 0x37b95d5e,
+ 0x00000000, 0x0001cf9c, 0x000003b5, 0x0000001c, 0xcf946220,
+ 0x02321e27, 0x5030201a, 0x0003f000, 0x000037c0, 0x00000104,
+ 0x01026a2f, 0x0000000a, 0x00000fff, 0xffb81018, 0x00000000,
+ 0x000007d0, 0x02020002, 0x01000e0e, 0x0a021501, 0x00000e0e,
+ 0x00000007, 0x00000000, 0x00000110, 0x00022222, 0x00158d18,
+ 0x00071981, 0x7999a83a, 0x00000000, 0x0000019c, 0x001c0000,
+ 0x00000000, 0x0000019c, 0x000001b5, 0x00000000, 0x0000019c,
+ 0x001c0000, 0x00000000, 0x0000019c, 0x000001b5, 0x00000000
+};
+
+static const uint32_t ar9380_2_2_vals_5g40[] = {
+ 0x00000023, 0x00000460, 0x000002d0, 0x00001cc0, 0x07d007d0,
+ 0x128d804f, 0x08f04800, 0x00003210, 0x00007d00, 0x0dd08f29,
+ 0xa4653c00, 0x03284f3e, 0x00000000, 0x10804008, 0x00000000,
+ 0x10804008, 0x00000000, 0x10804008, 0xd00a8005, 0x206a022e,
+ 0x5ac640d0, 0x06903081, 0x05eea6d4, 0x0000059c, 0x000000c4,
+ 0x0372111a, 0x001c2020, 0x6d4000e2, 0x7ec88d2e, 0x37b9605e,
+ 0x00000000, 0x0001cf9c, 0x000003b5, 0x0000001c, 0xcf946220,
+ 0x02321e27, 0x5030201a, 0x0003f000, 0x000037c4, 0x00000104,
+ 0x01026a2f, 0x00000014, 0x10000fff, 0xffb81018, 0x00000000,
+ 0x00000fa0, 0x02020002, 0x01000e0e, 0x0a021501, 0x00000e0e,
+ 0x00000007, 0x00000000, 0x00000110, 0x00022222, 0x00158d18,
+ 0x00071981, 0x7999a83a, 0x00000000, 0x0000019c, 0x001c0000,
+ 0x00000000, 0x0000019c, 0x000001b5, 0x00000000, 0x0000019c,
+ 0x001c0000, 0x00000000, 0x0000019c, 0x000001b5, 0x00000000
+};
+
+static const uint32_t ar9380_2_2_vals_2g40[] = {
+ 0x00000023, 0x000002c0, 0x00000318, 0x00007c70, 0x10801600,
+ 0x12e00057, 0x08f04810, 0x0000320a, 0x00006880, 0x0b283f31,
+ 0x24652800, 0x05d08f20, 0x00000000, 0x50804008, 0x00000000,
+ 0x50804008, 0x00000000, 0x50804008, 0xd00a8011, 0x206a012e,
+ 0x5ac640d0, 0x06903881, 0x05eea6d4, 0x0000119c, 0x000000c4,
+ 0x037216a0, 0x001c2020, 0x6d4000e2, 0x7ec84d2e, 0x3379605e,
+ 0x00000000, 0x00021f9c, 0x000003ce, 0x00000021, 0xcf946222,
+ 0x02291e27, 0x50302012, 0x0001a000, 0x000037c4, 0x00000004,
+ 0x01026a2f, 0x00000016, 0x10000fff, 0xffb81018, 0x00000210,
+ 0x00001130, 0x02020002, 0x01000e0e, 0x3a021501, 0x00000e0e,
+ 0x0000000b, 0x00000150, 0x00000110, 0x00022222, 0x00158d18,
+ 0x00071981, 0x7999a83a, 0x00000000, 0x0000019c, 0x001c0000,
+ 0x00000000, 0x0000019c, 0x000001ce, 0x00000150, 0x0000019c,
+ 0x001c0000, 0x00000000, 0x0000019c, 0x000001ce, 0x00000150
+};
+
+static const uint32_t ar9380_2_2_vals_2g20[] = {
+ 0x00000023, 0x00000160, 0x0000018c, 0x00003e38, 0x08400b00,
+ 0x12e0002b, 0x08f04810, 0x0000320a, 0x00003440, 0x0b283f31,
+ 0x24652800, 0x05d08f20, 0x00000000, 0x50804008, 0x00000000,
+ 0x50804008, 0x00000000, 0x50804008, 0xd00a8011, 0x206a012e,
+ 0x5ac640d0, 0x06903881, 0x05eea6d4, 0x0000119c, 0x000000c4,
+ 0x037216a0, 0x001c2020, 0x6c4000e2, 0x7ec84d2e, 0x33795d5e,
+ 0x00000000, 0x00021f9c, 0x000003ce, 0x00000021, 0xcf946222,
+ 0x02291e27, 0x50302012, 0x0001a000, 0x000037c0, 0x00000004,
+ 0x01026a2f, 0x0000000b, 0x00000fff, 0xffb81018, 0x00000108,
+ 0x00000898, 0x02020002, 0x01000e0e, 0x3a021501, 0x00000e0e,
+ 0x0000000b, 0x00000150, 0x00000110, 0x00022222, 0x00158d18,
+ 0x00071982, 0x7999a83a, 0x00000000, 0x0000019c, 0x001c0000,
+ 0x00000000, 0x0000019c, 0x000001ce, 0x00000150, 0x0000019c,
+ 0x001c0000, 0x00000000, 0x0000019c, 0x000001ce, 0x00000150
+};
+
+static const uint16_t ar9380_2_2_cm_regs[] = {
+ P(0x040a4), P(0x07008), P(0x07020), P(0x07034), P(0x07038),
+ P(0x07048), P(0x00008), P(0x00030), P(0x00034), P(0x00040),
+ P(0x00044), P(0x00048), P(0x0004c), P(0x00050), P(0x01040),
+ P(0x01044), P(0x01048), P(0x0104c), P(0x01050), P(0x01054),
+ P(0x01058), P(0x0105c), P(0x01060), P(0x01064), P(0x010f0),
+ P(0x01270), P(0x012b0), P(0x012f0), P(0x0143c), P(0x0147c),
+ P(0x08000), P(0x08004), P(0x08008), P(0x0800c), P(0x08018),
+ P(0x08020), P(0x08038), P(0x0803c), P(0x08040), P(0x08044),
+ P(0x08048), P(0x0804c), P(0x08054), P(0x08058), P(0x0805c),
+ P(0x08060), P(0x08064), P(0x08070), P(0x08074), P(0x08078),
+ P(0x0809c), P(0x080a0), P(0x080a4), P(0x080a8), P(0x080ac),
+ P(0x080b0), P(0x080b4), P(0x080b8), P(0x080bc), P(0x080c0),
+ P(0x080c4), P(0x080c8), P(0x080cc), P(0x080d0), P(0x080d4),
+ P(0x080d8), P(0x080dc), P(0x080e0), P(0x080e4), P(0x080e8),
+ P(0x080ec), P(0x080f0), P(0x080f4), P(0x080fc), P(0x08100),
+ P(0x08108), P(0x0810c), P(0x08110), P(0x08114), P(0x08118),
+ P(0x0811c), P(0x08124), P(0x08128), P(0x0812c), P(0x08130),
+ P(0x08134), P(0x08138), P(0x0813c), P(0x08144), P(0x08168),
+ P(0x0816c), P(0x081c0), P(0x081c4), P(0x081c8), P(0x081cc),
+ P(0x081ec), P(0x081f0), P(0x081f4), P(0x081f8), P(0x081fc),
+ P(0x08240), P(0x08244), P(0x08248), P(0x0824c), P(0x08250),
+ P(0x08254), P(0x08258), P(0x0825c), P(0x08260), P(0x08264),
+ P(0x08268), P(0x0826c), P(0x08270), P(0x08274), P(0x08278),
+ P(0x0827c), P(0x08284), P(0x08288), P(0x0828c), P(0x08294),
+ P(0x08298), P(0x0829c), P(0x08300), P(0x08314), P(0x0831c),
+ P(0x08328), P(0x0832c), P(0x08330), P(0x08334), P(0x08338),
+ P(0x0833c), P(0x08340), P(0x08344), P(0x08348), P(0x0835c),
+ P(0x08360), P(0x08364), P(0x08368), P(0x08370), P(0x08374),
+ P(0x08378), P(0x0837c), P(0x08380), P(0x08384), P(0x08390),
+ P(0x08394), P(0x08398), P(0x0839c), P(0x083a0), P(0x083a4),
+ P(0x083a8), P(0x083ac), P(0x083b0), P(0x083b4), P(0x083b8),
+ P(0x083bc), P(0x083c0), P(0x083c4), P(0x083c8), P(0x083cc),
+ P(0x083d0), P(0x09800), P(0x09804), P(0x09808), P(0x0980c),
+ P(0x09814), P(0x09818), P(0x0981c), P(0x09834), P(0x09838),
+ P(0x0983c), P(0x09880), P(0x09884), P(0x098a4), P(0x098b0),
+ P(0x098d0), P(0x098d4), P(0x098dc), P(0x098f0), P(0x098f4),
+ P(0x09c04), P(0x09c08), P(0x09c0c), P(0x09c10), P(0x09c14),
+ P(0x09c18), P(0x09c1c), P(0x09d00), P(0x09d04), P(0x09d08),
+ P(0x09d0c), P(0x09d10), P(0x09d14), P(0x09d18), P(0x09e08),
+ P(0x09e24), P(0x09e28), P(0x09e30), P(0x09e34), P(0x09e38),
+ P(0x09e40), P(0x09e4c), P(0x09e50), P(0x09e54), P(0x09fc0),
+ P(0x09fc4), P(0x09fcc), P(0x09fd0), P(0x0a20c), P(0x0a220),
+ P(0x0a224), P(0x0a228), P(0x0a23c), P(0x0a244), P(0x0a2a0),
+ P(0x0a2c0), P(0x0a2c8), P(0x0a2cc), P(0x0a2d4), P(0x0a2ec),
+ P(0x0a2f0), P(0x0a2f4), P(0x0a2f8), P(0x0a344), P(0x0a34c),
+ P(0x0a350), P(0x0a364), P(0x0a370), P(0x0a390), P(0x0a394),
+ P(0x0a398), P(0x0a39c), P(0x0a3a0), P(0x0a3a4), P(0x0a3a8),
+ P(0x0a3ac), P(0x0a3c0), P(0x0a3c4), P(0x0a3c8), P(0x0a3cc),
+ P(0x0a3d0), P(0x0a3d4), P(0x0a3d8), P(0x0a3dc), P(0x0a3e0),
+ P(0x0a3e4), P(0x0a3e8), P(0x0a3ec), P(0x0a3f0), P(0x0a3f4),
+ P(0x0a3f8), P(0x0a3fc), P(0x0a400), P(0x0a404), P(0x0a408),
+ P(0x0a40c), P(0x0a414), P(0x0a418), P(0x0a41c), P(0x0a420),
+ P(0x0a424), P(0x0a428), P(0x0a42c), P(0x0a430), P(0x0a434),
+ P(0x0a438), P(0x0a43c), P(0x0a440), P(0x0a444), P(0x0a448),
+ P(0x0a44c), P(0x0a450), P(0x0a458), P(0x0a640), P(0x0a644),
+ P(0x0a648), P(0x0a64c), P(0x0a670), P(0x0a674), P(0x0a678),
+ P(0x0a67c), P(0x0a680), P(0x0a684), P(0x0a688), P(0x0a690),
+ P(0x0a7c0), P(0x0a7c4), P(0x0a7c8), P(0x0a7cc), P(0x0a7d0),
+ P(0x0a7d4), P(0x0a7dc), P(0x0a8d0), P(0x0a8d4), P(0x0a8dc),
+ P(0x0a8f0), P(0x0a8f4), P(0x0b2d0), P(0x0b2d4), P(0x0b2ec),
+ P(0x0b2f0), P(0x0b2f4), P(0x0b2f8), P(0x0b408), P(0x0b40c),
+ P(0x0b420), P(0x0b8d0), P(0x0b8d4), P(0x0b8dc), P(0x0b8f0),
+ P(0x0b8f4), P(0x0c2d0), P(0x0c2d4), P(0x0c2ec), P(0x0c2f0),
+ P(0x0c2f4), P(0x0c2f8), P(0x0c408), P(0x0c40c), P(0x0c420),
+ P(0x16000), P(0x16004), P(0x16008), P(0x1600c), P(0x16040),
+ P(0x1604c), P(0x16050), P(0x16054), P(0x16058), P(0x1605c),
+ P(0x16060), P(0x16064), P(0x1606c), P(0x16080), P(0x16084),
+ P(0x16088), P(0x1608c), P(0x16090), P(0x16098), P(0x160a0),
+ P(0x160a4), P(0x160a8), P(0x160b4), P(0x160c0), P(0x160c4),
+ P(0x160c8), P(0x160cc), P(0x16100), P(0x16104), P(0x16108),
+ P(0x16144), P(0x16148), P(0x16280), P(0x16284), P(0x16288),
+ P(0x1628c), P(0x16290), P(0x16294), P(0x16380), P(0x16384),
+ P(0x16388), P(0x1638c), P(0x16390), P(0x16394), P(0x16398),
+ P(0x1639c), P(0x163a0), P(0x163a4), P(0x163a8), P(0x163ac),
+ P(0x163b0), P(0x163b4), P(0x163b8), P(0x163bc), P(0x163c0),
+ P(0x163c4), P(0x163c8), P(0x163cc), P(0x163d0), P(0x163d4),
+ P(0x16400), P(0x16404), P(0x16408), P(0x1640c), P(0x16440),
+ P(0x1644c), P(0x16450), P(0x16454), P(0x16458), P(0x1645c),
+ P(0x16460), P(0x16464), P(0x1646c), P(0x16500), P(0x16504),
+ P(0x16508), P(0x16544), P(0x16548), P(0x16780), P(0x16784),
+ P(0x16788), P(0x1678c), P(0x16790), P(0x16794), P(0x16798),
+ P(0x1679c), P(0x167a0), P(0x167a4), P(0x167a8), P(0x167ac),
+ P(0x167b0), P(0x167b4), P(0x167b8), P(0x167bc), P(0x167c0),
+ P(0x167c4), P(0x167c8), P(0x167cc), P(0x167d0), P(0x167d4),
+ P(0x16800), P(0x16804), P(0x16808), P(0x1680c), P(0x16840),
+ P(0x1684c), P(0x16850), P(0x16854), P(0x16858), P(0x1685c),
+ P(0x16860), P(0x16864), P(0x1686c), P(0x16900), P(0x16904),
+ P(0x16908), P(0x16944), P(0x16948), P(0x16b80), P(0x16b84),
+ P(0x16b88), P(0x16b8c), P(0x16b90), P(0x16b94), P(0x16b98),
+ P(0x16b9c), P(0x16ba0), P(0x16ba4), P(0x16ba8), P(0x16bac),
+ P(0x16bb0), P(0x16bb4), P(0x16bb8), P(0x16bbc), P(0x16bc0),
+ P(0x16bc4), P(0x16bc8), P(0x16bcc), P(0x16bd0), P(0x16bd4)
+};
+
+static const uint32_t ar9380_2_2_cm_vals[] = {
+ 0x00a0c1c9, 0x00000000, 0x00000000, 0x00000002, 0x000004c2,
+ 0x00000008, 0x00000000, 0x00020085, 0x00000005, 0x00000000,
+ 0x00000000, 0x00000008, 0x00000010, 0x00000000, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x00000100,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x000fc78f,
+ 0x0000000f, 0x00000000, 0x00000310, 0x00000020, 0x00000000,
+ 0x0000000f, 0x00000000, 0x02ff0000, 0x0e070605, 0x0000000d,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2a800000,
+ 0x06900168, 0x13881c20, 0x01f40000, 0x00252500, 0x00a00000,
+ 0x00400000, 0x00000000, 0xffffffff, 0x0000ffff, 0x3f3f3f3f,
+ 0x00000000, 0x00000000, 0x00000000, 0x00020000, 0x00000000,
+ 0x00000052, 0x00000000, 0x00000000, 0x000007ff, 0x000000aa,
+ 0x00003210, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000ffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0x00000000, 0x33332210, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00100000, 0x0010f424, 0x00000800, 0x0001e848, 0x00000000,
+ 0x00000000, 0x00000000, 0x40000000, 0x00080922, 0x9bc00010,
+ 0xffffffff, 0x0000ffff, 0x00000000, 0x40000000, 0x003e4180,
+ 0x00000004, 0x0000002c, 0x0000002c, 0x000000ff, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000140, 0x00000000, 0x0000010d,
+ 0x00000000, 0x00000007, 0x00000302, 0x00000700, 0x00ff0000,
+ 0x02400000, 0x000107ff, 0xaa48105b, 0x008f0000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x000000ff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x0000fa14,
+ 0x000f0c00, 0x33332210, 0x33332210, 0x33332210, 0x33332210,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000200,
+ 0x000301ff, 0xafe68e30, 0xfd14e000, 0x9c0a9f6b, 0x04900000,
+ 0x9280c00a, 0x00000000, 0x00020028, 0x6400a290, 0x0108ecff,
+ 0x0d000600, 0x201fff00, 0x00001042, 0x00200400, 0x32840bbe,
+ 0x004b6a8e, 0x00000820, 0x00000000, 0x00000000, 0x00000000,
+ 0xff55ff55, 0x0320ff55, 0x00000000, 0x00000000, 0x00046384,
+ 0x05b6b440, 0x00b6b440, 0xc080a333, 0x40206c10, 0x009c4060,
+ 0x9883800a, 0x01834061, 0x00c0040b, 0x00000000, 0x0038230c,
+ 0x990bb515, 0x0c6f0000, 0x06336f77, 0x6af6532f, 0x0cc80c00,
+ 0x0d261820, 0x00001004, 0x00ff03f1, 0x00000000, 0x803e4788,
+ 0x0001efb5, 0x40000014, 0x01193b93, 0x00000000, 0x00000000,
+ 0x00000000, 0x10002310, 0x00000000, 0x0c000000, 0x00000001,
+ 0x00000001, 0x00000000, 0x18c43433, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0000a000, 0x00000000, 0x00000000, 0x00000001, 0x00000444,
+ 0x001f0e0f, 0x0075393f, 0xb79f6427, 0x00000000, 0xaaaaaaaa,
+ 0x3c466478, 0x20202020, 0x22222220, 0x20200020, 0x20202020,
+ 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
+ 0x20202020, 0x20202020, 0x20202020, 0x00000000, 0x00000246,
+ 0x0cdbd380, 0x000f0f01, 0x8fa91f01, 0x00000000, 0x0e79e5c6,
+ 0x00820820, 0x1ce739ce, 0x2d001dce, 0x1ce739ce, 0x000001ce,
+ 0x1ce739ce, 0x000001ce, 0x1ce739ce, 0x1ce739ce, 0x00000000,
+ 0x00001801, 0x00100000, 0x00000000, 0x00000000, 0x06000080,
+ 0x00000001, 0x00010000, 0x00000000, 0x00000000, 0x3fad9d74,
+ 0x0048060a, 0x00003c37, 0x03020100, 0x09080504, 0x0d0c0b0a,
+ 0x13121110, 0x31301514, 0x35343332, 0x00000036, 0x00000838,
+ 0x00000000, 0xfffffffc, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000001, 0x004b6a8e, 0x00000820, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000080, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x0e79e5c0, 0x00820820,
+ 0x00000000, 0x004b6a8e, 0x00000820, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000080, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0e79e5c0, 0x00820820, 0x00000000,
+ 0x36db6db6, 0x6db6db40, 0x73f00000, 0x00000000, 0x7f80fff8,
+ 0x76d005b5, 0x556cf031, 0x13449440, 0x0c51c92c, 0x3db7fffc,
+ 0xfffffffc, 0x000f0278, 0x6db60000, 0x00000000, 0x0e48048c,
+ 0x54214514, 0x119f481e, 0x24926490, 0xd2888888, 0x0a108ffe,
+ 0x812fc370, 0x423c8000, 0x92480080, 0x00adb6d0, 0x6db6db60,
+ 0x6db6db6c, 0x01e6c000, 0x3fffbe01, 0xfff80000, 0x00080010,
+ 0x02084080, 0x00000000, 0x058a0001, 0x3d840208, 0x05a20408,
+ 0x00038c07, 0x00000004, 0x458aa14f, 0x00000000, 0x00000000,
+ 0x00800700, 0x00800700, 0x00800700, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000a0,
+ 0x000c0000, 0x14021402, 0x00001402, 0x00000000, 0x00000000,
+ 0x36db6db6, 0x6db6db40, 0x73f00000, 0x00000000, 0x7f80fff8,
+ 0x76d005b5, 0x556cf031, 0x13449440, 0x0c51c92c, 0x3db7fffc,
+ 0xfffffffc, 0x000f0278, 0x6db60000, 0x3fffbe01, 0xfff80000,
+ 0x00080010, 0x02084080, 0x00000000, 0x00000000, 0x00000000,
+ 0x00800700, 0x00800700, 0x00800700, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000a0,
+ 0x000c0000, 0x14021402, 0x00001402, 0x00000000, 0x00000000,
+ 0x36db6db6, 0x6db6db40, 0x73f00000, 0x00000000, 0x7f80fff8,
+ 0x76d005b5, 0x556cf031, 0x13449440, 0x0c51c92c, 0x3db7fffc,
+ 0xfffffffc, 0x000f0278, 0x6db60000, 0x3fffbe01, 0xfff80000,
+ 0x00080010, 0x02084080, 0x00000000, 0x00000000, 0x00000000,
+ 0x00800700, 0x00800700, 0x00800700, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000a0,
+ 0x000c0000, 0x14021402, 0x00001402, 0x00000000, 0x00000000
+};
+
+static const uint16_t ar9380_2_2_fast_clock_regs[] = {
+ P(0x01030), P(0x01070), P(0x010b0), P(0x08014), P(0x0801c),
+ P(0x08318), P(0x09e00), P(0x0a230), P(0x0a254)
+};
+
+static const uint32_t ar9380_2_2_fast_clock_vals_5g20[] = {
+ 0x00000268, 0x0000018c, 0x00000fd0, 0x044c044c, 0x148ec02b,
+ 0x000044c0, 0x0372131c, 0x0000000b, 0x00000898
+};
+
+static const uint32_t ar9380_2_2_fast_clock_vals_5g40[] = {
+ 0x000004d0, 0x00000318, 0x00001fa0, 0x08980898, 0x148ec057,
+ 0x00008980, 0x0372131c, 0x00000016, 0x00001130
+};
+
+static const struct athn_ini ar9380_2_2_ini = {
+ nitems(ar9380_2_2_regs),
+ ar9380_2_2_regs,
+ ar9380_2_2_vals_5g20,
+ ar9380_2_2_vals_5g40,
+ ar9380_2_2_vals_2g40,
+ ar9380_2_2_vals_2g20,
+ nitems(ar9380_2_2_cm_regs),
+ ar9380_2_2_cm_regs,
+ ar9380_2_2_cm_vals,
+ nitems(ar9380_2_2_fast_clock_regs),
+ ar9380_2_2_fast_clock_regs,
+ ar9380_2_2_fast_clock_vals_5g20,
+ ar9380_2_2_fast_clock_vals_5g40
+};
+
+/*
+ * AR9485 1.1 programming.
+ */
+
+static const uint16_t ar9485_1_1_regs[] = {
+ P(0x01030), P(0x01070), P(0x010b0), P(0x08014), P(0x0801c),
+ P(0x08120), P(0x081d0), P(0x08318), P(0x09810), P(0x09820),
+ P(0x09824), P(0x09828), P(0x0982c), P(0x09830), P(0x09c00),
+ P(0x09e00), P(0x09e04), P(0x09e0c), P(0x09e10), P(0x09e14),
+ P(0x09e18), P(0x09e1c), P(0x09e20), P(0x09e2c), P(0x09e3c),
+ P(0x09e44), P(0x09e48), P(0x09fc8), P(0x0a204), P(0x0a208),
+ P(0x0a230), P(0x0a234), P(0x0a238), P(0x0a250), P(0x0a254),
+ P(0x0a258), P(0x0a25c), P(0x0a260), P(0x0a264), P(0x0a280),
+ P(0x0a284), P(0x0a288), P(0x0a28c), P(0x0a2c4), P(0x0a2d0),
+ P(0x0a2d8), P(0x0a358), P(0x0be04), P(0x0be18), P(0x1609c),
+ P(0x160ac), P(0x160b0), P(0x1610c), P(0x16140)
+};
+
+static const uint32_t ar9485_1_1_vals_2g40[] = {
+ 0x000002c0, 0x00000318, 0x00007c70, 0x10801600, 0x12e00057,
+ 0x08f04810, 0x0000320a, 0x00006880, 0xd00a8005, 0x206a002e,
+ 0x5ac640d0, 0x06903881, 0x05eea6d4, 0x0000059c, 0x00000044,
+ 0x037216a0, 0x00182020, 0x6d4000e2, 0x7ec80d2e, 0x3139605e,
+ 0x00000000, 0x00021f9c, 0x000003ce, 0x00000021, 0xcf946222,
+ 0x02282324, 0x50302010, 0x0001a000, 0x01303fc4, 0x00000004,
+ 0x00004016, 0x10000fff, 0xffb81018, 0x00000210, 0x00001130,
+ 0x02020002, 0x01000e0e, 0x3a021501, 0x00000e0e, 0x0000000b,
+ 0x000002a0, 0x00000000, 0x00000000, 0x00158d18, 0x00071982,
+ 0xf999a83a, 0x00000000, 0x00802020, 0x00000000, 0x0b283f31,
+ 0x24611800, 0x03284f3e, 0x00170000, 0x50804008
+};
+
+static const uint32_t ar9485_1_1_vals_2g20[] = {
+ 0x00000160, 0x0000018c, 0x00003e38, 0x08400b00, 0x12e0002b,
+ 0x08f04810, 0x0000320a, 0x00003440, 0xd00a8005, 0x206a002e,
+ 0x5ac640d0, 0x06903881, 0x05eea6d4, 0x0000059c, 0x00000044,
+ 0x037216a0, 0x00182020, 0x6c4000e2, 0x7ec80d2e, 0x31395d5e,
+ 0x00000000, 0x00021f9c, 0x000003ce, 0x00000021, 0xcf946222,
+ 0x02282324, 0x50302010, 0x0001a000, 0x01303fc0, 0x00000004,
+ 0x0000400b, 0x10000fff, 0xffb81018, 0x00000108, 0x00000898,
+ 0x02020002, 0x01000e0e, 0x3a021501, 0x00000e0e, 0x0000000b,
+ 0x000002a0, 0x00000000, 0x00000000, 0x00158d18, 0x00071982,
+ 0xf999a83a, 0x00000000, 0x00802020, 0x00000000, 0x0b283f31,
+ 0x24611800, 0x03284f3e, 0x00170000, 0x50804008
+};
+
+static const uint16_t ar9485_1_1_cm_regs[] = {
+ P(0x04014), P(0x04090), P(0x040a4), P(0x07010), P(0x07020),
+ P(0x07034), P(0x07038), P(0x07048), P(0x0a580), P(0x0a584),
+ P(0x0a588), P(0x0a58c), P(0x0a590), P(0x0a594), P(0x0a598),
+ P(0x0a59c), P(0x0a5a0), P(0x0a5a4), P(0x0a5a8), P(0x0a5ac),
+ P(0x0a5b0), P(0x0a5b4), P(0x0a5b8), P(0x0a5bc), P(0x00008),
+ P(0x00030), P(0x00034), P(0x00040), P(0x00044), P(0x00048),
+ P(0x0004c), P(0x00050), P(0x01040), P(0x01044), P(0x01048),
+ P(0x0104c), P(0x01050), P(0x01054), P(0x01058), P(0x0105c),
+ P(0x01060), P(0x01064), P(0x010f0), P(0x01270), P(0x012b0),
+ P(0x012f0), P(0x0143c), P(0x0147c), P(0x08000), P(0x08004),
+ P(0x08008), P(0x0800c), P(0x08018), P(0x08020), P(0x08038),
+ P(0x0803c), P(0x08040), P(0x08044), P(0x08048), P(0x0804c),
+ P(0x08054), P(0x08058), P(0x0805c), P(0x08060), P(0x08064),
+ P(0x08070), P(0x08074), P(0x08078), P(0x0809c), P(0x080a0),
+ P(0x080a4), P(0x080a8), P(0x080ac), P(0x080b0), P(0x080b4),
+ P(0x080b8), P(0x080bc), P(0x080c0), P(0x080c4), P(0x080c8),
+ P(0x080cc), P(0x080d0), P(0x080d4), P(0x080d8), P(0x080dc),
+ P(0x080e0), P(0x080e4), P(0x080e8), P(0x080ec), P(0x080f0),
+ P(0x080f4), P(0x080fc), P(0x08100), P(0x08108), P(0x0810c),
+ P(0x08110), P(0x08114), P(0x08118), P(0x0811c), P(0x08124),
+ P(0x08128), P(0x0812c), P(0x08130), P(0x08134), P(0x08138),
+ P(0x0813c), P(0x08144), P(0x08168), P(0x0816c), P(0x08170),
+ P(0x08174), P(0x08178), P(0x0817c), P(0x081c0), P(0x081c4),
+ P(0x081d4), P(0x081ec), P(0x081f0), P(0x081f4), P(0x081f8),
+ P(0x081fc), P(0x08240), P(0x08244), P(0x08248), P(0x0824c),
+ P(0x08250), P(0x08254), P(0x08258), P(0x0825c), P(0x08260),
+ P(0x08264), P(0x08268), P(0x0826c), P(0x08270), P(0x08274),
+ P(0x08278), P(0x0827c), P(0x08284), P(0x08288), P(0x0828c),
+ P(0x08294), P(0x08298), P(0x0829c), P(0x08300), P(0x08314),
+ P(0x0831c), P(0x08328), P(0x0832c), P(0x08330), P(0x08334),
+ P(0x08338), P(0x0833c), P(0x08340), P(0x08344), P(0x08348),
+ P(0x0835c), P(0x08360), P(0x08364), P(0x08368), P(0x08370),
+ P(0x08374), P(0x08378), P(0x0837c), P(0x08380), P(0x08384),
+ P(0x08390), P(0x08394), P(0x08398), P(0x0839c), P(0x083a0),
+ P(0x083a4), P(0x083a8), P(0x083ac), P(0x083b0), P(0x083b4),
+ P(0x083b8), P(0x083bc), P(0x083c0), P(0x083c4), P(0x083c8),
+ P(0x083cc), P(0x083d0), P(0x09800), P(0x09804), P(0x09808),
+ P(0x0980c), P(0x09814), P(0x09818), P(0x0981c), P(0x09834),
+ P(0x09838), P(0x0983c), P(0x09880), P(0x09884), P(0x098a4),
+ P(0x098b0), P(0x098d0), P(0x098d4), P(0x098dc), P(0x098f0),
+ P(0x098f4), P(0x09c04), P(0x09c08), P(0x09c0c), P(0x09c10),
+ P(0x09c14), P(0x09c18), P(0x09c1c), P(0x09d00), P(0x09d04),
+ P(0x09d08), P(0x09d0c), P(0x09d10), P(0x09d14), P(0x09d18),
+ P(0x09d1c), P(0x09e08), P(0x09e24), P(0x09e28), P(0x09e30),
+ P(0x09e34), P(0x09e38), P(0x09e40), P(0x09e4c), P(0x09e50),
+ P(0x09fc0), P(0x09fc4), P(0x09fcc), P(0x0a20c), P(0x0a210),
+ P(0x0a220), P(0x0a224), P(0x0a228), P(0x0a23c), P(0x0a244),
+ P(0x0a2a0), P(0x0a2c0), P(0x0a2c8), P(0x0a2cc), P(0x0a2d4),
+ P(0x0a2dc), P(0x0a2e0), P(0x0a2e4), P(0x0a2e8), P(0x0a2ec),
+ P(0x0a2f0), P(0x0a2f4), P(0x0a2f8), P(0x0a344), P(0x0a34c),
+ P(0x0a350), P(0x0a364), P(0x0a370), P(0x0a390), P(0x0a394),
+ P(0x0a398), P(0x0a39c), P(0x0a3a0), P(0x0a3a4), P(0x0a3a8),
+ P(0x0a3ac), P(0x0a3c0), P(0x0a3c4), P(0x0a3c8), P(0x0a3cc),
+ P(0x0a3d0), P(0x0a3d4), P(0x0a3d8), P(0x0a3dc), P(0x0a3e0),
+ P(0x0a3e4), P(0x0a3e8), P(0x0a3ec), P(0x0a3f0), P(0x0a3f4),
+ P(0x0a3f8), P(0x0a3fc), P(0x0a400), P(0x0a404), P(0x0a408),
+ P(0x0a40c), P(0x0a414), P(0x0a418), P(0x0a41c), P(0x0a420),
+ P(0x0a424), P(0x0a428), P(0x0a42c), P(0x0a430), P(0x0a434),
+ P(0x0a438), P(0x0a43c), P(0x0a440), P(0x0a444), P(0x0a448),
+ P(0x0a44c), P(0x0a450), P(0x0a5c4), P(0x0a5c8), P(0x0a5cc),
+ P(0x0a760), P(0x0a764), P(0x0a768), P(0x0a76c), P(0x0a770),
+ P(0x0a774), P(0x0a778), P(0x0a780), P(0x0a7c0), P(0x0a7c4),
+ P(0x0a7c8), P(0x0a7cc), P(0x0a7d0), P(0x0a7d4), P(0x0a7dc),
+ P(0x16000), P(0x16004), P(0x16008), P(0x1600c), P(0x16040),
+ P(0x1604c), P(0x16050), P(0x16054), P(0x16080), P(0x16084),
+ P(0x16088), P(0x1608c), P(0x16090), P(0x16098), P(0x160a0),
+ P(0x160a4), P(0x160a8), P(0x160b4), P(0x160c0), P(0x160c4),
+ P(0x160c8), P(0x160cc), P(0x160d0), P(0x16100), P(0x16104),
+ P(0x16108), P(0x16144), P(0x16148), P(0x16240), P(0x16244),
+ P(0x16248), P(0x1624c), P(0x16280), P(0x16284), P(0x16288),
+ P(0x1628c), P(0x16290), P(0x16380), P(0x16384), P(0x16388),
+ P(0x1638c), P(0x16390), P(0x16394), P(0x16398), P(0x1639c),
+ P(0x163a0), P(0x163a4), P(0x163a8), P(0x163ac), P(0x163b0),
+ P(0x163b4), P(0x163b8), P(0x163bc), P(0x163c0), P(0x163c4),
+ P(0x163c8), P(0x163cc), P(0x163d0), P(0x163d4), P(0x16c40),
+ P(0x16c44)
+};
+
+static const uint32_t ar9485_1_1_cm_vals[] = {
+ 0xba280400, 0x00aa10aa, 0x00a0c9c9, 0x00000022, 0x00000000,
+ 0x00000002, 0x000004c2, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00020085, 0x00000005, 0x00000000, 0x00000000, 0x00000008,
+ 0x00000010, 0x00000000, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f, 0x002ffc0f,
+ 0x002ffc0f, 0x002ffc0f, 0x00000100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x000fc78f, 0x0000000f, 0x00000000,
+ 0x00000310, 0x00000020, 0x00000000, 0x0000000f, 0x00000000,
+ 0x02ff0000, 0x0e070605, 0x0000000d, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x2a800000, 0x06900168, 0x13881c22,
+ 0x01f40000, 0x00252500, 0x00a00000, 0x00400000, 0x00000000,
+ 0xffffffff, 0x0000ffff, 0x3f3f3f3f, 0x00000000, 0x00000000,
+ 0x00000000, 0x00020000, 0x00000000, 0x00000052, 0x00000000,
+ 0x00000000, 0x000007ff, 0x000000aa, 0x00003210, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0000ffff, 0xffffffff, 0x00000000, 0x00000000, 0x18486200,
+ 0x33332210, 0x00000000, 0x00020000, 0x00000000, 0x33332210,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00100000, 0x0010f400, 0x00000800, 0x0001e800,
+ 0x00000000, 0x00000000, 0x00000000, 0x40000000, 0x00080922,
+ 0x9ca00010, 0xffffffff, 0x0000ffff, 0x00000000, 0x40000000,
+ 0x003e4180, 0x00000004, 0x0000002c, 0x0000002c, 0x000000ff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000140, 0x00000000,
+ 0x0000010d, 0x00000000, 0x00000007, 0x00000302, 0x00000700,
+ 0x00ff0000, 0x02400000, 0x000107ff, 0xa248105b, 0x008f0000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x000000ff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
+ 0x0000fa14, 0x000f0c00, 0x33332210, 0x33332210, 0x33332210,
+ 0x33332210, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000200, 0x000301ff, 0xafe68e30, 0xfd14e000, 0x9c0a8f6b,
+ 0x04800000, 0x9280c00a, 0x00000000, 0x00020028, 0x5f3ca3de,
+ 0x0108ecff, 0x14750600, 0x201fff00, 0x00001042, 0x00200400,
+ 0x52440bbe, 0x004b6a8e, 0x00000820, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x03200000, 0x00000000, 0x00000000,
+ 0x00046384, 0x05b6b440, 0x00b6b440, 0xc080a333, 0x40206c10,
+ 0x009c4060, 0x1883800a, 0x01834061, 0x00c00400, 0x00000000,
+ 0x00000000, 0x0038233c, 0x9927b515, 0x12ef0200, 0x06336f77,
+ 0x6af6532f, 0x0cc80c00, 0x0d261820, 0x00001004, 0x00ff03f1,
+ 0x80be4788, 0x0001efb5, 0x40000014, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x10002310, 0x00000000, 0x0c000000,
+ 0x00000001, 0x00000001, 0x00000000, 0x18c43433, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0000a000, 0x00000000, 0x00000000, 0x00000001, 0x00000444,
+ 0x001f0e0f, 0x0075393f, 0xb79f6427, 0x000000ff, 0x3b3b3b3b,
+ 0x2f2f2f2f, 0x20202020, 0x22222220, 0x20200020, 0x20202020,
+ 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020,
+ 0x20202020, 0x20202020, 0x20202020, 0x00000000, 0x00000006,
+ 0x0cdbd380, 0x000f0f01, 0x8fa91f01, 0x00000000, 0x0e79e5c6,
+ 0x00820820, 0x1ce739cf, 0x2d0019ce, 0x1ce739ce, 0x000001ce,
+ 0x1ce739ce, 0x000001ce, 0x1ce739ce, 0x1ce739ce, 0x00000000,
+ 0x00001801, 0x00000000, 0x00000000, 0x00000000, 0x04000000,
+ 0x00000001, 0x00010000, 0xbfad9d74, 0x0048060a, 0x00000637,
+ 0x03020100, 0x09080504, 0x0d0c0b0a, 0x13121110, 0x31301514,
+ 0x35343332, 0x00000036, 0x00000838, 0x00000000, 0xfffffffc,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000,
+ 0x36db6db6, 0x6db6db40, 0x73800000, 0x00000000, 0x7f80fff8,
+ 0x000f0278, 0x4db6db8c, 0x6db60000, 0x00080000, 0x0e48048c,
+ 0x14214514, 0x119f081e, 0x24926490, 0xd28b3330, 0xc2108ffe,
+ 0x812fc370, 0x423c8000, 0x92480040, 0x006db6db, 0x0186db60,
+ 0x6db6db6c, 0x6de6fbe0, 0xf7dfcf3c, 0x04cb0001, 0xfff80015,
+ 0x00080010, 0x01884080, 0x00008040, 0x08400000, 0x1bf90f00,
+ 0x00000000, 0x00000000, 0x01000015, 0x00d30000, 0x00318000,
+ 0x50000000, 0x4b96210f, 0x00000000, 0x00000000, 0x00800700,
+ 0x00800700, 0x00800700, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x000000a0, 0x000c0000,
+ 0x14021402, 0x00001402, 0x00000000, 0x00000000, 0x13188278,
+ 0x12000000
+};
+
+static const struct athn_ini ar9485_1_1_ini = {
+ nitems(ar9485_1_1_regs),
+ ar9485_1_1_regs,
+ NULL, /* 2GHz only. */
+ NULL, /* 2GHz only. */
+ ar9485_1_1_vals_2g40,
+ ar9485_1_1_vals_2g20,
+ nitems(ar9485_1_1_cm_regs),
+ ar9485_1_1_cm_regs,
+ ar9485_1_1_cm_vals
+};
+
+/*
+ * AR9380 2.2 Tx gains.
+ */
+static const uint16_t ar9380_2_2_tx_gain_regs[] = {
+ P(0x0a2dc), P(0x0a2e0), P(0x0a2e4), P(0x0a2e8), P(0x0a410),
+ P(0x0a500), P(0x0a504), P(0x0a508), P(0x0a50c), P(0x0a510),
+ P(0x0a514), P(0x0a518), P(0x0a51c), P(0x0a520), P(0x0a524),
+ P(0x0a528), P(0x0a52c), P(0x0a530), P(0x0a534), P(0x0a538),
+ P(0x0a53c), P(0x0a540), P(0x0a544), P(0x0a548), P(0x0a54c),
+ P(0x0a550), P(0x0a554), P(0x0a558), P(0x0a55c), P(0x0a560),
+ P(0x0a564), P(0x0a568), P(0x0a56c), P(0x0a570), P(0x0a574),
+ P(0x0a578), P(0x0a57c), P(0x0a580), P(0x0a584), P(0x0a588),
+ P(0x0a58c), P(0x0a590), P(0x0a594), P(0x0a598), P(0x0a59c),
+ P(0x0a5a0), P(0x0a5a4), P(0x0a5a8), P(0x0a5ac), P(0x0a5b0),
+ P(0x0a5b4), P(0x0a5b8), P(0x0a5bc), P(0x0a5c0), P(0x0a5c4),
+ P(0x0a5c8), P(0x0a5cc), P(0x0a5d0), P(0x0a5d4), P(0x0a5d8),
+ P(0x0a5dc), P(0x0a5e0), P(0x0a5e4), P(0x0a5e8), P(0x0a5ec),
+ P(0x0a5f0), P(0x0a5f4), P(0x0a5f8), P(0x0a5fc), P(0x0a600),
+ P(0x0a604), P(0x0a608), P(0x0a60c), P(0x0a610), P(0x0a614),
+ P(0x0a618), P(0x0a61c), P(0x0a620), P(0x0a624), P(0x0a628),
+ P(0x0a62c), P(0x0a630), P(0x0a634), P(0x0a638), P(0x0a63c),
+ P(0x0b2dc), P(0x0b2e0), P(0x0b2e4), P(0x0b2e8), P(0x0c2dc),
+ P(0x0c2e0), P(0x0c2e4), P(0x0c2e8), P(0x16044), P(0x16048),
+ P(0x16068), P(0x16444), P(0x16448), P(0x16468), P(0x16844),
+ P(0x16848), P(0x16868)
+};
+
+static const uint32_t ar9380_2_2_tx_gain_vals_5g[] = {
+ 0x00033800, 0x0003c000, 0x03fc0000, 0x00000000, 0x000050d9,
+ 0x00000000, 0x06000003, 0x0a000020, 0x10000023, 0x16000220,
+ 0x1c000223, 0x21002220, 0x27002223, 0x2b022220, 0x2f022222,
+ 0x34022225, 0x3a02222a, 0x3e02222c, 0x4202242a, 0x4702244a,
+ 0x4b02244c, 0x4e02246c, 0x52022470, 0x55022490, 0x59022492,
+ 0x5d022692, 0x61022892, 0x65024890, 0x69024892, 0x6e024c92,
+ 0x74026e92, 0x74026e92, 0x74026e92, 0x74026e92, 0x74026e92,
+ 0x74026e92, 0x74026e92, 0x00800000, 0x06800003, 0x0a800020,
+ 0x10800023, 0x16800220, 0x1c800223, 0x21802220, 0x27802223,
+ 0x2b822220, 0x2f822222, 0x34822225, 0x3a82222a, 0x3e82222c,
+ 0x4282242a, 0x4782244a, 0x4b82244c, 0x4e82246c, 0x52822470,
+ 0x55822490, 0x59822492, 0x5d822692, 0x61822892, 0x65824890,
+ 0x69824892, 0x6e824c92, 0x74826e92, 0x74826e92, 0x74826e92,
+ 0x74826e92, 0x74826e92, 0x74826e92, 0x74826e92, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02004000,
+ 0x02004801, 0x02808a02, 0x0380ce03, 0x04411104, 0x04411104,
+ 0x04411104, 0x04411104, 0x04411104, 0x04411104, 0x04411104,
+ 0x00033800, 0x0003c000, 0x03fc0000, 0x00000000, 0x00033800,
+ 0x0003c000, 0x03fc0000, 0x00000000, 0x012492d4, 0x62480001,
+ 0x6db6db6c, 0x012492d4, 0x62480001, 0x6db6db6c, 0x012492d4,
+ 0x62480001, 0x6db6db6c
+};
+
+static const uint32_t ar9380_2_2_tx_gain_vals_2g[] = {
+ 0x00637800, 0x03838000, 0x03fc0000, 0x00000000, 0x000050d9,
+ 0x00000000, 0x04000002, 0x08000004, 0x0b000200, 0x0f000202,
+ 0x12000400, 0x16000402, 0x19000404, 0x1c000603, 0x21000a02,
+ 0x25000a04, 0x28000a20, 0x2c000e20, 0x30000e22, 0x34000e24,
+ 0x38001640, 0x3c001660, 0x3f001861, 0x43001a81, 0x47001a83,
+ 0x4a001c84, 0x4e001ce3, 0x52001ce5, 0x56001ce9, 0x5a001ceb,
+ 0x5d001eec, 0x5d001eec, 0x5d001eec, 0x5d001eec, 0x5d001eec,
+ 0x5d001eec, 0x5d001eec, 0x00800000, 0x04800002, 0x08800004,
+ 0x0b800200, 0x0f800202, 0x12800400, 0x16800402, 0x19800404,
+ 0x1c800603, 0x21800a02, 0x25800a04, 0x28800a20, 0x2c800e20,
+ 0x30800e22, 0x34800e24, 0x38801640, 0x3c801660, 0x3f801861,
+ 0x43801a81, 0x47801a83, 0x4a801c84, 0x4e801ce3, 0x52801ce5,
+ 0x56801ce9, 0x5a801ceb, 0x5d801eec, 0x5d801eec, 0x5d801eec,
+ 0x5d801eec, 0x5d801eec, 0x5d801eec, 0x5d801eec, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01404000,
+ 0x01404501, 0x02008501, 0x0280ca03, 0x03010c04, 0x04014c04,
+ 0x04015005, 0x04015005, 0x04015005, 0x04015005, 0x04015005,
+ 0x00637800, 0x03838000, 0x03fc0000, 0x00000000, 0x00637800,
+ 0x03838000, 0x03fc0000, 0x00000000, 0x012492d4, 0x62480001,
+ 0x6db6db6c, 0x012492d4, 0x62480001, 0x6db6db6c, 0x012492d4,
+ 0x62480001, 0x6db6db6c
+};
+
+static const struct athn_gain ar9380_2_2_tx_gain = {
+ nitems(ar9380_2_2_tx_gain_regs),
+ ar9380_2_2_tx_gain_regs,
+ ar9380_2_2_tx_gain_vals_5g,
+ ar9380_2_2_tx_gain_vals_2g
+};
+
+/*
+ * AR9380 2.2 high ob/db Tx gains.
+ */
+static const uint32_t ar9380_2_2_tx_gain_high_ob_db_vals_5g[] = {
+ 0x01feee00, 0x0000f000, 0x01ff0000, 0x00000000, 0x000050d8,
+ 0x00002220, 0x04002222, 0x09002421, 0x0d002621, 0x13004620,
+ 0x19004a20, 0x1d004e20, 0x21005420, 0x26005e20, 0x2b005e40,
+ 0x2f005e42, 0x33005e44, 0x38005e65, 0x3c005e69, 0x40005e6b,
+ 0x44005e6d, 0x49005e72, 0x4e005eb2, 0x53005f12, 0x59025eb2,
+ 0x5e025f12, 0x61027f12, 0x6702bf12, 0x6b02bf14, 0x6f02bf16,
+ 0x6f02bf16, 0x6f02bf16, 0x6f02bf16, 0x6f02bf16, 0x6f02bf16,
+ 0x6f02bf16, 0x6f02bf16, 0x00802220, 0x04802222, 0x09802421,
+ 0x0d802621, 0x13804620, 0x19804a20, 0x1d804e20, 0x21805420,
+ 0x26805e20, 0x2b805e40, 0x2f805e42, 0x33805e44, 0x38805e65,
+ 0x3c805e69, 0x40805e6b, 0x44805e6d, 0x49805e72, 0x4e805eb2,
+ 0x53805f12, 0x59825eb2, 0x5e825f12, 0x61827f12, 0x6782bf12,
+ 0x6b82bf14, 0x6f82bf16, 0x6f82bf16, 0x6f82bf16, 0x6f82bf16,
+ 0x6f82bf16, 0x6f82bf16, 0x6f82bf16, 0x6f82bf16, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00804000, 0x00804201,
+ 0x0280c802, 0x0280ca03, 0x04c15104, 0x04c15305, 0x04c15305,
+ 0x04c15305, 0x04c15305, 0x04c15305, 0x04c15305, 0x04c15305,
+ 0x01feee00, 0x0000f000, 0x01ff0000, 0x00000000, 0x01feee00,
+ 0x0000f000, 0x01ff0000, 0x00000000, 0x056db2e4, 0x8e480001,
+ 0x6db6db6c, 0x056db2e4, 0x8e480001, 0x6db6db6c, 0x056db2e4,
+ 0x8e480001, 0x6db6db6c
+};
+
+static const uint32_t ar9380_2_2_tx_gain_high_ob_db_vals_2g[] = {
+ 0x00637800, 0x03838000, 0x03fc0000, 0x00000000, 0x000050d9,
+ 0x00000000, 0x04000002, 0x08000004, 0x0b000200, 0x0f000202,
+ 0x11000400, 0x15000402, 0x19000404, 0x1b000603, 0x1f000a02,
+ 0x23000a04, 0x26000a20, 0x2a000e20, 0x2e000e22, 0x31000e24,
+ 0x34001640, 0x38001660, 0x3b001861, 0x3e001a81, 0x42001a83,
+ 0x44001c84, 0x48001ce3, 0x4c001ce5, 0x50001ce9, 0x54001ceb,
+ 0x56001eec, 0x56001eec, 0x56001eec, 0x56001eec, 0x56001eec,
+ 0x56001eec, 0x56001eec, 0x00800000, 0x04800002, 0x08800004,
+ 0x0b800200, 0x0f800202, 0x11800400, 0x15800402, 0x19800404,
+ 0x1b800603, 0x1f800a02, 0x23800a04, 0x26800a20, 0x2a800e20,
+ 0x2e800e22, 0x31800e24, 0x34801640, 0x38801660, 0x3b801861,
+ 0x3e801a81, 0x42801a83, 0x44801c84, 0x48801ce3, 0x4c801ce5,
+ 0x50801ce9, 0x54801ceb, 0x56801eec, 0x56801eec, 0x56801eec,
+ 0x56801eec, 0x56801eec, 0x56801eec, 0x56801eec, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01404000,
+ 0x01404501, 0x02008501, 0x0280ca03, 0x03010c04, 0x04014c04,
+ 0x04015005, 0x04015005, 0x04015005, 0x04015005, 0x04015005,
+ 0x00637800, 0x03838000, 0x03fc0000, 0x00000000, 0x00637800,
+ 0x03838000, 0x03fc0000, 0x00000000, 0x056db2e4, 0x8e480001,
+ 0x6db6db6c, 0x056db2e4, 0x8e480001, 0x6db6db6c, 0x056db2e4,
+ 0x8e480001, 0x6db6db6c
+};
+
+static const struct athn_gain ar9380_2_2_tx_gain_high_ob_db = {
+ nitems(ar9380_2_2_tx_gain_regs),
+ ar9380_2_2_tx_gain_regs,
+ ar9380_2_2_tx_gain_high_ob_db_vals_5g,
+ ar9380_2_2_tx_gain_high_ob_db_vals_2g
+};
+
+/*
+ * AR9380 2.2 low ob/db Tx gains.
+ */
+static const uint32_t ar9380_2_2_tx_gain_low_ob_db_vals_5g[] = {
+ 0x0380c7fc, 0x0000f800, 0x03ff0000, 0x00000000, 0x000050d9,
+ 0x00000000, 0x06000003, 0x0a000020, 0x10000023, 0x16000220,
+ 0x1c000223, 0x21002220, 0x27002223, 0x2b022220, 0x2f022222,
+ 0x34022225, 0x3a02222a, 0x3e02222c, 0x4202242a, 0x4702244a,
+ 0x4b02244c, 0x4e02246c, 0x5302266c, 0x5702286c, 0x5c02486b,
+ 0x61024a6c, 0x66026a6c, 0x6b026e6c, 0x7002708c, 0x7302b08a,
+ 0x7702b08c, 0x7702b08c, 0x7702b08c, 0x7702b08c, 0x7702b08c,
+ 0x7702b08c, 0x7702b08c, 0x00800000, 0x06800003, 0x0a800020,
+ 0x10800023, 0x16800220, 0x1c800223, 0x21802220, 0x27802223,
+ 0x2b822220, 0x2f822222, 0x34822225, 0x3a82222a, 0x3e82222c,
+ 0x4282242a, 0x4782244a, 0x4b82244c, 0x4e82246c, 0x5382266c,
+ 0x5782286c, 0x5c82486b, 0x61824a6c, 0x66826a6c, 0x6b826e6c,
+ 0x7082708c, 0x7382b08a, 0x7782b08c, 0x7782b08c, 0x7782b08c,
+ 0x7782b08c, 0x7782b08c, 0x7782b08c, 0x7782b08c, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01404000,
+ 0x01404501, 0x02008802, 0x0300cc03, 0x0300cc03, 0x0300cc03,
+ 0x03810c03, 0x03810e04, 0x03810e04, 0x03810e04, 0x03810e04,
+ 0x0380c7fc, 0x0000f800, 0x03ff0000, 0x00000000, 0x0380c7fc,
+ 0x0000f800, 0x03ff0000, 0x00000000, 0x012492d4, 0x66480001,
+ 0x6db6db6c, 0x012492d4, 0x66480001, 0x6db6db6c, 0x012492d4,
+ 0x66480001, 0x6db6db6c
+};
+
+static const uint32_t ar9380_2_2_tx_gain_low_ob_db_vals_2g[] = {
+ 0x00637800, 0x03838000, 0x03fc0000, 0x00000000, 0x000050d9,
+ 0x00000000, 0x04000002, 0x08000004, 0x0b000200, 0x0f000202,
+ 0x12000400, 0x16000402, 0x19000404, 0x1c000603, 0x21000a02,
+ 0x25000a04, 0x28000a20, 0x2c000e20, 0x30000e22, 0x34000e24,
+ 0x38001640, 0x3c001660, 0x3f001861, 0x43001a81, 0x47001a83,
+ 0x4a001c84, 0x4e001ce3, 0x52001ce5, 0x56001ce9, 0x5a001ceb,
+ 0x5d001eec, 0x5d001eec, 0x5d001eec, 0x5d001eec, 0x5d001eec,
+ 0x5d001eec, 0x5d001eec, 0x00800000, 0x04800002, 0x08800004,
+ 0x0b800200, 0x0f800202, 0x12800400, 0x16800402, 0x19800404,
+ 0x1c800603, 0x21800a02, 0x25800a04, 0x28800a20, 0x2c800e20,
+ 0x30800e22, 0x34800e24, 0x38801640, 0x3c801660, 0x3f801861,
+ 0x43801a81, 0x47801a83, 0x4a801c84, 0x4e801ce3, 0x52801ce5,
+ 0x56801ce9, 0x5a801ceb, 0x5d801eec, 0x5d801eec, 0x5d801eec,
+ 0x5d801eec, 0x5d801eec, 0x5d801eec, 0x5d801eec, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01404000,
+ 0x01404501, 0x02008501, 0x0280ca03, 0x03010c04, 0x04014c04,
+ 0x04015005, 0x04015005, 0x04015005, 0x04015005, 0x04015005,
+ 0x00637800, 0x03838000, 0x03fc0000, 0x00000000, 0x00637800,
+ 0x03838000, 0x03fc0000, 0x00000000, 0x012492d4, 0x66480001,
+ 0x6db6db6c, 0x012492d4, 0x66480001, 0x6db6db6c, 0x012492d4,
+ 0x66480001, 0x6db6db6c
+};
+
+static const struct athn_gain ar9380_2_2_tx_gain_low_ob_db = {
+ nitems(ar9380_2_2_tx_gain_regs),
+ ar9380_2_2_tx_gain_regs,
+ ar9380_2_2_tx_gain_low_ob_db_vals_5g,
+ ar9380_2_2_tx_gain_low_ob_db_vals_2g
+};
+
+/*
+ * AR9380 2.2 high power Tx gains.
+ */
+static const uint32_t ar9380_2_2_tx_gain_high_power_vals_5g[] = {
+ 0x0380c7fc, 0x0000f800, 0x03ff0000, 0x00000000, 0x000050d8,
+ 0x00002220, 0x04002222, 0x09002421, 0x0d002621, 0x13004620,
+ 0x19004a20, 0x1d004e20, 0x21005420, 0x26005e20, 0x2b005e40,
+ 0x2f005e42, 0x33005e44, 0x38005e65, 0x3c005e69, 0x40005e6b,
+ 0x44005e6d, 0x49005e72, 0x4e005eb2, 0x53005f12, 0x59025eb2,
+ 0x5e025f12, 0x61027f12, 0x6702bf12, 0x6b02bf14, 0x6f02bf16,
+ 0x6f02bf16, 0x6f02bf16, 0x6f02bf16, 0x6f02bf16, 0x6f02bf16,
+ 0x6f02bf16, 0x6f02bf16, 0x00802220, 0x04802222, 0x09802421,
+ 0x0d802621, 0x13804620, 0x19804a20, 0x1d804e20, 0x21805420,
+ 0x26805e20, 0x2b805e40, 0x2f805e42, 0x33805e44, 0x38805e65,
+ 0x3c805e69, 0x40805e6b, 0x44805e6d, 0x49805e72, 0x4e805eb2,
+ 0x53805f12, 0x59825eb2, 0x5e825f12, 0x61827f12, 0x6782bf12,
+ 0x6b82bf14, 0x6f82bf16, 0x6f82bf16, 0x6f82bf16, 0x6f82bf16,
+ 0x6f82bf16, 0x6f82bf16, 0x6f82bf16, 0x6f82bf16, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00804000, 0x00804201,
+ 0x0280c802, 0x0280ca03, 0x04c15104, 0x04c15305, 0x04c15305,
+ 0x04c15305, 0x04c15305, 0x04c15305, 0x04c15305, 0x04c15305,
+ 0x0380c7fc, 0x0000f800, 0x03ff0000, 0x00000000, 0x0380c7fc,
+ 0x0000f800, 0x03ff0000, 0x00000000, 0x056db2e6, 0xae480001,
+ 0x6eb6db6c, 0x056db2e6, 0xae480001, 0x6eb6db6c, 0x056db2e6,
+ 0xae480001, 0x6eb6db6c
+};
+
+static const uint32_t ar9380_2_2_tx_gain_high_power_vals_2g[] = {
+ 0x00637800, 0x03838000, 0x03fc0000, 0x00000000, 0x000050d9,
+ 0x00000000, 0x04000002, 0x08000004, 0x0b000200, 0x0f000202,
+ 0x11000400, 0x15000402, 0x19000404, 0x1b000603, 0x1f000a02,
+ 0x23000a04, 0x26000a20, 0x2a000e20, 0x2e000e22, 0x31000e24,
+ 0x34001640, 0x38001660, 0x3b001861, 0x3e001a81, 0x42001a83,
+ 0x44001c84, 0x48001ce3, 0x4c001ce5, 0x50001ce9, 0x54001ceb,
+ 0x56001eec, 0x56001eec, 0x56001eec, 0x56001eec, 0x56001eec,
+ 0x56001eec, 0x56001eec, 0x00800000, 0x04800002, 0x08800004,
+ 0x0b800200, 0x0f800202, 0x11800400, 0x15800402, 0x19800404,
+ 0x1b800603, 0x1f800a02, 0x23800a04, 0x26800a20, 0x2a800e20,
+ 0x2e800e22, 0x31800e24, 0x34801640, 0x38801660, 0x3b801861,
+ 0x3e801a81, 0x42801a83, 0x44801c84, 0x48801ce3, 0x4c801ce5,
+ 0x50801ce9, 0x54801ceb, 0x56801eec, 0x56801eec, 0x56801eec,
+ 0x56801eec, 0x56801eec, 0x56801eec, 0x56801eec, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01404000,
+ 0x01404501, 0x02008501, 0x0280ca03, 0x03010c04, 0x04014c04,
+ 0x04015005, 0x04015005, 0x04015005, 0x04015005, 0x04015005,
+ 0x00637800, 0x03838000, 0x03fc0000, 0x00000000, 0x00637800,
+ 0x03838000, 0x03fc0000, 0x00000000, 0x056db2e6, 0xae480001,
+ 0x6eb6db6c, 0x056db2e6, 0xae480001, 0x6eb6db6c, 0x056db2e6,
+ 0xae480001, 0x6eb6db6c
+};
+
+static const struct athn_gain ar9380_2_2_tx_gain_high_power = {
+ nitems(ar9380_2_2_tx_gain_regs),
+ ar9380_2_2_tx_gain_regs,
+ ar9380_2_2_tx_gain_high_power_vals_5g,
+ ar9380_2_2_tx_gain_high_power_vals_2g
+};
+
+/*
+ * AR9485 1.1 Tx gains.
+ */
+static const uint16_t ar9485_1_1_tx_gain_regs[] = {
+ P(0x098bc), P(0x0a410), P(0x0a458), P(0x0a500), P(0x0a504),
+ P(0x0a508), P(0x0a50c), P(0x0a510), P(0x0a514), P(0x0a518),
+ P(0x0a51c), P(0x0a520), P(0x0a524), P(0x0a528), P(0x0a52c),
+ P(0x0a530), P(0x0a534), P(0x0a538), P(0x0a53c), P(0x0a540),
+ P(0x0a544), P(0x0a548), P(0x0a54c), P(0x0a550), P(0x0a554),
+ P(0x0a558), P(0x0a55c), P(0x0a560), P(0x0a564), P(0x0a568),
+ P(0x0a56c), P(0x0a570), P(0x0a574), P(0x0a578), P(0x0a57c),
+ P(0x0b500), P(0x0b504), P(0x0b508), P(0x0b50c), P(0x0b510),
+ P(0x0b514), P(0x0b518), P(0x0b51c), P(0x0b520), P(0x0b524),
+ P(0x0b528), P(0x0b52c), P(0x0b530), P(0x0b534), P(0x0b538),
+ P(0x0b53c), P(0x0b540), P(0x0b544), P(0x0b548), P(0x0b54c),
+ P(0x0b550), P(0x0b554), P(0x0b558), P(0x0b55c), P(0x0b560),
+ P(0x0b564), P(0x0b568), P(0x0b56c), P(0x0b570), P(0x0b574),
+ P(0x0b578), P(0x0b57c), P(0x16044), P(0x16048),
+};
+
+static const uint32_t ar9485_1_1_tx_gain_vals_2g[] = {
+ 0x00000002, 0x000050d8, 0x00000000, 0x00000000, 0x04000002,
+ 0x08000004, 0x0d000200, 0x11000202, 0x15000400, 0x19000402,
+ 0x1d000404, 0x21000603, 0x25000605, 0x2a000a03, 0x2c000a04,
+ 0x34000e20, 0x35000e21, 0x43000e62, 0x45000e63, 0x49000e65,
+ 0x4b000e66, 0x4d001645, 0x51001865, 0x55001a86, 0x57001ce9,
+ 0x5a001ceb, 0x5e001eeb, 0x5e001eeb, 0x5e001eeb, 0x5e001eeb,
+ 0x5e001eeb, 0x5e001eeb, 0x5e001eeb, 0x5e001eeb, 0x5e001eeb,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x05d6b2db, 0x6c924260
+};
+
+static const struct athn_gain ar9485_1_1_tx_gain = {
+ nitems(ar9485_1_1_tx_gain_regs),
+ ar9485_1_1_tx_gain_regs,
+ NULL, /* 2GHz only. */
+ ar9485_1_1_tx_gain_vals_2g
+};
+
+/*
+ * AR9380 2.2 Rx gains.
+ */
+static const uint16_t ar9380_2_2_rx_gain_regs[] = {
+ P(0x0a000), P(0x0a004), P(0x0a008), P(0x0a00c), P(0x0a010),
+ P(0x0a014), P(0x0a018), P(0x0a01c), P(0x0a020), P(0x0a024),
+ P(0x0a028), P(0x0a02c), P(0x0a030), P(0x0a034), P(0x0a038),
+ P(0x0a03c), P(0x0a040), P(0x0a044), P(0x0a048), P(0x0a04c),
+ P(0x0a050), P(0x0a054), P(0x0a058), P(0x0a05c), P(0x0a060),
+ P(0x0a064), P(0x0a068), P(0x0a06c), P(0x0a070), P(0x0a074),
+ P(0x0a078), P(0x0a07c), P(0x0a080), P(0x0a084), P(0x0a088),
+ P(0x0a08c), P(0x0a090), P(0x0a094), P(0x0a098), P(0x0a09c),
+ P(0x0a0a0), P(0x0a0a4), P(0x0a0a8), P(0x0a0ac), P(0x0a0b0),
+ P(0x0a0b4), P(0x0a0b8), P(0x0a0bc), P(0x0a0c0), P(0x0a0c4),
+ P(0x0a0c8), P(0x0a0cc), P(0x0a0d0), P(0x0a0d4), P(0x0a0d8),
+ P(0x0a0dc), P(0x0a0e0), P(0x0a0e4), P(0x0a0e8), P(0x0a0ec),
+ P(0x0a0f0), P(0x0a0f4), P(0x0a0f8), P(0x0a0fc), P(0x0a100),
+ P(0x0a104), P(0x0a108), P(0x0a10c), P(0x0a110), P(0x0a114),
+ P(0x0a118), P(0x0a11c), P(0x0a120), P(0x0a124), P(0x0a128),
+ P(0x0a12c), P(0x0a130), P(0x0a134), P(0x0a138), P(0x0a13c),
+ P(0x0a140), P(0x0a144), P(0x0a148), P(0x0a14c), P(0x0a150),
+ P(0x0a154), P(0x0a158), P(0x0a15c), P(0x0a160), P(0x0a164),
+ P(0x0a168), P(0x0a16c), P(0x0a170), P(0x0a174), P(0x0a178),
+ P(0x0a17c), P(0x0a180), P(0x0a184), P(0x0a188), P(0x0a18c),
+ P(0x0a190), P(0x0a194), P(0x0a198), P(0x0a19c), P(0x0a1a0),
+ P(0x0a1a4), P(0x0a1a8), P(0x0a1ac), P(0x0a1b0), P(0x0a1b4),
+ P(0x0a1b8), P(0x0a1bc), P(0x0a1c0), P(0x0a1c4), P(0x0a1c8),
+ P(0x0a1cc), P(0x0a1d0), P(0x0a1d4), P(0x0a1d8), P(0x0a1dc),
+ P(0x0a1e0), P(0x0a1e4), P(0x0a1e8), P(0x0a1ec), P(0x0a1f0),
+ P(0x0a1f4), P(0x0a1f8), P(0x0a1fc), P(0x0b000), P(0x0b004),
+ P(0x0b008), P(0x0b00c), P(0x0b010), P(0x0b014), P(0x0b018),
+ P(0x0b01c), P(0x0b020), P(0x0b024), P(0x0b028), P(0x0b02c),
+ P(0x0b030), P(0x0b034), P(0x0b038), P(0x0b03c), P(0x0b040),
+ P(0x0b044), P(0x0b048), P(0x0b04c), P(0x0b050), P(0x0b054),
+ P(0x0b058), P(0x0b05c), P(0x0b060), P(0x0b064), P(0x0b068),
+ P(0x0b06c), P(0x0b070), P(0x0b074), P(0x0b078), P(0x0b07c),
+ P(0x0b080), P(0x0b084), P(0x0b088), P(0x0b08c), P(0x0b090),
+ P(0x0b094), P(0x0b098), P(0x0b09c), P(0x0b0a0), P(0x0b0a4),
+ P(0x0b0a8), P(0x0b0ac), P(0x0b0b0), P(0x0b0b4), P(0x0b0b8),
+ P(0x0b0bc), P(0x0b0c0), P(0x0b0c4), P(0x0b0c8), P(0x0b0cc),
+ P(0x0b0d0), P(0x0b0d4), P(0x0b0d8), P(0x0b0dc), P(0x0b0e0),
+ P(0x0b0e4), P(0x0b0e8), P(0x0b0ec), P(0x0b0f0), P(0x0b0f4),
+ P(0x0b0f8), P(0x0b0fc), P(0x0b100), P(0x0b104), P(0x0b108),
+ P(0x0b10c), P(0x0b110), P(0x0b114), P(0x0b118), P(0x0b11c),
+ P(0x0b120), P(0x0b124), P(0x0b128), P(0x0b12c), P(0x0b130),
+ P(0x0b134), P(0x0b138), P(0x0b13c), P(0x0b140), P(0x0b144),
+ P(0x0b148), P(0x0b14c), P(0x0b150), P(0x0b154), P(0x0b158),
+ P(0x0b15c), P(0x0b160), P(0x0b164), P(0x0b168), P(0x0b16c),
+ P(0x0b170), P(0x0b174), P(0x0b178), P(0x0b17c), P(0x0b180),
+ P(0x0b184), P(0x0b188), P(0x0b18c), P(0x0b190), P(0x0b194),
+ P(0x0b198), P(0x0b19c), P(0x0b1a0), P(0x0b1a4), P(0x0b1a8),
+ P(0x0b1ac), P(0x0b1b0), P(0x0b1b4), P(0x0b1b8), P(0x0b1bc),
+ P(0x0b1c0), P(0x0b1c4), P(0x0b1c8), P(0x0b1cc), P(0x0b1d0),
+ P(0x0b1d4), P(0x0b1d8), P(0x0b1dc), P(0x0b1e0), P(0x0b1e4),
+ P(0x0b1e8), P(0x0b1ec), P(0x0b1f0), P(0x0b1f4), P(0x0b1f8),
+ P(0x0b1fc)
+};
+
+static const uint32_t ar9380_2_2_rx_gain_vals[] = {
+ 0x00010000, 0x00030002, 0x00050004, 0x00810080, 0x00830082,
+ 0x01810180, 0x01830182, 0x01850184, 0x01890188, 0x018b018a,
+ 0x018d018c, 0x01910190, 0x01930192, 0x01950194, 0x038a0196,
+ 0x038c038b, 0x0390038d, 0x03920391, 0x03940393, 0x03960395,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x22222229, 0x1d1d1d1d, 0x1d1d1d1d,
+ 0x1d1d1d1d, 0x171d1d1d, 0x11111717, 0x00030311, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x001f0000, 0x01000101,
+ 0x011e011f, 0x011c011d, 0x02030204, 0x02010202, 0x021f0200,
+ 0x0302021e, 0x03000301, 0x031e031f, 0x0402031d, 0x04000401,
+ 0x041e041f, 0x0502041d, 0x05000501, 0x051e051f, 0x06010602,
+ 0x061f0600, 0x061d061e, 0x07020703, 0x07000701, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x001f0000, 0x01000101, 0x011e011f, 0x011c011d, 0x02030204,
+ 0x02010202, 0x021f0200, 0x0302021e, 0x03000301, 0x031e031f,
+ 0x0402031d, 0x04000401, 0x041e041f, 0x0502041d, 0x05000501,
+ 0x051e051f, 0x06010602, 0x061f0600, 0x061d061e, 0x07020703,
+ 0x07000701, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000396,
+ 0x00000396, 0x00000396, 0x00000196, 0x00010000, 0x00030002,
+ 0x00050004, 0x00810080, 0x00830082, 0x01810180, 0x01830182,
+ 0x01850184, 0x02810280, 0x02830282, 0x02850284, 0x02890288,
+ 0x028b028a, 0x0388028c, 0x038a0389, 0x038c038b, 0x0390038d,
+ 0x03920391, 0x03940393, 0x03960395, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x2a2d2f32, 0x21232328, 0x19191c1e, 0x12141417, 0x07070e0e,
+ 0x03030305, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x003f0020, 0x00400041, 0x0140005f, 0x0160015f,
+ 0x017e017f, 0x02410242, 0x025f0240, 0x027f0260, 0x0341027e,
+ 0x035f0340, 0x037f0360, 0x04400441, 0x0460045f, 0x0541047f,
+ 0x055f0540, 0x057f0560, 0x06400641, 0x0660065f, 0x067e067f,
+ 0x07410742, 0x075f0740, 0x077f0760, 0x07800781, 0x07a0079f,
+ 0x07c107bf, 0x000007c0, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x003f0020, 0x00400041,
+ 0x0140005f, 0x0160015f, 0x017e017f, 0x02410242, 0x025f0240,
+ 0x027f0260, 0x0341027e, 0x035f0340, 0x037f0360, 0x04400441,
+ 0x0460045f, 0x0541047f, 0x055f0540, 0x057f0560, 0x06400641,
+ 0x0660065f, 0x067e067f, 0x07410742, 0x075f0740, 0x077f0760,
+ 0x07800781, 0x07a0079f, 0x07c107bf, 0x000007c0, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000396, 0x00000396, 0x00000396,
+ 0x00000196
+};
+
+static const struct athn_gain ar9380_2_2_rx_gain = {
+ nitems(ar9380_2_2_rx_gain_regs),
+ ar9380_2_2_rx_gain_regs,
+ ar9380_2_2_rx_gain_vals,
+ ar9380_2_2_rx_gain_vals
+};
+
+/*
+ * AR9380 2.2 without external low-noise amplifier Rx gains.
+ */
+static const uint32_t ar9380_2_2_rx_gain_wo_xlna_vals[] = {
+ 0x00010000, 0x00030002, 0x00050004, 0x00810080, 0x00830082,
+ 0x01810180, 0x01830182, 0x01850184, 0x01890188, 0x018b018a,
+ 0x018d018c, 0x03820190, 0x03840383, 0x03880385, 0x038a0389,
+ 0x038c038b, 0x0390038d, 0x03920391, 0x03940393, 0x03960395,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x29292929, 0x29292929, 0x29292929,
+ 0x29292929, 0x22292929, 0x1d1d2222, 0x0c111117, 0x00030303,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x001f0000, 0x01000101,
+ 0x011e011f, 0x011c011d, 0x02030204, 0x02010202, 0x021f0200,
+ 0x0302021e, 0x03000301, 0x031e031f, 0x0402031d, 0x04000401,
+ 0x041e041f, 0x0502041d, 0x05000501, 0x051e051f, 0x06010602,
+ 0x061f0600, 0x061d061e, 0x07020703, 0x07000701, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x001f0000, 0x01000101, 0x011e011f, 0x011c011d, 0x02030204,
+ 0x02010202, 0x021f0200, 0x0302021e, 0x03000301, 0x031e031f,
+ 0x0402031d, 0x04000401, 0x041e041f, 0x0502041d, 0x05000501,
+ 0x051e051f, 0x06010602, 0x061f0600, 0x061d061e, 0x07020703,
+ 0x07000701, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000396,
+ 0x00000396, 0x00000396, 0x00000196, 0x00010000, 0x00030002,
+ 0x00050004, 0x00810080, 0x00830082, 0x01810180, 0x01830182,
+ 0x01850184, 0x02810280, 0x02830282, 0x02850284, 0x02890288,
+ 0x028b028a, 0x0388028c, 0x038a0389, 0x038c038b, 0x0390038d,
+ 0x03920391, 0x03940393, 0x03960395, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x32323232, 0x2f2f3232, 0x23282a2d, 0x1c1e2123, 0x14171919,
+ 0x0e0e1214, 0x03050707, 0x00030303, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x003f0020, 0x00400041, 0x0140005f, 0x0160015f,
+ 0x017e017f, 0x02410242, 0x025f0240, 0x027f0260, 0x0341027e,
+ 0x035f0340, 0x037f0360, 0x04400441, 0x0460045f, 0x0541047f,
+ 0x055f0540, 0x057f0560, 0x06400641, 0x0660065f, 0x067e067f,
+ 0x07410742, 0x075f0740, 0x077f0760, 0x07800781, 0x07a0079f,
+ 0x07c107bf, 0x000007c0, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x003f0020, 0x00400041,
+ 0x0140005f, 0x0160015f, 0x017e017f, 0x02410242, 0x025f0240,
+ 0x027f0260, 0x0341027e, 0x035f0340, 0x037f0360, 0x04400441,
+ 0x0460045f, 0x0541047f, 0x055f0540, 0x057f0560, 0x06400641,
+ 0x0660065f, 0x067e067f, 0x07410742, 0x075f0740, 0x077f0760,
+ 0x07800781, 0x07a0079f, 0x07c107bf, 0x000007c0, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000396, 0x00000396, 0x00000396,
+ 0x00000196
+};
+
+static const struct athn_gain ar9380_2_2_rx_gain_wo_xlna = {
+ nitems(ar9380_2_2_rx_gain_regs),
+ ar9380_2_2_rx_gain_regs,
+ ar9380_2_2_rx_gain_wo_xlna_vals,
+ ar9380_2_2_rx_gain_wo_xlna_vals
+};
+
+/*
+ * AR9485 1.1 Rx gains.
+ */
+static const uint16_t ar9485_1_1_rx_gain_regs[] = {
+ P(0x0a000), P(0x0a004), P(0x0a008), P(0x0a00c), P(0x0a010),
+ P(0x0a014), P(0x0a018), P(0x0a01c), P(0x0a020), P(0x0a024),
+ P(0x0a028), P(0x0a02c), P(0x0a030), P(0x0a034), P(0x0a038),
+ P(0x0a03c), P(0x0a040), P(0x0a044), P(0x0a048), P(0x0a04c),
+ P(0x0a050), P(0x0a054), P(0x0a058), P(0x0a05c), P(0x0a060),
+ P(0x0a064), P(0x0a068), P(0x0a06c), P(0x0a070), P(0x0a074),
+ P(0x0a078), P(0x0a07c), P(0x0a080), P(0x0a084), P(0x0a088),
+ P(0x0a08c), P(0x0a090), P(0x0a094), P(0x0a098), P(0x0a09c),
+ P(0x0a0a0), P(0x0a0a4), P(0x0a0a8), P(0x0a0ac), P(0x0a0b0),
+ P(0x0a0b4), P(0x0a0b8), P(0x0a0bc), P(0x0a0c0), P(0x0a0c4),
+ P(0x0a0c8), P(0x0a0cc), P(0x0a0d0), P(0x0a0d4), P(0x0a0d8),
+ P(0x0a0dc), P(0x0a0e0), P(0x0a0e4), P(0x0a0e8), P(0x0a0ec),
+ P(0x0a0f0), P(0x0a0f4), P(0x0a0f8), P(0x0a0fc), P(0x0a100),
+ P(0x0a104), P(0x0a108), P(0x0a10c), P(0x0a110), P(0x0a114),
+ P(0x0a118), P(0x0a11c), P(0x0a120), P(0x0a124), P(0x0a128),
+ P(0x0a12c), P(0x0a130), P(0x0a134), P(0x0a138), P(0x0a13c),
+ P(0x0a140), P(0x0a144), P(0x0a148), P(0x0a14c), P(0x0a150),
+ P(0x0a154), P(0x0a158), P(0x0a15c), P(0x0a160), P(0x0a164),
+ P(0x0a168), P(0x0a16c), P(0x0a170), P(0x0a174), P(0x0a178),
+ P(0x0a17c), P(0x0a180), P(0x0a184), P(0x0a188), P(0x0a18c),
+ P(0x0a190), P(0x0a194), P(0x0a198), P(0x0a19c), P(0x0a1a0),
+ P(0x0a1a4), P(0x0a1a8), P(0x0a1ac), P(0x0a1b0), P(0x0a1b4),
+ P(0x0a1b8), P(0x0a1bc), P(0x0a1c0), P(0x0a1c4), P(0x0a1c8),
+ P(0x0a1cc), P(0x0a1d0), P(0x0a1d4), P(0x0a1d8), P(0x0a1dc),
+ P(0x0a1e0), P(0x0a1e4), P(0x0a1e8), P(0x0a1ec), P(0x0a1f0),
+ P(0x0a1f4), P(0x0a1f8), P(0x0a1fc)
+};
+
+static const uint32_t ar9485_1_1_rx_gain_vals[] = {
+ 0x00060005, 0x00810080, 0x00830082, 0x00850084, 0x01820181,
+ 0x01840183, 0x01880185, 0x018a0189, 0x02850284, 0x02890288,
+ 0x028b028a, 0x03850384, 0x03890388, 0x038b038a, 0x038d038c,
+ 0x03910390, 0x03930392, 0x03950394, 0x00000396, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x28282828, 0x28282828, 0x28282828,
+ 0x28282828, 0x28282828, 0x24242428, 0x171e1e1e, 0x02020b0b,
+ 0x02020202, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x22072208, 0x22052206,
+ 0x22032204, 0x22012202, 0x221f2200, 0x221d221e, 0x33023303,
+ 0x33003301, 0x331e331f, 0x4402331d, 0x44004401, 0x441e441f,
+ 0x55025503, 0x55005501, 0x551e551f, 0x6602551d, 0x66006601,
+ 0x661e661f, 0x7703661d, 0x77017702, 0x00007700, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x001f0000, 0x111f1100, 0x111d111e, 0x111b111c, 0x22032204,
+ 0x22012202, 0x221f2200, 0x221d221e, 0x33013302, 0x331f3300,
+ 0x4402331e, 0x44004401, 0x441e441f, 0x55015502, 0x551f5500,
+ 0x6602551e, 0x66006601, 0x661e661f, 0x7703661d, 0x77017702,
+ 0x00007700, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000396,
+ 0x00000396, 0x00000396, 0x00000296
+};
+
+static const struct athn_gain ar9485_1_1_rx_gain = {
+ nitems(ar9485_1_1_rx_gain_regs),
+ ar9485_1_1_rx_gain_regs,
+ NULL, /* 2GHz only. */
+ ar9485_1_1_rx_gain_vals
+};
+
+/*
+ * Serializer/Deserializer programming.
+ */
+
+static const uint32_t ar9380_2_2_serdes_regs[] = {
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES,
+ AR_PCIE_SERDES2
+};
+
+static const uint32_t ar9380_2_2_serdes_vals[] = {
+ 0x08212e5e,
+ 0x0008003b,
+ 0x00000000
+};
+
+static const struct athn_serdes ar9380_2_2_serdes = {
+ nitems(ar9380_2_2_serdes_vals),
+ ar9380_2_2_serdes_regs,
+ ar9380_2_2_serdes_vals
+};
+
+static const uint32_t ar9485_1_1_serdes_regs[] = {
+ 0x00018c00,
+ 0x00018c04,
+ 0x00018c08
+};
+
+static const uint32_t ar9485_1_1_serdes_vals[] = {
+ 0x18013e5e,
+ 0x000801d8,
+ 0x0000080c
+};
+
+static const struct athn_serdes ar9485_1_1_serdes = {
+ nitems(ar9485_1_1_serdes_vals),
+ ar9485_1_1_serdes_regs,
+ ar9485_1_1_serdes_vals
+};
diff --git a/sys/dev/athn/usb/ar9271u.h b/sys/dev/athn/usb/ar9271u.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/usb/ar9271u.h
@@ -0,0 +1 @@
+void ar9271u_attach(struct athn_usb_softc *uc);
diff --git a/sys/dev/athn/usb/ar9271u.c b/sys/dev/athn/usb/ar9271u.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/usb/ar9271u.c
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2022 Farhan Khan <khanzf@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_wlan.h"
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/athn/athnvar.h>
+#include <dev/athn/athnreg.h>
+#include <dev/athn/usb/if_athn_usb.h>
+
+void
+ar9271u_attach(struct athn_usb_softc *usc)
+{
+ struct athn_softc *sc = &usc->sc_sc;
+ sc->fwname = "athn-ar9271fw";
+ printf("Start of ar9271u_attach\n");
+}
diff --git a/sys/dev/athn/usb/if_athn_usb.h b/sys/dev/athn/usb/if_athn_usb.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/usb/if_athn_usb.h
@@ -0,0 +1,544 @@
+/* $OpenBSD: if_athn_usb.h,v 1.13 2022/01/09 05:43:00 jsg Exp $ */
+
+/*-
+ * Copyright (c) 2022 Farhan Khan <khanzf@gmail.com>
+ * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <dev/athn/athnvar.h> /* for struct rtwn_rx_stat_common */
+
+struct athn_usb_softc;
+
+/* Start of FreeBSD constructs */
+#define ATHN_IFACE_INDEX 0
+#define EDCA_NUM_AC 4
+
+void ar9271u_attach(struct athn_usb_softc *);
+
+enum {
+ ATHN_CHIP_AR9271U,
+ ATHN_CHIP_MAX_USB
+};
+
+/*
+struct athn_data {
+ uint8_t *buf;
+ int id;
+ uint16_t buflen;
+ struct mbuf *m;
+ struct ieee80211_node *ni;
+ STAILQ_ENTRY(athn_data) next;
+};
+typedef STAILQ_HEAD(, athn_data) athn_datahead;
+*/
+
+/* various supported device vendors/products */
+typedef void (*chip_usb_attach)(struct athn_usb_softc *);
+
+static const chip_usb_attach athn_chip_usb_attach[ATHN_CHIP_MAX_USB] = {
+ [ATHN_CHIP_AR9271U] = ar9271u_attach
+};
+
+static __inline void
+athn_usb_attach_private(struct athn_usb_softc *usc, int chip)
+{
+ athn_chip_usb_attach[chip](usc);
+}
+/* End of FreeBSD constructs */
+
+
+/* Maximum number of STAs firmware can handle. */
+#define AR_USB_MAX_STA 8
+
+#define AR_USB_DEFAULT_NF (-95)
+
+/* USB requests. */
+#define AR_FW_DOWNLOAD 0x30
+#define AR_FW_DOWNLOAD_COMP 0x31
+
+/* USB endpoints addresses. */
+#define AR_PIPE_TX_DATA (UE_DIR_OUT | 1)
+#define AR_PIPE_RX_DATA (UE_DIR_IN | 2)
+#define AR_PIPE_RX_INTR (UE_DIR_IN | 3)
+#define AR_PIPE_TX_INTR (UE_DIR_OUT | 4)
+
+/* Wireless module interface commands. */
+#define AR_WMI_CMD_ECHO 0x001
+#define AR_WMI_CMD_ACCESS_MEMORY 0x002
+#define AR_WMI_GET_FW_VERSION 0x003
+#define AR_WMI_CMD_DISABLE_INTR 0x004
+#define AR_WMI_CMD_ENABLE_INTR 0x005
+#define AR_WMI_CMD_ATH_INIT 0x006
+#define AR_WMI_CMD_ABORT_TXQ 0x007
+#define AR_WMI_CMD_STOP_TX_DMA 0x008
+#define AR_WMI_CMD_ABORT_TX_DMA 0x009
+#define AR_WMI_CMD_DRAIN_TXQ 0x00a
+#define AR_WMI_CMD_DRAIN_TXQ_ALL 0x00b
+#define AR_WMI_CMD_START_RECV 0x00c
+#define AR_WMI_CMD_STOP_RECV 0x00d
+#define AR_WMI_CMD_FLUSH_RECV 0x00e
+#define AR_WMI_CMD_SET_MODE 0x00f
+#define AR_WMI_CMD_NODE_CREATE 0x010
+#define AR_WMI_CMD_NODE_REMOVE 0x011
+#define AR_WMI_CMD_VAP_REMOVE 0x012
+#define AR_WMI_CMD_VAP_CREATE 0x013
+#define AR_WMI_CMD_REG_READ 0x014
+#define AR_WMI_CMD_REG_WRITE 0x015
+#define AR_WMI_CMD_RC_STATE_CHANGE 0x016
+#define AR_WMI_CMD_RC_RATE_UPDATE 0x017
+#define AR_WMI_CMD_TARGET_IC_UPDATE 0x018
+#define AR_WMI_CMD_TX_AGGR_ENABLE 0x019
+#define AR_WMI_CMD_TGT_DETACH 0x020
+#define AR_WMI_CMD_NODE_UPDATE 0x021
+#define AR_WMI_CMD_INT_STATS 0x022
+#define AR_WMI_CMD_TX_STATS 0x023
+#define AR_WMI_CMD_RX_STATS 0x024
+#define AR_WMI_CMD_BITRATE_MASK 0x025
+#define AR_WMI_CMD_REG_RMW 0x026
+
+/* Wireless module interface events. */
+#define AR_WMI_EVT_TGT_RDY 0x001
+#define AR_WMI_EVT_SWBA 0x002
+#define AR_WMI_EVT_FATAL 0x003
+#define AR_WMI_EVT_TXTO 0x004
+#define AR_WMI_EVT_BMISS 0x005
+#define AR_WMI_EVT_DELBA 0x006
+#define AR_WMI_EVT_TXSTATUS 0x007
+
+/* Structure for service AR_SVC_WMI_CONTROL. */
+struct ar_wmi_cmd_hdr {
+ uint16_t cmd_id;
+#define AR_WMI_EVT_FLAG 0x1000
+
+ uint16_t seq_no;
+} __packed;
+
+/* Values for AR_WMI_CMD_SET_MODE. */
+#define AR_HTC_MODE_11NA 0
+#define AR_HTC_MODE_11NG 1
+
+#define AR_MAX_WRITE_COUNT 32
+/* Structure for command AR_WMI_CMD_REG_WRITE. */
+struct ar_wmi_cmd_reg_write {
+ uint32_t addr;
+ uint32_t val;
+} __packed;
+
+/* Structure for command AR_WMI_CMD_NODE_{CREATE,REMOVE}. */
+struct ar_htc_target_sta {
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
+ uint8_t bssid[IEEE80211_ADDR_LEN];
+ uint8_t sta_index;
+ uint8_t vif_index;
+ uint8_t is_vif_sta;
+ uint16_t flags;
+#define AR_HTC_STA_AUTH 0x0001
+#define AR_HTC_STA_QOS 0x0002
+#define AR_HTC_STA_ERP 0x0004
+#define AR_HTC_STA_HT 0x0008
+
+ uint16_t htcap;
+ uint16_t maxampdu;
+ uint8_t pad;
+
+ /* Internal state. */
+ uint16_t txseqmgmt;
+ uint16_t iv16;
+ uint32_t iv32;
+ void *ni_vap;
+} __packed;
+
+/* Structures for command AR_WMI_CMD_RC_RATE_UPDATE. */
+#define AR_HTC_RATE_MAX 30
+struct ar_htc_rateset {
+ uint8_t rs_nrates;
+ uint8_t rs_rates[AR_HTC_RATE_MAX];
+} __packed;
+
+struct ar_htc_target_rate {
+ uint8_t sta_index;
+ uint8_t isnew;
+ uint8_t pad[2];
+ uint32_t capflags;
+#define AR_RC_DS_FLAG 0x00000001
+#define AR_RC_40_FLAG 0x00000002
+#define AR_RC_SGI_FLAG 0x00000004
+#define AR_RC_HT_FLAG 0x00000008
+#define AR_RC_STBC_FLAG 0x00000030 /* 2 bits */
+#define AR_RC_WEP_TKIP_FLAG 0x00000100
+
+ struct ar_htc_rateset lg_rates;
+ struct ar_htc_rateset ht_rates;
+} __packed;
+
+/* Structure for command AR_WMI_CMD_TX_AGGR_ENABLE. */
+struct ar_htc_target_aggr {
+ uint8_t sta_index;
+ uint8_t tidno;
+ uint8_t aggr_enable;
+ uint8_t padding;
+} __packed;
+
+/* Structure for command AR_WMI_CMD_VAP_CREATE. */
+struct ar_htc_target_vif {
+ uint8_t index;
+ uint32_t opmode;
+#define AR_HTC_M_IBSS 0
+#define AR_HTC_M_STA 1
+#define AR_HTC_M_WDS 2
+#define AR_HTC_M_AHDEMO 3
+#define AR_HTC_M_HOSTAP 6
+#define AR_HTC_M_MONITOR 8
+ uint8_t myaddr[IEEE80211_ADDR_LEN];
+ uint8_t ath_cap;
+ uint16_t rtsthreshold;
+ uint8_t pad;
+
+ /* Internal state. */
+ int8_t nodeindex;
+ void *iv_bss;
+} __packed;
+
+/* Structure for command AM_WMI_CMD_TARGET_IC_UPDATE. */
+struct ar_htc_cap_target {
+ uint32_t ampdu_limit;
+ uint8_t ampdu_subframes;
+ uint8_t enable_coex;
+ uint8_t txchainmask;
+ uint8_t pad;
+} __packed;
+
+struct ar_wmi_evt_txstatus {
+ uint8_t cookie;
+
+ /*
+ * Legacy rates are indicated as rate array indices.
+ * HT rates are indicated as MCS indices.
+ */
+ uint8_t rate;
+#define AR_HTC_TXSTAT_RATE 0x0f
+#define AR_HTC_TXSTAT_EPID 0xf0
+#define AR_HTC_TXSTAT_EPID_SHIFT 4
+
+ uint8_t flags;
+#define AR_HTC_TXSTAT_ACK 0x01
+#define AR_HTC_TXSTAT_FILT 0x02
+#define AR_HTC_TXSTAT_RTC_CTS 0x04
+#define AR_HTC_TXSTAT_MCS 0x08
+#define AR_HTC_TXSTAT_CW40 0x10
+#define AR_HTC_TXSTAT_SGI 0x20
+} __packed;
+
+/* Structure for event AR_WMI_EVT_TXSTATUS. */
+#define AR_HTC_MAX_TX_STATUS 12
+struct ar_wmi_evt_txstatus_list {
+ uint8_t count;
+ struct ar_wmi_evt_txstatus ts[AR_HTC_MAX_TX_STATUS];
+} __packed;
+
+/* HTC header. */
+struct ar_htc_frame_hdr {
+ uint8_t endpoint_id;
+ uint8_t flags;
+#define AR_HTC_FLAG_NEED_CREDIT_UPDATE 0x01
+#define AR_HTC_FLAG_TRAILER 0x02
+#define AR_HTC_FLAG_CREDIT_REDISTRIBUTION 0x03
+
+ uint16_t payload_len;
+ uint8_t control[4];
+} __packed;
+
+/* Structure for HTC endpoint id 0. */
+struct ar_htc_msg_hdr {
+ uint16_t msg_id;
+#define AR_HTC_MSG_READY 0x0001
+#define AR_HTC_MSG_CONN_SVC 0x0002
+#define AR_HTC_MSG_CONN_SVC_RSP 0x0003
+#define AR_HTC_MSG_SETUP_COMPLETE 0x0004
+#define AR_HTC_MSG_CONF_PIPE 0x0005
+#define AR_HTC_MSG_CONF_PIPE_RSP 0x0006
+} __packed;
+
+/* Structure for services AR_SVC_WMI_DATA_{VO,VI,BE,BK}. */
+struct ar_tx_frame {
+ uint8_t data_type;
+#define AR_HTC_AMPDU 1
+#define AR_HTC_NORMAL 2
+
+ uint8_t node_idx;
+ uint8_t vif_idx;
+ uint8_t tid;
+ uint32_t flags;
+#define AR_HTC_TX_CTSONLY 0x00000001
+#define AR_HTC_TX_RTSCTS 0x00000002
+#define AR_HTC_TX_USE_MIN_RATE 0x00000100
+
+ uint8_t key_type;
+ uint8_t key_idx;
+ uint8_t cookie;
+ uint8_t pad;
+} __packed;
+
+/* Structure for service AR_SVC_WMI_MGMT. */
+struct ar_tx_mgmt {
+ uint8_t node_idx;
+ uint8_t vif_idx;
+ uint8_t tid;
+ uint8_t flags;
+ uint8_t key_type;
+ uint8_t key_idx;
+ uint8_t cookie;
+ uint8_t pad;
+} __packed;
+
+/* Structure for service AR_SVC_WMI_BEACON. */
+struct ar_tx_bcn {
+ uint8_t len_changed;
+ uint8_t vif_idx;
+ uint16_t rev;
+} __packed;
+
+/* Structure for message AR_HTC_MSG_READY. */
+struct ar_htc_msg_ready {
+ uint16_t credits;
+ uint16_t credits_size;
+ uint8_t max_endpoints;
+ uint8_t reserved;
+} __packed;
+
+/* Structure for message AR_HTC_MSG_CONF_PIPE. */
+struct ar_htc_msg_config_pipe {
+ uint8_t pipe_id;
+ uint8_t credits;
+} __packed;
+
+/* Structure for message AR_HTC_MSG_CONN_SVC. */
+struct ar_htc_msg_conn_svc {
+ uint16_t svc_id;
+ uint16_t conn_flags;
+ uint8_t dl_pipeid;
+ uint8_t ul_pipeid;
+ uint8_t svc_meta_len;
+ uint8_t reserved;
+} __packed;
+
+/* Structure for message AR_HTC_MSG_CONN_SVC_RSP. */
+struct ar_htc_msg_conn_svc_rsp {
+ uint16_t svc_id;
+ uint8_t status;
+#define AR_HTC_SVC_SUCCESS 0
+#define AR_HTC_SVC_NOT_FOUND 1
+#define AR_HTC_SVC_FAILED 2
+#define AR_HTC_SVC_NO_RESOURCES 3
+#define AR_HTC_SVC_NO_MORE_EP 4
+
+ uint8_t endpoint_id;
+ uint16_t max_msg_len;
+ uint8_t svc_meta_len;
+ uint8_t reserved;
+} __packed;
+
+#define AR_SVC(grp, idx) ((grp) << 8 | (idx))
+#define AR_SVC_IDX(svc) ((svc) & 0xff)
+/* Service groups. */
+#define AR_SVC_GRP_RSVD 0
+#define AR_SVC_GRP_WMI 1
+/* Service identifiers for WMI group. */
+#define AR_SVC_WMI_CONTROL AR_SVC(AR_SVC_GRP_WMI, 0)
+#define AR_SVC_WMI_BEACON AR_SVC(AR_SVC_GRP_WMI, 1)
+#define AR_SVC_WMI_CAB AR_SVC(AR_SVC_GRP_WMI, 2)
+#define AR_SVC_WMI_UAPSD AR_SVC(AR_SVC_GRP_WMI, 3)
+#define AR_SVC_WMI_MGMT AR_SVC(AR_SVC_GRP_WMI, 4)
+#define AR_SVC_WMI_DATA_VO AR_SVC(AR_SVC_GRP_WMI, 5)
+#define AR_SVC_WMI_DATA_VI AR_SVC(AR_SVC_GRP_WMI, 6)
+#define AR_SVC_WMI_DATA_BE AR_SVC(AR_SVC_GRP_WMI, 7)
+#define AR_SVC_WMI_DATA_BK AR_SVC(AR_SVC_GRP_WMI, 8)
+
+struct ar_stream_hdr {
+ uint16_t len;
+ uint16_t tag;
+#define AR_USB_RX_STREAM_TAG 0x4e00
+#define AR_USB_TX_STREAM_TAG 0x697e
+} __packed __attribute__((aligned(4)));
+
+#define AR_MAX_CHAINS 3
+
+/* Rx descriptor. */
+struct ar_rx_status {
+ uint64_t rs_tstamp;
+ uint16_t rs_datalen;
+ uint8_t rs_status;
+#define AR_RXS_RXERR_CRC 0x01
+#define AR_RXS_RXERR_PHY 0x02
+#define AR_RXS_RXERR_FIFO 0x04
+#define AR_RXS_RXERR_DECRYPT 0x08
+#define AR_RXS_RXERR_MIC 0x10
+ uint8_t rs_phyerr;
+ int8_t rs_rssi;
+ int8_t rs_rssi_ctl[AR_MAX_CHAINS];
+ int8_t rs_rssi_ext[AR_MAX_CHAINS];
+ uint8_t rs_keyix;
+ uint8_t rs_rate;
+ uint8_t rs_antenna;
+ uint8_t rs_more;
+ uint8_t rs_isaggr;
+ uint8_t rs_moreaggr;
+ uint8_t rs_num_delims;
+ uint8_t rs_flags;
+#define AR_RXS_FLAG_GI 0x04
+#define AR_RXS_FLAG_2040 0x08
+
+ uint8_t rs_dummy;
+ uint32_t rs_evm[AR_MAX_CHAINS];
+} __packed __attribute__((aligned(4)));
+
+
+/*
+ * Driver definitions.
+ */
+#define ATHN_USB_RX_LIST_COUNT 1
+#define ATHN_USB_TX_LIST_COUNT (8 + 1) /* NB: +1 for beacons. */
+
+#define ATHN_USB_HOST_CMD_RING_COUNT 32
+
+#define ATHN_USB_RXBUFSZ (8 * 1024) /* XXX Linux 16K */
+#define ATHN_USB_TXBUFSZ \
+ ((sizeof(struct ar_stream_hdr) + \
+ sizeof(struct ar_htc_frame_hdr) + \
+ sizeof(struct ar_tx_frame) + \
+ IEEE80211_MAX_LEN + 3) & ~3)
+#define ATHN_USB_TXCMDSZ 512
+
+#define ATHN_USB_TX_TIMEOUT 5000 /* ms */
+#define ATHN_USB_CMD_TIMEOUT 500 /* ms */ // Originally 1000
+
+struct athn_usb_rx_stream {
+ struct mbuf *m;
+ int moff;
+ int left;
+};
+
+struct athn_usb_rx_data {
+ struct athn_usb_softc *sc;
+ struct usbd_xfer *xfer;
+ uint8_t *buf;
+};
+
+struct athn_usb_tx_data {
+ struct athn_usb_softc *sc;
+ struct usbd_xfer *xfer;
+ uint8_t *buf;
+ uint32_t len; // FreeBSD addition
+ TAILQ_ENTRY(athn_usb_tx_data) next;
+};
+
+struct athn_usb_host_cmd {
+ void (*cb)(struct athn_usb_softc *, void *);
+ uint8_t data[256];
+};
+
+struct athn_usb_cmd_newstate {
+ enum ieee80211_state state;
+ int arg;
+};
+
+struct athn_usb_cmd_key {
+ struct ieee80211_node *ni;
+ struct ieee80211_key *key;
+};
+
+struct athn_usb_aggr_cmd {
+ uint8_t sta_index;
+ uint8_t tid;
+};
+
+struct athn_usb_host_cmd_ring {
+ struct athn_usb_host_cmd cmd[ATHN_USB_HOST_CMD_RING_COUNT];
+ int cur;
+ int next;
+ int queued;
+};
+
+// XXX Should this be moved elsewhere?
+#define ATHN_USB_CMD_LIST_COUNT 1
+
+struct athn_usb_softc {
+ struct athn_softc sc_sc;
+#define usb_dev sc_sc.sc_dev
+ int sc_athn_attached;
+
+ /* USB specific goo. */
+ struct usb_device *sc_udev;
+ struct usb_interface *sc_iface;
+#if 0
+ struct usb_task sc_task;
+#endif
+
+ u_int flags;
+#define ATHN_USB_FLAG_AR7010 0x01
+
+ struct athn_usb_rx_stream rx_stream;
+
+ struct usbd_pipe *tx_data_pipe;
+ struct usbd_pipe *rx_data_pipe;
+ struct usbd_pipe *rx_intr_pipe;
+ struct usbd_pipe *tx_intr_pipe;
+ uint8_t *ibuf;
+ size_t ibuflen;
+
+ struct ar_wmi_cmd_reg_write wbuf[AR_MAX_WRITE_COUNT];
+ int wcount;
+
+ uint16_t wmi_seq_no;
+ uint16_t wait_cmd_id;
+ uint16_t wait_msg_id;
+ void *obuf;
+ struct ar_htc_msg_conn_svc_rsp *msg_conn_svc_rsp;
+
+ struct athn_usb_host_cmd_ring cmdq;
+ struct athn_usb_rx_data rx_data[ATHN_USB_RX_LIST_COUNT];
+ struct athn_usb_tx_data tx_data[ATHN_USB_TX_LIST_COUNT];
+ TAILQ_HEAD(, athn_usb_tx_data) tx_free_list;
+ struct athn_usb_tx_data tx_cmd;
+ struct athn_usb_tx_data *tx_bcn;
+
+ uint8_t ep_ctrl;
+ uint8_t ep_bcn;
+ uint8_t ep_cab;
+ uint8_t ep_uapsd;
+ uint8_t ep_mgmt;
+ uint8_t ep_data[EDCA_NUM_AC];
+#if 0
+#endif
+
+ /*
+ * Firmware cannot handle more than 8 STAs.
+ * We use a bitmask to keep track of available slots in the firmware's
+ * node array. A 1 bit at index N, as determined by ffs(3), means the
+ * slot at this index is available.
+ */
+ uint8_t free_node_slots;
+
+ void (*sc_node_free)(struct ieee80211com *,
+ struct ieee80211_node *);
+ int sc_key_tasks;
+
+ /* FreeBSD additions */
+// struct athn_data usc_cmd[ATHN_USB_CMD_LIST_COUNT];
+ struct usb_xfer *usc_xfer[ATHN_N_TRANSFERS];
+
+// STAILQ_HEAD(, athn_data) tx_intr_queue;
+};
diff --git a/sys/dev/athn/usb/if_athn_usb.c b/sys/dev/athn/usb/if_athn_usb.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/athn/usb/if_athn_usb.c
@@ -0,0 +1,3630 @@
+/* $OpenBSD: if_athn_usb.c,v 1.63 2021/11/22 10:17:14 mglocker Exp $ */
+
+/*-
+ * Copyright (c) 2022 Farhan Khan <khanzf@gmail.com>
+ * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr>
+ * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * USB front-end for Atheros AR9271 and AR7010 chipsets.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/linker.h>
+#include <sys/kdb.h>
+#include <sys/firmware.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include "usbdevs.h"
+
+#include <dev/athn/athnreg.h>
+#include <dev/athn/athnvar.h>
+
+#define ECDA_NUM_AC 4
+#include <dev/athn/usb/if_athn_usb.h>
+
+#include <sys/sockio.h> // Delete this
+
+MALLOC_DEFINE(M_ATHN_USB, "athn_usb", "athn usb private state");
+
+int debug_knob = 1;
+#define DEBUG_PRINTF(format, ...) if (debug_knob == 1) { printf("DEBUG: " format, ##__VA_ARGS__);}
+
+#if 0
+static const struct athn_usb_type {
+ struct usb_devno devno;
+ u_int flags;
+} athn_usb_devs[] = {
+ {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_AR9280 },
+ ATHN_USB_FLAG_AR7010 },
+ {{ USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_AR9287 },
+ ATHN_USB_FLAG_AR7010 },
+ {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_1 }},
+ {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_2 }},
+ {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_3 }},
+ {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9280 },
+ ATHN_USB_FLAG_AR7010 },
+ {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9287 },
+ ATHN_USB_FLAG_AR7010 },
+ {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_1 }},
+ {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_2 }},
+ {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_3 }},
+ {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_4 }},
+ {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_5 }},
+ {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_6 }},
+ {{ USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_AR9271 }},
+ {{ USB_VENDOR_LITEON, USB_PRODUCT_LITEON_AR9271 }},
+ {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1100 }},
+ {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3200 },
+ ATHN_USB_FLAG_AR7010 },
+ {{ USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_N5HBZ0000055 },
+ ATHN_USB_FLAG_AR7010 },
+ {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_UWABR100 },
+ ATHN_USB_FLAG_AR7010 },
+ {{ USB_VENDOR_VIA, USB_PRODUCT_VIA_AR9271 }}
+};
+#define athn_usb_lookup(v, p) \
+ ((const struct athn_usb_type *)usb_lookup(athn_usb_devs, v, p))
+#endif
+
+static int athn_usb_match(device_t);
+static int athn_usb_attach(device_t);
+int athn_usb_detach(device_t);
+static int athn_usb_attachhook(device_t);
+int athn_usb_open_pipes(struct athn_usb_softc *, device_t);
+void athn_usb_close_pipes(struct athn_usb_softc *);
+int athn_usb_alloc_rx_list(struct athn_usb_softc *);
+void athn_usb_free_rx_list(struct athn_usb_softc *);
+int athn_usb_alloc_tx_list(struct athn_usb_softc *);
+void athn_usb_free_tx_list(struct athn_usb_softc *);
+int athn_usb_alloc_tx_cmd(struct athn_usb_softc *);
+void athn_usb_free_tx_cmd(struct athn_usb_softc *);
+//void athn_usb_task(void *);
+static void athn_cmdq_cb(void *, int);
+void athn_usb_do_async(struct athn_usb_softc *,
+ void (*)(struct athn_usb_softc *, void *), void *, int);
+void athn_usb_wait_async(struct athn_usb_softc *);
+int athn_usb_load_firmware(struct athn_usb_softc *);
+int athn_usb_htc_msg(struct athn_usb_softc *, uint16_t, void *,
+ int);
+int athn_usb_htc_setup(struct athn_usb_softc *);
+int athn_usb_htc_connect_svc(struct athn_usb_softc *, uint16_t,
+ uint8_t, uint8_t, uint8_t *);
+int athn_usb_wmi_xcmd(struct athn_usb_softc *, uint16_t, void *,
+ int, void *);
+int athn_usb_read_rom(struct athn_softc *);
+uint32_t athn_usb_read(struct athn_softc *, uint32_t);
+void athn_usb_write(struct athn_softc *, uint32_t, uint32_t);
+void athn_usb_write_barrier(struct athn_softc *);
+int athn_usb_media_change(struct ifnet *);
+void athn_usb_next_scan(void *);
+int athn_usb_newstate(struct ieee80211com *, enum ieee80211_state,
+ int);
+void athn_usb_newstate_cb(struct athn_usb_softc *, void *);
+void athn_usb_newassoc(struct ieee80211_node *, int);
+void athn_usb_newassoc_cb(struct athn_usb_softc *, void *);
+struct ieee80211_node *athn_usb_node_alloc(struct ieee80211vap *, const uint8_t mac[IEEE80211_ADDR_LEN]);
+void athn_usb_count_active_sta(void *, struct ieee80211_node *);
+void athn_usb_newauth_cb(struct athn_usb_softc *, void *);
+int athn_usb_newauth(struct ieee80211com *,
+ struct ieee80211_node *, int, uint16_t);
+void athn_usb_node_free(struct ieee80211com *,
+ struct ieee80211_node *);
+void athn_usb_node_free_cb(struct athn_usb_softc *, void *);
+int athn_usb_ampdu_tx_start(struct ieee80211com *,
+ struct ieee80211_node *, uint8_t);
+void athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *, void *);
+void athn_usb_ampdu_tx_stop(struct ieee80211com *,
+ struct ieee80211_node *, uint8_t);
+void athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *, void *);
+void athn_usb_clean_nodes(void *, struct ieee80211_node *);
+int athn_usb_create_node(struct athn_usb_softc *,
+ struct ieee80211_node *);
+int athn_usb_node_set_rates(struct athn_usb_softc *,
+ struct ieee80211_node *);
+int athn_usb_remove_node(struct athn_usb_softc *,
+ struct ieee80211_node *);
+void athn_usb_rx_enable(struct athn_softc *);
+int athn_set_chan(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *);
+int athn_usb_switch_chan(struct athn_softc *,
+ struct ieee80211_channel *, struct ieee80211_channel *);
+void athn_usb_updateedca(struct ieee80211com *);
+void athn_usb_updateedca_cb(struct athn_usb_softc *, void *);
+void athn_usb_updateslot(struct ieee80211com *);
+void athn_usb_updateslot_cb(struct athn_usb_softc *, void *);
+int athn_usb_set_key(struct ieee80211vap *, const struct ieee80211_key *);
+void athn_usb_set_key_cb(struct athn_usb_softc *, void *);
+int athn_usb_delete_key(struct ieee80211vap *, const struct ieee80211_key *);
+void athn_usb_delete_key_cb(struct athn_usb_softc *, void *);
+void athn_usb_bcneof(struct usbd_xfer *, void *);
+void athn_usb_swba(struct athn_usb_softc *);
+void athn_usb_tx_status(void *, struct ieee80211_node *);
+void athn_usb_rx_wmi_ctrl(struct athn_usb_softc *, uint8_t *, int);
+void athn_usb_intr(struct usb_xfer *, usb_error_t);
+void athn_usb_rx_radiotap(struct athn_softc *, struct mbuf *,
+ struct ar_rx_status *);
+void athn_usb_rx_frame(struct athn_usb_softc *, struct mbuf *);
+// struct mbuf_list *);
+void athn_usb_rxeof(struct usbd_xfer *, void *);
+void athn_usb_txeof(struct usbd_xfer *, void *);
+int athn_usb_tx(struct athn_softc *, struct mbuf *,
+ struct ieee80211_node *);
+void athn_usb_start(struct ifnet *);
+void athn_usb_watchdog(struct ifnet *);
+int athn_usb_ioctl(struct ieee80211com *, u_long, void *);
+int athn_usb_init(struct athn_softc *);
+static int athn_usb_stop(struct athn_usb_softc *);
+void ar9271_load_ani(struct athn_softc *);
+int ar5008_ccmp_decap(struct athn_softc *, struct mbuf *,
+ struct ieee80211_node *);
+int ar5008_ccmp_encap(struct mbuf *, u_int, struct ieee80211_key *);
+
+/* Shortcut. */
+#define athn_usb_wmi_cmd(sc, cmd_id) \
+ athn_usb_wmi_xcmd(sc, cmd_id, NULL, 0, NULL)
+
+/* Extern functions. */
+void athn_led_init(struct athn_softc *);
+void athn_set_led(struct athn_softc *, int);
+void athn_btcoex_init(struct athn_softc *);
+void athn_set_rxfilter(struct athn_softc *, uint32_t);
+int athn_reset(struct athn_softc *, int);
+void athn_init_pll(struct athn_softc *,
+ const struct ieee80211_channel *);
+int athn_set_power_awake(struct athn_softc *);
+void athn_set_power_sleep(struct athn_softc *);
+void athn_reset_key(struct athn_softc *, int);
+int athn_set_key(struct ieee80211com *, struct ieee80211_node *,
+ struct ieee80211_key *);
+void athn_delete_key(struct ieee80211com *, struct ieee80211_node *,
+ struct ieee80211_key *);
+void athn_rx_start(struct athn_softc *);
+void athn_set_sta_timers(struct athn_softc *);
+void athn_set_hostap_timers(struct athn_softc *);
+void athn_set_opmode(struct athn_softc *);
+void athn_set_bss(struct athn_softc *, struct ieee80211_node *);
+int athn_hw_reset(struct athn_softc *, struct ieee80211_channel *,
+ struct ieee80211_channel *, int);
+void athn_updateedca(struct ieee80211com *);
+void athn_updateslot(struct ieee80211com *);
+
+
+/* FreeBSD additions */
+//void athn_intr_rx_callback(struct usb_xfer *, usb_error_t);
+void athn_intr_tx_callback(struct usb_xfer *, usb_error_t);
+void athn_data_rx_callback(struct usb_xfer *, usb_error_t);
+void athn_data_tx_callback(struct usb_xfer *, usb_error_t);
+
+#define ATHN_USB_DEV(v, p) { USB_VPI(v, p, 0) }
+static const STRUCT_USB_HOST_ID athn_devs[] = {
+ ATHN_USB_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271U)
+};
+
+
+#if 0
+const struct cfattach athn_usb_ca = {
+ sizeof(struct athn_usb_softc),
+ athn_usb_match,
+ athn_usb_attach,
+ athn_usb_detach
+};
+#endif
+
+#define ATHN_CONFIG_INDEX 0
+
+static const struct usb_config athn_config_common[ATHN_N_TRANSFERS] = {
+ [ATHN_TX_DATA] = {
+ .type = UE_BULK,
+ .endpoint = 0x01, // AR_PIPE_TX_DATA,
+ .direction = UE_DIR_TX,
+ .flags = {
+ .short_xfer_ok = 1,
+// .force_short_xfer = 1,
+ .pipe_bof = 1
+ },
+ .callback = athn_data_tx_callback,
+ .bufsize = 0x200,
+ },
+ [ATHN_RX_DATA] = {
+ .type = UE_BULK,
+ .endpoint = 0x82, //AR_PIPE_RX_DATA,
+ .direction = UE_DIR_RX,
+ .flags = {
+ .short_xfer_ok = 1,
+// .force_short_xfer = 1,
+ .pipe_bof = 1
+ },
+ .callback = athn_data_rx_callback,
+ .bufsize = 0x200,
+ },
+ [ATHN_RX_INTR] = {
+ .type = UE_INTERRUPT,
+ .endpoint = 0x83, // AR_PIPE_RX_INTR,
+ .direction = UE_DIR_RX,
+ .flags = {
+ .short_xfer_ok = 1,
+// .force_short_xfer = 1,
+ .pipe_bof = 1
+ },
+ .callback = athn_usb_intr,
+ .bufsize = 0x40,
+// .callback = athn_intr_rx_callback,
+// .interval = USB_DEFAULT_INTERVAL,
+ },
+ [ATHN_TX_INTR] = {
+ .type = UE_INTERRUPT,
+ .endpoint = 0x04, //AR_PIPE_TX_INTR,
+ .direction = UE_DIR_TX,
+ .flags = {
+// .short_xfer_ok = 1,
+// .force_short_xfer = 1,
+ .pipe_bof = 1
+ },
+ .callback= athn_intr_tx_callback,
+ .bufsize = 512, // 200, //40,
+ .timeout = ATHN_USB_CMD_TIMEOUT,
+// .interval = 1,
+ }
+};
+
+/* FreeBSD additions */
+void
+athn_data_rx_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+ int actlen;
+// struct usb_page_cache *pc;
+ usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+ switch(USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ /* XXX Fall through */
+ case USB_ST_SETUP:
+ //pc = usbd_xfer_get_frame(xfer, 0);
+ usbd_xfer_get_frame(xfer, 0);
+ usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
+ usbd_transfer_submit(xfer);
+ break;
+ default: /* Error */
+ break;
+ }
+
+ return;
+}
+
+
+/* FreeBSD additions */
+void
+athn_data_tx_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+ int actlen;
+
+ usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+ switch(USB_GET_STATE(xfer)) {
+ case USB_ST_SETUP:
+ usbd_transfer_submit(xfer);
+ break;
+ case USB_ST_TRANSFERRED:
+ break;
+ default: /* Error */
+ break;
+ }
+
+ return;
+}
+
+/* FreeBSD additions */
+void
+athn_intr_tx_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+ int actlen;
+ struct athn_usb_softc *usc = usbd_xfer_softc(xfer);
+ struct athn_usb_tx_data *data = &usc->tx_cmd;
+
+// struct athn_data *data;
+ usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+ switch(USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+
+ /* It seems like something else should go here, but not certain */
+ /* Not implementing fallthrough for this */
+// msg->msg_id = htobe16(msg_id);
+ break;
+ case USB_ST_SETUP:
+/*
+ if (data == NULL) {
+ printf("Empty pending queue?\n");
+ // DPRINTF(SC, ATHN_DEBUG_XMIT,
+ // "%s: empty pending queue\n", __func__);
+ return;
+ }
+
+ STAILQ_REMOVE_HEAD(&usc->tx_intr_queue, next);
+
+*/
+
+ usbd_xfer_set_frame_data(xfer, 0, data->buf, data->len);
+// usbd_xfer_set_frames(xfer, 2);
+// usbd_xfer_set_stall(xfer);
+ usbd_transfer_submit(xfer);
+ // STAILQ_FOREACH(cur_data, &sc_tx_intr_active, next) {
+
+
+ // }
+
+
+
+// usbd_xfer_set_frame_data(xfer, 0, data->buf,
+// usbd_xfer_max_len(xfer));
+// usbd_transfer_submit(xfer);
+ break;
+ default: /* Error */
+ break;
+ }
+
+ return;
+}
+/* End of FreeBSD additions */
+
+static int
+athn_usb_match(device_t self)
+{
+ struct usb_attach_arg *uaa = device_get_ivars(self);
+
+ if (uaa->usb_mode != USB_MODE_HOST)
+ return (ENXIO);
+ if (uaa->info.bConfigIndex != ATHN_CONFIG_INDEX)
+ return (ENXIO);
+ if (uaa->info.bIfaceIndex != ATHN_IFACE_INDEX)
+ return (ENXIO);
+
+ return (usbd_lookup_id_by_uaa(athn_devs, sizeof(athn_devs), uaa));
+}
+
+static int
+athn_usb_resume(device_t self)
+{
+ return 0;
+}
+
+static int
+athn_usb_attach(device_t self)
+{
+ struct usb_attach_arg *uaa = device_get_ivars(self);
+ struct athn_usb_softc *usc = device_get_softc(self);
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ int error;
+
+ ic->ic_name = device_get_nameunit(self);
+
+ usc->sc_udev = uaa->device;
+ usc->sc_iface = uaa->iface;
+ sc->sc_dev = self;
+
+ //usc->flags = athn_usb_lookup(uaa->vendor, uaa->product)->flags; // OpenBSD
+ usc->flags = 0x0;
+ sc->flags |= ATHN_FLAG_USB;
+#ifdef notyet
+ /* Check if it is a combo WiFi+Bluetooth (WB193) device. */
+ if (strncmp(product, "wb193", 5) == 0)
+ sc->flags |= ATHN_FLAG_BTCOEX3WIRE;
+#endif
+
+ sc->ops.read = athn_usb_read;
+ sc->ops.write = athn_usb_write;
+ sc->ops.write_barrier = athn_usb_write_barrier;
+
+ sc->sc_init = athn_usb_init;
+
+ athn_usb_attach_private(usc, USB_GET_DRIVER_INFO(uaa));
+
+ // OpenBSD below
+ //usb_init_task(&usc->sc_task, athn_usb_task, sc, USB_TASK_TYPE_GENERIC);
+ // FreeBSD side
+ mtx_init(&sc->sc_mtx, ic->ic_name, MTX_NETWORK_LOCK, MTX_DEF);
+ ATHN_CMDQ_LOCK_INIT(sc);
+ TASK_INIT(&sc->cmdq_task, 0, athn_cmdq_cb, sc);
+
+ if (athn_usb_open_pipes(usc, self) != 0)
+ goto fail;
+
+// STAILQ_INIT(&usc->tx_intr_queue);
+
+ /* Allocate xfer for firmware commands. */
+ error = athn_usb_alloc_tx_cmd(usc);
+ if (error)
+ goto fail;
+
+// config_mountroot(self, athn_usb_attachhook);
+ error = athn_usb_attachhook(self);
+ if (error) {
+ goto fail;
+ }
+ DEBUG_PRINTF("Disabling auto-delete!!\n");
+// goto fail;
+ return 0;
+
+fail:
+ DEBUG_PRINTF("Detaching...\n");
+ athn_usb_detach(self);
+ return (ENXIO);
+}
+
+int
+athn_usb_detach(device_t self)
+{
+ struct athn_usb_softc *usc = device_get_softc(self);
+ struct athn_softc *sc = &usc->sc_sc;
+
+ printf("Destroy!\n");
+ usbd_transfer_unsetup(usc->usc_xfer, ATHN_N_TRANSFERS);
+ mtx_destroy(&sc->sc_mtx);
+ DEBUG_PRINTF("Destroy\n");
+ printf("End of athn_usb_detach\n");
+ return 0;
+#if 0
+ struct athn_usb_softc *usc = (struct athn_usb_softc *)self;
+ struct athn_softc *sc = &usc->sc_sc;
+
+ if (usc->sc_athn_attached)
+ athn_detach(sc);
+
+ /* Wait for all async commands to complete. */
+ athn_usb_wait_async(usc);
+
+ usbd_ref_wait(usc->sc_udev);
+
+ /* Abort and close Tx/Rx pipes. */
+ athn_usb_close_pipes(usc);
+
+ /* Free Tx/Rx buffers. */
+ athn_usb_free_tx_cmd(usc);
+ athn_usb_free_tx_list(usc);
+ athn_usb_free_rx_list(usc);
+
+ return (0);
+#endif
+}
+
+static void
+athn_usb_vap_delete(struct ieee80211vap *vap)
+{
+ DEBUG_PRINTF("athn_usb_vap_delete Unimplemented! Memory leak\n");
+}
+
+static struct ieee80211vap *
+athn_usb_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
+ enum ieee80211_opmode opmode, int flags,
+ const uint8_t bssid[IEEE80211_ADDR_LEN],
+ const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+// struct athn_softc *sc = ic->ic_softc;
+ struct athn_vap *avp;
+ struct ieee80211vap *vap;
+// struct ifnet *ifp;
+
+ /* From zyd and rsu, not sure if this applies to athn */
+// if (!TAILQ_EMPTY(&ic->ic_vaps)) {
+// DEBUG_PRINF("VAP create returns null\n");
+// return (NULL);
+// }
+
+ if (opmode == IEEE80211_M_MONITOR) {
+ DEBUG_PRINTF("monitor mode\n");
+ }
+
+ avp = malloc(sizeof(struct athn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
+ vap = &avp->vap;
+
+ if(ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid) != 0) {
+ DEBUG_PRINTF("ieee80211_vap_setup failed\n");
+ free(avp, M_80211_VAP);
+ return (NULL);
+ }
+
+ /* override state transition machine */
+ avp->newstate = vap->iv_newstate;
+ vap->iv_newstate = athn_newstate;
+
+// vap->vp_set_key = athn_usb_set_key;
+// vap->vp_delete_key = athn_usb_delete_key;
+
+/*
+ vap->iv_update_beacon = ??
+ vap->iv_reset = ??
+ vap->iv_key_alloc = ??
+ vap->iv_key_set = athn_usb_set_key;
+ vap->iv_key_delete = athn_usb_delete_key;
+ vap->iv_max_aid = ??
+
+ vap->iv_ampdu_density = ??
+ vap->iv_ampdu_rxmax = ??
+
+ vap->iv_recv_mgmt = ??
+*/
+
+ ieee80211_vap_attach(vap, athn_usb_media_change, //ieee80211_media_change,
+ ieee80211_media_status, mac);
+ ic->ic_opmode = opmode;
+
+ /* BUS-specific additions */
+ //vap->iv_key_delete = sc->sc_key_delete;
+ //vap->iv_key_set = sc->sc_key_set;
+
+ return(vap);
+
+ //ifp = vap->iv_ifp;
+ //ifp->if_capabilities = ???;
+}
+
+int
+athn_usb_attachhook(device_t self)
+{
+// struct usb_attach_arg *uaa = device_get_ivars(self);
+ struct athn_usb_softc *usc = device_get_softc(self);
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct athn_ops *ops = &sc->ops;
+// struct ieee80211com *ic = &sc->sc_ic;
+// struct ifnet *ifp = &ic->ic_if;
+// int s, i, error;
+ int error;
+
+ ic->ic_softc = sc;
+
+ /* Load firmware. */
+ debug_knob = 0;
+ error = athn_usb_load_firmware(usc);
+ if (error != 0) {
+ device_printf(sc->sc_dev, "could not load firmware\n");
+ return(ENXIO);
+ }
+
+ /* Setup the host transport communication interface. */
+ error = athn_usb_htc_setup(usc);
+ if (error != 0) {
+ return(ENXIO);
+ }
+
+ /* We're now ready to attach the bus agnostic driver. */
+ sc->sc_key_delete = athn_usb_delete_key;
+ sc->sc_key_set = athn_usb_set_key;
+
+ error = athn_attach(sc);
+ if (error != 0) {
+ return (ENXIO);
+ }
+ usc->sc_athn_attached = 1;
+ /* Override some operations for USB. */
+
+ // Attach VAP-specific "stuff"
+ ic->ic_vap_create = athn_usb_vap_create;
+ ic->ic_vap_delete = athn_usb_vap_delete; // Not finished
+// ic->ic_ioctl = athn_usb_ioctl;
+// ifp->if_start = athn_usb_start;
+// ifp->if_watchdog = athn_usb_watchdog;
+ ic->ic_node_alloc = athn_usb_node_alloc;
+// ic->ic_newauth = athn_usb_newauth;
+ ic->ic_newassoc = athn_usb_newassoc;
+#ifndef IEEE80211_STA_ONLY
+// usc->sc_node_free = ic->ic_node_free; // No OpenBSD equivalent?
+// ic->ic_node_free = athn_usb_node_free; // No OpenBSD equivalent?
+#endif
+// ic->ic_updateslot = athn_usb_updateslot;
+// ic->ic_updateedca = athn_usb_updateedca;
+
+// vp->vp_set_key = athn_usb_set_key;
+// vp->vp_delete_key = athn_usb_delete_key; // For VAP
+// ic->ic_set_key = athn_usb_set_key; // For VAP
+// ic->ic_delete_key = athn_usb_delete_key; // For VAP
+#ifdef notyet
+ ic->ic_ampdu_tx_start = athn_usb_ampdu_tx_start; // For VAP
+ ic->ic_ampdu_tx_stop = athn_usb_ampdu_tx_stop; // For VAP
+#endif
+// ic->ic_newstate = athn_usb_newstate;
+#if 0
+ ic->ic_media.ifm_change = athn_usb_media_change;
+ timeout_set(&sc->scan_to, athn_usb_next_scan, usc);
+
+ ops->rx_enable = athn_usb_rx_enable;
+#endif
+
+ /* Reset HW key cache entries. */
+ int i; // XXX In the future move this integer back up
+// sc->kc_entries = 10;
+ for (i = 0; i < sc->kc_entries; i++)
+ athn_reset_key(sc, i);
+
+ ops->enable_antenna_diversity(sc);
+
+#ifdef ATHN_BT_COEXISTENCE
+ /* Configure bluetooth coexistence for combo chips. */
+ if (sc->flags & ATHN_FLAG_BTCOEX)
+ athn_btcoex_init(sc);
+#endif
+ /* Configure LED. */
+ athn_led_init(sc);
+
+// if (bootverbose)
+ ieee80211_announce(ic);
+
+ return 0;
+}
+
+int
+athn_usb_open_pipes(struct athn_usb_softc *usc, device_t dev)
+{
+// struct usb_config *rtwn_config;
+ struct athn_softc *sc = &usc->sc_sc;
+// const uint8_t iface_index = ATHN_IFACE_INDEX;
+// struct usb_endpoint *ep, *ep_end;
+//#define ATHN_MAX_EPOUT 4 // Move to header file
+// uint8_t addr[ATHN_MAX_EPOUT];
+ struct usb_attach_arg *uaa = device_get_ivars(dev);
+ int error;
+ int isize;
+ uint8_t iface_index = ATHN_IFACE_INDEX;
+ int ret = ENXIO;
+
+ error = usbd_transfer_setup(uaa->device, &iface_index, usc->usc_xfer,
+ athn_config_common, ATHN_N_TRANSFERS, sc, &sc->sc_mtx);
+ if (error) {
+ device_printf(dev, "could not allocate USB transfers, "
+ "err=%s\n", usbd_errstr(error));
+ ret = ENXIO;
+ return (ret);
+ }
+
+ // OpenBSD side has this getting the max size manually
+ //
+ //ed = usbd_get_endpoint_descriptor(usc->sc_iface, AR_PIPE_RX_INTR);
+ //isize = UGETW(ed->wMaxPacketSize);
+
+ //
+ //
+
+ isize = 1 * 64; // Currently hard-coding this value
+ usc->ibuflen = isize;
+ usc->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
+
+// ATHN_LOCK(sc);
+ // Commenting out after wireshark analysis
+// usbd_transfer_start(usc->usc_xfer[ATHN_RX_INTR]);
+// usbd_transfer_start(usc->usc_xfer[ATHN_RX_DATA]);
+// usbd_transfer_start(usc->usc_xfer[ATHN_TX_INTR]);
+// usbd_transfer_start(usc->usc_xfer[ATHN_TX_DATA]);
+// ATHN_UNLOCK(sc);
+
+ return 0;
+#if 0
+ usb_endpoint_descriptor_t *ed;
+ int isize, error;
+
+ error = usbd_open_pipe(usc->sc_iface, AR_PIPE_TX_DATA, 0,
+ &usc->tx_data_pipe);
+ if (error != 0) {
+ printf("%s: could not open Tx bulk pipe\n",
+ usc->usb_dev.dv_xname);
+ goto fail;
+ }
+
+ error = usbd_open_pipe(usc->sc_iface, AR_PIPE_RX_DATA, 0,
+ &usc->rx_data_pipe);
+ if (error != 0) {
+ printf("%s: could not open Rx bulk pipe\n",
+ usc->usb_dev.dv_xname);
+ goto fail;
+ }
+
+ ed = usbd_get_endpoint_descriptor(usc->sc_iface, AR_PIPE_RX_INTR);
+ if (ed == NULL) {
+ printf("%s: could not retrieve Rx intr pipe descriptor\n",
+ usc->usb_dev.dv_xname);
+ goto fail;
+ }
+ isize = UGETW(ed->wMaxPacketSize);
+ if (isize == 0) {
+ printf("%s: invalid Rx intr pipe descriptor\n",
+ usc->usb_dev.dv_xname);
+ goto fail;
+ }
+ usc->ibuf = malloc(isize, M_USBDEV, M_NOWAIT);
+ if (usc->ibuf == NULL) {
+ printf("%s: could not allocate Rx intr buffer\n",
+ usc->usb_dev.dv_xname);
+ goto fail;
+ }
+ usc->ibuflen = isize;
+ error = usbd_open_pipe_intr(usc->sc_iface, AR_PIPE_RX_INTR,
+ USBD_SHORT_XFER_OK, &usc->rx_intr_pipe, usc, usc->ibuf, isize,
+ athn_usb_intr, USBD_DEFAULT_INTERVAL);
+ if (error != 0) {
+ printf("%s: could not open Rx intr pipe\n",
+ usc->usb_dev.dv_xname);
+ goto fail;
+ }
+
+ error = usbd_open_pipe(usc->sc_iface, AR_PIPE_TX_INTR, 0,
+ &usc->tx_intr_pipe);
+ if (error != 0) {
+ printf("%s: could not open Tx intr pipe\n",
+ usc->usb_dev.dv_xname);
+ goto fail;
+ }
+ fail:
+ if (error != 0)
+ athn_usb_close_pipes(usc);
+ return (error);
+#endif
+}
+
+void
+athn_usb_close_pipes(struct athn_usb_softc *usc)
+{
+ DEBUG_PRINTF("Unimplemented: %s:%d\n", __func__, __LINE__);
+#if 0
+ if (usc->tx_data_pipe != NULL) {
+ usbd_close_pipe(usc->tx_data_pipe);
+ usc->tx_data_pipe = NULL;
+ }
+ if (usc->rx_data_pipe != NULL) {
+ usbd_close_pipe(usc->rx_data_pipe);
+ usc->rx_data_pipe = NULL;
+ }
+ if (usc->tx_intr_pipe != NULL) {
+ usbd_close_pipe(usc->tx_intr_pipe);
+ usc->tx_intr_pipe = NULL;
+ }
+ if (usc->rx_intr_pipe != NULL) {
+ usbd_close_pipe(usc->rx_intr_pipe);
+ usc->rx_intr_pipe = NULL;
+ }
+ if (usc->ibuf != NULL) {
+ free(usc->ibuf, M_USBDEV, usc->ibuflen);
+ usc->ibuf = NULL;
+ }
+#endif
+}
+
+int
+athn_usb_alloc_rx_list(struct athn_usb_softc *usc)
+{
+#if 0
+ printf("Unimplemented: %s:%d\n", __func__, __LINE__);
+ return 0;
+#else
+ struct athn_usb_rx_data *data;
+ int i, error = 0;
+
+ printf("athn_usb_alloc_rx_list start\n");
+
+ for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) {
+ data = &usc->rx_data[i];
+
+ data->sc = usc; /* Backpointer for callbacks. */
+
+ // XXX This seems to setup an auto-transfer to USB,
+ // but FreeBSD has a totally different model.
+ // I need to verify how this should be done.
+/*
+ data->xfer = usbd_alloc_xfer(usc->sc_udev);
+ if (data->xfer == NULL) {
+ printf("%s: could not allocate xfer\n",
+ usc->usb_dev.dv_xname);
+ error = ENOMEM;
+ break;
+ }
+*/
+ data->buf = malloc(ATHN_USB_RXBUFSZ, M_USBDEV, M_NOWAIT);
+ if (data->buf == NULL) {
+ printf(": could not allocate xfer buffer\n"); //,
+ error = ENOMEM;
+ break;
+ }
+ }
+ if (error != 0) {
+ printf("athn_usb_free_rx_list prego\n");
+ athn_usb_free_rx_list(usc);
+ }
+ return (error);
+#endif
+}
+
+void
+athn_usb_free_rx_list(struct athn_usb_softc *usc)
+{
+ printf("Unimplemented: %s:%d\n", __func__, __LINE__);
+#if 0
+ int i;
+
+ /* NB: Caller must abort pipe first. */
+ for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) {
+ if (usc->rx_data[i].xfer != NULL)
+ usbd_free_xfer(usc->rx_data[i].xfer);
+ usc->rx_data[i].xfer = NULL;
+ }
+#endif
+}
+
+int
+athn_usb_alloc_tx_list(struct athn_usb_softc *usc)
+{
+#if 0
+ printf("Tracing: %s:%d\n", __func__, __LINE__);
+ return 0;
+#else
+ struct athn_usb_tx_data *data;
+ int i, error = 0;
+
+ TAILQ_INIT(&usc->tx_free_list);
+ for (i = 0; i < ATHN_USB_TX_LIST_COUNT; i++) {
+ data = &usc->tx_data[i];
+
+ data->sc = usc; /* Backpointer for callbacks. */
+
+ // XXX This seems to setup an auto-transfer to USB,
+ // but FreeBSD has a totally different model.
+ // I need to verify how this should be done.
+/*
+ data->xfer = usbd_alloc_xfer(usc->sc_udev);
+ if (data->xfer == NULL) {
+ printf("%s: could not allocate xfer\n",
+ usc->usb_dev.dv_xname);
+ error = ENOMEM;
+ break;
+ }
+*/
+ data->buf = malloc(ATHN_USB_TXBUFSZ, M_USBDEV, M_NOWAIT);
+ // OpenBSD
+ //data->buf = usbd_alloc_buffer(data->xfer, ATHN_USB_TXBUFSZ);
+ if (data->buf == NULL) {
+ printf(": could not allocate xfer buffer\n");
+// printf("%s: could not allocate xfer buffer\n",
+// usc->usb_dev.dv_xname);
+ error = ENOMEM;
+ break;
+ }
+ /* Append this Tx buffer to our free list. */
+ TAILQ_INSERT_TAIL(&usc->tx_free_list, data, next);
+ }
+ if (error != 0)
+ athn_usb_free_tx_list(usc);
+ return (error);
+#endif
+}
+
+void
+athn_usb_free_tx_list(struct athn_usb_softc *usc)
+{
+#if 0
+ int i;
+
+ /* NB: Caller must abort pipe first. */
+ for (i = 0; i < ATHN_USB_TX_LIST_COUNT; i++) {
+ if (usc->tx_data[i].xfer != NULL)
+ usbd_free_xfer(usc->tx_data[i].xfer);
+ usc->tx_data[i].xfer = NULL;
+ }
+#endif
+}
+
+int
+athn_usb_alloc_tx_cmd(struct athn_usb_softc *usc)
+{
+// struct athn_softc *sc = &usc->sc_sc;
+// int error;
+
+// error = athn_usb_alloc_list(sc, usc->usc_cmd,
+// ATHN_USB_CMD_LIST_COUNT, ATHN_USB_TXCMDSZ);
+// if (error)
+// return (error);
+
+ // STAILQ stuff
+
+ struct athn_usb_tx_data *data = &usc->tx_cmd;
+
+ data->sc = usc; /* Backpointer for callbacks. */
+
+ data->xfer = malloc(ATHN_USB_TXBUFSZ, M_USBDEV, M_NOWAIT | M_ZERO);
+ if (data->xfer == NULL) {
+ printf(": could not allocate xfer\n");
+ return (ENOMEM);
+ }
+
+ data->buf = malloc(ATHN_USB_TXCMDSZ, M_USBDEV, M_NOWAIT | M_ZERO);
+ if (data->buf == NULL) {
+ printf(": could not allocate xfer buffer\n");
+ return (ENOMEM);
+ }
+ return (0);
+}
+
+void
+athn_usb_free_tx_cmd(struct athn_usb_softc *usc)
+{
+#if 0
+ if (usc->tx_cmd.xfer != NULL)
+ usbd_free_xfer(usc->tx_cmd.xfer);
+ usc->tx_cmd.xfer = NULL;
+#endif
+}
+
+//athn_usb_task(void *arg)
+void
+athn_cmdq_cb(void *arg, int pending)
+{
+ // Based on rtwn_cmdq_cb from if_rtwn_task.c
+ printf("athn_cmdq_cb unimplemented\n");
+#if 0
+ struct athn_usb_softc *usc = arg;
+ struct athn_usb_host_cmd_ring *ring = &usc->cmdq;
+ struct athn_usb_host_cmd *cmd;
+ int s;
+
+ /* Process host commands. */
+ s = splusb();
+ while (ring->next != ring->cur) {
+ cmd = &ring->cmd[ring->next];
+ splx(s);
+ /* Invoke callback. */
+ cmd->cb(usc, cmd->data);
+ s = splusb();
+ ring->queued--;
+ ring->next = (ring->next + 1) % ATHN_USB_HOST_CMD_RING_COUNT;
+ }
+ splx(s);
+#endif
+}
+
+void
+athn_usb_do_async(struct athn_usb_softc *usc,
+ void (*cb)(struct athn_usb_softc *, void *), void *arg, int len)
+{
+#if 0
+ struct athn_usb_host_cmd_ring *ring = &usc->cmdq;
+ struct athn_usb_host_cmd *cmd;
+ int s;
+
+ if (ring->queued == ATHN_USB_HOST_CMD_RING_COUNT) {
+ printf("%s: host cmd queue overrun\n", usc->usb_dev.dv_xname);
+ return; /* XXX */
+ }
+
+ s = splusb();
+ cmd = &ring->cmd[ring->cur];
+ cmd->cb = cb;
+ KASSERT(len <= sizeof(cmd->data));
+ memcpy(cmd->data, arg, len);
+ ring->cur = (ring->cur + 1) % ATHN_USB_HOST_CMD_RING_COUNT;
+
+ /* If there is no pending command already, schedule a task. */
+ if (++ring->queued == 1)
+ usb_add_task(usc->sc_udev, &usc->sc_task);
+ splx(s);
+#endif
+}
+
+void
+athn_usb_wait_async(struct athn_usb_softc *usc)
+{
+#if 0
+ /* Wait for all queued asynchronous commands to complete. */
+ usb_wait_task(usc->sc_udev, &usc->sc_task);
+#endif
+}
+
+int
+athn_usb_load_firmware(struct athn_usb_softc *usc)
+{
+ struct athn_softc *sc = &usc->sc_sc;
+ usb_device_request_t req;
+ char *ptr;
+ const struct firmware *fw;
+ int mlen, error, size;
+ uint32_t addr;
+
+ error = 0;
+
+ /* Determine which firmware image to load. */
+ /*
+ if (usc->flags & ATHN_USB_FLAG_AR7010) {
+ dd = usbd_get_device_descriptor(usc->sc_udev);
+ name = "athn-open-ar7010";
+ } else {
+ name = "athn-open-ar9271";
+ }
+ */
+
+ /* Read firmware image from the filesystem */
+ ATHN_LOCK(sc);
+ fw = firmware_get(sc->fwname);
+ DEBUG_PRINTF("The size of the fw is: %zu\n", fw->datasize);
+ ATHN_UNLOCK(sc);
+ if (fw == NULL) {
+ device_printf(sc->sc_dev, "failed to load of file %s\n", sc->fwname);
+ return (ENOENT);
+ }
+
+ ptr = __DECONST(char *, fw->data);
+ addr = AR9271_FIRMWARE >> 8;
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = AR_FW_DOWNLOAD;
+ USETW(req.wIndex, 0);
+ size = fw->datasize;
+ ATHN_LOCK(sc);
+ while (size > 0) {
+ mlen = MIN(size, 4096);
+
+ USETW(req.wValue, addr);
+ USETW(req.wLength, mlen);
+ if (usbd_do_request_flags(usc->sc_udev, &sc->sc_mtx,
+ &req, ptr, 0, NULL, 250) != 0) {
+ error = EIO;
+ break;
+ }
+ addr += mlen >> 8;
+ ptr += mlen;
+ size -= mlen;
+ }
+ ATHN_UNLOCK(sc);
+
+ addr = AR9271_FIRMWARE_TEXT >> 8;
+
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = AR_FW_DOWNLOAD_COMP;
+ USETW(req.wIndex, 0);
+ USETW(req.wValue, addr);
+ USETW(req.wLength, 0);
+ usc->wait_msg_id = AR_HTC_MSG_READY;
+ ATHN_LOCK(sc);
+ error = usbd_do_request(usc->sc_udev, &sc->sc_mtx, &req, NULL);
+// usbd_transfer_start(RX_INTR); //////////////////////////////
+ usbd_transfer_start(usc->usc_xfer[ATHN_RX_INTR]);
+ int retries = 10;
+ while (usbd_transfer_pending(usc->usc_xfer[ATHN_RX_INTR]) && retries--) {
+ ATHN_UNLOCK(sc);
+ pause("W", hz / 16);
+ ATHN_LOCK(sc);
+ }
+ if (error == 0 && usc->wait_msg_id != 0) {
+ DEBUG_PRINTF("Error is %d\n", error);
+// error = tsleep(&usc->wait_msg_id, 0, "athnfw", hz); /* Wait 1 second at most */
+ error = msleep(&usc->wait_msg_id, &sc->sc_mtx, 0, "athnfw", 2 * hz); /* Wait 1 second at most */
+
+// msleep(const void *chan, struct mtx *mtx, int priority, const char *wmesg, int timo);
+
+ if (error) {
+ ATHN_UNLOCK(sc);
+ return error;
+ }
+ }
+ ATHN_UNLOCK(sc);
+
+ usc->wait_msg_id = 0;
+
+ firmware_put(fw, FIRMWARE_UNLOAD);
+ if (error != 0)
+ DEBUG_PRINTF("Bad: %s: error=%d\n", __func__, error);
+// device_printf(sc->sc_dev, "%s: %s: error=%d\n", __func__, name, error);
+ return error;
+}
+
+#if 0
+int
+athn_usb_load_firmware(struct athn_usb_softc *usc)
+{
+ struct athn_softc *sc = &usc->sc_sc;
+ const struct firmware *fw;
+ size_t fwsize, size;
+ int error = 0;
+ int mlen;
+ void *fw_copy_head;
+ unsigned char *ptr;
+ uint32_t addr;
+ usb_device_request_t req;
+ printf("athn_usb_load_firmware start\n");
+
+ ATHN_LOCK(sc);
+ fw = firmware_get(sc->fwname);
+ ATHN_UNLOCK(sc);
+ if (fw == NULL) {
+ device_printf(sc->sc_dev, "failed to load of file %s\n", sc->fwname);
+ return (ENOENT);
+ }
+
+#ifdef CHECK_THE_FIRMWARE
+ size_t len;
+ len = fw->datasize;
+ if (len < 999999 || len > sc->fwsize_limit) {
+ device_printf(sc->sc_dev, "wrong firmware size (%zu)\n", len);
+ error = EINVAL;
+ return error;
+ }
+#endif
+ fwsize = fw->datasize;
+#if 0
+ usb_device_descriptor_t *dd;
+ usb_device_request_t req;
+ const char *name;
+ u_char *fw, *ptr;
+ fwsize, size;
+ uint32_t addr;
+ int s, mlen, error;
+
+ /* Determine which firmware image to load. */
+ if (usc->flags & ATHN_USB_FLAG_AR7010) {
+ dd = usbd_get_device_descriptor(usc->sc_udev);
+ name = "athn-open-ar7010";
+ } else
+ name = "athn-open-ar9271";
+ /* Read firmware image from the filesystem. */
+ if ((error = loadfirmware(name, &fw, &fwsize)) != 0) {
+ printf("%s: failed loadfirmware of file %s (error %d)\n",
+ usc->usb_dev.dv_xname, name, error);
+ return (error);
+ }
+#endif
+
+ fw_copy_head = malloc(fw->datasize, M_ATHN_USB, M_WAITOK);
+ memcpy(fw_copy_head, fw->data, fw->datasize);
+ ptr = fw_copy_head;
+
+ addr = AR9271_FIRMWARE >> 8;
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = AR_FW_DOWNLOAD;
+ USETW(req.wIndex, 0);
+ size = fwsize;
+ while (size > 0) {
+ mlen = MIN(size, 4096);
+
+ USETW(req.wValue, addr);
+ USETW(req.wLength, mlen);
+ error = usbd_do_request(usc->sc_udev, NULL, &req, (void *)ptr);
+ if (error != 0) {
+ printf("usbd_do_request error %d at %s:%d\n", error, __FILE__, __LINE__);
+ return (error);
+ }
+ addr += mlen >> 8;
+ ptr += mlen;
+ size -= mlen;
+ }
+ free(fw_copy_head, M_DEVBUF);
+
+ /* Start firmware. */
+ if (usc->flags & ATHN_USB_FLAG_AR7010) {
+ printf("AR7010_FIRMWARE_TEXT\n");
+ addr = AR7010_FIRMWARE_TEXT >> 8;
+ }
+ else {
+ printf("AR9271_FIRMWARE_TEXT\n");
+ addr = AR9271_FIRMWARE_TEXT >> 8;
+ }
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = AR_FW_DOWNLOAD_COMP;
+ USETW(req.wIndex, 0);
+ USETW(req.wValue, addr);
+ USETW(req.wLength, 0);
+ usc->wait_msg_id = AR_HTC_MSG_READY;
+ error = usbd_do_request(usc->sc_udev, NULL, &req, NULL);
+ /* Wait at most 1 second for firmware to boot. */
+ if (error == 0 && usc->wait_msg_id != 0) {
+ printf("Latter error! %d %d\n", error, usc->wait_msg_id);
+// ATHN_LOCK(sc);
+ // XXX Update this in the future to check wakeup() value
+ error = tsleep(sc, 0, "athnfw", hz);
+// error = mtx_sleep(sc, &sc->sc_mtx, 0 , "athnfw", hz);
+// if (error == EINTR)
+// printf("EINTR on line %d\n", __LINE__);
+// else if (error == ERESTART)
+// printf("ERESTART on line %d\n", __LINE__);
+// else if (error == EWOULDBLOCK)
+// printf("EWOULDBLOCK on %d\n", __LINE__);
+// else
+// printf("Clear on %d\n", __LINE__);
+// ATHN_UNLOCK(sc);
+ }
+ usc->wait_msg_id = 0;
+ printf("sending back %d\n", error);
+ return (error);
+}
+#endif
+
+int
+athn_usb_htc_msg(struct athn_usb_softc *usc, uint16_t msg_id, void *buf,
+ int len)
+{
+ struct athn_softc *sc = &usc->sc_sc;
+ struct athn_usb_tx_data *data = &usc->tx_cmd;
+ struct ar_htc_frame_hdr *htc;
+ struct ar_htc_msg_hdr *msg;
+
+ htc = (struct ar_htc_frame_hdr *)data->buf;
+ memset(htc, 0, sizeof(*htc));
+ htc->endpoint_id = 0;
+ htc->payload_len = htobe16(sizeof(*msg) + len);
+
+ msg = (struct ar_htc_msg_hdr *)&htc[1];
+ msg->msg_id = htobe16(msg_id);
+
+ memcpy(&msg[1], buf, len);
+
+ /*
+ * FreeBSD addition, required because OpenBSD's xfer mechanism
+ * specifies the length during transfer, whereas FreeBSD's callback
+ * mechanism does not.
+ */
+ data->len = sizeof(*htc) + sizeof(*msg) + len;
+
+// ATHN_LOCK(sc);
+ usbd_transfer_start(usc->usc_xfer[ATHN_RX_INTR]);
+ usbd_transfer_start(usc->usc_xfer[ATHN_TX_INTR]);
+ while (usbd_transfer_pending(usc->usc_xfer[ATHN_TX_INTR])) {
+ ATHN_UNLOCK(sc);
+ pause("Farhan was here", hz / 16);
+ ATHN_LOCK(sc);
+ }
+// ATHN_UNLOCK(sc);
+
+ return 0;
+#if 0
+
+ usbd_setup_xfer(
+ data->xfer, // xfer
+ usc->tx_intr_pipe, // pipe
+ NULL, // priv data?
+ data->buf, // buffer data?
+ sizeof(*htc) + sizeof(*msg) + len, // length of data
+ USBD_SHORT_XFER_OK | USBD_NO_COPY | USBD_SYNCHRONOUS, // flags
+ ATHN_USB_CMD_TIMEOUT, // timeout time
+ NULL); // callback function?
+ return (usbd_transfer(data->xfer));
+#endif
+}
+
+int
+athn_usb_htc_setup(struct athn_usb_softc *usc)
+{
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ar_htc_msg_config_pipe cfg;
+ int error;
+
+ /*
+ * Connect WMI services to USB pipes.
+ */
+ DEBUG_PRINTF("++Load Step 1\n");
+ error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CONTROL,
+ AR_PIPE_TX_INTR, AR_PIPE_RX_INTR, &usc->ep_ctrl);
+ if (error != 0) {
+ DEBUG_PRINTF("Step 1 error %d\n", error);
+ return (error);
+ }
+ DEBUG_PRINTF("++Load Step 2\n");
+ error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_BEACON,
+ AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_bcn);
+ if (error != 0)
+ return (error);
+ DEBUG_PRINTF("++Load Step 3\n");
+ error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CAB,
+ AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_cab);
+ if (error != 0)
+ return (error);
+ DEBUG_PRINTF("++Load Step 4\n");
+ error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_UAPSD,
+ AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_uapsd);
+ if (error != 0)
+ return (error);
+ DEBUG_PRINTF("++Load Step 5\n");
+ error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_MGMT,
+ AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_mgmt);
+ if (error != 0)
+ return (error);
+ DEBUG_PRINTF("++Load Step 6\n");
+ error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BE,
+ AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[WME_AC_BE]);
+ if (error != 0)
+ return (error);
+ DEBUG_PRINTF("++Load Step 7\n");
+ error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BK,
+ AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[WME_AC_BK]);
+ if (error != 0)
+ return (error);
+ DEBUG_PRINTF("++Load Step 8\n");
+ error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VI,
+ AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[WME_AC_VI]);
+ if (error != 0)
+ return (error);
+ DEBUG_PRINTF("++Load Step 9\n");
+ error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VO,
+ AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[WME_AC_VO]);
+ if (error != 0)
+ return (error);
+
+ /* Set credits for WLAN Tx pipe. */
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.pipe_id = UE_GET_ADDR(AR_PIPE_TX_DATA);
+ cfg.credits = (usc->flags & ATHN_USB_FLAG_AR7010) ? 45 : 33;
+ usc->wait_msg_id = AR_HTC_MSG_CONF_PIPE_RSP;
+ // XXX Come back to this maybe?
+ ATHN_LOCK(sc);
+ error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONF_PIPE, &cfg, sizeof(cfg));
+ if (error == 0 && usc->wait_msg_id != 0) {
+ //error = tsleep(sc, 0, "athnhtc", hz);
+ error = msleep(&usc->wait_msg_id, &sc->sc_mtx, 0, "athnhtc", hz);
+ }
+ ATHN_UNLOCK(sc);
+ usc->wait_msg_id = 0;
+ if (error != 0) {
+ DEBUG_PRINTF("%s: could not configure pipe\n", sc->sc_ic.ic_name);
+ return (error);
+ }
+
+ ATHN_LOCK(sc);
+ error = athn_usb_htc_msg(usc, AR_HTC_MSG_SETUP_COMPLETE, NULL, 0);
+ ATHN_UNLOCK(sc);
+ if (error != 0) {
+ DEBUG_PRINTF("%s: could not complete setup\n", sc->sc_ic.ic_name);
+ return (error);
+ }
+ return (0);
+}
+
+int
+athn_usb_htc_connect_svc(struct athn_usb_softc *usc, uint16_t svc_id,
+ uint8_t ul_pipe, uint8_t dl_pipe, uint8_t *endpoint_id)
+{
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ar_htc_msg_conn_svc msg;
+ struct ar_htc_msg_conn_svc_rsp rsp;
+ int error;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.svc_id = htobe16(svc_id);
+ msg.dl_pipeid = UE_GET_ADDR(dl_pipe);
+ msg.ul_pipeid = UE_GET_ADDR(ul_pipe);
+ usc->msg_conn_svc_rsp = &rsp;
+ usc->wait_msg_id = AR_HTC_MSG_CONN_SVC_RSP;
+
+ ATHN_LOCK(sc);
+ error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONN_SVC, &msg, sizeof(msg));
+
+ /* Wait at most 1 second for response. */
+ if (error == 0 && usc->wait_msg_id != 0) {
+ DEBUG_PRINTF("Sleep here Line: %d\n", __LINE__);
+ error = msleep(&usc->wait_msg_id, &sc->sc_mtx, 0, "athnhtc", 10 * hz);
+ DEBUG_PRINTF("Working with Hans, msg_id = %d\n", usc->wait_msg_id);
+ /* Wait 1 second at most */
+ }
+ ATHN_UNLOCK(sc);
+ usc->wait_msg_id = 0;
+// splx(s);
+ if (error != 0) {
+ DEBUG_PRINTF("error waiting for service %d connection\n", svc_id);
+// printf("%s: error waiting for service %d connection\n",
+// usc->usb_dev.dv_xname, svc_id);
+ return (error);
+ }
+ if (rsp.status != AR_HTC_SVC_SUCCESS) {
+ printf(": service %d connection failed, error %d\n", svc_id, rsp.status);
+ return (EIO);
+ }
+// DPRINTF(("service %d successfully connected to endpoint %d\n",
+// svc_id, rsp.endpoint_id));
+
+ /* Return endpoint id. */
+ *endpoint_id = rsp.endpoint_id;
+ return (0);
+#if 0
+#endif
+}
+
+int
+athn_usb_wmi_xcmd(struct athn_usb_softc *usc, uint16_t cmd_id, void *ibuf,
+ int ilen, void *obuf)
+{
+ struct athn_usb_tx_data *data = &usc->tx_cmd;
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ar_htc_frame_hdr *htc;
+ struct ar_wmi_cmd_hdr *wmi;
+ int error;
+
+ DEBUG_PRINTF("athn_usb_wmi_xcmd cmd_id = %d\n", cmd_id);
+
+// if (usbd_is_dying(usc->sc_udev))
+// return ENXIO;
+
+// s = splusb();
+ // REVISIT THIS CODE BELOW. WHY THE LOOP?!?!?!?
+#if 1 // Why is this here at all???
+ while (usc->wait_cmd_id) {
+ /*
+ * The previous USB transfer is not done yet. We can't use
+ * data->xfer until it is done or we'll cause major confusion
+ * in the USB stack.
+ */
+ //tsleep(&usc->wait_cmd_id, 0, "athnwmx", ATHN_USB_CMD_TIMEOUT);
+ ATHN_LOCK(sc);
+ DEBUG_PRINTF("This one probably needs some sort of wakeup equivalent... %d\n", usc->wait_cmd_id);
+ msleep(&usc->wait_cmd_id, &sc->sc_mtx, 0, "athnwmx", ATHN_USB_CMD_TIMEOUT); /* Wait 1 second at most */
+ ATHN_UNLOCK(sc);
+// tsleep_nsec(&usc->wait_cmd_id, 0, "athnwmx",
+// MSEC_TO_NSEC(ATHN_USB_CMD_TIMEOUT));
+// if (usbd_is_dying(usc->sc_udev)) {
+// splx(s);
+// return ENXIO;
+ }
+#endif
+// splx(s);
+
+ htc = (struct ar_htc_frame_hdr *)data->buf;
+ memset(htc, 0, sizeof(*htc));
+ htc->endpoint_id = usc->ep_ctrl;
+ htc->payload_len = htobe16(sizeof(*wmi) + ilen);
+
+ wmi = (struct ar_wmi_cmd_hdr *)&htc[1];
+ wmi->cmd_id = htobe16(cmd_id);
+ usc->wmi_seq_no++;
+ wmi->seq_no = htobe16(usc->wmi_seq_no);
+
+ memcpy(&wmi[1], ibuf, ilen);
+
+ data->len = sizeof(*htc) + sizeof(*wmi) + ilen;
+
+ ATHN_LOCK(sc);
+ usbd_transfer_start(usc->usc_xfer[ATHN_TX_INTR]);
+ ATHN_UNLOCK(sc);
+
+// usbd_setup_xfer(data->xfer, usc->tx_intr_pipe, NULL, data->buf,
+// sizeof(*htc) + sizeof(*wmi) + ilen,
+// USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_CMD_TIMEOUT,
+// NULL);
+// s = splusb();
+// error = usbd_transfer(data->xfer);
+// if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) {
+// splx(s);
+// return (error);
+// }
+ usc->obuf = obuf;
+ usc->wait_cmd_id = cmd_id;
+ /*
+ * Wait for WMI command complete interrupt. In case it does not fire
+ * wait until the USB transfer times out to avoid racing the transfer.
+ */
+// error = tsleep(&usc->wait_cmd_id, 0, "athnwmi", ATHN_USB_CMD_TIMEOUT);
+ ATHN_LOCK(sc);
+ error = msleep(&usc->wait_cmd_id, &sc->sc_mtx, 0, "athnwmi", ATHN_USB_CMD_TIMEOUT);
+ ATHN_UNLOCK(sc);
+// error = tsleep_nsec(&usc->wait_cmd_id, 0, "athnwmi",
+// MSEC_TO_NSEC(ATHN_USB_CMD_TIMEOUT));
+ if (error) {
+ if (error == EWOULDBLOCK) {
+ if (cmd_id != 0x15)
+ device_printf(sc->sc_dev, "firmware command 0x%x timed out\n", cmd_id);
+ error = ETIMEDOUT;
+ }
+ }
+
+ /*
+ * Both the WMI command and transfer are done or have timed out.
+ * Allow other threads to enter this function and use data->xfer.
+ */
+ usc->wait_cmd_id = 0;
+ wakeup(&usc->wait_cmd_id);
+
+// splx(s);
+ return (error);
+}
+
+int
+athn_usb_read_rom(struct athn_softc *sc)
+{
+ struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
+ uint32_t addrs[8], vals[8], addr;
+ uint16_t *eep;
+ int i, j, error;
+
+ /* Read EEPROM by blocks of 16 bytes. */
+ eep = sc->eep;
+ addr = AR_EEPROM_OFFSET(sc->eep_base);
+ for (i = 0; i < sc->eep_size / 16; i++) {
+ for (j = 0; j < 8; j++, addr += 4)
+ addrs[j] = htobe32(addr);
+ error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ,
+ addrs, sizeof(addrs), vals);
+ if (error != 0)
+ break;
+ for (j = 0; j < 8; j++)
+ *eep++ = htobe32(vals[j]);
+ }
+ return (error);
+}
+
+uint32_t
+athn_usb_read(struct athn_softc *sc, uint32_t addr)
+{
+ struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
+ uint32_t val;
+ int error;
+
+DEBUG_PRINTF("DEBUG: athn_usb_read addr = %d\n", addr);
+
+ /* Flush pending writes for strict consistency. */
+ athn_usb_write_barrier(sc);
+
+ addr = htobe32(addr);
+ error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ,
+ &addr, sizeof(addr), &val);
+ if (error != 0) {
+ printf("hed tine: athn_usb_read val = 0xdeadbeef\n");
+ return (0xdeadbeef);
+ }
+DEBUG_PRINTF("DEBUG: athn_usb_read val = %d\n", val);
+ return (htobe32(val));
+}
+
+void
+athn_usb_write(struct athn_softc *sc, uint32_t addr, uint32_t val)
+{
+ struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
+
+DEBUG_PRINTF("DEBUG: athn_usb_write, addr = %d, val = %d\n", addr, val);
+ usc->wbuf[usc->wcount].addr = htobe32(addr);
+ usc->wbuf[usc->wcount].val = htobe32(val);
+ if (++usc->wcount == AR_MAX_WRITE_COUNT)
+ athn_usb_write_barrier(sc);
+}
+
+void
+athn_usb_write_barrier(struct athn_softc *sc)
+{
+ struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
+
+DEBUG_PRINTF("DEBUG: athn_usb_write_barrier\n");
+ if (usc->wcount == 0)
+ return; /* Nothing to write. */
+
+ (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_WRITE,
+ usc->wbuf, usc->wcount * sizeof(usc->wbuf[0]), NULL);
+ usc->wcount = 0; /* Always flush buffer. */
+}
+
+int
+athn_usb_media_change(struct ifnet *ifp)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+ struct athn_usb_softc *usc = (struct athn_usb_softc *)ifp->if_softc;
+ int error;
+
+ if (usbd_is_dying(usc->sc_udev))
+ return ENXIO;
+
+ error = ieee80211_media_change(ifp);
+ if (error != ENETRESET)
+ return (error);
+
+ if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
+ (IFF_UP | IFF_RUNNING)) {
+ athn_usb_stop(ifp);
+ error = athn_usb_init(ifp);
+ }
+ return (error);
+#endif
+}
+
+void
+athn_usb_next_scan(void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_softc *usc = arg;
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ int s;
+
+ if (usbd_is_dying(usc->sc_udev))
+ return;
+
+ usbd_ref_incr(usc->sc_udev);
+
+ s = splnet();
+ if (ic->ic_state == IEEE80211_S_SCAN)
+ ieee80211_next_scan(&ic->ic_if);
+ splx(s);
+
+ usbd_ref_decr(usc->sc_udev);
+#endif
+}
+
+int
+athn_usb_newstate(struct ieee80211com *ic, enum ieee80211_state nstate,
+ int arg)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+ struct athn_usb_softc *usc = ic->ic_softc;
+ struct athn_usb_cmd_newstate cmd;
+
+ /* Do it in a process context. */
+ cmd.state = nstate;
+ cmd.arg = arg;
+ athn_usb_do_async(usc, athn_usb_newstate_cb, &cmd, sizeof(cmd));
+ return (0);
+#endif
+}
+
+void
+athn_usb_newstate_cb(struct athn_usb_softc *usc, void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_cmd_newstate *cmd = arg;
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ enum ieee80211_state ostate;
+ uint32_t reg, imask;
+ int s, error;
+
+ timeout_del(&sc->calib_to);
+
+ s = splnet();
+ ostate = ic->ic_state;
+
+ if (ostate == IEEE80211_S_RUN && ic->ic_opmode == IEEE80211_M_STA) {
+ athn_usb_remove_node(usc, ic->ic_bss);
+ reg = AR_READ(sc, AR_RX_FILTER);
+ reg = (reg & ~AR_RX_FILTER_MYBEACON) |
+ AR_RX_FILTER_BEACON;
+ AR_WRITE(sc, AR_RX_FILTER, reg);
+ AR_WRITE_BARRIER(sc);
+ }
+ switch (cmd->state) {
+ case IEEE80211_S_INIT:
+ athn_set_led(sc, 0);
+ break;
+ case IEEE80211_S_SCAN:
+ /* Make the LED blink while scanning. */
+ athn_set_led(sc, !sc->led_state);
+ error = athn_usb_switch_chan(sc, ic->ic_bss->ni_chan, NULL);
+ if (error)
+ printf("%s: could not switch to channel %d\n",
+ usc->usb_dev.dv_xname,
+ ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan));
+ if (!usbd_is_dying(usc->sc_udev))
+ timeout_add_msec(&sc->scan_to, 200);
+ break;
+ case IEEE80211_S_AUTH:
+ athn_set_led(sc, 0);
+ error = athn_usb_switch_chan(sc, ic->ic_bss->ni_chan, NULL);
+ if (error)
+ printf("%s: could not switch to channel %d\n",
+ usc->usb_dev.dv_xname,
+ ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan));
+ break;
+ case IEEE80211_S_ASSOC:
+ break;
+ case IEEE80211_S_RUN:
+ athn_set_led(sc, 1);
+
+ if (ic->ic_opmode == IEEE80211_M_MONITOR)
+ break;
+
+ if (ic->ic_opmode == IEEE80211_M_STA) {
+ /* Create node entry for our BSS */
+ error = athn_usb_create_node(usc, ic->ic_bss);
+ if (error)
+ printf("%s: could not update firmware station "
+ "table\n", usc->usb_dev.dv_xname);
+ }
+ athn_set_bss(sc, ic->ic_bss);
+ athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR);
+#ifndef IEEE80211_STA_ONLY
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+ athn_usb_switch_chan(sc, ic->ic_bss->ni_chan, NULL);
+ athn_set_hostap_timers(sc);
+ /* Enable software beacon alert interrupts. */
+ imask = htobe32(AR_IMR_SWBA);
+ } else
+#endif
+ {
+ athn_set_sta_timers(sc);
+ /* Enable beacon miss interrupts. */
+ imask = htobe32(AR_IMR_BMISS);
+
+ /* Stop receiving beacons from other BSS. */
+ reg = AR_READ(sc, AR_RX_FILTER);
+ reg = (reg & ~AR_RX_FILTER_BEACON) |
+ AR_RX_FILTER_MYBEACON;
+ AR_WRITE(sc, AR_RX_FILTER, reg);
+ AR_WRITE_BARRIER(sc);
+ }
+ athn_usb_wmi_xcmd(usc, AR_WMI_CMD_ENABLE_INTR,
+ &imask, sizeof(imask), NULL);
+ break;
+ }
+ (void)sc->sc_newstate(ic, cmd->state, cmd->arg);
+ splx(s);
+#endif
+}
+
+void
+athn_usb_newassoc(struct ieee80211_node *ni, int isnew)
+{
+ printf("%s unimplemented...\n", __func__);
+#if 0
+ printf("%s unimplemented.\n", __func__);
+//#ifndef IEEE80211_STA_ONLY
+ struct athn_usb_softc *usc = ic->ic_softc;
+
+ if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
+ ic->ic_state != IEEE80211_S_RUN)
+ return;
+
+ /* Update the node's supported rates in a process context. */
+ ieee80211_ref_node(ni);
+ athn_usb_do_async(usc, athn_usb_newassoc_cb, &ni, sizeof(ni));
+#endif
+}
+
+#ifndef IEEE80211_STA_ONLY
+void
+athn_usb_newassoc_cb(struct athn_usb_softc *usc, void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct ieee80211com *ic = &usc->sc_sc.sc_ic;
+ struct ieee80211_node *ni = *(void **)arg;
+ struct athn_node *an = (struct athn_node *)ni;
+ int s;
+
+ if (ic->ic_state != IEEE80211_S_RUN)
+ return;
+
+ s = splnet();
+ /* NB: Node may have left before we got scheduled. */
+ if (an->sta_index != 0)
+ (void)athn_usb_node_set_rates(usc, ni);
+ ieee80211_release_node(ic, ni);
+ splx(s);
+#endif
+}
+#endif
+
+struct ieee80211_node *
+athn_usb_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+// printf("%s unimplemented.\n", __func__);
+// return NULL;
+//#if 0
+ struct athn_node *an;
+
+ an = malloc(sizeof(struct athn_node), M_80211_NODE, M_NOWAIT | M_ZERO);
+ return (struct ieee80211_node *)an;
+//#endif
+}
+
+
+#ifndef IEEE80211_STA_ONLY
+void
+athn_usb_count_active_sta(void *arg, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ int *nsta = arg;
+ struct athn_node *an = (struct athn_node *)ni;
+
+ if (an->sta_index == 0)
+ return;
+
+ if ((ni->ni_state == IEEE80211_STA_AUTH ||
+ ni->ni_state == IEEE80211_STA_ASSOC) &&
+ ni->ni_inact < IEEE80211_INACT_MAX)
+ (*nsta)++;
+#endif
+}
+
+struct athn_usb_newauth_cb_arg {
+ struct ieee80211_node *ni;
+ uint16_t seq;
+};
+
+void
+athn_usb_newauth_cb(struct athn_usb_softc *usc, void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct ieee80211com *ic = &usc->sc_sc.sc_ic;
+ struct athn_usb_newauth_cb_arg *a = arg;
+ struct ieee80211_node *ni = a->ni;
+ uint16_t seq = a->seq;
+ struct athn_node *an = (struct athn_node *)ni;
+ int s, error = 0;
+
+ if (ic->ic_state != IEEE80211_S_RUN)
+ return;
+
+ s = splnet();
+ if (an->sta_index == 0) {
+ error = athn_usb_create_node(usc, ni);
+ if (error)
+ printf("%s: could not add station %s to firmware "
+ "table\n", usc->usb_dev.dv_xname,
+ ether_sprintf(ni->ni_macaddr));
+ }
+ if (error == 0)
+ ieee80211_auth_open_confirm(ic, ni, seq);
+ ieee80211_unref_node(&ni);
+ splx(s);
+#endif
+}
+#endif
+
+int
+athn_usb_newauth(struct ieee80211com *ic, struct ieee80211_node *ni,
+ int isnew, uint16_t seq)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+#ifndef IEEE80211_STA_ONLY
+ struct athn_usb_softc *usc = ic->ic_softc;
+ struct ifnet *ifp = &ic->ic_if;
+ struct athn_node *an = (struct athn_node *)ni;
+ int nsta;
+ struct athn_usb_newauth_cb_arg arg;
+
+ if (ic->ic_opmode != IEEE80211_M_HOSTAP)
+ return 0;
+
+ if (!isnew && an->sta_index != 0) /* already in firmware table */
+ return 0;
+
+ /* Check if we have room in the firmware table. */
+ nsta = 1; /* Account for default node. */
+ ieee80211_iterate_nodes(ic, athn_usb_count_active_sta, &nsta);
+ if (nsta >= AR_USB_MAX_STA) {
+ if (ifp->if_flags & IFF_DEBUG)
+ printf("%s: cannot authenticate station %s: firmware "
+ "table is full\n", usc->usb_dev.dv_xname,
+ ether_sprintf(ni->ni_macaddr));
+ return ENOSPC;
+ }
+
+ /*
+ * In a process context, try to add this node to the
+ * firmware table and confirm the AUTH request.
+ */
+ arg.ni = ieee80211_ref_node(ni);
+ arg.seq = seq;
+ athn_usb_do_async(usc, athn_usb_newauth_cb, &arg, sizeof(arg));
+ return EBUSY;
+#else
+ return 0;
+#endif /* IEEE80211_STA_ONLY */
+#endif
+}
+
+#ifndef IEEE80211_STA_ONLY
+void
+athn_usb_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_softc *usc = ic->ic_softc;
+ struct athn_node *an = (struct athn_node *)ni;
+
+ /*
+ * Remove the node from the firmware table in a process context.
+ * Pass an index rather than the pointer which we will free.
+ */
+ if (an->sta_index != 0)
+ athn_usb_do_async(usc, athn_usb_node_free_cb,
+ &an->sta_index, sizeof(an->sta_index));
+ usc->sc_node_free(ic, ni);
+#endif
+}
+
+void
+athn_usb_node_free_cb(struct athn_usb_softc *usc, void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct ieee80211com *ic = &usc->sc_sc.sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+ uint8_t sta_index = *(uint8_t *)arg;
+ int error;
+
+ error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE,
+ &sta_index, sizeof(sta_index), NULL);
+ if (error) {
+ printf("%s: could not remove station %u from firmware table\n",
+ usc->usb_dev.dv_xname, sta_index);
+ return;
+ }
+ usc->free_node_slots |= (1 << sta_index);
+ if (ifp->if_flags & IFF_DEBUG)
+ printf("%s: station %u removed from firmware table\n",
+ usc->usb_dev.dv_xname, sta_index);
+#endif
+}
+#endif /* IEEE80211_STA_ONLY */
+
+int
+athn_usb_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
+ uint8_t tid)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+ struct athn_usb_softc *usc = ic->ic_softc;
+ struct athn_node *an = (struct athn_node *)ni;
+ struct athn_usb_aggr_cmd cmd;
+
+ /* Do it in a process context. */
+ cmd.sta_index = an->sta_index;
+ cmd.tid = tid;
+ athn_usb_do_async(usc, athn_usb_ampdu_tx_start_cb, &cmd, sizeof(cmd));
+ return (0);
+#endif
+}
+
+void
+athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *usc, void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_aggr_cmd *cmd = arg;
+ struct ar_htc_target_aggr aggr;
+
+ memset(&aggr, 0, sizeof(aggr));
+ aggr.sta_index = cmd->sta_index;
+ aggr.tidno = cmd->tid;
+ aggr.aggr_enable = 1;
+ (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE,
+ &aggr, sizeof(aggr), NULL);
+#endif
+}
+
+void
+athn_usb_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
+ uint8_t tid)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_softc *usc = ic->ic_softc;
+ struct athn_node *an = (struct athn_node *)ni;
+ struct athn_usb_aggr_cmd cmd;
+
+ /* Do it in a process context. */
+ cmd.sta_index = an->sta_index;
+ cmd.tid = tid;
+ athn_usb_do_async(usc, athn_usb_ampdu_tx_stop_cb, &cmd, sizeof(cmd));
+#endif
+}
+
+void
+athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *usc, void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_aggr_cmd *cmd = arg;
+ struct ar_htc_target_aggr aggr;
+
+ memset(&aggr, 0, sizeof(aggr));
+ aggr.sta_index = cmd->sta_index;
+ aggr.tidno = cmd->tid;
+ aggr.aggr_enable = 0;
+ (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE,
+ &aggr, sizeof(aggr), NULL);
+#endif
+}
+
+#ifndef IEEE80211_STA_ONLY
+/* Try to find a node we can evict to make room in the firmware table. */
+void
+athn_usb_clean_nodes(void *arg, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_softc *usc = arg;
+ struct ieee80211com *ic = &usc->sc_sc.sc_ic;
+ struct athn_node *an = (struct athn_node *)ni;
+
+ /*
+ * Don't remove the default node (used for management frames).
+ * Nodes which are not in the firmware table also have index zero.
+ */
+ if (an->sta_index == 0)
+ return;
+
+ /* Remove non-associated nodes. */
+ if (ni->ni_state != IEEE80211_STA_AUTH &&
+ ni->ni_state != IEEE80211_STA_ASSOC) {
+ athn_usb_remove_node(usc, ni);
+ return;
+ }
+
+ /*
+ * Kick off inactive associated nodes. This won't help
+ * immediately but will help if the new STA retries later.
+ */
+ if (ni->ni_inact >= IEEE80211_INACT_MAX) {
+ IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
+ IEEE80211_REASON_AUTH_EXPIRE);
+ ieee80211_node_leave(ic, ni);
+ }
+#endif // End of the FreeBSD endif
+}
+#endif
+
+int
+athn_usb_create_node(struct athn_usb_softc *usc, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+ struct athn_node *an = (struct athn_node *)ni;
+ struct ar_htc_target_sta sta;
+ int error, sta_index;
+#ifndef IEEE80211_STA_ONLY
+ struct ieee80211com *ic = &usc->sc_sc.sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+
+ /* Firmware cannot handle more than 8 STAs. Try to make room first. */
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP)
+ ieee80211_iterate_nodes(ic, athn_usb_clean_nodes, usc);
+#endif
+ if (usc->free_node_slots == 0x00)
+ return ENOBUFS;
+
+ sta_index = ffs(usc->free_node_slots) - 1;
+ if (sta_index < 0 || sta_index >= AR_USB_MAX_STA)
+ return ENOSPC;
+
+ /* Create node entry on target. */
+ memset(&sta, 0, sizeof(sta));
+ IEEE80211_ADDR_COPY(sta.macaddr, ni->ni_macaddr);
+ IEEE80211_ADDR_COPY(sta.bssid, ni->ni_bssid);
+ sta.sta_index = sta_index;
+ sta.maxampdu = 0xffff;
+ if (ni->ni_flags & IEEE80211_NODE_HT)
+ sta.flags |= htobe16(AR_HTC_STA_HT);
+ error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_CREATE,
+ &sta, sizeof(sta), NULL);
+ if (error != 0)
+ return (error);
+ an->sta_index = sta_index;
+ usc->free_node_slots &= ~(1 << an->sta_index);
+
+#ifndef IEEE80211_STA_ONLY
+ if (ifp->if_flags & IFF_DEBUG)
+ printf("%s: station %u (%s) added to firmware table\n",
+ usc->usb_dev.dv_xname, sta_index,
+ ether_sprintf(ni->ni_macaddr));
+#endif
+ return athn_usb_node_set_rates(usc, ni);
+#endif
+}
+
+int
+athn_usb_node_set_rates(struct athn_usb_softc *usc, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+ struct athn_node *an = (struct athn_node *)ni;
+ struct ar_htc_target_rate rate;
+ int i, j;
+
+ /* Setup supported rates. */
+ memset(&rate, 0, sizeof(rate));
+ rate.sta_index = an->sta_index;
+ rate.isnew = 1;
+ rate.lg_rates.rs_nrates = ni->ni_rates.rs_nrates;
+ memcpy(rate.lg_rates.rs_rates, ni->ni_rates.rs_rates,
+ ni->ni_rates.rs_nrates);
+ if (ni->ni_flags & IEEE80211_NODE_HT) {
+ rate.capflags |= htobe32(AR_RC_HT_FLAG);
+ /* Setup HT rates. */
+ for (i = 0, j = 0; i < IEEE80211_HT_NUM_MCS; i++) {
+ if (!isset(ni->ni_rxmcs, i))
+ continue;
+ if (j >= AR_HTC_RATE_MAX)
+ break;
+ rate.ht_rates.rs_rates[j++] = i;
+ }
+ rate.ht_rates.rs_nrates = j;
+
+ if (ni->ni_rxmcs[1]) /* dual-stream MIMO rates */
+ rate.capflags |= htobe32(AR_RC_DS_FLAG);
+#ifdef notyet
+ if (ni->ni_htcaps & IEEE80211_HTCAP_CBW20_40)
+ rate.capflags |= htobe32(AR_RC_40_FLAG);
+ if (ni->ni_htcaps & IEEE80211_HTCAP_SGI40)
+ rate.capflags |= htobe32(AR_RC_SGI_FLAG);
+ if (ni->ni_htcaps & IEEE80211_HTCAP_SGI20)
+ rate.capflags |= htobe32(AR_RC_SGI_FLAG);
+#endif
+ }
+
+ return athn_usb_wmi_xcmd(usc, AR_WMI_CMD_RC_RATE_UPDATE,
+ &rate, sizeof(rate), NULL);
+#endif
+}
+
+int
+athn_usb_remove_node(struct athn_usb_softc *usc, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+ struct athn_node *an = (struct athn_node *)ni;
+ int error;
+#ifndef IEEE80211_STA_ONLY
+ struct ieee80211com *ic = &usc->sc_sc.sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+#endif
+
+ error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE,
+ &an->sta_index, sizeof(an->sta_index), NULL);
+ if (error) {
+ printf("%s: could not remove station %u (%s) from "
+ "firmware table\n", usc->usb_dev.dv_xname, an->sta_index,
+ ether_sprintf(ni->ni_macaddr));
+ return error;
+ }
+
+#ifndef IEEE80211_STA_ONLY
+ if (ifp->if_flags & IFF_DEBUG)
+ printf("%s: station %u (%s) removed from firmware table\n",
+ usc->usb_dev.dv_xname, an->sta_index,
+ ether_sprintf(ni->ni_macaddr));
+#endif
+
+ usc->free_node_slots |= (1 << an->sta_index);
+ an->sta_index = 0;
+ return 0;
+#endif
+}
+
+void
+athn_usb_rx_enable(struct athn_softc *sc)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ AR_WRITE(sc, AR_CR, AR_CR_RXE);
+ AR_WRITE_BARRIER(sc);
+#endif
+}
+
+int
+athn_usb_switch_chan(struct athn_softc *sc, struct ieee80211_channel *c,
+ struct ieee80211_channel *extc)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+ struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
+ uint16_t mode;
+ int error;
+
+ /* Disable interrupts. */
+ error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR);
+ if (error != 0)
+ goto reset;
+ /* Stop all Tx queues. */
+ error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL);
+ if (error != 0)
+ goto reset;
+ /* Stop Rx. */
+ error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV);
+ if (error != 0)
+ goto reset;
+
+ /* If band or bandwidth changes, we need to do a full reset. */
+ if (c->ic_flags != sc->curchan->ic_flags ||
+ ((extc != NULL) ^ (sc->curchanext != NULL))) {
+ DPRINTFN(2, ("channel band switch\n"));
+ goto reset;
+ }
+
+ error = athn_set_chan(sc, c, extc);
+ if (AR_SREV_9271(sc) && error == 0)
+ ar9271_load_ani(sc);
+ if (error != 0) {
+ reset: /* Error found, try a full reset. */
+ DPRINTFN(3, ("needs a full reset\n"));
+ error = athn_hw_reset(sc, c, extc, 0);
+ if (error != 0) /* Hopeless case. */
+ return (error);
+
+ error = athn_set_chan(sc, c, extc);
+ if (AR_SREV_9271(sc) && error == 0)
+ ar9271_load_ani(sc);
+ if (error != 0)
+ return (error);
+ }
+
+ sc->ops.set_txpower(sc, c, extc);
+
+ error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV);
+ if (error != 0)
+ return (error);
+ athn_rx_start(sc);
+
+ mode = htobe16(IEEE80211_IS_CHAN_2GHZ(c) ?
+ AR_HTC_MODE_11NG : AR_HTC_MODE_11NA);
+ error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE,
+ &mode, sizeof(mode), NULL);
+ if (error != 0)
+ return (error);
+
+ /* Re-enable interrupts. */
+ error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ENABLE_INTR);
+ return (error);
+#endif
+}
+
+void
+athn_usb_updateedca(struct ieee80211com *ic)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_softc *usc = ic->ic_softc;
+
+ /* Do it in a process context. */
+ athn_usb_do_async(usc, athn_usb_updateedca_cb, NULL, 0);
+#endif
+}
+
+void
+athn_usb_updateedca_cb(struct athn_usb_softc *usc, void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ int s;
+
+ s = splnet();
+ athn_updateedca(&usc->sc_sc.sc_ic);
+ splx(s);
+#endif
+}
+
+void
+athn_usb_updateslot(struct ieee80211com *ic)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_softc *usc = ic->ic_softc;
+
+ return; /* XXX */
+ /* Do it in a process context. */
+ athn_usb_do_async(usc, athn_usb_updateslot_cb, NULL, 0);
+#endif
+}
+
+void
+athn_usb_updateslot_cb(struct athn_usb_softc *usc, void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ int s;
+
+ s = splnet();
+ athn_updateslot(&usc->sc_sc.sc_ic);
+ splx(s);
+#endif
+}
+
+int
+athn_usb_set_key(struct ieee80211vap *vap, const struct ieee80211_key *k)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+ struct athn_usb_softc *usc = ic->ic_softc;
+ struct athn_usb_cmd_key cmd;
+
+ /* Defer setting of WEP keys until interface is brought up. */
+ if ((ic->ic_if.if_flags & (IFF_UP | IFF_RUNNING)) !=
+ (IFF_UP | IFF_RUNNING))
+ return (0);
+
+ /* Do it in a process context. */
+ cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL;
+ cmd.key = k;
+ athn_usb_do_async(usc, athn_usb_set_key_cb, &cmd, sizeof(cmd));
+ usc->sc_key_tasks++;
+ return EBUSY;
+#endif
+}
+
+void
+athn_usb_set_key_cb(struct athn_usb_softc *usc, void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct ieee80211com *ic = &usc->sc_sc.sc_ic;
+ struct athn_usb_cmd_key *cmd = arg;
+ int s;
+
+ usc->sc_key_tasks--;
+
+ s = splnet();
+ athn_usb_write_barrier(&usc->sc_sc);
+ athn_set_key(ic, cmd->ni, cmd->key);
+ if (usc->sc_key_tasks == 0) {
+ DPRINTF(("marking port %s valid\n",
+ ether_sprintf(cmd->ni->ni_macaddr)));
+ cmd->ni->ni_port_valid = 1;
+ ieee80211_set_link_state(ic, LINK_STATE_UP);
+ }
+ if (cmd->ni != NULL)
+ ieee80211_release_node(ic, cmd->ni);
+ splx(s);
+#endif
+}
+
+int
+athn_usb_delete_key(struct ieee80211vap *vap, const struct ieee80211_key *k)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+ struct athn_usb_softc *usc = ic->ic_softc;
+ struct athn_usb_cmd_key cmd;
+
+ if (!(ic->ic_if.if_flags & IFF_RUNNING) ||
+ ic->ic_state != IEEE80211_S_RUN)
+ return; /* Nothing to do. */
+
+ /* Do it in a process context. */
+ cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL;
+ cmd.key = k;
+ athn_usb_do_async(usc, athn_usb_delete_key_cb, &cmd, sizeof(cmd));
+#endif
+}
+
+void
+athn_usb_delete_key_cb(struct athn_usb_softc *usc, void *arg)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct ieee80211com *ic = &usc->sc_sc.sc_ic;
+ struct athn_usb_cmd_key *cmd = arg;
+ int s;
+
+ s = splnet();
+ athn_delete_key(ic, cmd->ni, cmd->key);
+ if (cmd->ni != NULL)
+ ieee80211_release_node(ic, cmd->ni);
+ splx(s);
+#endif
+}
+
+#ifndef IEEE80211_STA_ONLY
+void
+athn_usb_bcneof(struct usbd_xfer *xfer, void *priv)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_tx_data *data = priv;
+ struct athn_usb_softc *usc = data->sc;
+
+ if (__predict_false(status == USBD_STALLED))
+ usbd_clear_endpoint_stall_async(usc->tx_data_pipe);
+ usc->tx_bcn = data;
+#endif
+}
+
+/*
+ * Process Software Beacon Alert interrupts.
+ */
+void
+athn_usb_swba(struct athn_usb_softc *usc)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct athn_usb_tx_data *data;
+ struct ieee80211_frame *wh;
+ struct ar_stream_hdr *hdr;
+ struct ar_htc_frame_hdr *htc;
+ struct ar_tx_bcn *bcn;
+ struct mbuf *m;
+ int error;
+
+ if (ic->ic_dtim_count == 0)
+ ic->ic_dtim_count = ic->ic_dtim_period - 1;
+ else
+ ic->ic_dtim_count--;
+
+ /* Make sure previous beacon has been sent. */
+ if (usc->tx_bcn == NULL)
+ return;
+ data = usc->tx_bcn;
+
+ /* Get new beacon. */
+ m = ieee80211_beacon_alloc(ic, ic->ic_bss);
+ if (__predict_false(m == NULL))
+ return;
+ /* Assign sequence number. */
+ wh = mtod(m, struct ieee80211_frame *);
+ *(uint16_t *)&wh->i_seq[0] =
+ htole16(ic->ic_bss->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
+ ic->ic_bss->ni_txseq++;
+
+ hdr = (struct ar_stream_hdr *)data->buf;
+ hdr->tag = htole16(AR_USB_TX_STREAM_TAG);
+ hdr->len = htole16(sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len);
+
+ htc = (struct ar_htc_frame_hdr *)&hdr[1];
+ memset(htc, 0, sizeof(*htc));
+ htc->endpoint_id = usc->ep_bcn;
+ htc->payload_len = htobe16(sizeof(*bcn) + m->m_pkthdr.len);
+
+ bcn = (struct ar_tx_bcn *)&htc[1];
+ memset(bcn, 0, sizeof(*bcn));
+ bcn->vif_idx = 0;
+
+ m_copydata(m, 0, m->m_pkthdr.len, &bcn[1]);
+
+ usbd_setup_xfer(data->xfer, usc->tx_data_pipe, data, data->buf,
+ sizeof(*hdr) + sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len,
+ USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT,
+ athn_usb_bcneof);
+
+ m_freem(m);
+ usc->tx_bcn = NULL;
+ error = usbd_transfer(data->xfer);
+ if (__predict_false(error != USBD_IN_PROGRESS && error != 0))
+ usc->tx_bcn = data;
+#endif
+}
+#endif
+
+/* Update current transmit rate for a node based on firmware Tx status. */
+void
+athn_usb_tx_status(void *arg, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct ar_wmi_evt_txstatus *ts = arg;
+ struct athn_node *an = (struct athn_node *)ni;
+ uint8_t rate_index = (ts->rate & AR_HTC_TXSTAT_RATE);
+
+ if (an->sta_index != ts->cookie) /* Tx report for a different node */
+ return;
+
+ if (ts->flags & AR_HTC_TXSTAT_MCS) {
+ if (isset(ni->ni_rxmcs, rate_index))
+ ni->ni_txmcs = rate_index;
+ } else if (rate_index < ni->ni_rates.rs_nrates)
+ ni->ni_txrate = rate_index;
+#endif
+}
+
+void
+athn_usb_rx_wmi_ctrl(struct athn_usb_softc *usc, uint8_t *buf, int len)
+{
+ struct ar_wmi_cmd_hdr *wmi;
+ uint16_t cmd_id;
+
+ if (__predict_false(len < sizeof(*wmi)))
+ return;
+ wmi = (struct ar_wmi_cmd_hdr *)buf;
+// cmd_id = betoh16(wmi->cmd_id);
+ cmd_id = be16toh(wmi->cmd_id);
+
+ if (!(cmd_id & AR_WMI_EVT_FLAG)) {
+ if (usc->wait_cmd_id != cmd_id) {
+ printf("errir, fiz me\n");
+ return; /* Unexpected reply. */
+ }
+ if (usc->obuf != NULL) {
+ /* Copy answer into caller supplied buffer. */
+ memcpy(usc->obuf, &wmi[1], len - sizeof(*wmi));
+ }
+ /* Notify caller of completion. */
+ wakeup(&usc->wait_cmd_id);
+ return;
+ }
+ switch (cmd_id & 0xfff) {
+#ifndef IEEE80211_STA_ONLY
+ case AR_WMI_EVT_SWBA:
+ athn_usb_swba(usc);
+ break;
+#endif
+ case AR_WMI_EVT_TXSTATUS: {
+#if 0 // Temporary commenting this out
+ struct ar_wmi_evt_txstatus_list *tsl;
+ int i;
+
+ tsl = (struct ar_wmi_evt_txstatus_list *)&wmi[1];
+ for (i = 0; i < tsl->count && i < nitems(tsl->ts); i++) {
+ struct ieee80211com *ic = &usc->sc_sc.sc_ic;
+ struct athn_node *an = (struct athn_node *)ic->ic_bss;
+ struct ar_wmi_evt_txstatus *ts = &tsl->ts[i];
+ uint8_t qid;
+
+ /* Skip the node we use to send management frames. */
+ if (ts->cookie == 0)
+ continue;
+
+ /* Skip Tx reports for non-data frame endpoints. */
+ qid = (ts->rate & AR_HTC_TXSTAT_EPID) >>
+ AR_HTC_TXSTAT_EPID_SHIFT;
+ if (qid != usc->ep_data[EDCA_AC_BE] &&
+ qid != usc->ep_data[EDCA_AC_BK] &&
+ qid != usc->ep_data[EDCA_AC_VI] &&
+ qid != usc->ep_data[EDCA_AC_VO])
+ continue;
+
+ if (ts->cookie == an->sta_index)
+ athn_usb_tx_status(ts, ic->ic_bss);
+ else
+ ieee80211_iterate_nodes(ic, athn_usb_tx_status,
+ ts);
+ }
+ break;
+#endif // End of the temp comment out
+ printf("AR_WMI_EVT_TXSTATUS The above code is temporary removed, this should be enabled.\n");
+ }
+ case AR_WMI_EVT_FATAL:
+ device_printf(usc->sc_sc.sc_dev, "fatal firmware error\n");
+ break;
+ default:
+ DPRINTF(("WMI event %d ignored\n", cmd_id));
+ break;
+ }
+}
+
+void
+athn_usb_intr(struct usb_xfer *xfer, usb_error_t usb_error)
+{
+ int actlen;
+ struct athn_usb_softc *usc = usbd_xfer_softc(xfer);
+ struct ar_htc_frame_hdr *htc;
+ struct ar_htc_msg_hdr *msg;
+ uint8_t *buf = usc->ibuf;
+ struct usb_page_cache *pc = NULL;
+ int len;
+ uint16_t msg_id;
+// struct athn_usb_tx_data *data = &usc->tx_cmd;
+
+ usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+ switch(USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ pc = usbd_xfer_get_frame(xfer, 0);
+ usbd_copy_out(pc, 0, usc->ibuf, actlen);
+ len = actlen;
+
+ /* Skip watchdog pattern if present. */
+ if (len >= 4 && *(uint32_t *)buf == htobe32(0x00c60000)) {
+ buf += 4;
+ len -= 4;
+ }
+
+ htc = (struct ar_htc_frame_hdr *)buf;
+ buf += sizeof(*htc);
+ len -= sizeof(*htc);
+
+ if (htc->endpoint_id != 0) {
+// if (__predict_false(htc->endpoint_id != usc->ep_ctrl))
+// return;
+ /* Remove trailer if present .*/
+ if (htc->flags & AR_HTC_FLAG_TRAILER) {
+ if (__predict_false(len < htc->control[0]))
+ goto TR_SETUP;
+ // return;
+ len -= htc->control[0];
+ }
+ athn_usb_rx_wmi_ctrl(usc, buf, len);
+ goto TR_SETUP;
+// return;
+ }
+
+ // XXX put this back in
+ if (__predict_false(len < sizeof(*msg))) {
+ goto TR_SETUP;
+ // return;
+ }
+ msg = (struct ar_htc_msg_hdr *)buf;
+ msg_id = be16toh(msg->msg_id);
+
+ switch (msg_id) {
+ case AR_HTC_MSG_READY:
+ if (usc->wait_msg_id != msg_id) {
+ break;
+ }
+ usc->wait_msg_id = 0;
+ wakeup(&usc->wait_msg_id);
+ break;
+ case AR_HTC_MSG_CONN_SVC_RSP:
+ if (usc->wait_msg_id != msg_id) {
+ break;
+ }
+ if (usc->msg_conn_svc_rsp != NULL) {
+ memcpy(usc->msg_conn_svc_rsp, &msg[1],
+ sizeof(struct ar_htc_msg_conn_svc_rsp));
+ }
+ usc->wait_msg_id = 0;
+ wakeup(&usc->wait_msg_id);
+ break;
+ case AR_HTC_MSG_CONF_PIPE_RSP:
+ if (usc->wait_msg_id != msg_id)
+ break;
+ usc->wait_msg_id = 0;
+ wakeup(&usc->wait_msg_id);
+ break;
+ default:
+ printf("====HTC message %d ignored\n", msg_id); // This should be a debug message?
+ break;
+ }
+
+
+// break; /* No fallthrough */
+ /* XXX Fallthrough */
+ case USB_ST_SETUP:
+ TR_SETUP:
+ usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
+ usbd_xfer_set_frames(xfer, 1);
+ usbd_transfer_submit(xfer);
+ break;
+ case USB_ST_ERROR:
+ break;
+ default: /* Error */
+ break;
+ // XXX Based on other drivers, there should be a verification for USB_ERR_CANCELLED
+ }
+
+ return;
+}
+
+void
+athn_usb_rx_radiotap(struct athn_softc *sc, struct mbuf *m,
+ struct ar_rx_status *rs)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+
+#define IEEE80211_RADIOTAP_F_SHORTGI 0x80 /* XXX from FBSD */
+
+ struct athn_rx_radiotap_header *tap = &sc->sc_rxtap;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct mbuf mb;
+ uint8_t rate;
+
+ tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
+ tap->wr_tsft = htole64(betoh64(rs->rs_tstamp));
+ tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
+ tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
+ tap->wr_dbm_antsignal = rs->rs_rssi;
+ /* XXX noise. */
+ tap->wr_antenna = rs->rs_antenna;
+ tap->wr_rate = 0; /* In case it can't be found below. */
+ rate = rs->rs_rate;
+ if (rate & 0x80) { /* HT. */
+ /* Bit 7 set means HT MCS instead of rate. */
+ tap->wr_rate = rate;
+ if (!(rs->rs_flags & AR_RXS_FLAG_GI))
+ tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI;
+
+ } else if (rate & 0x10) { /* CCK. */
+ if (rate & 0x04)
+ tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+ switch (rate & ~0x14) {
+ case 0xb: tap->wr_rate = 2; break;
+ case 0xa: tap->wr_rate = 4; break;
+ case 0x9: tap->wr_rate = 11; break;
+ case 0x8: tap->wr_rate = 22; break;
+ }
+ } else { /* OFDM. */
+ switch (rate) {
+ case 0xb: tap->wr_rate = 12; break;
+ case 0xf: tap->wr_rate = 18; break;
+ case 0xa: tap->wr_rate = 24; break;
+ case 0xe: tap->wr_rate = 36; break;
+ case 0x9: tap->wr_rate = 48; break;
+ case 0xd: tap->wr_rate = 72; break;
+ case 0x8: tap->wr_rate = 96; break;
+ case 0xc: tap->wr_rate = 108; break;
+ }
+ }
+ mb.m_data = (caddr_t)tap;
+ mb.m_len = sc->sc_rxtap_len;
+ mb.m_next = m;
+ mb.m_nextpkt = NULL;
+ mb.m_type = 0;
+ mb.m_flags = 0;
+ bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
+#endif
+}
+
+void
+athn_usb_rx_frame(struct athn_usb_softc *usc, struct mbuf *m)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+ struct ieee80211_frame *wh;
+ struct ieee80211_node *ni;
+ struct ieee80211_rxinfo rxi;
+ struct ar_htc_frame_hdr *htc;
+ struct ar_rx_status *rs;
+ uint16_t datalen;
+ int s;
+
+ if (__predict_false(m->m_len < sizeof(*htc)))
+ goto skip;
+ htc = mtod(m, struct ar_htc_frame_hdr *);
+ if (__predict_false(htc->endpoint_id == 0)) {
+ DPRINTF(("bad endpoint %d\n", htc->endpoint_id));
+ goto skip;
+ }
+ if (htc->flags & AR_HTC_FLAG_TRAILER) {
+ if (m->m_len < htc->control[0])
+ goto skip;
+ m_adj(m, -(int)htc->control[0]);
+ }
+ m_adj(m, sizeof(*htc)); /* Strip HTC header. */
+
+ if (__predict_false(m->m_len < sizeof(*rs)))
+ goto skip;
+ rs = mtod(m, struct ar_rx_status *);
+
+ /* Make sure that payload fits. */
+ datalen = betoh16(rs->rs_datalen);
+ if (__predict_false(m->m_len < sizeof(*rs) + datalen))
+ goto skip;
+
+ if (__predict_false(datalen < sizeof(*wh) + IEEE80211_CRC_LEN))
+ goto skip;
+
+ if (rs->rs_status != 0) {
+ if (rs->rs_status & AR_RXS_RXERR_DECRYPT)
+ ic->ic_stats.is_ccmp_dec_errs++;
+ ifp->if_ierrors++;
+ goto skip;
+ }
+ m_adj(m, sizeof(*rs)); /* Strip Rx status. */
+
+ s = splnet();
+
+ /* Grab a reference to the source node. */
+ wh = mtod(m, struct ieee80211_frame *);
+ ni = ieee80211_find_rxnode(ic, wh);
+
+ /* Remove any HW padding after the 802.11 header. */
+ if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) {
+ u_int hdrlen = ieee80211_get_hdrlen(wh);
+ if (hdrlen & 3) {
+ memmove((caddr_t)wh + 2, wh, hdrlen);
+ m_adj(m, 2);
+ }
+ wh = mtod(m, struct ieee80211_frame *);
+ }
+#if NBPFILTER > 0
+ if (__predict_false(sc->sc_drvbpf != NULL))
+ athn_usb_rx_radiotap(sc, m, rs);
+#endif
+ /* Trim 802.11 FCS after radiotap. */
+ m_adj(m, -IEEE80211_CRC_LEN);
+
+ /* Send the frame to the 802.11 layer. */
+ rxi.rxi_flags = 0;
+ rxi.rxi_rssi = rs->rs_rssi + AR_USB_DEFAULT_NF;
+ rxi.rxi_tstamp = betoh64(rs->rs_tstamp);
+ if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL) &&
+ (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
+ (ic->ic_flags & IEEE80211_F_RSNON) &&
+ (ni->ni_flags & IEEE80211_NODE_RXPROT) &&
+ (ni->ni_rsncipher == IEEE80211_CIPHER_CCMP ||
+ (IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+ ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP))) {
+ if (ar5008_ccmp_decap(sc, m, ni) != 0) {
+ ifp->if_ierrors++;
+ ieee80211_release_node(ic, ni);
+ splx(s);
+ goto skip;
+ }
+ rxi.rxi_flags |= IEEE80211_RXI_HWDEC;
+ }
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
+
+ /* Node is no longer needed. */
+ ieee80211_release_node(ic, ni);
+ splx(s);
+ return;
+ skip:
+ m_freem(m);
+#endif
+}
+
+void
+athn_usb_rxeof(struct usbd_xfer *xfer, void *priv)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ struct athn_usb_rx_data *data = priv;
+ struct athn_usb_softc *usc = data->sc;
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+ struct athn_usb_rx_stream *stream = &usc->rx_stream;
+ uint8_t *buf = data->buf;
+ struct ar_stream_hdr *hdr;
+ struct mbuf *m;
+ uint16_t pktlen;
+ int off, len;
+
+ if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
+ DPRINTF(("RX status=%d\n", status));
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(usc->rx_data_pipe);
+ if (status != USBD_CANCELLED)
+ goto resubmit;
+ return;
+ }
+ usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
+
+ if (stream->left > 0) {
+ if (len >= stream->left) {
+ /* We have all our pktlen bytes now. */
+ if (__predict_true(stream->m != NULL)) {
+ memcpy(mtod(stream->m, uint8_t *) +
+ stream->moff, buf, stream->left);
+ athn_usb_rx_frame(usc, stream->m, &ml);
+ stream->m = NULL;
+ }
+ /* Next header is 32-bit aligned. */
+ off = (stream->left + 3) & ~3;
+ buf += off;
+ len -= off;
+ stream->left = 0;
+ } else {
+ /* Still need more bytes, save what we have. */
+ if (__predict_true(stream->m != NULL)) {
+ memcpy(mtod(stream->m, uint8_t *) +
+ stream->moff, buf, len);
+ stream->moff += len;
+ }
+ stream->left -= len;
+ goto resubmit;
+ }
+ }
+ KASSERT(stream->left == 0);
+ while (len >= sizeof(*hdr)) {
+ hdr = (struct ar_stream_hdr *)buf;
+ if (hdr->tag != htole16(AR_USB_RX_STREAM_TAG)) {
+ DPRINTF(("invalid tag 0x%x\n", hdr->tag));
+ break;
+ }
+ pktlen = letoh16(hdr->len);
+ buf += sizeof(*hdr);
+ len -= sizeof(*hdr);
+
+ if (__predict_true(pktlen <= MCLBYTES)) {
+ /* Allocate an mbuf to store the next pktlen bytes. */
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (__predict_true(m != NULL)) {
+ m->m_pkthdr.len = m->m_len = pktlen;
+ if (pktlen > MHLEN) {
+ MCLGET(m, M_DONTWAIT);
+ if (!(m->m_flags & M_EXT)) {
+ m_free(m);
+ m = NULL;
+ }
+ }
+ }
+ } else /* Drop frames larger than MCLBYTES. */
+ m = NULL;
+
+ if (m == NULL)
+ ifp->if_ierrors++;
+
+ /*
+ * NB: m can be NULL, in which case the next pktlen bytes
+ * will be discarded from the Rx stream.
+ */
+ if (pktlen > len) {
+ /* Need more bytes, save what we have. */
+ stream->m = m; /* NB: m can be NULL. */
+ if (__predict_true(stream->m != NULL)) {
+ memcpy(mtod(stream->m, uint8_t *), buf, len);
+ stream->moff = len;
+ }
+ stream->left = pktlen - len;
+ goto resubmit;
+ }
+ if (__predict_true(m != NULL)) {
+ /* We have all the pktlen bytes in this xfer. */
+ memcpy(mtod(m, uint8_t *), buf, pktlen);
+ athn_usb_rx_frame(usc, m, &ml);
+ }
+
+ /* Next header is 32-bit aligned. */
+ off = (pktlen + 3) & ~3;
+ buf += off;
+ len -= off;
+ }
+ if_input(ifp, &ml);
+
+ resubmit:
+ /* Setup a new transfer. */
+ usbd_setup_xfer(xfer, usc->rx_data_pipe, data, data->buf,
+ ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
+ USBD_NO_TIMEOUT, athn_usb_rxeof);
+ (void)usbd_transfer(xfer);
+#endif
+}
+
+void
+athn_usb_txeof(struct usbd_xfer *xfer, void *priv)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_usb_tx_data *data = priv;
+ struct athn_usb_softc *usc = data->sc;
+ struct athn_softc *sc = &usc->sc_sc;
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
+ int s;
+
+ s = splnet();
+ /* Put this Tx buffer back to our free list. */
+ TAILQ_INSERT_TAIL(&usc->tx_free_list, data, next);
+
+ if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
+ DPRINTF(("TX status=%d\n", status));
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(usc->tx_data_pipe);
+ ifp->if_oerrors++;
+ splx(s);
+ /* XXX Why return? */
+ return;
+ }
+ sc->sc_tx_timer = 0;
+
+ /* We just released a Tx buffer, notify Tx. */
+ if (ifq_is_oactive(&ifp->if_snd)) {
+ ifq_clr_oactive(&ifp->if_snd);
+ ifp->if_start(ifp);
+ }
+ splx(s);
+#endif
+}
+
+int
+athn_usb_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
+{
+ printf("%s unimplemented.\n", __func__);
+ return 0;
+#if 0
+ struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
+ struct athn_node *an = (struct athn_node *)ni;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_frame *wh;
+ struct ieee80211_key *k = NULL;
+ struct athn_usb_tx_data *data;
+ struct ar_stream_hdr *hdr;
+ struct ar_htc_frame_hdr *htc;
+ struct ar_tx_frame *txf;
+ struct ar_tx_mgmt *txm;
+ uint8_t *frm;
+ uint16_t qos;
+ uint8_t qid, tid = 0;
+ int hasqos, xferlen, error;
+
+ wh = mtod(m, struct ieee80211_frame *);
+ if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
+ k = ieee80211_get_txkey(ic, wh, ni);
+ if (k->k_cipher == IEEE80211_CIPHER_CCMP) {
+ u_int hdrlen = ieee80211_get_hdrlen(wh);
+ if (ar5008_ccmp_encap(m, hdrlen, k) != 0)
+ return (ENOBUFS);
+ } else {
+ if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
+ return (ENOBUFS);
+ k = NULL; /* skip hardware crypto further below */
+ }
+ wh = mtod(m, struct ieee80211_frame *);
+ }
+ if ((hasqos = ieee80211_has_qos(wh))) {
+ qos = ieee80211_get_qos(wh);
+ tid = qos & IEEE80211_QOS_TID;
+ qid = ieee80211_up_to_ac(ic, tid);
+ } else
+ qid = EDCA_AC_BE;
+
+ /* Grab a Tx buffer from our free list. */
+ data = TAILQ_FIRST(&usc->tx_free_list);
+ TAILQ_REMOVE(&usc->tx_free_list, data, next);
+
+#if NBPFILTER > 0
+ /* XXX Change radiotap Tx header for USB (no txrate). */
+ if (__predict_false(sc->sc_drvbpf != NULL)) {
+ struct athn_tx_radiotap_header *tap = &sc->sc_txtap;
+ struct mbuf mb;
+
+ tap->wt_flags = 0;
+ tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
+ tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
+ mb.m_data = (caddr_t)tap;
+ mb.m_len = sc->sc_txtap_len;
+ mb.m_next = m;
+ mb.m_nextpkt = NULL;
+ mb.m_type = 0;
+ mb.m_flags = 0;
+ bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
+ }
+#endif
+
+ /* NB: We don't take advantage of USB Tx stream mode for now. */
+ hdr = (struct ar_stream_hdr *)data->buf;
+ hdr->tag = htole16(AR_USB_TX_STREAM_TAG);
+
+ htc = (struct ar_htc_frame_hdr *)&hdr[1];
+ memset(htc, 0, sizeof(*htc));
+ if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
+ IEEE80211_FC0_TYPE_DATA) {
+ htc->endpoint_id = usc->ep_data[qid];
+
+ txf = (struct ar_tx_frame *)&htc[1];
+ memset(txf, 0, sizeof(*txf));
+ txf->data_type = AR_HTC_NORMAL;
+ txf->node_idx = an->sta_index;
+ txf->vif_idx = 0;
+ txf->tid = tid;
+ if (m->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold)
+ txf->flags |= htobe32(AR_HTC_TX_RTSCTS);
+ else if (ic->ic_flags & IEEE80211_F_USEPROT) {
+ if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
+ txf->flags |= htobe32(AR_HTC_TX_CTSONLY);
+ else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
+ txf->flags |= htobe32(AR_HTC_TX_RTSCTS);
+ }
+
+ if (k != NULL) {
+ /* Map 802.11 cipher to hardware encryption type. */
+ if (k->k_cipher == IEEE80211_CIPHER_CCMP) {
+ txf->key_type = AR_ENCR_TYPE_AES;
+ } else
+ panic("unsupported cipher");
+ /*
+ * NB: The key cache entry index is stored in the key
+ * private field when the key is installed.
+ */
+ txf->key_idx = (uintptr_t)k->k_priv;
+ } else
+ txf->key_idx = 0xff;
+
+ txf->cookie = an->sta_index;
+ frm = (uint8_t *)&txf[1];
+ } else {
+ htc->endpoint_id = usc->ep_mgmt;
+
+ txm = (struct ar_tx_mgmt *)&htc[1];
+ memset(txm, 0, sizeof(*txm));
+ txm->node_idx = an->sta_index;
+ txm->vif_idx = 0;
+ txm->key_idx = 0xff;
+ txm->cookie = an->sta_index;
+ frm = (uint8_t *)&txm[1];
+ }
+ /* Copy payload. */
+ m_copydata(m, 0, m->m_pkthdr.len, frm);
+ frm += m->m_pkthdr.len;
+ m_freem(m);
+
+ /* Finalize headers. */
+ htc->payload_len = htobe16(frm - (uint8_t *)&htc[1]);
+ hdr->len = htole16(frm - (uint8_t *)&hdr[1]);
+ xferlen = frm - data->buf;
+
+ usbd_setup_xfer(data->xfer, usc->tx_data_pipe, data, data->buf,
+ xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT,
+ athn_usb_txeof);
+ error = usbd_transfer(data->xfer);
+ if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) {
+ /* Put this Tx buffer back to our free list. */
+ TAILQ_INSERT_TAIL(&usc->tx_free_list, data, next);
+ return (error);
+ }
+ ieee80211_release_node(ic, ni);
+ return (0);
+#endif
+}
+
+void
+athn_usb_start(struct ifnet *ifp)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_softc *sc = ifp->if_softc;
+ struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_node *ni;
+ struct mbuf *m;
+
+ if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
+ return;
+
+ for (;;) {
+ if (TAILQ_EMPTY(&usc->tx_free_list)) {
+ ifq_set_oactive(&ifp->if_snd);
+ break;
+ }
+ /* Send pending management frames first. */
+ m = mq_dequeue(&ic->ic_mgtq);
+ if (m != NULL) {
+ ni = m->m_pkthdr.ph_cookie;
+ goto sendit;
+ }
+ if (ic->ic_state != IEEE80211_S_RUN)
+ break;
+
+ /* Encapsulate and send data frames. */
+ m = ifq_dequeue(&ifp->if_snd);
+ if (m == NULL)
+ break;
+#if NBPFILTER > 0
+ if (ifp->if_bpf != NULL)
+ bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
+#endif
+ if ((m = ieee80211_encap(ifp, m, &ni)) == NULL)
+ continue;
+ sendit:
+#if NBPFILTER > 0
+ if (ic->ic_rawbpf != NULL)
+ bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
+#endif
+ if (athn_usb_tx(sc, m, ni) != 0) {
+ ieee80211_release_node(ic, ni);
+ ifp->if_oerrors++;
+ continue;
+ }
+
+ sc->sc_tx_timer = 5;
+ ifp->if_timer = 1;
+ }
+#endif
+}
+
+void
+athn_usb_watchdog(struct ifnet *ifp)
+{
+ printf("%s unimplemented.\n", __func__);
+#if 0
+ struct athn_softc *sc = ifp->if_softc;
+
+ ifp->if_timer = 0;
+
+ if (sc->sc_tx_timer > 0) {
+ if (--sc->sc_tx_timer == 0) {
+ printf("%s: device timeout\n", sc->sc_dev.dv_xname);
+ /* athn_usb_init(ifp); XXX needs a process context! */
+ ifp->if_oerrors++;
+ return;
+ }
+ ifp->if_timer = 1;
+ }
+ ieee80211_watchdog(ifp);
+#endif
+}
+
+int
+athn_usb_ioctl(struct ieee80211com *ic, u_long cmd, void *data)
+{
+// struct athn_softc *sc = ic->ic_softc;
+/// struct ifreq *ifr = (struct ifreq *)data;
+// struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
+// struct ieee80211com *ic = &sc->sc_ic;
+ int error = 0;
+
+
+
+// usbd_ref_incr(usc->sc_udev);
+
+ switch (cmd) {
+ case SIOCSIFADDR:
+ printf("SIOCIFADDR not implemented!\n");
+// ifp->if_flags |= IFF_UP;
+ /* FALLTHROUGH */
+ case SIOCSIFFLAGS:
+ printf("SIOCSIFFLAGS not implemented!\n");
+/*
+ if (ifp->if_flags & IFF_UP) {
+ if (!(ifp->if_flags & IFF_RUNNING))
+ error = athn_usb_init(ifp);
+ } else {
+ if (ifp->if_flags & IFF_RUNNING)
+ athn_usb_stop(ifp);
+ }
+*/
+ break;
+ case IEEE80211_IOC_CHANNEL:
+// case SIOCS80211CHANNEL: // OpenBSD version
+ printf("SIOCS80211CHANNEL not implemented!\n");
+/*
+ error = ieee80211_ioctl(ifp, cmd, data);
+ if (error == ENETRESET &&
+ ic->ic_opmode == IEEE80211_M_MONITOR) {
+ if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
+ (IFF_UP | IFF_RUNNING)) {
+ athn_usb_switch_chan(sc, ic->ic_ibss_chan,
+ NULL);
+ }
+ error = 0;
+ }
+*/
+ break;
+ default: {
+ struct ieee80211vap *vap;
+// struct ifnet *ifp;
+ printf("default not implemented! cmd = %lu\n", cmd);
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ printf("A VAP failed\n");
+// ifp = vap->iv_ifp;
+// printf("ifp->if_xname: %s\n", ic->ic_name);
+ }
+ error = ENOTTY;
+// error = ieee80211_ioctl(ifp, cmd, data);
+ }
+ }
+
+ /*
+ if (error == ENETRESET) {
+ error = 0;
+ if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
+ (IFF_UP | IFF_RUNNING)) {
+ athn_usb_stop(ifp);
+ error = athn_usb_init(ifp);
+ }
+ }
+ */
+
+// usbd_ref_decr(usc->sc_udev);
+
+ return (error);
+}
+
+int
+athn_usb_init(struct athn_softc *sc)
+{
+ DEBUG_PRINTF("%s unimplemented.\n", __func__);
+// struct athn_softc *sc = ifp->if_softc;
+// struct athn_usb_softc *usc = device_get_softc(self);
+ struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
+ struct athn_ops *ops = &sc->ops;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211_channel *c, *extc;
+// struct athn_usb_rx_data *data;
+ struct ar_htc_target_vif hvif;
+ struct ar_htc_target_sta sta;
+ struct ar_htc_cap_target hic;
+ uint16_t mode;
+ //int i, error;
+ int error;
+
+ /* Init host async commands ring. */
+ usc->cmdq.cur = usc->cmdq.next = usc->cmdq.queued = 0;
+
+ /* Allocate Tx/Rx buffers. */
+ error = athn_usb_alloc_rx_list(usc);
+ if (error != 0)
+ goto fail;
+ else
+ printf("not a phayl 1!\n");
+ error = athn_usb_alloc_tx_list(usc);
+ if (error != 0)
+ goto fail;
+ else
+ printf("not a phayl 2!\n");
+ /* Steal one buffer for beacons. */
+ DEBUG_PRINTF("Tracing: %s:%d\n", __func__, __LINE__);
+ usc->tx_bcn = TAILQ_FIRST(&usc->tx_free_list);
+ DEBUG_PRINTF("Tracing: %s:%d\n", __func__, __LINE__);
+ TAILQ_REMOVE(&usc->tx_free_list, usc->tx_bcn, next);
+ DEBUG_PRINTF("Tracing: %s:%d\n", __func__, __LINE__);
+
+// c = ic->ic_bsschan;
+ c = ic->ic_curchan;
+ extc = NULL;
+ DEBUG_PRINTF("temporarily cutting out iv_bss->ni_chan, DEFINITELY do not ignore this\n");
+
+ /* In case a new MAC address has been configured. */
+// IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
+
+ error = athn_set_power_awake(sc);
+ if (error != 0) {
+ printf("Power on failed 1\n");
+ goto fail;
+ }
+
+ error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_FLUSH_RECV);
+ if (error != 0) {
+ printf("Power on failed 2\n");
+ goto fail;
+ }
+
+ error = athn_hw_reset(sc, c, extc, 1);
+ if (error != 0) {
+ printf("Power on failed 3\n");
+ goto fail;
+ }
+
+printf("earlybird\n");
+return 1;
+ ops->set_txpower(sc, c, extc);
+
+ mode = htobe16(IEEE80211_IS_CHAN_2GHZ(c) ?
+ AR_HTC_MODE_11NG : AR_HTC_MODE_11NA);
+ // Hard-coding in AR_HTC_MODE_11NA
+ mode = AR_HTC_MODE_11NA;
+ error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE,
+ &mode, sizeof(mode), NULL);
+ if (error != 0)
+ goto fail;
+
+ error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ATH_INIT);
+ if (error != 0)
+ goto fail;
+
+ error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV);
+ if (error != 0)
+ goto fail;
+
+ athn_rx_start(sc);
+
+ /* Create main interface on target. */
+ memset(&hvif, 0, sizeof(hvif));
+ hvif.index = 0;
+ IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_macaddr);
+ switch (ic->ic_opmode) {
+ case IEEE80211_M_STA:
+ hvif.opmode = htobe32(AR_HTC_M_STA);
+ break;
+ case IEEE80211_M_MONITOR:
+ hvif.opmode = htobe32(AR_HTC_M_MONITOR);
+ break;
+#ifndef IEEE80211_STA_ONLY
+ case IEEE80211_M_IBSS:
+ hvif.opmode = htobe32(AR_HTC_M_IBSS);
+ break;
+ case IEEE80211_M_AHDEMO:
+ hvif.opmode = htobe32(AR_HTC_M_AHDEMO);
+ break;
+ case IEEE80211_M_HOSTAP:
+ hvif.opmode = htobe32(AR_HTC_M_HOSTAP);
+ break;
+ default:
+ goto fail;
+#endif
+ }
+// hvif.rtsthreshold = htobe16(ic->ic_rtsthreshold);
+ DPRINTF(("creating VAP\n"));
+ error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_CREATE,
+ &hvif, sizeof(hvif), NULL);
+ if (error != 0)
+ goto fail;
+
+ /* Create a fake node to send management frames before assoc. */
+ memset(&sta, 0, sizeof(sta));
+ IEEE80211_ADDR_COPY(sta.macaddr, ic->ic_macaddr);
+ sta.sta_index = 0;
+ sta.is_vif_sta = 1;
+ sta.vif_index = hvif.index;
+ sta.maxampdu = 0xffff;
+ DPRINTF(("creating default node\n"));
+ error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_CREATE,
+ &sta, sizeof(sta), NULL);
+ if (error != 0)
+ goto fail;
+ usc->free_node_slots = ~(1 << sta.sta_index);
+
+ /* Update target capabilities. */
+ memset(&hic, 0, sizeof(hic));
+ hic.ampdu_limit = htobe32(0x0000ffff);
+ hic.ampdu_subframes = 20;
+ hic.txchainmask = sc->txchainmask;
+ DPRINTF(("updating target configuration\n"));
+ error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TARGET_IC_UPDATE,
+ &hic, sizeof(hic), NULL);
+ if (error != 0)
+ goto fail;
+
+ return 0; // Get out of jail early card
+#if 0
+ /* Queue Rx xfers. */
+ for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) {
+ data = &usc->rx_data[i];
+
+ usbd_setup_xfer(data->xfer, usc->rx_data_pipe, data, data->buf,
+ ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
+ USBD_NO_TIMEOUT, athn_usb_rxeof);
+ error = usbd_transfer(data->xfer);
+ if (error != 0 && error != USBD_IN_PROGRESS)
+ goto fail;
+ }
+ /* We're ready to go. */
+ ifp->if_flags |= IFF_RUNNING;
+ ifq_clr_oactive(&ifp->if_snd);
+
+#ifdef notyet
+ if (ic->ic_flags & IEEE80211_F_WEPON) {
+ /* Install WEP keys. */
+ for (i = 0; i < IEEE80211_WEP_NKID; i++)
+ athn_usb_set_key(ic, NULL, &ic->ic_nw_keys[i]);
+ }
+#endif
+ if (ic->ic_opmode == IEEE80211_M_MONITOR)
+ ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+ else
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+#endif
+ athn_usb_wait_async(usc);
+ return (0);
+ fail:
+ DEBUG_PRINTF("athn_usb_stop not working cuz you know...\n");
+// athn_usb_stop(ifp);
+ return (error);
+}
+
+static int
+athn_usb_suspend(device_t self)
+{
+ int error;
+ struct athn_usb_softc *usc = device_get_softc(self);
+ // Transparent handler
+ error = athn_usb_stop(usc);
+
+ return (error);
+}
+
+
+static int
+athn_usb_stop(struct athn_usb_softc *usc)
+{
+ DEBUG_PRINTF("%s unimplemented.\n", __func__);
+ struct athn_softc *sc = &usc->sc_sc;
+// struct athn_softc *sc = ifp->if_softc;
+// struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ar_htc_target_vif hvif;
+ uint8_t sta_index;
+// int s;
+
+ DEBUG_PRINTF("This needs to be fixed!\n");
+ /*
+ sc->sc_tx_timer = 0;
+ ifp->if_timer = 0;
+ ifp->if_flags &= ~IFF_RUNNING;
+ ifq_clr_oactive(&ifp->if_snd);
+ */
+
+// s = splusb();
+// ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+
+ /* Wait for all async commands to complete. */
+ athn_usb_wait_async(usc);
+
+ callout_stop(&sc->scan_to);
+ callout_stop(&sc->calib_to);
+
+ /* Remove all non-default nodes. */
+ for (sta_index = 1; sta_index < AR_USB_MAX_STA; sta_index++) {
+ if (usc->free_node_slots & (1 << sta_index))
+ continue;
+ (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE,
+ &sta_index, sizeof(sta_index), NULL);
+ }
+
+ /* Remove main interface. This also invalidates our default node. */
+ memset(&hvif, 0, sizeof(hvif));
+ hvif.index = 0;
+ IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_macaddr);
+ (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_REMOVE,
+ &hvif, sizeof(hvif), NULL);
+
+ usc->free_node_slots = 0xff;
+
+ (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR);
+ (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL);
+ (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV);
+
+ athn_reset(sc, 0);
+ athn_init_pll(sc, NULL);
+ athn_set_power_awake(sc);
+ athn_reset(sc, 1);
+ athn_init_pll(sc, NULL);
+ athn_set_power_sleep(sc);
+
+ /* Abort Tx/Rx. */
+// usbd_abort_pipe(usc->tx_data_pipe);
+// usbd_abort_pipe(usc->rx_data_pipe);
+ usbd_transfer_stop(usc->usc_xfer[ATHN_TX_DATA]);
+ usbd_transfer_stop(usc->usc_xfer[ATHN_RX_DATA]);
+
+ /* Free Tx/Rx buffers. */
+ athn_usb_free_tx_list(usc);
+ athn_usb_free_rx_list(usc);
+
+ /* Flush Rx stream. */
+ m_freem(usc->rx_stream.m);
+ usc->rx_stream.m = NULL;
+ usc->rx_stream.left = 0;
+
+ return 0; // Do error checking elsewhere?
+}
+
+
+
+
+static device_method_t athn_usb_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, athn_usb_match),
+ DEVMETHOD(device_attach, athn_usb_attach),
+ DEVMETHOD(device_detach, athn_usb_detach),
+ DEVMETHOD(device_suspend, athn_usb_suspend),
+ DEVMETHOD(device_resume, athn_usb_resume),
+
+ DEVMETHOD_END
+};
+
+static driver_t athn_usb_driver = {
+ .name = "athn",
+ .methods = athn_usb_methods,
+ .size = sizeof(struct athn_usb_softc)
+};
+
+//static devclass_t athn_usb_devclass;
+
+DRIVER_MODULE(athn_usb, uhub, athn_usb_driver, NULL, NULL);
+MODULE_VERSION(athn_usb, 1);
+MODULE_DEPEND(athn_usb, usb, 1, 1, 1);
+MODULE_DEPEND(athn_usb, wlan, 1, 1, 1);
+MODULE_DEPEND(athn_usb, athn, 1, 1, 1);
+USB_PNP_HOST_INFO(athn_devs);
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1339,6 +1339,7 @@
product ATHEROS2 3CRUSBN275 0x1010 3CRUSBN275
product ATHEROS2 WN612 0x1011 WN612
product ATHEROS2 AR9170 0x9170 AR9170
+product ATHEROS2 AR9271U 0x9271 AR9271U
/* Atmel Comp. products */
product ATMEL STK541 0x2109 Zigbee Controller
diff --git a/sys/modules/athn/Makefile b/sys/modules/athn/Makefile
new file mode 100644
--- /dev/null
+++ b/sys/modules/athn/Makefile
@@ -0,0 +1,26 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/dev/athn
+
+SYSDIR?=${SRCTOP}/sys
+.include "${SYSDIR}/conf/kern.opts.mk"
+
+KMOD = athn
+SRCS = athn.c athnreg.h athnvar.h \
+ ic/ar5008reg.h ic/ar9285.c ic/ar9285reg.h \
+ ic/ar9280.c ic/ar5008.c ic/ar5416.c ic/ar9287.c ic/ar9380.c \
+ bus_if.h device_if.h \
+ opt_bus.h opt_rtwn.h opt_wlan.h
+
+#.PATH: ${SRCTOP}/sys/dev/athn/ar9271
+#SRCS += ar9271u.c ar9271u.h
+
+#opt_rtwn.h:
+# @echo "#define RTWN_DEBUG 1" > ${.TARGET}
+#.if ${MK_SOURCELESS_UCODE} == "no"
+# @echo "#define RTWN_WITHOUT_UCODE 1" >> ${.TARGET}
+#.endif
+
+EXPORT_SYMS= YES
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/athn_usb/Makefile b/sys/modules/athn_usb/Makefile
new file mode 100644
--- /dev/null
+++ b/sys/modules/athn_usb/Makefile
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/dev/athn/usb
+
+SYSDIR?=${SRCTOP}/sys
+.include "${SYSDIR}/conf/kern.opts.mk"
+
+KMOD = if_athn_usb
+SRCS = if_athn_usb.c if_athn_usb.h \
+ ar9271u.c \
+ bus_if.h device_if.h \
+ opt_bus.h opt_athn.h opt_usb.h opt_wlan.h usb_if.h usbdevs.h
+
+#.PATH: ${SRCTOP}/sys/dev/athn/ar9271
+#SRCS += ar9271u.c
+
+#opt_athn.h:
+# @echo "#define RTWN_DEBUG 1" > ${.TARGET}
+#.if ${MK_SOURCELESS_UCODE} == "no"
+# @echo "#define RTWN_WITHOUT_UCODE 1" >> ${.TARGET}
+#.endif
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/athnfw/Makefile b/sys/modules/athnfw/Makefile
new file mode 100644
--- /dev/null
+++ b/sys/modules/athnfw/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= ar9271fw
+
+.include <bsd.subdir.mk>
diff --git a/sys/modules/athnfw/Makefile.inc b/sys/modules/athnfw/Makefile.inc
new file mode 100644
--- /dev/null
+++ b/sys/modules/athnfw/Makefile.inc
@@ -0,0 +1,15 @@
+# $FreeBSD$
+#
+# Common rules for building firmware. Note this gets auto-included
+# by the subdir Makefile's as a consequence of included bsd.kmod.mk.
+
+_FIRM= ${IMG}.fw
+
+CLEANFILES+= ${_FIRM}
+
+FIRMWS= ${_FIRM}:${KMOD}:111
+
+# FIRMWARE_LICENSE= clearbsd
+
+${_FIRM}: ${SRCTOP}/sys/contrib/dev/athn/${_FIRM}.uu
+ uudecode -p ${.ALLSRC} > ${.TARGET}
diff --git a/sys/modules/athnfw/ar9271fw/Makefile b/sys/modules/athnfw/ar9271fw/Makefile
new file mode 100644
--- /dev/null
+++ b/sys/modules/athnfw/ar9271fw/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= athn-ar9271fw
+IMG= athn-ar9271fw
+
+.include <bsd.kmod.mk>

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 21, 8:23 AM (4 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17666947
Default Alt Text
D49884.diff (892 KB)

Event Timeline