0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include <linux/bitrev.h>
0040 #include "carl9170.h"
0041 #include "cmd.h"
0042 #include "phy.h"
0043
0044 static int carl9170_init_power_cal(struct ar9170 *ar)
0045 {
0046 carl9170_regwrite_begin(ar);
0047
0048 carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE_MAX, 0x7f);
0049 carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE1, 0x3f3f3f3f);
0050 carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE2, 0x3f3f3f3f);
0051 carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE3, 0x3f3f3f3f);
0052 carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE4, 0x3f3f3f3f);
0053 carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE5, 0x3f3f3f3f);
0054 carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE6, 0x3f3f3f3f);
0055 carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE7, 0x3f3f3f3f);
0056 carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE8, 0x3f3f3f3f);
0057 carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE9, 0x3f3f3f3f);
0058
0059 carl9170_regwrite_finish();
0060 return carl9170_regwrite_result();
0061 }
0062
0063 struct carl9170_phy_init {
0064 u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
0065 };
0066
0067 static struct carl9170_phy_init ar5416_phy_init[] = {
0068 { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
0069 { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
0070 { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0071 { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
0072 { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
0073 { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
0074 { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
0075 { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0076 { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
0077 { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
0078 { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
0079 { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
0080 { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0081 { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
0082 { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
0083 { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
0084 { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
0085 { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
0086 { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
0087 { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
0088 { 0x1c5850, 0x6c48b4e4, 0x6d48b4e4, 0x6d48b0e4, 0x6c48b0e4, },
0089 { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
0090 { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
0091 { 0x1c585c, 0x31395c5e, 0x3139605e, 0x3139605e, 0x31395c5e, },
0092 { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
0093 { 0x1c5864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
0094 { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
0095 { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
0096 { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0097 { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0098 { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0099 { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0100 { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
0101 { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
0102 { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
0103 { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
0104 { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
0105 { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
0106 { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
0107 { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
0108 { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
0109 { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
0110 { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
0111 { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
0112 { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
0113 { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
0114 { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
0115 { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
0116 { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
0117 { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
0118 { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0119 { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
0120 { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0121 { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0122 { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0123 { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0124 { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0125 { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0126 { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0127 { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0128 { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0129 { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0130 { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
0131 { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
0132 { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
0133 { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
0134 { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
0135 { 0x1c59bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
0136 { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
0137 { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
0138 { 0x1c59c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, },
0139 { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
0140 { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
0141 { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0142 { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0143 { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0144 { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
0145 { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
0146 { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
0147 { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
0148 { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0149 { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
0150 { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0151 { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
0152 { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
0153 { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
0154 { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
0155 { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
0156 { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
0157 { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
0158 { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
0159 { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
0160 { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
0161 { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
0162 { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
0163 { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
0164 { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
0165 { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
0166 { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
0167 { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
0168 { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
0169 { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
0170 { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
0171 { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
0172 { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
0173 { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
0174 { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
0175 { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
0176 { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
0177 { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
0178 { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
0179 { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
0180 { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
0181 { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
0182 { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
0183 { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
0184 { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
0185 { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
0186 { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
0187 { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
0188 { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
0189 { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
0190 { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0191 { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0192 { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0193 { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0194 { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0195 { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0196 { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0197 { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0198 { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0199 { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0200 { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0201 { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0202 { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0203 { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0204 { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0205 { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0206 { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0207 { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0208 { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0209 { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0210 { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0211 { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0212 { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0213 { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
0214 { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0215 { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
0216 { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
0217 { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
0218 { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
0219 { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
0220 { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
0221 { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
0222 { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
0223 { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
0224 { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
0225 { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
0226 { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
0227 { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
0228 { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
0229 { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
0230 { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
0231 { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
0232 { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
0233 { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
0234 { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
0235 { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
0236 { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
0237 { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
0238 { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
0239 { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
0240 { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
0241 { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
0242 { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
0243 { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
0244 { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
0245 { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
0246 { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
0247 { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
0248 { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
0249 { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
0250 { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
0251 { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
0252 { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
0253 { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
0254 { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
0255 { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0256 { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0257 { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0258 { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0259 { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0260 { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0261 { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0262 { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0263 { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0264 { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0265 { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0266 { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0267 { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0268 { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0269 { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0270 { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0271 { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0272 { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0273 { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0274 { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0275 { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
0276 { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
0277 { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
0278 { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0279 { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0280 { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0281 { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0282 { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0283 { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0284 { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0285 { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0286 { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0287 { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0288 { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0289 { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0290 { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0291 { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0292 { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0293 { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0294 { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0295 { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0296 { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
0297 { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
0298 { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
0299 { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
0300 { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
0301 { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
0302 { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
0303 { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
0304 { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
0305 { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
0306 { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
0307 { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0308 { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
0309 { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
0310 { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
0311 { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
0312 { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
0313 { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
0314 { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
0315 { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
0316 { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
0317 { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0318 { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
0319 { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
0320 { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
0321 { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
0322 { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0323 { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
0324 { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
0325 { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
0326 { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
0327 { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
0328 { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
0329 { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
0330 { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
0331 { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
0332 { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
0333 { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
0334 { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
0335 { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
0336 { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
0337 { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
0338 { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0339 { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0340 { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0341 { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0342 { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0343 { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0344 { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0345 { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
0346 { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
0347 { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
0348 { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
0349 { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
0350 { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
0351 { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
0352 { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
0353 { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
0354 { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
0355 { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
0356 { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0357 { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0358 { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0359 { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0360 { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0361 { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0362 { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0363 { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0364 { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0365 { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0366 { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0367 { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
0368 { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
0369 { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
0370 { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
0371 { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
0372 { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
0373 { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
0374 { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
0375 { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
0376 { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
0377 { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
0378 { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
0379 { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
0380 { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
0381 { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
0382 { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
0383
0384 { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
0385 { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
0386 { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
0387 { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
0388 { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
0389 { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
0390 { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
0391 { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
0392 { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
0393 { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
0394 { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
0395 { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
0396 { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
0397 { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
0398 { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
0399 { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
0400 };
0401
0402
0403
0404
0405
0406 static u32 carl9170_def_val(u32 reg, bool is_2ghz, bool is_40mhz)
0407 {
0408 unsigned int i;
0409 for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
0410 if (ar5416_phy_init[i].reg != reg)
0411 continue;
0412
0413 if (is_2ghz) {
0414 if (is_40mhz)
0415 return ar5416_phy_init[i]._2ghz_40;
0416 else
0417 return ar5416_phy_init[i]._2ghz_20;
0418 } else {
0419 if (is_40mhz)
0420 return ar5416_phy_init[i]._5ghz_40;
0421 else
0422 return ar5416_phy_init[i]._5ghz_20;
0423 }
0424 }
0425 return 0;
0426 }
0427
0428
0429
0430
0431
0432 static int carl9170_init_phy_from_eeprom(struct ar9170 *ar,
0433 bool is_2ghz, bool is_40mhz)
0434 {
0435 static const u8 xpd2pd[16] = {
0436 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2,
0437 0x2, 0x3, 0x7, 0x2, 0xb, 0x2, 0x2, 0x2
0438 };
0439
0440 struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz];
0441 u32 val;
0442
0443 carl9170_regwrite_begin(ar);
0444
0445
0446 carl9170_regwrite(AR9170_PHY_REG_SWITCH_COM,
0447 le32_to_cpu(m->antCtrlCommon));
0448
0449
0450 carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_0,
0451 le32_to_cpu(m->antCtrlChain[0]));
0452
0453
0454 carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_2,
0455 le32_to_cpu(m->antCtrlChain[1]));
0456
0457
0458 if (!is_40mhz) {
0459 val = carl9170_def_val(AR9170_PHY_REG_SETTLING,
0460 is_2ghz, is_40mhz);
0461 SET_VAL(AR9170_PHY_SETTLING_SWITCH, val, m->switchSettling);
0462 carl9170_regwrite(AR9170_PHY_REG_SETTLING, val);
0463 }
0464
0465
0466 val = carl9170_def_val(AR9170_PHY_REG_DESIRED_SZ, is_2ghz, is_40mhz);
0467 SET_VAL(AR9170_PHY_DESIRED_SZ_PGA, val, m->pgaDesiredSize);
0468 SET_VAL(AR9170_PHY_DESIRED_SZ_ADC, val, m->adcDesiredSize);
0469 carl9170_regwrite(AR9170_PHY_REG_DESIRED_SZ, val);
0470
0471
0472 val = carl9170_def_val(AR9170_PHY_REG_RF_CTL4, is_2ghz, is_40mhz);
0473 SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF, val, m->txEndToXpaOff);
0474 SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF, val, m->txEndToXpaOff);
0475 SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAB_ON, val, m->txFrameToXpaOn);
0476 SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAA_ON, val, m->txFrameToXpaOn);
0477 carl9170_regwrite(AR9170_PHY_REG_RF_CTL4, val);
0478
0479
0480 val = carl9170_def_val(AR9170_PHY_REG_RF_CTL3, is_2ghz, is_40mhz);
0481 SET_VAL(AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON, val, m->txEndToRxOn);
0482 carl9170_regwrite(AR9170_PHY_REG_RF_CTL3, val);
0483
0484
0485 val = carl9170_def_val(0x1c8864, is_2ghz, is_40mhz);
0486 val = (val & ~0x7f000) | (m->thresh62 << 12);
0487 carl9170_regwrite(0x1c8864, val);
0488
0489
0490 val = carl9170_def_val(AR9170_PHY_REG_RXGAIN, is_2ghz, is_40mhz);
0491 SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[0]);
0492 carl9170_regwrite(AR9170_PHY_REG_RXGAIN, val);
0493
0494
0495 val = carl9170_def_val(AR9170_PHY_REG_RXGAIN_CHAIN_2,
0496 is_2ghz, is_40mhz);
0497 SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[1]);
0498 carl9170_regwrite(AR9170_PHY_REG_RXGAIN_CHAIN_2, val);
0499
0500
0501 val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ, is_2ghz, is_40mhz);
0502 SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[0]);
0503
0504 if (!is_2ghz)
0505 SET_VAL(AR9170_PHY_GAIN_2GHZ_BSW_MARGIN, val, m->bswMargin[0]);
0506 carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ, val);
0507
0508
0509 val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2,
0510 is_2ghz, is_40mhz);
0511 SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[1]);
0512 carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2, val);
0513
0514
0515 val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(0),
0516 is_2ghz, is_40mhz);
0517 SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[0]);
0518 SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[0]);
0519 carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(0), val);
0520
0521
0522 val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(2),
0523 is_2ghz, is_40mhz);
0524 SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[1]);
0525 SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[1]);
0526 carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(2), val);
0527
0528
0529 val = carl9170_def_val(AR9170_PHY_REG_TPCRG1, is_2ghz, is_40mhz);
0530 SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_1, val,
0531 xpd2pd[m->xpdGain & 0xf] & 3);
0532 SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_2, val,
0533 xpd2pd[m->xpdGain & 0xf] >> 2);
0534 carl9170_regwrite(AR9170_PHY_REG_TPCRG1, val);
0535
0536 carl9170_regwrite(AR9170_PHY_REG_RX_CHAINMASK, ar->eeprom.rx_mask);
0537 carl9170_regwrite(AR9170_PHY_REG_CAL_CHAINMASK, ar->eeprom.rx_mask);
0538
0539 carl9170_regwrite_finish();
0540 return carl9170_regwrite_result();
0541 }
0542
0543 static int carl9170_init_phy(struct ar9170 *ar, enum nl80211_band band)
0544 {
0545 int i, err;
0546 u32 val;
0547 bool is_2ghz = band == NL80211_BAND_2GHZ;
0548 bool is_40mhz = conf_is_ht40(&ar->hw->conf);
0549
0550 carl9170_regwrite_begin(ar);
0551
0552 for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
0553 if (is_40mhz) {
0554 if (is_2ghz)
0555 val = ar5416_phy_init[i]._2ghz_40;
0556 else
0557 val = ar5416_phy_init[i]._5ghz_40;
0558 } else {
0559 if (is_2ghz)
0560 val = ar5416_phy_init[i]._2ghz_20;
0561 else
0562 val = ar5416_phy_init[i]._5ghz_20;
0563 }
0564
0565 carl9170_regwrite(ar5416_phy_init[i].reg, val);
0566 }
0567
0568 carl9170_regwrite_finish();
0569 err = carl9170_regwrite_result();
0570 if (err)
0571 return err;
0572
0573 err = carl9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz);
0574 if (err)
0575 return err;
0576
0577 err = carl9170_init_power_cal(ar);
0578 if (err)
0579 return err;
0580
0581 if (!ar->fw.hw_counters) {
0582 err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC,
0583 is_2ghz ? 0x5163 : 0x5143);
0584 }
0585
0586 return err;
0587 }
0588
0589 struct carl9170_rf_initvals {
0590 u32 reg, _5ghz, _2ghz;
0591 };
0592
0593 static struct carl9170_rf_initvals carl9170_rf_initval[] = {
0594
0595 { 0x1c58b0, 0x1e5795e5, 0x1e5795e5},
0596 { 0x1c58e0, 0x02008020, 0x02008020},
0597
0598 { 0x1c58b0, 0x02108421, 0x02108421},
0599 { 0x1c58ec, 0x00000008, 0x00000008},
0600
0601 { 0x1c58b0, 0x0e73ff17, 0x0e73ff17},
0602 { 0x1c58e0, 0x00000420, 0x00000420},
0603
0604 { 0x1c58f0, 0x01400018, 0x01c00018},
0605
0606 { 0x1c58b0, 0x000001a1, 0x000001a1},
0607 { 0x1c58e8, 0x00000001, 0x00000001},
0608
0609 { 0x1c58b0, 0x00000013, 0x00000013},
0610 { 0x1c58e4, 0x00000002, 0x00000002},
0611
0612 { 0x1c58b0, 0x00000000, 0x00000000},
0613 { 0x1c58b0, 0x00000000, 0x00000000},
0614 { 0x1c58b0, 0x00000000, 0x00000000},
0615 { 0x1c58b0, 0x00000000, 0x00000000},
0616 { 0x1c58b0, 0x00000000, 0x00000000},
0617 { 0x1c58b0, 0x00004000, 0x00004000},
0618 { 0x1c58b0, 0x00006c00, 0x00006c00},
0619 { 0x1c58b0, 0x00002c00, 0x00002c00},
0620 { 0x1c58b0, 0x00004800, 0x00004800},
0621 { 0x1c58b0, 0x00004000, 0x00004000},
0622 { 0x1c58b0, 0x00006000, 0x00006000},
0623 { 0x1c58b0, 0x00001000, 0x00001000},
0624 { 0x1c58b0, 0x00004000, 0x00004000},
0625 { 0x1c58b0, 0x00007c00, 0x00007c00},
0626 { 0x1c58b0, 0x00007c00, 0x00007c00},
0627 { 0x1c58b0, 0x00007c00, 0x00007c00},
0628 { 0x1c58b0, 0x00007c00, 0x00007c00},
0629 { 0x1c58b0, 0x00007c00, 0x00007c00},
0630 { 0x1c58b0, 0x00087c00, 0x00087c00},
0631 { 0x1c58b0, 0x00007c00, 0x00007c00},
0632 { 0x1c58b0, 0x00005400, 0x00005400},
0633 { 0x1c58b0, 0x00000c00, 0x00000c00},
0634 { 0x1c58b0, 0x00001800, 0x00001800},
0635 { 0x1c58b0, 0x00007c00, 0x00007c00},
0636 { 0x1c58b0, 0x00006c00, 0x00006c00},
0637 { 0x1c58b0, 0x00006c00, 0x00006c00},
0638 { 0x1c58b0, 0x00007c00, 0x00007c00},
0639 { 0x1c58b0, 0x00002c00, 0x00002c00},
0640 { 0x1c58b0, 0x00003c00, 0x00003c00},
0641 { 0x1c58b0, 0x00003800, 0x00003800},
0642 { 0x1c58b0, 0x00001c00, 0x00001c00},
0643 { 0x1c58b0, 0x00000800, 0x00000800},
0644 { 0x1c58b0, 0x00000408, 0x00000408},
0645 { 0x1c58b0, 0x00004c15, 0x00004c15},
0646 { 0x1c58b0, 0x00004188, 0x00004188},
0647 { 0x1c58b0, 0x0000201e, 0x0000201e},
0648 { 0x1c58b0, 0x00010408, 0x00010408},
0649 { 0x1c58b0, 0x00000801, 0x00000801},
0650 { 0x1c58b0, 0x00000c08, 0x00000c08},
0651 { 0x1c58b0, 0x0000181e, 0x0000181e},
0652 { 0x1c58b0, 0x00001016, 0x00001016},
0653 { 0x1c58b0, 0x00002800, 0x00002800},
0654 { 0x1c58b0, 0x00004010, 0x00004010},
0655 { 0x1c58b0, 0x0000081c, 0x0000081c},
0656 { 0x1c58b0, 0x00000115, 0x00000115},
0657 { 0x1c58b0, 0x00000015, 0x00000015},
0658 { 0x1c58b0, 0x00000066, 0x00000066},
0659 { 0x1c58b0, 0x0000001c, 0x0000001c},
0660 { 0x1c58b0, 0x00000000, 0x00000000},
0661 { 0x1c58b0, 0x00000004, 0x00000004},
0662 { 0x1c58b0, 0x00000015, 0x00000015},
0663 { 0x1c58b0, 0x0000001f, 0x0000001f},
0664 { 0x1c58e0, 0x00000000, 0x00000400},
0665
0666 { 0x1c58b0, 0x000000a0, 0x000000a0},
0667 { 0x1c58b0, 0x00000000, 0x00000000},
0668 { 0x1c58b0, 0x00000040, 0x00000040},
0669 { 0x1c58f0, 0x0000001c, 0x0000001c},
0670 };
0671
0672 static int carl9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
0673 {
0674 int err, i;
0675
0676 carl9170_regwrite_begin(ar);
0677
0678 for (i = 0; i < ARRAY_SIZE(carl9170_rf_initval); i++)
0679 carl9170_regwrite(carl9170_rf_initval[i].reg,
0680 band5ghz ? carl9170_rf_initval[i]._5ghz
0681 : carl9170_rf_initval[i]._2ghz);
0682
0683 carl9170_regwrite_finish();
0684 err = carl9170_regwrite_result();
0685 if (err)
0686 wiphy_err(ar->hw->wiphy, "rf init failed\n");
0687
0688 return err;
0689 }
0690
0691 struct carl9170_phy_freq_params {
0692 u8 coeff_exp;
0693 u16 coeff_man;
0694 u8 coeff_exp_shgi;
0695 u16 coeff_man_shgi;
0696 };
0697
0698 enum carl9170_bw {
0699 CARL9170_BW_20,
0700 CARL9170_BW_40_BELOW,
0701 CARL9170_BW_40_ABOVE,
0702
0703 __CARL9170_NUM_BW,
0704 };
0705
0706 struct carl9170_phy_freq_entry {
0707 u16 freq;
0708 struct carl9170_phy_freq_params params[__CARL9170_NUM_BW];
0709 };
0710
0711
0712 static const struct carl9170_phy_freq_entry carl9170_phy_freq_params[] = {
0713
0714
0715
0716
0717
0718
0719 { 2412, {
0720 { 3, 21737, 3, 19563, },
0721 { 3, 21827, 3, 19644, },
0722 { 3, 21647, 3, 19482, },
0723 } },
0724 { 2417, {
0725 { 3, 21692, 3, 19523, },
0726 { 3, 21782, 3, 19604, },
0727 { 3, 21602, 3, 19442, },
0728 } },
0729 { 2422, {
0730 { 3, 21647, 3, 19482, },
0731 { 3, 21737, 3, 19563, },
0732 { 3, 21558, 3, 19402, },
0733 } },
0734 { 2427, {
0735 { 3, 21602, 3, 19442, },
0736 { 3, 21692, 3, 19523, },
0737 { 3, 21514, 3, 19362, },
0738 } },
0739 { 2432, {
0740 { 3, 21558, 3, 19402, },
0741 { 3, 21647, 3, 19482, },
0742 { 3, 21470, 3, 19323, },
0743 } },
0744 { 2437, {
0745 { 3, 21514, 3, 19362, },
0746 { 3, 21602, 3, 19442, },
0747 { 3, 21426, 3, 19283, },
0748 } },
0749 { 2442, {
0750 { 3, 21470, 3, 19323, },
0751 { 3, 21558, 3, 19402, },
0752 { 3, 21382, 3, 19244, },
0753 } },
0754 { 2447, {
0755 { 3, 21426, 3, 19283, },
0756 { 3, 21514, 3, 19362, },
0757 { 3, 21339, 3, 19205, },
0758 } },
0759 { 2452, {
0760 { 3, 21382, 3, 19244, },
0761 { 3, 21470, 3, 19323, },
0762 { 3, 21295, 3, 19166, },
0763 } },
0764 { 2457, {
0765 { 3, 21339, 3, 19205, },
0766 { 3, 21426, 3, 19283, },
0767 { 3, 21252, 3, 19127, },
0768 } },
0769 { 2462, {
0770 { 3, 21295, 3, 19166, },
0771 { 3, 21382, 3, 19244, },
0772 { 3, 21209, 3, 19088, },
0773 } },
0774 { 2467, {
0775 { 3, 21252, 3, 19127, },
0776 { 3, 21339, 3, 19205, },
0777 { 3, 21166, 3, 19050, },
0778 } },
0779 { 2472, {
0780 { 3, 21209, 3, 19088, },
0781 { 3, 21295, 3, 19166, },
0782 { 3, 21124, 3, 19011, },
0783 } },
0784 { 2484, {
0785 { 3, 21107, 3, 18996, },
0786 { 3, 21192, 3, 19073, },
0787 { 3, 21022, 3, 18920, },
0788 } },
0789 { 4920, {
0790 { 4, 21313, 4, 19181, },
0791 { 4, 21356, 4, 19220, },
0792 { 4, 21269, 4, 19142, },
0793 } },
0794 { 4940, {
0795 { 4, 21226, 4, 19104, },
0796 { 4, 21269, 4, 19142, },
0797 { 4, 21183, 4, 19065, },
0798 } },
0799 { 4960, {
0800 { 4, 21141, 4, 19027, },
0801 { 4, 21183, 4, 19065, },
0802 { 4, 21098, 4, 18988, },
0803 } },
0804 { 4980, {
0805 { 4, 21056, 4, 18950, },
0806 { 4, 21098, 4, 18988, },
0807 { 4, 21014, 4, 18912, },
0808 } },
0809 { 5040, {
0810 { 4, 20805, 4, 18725, },
0811 { 4, 20846, 4, 18762, },
0812 { 4, 20764, 4, 18687, },
0813 } },
0814 { 5060, {
0815 { 4, 20723, 4, 18651, },
0816 { 4, 20764, 4, 18687, },
0817 { 4, 20682, 4, 18614, },
0818 } },
0819 { 5080, {
0820 { 4, 20641, 4, 18577, },
0821 { 4, 20682, 4, 18614, },
0822 { 4, 20601, 4, 18541, },
0823 } },
0824 { 5180, {
0825 { 4, 20243, 4, 18219, },
0826 { 4, 20282, 4, 18254, },
0827 { 4, 20204, 4, 18183, },
0828 } },
0829 { 5200, {
0830 { 4, 20165, 4, 18148, },
0831 { 4, 20204, 4, 18183, },
0832 { 4, 20126, 4, 18114, },
0833 } },
0834 { 5220, {
0835 { 4, 20088, 4, 18079, },
0836 { 4, 20126, 4, 18114, },
0837 { 4, 20049, 4, 18044, },
0838 } },
0839 { 5240, {
0840 { 4, 20011, 4, 18010, },
0841 { 4, 20049, 4, 18044, },
0842 { 4, 19973, 4, 17976, },
0843 } },
0844 { 5260, {
0845 { 4, 19935, 4, 17941, },
0846 { 4, 19973, 4, 17976, },
0847 { 4, 19897, 4, 17907, },
0848 } },
0849 { 5280, {
0850 { 4, 19859, 4, 17873, },
0851 { 4, 19897, 4, 17907, },
0852 { 4, 19822, 4, 17840, },
0853 } },
0854 { 5300, {
0855 { 4, 19784, 4, 17806, },
0856 { 4, 19822, 4, 17840, },
0857 { 4, 19747, 4, 17772, },
0858 } },
0859 { 5320, {
0860 { 4, 19710, 4, 17739, },
0861 { 4, 19747, 4, 17772, },
0862 { 4, 19673, 4, 17706, },
0863 } },
0864 { 5500, {
0865 { 4, 19065, 4, 17159, },
0866 { 4, 19100, 4, 17190, },
0867 { 4, 19030, 4, 17127, },
0868 } },
0869 { 5520, {
0870 { 4, 18996, 4, 17096, },
0871 { 4, 19030, 4, 17127, },
0872 { 4, 18962, 4, 17065, },
0873 } },
0874 { 5540, {
0875 { 4, 18927, 4, 17035, },
0876 { 4, 18962, 4, 17065, },
0877 { 4, 18893, 4, 17004, },
0878 } },
0879 { 5560, {
0880 { 4, 18859, 4, 16973, },
0881 { 4, 18893, 4, 17004, },
0882 { 4, 18825, 4, 16943, },
0883 } },
0884 { 5580, {
0885 { 4, 18792, 4, 16913, },
0886 { 4, 18825, 4, 16943, },
0887 { 4, 18758, 4, 16882, },
0888 } },
0889 { 5600, {
0890 { 4, 18725, 4, 16852, },
0891 { 4, 18758, 4, 16882, },
0892 { 4, 18691, 4, 16822, },
0893 } },
0894 { 5620, {
0895 { 4, 18658, 4, 16792, },
0896 { 4, 18691, 4, 16822, },
0897 { 4, 18625, 4, 16762, },
0898 } },
0899 { 5640, {
0900 { 4, 18592, 4, 16733, },
0901 { 4, 18625, 4, 16762, },
0902 { 4, 18559, 4, 16703, },
0903 } },
0904 { 5660, {
0905 { 4, 18526, 4, 16673, },
0906 { 4, 18559, 4, 16703, },
0907 { 4, 18493, 4, 16644, },
0908 } },
0909 { 5680, {
0910 { 4, 18461, 4, 16615, },
0911 { 4, 18493, 4, 16644, },
0912 { 4, 18428, 4, 16586, },
0913 } },
0914 { 5700, {
0915 { 4, 18396, 4, 16556, },
0916 { 4, 18428, 4, 16586, },
0917 { 4, 18364, 4, 16527, },
0918 } },
0919 { 5745, {
0920 { 4, 18252, 4, 16427, },
0921 { 4, 18284, 4, 16455, },
0922 { 4, 18220, 4, 16398, },
0923 } },
0924 { 5765, {
0925 { 4, 18189, 5, 32740, },
0926 { 4, 18220, 4, 16398, },
0927 { 4, 18157, 5, 32683, },
0928 } },
0929 { 5785, {
0930 { 4, 18126, 5, 32626, },
0931 { 4, 18157, 5, 32683, },
0932 { 4, 18094, 5, 32570, },
0933 } },
0934 { 5805, {
0935 { 4, 18063, 5, 32514, },
0936 { 4, 18094, 5, 32570, },
0937 { 4, 18032, 5, 32458, },
0938 } },
0939 { 5825, {
0940 { 4, 18001, 5, 32402, },
0941 { 4, 18032, 5, 32458, },
0942 { 4, 17970, 5, 32347, },
0943 } },
0944 { 5170, {
0945 { 4, 20282, 4, 18254, },
0946 { 4, 20321, 4, 18289, },
0947 { 4, 20243, 4, 18219, },
0948 } },
0949 { 5190, {
0950 { 4, 20204, 4, 18183, },
0951 { 4, 20243, 4, 18219, },
0952 { 4, 20165, 4, 18148, },
0953 } },
0954 { 5210, {
0955 { 4, 20126, 4, 18114, },
0956 { 4, 20165, 4, 18148, },
0957 { 4, 20088, 4, 18079, },
0958 } },
0959 { 5230, {
0960 { 4, 20049, 4, 18044, },
0961 { 4, 20088, 4, 18079, },
0962 { 4, 20011, 4, 18010, },
0963 } },
0964 };
0965
0966 static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
0967 u32 freq, enum carl9170_bw bw)
0968 {
0969 int err;
0970 u32 d0, d1, td0, td1, fd0, fd1;
0971 u8 chansel;
0972 u8 refsel0 = 1, refsel1 = 0;
0973 u8 lf_synth = 0;
0974
0975 switch (bw) {
0976 case CARL9170_BW_40_ABOVE:
0977 freq += 10;
0978 break;
0979 case CARL9170_BW_40_BELOW:
0980 freq -= 10;
0981 break;
0982 case CARL9170_BW_20:
0983 break;
0984 default:
0985 BUG();
0986 return -ENOSYS;
0987 }
0988
0989 if (band5ghz) {
0990 if (freq % 10) {
0991 chansel = (freq - 4800) / 5;
0992 } else {
0993 chansel = ((freq - 4800) / 10) * 2;
0994 refsel0 = 0;
0995 refsel1 = 1;
0996 }
0997 chansel = bitrev8(chansel);
0998 } else {
0999 if (freq == 2484) {
1000 chansel = 10 + (freq - 2274) / 5;
1001 lf_synth = 1;
1002 } else
1003 chansel = 16 + (freq - 2272) / 5;
1004 chansel *= 4;
1005 chansel = bitrev8(chansel);
1006 }
1007
1008 d1 = chansel;
1009 d0 = 0x21 |
1010 refsel0 << 3 |
1011 refsel1 << 2 |
1012 lf_synth << 1;
1013 td0 = d0 & 0x1f;
1014 td1 = d1 & 0x1f;
1015 fd0 = td1 << 5 | td0;
1016
1017 td0 = (d0 >> 5) & 0x7;
1018 td1 = (d1 >> 5) & 0x7;
1019 fd1 = td1 << 5 | td0;
1020
1021 carl9170_regwrite_begin(ar);
1022
1023 carl9170_regwrite(0x1c58b0, fd0);
1024 carl9170_regwrite(0x1c58e8, fd1);
1025
1026 carl9170_regwrite_finish();
1027 err = carl9170_regwrite_result();
1028 if (err)
1029 return err;
1030
1031 return 0;
1032 }
1033
1034 static const struct carl9170_phy_freq_params *
1035 carl9170_get_hw_dyn_params(struct ieee80211_channel *channel,
1036 enum carl9170_bw bw)
1037 {
1038 unsigned int chanidx = 0;
1039 u16 freq = 2412;
1040
1041 if (channel) {
1042 chanidx = channel->hw_value;
1043 freq = channel->center_freq;
1044 }
1045
1046 BUG_ON(chanidx >= ARRAY_SIZE(carl9170_phy_freq_params));
1047
1048 BUILD_BUG_ON(__CARL9170_NUM_BW != 3);
1049
1050 WARN_ON(carl9170_phy_freq_params[chanidx].freq != freq);
1051
1052 return &carl9170_phy_freq_params[chanidx].params[bw];
1053 }
1054
1055 static int carl9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
1056 {
1057 int idx = nfreqs - 2;
1058
1059 while (idx >= 0) {
1060 if (f >= freqs[idx])
1061 return idx;
1062 idx--;
1063 }
1064
1065 return 0;
1066 }
1067
1068 static s32 carl9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
1069 {
1070
1071 if (y2 == y1)
1072 return y1;
1073
1074
1075 if (x == x1)
1076 return y1;
1077 if (x == x2)
1078 return y2;
1079
1080
1081 if (x2 == x1)
1082 return y1;
1083
1084 return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
1085 }
1086
1087 static u8 carl9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
1088 {
1089 #define SHIFT 8
1090 s32 y;
1091
1092 y = carl9170_interpolate_s32(x << SHIFT, x1 << SHIFT,
1093 y1 << SHIFT, x2 << SHIFT, y2 << SHIFT);
1094
1095
1096
1097
1098
1099
1100 return (y >> SHIFT) + ((y & (1 << (SHIFT - 1))) >> (SHIFT - 1));
1101 #undef SHIFT
1102 }
1103
1104 static u8 carl9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array)
1105 {
1106 int i;
1107
1108 for (i = 0; i < 3; i++) {
1109 if (x <= x_array[i + 1])
1110 break;
1111 }
1112
1113 return carl9170_interpolate_u8(x, x_array[i], y_array[i],
1114 x_array[i + 1], y_array[i + 1]);
1115 }
1116
1117 static int carl9170_set_freq_cal_data(struct ar9170 *ar,
1118 struct ieee80211_channel *channel)
1119 {
1120 u8 *cal_freq_pier;
1121 u8 vpds[2][AR5416_PD_GAIN_ICEPTS];
1122 u8 pwrs[2][AR5416_PD_GAIN_ICEPTS];
1123 int chain, idx, i;
1124 u32 phy_data = 0;
1125 u8 f, tmp;
1126
1127 switch (channel->band) {
1128 case NL80211_BAND_2GHZ:
1129 f = channel->center_freq - 2300;
1130 cal_freq_pier = ar->eeprom.cal_freq_pier_2G;
1131 i = AR5416_NUM_2G_CAL_PIERS - 1;
1132 break;
1133
1134 case NL80211_BAND_5GHZ:
1135 f = (channel->center_freq - 4800) / 5;
1136 cal_freq_pier = ar->eeprom.cal_freq_pier_5G;
1137 i = AR5416_NUM_5G_CAL_PIERS - 1;
1138 break;
1139
1140 default:
1141 return -EINVAL;
1142 }
1143
1144 for (; i >= 0; i--) {
1145 if (cal_freq_pier[i] != 0xff)
1146 break;
1147 }
1148 if (i < 0)
1149 return -EINVAL;
1150
1151 idx = carl9170_find_freq_idx(i, cal_freq_pier, f);
1152
1153 carl9170_regwrite_begin(ar);
1154
1155 for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) {
1156 for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) {
1157 struct ar9170_calibration_data_per_freq *cal_pier_data;
1158 int j;
1159
1160 switch (channel->band) {
1161 case NL80211_BAND_2GHZ:
1162 cal_pier_data = &ar->eeprom.
1163 cal_pier_data_2G[chain][idx];
1164 break;
1165
1166 case NL80211_BAND_5GHZ:
1167 cal_pier_data = &ar->eeprom.
1168 cal_pier_data_5G[chain][idx];
1169 break;
1170
1171 default:
1172 return -EINVAL;
1173 }
1174
1175 for (j = 0; j < 2; j++) {
1176 vpds[j][i] = carl9170_interpolate_u8(f,
1177 cal_freq_pier[idx],
1178 cal_pier_data->vpd_pdg[j][i],
1179 cal_freq_pier[idx + 1],
1180 cal_pier_data[1].vpd_pdg[j][i]);
1181
1182 pwrs[j][i] = carl9170_interpolate_u8(f,
1183 cal_freq_pier[idx],
1184 cal_pier_data->pwr_pdg[j][i],
1185 cal_freq_pier[idx + 1],
1186 cal_pier_data[1].pwr_pdg[j][i]) / 2;
1187 }
1188 }
1189
1190 for (i = 0; i < 76; i++) {
1191 if (i < 25) {
1192 tmp = carl9170_interpolate_val(i, &pwrs[0][0],
1193 &vpds[0][0]);
1194 } else {
1195 tmp = carl9170_interpolate_val(i - 12,
1196 &pwrs[1][0],
1197 &vpds[1][0]);
1198 }
1199
1200 phy_data |= tmp << ((i & 3) << 3);
1201 if ((i & 3) == 3) {
1202 carl9170_regwrite(0x1c6280 + chain * 0x1000 +
1203 (i & ~3), phy_data);
1204 phy_data = 0;
1205 }
1206 }
1207
1208 for (i = 19; i < 32; i++)
1209 carl9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2),
1210 0x0);
1211 }
1212
1213 carl9170_regwrite_finish();
1214 return carl9170_regwrite_result();
1215 }
1216
1217 static u8 carl9170_get_max_edge_power(struct ar9170 *ar,
1218 u32 freq, struct ar9170_calctl_edges edges[])
1219 {
1220 int i;
1221 u8 rc = AR5416_MAX_RATE_POWER;
1222 u8 f;
1223 if (freq < 3000)
1224 f = freq - 2300;
1225 else
1226 f = (freq - 4800) / 5;
1227
1228 for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
1229 if (edges[i].channel == 0xff)
1230 break;
1231 if (f == edges[i].channel) {
1232
1233 rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS;
1234 break;
1235 }
1236 if (i > 0 && f < edges[i].channel) {
1237 if (f > edges[i - 1].channel &&
1238 edges[i - 1].power_flags &
1239 AR9170_CALCTL_EDGE_FLAGS) {
1240
1241 rc = edges[i - 1].power_flags &
1242 ~AR9170_CALCTL_EDGE_FLAGS;
1243 }
1244 break;
1245 }
1246 }
1247
1248 if (i == AR5416_NUM_BAND_EDGES) {
1249 if (f > edges[i - 1].channel &&
1250 edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
1251
1252 rc = edges[i - 1].power_flags &
1253 ~AR9170_CALCTL_EDGE_FLAGS;
1254 }
1255 }
1256 return rc;
1257 }
1258
1259 static u8 carl9170_get_heavy_clip(struct ar9170 *ar, u32 freq,
1260 enum carl9170_bw bw, struct ar9170_calctl_edges edges[])
1261 {
1262 u8 f;
1263 int i;
1264 u8 rc = 0;
1265
1266 if (freq < 3000)
1267 f = freq - 2300;
1268 else
1269 f = (freq - 4800) / 5;
1270
1271 if (bw == CARL9170_BW_40_BELOW || bw == CARL9170_BW_40_ABOVE)
1272 rc |= 0xf0;
1273
1274 for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
1275 if (edges[i].channel == 0xff)
1276 break;
1277 if (f == edges[i].channel) {
1278 if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS))
1279 rc |= 0x0f;
1280 break;
1281 }
1282 }
1283
1284 return rc;
1285 }
1286
1287
1288
1289
1290
1291 static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
1292 {
1293 u8 ctl_grp;
1294 u8 ctl_idx;
1295 int i, j;
1296 struct ctl_modes {
1297 u8 ctl_mode;
1298 u8 max_power;
1299 u8 *pwr_cal_data;
1300 int pwr_cal_len;
1301 } *modes;
1302
1303
1304
1305
1306
1307 struct ctl_modes mode_list_2ghz[] = {
1308 { CTL_11B, 0, ar->power_2G_cck, 4 },
1309 { CTL_11G, 0, ar->power_2G_ofdm, 4 },
1310 { CTL_2GHT20, 0, ar->power_2G_ht20, 8 },
1311 { CTL_2GHT40, 0, ar->power_2G_ht40, 8 },
1312 };
1313 struct ctl_modes mode_list_5ghz[] = {
1314 { CTL_11A, 0, ar->power_5G_leg, 4 },
1315 { CTL_5GHT20, 0, ar->power_5G_ht20, 8 },
1316 { CTL_5GHT40, 0, ar->power_5G_ht40, 8 },
1317 };
1318 int nr_modes;
1319
1320 #define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n])
1321
1322 ar->heavy_clip = 0;
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332 ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory,
1333 ar->hw->conf.chandef.chan->band);
1334
1335
1336 if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL)
1337 ctl_grp = CTL_FCC;
1338
1339 if (ctl_grp != CTL_FCC)
1340
1341 return;
1342
1343 if (ar->hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) {
1344 modes = mode_list_2ghz;
1345 nr_modes = ARRAY_SIZE(mode_list_2ghz);
1346 } else {
1347 modes = mode_list_5ghz;
1348 nr_modes = ARRAY_SIZE(mode_list_5ghz);
1349 }
1350
1351 for (i = 0; i < nr_modes; i++) {
1352 u8 c = ctl_grp | modes[i].ctl_mode;
1353 for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++)
1354 if (c == ar->eeprom.ctl_index[ctl_idx])
1355 break;
1356 if (ctl_idx < AR5416_NUM_CTLS) {
1357 int f_off = 0;
1358
1359
1360
1361
1362
1363 if (modes[i].ctl_mode == CTL_11G) {
1364 ar->heavy_clip =
1365 carl9170_get_heavy_clip(ar,
1366 freq, bw, EDGES(ctl_idx, 1));
1367 }
1368
1369
1370 if (modes[i].ctl_mode == CTL_2GHT40 ||
1371 modes[i].ctl_mode == CTL_5GHT40) {
1372 if (bw == CARL9170_BW_40_BELOW)
1373 f_off = -10;
1374 else
1375 f_off = 10;
1376 }
1377
1378 modes[i].max_power =
1379 carl9170_get_max_edge_power(ar,
1380 freq + f_off, EDGES(ctl_idx, 1));
1381
1382
1383
1384
1385
1386
1387
1388 } else {
1389
1390
1391
1392
1393
1394
1395 int k = i;
1396
1397 modes[i].max_power = AR5416_MAX_RATE_POWER;
1398 while (k-- > 0) {
1399 if (modes[k].max_power !=
1400 AR5416_MAX_RATE_POWER) {
1401 modes[i].max_power = modes[k].max_power;
1402 break;
1403 }
1404 }
1405 }
1406
1407
1408 for (j = 0; j < modes[i].pwr_cal_len; j++) {
1409 modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j],
1410 modes[i].max_power);
1411 }
1412 }
1413
1414 if (ar->heavy_clip & 0xf0) {
1415 ar->power_2G_ht40[0]--;
1416 ar->power_2G_ht40[1]--;
1417 ar->power_2G_ht40[2]--;
1418 }
1419 if (ar->heavy_clip & 0xf) {
1420 ar->power_2G_ht20[0]++;
1421 ar->power_2G_ht20[1]++;
1422 ar->power_2G_ht20[2]++;
1423 }
1424
1425 #undef EDGES
1426 }
1427
1428 static void carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
1429 enum carl9170_bw bw)
1430 {
1431 struct ar9170_calibration_target_power_legacy *ctpl;
1432 struct ar9170_calibration_target_power_ht *ctph;
1433 u8 *ctpres;
1434 int ntargets;
1435 int idx, i, n;
1436 u8 f;
1437 u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
1438
1439 if (freq < 3000)
1440 f = freq - 2300;
1441 else
1442 f = (freq - 4800) / 5;
1443
1444
1445
1446
1447
1448
1449 for (i = 0; i < 3; i++) {
1450 switch (i) {
1451 case 0:
1452 ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
1453 ntargets = AR5416_NUM_5G_TARGET_PWRS;
1454 ctpres = ar->power_5G_leg;
1455 break;
1456 case 1:
1457 ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
1458 ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
1459 ctpres = ar->power_2G_cck;
1460 break;
1461 case 2:
1462 ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
1463 ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
1464 ctpres = ar->power_2G_ofdm;
1465 break;
1466 default:
1467 BUG();
1468 }
1469
1470 for (n = 0; n < ntargets; n++) {
1471 if (ctpl[n].freq == 0xff)
1472 break;
1473 pwr_freqs[n] = ctpl[n].freq;
1474 }
1475 ntargets = n;
1476 idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f);
1477 for (n = 0; n < 4; n++)
1478 ctpres[n] = carl9170_interpolate_u8(f,
1479 ctpl[idx + 0].freq, ctpl[idx + 0].power[n],
1480 ctpl[idx + 1].freq, ctpl[idx + 1].power[n]);
1481 }
1482
1483
1484 for (i = 0; i < 4; i++) {
1485 switch (i) {
1486 case 0:
1487 ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
1488 ntargets = AR5416_NUM_5G_TARGET_PWRS;
1489 ctpres = ar->power_5G_ht20;
1490 break;
1491 case 1:
1492 ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
1493 ntargets = AR5416_NUM_5G_TARGET_PWRS;
1494 ctpres = ar->power_5G_ht40;
1495 break;
1496 case 2:
1497 ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
1498 ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
1499 ctpres = ar->power_2G_ht20;
1500 break;
1501 case 3:
1502 ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
1503 ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
1504 ctpres = ar->power_2G_ht40;
1505 break;
1506 default:
1507 BUG();
1508 }
1509
1510 for (n = 0; n < ntargets; n++) {
1511 if (ctph[n].freq == 0xff)
1512 break;
1513 pwr_freqs[n] = ctph[n].freq;
1514 }
1515 ntargets = n;
1516 idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f);
1517 for (n = 0; n < 8; n++)
1518 ctpres[n] = carl9170_interpolate_u8(f,
1519 ctph[idx + 0].freq, ctph[idx + 0].power[n],
1520 ctph[idx + 1].freq, ctph[idx + 1].power[n]);
1521 }
1522
1523
1524 carl9170_calc_ctl(ar, freq, bw);
1525 }
1526
1527 int carl9170_get_noisefloor(struct ar9170 *ar)
1528 {
1529 static const u32 phy_regs[] = {
1530 AR9170_PHY_REG_CCA, AR9170_PHY_REG_CH2_CCA,
1531 AR9170_PHY_REG_EXT_CCA, AR9170_PHY_REG_CH2_EXT_CCA };
1532 u32 phy_res[ARRAY_SIZE(phy_regs)];
1533 int err, i;
1534
1535 BUILD_BUG_ON(ARRAY_SIZE(phy_regs) != ARRAY_SIZE(ar->noise));
1536
1537 err = carl9170_read_mreg(ar, ARRAY_SIZE(phy_regs), phy_regs, phy_res);
1538 if (err)
1539 return err;
1540
1541 for (i = 0; i < 2; i++) {
1542 ar->noise[i] = sign_extend32(GET_VAL(
1543 AR9170_PHY_CCA_MIN_PWR, phy_res[i]), 8);
1544
1545 ar->noise[i + 2] = sign_extend32(GET_VAL(
1546 AR9170_PHY_EXT_CCA_MIN_PWR, phy_res[i + 2]), 8);
1547 }
1548
1549 if (ar->channel)
1550 ar->survey[ar->channel->hw_value].noise = ar->noise[0];
1551
1552 return 0;
1553 }
1554
1555 static enum carl9170_bw nl80211_to_carl(enum nl80211_channel_type type)
1556 {
1557 switch (type) {
1558 case NL80211_CHAN_NO_HT:
1559 case NL80211_CHAN_HT20:
1560 return CARL9170_BW_20;
1561 case NL80211_CHAN_HT40MINUS:
1562 return CARL9170_BW_40_BELOW;
1563 case NL80211_CHAN_HT40PLUS:
1564 return CARL9170_BW_40_ABOVE;
1565 default:
1566 BUG();
1567 }
1568 }
1569
1570 int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1571 enum nl80211_channel_type _bw)
1572 {
1573 const struct carl9170_phy_freq_params *freqpar;
1574 struct carl9170_rf_init_result rf_res;
1575 struct carl9170_rf_init rf;
1576 u32 tmp, offs = 0, new_ht = 0;
1577 int err;
1578 enum carl9170_bw bw;
1579 struct ieee80211_channel *old_channel = NULL;
1580
1581 bw = nl80211_to_carl(_bw);
1582
1583 if (conf_is_ht(&ar->hw->conf))
1584 new_ht |= CARL9170FW_PHY_HT_ENABLE;
1585
1586 if (conf_is_ht40(&ar->hw->conf))
1587 new_ht |= CARL9170FW_PHY_HT_DYN2040;
1588
1589
1590 if (ar->channel) {
1591 old_channel = ar->channel;
1592 ar->channel = NULL;
1593 }
1594
1595
1596 err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET,
1597 AR9170_PWR_RESET_BB_COLD_RESET);
1598 if (err)
1599 return err;
1600
1601 err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0);
1602 if (err)
1603 return err;
1604
1605 err = carl9170_init_phy(ar, channel->band);
1606 if (err)
1607 return err;
1608
1609 err = carl9170_init_rf_banks_0_7(ar,
1610 channel->band == NL80211_BAND_5GHZ);
1611 if (err)
1612 return err;
1613
1614 err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL);
1615 if (err)
1616 return err;
1617
1618 err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE,
1619 0x200);
1620 if (err)
1621 return err;
1622
1623 err = carl9170_init_rf_bank4_pwr(ar,
1624 channel->band == NL80211_BAND_5GHZ,
1625 channel->center_freq, bw);
1626 if (err)
1627 return err;
1628
1629 tmp = AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 |
1630 AR9170_PHY_TURBO_FC_HT_EN;
1631
1632 switch (bw) {
1633 case CARL9170_BW_20:
1634 break;
1635 case CARL9170_BW_40_BELOW:
1636 tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN |
1637 AR9170_PHY_TURBO_FC_SHORT_GI_40;
1638 offs = 3;
1639 break;
1640 case CARL9170_BW_40_ABOVE:
1641 tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN |
1642 AR9170_PHY_TURBO_FC_SHORT_GI_40 |
1643 AR9170_PHY_TURBO_FC_DYN2040_PRI_CH;
1644 offs = 1;
1645 break;
1646 default:
1647 BUG();
1648 return -ENOSYS;
1649 }
1650
1651 if (ar->eeprom.tx_mask != 1)
1652 tmp |= AR9170_PHY_TURBO_FC_WALSH;
1653
1654 err = carl9170_write_reg(ar, AR9170_PHY_REG_TURBO, tmp);
1655 if (err)
1656 return err;
1657
1658 err = carl9170_set_freq_cal_data(ar, channel);
1659 if (err)
1660 return err;
1661
1662 carl9170_set_power_cal(ar, channel->center_freq, bw);
1663
1664 err = carl9170_set_mac_tpc(ar, channel);
1665 if (err)
1666 return err;
1667
1668 freqpar = carl9170_get_hw_dyn_params(channel, bw);
1669
1670 rf.ht_settings = new_ht;
1671 if (conf_is_ht40(&ar->hw->conf))
1672 SET_VAL(CARL9170FW_PHY_HT_EXT_CHAN_OFF, rf.ht_settings, offs);
1673
1674 rf.freq = cpu_to_le32(channel->center_freq * 1000);
1675 rf.delta_slope_coeff_exp = cpu_to_le32(freqpar->coeff_exp);
1676 rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man);
1677 rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi);
1678 rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi);
1679 rf.finiteLoopCount = cpu_to_le32(2000);
1680 err = carl9170_exec_cmd(ar, CARL9170_CMD_RF_INIT, sizeof(rf), &rf,
1681 sizeof(rf_res), &rf_res);
1682 if (err)
1683 return err;
1684
1685 err = le32_to_cpu(rf_res.ret);
1686 if (err != 0) {
1687 ar->chan_fail++;
1688 ar->total_chan_fail++;
1689
1690 wiphy_err(ar->hw->wiphy, "channel change: %d -> %d "
1691 "failed (%d).\n", old_channel ?
1692 old_channel->center_freq : -1, channel->center_freq,
1693 err);
1694
1695 if (ar->chan_fail > 3) {
1696
1697
1698
1699
1700
1701
1702 carl9170_restart(ar, CARL9170_RR_TOO_MANY_PHY_ERRORS);
1703 return 0;
1704 }
1705
1706 err = carl9170_set_channel(ar, channel, _bw);
1707 if (err)
1708 return err;
1709 } else {
1710 ar->chan_fail = 0;
1711 }
1712
1713 if (ar->heavy_clip) {
1714 err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE,
1715 0x200 | ar->heavy_clip);
1716 if (err) {
1717 if (net_ratelimit()) {
1718 wiphy_err(ar->hw->wiphy, "failed to set "
1719 "heavy clip\n");
1720 }
1721
1722 return err;
1723 }
1724 }
1725
1726 ar->channel = channel;
1727 ar->ht_settings = new_ht;
1728 return 0;
1729 }