162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * RTL8XXXU mac80211 USB driver - 8723b 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 rtl8723b_mac_init_table[] = { 3662306a36Sopenharmony_ci {0x02f, 0x30}, {0x035, 0x00}, {0x039, 0x08}, {0x04e, 0xe0}, 3762306a36Sopenharmony_ci {0x064, 0x00}, {0x067, 0x20}, {0x428, 0x0a}, {0x429, 0x10}, 3862306a36Sopenharmony_ci {0x430, 0x00}, {0x431, 0x00}, 3962306a36Sopenharmony_ci {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, {0x435, 0x05}, 4062306a36Sopenharmony_ci {0x436, 0x07}, {0x437, 0x08}, {0x43c, 0x04}, {0x43d, 0x05}, 4162306a36Sopenharmony_ci {0x43e, 0x07}, {0x43f, 0x08}, {0x440, 0x5d}, {0x441, 0x01}, 4262306a36Sopenharmony_ci {0x442, 0x00}, {0x444, 0x10}, {0x445, 0x00}, {0x446, 0x00}, 4362306a36Sopenharmony_ci {0x447, 0x00}, {0x448, 0x00}, {0x449, 0xf0}, {0x44a, 0x0f}, 4462306a36Sopenharmony_ci {0x44b, 0x3e}, {0x44c, 0x10}, {0x44d, 0x00}, {0x44e, 0x00}, 4562306a36Sopenharmony_ci {0x44f, 0x00}, {0x450, 0x00}, {0x451, 0xf0}, {0x452, 0x0f}, 4662306a36Sopenharmony_ci {0x453, 0x00}, {0x456, 0x5e}, {0x460, 0x66}, {0x461, 0x66}, 4762306a36Sopenharmony_ci {0x4c8, 0xff}, {0x4c9, 0x08}, {0x4cc, 0xff}, 4862306a36Sopenharmony_ci {0x4cd, 0xff}, {0x4ce, 0x01}, {0x500, 0x26}, {0x501, 0xa2}, 4962306a36Sopenharmony_ci {0x502, 0x2f}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xa3}, 5062306a36Sopenharmony_ci {0x506, 0x5e}, {0x507, 0x00}, {0x508, 0x2b}, {0x509, 0xa4}, 5162306a36Sopenharmony_ci {0x50a, 0x5e}, {0x50b, 0x00}, {0x50c, 0x4f}, {0x50d, 0xa4}, 5262306a36Sopenharmony_ci {0x50e, 0x00}, {0x50f, 0x00}, {0x512, 0x1c}, {0x514, 0x0a}, 5362306a36Sopenharmony_ci {0x516, 0x0a}, {0x525, 0x4f}, 5462306a36Sopenharmony_ci {0x550, 0x10}, {0x551, 0x10}, {0x559, 0x02}, {0x55c, 0x50}, 5562306a36Sopenharmony_ci {0x55d, 0xff}, {0x605, 0x30}, {0x608, 0x0e}, {0x609, 0x2a}, 5662306a36Sopenharmony_ci {0x620, 0xff}, {0x621, 0xff}, {0x622, 0xff}, {0x623, 0xff}, 5762306a36Sopenharmony_ci {0x624, 0xff}, {0x625, 0xff}, {0x626, 0xff}, {0x627, 0xff}, 5862306a36Sopenharmony_ci {0x638, 0x50}, {0x63c, 0x0a}, {0x63d, 0x0a}, {0x63e, 0x0e}, 5962306a36Sopenharmony_ci {0x63f, 0x0e}, {0x640, 0x40}, {0x642, 0x40}, {0x643, 0x00}, 6062306a36Sopenharmony_ci {0x652, 0xc8}, {0x66e, 0x05}, {0x700, 0x21}, {0x701, 0x43}, 6162306a36Sopenharmony_ci {0x702, 0x65}, {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43}, 6262306a36Sopenharmony_ci {0x70a, 0x65}, {0x70b, 0x87}, {0x765, 0x18}, {0x76e, 0x04}, 6362306a36Sopenharmony_ci {0xffff, 0xff}, 6462306a36Sopenharmony_ci}; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic const struct rtl8xxxu_reg32val rtl8723b_phy_1t_init_table[] = { 6762306a36Sopenharmony_ci {0x800, 0x80040000}, {0x804, 0x00000003}, 6862306a36Sopenharmony_ci {0x808, 0x0000fc00}, {0x80c, 0x0000000a}, 6962306a36Sopenharmony_ci {0x810, 0x10001331}, {0x814, 0x020c3d10}, 7062306a36Sopenharmony_ci {0x818, 0x02200385}, {0x81c, 0x00000000}, 7162306a36Sopenharmony_ci {0x820, 0x01000100}, {0x824, 0x00190204}, 7262306a36Sopenharmony_ci {0x828, 0x00000000}, {0x82c, 0x00000000}, 7362306a36Sopenharmony_ci {0x830, 0x00000000}, {0x834, 0x00000000}, 7462306a36Sopenharmony_ci {0x838, 0x00000000}, {0x83c, 0x00000000}, 7562306a36Sopenharmony_ci {0x840, 0x00010000}, {0x844, 0x00000000}, 7662306a36Sopenharmony_ci {0x848, 0x00000000}, {0x84c, 0x00000000}, 7762306a36Sopenharmony_ci {0x850, 0x00000000}, {0x854, 0x00000000}, 7862306a36Sopenharmony_ci {0x858, 0x569a11a9}, {0x85c, 0x01000014}, 7962306a36Sopenharmony_ci {0x860, 0x66f60110}, {0x864, 0x061f0649}, 8062306a36Sopenharmony_ci {0x868, 0x00000000}, {0x86c, 0x27272700}, 8162306a36Sopenharmony_ci {0x870, 0x07000760}, {0x874, 0x25004000}, 8262306a36Sopenharmony_ci {0x878, 0x00000808}, {0x87c, 0x00000000}, 8362306a36Sopenharmony_ci {0x880, 0xb0000c1c}, {0x884, 0x00000001}, 8462306a36Sopenharmony_ci {0x888, 0x00000000}, {0x88c, 0xccc000c0}, 8562306a36Sopenharmony_ci {0x890, 0x00000800}, {0x894, 0xfffffffe}, 8662306a36Sopenharmony_ci {0x898, 0x40302010}, {0x89c, 0x00706050}, 8762306a36Sopenharmony_ci {0x900, 0x00000000}, {0x904, 0x00000023}, 8862306a36Sopenharmony_ci {0x908, 0x00000000}, {0x90c, 0x81121111}, 8962306a36Sopenharmony_ci {0x910, 0x00000002}, {0x914, 0x00000201}, 9062306a36Sopenharmony_ci {0xa00, 0x00d047c8}, {0xa04, 0x80ff800c}, 9162306a36Sopenharmony_ci {0xa08, 0x8c838300}, {0xa0c, 0x2e7f120f}, 9262306a36Sopenharmony_ci {0xa10, 0x9500bb78}, {0xa14, 0x1114d028}, 9362306a36Sopenharmony_ci {0xa18, 0x00881117}, {0xa1c, 0x89140f00}, 9462306a36Sopenharmony_ci {0xa20, 0x1a1b0000}, {0xa24, 0x090e1317}, 9562306a36Sopenharmony_ci {0xa28, 0x00000204}, {0xa2c, 0x00d30000}, 9662306a36Sopenharmony_ci {0xa70, 0x101fbf00}, {0xa74, 0x00000007}, 9762306a36Sopenharmony_ci {0xa78, 0x00000900}, {0xa7c, 0x225b0606}, 9862306a36Sopenharmony_ci {0xa80, 0x21806490}, {0xb2c, 0x00000000}, 9962306a36Sopenharmony_ci {0xc00, 0x48071d40}, {0xc04, 0x03a05611}, 10062306a36Sopenharmony_ci {0xc08, 0x000000e4}, {0xc0c, 0x6c6c6c6c}, 10162306a36Sopenharmony_ci {0xc10, 0x08800000}, {0xc14, 0x40000100}, 10262306a36Sopenharmony_ci {0xc18, 0x08800000}, {0xc1c, 0x40000100}, 10362306a36Sopenharmony_ci {0xc20, 0x00000000}, {0xc24, 0x00000000}, 10462306a36Sopenharmony_ci {0xc28, 0x00000000}, {0xc2c, 0x00000000}, 10562306a36Sopenharmony_ci {0xc30, 0x69e9ac44}, {0xc34, 0x469652af}, 10662306a36Sopenharmony_ci {0xc38, 0x49795994}, {0xc3c, 0x0a97971c}, 10762306a36Sopenharmony_ci {0xc40, 0x1f7c403f}, {0xc44, 0x000100b7}, 10862306a36Sopenharmony_ci {0xc48, 0xec020107}, {0xc4c, 0x007f037f}, 10962306a36Sopenharmony_ci {0xc50, 0x69553420}, {0xc54, 0x43bc0094}, 11062306a36Sopenharmony_ci {0xc58, 0x00013149}, {0xc5c, 0x00250492}, 11162306a36Sopenharmony_ci {0xc60, 0x00000000}, {0xc64, 0x7112848b}, 11262306a36Sopenharmony_ci {0xc68, 0x47c00bff}, {0xc6c, 0x00000036}, 11362306a36Sopenharmony_ci {0xc70, 0x2c7f000d}, {0xc74, 0x020610db}, 11462306a36Sopenharmony_ci {0xc78, 0x0000001f}, {0xc7c, 0x00b91612}, 11562306a36Sopenharmony_ci {0xc80, 0x390000e4}, {0xc84, 0x20f60000}, 11662306a36Sopenharmony_ci {0xc88, 0x40000100}, {0xc8c, 0x20200000}, 11762306a36Sopenharmony_ci {0xc90, 0x00020e1a}, {0xc94, 0x00000000}, 11862306a36Sopenharmony_ci {0xc98, 0x00020e1a}, {0xc9c, 0x00007f7f}, 11962306a36Sopenharmony_ci {0xca0, 0x00000000}, {0xca4, 0x000300a0}, 12062306a36Sopenharmony_ci {0xca8, 0x00000000}, {0xcac, 0x00000000}, 12162306a36Sopenharmony_ci {0xcb0, 0x00000000}, {0xcb4, 0x00000000}, 12262306a36Sopenharmony_ci {0xcb8, 0x00000000}, {0xcbc, 0x28000000}, 12362306a36Sopenharmony_ci {0xcc0, 0x00000000}, {0xcc4, 0x00000000}, 12462306a36Sopenharmony_ci {0xcc8, 0x00000000}, {0xccc, 0x00000000}, 12562306a36Sopenharmony_ci {0xcd0, 0x00000000}, {0xcd4, 0x00000000}, 12662306a36Sopenharmony_ci {0xcd8, 0x64b22427}, {0xcdc, 0x00766932}, 12762306a36Sopenharmony_ci {0xce0, 0x00222222}, {0xce4, 0x00000000}, 12862306a36Sopenharmony_ci {0xce8, 0x37644302}, {0xcec, 0x2f97d40c}, 12962306a36Sopenharmony_ci {0xd00, 0x00000740}, {0xd04, 0x40020401}, 13062306a36Sopenharmony_ci {0xd08, 0x0000907f}, {0xd0c, 0x20010201}, 13162306a36Sopenharmony_ci {0xd10, 0xa0633333}, {0xd14, 0x3333bc53}, 13262306a36Sopenharmony_ci {0xd18, 0x7a8f5b6f}, {0xd2c, 0xcc979975}, 13362306a36Sopenharmony_ci {0xd30, 0x00000000}, {0xd34, 0x80608000}, 13462306a36Sopenharmony_ci {0xd38, 0x00000000}, {0xd3c, 0x00127353}, 13562306a36Sopenharmony_ci {0xd40, 0x00000000}, {0xd44, 0x00000000}, 13662306a36Sopenharmony_ci {0xd48, 0x00000000}, {0xd4c, 0x00000000}, 13762306a36Sopenharmony_ci {0xd50, 0x6437140a}, {0xd54, 0x00000000}, 13862306a36Sopenharmony_ci {0xd58, 0x00000282}, {0xd5c, 0x30032064}, 13962306a36Sopenharmony_ci {0xd60, 0x4653de68}, {0xd64, 0x04518a3c}, 14062306a36Sopenharmony_ci {0xd68, 0x00002101}, {0xd6c, 0x2a201c16}, 14162306a36Sopenharmony_ci {0xd70, 0x1812362e}, {0xd74, 0x322c2220}, 14262306a36Sopenharmony_ci {0xd78, 0x000e3c24}, {0xe00, 0x2d2d2d2d}, 14362306a36Sopenharmony_ci {0xe04, 0x2d2d2d2d}, {0xe08, 0x0390272d}, 14462306a36Sopenharmony_ci {0xe10, 0x2d2d2d2d}, {0xe14, 0x2d2d2d2d}, 14562306a36Sopenharmony_ci {0xe18, 0x2d2d2d2d}, {0xe1c, 0x2d2d2d2d}, 14662306a36Sopenharmony_ci {0xe28, 0x00000000}, {0xe30, 0x1000dc1f}, 14762306a36Sopenharmony_ci {0xe34, 0x10008c1f}, {0xe38, 0x02140102}, 14862306a36Sopenharmony_ci {0xe3c, 0x681604c2}, {0xe40, 0x01007c00}, 14962306a36Sopenharmony_ci {0xe44, 0x01004800}, {0xe48, 0xfb000000}, 15062306a36Sopenharmony_ci {0xe4c, 0x000028d1}, {0xe50, 0x1000dc1f}, 15162306a36Sopenharmony_ci {0xe54, 0x10008c1f}, {0xe58, 0x02140102}, 15262306a36Sopenharmony_ci {0xe5c, 0x28160d05}, {0xe60, 0x00000008}, 15362306a36Sopenharmony_ci {0xe68, 0x001b2556}, {0xe6c, 0x00c00096}, 15462306a36Sopenharmony_ci {0xe70, 0x00c00096}, {0xe74, 0x01000056}, 15562306a36Sopenharmony_ci {0xe78, 0x01000014}, {0xe7c, 0x01000056}, 15662306a36Sopenharmony_ci {0xe80, 0x01000014}, {0xe84, 0x00c00096}, 15762306a36Sopenharmony_ci {0xe88, 0x01000056}, {0xe8c, 0x00c00096}, 15862306a36Sopenharmony_ci {0xed0, 0x00c00096}, {0xed4, 0x00c00096}, 15962306a36Sopenharmony_ci {0xed8, 0x00c00096}, {0xedc, 0x000000d6}, 16062306a36Sopenharmony_ci {0xee0, 0x000000d6}, {0xeec, 0x01c00016}, 16162306a36Sopenharmony_ci {0xf14, 0x00000003}, {0xf4c, 0x00000000}, 16262306a36Sopenharmony_ci {0xf00, 0x00000300}, 16362306a36Sopenharmony_ci {0x820, 0x01000100}, {0x800, 0x83040000}, 16462306a36Sopenharmony_ci {0xffff, 0xffffffff}, 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic const struct rtl8xxxu_reg32val rtl8xxx_agc_8723bu_table[] = { 16862306a36Sopenharmony_ci {0xc78, 0xfd000001}, {0xc78, 0xfc010001}, 16962306a36Sopenharmony_ci {0xc78, 0xfb020001}, {0xc78, 0xfa030001}, 17062306a36Sopenharmony_ci {0xc78, 0xf9040001}, {0xc78, 0xf8050001}, 17162306a36Sopenharmony_ci {0xc78, 0xf7060001}, {0xc78, 0xf6070001}, 17262306a36Sopenharmony_ci {0xc78, 0xf5080001}, {0xc78, 0xf4090001}, 17362306a36Sopenharmony_ci {0xc78, 0xf30a0001}, {0xc78, 0xf20b0001}, 17462306a36Sopenharmony_ci {0xc78, 0xf10c0001}, {0xc78, 0xf00d0001}, 17562306a36Sopenharmony_ci {0xc78, 0xef0e0001}, {0xc78, 0xee0f0001}, 17662306a36Sopenharmony_ci {0xc78, 0xed100001}, {0xc78, 0xec110001}, 17762306a36Sopenharmony_ci {0xc78, 0xeb120001}, {0xc78, 0xea130001}, 17862306a36Sopenharmony_ci {0xc78, 0xe9140001}, {0xc78, 0xe8150001}, 17962306a36Sopenharmony_ci {0xc78, 0xe7160001}, {0xc78, 0xe6170001}, 18062306a36Sopenharmony_ci {0xc78, 0xe5180001}, {0xc78, 0xe4190001}, 18162306a36Sopenharmony_ci {0xc78, 0xe31a0001}, {0xc78, 0xa51b0001}, 18262306a36Sopenharmony_ci {0xc78, 0xa41c0001}, {0xc78, 0xa31d0001}, 18362306a36Sopenharmony_ci {0xc78, 0x671e0001}, {0xc78, 0x661f0001}, 18462306a36Sopenharmony_ci {0xc78, 0x65200001}, {0xc78, 0x64210001}, 18562306a36Sopenharmony_ci {0xc78, 0x63220001}, {0xc78, 0x4a230001}, 18662306a36Sopenharmony_ci {0xc78, 0x49240001}, {0xc78, 0x48250001}, 18762306a36Sopenharmony_ci {0xc78, 0x47260001}, {0xc78, 0x46270001}, 18862306a36Sopenharmony_ci {0xc78, 0x45280001}, {0xc78, 0x44290001}, 18962306a36Sopenharmony_ci {0xc78, 0x432a0001}, {0xc78, 0x422b0001}, 19062306a36Sopenharmony_ci {0xc78, 0x292c0001}, {0xc78, 0x282d0001}, 19162306a36Sopenharmony_ci {0xc78, 0x272e0001}, {0xc78, 0x262f0001}, 19262306a36Sopenharmony_ci {0xc78, 0x0a300001}, {0xc78, 0x09310001}, 19362306a36Sopenharmony_ci {0xc78, 0x08320001}, {0xc78, 0x07330001}, 19462306a36Sopenharmony_ci {0xc78, 0x06340001}, {0xc78, 0x05350001}, 19562306a36Sopenharmony_ci {0xc78, 0x04360001}, {0xc78, 0x03370001}, 19662306a36Sopenharmony_ci {0xc78, 0x02380001}, {0xc78, 0x01390001}, 19762306a36Sopenharmony_ci {0xc78, 0x013a0001}, {0xc78, 0x013b0001}, 19862306a36Sopenharmony_ci {0xc78, 0x013c0001}, {0xc78, 0x013d0001}, 19962306a36Sopenharmony_ci {0xc78, 0x013e0001}, {0xc78, 0x013f0001}, 20062306a36Sopenharmony_ci {0xc78, 0xfc400001}, {0xc78, 0xfb410001}, 20162306a36Sopenharmony_ci {0xc78, 0xfa420001}, {0xc78, 0xf9430001}, 20262306a36Sopenharmony_ci {0xc78, 0xf8440001}, {0xc78, 0xf7450001}, 20362306a36Sopenharmony_ci {0xc78, 0xf6460001}, {0xc78, 0xf5470001}, 20462306a36Sopenharmony_ci {0xc78, 0xf4480001}, {0xc78, 0xf3490001}, 20562306a36Sopenharmony_ci {0xc78, 0xf24a0001}, {0xc78, 0xf14b0001}, 20662306a36Sopenharmony_ci {0xc78, 0xf04c0001}, {0xc78, 0xef4d0001}, 20762306a36Sopenharmony_ci {0xc78, 0xee4e0001}, {0xc78, 0xed4f0001}, 20862306a36Sopenharmony_ci {0xc78, 0xec500001}, {0xc78, 0xeb510001}, 20962306a36Sopenharmony_ci {0xc78, 0xea520001}, {0xc78, 0xe9530001}, 21062306a36Sopenharmony_ci {0xc78, 0xe8540001}, {0xc78, 0xe7550001}, 21162306a36Sopenharmony_ci {0xc78, 0xe6560001}, {0xc78, 0xe5570001}, 21262306a36Sopenharmony_ci {0xc78, 0xe4580001}, {0xc78, 0xe3590001}, 21362306a36Sopenharmony_ci {0xc78, 0xa65a0001}, {0xc78, 0xa55b0001}, 21462306a36Sopenharmony_ci {0xc78, 0xa45c0001}, {0xc78, 0xa35d0001}, 21562306a36Sopenharmony_ci {0xc78, 0x675e0001}, {0xc78, 0x665f0001}, 21662306a36Sopenharmony_ci {0xc78, 0x65600001}, {0xc78, 0x64610001}, 21762306a36Sopenharmony_ci {0xc78, 0x63620001}, {0xc78, 0x62630001}, 21862306a36Sopenharmony_ci {0xc78, 0x61640001}, {0xc78, 0x48650001}, 21962306a36Sopenharmony_ci {0xc78, 0x47660001}, {0xc78, 0x46670001}, 22062306a36Sopenharmony_ci {0xc78, 0x45680001}, {0xc78, 0x44690001}, 22162306a36Sopenharmony_ci {0xc78, 0x436a0001}, {0xc78, 0x426b0001}, 22262306a36Sopenharmony_ci {0xc78, 0x286c0001}, {0xc78, 0x276d0001}, 22362306a36Sopenharmony_ci {0xc78, 0x266e0001}, {0xc78, 0x256f0001}, 22462306a36Sopenharmony_ci {0xc78, 0x24700001}, {0xc78, 0x09710001}, 22562306a36Sopenharmony_ci {0xc78, 0x08720001}, {0xc78, 0x07730001}, 22662306a36Sopenharmony_ci {0xc78, 0x06740001}, {0xc78, 0x05750001}, 22762306a36Sopenharmony_ci {0xc78, 0x04760001}, {0xc78, 0x03770001}, 22862306a36Sopenharmony_ci {0xc78, 0x02780001}, {0xc78, 0x01790001}, 22962306a36Sopenharmony_ci {0xc78, 0x017a0001}, {0xc78, 0x017b0001}, 23062306a36Sopenharmony_ci {0xc78, 0x017c0001}, {0xc78, 0x017d0001}, 23162306a36Sopenharmony_ci {0xc78, 0x017e0001}, {0xc78, 0x017f0001}, 23262306a36Sopenharmony_ci {0xc50, 0x69553422}, 23362306a36Sopenharmony_ci {0xc50, 0x69553420}, 23462306a36Sopenharmony_ci {0x824, 0x00390204}, 23562306a36Sopenharmony_ci {0xffff, 0xffffffff} 23662306a36Sopenharmony_ci}; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_cistatic const struct rtl8xxxu_rfregval rtl8723bu_radioa_1t_init_table[] = { 23962306a36Sopenharmony_ci {0x00, 0x00010000}, {0xb0, 0x000dffe0}, 24062306a36Sopenharmony_ci {0xfe, 0x00000000}, {0xfe, 0x00000000}, 24162306a36Sopenharmony_ci {0xfe, 0x00000000}, {0xb1, 0x00000018}, 24262306a36Sopenharmony_ci {0xfe, 0x00000000}, {0xfe, 0x00000000}, 24362306a36Sopenharmony_ci {0xfe, 0x00000000}, {0xb2, 0x00084c00}, 24462306a36Sopenharmony_ci {0xb5, 0x0000d2cc}, {0xb6, 0x000925aa}, 24562306a36Sopenharmony_ci {0xb7, 0x00000010}, {0xb8, 0x0000907f}, 24662306a36Sopenharmony_ci {0x5c, 0x00000002}, {0x7c, 0x00000002}, 24762306a36Sopenharmony_ci {0x7e, 0x00000005}, {0x8b, 0x0006fc00}, 24862306a36Sopenharmony_ci {0xb0, 0x000ff9f0}, {0x1c, 0x000739d2}, 24962306a36Sopenharmony_ci {0x1e, 0x00000000}, {0xdf, 0x00000780}, 25062306a36Sopenharmony_ci {0x50, 0x00067435}, 25162306a36Sopenharmony_ci /* 25262306a36Sopenharmony_ci * The 8723bu vendor driver indicates that bit 8 should be set in 25362306a36Sopenharmony_ci * 0x51 for package types TFBGA90, TFBGA80, and TFBGA79. However 25462306a36Sopenharmony_ci * they never actually check the package type - and just default 25562306a36Sopenharmony_ci * to not setting it. 25662306a36Sopenharmony_ci */ 25762306a36Sopenharmony_ci {0x51, 0x0006b04e}, 25862306a36Sopenharmony_ci {0x52, 0x000007d2}, {0x53, 0x00000000}, 25962306a36Sopenharmony_ci {0x54, 0x00050400}, {0x55, 0x0004026e}, 26062306a36Sopenharmony_ci {0xdd, 0x0000004c}, {0x70, 0x00067435}, 26162306a36Sopenharmony_ci /* 26262306a36Sopenharmony_ci * 0x71 has same package type condition as for register 0x51 26362306a36Sopenharmony_ci */ 26462306a36Sopenharmony_ci {0x71, 0x0006b04e}, 26562306a36Sopenharmony_ci {0x72, 0x000007d2}, {0x73, 0x00000000}, 26662306a36Sopenharmony_ci {0x74, 0x00050400}, {0x75, 0x0004026e}, 26762306a36Sopenharmony_ci {0xef, 0x00000100}, {0x34, 0x0000add7}, 26862306a36Sopenharmony_ci {0x35, 0x00005c00}, {0x34, 0x00009dd4}, 26962306a36Sopenharmony_ci {0x35, 0x00005000}, {0x34, 0x00008dd1}, 27062306a36Sopenharmony_ci {0x35, 0x00004400}, {0x34, 0x00007dce}, 27162306a36Sopenharmony_ci {0x35, 0x00003800}, {0x34, 0x00006cd1}, 27262306a36Sopenharmony_ci {0x35, 0x00004400}, {0x34, 0x00005cce}, 27362306a36Sopenharmony_ci {0x35, 0x00003800}, {0x34, 0x000048ce}, 27462306a36Sopenharmony_ci {0x35, 0x00004400}, {0x34, 0x000034ce}, 27562306a36Sopenharmony_ci {0x35, 0x00003800}, {0x34, 0x00002451}, 27662306a36Sopenharmony_ci {0x35, 0x00004400}, {0x34, 0x0000144e}, 27762306a36Sopenharmony_ci {0x35, 0x00003800}, {0x34, 0x00000051}, 27862306a36Sopenharmony_ci {0x35, 0x00004400}, {0xef, 0x00000000}, 27962306a36Sopenharmony_ci {0xef, 0x00000100}, {0xed, 0x00000010}, 28062306a36Sopenharmony_ci {0x44, 0x0000add7}, {0x44, 0x00009dd4}, 28162306a36Sopenharmony_ci {0x44, 0x00008dd1}, {0x44, 0x00007dce}, 28262306a36Sopenharmony_ci {0x44, 0x00006cc1}, {0x44, 0x00005cce}, 28362306a36Sopenharmony_ci {0x44, 0x000044d1}, {0x44, 0x000034ce}, 28462306a36Sopenharmony_ci {0x44, 0x00002451}, {0x44, 0x0000144e}, 28562306a36Sopenharmony_ci {0x44, 0x00000051}, {0xef, 0x00000000}, 28662306a36Sopenharmony_ci {0xed, 0x00000000}, {0x7f, 0x00020080}, 28762306a36Sopenharmony_ci {0xef, 0x00002000}, {0x3b, 0x000380ef}, 28862306a36Sopenharmony_ci {0x3b, 0x000302fe}, {0x3b, 0x00028ce6}, 28962306a36Sopenharmony_ci {0x3b, 0x000200bc}, {0x3b, 0x000188a5}, 29062306a36Sopenharmony_ci {0x3b, 0x00010fbc}, {0x3b, 0x00008f71}, 29162306a36Sopenharmony_ci {0x3b, 0x00000900}, {0xef, 0x00000000}, 29262306a36Sopenharmony_ci {0xed, 0x00000001}, {0x40, 0x000380ef}, 29362306a36Sopenharmony_ci {0x40, 0x000302fe}, {0x40, 0x00028ce6}, 29462306a36Sopenharmony_ci {0x40, 0x000200bc}, {0x40, 0x000188a5}, 29562306a36Sopenharmony_ci {0x40, 0x00010fbc}, {0x40, 0x00008f71}, 29662306a36Sopenharmony_ci {0x40, 0x00000900}, {0xed, 0x00000000}, 29762306a36Sopenharmony_ci {0x82, 0x00080000}, {0x83, 0x00008000}, 29862306a36Sopenharmony_ci {0x84, 0x00048d80}, {0x85, 0x00068000}, 29962306a36Sopenharmony_ci {0xa2, 0x00080000}, {0xa3, 0x00008000}, 30062306a36Sopenharmony_ci {0xa4, 0x00048d80}, {0xa5, 0x00068000}, 30162306a36Sopenharmony_ci {0xed, 0x00000002}, {0xef, 0x00000002}, 30262306a36Sopenharmony_ci {0x56, 0x00000032}, {0x76, 0x00000032}, 30362306a36Sopenharmony_ci {0x01, 0x00000780}, 30462306a36Sopenharmony_ci {0xff, 0xffffffff} 30562306a36Sopenharmony_ci}; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic int rtl8723bu_identify_chip(struct rtl8xxxu_priv *priv) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 31062306a36Sopenharmony_ci u32 val32, sys_cfg, vendor; 31162306a36Sopenharmony_ci int ret = 0; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG); 31462306a36Sopenharmony_ci priv->chip_cut = u32_get_bits(sys_cfg, SYS_CFG_CHIP_VERSION_MASK); 31562306a36Sopenharmony_ci if (sys_cfg & SYS_CFG_TRP_VAUX_EN) { 31662306a36Sopenharmony_ci dev_info(dev, "Unsupported test chip\n"); 31762306a36Sopenharmony_ci ret = -ENOTSUPP; 31862306a36Sopenharmony_ci goto out; 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci strscpy(priv->chip_name, "8723BU", sizeof(priv->chip_name)); 32262306a36Sopenharmony_ci priv->rtl_chip = RTL8723B; 32362306a36Sopenharmony_ci priv->rf_paths = 1; 32462306a36Sopenharmony_ci priv->rx_paths = 1; 32562306a36Sopenharmony_ci priv->tx_paths = 1; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_MULTI_FUNC_CTRL); 32862306a36Sopenharmony_ci if (val32 & MULTI_WIFI_FUNC_EN) 32962306a36Sopenharmony_ci priv->has_wifi = 1; 33062306a36Sopenharmony_ci if (val32 & MULTI_BT_FUNC_EN) 33162306a36Sopenharmony_ci priv->has_bluetooth = 1; 33262306a36Sopenharmony_ci if (val32 & MULTI_GPS_FUNC_EN) 33362306a36Sopenharmony_ci priv->has_gps = 1; 33462306a36Sopenharmony_ci priv->is_multi_func = 1; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci vendor = sys_cfg & SYS_CFG_VENDOR_EXT_MASK; 33762306a36Sopenharmony_ci rtl8xxxu_identify_vendor_2bits(priv, vendor); 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_GPIO_OUTSTS); 34062306a36Sopenharmony_ci priv->rom_rev = u32_get_bits(val32, GPIO_RF_RL_ID); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci rtl8xxxu_config_endpoints_sie(priv); 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci /* 34562306a36Sopenharmony_ci * Fallback for devices that do not provide REG_NORMAL_SIE_EP_TX 34662306a36Sopenharmony_ci */ 34762306a36Sopenharmony_ci if (!priv->ep_tx_count) 34862306a36Sopenharmony_ci ret = rtl8xxxu_config_endpoints_no_sie(priv); 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ciout: 35162306a36Sopenharmony_ci return ret; 35262306a36Sopenharmony_ci} 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_cistatic void rtl8723bu_write_btreg(struct rtl8xxxu_priv *priv, u8 reg, u8 data) 35562306a36Sopenharmony_ci{ 35662306a36Sopenharmony_ci struct h2c_cmd h2c; 35762306a36Sopenharmony_ci int reqnum = 0; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci memset(&h2c, 0, sizeof(struct h2c_cmd)); 36062306a36Sopenharmony_ci h2c.bt_mp_oper.cmd = H2C_8723B_BT_MP_OPER; 36162306a36Sopenharmony_ci h2c.bt_mp_oper.operreq = 0 | (reqnum << 4); 36262306a36Sopenharmony_ci h2c.bt_mp_oper.opcode = BT_MP_OP_WRITE_REG_VALUE; 36362306a36Sopenharmony_ci h2c.bt_mp_oper.data = data; 36462306a36Sopenharmony_ci rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.bt_mp_oper)); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci reqnum++; 36762306a36Sopenharmony_ci memset(&h2c, 0, sizeof(struct h2c_cmd)); 36862306a36Sopenharmony_ci h2c.bt_mp_oper.cmd = H2C_8723B_BT_MP_OPER; 36962306a36Sopenharmony_ci h2c.bt_mp_oper.operreq = 0 | (reqnum << 4); 37062306a36Sopenharmony_ci h2c.bt_mp_oper.opcode = BT_MP_OP_WRITE_REG_VALUE; 37162306a36Sopenharmony_ci h2c.bt_mp_oper.addr = reg; 37262306a36Sopenharmony_ci rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.bt_mp_oper)); 37362306a36Sopenharmony_ci} 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_cistatic void rtl8723bu_reset_8051(struct rtl8xxxu_priv *priv) 37662306a36Sopenharmony_ci{ 37762306a36Sopenharmony_ci u8 val8; 37862306a36Sopenharmony_ci u16 sys_func; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL); 38162306a36Sopenharmony_ci val8 &= ~BIT(1); 38262306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RSV_CTRL, val8); 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); 38562306a36Sopenharmony_ci val8 &= ~BIT(0); 38662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci sys_func = rtl8xxxu_read16(priv, REG_SYS_FUNC); 38962306a36Sopenharmony_ci sys_func &= ~SYS_FUNC_CPU_ENABLE; 39062306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_SYS_FUNC, sys_func); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL); 39362306a36Sopenharmony_ci val8 &= ~BIT(1); 39462306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RSV_CTRL, val8); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); 39762306a36Sopenharmony_ci val8 |= BIT(0); 39862306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci sys_func |= SYS_FUNC_CPU_ENABLE; 40162306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_SYS_FUNC, sys_func); 40262306a36Sopenharmony_ci} 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_cistatic void 40562306a36Sopenharmony_cirtl8723b_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) 40662306a36Sopenharmony_ci{ 40762306a36Sopenharmony_ci u32 val32, ofdm, mcs; 40862306a36Sopenharmony_ci u8 cck, ofdmbase, mcsbase; 40962306a36Sopenharmony_ci int group, tx_idx; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci tx_idx = 0; 41262306a36Sopenharmony_ci group = rtl8xxxu_gen2_channel_to_group(channel); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci cck = priv->cck_tx_power_index_B[group]; 41562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_AGC_A_CCK1_MCS32); 41662306a36Sopenharmony_ci val32 &= 0xffff00ff; 41762306a36Sopenharmony_ci val32 |= (cck << 8); 41862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_CCK1_MCS32, val32); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11); 42162306a36Sopenharmony_ci val32 &= 0xff; 42262306a36Sopenharmony_ci val32 |= ((cck << 8) | (cck << 16) | (cck << 24)); 42362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32); 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci ofdmbase = priv->ht40_1s_tx_power_index_B[group]; 42662306a36Sopenharmony_ci ofdmbase += priv->ofdm_tx_power_diff[tx_idx].b; 42762306a36Sopenharmony_ci ofdm = ofdmbase | ofdmbase << 8 | ofdmbase << 16 | ofdmbase << 24; 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE18_06, ofdm); 43062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE54_24, ofdm); 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci mcsbase = priv->ht40_1s_tx_power_index_B[group]; 43362306a36Sopenharmony_ci if (ht40) 43462306a36Sopenharmony_ci mcsbase += priv->ht40_tx_power_diff[tx_idx++].b; 43562306a36Sopenharmony_ci else 43662306a36Sopenharmony_ci mcsbase += priv->ht20_tx_power_diff[tx_idx++].b; 43762306a36Sopenharmony_ci mcs = mcsbase | mcsbase << 8 | mcsbase << 16 | mcsbase << 24; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS03_MCS00, mcs); 44062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS07_MCS04, mcs); 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_cistatic int rtl8723bu_parse_efuse(struct rtl8xxxu_priv *priv) 44462306a36Sopenharmony_ci{ 44562306a36Sopenharmony_ci struct rtl8723bu_efuse *efuse = &priv->efuse_wifi.efuse8723bu; 44662306a36Sopenharmony_ci int i; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci if (efuse->rtl_id != cpu_to_le16(0x8129)) 44962306a36Sopenharmony_ci return -EINVAL; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci ether_addr_copy(priv->mac_addr, efuse->mac_addr); 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci memcpy(priv->cck_tx_power_index_A, efuse->tx_power_index_A.cck_base, 45462306a36Sopenharmony_ci sizeof(efuse->tx_power_index_A.cck_base)); 45562306a36Sopenharmony_ci memcpy(priv->cck_tx_power_index_B, efuse->tx_power_index_B.cck_base, 45662306a36Sopenharmony_ci sizeof(efuse->tx_power_index_B.cck_base)); 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci memcpy(priv->ht40_1s_tx_power_index_A, 45962306a36Sopenharmony_ci efuse->tx_power_index_A.ht40_base, 46062306a36Sopenharmony_ci sizeof(efuse->tx_power_index_A.ht40_base)); 46162306a36Sopenharmony_ci memcpy(priv->ht40_1s_tx_power_index_B, 46262306a36Sopenharmony_ci efuse->tx_power_index_B.ht40_base, 46362306a36Sopenharmony_ci sizeof(efuse->tx_power_index_B.ht40_base)); 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci priv->ofdm_tx_power_diff[0].a = 46662306a36Sopenharmony_ci efuse->tx_power_index_A.ht20_ofdm_1s_diff.a; 46762306a36Sopenharmony_ci priv->ofdm_tx_power_diff[0].b = 46862306a36Sopenharmony_ci efuse->tx_power_index_B.ht20_ofdm_1s_diff.a; 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci priv->ht20_tx_power_diff[0].a = 47162306a36Sopenharmony_ci efuse->tx_power_index_A.ht20_ofdm_1s_diff.b; 47262306a36Sopenharmony_ci priv->ht20_tx_power_diff[0].b = 47362306a36Sopenharmony_ci efuse->tx_power_index_B.ht20_ofdm_1s_diff.b; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci priv->ht40_tx_power_diff[0].a = 0; 47662306a36Sopenharmony_ci priv->ht40_tx_power_diff[0].b = 0; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci for (i = 1; i < RTL8723B_TX_COUNT; i++) { 47962306a36Sopenharmony_ci priv->ofdm_tx_power_diff[i].a = 48062306a36Sopenharmony_ci efuse->tx_power_index_A.pwr_diff[i - 1].ofdm; 48162306a36Sopenharmony_ci priv->ofdm_tx_power_diff[i].b = 48262306a36Sopenharmony_ci efuse->tx_power_index_B.pwr_diff[i - 1].ofdm; 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci priv->ht20_tx_power_diff[i].a = 48562306a36Sopenharmony_ci efuse->tx_power_index_A.pwr_diff[i - 1].ht20; 48662306a36Sopenharmony_ci priv->ht20_tx_power_diff[i].b = 48762306a36Sopenharmony_ci efuse->tx_power_index_B.pwr_diff[i - 1].ht20; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci priv->ht40_tx_power_diff[i].a = 49062306a36Sopenharmony_ci efuse->tx_power_index_A.pwr_diff[i - 1].ht40; 49162306a36Sopenharmony_ci priv->ht40_tx_power_diff[i].b = 49262306a36Sopenharmony_ci efuse->tx_power_index_B.pwr_diff[i - 1].ht40; 49362306a36Sopenharmony_ci } 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci priv->default_crystal_cap = priv->efuse_wifi.efuse8723bu.xtal_k & 0x3f; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci return 0; 49862306a36Sopenharmony_ci} 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_cistatic int rtl8723bu_load_firmware(struct rtl8xxxu_priv *priv) 50162306a36Sopenharmony_ci{ 50262306a36Sopenharmony_ci const char *fw_name; 50362306a36Sopenharmony_ci int ret; 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci if (priv->enable_bluetooth) 50662306a36Sopenharmony_ci fw_name = "rtlwifi/rtl8723bu_bt.bin"; 50762306a36Sopenharmony_ci else 50862306a36Sopenharmony_ci fw_name = "rtlwifi/rtl8723bu_nic.bin"; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci ret = rtl8xxxu_load_firmware(priv, fw_name); 51162306a36Sopenharmony_ci return ret; 51262306a36Sopenharmony_ci} 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_cistatic void rtl8723bu_init_phy_bb(struct rtl8xxxu_priv *priv) 51562306a36Sopenharmony_ci{ 51662306a36Sopenharmony_ci u8 val8; 51762306a36Sopenharmony_ci u16 val16; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); 52062306a36Sopenharmony_ci val16 |= SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB | SYS_FUNC_DIO_RF; 52162306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00); 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci /* 6. 0x1f[7:0] = 0x07 */ 52662306a36Sopenharmony_ci val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB; 52762306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RF_CTRL, val8); 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci /* Why? */ 53062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_SYS_FUNC, 0xe3); 53162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_AFE_XTAL_CTRL + 1, 0x80); 53262306a36Sopenharmony_ci rtl8xxxu_init_phy_regs(priv, rtl8723b_phy_1t_init_table); 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci rtl8xxxu_init_phy_regs(priv, rtl8xxx_agc_8723bu_table); 53562306a36Sopenharmony_ci} 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_cistatic int rtl8723bu_init_phy_rf(struct rtl8xxxu_priv *priv) 53862306a36Sopenharmony_ci{ 53962306a36Sopenharmony_ci int ret; 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci ret = rtl8xxxu_init_phy_rf(priv, rtl8723bu_radioa_1t_init_table, RF_A); 54262306a36Sopenharmony_ci /* 54362306a36Sopenharmony_ci * PHY LCK 54462306a36Sopenharmony_ci */ 54562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, 0xb0, 0xdfbe0); 54662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, 0x8c01); 54762306a36Sopenharmony_ci msleep(200); 54862306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, 0xb0, 0xdffe0); 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ci return ret; 55162306a36Sopenharmony_ci} 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_civoid rtl8723bu_phy_init_antenna_selection(struct rtl8xxxu_priv *priv) 55462306a36Sopenharmony_ci{ 55562306a36Sopenharmony_ci u32 val32; 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_PAD_CTRL1); 55862306a36Sopenharmony_ci val32 &= ~(BIT(20) | BIT(24)); 55962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_PAD_CTRL1, val32); 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_GPIO_MUXCFG); 56262306a36Sopenharmony_ci val32 &= ~BIT(4); 56362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_GPIO_MUXCFG, val32); 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_GPIO_MUXCFG); 56662306a36Sopenharmony_ci val32 |= BIT(3); 56762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_GPIO_MUXCFG, val32); 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_LEDCFG0); 57062306a36Sopenharmony_ci val32 |= BIT(24); 57162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_LEDCFG0, val32); 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_LEDCFG0); 57462306a36Sopenharmony_ci val32 &= ~BIT(23); 57562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_LEDCFG0, val32); 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_RFE_BUFFER); 57862306a36Sopenharmony_ci val32 |= (BIT(0) | BIT(1)); 57962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RFE_BUFFER, val32); 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_RFE_CTRL_ANTA_SRC); 58262306a36Sopenharmony_ci val32 &= 0xffffff00; 58362306a36Sopenharmony_ci val32 |= 0x77; 58462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RFE_CTRL_ANTA_SRC, val32); 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_PWR_DATA); 58762306a36Sopenharmony_ci val32 |= PWR_DATA_EEPRPAD_RFE_CTRL_EN; 58862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_PWR_DATA, val32); 58962306a36Sopenharmony_ci} 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_cistatic int rtl8723bu_iqk_path_a(struct rtl8xxxu_priv *priv) 59262306a36Sopenharmony_ci{ 59362306a36Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c, path_sel, val32; 59462306a36Sopenharmony_ci int result = 0; 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci path_sel = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci /* 59962306a36Sopenharmony_ci * Leave IQK mode 60062306a36Sopenharmony_ci */ 60162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 60262306a36Sopenharmony_ci val32 &= 0x000000ff; 60362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci /* 60662306a36Sopenharmony_ci * Enable path A PA in TX IQK mode 60762306a36Sopenharmony_ci */ 60862306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); 60962306a36Sopenharmony_ci val32 |= 0x80000; 61062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); 61162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x20000); 61262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0003f); 61362306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xc7f87); 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci /* 61662306a36Sopenharmony_ci * Tx IQK setting 61762306a36Sopenharmony_ci */ 61862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); 61962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci /* path-A IQK setting */ 62262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); 62362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); 62462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); 62562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x821403ea); 62862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28110000); 62962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82110000); 63062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28110000); 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ci /* LO calibration setting */ 63362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911); 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci /* 63662306a36Sopenharmony_ci * Enter IQK mode 63762306a36Sopenharmony_ci */ 63862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 63962306a36Sopenharmony_ci val32 &= 0x000000ff; 64062306a36Sopenharmony_ci val32 |= 0x80800000; 64162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci /* 64462306a36Sopenharmony_ci * The vendor driver indicates the USB module is always using 64562306a36Sopenharmony_ci * S0S1 path 1 for the 8723bu. This may be different for 8192eu 64662306a36Sopenharmony_ci */ 64762306a36Sopenharmony_ci if (priv->rf_paths > 1) 64862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000000); 64962306a36Sopenharmony_ci else 65062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000280); 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci /* 65362306a36Sopenharmony_ci * Bit 12 seems to be BT_GRANT, and is only found in the 8723bu. 65462306a36Sopenharmony_ci * No trace of this in the 8192eu or 8188eu vendor drivers. 65562306a36Sopenharmony_ci */ 65662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00000800); 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 65962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); 66062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci mdelay(1); 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci /* Restore Ant Path */ 66562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel); 66662306a36Sopenharmony_ci#ifdef RTL8723BU_BT 66762306a36Sopenharmony_ci /* GNT_BT = 1 */ 66862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00001800); 66962306a36Sopenharmony_ci#endif 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci /* 67262306a36Sopenharmony_ci * Leave IQK mode 67362306a36Sopenharmony_ci */ 67462306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 67562306a36Sopenharmony_ci val32 &= 0x000000ff; 67662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci /* Check failed */ 67962306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 68062306a36Sopenharmony_ci reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); 68162306a36Sopenharmony_ci reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci val32 = (reg_e9c >> 16) & 0x3ff; 68462306a36Sopenharmony_ci if (val32 & 0x200) 68562306a36Sopenharmony_ci val32 = 0x400 - val32; 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 68862306a36Sopenharmony_ci ((reg_e94 & 0x03ff0000) != 0x01420000) && 68962306a36Sopenharmony_ci ((reg_e9c & 0x03ff0000) != 0x00420000) && 69062306a36Sopenharmony_ci ((reg_e94 & 0x03ff0000) < 0x01100000) && 69162306a36Sopenharmony_ci ((reg_e94 & 0x03ff0000) > 0x00f00000) && 69262306a36Sopenharmony_ci val32 < 0xf) 69362306a36Sopenharmony_ci result |= 0x01; 69462306a36Sopenharmony_ci else /* If TX not OK, ignore RX */ 69562306a36Sopenharmony_ci goto out; 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ciout: 69862306a36Sopenharmony_ci return result; 69962306a36Sopenharmony_ci} 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_cistatic int rtl8723bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv) 70262306a36Sopenharmony_ci{ 70362306a36Sopenharmony_ci u32 reg_ea4, reg_eac, reg_e94, reg_e9c, path_sel, val32; 70462306a36Sopenharmony_ci int result = 0; 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci path_sel = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci /* 70962306a36Sopenharmony_ci * Leave IQK mode 71062306a36Sopenharmony_ci */ 71162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 71262306a36Sopenharmony_ci val32 &= 0x000000ff; 71362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci /* 71662306a36Sopenharmony_ci * Enable path A PA in TX IQK mode 71762306a36Sopenharmony_ci */ 71862306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); 71962306a36Sopenharmony_ci val32 |= 0x80000; 72062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); 72162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); 72262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0001f); 72362306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7fb7); 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci /* 72662306a36Sopenharmony_ci * Tx IQK setting 72762306a36Sopenharmony_ci */ 72862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); 72962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 73062306a36Sopenharmony_ci 73162306a36Sopenharmony_ci /* path-A IQK setting */ 73262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); 73362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); 73462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); 73562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82160ff0); 73862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28110000); 73962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82110000); 74062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28110000); 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci /* LO calibration setting */ 74362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci /* 74662306a36Sopenharmony_ci * Enter IQK mode 74762306a36Sopenharmony_ci */ 74862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 74962306a36Sopenharmony_ci val32 &= 0x000000ff; 75062306a36Sopenharmony_ci val32 |= 0x80800000; 75162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ci /* 75462306a36Sopenharmony_ci * The vendor driver indicates the USB module is always using 75562306a36Sopenharmony_ci * S0S1 path 1 for the 8723bu. This may be different for 8192eu 75662306a36Sopenharmony_ci */ 75762306a36Sopenharmony_ci if (priv->rf_paths > 1) 75862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000000); 75962306a36Sopenharmony_ci else 76062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000280); 76162306a36Sopenharmony_ci 76262306a36Sopenharmony_ci /* 76362306a36Sopenharmony_ci * Bit 12 seems to be BT_GRANT, and is only found in the 8723bu. 76462306a36Sopenharmony_ci * No trace of this in the 8192eu or 8188eu vendor drivers. 76562306a36Sopenharmony_ci */ 76662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00000800); 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 76962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); 77062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_ci mdelay(1); 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci /* Restore Ant Path */ 77562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel); 77662306a36Sopenharmony_ci#ifdef RTL8723BU_BT 77762306a36Sopenharmony_ci /* GNT_BT = 1 */ 77862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00001800); 77962306a36Sopenharmony_ci#endif 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci /* 78262306a36Sopenharmony_ci * Leave IQK mode 78362306a36Sopenharmony_ci */ 78462306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 78562306a36Sopenharmony_ci val32 &= 0x000000ff; 78662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci /* Check failed */ 78962306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 79062306a36Sopenharmony_ci reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); 79162306a36Sopenharmony_ci reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci val32 = (reg_e9c >> 16) & 0x3ff; 79462306a36Sopenharmony_ci if (val32 & 0x200) 79562306a36Sopenharmony_ci val32 = 0x400 - val32; 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 79862306a36Sopenharmony_ci ((reg_e94 & 0x03ff0000) != 0x01420000) && 79962306a36Sopenharmony_ci ((reg_e9c & 0x03ff0000) != 0x00420000) && 80062306a36Sopenharmony_ci ((reg_e94 & 0x03ff0000) < 0x01100000) && 80162306a36Sopenharmony_ci ((reg_e94 & 0x03ff0000) > 0x00f00000) && 80262306a36Sopenharmony_ci val32 < 0xf) 80362306a36Sopenharmony_ci result |= 0x01; 80462306a36Sopenharmony_ci else /* If TX not OK, ignore RX */ 80562306a36Sopenharmony_ci goto out; 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci val32 = 0x80007c00 | (reg_e94 &0x3ff0000) | 80862306a36Sopenharmony_ci ((reg_e9c & 0x3ff0000) >> 16); 80962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, val32); 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_ci /* 81262306a36Sopenharmony_ci * Modify RX IQK mode 81362306a36Sopenharmony_ci */ 81462306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 81562306a36Sopenharmony_ci val32 &= 0x000000ff; 81662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 81762306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); 81862306a36Sopenharmony_ci val32 |= 0x80000; 81962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); 82062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); 82162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0001f); 82262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7d77); 82362306a36Sopenharmony_ci 82462306a36Sopenharmony_ci /* 82562306a36Sopenharmony_ci * PA, PAD setting 82662306a36Sopenharmony_ci */ 82762306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0xf80); 82862306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_55, 0x4021f); 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci /* 83162306a36Sopenharmony_ci * RX IQK setting 83262306a36Sopenharmony_ci */ 83362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci /* path-A IQK setting */ 83662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); 83762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x18008c1c); 83862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_B, 0x38008c1c); 83962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_B, 0x38008c1c); 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82110000); 84262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x2816001f); 84362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_B, 0x82110000); 84462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_B, 0x28110000); 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci /* LO calibration setting */ 84762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a8d1); 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci /* 85062306a36Sopenharmony_ci * Enter IQK mode 85162306a36Sopenharmony_ci */ 85262306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 85362306a36Sopenharmony_ci val32 &= 0x000000ff; 85462306a36Sopenharmony_ci val32 |= 0x80800000; 85562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci if (priv->rf_paths > 1) 85862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000000); 85962306a36Sopenharmony_ci else 86062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00000280); 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci /* 86362306a36Sopenharmony_ci * Disable BT 86462306a36Sopenharmony_ci */ 86562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00000800); 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 86862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); 86962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci mdelay(1); 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_ci /* Restore Ant Path */ 87462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel); 87562306a36Sopenharmony_ci#ifdef RTL8723BU_BT 87662306a36Sopenharmony_ci /* GNT_BT = 1 */ 87762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, 0x00001800); 87862306a36Sopenharmony_ci#endif 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci /* 88162306a36Sopenharmony_ci * Leave IQK mode 88262306a36Sopenharmony_ci */ 88362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 88462306a36Sopenharmony_ci val32 &= 0x000000ff; 88562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_ci /* Check failed */ 88862306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 88962306a36Sopenharmony_ci reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x780); 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_ci val32 = (reg_eac >> 16) & 0x3ff; 89462306a36Sopenharmony_ci if (val32 & 0x200) 89562306a36Sopenharmony_ci val32 = 0x400 - val32; 89662306a36Sopenharmony_ci 89762306a36Sopenharmony_ci if (!(reg_eac & BIT(27)) && 89862306a36Sopenharmony_ci ((reg_ea4 & 0x03ff0000) != 0x01320000) && 89962306a36Sopenharmony_ci ((reg_eac & 0x03ff0000) != 0x00360000) && 90062306a36Sopenharmony_ci ((reg_ea4 & 0x03ff0000) < 0x01100000) && 90162306a36Sopenharmony_ci ((reg_ea4 & 0x03ff0000) > 0x00f00000) && 90262306a36Sopenharmony_ci val32 < 0xf) 90362306a36Sopenharmony_ci result |= 0x02; 90462306a36Sopenharmony_ci else /* If TX not OK, ignore RX */ 90562306a36Sopenharmony_ci goto out; 90662306a36Sopenharmony_ciout: 90762306a36Sopenharmony_ci return result; 90862306a36Sopenharmony_ci} 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_cistatic void rtl8723bu_phy_iqcalibrate(struct rtl8xxxu_priv *priv, 91162306a36Sopenharmony_ci int result[][8], int t) 91262306a36Sopenharmony_ci{ 91362306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 91462306a36Sopenharmony_ci u32 i, val32; 91562306a36Sopenharmony_ci int path_a_ok /*, path_b_ok */; 91662306a36Sopenharmony_ci int retry = 2; 91762306a36Sopenharmony_ci static const u32 adda_regs[RTL8XXXU_ADDA_REGS] = { 91862306a36Sopenharmony_ci REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH, 91962306a36Sopenharmony_ci REG_RX_WAIT_CCA, REG_TX_CCK_RFON, 92062306a36Sopenharmony_ci REG_TX_CCK_BBON, REG_TX_OFDM_RFON, 92162306a36Sopenharmony_ci REG_TX_OFDM_BBON, REG_TX_TO_RX, 92262306a36Sopenharmony_ci REG_TX_TO_TX, REG_RX_CCK, 92362306a36Sopenharmony_ci REG_RX_OFDM, REG_RX_WAIT_RIFS, 92462306a36Sopenharmony_ci REG_RX_TO_RX, REG_STANDBY, 92562306a36Sopenharmony_ci REG_SLEEP, REG_PMPD_ANAEN 92662306a36Sopenharmony_ci }; 92762306a36Sopenharmony_ci static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = { 92862306a36Sopenharmony_ci REG_TXPAUSE, REG_BEACON_CTRL, 92962306a36Sopenharmony_ci REG_BEACON_CTRL_1, REG_GPIO_MUXCFG 93062306a36Sopenharmony_ci }; 93162306a36Sopenharmony_ci static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = { 93262306a36Sopenharmony_ci REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR, 93362306a36Sopenharmony_ci REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B, 93462306a36Sopenharmony_ci REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE, 93562306a36Sopenharmony_ci REG_FPGA0_XB_RF_INT_OE, REG_FPGA0_RF_MODE 93662306a36Sopenharmony_ci }; 93762306a36Sopenharmony_ci u8 xa_agc = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1) & 0xff; 93862306a36Sopenharmony_ci u8 xb_agc = rtl8xxxu_read32(priv, REG_OFDM0_XB_AGC_CORE1) & 0xff; 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_ci /* 94162306a36Sopenharmony_ci * Note: IQ calibration must be performed after loading 94262306a36Sopenharmony_ci * PHY_REG.txt , and radio_a, radio_b.txt 94362306a36Sopenharmony_ci */ 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci if (t == 0) { 94662306a36Sopenharmony_ci /* Save ADDA parameters, turn Path A ADDA on */ 94762306a36Sopenharmony_ci rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup, 94862306a36Sopenharmony_ci RTL8XXXU_ADDA_REGS); 94962306a36Sopenharmony_ci rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup); 95062306a36Sopenharmony_ci rtl8xxxu_save_regs(priv, iqk_bb_regs, 95162306a36Sopenharmony_ci priv->bb_backup, RTL8XXXU_BB_REGS); 95262306a36Sopenharmony_ci } 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci rtl8xxxu_path_adda_on(priv, adda_regs, true); 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci /* MAC settings */ 95762306a36Sopenharmony_ci rtl8xxxu_mac_calibration(priv, iqk_mac_regs, priv->mac_backup); 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_CCK0_AFE_SETTING); 96062306a36Sopenharmony_ci val32 |= 0x0f000000; 96162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_AFE_SETTING, val32); 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05600); 96462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4); 96562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x22204000); 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci /* 96862306a36Sopenharmony_ci * RX IQ calibration setting for 8723B D cut large current issue 96962306a36Sopenharmony_ci * when leaving IPS 97062306a36Sopenharmony_ci */ 97162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 97262306a36Sopenharmony_ci val32 &= 0x000000ff; 97362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); 97662306a36Sopenharmony_ci val32 |= 0x80000; 97762306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); 97862306a36Sopenharmony_ci 97962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); 98062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0001f); 98162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7fb7); 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_ED); 98462306a36Sopenharmony_ci val32 |= 0x20; 98562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_ED, val32); 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_43, 0x60fbd); 98862306a36Sopenharmony_ci 98962306a36Sopenharmony_ci for (i = 0; i < retry; i++) { 99062306a36Sopenharmony_ci path_a_ok = rtl8723bu_iqk_path_a(priv); 99162306a36Sopenharmony_ci if (path_a_ok == 0x01) { 99262306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 99362306a36Sopenharmony_ci val32 &= 0x000000ff; 99462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 99762306a36Sopenharmony_ci REG_TX_POWER_BEFORE_IQK_A); 99862306a36Sopenharmony_ci result[t][0] = (val32 >> 16) & 0x3ff; 99962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 100062306a36Sopenharmony_ci REG_TX_POWER_AFTER_IQK_A); 100162306a36Sopenharmony_ci result[t][1] = (val32 >> 16) & 0x3ff; 100262306a36Sopenharmony_ci 100362306a36Sopenharmony_ci break; 100462306a36Sopenharmony_ci } 100562306a36Sopenharmony_ci } 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_ci if (!path_a_ok) 100862306a36Sopenharmony_ci dev_dbg(dev, "%s: Path A TX IQK failed!\n", __func__); 100962306a36Sopenharmony_ci 101062306a36Sopenharmony_ci for (i = 0; i < retry; i++) { 101162306a36Sopenharmony_ci path_a_ok = rtl8723bu_rx_iqk_path_a(priv); 101262306a36Sopenharmony_ci if (path_a_ok == 0x03) { 101362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 101462306a36Sopenharmony_ci REG_RX_POWER_BEFORE_IQK_A_2); 101562306a36Sopenharmony_ci result[t][2] = (val32 >> 16) & 0x3ff; 101662306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 101762306a36Sopenharmony_ci REG_RX_POWER_AFTER_IQK_A_2); 101862306a36Sopenharmony_ci result[t][3] = (val32 >> 16) & 0x3ff; 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_ci break; 102162306a36Sopenharmony_ci } 102262306a36Sopenharmony_ci } 102362306a36Sopenharmony_ci 102462306a36Sopenharmony_ci if (!path_a_ok) 102562306a36Sopenharmony_ci dev_dbg(dev, "%s: Path A RX IQK failed!\n", __func__); 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci if (priv->tx_paths > 1) { 102862306a36Sopenharmony_ci#if 1 102962306a36Sopenharmony_ci dev_warn(dev, "%s: Path B not supported\n", __func__); 103062306a36Sopenharmony_ci#else 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_ci /* 103362306a36Sopenharmony_ci * Path A into standby 103462306a36Sopenharmony_ci */ 103562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 103662306a36Sopenharmony_ci val32 &= 0x000000ff; 103762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 103862306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0x10000); 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 104162306a36Sopenharmony_ci val32 &= 0x000000ff; 104262306a36Sopenharmony_ci val32 |= 0x80800000; 104362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 104462306a36Sopenharmony_ci 104562306a36Sopenharmony_ci /* Turn Path B ADDA on */ 104662306a36Sopenharmony_ci rtl8xxxu_path_adda_on(priv, adda_regs, false); 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_ci for (i = 0; i < retry; i++) { 104962306a36Sopenharmony_ci path_b_ok = rtl8xxxu_iqk_path_b(priv); 105062306a36Sopenharmony_ci if (path_b_ok == 0x03) { 105162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_B); 105262306a36Sopenharmony_ci result[t][4] = (val32 >> 16) & 0x3ff; 105362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_B); 105462306a36Sopenharmony_ci result[t][5] = (val32 >> 16) & 0x3ff; 105562306a36Sopenharmony_ci break; 105662306a36Sopenharmony_ci } 105762306a36Sopenharmony_ci } 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci if (!path_b_ok) 106062306a36Sopenharmony_ci dev_dbg(dev, "%s: Path B IQK failed!\n", __func__); 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_ci for (i = 0; i < retry; i++) { 106362306a36Sopenharmony_ci path_b_ok = rtl8723bu_rx_iqk_path_b(priv); 106462306a36Sopenharmony_ci if (path_a_ok == 0x03) { 106562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 106662306a36Sopenharmony_ci REG_RX_POWER_BEFORE_IQK_B_2); 106762306a36Sopenharmony_ci result[t][6] = (val32 >> 16) & 0x3ff; 106862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, 106962306a36Sopenharmony_ci REG_RX_POWER_AFTER_IQK_B_2); 107062306a36Sopenharmony_ci result[t][7] = (val32 >> 16) & 0x3ff; 107162306a36Sopenharmony_ci break; 107262306a36Sopenharmony_ci } 107362306a36Sopenharmony_ci } 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci if (!path_b_ok) 107662306a36Sopenharmony_ci dev_dbg(dev, "%s: Path B RX IQK failed!\n", __func__); 107762306a36Sopenharmony_ci#endif 107862306a36Sopenharmony_ci } 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_ci /* Back to BB mode, load original value */ 108162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 108262306a36Sopenharmony_ci val32 &= 0x000000ff; 108362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 108462306a36Sopenharmony_ci 108562306a36Sopenharmony_ci if (t) { 108662306a36Sopenharmony_ci /* Reload ADDA power saving parameters */ 108762306a36Sopenharmony_ci rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup, 108862306a36Sopenharmony_ci RTL8XXXU_ADDA_REGS); 108962306a36Sopenharmony_ci 109062306a36Sopenharmony_ci /* Reload MAC parameters */ 109162306a36Sopenharmony_ci rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup); 109262306a36Sopenharmony_ci 109362306a36Sopenharmony_ci /* Reload BB parameters */ 109462306a36Sopenharmony_ci rtl8xxxu_restore_regs(priv, iqk_bb_regs, 109562306a36Sopenharmony_ci priv->bb_backup, RTL8XXXU_BB_REGS); 109662306a36Sopenharmony_ci 109762306a36Sopenharmony_ci /* Restore RX initial gain */ 109862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); 109962306a36Sopenharmony_ci val32 &= 0xffffff00; 110062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32 | 0x50); 110162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32 | xa_agc); 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci if (priv->tx_paths > 1) { 110462306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_XB_AGC_CORE1); 110562306a36Sopenharmony_ci val32 &= 0xffffff00; 110662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XB_AGC_CORE1, 110762306a36Sopenharmony_ci val32 | 0x50); 110862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XB_AGC_CORE1, 110962306a36Sopenharmony_ci val32 | xb_agc); 111062306a36Sopenharmony_ci } 111162306a36Sopenharmony_ci 111262306a36Sopenharmony_ci /* Load 0xe30 IQC default value */ 111362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00); 111462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00); 111562306a36Sopenharmony_ci } 111662306a36Sopenharmony_ci} 111762306a36Sopenharmony_ci 111862306a36Sopenharmony_cistatic void rtl8723bu_phy_iq_calibrate(struct rtl8xxxu_priv *priv) 111962306a36Sopenharmony_ci{ 112062306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 112162306a36Sopenharmony_ci int result[4][8]; /* last is final result */ 112262306a36Sopenharmony_ci int i, candidate; 112362306a36Sopenharmony_ci bool path_a_ok, path_b_ok; 112462306a36Sopenharmony_ci u32 reg_e94, reg_e9c, reg_ea4, reg_eac; 112562306a36Sopenharmony_ci u32 reg_eb4, reg_ebc, reg_ec4, reg_ecc; 112662306a36Sopenharmony_ci u32 val32, bt_control; 112762306a36Sopenharmony_ci s32 reg_tmp = 0; 112862306a36Sopenharmony_ci bool simu; 112962306a36Sopenharmony_ci 113062306a36Sopenharmony_ci rtl8xxxu_gen2_prepare_calibrate(priv, 1); 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_ci memset(result, 0, sizeof(result)); 113362306a36Sopenharmony_ci candidate = -1; 113462306a36Sopenharmony_ci 113562306a36Sopenharmony_ci path_a_ok = false; 113662306a36Sopenharmony_ci path_b_ok = false; 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_ci bt_control = rtl8xxxu_read32(priv, REG_BT_CONTROL_8723BU); 113962306a36Sopenharmony_ci 114062306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 114162306a36Sopenharmony_ci rtl8723bu_phy_iqcalibrate(priv, result, i); 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci if (i == 1) { 114462306a36Sopenharmony_ci simu = rtl8xxxu_gen2_simularity_compare(priv, 114562306a36Sopenharmony_ci result, 0, 1); 114662306a36Sopenharmony_ci if (simu) { 114762306a36Sopenharmony_ci candidate = 0; 114862306a36Sopenharmony_ci break; 114962306a36Sopenharmony_ci } 115062306a36Sopenharmony_ci } 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci if (i == 2) { 115362306a36Sopenharmony_ci simu = rtl8xxxu_gen2_simularity_compare(priv, 115462306a36Sopenharmony_ci result, 0, 2); 115562306a36Sopenharmony_ci if (simu) { 115662306a36Sopenharmony_ci candidate = 0; 115762306a36Sopenharmony_ci break; 115862306a36Sopenharmony_ci } 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_ci simu = rtl8xxxu_gen2_simularity_compare(priv, 116162306a36Sopenharmony_ci result, 1, 2); 116262306a36Sopenharmony_ci if (simu) { 116362306a36Sopenharmony_ci candidate = 1; 116462306a36Sopenharmony_ci } else { 116562306a36Sopenharmony_ci for (i = 0; i < 8; i++) 116662306a36Sopenharmony_ci reg_tmp += result[3][i]; 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_ci if (reg_tmp) 116962306a36Sopenharmony_ci candidate = 3; 117062306a36Sopenharmony_ci else 117162306a36Sopenharmony_ci candidate = -1; 117262306a36Sopenharmony_ci } 117362306a36Sopenharmony_ci } 117462306a36Sopenharmony_ci } 117562306a36Sopenharmony_ci 117662306a36Sopenharmony_ci for (i = 0; i < 4; i++) { 117762306a36Sopenharmony_ci reg_e94 = result[i][0]; 117862306a36Sopenharmony_ci reg_e9c = result[i][1]; 117962306a36Sopenharmony_ci reg_ea4 = result[i][2]; 118062306a36Sopenharmony_ci reg_eac = result[i][3]; 118162306a36Sopenharmony_ci reg_eb4 = result[i][4]; 118262306a36Sopenharmony_ci reg_ebc = result[i][5]; 118362306a36Sopenharmony_ci reg_ec4 = result[i][6]; 118462306a36Sopenharmony_ci reg_ecc = result[i][7]; 118562306a36Sopenharmony_ci } 118662306a36Sopenharmony_ci 118762306a36Sopenharmony_ci if (candidate >= 0) { 118862306a36Sopenharmony_ci reg_e94 = result[candidate][0]; 118962306a36Sopenharmony_ci priv->rege94 = reg_e94; 119062306a36Sopenharmony_ci reg_e9c = result[candidate][1]; 119162306a36Sopenharmony_ci priv->rege9c = reg_e9c; 119262306a36Sopenharmony_ci reg_ea4 = result[candidate][2]; 119362306a36Sopenharmony_ci reg_eac = result[candidate][3]; 119462306a36Sopenharmony_ci reg_eb4 = result[candidate][4]; 119562306a36Sopenharmony_ci priv->regeb4 = reg_eb4; 119662306a36Sopenharmony_ci reg_ebc = result[candidate][5]; 119762306a36Sopenharmony_ci priv->regebc = reg_ebc; 119862306a36Sopenharmony_ci reg_ec4 = result[candidate][6]; 119962306a36Sopenharmony_ci reg_ecc = result[candidate][7]; 120062306a36Sopenharmony_ci dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate); 120162306a36Sopenharmony_ci dev_dbg(dev, 120262306a36Sopenharmony_ci "%s: e94 =%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x ecc=%x\n", 120362306a36Sopenharmony_ci __func__, reg_e94, reg_e9c, 120462306a36Sopenharmony_ci reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc); 120562306a36Sopenharmony_ci path_a_ok = true; 120662306a36Sopenharmony_ci path_b_ok = true; 120762306a36Sopenharmony_ci } else { 120862306a36Sopenharmony_ci reg_e94 = reg_eb4 = priv->rege94 = priv->regeb4 = 0x100; 120962306a36Sopenharmony_ci reg_e9c = reg_ebc = priv->rege9c = priv->regebc = 0x0; 121062306a36Sopenharmony_ci } 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci if (reg_e94 && candidate >= 0) 121362306a36Sopenharmony_ci rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result, 121462306a36Sopenharmony_ci candidate, (reg_ea4 == 0)); 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_ci if (priv->tx_paths > 1 && reg_eb4) 121762306a36Sopenharmony_ci rtl8xxxu_fill_iqk_matrix_b(priv, path_b_ok, result, 121862306a36Sopenharmony_ci candidate, (reg_ec4 == 0)); 121962306a36Sopenharmony_ci 122062306a36Sopenharmony_ci rtl8xxxu_save_regs(priv, rtl8xxxu_iqk_phy_iq_bb_reg, 122162306a36Sopenharmony_ci priv->bb_recovery_backup, RTL8XXXU_BB_REGS); 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_BT_CONTROL_8723BU, bt_control); 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); 122662306a36Sopenharmony_ci val32 |= 0x80000; 122762306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); 122862306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x18000); 122962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0001f); 123062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xe6177); 123162306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_ED); 123262306a36Sopenharmony_ci val32 |= 0x20; 123362306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_ED, val32); 123462306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, 0x43, 0x300bd); 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci if (priv->rf_paths > 1) 123762306a36Sopenharmony_ci dev_dbg(dev, "%s: 8723BU 2T not supported\n", __func__); 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_ci rtl8xxxu_gen2_prepare_calibrate(priv, 0); 124062306a36Sopenharmony_ci} 124162306a36Sopenharmony_ci 124262306a36Sopenharmony_cistatic int rtl8723bu_active_to_emu(struct rtl8xxxu_priv *priv) 124362306a36Sopenharmony_ci{ 124462306a36Sopenharmony_ci u8 val8; 124562306a36Sopenharmony_ci u16 val16; 124662306a36Sopenharmony_ci u32 val32; 124762306a36Sopenharmony_ci int count, ret = 0; 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_ci /* Turn off RF */ 125062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RF_CTRL, 0); 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_ci /* Enable rising edge triggering interrupt */ 125362306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_GPIO_INTM); 125462306a36Sopenharmony_ci val16 &= ~GPIO_INTM_EDGE_TRIG_IRQ; 125562306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_GPIO_INTM, val16); 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_ci /* Release WLON reset 0x04[16]= 1*/ 125862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); 125962306a36Sopenharmony_ci val32 |= APS_FSMCO_WLON_RESET; 126062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); 126162306a36Sopenharmony_ci 126262306a36Sopenharmony_ci /* 0x0005[1] = 1 turn off MAC by HW state machine*/ 126362306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 126462306a36Sopenharmony_ci val8 |= BIT(1); 126562306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ci for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { 126862306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 126962306a36Sopenharmony_ci if ((val8 & BIT(1)) == 0) 127062306a36Sopenharmony_ci break; 127162306a36Sopenharmony_ci udelay(10); 127262306a36Sopenharmony_ci } 127362306a36Sopenharmony_ci 127462306a36Sopenharmony_ci if (!count) { 127562306a36Sopenharmony_ci dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n", 127662306a36Sopenharmony_ci __func__); 127762306a36Sopenharmony_ci ret = -EBUSY; 127862306a36Sopenharmony_ci goto exit; 127962306a36Sopenharmony_ci } 128062306a36Sopenharmony_ci 128162306a36Sopenharmony_ci /* Enable BT control XTAL setting */ 128262306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_AFE_MISC); 128362306a36Sopenharmony_ci val8 &= ~AFE_MISC_WL_XTAL_CTRL; 128462306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_AFE_MISC, val8); 128562306a36Sopenharmony_ci 128662306a36Sopenharmony_ci /* 0x0000[5] = 1 analog Ips to digital, 1:isolation */ 128762306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); 128862306a36Sopenharmony_ci val8 |= SYS_ISO_ANALOG_IPS; 128962306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); 129062306a36Sopenharmony_ci 129162306a36Sopenharmony_ci /* 0x0020[0] = 0 disable LDOA12 MACRO block*/ 129262306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL); 129362306a36Sopenharmony_ci val8 &= ~LDOA15_ENABLE; 129462306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8); 129562306a36Sopenharmony_ci 129662306a36Sopenharmony_ciexit: 129762306a36Sopenharmony_ci return ret; 129862306a36Sopenharmony_ci} 129962306a36Sopenharmony_ci 130062306a36Sopenharmony_cistatic int rtl8723b_emu_to_active(struct rtl8xxxu_priv *priv) 130162306a36Sopenharmony_ci{ 130262306a36Sopenharmony_ci u8 val8; 130362306a36Sopenharmony_ci u32 val32; 130462306a36Sopenharmony_ci int count, ret = 0; 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci /* 0x20[0] = 1 enable LDOA12 MACRO block for all interface */ 130762306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL); 130862306a36Sopenharmony_ci val8 |= LDOA15_ENABLE; 130962306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8); 131062306a36Sopenharmony_ci 131162306a36Sopenharmony_ci /* 0x67[0] = 0 to disable BT_GPS_SEL pins*/ 131262306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, 0x0067); 131362306a36Sopenharmony_ci val8 &= ~BIT(4); 131462306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0x0067, val8); 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_ci mdelay(1); 131762306a36Sopenharmony_ci 131862306a36Sopenharmony_ci /* 0x00[5] = 0 release analog Ips to digital, 1:isolation */ 131962306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); 132062306a36Sopenharmony_ci val8 &= ~SYS_ISO_ANALOG_IPS; 132162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); 132262306a36Sopenharmony_ci 132362306a36Sopenharmony_ci /* Disable SW LPS 0x04[10]= 0 */ 132462306a36Sopenharmony_ci val32 = rtl8xxxu_read8(priv, REG_APS_FSMCO); 132562306a36Sopenharmony_ci val32 &= ~APS_FSMCO_SW_LPS; 132662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); 132762306a36Sopenharmony_ci 132862306a36Sopenharmony_ci /* Wait until 0x04[17] = 1 power ready */ 132962306a36Sopenharmony_ci for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { 133062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); 133162306a36Sopenharmony_ci if (val32 & BIT(17)) 133262306a36Sopenharmony_ci break; 133362306a36Sopenharmony_ci 133462306a36Sopenharmony_ci udelay(10); 133562306a36Sopenharmony_ci } 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci if (!count) { 133862306a36Sopenharmony_ci ret = -EBUSY; 133962306a36Sopenharmony_ci goto exit; 134062306a36Sopenharmony_ci } 134162306a36Sopenharmony_ci 134262306a36Sopenharmony_ci /* We should be able to optimize the following three entries into one */ 134362306a36Sopenharmony_ci 134462306a36Sopenharmony_ci /* Release WLON reset 0x04[16]= 1*/ 134562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); 134662306a36Sopenharmony_ci val32 |= APS_FSMCO_WLON_RESET; 134762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); 134862306a36Sopenharmony_ci 134962306a36Sopenharmony_ci /* Disable HWPDN 0x04[15]= 0*/ 135062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); 135162306a36Sopenharmony_ci val32 &= ~APS_FSMCO_HW_POWERDOWN; 135262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci /* Disable WL suspend*/ 135562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); 135662306a36Sopenharmony_ci val32 &= ~(APS_FSMCO_HW_SUSPEND | APS_FSMCO_PCIE); 135762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_ci /* Set, then poll until 0 */ 136062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); 136162306a36Sopenharmony_ci val32 |= APS_FSMCO_MAC_ENABLE; 136262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_APS_FSMCO, val32); 136362306a36Sopenharmony_ci 136462306a36Sopenharmony_ci for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { 136562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO); 136662306a36Sopenharmony_ci if ((val32 & APS_FSMCO_MAC_ENABLE) == 0) { 136762306a36Sopenharmony_ci ret = 0; 136862306a36Sopenharmony_ci break; 136962306a36Sopenharmony_ci } 137062306a36Sopenharmony_ci udelay(10); 137162306a36Sopenharmony_ci } 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci if (!count) { 137462306a36Sopenharmony_ci ret = -EBUSY; 137562306a36Sopenharmony_ci goto exit; 137662306a36Sopenharmony_ci } 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_ci /* Enable WL control XTAL setting */ 137962306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_AFE_MISC); 138062306a36Sopenharmony_ci val8 |= AFE_MISC_WL_XTAL_CTRL; 138162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_AFE_MISC, val8); 138262306a36Sopenharmony_ci 138362306a36Sopenharmony_ci /* Enable falling edge triggering interrupt */ 138462306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 1); 138562306a36Sopenharmony_ci val8 |= BIT(1); 138662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_GPIO_INTM + 1, val8); 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci /* Enable GPIO9 interrupt mode */ 138962306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_GPIO_IO_SEL_2 + 1); 139062306a36Sopenharmony_ci val8 |= BIT(1); 139162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_GPIO_IO_SEL_2 + 1, val8); 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_ci /* Enable GPIO9 input mode */ 139462306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_GPIO_IO_SEL_2); 139562306a36Sopenharmony_ci val8 &= ~BIT(1); 139662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_GPIO_IO_SEL_2, val8); 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_ci /* Enable HSISR GPIO[C:0] interrupt */ 139962306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_HSIMR); 140062306a36Sopenharmony_ci val8 |= BIT(0); 140162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_HSIMR, val8); 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci /* Enable HSISR GPIO9 interrupt */ 140462306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_HSIMR + 2); 140562306a36Sopenharmony_ci val8 |= BIT(1); 140662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_HSIMR + 2, val8); 140762306a36Sopenharmony_ci 140862306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_MULTI_FUNC_CTRL); 140962306a36Sopenharmony_ci val8 |= MULTI_WIFI_HW_ROF_EN; 141062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_MULTI_FUNC_CTRL, val8); 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci /* For GPIO9 internal pull high setting BIT(14) */ 141362306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_MULTI_FUNC_CTRL + 1); 141462306a36Sopenharmony_ci val8 |= BIT(6); 141562306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_MULTI_FUNC_CTRL + 1, val8); 141662306a36Sopenharmony_ci 141762306a36Sopenharmony_ciexit: 141862306a36Sopenharmony_ci return ret; 141962306a36Sopenharmony_ci} 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_cistatic int rtl8723bu_power_on(struct rtl8xxxu_priv *priv) 142262306a36Sopenharmony_ci{ 142362306a36Sopenharmony_ci u8 val8; 142462306a36Sopenharmony_ci u16 val16; 142562306a36Sopenharmony_ci u32 val32; 142662306a36Sopenharmony_ci int ret; 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_ci rtl8xxxu_disabled_to_emu(priv); 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci ret = rtl8723b_emu_to_active(priv); 143162306a36Sopenharmony_ci if (ret) 143262306a36Sopenharmony_ci goto exit; 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_ci /* 143562306a36Sopenharmony_ci * Enable MAC DMA/WMAC/SCHEDULE/SEC block 143662306a36Sopenharmony_ci * Set CR bit10 to enable 32k calibration. 143762306a36Sopenharmony_ci */ 143862306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_CR); 143962306a36Sopenharmony_ci val16 |= (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | 144062306a36Sopenharmony_ci CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | 144162306a36Sopenharmony_ci CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE | 144262306a36Sopenharmony_ci CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE | 144362306a36Sopenharmony_ci CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE); 144462306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_CR, val16); 144562306a36Sopenharmony_ci 144662306a36Sopenharmony_ci /* 144762306a36Sopenharmony_ci * BT coexist power on settings. This is identical for 1 and 2 144862306a36Sopenharmony_ci * antenna parts. 144962306a36Sopenharmony_ci */ 145062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_PAD_CTRL1 + 3, 0x20); 145162306a36Sopenharmony_ci 145262306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); 145362306a36Sopenharmony_ci val16 |= SYS_FUNC_BBRSTB | SYS_FUNC_BB_GLB_RSTN; 145462306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); 145562306a36Sopenharmony_ci 145662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_BT_CONTROL_8723BU + 1, 0x18); 145762306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x04); 145862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00); 145962306a36Sopenharmony_ci /* Antenna inverse */ 146062306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0xfe08, 0x01); 146162306a36Sopenharmony_ci 146262306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_PWR_DATA); 146362306a36Sopenharmony_ci val16 |= PWR_DATA_EEPRPAD_RFE_CTRL_EN; 146462306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_PWR_DATA, val16); 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_LEDCFG0); 146762306a36Sopenharmony_ci val32 |= LEDCFG0_DPDT_SELECT; 146862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_LEDCFG0, val32); 146962306a36Sopenharmony_ci 147062306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_PAD_CTRL1); 147162306a36Sopenharmony_ci val8 &= ~PAD_CTRL1_SW_DPDT_SEL_DATA; 147262306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8); 147362306a36Sopenharmony_ciexit: 147462306a36Sopenharmony_ci return ret; 147562306a36Sopenharmony_ci} 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_cistatic void rtl8723bu_power_off(struct rtl8xxxu_priv *priv) 147862306a36Sopenharmony_ci{ 147962306a36Sopenharmony_ci u8 val8; 148062306a36Sopenharmony_ci u16 val16; 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci rtl8xxxu_flush_fifo(priv); 148362306a36Sopenharmony_ci 148462306a36Sopenharmony_ci /* 148562306a36Sopenharmony_ci * Disable TX report timer 148662306a36Sopenharmony_ci */ 148762306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_TX_REPORT_CTRL); 148862306a36Sopenharmony_ci val8 &= ~TX_REPORT_CTRL_TIMER_ENABLE; 148962306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL, val8); 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_CR, 0x0000); 149262306a36Sopenharmony_ci 149362306a36Sopenharmony_ci rtl8xxxu_active_to_lps(priv); 149462306a36Sopenharmony_ci 149562306a36Sopenharmony_ci /* Reset Firmware if running in RAM */ 149662306a36Sopenharmony_ci if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL) 149762306a36Sopenharmony_ci rtl8xxxu_firmware_self_reset(priv); 149862306a36Sopenharmony_ci 149962306a36Sopenharmony_ci /* Reset MCU */ 150062306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); 150162306a36Sopenharmony_ci val16 &= ~SYS_FUNC_CPU_ENABLE; 150262306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_ci /* Reset MCU ready status */ 150562306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); 150662306a36Sopenharmony_ci 150762306a36Sopenharmony_ci rtl8723bu_active_to_emu(priv); 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 151062306a36Sopenharmony_ci val8 |= BIT(3); /* APS_FSMCO_HW_SUSPEND */ 151162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci /* 0x48[16] = 1 to enable GPIO9 as EXT wakeup */ 151462306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2); 151562306a36Sopenharmony_ci val8 |= BIT(0); 151662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8); 151762306a36Sopenharmony_ci} 151862306a36Sopenharmony_ci 151962306a36Sopenharmony_cistatic void rtl8723b_enable_rf(struct rtl8xxxu_priv *priv) 152062306a36Sopenharmony_ci{ 152162306a36Sopenharmony_ci struct h2c_cmd h2c; 152262306a36Sopenharmony_ci u32 val32; 152362306a36Sopenharmony_ci u8 val8; 152462306a36Sopenharmony_ci 152562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_RX_WAIT_CCA); 152662306a36Sopenharmony_ci val32 |= (BIT(22) | BIT(23)); 152762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, val32); 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci /* 153062306a36Sopenharmony_ci * No indication anywhere as to what 0x0790 does. The 2 antenna 153162306a36Sopenharmony_ci * vendor code preserves bits 6-7 here. 153262306a36Sopenharmony_ci */ 153362306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0x0790, 0x05); 153462306a36Sopenharmony_ci /* 153562306a36Sopenharmony_ci * 0x0778 seems to be related to enabling the number of antennas 153662306a36Sopenharmony_ci * In the vendor driver halbtc8723b2ant_InitHwConfig() sets it 153762306a36Sopenharmony_ci * to 0x03, while halbtc8723b1ant_InitHwConfig() sets it to 0x01 153862306a36Sopenharmony_ci */ 153962306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0x0778, 0x01); 154062306a36Sopenharmony_ci 154162306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_GPIO_MUXCFG); 154262306a36Sopenharmony_ci val8 |= BIT(5); 154362306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_GPIO_MUXCFG, val8); 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_IQADJ_G1, 0x780); 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_ci rtl8723bu_write_btreg(priv, 0x3c, 0x15); /* BT TRx Mask on */ 154862306a36Sopenharmony_ci 154962306a36Sopenharmony_ci /* 155062306a36Sopenharmony_ci * Set BT grant to low 155162306a36Sopenharmony_ci */ 155262306a36Sopenharmony_ci memset(&h2c, 0, sizeof(struct h2c_cmd)); 155362306a36Sopenharmony_ci h2c.bt_grant.cmd = H2C_8723B_BT_GRANT; 155462306a36Sopenharmony_ci h2c.bt_grant.data = 0; 155562306a36Sopenharmony_ci rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.bt_grant)); 155662306a36Sopenharmony_ci 155762306a36Sopenharmony_ci /* 155862306a36Sopenharmony_ci * WLAN action by PTA 155962306a36Sopenharmony_ci */ 156062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x0c); 156162306a36Sopenharmony_ci 156262306a36Sopenharmony_ci /* 156362306a36Sopenharmony_ci * BT select S0/S1 controlled by WiFi 156462306a36Sopenharmony_ci */ 156562306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, 0x0067); 156662306a36Sopenharmony_ci val8 |= BIT(5); 156762306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0x0067, val8); 156862306a36Sopenharmony_ci 156962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_PWR_DATA); 157062306a36Sopenharmony_ci val32 |= PWR_DATA_EEPRPAD_RFE_CTRL_EN; 157162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_PWR_DATA, val32); 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_ci /* 157462306a36Sopenharmony_ci * Bits 6/7 are marked in/out ... but for what? 157562306a36Sopenharmony_ci */ 157662306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0x0974, 0xff); 157762306a36Sopenharmony_ci 157862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_RFE_BUFFER); 157962306a36Sopenharmony_ci val32 |= (BIT(0) | BIT(1)); 158062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RFE_BUFFER, val32); 158162306a36Sopenharmony_ci 158262306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RFE_CTRL_ANTA_SRC, 0x77); 158362306a36Sopenharmony_ci 158462306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_LEDCFG0); 158562306a36Sopenharmony_ci val32 &= ~BIT(24); 158662306a36Sopenharmony_ci val32 |= BIT(23); 158762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_LEDCFG0, val32); 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_ci /* 159062306a36Sopenharmony_ci * Fix external switch Main->S1, Aux->S0 159162306a36Sopenharmony_ci */ 159262306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_PAD_CTRL1); 159362306a36Sopenharmony_ci val8 &= ~BIT(0); 159462306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8); 159562306a36Sopenharmony_ci 159662306a36Sopenharmony_ci memset(&h2c, 0, sizeof(struct h2c_cmd)); 159762306a36Sopenharmony_ci h2c.ant_sel_rsv.cmd = H2C_8723B_ANT_SEL_RSV; 159862306a36Sopenharmony_ci h2c.ant_sel_rsv.ant_inverse = 1; 159962306a36Sopenharmony_ci h2c.ant_sel_rsv.int_switch_type = 0; 160062306a36Sopenharmony_ci rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.ant_sel_rsv)); 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci /* 160362306a36Sopenharmony_ci * Different settings per different antenna position. 160462306a36Sopenharmony_ci * Antenna Position: | Normal Inverse 160562306a36Sopenharmony_ci * -------------------------------------------------- 160662306a36Sopenharmony_ci * Antenna switch to BT: | 0x280, 0x00 160762306a36Sopenharmony_ci * Antenna switch to WiFi: | 0x0, 0x280 160862306a36Sopenharmony_ci * Antenna switch to PTA: | 0x200, 0x80 160962306a36Sopenharmony_ci */ 161062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x80); 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_ci /* 161362306a36Sopenharmony_ci * Software control, antenna at WiFi side 161462306a36Sopenharmony_ci */ 161562306a36Sopenharmony_ci rtl8723bu_set_ps_tdma(priv, 0x08, 0x00, 0x00, 0x00, 0x00); 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555); 161862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x55555555); 161962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); 162062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci memset(&h2c, 0, sizeof(struct h2c_cmd)); 162362306a36Sopenharmony_ci h2c.bt_info.cmd = H2C_8723B_BT_INFO; 162462306a36Sopenharmony_ci h2c.bt_info.data = BIT(0); 162562306a36Sopenharmony_ci rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.bt_info)); 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci memset(&h2c, 0, sizeof(struct h2c_cmd)); 162862306a36Sopenharmony_ci h2c.ignore_wlan.cmd = H2C_8723B_BT_IGNORE_WLANACT; 162962306a36Sopenharmony_ci h2c.ignore_wlan.data = 0; 163062306a36Sopenharmony_ci rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.ignore_wlan)); 163162306a36Sopenharmony_ci} 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_cistatic void rtl8723bu_init_aggregation(struct rtl8xxxu_priv *priv) 163462306a36Sopenharmony_ci{ 163562306a36Sopenharmony_ci u32 agg_rx; 163662306a36Sopenharmony_ci u8 agg_ctrl; 163762306a36Sopenharmony_ci 163862306a36Sopenharmony_ci /* 163962306a36Sopenharmony_ci * For now simply disable RX aggregation 164062306a36Sopenharmony_ci */ 164162306a36Sopenharmony_ci agg_ctrl = rtl8xxxu_read8(priv, REG_TRXDMA_CTRL); 164262306a36Sopenharmony_ci agg_ctrl &= ~TRXDMA_CTRL_RXDMA_AGG_EN; 164362306a36Sopenharmony_ci 164462306a36Sopenharmony_ci agg_rx = rtl8xxxu_read32(priv, REG_RXDMA_AGG_PG_TH); 164562306a36Sopenharmony_ci agg_rx &= ~RXDMA_USB_AGG_ENABLE; 164662306a36Sopenharmony_ci agg_rx &= ~0xff0f; 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); 164962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RXDMA_AGG_PG_TH, agg_rx); 165062306a36Sopenharmony_ci} 165162306a36Sopenharmony_ci 165262306a36Sopenharmony_cistatic void rtl8723bu_init_statistics(struct rtl8xxxu_priv *priv) 165362306a36Sopenharmony_ci{ 165462306a36Sopenharmony_ci u32 val32; 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_ci /* Time duration for NHM unit: 4us, 0x2710=40ms */ 165762306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_NHM_TIMER_8723B + 2, 0x2710); 165862306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_NHM_TH9_TH10_8723B + 2, 0xffff); 165962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_NHM_TH3_TO_TH0_8723B, 0xffffff52); 166062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_NHM_TH7_TO_TH4_8723B, 0xffffffff); 166162306a36Sopenharmony_ci /* TH8 */ 166262306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 166362306a36Sopenharmony_ci val32 |= 0xff; 166462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 166562306a36Sopenharmony_ci /* Enable CCK */ 166662306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_NHM_TH9_TH10_8723B); 166762306a36Sopenharmony_ci val32 |= BIT(8) | BIT(9) | BIT(10); 166862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_NHM_TH9_TH10_8723B, val32); 166962306a36Sopenharmony_ci /* Max power amongst all RX antennas */ 167062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_FA_RSTC); 167162306a36Sopenharmony_ci val32 |= BIT(7); 167262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_FA_RSTC, val32); 167362306a36Sopenharmony_ci} 167462306a36Sopenharmony_ci 167562306a36Sopenharmony_cistatic s8 rtl8723b_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats) 167662306a36Sopenharmony_ci{ 167762306a36Sopenharmony_ci u8 cck_agc_rpt = phy_stats->cck_agc_rpt_ofdm_cfosho_a; 167862306a36Sopenharmony_ci s8 rx_pwr_all = 0x00; 167962306a36Sopenharmony_ci u8 vga_idx, lna_idx; 168062306a36Sopenharmony_ci 168162306a36Sopenharmony_ci lna_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_LNA_IDX_MASK); 168262306a36Sopenharmony_ci vga_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_VGA_IDX_MASK); 168362306a36Sopenharmony_ci 168462306a36Sopenharmony_ci switch (lna_idx) { 168562306a36Sopenharmony_ci case 6: 168662306a36Sopenharmony_ci rx_pwr_all = -34 - (2 * vga_idx); 168762306a36Sopenharmony_ci break; 168862306a36Sopenharmony_ci case 4: 168962306a36Sopenharmony_ci rx_pwr_all = -14 - (2 * vga_idx); 169062306a36Sopenharmony_ci break; 169162306a36Sopenharmony_ci case 1: 169262306a36Sopenharmony_ci rx_pwr_all = 6 - (2 * vga_idx); 169362306a36Sopenharmony_ci break; 169462306a36Sopenharmony_ci case 0: 169562306a36Sopenharmony_ci rx_pwr_all = 16 - (2 * vga_idx); 169662306a36Sopenharmony_ci break; 169762306a36Sopenharmony_ci default: 169862306a36Sopenharmony_ci break; 169962306a36Sopenharmony_ci } 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ci return rx_pwr_all; 170262306a36Sopenharmony_ci} 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_cistruct rtl8xxxu_fileops rtl8723bu_fops = { 170562306a36Sopenharmony_ci .identify_chip = rtl8723bu_identify_chip, 170662306a36Sopenharmony_ci .parse_efuse = rtl8723bu_parse_efuse, 170762306a36Sopenharmony_ci .load_firmware = rtl8723bu_load_firmware, 170862306a36Sopenharmony_ci .power_on = rtl8723bu_power_on, 170962306a36Sopenharmony_ci .power_off = rtl8723bu_power_off, 171062306a36Sopenharmony_ci .read_efuse = rtl8xxxu_read_efuse, 171162306a36Sopenharmony_ci .reset_8051 = rtl8723bu_reset_8051, 171262306a36Sopenharmony_ci .llt_init = rtl8xxxu_auto_llt_table, 171362306a36Sopenharmony_ci .init_phy_bb = rtl8723bu_init_phy_bb, 171462306a36Sopenharmony_ci .init_phy_rf = rtl8723bu_init_phy_rf, 171562306a36Sopenharmony_ci .phy_init_antenna_selection = rtl8723bu_phy_init_antenna_selection, 171662306a36Sopenharmony_ci .phy_lc_calibrate = rtl8723a_phy_lc_calibrate, 171762306a36Sopenharmony_ci .phy_iq_calibrate = rtl8723bu_phy_iq_calibrate, 171862306a36Sopenharmony_ci .config_channel = rtl8xxxu_gen2_config_channel, 171962306a36Sopenharmony_ci .parse_rx_desc = rtl8xxxu_parse_rxdesc24, 172062306a36Sopenharmony_ci .parse_phystats = rtl8723au_rx_parse_phystats, 172162306a36Sopenharmony_ci .init_aggregation = rtl8723bu_init_aggregation, 172262306a36Sopenharmony_ci .init_statistics = rtl8723bu_init_statistics, 172362306a36Sopenharmony_ci .init_burst = rtl8xxxu_init_burst, 172462306a36Sopenharmony_ci .enable_rf = rtl8723b_enable_rf, 172562306a36Sopenharmony_ci .disable_rf = rtl8xxxu_gen2_disable_rf, 172662306a36Sopenharmony_ci .usb_quirks = rtl8xxxu_gen2_usb_quirks, 172762306a36Sopenharmony_ci .set_tx_power = rtl8723b_set_tx_power, 172862306a36Sopenharmony_ci .update_rate_mask = rtl8xxxu_gen2_update_rate_mask, 172962306a36Sopenharmony_ci .report_connect = rtl8xxxu_gen2_report_connect, 173062306a36Sopenharmony_ci .report_rssi = rtl8xxxu_gen2_report_rssi, 173162306a36Sopenharmony_ci .fill_txdesc = rtl8xxxu_fill_txdesc_v2, 173262306a36Sopenharmony_ci .set_crystal_cap = rtl8723a_set_crystal_cap, 173362306a36Sopenharmony_ci .cck_rssi = rtl8723b_cck_rssi, 173462306a36Sopenharmony_ci .writeN_block_size = 1024, 173562306a36Sopenharmony_ci .tx_desc_size = sizeof(struct rtl8xxxu_txdesc40), 173662306a36Sopenharmony_ci .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), 173762306a36Sopenharmony_ci .has_s0s1 = 1, 173862306a36Sopenharmony_ci .has_tx_report = 1, 173962306a36Sopenharmony_ci .gen2_thermal_meter = 1, 174062306a36Sopenharmony_ci .needs_full_init = 1, 174162306a36Sopenharmony_ci .init_reg_hmtfr = 1, 174262306a36Sopenharmony_ci .ampdu_max_time = 0x5e, 174362306a36Sopenharmony_ci .ustime_tsf_edca = 0x50, 174462306a36Sopenharmony_ci .max_aggr_num = 0x0c14, 174562306a36Sopenharmony_ci .supports_ap = 1, 174662306a36Sopenharmony_ci .max_macid_num = 128, 174762306a36Sopenharmony_ci .adda_1t_init = 0x01c00014, 174862306a36Sopenharmony_ci .adda_1t_path_on = 0x01c00014, 174962306a36Sopenharmony_ci .adda_2t_path_on_a = 0x01c00014, 175062306a36Sopenharmony_ci .adda_2t_path_on_b = 0x01c00014, 175162306a36Sopenharmony_ci .trxff_boundary = 0x3f7f, 175262306a36Sopenharmony_ci .pbp_rx = PBP_PAGE_SIZE_256, 175362306a36Sopenharmony_ci .pbp_tx = PBP_PAGE_SIZE_256, 175462306a36Sopenharmony_ci .mactable = rtl8723b_mac_init_table, 175562306a36Sopenharmony_ci .total_page_num = TX_TOTAL_PAGE_NUM_8723B, 175662306a36Sopenharmony_ci .page_num_hi = TX_PAGE_NUM_HI_PQ_8723B, 175762306a36Sopenharmony_ci .page_num_lo = TX_PAGE_NUM_LO_PQ_8723B, 175862306a36Sopenharmony_ci .page_num_norm = TX_PAGE_NUM_NORM_PQ_8723B, 175962306a36Sopenharmony_ci}; 1760