Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003 
0004   Broadcom B43 wireless driver
0005   IEEE 802.11n LCN-PHY data tables
0006 
0007   Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
0008 
0009 
0010 */
0011 
0012 #include "b43.h"
0013 #include "tables_phy_lcn.h"
0014 #include "phy_common.h"
0015 #include "phy_lcn.h"
0016 
0017 struct b43_lcntab_tx_gain_tbl_entry {
0018     u8 gm;
0019     u8 pga;
0020     u8 pad;
0021     u8 dac;
0022     u8 bb_mult;
0023 };
0024 
0025 /**************************************************
0026  * Static tables.
0027  **************************************************/
0028 
0029 static const u16 b43_lcntab_0x02[] = {
0030     0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0031     0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0032     0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0033     0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0034     0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0035     0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0036     0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0037     0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0038     0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0039     0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0040     0x014d, 0x014d, 0x014d, 0x014d,
0041 };
0042 
0043 static const u16 b43_lcntab_0x01[] = {
0044     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0045     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0046     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0047     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0048     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0049     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0050     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0051     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0052     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0053     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0054     0x0000, 0x0000, 0x0000, 0x0000,
0055 };
0056 
0057 static const u32 b43_lcntab_0x0b[] = {
0058     0x000141f8, 0x000021f8, 0x000021fb, 0x000041fb,
0059     0x0001fedb, 0x0000217b, 0x00002133, 0x000040eb,
0060     0x0001fea3, 0x0000024b,
0061 };
0062 
0063 static const u32 b43_lcntab_0x0c[] = {
0064     0x00100001, 0x00200010, 0x00300001, 0x00400010,
0065     0x00500022, 0x00600122, 0x00700222, 0x00800322,
0066     0x00900422, 0x00a00522, 0x00b00622, 0x00c00722,
0067     0x00d00822, 0x00f00922, 0x00100a22, 0x00200b22,
0068     0x00300c22, 0x00400d22, 0x00500e22, 0x00600f22,
0069 };
0070 
0071 static const u32 b43_lcntab_0x0d[] = {
0072     0x00000000, 0x00000000, 0x10000000, 0x00000000,
0073     0x20000000, 0x00000000, 0x30000000, 0x00000000,
0074     0x40000000, 0x00000000, 0x50000000, 0x00000000,
0075     0x60000000, 0x00000000, 0x70000000, 0x00000000,
0076     0x80000000, 0x00000000, 0x90000000, 0x00000008,
0077     0xa0000000, 0x00000008, 0xb0000000, 0x00000008,
0078     0xc0000000, 0x00000008, 0xd0000000, 0x00000008,
0079     0xe0000000, 0x00000008, 0xf0000000, 0x00000008,
0080     0x00000000, 0x00000009, 0x10000000, 0x00000009,
0081     0x20000000, 0x00000019, 0x30000000, 0x00000019,
0082     0x40000000, 0x00000019, 0x50000000, 0x00000019,
0083     0x60000000, 0x00000019, 0x70000000, 0x00000019,
0084     0x80000000, 0x00000019, 0x90000000, 0x00000019,
0085     0xa0000000, 0x00000019, 0xb0000000, 0x00000019,
0086     0xc0000000, 0x00000019, 0xd0000000, 0x00000019,
0087     0xe0000000, 0x00000019, 0xf0000000, 0x00000019,
0088     0x00000000, 0x0000001a, 0x10000000, 0x0000001a,
0089     0x20000000, 0x0000001a, 0x30000000, 0x0000001a,
0090     0x40000000, 0x0000001a, 0x50000000, 0x00000002,
0091     0x60000000, 0x00000002, 0x70000000, 0x00000002,
0092     0x80000000, 0x00000002, 0x90000000, 0x00000002,
0093     0xa0000000, 0x00000002, 0xb0000000, 0x00000002,
0094     0xc0000000, 0x0000000a, 0xd0000000, 0x0000000a,
0095     0xe0000000, 0x0000000a, 0xf0000000, 0x0000000a,
0096     0x00000000, 0x0000000b, 0x10000000, 0x0000000b,
0097     0x20000000, 0x0000000b, 0x30000000, 0x0000000b,
0098     0x40000000, 0x0000000b, 0x50000000, 0x0000001b,
0099     0x60000000, 0x0000001b, 0x70000000, 0x0000001b,
0100     0x80000000, 0x0000001b, 0x90000000, 0x0000001b,
0101     0xa0000000, 0x0000001b, 0xb0000000, 0x0000001b,
0102     0xc0000000, 0x0000001b, 0xd0000000, 0x0000001b,
0103     0xe0000000, 0x0000001b, 0xf0000000, 0x0000001b,
0104     0x00000000, 0x0000001c, 0x10000000, 0x0000001c,
0105     0x20000000, 0x0000001c, 0x30000000, 0x0000001c,
0106     0x40000000, 0x0000001c, 0x50000000, 0x0000001c,
0107     0x60000000, 0x0000001c, 0x70000000, 0x0000001c,
0108     0x80000000, 0x0000001c, 0x90000000, 0x0000001c,
0109 };
0110 
0111 static const u16 b43_lcntab_0x0e[] = {
0112     0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406,
0113     0x0407, 0x0408, 0x0409, 0x040a, 0x058b, 0x058c,
0114     0x058d, 0x058e, 0x058f, 0x0090, 0x0091, 0x0092,
0115     0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 0x0198,
0116     0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e,
0117     0x019f, 0x01a0, 0x01a1, 0x01a2, 0x01a3, 0x01a4,
0118     0x01a5, 0x0000,
0119 };
0120 
0121 static const u16 b43_lcntab_0x0f[] = {
0122     0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
0123     0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
0124     0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
0125     0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
0126     0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
0127     0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
0128     0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
0129     0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
0130     0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
0131     0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
0132     0x000a, 0x0009, 0x0006, 0x0005,
0133 };
0134 
0135 static const u16 b43_lcntab_0x10[] = {
0136     0x005f, 0x0036, 0x0029, 0x001f, 0x005f, 0x0036,
0137     0x0029, 0x001f, 0x005f, 0x0036, 0x0029, 0x001f,
0138     0x005f, 0x0036, 0x0029, 0x001f,
0139 };
0140 
0141 static const u16 b43_lcntab_0x11[] = {
0142     0x0009, 0x000f, 0x0014, 0x0018, 0x00fe, 0x0007,
0143     0x000b, 0x000f, 0x00fb, 0x00fe, 0x0001, 0x0005,
0144     0x0008, 0x000b, 0x000e, 0x0011, 0x0014, 0x0017,
0145     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0146     0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f,
0147     0x0012, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0148     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003,
0149     0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015,
0150     0x0018, 0x001b, 0x0000, 0x0000, 0x0000, 0x0000,
0151     0x0000, 0x0000, 0x0003, 0x00eb, 0x0000, 0x0000,
0152 };
0153 
0154 static const u32 b43_lcntab_0x12[] = {
0155     0x00000000, 0x00000000, 0x00000000, 0x00000000,
0156     0x00000000, 0x00000000, 0x00000000, 0x00000000,
0157     0x00000004, 0x00000000, 0x00000004, 0x00000008,
0158     0x00000001, 0x00000005, 0x00000009, 0x0000000d,
0159     0x0000004d, 0x0000008d, 0x0000000d, 0x0000004d,
0160     0x0000008d, 0x000000cd, 0x0000004f, 0x0000008f,
0161     0x000000cf, 0x000000d3, 0x00000113, 0x00000513,
0162     0x00000913, 0x00000953, 0x00000d53, 0x00001153,
0163     0x00001193, 0x00005193, 0x00009193, 0x0000d193,
0164     0x00011193, 0x00000000, 0x00000000, 0x00000000,
0165     0x00000000, 0x00000000, 0x00000000, 0x00000004,
0166     0x00000000, 0x00000004, 0x00000008, 0x00000001,
0167     0x00000005, 0x00000009, 0x0000000d, 0x0000004d,
0168     0x0000008d, 0x0000000d, 0x0000004d, 0x0000008d,
0169     0x000000cd, 0x0000004f, 0x0000008f, 0x000000cf,
0170     0x000000d3, 0x00000113, 0x00000513, 0x00000913,
0171     0x00000953, 0x00000d53, 0x00001153, 0x00005153,
0172     0x00009153, 0x0000d153, 0x00011153, 0x00015153,
0173     0x00019153, 0x0001d153, 0x00000000, 0x00000000,
0174     0x00000000, 0x00000000, 0x00000000, 0x00000000,
0175     0x00000000, 0x00000000, 0x00000000, 0x00000000,
0176     0x00000000, 0x00000000, 0x00000000, 0x00000000,
0177     0x00000000, 0x00000000, 0x00000000, 0x00000000,
0178     0x00000000, 0x00000000, 0x00000000, 0x00000000,
0179 };
0180 
0181 static const u16 b43_lcntab_0x14[] = {
0182     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0183     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0184     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0185     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0186     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0187     0x0002, 0x0003, 0x0001, 0x0003, 0x0002, 0x0001,
0188     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0189     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0190     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0191     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0192     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0193     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0194     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0195     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0196     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0197     0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003,
0198     0x0001, 0x0003, 0x0002, 0x0001, 0x0001, 0x0001,
0199     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0200     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0201     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0202     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0203     0x0001, 0x0001,
0204 };
0205 
0206 static const u16 b43_lcntab_0x17[] = {
0207     0x001a, 0x0034, 0x004e, 0x0068, 0x009c, 0x00d0,
0208     0x00ea, 0x0104, 0x0034, 0x0068, 0x009c, 0x00d0,
0209     0x0138, 0x01a0, 0x01d4, 0x0208, 0x004e, 0x009c,
0210     0x00ea, 0x0138, 0x01d4, 0x0270, 0x02be, 0x030c,
0211     0x0068, 0x00d0, 0x0138, 0x01a0, 0x0270, 0x0340,
0212     0x03a8, 0x0410, 0x0018, 0x009c, 0x00d0, 0x0104,
0213     0x00ea, 0x0138, 0x0186, 0x00d0, 0x0104, 0x0104,
0214     0x0138, 0x016c, 0x016c, 0x01a0, 0x0138, 0x0186,
0215     0x0186, 0x01d4, 0x0222, 0x0222, 0x0270, 0x0104,
0216     0x0138, 0x016c, 0x0138, 0x016c, 0x01a0, 0x01d4,
0217     0x01a0, 0x01d4, 0x0208, 0x0208, 0x023c, 0x0186,
0218     0x01d4, 0x0222, 0x01d4, 0x0222, 0x0270, 0x02be,
0219     0x0270, 0x02be, 0x030c, 0x030c, 0x035a, 0x0036,
0220     0x006c, 0x00a2, 0x00d8, 0x0144, 0x01b0, 0x01e6,
0221     0x021c, 0x006c, 0x00d8, 0x0144, 0x01b0, 0x0288,
0222     0x0360, 0x03cc, 0x0438, 0x00a2, 0x0144, 0x01e6,
0223     0x0288, 0x03cc, 0x0510, 0x05b2, 0x0654, 0x00d8,
0224     0x01b0, 0x0288, 0x0360, 0x0510, 0x06c0, 0x0798,
0225     0x0870, 0x0018, 0x0144, 0x01b0, 0x021c, 0x01e6,
0226     0x0288, 0x032a, 0x01b0, 0x021c, 0x021c, 0x0288,
0227     0x02f4, 0x02f4, 0x0360, 0x0288, 0x032a, 0x032a,
0228     0x03cc, 0x046e, 0x046e, 0x0510, 0x021c, 0x0288,
0229     0x02f4, 0x0288, 0x02f4, 0x0360, 0x03cc, 0x0360,
0230     0x03cc, 0x0438, 0x0438, 0x04a4, 0x032a, 0x03cc,
0231     0x046e, 0x03cc, 0x046e, 0x0510, 0x05b2, 0x0510,
0232     0x05b2, 0x0654, 0x0654, 0x06f6,
0233 };
0234 
0235 static const u16 b43_lcntab_0x00[] = {
0236     0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00,
0237     0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005,
0238     0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
0239     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0240     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0241     0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
0242     0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003,
0243     0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007,
0244     0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
0245     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0246     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0247     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0248     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0249     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0250     0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
0251     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0252     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0253     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0254 };
0255 
0256 static const u32 b43_lcntab_0x18[] = {
0257     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0258     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0259     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0260     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0261     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0262     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0263     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0264     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0265     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0266     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0267     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0268     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0269     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0270     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0271     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0272     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0273     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0274     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0275     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0276     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0277     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0278     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0279     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0280     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0281     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0282     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0283     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0284     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0285     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0286     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0287     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0288     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0289     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0290     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0291     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0292     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0293     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0294     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0295     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0296     0x00080000, 0x00080000, 0x00080000, 0x00080000,
0297 };
0298 
0299 /**************************************************
0300  * TX gain.
0301  **************************************************/
0302 
0303 static const struct b43_lcntab_tx_gain_tbl_entry
0304     b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0[B43_LCNTAB_TX_GAIN_SIZE] = {
0305     { 0x03, 0x00, 0x1f, 0x0, 0x48 },
0306     { 0x03, 0x00, 0x1f, 0x0, 0x46 },
0307     { 0x03, 0x00, 0x1f, 0x0, 0x44 },
0308     { 0x03, 0x00, 0x1e, 0x0, 0x43 },
0309     { 0x03, 0x00, 0x1d, 0x0, 0x44 },
0310     { 0x03, 0x00, 0x1c, 0x0, 0x44 },
0311     { 0x03, 0x00, 0x1b, 0x0, 0x45 },
0312     { 0x03, 0x00, 0x1a, 0x0, 0x46 },
0313     { 0x03, 0x00, 0x19, 0x0, 0x46 },
0314     { 0x03, 0x00, 0x18, 0x0, 0x47 },
0315     { 0x03, 0x00, 0x17, 0x0, 0x48 },
0316     { 0x03, 0x00, 0x17, 0x0, 0x46 },
0317     { 0x03, 0x00, 0x16, 0x0, 0x47 },
0318     { 0x03, 0x00, 0x15, 0x0, 0x48 },
0319     { 0x03, 0x00, 0x15, 0x0, 0x46 },
0320     { 0x03, 0x00, 0x15, 0x0, 0x44 },
0321     { 0x03, 0x00, 0x15, 0x0, 0x42 },
0322     { 0x03, 0x00, 0x15, 0x0, 0x40 },
0323     { 0x03, 0x00, 0x15, 0x0, 0x3f },
0324     { 0x03, 0x00, 0x14, 0x0, 0x40 },
0325     { 0x03, 0x00, 0x13, 0x0, 0x41 },
0326     { 0x03, 0x00, 0x13, 0x0, 0x40 },
0327     { 0x03, 0x00, 0x12, 0x0, 0x41 },
0328     { 0x03, 0x00, 0x12, 0x0, 0x40 },
0329     { 0x03, 0x00, 0x11, 0x0, 0x41 },
0330     { 0x03, 0x00, 0x11, 0x0, 0x40 },
0331     { 0x03, 0x00, 0x10, 0x0, 0x41 },
0332     { 0x03, 0x00, 0x10, 0x0, 0x40 },
0333     { 0x03, 0x00, 0x10, 0x0, 0x3e },
0334     { 0x03, 0x00, 0x10, 0x0, 0x3c },
0335     { 0x03, 0x00, 0x10, 0x0, 0x3a },
0336     { 0x03, 0x00, 0x0f, 0x0, 0x3d },
0337     { 0x03, 0x00, 0x0f, 0x0, 0x3b },
0338     { 0x03, 0x00, 0x0e, 0x0, 0x3d },
0339     { 0x03, 0x00, 0x0e, 0x0, 0x3c },
0340     { 0x03, 0x00, 0x0e, 0x0, 0x3a },
0341     { 0x03, 0x00, 0x0d, 0x0, 0x3c },
0342     { 0x03, 0x00, 0x0d, 0x0, 0x3b },
0343     { 0x03, 0x00, 0x0c, 0x0, 0x3e },
0344     { 0x03, 0x00, 0x0c, 0x0, 0x3c },
0345     { 0x03, 0x00, 0x0c, 0x0, 0x3a },
0346     { 0x03, 0x00, 0x0b, 0x0, 0x3e },
0347     { 0x03, 0x00, 0x0b, 0x0, 0x3c },
0348     { 0x03, 0x00, 0x0b, 0x0, 0x3b },
0349     { 0x03, 0x00, 0x0b, 0x0, 0x39 },
0350     { 0x03, 0x00, 0x0a, 0x0, 0x3d },
0351     { 0x03, 0x00, 0x0a, 0x0, 0x3b },
0352     { 0x03, 0x00, 0x0a, 0x0, 0x39 },
0353     { 0x03, 0x00, 0x09, 0x0, 0x3e },
0354     { 0x03, 0x00, 0x09, 0x0, 0x3c },
0355     { 0x03, 0x00, 0x09, 0x0, 0x3a },
0356     { 0x03, 0x00, 0x09, 0x0, 0x39 },
0357     { 0x03, 0x00, 0x08, 0x0, 0x3e },
0358     { 0x03, 0x00, 0x08, 0x0, 0x3c },
0359     { 0x03, 0x00, 0x08, 0x0, 0x3a },
0360     { 0x03, 0x00, 0x08, 0x0, 0x39 },
0361     { 0x03, 0x00, 0x08, 0x0, 0x37 },
0362     { 0x03, 0x00, 0x07, 0x0, 0x3d },
0363     { 0x03, 0x00, 0x07, 0x0, 0x3c },
0364     { 0x03, 0x00, 0x07, 0x0, 0x3a },
0365     { 0x03, 0x00, 0x07, 0x0, 0x38 },
0366     { 0x03, 0x00, 0x07, 0x0, 0x37 },
0367     { 0x03, 0x00, 0x06, 0x0, 0x3e },
0368     { 0x03, 0x00, 0x06, 0x0, 0x3c },
0369     { 0x03, 0x00, 0x06, 0x0, 0x3a },
0370     { 0x03, 0x00, 0x06, 0x0, 0x39 },
0371     { 0x03, 0x00, 0x06, 0x0, 0x37 },
0372     { 0x03, 0x00, 0x06, 0x0, 0x36 },
0373     { 0x03, 0x00, 0x06, 0x0, 0x34 },
0374     { 0x03, 0x00, 0x05, 0x0, 0x3d },
0375     { 0x03, 0x00, 0x05, 0x0, 0x3b },
0376     { 0x03, 0x00, 0x05, 0x0, 0x39 },
0377     { 0x03, 0x00, 0x05, 0x0, 0x38 },
0378     { 0x03, 0x00, 0x05, 0x0, 0x36 },
0379     { 0x03, 0x00, 0x05, 0x0, 0x35 },
0380     { 0x03, 0x00, 0x05, 0x0, 0x33 },
0381     { 0x03, 0x00, 0x04, 0x0, 0x3e },
0382     { 0x03, 0x00, 0x04, 0x0, 0x3c },
0383     { 0x03, 0x00, 0x04, 0x0, 0x3a },
0384     { 0x03, 0x00, 0x04, 0x0, 0x39 },
0385     { 0x03, 0x00, 0x04, 0x0, 0x37 },
0386     { 0x03, 0x00, 0x04, 0x0, 0x36 },
0387     { 0x03, 0x00, 0x04, 0x0, 0x34 },
0388     { 0x03, 0x00, 0x04, 0x0, 0x33 },
0389     { 0x03, 0x00, 0x04, 0x0, 0x31 },
0390     { 0x03, 0x00, 0x04, 0x0, 0x30 },
0391     { 0x03, 0x00, 0x04, 0x0, 0x2e },
0392     { 0x03, 0x00, 0x03, 0x0, 0x3c },
0393     { 0x03, 0x00, 0x03, 0x0, 0x3a },
0394     { 0x03, 0x00, 0x03, 0x0, 0x39 },
0395     { 0x03, 0x00, 0x03, 0x0, 0x37 },
0396     { 0x03, 0x00, 0x03, 0x0, 0x36 },
0397     { 0x03, 0x00, 0x03, 0x0, 0x34 },
0398     { 0x03, 0x00, 0x03, 0x0, 0x33 },
0399     { 0x03, 0x00, 0x03, 0x0, 0x31 },
0400     { 0x03, 0x00, 0x03, 0x0, 0x30 },
0401     { 0x03, 0x00, 0x03, 0x0, 0x2e },
0402     { 0x03, 0x00, 0x03, 0x0, 0x2d },
0403     { 0x03, 0x00, 0x03, 0x0, 0x2c },
0404     { 0x03, 0x00, 0x03, 0x0, 0x2b },
0405     { 0x03, 0x00, 0x03, 0x0, 0x29 },
0406     { 0x03, 0x00, 0x02, 0x0, 0x3d },
0407     { 0x03, 0x00, 0x02, 0x0, 0x3b },
0408     { 0x03, 0x00, 0x02, 0x0, 0x39 },
0409     { 0x03, 0x00, 0x02, 0x0, 0x38 },
0410     { 0x03, 0x00, 0x02, 0x0, 0x36 },
0411     { 0x03, 0x00, 0x02, 0x0, 0x35 },
0412     { 0x03, 0x00, 0x02, 0x0, 0x33 },
0413     { 0x03, 0x00, 0x02, 0x0, 0x32 },
0414     { 0x03, 0x00, 0x02, 0x0, 0x30 },
0415     { 0x03, 0x00, 0x02, 0x0, 0x2f },
0416     { 0x03, 0x00, 0x02, 0x0, 0x2e },
0417     { 0x03, 0x00, 0x02, 0x0, 0x2c },
0418     { 0x03, 0x00, 0x02, 0x0, 0x2b },
0419     { 0x03, 0x00, 0x02, 0x0, 0x2a },
0420     { 0x03, 0x00, 0x02, 0x0, 0x29 },
0421     { 0x03, 0x00, 0x02, 0x0, 0x27 },
0422     { 0x03, 0x00, 0x02, 0x0, 0x26 },
0423     { 0x03, 0x00, 0x02, 0x0, 0x25 },
0424     { 0x03, 0x00, 0x02, 0x0, 0x24 },
0425     { 0x03, 0x00, 0x02, 0x0, 0x23 },
0426     { 0x03, 0x00, 0x02, 0x0, 0x22 },
0427     { 0x03, 0x00, 0x02, 0x0, 0x21 },
0428     { 0x03, 0x00, 0x02, 0x0, 0x20 },
0429     { 0x03, 0x00, 0x01, 0x0, 0x3f },
0430     { 0x03, 0x00, 0x01, 0x0, 0x3d },
0431     { 0x03, 0x00, 0x01, 0x0, 0x3b },
0432     { 0x03, 0x00, 0x01, 0x0, 0x39 },
0433 };
0434 
0435 /**************************************************
0436  * SW control.
0437  **************************************************/
0438 
0439 static const u16 b43_lcntab_sw_ctl_4313_epa_rev0[] = {
0440     0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
0441     0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
0442     0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
0443     0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
0444     0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
0445     0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
0446     0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
0447     0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
0448     0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
0449     0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
0450     0x0002, 0x0008, 0x0004, 0x0001,
0451 };
0452 
0453 /**************************************************
0454  * R/W ops.
0455  **************************************************/
0456 
0457 u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset)
0458 {
0459     u32 type, value;
0460 
0461     type = offset & B43_LCNTAB_TYPEMASK;
0462     offset &= ~B43_LCNTAB_TYPEMASK;
0463     B43_WARN_ON(offset > 0xFFFF);
0464 
0465     switch (type) {
0466     case B43_LCNTAB_8BIT:
0467         b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
0468         value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO) & 0xFF;
0469         break;
0470     case B43_LCNTAB_16BIT:
0471         b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
0472         value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
0473         break;
0474     case B43_LCNTAB_32BIT:
0475         b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
0476         value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
0477         value |= (b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI) << 16);
0478         break;
0479     default:
0480         B43_WARN_ON(1);
0481         value = 0;
0482     }
0483 
0484     return value;
0485 }
0486 
0487 void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset,
0488               unsigned int nr_elements, void *_data)
0489 {
0490     u32 type;
0491     u8 *data = _data;
0492     unsigned int i;
0493 
0494     type = offset & B43_LCNTAB_TYPEMASK;
0495     offset &= ~B43_LCNTAB_TYPEMASK;
0496     B43_WARN_ON(offset > 0xFFFF);
0497 
0498     b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
0499 
0500     for (i = 0; i < nr_elements; i++) {
0501         switch (type) {
0502         case B43_LCNTAB_8BIT:
0503             *data = b43_phy_read(dev,
0504                          B43_PHY_LCN_TABLE_DATALO) & 0xFF;
0505             data++;
0506             break;
0507         case B43_LCNTAB_16BIT:
0508             *((u16 *)data) = b43_phy_read(dev,
0509                               B43_PHY_LCN_TABLE_DATALO);
0510             data += 2;
0511             break;
0512         case B43_LCNTAB_32BIT:
0513             *((u32 *)data) = b43_phy_read(dev,
0514                         B43_PHY_LCN_TABLE_DATALO);
0515             *((u32 *)data) |= (b43_phy_read(dev,
0516                        B43_PHY_LCN_TABLE_DATAHI) << 16);
0517             data += 4;
0518             break;
0519         default:
0520             B43_WARN_ON(1);
0521         }
0522     }
0523 }
0524 
0525 void b43_lcntab_write(struct b43_wldev *dev, u32 offset, u32 value)
0526 {
0527     u32 type;
0528 
0529     type = offset & B43_LCNTAB_TYPEMASK;
0530     offset &= 0xFFFF;
0531 
0532     switch (type) {
0533     case B43_LCNTAB_8BIT:
0534         B43_WARN_ON(value & ~0xFF);
0535         b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
0536         b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
0537         break;
0538     case B43_LCNTAB_16BIT:
0539         B43_WARN_ON(value & ~0xFFFF);
0540         b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
0541         b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
0542         break;
0543     case B43_LCNTAB_32BIT:
0544         b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
0545         b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, value >> 16);
0546         b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value & 0xFFFF);
0547         break;
0548     default:
0549         B43_WARN_ON(1);
0550     }
0551 
0552     return;
0553 }
0554 
0555 void b43_lcntab_write_bulk(struct b43_wldev *dev, u32 offset,
0556                unsigned int nr_elements, const void *_data)
0557 {
0558     u32 type, value;
0559     const u8 *data = _data;
0560     unsigned int i;
0561 
0562     type = offset & B43_LCNTAB_TYPEMASK;
0563     offset &= ~B43_LCNTAB_TYPEMASK;
0564     B43_WARN_ON(offset > 0xFFFF);
0565 
0566     b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
0567 
0568     for (i = 0; i < nr_elements; i++) {
0569         switch (type) {
0570         case B43_LCNTAB_8BIT:
0571             value = *data;
0572             data++;
0573             B43_WARN_ON(value & ~0xFF);
0574             b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
0575             break;
0576         case B43_LCNTAB_16BIT:
0577             value = *((u16 *)data);
0578             data += 2;
0579             B43_WARN_ON(value & ~0xFFFF);
0580             b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
0581             break;
0582         case B43_LCNTAB_32BIT:
0583             value = *((u32 *)data);
0584             data += 4;
0585             b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI,
0586                       value >> 16);
0587             b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO,
0588                       value & 0xFFFF);
0589             break;
0590         default:
0591             B43_WARN_ON(1);
0592         }
0593     }
0594 }
0595 
0596 /**************************************************
0597  * Tables ops.
0598  **************************************************/
0599 
0600 #define lcntab_upload(dev, offset, data) do { \
0601         b43_lcntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
0602     } while (0)
0603 static void b43_phy_lcn_upload_static_tables(struct b43_wldev *dev)
0604 {
0605     lcntab_upload(dev, B43_LCNTAB16(0x02, 0), b43_lcntab_0x02);
0606     lcntab_upload(dev, B43_LCNTAB16(0x01, 0), b43_lcntab_0x01);
0607     lcntab_upload(dev, B43_LCNTAB32(0x0b, 0), b43_lcntab_0x0b);
0608     lcntab_upload(dev, B43_LCNTAB32(0x0c, 0), b43_lcntab_0x0c);
0609     lcntab_upload(dev, B43_LCNTAB32(0x0d, 0), b43_lcntab_0x0d);
0610     lcntab_upload(dev, B43_LCNTAB16(0x0e, 0), b43_lcntab_0x0e);
0611     lcntab_upload(dev, B43_LCNTAB16(0x0f, 0), b43_lcntab_0x0f);
0612     lcntab_upload(dev, B43_LCNTAB16(0x10, 0), b43_lcntab_0x10);
0613     lcntab_upload(dev, B43_LCNTAB16(0x11, 0), b43_lcntab_0x11);
0614     lcntab_upload(dev, B43_LCNTAB32(0x12, 0), b43_lcntab_0x12);
0615     lcntab_upload(dev, B43_LCNTAB16(0x14, 0), b43_lcntab_0x14);
0616     lcntab_upload(dev, B43_LCNTAB16(0x17, 0), b43_lcntab_0x17);
0617     lcntab_upload(dev, B43_LCNTAB16(0x00, 0), b43_lcntab_0x00);
0618     lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18);
0619 }
0620 
0621 static void b43_phy_lcn_load_tx_gain_tab(struct b43_wldev *dev,
0622             const struct b43_lcntab_tx_gain_tbl_entry *gain_table)
0623 {
0624     u32 i;
0625     u32 val;
0626 
0627     u16 pa_gain = 0x70;
0628     if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM)
0629         pa_gain = 0x10;
0630 
0631     for (i = 0; i < B43_LCNTAB_TX_GAIN_SIZE; i++) {
0632         val = ((pa_gain << 24) |
0633                (gain_table[i].pad << 16) |
0634                (gain_table[i].pga << 8) |
0635             gain_table[i].gm);
0636         b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0xc0 + i), val);
0637 
0638         /* brcmsmac doesn't maskset, we follow newer wl here */
0639         val = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i));
0640         val &= 0x000fffff;
0641         val |= ((gain_table[i].dac << 28) |
0642             (gain_table[i].bb_mult << 20));
0643         b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x140 + i), val);
0644     }
0645 }
0646 
0647 /* wlc_lcnphy_load_rfpower */
0648 static void b43_phy_lcn_load_rfpower(struct b43_wldev *dev)
0649 {
0650     u32 bbmult, rfgain;
0651     u8 i;
0652 
0653     for (i = 0; i < 128; i++) {
0654         bbmult = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i));
0655         bbmult >>= 20;
0656         rfgain = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0xc0 + i));
0657 
0658         /* TODO: calculate value for 0x240 + i table offset
0659          * b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), val);
0660          */
0661     }
0662 }
0663 
0664 /* Not implemented in brcmsmac, noticed in wl in MMIO dump */
0665 static void b43_phy_lcn_rewrite_rfpower_table(struct b43_wldev *dev)
0666 {
0667     int i;
0668     u32 tmp;
0669     for (i = 0; i < 128; i++) {
0670         tmp = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x240 + i));
0671         b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), tmp);
0672     }
0673 }
0674 
0675 /* wlc_lcnphy_clear_papd_comptable */
0676 static void b43_phy_lcn_clean_papd_comp_table(struct b43_wldev *dev)
0677 {
0678     u8 i;
0679 
0680     for (i = 0; i < 0x80; i++)
0681         b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000);
0682 }
0683 
0684 /* wlc_lcnphy_tbl_init */
0685 void b43_phy_lcn_tables_init(struct b43_wldev *dev)
0686 {
0687     struct ssb_sprom *sprom = dev->dev->bus_sprom;
0688 
0689     b43_phy_lcn_upload_static_tables(dev);
0690 
0691     if (b43_current_band(dev->wl) == NL80211_BAND_2GHZ) {
0692         if (sprom->boardflags_lo & B43_BFL_FEM)
0693             b43_phy_lcn_load_tx_gain_tab(dev,
0694                 b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0);
0695         else
0696             b43err(dev->wl,
0697                    "TX gain table unknown for this card\n");
0698     }
0699 
0700     if (sprom->boardflags_lo & B43_BFL_FEM &&
0701         !(sprom->boardflags_hi & B43_BFH_FEM_BT))
0702         b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0),
0703             ARRAY_SIZE(b43_lcntab_sw_ctl_4313_epa_rev0),
0704             b43_lcntab_sw_ctl_4313_epa_rev0);
0705     else
0706         b43err(dev->wl, "SW ctl table is unknown for this card\n");
0707 
0708     b43_phy_lcn_load_rfpower(dev);
0709     b43_phy_lcn_rewrite_rfpower_table(dev);
0710     b43_phy_lcn_clean_papd_comp_table(dev);
0711 }