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