linux/drivers/net/wireless/broadcom/b43/tables_phy_lcn.c
<<
>>
Prefs
   1/*
   2
   3  Broadcom B43 wireless driver
   4  IEEE 802.11n LCN-PHY data tables
   5
   6  Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
   7
   8  This program is free software; you can redistribute it and/or modify
   9  it under the terms of the GNU General Public License as published by
  10  the Free Software Foundation; either version 2 of the License, or
  11  (at your option) any later version.
  12
  13  This program is distributed in the hope that it will be useful,
  14  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16  GNU General Public License for more details.
  17
  18  You should have received a copy of the GNU General Public License
  19  along with this program; see the file COPYING.  If not, write to
  20  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
  21  Boston, MA 02110-1301, USA.
  22
  23*/
  24
  25#include "b43.h"
  26#include "tables_phy_lcn.h"
  27#include "phy_common.h"
  28#include "phy_lcn.h"
  29
  30struct b43_lcntab_tx_gain_tbl_entry {
  31        u8 gm;
  32        u8 pga;
  33        u8 pad;
  34        u8 dac;
  35        u8 bb_mult;
  36};
  37
  38/**************************************************
  39 * Static tables.
  40 **************************************************/
  41
  42static const u16 b43_lcntab_0x02[] = {
  43        0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
  44        0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
  45        0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
  46        0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
  47        0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
  48        0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
  49        0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
  50        0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
  51        0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
  52        0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
  53        0x014d, 0x014d, 0x014d, 0x014d,
  54};
  55
  56static const u16 b43_lcntab_0x01[] = {
  57        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  58        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  59        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  60        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  61        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  62        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  63        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  64        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  65        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  66        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  67        0x0000, 0x0000, 0x0000, 0x0000,
  68};
  69
  70static const u32 b43_lcntab_0x0b[] = {
  71        0x000141f8, 0x000021f8, 0x000021fb, 0x000041fb,
  72        0x0001fedb, 0x0000217b, 0x00002133, 0x000040eb,
  73        0x0001fea3, 0x0000024b,
  74};
  75
  76static const u32 b43_lcntab_0x0c[] = {
  77        0x00100001, 0x00200010, 0x00300001, 0x00400010,
  78        0x00500022, 0x00600122, 0x00700222, 0x00800322,
  79        0x00900422, 0x00a00522, 0x00b00622, 0x00c00722,
  80        0x00d00822, 0x00f00922, 0x00100a22, 0x00200b22,
  81        0x00300c22, 0x00400d22, 0x00500e22, 0x00600f22,
  82};
  83
  84static const u32 b43_lcntab_0x0d[] = {
  85        0x00000000, 0x00000000, 0x10000000, 0x00000000,
  86        0x20000000, 0x00000000, 0x30000000, 0x00000000,
  87        0x40000000, 0x00000000, 0x50000000, 0x00000000,
  88        0x60000000, 0x00000000, 0x70000000, 0x00000000,
  89        0x80000000, 0x00000000, 0x90000000, 0x00000008,
  90        0xa0000000, 0x00000008, 0xb0000000, 0x00000008,
  91        0xc0000000, 0x00000008, 0xd0000000, 0x00000008,
  92        0xe0000000, 0x00000008, 0xf0000000, 0x00000008,
  93        0x00000000, 0x00000009, 0x10000000, 0x00000009,
  94        0x20000000, 0x00000019, 0x30000000, 0x00000019,
  95        0x40000000, 0x00000019, 0x50000000, 0x00000019,
  96        0x60000000, 0x00000019, 0x70000000, 0x00000019,
  97        0x80000000, 0x00000019, 0x90000000, 0x00000019,
  98        0xa0000000, 0x00000019, 0xb0000000, 0x00000019,
  99        0xc0000000, 0x00000019, 0xd0000000, 0x00000019,
 100        0xe0000000, 0x00000019, 0xf0000000, 0x00000019,
 101        0x00000000, 0x0000001a, 0x10000000, 0x0000001a,
 102        0x20000000, 0x0000001a, 0x30000000, 0x0000001a,
 103        0x40000000, 0x0000001a, 0x50000000, 0x00000002,
 104        0x60000000, 0x00000002, 0x70000000, 0x00000002,
 105        0x80000000, 0x00000002, 0x90000000, 0x00000002,
 106        0xa0000000, 0x00000002, 0xb0000000, 0x00000002,
 107        0xc0000000, 0x0000000a, 0xd0000000, 0x0000000a,
 108        0xe0000000, 0x0000000a, 0xf0000000, 0x0000000a,
 109        0x00000000, 0x0000000b, 0x10000000, 0x0000000b,
 110        0x20000000, 0x0000000b, 0x30000000, 0x0000000b,
 111        0x40000000, 0x0000000b, 0x50000000, 0x0000001b,
 112        0x60000000, 0x0000001b, 0x70000000, 0x0000001b,
 113        0x80000000, 0x0000001b, 0x90000000, 0x0000001b,
 114        0xa0000000, 0x0000001b, 0xb0000000, 0x0000001b,
 115        0xc0000000, 0x0000001b, 0xd0000000, 0x0000001b,
 116        0xe0000000, 0x0000001b, 0xf0000000, 0x0000001b,
 117        0x00000000, 0x0000001c, 0x10000000, 0x0000001c,
 118        0x20000000, 0x0000001c, 0x30000000, 0x0000001c,
 119        0x40000000, 0x0000001c, 0x50000000, 0x0000001c,
 120        0x60000000, 0x0000001c, 0x70000000, 0x0000001c,
 121        0x80000000, 0x0000001c, 0x90000000, 0x0000001c,
 122};
 123
 124static const u16 b43_lcntab_0x0e[] = {
 125        0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406,
 126        0x0407, 0x0408, 0x0409, 0x040a, 0x058b, 0x058c,
 127        0x058d, 0x058e, 0x058f, 0x0090, 0x0091, 0x0092,
 128        0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 0x0198,
 129        0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e,
 130        0x019f, 0x01a0, 0x01a1, 0x01a2, 0x01a3, 0x01a4,
 131        0x01a5, 0x0000,
 132};
 133
 134static const u16 b43_lcntab_0x0f[] = {
 135        0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
 136        0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
 137        0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
 138        0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
 139        0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
 140        0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
 141        0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
 142        0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
 143        0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
 144        0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
 145        0x000a, 0x0009, 0x0006, 0x0005,
 146};
 147
 148static const u16 b43_lcntab_0x10[] = {
 149        0x005f, 0x0036, 0x0029, 0x001f, 0x005f, 0x0036,
 150        0x0029, 0x001f, 0x005f, 0x0036, 0x0029, 0x001f,
 151        0x005f, 0x0036, 0x0029, 0x001f,
 152};
 153
 154static const u16 b43_lcntab_0x11[] = {
 155        0x0009, 0x000f, 0x0014, 0x0018, 0x00fe, 0x0007,
 156        0x000b, 0x000f, 0x00fb, 0x00fe, 0x0001, 0x0005,
 157        0x0008, 0x000b, 0x000e, 0x0011, 0x0014, 0x0017,
 158        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 159        0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f,
 160        0x0012, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 161        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003,
 162        0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015,
 163        0x0018, 0x001b, 0x0000, 0x0000, 0x0000, 0x0000,
 164        0x0000, 0x0000, 0x0003, 0x00eb, 0x0000, 0x0000,
 165};
 166
 167static const u32 b43_lcntab_0x12[] = {
 168        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 169        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 170        0x00000004, 0x00000000, 0x00000004, 0x00000008,
 171        0x00000001, 0x00000005, 0x00000009, 0x0000000d,
 172        0x0000004d, 0x0000008d, 0x0000000d, 0x0000004d,
 173        0x0000008d, 0x000000cd, 0x0000004f, 0x0000008f,
 174        0x000000cf, 0x000000d3, 0x00000113, 0x00000513,
 175        0x00000913, 0x00000953, 0x00000d53, 0x00001153,
 176        0x00001193, 0x00005193, 0x00009193, 0x0000d193,
 177        0x00011193, 0x00000000, 0x00000000, 0x00000000,
 178        0x00000000, 0x00000000, 0x00000000, 0x00000004,
 179        0x00000000, 0x00000004, 0x00000008, 0x00000001,
 180        0x00000005, 0x00000009, 0x0000000d, 0x0000004d,
 181        0x0000008d, 0x0000000d, 0x0000004d, 0x0000008d,
 182        0x000000cd, 0x0000004f, 0x0000008f, 0x000000cf,
 183        0x000000d3, 0x00000113, 0x00000513, 0x00000913,
 184        0x00000953, 0x00000d53, 0x00001153, 0x00005153,
 185        0x00009153, 0x0000d153, 0x00011153, 0x00015153,
 186        0x00019153, 0x0001d153, 0x00000000, 0x00000000,
 187        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 188        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 189        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 190        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 191        0x00000000, 0x00000000, 0x00000000, 0x00000000,
 192};
 193
 194static const u16 b43_lcntab_0x14[] = {
 195        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 196        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 197        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 198        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 199        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 200        0x0002, 0x0003, 0x0001, 0x0003, 0x0002, 0x0001,
 201        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 202        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 203        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 204        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 205        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 206        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 207        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 208        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 209        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 210        0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003,
 211        0x0001, 0x0003, 0x0002, 0x0001, 0x0001, 0x0001,
 212        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 213        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 214        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 215        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
 216        0x0001, 0x0001,
 217};
 218
 219static const u16 b43_lcntab_0x17[] = {
 220        0x001a, 0x0034, 0x004e, 0x0068, 0x009c, 0x00d0,
 221        0x00ea, 0x0104, 0x0034, 0x0068, 0x009c, 0x00d0,
 222        0x0138, 0x01a0, 0x01d4, 0x0208, 0x004e, 0x009c,
 223        0x00ea, 0x0138, 0x01d4, 0x0270, 0x02be, 0x030c,
 224        0x0068, 0x00d0, 0x0138, 0x01a0, 0x0270, 0x0340,
 225        0x03a8, 0x0410, 0x0018, 0x009c, 0x00d0, 0x0104,
 226        0x00ea, 0x0138, 0x0186, 0x00d0, 0x0104, 0x0104,
 227        0x0138, 0x016c, 0x016c, 0x01a0, 0x0138, 0x0186,
 228        0x0186, 0x01d4, 0x0222, 0x0222, 0x0270, 0x0104,
 229        0x0138, 0x016c, 0x0138, 0x016c, 0x01a0, 0x01d4,
 230        0x01a0, 0x01d4, 0x0208, 0x0208, 0x023c, 0x0186,
 231        0x01d4, 0x0222, 0x01d4, 0x0222, 0x0270, 0x02be,
 232        0x0270, 0x02be, 0x030c, 0x030c, 0x035a, 0x0036,
 233        0x006c, 0x00a2, 0x00d8, 0x0144, 0x01b0, 0x01e6,
 234        0x021c, 0x006c, 0x00d8, 0x0144, 0x01b0, 0x0288,
 235        0x0360, 0x03cc, 0x0438, 0x00a2, 0x0144, 0x01e6,
 236        0x0288, 0x03cc, 0x0510, 0x05b2, 0x0654, 0x00d8,
 237        0x01b0, 0x0288, 0x0360, 0x0510, 0x06c0, 0x0798,
 238        0x0870, 0x0018, 0x0144, 0x01b0, 0x021c, 0x01e6,
 239        0x0288, 0x032a, 0x01b0, 0x021c, 0x021c, 0x0288,
 240        0x02f4, 0x02f4, 0x0360, 0x0288, 0x032a, 0x032a,
 241        0x03cc, 0x046e, 0x046e, 0x0510, 0x021c, 0x0288,
 242        0x02f4, 0x0288, 0x02f4, 0x0360, 0x03cc, 0x0360,
 243        0x03cc, 0x0438, 0x0438, 0x04a4, 0x032a, 0x03cc,
 244        0x046e, 0x03cc, 0x046e, 0x0510, 0x05b2, 0x0510,
 245        0x05b2, 0x0654, 0x0654, 0x06f6,
 246};
 247
 248static const u16 b43_lcntab_0x00[] = {
 249        0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00,
 250        0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005,
 251        0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
 252        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 253        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 254        0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
 255        0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003,
 256        0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007,
 257        0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
 258        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 259        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 260        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 261        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 262        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 263        0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
 264        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 265        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 266        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 267};
 268
 269static const u32 b43_lcntab_0x18[] = {
 270        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 271        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 272        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 273        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 274        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 275        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 276        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 277        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 278        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 279        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 280        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 281        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 282        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 283        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 284        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 285        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 286        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 287        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 288        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 289        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 290        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 291        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 292        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 293        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 294        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 295        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 296        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 297        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 298        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 299        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 300        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 301        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 302        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 303        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 304        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 305        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 306        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 307        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 308        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 309        0x00080000, 0x00080000, 0x00080000, 0x00080000,
 310};
 311
 312/**************************************************
 313 * TX gain.
 314 **************************************************/
 315
 316static const struct b43_lcntab_tx_gain_tbl_entry
 317        b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0[B43_LCNTAB_TX_GAIN_SIZE] = {
 318        { 0x03, 0x00, 0x1f, 0x0, 0x48 },
 319        { 0x03, 0x00, 0x1f, 0x0, 0x46 },
 320        { 0x03, 0x00, 0x1f, 0x0, 0x44 },
 321        { 0x03, 0x00, 0x1e, 0x0, 0x43 },
 322        { 0x03, 0x00, 0x1d, 0x0, 0x44 },
 323        { 0x03, 0x00, 0x1c, 0x0, 0x44 },
 324        { 0x03, 0x00, 0x1b, 0x0, 0x45 },
 325        { 0x03, 0x00, 0x1a, 0x0, 0x46 },
 326        { 0x03, 0x00, 0x19, 0x0, 0x46 },
 327        { 0x03, 0x00, 0x18, 0x0, 0x47 },
 328        { 0x03, 0x00, 0x17, 0x0, 0x48 },
 329        { 0x03, 0x00, 0x17, 0x0, 0x46 },
 330        { 0x03, 0x00, 0x16, 0x0, 0x47 },
 331        { 0x03, 0x00, 0x15, 0x0, 0x48 },
 332        { 0x03, 0x00, 0x15, 0x0, 0x46 },
 333        { 0x03, 0x00, 0x15, 0x0, 0x44 },
 334        { 0x03, 0x00, 0x15, 0x0, 0x42 },
 335        { 0x03, 0x00, 0x15, 0x0, 0x40 },
 336        { 0x03, 0x00, 0x15, 0x0, 0x3f },
 337        { 0x03, 0x00, 0x14, 0x0, 0x40 },
 338        { 0x03, 0x00, 0x13, 0x0, 0x41 },
 339        { 0x03, 0x00, 0x13, 0x0, 0x40 },
 340        { 0x03, 0x00, 0x12, 0x0, 0x41 },
 341        { 0x03, 0x00, 0x12, 0x0, 0x40 },
 342        { 0x03, 0x00, 0x11, 0x0, 0x41 },
 343        { 0x03, 0x00, 0x11, 0x0, 0x40 },
 344        { 0x03, 0x00, 0x10, 0x0, 0x41 },
 345        { 0x03, 0x00, 0x10, 0x0, 0x40 },
 346        { 0x03, 0x00, 0x10, 0x0, 0x3e },
 347        { 0x03, 0x00, 0x10, 0x0, 0x3c },
 348        { 0x03, 0x00, 0x10, 0x0, 0x3a },
 349        { 0x03, 0x00, 0x0f, 0x0, 0x3d },
 350        { 0x03, 0x00, 0x0f, 0x0, 0x3b },
 351        { 0x03, 0x00, 0x0e, 0x0, 0x3d },
 352        { 0x03, 0x00, 0x0e, 0x0, 0x3c },
 353        { 0x03, 0x00, 0x0e, 0x0, 0x3a },
 354        { 0x03, 0x00, 0x0d, 0x0, 0x3c },
 355        { 0x03, 0x00, 0x0d, 0x0, 0x3b },
 356        { 0x03, 0x00, 0x0c, 0x0, 0x3e },
 357        { 0x03, 0x00, 0x0c, 0x0, 0x3c },
 358        { 0x03, 0x00, 0x0c, 0x0, 0x3a },
 359        { 0x03, 0x00, 0x0b, 0x0, 0x3e },
 360        { 0x03, 0x00, 0x0b, 0x0, 0x3c },
 361        { 0x03, 0x00, 0x0b, 0x0, 0x3b },
 362        { 0x03, 0x00, 0x0b, 0x0, 0x39 },
 363        { 0x03, 0x00, 0x0a, 0x0, 0x3d },
 364        { 0x03, 0x00, 0x0a, 0x0, 0x3b },
 365        { 0x03, 0x00, 0x0a, 0x0, 0x39 },
 366        { 0x03, 0x00, 0x09, 0x0, 0x3e },
 367        { 0x03, 0x00, 0x09, 0x0, 0x3c },
 368        { 0x03, 0x00, 0x09, 0x0, 0x3a },
 369        { 0x03, 0x00, 0x09, 0x0, 0x39 },
 370        { 0x03, 0x00, 0x08, 0x0, 0x3e },
 371        { 0x03, 0x00, 0x08, 0x0, 0x3c },
 372        { 0x03, 0x00, 0x08, 0x0, 0x3a },
 373        { 0x03, 0x00, 0x08, 0x0, 0x39 },
 374        { 0x03, 0x00, 0x08, 0x0, 0x37 },
 375        { 0x03, 0x00, 0x07, 0x0, 0x3d },
 376        { 0x03, 0x00, 0x07, 0x0, 0x3c },
 377        { 0x03, 0x00, 0x07, 0x0, 0x3a },
 378        { 0x03, 0x00, 0x07, 0x0, 0x38 },
 379        { 0x03, 0x00, 0x07, 0x0, 0x37 },
 380        { 0x03, 0x00, 0x06, 0x0, 0x3e },
 381        { 0x03, 0x00, 0x06, 0x0, 0x3c },
 382        { 0x03, 0x00, 0x06, 0x0, 0x3a },
 383        { 0x03, 0x00, 0x06, 0x0, 0x39 },
 384        { 0x03, 0x00, 0x06, 0x0, 0x37 },
 385        { 0x03, 0x00, 0x06, 0x0, 0x36 },
 386        { 0x03, 0x00, 0x06, 0x0, 0x34 },
 387        { 0x03, 0x00, 0x05, 0x0, 0x3d },
 388        { 0x03, 0x00, 0x05, 0x0, 0x3b },
 389        { 0x03, 0x00, 0x05, 0x0, 0x39 },
 390        { 0x03, 0x00, 0x05, 0x0, 0x38 },
 391        { 0x03, 0x00, 0x05, 0x0, 0x36 },
 392        { 0x03, 0x00, 0x05, 0x0, 0x35 },
 393        { 0x03, 0x00, 0x05, 0x0, 0x33 },
 394        { 0x03, 0x00, 0x04, 0x0, 0x3e },
 395        { 0x03, 0x00, 0x04, 0x0, 0x3c },
 396        { 0x03, 0x00, 0x04, 0x0, 0x3a },
 397        { 0x03, 0x00, 0x04, 0x0, 0x39 },
 398        { 0x03, 0x00, 0x04, 0x0, 0x37 },
 399        { 0x03, 0x00, 0x04, 0x0, 0x36 },
 400        { 0x03, 0x00, 0x04, 0x0, 0x34 },
 401        { 0x03, 0x00, 0x04, 0x0, 0x33 },
 402        { 0x03, 0x00, 0x04, 0x0, 0x31 },
 403        { 0x03, 0x00, 0x04, 0x0, 0x30 },
 404        { 0x03, 0x00, 0x04, 0x0, 0x2e },
 405        { 0x03, 0x00, 0x03, 0x0, 0x3c },
 406        { 0x03, 0x00, 0x03, 0x0, 0x3a },
 407        { 0x03, 0x00, 0x03, 0x0, 0x39 },
 408        { 0x03, 0x00, 0x03, 0x0, 0x37 },
 409        { 0x03, 0x00, 0x03, 0x0, 0x36 },
 410        { 0x03, 0x00, 0x03, 0x0, 0x34 },
 411        { 0x03, 0x00, 0x03, 0x0, 0x33 },
 412        { 0x03, 0x00, 0x03, 0x0, 0x31 },
 413        { 0x03, 0x00, 0x03, 0x0, 0x30 },
 414        { 0x03, 0x00, 0x03, 0x0, 0x2e },
 415        { 0x03, 0x00, 0x03, 0x0, 0x2d },
 416        { 0x03, 0x00, 0x03, 0x0, 0x2c },
 417        { 0x03, 0x00, 0x03, 0x0, 0x2b },
 418        { 0x03, 0x00, 0x03, 0x0, 0x29 },
 419        { 0x03, 0x00, 0x02, 0x0, 0x3d },
 420        { 0x03, 0x00, 0x02, 0x0, 0x3b },
 421        { 0x03, 0x00, 0x02, 0x0, 0x39 },
 422        { 0x03, 0x00, 0x02, 0x0, 0x38 },
 423        { 0x03, 0x00, 0x02, 0x0, 0x36 },
 424        { 0x03, 0x00, 0x02, 0x0, 0x35 },
 425        { 0x03, 0x00, 0x02, 0x0, 0x33 },
 426        { 0x03, 0x00, 0x02, 0x0, 0x32 },
 427        { 0x03, 0x00, 0x02, 0x0, 0x30 },
 428        { 0x03, 0x00, 0x02, 0x0, 0x2f },
 429        { 0x03, 0x00, 0x02, 0x0, 0x2e },
 430        { 0x03, 0x00, 0x02, 0x0, 0x2c },
 431        { 0x03, 0x00, 0x02, 0x0, 0x2b },
 432        { 0x03, 0x00, 0x02, 0x0, 0x2a },
 433        { 0x03, 0x00, 0x02, 0x0, 0x29 },
 434        { 0x03, 0x00, 0x02, 0x0, 0x27 },
 435        { 0x03, 0x00, 0x02, 0x0, 0x26 },
 436        { 0x03, 0x00, 0x02, 0x0, 0x25 },
 437        { 0x03, 0x00, 0x02, 0x0, 0x24 },
 438        { 0x03, 0x00, 0x02, 0x0, 0x23 },
 439        { 0x03, 0x00, 0x02, 0x0, 0x22 },
 440        { 0x03, 0x00, 0x02, 0x0, 0x21 },
 441        { 0x03, 0x00, 0x02, 0x0, 0x20 },
 442        { 0x03, 0x00, 0x01, 0x0, 0x3f },
 443        { 0x03, 0x00, 0x01, 0x0, 0x3d },
 444        { 0x03, 0x00, 0x01, 0x0, 0x3b },
 445        { 0x03, 0x00, 0x01, 0x0, 0x39 },
 446};
 447
 448/**************************************************
 449 * SW control.
 450 **************************************************/
 451
 452static const u16 b43_lcntab_sw_ctl_4313_epa_rev0[] = {
 453        0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
 454        0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
 455        0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
 456        0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
 457        0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
 458        0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
 459        0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
 460        0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
 461        0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
 462        0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
 463        0x0002, 0x0008, 0x0004, 0x0001,
 464};
 465
 466/**************************************************
 467 * R/W ops.
 468 **************************************************/
 469
 470u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset)
 471{
 472        u32 type, value;
 473
 474        type = offset & B43_LCNTAB_TYPEMASK;
 475        offset &= ~B43_LCNTAB_TYPEMASK;
 476        B43_WARN_ON(offset > 0xFFFF);
 477
 478        switch (type) {
 479        case B43_LCNTAB_8BIT:
 480                b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
 481                value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO) & 0xFF;
 482                break;
 483        case B43_LCNTAB_16BIT:
 484                b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
 485                value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
 486                break;
 487        case B43_LCNTAB_32BIT:
 488                b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
 489                value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
 490                value |= (b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI) << 16);
 491                break;
 492        default:
 493                B43_WARN_ON(1);
 494                value = 0;
 495        }
 496
 497        return value;
 498}
 499
 500void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset,
 501                          unsigned int nr_elements, void *_data)
 502{
 503        u32 type;
 504        u8 *data = _data;
 505        unsigned int i;
 506
 507        type = offset & B43_LCNTAB_TYPEMASK;
 508        offset &= ~B43_LCNTAB_TYPEMASK;
 509        B43_WARN_ON(offset > 0xFFFF);
 510
 511        b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
 512
 513        for (i = 0; i < nr_elements; i++) {
 514                switch (type) {
 515                case B43_LCNTAB_8BIT:
 516                        *data = b43_phy_read(dev,
 517                                             B43_PHY_LCN_TABLE_DATALO) & 0xFF;
 518                        data++;
 519                        break;
 520                case B43_LCNTAB_16BIT:
 521                        *((u16 *)data) = b43_phy_read(dev,
 522                                                      B43_PHY_LCN_TABLE_DATALO);
 523                        data += 2;
 524                        break;
 525                case B43_LCNTAB_32BIT:
 526                        *((u32 *)data) = b43_phy_read(dev,
 527                                                B43_PHY_LCN_TABLE_DATALO);
 528                        *((u32 *)data) |= (b43_phy_read(dev,
 529                                           B43_PHY_LCN_TABLE_DATAHI) << 16);
 530                        data += 4;
 531                        break;
 532                default:
 533                        B43_WARN_ON(1);
 534                }
 535        }
 536}
 537
 538void b43_lcntab_write(struct b43_wldev *dev, u32 offset, u32 value)
 539{
 540        u32 type;
 541
 542        type = offset & B43_LCNTAB_TYPEMASK;
 543        offset &= 0xFFFF;
 544
 545        switch (type) {
 546        case B43_LCNTAB_8BIT:
 547                B43_WARN_ON(value & ~0xFF);
 548                b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
 549                b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
 550                break;
 551        case B43_LCNTAB_16BIT:
 552                B43_WARN_ON(value & ~0xFFFF);
 553                b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
 554                b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
 555                break;
 556        case B43_LCNTAB_32BIT:
 557                b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
 558                b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, value >> 16);
 559                b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value & 0xFFFF);
 560                break;
 561        default:
 562                B43_WARN_ON(1);
 563        }
 564
 565        return;
 566}
 567
 568void b43_lcntab_write_bulk(struct b43_wldev *dev, u32 offset,
 569                           unsigned int nr_elements, const void *_data)
 570{
 571        u32 type, value;
 572        const u8 *data = _data;
 573        unsigned int i;
 574
 575        type = offset & B43_LCNTAB_TYPEMASK;
 576        offset &= ~B43_LCNTAB_TYPEMASK;
 577        B43_WARN_ON(offset > 0xFFFF);
 578
 579        b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
 580
 581        for (i = 0; i < nr_elements; i++) {
 582                switch (type) {
 583                case B43_LCNTAB_8BIT:
 584                        value = *data;
 585                        data++;
 586                        B43_WARN_ON(value & ~0xFF);
 587                        b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
 588                        break;
 589                case B43_LCNTAB_16BIT:
 590                        value = *((u16 *)data);
 591                        data += 2;
 592                        B43_WARN_ON(value & ~0xFFFF);
 593                        b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
 594                        break;
 595                case B43_LCNTAB_32BIT:
 596                        value = *((u32 *)data);
 597                        data += 4;
 598                        b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI,
 599                                      value >> 16);
 600                        b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO,
 601                                      value & 0xFFFF);
 602                        break;
 603                default:
 604                        B43_WARN_ON(1);
 605                }
 606        }
 607}
 608
 609/**************************************************
 610 * Tables ops.
 611 **************************************************/
 612
 613#define lcntab_upload(dev, offset, data) do { \
 614                b43_lcntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
 615        } while (0)
 616static void b43_phy_lcn_upload_static_tables(struct b43_wldev *dev)
 617{
 618        lcntab_upload(dev, B43_LCNTAB16(0x02, 0), b43_lcntab_0x02);
 619        lcntab_upload(dev, B43_LCNTAB16(0x01, 0), b43_lcntab_0x01);
 620        lcntab_upload(dev, B43_LCNTAB32(0x0b, 0), b43_lcntab_0x0b);
 621        lcntab_upload(dev, B43_LCNTAB32(0x0c, 0), b43_lcntab_0x0c);
 622        lcntab_upload(dev, B43_LCNTAB32(0x0d, 0), b43_lcntab_0x0d);
 623        lcntab_upload(dev, B43_LCNTAB16(0x0e, 0), b43_lcntab_0x0e);
 624        lcntab_upload(dev, B43_LCNTAB16(0x0f, 0), b43_lcntab_0x0f);
 625        lcntab_upload(dev, B43_LCNTAB16(0x10, 0), b43_lcntab_0x10);
 626        lcntab_upload(dev, B43_LCNTAB16(0x11, 0), b43_lcntab_0x11);
 627        lcntab_upload(dev, B43_LCNTAB32(0x12, 0), b43_lcntab_0x12);
 628        lcntab_upload(dev, B43_LCNTAB16(0x14, 0), b43_lcntab_0x14);
 629        lcntab_upload(dev, B43_LCNTAB16(0x17, 0), b43_lcntab_0x17);
 630        lcntab_upload(dev, B43_LCNTAB16(0x00, 0), b43_lcntab_0x00);
 631        lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18);
 632}
 633
 634static void b43_phy_lcn_load_tx_gain_tab(struct b43_wldev *dev,
 635                        const struct b43_lcntab_tx_gain_tbl_entry *gain_table)
 636{
 637        u32 i;
 638        u32 val;
 639
 640        u16 pa_gain = 0x70;
 641        if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM)
 642                pa_gain = 0x10;
 643
 644        for (i = 0; i < B43_LCNTAB_TX_GAIN_SIZE; i++) {
 645                val = ((pa_gain << 24) |
 646                       (gain_table[i].pad << 16) |
 647                       (gain_table[i].pga << 8) |
 648                        gain_table[i].gm);
 649                b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0xc0 + i), val);
 650
 651                /* brcmsmac doesn't maskset, we follow newer wl here */
 652                val = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i));
 653                val &= 0x000fffff;
 654                val |= ((gain_table[i].dac << 28) |
 655                        (gain_table[i].bb_mult << 20));
 656                b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x140 + i), val);
 657        }
 658}
 659
 660/* wlc_lcnphy_load_rfpower */
 661static void b43_phy_lcn_load_rfpower(struct b43_wldev *dev)
 662{
 663        u32 bbmult, rfgain;
 664        u8 i;
 665
 666        for (i = 0; i < 128; i++) {
 667                bbmult = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i));
 668                bbmult >>= 20;
 669                rfgain = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0xc0 + i));
 670
 671                /* TODO: calculate value for 0x240 + i table offset
 672                 * b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), val);
 673                 */
 674        }
 675}
 676
 677/* Not implemented in brcmsmac, noticed in wl in MMIO dump */
 678static void b43_phy_lcn_rewrite_rfpower_table(struct b43_wldev *dev)
 679{
 680        int i;
 681        u32 tmp;
 682        for (i = 0; i < 128; i++) {
 683                tmp = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x240 + i));
 684                b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), tmp);
 685        }
 686}
 687
 688/* wlc_lcnphy_clear_papd_comptable */
 689static void b43_phy_lcn_clean_papd_comp_table(struct b43_wldev *dev)
 690{
 691        u8 i;
 692
 693        for (i = 0; i < 0x80; i++)
 694                b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000);
 695}
 696
 697/* wlc_lcnphy_tbl_init */
 698void b43_phy_lcn_tables_init(struct b43_wldev *dev)
 699{
 700        struct ssb_sprom *sprom = dev->dev->bus_sprom;
 701
 702        b43_phy_lcn_upload_static_tables(dev);
 703
 704        if (b43_current_band(dev->wl) == NL80211_BAND_2GHZ) {
 705                if (sprom->boardflags_lo & B43_BFL_FEM)
 706                        b43_phy_lcn_load_tx_gain_tab(dev,
 707                                b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0);
 708                else
 709                        b43err(dev->wl,
 710                               "TX gain table unknown for this card\n");
 711        }
 712
 713        if (sprom->boardflags_lo & B43_BFL_FEM &&
 714            !(sprom->boardflags_hi & B43_BFH_FEM_BT))
 715                b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0),
 716                        ARRAY_SIZE(b43_lcntab_sw_ctl_4313_epa_rev0),
 717                        b43_lcntab_sw_ctl_4313_epa_rev0);
 718        else
 719                b43err(dev->wl, "SW ctl table is unknown for this card\n");
 720
 721        b43_phy_lcn_load_rfpower(dev);
 722        b43_phy_lcn_rewrite_rfpower_table(dev);
 723        b43_phy_lcn_clean_papd_comp_table(dev);
 724}
 725