162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * RTL8XXXU mac80211 USB driver - 8192e specific subdriver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Portions, notably calibration code: 862306a36Sopenharmony_ci * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * This driver was written as a replacement for the vendor provided 1162306a36Sopenharmony_ci * rtl8723au driver. As the Realtek 8xxx chips are very similar in 1262306a36Sopenharmony_ci * their programming interface, I have started adding support for 1362306a36Sopenharmony_ci * additional 8xxx chips like the 8192cu, 8188cus, etc. 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <linux/init.h> 1762306a36Sopenharmony_ci#include <linux/kernel.h> 1862306a36Sopenharmony_ci#include <linux/sched.h> 1962306a36Sopenharmony_ci#include <linux/errno.h> 2062306a36Sopenharmony_ci#include <linux/slab.h> 2162306a36Sopenharmony_ci#include <linux/module.h> 2262306a36Sopenharmony_ci#include <linux/spinlock.h> 2362306a36Sopenharmony_ci#include <linux/list.h> 2462306a36Sopenharmony_ci#include <linux/usb.h> 2562306a36Sopenharmony_ci#include <linux/netdevice.h> 2662306a36Sopenharmony_ci#include <linux/etherdevice.h> 2762306a36Sopenharmony_ci#include <linux/ethtool.h> 2862306a36Sopenharmony_ci#include <linux/wireless.h> 2962306a36Sopenharmony_ci#include <linux/firmware.h> 3062306a36Sopenharmony_ci#include <linux/moduleparam.h> 3162306a36Sopenharmony_ci#include <net/mac80211.h> 3262306a36Sopenharmony_ci#include "rtl8xxxu.h" 3362306a36Sopenharmony_ci#include "rtl8xxxu_regs.h" 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic const struct rtl8xxxu_reg8val rtl8192e_mac_init_table[] = { 3662306a36Sopenharmony_ci {0x011, 0xeb}, {0x012, 0x07}, {0x014, 0x75}, {0x303, 0xa7}, 3762306a36Sopenharmony_ci {0x428, 0x0a}, {0x429, 0x10}, {0x430, 0x00}, {0x431, 0x00}, 3862306a36Sopenharmony_ci {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, {0x435, 0x05}, 3962306a36Sopenharmony_ci {0x436, 0x07}, {0x437, 0x08}, {0x43c, 0x04}, {0x43d, 0x05}, 4062306a36Sopenharmony_ci {0x43e, 0x07}, {0x43f, 0x08}, {0x440, 0x5d}, {0x441, 0x01}, 4162306a36Sopenharmony_ci {0x442, 0x00}, {0x444, 0x10}, {0x445, 0x00}, {0x446, 0x00}, 4262306a36Sopenharmony_ci {0x447, 0x00}, {0x448, 0x00}, {0x449, 0xf0}, {0x44a, 0x0f}, 4362306a36Sopenharmony_ci {0x44b, 0x3e}, {0x44c, 0x10}, {0x44d, 0x00}, {0x44e, 0x00}, 4462306a36Sopenharmony_ci {0x44f, 0x00}, {0x450, 0x00}, {0x451, 0xf0}, {0x452, 0x0f}, 4562306a36Sopenharmony_ci {0x453, 0x00}, {0x456, 0x5e}, {0x460, 0x66}, {0x461, 0x66}, 4662306a36Sopenharmony_ci {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff}, {0x4cd, 0xff}, 4762306a36Sopenharmony_ci {0x4ce, 0x01}, {0x500, 0x26}, {0x501, 0xa2}, {0x502, 0x2f}, 4862306a36Sopenharmony_ci {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3}, {0x506, 0x5e}, 4962306a36Sopenharmony_ci {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4}, {0x50a, 0x5e}, 5062306a36Sopenharmony_ci {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4}, {0x50e, 0x00}, 5162306a36Sopenharmony_ci {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a}, {0x516, 0x0a}, 5262306a36Sopenharmony_ci {0x525, 0x4f}, {0x540, 0x12}, {0x541, 0x64}, {0x550, 0x10}, 5362306a36Sopenharmony_ci {0x551, 0x10}, {0x559, 0x02}, {0x55c, 0x50}, {0x55d, 0xff}, 5462306a36Sopenharmony_ci {0x605, 0x30}, {0x608, 0x0e}, {0x609, 0x2a}, {0x620, 0xff}, 5562306a36Sopenharmony_ci {0x621, 0xff}, {0x622, 0xff}, {0x623, 0xff}, {0x624, 0xff}, 5662306a36Sopenharmony_ci {0x625, 0xff}, {0x626, 0xff}, {0x627, 0xff}, {0x638, 0x50}, 5762306a36Sopenharmony_ci {0x63c, 0x0a}, {0x63d, 0x0a}, {0x63e, 0x0e}, {0x63f, 0x0e}, 5862306a36Sopenharmony_ci {0x640, 0x40}, {0x642, 0x40}, {0x643, 0x00}, {0x652, 0xc8}, 5962306a36Sopenharmony_ci {0x66e, 0x05}, {0x700, 0x21}, {0x701, 0x43}, {0x702, 0x65}, 6062306a36Sopenharmony_ci {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43}, {0x70a, 0x65}, 6162306a36Sopenharmony_ci {0x70b, 0x87}, 6262306a36Sopenharmony_ci {0xffff, 0xff}, 6362306a36Sopenharmony_ci}; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistatic const struct rtl8xxxu_reg32val rtl8192eu_phy_init_table[] = { 6662306a36Sopenharmony_ci {0x800, 0x80040000}, {0x804, 0x00000003}, 6762306a36Sopenharmony_ci {0x808, 0x0000fc00}, {0x80c, 0x0000000a}, 6862306a36Sopenharmony_ci {0x810, 0x10001331}, {0x814, 0x020c3d10}, 6962306a36Sopenharmony_ci {0x818, 0x02220385}, {0x81c, 0x00000000}, 7062306a36Sopenharmony_ci {0x820, 0x01000100}, {0x824, 0x00390204}, 7162306a36Sopenharmony_ci {0x828, 0x01000100}, {0x82c, 0x00390204}, 7262306a36Sopenharmony_ci {0x830, 0x32323232}, {0x834, 0x30303030}, 7362306a36Sopenharmony_ci {0x838, 0x30303030}, {0x83c, 0x30303030}, 7462306a36Sopenharmony_ci {0x840, 0x00010000}, {0x844, 0x00010000}, 7562306a36Sopenharmony_ci {0x848, 0x28282828}, {0x84c, 0x28282828}, 7662306a36Sopenharmony_ci {0x850, 0x00000000}, {0x854, 0x00000000}, 7762306a36Sopenharmony_ci {0x858, 0x009a009a}, {0x85c, 0x01000014}, 7862306a36Sopenharmony_ci {0x860, 0x66f60000}, {0x864, 0x061f0000}, 7962306a36Sopenharmony_ci {0x868, 0x30303030}, {0x86c, 0x30303030}, 8062306a36Sopenharmony_ci {0x870, 0x00000000}, {0x874, 0x55004200}, 8162306a36Sopenharmony_ci {0x878, 0x08080808}, {0x87c, 0x00000000}, 8262306a36Sopenharmony_ci {0x880, 0xb0000c1c}, {0x884, 0x00000001}, 8362306a36Sopenharmony_ci {0x888, 0x00000000}, {0x88c, 0xcc0000c0}, 8462306a36Sopenharmony_ci {0x890, 0x00000800}, {0x894, 0xfffffffe}, 8562306a36Sopenharmony_ci {0x898, 0x40302010}, {0x900, 0x00000000}, 8662306a36Sopenharmony_ci {0x904, 0x00000023}, {0x908, 0x00000000}, 8762306a36Sopenharmony_ci {0x90c, 0x81121313}, {0x910, 0x806c0001}, 8862306a36Sopenharmony_ci {0x914, 0x00000001}, {0x918, 0x00000000}, 8962306a36Sopenharmony_ci {0x91c, 0x00010000}, {0x924, 0x00000001}, 9062306a36Sopenharmony_ci {0x928, 0x00000000}, {0x92c, 0x00000000}, 9162306a36Sopenharmony_ci {0x930, 0x00000000}, {0x934, 0x00000000}, 9262306a36Sopenharmony_ci {0x938, 0x00000000}, {0x93c, 0x00000000}, 9362306a36Sopenharmony_ci {0x940, 0x00000000}, {0x944, 0x00000000}, 9462306a36Sopenharmony_ci {0x94c, 0x00000008}, {0xa00, 0x00d0c7c8}, 9562306a36Sopenharmony_ci {0xa04, 0x81ff000c}, {0xa08, 0x8c838300}, 9662306a36Sopenharmony_ci {0xa0c, 0x2e68120f}, {0xa10, 0x95009b78}, 9762306a36Sopenharmony_ci {0xa14, 0x1114d028}, {0xa18, 0x00881117}, 9862306a36Sopenharmony_ci {0xa1c, 0x89140f00}, {0xa20, 0x1a1b0000}, 9962306a36Sopenharmony_ci {0xa24, 0x090e1317}, {0xa28, 0x00000204}, 10062306a36Sopenharmony_ci {0xa2c, 0x00d30000}, {0xa70, 0x101fff00}, 10162306a36Sopenharmony_ci {0xa74, 0x00000007}, {0xa78, 0x00000900}, 10262306a36Sopenharmony_ci {0xa7c, 0x225b0606}, {0xa80, 0x218075b1}, 10362306a36Sopenharmony_ci {0xb38, 0x00000000}, {0xc00, 0x48071d40}, 10462306a36Sopenharmony_ci {0xc04, 0x03a05633}, {0xc08, 0x000000e4}, 10562306a36Sopenharmony_ci {0xc0c, 0x6c6c6c6c}, {0xc10, 0x08800000}, 10662306a36Sopenharmony_ci {0xc14, 0x40000100}, {0xc18, 0x08800000}, 10762306a36Sopenharmony_ci {0xc1c, 0x40000100}, {0xc20, 0x00000000}, 10862306a36Sopenharmony_ci {0xc24, 0x00000000}, {0xc28, 0x00000000}, 10962306a36Sopenharmony_ci {0xc2c, 0x00000000}, {0xc30, 0x69e9ac47}, 11062306a36Sopenharmony_ci {0xc34, 0x469652af}, {0xc38, 0x49795994}, 11162306a36Sopenharmony_ci {0xc3c, 0x0a97971c}, {0xc40, 0x1f7c403f}, 11262306a36Sopenharmony_ci {0xc44, 0x000100b7}, {0xc48, 0xec020107}, 11362306a36Sopenharmony_ci {0xc4c, 0x007f037f}, 11462306a36Sopenharmony_ci#ifdef EXT_PA_8192EU 11562306a36Sopenharmony_ci /* External PA or external LNA */ 11662306a36Sopenharmony_ci {0xc50, 0x00340220}, 11762306a36Sopenharmony_ci#else 11862306a36Sopenharmony_ci {0xc50, 0x00340020}, 11962306a36Sopenharmony_ci#endif 12062306a36Sopenharmony_ci {0xc54, 0x0080801f}, 12162306a36Sopenharmony_ci#ifdef EXT_PA_8192EU 12262306a36Sopenharmony_ci /* External PA or external LNA */ 12362306a36Sopenharmony_ci {0xc58, 0x00000220}, 12462306a36Sopenharmony_ci#else 12562306a36Sopenharmony_ci {0xc58, 0x00000020}, 12662306a36Sopenharmony_ci#endif 12762306a36Sopenharmony_ci {0xc5c, 0x00248492}, {0xc60, 0x00000000}, 12862306a36Sopenharmony_ci {0xc64, 0x7112848b}, {0xc68, 0x47c00bff}, 12962306a36Sopenharmony_ci {0xc6c, 0x00000036}, {0xc70, 0x00000600}, 13062306a36Sopenharmony_ci {0xc74, 0x02013169}, {0xc78, 0x0000001f}, 13162306a36Sopenharmony_ci {0xc7c, 0x00b91612}, 13262306a36Sopenharmony_ci#ifdef EXT_PA_8192EU 13362306a36Sopenharmony_ci /* External PA or external LNA */ 13462306a36Sopenharmony_ci {0xc80, 0x2d4000b5}, 13562306a36Sopenharmony_ci#else 13662306a36Sopenharmony_ci {0xc80, 0x40000100}, 13762306a36Sopenharmony_ci#endif 13862306a36Sopenharmony_ci {0xc84, 0x21f60000}, 13962306a36Sopenharmony_ci#ifdef EXT_PA_8192EU 14062306a36Sopenharmony_ci /* External PA or external LNA */ 14162306a36Sopenharmony_ci {0xc88, 0x2d4000b5}, 14262306a36Sopenharmony_ci#else 14362306a36Sopenharmony_ci {0xc88, 0x40000100}, 14462306a36Sopenharmony_ci#endif 14562306a36Sopenharmony_ci {0xc8c, 0xa0e40000}, {0xc90, 0x00121820}, 14662306a36Sopenharmony_ci {0xc94, 0x00000000}, {0xc98, 0x00121820}, 14762306a36Sopenharmony_ci {0xc9c, 0x00007f7f}, {0xca0, 0x00000000}, 14862306a36Sopenharmony_ci {0xca4, 0x000300a0}, {0xca8, 0x00000000}, 14962306a36Sopenharmony_ci {0xcac, 0x00000000}, {0xcb0, 0x00000000}, 15062306a36Sopenharmony_ci {0xcb4, 0x00000000}, {0xcb8, 0x00000000}, 15162306a36Sopenharmony_ci {0xcbc, 0x28000000}, {0xcc0, 0x00000000}, 15262306a36Sopenharmony_ci {0xcc4, 0x00000000}, {0xcc8, 0x00000000}, 15362306a36Sopenharmony_ci {0xccc, 0x00000000}, {0xcd0, 0x00000000}, 15462306a36Sopenharmony_ci {0xcd4, 0x00000000}, {0xcd8, 0x64b22427}, 15562306a36Sopenharmony_ci {0xcdc, 0x00766932}, {0xce0, 0x00222222}, 15662306a36Sopenharmony_ci {0xce4, 0x00040000}, {0xce8, 0x77644302}, 15762306a36Sopenharmony_ci {0xcec, 0x2f97d40c}, {0xd00, 0x00080740}, 15862306a36Sopenharmony_ci {0xd04, 0x00020403}, {0xd08, 0x0000907f}, 15962306a36Sopenharmony_ci {0xd0c, 0x20010201}, {0xd10, 0xa0633333}, 16062306a36Sopenharmony_ci {0xd14, 0x3333bc43}, {0xd18, 0x7a8f5b6b}, 16162306a36Sopenharmony_ci {0xd1c, 0x0000007f}, {0xd2c, 0xcc979975}, 16262306a36Sopenharmony_ci {0xd30, 0x00000000}, {0xd34, 0x80608000}, 16362306a36Sopenharmony_ci {0xd38, 0x00000000}, {0xd3c, 0x00127353}, 16462306a36Sopenharmony_ci {0xd40, 0x00000000}, {0xd44, 0x00000000}, 16562306a36Sopenharmony_ci {0xd48, 0x00000000}, {0xd4c, 0x00000000}, 16662306a36Sopenharmony_ci {0xd50, 0x6437140a}, {0xd54, 0x00000000}, 16762306a36Sopenharmony_ci {0xd58, 0x00000282}, {0xd5c, 0x30032064}, 16862306a36Sopenharmony_ci {0xd60, 0x4653de68}, {0xd64, 0x04518a3c}, 16962306a36Sopenharmony_ci {0xd68, 0x00002101}, {0xd6c, 0x2a201c16}, 17062306a36Sopenharmony_ci {0xd70, 0x1812362e}, {0xd74, 0x322c2220}, 17162306a36Sopenharmony_ci {0xd78, 0x000e3c24}, {0xd80, 0x01081008}, 17262306a36Sopenharmony_ci {0xd84, 0x00000800}, {0xd88, 0xf0b50000}, 17362306a36Sopenharmony_ci {0xe00, 0x30303030}, {0xe04, 0x30303030}, 17462306a36Sopenharmony_ci {0xe08, 0x03903030}, {0xe10, 0x30303030}, 17562306a36Sopenharmony_ci {0xe14, 0x30303030}, {0xe18, 0x30303030}, 17662306a36Sopenharmony_ci {0xe1c, 0x30303030}, {0xe28, 0x00000000}, 17762306a36Sopenharmony_ci {0xe30, 0x1000dc1f}, {0xe34, 0x10008c1f}, 17862306a36Sopenharmony_ci {0xe38, 0x02140102}, {0xe3c, 0x681604c2}, 17962306a36Sopenharmony_ci {0xe40, 0x01007c00}, {0xe44, 0x01004800}, 18062306a36Sopenharmony_ci {0xe48, 0xfb000000}, {0xe4c, 0x000028d1}, 18162306a36Sopenharmony_ci {0xe50, 0x1000dc1f}, {0xe54, 0x10008c1f}, 18262306a36Sopenharmony_ci {0xe58, 0x02140102}, {0xe5c, 0x28160d05}, 18362306a36Sopenharmony_ci {0xe60, 0x00000008}, {0xe68, 0x0fc05656}, 18462306a36Sopenharmony_ci {0xe6c, 0x03c09696}, {0xe70, 0x03c09696}, 18562306a36Sopenharmony_ci {0xe74, 0x0c005656}, {0xe78, 0x0c005656}, 18662306a36Sopenharmony_ci {0xe7c, 0x0c005656}, {0xe80, 0x0c005656}, 18762306a36Sopenharmony_ci {0xe84, 0x03c09696}, {0xe88, 0x0c005656}, 18862306a36Sopenharmony_ci {0xe8c, 0x03c09696}, {0xed0, 0x03c09696}, 18962306a36Sopenharmony_ci {0xed4, 0x03c09696}, {0xed8, 0x03c09696}, 19062306a36Sopenharmony_ci {0xedc, 0x0000d6d6}, {0xee0, 0x0000d6d6}, 19162306a36Sopenharmony_ci {0xeec, 0x0fc01616}, {0xee4, 0xb0000c1c}, 19262306a36Sopenharmony_ci {0xee8, 0x00000001}, {0xf14, 0x00000003}, 19362306a36Sopenharmony_ci {0xf4c, 0x00000000}, {0xf00, 0x00000300}, 19462306a36Sopenharmony_ci {0xffff, 0xffffffff}, 19562306a36Sopenharmony_ci}; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic const struct rtl8xxxu_reg32val rtl8xxx_agc_8192eu_std_table[] = { 19862306a36Sopenharmony_ci {0xc78, 0xfb000001}, {0xc78, 0xfb010001}, 19962306a36Sopenharmony_ci {0xc78, 0xfb020001}, {0xc78, 0xfb030001}, 20062306a36Sopenharmony_ci {0xc78, 0xfb040001}, {0xc78, 0xfb050001}, 20162306a36Sopenharmony_ci {0xc78, 0xfa060001}, {0xc78, 0xf9070001}, 20262306a36Sopenharmony_ci {0xc78, 0xf8080001}, {0xc78, 0xf7090001}, 20362306a36Sopenharmony_ci {0xc78, 0xf60a0001}, {0xc78, 0xf50b0001}, 20462306a36Sopenharmony_ci {0xc78, 0xf40c0001}, {0xc78, 0xf30d0001}, 20562306a36Sopenharmony_ci {0xc78, 0xf20e0001}, {0xc78, 0xf10f0001}, 20662306a36Sopenharmony_ci {0xc78, 0xf0100001}, {0xc78, 0xef110001}, 20762306a36Sopenharmony_ci {0xc78, 0xee120001}, {0xc78, 0xed130001}, 20862306a36Sopenharmony_ci {0xc78, 0xec140001}, {0xc78, 0xeb150001}, 20962306a36Sopenharmony_ci {0xc78, 0xea160001}, {0xc78, 0xe9170001}, 21062306a36Sopenharmony_ci {0xc78, 0xe8180001}, {0xc78, 0xe7190001}, 21162306a36Sopenharmony_ci {0xc78, 0xc81a0001}, {0xc78, 0xc71b0001}, 21262306a36Sopenharmony_ci {0xc78, 0xc61c0001}, {0xc78, 0x071d0001}, 21362306a36Sopenharmony_ci {0xc78, 0x061e0001}, {0xc78, 0x051f0001}, 21462306a36Sopenharmony_ci {0xc78, 0x04200001}, {0xc78, 0x03210001}, 21562306a36Sopenharmony_ci {0xc78, 0xaa220001}, {0xc78, 0xa9230001}, 21662306a36Sopenharmony_ci {0xc78, 0xa8240001}, {0xc78, 0xa7250001}, 21762306a36Sopenharmony_ci {0xc78, 0xa6260001}, {0xc78, 0x85270001}, 21862306a36Sopenharmony_ci {0xc78, 0x84280001}, {0xc78, 0x83290001}, 21962306a36Sopenharmony_ci {0xc78, 0x252a0001}, {0xc78, 0x242b0001}, 22062306a36Sopenharmony_ci {0xc78, 0x232c0001}, {0xc78, 0x222d0001}, 22162306a36Sopenharmony_ci {0xc78, 0x672e0001}, {0xc78, 0x662f0001}, 22262306a36Sopenharmony_ci {0xc78, 0x65300001}, {0xc78, 0x64310001}, 22362306a36Sopenharmony_ci {0xc78, 0x63320001}, {0xc78, 0x62330001}, 22462306a36Sopenharmony_ci {0xc78, 0x61340001}, {0xc78, 0x45350001}, 22562306a36Sopenharmony_ci {0xc78, 0x44360001}, {0xc78, 0x43370001}, 22662306a36Sopenharmony_ci {0xc78, 0x42380001}, {0xc78, 0x41390001}, 22762306a36Sopenharmony_ci {0xc78, 0x403a0001}, {0xc78, 0x403b0001}, 22862306a36Sopenharmony_ci {0xc78, 0x403c0001}, {0xc78, 0x403d0001}, 22962306a36Sopenharmony_ci {0xc78, 0x403e0001}, {0xc78, 0x403f0001}, 23062306a36Sopenharmony_ci {0xc78, 0xfb400001}, {0xc78, 0xfb410001}, 23162306a36Sopenharmony_ci {0xc78, 0xfb420001}, {0xc78, 0xfb430001}, 23262306a36Sopenharmony_ci {0xc78, 0xfb440001}, {0xc78, 0xfb450001}, 23362306a36Sopenharmony_ci {0xc78, 0xfa460001}, {0xc78, 0xf9470001}, 23462306a36Sopenharmony_ci {0xc78, 0xf8480001}, {0xc78, 0xf7490001}, 23562306a36Sopenharmony_ci {0xc78, 0xf64a0001}, {0xc78, 0xf54b0001}, 23662306a36Sopenharmony_ci {0xc78, 0xf44c0001}, {0xc78, 0xf34d0001}, 23762306a36Sopenharmony_ci {0xc78, 0xf24e0001}, {0xc78, 0xf14f0001}, 23862306a36Sopenharmony_ci {0xc78, 0xf0500001}, {0xc78, 0xef510001}, 23962306a36Sopenharmony_ci {0xc78, 0xee520001}, {0xc78, 0xed530001}, 24062306a36Sopenharmony_ci {0xc78, 0xec540001}, {0xc78, 0xeb550001}, 24162306a36Sopenharmony_ci {0xc78, 0xea560001}, {0xc78, 0xe9570001}, 24262306a36Sopenharmony_ci {0xc78, 0xe8580001}, {0xc78, 0xe7590001}, 24362306a36Sopenharmony_ci {0xc78, 0xe65a0001}, {0xc78, 0xe55b0001}, 24462306a36Sopenharmony_ci {0xc78, 0xe45c0001}, {0xc78, 0xe35d0001}, 24562306a36Sopenharmony_ci {0xc78, 0xe25e0001}, {0xc78, 0xe15f0001}, 24662306a36Sopenharmony_ci {0xc78, 0x8a600001}, {0xc78, 0x89610001}, 24762306a36Sopenharmony_ci {0xc78, 0x88620001}, {0xc78, 0x87630001}, 24862306a36Sopenharmony_ci {0xc78, 0x86640001}, {0xc78, 0x85650001}, 24962306a36Sopenharmony_ci {0xc78, 0x84660001}, {0xc78, 0x83670001}, 25062306a36Sopenharmony_ci {0xc78, 0x82680001}, {0xc78, 0x6b690001}, 25162306a36Sopenharmony_ci {0xc78, 0x6a6a0001}, {0xc78, 0x696b0001}, 25262306a36Sopenharmony_ci {0xc78, 0x686c0001}, {0xc78, 0x676d0001}, 25362306a36Sopenharmony_ci {0xc78, 0x666e0001}, {0xc78, 0x656f0001}, 25462306a36Sopenharmony_ci {0xc78, 0x64700001}, {0xc78, 0x63710001}, 25562306a36Sopenharmony_ci {0xc78, 0x62720001}, {0xc78, 0x61730001}, 25662306a36Sopenharmony_ci {0xc78, 0x49740001}, {0xc78, 0x48750001}, 25762306a36Sopenharmony_ci {0xc78, 0x47760001}, {0xc78, 0x46770001}, 25862306a36Sopenharmony_ci {0xc78, 0x45780001}, {0xc78, 0x44790001}, 25962306a36Sopenharmony_ci {0xc78, 0x437a0001}, {0xc78, 0x427b0001}, 26062306a36Sopenharmony_ci {0xc78, 0x417c0001}, {0xc78, 0x407d0001}, 26162306a36Sopenharmony_ci {0xc78, 0x407e0001}, {0xc78, 0x407f0001}, 26262306a36Sopenharmony_ci {0xc50, 0x00040022}, {0xc50, 0x00040020}, 26362306a36Sopenharmony_ci {0xffff, 0xffffffff} 26462306a36Sopenharmony_ci}; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistatic const struct rtl8xxxu_reg32val rtl8xxx_agc_8192eu_highpa_table[] = { 26762306a36Sopenharmony_ci {0xc78, 0xfa000001}, {0xc78, 0xf9010001}, 26862306a36Sopenharmony_ci {0xc78, 0xf8020001}, {0xc78, 0xf7030001}, 26962306a36Sopenharmony_ci {0xc78, 0xf6040001}, {0xc78, 0xf5050001}, 27062306a36Sopenharmony_ci {0xc78, 0xf4060001}, {0xc78, 0xf3070001}, 27162306a36Sopenharmony_ci {0xc78, 0xf2080001}, {0xc78, 0xf1090001}, 27262306a36Sopenharmony_ci {0xc78, 0xf00a0001}, {0xc78, 0xef0b0001}, 27362306a36Sopenharmony_ci {0xc78, 0xee0c0001}, {0xc78, 0xed0d0001}, 27462306a36Sopenharmony_ci {0xc78, 0xec0e0001}, {0xc78, 0xeb0f0001}, 27562306a36Sopenharmony_ci {0xc78, 0xea100001}, {0xc78, 0xe9110001}, 27662306a36Sopenharmony_ci {0xc78, 0xe8120001}, {0xc78, 0xe7130001}, 27762306a36Sopenharmony_ci {0xc78, 0xe6140001}, {0xc78, 0xe5150001}, 27862306a36Sopenharmony_ci {0xc78, 0xe4160001}, {0xc78, 0xe3170001}, 27962306a36Sopenharmony_ci {0xc78, 0xe2180001}, {0xc78, 0xe1190001}, 28062306a36Sopenharmony_ci {0xc78, 0x8a1a0001}, {0xc78, 0x891b0001}, 28162306a36Sopenharmony_ci {0xc78, 0x881c0001}, {0xc78, 0x871d0001}, 28262306a36Sopenharmony_ci {0xc78, 0x861e0001}, {0xc78, 0x851f0001}, 28362306a36Sopenharmony_ci {0xc78, 0x84200001}, {0xc78, 0x83210001}, 28462306a36Sopenharmony_ci {0xc78, 0x82220001}, {0xc78, 0x6a230001}, 28562306a36Sopenharmony_ci {0xc78, 0x69240001}, {0xc78, 0x68250001}, 28662306a36Sopenharmony_ci {0xc78, 0x67260001}, {0xc78, 0x66270001}, 28762306a36Sopenharmony_ci {0xc78, 0x65280001}, {0xc78, 0x64290001}, 28862306a36Sopenharmony_ci {0xc78, 0x632a0001}, {0xc78, 0x622b0001}, 28962306a36Sopenharmony_ci {0xc78, 0x612c0001}, {0xc78, 0x602d0001}, 29062306a36Sopenharmony_ci {0xc78, 0x472e0001}, {0xc78, 0x462f0001}, 29162306a36Sopenharmony_ci {0xc78, 0x45300001}, {0xc78, 0x44310001}, 29262306a36Sopenharmony_ci {0xc78, 0x43320001}, {0xc78, 0x42330001}, 29362306a36Sopenharmony_ci {0xc78, 0x41340001}, {0xc78, 0x40350001}, 29462306a36Sopenharmony_ci {0xc78, 0x40360001}, {0xc78, 0x40370001}, 29562306a36Sopenharmony_ci {0xc78, 0x40380001}, {0xc78, 0x40390001}, 29662306a36Sopenharmony_ci {0xc78, 0x403a0001}, {0xc78, 0x403b0001}, 29762306a36Sopenharmony_ci {0xc78, 0x403c0001}, {0xc78, 0x403d0001}, 29862306a36Sopenharmony_ci {0xc78, 0x403e0001}, {0xc78, 0x403f0001}, 29962306a36Sopenharmony_ci {0xc78, 0xfa400001}, {0xc78, 0xf9410001}, 30062306a36Sopenharmony_ci {0xc78, 0xf8420001}, {0xc78, 0xf7430001}, 30162306a36Sopenharmony_ci {0xc78, 0xf6440001}, {0xc78, 0xf5450001}, 30262306a36Sopenharmony_ci {0xc78, 0xf4460001}, {0xc78, 0xf3470001}, 30362306a36Sopenharmony_ci {0xc78, 0xf2480001}, {0xc78, 0xf1490001}, 30462306a36Sopenharmony_ci {0xc78, 0xf04a0001}, {0xc78, 0xef4b0001}, 30562306a36Sopenharmony_ci {0xc78, 0xee4c0001}, {0xc78, 0xed4d0001}, 30662306a36Sopenharmony_ci {0xc78, 0xec4e0001}, {0xc78, 0xeb4f0001}, 30762306a36Sopenharmony_ci {0xc78, 0xea500001}, {0xc78, 0xe9510001}, 30862306a36Sopenharmony_ci {0xc78, 0xe8520001}, {0xc78, 0xe7530001}, 30962306a36Sopenharmony_ci {0xc78, 0xe6540001}, {0xc78, 0xe5550001}, 31062306a36Sopenharmony_ci {0xc78, 0xe4560001}, {0xc78, 0xe3570001}, 31162306a36Sopenharmony_ci {0xc78, 0xe2580001}, {0xc78, 0xe1590001}, 31262306a36Sopenharmony_ci {0xc78, 0x8a5a0001}, {0xc78, 0x895b0001}, 31362306a36Sopenharmony_ci {0xc78, 0x885c0001}, {0xc78, 0x875d0001}, 31462306a36Sopenharmony_ci {0xc78, 0x865e0001}, {0xc78, 0x855f0001}, 31562306a36Sopenharmony_ci {0xc78, 0x84600001}, {0xc78, 0x83610001}, 31662306a36Sopenharmony_ci {0xc78, 0x82620001}, {0xc78, 0x6a630001}, 31762306a36Sopenharmony_ci {0xc78, 0x69640001}, {0xc78, 0x68650001}, 31862306a36Sopenharmony_ci {0xc78, 0x67660001}, {0xc78, 0x66670001}, 31962306a36Sopenharmony_ci {0xc78, 0x65680001}, {0xc78, 0x64690001}, 32062306a36Sopenharmony_ci {0xc78, 0x636a0001}, {0xc78, 0x626b0001}, 32162306a36Sopenharmony_ci {0xc78, 0x616c0001}, {0xc78, 0x606d0001}, 32262306a36Sopenharmony_ci {0xc78, 0x476e0001}, {0xc78, 0x466f0001}, 32362306a36Sopenharmony_ci {0xc78, 0x45700001}, {0xc78, 0x44710001}, 32462306a36Sopenharmony_ci {0xc78, 0x43720001}, {0xc78, 0x42730001}, 32562306a36Sopenharmony_ci {0xc78, 0x41740001}, {0xc78, 0x40750001}, 32662306a36Sopenharmony_ci {0xc78, 0x40760001}, {0xc78, 0x40770001}, 32762306a36Sopenharmony_ci {0xc78, 0x40780001}, {0xc78, 0x40790001}, 32862306a36Sopenharmony_ci {0xc78, 0x407a0001}, {0xc78, 0x407b0001}, 32962306a36Sopenharmony_ci {0xc78, 0x407c0001}, {0xc78, 0x407d0001}, 33062306a36Sopenharmony_ci {0xc78, 0x407e0001}, {0xc78, 0x407f0001}, 33162306a36Sopenharmony_ci {0xc50, 0x00040222}, {0xc50, 0x00040220}, 33262306a36Sopenharmony_ci {0xffff, 0xffffffff} 33362306a36Sopenharmony_ci}; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_cistatic const struct rtl8xxxu_rfregval rtl8192eu_radioa_init_table[] = { 33662306a36Sopenharmony_ci {0x7f, 0x00000082}, {0x81, 0x0003fc00}, 33762306a36Sopenharmony_ci {0x00, 0x00030000}, {0x08, 0x00008400}, 33862306a36Sopenharmony_ci {0x18, 0x00000407}, {0x19, 0x00000012}, 33962306a36Sopenharmony_ci {0x1b, 0x00000064}, {0x1e, 0x00080009}, 34062306a36Sopenharmony_ci {0x1f, 0x00000880}, {0x2f, 0x0001a060}, 34162306a36Sopenharmony_ci {0x3f, 0x00000000}, {0x42, 0x000060c0}, 34262306a36Sopenharmony_ci {0x57, 0x000d0000}, {0x58, 0x000be180}, 34362306a36Sopenharmony_ci {0x67, 0x00001552}, {0x83, 0x00000000}, 34462306a36Sopenharmony_ci {0xb0, 0x000ff9f1}, {0xb1, 0x00055418}, 34562306a36Sopenharmony_ci {0xb2, 0x0008cc00}, {0xb4, 0x00043083}, 34662306a36Sopenharmony_ci {0xb5, 0x00008166}, {0xb6, 0x0000803e}, 34762306a36Sopenharmony_ci {0xb7, 0x0001c69f}, {0xb8, 0x0000407f}, 34862306a36Sopenharmony_ci {0xb9, 0x00080001}, {0xba, 0x00040001}, 34962306a36Sopenharmony_ci {0xbb, 0x00000400}, {0xbf, 0x000c0000}, 35062306a36Sopenharmony_ci {0xc2, 0x00002400}, {0xc3, 0x00000009}, 35162306a36Sopenharmony_ci {0xc4, 0x00040c91}, {0xc5, 0x00099999}, 35262306a36Sopenharmony_ci {0xc6, 0x000000a3}, {0xc7, 0x00088820}, 35362306a36Sopenharmony_ci {0xc8, 0x00076c06}, {0xc9, 0x00000000}, 35462306a36Sopenharmony_ci {0xca, 0x00080000}, {0xdf, 0x00000180}, 35562306a36Sopenharmony_ci {0xef, 0x000001a0}, {0x51, 0x00069545}, 35662306a36Sopenharmony_ci {0x52, 0x0007e45e}, {0x53, 0x00000071}, 35762306a36Sopenharmony_ci {0x56, 0x00051ff3}, {0x35, 0x000000a8}, 35862306a36Sopenharmony_ci {0x35, 0x000001e2}, {0x35, 0x000002a8}, 35962306a36Sopenharmony_ci {0x36, 0x00001c24}, {0x36, 0x00009c24}, 36062306a36Sopenharmony_ci {0x36, 0x00011c24}, {0x36, 0x00019c24}, 36162306a36Sopenharmony_ci {0x18, 0x00000c07}, {0x5a, 0x00048000}, 36262306a36Sopenharmony_ci {0x19, 0x000739d0}, 36362306a36Sopenharmony_ci#ifdef EXT_PA_8192EU 36462306a36Sopenharmony_ci /* External PA or external LNA */ 36562306a36Sopenharmony_ci {0x34, 0x0000a093}, {0x34, 0x0000908f}, 36662306a36Sopenharmony_ci {0x34, 0x0000808c}, {0x34, 0x0000704d}, 36762306a36Sopenharmony_ci {0x34, 0x0000604a}, {0x34, 0x00005047}, 36862306a36Sopenharmony_ci {0x34, 0x0000400a}, {0x34, 0x00003007}, 36962306a36Sopenharmony_ci {0x34, 0x00002004}, {0x34, 0x00001001}, 37062306a36Sopenharmony_ci {0x34, 0x00000000}, 37162306a36Sopenharmony_ci#else 37262306a36Sopenharmony_ci /* Regular */ 37362306a36Sopenharmony_ci {0x34, 0x0000add7}, {0x34, 0x00009dd4}, 37462306a36Sopenharmony_ci {0x34, 0x00008dd1}, {0x34, 0x00007dce}, 37562306a36Sopenharmony_ci {0x34, 0x00006dcb}, {0x34, 0x00005dc8}, 37662306a36Sopenharmony_ci {0x34, 0x00004dc5}, {0x34, 0x000034cc}, 37762306a36Sopenharmony_ci {0x34, 0x0000244f}, {0x34, 0x0000144c}, 37862306a36Sopenharmony_ci {0x34, 0x00000014}, 37962306a36Sopenharmony_ci#endif 38062306a36Sopenharmony_ci {0x00, 0x00030159}, 38162306a36Sopenharmony_ci {0x84, 0x00068180}, 38262306a36Sopenharmony_ci {0x86, 0x0000014e}, 38362306a36Sopenharmony_ci {0x87, 0x00048e00}, 38462306a36Sopenharmony_ci {0x8e, 0x00065540}, 38562306a36Sopenharmony_ci {0x8f, 0x00088000}, 38662306a36Sopenharmony_ci {0xef, 0x000020a0}, 38762306a36Sopenharmony_ci#ifdef EXT_PA_8192EU 38862306a36Sopenharmony_ci /* External PA or external LNA */ 38962306a36Sopenharmony_ci {0x3b, 0x000f07b0}, 39062306a36Sopenharmony_ci#else 39162306a36Sopenharmony_ci {0x3b, 0x000f02b0}, 39262306a36Sopenharmony_ci#endif 39362306a36Sopenharmony_ci {0x3b, 0x000ef7b0}, {0x3b, 0x000d4fb0}, 39462306a36Sopenharmony_ci {0x3b, 0x000cf060}, {0x3b, 0x000b0090}, 39562306a36Sopenharmony_ci {0x3b, 0x000a0080}, {0x3b, 0x00090080}, 39662306a36Sopenharmony_ci {0x3b, 0x0008f780}, 39762306a36Sopenharmony_ci#ifdef EXT_PA_8192EU 39862306a36Sopenharmony_ci /* External PA or external LNA */ 39962306a36Sopenharmony_ci {0x3b, 0x000787b0}, 40062306a36Sopenharmony_ci#else 40162306a36Sopenharmony_ci {0x3b, 0x00078730}, 40262306a36Sopenharmony_ci#endif 40362306a36Sopenharmony_ci {0x3b, 0x00060fb0}, {0x3b, 0x0005ffa0}, 40462306a36Sopenharmony_ci {0x3b, 0x00040620}, {0x3b, 0x00037090}, 40562306a36Sopenharmony_ci {0x3b, 0x00020080}, {0x3b, 0x0001f060}, 40662306a36Sopenharmony_ci {0x3b, 0x0000ffb0}, {0xef, 0x000000a0}, 40762306a36Sopenharmony_ci {0xfe, 0x00000000}, {0x18, 0x0000fc07}, 40862306a36Sopenharmony_ci {0xfe, 0x00000000}, {0xfe, 0x00000000}, 40962306a36Sopenharmony_ci {0xfe, 0x00000000}, {0xfe, 0x00000000}, 41062306a36Sopenharmony_ci {0x1e, 0x00000001}, {0x1f, 0x00080000}, 41162306a36Sopenharmony_ci {0x00, 0x00033e70}, 41262306a36Sopenharmony_ci {0xff, 0xffffffff} 41362306a36Sopenharmony_ci}; 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_cistatic const struct rtl8xxxu_rfregval rtl8192eu_radiob_init_table[] = { 41662306a36Sopenharmony_ci {0x7f, 0x00000082}, {0x81, 0x0003fc00}, 41762306a36Sopenharmony_ci {0x00, 0x00030000}, {0x08, 0x00008400}, 41862306a36Sopenharmony_ci {0x18, 0x00000407}, {0x19, 0x00000012}, 41962306a36Sopenharmony_ci {0x1b, 0x00000064}, {0x1e, 0x00080009}, 42062306a36Sopenharmony_ci {0x1f, 0x00000880}, {0x2f, 0x0001a060}, 42162306a36Sopenharmony_ci {0x3f, 0x00000000}, {0x42, 0x000060c0}, 42262306a36Sopenharmony_ci {0x57, 0x000d0000}, {0x58, 0x000be180}, 42362306a36Sopenharmony_ci {0x67, 0x00001552}, {0x7f, 0x00000082}, 42462306a36Sopenharmony_ci {0x81, 0x0003f000}, {0x83, 0x00000000}, 42562306a36Sopenharmony_ci {0xdf, 0x00000180}, {0xef, 0x000001a0}, 42662306a36Sopenharmony_ci {0x51, 0x00069545}, {0x52, 0x0007e42e}, 42762306a36Sopenharmony_ci {0x53, 0x00000071}, {0x56, 0x00051ff3}, 42862306a36Sopenharmony_ci {0x35, 0x000000a8}, {0x35, 0x000001e0}, 42962306a36Sopenharmony_ci {0x35, 0x000002a8}, {0x36, 0x00001ca8}, 43062306a36Sopenharmony_ci {0x36, 0x00009c24}, {0x36, 0x00011c24}, 43162306a36Sopenharmony_ci {0x36, 0x00019c24}, {0x18, 0x00000c07}, 43262306a36Sopenharmony_ci {0x5a, 0x00048000}, {0x19, 0x000739d0}, 43362306a36Sopenharmony_ci#ifdef EXT_PA_8192EU 43462306a36Sopenharmony_ci /* External PA or external LNA */ 43562306a36Sopenharmony_ci {0x34, 0x0000a093}, {0x34, 0x0000908f}, 43662306a36Sopenharmony_ci {0x34, 0x0000808c}, {0x34, 0x0000704d}, 43762306a36Sopenharmony_ci {0x34, 0x0000604a}, {0x34, 0x00005047}, 43862306a36Sopenharmony_ci {0x34, 0x0000400a}, {0x34, 0x00003007}, 43962306a36Sopenharmony_ci {0x34, 0x00002004}, {0x34, 0x00001001}, 44062306a36Sopenharmony_ci {0x34, 0x00000000}, 44162306a36Sopenharmony_ci#else 44262306a36Sopenharmony_ci {0x34, 0x0000add7}, {0x34, 0x00009dd4}, 44362306a36Sopenharmony_ci {0x34, 0x00008dd1}, {0x34, 0x00007dce}, 44462306a36Sopenharmony_ci {0x34, 0x00006dcb}, {0x34, 0x00005dc8}, 44562306a36Sopenharmony_ci {0x34, 0x00004dc5}, {0x34, 0x000034cc}, 44662306a36Sopenharmony_ci {0x34, 0x0000244f}, {0x34, 0x0000144c}, 44762306a36Sopenharmony_ci {0x34, 0x00000014}, 44862306a36Sopenharmony_ci#endif 44962306a36Sopenharmony_ci {0x00, 0x00030159}, {0x84, 0x00068180}, 45062306a36Sopenharmony_ci {0x86, 0x000000ce}, {0x87, 0x00048a00}, 45162306a36Sopenharmony_ci {0x8e, 0x00065540}, {0x8f, 0x00088000}, 45262306a36Sopenharmony_ci {0xef, 0x000020a0}, 45362306a36Sopenharmony_ci#ifdef EXT_PA_8192EU 45462306a36Sopenharmony_ci /* External PA or external LNA */ 45562306a36Sopenharmony_ci {0x3b, 0x000f07b0}, 45662306a36Sopenharmony_ci#else 45762306a36Sopenharmony_ci {0x3b, 0x000f02b0}, 45862306a36Sopenharmony_ci#endif 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci {0x3b, 0x000ef7b0}, {0x3b, 0x000d4fb0}, 46162306a36Sopenharmony_ci {0x3b, 0x000cf060}, {0x3b, 0x000b0090}, 46262306a36Sopenharmony_ci {0x3b, 0x000a0080}, {0x3b, 0x00090080}, 46362306a36Sopenharmony_ci {0x3b, 0x0008f780}, 46462306a36Sopenharmony_ci#ifdef EXT_PA_8192EU 46562306a36Sopenharmony_ci /* External PA or external LNA */ 46662306a36Sopenharmony_ci {0x3b, 0x000787b0}, 46762306a36Sopenharmony_ci#else 46862306a36Sopenharmony_ci {0x3b, 0x00078730}, 46962306a36Sopenharmony_ci#endif 47062306a36Sopenharmony_ci {0x3b, 0x00060fb0}, {0x3b, 0x0005ffa0}, 47162306a36Sopenharmony_ci {0x3b, 0x00040620}, {0x3b, 0x00037090}, 47262306a36Sopenharmony_ci {0x3b, 0x00020080}, {0x3b, 0x0001f060}, 47362306a36Sopenharmony_ci {0x3b, 0x0000ffb0}, {0xef, 0x000000a0}, 47462306a36Sopenharmony_ci {0x00, 0x00010159}, {0xfe, 0x00000000}, 47562306a36Sopenharmony_ci {0xfe, 0x00000000}, {0xfe, 0x00000000}, 47662306a36Sopenharmony_ci {0xfe, 0x00000000}, {0x1e, 0x00000001}, 47762306a36Sopenharmony_ci {0x1f, 0x00080000}, {0x00, 0x00033e70}, 47862306a36Sopenharmony_ci {0xff, 0xffffffff} 47962306a36Sopenharmony_ci}; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_cistatic int rtl8192eu_identify_chip(struct rtl8xxxu_priv *priv) 48262306a36Sopenharmony_ci{ 48362306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 48462306a36Sopenharmony_ci u32 val32, bonding, sys_cfg, vendor; 48562306a36Sopenharmony_ci int ret = 0; 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG); 48862306a36Sopenharmony_ci priv->chip_cut = u32_get_bits(sys_cfg, SYS_CFG_CHIP_VERSION_MASK); 48962306a36Sopenharmony_ci if (sys_cfg & SYS_CFG_TRP_VAUX_EN) { 49062306a36Sopenharmony_ci dev_info(dev, "Unsupported test chip\n"); 49162306a36Sopenharmony_ci ret = -ENOTSUPP; 49262306a36Sopenharmony_ci goto out; 49362306a36Sopenharmony_ci } 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci bonding = rtl8xxxu_read32(priv, REG_HPON_FSM); 49662306a36Sopenharmony_ci bonding &= HPON_FSM_BONDING_MASK; 49762306a36Sopenharmony_ci if (bonding == HPON_FSM_BONDING_1T2R) { 49862306a36Sopenharmony_ci strscpy(priv->chip_name, "8191EU", sizeof(priv->chip_name)); 49962306a36Sopenharmony_ci priv->tx_paths = 1; 50062306a36Sopenharmony_ci priv->rtl_chip = RTL8191E; 50162306a36Sopenharmony_ci } else { 50262306a36Sopenharmony_ci strscpy(priv->chip_name, "8192EU", sizeof(priv->chip_name)); 50362306a36Sopenharmony_ci priv->tx_paths = 2; 50462306a36Sopenharmony_ci priv->rtl_chip = RTL8192E; 50562306a36Sopenharmony_ci } 50662306a36Sopenharmony_ci priv->rf_paths = 2; 50762306a36Sopenharmony_ci priv->rx_paths = 2; 50862306a36Sopenharmony_ci priv->has_wifi = 1; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci vendor = sys_cfg & SYS_CFG_VENDOR_EXT_MASK; 51162306a36Sopenharmony_ci rtl8xxxu_identify_vendor_2bits(priv, vendor); 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_GPIO_OUTSTS); 51462306a36Sopenharmony_ci priv->rom_rev = u32_get_bits(val32, GPIO_RF_RL_ID); 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ci rtl8xxxu_config_endpoints_sie(priv); 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci /* 51962306a36Sopenharmony_ci * Fallback for devices that do not provide REG_NORMAL_SIE_EP_TX 52062306a36Sopenharmony_ci */ 52162306a36Sopenharmony_ci if (!priv->ep_tx_count) 52262306a36Sopenharmony_ci ret = rtl8xxxu_config_endpoints_no_sie(priv); 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ciout: 52562306a36Sopenharmony_ci return ret; 52662306a36Sopenharmony_ci} 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_cistatic void 52962306a36Sopenharmony_cirtl8192e_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) 53062306a36Sopenharmony_ci{ 53162306a36Sopenharmony_ci u32 val32, ofdm, mcs; 53262306a36Sopenharmony_ci u8 cck, ofdmbase, mcsbase; 53362306a36Sopenharmony_ci int group, tx_idx; 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci tx_idx = 0; 53662306a36Sopenharmony_ci group = rtl8xxxu_gen2_channel_to_group(channel); 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci cck = priv->cck_tx_power_index_A[group]; 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_AGC_A_CCK1_MCS32); 54162306a36Sopenharmony_ci val32 &= 0xffff00ff; 54262306a36Sopenharmony_ci val32 |= (cck << 8); 54362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_CCK1_MCS32, val32); 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11); 54662306a36Sopenharmony_ci val32 &= 0xff; 54762306a36Sopenharmony_ci val32 |= ((cck << 8) | (cck << 16) | (cck << 24)); 54862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32); 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ci ofdmbase = priv->ht40_1s_tx_power_index_A[group]; 55162306a36Sopenharmony_ci ofdmbase += priv->ofdm_tx_power_diff[tx_idx].a; 55262306a36Sopenharmony_ci ofdm = ofdmbase | ofdmbase << 8 | ofdmbase << 16 | ofdmbase << 24; 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE18_06, ofdm); 55562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE54_24, ofdm); 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci mcsbase = priv->ht40_1s_tx_power_index_A[group]; 55862306a36Sopenharmony_ci if (ht40) 55962306a36Sopenharmony_ci mcsbase += priv->ht40_tx_power_diff[tx_idx++].a; 56062306a36Sopenharmony_ci else 56162306a36Sopenharmony_ci mcsbase += priv->ht20_tx_power_diff[tx_idx++].a; 56262306a36Sopenharmony_ci mcs = mcsbase | mcsbase << 8 | mcsbase << 16 | mcsbase << 24; 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS03_MCS00, mcs); 56562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS07_MCS04, mcs); 56662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS11_MCS08, mcs); 56762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS15_MCS12, mcs); 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci if (priv->tx_paths > 1) { 57062306a36Sopenharmony_ci cck = priv->cck_tx_power_index_B[group]; 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK1_55_MCS32); 57362306a36Sopenharmony_ci val32 &= 0xff; 57462306a36Sopenharmony_ci val32 |= ((cck << 8) | (cck << 16) | (cck << 24)); 57562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK1_55_MCS32, val32); 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11); 57862306a36Sopenharmony_ci val32 &= 0xffffff00; 57962306a36Sopenharmony_ci val32 |= cck; 58062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32); 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci ofdmbase = priv->ht40_1s_tx_power_index_B[group]; 58362306a36Sopenharmony_ci ofdmbase += priv->ofdm_tx_power_diff[tx_idx].b; 58462306a36Sopenharmony_ci ofdm = ofdmbase | ofdmbase << 8 | 58562306a36Sopenharmony_ci ofdmbase << 16 | ofdmbase << 24; 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_B_RATE18_06, ofdm); 58862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_B_RATE54_24, ofdm); 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci mcsbase = priv->ht40_1s_tx_power_index_B[group]; 59162306a36Sopenharmony_ci if (ht40) 59262306a36Sopenharmony_ci mcsbase += priv->ht40_tx_power_diff[tx_idx++].b; 59362306a36Sopenharmony_ci else 59462306a36Sopenharmony_ci mcsbase += priv->ht20_tx_power_diff[tx_idx++].b; 59562306a36Sopenharmony_ci mcs = mcsbase | mcsbase << 8 | mcsbase << 16 | mcsbase << 24; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS03_MCS00, mcs); 59862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS07_MCS04, mcs); 59962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS11_MCS08, mcs); 60062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS15_MCS12, mcs); 60162306a36Sopenharmony_ci } 60262306a36Sopenharmony_ci} 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_cistatic int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv) 60562306a36Sopenharmony_ci{ 60662306a36Sopenharmony_ci struct rtl8192eu_efuse *efuse = &priv->efuse_wifi.efuse8192eu; 60762306a36Sopenharmony_ci int i; 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci if (efuse->rtl_id != cpu_to_le16(0x8129)) 61062306a36Sopenharmony_ci return -EINVAL; 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci ether_addr_copy(priv->mac_addr, efuse->mac_addr); 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci memcpy(priv->cck_tx_power_index_A, efuse->tx_power_index_A.cck_base, 61562306a36Sopenharmony_ci sizeof(efuse->tx_power_index_A.cck_base)); 61662306a36Sopenharmony_ci memcpy(priv->cck_tx_power_index_B, efuse->tx_power_index_B.cck_base, 61762306a36Sopenharmony_ci sizeof(efuse->tx_power_index_B.cck_base)); 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci memcpy(priv->ht40_1s_tx_power_index_A, 62062306a36Sopenharmony_ci efuse->tx_power_index_A.ht40_base, 62162306a36Sopenharmony_ci sizeof(efuse->tx_power_index_A.ht40_base)); 62262306a36Sopenharmony_ci memcpy(priv->ht40_1s_tx_power_index_B, 62362306a36Sopenharmony_ci efuse->tx_power_index_B.ht40_base, 62462306a36Sopenharmony_ci sizeof(efuse->tx_power_index_B.ht40_base)); 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci priv->ht20_tx_power_diff[0].a = 62762306a36Sopenharmony_ci efuse->tx_power_index_A.ht20_ofdm_1s_diff.b; 62862306a36Sopenharmony_ci priv->ht20_tx_power_diff[0].b = 62962306a36Sopenharmony_ci efuse->tx_power_index_B.ht20_ofdm_1s_diff.b; 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci priv->ht40_tx_power_diff[0].a = 0; 63262306a36Sopenharmony_ci priv->ht40_tx_power_diff[0].b = 0; 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_ci for (i = 1; i < RTL8723B_TX_COUNT; i++) { 63562306a36Sopenharmony_ci priv->ofdm_tx_power_diff[i].a = 63662306a36Sopenharmony_ci efuse->tx_power_index_A.pwr_diff[i - 1].ofdm; 63762306a36Sopenharmony_ci priv->ofdm_tx_power_diff[i].b = 63862306a36Sopenharmony_ci efuse->tx_power_index_B.pwr_diff[i - 1].ofdm; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci priv->ht20_tx_power_diff[i].a = 64162306a36Sopenharmony_ci efuse->tx_power_index_A.pwr_diff[i - 1].ht20; 64262306a36Sopenharmony_ci priv->ht20_tx_power_diff[i].b = 64362306a36Sopenharmony_ci efuse->tx_power_index_B.pwr_diff[i - 1].ht20; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci priv->ht40_tx_power_diff[i].a = 64662306a36Sopenharmony_ci efuse->tx_power_index_A.pwr_diff[i - 1].ht40; 64762306a36Sopenharmony_ci priv->ht40_tx_power_diff[i].b = 64862306a36Sopenharmony_ci efuse->tx_power_index_B.pwr_diff[i - 1].ht40; 64962306a36Sopenharmony_ci } 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci priv->default_crystal_cap = priv->efuse_wifi.efuse8192eu.xtal_k & 0x3f; 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci return 0; 65462306a36Sopenharmony_ci} 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_cistatic int rtl8192eu_load_firmware(struct rtl8xxxu_priv *priv) 65762306a36Sopenharmony_ci{ 65862306a36Sopenharmony_ci const char *fw_name; 65962306a36Sopenharmony_ci int ret; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci fw_name = "rtlwifi/rtl8192eu_nic.bin"; 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci ret = rtl8xxxu_load_firmware(priv, fw_name); 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci return ret; 66662306a36Sopenharmony_ci} 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_cistatic void rtl8192eu_init_phy_bb(struct rtl8xxxu_priv *priv) 66962306a36Sopenharmony_ci{ 67062306a36Sopenharmony_ci u8 val8; 67162306a36Sopenharmony_ci u16 val16; 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); 67462306a36Sopenharmony_ci val16 |= SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB | SYS_FUNC_DIO_RF; 67562306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci /* 6. 0x1f[7:0] = 0x07 */ 67862306a36Sopenharmony_ci val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB; 67962306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RF_CTRL, val8); 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); 68262306a36Sopenharmony_ci val16 |= (SYS_FUNC_USBA | SYS_FUNC_USBD | SYS_FUNC_DIO_RF | 68362306a36Sopenharmony_ci SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB); 68462306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); 68562306a36Sopenharmony_ci val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB; 68662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RF_CTRL, val8); 68762306a36Sopenharmony_ci rtl8xxxu_init_phy_regs(priv, rtl8192eu_phy_init_table); 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci if (priv->hi_pa) 69062306a36Sopenharmony_ci rtl8xxxu_init_phy_regs(priv, rtl8xxx_agc_8192eu_highpa_table); 69162306a36Sopenharmony_ci else 69262306a36Sopenharmony_ci rtl8xxxu_init_phy_regs(priv, rtl8xxx_agc_8192eu_std_table); 69362306a36Sopenharmony_ci} 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_cistatic int rtl8192eu_init_phy_rf(struct rtl8xxxu_priv *priv) 69662306a36Sopenharmony_ci{ 69762306a36Sopenharmony_ci int ret; 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci ret = rtl8xxxu_init_phy_rf(priv, rtl8192eu_radioa_init_table, RF_A); 70062306a36Sopenharmony_ci if (ret) 70162306a36Sopenharmony_ci goto exit; 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci ret = rtl8xxxu_init_phy_rf(priv, rtl8192eu_radiob_init_table, RF_B); 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ciexit: 70662306a36Sopenharmony_ci return ret; 70762306a36Sopenharmony_ci} 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_cistatic int rtl8192eu_iqk_path_a(struct rtl8xxxu_priv *priv) 71062306a36Sopenharmony_ci{ 71162306a36Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c; 71262306a36Sopenharmony_ci int result = 0; 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci /* 71562306a36Sopenharmony_ci * TX IQK 71662306a36Sopenharmony_ci * PA/PAD controlled by 0x0 71762306a36Sopenharmony_ci */ 71862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 71962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00180); 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); 72262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x20000); 72362306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); 72462306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0x07f77); 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ci /* Path A IQK setting */ 72962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); 73062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); 73162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); 73262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82140303); 73562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x68160000); 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci /* LO calibration setting */ 73862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911); 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 74162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); 74262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ci mdelay(10); 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci /* Check failed */ 74762306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 74862306a36Sopenharmony_ci reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); 74962306a36Sopenharmony_ci reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 75262306a36Sopenharmony_ci ((reg_e94 & 0x03ff0000) != 0x01420000) && 75362306a36Sopenharmony_ci ((reg_e9c & 0x03ff0000) != 0x00420000)) 75462306a36Sopenharmony_ci result |= 0x01; 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci return result; 75762306a36Sopenharmony_ci} 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_cistatic int rtl8192eu_rx_iqk_path_a(struct rtl8xxxu_priv *priv) 76062306a36Sopenharmony_ci{ 76162306a36Sopenharmony_ci u32 reg_ea4, reg_eac, reg_e94, reg_e9c, val32; 76262306a36Sopenharmony_ci int result = 0; 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci /* Leave IQK mode */ 76562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00); 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci /* Enable path A PA in TX IQK mode */ 76862306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); 76962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); 77062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); 77162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173); 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0); 77462306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x30000); 77562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G1, 0x0000f); 77662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0xf1173); 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci /* PA/PAD control by 0x56, and set = 0x0 */ 77962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00980); 78062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x511e0); 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci /* Enter IQK mode */ 78362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci /* TX IQK setting */ 78662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); 78762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci /* path-A IQK setting */ 79062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); 79162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); 79262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); 79362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x8216031f); 79662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x6816031f); 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci /* LO calibration setting */ 79962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 80262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); 80362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 80462306a36Sopenharmony_ci 80562306a36Sopenharmony_ci mdelay(10); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci /* Check failed */ 80862306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 80962306a36Sopenharmony_ci reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); 81062306a36Sopenharmony_ci reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 81362306a36Sopenharmony_ci ((reg_e94 & 0x03ff0000) != 0x01420000) && 81462306a36Sopenharmony_ci ((reg_e9c & 0x03ff0000) != 0x00420000)) { 81562306a36Sopenharmony_ci result |= 0x01; 81662306a36Sopenharmony_ci } else { 81762306a36Sopenharmony_ci /* PA/PAD controlled by 0x0 */ 81862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 81962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180); 82062306a36Sopenharmony_ci goto out; 82162306a36Sopenharmony_ci } 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_ci val32 = 0x80007c00 | 82462306a36Sopenharmony_ci (reg_e94 & 0x03ff0000) | ((reg_e9c >> 16) & 0x03ff); 82562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, val32); 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci /* Modify RX IQK mode table */ 82862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); 83162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); 83262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); 83362306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7ff2); 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0); 83662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x30000); 83762306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G1, 0x0000f); 83862306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0xf7ff2); 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_ci /* PA/PAD control by 0x56, and set = 0x0 */ 84162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00980); 84262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x510e0); 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_ci /* Enter IQK mode */ 84562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci /* IQK setting */ 84862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ci /* Path A IQK setting */ 85162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); 85262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x18008c1c); 85362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); 85462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x821608ff); 85762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x281608ff); 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci /* LO calibration setting */ 86062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a891); 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 86362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); 86462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ci mdelay(10); 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 86962306a36Sopenharmony_ci reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 87262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180); 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci if (!(reg_eac & BIT(27)) && 87562306a36Sopenharmony_ci ((reg_ea4 & 0x03ff0000) != 0x01320000) && 87662306a36Sopenharmony_ci ((reg_eac & 0x03ff0000) != 0x00360000)) 87762306a36Sopenharmony_ci result |= 0x02; 87862306a36Sopenharmony_ci else 87962306a36Sopenharmony_ci dev_warn(&priv->udev->dev, "%s: Path A RX IQK failed!\n", 88062306a36Sopenharmony_ci __func__); 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ciout: 88362306a36Sopenharmony_ci return result; 88462306a36Sopenharmony_ci} 88562306a36Sopenharmony_ci 88662306a36Sopenharmony_cistatic int rtl8192eu_iqk_path_b(struct rtl8xxxu_priv *priv) 88762306a36Sopenharmony_ci{ 88862306a36Sopenharmony_ci u32 reg_eac, reg_eb4, reg_ebc; 88962306a36Sopenharmony_ci int result = 0; 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 89262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x00180); 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0); 89562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x20000); 89662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G1, 0x0000f); 89762306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0x07f77); 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); 90062306a36Sopenharmony_ci 90162306a36Sopenharmony_ci /* Path B IQK setting */ 90262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); 90362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); 90462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x18008c1c); 90562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); 90662306a36Sopenharmony_ci 90762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82140303); 90862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x68160000); 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_ci /* LO calibration setting */ 91162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911); 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 91462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa000000); 91562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_ci mdelay(1); 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_ci /* Check failed */ 92062306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 92162306a36Sopenharmony_ci reg_eb4 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); 92262306a36Sopenharmony_ci reg_ebc = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci if (!(reg_eac & BIT(31)) && 92562306a36Sopenharmony_ci ((reg_eb4 & 0x03ff0000) != 0x01420000) && 92662306a36Sopenharmony_ci ((reg_ebc & 0x03ff0000) != 0x00420000)) 92762306a36Sopenharmony_ci result |= 0x01; 92862306a36Sopenharmony_ci else 92962306a36Sopenharmony_ci dev_warn(&priv->udev->dev, "%s: Path B IQK failed!\n", 93062306a36Sopenharmony_ci __func__); 93162306a36Sopenharmony_ci 93262306a36Sopenharmony_ci return result; 93362306a36Sopenharmony_ci} 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_cistatic int rtl8192eu_rx_iqk_path_b(struct rtl8xxxu_priv *priv) 93662306a36Sopenharmony_ci{ 93762306a36Sopenharmony_ci u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc, val32; 93862306a36Sopenharmony_ci int result = 0; 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_ci /* Leave IQK mode */ 94162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ci /* Enable path A PA in TX IQK mode */ 94462306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0); 94562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x30000); 94662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G1, 0x0000f); 94762306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0xf1173); 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); 95062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); 95162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); 95262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173); 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci /* PA/PAD control by 0x56, and set = 0x0 */ 95562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x00980); 95662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_PAD_TXG, 0x511e0); 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci /* Enter IQK mode */ 95962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci /* TX IQK setting */ 96262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); 96362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ci /* path-A IQK setting */ 96662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); 96762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); 96862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x18008c1c); 96962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x8216031f); 97262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x6816031f); 97362306a36Sopenharmony_ci 97462306a36Sopenharmony_ci /* LO calibration setting */ 97562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); 97662306a36Sopenharmony_ci 97762306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 97862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa000000); 97962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_ci mdelay(10); 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci /* Check failed */ 98462306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 98562306a36Sopenharmony_ci reg_eb4 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); 98662306a36Sopenharmony_ci reg_ebc = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci if (!(reg_eac & BIT(31)) && 98962306a36Sopenharmony_ci ((reg_eb4 & 0x03ff0000) != 0x01420000) && 99062306a36Sopenharmony_ci ((reg_ebc & 0x03ff0000) != 0x00420000)) { 99162306a36Sopenharmony_ci result |= 0x01; 99262306a36Sopenharmony_ci } else { 99362306a36Sopenharmony_ci /* 99462306a36Sopenharmony_ci * PA/PAD controlled by 0x0 99562306a36Sopenharmony_ci * Vendor driver restores RF_A here which I believe is a bug 99662306a36Sopenharmony_ci */ 99762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 99862306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x180); 99962306a36Sopenharmony_ci goto out; 100062306a36Sopenharmony_ci } 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_ci val32 = 0x80007c00 | 100362306a36Sopenharmony_ci (reg_eb4 & 0x03ff0000) | ((reg_ebc >> 16) & 0x03ff); 100462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, val32); 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci /* Modify RX IQK mode table */ 100762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0); 101062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x30000); 101162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G1, 0x0000f); 101262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0xf7ff2); 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0); 101562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); 101662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); 101762306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7ff2); 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci /* PA/PAD control by 0x56, and set = 0x0 */ 102062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x00980); 102162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_PAD_TXG, 0x510e0); 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci /* Enter IQK mode */ 102462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); 102562306a36Sopenharmony_ci 102662306a36Sopenharmony_ci /* IQK setting */ 102762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 102862306a36Sopenharmony_ci 102962306a36Sopenharmony_ci /* Path A IQK setting */ 103062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); 103162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); 103262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); 103362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x18008c1c); 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x821608ff); 103662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x281608ff); 103762306a36Sopenharmony_ci 103862306a36Sopenharmony_ci /* LO calibration setting */ 103962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a891); 104062306a36Sopenharmony_ci 104162306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 104262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa000000); 104362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 104462306a36Sopenharmony_ci 104562306a36Sopenharmony_ci mdelay(10); 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 104862306a36Sopenharmony_ci reg_ec4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_B_2); 104962306a36Sopenharmony_ci reg_ecc = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2); 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 105262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x180); 105362306a36Sopenharmony_ci 105462306a36Sopenharmony_ci if (!(reg_eac & BIT(30)) && 105562306a36Sopenharmony_ci ((reg_ec4 & 0x03ff0000) != 0x01320000) && 105662306a36Sopenharmony_ci ((reg_ecc & 0x03ff0000) != 0x00360000)) 105762306a36Sopenharmony_ci result |= 0x02; 105862306a36Sopenharmony_ci else 105962306a36Sopenharmony_ci dev_warn(&priv->udev->dev, "%s: Path B RX IQK failed!\n", 106062306a36Sopenharmony_ci __func__); 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_ciout: 106362306a36Sopenharmony_ci return result; 106462306a36Sopenharmony_ci} 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_cistatic void rtl8192eu_phy_iqcalibrate(struct rtl8xxxu_priv *priv, 106762306a36Sopenharmony_ci int result[][8], int t) 106862306a36Sopenharmony_ci{ 106962306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 107062306a36Sopenharmony_ci u32 i, val32; 107162306a36Sopenharmony_ci int path_a_ok, path_b_ok; 107262306a36Sopenharmony_ci int retry = 2; 107362306a36Sopenharmony_ci static const u32 adda_regs[RTL8XXXU_ADDA_REGS] = { 107462306a36Sopenharmony_ci REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH, 107562306a36Sopenharmony_ci REG_RX_WAIT_CCA, REG_TX_CCK_RFON, 107662306a36Sopenharmony_ci REG_TX_CCK_BBON, REG_TX_OFDM_RFON, 107762306a36Sopenharmony_ci REG_TX_OFDM_BBON, REG_TX_TO_RX, 107862306a36Sopenharmony_ci REG_TX_TO_TX, REG_RX_CCK, 107962306a36Sopenharmony_ci REG_RX_OFDM, REG_RX_WAIT_RIFS, 108062306a36Sopenharmony_ci REG_RX_TO_RX, REG_STANDBY, 108162306a36Sopenharmony_ci REG_SLEEP, REG_PMPD_ANAEN 108262306a36Sopenharmony_ci }; 108362306a36Sopenharmony_ci static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = { 108462306a36Sopenharmony_ci REG_TXPAUSE, REG_BEACON_CTRL, 108562306a36Sopenharmony_ci REG_BEACON_CTRL_1, REG_GPIO_MUXCFG 108662306a36Sopenharmony_ci }; 108762306a36Sopenharmony_ci static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = { 108862306a36Sopenharmony_ci REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR, 108962306a36Sopenharmony_ci REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B, 109062306a36Sopenharmony_ci REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE, 109162306a36Sopenharmony_ci REG_FPGA0_XB_RF_INT_OE, REG_CCK0_AFE_SETTING 109262306a36Sopenharmony_ci }; 109362306a36Sopenharmony_ci u8 xa_agc = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1) & 0xff; 109462306a36Sopenharmony_ci u8 xb_agc = rtl8xxxu_read32(priv, REG_OFDM0_XB_AGC_CORE1) & 0xff; 109562306a36Sopenharmony_ci 109662306a36Sopenharmony_ci /* 109762306a36Sopenharmony_ci * Note: IQ calibration must be performed after loading 109862306a36Sopenharmony_ci * PHY_REG.txt , and radio_a, radio_b.txt 109962306a36Sopenharmony_ci */ 110062306a36Sopenharmony_ci 110162306a36Sopenharmony_ci if (t == 0) { 110262306a36Sopenharmony_ci /* Save ADDA parameters, turn Path A ADDA on */ 110362306a36Sopenharmony_ci rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup, 110462306a36Sopenharmony_ci RTL8XXXU_ADDA_REGS); 110562306a36Sopenharmony_ci rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup); 110662306a36Sopenharmony_ci rtl8xxxu_save_regs(priv, iqk_bb_regs, 110762306a36Sopenharmony_ci priv->bb_backup, RTL8XXXU_BB_REGS); 110862306a36Sopenharmony_ci } 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_ci rtl8xxxu_path_adda_on(priv, adda_regs, true); 111162306a36Sopenharmony_ci 111262306a36Sopenharmony_ci /* MAC settings */ 111362306a36Sopenharmony_ci rtl8xxxu_mac_calibration(priv, iqk_mac_regs, priv->mac_backup); 111462306a36Sopenharmony_ci 111562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_CCK0_AFE_SETTING); 111662306a36Sopenharmony_ci val32 |= 0x0f000000; 111762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_AFE_SETTING, val32); 111862306a36Sopenharmony_ci 111962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05600); 112062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4); 112162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x22208200); 112262306a36Sopenharmony_ci 112362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_XAB_RF_SW_CTRL); 112462306a36Sopenharmony_ci val32 |= (FPGA0_RF_PAPE | (FPGA0_RF_PAPE << FPGA0_RF_BD_CTRL_SHIFT)); 112562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_XAB_RF_SW_CTRL, val32); 112662306a36Sopenharmony_ci 112762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_RF_INT_OE); 112862306a36Sopenharmony_ci val32 |= BIT(10); 112962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_XA_RF_INT_OE, val32); 113062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_RF_INT_OE); 113162306a36Sopenharmony_ci val32 |= BIT(10); 113262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_XB_RF_INT_OE, val32); 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); 113562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); 113662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_ci for (i = 0; i < retry; i++) { 113962306a36Sopenharmony_ci path_a_ok = rtl8192eu_iqk_path_a(priv); 114062306a36Sopenharmony_ci if (path_a_ok == 0x01) { 114162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 114262306a36Sopenharmony_ci REG_TX_POWER_BEFORE_IQK_A); 114362306a36Sopenharmony_ci result[t][0] = (val32 >> 16) & 0x3ff; 114462306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 114562306a36Sopenharmony_ci REG_TX_POWER_AFTER_IQK_A); 114662306a36Sopenharmony_ci result[t][1] = (val32 >> 16) & 0x3ff; 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_ci break; 114962306a36Sopenharmony_ci } 115062306a36Sopenharmony_ci } 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci if (!path_a_ok) 115362306a36Sopenharmony_ci dev_dbg(dev, "%s: Path A TX IQK failed!\n", __func__); 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_ci for (i = 0; i < retry; i++) { 115662306a36Sopenharmony_ci path_a_ok = rtl8192eu_rx_iqk_path_a(priv); 115762306a36Sopenharmony_ci if (path_a_ok == 0x03) { 115862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 115962306a36Sopenharmony_ci REG_RX_POWER_BEFORE_IQK_A_2); 116062306a36Sopenharmony_ci result[t][2] = (val32 >> 16) & 0x3ff; 116162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 116262306a36Sopenharmony_ci REG_RX_POWER_AFTER_IQK_A_2); 116362306a36Sopenharmony_ci result[t][3] = (val32 >> 16) & 0x3ff; 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_ci break; 116662306a36Sopenharmony_ci } 116762306a36Sopenharmony_ci } 116862306a36Sopenharmony_ci 116962306a36Sopenharmony_ci if (!path_a_ok) 117062306a36Sopenharmony_ci dev_dbg(dev, "%s: Path A RX IQK failed!\n", __func__); 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ci if (priv->rf_paths > 1) { 117362306a36Sopenharmony_ci /* Path A into standby */ 117462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 117562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0x10000); 117662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_ci /* Turn Path B ADDA on */ 117962306a36Sopenharmony_ci rtl8xxxu_path_adda_on(priv, adda_regs, false); 118062306a36Sopenharmony_ci 118162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000); 118262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); 118362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 118462306a36Sopenharmony_ci 118562306a36Sopenharmony_ci for (i = 0; i < retry; i++) { 118662306a36Sopenharmony_ci path_b_ok = rtl8192eu_iqk_path_b(priv); 118762306a36Sopenharmony_ci if (path_b_ok == 0x01) { 118862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); 118962306a36Sopenharmony_ci result[t][4] = (val32 >> 16) & 0x3ff; 119062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); 119162306a36Sopenharmony_ci result[t][5] = (val32 >> 16) & 0x3ff; 119262306a36Sopenharmony_ci break; 119362306a36Sopenharmony_ci } 119462306a36Sopenharmony_ci } 119562306a36Sopenharmony_ci 119662306a36Sopenharmony_ci if (!path_b_ok) 119762306a36Sopenharmony_ci dev_dbg(dev, "%s: Path B IQK failed!\n", __func__); 119862306a36Sopenharmony_ci 119962306a36Sopenharmony_ci for (i = 0; i < retry; i++) { 120062306a36Sopenharmony_ci path_b_ok = rtl8192eu_rx_iqk_path_b(priv); 120162306a36Sopenharmony_ci if (path_b_ok == 0x03) { 120262306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 120362306a36Sopenharmony_ci REG_RX_POWER_BEFORE_IQK_B_2); 120462306a36Sopenharmony_ci result[t][6] = (val32 >> 16) & 0x3ff; 120562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 120662306a36Sopenharmony_ci REG_RX_POWER_AFTER_IQK_B_2); 120762306a36Sopenharmony_ci result[t][7] = (val32 >> 16) & 0x3ff; 120862306a36Sopenharmony_ci break; 120962306a36Sopenharmony_ci } 121062306a36Sopenharmony_ci } 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci if (!path_b_ok) 121362306a36Sopenharmony_ci dev_dbg(dev, "%s: Path B RX IQK failed!\n", __func__); 121462306a36Sopenharmony_ci } 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_ci /* Back to BB mode, load original value */ 121762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000); 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_ci if (t) { 122062306a36Sopenharmony_ci /* Reload ADDA power saving parameters */ 122162306a36Sopenharmony_ci rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup, 122262306a36Sopenharmony_ci RTL8XXXU_ADDA_REGS); 122362306a36Sopenharmony_ci 122462306a36Sopenharmony_ci /* Reload MAC parameters */ 122562306a36Sopenharmony_ci rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup); 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_ci /* Reload BB parameters */ 122862306a36Sopenharmony_ci rtl8xxxu_restore_regs(priv, iqk_bb_regs, 122962306a36Sopenharmony_ci priv->bb_backup, RTL8XXXU_BB_REGS); 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ci /* Restore RX initial gain */ 123262306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); 123362306a36Sopenharmony_ci val32 &= 0xffffff00; 123462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32 | 0x50); 123562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32 | xa_agc); 123662306a36Sopenharmony_ci 123762306a36Sopenharmony_ci if (priv->rf_paths > 1) { 123862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_AGC_CORE1); 123962306a36Sopenharmony_ci val32 &= 0xffffff00; 124062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XB_AGC_CORE1, 124162306a36Sopenharmony_ci val32 | 0x50); 124262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XB_AGC_CORE1, 124362306a36Sopenharmony_ci val32 | xb_agc); 124462306a36Sopenharmony_ci } 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_ci /* Load 0xe30 IQC default value */ 124762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00); 124862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00); 124962306a36Sopenharmony_ci } 125062306a36Sopenharmony_ci} 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_cistatic void rtl8192eu_phy_iq_calibrate(struct rtl8xxxu_priv *priv) 125362306a36Sopenharmony_ci{ 125462306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 125562306a36Sopenharmony_ci int result[4][8]; /* last is final result */ 125662306a36Sopenharmony_ci int i, candidate; 125762306a36Sopenharmony_ci bool path_a_ok, path_b_ok; 125862306a36Sopenharmony_ci u32 reg_e94, reg_e9c, reg_ea4, reg_eac; 125962306a36Sopenharmony_ci u32 reg_eb4, reg_ebc, reg_ec4, reg_ecc; 126062306a36Sopenharmony_ci bool simu; 126162306a36Sopenharmony_ci 126262306a36Sopenharmony_ci memset(result, 0, sizeof(result)); 126362306a36Sopenharmony_ci candidate = -1; 126462306a36Sopenharmony_ci 126562306a36Sopenharmony_ci path_a_ok = false; 126662306a36Sopenharmony_ci path_b_ok = false; 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 126962306a36Sopenharmony_ci rtl8192eu_phy_iqcalibrate(priv, result, i); 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_ci if (i == 1) { 127262306a36Sopenharmony_ci simu = rtl8xxxu_gen2_simularity_compare(priv, 127362306a36Sopenharmony_ci result, 0, 1); 127462306a36Sopenharmony_ci if (simu) { 127562306a36Sopenharmony_ci candidate = 0; 127662306a36Sopenharmony_ci break; 127762306a36Sopenharmony_ci } 127862306a36Sopenharmony_ci } 127962306a36Sopenharmony_ci 128062306a36Sopenharmony_ci if (i == 2) { 128162306a36Sopenharmony_ci simu = rtl8xxxu_gen2_simularity_compare(priv, 128262306a36Sopenharmony_ci result, 0, 2); 128362306a36Sopenharmony_ci if (simu) { 128462306a36Sopenharmony_ci candidate = 0; 128562306a36Sopenharmony_ci break; 128662306a36Sopenharmony_ci } 128762306a36Sopenharmony_ci 128862306a36Sopenharmony_ci simu = rtl8xxxu_gen2_simularity_compare(priv, 128962306a36Sopenharmony_ci result, 1, 2); 129062306a36Sopenharmony_ci if (simu) 129162306a36Sopenharmony_ci candidate = 1; 129262306a36Sopenharmony_ci else 129362306a36Sopenharmony_ci candidate = 3; 129462306a36Sopenharmony_ci } 129562306a36Sopenharmony_ci } 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_ci for (i = 0; i < 4; i++) { 129862306a36Sopenharmony_ci reg_e94 = result[i][0]; 129962306a36Sopenharmony_ci reg_e9c = result[i][1]; 130062306a36Sopenharmony_ci reg_ea4 = result[i][2]; 130162306a36Sopenharmony_ci reg_eb4 = result[i][4]; 130262306a36Sopenharmony_ci reg_ebc = result[i][5]; 130362306a36Sopenharmony_ci reg_ec4 = result[i][6]; 130462306a36Sopenharmony_ci } 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci if (candidate >= 0) { 130762306a36Sopenharmony_ci reg_e94 = result[candidate][0]; 130862306a36Sopenharmony_ci priv->rege94 = reg_e94; 130962306a36Sopenharmony_ci reg_e9c = result[candidate][1]; 131062306a36Sopenharmony_ci priv->rege9c = reg_e9c; 131162306a36Sopenharmony_ci reg_ea4 = result[candidate][2]; 131262306a36Sopenharmony_ci reg_eac = result[candidate][3]; 131362306a36Sopenharmony_ci reg_eb4 = result[candidate][4]; 131462306a36Sopenharmony_ci priv->regeb4 = reg_eb4; 131562306a36Sopenharmony_ci reg_ebc = result[candidate][5]; 131662306a36Sopenharmony_ci priv->regebc = reg_ebc; 131762306a36Sopenharmony_ci reg_ec4 = result[candidate][6]; 131862306a36Sopenharmony_ci reg_ecc = result[candidate][7]; 131962306a36Sopenharmony_ci dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate); 132062306a36Sopenharmony_ci dev_dbg(dev, 132162306a36Sopenharmony_ci "%s: e94 =%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x ecc=%x\n", 132262306a36Sopenharmony_ci __func__, reg_e94, reg_e9c, 132362306a36Sopenharmony_ci reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc); 132462306a36Sopenharmony_ci path_a_ok = true; 132562306a36Sopenharmony_ci path_b_ok = true; 132662306a36Sopenharmony_ci } else { 132762306a36Sopenharmony_ci reg_e94 = reg_eb4 = priv->rege94 = priv->regeb4 = 0x100; 132862306a36Sopenharmony_ci reg_e9c = reg_ebc = priv->rege9c = priv->regebc = 0x0; 132962306a36Sopenharmony_ci } 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_ci if (reg_e94 && candidate >= 0) 133262306a36Sopenharmony_ci rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result, 133362306a36Sopenharmony_ci candidate, (reg_ea4 == 0)); 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci if (priv->rf_paths > 1) 133662306a36Sopenharmony_ci rtl8xxxu_fill_iqk_matrix_b(priv, path_b_ok, result, 133762306a36Sopenharmony_ci candidate, (reg_ec4 == 0)); 133862306a36Sopenharmony_ci 133962306a36Sopenharmony_ci rtl8xxxu_save_regs(priv, rtl8xxxu_iqk_phy_iq_bb_reg, 134062306a36Sopenharmony_ci priv->bb_recovery_backup, RTL8XXXU_BB_REGS); 134162306a36Sopenharmony_ci} 134262306a36Sopenharmony_ci 134362306a36Sopenharmony_ci/* 134462306a36Sopenharmony_ci * This is needed for 8723bu as well, presumable 134562306a36Sopenharmony_ci */ 134662306a36Sopenharmony_cistatic void rtl8192e_crystal_afe_adjust(struct rtl8xxxu_priv *priv) 134762306a36Sopenharmony_ci{ 134862306a36Sopenharmony_ci u8 val8; 134962306a36Sopenharmony_ci u32 val32; 135062306a36Sopenharmony_ci 135162306a36Sopenharmony_ci /* 135262306a36Sopenharmony_ci * 40Mhz crystal source, MAC 0x28[2]=0 135362306a36Sopenharmony_ci */ 135462306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_AFE_PLL_CTRL); 135562306a36Sopenharmony_ci val8 &= 0xfb; 135662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_AFE_PLL_CTRL, val8); 135762306a36Sopenharmony_ci 135862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_AFE_CTRL4); 135962306a36Sopenharmony_ci val32 &= 0xfffffc7f; 136062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_AFE_CTRL4, val32); 136162306a36Sopenharmony_ci 136262306a36Sopenharmony_ci /* 136362306a36Sopenharmony_ci * 92e AFE parameter 136462306a36Sopenharmony_ci * AFE PLL KVCO selection, MAC 0x28[6]=1 136562306a36Sopenharmony_ci */ 136662306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_AFE_PLL_CTRL); 136762306a36Sopenharmony_ci val8 &= 0xbf; 136862306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_AFE_PLL_CTRL, val8); 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci /* 137162306a36Sopenharmony_ci * AFE PLL KVCO selection, MAC 0x78[21]=0 137262306a36Sopenharmony_ci */ 137362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_AFE_CTRL4); 137462306a36Sopenharmony_ci val32 &= 0xffdfffff; 137562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_AFE_CTRL4, val32); 137662306a36Sopenharmony_ci} 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_cistatic void rtl8192e_disabled_to_emu(struct rtl8xxxu_priv *priv) 137962306a36Sopenharmony_ci{ 138062306a36Sopenharmony_ci u8 val8; 138162306a36Sopenharmony_ci 138262306a36Sopenharmony_ci /* Clear suspend enable and power down enable*/ 138362306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 138462306a36Sopenharmony_ci val8 &= ~(BIT(3) | BIT(4)); 138562306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 138662306a36Sopenharmony_ci} 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_cistatic int rtl8192e_emu_to_active(struct rtl8xxxu_priv *priv) 138962306a36Sopenharmony_ci{ 139062306a36Sopenharmony_ci u8 val8; 139162306a36Sopenharmony_ci u32 val32; 139262306a36Sopenharmony_ci int count, ret = 0; 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_ci /* disable HWPDN 0x04[15]=0*/ 139562306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 139662306a36Sopenharmony_ci val8 &= ~BIT(7); 139762306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 139862306a36Sopenharmony_ci 139962306a36Sopenharmony_ci /* disable SW LPS 0x04[10]= 0 */ 140062306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 140162306a36Sopenharmony_ci val8 &= ~BIT(2); 140262306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 140362306a36Sopenharmony_ci 140462306a36Sopenharmony_ci /* disable WL suspend*/ 140562306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 140662306a36Sopenharmony_ci val8 &= ~(BIT(3) | BIT(4)); 140762306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 140862306a36Sopenharmony_ci 140962306a36Sopenharmony_ci /* wait till 0x04[17] = 1 power ready*/ 141062306a36Sopenharmony_ci for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { 141162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); 141262306a36Sopenharmony_ci if (val32 & BIT(17)) 141362306a36Sopenharmony_ci break; 141462306a36Sopenharmony_ci 141562306a36Sopenharmony_ci udelay(10); 141662306a36Sopenharmony_ci } 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ci if (!count) { 141962306a36Sopenharmony_ci ret = -EBUSY; 142062306a36Sopenharmony_ci goto exit; 142162306a36Sopenharmony_ci } 142262306a36Sopenharmony_ci 142362306a36Sopenharmony_ci /* We should be able to optimize the following three entries into one */ 142462306a36Sopenharmony_ci 142562306a36Sopenharmony_ci /* release WLON reset 0x04[16]= 1*/ 142662306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 2); 142762306a36Sopenharmony_ci val8 |= BIT(0); 142862306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_APS_FSMCO + 2, val8); 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci /* set, then poll until 0 */ 143162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); 143262306a36Sopenharmony_ci val32 |= APS_FSMCO_MAC_ENABLE; 143362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); 143462306a36Sopenharmony_ci 143562306a36Sopenharmony_ci for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { 143662306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); 143762306a36Sopenharmony_ci if ((val32 & APS_FSMCO_MAC_ENABLE) == 0) { 143862306a36Sopenharmony_ci ret = 0; 143962306a36Sopenharmony_ci break; 144062306a36Sopenharmony_ci } 144162306a36Sopenharmony_ci udelay(10); 144262306a36Sopenharmony_ci } 144362306a36Sopenharmony_ci 144462306a36Sopenharmony_ci if (!count) { 144562306a36Sopenharmony_ci ret = -EBUSY; 144662306a36Sopenharmony_ci goto exit; 144762306a36Sopenharmony_ci } 144862306a36Sopenharmony_ci 144962306a36Sopenharmony_ciexit: 145062306a36Sopenharmony_ci return ret; 145162306a36Sopenharmony_ci} 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_cistatic int rtl8192eu_active_to_lps(struct rtl8xxxu_priv *priv) 145462306a36Sopenharmony_ci{ 145562306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 145662306a36Sopenharmony_ci u8 val8; 145762306a36Sopenharmony_ci u16 val16; 145862306a36Sopenharmony_ci u32 val32; 145962306a36Sopenharmony_ci int retry, retval; 146062306a36Sopenharmony_ci 146162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); 146262306a36Sopenharmony_ci 146362306a36Sopenharmony_ci retry = 100; 146462306a36Sopenharmony_ci retval = -EBUSY; 146562306a36Sopenharmony_ci /* 146662306a36Sopenharmony_ci * Poll 32 bit wide 0x05f8 for 0x00000000 to ensure no TX is pending. 146762306a36Sopenharmony_ci */ 146862306a36Sopenharmony_ci do { 146962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_SCH_TX_CMD); 147062306a36Sopenharmony_ci if (!val32) { 147162306a36Sopenharmony_ci retval = 0; 147262306a36Sopenharmony_ci break; 147362306a36Sopenharmony_ci } 147462306a36Sopenharmony_ci } while (retry--); 147562306a36Sopenharmony_ci 147662306a36Sopenharmony_ci if (!retry) { 147762306a36Sopenharmony_ci dev_warn(dev, "Failed to flush TX queue\n"); 147862306a36Sopenharmony_ci retval = -EBUSY; 147962306a36Sopenharmony_ci goto out; 148062306a36Sopenharmony_ci } 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci /* Disable CCK and OFDM, clock gated */ 148362306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); 148462306a36Sopenharmony_ci val8 &= ~SYS_FUNC_BBRSTB; 148562306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); 148662306a36Sopenharmony_ci 148762306a36Sopenharmony_ci udelay(2); 148862306a36Sopenharmony_ci 148962306a36Sopenharmony_ci /* Reset whole BB */ 149062306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); 149162306a36Sopenharmony_ci val8 &= ~SYS_FUNC_BB_GLB_RSTN; 149262306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_ci /* Reset MAC TRX */ 149562306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_CR); 149662306a36Sopenharmony_ci val16 &= 0xff00; 149762306a36Sopenharmony_ci val16 |= (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE); 149862306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_CR, val16); 149962306a36Sopenharmony_ci 150062306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_CR); 150162306a36Sopenharmony_ci val16 &= ~CR_SECURITY_ENABLE; 150262306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_CR, val16); 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_DUAL_TSF_RST); 150562306a36Sopenharmony_ci val8 |= DUAL_TSF_TX_OK; 150662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, val8); 150762306a36Sopenharmony_ci 150862306a36Sopenharmony_ciout: 150962306a36Sopenharmony_ci return retval; 151062306a36Sopenharmony_ci} 151162306a36Sopenharmony_ci 151262306a36Sopenharmony_cistatic int rtl8192eu_active_to_emu(struct rtl8xxxu_priv *priv) 151362306a36Sopenharmony_ci{ 151462306a36Sopenharmony_ci u8 val8; 151562306a36Sopenharmony_ci int count, ret = 0; 151662306a36Sopenharmony_ci 151762306a36Sopenharmony_ci /* Turn off RF */ 151862306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_RF_CTRL); 151962306a36Sopenharmony_ci val8 &= ~RF_ENABLE; 152062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RF_CTRL, val8); 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci /* Switch DPDT_SEL_P output from register 0x65[2] */ 152362306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_LEDCFG2); 152462306a36Sopenharmony_ci val8 &= ~LEDCFG2_DPDT_SELECT; 152562306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_LEDCFG2, val8); 152662306a36Sopenharmony_ci 152762306a36Sopenharmony_ci /* 0x0005[1] = 1 turn off MAC by HW state machine*/ 152862306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 152962306a36Sopenharmony_ci val8 |= BIT(1); 153062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_ci for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { 153362306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 153462306a36Sopenharmony_ci if ((val8 & BIT(1)) == 0) 153562306a36Sopenharmony_ci break; 153662306a36Sopenharmony_ci udelay(10); 153762306a36Sopenharmony_ci } 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_ci if (!count) { 154062306a36Sopenharmony_ci dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n", 154162306a36Sopenharmony_ci __func__); 154262306a36Sopenharmony_ci ret = -EBUSY; 154362306a36Sopenharmony_ci goto exit; 154462306a36Sopenharmony_ci } 154562306a36Sopenharmony_ci 154662306a36Sopenharmony_ciexit: 154762306a36Sopenharmony_ci return ret; 154862306a36Sopenharmony_ci} 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_cistatic int rtl8192eu_emu_to_disabled(struct rtl8xxxu_priv *priv) 155162306a36Sopenharmony_ci{ 155262306a36Sopenharmony_ci u8 val8; 155362306a36Sopenharmony_ci 155462306a36Sopenharmony_ci /* 0x04[12:11] = 01 enable WL suspend */ 155562306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 155662306a36Sopenharmony_ci val8 &= ~(BIT(3) | BIT(4)); 155762306a36Sopenharmony_ci val8 |= BIT(3); 155862306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 155962306a36Sopenharmony_ci 156062306a36Sopenharmony_ci return 0; 156162306a36Sopenharmony_ci} 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_cistatic int rtl8192eu_power_on(struct rtl8xxxu_priv *priv) 156462306a36Sopenharmony_ci{ 156562306a36Sopenharmony_ci u16 val16; 156662306a36Sopenharmony_ci u32 val32; 156762306a36Sopenharmony_ci int ret; 156862306a36Sopenharmony_ci 156962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_SYS_CFG); 157062306a36Sopenharmony_ci if (val32 & SYS_CFG_SPS_LDO_SEL) { 157162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_LDO_SW_CTRL, 0xc3); 157262306a36Sopenharmony_ci } else { 157362306a36Sopenharmony_ci /* 157462306a36Sopenharmony_ci * Raise 1.2V voltage 157562306a36Sopenharmony_ci */ 157662306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_8192E_LDOV12_CTRL); 157762306a36Sopenharmony_ci val32 &= 0xff0fffff; 157862306a36Sopenharmony_ci val32 |= 0x00500000; 157962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_8192E_LDOV12_CTRL, val32); 158062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_LDO_SW_CTRL, 0x83); 158162306a36Sopenharmony_ci } 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_ci /* 158462306a36Sopenharmony_ci * Adjust AFE before enabling PLL 158562306a36Sopenharmony_ci */ 158662306a36Sopenharmony_ci rtl8192e_crystal_afe_adjust(priv); 158762306a36Sopenharmony_ci rtl8192e_disabled_to_emu(priv); 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_ci ret = rtl8192e_emu_to_active(priv); 159062306a36Sopenharmony_ci if (ret) 159162306a36Sopenharmony_ci goto exit; 159262306a36Sopenharmony_ci 159362306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_CR, 0x0000); 159462306a36Sopenharmony_ci 159562306a36Sopenharmony_ci /* 159662306a36Sopenharmony_ci * Enable MAC DMA/WMAC/SCHEDULE/SEC block 159762306a36Sopenharmony_ci * Set CR bit10 to enable 32k calibration. 159862306a36Sopenharmony_ci */ 159962306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_CR); 160062306a36Sopenharmony_ci val16 |= (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | 160162306a36Sopenharmony_ci CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | 160262306a36Sopenharmony_ci CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE | 160362306a36Sopenharmony_ci CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE | 160462306a36Sopenharmony_ci CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE); 160562306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_CR, val16); 160662306a36Sopenharmony_ci 160762306a36Sopenharmony_ciexit: 160862306a36Sopenharmony_ci return ret; 160962306a36Sopenharmony_ci} 161062306a36Sopenharmony_ci 161162306a36Sopenharmony_cistatic void rtl8192eu_power_off(struct rtl8xxxu_priv *priv) 161262306a36Sopenharmony_ci{ 161362306a36Sopenharmony_ci u8 val8; 161462306a36Sopenharmony_ci u16 val16; 161562306a36Sopenharmony_ci 161662306a36Sopenharmony_ci rtl8xxxu_flush_fifo(priv); 161762306a36Sopenharmony_ci 161862306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_TX_REPORT_CTRL); 161962306a36Sopenharmony_ci val8 &= ~TX_REPORT_CTRL_TIMER_ENABLE; 162062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL, val8); 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci /* Turn off RF */ 162362306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00); 162462306a36Sopenharmony_ci 162562306a36Sopenharmony_ci rtl8192eu_active_to_lps(priv); 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci /* Reset Firmware if running in RAM */ 162862306a36Sopenharmony_ci if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL) 162962306a36Sopenharmony_ci rtl8xxxu_firmware_self_reset(priv); 163062306a36Sopenharmony_ci 163162306a36Sopenharmony_ci /* Reset MCU */ 163262306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); 163362306a36Sopenharmony_ci val16 &= ~SYS_FUNC_CPU_ENABLE; 163462306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); 163562306a36Sopenharmony_ci 163662306a36Sopenharmony_ci /* Reset MCU ready status */ 163762306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); 163862306a36Sopenharmony_ci 163962306a36Sopenharmony_ci rtl8xxxu_reset_8051(priv); 164062306a36Sopenharmony_ci 164162306a36Sopenharmony_ci rtl8192eu_active_to_emu(priv); 164262306a36Sopenharmony_ci rtl8192eu_emu_to_disabled(priv); 164362306a36Sopenharmony_ci} 164462306a36Sopenharmony_ci 164562306a36Sopenharmony_cistatic void rtl8192e_enable_rf(struct rtl8xxxu_priv *priv) 164662306a36Sopenharmony_ci{ 164762306a36Sopenharmony_ci u32 val32; 164862306a36Sopenharmony_ci u8 val8; 164962306a36Sopenharmony_ci 165062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_RX_WAIT_CCA); 165162306a36Sopenharmony_ci val32 |= (BIT(22) | BIT(23)); 165262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, val32); 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_GPIO_MUXCFG); 165562306a36Sopenharmony_ci val8 |= BIT(5); 165662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_GPIO_MUXCFG, val8); 165762306a36Sopenharmony_ci 165862306a36Sopenharmony_ci /* 165962306a36Sopenharmony_ci * WLAN action by PTA 166062306a36Sopenharmony_ci */ 166162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x04); 166262306a36Sopenharmony_ci 166362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_PWR_DATA); 166462306a36Sopenharmony_ci val32 |= PWR_DATA_EEPRPAD_RFE_CTRL_EN; 166562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_PWR_DATA, val32); 166662306a36Sopenharmony_ci 166762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_RFE_BUFFER); 166862306a36Sopenharmony_ci val32 |= (BIT(0) | BIT(1)); 166962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RFE_BUFFER, val32); 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RFE_CTRL_ANTA_SRC, 0x77); 167262306a36Sopenharmony_ci 167362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_LEDCFG0); 167462306a36Sopenharmony_ci val32 &= ~BIT(24); 167562306a36Sopenharmony_ci val32 |= BIT(23); 167662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_LEDCFG0, val32); 167762306a36Sopenharmony_ci 167862306a36Sopenharmony_ci /* 167962306a36Sopenharmony_ci * Fix external switch Main->S1, Aux->S0 168062306a36Sopenharmony_ci */ 168162306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_PAD_CTRL1); 168262306a36Sopenharmony_ci val8 &= ~BIT(0); 168362306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8); 168462306a36Sopenharmony_ci 168562306a36Sopenharmony_ci /* 168662306a36Sopenharmony_ci * Fix transmission failure of rtl8192e. 168762306a36Sopenharmony_ci */ 168862306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); 168962306a36Sopenharmony_ci} 169062306a36Sopenharmony_ci 169162306a36Sopenharmony_cistatic s8 rtl8192e_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats) 169262306a36Sopenharmony_ci{ 169362306a36Sopenharmony_ci static const s8 lna_gain_table_0[8] = {15, 9, -10, -21, -23, -27, -43, -44}; 169462306a36Sopenharmony_ci static const s8 lna_gain_table_1[8] = {24, 18, 13, -4, -11, -18, -31, -36}; 169562306a36Sopenharmony_ci 169662306a36Sopenharmony_ci u8 cck_agc_rpt = phy_stats->cck_agc_rpt_ofdm_cfosho_a; 169762306a36Sopenharmony_ci s8 rx_pwr_all = 0x00; 169862306a36Sopenharmony_ci u8 vga_idx, lna_idx; 169962306a36Sopenharmony_ci s8 lna_gain = 0; 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ci lna_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_LNA_IDX_MASK); 170262306a36Sopenharmony_ci vga_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_VGA_IDX_MASK); 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_ci if (priv->cck_agc_report_type == 0) 170562306a36Sopenharmony_ci lna_gain = lna_gain_table_0[lna_idx]; 170662306a36Sopenharmony_ci else 170762306a36Sopenharmony_ci lna_gain = lna_gain_table_1[lna_idx]; 170862306a36Sopenharmony_ci 170962306a36Sopenharmony_ci rx_pwr_all = lna_gain - (2 * vga_idx); 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_ci return rx_pwr_all; 171262306a36Sopenharmony_ci} 171362306a36Sopenharmony_ci 171462306a36Sopenharmony_cistatic int rtl8192eu_led_brightness_set(struct led_classdev *led_cdev, 171562306a36Sopenharmony_ci enum led_brightness brightness) 171662306a36Sopenharmony_ci{ 171762306a36Sopenharmony_ci struct rtl8xxxu_priv *priv = container_of(led_cdev, 171862306a36Sopenharmony_ci struct rtl8xxxu_priv, 171962306a36Sopenharmony_ci led_cdev); 172062306a36Sopenharmony_ci u8 ledcfg = rtl8xxxu_read8(priv, REG_LEDCFG1); 172162306a36Sopenharmony_ci 172262306a36Sopenharmony_ci if (brightness == LED_OFF) { 172362306a36Sopenharmony_ci ledcfg &= ~LEDCFG1_HW_LED_CONTROL; 172462306a36Sopenharmony_ci ledcfg |= LEDCFG1_LED_DISABLE; 172562306a36Sopenharmony_ci } else if (brightness == LED_ON) { 172662306a36Sopenharmony_ci ledcfg &= ~(LEDCFG1_HW_LED_CONTROL | LEDCFG1_LED_DISABLE); 172762306a36Sopenharmony_ci } else if (brightness == RTL8XXXU_HW_LED_CONTROL) { 172862306a36Sopenharmony_ci ledcfg &= ~LEDCFG1_LED_DISABLE; 172962306a36Sopenharmony_ci ledcfg |= LEDCFG1_HW_LED_CONTROL; 173062306a36Sopenharmony_ci } 173162306a36Sopenharmony_ci 173262306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_LEDCFG1, ledcfg); 173362306a36Sopenharmony_ci 173462306a36Sopenharmony_ci return 0; 173562306a36Sopenharmony_ci} 173662306a36Sopenharmony_ci 173762306a36Sopenharmony_cistruct rtl8xxxu_fileops rtl8192eu_fops = { 173862306a36Sopenharmony_ci .identify_chip = rtl8192eu_identify_chip, 173962306a36Sopenharmony_ci .parse_efuse = rtl8192eu_parse_efuse, 174062306a36Sopenharmony_ci .load_firmware = rtl8192eu_load_firmware, 174162306a36Sopenharmony_ci .power_on = rtl8192eu_power_on, 174262306a36Sopenharmony_ci .power_off = rtl8192eu_power_off, 174362306a36Sopenharmony_ci .read_efuse = rtl8xxxu_read_efuse, 174462306a36Sopenharmony_ci .reset_8051 = rtl8xxxu_reset_8051, 174562306a36Sopenharmony_ci .llt_init = rtl8xxxu_auto_llt_table, 174662306a36Sopenharmony_ci .init_phy_bb = rtl8192eu_init_phy_bb, 174762306a36Sopenharmony_ci .init_phy_rf = rtl8192eu_init_phy_rf, 174862306a36Sopenharmony_ci .phy_lc_calibrate = rtl8723a_phy_lc_calibrate, 174962306a36Sopenharmony_ci .phy_iq_calibrate = rtl8192eu_phy_iq_calibrate, 175062306a36Sopenharmony_ci .config_channel = rtl8xxxu_gen2_config_channel, 175162306a36Sopenharmony_ci .parse_rx_desc = rtl8xxxu_parse_rxdesc24, 175262306a36Sopenharmony_ci .parse_phystats = rtl8723au_rx_parse_phystats, 175362306a36Sopenharmony_ci .enable_rf = rtl8192e_enable_rf, 175462306a36Sopenharmony_ci .disable_rf = rtl8xxxu_gen2_disable_rf, 175562306a36Sopenharmony_ci .usb_quirks = rtl8xxxu_gen2_usb_quirks, 175662306a36Sopenharmony_ci .set_tx_power = rtl8192e_set_tx_power, 175762306a36Sopenharmony_ci .update_rate_mask = rtl8xxxu_gen2_update_rate_mask, 175862306a36Sopenharmony_ci .report_connect = rtl8xxxu_gen2_report_connect, 175962306a36Sopenharmony_ci .report_rssi = rtl8xxxu_gen2_report_rssi, 176062306a36Sopenharmony_ci .fill_txdesc = rtl8xxxu_fill_txdesc_v2, 176162306a36Sopenharmony_ci .set_crystal_cap = rtl8723a_set_crystal_cap, 176262306a36Sopenharmony_ci .cck_rssi = rtl8192e_cck_rssi, 176362306a36Sopenharmony_ci .led_classdev_brightness_set = rtl8192eu_led_brightness_set, 176462306a36Sopenharmony_ci .writeN_block_size = 128, 176562306a36Sopenharmony_ci .tx_desc_size = sizeof(struct rtl8xxxu_txdesc40), 176662306a36Sopenharmony_ci .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), 176762306a36Sopenharmony_ci .has_s0s1 = 0, 176862306a36Sopenharmony_ci .gen2_thermal_meter = 1, 176962306a36Sopenharmony_ci .needs_full_init = 1, 177062306a36Sopenharmony_ci .supports_ap = 1, 177162306a36Sopenharmony_ci .max_macid_num = 128, 177262306a36Sopenharmony_ci .adda_1t_init = 0x0fc01616, 177362306a36Sopenharmony_ci .adda_1t_path_on = 0x0fc01616, 177462306a36Sopenharmony_ci .adda_2t_path_on_a = 0x0fc01616, 177562306a36Sopenharmony_ci .adda_2t_path_on_b = 0x0fc01616, 177662306a36Sopenharmony_ci .trxff_boundary = 0x3cff, 177762306a36Sopenharmony_ci .mactable = rtl8192e_mac_init_table, 177862306a36Sopenharmony_ci .total_page_num = TX_TOTAL_PAGE_NUM_8192E, 177962306a36Sopenharmony_ci .page_num_hi = TX_PAGE_NUM_HI_PQ_8192E, 178062306a36Sopenharmony_ci .page_num_lo = TX_PAGE_NUM_LO_PQ_8192E, 178162306a36Sopenharmony_ci .page_num_norm = TX_PAGE_NUM_NORM_PQ_8192E, 178262306a36Sopenharmony_ci}; 1783