162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * RTL8XXXU mac80211 USB driver - 8710bu aka 8188gu specific subdriver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2023 Bitterblue Smith <rtl8821cerfe2@gmail.com> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Portions copied from existing rtl8xxxu code: 862306a36Sopenharmony_ci * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com> 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Portions, notably calibration code: 1162306a36Sopenharmony_ci * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/init.h> 1562306a36Sopenharmony_ci#include <linux/kernel.h> 1662306a36Sopenharmony_ci#include <linux/sched.h> 1762306a36Sopenharmony_ci#include <linux/errno.h> 1862306a36Sopenharmony_ci#include <linux/slab.h> 1962306a36Sopenharmony_ci#include <linux/module.h> 2062306a36Sopenharmony_ci#include <linux/spinlock.h> 2162306a36Sopenharmony_ci#include <linux/list.h> 2262306a36Sopenharmony_ci#include <linux/usb.h> 2362306a36Sopenharmony_ci#include <linux/netdevice.h> 2462306a36Sopenharmony_ci#include <linux/etherdevice.h> 2562306a36Sopenharmony_ci#include <linux/ethtool.h> 2662306a36Sopenharmony_ci#include <linux/wireless.h> 2762306a36Sopenharmony_ci#include <linux/firmware.h> 2862306a36Sopenharmony_ci#include <linux/moduleparam.h> 2962306a36Sopenharmony_ci#include <net/mac80211.h> 3062306a36Sopenharmony_ci#include "rtl8xxxu.h" 3162306a36Sopenharmony_ci#include "rtl8xxxu_regs.h" 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistatic const struct rtl8xxxu_reg8val rtl8710b_mac_init_table[] = { 3462306a36Sopenharmony_ci {0x421, 0x0F}, {0x428, 0x0A}, {0x429, 0x10}, {0x430, 0x00}, 3562306a36Sopenharmony_ci {0x431, 0x00}, {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04}, 3662306a36Sopenharmony_ci {0x435, 0x05}, {0x436, 0x07}, {0x437, 0x08}, {0x43C, 0x04}, 3762306a36Sopenharmony_ci {0x43D, 0x05}, {0x43E, 0x07}, {0x43F, 0x08}, {0x440, 0x5D}, 3862306a36Sopenharmony_ci {0x441, 0x01}, {0x442, 0x00}, {0x444, 0x10}, {0x445, 0x00}, 3962306a36Sopenharmony_ci {0x446, 0x00}, {0x447, 0x00}, {0x448, 0x00}, {0x449, 0xF0}, 4062306a36Sopenharmony_ci {0x44A, 0x0F}, {0x44B, 0x3E}, {0x44C, 0x10}, {0x44D, 0x00}, 4162306a36Sopenharmony_ci {0x44E, 0x00}, {0x44F, 0x00}, {0x450, 0x00}, {0x451, 0xF0}, 4262306a36Sopenharmony_ci {0x452, 0x0F}, {0x453, 0x00}, {0x456, 0x5E}, {0x460, 0x66}, 4362306a36Sopenharmony_ci {0x461, 0x66}, {0x4C8, 0xFF}, {0x4C9, 0x08}, {0x4CC, 0xFF}, 4462306a36Sopenharmony_ci {0x4CD, 0xFF}, {0x4CE, 0x01}, {0x500, 0x26}, {0x501, 0xA2}, 4562306a36Sopenharmony_ci {0x502, 0x2F}, {0x503, 0x00}, {0x504, 0x28}, {0x505, 0xA3}, 4662306a36Sopenharmony_ci {0x506, 0x5E}, {0x507, 0x00}, {0x508, 0x2B}, {0x509, 0xA4}, 4762306a36Sopenharmony_ci {0x50A, 0x5E}, {0x50B, 0x00}, {0x50C, 0x4F}, {0x50D, 0xA4}, 4862306a36Sopenharmony_ci {0x50E, 0x00}, {0x50F, 0x00}, {0x512, 0x1C}, {0x514, 0x0A}, 4962306a36Sopenharmony_ci {0x516, 0x0A}, {0x525, 0x4F}, {0x550, 0x10}, {0x551, 0x10}, 5062306a36Sopenharmony_ci {0x559, 0x02}, {0x55C, 0x28}, {0x55D, 0xFF}, {0x605, 0x30}, 5162306a36Sopenharmony_ci {0x608, 0x0E}, {0x609, 0x2A}, {0x620, 0xFF}, {0x621, 0xFF}, 5262306a36Sopenharmony_ci {0x622, 0xFF}, {0x623, 0xFF}, {0x624, 0xFF}, {0x625, 0xFF}, 5362306a36Sopenharmony_ci {0x626, 0xFF}, {0x627, 0xFF}, {0x638, 0x28}, {0x63C, 0x0A}, 5462306a36Sopenharmony_ci {0x63D, 0x0A}, {0x63E, 0x0C}, {0x63F, 0x0C}, {0x640, 0x40}, 5562306a36Sopenharmony_ci {0x642, 0x40}, {0x643, 0x00}, {0x652, 0xC8}, {0x66A, 0xB0}, 5662306a36Sopenharmony_ci {0x66E, 0x05}, {0x700, 0x21}, {0x701, 0x43}, {0x702, 0x65}, 5762306a36Sopenharmony_ci {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43}, {0x70A, 0x65}, 5862306a36Sopenharmony_ci {0x70B, 0x87}, 5962306a36Sopenharmony_ci {0xffff, 0xff}, 6062306a36Sopenharmony_ci}; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* If updating the phy init tables, also update rtl8710b_revise_cck_tx_psf(). */ 6362306a36Sopenharmony_cistatic const struct rtl8xxxu_reg32val rtl8710bu_qfn48m_u_phy_init_table[] = { 6462306a36Sopenharmony_ci {0x800, 0x80045700}, {0x804, 0x00000001}, 6562306a36Sopenharmony_ci {0x808, 0x00FC8000}, {0x80C, 0x0000000A}, 6662306a36Sopenharmony_ci {0x810, 0x10001331}, {0x814, 0x020C3D10}, 6762306a36Sopenharmony_ci {0x818, 0x00200385}, {0x81C, 0x00000000}, 6862306a36Sopenharmony_ci {0x820, 0x01000100}, {0x824, 0x00390204}, 6962306a36Sopenharmony_ci {0x828, 0x00000000}, {0x82C, 0x00000000}, 7062306a36Sopenharmony_ci {0x830, 0x00000000}, {0x834, 0x00000000}, 7162306a36Sopenharmony_ci {0x838, 0x00000000}, {0x83C, 0x00000000}, 7262306a36Sopenharmony_ci {0x840, 0x00010000}, {0x844, 0x00000000}, 7362306a36Sopenharmony_ci {0x848, 0x00000000}, {0x84C, 0x00000000}, 7462306a36Sopenharmony_ci {0x850, 0x00030000}, {0x854, 0x00000000}, 7562306a36Sopenharmony_ci {0x858, 0x7E1A569A}, {0x85C, 0x569A569A}, 7662306a36Sopenharmony_ci {0x860, 0x00000130}, {0x864, 0x20000000}, 7762306a36Sopenharmony_ci {0x868, 0x00000000}, {0x86C, 0x27272700}, 7862306a36Sopenharmony_ci {0x870, 0x00050000}, {0x874, 0x25005000}, 7962306a36Sopenharmony_ci {0x878, 0x00000808}, {0x87C, 0x004F0201}, 8062306a36Sopenharmony_ci {0x880, 0xB0000B1E}, {0x884, 0x00000007}, 8162306a36Sopenharmony_ci {0x888, 0x00000000}, {0x88C, 0xCCC400C0}, 8262306a36Sopenharmony_ci {0x890, 0x00000800}, {0x894, 0xFFFFFFFE}, 8362306a36Sopenharmony_ci {0x898, 0x40302010}, {0x89C, 0x00706050}, 8462306a36Sopenharmony_ci {0x900, 0x00000000}, {0x904, 0x00000023}, 8562306a36Sopenharmony_ci {0x908, 0x00000000}, {0x90C, 0x81121111}, 8662306a36Sopenharmony_ci {0x910, 0x00000402}, {0x914, 0x00000201}, 8762306a36Sopenharmony_ci {0x920, 0x18C6318C}, {0x924, 0x0000018C}, 8862306a36Sopenharmony_ci {0x948, 0x99000000}, {0x94C, 0x00000010}, 8962306a36Sopenharmony_ci {0x950, 0x00003000}, {0x954, 0x5A880000}, 9062306a36Sopenharmony_ci {0x958, 0x4BC6D87A}, {0x95C, 0x04EB9B79}, 9162306a36Sopenharmony_ci {0x96C, 0x00000003}, {0x970, 0x00000000}, 9262306a36Sopenharmony_ci {0x974, 0x00000000}, {0x978, 0x00000000}, 9362306a36Sopenharmony_ci {0x97C, 0x13000000}, {0x980, 0x00000000}, 9462306a36Sopenharmony_ci {0xA00, 0x00D046C8}, {0xA04, 0x80FF800C}, 9562306a36Sopenharmony_ci {0xA08, 0x84838300}, {0xA0C, 0x2E20100F}, 9662306a36Sopenharmony_ci {0xA10, 0x9500BB78}, {0xA14, 0x1114D028}, 9762306a36Sopenharmony_ci {0xA18, 0x00881117}, {0xA1C, 0x89140F00}, 9862306a36Sopenharmony_ci {0xA20, 0xE82C0001}, {0xA24, 0x64B80C1C}, 9962306a36Sopenharmony_ci {0xA28, 0x00008810}, {0xA2C, 0x00D30000}, 10062306a36Sopenharmony_ci {0xA70, 0x101FBF00}, {0xA74, 0x00000007}, 10162306a36Sopenharmony_ci {0xA78, 0x00000900}, {0xA7C, 0x225B0606}, 10262306a36Sopenharmony_ci {0xA80, 0x218075B1}, {0xA84, 0x00200000}, 10362306a36Sopenharmony_ci {0xA88, 0x040C0000}, {0xA8C, 0x12345678}, 10462306a36Sopenharmony_ci {0xA90, 0xABCDEF00}, {0xA94, 0x001B1B89}, 10562306a36Sopenharmony_ci {0xA98, 0x00000000}, {0xA9C, 0x80020000}, 10662306a36Sopenharmony_ci {0xAA0, 0x00000000}, {0xAA4, 0x0000000C}, 10762306a36Sopenharmony_ci {0xAA8, 0xCA110058}, {0xAAC, 0x01235667}, 10862306a36Sopenharmony_ci {0xAB0, 0x00000000}, {0xAB4, 0x20201402}, 10962306a36Sopenharmony_ci {0xB2C, 0x00000000}, {0xC00, 0x48071D40}, 11062306a36Sopenharmony_ci {0xC04, 0x03A05611}, {0xC08, 0x000000E4}, 11162306a36Sopenharmony_ci {0xC0C, 0x6C6C6C6C}, {0xC10, 0x18800000}, 11262306a36Sopenharmony_ci {0xC14, 0x40000100}, {0xC18, 0x08800000}, 11362306a36Sopenharmony_ci {0xC1C, 0x40000100}, {0xC20, 0x00000000}, 11462306a36Sopenharmony_ci {0xC24, 0x00000000}, {0xC28, 0x00000000}, 11562306a36Sopenharmony_ci {0xC2C, 0x00000000}, {0xC30, 0x69E9AC4A}, 11662306a36Sopenharmony_ci {0xC34, 0x31000040}, {0xC38, 0x21688080}, 11762306a36Sopenharmony_ci {0xC3C, 0x0000170C}, {0xC40, 0x1F78403F}, 11862306a36Sopenharmony_ci {0xC44, 0x00010036}, {0xC48, 0xEC020107}, 11962306a36Sopenharmony_ci {0xC4C, 0x007F037F}, {0xC50, 0x69553420}, 12062306a36Sopenharmony_ci {0xC54, 0x43BC0094}, {0xC58, 0x00013169}, 12162306a36Sopenharmony_ci {0xC5C, 0x00250492}, {0xC60, 0x00280A00}, 12262306a36Sopenharmony_ci {0xC64, 0x7112848B}, {0xC68, 0x47C074FF}, 12362306a36Sopenharmony_ci {0xC6C, 0x00000036}, {0xC70, 0x2C7F000D}, 12462306a36Sopenharmony_ci {0xC74, 0x020600DB}, {0xC78, 0x0000001F}, 12562306a36Sopenharmony_ci {0xC7C, 0x00B91612}, {0xC80, 0x390000E4}, 12662306a36Sopenharmony_ci {0xC84, 0x11F60000}, {0xC88, 0x1051B75F}, 12762306a36Sopenharmony_ci {0xC8C, 0x20200109}, {0xC90, 0x00091521}, 12862306a36Sopenharmony_ci {0xC94, 0x00000000}, {0xC98, 0x00121820}, 12962306a36Sopenharmony_ci {0xC9C, 0x00007F7F}, {0xCA0, 0x00011000}, 13062306a36Sopenharmony_ci {0xCA4, 0x800000A0}, {0xCA8, 0x84E6C606}, 13162306a36Sopenharmony_ci {0xCAC, 0x00000060}, {0xCB0, 0x00000000}, 13262306a36Sopenharmony_ci {0xCB4, 0x00000000}, {0xCB8, 0x00000000}, 13362306a36Sopenharmony_ci {0xCBC, 0x28000000}, {0xCC0, 0x1051B75F}, 13462306a36Sopenharmony_ci {0xCC4, 0x00000109}, {0xCC8, 0x000442D6}, 13562306a36Sopenharmony_ci {0xCCC, 0x00000000}, {0xCD0, 0x000001C8}, 13662306a36Sopenharmony_ci {0xCD4, 0x001C8000}, {0xCD8, 0x00000100}, 13762306a36Sopenharmony_ci {0xCDC, 0x40100000}, {0xCE0, 0x00222220}, 13862306a36Sopenharmony_ci {0xCE4, 0x10000000}, {0xCE8, 0x37644302}, 13962306a36Sopenharmony_ci {0xCEC, 0x2F97D40C}, {0xD00, 0x04030740}, 14062306a36Sopenharmony_ci {0xD04, 0x40020401}, {0xD08, 0x0000907F}, 14162306a36Sopenharmony_ci {0xD0C, 0x20010201}, {0xD10, 0xA0633333}, 14262306a36Sopenharmony_ci {0xD14, 0x3333BC53}, {0xD18, 0x7A8F5B6F}, 14362306a36Sopenharmony_ci {0xD2C, 0xCB979975}, {0xD30, 0x00000000}, 14462306a36Sopenharmony_ci {0xD34, 0x40608000}, {0xD38, 0x88000000}, 14562306a36Sopenharmony_ci {0xD3C, 0xC0127353}, {0xD40, 0x00000000}, 14662306a36Sopenharmony_ci {0xD44, 0x00000000}, {0xD48, 0x00000000}, 14762306a36Sopenharmony_ci {0xD4C, 0x00000000}, {0xD50, 0x00006528}, 14862306a36Sopenharmony_ci {0xD54, 0x00000000}, {0xD58, 0x00000282}, 14962306a36Sopenharmony_ci {0xD5C, 0x30032064}, {0xD60, 0x4653DE68}, 15062306a36Sopenharmony_ci {0xD64, 0x04518A3C}, {0xD68, 0x00002101}, 15162306a36Sopenharmony_ci {0xE00, 0x2D2D2D2D}, {0xE04, 0x2D2D2D2D}, 15262306a36Sopenharmony_ci {0xE08, 0x0390272D}, {0xE10, 0x2D2D2D2D}, 15362306a36Sopenharmony_ci {0xE14, 0x2D2D2D2D}, {0xE18, 0x2D2D2D2D}, 15462306a36Sopenharmony_ci {0xE1C, 0x2D2D2D2D}, {0xE28, 0x00000000}, 15562306a36Sopenharmony_ci {0xE30, 0x1000DC1F}, {0xE34, 0x10008C1F}, 15662306a36Sopenharmony_ci {0xE38, 0x02140102}, {0xE3C, 0x681604C2}, 15762306a36Sopenharmony_ci {0xE40, 0x01007C00}, {0xE44, 0x01004800}, 15862306a36Sopenharmony_ci {0xE48, 0xFB000000}, {0xE4C, 0x000028D1}, 15962306a36Sopenharmony_ci {0xE50, 0x1000DC1F}, {0xE54, 0x10008C1F}, 16062306a36Sopenharmony_ci {0xE58, 0x02140102}, {0xE5C, 0x28160D05}, 16162306a36Sopenharmony_ci {0xE60, 0x0000C008}, {0xE68, 0x001B25A4}, 16262306a36Sopenharmony_ci {0xE64, 0x281600A0}, {0xE6C, 0x01C00010}, 16362306a36Sopenharmony_ci {0xE70, 0x01C00010}, {0xE74, 0x02000010}, 16462306a36Sopenharmony_ci {0xE78, 0x02000010}, {0xE7C, 0x02000010}, 16562306a36Sopenharmony_ci {0xE80, 0x02000010}, {0xE84, 0x01C00010}, 16662306a36Sopenharmony_ci {0xE88, 0x02000010}, {0xE8C, 0x01C00010}, 16762306a36Sopenharmony_ci {0xED0, 0x01C00010}, {0xED4, 0x01C00010}, 16862306a36Sopenharmony_ci {0xED8, 0x01C00010}, {0xEDC, 0x00000010}, 16962306a36Sopenharmony_ci {0xEE0, 0x00000010}, {0xEEC, 0x03C00010}, 17062306a36Sopenharmony_ci {0xF14, 0x00000003}, {0xF00, 0x00100300}, 17162306a36Sopenharmony_ci {0xF08, 0x0000800B}, {0xF0C, 0x0000F007}, 17262306a36Sopenharmony_ci {0xF10, 0x0000A487}, {0xF1C, 0x80000064}, 17362306a36Sopenharmony_ci {0xF38, 0x00030155}, {0xF3C, 0x0000003A}, 17462306a36Sopenharmony_ci {0xF4C, 0x13000000}, {0xF50, 0x00000000}, 17562306a36Sopenharmony_ci {0xF18, 0x00000000}, 17662306a36Sopenharmony_ci {0xffff, 0xffffffff}, 17762306a36Sopenharmony_ci}; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci/* If updating the phy init tables, also update rtl8710b_revise_cck_tx_psf(). */ 18062306a36Sopenharmony_cistatic const struct rtl8xxxu_reg32val rtl8710bu_qfn48m_s_phy_init_table[] = { 18162306a36Sopenharmony_ci {0x800, 0x80045700}, {0x804, 0x00000001}, 18262306a36Sopenharmony_ci {0x808, 0x00FC8000}, {0x80C, 0x0000000A}, 18362306a36Sopenharmony_ci {0x810, 0x10001331}, {0x814, 0x020C3D10}, 18462306a36Sopenharmony_ci {0x818, 0x00200385}, {0x81C, 0x00000000}, 18562306a36Sopenharmony_ci {0x820, 0x01000100}, {0x824, 0x00390204}, 18662306a36Sopenharmony_ci {0x828, 0x00000000}, {0x82C, 0x00000000}, 18762306a36Sopenharmony_ci {0x830, 0x00000000}, {0x834, 0x00000000}, 18862306a36Sopenharmony_ci {0x838, 0x00000000}, {0x83C, 0x00000000}, 18962306a36Sopenharmony_ci {0x840, 0x00010000}, {0x844, 0x00000000}, 19062306a36Sopenharmony_ci {0x848, 0x00000000}, {0x84C, 0x00000000}, 19162306a36Sopenharmony_ci {0x850, 0x00030000}, {0x854, 0x00000000}, 19262306a36Sopenharmony_ci {0x858, 0x7E1A569A}, {0x85C, 0x569A569A}, 19362306a36Sopenharmony_ci {0x860, 0x00000130}, {0x864, 0x20000000}, 19462306a36Sopenharmony_ci {0x868, 0x00000000}, {0x86C, 0x27272700}, 19562306a36Sopenharmony_ci {0x870, 0x00050000}, {0x874, 0x25005000}, 19662306a36Sopenharmony_ci {0x878, 0x00000808}, {0x87C, 0x004F0201}, 19762306a36Sopenharmony_ci {0x880, 0xB0000B1E}, {0x884, 0x00000007}, 19862306a36Sopenharmony_ci {0x888, 0x00000000}, {0x88C, 0xCCC400C0}, 19962306a36Sopenharmony_ci {0x890, 0x00000800}, {0x894, 0xFFFFFFFE}, 20062306a36Sopenharmony_ci {0x898, 0x40302010}, {0x89C, 0x00706050}, 20162306a36Sopenharmony_ci {0x900, 0x00000000}, {0x904, 0x00000023}, 20262306a36Sopenharmony_ci {0x908, 0x00000000}, {0x90C, 0x81121111}, 20362306a36Sopenharmony_ci {0x910, 0x00000402}, {0x914, 0x00000201}, 20462306a36Sopenharmony_ci {0x920, 0x18C6318C}, {0x924, 0x0000018C}, 20562306a36Sopenharmony_ci {0x948, 0x99000000}, {0x94C, 0x00000010}, 20662306a36Sopenharmony_ci {0x950, 0x00003000}, {0x954, 0x5A880000}, 20762306a36Sopenharmony_ci {0x958, 0x4BC6D87A}, {0x95C, 0x04EB9B79}, 20862306a36Sopenharmony_ci {0x96C, 0x00000003}, {0x970, 0x00000000}, 20962306a36Sopenharmony_ci {0x974, 0x00000000}, {0x978, 0x00000000}, 21062306a36Sopenharmony_ci {0x97C, 0x13000000}, {0x980, 0x00000000}, 21162306a36Sopenharmony_ci {0xA00, 0x00D046C8}, {0xA04, 0x80FF800C}, 21262306a36Sopenharmony_ci {0xA08, 0x84838300}, {0xA0C, 0x2A20100F}, 21362306a36Sopenharmony_ci {0xA10, 0x9500BB78}, {0xA14, 0x1114D028}, 21462306a36Sopenharmony_ci {0xA18, 0x00881117}, {0xA1C, 0x89140F00}, 21562306a36Sopenharmony_ci {0xA20, 0xE82C0001}, {0xA24, 0x64B80C1C}, 21662306a36Sopenharmony_ci {0xA28, 0x00008810}, {0xA2C, 0x00D30000}, 21762306a36Sopenharmony_ci {0xA70, 0x101FBF00}, {0xA74, 0x00000007}, 21862306a36Sopenharmony_ci {0xA78, 0x00000900}, {0xA7C, 0x225B0606}, 21962306a36Sopenharmony_ci {0xA80, 0x218075B1}, {0xA84, 0x00200000}, 22062306a36Sopenharmony_ci {0xA88, 0x040C0000}, {0xA8C, 0x12345678}, 22162306a36Sopenharmony_ci {0xA90, 0xABCDEF00}, {0xA94, 0x001B1B89}, 22262306a36Sopenharmony_ci {0xA98, 0x00000000}, {0xA9C, 0x80020000}, 22362306a36Sopenharmony_ci {0xAA0, 0x00000000}, {0xAA4, 0x0000000C}, 22462306a36Sopenharmony_ci {0xAA8, 0xCA110058}, {0xAAC, 0x01235667}, 22562306a36Sopenharmony_ci {0xAB0, 0x00000000}, {0xAB4, 0x20201402}, 22662306a36Sopenharmony_ci {0xB2C, 0x00000000}, {0xC00, 0x48071D40}, 22762306a36Sopenharmony_ci {0xC04, 0x03A05611}, {0xC08, 0x000000E4}, 22862306a36Sopenharmony_ci {0xC0C, 0x6C6C6C6C}, {0xC10, 0x18800000}, 22962306a36Sopenharmony_ci {0xC14, 0x40000100}, {0xC18, 0x08800000}, 23062306a36Sopenharmony_ci {0xC1C, 0x40000100}, {0xC20, 0x00000000}, 23162306a36Sopenharmony_ci {0xC24, 0x00000000}, {0xC28, 0x00000000}, 23262306a36Sopenharmony_ci {0xC2C, 0x00000000}, {0xC30, 0x69E9AC4A}, 23362306a36Sopenharmony_ci {0xC34, 0x31000040}, {0xC38, 0x21688080}, 23462306a36Sopenharmony_ci {0xC3C, 0x0000170C}, {0xC40, 0x1F78403F}, 23562306a36Sopenharmony_ci {0xC44, 0x00010036}, {0xC48, 0xEC020107}, 23662306a36Sopenharmony_ci {0xC4C, 0x007F037F}, {0xC50, 0x69553420}, 23762306a36Sopenharmony_ci {0xC54, 0x43BC0094}, {0xC58, 0x00013169}, 23862306a36Sopenharmony_ci {0xC5C, 0x00250492}, {0xC60, 0x00280A00}, 23962306a36Sopenharmony_ci {0xC64, 0x7112848B}, {0xC68, 0x47C074FF}, 24062306a36Sopenharmony_ci {0xC6C, 0x00000036}, {0xC70, 0x2C7F000D}, 24162306a36Sopenharmony_ci {0xC74, 0x020600DB}, {0xC78, 0x0000001F}, 24262306a36Sopenharmony_ci {0xC7C, 0x00B91612}, {0xC80, 0x390000E4}, 24362306a36Sopenharmony_ci {0xC84, 0x11F60000}, {0xC88, 0x1051B75F}, 24462306a36Sopenharmony_ci {0xC8C, 0x20200109}, {0xC90, 0x00091521}, 24562306a36Sopenharmony_ci {0xC94, 0x00000000}, {0xC98, 0x00121820}, 24662306a36Sopenharmony_ci {0xC9C, 0x00007F7F}, {0xCA0, 0x00011000}, 24762306a36Sopenharmony_ci {0xCA4, 0x800000A0}, {0xCA8, 0x84E6C606}, 24862306a36Sopenharmony_ci {0xCAC, 0x00000060}, {0xCB0, 0x00000000}, 24962306a36Sopenharmony_ci {0xCB4, 0x00000000}, {0xCB8, 0x00000000}, 25062306a36Sopenharmony_ci {0xCBC, 0x28000000}, {0xCC0, 0x1051B75F}, 25162306a36Sopenharmony_ci {0xCC4, 0x00000109}, {0xCC8, 0x000442D6}, 25262306a36Sopenharmony_ci {0xCCC, 0x00000000}, {0xCD0, 0x000001C8}, 25362306a36Sopenharmony_ci {0xCD4, 0x001C8000}, {0xCD8, 0x00000100}, 25462306a36Sopenharmony_ci {0xCDC, 0x40100000}, {0xCE0, 0x00222220}, 25562306a36Sopenharmony_ci {0xCE4, 0x10000000}, {0xCE8, 0x37644302}, 25662306a36Sopenharmony_ci {0xCEC, 0x2F97D40C}, {0xD00, 0x04030740}, 25762306a36Sopenharmony_ci {0xD04, 0x40020401}, {0xD08, 0x0000907F}, 25862306a36Sopenharmony_ci {0xD0C, 0x20010201}, {0xD10, 0xA0633333}, 25962306a36Sopenharmony_ci {0xD14, 0x3333BC53}, {0xD18, 0x7A8F5B6F}, 26062306a36Sopenharmony_ci {0xD2C, 0xCB979975}, {0xD30, 0x00000000}, 26162306a36Sopenharmony_ci {0xD34, 0x40608000}, {0xD38, 0x88000000}, 26262306a36Sopenharmony_ci {0xD3C, 0xC0127353}, {0xD40, 0x00000000}, 26362306a36Sopenharmony_ci {0xD44, 0x00000000}, {0xD48, 0x00000000}, 26462306a36Sopenharmony_ci {0xD4C, 0x00000000}, {0xD50, 0x00006528}, 26562306a36Sopenharmony_ci {0xD54, 0x00000000}, {0xD58, 0x00000282}, 26662306a36Sopenharmony_ci {0xD5C, 0x30032064}, {0xD60, 0x4653DE68}, 26762306a36Sopenharmony_ci {0xD64, 0x04518A3C}, {0xD68, 0x00002101}, 26862306a36Sopenharmony_ci {0xE00, 0x2D2D2D2D}, {0xE04, 0x2D2D2D2D}, 26962306a36Sopenharmony_ci {0xE08, 0x0390272D}, {0xE10, 0x2D2D2D2D}, 27062306a36Sopenharmony_ci {0xE14, 0x2D2D2D2D}, {0xE18, 0x2D2D2D2D}, 27162306a36Sopenharmony_ci {0xE1C, 0x2D2D2D2D}, {0xE28, 0x00000000}, 27262306a36Sopenharmony_ci {0xE30, 0x1000DC1F}, {0xE34, 0x10008C1F}, 27362306a36Sopenharmony_ci {0xE38, 0x02140102}, {0xE3C, 0x681604C2}, 27462306a36Sopenharmony_ci {0xE40, 0x01007C00}, {0xE44, 0x01004800}, 27562306a36Sopenharmony_ci {0xE48, 0xFB000000}, {0xE4C, 0x000028D1}, 27662306a36Sopenharmony_ci {0xE50, 0x1000DC1F}, {0xE54, 0x10008C1F}, 27762306a36Sopenharmony_ci {0xE58, 0x02140102}, {0xE5C, 0x28160D05}, 27862306a36Sopenharmony_ci {0xE60, 0x0000C008}, {0xE68, 0x001B25A4}, 27962306a36Sopenharmony_ci {0xE64, 0x281600A0}, {0xE6C, 0x01C00010}, 28062306a36Sopenharmony_ci {0xE70, 0x01C00010}, {0xE74, 0x02000010}, 28162306a36Sopenharmony_ci {0xE78, 0x02000010}, {0xE7C, 0x02000010}, 28262306a36Sopenharmony_ci {0xE80, 0x02000010}, {0xE84, 0x01C00010}, 28362306a36Sopenharmony_ci {0xE88, 0x02000010}, {0xE8C, 0x01C00010}, 28462306a36Sopenharmony_ci {0xED0, 0x01C00010}, {0xED4, 0x01C00010}, 28562306a36Sopenharmony_ci {0xED8, 0x01C00010}, {0xEDC, 0x00000010}, 28662306a36Sopenharmony_ci {0xEE0, 0x00000010}, {0xEEC, 0x03C00010}, 28762306a36Sopenharmony_ci {0xF14, 0x00000003}, {0xF00, 0x00100300}, 28862306a36Sopenharmony_ci {0xF08, 0x0000800B}, {0xF0C, 0x0000F007}, 28962306a36Sopenharmony_ci {0xF10, 0x0000A487}, {0xF1C, 0x80000064}, 29062306a36Sopenharmony_ci {0xF38, 0x00030155}, {0xF3C, 0x0000003A}, 29162306a36Sopenharmony_ci {0xF4C, 0x13000000}, {0xF50, 0x00000000}, 29262306a36Sopenharmony_ci {0xF18, 0x00000000}, 29362306a36Sopenharmony_ci {0xffff, 0xffffffff}, 29462306a36Sopenharmony_ci}; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistatic const struct rtl8xxxu_reg32val rtl8710b_agc_table[] = { 29762306a36Sopenharmony_ci {0xC78, 0xFC000001}, {0xC78, 0xFB010001}, 29862306a36Sopenharmony_ci {0xC78, 0xFA020001}, {0xC78, 0xF9030001}, 29962306a36Sopenharmony_ci {0xC78, 0xF8040001}, {0xC78, 0xF7050001}, 30062306a36Sopenharmony_ci {0xC78, 0xF6060001}, {0xC78, 0xF5070001}, 30162306a36Sopenharmony_ci {0xC78, 0xF4080001}, {0xC78, 0xF3090001}, 30262306a36Sopenharmony_ci {0xC78, 0xF20A0001}, {0xC78, 0xF10B0001}, 30362306a36Sopenharmony_ci {0xC78, 0xF00C0001}, {0xC78, 0xEF0D0001}, 30462306a36Sopenharmony_ci {0xC78, 0xEE0E0001}, {0xC78, 0xED0F0001}, 30562306a36Sopenharmony_ci {0xC78, 0xEC100001}, {0xC78, 0xEB110001}, 30662306a36Sopenharmony_ci {0xC78, 0xEA120001}, {0xC78, 0xE9130001}, 30762306a36Sopenharmony_ci {0xC78, 0xE8140001}, {0xC78, 0xE7150001}, 30862306a36Sopenharmony_ci {0xC78, 0xE6160001}, {0xC78, 0xE5170001}, 30962306a36Sopenharmony_ci {0xC78, 0xE4180001}, {0xC78, 0xE3190001}, 31062306a36Sopenharmony_ci {0xC78, 0xE21A0001}, {0xC78, 0xE11B0001}, 31162306a36Sopenharmony_ci {0xC78, 0xE01C0001}, {0xC78, 0xC31D0001}, 31262306a36Sopenharmony_ci {0xC78, 0xC21E0001}, {0xC78, 0xC11F0001}, 31362306a36Sopenharmony_ci {0xC78, 0xC0200001}, {0xC78, 0xA3210001}, 31462306a36Sopenharmony_ci {0xC78, 0xA2220001}, {0xC78, 0xA1230001}, 31562306a36Sopenharmony_ci {0xC78, 0xA0240001}, {0xC78, 0x86250001}, 31662306a36Sopenharmony_ci {0xC78, 0x85260001}, {0xC78, 0x84270001}, 31762306a36Sopenharmony_ci {0xC78, 0x83280001}, {0xC78, 0x82290001}, 31862306a36Sopenharmony_ci {0xC78, 0x812A0001}, {0xC78, 0x802B0001}, 31962306a36Sopenharmony_ci {0xC78, 0x632C0001}, {0xC78, 0x622D0001}, 32062306a36Sopenharmony_ci {0xC78, 0x612E0001}, {0xC78, 0x602F0001}, 32162306a36Sopenharmony_ci {0xC78, 0x42300001}, {0xC78, 0x41310001}, 32262306a36Sopenharmony_ci {0xC78, 0x40320001}, {0xC78, 0x23330001}, 32362306a36Sopenharmony_ci {0xC78, 0x22340001}, {0xC78, 0x21350001}, 32462306a36Sopenharmony_ci {0xC78, 0x20360001}, {0xC78, 0x02370001}, 32562306a36Sopenharmony_ci {0xC78, 0x01380001}, {0xC78, 0x00390001}, 32662306a36Sopenharmony_ci {0xC78, 0x003A0001}, {0xC78, 0x003B0001}, 32762306a36Sopenharmony_ci {0xC78, 0x003C0001}, {0xC78, 0x003D0001}, 32862306a36Sopenharmony_ci {0xC78, 0x003E0001}, {0xC78, 0x003F0001}, 32962306a36Sopenharmony_ci {0xC78, 0xF7400001}, {0xC78, 0xF7410001}, 33062306a36Sopenharmony_ci {0xC78, 0xF7420001}, {0xC78, 0xF7430001}, 33162306a36Sopenharmony_ci {0xC78, 0xF7440001}, {0xC78, 0xF7450001}, 33262306a36Sopenharmony_ci {0xC78, 0xF7460001}, {0xC78, 0xF7470001}, 33362306a36Sopenharmony_ci {0xC78, 0xF7480001}, {0xC78, 0xF6490001}, 33462306a36Sopenharmony_ci {0xC78, 0xF34A0001}, {0xC78, 0xF24B0001}, 33562306a36Sopenharmony_ci {0xC78, 0xF14C0001}, {0xC78, 0xF04D0001}, 33662306a36Sopenharmony_ci {0xC78, 0xD14E0001}, {0xC78, 0xD04F0001}, 33762306a36Sopenharmony_ci {0xC78, 0xB5500001}, {0xC78, 0xB4510001}, 33862306a36Sopenharmony_ci {0xC78, 0xB3520001}, {0xC78, 0xB2530001}, 33962306a36Sopenharmony_ci {0xC78, 0xB1540001}, {0xC78, 0xB0550001}, 34062306a36Sopenharmony_ci {0xC78, 0xAF560001}, {0xC78, 0xAE570001}, 34162306a36Sopenharmony_ci {0xC78, 0xAD580001}, {0xC78, 0xAC590001}, 34262306a36Sopenharmony_ci {0xC78, 0xAB5A0001}, {0xC78, 0xAA5B0001}, 34362306a36Sopenharmony_ci {0xC78, 0xA95C0001}, {0xC78, 0xA85D0001}, 34462306a36Sopenharmony_ci {0xC78, 0xA75E0001}, {0xC78, 0xA65F0001}, 34562306a36Sopenharmony_ci {0xC78, 0xA5600001}, {0xC78, 0xA4610001}, 34662306a36Sopenharmony_ci {0xC78, 0xA3620001}, {0xC78, 0xA2630001}, 34762306a36Sopenharmony_ci {0xC78, 0xA1640001}, {0xC78, 0xA0650001}, 34862306a36Sopenharmony_ci {0xC78, 0x87660001}, {0xC78, 0x86670001}, 34962306a36Sopenharmony_ci {0xC78, 0x85680001}, {0xC78, 0x84690001}, 35062306a36Sopenharmony_ci {0xC78, 0x836A0001}, {0xC78, 0x826B0001}, 35162306a36Sopenharmony_ci {0xC78, 0x816C0001}, {0xC78, 0x806D0001}, 35262306a36Sopenharmony_ci {0xC78, 0x636E0001}, {0xC78, 0x626F0001}, 35362306a36Sopenharmony_ci {0xC78, 0x61700001}, {0xC78, 0x60710001}, 35462306a36Sopenharmony_ci {0xC78, 0x42720001}, {0xC78, 0x41730001}, 35562306a36Sopenharmony_ci {0xC78, 0x40740001}, {0xC78, 0x23750001}, 35662306a36Sopenharmony_ci {0xC78, 0x22760001}, {0xC78, 0x21770001}, 35762306a36Sopenharmony_ci {0xC78, 0x20780001}, {0xC78, 0x03790001}, 35862306a36Sopenharmony_ci {0xC78, 0x027A0001}, {0xC78, 0x017B0001}, 35962306a36Sopenharmony_ci {0xC78, 0x007C0001}, {0xC78, 0x007D0001}, 36062306a36Sopenharmony_ci {0xC78, 0x007E0001}, {0xC78, 0x007F0001}, 36162306a36Sopenharmony_ci {0xC50, 0x69553422}, {0xC50, 0x69553420}, 36262306a36Sopenharmony_ci {0xffff, 0xffffffff} 36362306a36Sopenharmony_ci}; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_cistatic const struct rtl8xxxu_rfregval rtl8710bu_qfn48m_u_radioa_init_table[] = { 36662306a36Sopenharmony_ci {0x00, 0x00030000}, {0x08, 0x00008400}, 36762306a36Sopenharmony_ci {0x17, 0x00000000}, {0x18, 0x00000C01}, 36862306a36Sopenharmony_ci {0x19, 0x000739D2}, {0x1C, 0x00000C4C}, 36962306a36Sopenharmony_ci {0x1B, 0x00000C6C}, {0x1E, 0x00080009}, 37062306a36Sopenharmony_ci {0x1F, 0x00000880}, {0x2F, 0x0001A060}, 37162306a36Sopenharmony_ci {0x3F, 0x00015000}, {0x42, 0x000060C0}, 37262306a36Sopenharmony_ci {0x57, 0x000D0000}, {0x58, 0x000C0160}, 37362306a36Sopenharmony_ci {0x67, 0x00001552}, {0x83, 0x00000000}, 37462306a36Sopenharmony_ci {0xB0, 0x000FF9F0}, {0xB1, 0x00010018}, 37562306a36Sopenharmony_ci {0xB2, 0x00054C00}, {0xB4, 0x0004486B}, 37662306a36Sopenharmony_ci {0xB5, 0x0000112A}, {0xB6, 0x0000053E}, 37762306a36Sopenharmony_ci {0xB7, 0x00014408}, {0xB8, 0x00010200}, 37862306a36Sopenharmony_ci {0xB9, 0x00080801}, {0xBA, 0x00040001}, 37962306a36Sopenharmony_ci {0xBB, 0x00000400}, {0xBF, 0x000C0000}, 38062306a36Sopenharmony_ci {0xC2, 0x00002400}, {0xC3, 0x00000009}, 38162306a36Sopenharmony_ci {0xC4, 0x00040C91}, {0xC5, 0x00099999}, 38262306a36Sopenharmony_ci {0xC6, 0x000000A3}, {0xC7, 0x00088820}, 38362306a36Sopenharmony_ci {0xC8, 0x00076C06}, {0xC9, 0x00000000}, 38462306a36Sopenharmony_ci {0xCA, 0x00080000}, {0xDF, 0x00000180}, 38562306a36Sopenharmony_ci {0xEF, 0x000001A8}, {0x3D, 0x00000003}, 38662306a36Sopenharmony_ci {0x3D, 0x00080003}, {0x51, 0x000F1E69}, 38762306a36Sopenharmony_ci {0x52, 0x000FBF6C}, {0x53, 0x0000032F}, 38862306a36Sopenharmony_ci {0x54, 0x00055007}, {0x56, 0x000517F0}, 38962306a36Sopenharmony_ci {0x35, 0x000000F4}, {0x35, 0x00000179}, 39062306a36Sopenharmony_ci {0x35, 0x000002F4}, {0x36, 0x00000BF8}, 39162306a36Sopenharmony_ci {0x36, 0x00008BF8}, {0x36, 0x00010BF8}, 39262306a36Sopenharmony_ci {0x36, 0x00018BF8}, {0x18, 0x00000C01}, 39362306a36Sopenharmony_ci {0x5A, 0x00048000}, {0x5A, 0x00048000}, 39462306a36Sopenharmony_ci {0x34, 0x0000ADF5}, {0x34, 0x00009DF2}, 39562306a36Sopenharmony_ci {0x34, 0x00008DEF}, {0x34, 0x00007DEC}, 39662306a36Sopenharmony_ci {0x34, 0x00006DE9}, {0x34, 0x00005CEC}, 39762306a36Sopenharmony_ci {0x34, 0x00004CE9}, {0x34, 0x00003C6C}, 39862306a36Sopenharmony_ci {0x34, 0x00002C69}, {0x34, 0x0000106E}, 39962306a36Sopenharmony_ci {0x34, 0x0000006B}, {0x84, 0x00048000}, 40062306a36Sopenharmony_ci {0x87, 0x00000065}, {0x8E, 0x00065540}, 40162306a36Sopenharmony_ci {0xDF, 0x00000110}, {0x86, 0x0000002A}, 40262306a36Sopenharmony_ci {0x8F, 0x00088000}, {0x81, 0x0003FD80}, 40362306a36Sopenharmony_ci {0xEF, 0x00082000}, {0x3B, 0x000F0F00}, 40462306a36Sopenharmony_ci {0x3B, 0x000E0E00}, {0x3B, 0x000DFE00}, 40562306a36Sopenharmony_ci {0x3B, 0x000C0D00}, {0x3B, 0x000B0C00}, 40662306a36Sopenharmony_ci {0x3B, 0x000A0500}, {0x3B, 0x00090400}, 40762306a36Sopenharmony_ci {0x3B, 0x00080000}, {0x3B, 0x00070F00}, 40862306a36Sopenharmony_ci {0x3B, 0x00060E00}, {0x3B, 0x00050A00}, 40962306a36Sopenharmony_ci {0x3B, 0x00040D00}, {0x3B, 0x00030C00}, 41062306a36Sopenharmony_ci {0x3B, 0x00020500}, {0x3B, 0x00010400}, 41162306a36Sopenharmony_ci {0x3B, 0x00000000}, {0xEF, 0x00080000}, 41262306a36Sopenharmony_ci {0xEF, 0x00088000}, {0x3B, 0x00000170}, 41362306a36Sopenharmony_ci {0x3B, 0x000C0030}, {0xEF, 0x00080000}, 41462306a36Sopenharmony_ci {0xEF, 0x00080000}, {0x30, 0x00010000}, 41562306a36Sopenharmony_ci {0x31, 0x0000000F}, {0x32, 0x00047EFE}, 41662306a36Sopenharmony_ci {0xEF, 0x00000000}, {0x00, 0x00010159}, 41762306a36Sopenharmony_ci {0x18, 0x0000FC01}, {0xFE, 0x00000000}, 41862306a36Sopenharmony_ci {0x00, 0x00033D95}, 41962306a36Sopenharmony_ci {0xff, 0xffffffff} 42062306a36Sopenharmony_ci}; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_cistatic const struct rtl8xxxu_rfregval rtl8710bu_qfn48m_s_radioa_init_table[] = { 42362306a36Sopenharmony_ci {0x00, 0x00030000}, {0x08, 0x00008400}, 42462306a36Sopenharmony_ci {0x17, 0x00000000}, {0x18, 0x00000C01}, 42562306a36Sopenharmony_ci {0x19, 0x000739D2}, {0x1C, 0x00000C4C}, 42662306a36Sopenharmony_ci {0x1B, 0x00000C6C}, {0x1E, 0x00080009}, 42762306a36Sopenharmony_ci {0x1F, 0x00000880}, {0x2F, 0x0001A060}, 42862306a36Sopenharmony_ci {0x3F, 0x00015000}, {0x42, 0x000060C0}, 42962306a36Sopenharmony_ci {0x57, 0x000D0000}, {0x58, 0x000C0160}, 43062306a36Sopenharmony_ci {0x67, 0x00001552}, {0x83, 0x00000000}, 43162306a36Sopenharmony_ci {0xB0, 0x000FF9F0}, {0xB1, 0x00010018}, 43262306a36Sopenharmony_ci {0xB2, 0x00054C00}, {0xB4, 0x0004486B}, 43362306a36Sopenharmony_ci {0xB5, 0x0000112A}, {0xB6, 0x0000053E}, 43462306a36Sopenharmony_ci {0xB7, 0x00014408}, {0xB8, 0x00010200}, 43562306a36Sopenharmony_ci {0xB9, 0x00080801}, {0xBA, 0x00040001}, 43662306a36Sopenharmony_ci {0xBB, 0x00000400}, {0xBF, 0x000C0000}, 43762306a36Sopenharmony_ci {0xC2, 0x00002400}, {0xC3, 0x00000009}, 43862306a36Sopenharmony_ci {0xC4, 0x00040C91}, {0xC5, 0x00099999}, 43962306a36Sopenharmony_ci {0xC6, 0x000000A3}, {0xC7, 0x00088820}, 44062306a36Sopenharmony_ci {0xC8, 0x00076C06}, {0xC9, 0x00000000}, 44162306a36Sopenharmony_ci {0xCA, 0x00080000}, {0xDF, 0x00000180}, 44262306a36Sopenharmony_ci {0xEF, 0x000001A8}, {0x3D, 0x00000003}, 44362306a36Sopenharmony_ci {0x3D, 0x00080003}, {0x51, 0x000F1E69}, 44462306a36Sopenharmony_ci {0x52, 0x000FBF6C}, {0x53, 0x0000032F}, 44562306a36Sopenharmony_ci {0x54, 0x00055007}, {0x56, 0x000517F0}, 44662306a36Sopenharmony_ci {0x35, 0x000000F4}, {0x35, 0x00000179}, 44762306a36Sopenharmony_ci {0x35, 0x000002F4}, {0x36, 0x00000BF8}, 44862306a36Sopenharmony_ci {0x36, 0x00008BF8}, {0x36, 0x00010BF8}, 44962306a36Sopenharmony_ci {0x36, 0x00018BF8}, {0x18, 0x00000C01}, 45062306a36Sopenharmony_ci {0x5A, 0x00048000}, {0x5A, 0x00048000}, 45162306a36Sopenharmony_ci {0x34, 0x0000ADF5}, {0x34, 0x00009DF2}, 45262306a36Sopenharmony_ci {0x34, 0x00008DEF}, {0x34, 0x00007DEC}, 45362306a36Sopenharmony_ci {0x34, 0x00006DE9}, {0x34, 0x00005CEC}, 45462306a36Sopenharmony_ci {0x34, 0x00004CE9}, {0x34, 0x00003C6C}, 45562306a36Sopenharmony_ci {0x34, 0x00002C69}, {0x34, 0x0000106E}, 45662306a36Sopenharmony_ci {0x34, 0x0000006B}, {0x84, 0x00048000}, 45762306a36Sopenharmony_ci {0x87, 0x00000065}, {0x8E, 0x00065540}, 45862306a36Sopenharmony_ci {0xDF, 0x00000110}, {0x86, 0x0000002A}, 45962306a36Sopenharmony_ci {0x8F, 0x00088000}, {0x81, 0x0003FD80}, 46062306a36Sopenharmony_ci {0xEF, 0x00082000}, {0x3B, 0x000F0F00}, 46162306a36Sopenharmony_ci {0x3B, 0x000E0E00}, {0x3B, 0x000DFE00}, 46262306a36Sopenharmony_ci {0x3B, 0x000C0D00}, {0x3B, 0x000B0C00}, 46362306a36Sopenharmony_ci {0x3B, 0x000A0500}, {0x3B, 0x00090400}, 46462306a36Sopenharmony_ci {0x3B, 0x00080000}, {0x3B, 0x00070F00}, 46562306a36Sopenharmony_ci {0x3B, 0x00060E00}, {0x3B, 0x00050A00}, 46662306a36Sopenharmony_ci {0x3B, 0x00040D00}, {0x3B, 0x00030C00}, 46762306a36Sopenharmony_ci {0x3B, 0x00020500}, {0x3B, 0x00010400}, 46862306a36Sopenharmony_ci {0x3B, 0x00000000}, {0xEF, 0x00080000}, 46962306a36Sopenharmony_ci {0xEF, 0x00088000}, {0x3B, 0x000000B0}, 47062306a36Sopenharmony_ci {0x3B, 0x000C0030}, {0xEF, 0x00080000}, 47162306a36Sopenharmony_ci {0xEF, 0x00080000}, {0x30, 0x00010000}, 47262306a36Sopenharmony_ci {0x31, 0x0000000F}, {0x32, 0x00047EFE}, 47362306a36Sopenharmony_ci {0xEF, 0x00000000}, {0x00, 0x00010159}, 47462306a36Sopenharmony_ci {0x18, 0x0000FC01}, {0xFE, 0x00000000}, 47562306a36Sopenharmony_ci {0x00, 0x00033D95}, 47662306a36Sopenharmony_ci {0xff, 0xffffffff} 47762306a36Sopenharmony_ci}; 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_cistatic u32 rtl8710b_indirect_read32(struct rtl8xxxu_priv *priv, u32 addr) 48062306a36Sopenharmony_ci{ 48162306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 48262306a36Sopenharmony_ci u32 val32, value = 0xffffffff; 48362306a36Sopenharmony_ci u8 polling_count = 0xff; 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci if (!IS_ALIGNED(addr, 4)) { 48662306a36Sopenharmony_ci dev_warn(dev, "%s: Aborting because 0x%x is not a multiple of 4.\n", 48762306a36Sopenharmony_ci __func__, addr); 48862306a36Sopenharmony_ci return value; 48962306a36Sopenharmony_ci } 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci mutex_lock(&priv->syson_indirect_access_mutex); 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_USB_HOST_INDIRECT_ADDR_8710B, addr); 49462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_EFUSE_INDIRECT_CTRL_8710B, NORMAL_REG_READ_OFFSET); 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci do 49762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_EFUSE_INDIRECT_CTRL_8710B); 49862306a36Sopenharmony_ci while ((val32 & BIT(31)) && (--polling_count > 0)); 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci if (polling_count == 0) 50162306a36Sopenharmony_ci dev_warn(dev, "%s: Failed to read from 0x%x, 0x806c = 0x%x\n", 50262306a36Sopenharmony_ci __func__, addr, val32); 50362306a36Sopenharmony_ci else 50462306a36Sopenharmony_ci value = rtl8xxxu_read32(priv, REG_USB_HOST_INDIRECT_DATA_8710B); 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci mutex_unlock(&priv->syson_indirect_access_mutex); 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_READ) 50962306a36Sopenharmony_ci dev_info(dev, "%s(%04x) = 0x%08x\n", __func__, addr, value); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci return value; 51262306a36Sopenharmony_ci} 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_cistatic void rtl8710b_indirect_write32(struct rtl8xxxu_priv *priv, u32 addr, u32 val) 51562306a36Sopenharmony_ci{ 51662306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 51762306a36Sopenharmony_ci u8 polling_count = 0xff; 51862306a36Sopenharmony_ci u32 val32; 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci if (!IS_ALIGNED(addr, 4)) { 52162306a36Sopenharmony_ci dev_warn(dev, "%s: Aborting because 0x%x is not a multiple of 4.\n", 52262306a36Sopenharmony_ci __func__, addr); 52362306a36Sopenharmony_ci return; 52462306a36Sopenharmony_ci } 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci mutex_lock(&priv->syson_indirect_access_mutex); 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_USB_HOST_INDIRECT_ADDR_8710B, addr); 52962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_USB_HOST_INDIRECT_DATA_8710B, val); 53062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_EFUSE_INDIRECT_CTRL_8710B, NORMAL_REG_WRITE_OFFSET); 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci do 53362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_EFUSE_INDIRECT_CTRL_8710B); 53462306a36Sopenharmony_ci while ((val32 & BIT(31)) && (--polling_count > 0)); 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci if (polling_count == 0) 53762306a36Sopenharmony_ci dev_warn(dev, "%s: Failed to write 0x%x to 0x%x, 0x806c = 0x%x\n", 53862306a36Sopenharmony_ci __func__, val, addr, val32); 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci mutex_unlock(&priv->syson_indirect_access_mutex); 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE) 54362306a36Sopenharmony_ci dev_info(dev, "%s(%04x) = 0x%08x\n", __func__, addr, val); 54462306a36Sopenharmony_ci} 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_cistatic u32 rtl8710b_read_syson_reg(struct rtl8xxxu_priv *priv, u32 addr) 54762306a36Sopenharmony_ci{ 54862306a36Sopenharmony_ci return rtl8710b_indirect_read32(priv, addr | SYSON_REG_BASE_ADDR_8710B); 54962306a36Sopenharmony_ci} 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_cistatic void rtl8710b_write_syson_reg(struct rtl8xxxu_priv *priv, u32 addr, u32 val) 55262306a36Sopenharmony_ci{ 55362306a36Sopenharmony_ci rtl8710b_indirect_write32(priv, addr | SYSON_REG_BASE_ADDR_8710B, val); 55462306a36Sopenharmony_ci} 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_cistatic int rtl8710b_read_efuse8(struct rtl8xxxu_priv *priv, u16 offset, u8 *data) 55762306a36Sopenharmony_ci{ 55862306a36Sopenharmony_ci u32 val32; 55962306a36Sopenharmony_ci int i; 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci /* Write Address */ 56262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_USB_HOST_INDIRECT_ADDR_8710B, offset); 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_EFUSE_INDIRECT_CTRL_8710B, EFUSE_READ_OFFSET); 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci /* Poll for data read */ 56762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_EFUSE_INDIRECT_CTRL_8710B); 56862306a36Sopenharmony_ci for (i = 0; i < RTL8XXXU_MAX_REG_POLL; i++) { 56962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_EFUSE_INDIRECT_CTRL_8710B); 57062306a36Sopenharmony_ci if (!(val32 & BIT(31))) 57162306a36Sopenharmony_ci break; 57262306a36Sopenharmony_ci } 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci if (i == RTL8XXXU_MAX_REG_POLL) 57562306a36Sopenharmony_ci return -EIO; 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_USB_HOST_INDIRECT_DATA_8710B); 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci *data = val32 & 0xff; 58062306a36Sopenharmony_ci return 0; 58162306a36Sopenharmony_ci} 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci#define EEPROM_PACKAGE_TYPE_8710B 0xF8 58462306a36Sopenharmony_ci#define PACKAGE_QFN48M_U 0xee 58562306a36Sopenharmony_ci#define PACKAGE_QFN48M_S 0xfe 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_cistatic int rtl8710bu_identify_chip(struct rtl8xxxu_priv *priv) 58862306a36Sopenharmony_ci{ 58962306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 59062306a36Sopenharmony_ci u32 cfg0, cfg2, vendor; 59162306a36Sopenharmony_ci u8 package_type = 0x7; /* a nonsense value */ 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci sprintf(priv->chip_name, "8710BU"); 59462306a36Sopenharmony_ci priv->rtl_chip = RTL8710B; 59562306a36Sopenharmony_ci priv->rf_paths = 1; 59662306a36Sopenharmony_ci priv->rx_paths = 1; 59762306a36Sopenharmony_ci priv->tx_paths = 1; 59862306a36Sopenharmony_ci priv->has_wifi = 1; 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci cfg0 = rtl8710b_read_syson_reg(priv, REG_SYS_SYSTEM_CFG0_8710B); 60162306a36Sopenharmony_ci priv->chip_cut = cfg0 & 0xf; 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ci if (cfg0 & BIT(16)) { 60462306a36Sopenharmony_ci dev_info(dev, "%s: Unsupported test chip\n", __func__); 60562306a36Sopenharmony_ci return -EOPNOTSUPP; 60662306a36Sopenharmony_ci } 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci vendor = u32_get_bits(cfg0, 0xc0); 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_ci /* SMIC and TSMC are swapped compared to rtl8xxxu_identify_vendor_2bits */ 61162306a36Sopenharmony_ci switch (vendor) { 61262306a36Sopenharmony_ci case 0: 61362306a36Sopenharmony_ci sprintf(priv->chip_vendor, "SMIC"); 61462306a36Sopenharmony_ci priv->vendor_smic = 1; 61562306a36Sopenharmony_ci break; 61662306a36Sopenharmony_ci case 1: 61762306a36Sopenharmony_ci sprintf(priv->chip_vendor, "TSMC"); 61862306a36Sopenharmony_ci break; 61962306a36Sopenharmony_ci case 2: 62062306a36Sopenharmony_ci sprintf(priv->chip_vendor, "UMC"); 62162306a36Sopenharmony_ci priv->vendor_umc = 1; 62262306a36Sopenharmony_ci break; 62362306a36Sopenharmony_ci default: 62462306a36Sopenharmony_ci sprintf(priv->chip_vendor, "unknown"); 62562306a36Sopenharmony_ci break; 62662306a36Sopenharmony_ci } 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci rtl8710b_read_efuse8(priv, EEPROM_PACKAGE_TYPE_8710B, &package_type); 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci if (package_type == 0xff) { 63162306a36Sopenharmony_ci dev_warn(dev, "Package type is undefined. Assuming it based on the vendor.\n"); 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci if (priv->vendor_umc) { 63462306a36Sopenharmony_ci package_type = PACKAGE_QFN48M_U; 63562306a36Sopenharmony_ci } else if (priv->vendor_smic) { 63662306a36Sopenharmony_ci package_type = PACKAGE_QFN48M_S; 63762306a36Sopenharmony_ci } else { 63862306a36Sopenharmony_ci dev_warn(dev, "The vendor is neither UMC nor SMIC. Assuming the package type is QFN48M_U.\n"); 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci /* 64162306a36Sopenharmony_ci * In this case the vendor driver doesn't set 64262306a36Sopenharmony_ci * the package type to anything, which is the 64362306a36Sopenharmony_ci * same as setting it to PACKAGE_DEFAULT (0). 64462306a36Sopenharmony_ci */ 64562306a36Sopenharmony_ci package_type = PACKAGE_QFN48M_U; 64662306a36Sopenharmony_ci } 64762306a36Sopenharmony_ci } else if (package_type != PACKAGE_QFN48M_S && 64862306a36Sopenharmony_ci package_type != PACKAGE_QFN48M_U) { 64962306a36Sopenharmony_ci dev_warn(dev, "Failed to read the package type. Assuming it's the default QFN48M_U.\n"); 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci /* 65262306a36Sopenharmony_ci * In this case the vendor driver actually sets it to 65362306a36Sopenharmony_ci * PACKAGE_DEFAULT, but that selects the same values 65462306a36Sopenharmony_ci * from the init tables as PACKAGE_QFN48M_U. 65562306a36Sopenharmony_ci */ 65662306a36Sopenharmony_ci package_type = PACKAGE_QFN48M_U; 65762306a36Sopenharmony_ci } 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci priv->package_type = package_type; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci dev_dbg(dev, "Package type: 0x%x\n", package_type); 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci cfg2 = rtl8710b_read_syson_reg(priv, REG_SYS_SYSTEM_CFG2_8710B); 66462306a36Sopenharmony_ci priv->rom_rev = cfg2 & 0xf; 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci return rtl8xxxu_config_endpoints_no_sie(priv); 66762306a36Sopenharmony_ci} 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_cistatic void rtl8710b_revise_cck_tx_psf(struct rtl8xxxu_priv *priv, u8 channel) 67062306a36Sopenharmony_ci{ 67162306a36Sopenharmony_ci if (channel == 13) { 67262306a36Sopenharmony_ci /* Normal values */ 67362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER2, 0x64B80C1C); 67462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_DEBUG_PORT, 0x00008810); 67562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER3, 0x01235667); 67662306a36Sopenharmony_ci /* Special value for channel 13 */ 67762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER1, 0xd1d80001); 67862306a36Sopenharmony_ci } else if (channel == 14) { 67962306a36Sopenharmony_ci /* Special values for channel 14 */ 68062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER2, 0x0000B81C); 68162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_DEBUG_PORT, 0x00000000); 68262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER3, 0x00003667); 68362306a36Sopenharmony_ci /* Normal value */ 68462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER1, 0xE82C0001); 68562306a36Sopenharmony_ci } else { 68662306a36Sopenharmony_ci /* Restore normal values from the phy init table */ 68762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER2, 0x64B80C1C); 68862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_DEBUG_PORT, 0x00008810); 68962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER3, 0x01235667); 69062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_TX_FILTER1, 0xE82C0001); 69162306a36Sopenharmony_ci } 69262306a36Sopenharmony_ci} 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_cistatic void rtl8710bu_config_channel(struct ieee80211_hw *hw) 69562306a36Sopenharmony_ci{ 69662306a36Sopenharmony_ci struct rtl8xxxu_priv *priv = hw->priv; 69762306a36Sopenharmony_ci bool ht40 = conf_is_ht40(&hw->conf); 69862306a36Sopenharmony_ci u8 channel, subchannel = 0; 69962306a36Sopenharmony_ci bool sec_ch_above = 0; 70062306a36Sopenharmony_ci u32 val32; 70162306a36Sopenharmony_ci u16 val16; 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci channel = (u8)hw->conf.chandef.chan->hw_value; 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci if (conf_is_ht40_plus(&hw->conf)) { 70662306a36Sopenharmony_ci sec_ch_above = 1; 70762306a36Sopenharmony_ci channel += 2; 70862306a36Sopenharmony_ci subchannel = 2; 70962306a36Sopenharmony_ci } else if (conf_is_ht40_minus(&hw->conf)) { 71062306a36Sopenharmony_ci sec_ch_above = 0; 71162306a36Sopenharmony_ci channel -= 2; 71262306a36Sopenharmony_ci subchannel = 1; 71362306a36Sopenharmony_ci } 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci /* Set channel */ 71662306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); 71762306a36Sopenharmony_ci u32p_replace_bits(&val32, channel, MODE_AG_CHANNEL_MASK); 71862306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci rtl8710b_revise_cck_tx_psf(priv, channel); 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci /* Set bandwidth mode */ 72362306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_WMAC_TRXPTCL_CTL); 72462306a36Sopenharmony_ci val16 &= ~WMAC_TRXPTCL_CTL_BW_MASK; 72562306a36Sopenharmony_ci if (ht40) 72662306a36Sopenharmony_ci val16 |= WMAC_TRXPTCL_CTL_BW_40; 72762306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_WMAC_TRXPTCL_CTL, val16); 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_DATA_SUBCHANNEL, subchannel); 73062306a36Sopenharmony_ci 73162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); 73262306a36Sopenharmony_ci u32p_replace_bits(&val32, ht40, FPGA_RF_MODE); 73362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE); 73662306a36Sopenharmony_ci u32p_replace_bits(&val32, ht40, FPGA_RF_MODE); 73762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32); 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_ci if (ht40) { 74062306a36Sopenharmony_ci /* Set Control channel to upper or lower. */ 74162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_CCK0_SYSTEM); 74262306a36Sopenharmony_ci u32p_replace_bits(&val32, !sec_ch_above, CCK0_SIDEBAND); 74362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_SYSTEM, val32); 74462306a36Sopenharmony_ci } 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci /* RXADC CLK */ 74762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); 74862306a36Sopenharmony_ci val32 |= GENMASK(10, 8); 74962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci /* TXDAC CLK */ 75262306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); 75362306a36Sopenharmony_ci val32 |= BIT(14) | BIT(12); 75462306a36Sopenharmony_ci val32 &= ~BIT(13); 75562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ci /* small BW */ 75862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT); 75962306a36Sopenharmony_ci val32 &= ~GENMASK(31, 30); 76062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32); 76162306a36Sopenharmony_ci 76262306a36Sopenharmony_ci /* adc buffer clk */ 76362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT); 76462306a36Sopenharmony_ci val32 &= ~BIT(29); 76562306a36Sopenharmony_ci val32 |= BIT(28); 76662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32); 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci /* adc buffer clk */ 76962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_RX_AFE); 77062306a36Sopenharmony_ci val32 &= ~BIT(29); 77162306a36Sopenharmony_ci val32 |= BIT(28); 77262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XA_RX_AFE, val32); 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_RF_INT_OE); 77562306a36Sopenharmony_ci val32 &= ~BIT(30); 77662306a36Sopenharmony_ci val32 |= BIT(29); 77762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_XB_RF_INT_OE, val32); 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci if (ht40) { 78062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); 78162306a36Sopenharmony_ci val32 &= ~BIT(19); 78262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); 78562306a36Sopenharmony_ci val32 &= ~GENMASK(23, 20); 78662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); 78962306a36Sopenharmony_ci val32 &= ~GENMASK(27, 24); 79062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci /* RF TRX_BW */ 79362306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); 79462306a36Sopenharmony_ci val32 &= ~MODE_AG_BW_MASK; 79562306a36Sopenharmony_ci val32 |= MODE_AG_BW_40MHZ_8723B; 79662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); 79762306a36Sopenharmony_ci } else { 79862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); 79962306a36Sopenharmony_ci val32 |= BIT(19); 80062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); 80362306a36Sopenharmony_ci val32 &= ~GENMASK(23, 20); 80462306a36Sopenharmony_ci val32 |= BIT(23); 80562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR); 80862306a36Sopenharmony_ci val32 &= ~GENMASK(27, 24); 80962306a36Sopenharmony_ci val32 |= BIT(27) | BIT(25); 81062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32); 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci /* RF TRX_BW */ 81362306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG); 81462306a36Sopenharmony_ci val32 &= ~MODE_AG_BW_MASK; 81562306a36Sopenharmony_ci val32 |= MODE_AG_BW_20MHZ_8723B; 81662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32); 81762306a36Sopenharmony_ci } 81862306a36Sopenharmony_ci} 81962306a36Sopenharmony_ci 82062306a36Sopenharmony_cistatic void rtl8710bu_init_aggregation(struct rtl8xxxu_priv *priv) 82162306a36Sopenharmony_ci{ 82262306a36Sopenharmony_ci u32 agg_rx; 82362306a36Sopenharmony_ci u8 agg_ctrl; 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci /* RX aggregation */ 82662306a36Sopenharmony_ci agg_ctrl = rtl8xxxu_read8(priv, REG_TRXDMA_CTRL); 82762306a36Sopenharmony_ci agg_ctrl &= ~TRXDMA_CTRL_RXDMA_AGG_EN; 82862306a36Sopenharmony_ci 82962306a36Sopenharmony_ci agg_rx = rtl8xxxu_read32(priv, REG_RXDMA_AGG_PG_TH); 83062306a36Sopenharmony_ci agg_rx &= ~RXDMA_USB_AGG_ENABLE; 83162306a36Sopenharmony_ci agg_rx &= ~0xFF0F; /* reset agg size and timeout */ 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); 83462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RXDMA_AGG_PG_TH, agg_rx); 83562306a36Sopenharmony_ci} 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_cistatic void rtl8710bu_init_statistics(struct rtl8xxxu_priv *priv) 83862306a36Sopenharmony_ci{ 83962306a36Sopenharmony_ci u32 val32; 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci /* Time duration for NHM unit: 4us, 0xc350=200ms */ 84262306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_NHM_TIMER_8723B + 2, 0xc350); 84362306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_NHM_TH9_TH10_8723B + 2, 0xffff); 84462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_NHM_TH3_TO_TH0_8723B, 0xffffff50); 84562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_NHM_TH7_TO_TH4_8723B, 0xffffffff); 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci /* TH8 */ 84862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 84962306a36Sopenharmony_ci val32 |= 0xff; 85062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_ci /* Enable CCK */ 85362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_NHM_TH9_TH10_8723B); 85462306a36Sopenharmony_ci val32 &= ~(BIT(8) | BIT(9) | BIT(10)); 85562306a36Sopenharmony_ci val32 |= BIT(8); 85662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_NHM_TH9_TH10_8723B, val32); 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci /* Max power amongst all RX antennas */ 85962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_FA_RSTC); 86062306a36Sopenharmony_ci val32 |= BIT(7); 86162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_FA_RSTC, val32); 86262306a36Sopenharmony_ci} 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_cistatic int rtl8710b_read_efuse(struct rtl8xxxu_priv *priv) 86562306a36Sopenharmony_ci{ 86662306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 86762306a36Sopenharmony_ci u8 val8, word_mask, header, extheader; 86862306a36Sopenharmony_ci u16 efuse_addr, offset; 86962306a36Sopenharmony_ci int i, ret = 0; 87062306a36Sopenharmony_ci u32 val32; 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci val32 = rtl8710b_read_syson_reg(priv, REG_SYS_EEPROM_CTRL0_8710B); 87362306a36Sopenharmony_ci priv->boot_eeprom = u32_get_bits(val32, EEPROM_BOOT); 87462306a36Sopenharmony_ci priv->has_eeprom = u32_get_bits(val32, EEPROM_ENABLE); 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_ci /* Default value is 0xff */ 87762306a36Sopenharmony_ci memset(priv->efuse_wifi.raw, 0xff, EFUSE_MAP_LEN); 87862306a36Sopenharmony_ci 87962306a36Sopenharmony_ci efuse_addr = 0; 88062306a36Sopenharmony_ci while (efuse_addr < EFUSE_REAL_CONTENT_LEN_8723A) { 88162306a36Sopenharmony_ci u16 map_addr; 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci ret = rtl8710b_read_efuse8(priv, efuse_addr++, &header); 88462306a36Sopenharmony_ci if (ret || header == 0xff) 88562306a36Sopenharmony_ci goto exit; 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_ci if ((header & 0x1f) == 0x0f) { /* extended header */ 88862306a36Sopenharmony_ci offset = (header & 0xe0) >> 5; 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ci ret = rtl8710b_read_efuse8(priv, efuse_addr++, &extheader); 89162306a36Sopenharmony_ci if (ret) 89262306a36Sopenharmony_ci goto exit; 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci /* All words disabled */ 89562306a36Sopenharmony_ci if ((extheader & 0x0f) == 0x0f) 89662306a36Sopenharmony_ci continue; 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci offset |= ((extheader & 0xf0) >> 1); 89962306a36Sopenharmony_ci word_mask = extheader & 0x0f; 90062306a36Sopenharmony_ci } else { 90162306a36Sopenharmony_ci offset = (header >> 4) & 0x0f; 90262306a36Sopenharmony_ci word_mask = header & 0x0f; 90362306a36Sopenharmony_ci } 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_ci /* Get word enable value from PG header */ 90662306a36Sopenharmony_ci 90762306a36Sopenharmony_ci /* We have 8 bits to indicate validity */ 90862306a36Sopenharmony_ci map_addr = offset * 8; 90962306a36Sopenharmony_ci for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { 91062306a36Sopenharmony_ci /* Check word enable condition in the section */ 91162306a36Sopenharmony_ci if (word_mask & BIT(i)) { 91262306a36Sopenharmony_ci map_addr += 2; 91362306a36Sopenharmony_ci continue; 91462306a36Sopenharmony_ci } 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_ci ret = rtl8710b_read_efuse8(priv, efuse_addr++, &val8); 91762306a36Sopenharmony_ci if (ret) 91862306a36Sopenharmony_ci goto exit; 91962306a36Sopenharmony_ci if (map_addr >= EFUSE_MAP_LEN - 1) { 92062306a36Sopenharmony_ci dev_warn(dev, "%s: Illegal map_addr (%04x), efuse corrupt!\n", 92162306a36Sopenharmony_ci __func__, map_addr); 92262306a36Sopenharmony_ci ret = -EINVAL; 92362306a36Sopenharmony_ci goto exit; 92462306a36Sopenharmony_ci } 92562306a36Sopenharmony_ci priv->efuse_wifi.raw[map_addr++] = val8; 92662306a36Sopenharmony_ci 92762306a36Sopenharmony_ci ret = rtl8710b_read_efuse8(priv, efuse_addr++, &val8); 92862306a36Sopenharmony_ci if (ret) 92962306a36Sopenharmony_ci goto exit; 93062306a36Sopenharmony_ci priv->efuse_wifi.raw[map_addr++] = val8; 93162306a36Sopenharmony_ci } 93262306a36Sopenharmony_ci } 93362306a36Sopenharmony_ci 93462306a36Sopenharmony_ciexit: 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ci return ret; 93762306a36Sopenharmony_ci} 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_cistatic int rtl8710bu_parse_efuse(struct rtl8xxxu_priv *priv) 94062306a36Sopenharmony_ci{ 94162306a36Sopenharmony_ci struct rtl8710bu_efuse *efuse = &priv->efuse_wifi.efuse8710bu; 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ci if (efuse->rtl_id != cpu_to_le16(0x8195)) 94462306a36Sopenharmony_ci return -EINVAL; 94562306a36Sopenharmony_ci 94662306a36Sopenharmony_ci ether_addr_copy(priv->mac_addr, efuse->mac_addr); 94762306a36Sopenharmony_ci 94862306a36Sopenharmony_ci memcpy(priv->cck_tx_power_index_A, efuse->tx_power_index_A.cck_base, 94962306a36Sopenharmony_ci sizeof(efuse->tx_power_index_A.cck_base)); 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_ci memcpy(priv->ht40_1s_tx_power_index_A, 95262306a36Sopenharmony_ci efuse->tx_power_index_A.ht40_base, 95362306a36Sopenharmony_ci sizeof(efuse->tx_power_index_A.ht40_base)); 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_ci priv->ofdm_tx_power_diff[0].a = efuse->tx_power_index_A.ht20_ofdm_1s_diff.a; 95662306a36Sopenharmony_ci priv->ht20_tx_power_diff[0].a = efuse->tx_power_index_A.ht20_ofdm_1s_diff.b; 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci priv->default_crystal_cap = efuse->xtal_k & 0x3f; 95962306a36Sopenharmony_ci 96062306a36Sopenharmony_ci return 0; 96162306a36Sopenharmony_ci} 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_cistatic int rtl8710bu_load_firmware(struct rtl8xxxu_priv *priv) 96462306a36Sopenharmony_ci{ 96562306a36Sopenharmony_ci if (priv->vendor_smic) { 96662306a36Sopenharmony_ci return rtl8xxxu_load_firmware(priv, "rtlwifi/rtl8710bufw_SMIC.bin"); 96762306a36Sopenharmony_ci } else if (priv->vendor_umc) { 96862306a36Sopenharmony_ci return rtl8xxxu_load_firmware(priv, "rtlwifi/rtl8710bufw_UMC.bin"); 96962306a36Sopenharmony_ci } else { 97062306a36Sopenharmony_ci dev_err(&priv->udev->dev, "We have no suitable firmware for this chip.\n"); 97162306a36Sopenharmony_ci return -1; 97262306a36Sopenharmony_ci } 97362306a36Sopenharmony_ci} 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_cistatic void rtl8710bu_init_phy_bb(struct rtl8xxxu_priv *priv) 97662306a36Sopenharmony_ci{ 97762306a36Sopenharmony_ci const struct rtl8xxxu_reg32val *phy_init_table; 97862306a36Sopenharmony_ci u32 val32; 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci /* Enable BB and RF */ 98162306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_SYS_FUNC_8710B); 98262306a36Sopenharmony_ci val32 |= GENMASK(17, 16) | GENMASK(26, 24); 98362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_SYS_FUNC_8710B, val32); 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci if (priv->package_type == PACKAGE_QFN48M_U) 98662306a36Sopenharmony_ci phy_init_table = rtl8710bu_qfn48m_u_phy_init_table; 98762306a36Sopenharmony_ci else 98862306a36Sopenharmony_ci phy_init_table = rtl8710bu_qfn48m_s_phy_init_table; 98962306a36Sopenharmony_ci 99062306a36Sopenharmony_ci rtl8xxxu_init_phy_regs(priv, phy_init_table); 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci rtl8xxxu_init_phy_regs(priv, rtl8710b_agc_table); 99362306a36Sopenharmony_ci} 99462306a36Sopenharmony_ci 99562306a36Sopenharmony_cistatic int rtl8710bu_init_phy_rf(struct rtl8xxxu_priv *priv) 99662306a36Sopenharmony_ci{ 99762306a36Sopenharmony_ci const struct rtl8xxxu_rfregval *radioa_init_table; 99862306a36Sopenharmony_ci 99962306a36Sopenharmony_ci if (priv->package_type == PACKAGE_QFN48M_U) 100062306a36Sopenharmony_ci radioa_init_table = rtl8710bu_qfn48m_u_radioa_init_table; 100162306a36Sopenharmony_ci else 100262306a36Sopenharmony_ci radioa_init_table = rtl8710bu_qfn48m_s_radioa_init_table; 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci return rtl8xxxu_init_phy_rf(priv, radioa_init_table, RF_A); 100562306a36Sopenharmony_ci} 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_cistatic int rtl8710bu_iqk_path_a(struct rtl8xxxu_priv *priv, u32 *lok_result) 100862306a36Sopenharmony_ci{ 100962306a36Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c, val32, path_sel_bb; 101062306a36Sopenharmony_ci int result = 0; 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x99000000); 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci /* 101762306a36Sopenharmony_ci * Leave IQK mode 101862306a36Sopenharmony_ci */ 101962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 102062306a36Sopenharmony_ci u32p_replace_bits(&val32, 0, 0xffffff00); 102162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci /* 102462306a36Sopenharmony_ci * Enable path A PA in TX IQK mode 102562306a36Sopenharmony_ci */ 102662306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); 102762306a36Sopenharmony_ci val32 |= 0x80000; 102862306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); 102962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x20000); 103062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); 103162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0x07ff7); 103262306a36Sopenharmony_ci 103362306a36Sopenharmony_ci /* PA,PAD gain adjust */ 103462306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); 103562306a36Sopenharmony_ci val32 |= BIT(11); 103662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); 103762306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_PAD_TXG); 103862306a36Sopenharmony_ci u32p_replace_bits(&val32, 0x1ed, 0x00fff); 103962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, val32); 104062306a36Sopenharmony_ci 104162306a36Sopenharmony_ci /* enter IQK mode */ 104262306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 104362306a36Sopenharmony_ci u32p_replace_bits(&val32, 0x808000, 0xffffff00); 104462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_ci /* path-A IQK setting */ 104762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); 104862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); 104962306a36Sopenharmony_ci 105062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x821403ff); 105162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160c06); 105262306a36Sopenharmony_ci 105362306a36Sopenharmony_ci /* LO calibration setting */ 105462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x02002911); 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 105762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xfa000000); 105862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 105962306a36Sopenharmony_ci 106062306a36Sopenharmony_ci mdelay(10); 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci /* 106562306a36Sopenharmony_ci * Leave IQK mode 106662306a36Sopenharmony_ci */ 106762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 106862306a36Sopenharmony_ci u32p_replace_bits(&val32, 0, 0xffffff00); 106962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); 107262306a36Sopenharmony_ci val32 &= ~BIT(11); 107362306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci /* save LOK result */ 107662306a36Sopenharmony_ci *lok_result = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC); 107762306a36Sopenharmony_ci 107862306a36Sopenharmony_ci /* Check failed */ 107962306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 108062306a36Sopenharmony_ci reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); 108162306a36Sopenharmony_ci reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 108462306a36Sopenharmony_ci ((reg_e94 & 0x03ff0000) != 0x01420000) && 108562306a36Sopenharmony_ci ((reg_e9c & 0x03ff0000) != 0x00420000)) 108662306a36Sopenharmony_ci result |= 0x01; 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci return result; 108962306a36Sopenharmony_ci} 109062306a36Sopenharmony_ci 109162306a36Sopenharmony_cistatic int rtl8710bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result) 109262306a36Sopenharmony_ci{ 109362306a36Sopenharmony_ci u32 reg_ea4, reg_eac, reg_e94, reg_e9c, val32, path_sel_bb, tmp; 109462306a36Sopenharmony_ci int result = 0; 109562306a36Sopenharmony_ci 109662306a36Sopenharmony_ci path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); 109762306a36Sopenharmony_ci 109862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x99000000); 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci /* 110162306a36Sopenharmony_ci * Leave IQK mode 110262306a36Sopenharmony_ci */ 110362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 110462306a36Sopenharmony_ci u32p_replace_bits(&val32, 0, 0xffffff00); 110562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 110662306a36Sopenharmony_ci 110762306a36Sopenharmony_ci /* modify RXIQK mode table */ 110862306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); 110962306a36Sopenharmony_ci val32 |= 0x80000; 111062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); 111162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); 111262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); 111362306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173); 111462306a36Sopenharmony_ci 111562306a36Sopenharmony_ci /* PA,PAD gain adjust */ 111662306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); 111762306a36Sopenharmony_ci val32 |= BIT(11); 111862306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); 111962306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_PAD_TXG); 112062306a36Sopenharmony_ci u32p_replace_bits(&val32, 0xf, 0x003e0); 112162306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, val32); 112262306a36Sopenharmony_ci 112362306a36Sopenharmony_ci /* 112462306a36Sopenharmony_ci * Enter IQK mode 112562306a36Sopenharmony_ci */ 112662306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 112762306a36Sopenharmony_ci u32p_replace_bits(&val32, 0x808000, 0xffffff00); 112862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 112962306a36Sopenharmony_ci 113062306a36Sopenharmony_ci /* path-A IQK setting */ 113162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c); 113262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c); 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x8216129f); 113562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160c00); 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci /* 113862306a36Sopenharmony_ci * Tx IQK setting 113962306a36Sopenharmony_ci */ 114062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); 114162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci /* LO calibration setting */ 114462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 114762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); 114862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci mdelay(10); 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci /* Check failed */ 115362306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 115462306a36Sopenharmony_ci reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); 115562306a36Sopenharmony_ci reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 115862306a36Sopenharmony_ci ((reg_e94 & 0x03ff0000) != 0x01420000) && 115962306a36Sopenharmony_ci ((reg_e9c & 0x03ff0000) != 0x00420000)) { 116062306a36Sopenharmony_ci result |= 0x01; 116162306a36Sopenharmony_ci } else { /* If TX not OK, ignore RX */ 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci /* reload RF path */ 116462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_ci /* 116762306a36Sopenharmony_ci * Leave IQK mode 116862306a36Sopenharmony_ci */ 116962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 117062306a36Sopenharmony_ci u32p_replace_bits(&val32, 0, 0xffffff00); 117162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); 117462306a36Sopenharmony_ci val32 &= ~BIT(11); 117562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); 117662306a36Sopenharmony_ci 117762306a36Sopenharmony_ci return result; 117862306a36Sopenharmony_ci } 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci val32 = 0x80007c00 | (reg_e94 & 0x3ff0000) | ((reg_e9c & 0x3ff0000) >> 16); 118162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, val32); 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_ci /* 118462306a36Sopenharmony_ci * Modify RX IQK mode table 118562306a36Sopenharmony_ci */ 118662306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 118762306a36Sopenharmony_ci u32p_replace_bits(&val32, 0, 0xffffff00); 118862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 118962306a36Sopenharmony_ci 119062306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT); 119162306a36Sopenharmony_ci val32 |= 0x80000; 119262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32); 119362306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000); 119462306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f); 119562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7ff2); 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_ci /* 119862306a36Sopenharmony_ci * PA, PAD setting 119962306a36Sopenharmony_ci */ 120062306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); 120162306a36Sopenharmony_ci val32 |= BIT(11); 120262306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); 120362306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_PAD_TXG); 120462306a36Sopenharmony_ci u32p_replace_bits(&val32, 0x2a, 0x00fff); 120562306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, val32); 120662306a36Sopenharmony_ci 120762306a36Sopenharmony_ci /* 120862306a36Sopenharmony_ci * Enter IQK mode 120962306a36Sopenharmony_ci */ 121062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 121162306a36Sopenharmony_ci u32p_replace_bits(&val32, 0x808000, 0xffffff00); 121262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 121362306a36Sopenharmony_ci 121462306a36Sopenharmony_ci /* 121562306a36Sopenharmony_ci * RX IQK setting 121662306a36Sopenharmony_ci */ 121762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_ci /* path-A IQK setting */ 122062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x38008c1c); 122162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x18008c1c); 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x2816169f); 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci /* LO calibration setting */ 122662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911); 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 122962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000); 123062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000); 123162306a36Sopenharmony_ci 123262306a36Sopenharmony_ci mdelay(10); 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_ci /* reload RF path */ 123562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); 123662306a36Sopenharmony_ci 123762306a36Sopenharmony_ci /* 123862306a36Sopenharmony_ci * Leave IQK mode 123962306a36Sopenharmony_ci */ 124062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 124162306a36Sopenharmony_ci u32p_replace_bits(&val32, 0, 0xffffff00); 124262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 124362306a36Sopenharmony_ci 124462306a36Sopenharmony_ci val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA); 124562306a36Sopenharmony_ci val32 &= ~BIT(11); 124662306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32); 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci /* reload LOK value */ 124962306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC, lok_result); 125062306a36Sopenharmony_ci 125162306a36Sopenharmony_ci /* Check failed */ 125262306a36Sopenharmony_ci reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 125362306a36Sopenharmony_ci reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); 125462306a36Sopenharmony_ci 125562306a36Sopenharmony_ci tmp = (reg_eac & 0x03ff0000) >> 16; 125662306a36Sopenharmony_ci if ((tmp & 0x200) > 0) 125762306a36Sopenharmony_ci tmp = 0x400 - tmp; 125862306a36Sopenharmony_ci 125962306a36Sopenharmony_ci if (!(reg_eac & BIT(27)) && 126062306a36Sopenharmony_ci ((reg_ea4 & 0x03ff0000) != 0x01320000) && 126162306a36Sopenharmony_ci ((reg_eac & 0x03ff0000) != 0x00360000) && 126262306a36Sopenharmony_ci (((reg_ea4 & 0x03ff0000) >> 16) < 0x11a) && 126362306a36Sopenharmony_ci (((reg_ea4 & 0x03ff0000) >> 16) > 0xe6) && 126462306a36Sopenharmony_ci (tmp < 0x1a)) 126562306a36Sopenharmony_ci result |= 0x02; 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ci return result; 126862306a36Sopenharmony_ci} 126962306a36Sopenharmony_ci 127062306a36Sopenharmony_cistatic void rtl8710bu_phy_iqcalibrate(struct rtl8xxxu_priv *priv, 127162306a36Sopenharmony_ci int result[][8], int t) 127262306a36Sopenharmony_ci{ 127362306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 127462306a36Sopenharmony_ci u32 i, val32, rx_initial_gain, lok_result; 127562306a36Sopenharmony_ci u32 path_sel_bb, path_sel_rf; 127662306a36Sopenharmony_ci int path_a_ok; 127762306a36Sopenharmony_ci int retry = 2; 127862306a36Sopenharmony_ci static const u32 adda_regs[RTL8XXXU_ADDA_REGS] = { 127962306a36Sopenharmony_ci REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH, 128062306a36Sopenharmony_ci REG_RX_WAIT_CCA, REG_TX_CCK_RFON, 128162306a36Sopenharmony_ci REG_TX_CCK_BBON, REG_TX_OFDM_RFON, 128262306a36Sopenharmony_ci REG_TX_OFDM_BBON, REG_TX_TO_RX, 128362306a36Sopenharmony_ci REG_TX_TO_TX, REG_RX_CCK, 128462306a36Sopenharmony_ci REG_RX_OFDM, REG_RX_WAIT_RIFS, 128562306a36Sopenharmony_ci REG_RX_TO_RX, REG_STANDBY, 128662306a36Sopenharmony_ci REG_SLEEP, REG_PMPD_ANAEN 128762306a36Sopenharmony_ci }; 128862306a36Sopenharmony_ci static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = { 128962306a36Sopenharmony_ci REG_TXPAUSE, REG_BEACON_CTRL, 129062306a36Sopenharmony_ci REG_BEACON_CTRL_1, REG_GPIO_MUXCFG 129162306a36Sopenharmony_ci }; 129262306a36Sopenharmony_ci static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = { 129362306a36Sopenharmony_ci REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR, 129462306a36Sopenharmony_ci REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B, 129562306a36Sopenharmony_ci REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE, 129662306a36Sopenharmony_ci REG_FPGA0_XB_RF_INT_OE, REG_CCK0_AFE_SETTING 129762306a36Sopenharmony_ci }; 129862306a36Sopenharmony_ci 129962306a36Sopenharmony_ci /* 130062306a36Sopenharmony_ci * Note: IQ calibration must be performed after loading 130162306a36Sopenharmony_ci * PHY_REG.txt , and radio_a, radio_b.txt 130262306a36Sopenharmony_ci */ 130362306a36Sopenharmony_ci 130462306a36Sopenharmony_ci rx_initial_gain = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci if (t == 0) { 130762306a36Sopenharmony_ci /* Save ADDA parameters, turn Path A ADDA on */ 130862306a36Sopenharmony_ci rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup, 130962306a36Sopenharmony_ci RTL8XXXU_ADDA_REGS); 131062306a36Sopenharmony_ci rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup); 131162306a36Sopenharmony_ci rtl8xxxu_save_regs(priv, iqk_bb_regs, 131262306a36Sopenharmony_ci priv->bb_backup, RTL8XXXU_BB_REGS); 131362306a36Sopenharmony_ci } 131462306a36Sopenharmony_ci 131562306a36Sopenharmony_ci rtl8xxxu_path_adda_on(priv, adda_regs, true); 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci if (t == 0) { 131862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM1); 131962306a36Sopenharmony_ci priv->pi_enabled = u32_get_bits(val32, FPGA0_HSSI_PARM1_PI); 132062306a36Sopenharmony_ci } 132162306a36Sopenharmony_ci 132262306a36Sopenharmony_ci if (!priv->pi_enabled) { 132362306a36Sopenharmony_ci /* Switch BB to PI mode to do IQ Calibration */ 132462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, 0x01000100); 132562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM1, 0x01000100); 132662306a36Sopenharmony_ci } 132762306a36Sopenharmony_ci 132862306a36Sopenharmony_ci /* MAC settings */ 132962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_PTCL_CTRL); 133062306a36Sopenharmony_ci val32 |= 0x00ff0000; 133162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_PTCL_CTRL, val32); 133262306a36Sopenharmony_ci 133362306a36Sopenharmony_ci /* save RF path */ 133462306a36Sopenharmony_ci path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); 133562306a36Sopenharmony_ci path_sel_rf = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_S0S1); 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci /* BB setting */ 133862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_CCK0_AFE_SETTING); 133962306a36Sopenharmony_ci val32 |= 0x0f000000; 134062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_CCK0_AFE_SETTING, val32); 134162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, 0x03c00010); 134262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05601); 134362306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4); 134462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x25204000); 134562306a36Sopenharmony_ci 134662306a36Sopenharmony_ci /* IQ calibration setting */ 134762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 134862306a36Sopenharmony_ci u32p_replace_bits(&val32, 0x808000, 0xffffff00); 134962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 135062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00); 135162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800); 135262306a36Sopenharmony_ci 135362306a36Sopenharmony_ci for (i = 0; i < retry; i++) { 135462306a36Sopenharmony_ci path_a_ok = rtl8710bu_iqk_path_a(priv, &lok_result); 135562306a36Sopenharmony_ci 135662306a36Sopenharmony_ci if (path_a_ok == 0x01) { 135762306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A); 135862306a36Sopenharmony_ci result[t][0] = (val32 >> 16) & 0x3ff; 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A); 136162306a36Sopenharmony_ci result[t][1] = (val32 >> 16) & 0x3ff; 136262306a36Sopenharmony_ci break; 136362306a36Sopenharmony_ci } else { 136462306a36Sopenharmony_ci result[t][0] = 0x100; 136562306a36Sopenharmony_ci result[t][1] = 0x0; 136662306a36Sopenharmony_ci } 136762306a36Sopenharmony_ci } 136862306a36Sopenharmony_ci 136962306a36Sopenharmony_ci for (i = 0; i < retry; i++) { 137062306a36Sopenharmony_ci path_a_ok = rtl8710bu_rx_iqk_path_a(priv, lok_result); 137162306a36Sopenharmony_ci 137262306a36Sopenharmony_ci if (path_a_ok == 0x03) { 137362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2); 137462306a36Sopenharmony_ci result[t][2] = (val32 >> 16) & 0x3ff; 137562306a36Sopenharmony_ci 137662306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2); 137762306a36Sopenharmony_ci result[t][3] = (val32 >> 16) & 0x3ff; 137862306a36Sopenharmony_ci break; 137962306a36Sopenharmony_ci } else { 138062306a36Sopenharmony_ci result[t][2] = 0x100; 138162306a36Sopenharmony_ci result[t][3] = 0x0; 138262306a36Sopenharmony_ci } 138362306a36Sopenharmony_ci } 138462306a36Sopenharmony_ci 138562306a36Sopenharmony_ci if (!path_a_ok) 138662306a36Sopenharmony_ci dev_warn(dev, "%s: Path A IQK failed!\n", __func__); 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci /* Back to BB mode, load original value */ 138962306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK); 139062306a36Sopenharmony_ci u32p_replace_bits(&val32, 0, 0xffffff00); 139162306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32); 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_ci if (t == 0) 139462306a36Sopenharmony_ci return; 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_ci /* Reload ADDA power saving parameters */ 139762306a36Sopenharmony_ci rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup, RTL8XXXU_ADDA_REGS); 139862306a36Sopenharmony_ci 139962306a36Sopenharmony_ci /* Reload MAC parameters */ 140062306a36Sopenharmony_ci rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup); 140162306a36Sopenharmony_ci 140262306a36Sopenharmony_ci /* Reload BB parameters */ 140362306a36Sopenharmony_ci rtl8xxxu_restore_regs(priv, iqk_bb_regs, priv->bb_backup, RTL8XXXU_BB_REGS); 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_ci /* Reload RF path */ 140662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); 140762306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_S0S1, path_sel_rf); 140862306a36Sopenharmony_ci 140962306a36Sopenharmony_ci /* Restore RX initial gain */ 141062306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); 141162306a36Sopenharmony_ci u32p_replace_bits(&val32, 0x50, 0x000000ff); 141262306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32); 141362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1); 141462306a36Sopenharmony_ci u32p_replace_bits(&val32, rx_initial_gain & 0xff, 0x000000ff); 141562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32); 141662306a36Sopenharmony_ci 141762306a36Sopenharmony_ci /* Load 0xe30 IQC default value */ 141862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00); 141962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00); 142062306a36Sopenharmony_ci} 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_cistatic void rtl8710bu_phy_iq_calibrate(struct rtl8xxxu_priv *priv) 142362306a36Sopenharmony_ci{ 142462306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 142562306a36Sopenharmony_ci int result[4][8]; /* last is final result */ 142662306a36Sopenharmony_ci int i, candidate; 142762306a36Sopenharmony_ci bool path_a_ok; 142862306a36Sopenharmony_ci s32 reg_e94, reg_e9c, reg_ea4, reg_eac; 142962306a36Sopenharmony_ci s32 reg_tmp = 0; 143062306a36Sopenharmony_ci bool simu; 143162306a36Sopenharmony_ci u32 path_sel_bb; 143262306a36Sopenharmony_ci 143362306a36Sopenharmony_ci /* Save RF path */ 143462306a36Sopenharmony_ci path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH); 143562306a36Sopenharmony_ci 143662306a36Sopenharmony_ci memset(result, 0, sizeof(result)); 143762306a36Sopenharmony_ci candidate = -1; 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_ci path_a_ok = false; 144062306a36Sopenharmony_ci 144162306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 144262306a36Sopenharmony_ci rtl8710bu_phy_iqcalibrate(priv, result, i); 144362306a36Sopenharmony_ci 144462306a36Sopenharmony_ci if (i == 1) { 144562306a36Sopenharmony_ci simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 1); 144662306a36Sopenharmony_ci if (simu) { 144762306a36Sopenharmony_ci candidate = 0; 144862306a36Sopenharmony_ci break; 144962306a36Sopenharmony_ci } 145062306a36Sopenharmony_ci } 145162306a36Sopenharmony_ci 145262306a36Sopenharmony_ci if (i == 2) { 145362306a36Sopenharmony_ci simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 2); 145462306a36Sopenharmony_ci if (simu) { 145562306a36Sopenharmony_ci candidate = 0; 145662306a36Sopenharmony_ci break; 145762306a36Sopenharmony_ci } 145862306a36Sopenharmony_ci 145962306a36Sopenharmony_ci simu = rtl8xxxu_gen2_simularity_compare(priv, result, 1, 2); 146062306a36Sopenharmony_ci if (simu) { 146162306a36Sopenharmony_ci candidate = 1; 146262306a36Sopenharmony_ci } else { 146362306a36Sopenharmony_ci for (i = 0; i < 8; i++) 146462306a36Sopenharmony_ci reg_tmp += result[3][i]; 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_ci if (reg_tmp) 146762306a36Sopenharmony_ci candidate = 3; 146862306a36Sopenharmony_ci else 146962306a36Sopenharmony_ci candidate = -1; 147062306a36Sopenharmony_ci } 147162306a36Sopenharmony_ci } 147262306a36Sopenharmony_ci } 147362306a36Sopenharmony_ci 147462306a36Sopenharmony_ci if (candidate >= 0) { 147562306a36Sopenharmony_ci reg_e94 = result[candidate][0]; 147662306a36Sopenharmony_ci reg_e9c = result[candidate][1]; 147762306a36Sopenharmony_ci reg_ea4 = result[candidate][2]; 147862306a36Sopenharmony_ci reg_eac = result[candidate][3]; 147962306a36Sopenharmony_ci 148062306a36Sopenharmony_ci dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate); 148162306a36Sopenharmony_ci dev_dbg(dev, "%s: e94=%x e9c=%x ea4=%x eac=%x\n", 148262306a36Sopenharmony_ci __func__, reg_e94, reg_e9c, reg_ea4, reg_eac); 148362306a36Sopenharmony_ci 148462306a36Sopenharmony_ci path_a_ok = true; 148562306a36Sopenharmony_ci 148662306a36Sopenharmony_ci if (reg_e94) 148762306a36Sopenharmony_ci rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result, 148862306a36Sopenharmony_ci candidate, (reg_ea4 == 0)); 148962306a36Sopenharmony_ci } 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_ci rtl8xxxu_save_regs(priv, rtl8xxxu_iqk_phy_iq_bb_reg, 149262306a36Sopenharmony_ci priv->bb_recovery_backup, RTL8XXXU_BB_REGS); 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb); 149562306a36Sopenharmony_ci} 149662306a36Sopenharmony_ci 149762306a36Sopenharmony_cistatic int rtl8710b_emu_to_active(struct rtl8xxxu_priv *priv) 149862306a36Sopenharmony_ci{ 149962306a36Sopenharmony_ci u8 val8; 150062306a36Sopenharmony_ci int count, ret = 0; 150162306a36Sopenharmony_ci 150262306a36Sopenharmony_ci /* AFE power mode selection: 1: LDO mode, 0: Power-cut mode */ 150362306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, 0x5d); 150462306a36Sopenharmony_ci val8 &= ~BIT(0); 150562306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0x5d, val8); 150662306a36Sopenharmony_ci 150762306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC_8710B); 150862306a36Sopenharmony_ci val8 |= BIT(0); 150962306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_SYS_FUNC_8710B, val8); 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0x56, 0x0e); 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, 0x20); 151462306a36Sopenharmony_ci val8 |= BIT(0); 151562306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0x20, val8); 151662306a36Sopenharmony_ci 151762306a36Sopenharmony_ci for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { 151862306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, 0x20); 151962306a36Sopenharmony_ci if (!(val8 & BIT(0))) 152062306a36Sopenharmony_ci break; 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci udelay(10); 152362306a36Sopenharmony_ci } 152462306a36Sopenharmony_ci 152562306a36Sopenharmony_ci if (!count) 152662306a36Sopenharmony_ci ret = -EBUSY; 152762306a36Sopenharmony_ci 152862306a36Sopenharmony_ci return ret; 152962306a36Sopenharmony_ci} 153062306a36Sopenharmony_ci 153162306a36Sopenharmony_cistatic int rtl8710bu_active_to_emu(struct rtl8xxxu_priv *priv) 153262306a36Sopenharmony_ci{ 153362306a36Sopenharmony_ci u8 val8; 153462306a36Sopenharmony_ci u32 val32; 153562306a36Sopenharmony_ci int count, ret = 0; 153662306a36Sopenharmony_ci 153762306a36Sopenharmony_ci /* Turn off RF */ 153862306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_SYS_FUNC_8710B); 153962306a36Sopenharmony_ci val32 &= ~GENMASK(26, 24); 154062306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_SYS_FUNC_8710B, val32); 154162306a36Sopenharmony_ci 154262306a36Sopenharmony_ci /* BB reset */ 154362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_SYS_FUNC_8710B); 154462306a36Sopenharmony_ci val32 &= ~GENMASK(17, 16); 154562306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_SYS_FUNC_8710B, val32); 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_ci /* Turn off MAC by HW state machine */ 154862306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, 0x20); 154962306a36Sopenharmony_ci val8 |= BIT(1); 155062306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0x20, val8); 155162306a36Sopenharmony_ci 155262306a36Sopenharmony_ci for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { 155362306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, 0x20); 155462306a36Sopenharmony_ci if ((val8 & BIT(1)) == 0) { 155562306a36Sopenharmony_ci ret = 0; 155662306a36Sopenharmony_ci break; 155762306a36Sopenharmony_ci } 155862306a36Sopenharmony_ci udelay(10); 155962306a36Sopenharmony_ci } 156062306a36Sopenharmony_ci 156162306a36Sopenharmony_ci if (!count) 156262306a36Sopenharmony_ci ret = -EBUSY; 156362306a36Sopenharmony_ci 156462306a36Sopenharmony_ci return ret; 156562306a36Sopenharmony_ci} 156662306a36Sopenharmony_ci 156762306a36Sopenharmony_cistatic int rtl8710bu_active_to_lps(struct rtl8xxxu_priv *priv) 156862306a36Sopenharmony_ci{ 156962306a36Sopenharmony_ci struct device *dev = &priv->udev->dev; 157062306a36Sopenharmony_ci u8 val8; 157162306a36Sopenharmony_ci u16 val16; 157262306a36Sopenharmony_ci u32 val32; 157362306a36Sopenharmony_ci int retry, retval; 157462306a36Sopenharmony_ci 157562306a36Sopenharmony_ci /* Tx Pause */ 157662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); 157762306a36Sopenharmony_ci 157862306a36Sopenharmony_ci retry = 100; 157962306a36Sopenharmony_ci retval = -EBUSY; 158062306a36Sopenharmony_ci /* 158162306a36Sopenharmony_ci * Poll 32 bit wide REG_SCH_TX_CMD for 0x00000000 to ensure no TX is pending. 158262306a36Sopenharmony_ci */ 158362306a36Sopenharmony_ci do { 158462306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_SCH_TX_CMD); 158562306a36Sopenharmony_ci if (!val32) { 158662306a36Sopenharmony_ci retval = 0; 158762306a36Sopenharmony_ci break; 158862306a36Sopenharmony_ci } 158962306a36Sopenharmony_ci udelay(10); 159062306a36Sopenharmony_ci } while (retry--); 159162306a36Sopenharmony_ci 159262306a36Sopenharmony_ci if (!retry) { 159362306a36Sopenharmony_ci dev_warn(dev, "Failed to flush TX queue\n"); 159462306a36Sopenharmony_ci retval = -EBUSY; 159562306a36Sopenharmony_ci return retval; 159662306a36Sopenharmony_ci } 159762306a36Sopenharmony_ci 159862306a36Sopenharmony_ci /* Disable CCK and OFDM, clock gated */ 159962306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); 160062306a36Sopenharmony_ci val8 &= ~SYS_FUNC_BBRSTB; 160162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); 160262306a36Sopenharmony_ci 160362306a36Sopenharmony_ci udelay(2); 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci /* Whole BB is reset */ 160662306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC); 160762306a36Sopenharmony_ci val8 &= ~SYS_FUNC_BB_GLB_RSTN; 160862306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_SYS_FUNC, val8); 160962306a36Sopenharmony_ci 161062306a36Sopenharmony_ci /* Reset MAC TRX */ 161162306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_CR); 161262306a36Sopenharmony_ci val16 &= 0xff00; 161362306a36Sopenharmony_ci val16 |= CR_HCI_RXDMA_ENABLE | CR_HCI_TXDMA_ENABLE; 161462306a36Sopenharmony_ci val16 &= ~CR_SECURITY_ENABLE; 161562306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_CR, val16); 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_ci /* Respond TxOK to scheduler */ 161862306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_DUAL_TSF_RST); 161962306a36Sopenharmony_ci val8 |= DUAL_TSF_TX_OK; 162062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, val8); 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci return retval; 162362306a36Sopenharmony_ci} 162462306a36Sopenharmony_ci 162562306a36Sopenharmony_cistatic int rtl8710bu_power_on(struct rtl8xxxu_priv *priv) 162662306a36Sopenharmony_ci{ 162762306a36Sopenharmony_ci u32 val32; 162862306a36Sopenharmony_ci u16 val16; 162962306a36Sopenharmony_ci u8 val8; 163062306a36Sopenharmony_ci int ret; 163162306a36Sopenharmony_ci 163262306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_USB_ACCESS_TIMEOUT, 0x80); 163362306a36Sopenharmony_ci 163462306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); 163562306a36Sopenharmony_ci val8 &= ~BIT(5); 163662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); 163762306a36Sopenharmony_ci 163862306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC_8710B); 163962306a36Sopenharmony_ci val8 |= BIT(0); 164062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_SYS_FUNC_8710B, val8); 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, 0x20); 164362306a36Sopenharmony_ci val8 |= BIT(0); 164462306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0x20, val8); 164562306a36Sopenharmony_ci 164662306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_AFE_CTRL_8710B, 0); 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_WL_STATUS_8710B); 164962306a36Sopenharmony_ci val8 |= BIT(1); 165062306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_WL_STATUS_8710B, val8); 165162306a36Sopenharmony_ci 165262306a36Sopenharmony_ci ret = rtl8710b_emu_to_active(priv); 165362306a36Sopenharmony_ci if (ret) 165462306a36Sopenharmony_ci return ret; 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_CR, 0); 165762306a36Sopenharmony_ci 165862306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_CR); 165962306a36Sopenharmony_ci 166062306a36Sopenharmony_ci val16 |= CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE | 166162306a36Sopenharmony_ci CR_TXDMA_ENABLE | CR_RXDMA_ENABLE | 166262306a36Sopenharmony_ci CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE | 166362306a36Sopenharmony_ci CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE; 166462306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_CR, val16); 166562306a36Sopenharmony_ci 166662306a36Sopenharmony_ci /* Enable hardware sequence number. */ 166762306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_HWSEQ_CTRL); 166862306a36Sopenharmony_ci val8 |= 0x7f; 166962306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_HWSEQ_CTRL, val8); 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_ci udelay(2); 167262306a36Sopenharmony_ci 167362306a36Sopenharmony_ci /* 167462306a36Sopenharmony_ci * Technically the rest was in the rtl8710bu_hal_init function, 167562306a36Sopenharmony_ci * not the power_on function, but it's fine because we only 167662306a36Sopenharmony_ci * call power_on from init_device. 167762306a36Sopenharmony_ci */ 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, 0xfef9); 168062306a36Sopenharmony_ci val8 &= ~BIT(0); 168162306a36Sopenharmony_ci rtl8xxxu_write8(priv, 0xfef9, val8); 168262306a36Sopenharmony_ci 168362306a36Sopenharmony_ci /* Clear the 0x40000138[5] to prevent CM4 Suspend */ 168462306a36Sopenharmony_ci val32 = rtl8710b_read_syson_reg(priv, 0x138); 168562306a36Sopenharmony_ci val32 &= ~BIT(5); 168662306a36Sopenharmony_ci rtl8710b_write_syson_reg(priv, 0x138, val32); 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_ci return ret; 168962306a36Sopenharmony_ci} 169062306a36Sopenharmony_ci 169162306a36Sopenharmony_cistatic void rtl8710bu_power_off(struct rtl8xxxu_priv *priv) 169262306a36Sopenharmony_ci{ 169362306a36Sopenharmony_ci u32 val32; 169462306a36Sopenharmony_ci u8 val8; 169562306a36Sopenharmony_ci 169662306a36Sopenharmony_ci rtl8xxxu_flush_fifo(priv); 169762306a36Sopenharmony_ci 169862306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_HISR0_8710B, 0xffffffff); 169962306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_HIMR0_8710B, 0x0); 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ci /* Set the 0x40000138[5] to allow CM4 Suspend */ 170262306a36Sopenharmony_ci val32 = rtl8710b_read_syson_reg(priv, 0x138); 170362306a36Sopenharmony_ci val32 |= BIT(5); 170462306a36Sopenharmony_ci rtl8710b_write_syson_reg(priv, 0x138, val32); 170562306a36Sopenharmony_ci 170662306a36Sopenharmony_ci /* Stop rx */ 170762306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_CR, 0x00); 170862306a36Sopenharmony_ci 170962306a36Sopenharmony_ci rtl8710bu_active_to_lps(priv); 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_ci /* Reset MCU ? */ 171262306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_8051FW_CTRL_V1_8710B + 3); 171362306a36Sopenharmony_ci val8 &= ~BIT(0); 171462306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_8051FW_CTRL_V1_8710B + 3, val8); 171562306a36Sopenharmony_ci 171662306a36Sopenharmony_ci /* Reset MCU ready status */ 171762306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_8051FW_CTRL_V1_8710B, 0x00); 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci rtl8710bu_active_to_emu(priv); 172062306a36Sopenharmony_ci} 172162306a36Sopenharmony_ci 172262306a36Sopenharmony_cistatic void rtl8710b_reset_8051(struct rtl8xxxu_priv *priv) 172362306a36Sopenharmony_ci{ 172462306a36Sopenharmony_ci u8 val8; 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_8051FW_CTRL_V1_8710B + 3); 172762306a36Sopenharmony_ci val8 &= ~BIT(0); 172862306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_8051FW_CTRL_V1_8710B + 3, val8); 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci udelay(50); 173162306a36Sopenharmony_ci 173262306a36Sopenharmony_ci val8 = rtl8xxxu_read8(priv, REG_8051FW_CTRL_V1_8710B + 3); 173362306a36Sopenharmony_ci val8 |= BIT(0); 173462306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_8051FW_CTRL_V1_8710B + 3, val8); 173562306a36Sopenharmony_ci} 173662306a36Sopenharmony_ci 173762306a36Sopenharmony_cistatic void rtl8710b_enable_rf(struct rtl8xxxu_priv *priv) 173862306a36Sopenharmony_ci{ 173962306a36Sopenharmony_ci u32 val32; 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_RF_CTRL, RF_ENABLE | RF_RSTB | RF_SDMRSTB); 174262306a36Sopenharmony_ci 174362306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); 174462306a36Sopenharmony_ci val32 &= ~(OFDM_RF_PATH_RX_MASK | OFDM_RF_PATH_TX_MASK); 174562306a36Sopenharmony_ci val32 |= OFDM_RF_PATH_RX_A | OFDM_RF_PATH_TX_A; 174662306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); 174762306a36Sopenharmony_ci 174862306a36Sopenharmony_ci rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); 174962306a36Sopenharmony_ci} 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_cistatic void rtl8710b_disable_rf(struct rtl8xxxu_priv *priv) 175262306a36Sopenharmony_ci{ 175362306a36Sopenharmony_ci u32 val32; 175462306a36Sopenharmony_ci 175562306a36Sopenharmony_ci val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE); 175662306a36Sopenharmony_ci val32 &= ~OFDM_RF_PATH_TX_MASK; 175762306a36Sopenharmony_ci rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32); 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_ci /* Power down RF module */ 176062306a36Sopenharmony_ci rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0); 176162306a36Sopenharmony_ci} 176262306a36Sopenharmony_ci 176362306a36Sopenharmony_cistatic void rtl8710b_usb_quirks(struct rtl8xxxu_priv *priv) 176462306a36Sopenharmony_ci{ 176562306a36Sopenharmony_ci u16 val16; 176662306a36Sopenharmony_ci 176762306a36Sopenharmony_ci rtl8xxxu_gen2_usb_quirks(priv); 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci val16 = rtl8xxxu_read16(priv, REG_CR); 177062306a36Sopenharmony_ci val16 |= (CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE); 177162306a36Sopenharmony_ci rtl8xxxu_write16(priv, REG_CR, val16); 177262306a36Sopenharmony_ci} 177362306a36Sopenharmony_ci 177462306a36Sopenharmony_ci#define XTAL1 GENMASK(29, 24) 177562306a36Sopenharmony_ci#define XTAL0 GENMASK(23, 18) 177662306a36Sopenharmony_ci 177762306a36Sopenharmony_cistatic void rtl8710b_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap) 177862306a36Sopenharmony_ci{ 177962306a36Sopenharmony_ci struct rtl8xxxu_cfo_tracking *cfo = &priv->cfo_tracking; 178062306a36Sopenharmony_ci u32 val32; 178162306a36Sopenharmony_ci 178262306a36Sopenharmony_ci if (crystal_cap == cfo->crystal_cap) 178362306a36Sopenharmony_ci return; 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci val32 = rtl8710b_read_syson_reg(priv, REG_SYS_XTAL_CTRL0_8710B); 178662306a36Sopenharmony_ci 178762306a36Sopenharmony_ci dev_dbg(&priv->udev->dev, 178862306a36Sopenharmony_ci "%s: Adjusting crystal cap from 0x%x (actually 0x%x 0x%x) to 0x%x\n", 178962306a36Sopenharmony_ci __func__, 179062306a36Sopenharmony_ci cfo->crystal_cap, 179162306a36Sopenharmony_ci u32_get_bits(val32, XTAL1), 179262306a36Sopenharmony_ci u32_get_bits(val32, XTAL0), 179362306a36Sopenharmony_ci crystal_cap); 179462306a36Sopenharmony_ci 179562306a36Sopenharmony_ci u32p_replace_bits(&val32, crystal_cap, XTAL1); 179662306a36Sopenharmony_ci u32p_replace_bits(&val32, crystal_cap, XTAL0); 179762306a36Sopenharmony_ci rtl8710b_write_syson_reg(priv, REG_SYS_XTAL_CTRL0_8710B, val32); 179862306a36Sopenharmony_ci 179962306a36Sopenharmony_ci cfo->crystal_cap = crystal_cap; 180062306a36Sopenharmony_ci} 180162306a36Sopenharmony_ci 180262306a36Sopenharmony_cistatic s8 rtl8710b_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats) 180362306a36Sopenharmony_ci{ 180462306a36Sopenharmony_ci struct jaguar2_phy_stats_type0 *phy_stats0 = (struct jaguar2_phy_stats_type0 *)phy_stats; 180562306a36Sopenharmony_ci u8 lna_idx = (phy_stats0->lna_h << 3) | phy_stats0->lna_l; 180662306a36Sopenharmony_ci u8 vga_idx = phy_stats0->vga; 180762306a36Sopenharmony_ci s8 rx_pwr_all = 0x00; 180862306a36Sopenharmony_ci 180962306a36Sopenharmony_ci switch (lna_idx) { 181062306a36Sopenharmony_ci case 7: 181162306a36Sopenharmony_ci rx_pwr_all = -52 - (2 * vga_idx); 181262306a36Sopenharmony_ci break; 181362306a36Sopenharmony_ci case 6: 181462306a36Sopenharmony_ci rx_pwr_all = -42 - (2 * vga_idx); 181562306a36Sopenharmony_ci break; 181662306a36Sopenharmony_ci case 5: 181762306a36Sopenharmony_ci rx_pwr_all = -36 - (2 * vga_idx); 181862306a36Sopenharmony_ci break; 181962306a36Sopenharmony_ci case 3: 182062306a36Sopenharmony_ci rx_pwr_all = -12 - (2 * vga_idx); 182162306a36Sopenharmony_ci break; 182262306a36Sopenharmony_ci case 2: 182362306a36Sopenharmony_ci rx_pwr_all = 0 - (2 * vga_idx); 182462306a36Sopenharmony_ci break; 182562306a36Sopenharmony_ci default: 182662306a36Sopenharmony_ci rx_pwr_all = 0; 182762306a36Sopenharmony_ci break; 182862306a36Sopenharmony_ci } 182962306a36Sopenharmony_ci 183062306a36Sopenharmony_ci return rx_pwr_all; 183162306a36Sopenharmony_ci} 183262306a36Sopenharmony_ci 183362306a36Sopenharmony_cistruct rtl8xxxu_fileops rtl8710bu_fops = { 183462306a36Sopenharmony_ci .identify_chip = rtl8710bu_identify_chip, 183562306a36Sopenharmony_ci .parse_efuse = rtl8710bu_parse_efuse, 183662306a36Sopenharmony_ci .load_firmware = rtl8710bu_load_firmware, 183762306a36Sopenharmony_ci .power_on = rtl8710bu_power_on, 183862306a36Sopenharmony_ci .power_off = rtl8710bu_power_off, 183962306a36Sopenharmony_ci .read_efuse = rtl8710b_read_efuse, 184062306a36Sopenharmony_ci .reset_8051 = rtl8710b_reset_8051, 184162306a36Sopenharmony_ci .llt_init = rtl8xxxu_auto_llt_table, 184262306a36Sopenharmony_ci .init_phy_bb = rtl8710bu_init_phy_bb, 184362306a36Sopenharmony_ci .init_phy_rf = rtl8710bu_init_phy_rf, 184462306a36Sopenharmony_ci .phy_lc_calibrate = rtl8188f_phy_lc_calibrate, 184562306a36Sopenharmony_ci .phy_iq_calibrate = rtl8710bu_phy_iq_calibrate, 184662306a36Sopenharmony_ci .config_channel = rtl8710bu_config_channel, 184762306a36Sopenharmony_ci .parse_rx_desc = rtl8xxxu_parse_rxdesc24, 184862306a36Sopenharmony_ci .parse_phystats = jaguar2_rx_parse_phystats, 184962306a36Sopenharmony_ci .init_aggregation = rtl8710bu_init_aggregation, 185062306a36Sopenharmony_ci .init_statistics = rtl8710bu_init_statistics, 185162306a36Sopenharmony_ci .init_burst = rtl8xxxu_init_burst, 185262306a36Sopenharmony_ci .enable_rf = rtl8710b_enable_rf, 185362306a36Sopenharmony_ci .disable_rf = rtl8710b_disable_rf, 185462306a36Sopenharmony_ci .usb_quirks = rtl8710b_usb_quirks, 185562306a36Sopenharmony_ci .set_tx_power = rtl8188f_set_tx_power, 185662306a36Sopenharmony_ci .update_rate_mask = rtl8xxxu_gen2_update_rate_mask, 185762306a36Sopenharmony_ci .report_connect = rtl8xxxu_gen2_report_connect, 185862306a36Sopenharmony_ci .report_rssi = rtl8xxxu_gen2_report_rssi, 185962306a36Sopenharmony_ci .fill_txdesc = rtl8xxxu_fill_txdesc_v2, 186062306a36Sopenharmony_ci .set_crystal_cap = rtl8710b_set_crystal_cap, 186162306a36Sopenharmony_ci .cck_rssi = rtl8710b_cck_rssi, 186262306a36Sopenharmony_ci .writeN_block_size = 4, 186362306a36Sopenharmony_ci .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), 186462306a36Sopenharmony_ci .tx_desc_size = sizeof(struct rtl8xxxu_txdesc40), 186562306a36Sopenharmony_ci .has_tx_report = 1, 186662306a36Sopenharmony_ci .gen2_thermal_meter = 1, 186762306a36Sopenharmony_ci .needs_full_init = 1, 186862306a36Sopenharmony_ci .init_reg_rxfltmap = 1, 186962306a36Sopenharmony_ci .init_reg_pkt_life_time = 1, 187062306a36Sopenharmony_ci .init_reg_hmtfr = 1, 187162306a36Sopenharmony_ci .ampdu_max_time = 0x5e, 187262306a36Sopenharmony_ci /* 187362306a36Sopenharmony_ci * The RTL8710BU vendor driver uses 0x50 here and it works fine, 187462306a36Sopenharmony_ci * but in rtl8xxxu 0x50 causes slow upload and random packet loss. Why? 187562306a36Sopenharmony_ci */ 187662306a36Sopenharmony_ci .ustime_tsf_edca = 0x28, 187762306a36Sopenharmony_ci .max_aggr_num = 0x0c14, 187862306a36Sopenharmony_ci .supports_ap = 1, 187962306a36Sopenharmony_ci .max_macid_num = 16, 188062306a36Sopenharmony_ci .adda_1t_init = 0x03c00016, 188162306a36Sopenharmony_ci .adda_1t_path_on = 0x03c00016, 188262306a36Sopenharmony_ci .trxff_boundary = 0x3f7f, 188362306a36Sopenharmony_ci .pbp_rx = PBP_PAGE_SIZE_256, 188462306a36Sopenharmony_ci .pbp_tx = PBP_PAGE_SIZE_256, 188562306a36Sopenharmony_ci .mactable = rtl8710b_mac_init_table, 188662306a36Sopenharmony_ci .total_page_num = TX_TOTAL_PAGE_NUM_8723B, 188762306a36Sopenharmony_ci .page_num_hi = TX_PAGE_NUM_HI_PQ_8723B, 188862306a36Sopenharmony_ci .page_num_lo = TX_PAGE_NUM_LO_PQ_8723B, 188962306a36Sopenharmony_ci .page_num_norm = TX_PAGE_NUM_NORM_PQ_8723B, 189062306a36Sopenharmony_ci}; 1891