brintos

brintos / linux-shallow public Read only

0
0
Text · 63.2 KiB · 222608d Raw
2111 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause2/* Copyright Fiona Klute <fiona.klute@gmx.de> */3 4#include <linux/of_net.h>5#include "main.h"6#include "coex.h"7#include "debug.h"8#include "mac.h"9#include "phy.h"10#include "reg.h"11#include "rx.h"12#include "rtw8703b.h"13#include "rtw8703b_tables.h"14#include "rtw8723x.h"15 16#define BIT_MASK_TXQ_INIT (BIT(7))17#define WLAN_RL_VAL 0x303018/* disable BAR */19#define WLAN_BAR_VAL 0x0201ffff20#define WLAN_PIFS_VAL 021#define WLAN_RX_PKT_LIMIT 0x1822#define WLAN_SLOT_TIME 0x0923#define WLAN_SPEC_SIFS 0x100a24#define WLAN_MAX_AGG_NR 0x1f25#define WLAN_AMPDU_MAX_TIME 0x7026 27/* unit is 32us */28#define TBTT_PROHIBIT_SETUP_TIME 0x0429#define TBTT_PROHIBIT_HOLD_TIME 0x8030#define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x6431 32/* raw pkt_stat->drv_info_sz is in unit of 8-bytes */33#define RX_DRV_INFO_SZ_UNIT_8703B 834 35#define TRANS_SEQ_END			\36	0xFFFF,				\37	RTW_PWR_CUT_ALL_MSK,		\38	RTW_PWR_INTF_ALL_MSK,		\39	0,				\40	RTW_PWR_CMD_END, 0, 041 42/* rssi in percentage % (dbm = % - 100) */43/* These are used to select simple signal quality levels, might need44 * tweaking. Same for rf_para tables below.45 */46static const u8 wl_rssi_step_8703b[] = {60, 50, 44, 30};47static const u8 bt_rssi_step_8703b[] = {30, 30, 30, 30};48static const struct coex_5g_afh_map afh_5g_8703b[] = { {0, 0, 0} };49 50/* Actually decreasing wifi TX power/RX gain isn't implemented in51 * rtw8703b, but hopefully adjusting the BT side helps.52 */53static const struct coex_rf_para rf_para_tx_8703b[] = {54	{0, 0, false, 7},  /* for normal */55	{0, 10, false, 7}, /* for WL-CPT */56	{1, 0, true, 4},57	{1, 2, true, 4},58	{1, 10, true, 4},59	{1, 15, true, 4}60};61 62static const struct coex_rf_para rf_para_rx_8703b[] = {63	{0, 0, false, 7},  /* for normal */64	{0, 10, false, 7}, /* for WL-CPT */65	{1, 0, true, 5},66	{1, 2, true, 5},67	{1, 10, true, 5},68	{1, 15, true, 5}69};70 71static const u32 rtw8703b_ofdm_swing_table[] = {72	0x0b40002d, /* 0,  -15.0dB */73	0x0c000030, /* 1,  -14.5dB */74	0x0cc00033, /* 2,  -14.0dB */75	0x0d800036, /* 3,  -13.5dB */76	0x0e400039, /* 4,  -13.0dB */77	0x0f00003c, /* 5,  -12.5dB */78	0x10000040, /* 6,  -12.0dB */79	0x11000044, /* 7,  -11.5dB */80	0x12000048, /* 8,  -11.0dB */81	0x1300004c, /* 9,  -10.5dB */82	0x14400051, /* 10, -10.0dB */83	0x15800056, /* 11, -9.5dB */84	0x16c0005b, /* 12, -9.0dB */85	0x18000060, /* 13, -8.5dB */86	0x19800066, /* 14, -8.0dB */87	0x1b00006c, /* 15, -7.5dB */88	0x1c800072, /* 16, -7.0dB */89	0x1e400079, /* 17, -6.5dB */90	0x20000080, /* 18, -6.0dB */91	0x22000088, /* 19, -5.5dB */92	0x24000090, /* 20, -5.0dB */93	0x26000098, /* 21, -4.5dB */94	0x288000a2, /* 22, -4.0dB */95	0x2ac000ab, /* 23, -3.5dB */96	0x2d4000b5, /* 24, -3.0dB */97	0x300000c0, /* 25, -2.5dB */98	0x32c000cb, /* 26, -2.0dB */99	0x35c000d7, /* 27, -1.5dB */100	0x390000e4, /* 28, -1.0dB */101	0x3c8000f2, /* 29, -0.5dB */102	0x40000100, /* 30, +0dB */103	0x43c0010f, /* 31, +0.5dB */104	0x47c0011f, /* 32, +1.0dB */105	0x4c000130, /* 33, +1.5dB */106	0x50800142, /* 34, +2.0dB */107	0x55400155, /* 35, +2.5dB */108	0x5a400169, /* 36, +3.0dB */109	0x5fc0017f, /* 37, +3.5dB */110	0x65400195, /* 38, +4.0dB */111	0x6b8001ae, /* 39, +4.5dB */112	0x71c001c7, /* 40, +5.0dB */113	0x788001e2, /* 41, +5.5dB */114	0x7f8001fe /* 42, +6.0dB */115};116 117static const u32 rtw8703b_cck_pwr_regs[] = {118	0x0a22, 0x0a23, 0x0a24, 0x0a25, 0x0a26, 0x0a27, 0x0a28, 0x0a29,119	0x0a9a, 0x0a9b, 0x0a9c, 0x0a9d, 0x0aa0, 0x0aa1, 0x0aa2, 0x0aa3,120};121 122static const u8 rtw8703b_cck_swing_table[][16] = {123	{0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02,124	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/125	{0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02,126	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/127	{0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02,128	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/129	{0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02,130	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/131	{0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02,132	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/133	{0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02,134	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/135	{0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02,136	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/137	{0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02,138	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/139	{0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03,140	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/141	{0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03,142	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/143	{0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03,144	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/145	{0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03,146	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/147	{0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03,148	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/149	{0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03,150	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/151	{0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04,152	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/153	{0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04,154	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/155	{0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04,156	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/157	{0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04,158	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/159	{0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04,160	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/161	{0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05,162	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/163	{0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05,164	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/165};166 167#define RTW_OFDM_SWING_TABLE_SIZE	ARRAY_SIZE(rtw8703b_ofdm_swing_table)168#define RTW_CCK_SWING_TABLE_SIZE	ARRAY_SIZE(rtw8703b_cck_swing_table)169 170static const struct rtw_pwr_seq_cmd trans_pre_enable_8703b[] = {171	/* set up external crystal (XTAL) */172	{REG_PAD_CTRL1 + 2,173	 RTW_PWR_CUT_ALL_MSK,174	 RTW_PWR_INTF_ALL_MSK,175	 RTW_PWR_ADDR_MAC,176	 RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},177	/* set CLK_REQ to high active */178	{0x0069,179	 RTW_PWR_CUT_ALL_MSK,180	 RTW_PWR_INTF_ALL_MSK,181	 RTW_PWR_ADDR_MAC,182	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},183	/* unlock ISO/CLK/power control register */184	{REG_RSV_CTRL,185	 RTW_PWR_CUT_ALL_MSK,186	 RTW_PWR_INTF_ALL_MSK,187	 RTW_PWR_ADDR_MAC,188	 RTW_PWR_CMD_WRITE, 0xff, 0},189	{TRANS_SEQ_END},190};191 192static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8703b[] = {193	{0x0005,194	 RTW_PWR_CUT_ALL_MSK,195	 RTW_PWR_INTF_ALL_MSK,196	 RTW_PWR_ADDR_MAC,197	 RTW_PWR_CMD_WRITE, BIT(7), 0},198	{TRANS_SEQ_END},199};200 201static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8703b[] = {202	{0x0023,203	 RTW_PWR_CUT_ALL_MSK,204	 RTW_PWR_INTF_SDIO_MSK,205	 RTW_PWR_ADDR_MAC,206	 RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},207	{0x0007,208	 RTW_PWR_CUT_ALL_MSK,209	 RTW_PWR_INTF_SDIO_MSK | RTW_PWR_INTF_USB_MSK,210	 RTW_PWR_ADDR_MAC,211	 RTW_PWR_CMD_WRITE, 0xFF, 0x20},212	{0x0006,213	 RTW_PWR_CUT_ALL_MSK,214	 RTW_PWR_INTF_ALL_MSK,215	 RTW_PWR_ADDR_MAC,216	 RTW_PWR_CMD_WRITE, BIT(0), 0},217	{0x0005,218	 RTW_PWR_CUT_ALL_MSK,219	 RTW_PWR_INTF_ALL_MSK,220	 RTW_PWR_ADDR_MAC,221	 RTW_PWR_CMD_WRITE, BIT(7), BIT(7)},222	{TRANS_SEQ_END},223};224 225static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8703b[] = {226	{0x0020,227	 RTW_PWR_CUT_ALL_MSK,228	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,229	 RTW_PWR_ADDR_MAC,230	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},231	{0x0067,232	 RTW_PWR_CUT_ALL_MSK,233	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,234	 RTW_PWR_ADDR_MAC,235	 RTW_PWR_CMD_WRITE, BIT(4), 0},236	{0x0001,237	 RTW_PWR_CUT_ALL_MSK,238	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,239	 RTW_PWR_ADDR_MAC,240	 RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS},241	{0x0000,242	 RTW_PWR_CUT_ALL_MSK,243	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,244	 RTW_PWR_ADDR_MAC,245	 RTW_PWR_CMD_WRITE, BIT(5), 0},246	{0x0005,247	 RTW_PWR_CUT_ALL_MSK,248	 RTW_PWR_INTF_ALL_MSK,249	 RTW_PWR_ADDR_MAC,250	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0},251	{0x0075,252	 RTW_PWR_CUT_ALL_MSK,253	 RTW_PWR_INTF_PCI_MSK,254	 RTW_PWR_ADDR_MAC,255	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},256	{0x0004,257	 RTW_PWR_CUT_ALL_MSK,258	 RTW_PWR_INTF_PCI_MSK,259	 RTW_PWR_ADDR_MAC,260	 RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},261	{0x0004,262	 RTW_PWR_CUT_ALL_MSK,263	 RTW_PWR_INTF_PCI_MSK,264	 RTW_PWR_ADDR_MAC,265	 RTW_PWR_CMD_WRITE, BIT(3), 0},266	/* wait for power ready */267	{0x0006,268	 RTW_PWR_CUT_ALL_MSK,269	 RTW_PWR_INTF_ALL_MSK,270	 RTW_PWR_ADDR_MAC,271	 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},272	{0x0075,273	 RTW_PWR_CUT_ALL_MSK,274	 RTW_PWR_INTF_PCI_MSK,275	 RTW_PWR_ADDR_MAC,276	 RTW_PWR_CMD_WRITE, BIT(0), 0},277	{0x0006,278	 RTW_PWR_CUT_ALL_MSK,279	 RTW_PWR_INTF_ALL_MSK,280	 RTW_PWR_ADDR_MAC,281	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},282	{0x0005,283	 RTW_PWR_CUT_ALL_MSK,284	 RTW_PWR_INTF_ALL_MSK,285	 RTW_PWR_ADDR_MAC,286	 RTW_PWR_CMD_WRITE, BIT(7), 0},287	{0x0005,288	 RTW_PWR_CUT_ALL_MSK,289	 RTW_PWR_INTF_ALL_MSK,290	 RTW_PWR_ADDR_MAC,291	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0},292	{0x0005,293	 RTW_PWR_CUT_ALL_MSK,294	 RTW_PWR_INTF_ALL_MSK,295	 RTW_PWR_ADDR_MAC,296	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},297	{0x0005,298	 RTW_PWR_CUT_ALL_MSK,299	 RTW_PWR_INTF_ALL_MSK,300	 RTW_PWR_ADDR_MAC,301	 RTW_PWR_CMD_POLLING, BIT(0), 0},302	{0x0010,303	 RTW_PWR_CUT_ALL_MSK,304	 RTW_PWR_INTF_ALL_MSK,305	 RTW_PWR_ADDR_MAC,306	 RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},307	{0x0049,308	 RTW_PWR_CUT_ALL_MSK,309	 RTW_PWR_INTF_ALL_MSK,310	 RTW_PWR_ADDR_MAC,311	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},312	{0x0063,313	 RTW_PWR_CUT_ALL_MSK,314	 RTW_PWR_INTF_ALL_MSK,315	 RTW_PWR_ADDR_MAC,316	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},317	{0x0062,318	 RTW_PWR_CUT_ALL_MSK,319	 RTW_PWR_INTF_ALL_MSK,320	 RTW_PWR_ADDR_MAC,321	 RTW_PWR_CMD_WRITE, BIT(1), 0},322	{0x0058,323	 RTW_PWR_CUT_ALL_MSK,324	 RTW_PWR_INTF_ALL_MSK,325	 RTW_PWR_ADDR_MAC,326	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},327	{0x005A,328	 RTW_PWR_CUT_ALL_MSK,329	 RTW_PWR_INTF_ALL_MSK,330	 RTW_PWR_ADDR_MAC,331	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},332	{0x0068,333	 RTW_PWR_CUT_TEST_MSK,334	 RTW_PWR_INTF_ALL_MSK,335	 RTW_PWR_ADDR_MAC,336	 RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},337	{0x0069,338	 RTW_PWR_CUT_ALL_MSK,339	 RTW_PWR_INTF_ALL_MSK,340	 RTW_PWR_ADDR_MAC,341	 RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},342	{TRANS_SEQ_END},343};344 345static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8703b[] = {346	{0x001f,347	 RTW_PWR_CUT_ALL_MSK,348	 RTW_PWR_INTF_ALL_MSK,349	 RTW_PWR_ADDR_MAC,350	 RTW_PWR_CMD_WRITE, 0xff, 0},351	{0x0049,352	 RTW_PWR_CUT_ALL_MSK,353	 RTW_PWR_INTF_ALL_MSK,354	 RTW_PWR_ADDR_MAC,355	 RTW_PWR_CMD_WRITE, BIT(1), 0},356	{0x0006,357	 RTW_PWR_CUT_ALL_MSK,358	 RTW_PWR_INTF_ALL_MSK,359	 RTW_PWR_ADDR_MAC,360	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},361	{0x0005,362	 RTW_PWR_CUT_ALL_MSK,363	 RTW_PWR_INTF_ALL_MSK,364	 RTW_PWR_ADDR_MAC,365	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},366	{0x0005,367	 RTW_PWR_CUT_ALL_MSK,368	 RTW_PWR_INTF_ALL_MSK,369	 RTW_PWR_ADDR_MAC,370	 RTW_PWR_CMD_POLLING, BIT(1), 0},371	{0x0010,372	 RTW_PWR_CUT_ALL_MSK,373	 RTW_PWR_INTF_ALL_MSK,374	 RTW_PWR_ADDR_MAC,375	 RTW_PWR_CMD_WRITE, BIT(6), 0},376	{0x0000,377	 RTW_PWR_CUT_ALL_MSK,378	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,379	 RTW_PWR_ADDR_MAC,380	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},381	{0x0020,382	 RTW_PWR_CUT_ALL_MSK,383	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,384	 RTW_PWR_ADDR_MAC,385	 RTW_PWR_CMD_WRITE, BIT(0), 0},386	{TRANS_SEQ_END},387};388 389static const struct rtw_pwr_seq_cmd trans_act_to_reset_mcu_8703b[] = {390	{REG_SYS_FUNC_EN + 1,391	 RTW_PWR_CUT_ALL_MSK,392	 RTW_PWR_INTF_SDIO_MSK,393	 RTW_PWR_ADDR_MAC,394	 RTW_PWR_CMD_WRITE, BIT_FEN_CPUEN, 0},395	/* reset MCU ready */396	{REG_MCUFW_CTRL,397	 RTW_PWR_CUT_ALL_MSK,398	 RTW_PWR_INTF_SDIO_MSK,399	 RTW_PWR_ADDR_MAC,400	 RTW_PWR_CMD_WRITE, 0xff, 0},401	/* reset MCU IO wrapper */402	{REG_RSV_CTRL + 1,403	 RTW_PWR_CUT_ALL_MSK,404	 RTW_PWR_INTF_SDIO_MSK,405	 RTW_PWR_ADDR_MAC,406	 RTW_PWR_CMD_WRITE, BIT(0), 0},407	{REG_RSV_CTRL + 1,408	 RTW_PWR_CUT_ALL_MSK,409	 RTW_PWR_INTF_SDIO_MSK,410	 RTW_PWR_ADDR_MAC,411	 RTW_PWR_CMD_WRITE, BIT(0), 1},412	{TRANS_SEQ_END},413};414 415static const struct rtw_pwr_seq_cmd trans_act_to_lps_8703b[] = {416	{0x0301,417	 RTW_PWR_CUT_ALL_MSK,418	 RTW_PWR_INTF_ALL_MSK,419	 RTW_PWR_ADDR_MAC,420	 RTW_PWR_CMD_WRITE, 0xff, 0xff},421	{0x0522,422	 RTW_PWR_CUT_ALL_MSK,423	 RTW_PWR_INTF_ALL_MSK,424	 RTW_PWR_ADDR_MAC,425	 RTW_PWR_CMD_WRITE, 0xff, 0xff},426	{0x05f8,427	 RTW_PWR_CUT_ALL_MSK,428	 RTW_PWR_INTF_ALL_MSK,429	 RTW_PWR_ADDR_MAC,430	 RTW_PWR_CMD_POLLING, 0xff, 0},431	{0x05f9,432	 RTW_PWR_CUT_ALL_MSK,433	 RTW_PWR_INTF_ALL_MSK,434	 RTW_PWR_ADDR_MAC,435	 RTW_PWR_CMD_POLLING, 0xff, 0},436	{0x05fa,437	 RTW_PWR_CUT_ALL_MSK,438	 RTW_PWR_INTF_ALL_MSK,439	 RTW_PWR_ADDR_MAC,440	 RTW_PWR_CMD_POLLING, 0xff, 0},441	{0x05fb,442	 RTW_PWR_CUT_ALL_MSK,443	 RTW_PWR_INTF_ALL_MSK,444	 RTW_PWR_ADDR_MAC,445	 RTW_PWR_CMD_POLLING, 0xff, 0},446	{0x0002,447	 RTW_PWR_CUT_ALL_MSK,448	 RTW_PWR_INTF_ALL_MSK,449	 RTW_PWR_ADDR_MAC,450	 RTW_PWR_CMD_WRITE, BIT(0), 0},451	{0x0002,452	 RTW_PWR_CUT_ALL_MSK,453	 RTW_PWR_INTF_ALL_MSK,454	 RTW_PWR_ADDR_MAC,455	 RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US},456	{0x0002,457	 RTW_PWR_CUT_ALL_MSK,458	 RTW_PWR_INTF_ALL_MSK,459	 RTW_PWR_ADDR_MAC,460	 RTW_PWR_CMD_WRITE, BIT(1), 0},461	{0x0100,462	 RTW_PWR_CUT_ALL_MSK,463	 RTW_PWR_INTF_ALL_MSK,464	 RTW_PWR_ADDR_MAC,465	 RTW_PWR_CMD_WRITE, 0xff, 0x03},466	{0x0101,467	 RTW_PWR_CUT_ALL_MSK,468	 RTW_PWR_INTF_ALL_MSK,469	 RTW_PWR_ADDR_MAC,470	 RTW_PWR_CMD_WRITE, BIT(1), 0},471	{0x0093,472	 RTW_PWR_CUT_ALL_MSK,473	 RTW_PWR_INTF_SDIO_MSK,474	 RTW_PWR_ADDR_MAC,475	 RTW_PWR_CMD_WRITE, 0xff, 0},476	{0x0553,477	 RTW_PWR_CUT_ALL_MSK,478	 RTW_PWR_INTF_ALL_MSK,479	 RTW_PWR_ADDR_MAC,480	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},481	{TRANS_SEQ_END},482};483 484static const struct rtw_pwr_seq_cmd *card_enable_flow_8703b[] = {485	trans_pre_enable_8703b,486	trans_carddis_to_cardemu_8703b,487	trans_cardemu_to_act_8703b,488	NULL489};490 491static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = {492	trans_act_to_lps_8703b,493	trans_act_to_reset_mcu_8703b,494	trans_act_to_cardemu_8703b,495	trans_cardemu_to_carddis_8703b,496	NULL497};498 499static const struct rtw_rfe_def rtw8703b_rfe_defs[] = {500	[0] = { .phy_pg_tbl	= &rtw8703b_bb_pg_tbl,501		.txpwr_lmt_tbl	= &rtw8703b_txpwr_lmt_tbl,},502};503 504static const struct rtw_page_table page_table_8703b[] = {505	{12, 2, 2, 0, 1},506	{12, 2, 2, 0, 1},507	{12, 2, 2, 0, 1},508	{12, 2, 2, 0, 1},509	{12, 2, 2, 0, 1},510};511 512static const struct rtw_rqpn rqpn_table_8703b[] = {513	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,514	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,515	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},516	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,517	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,518	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},519	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,520	 RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH,521	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},522	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,523	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,524	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},525	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,526	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,527	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},528};529 530/* Default power index table for RTL8703B, used if EFUSE does not531 * contain valid data. Replaces EFUSE data from offset 0x10 (start of532 * txpwr_idx_table).533 */534static const u8 rtw8703b_txpwr_idx_table[] = {535	0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,536	0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02537};538 539static void try_mac_from_devicetree(struct rtw_dev *rtwdev)540{541	struct device_node *node = rtwdev->dev->of_node;542	struct rtw_efuse *efuse = &rtwdev->efuse;543	int ret;544 545	if (node) {546		ret = of_get_mac_address(node, efuse->addr);547		if (ret == 0) {548			rtw_dbg(rtwdev, RTW_DBG_EFUSE,549				"got wifi mac address from DT: %pM\n",550				efuse->addr);551		}552	}553}554 555#define DBG_EFUSE_FIX(rtwdev, name)					\556	rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Fixed invalid EFUSE value: "	\557		# name "=0x%x\n", rtwdev->efuse.name)558 559static int rtw8703b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)560{561	struct rtw_efuse *efuse = &rtwdev->efuse;562	u8 *pwr = (u8 *)efuse->txpwr_idx_table;563	bool valid = false;564	int ret;565 566	ret = rtw8723x_read_efuse(rtwdev, log_map);567	if (ret != 0)568		return ret;569 570	if (!is_valid_ether_addr(efuse->addr))571		try_mac_from_devicetree(rtwdev);572 573	/* If TX power index table in EFUSE is invalid, fall back to574	 * built-in table.575	 */576	for (int i = 0; i < ARRAY_SIZE(rtw8703b_txpwr_idx_table); i++)577		if (pwr[i] != 0xff) {578			valid = true;579			break;580		}581	if (!valid) {582		for (int i = 0; i < ARRAY_SIZE(rtw8703b_txpwr_idx_table); i++)583			pwr[i] = rtw8703b_txpwr_idx_table[i];584		rtw_dbg(rtwdev, RTW_DBG_EFUSE,585			"Replaced invalid EFUSE TX power index table.");586		rtw8723x_debug_txpwr_limit(rtwdev,587					   efuse->txpwr_idx_table, 2);588	}589 590	/* Override invalid antenna settings. */591	if (efuse->bt_setting == 0xff) {592		/* shared antenna */593		efuse->bt_setting |= BIT(0);594		/* RF path A */595		efuse->bt_setting &= ~BIT(6);596		DBG_EFUSE_FIX(rtwdev, bt_setting);597	}598 599	/* Override invalid board options: The coex code incorrectly600	 * assumes that if bits 6 & 7 are set the board doesn't601	 * support coex. Regd is also derived from rf_board_option and602	 * should be 0 if there's no valid data.603	 */604	if (efuse->rf_board_option == 0xff) {605		efuse->regd = 0;606		efuse->rf_board_option &= GENMASK(5, 0);607		DBG_EFUSE_FIX(rtwdev, rf_board_option);608	}609 610	/* Override invalid crystal cap setting, default comes from611	 * vendor driver. Chip specific.612	 */613	if (efuse->crystal_cap == 0xff) {614		efuse->crystal_cap = 0x20;615		DBG_EFUSE_FIX(rtwdev, crystal_cap);616	}617 618	return 0;619}620 621static void rtw8703b_pwrtrack_init(struct rtw_dev *rtwdev)622{623	struct rtw_dm_info *dm_info = &rtwdev->dm_info;624	u8 path;625 626	/* TODO: The vendor driver selects these using tables in627	 * halrf_powertracking_ce.c, functions are called628	 * get_swing_index and get_cck_swing_index. There the current629	 * fixed values are only the defaults in case no match is630	 * found.631	 */632	dm_info->default_ofdm_index = 30;633	dm_info->default_cck_index = 20;634 635	for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {636		ewma_thermal_init(&dm_info->avg_thermal[path]);637		dm_info->delta_power_index[path] = 0;638	}639	dm_info->pwr_trk_triggered = false;640	dm_info->pwr_trk_init_trigger = true;641	dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;642	dm_info->txagc_remnant_cck = 0;643	dm_info->txagc_remnant_ofdm = 0;644}645 646static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev)647{648	u8 xtal_cap = rtwdev->efuse.crystal_cap & 0x3F;649 650	/* power on BB/RF domain */651	rtw_write16_set(rtwdev, REG_SYS_FUNC_EN,652			BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB);653	rtw_write8_set(rtwdev, REG_RF_CTRL,654		       BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);655	rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, 0x0780);656	rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, 0x80);657 658	rtw_phy_load_tables(rtwdev);659 660	rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF);661	/* 0xff is from vendor driver, rtw8723d uses662	 * BIT_HIQ_NO_LMT_EN_ROOT.  Comment in vendor driver: "Packet663	 * in Hi Queue Tx immediately". I wonder if setting all bits664	 * is really necessary.665	 */666	rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, 0xff);667	rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN);668 669	rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL,670			 xtal_cap | (xtal_cap << 6));671	rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN);672 673	/* Init EDCA */674	rtw_write16(rtwdev, REG_SPEC_SIFS, WLAN_SPEC_SIFS);675	rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS);676	rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS); /* CCK */677	rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS); /* OFDM */678	/* TXOP */679	rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226);680	rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324);681	rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B);682	rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F);683 684	/* Init retry */685	rtw_write8(rtwdev, REG_ACKTO, 0x40);686 687	/* Set up RX aggregation. sdio.c also sets DMA mode, but not688	 * the burst parameters.689	 */690	rtw_write8(rtwdev, REG_RXDMA_MODE,691		   BIT_DMA_MODE |692		   FIELD_PREP_CONST(BIT_MASK_AGG_BURST_NUM, AGG_BURST_NUM) |693		   FIELD_PREP_CONST(BIT_MASK_AGG_BURST_SIZE, AGG_BURST_SIZE));694 695	/* Init beacon parameters */696	rtw_write8(rtwdev, REG_BCN_CTRL,697		   BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT);698	rtw_write8(rtwdev, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);699	rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 1,700		   TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);701	rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 2,702		   (rtw_read8(rtwdev, REG_TBTT_PROHIBIT + 2) & 0xF0)703		   | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));704 705	/* configure packet burst */706	rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU);707	rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT);708	rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR);709	rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL);710	rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT_MASK_TXQ_INIT);711	rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME);712 713	rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME);714	rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL);715	rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL);716	rtw_write16(rtwdev, REG_ATIMWND, 0x2);717 718	rtw_phy_init(rtwdev);719 720	if (rtw_read32_mask(rtwdev, REG_BB_AMP, BIT_MASK_RX_LNA) != 0) {721		rtwdev->dm_info.rx_cck_agc_report_type = 1;722	} else {723		rtwdev->dm_info.rx_cck_agc_report_type = 0;724		rtw_warn(rtwdev, "unexpected cck agc report type");725	}726 727	rtw8723x_lck(rtwdev);728 729	rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50);730	rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20);731 732	rtw8703b_pwrtrack_init(rtwdev);733}734 735static bool rtw8703b_check_spur_ov_thres(struct rtw_dev *rtwdev,736					 u32 freq, u32 thres)737{738	bool ret = false;739 740	rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE);741	rtw_write32(rtwdev, REG_PSDFN, freq);742	rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq);743 744	msleep(30);745	if (rtw_read32(rtwdev, REG_PSDRPT) >= thres)746		ret = true;747 748	rtw_write32(rtwdev, REG_PSDFN, freq);749	rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE);750 751	return ret;752}753 754static void rtw8703b_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch)755{756	if (!notch) {757		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f);758		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0);759		rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);760		rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);761		rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);762		rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);763		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0);764		return;765	}766 767	switch (channel) {768	case 5:769		fallthrough;770	case 13:771		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xb);772		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);773		rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x06000000);774		rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);775		rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);776		rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);777		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);778		break;779	case 6:780		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x4);781		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);782		rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000600);783		rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);784		rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);785		rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);786		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);787		break;788	case 7:789		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x3);790		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);791		rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);792		rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);793		rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);794		rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x06000000);795		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);796		break;797	case 8:798		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xa);799		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);800		rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);801		rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);802		rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);803		rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000380);804		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);805		break;806	case 14:807		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5);808		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);809		rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);810		rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);811		rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);812		rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00180000);813		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);814		break;815	default:816		rtw_warn(rtwdev,817			 "Bug: Notch filter enable called for channel %u!",818			 channel);819		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0);820		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0);821		break;822	}823}824 825static void rtw8703b_spur_cal(struct rtw_dev *rtwdev, u8 channel)826{827	bool notch;828	u32 freq;829 830	if (channel == 5) {831		freq = FREQ_CH5;832	} else if (channel == 6) {833		freq = FREQ_CH6;834	} else if (channel == 7) {835		freq = FREQ_CH7;836	} else if (channel == 8) {837		freq = FREQ_CH8;838	} else if (channel == 13) {839		freq = FREQ_CH13;840	} else if (channel == 14) {841		freq = FREQ_CH14;842	} else {843		rtw8703b_cfg_notch(rtwdev, channel, false);844		return;845	}846 847	notch = rtw8703b_check_spur_ov_thres(rtwdev, freq, SPUR_THRES);848	rtw8703b_cfg_notch(rtwdev, channel, notch);849}850 851static void rtw8703b_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)852{853	u32 rf_cfgch_a;854	u32 rf_cfgch_b;855	/* default value for 20M */856	u32 rf_rck = 0x00000C08;857 858	rf_cfgch_a = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);859	rf_cfgch_b = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK);860 861	rf_cfgch_a &= ~RFCFGCH_CHANNEL_MASK;862	rf_cfgch_b &= ~RFCFGCH_CHANNEL_MASK;863	rf_cfgch_a |= (channel & RFCFGCH_CHANNEL_MASK);864	rf_cfgch_b |= (channel & RFCFGCH_CHANNEL_MASK);865 866	rf_cfgch_a &= ~RFCFGCH_BW_MASK;867	switch (bw) {868	case RTW_CHANNEL_WIDTH_20:869		rf_cfgch_a |= RFCFGCH_BW_20M;870		break;871	case RTW_CHANNEL_WIDTH_40:872		rf_cfgch_a |= RFCFGCH_BW_40M;873		rf_rck = 0x00000C4C;874		break;875	default:876		break;877	}878 879	rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch_a);880	rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch_b);881 882	rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK1, RFREG_MASK, rf_rck);883	rtw8703b_spur_cal(rtwdev, channel);884}885 886#define CCK_DFIR_NR_8703B 2887static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR_8703B] = {888	[0] = {889		{ .len = 4, .reg = REG_CCK_TXSF2, .val = 0x5A7DA0BD },890		{ .len = 4, .reg = REG_CCK_DBG, .val = 0x0000223B },891	},892	[1] = {893		{ .len = 4, .reg = REG_CCK_TXSF2, .val = 0x00000000 },894		{ .len = 4, .reg = REG_CCK_DBG, .val = 0x00000000 },895	},896};897 898static void rtw8703b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,899				    u8 primary_ch_idx)900{901	const struct rtw_backup_info *cck_dfir;902	int i;903 904	cck_dfir = channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1];905 906	for (i = 0; i < CCK_DFIR_NR_8703B; i++, cck_dfir++)907		rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val);908 909	switch (bw) {910	case RTW_CHANNEL_WIDTH_20:911		rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0);912		rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0);913		rtw_write32_mask(rtwdev, REG_OFDM0_TX_PSD_NOISE,914				 GENMASK(31, 20), 0x0);915		rtw_write32(rtwdev, REG_BBRX_DFIR, 0x4A880000);916		rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x19F60000);917		break;918	case RTW_CHANNEL_WIDTH_40:919		rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1);920		rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1);921		rtw_write32(rtwdev, REG_BBRX_DFIR, 0x40100000);922		rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x51F60000);923		rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND,924				 primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0);925		rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, 0xC00,926				 primary_ch_idx == RTW_SC_20_UPPER ? 2 : 1);927 928		rtw_write32_mask(rtwdev, REG_BB_PWR_SAV5_11N, GENMASK(27, 26),929				 primary_ch_idx == RTW_SC_20_UPPER ? 1 : 2);930		break;931	default:932		break;933	}934}935 936static void rtw8703b_set_channel(struct rtw_dev *rtwdev, u8 channel,937				 u8 bw, u8 primary_chan_idx)938{939	rtw8703b_set_channel_rf(rtwdev, channel, bw);940	rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);941	rtw8703b_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);942}943 944/* Not all indices are valid, based on available data. None of the945 * known valid values are positive, so use 0x7f as "invalid".946 */947#define LNA_IDX_INVALID 0x7f948static const s8 lna_gain_table[16] = {949	-2, LNA_IDX_INVALID, LNA_IDX_INVALID, LNA_IDX_INVALID,950	-6, LNA_IDX_INVALID, LNA_IDX_INVALID, -19,951	-32, LNA_IDX_INVALID, -36, -42,952	LNA_IDX_INVALID, LNA_IDX_INVALID, LNA_IDX_INVALID, -48,953};954 955static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx)956{957	s8 lna_gain = 0;958 959	if (lna_idx < ARRAY_SIZE(lna_gain_table))960		lna_gain = lna_gain_table[lna_idx];961 962	if (lna_gain >= 0) {963		rtw_warn(rtwdev, "incorrect lna index (%d)\n", lna_idx);964		return -120;965	}966 967	return lna_gain - 2 * vga_idx;968}969 970static void query_phy_status_cck(struct rtw_dev *rtwdev, u8 *phy_raw,971				 struct rtw_rx_pkt_stat *pkt_stat)972{973	struct phy_status_8703b *phy_status = (struct phy_status_8703b *)phy_raw;974	u8 vga_idx = phy_status->cck_agc_rpt_ofdm_cfosho_a & VGA_BITS;975	u8 lna_idx = phy_status->cck_agc_rpt_ofdm_cfosho_a & LNA_L_BITS;976	s8 rx_power;977 978	if (rtwdev->dm_info.rx_cck_agc_report_type == 1)979		lna_idx = FIELD_PREP(BIT_LNA_H_MASK,980				     phy_status->cck_rpt_b_ofdm_cfosho_b & LNA_H_BIT)981			| FIELD_PREP(BIT_LNA_L_MASK, lna_idx);982	else983		lna_idx = FIELD_PREP(BIT_LNA_L_MASK, lna_idx);984	rx_power = get_cck_rx_pwr(rtwdev, lna_idx, vga_idx);985 986	pkt_stat->rx_power[RF_PATH_A] = rx_power;987	pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);988	rtwdev->dm_info.rssi[RF_PATH_A] = pkt_stat->rssi;989	pkt_stat->signal_power = rx_power;990}991 992static void query_phy_status_ofdm(struct rtw_dev *rtwdev, u8 *phy_raw,993				  struct rtw_rx_pkt_stat *pkt_stat)994{995	struct phy_status_8703b *phy_status = (struct phy_status_8703b *)phy_raw;996	struct rtw_dm_info *dm_info = &rtwdev->dm_info;997	s8 val_s8;998 999	val_s8 = phy_status->path_agc[RF_PATH_A].gain & 0x3F;1000	pkt_stat->rx_power[RF_PATH_A] = (val_s8 * 2) - 110;1001	pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);1002	pkt_stat->rx_snr[RF_PATH_A] = (s8)(phy_status->path_rxsnr[RF_PATH_A] / 2);1003 1004	/* signal power reported by HW */1005	val_s8 = phy_status->cck_sig_qual_ofdm_pwdb_all >> 1;1006	pkt_stat->signal_power = (val_s8 & 0x7f) - 110;1007 1008	pkt_stat->rx_evm[RF_PATH_A] = phy_status->stream_rxevm[RF_PATH_A];1009	pkt_stat->cfo_tail[RF_PATH_A] = phy_status->path_cfotail[RF_PATH_A];1010 1011	dm_info->curr_rx_rate = pkt_stat->rate;1012	dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;1013	dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1;1014	/* convert to KHz (used only for debugfs) */1015	dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1;1016 1017	/* (EVM value as s8 / 2) is dbm, should usually be in -33 to 01018	 * range. rx_evm_dbm needs the absolute (positive) value.1019	 */1020	val_s8 = (s8)pkt_stat->rx_evm[RF_PATH_A];1021	val_s8 = clamp_t(s8, -val_s8 >> 1, 0, 64);1022	val_s8 &= 0x3F; /* 64->0: second path of 1SS rate is 64 */1023	dm_info->rx_evm_dbm[RF_PATH_A] = val_s8;1024}1025 1026static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,1027			     struct rtw_rx_pkt_stat *pkt_stat)1028{1029	if (pkt_stat->rate <= DESC_RATE11M)1030		query_phy_status_cck(rtwdev, phy_status, pkt_stat);1031	else1032		query_phy_status_ofdm(rtwdev, phy_status, pkt_stat);1033}1034 1035static void rtw8703b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,1036				   struct rtw_rx_pkt_stat *pkt_stat,1037				   struct ieee80211_rx_status *rx_status)1038{1039	struct ieee80211_hdr *hdr;1040	u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;1041	u8 *phy_status = NULL;1042 1043	memset(pkt_stat, 0, sizeof(*pkt_stat));1044 1045	pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);1046	pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);1047	pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);1048	pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&1049			      GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;1050	pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);1051	pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);1052	pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);1053	pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);1054	pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);1055	pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);1056	pkt_stat->ppdu_cnt = 0;1057	pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);1058 1059	pkt_stat->drv_info_sz *= RX_DRV_INFO_SZ_UNIT_8703B;1060 1061	if (pkt_stat->is_c2h)1062		return;1063 1064	hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +1065				       pkt_stat->drv_info_sz);1066 1067	pkt_stat->bw = GET_RX_DESC_BW(rx_desc);1068 1069	if (pkt_stat->phy_status) {1070		phy_status = rx_desc + desc_sz + pkt_stat->shift;1071		query_phy_status(rtwdev, phy_status, pkt_stat);1072	}1073 1074	rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);1075 1076	/* Rtl8723cs driver checks for size < 14 or size > 8192 and1077	 * simply drops the packet. Maybe this should go into1078	 * rtw_rx_fill_rx_status()?1079	 */1080	if (pkt_stat->pkt_len == 0) {1081		rx_status->flag |= RX_FLAG_NO_PSDU;1082		rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");1083	}1084}1085 1086#define ADDA_ON_VAL_8703B 0x03c000141087 1088static1089void rtw8703b_iqk_config_mac(struct rtw_dev *rtwdev,1090			     const struct rtw8723x_iqk_backup_regs *backup)1091{1092	rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[0], 0x3F);1093	for (int i = 1; i < RTW8723X_IQK_MAC8_REG_NUM; i++)1094		rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i],1095			   backup->mac8[i] & (~BIT(3)));1096}1097 1098#define IQK_LTE_WRITE_VAL_8703B 0x000077001099#define IQK_DELAY_TIME_8703B 41100 1101static void rtw8703b_iqk_one_shot(struct rtw_dev *rtwdev, bool tx)1102{1103	u32 regval;1104	ktime_t t;1105	s64 dur;1106	int ret;1107 1108	/* enter IQK mode */1109	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK);1110	rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8703B);1111 1112	/* One shot, LOK & IQK */1113	rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf9000000);1114	rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf8000000);1115 1116	t = ktime_get();1117	msleep(IQK_DELAY_TIME_8703B);1118	ret = read_poll_timeout(rtw_read32, regval, regval != 0, 1000,1119				100000, false, rtwdev,1120				REG_IQK_RDY);1121	dur = ktime_us_delta(ktime_get(), t);1122 1123	if (ret)1124		rtw_warn(rtwdev, "[IQK] %s timed out after %lldus!\n",1125			 tx ? "TX" : "RX", dur);1126	else1127		rtw_dbg(rtwdev, RTW_DBG_RFK,1128			"[IQK] %s done after %lldus\n",1129			tx ? "TX" : "RX", dur);1130}1131 1132static void rtw8703b_iqk_txrx_path_post(struct rtw_dev *rtwdev,1133					const struct rtw8723x_iqk_backup_regs *backup)1134{1135	rtw8723x_iqk_restore_lte_path_gnt(rtwdev, backup);1136	rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg);1137 1138	/* leave IQK mode */1139	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);1140	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x0);1141}1142 1143static u8 rtw8703b_iqk_check_tx_failed(struct rtw_dev *rtwdev)1144{1145	s32 tx_x, tx_y;1146	u32 tx_fail;1147 1148	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xeac = 0x%x\n",1149		rtw_read32(rtwdev, REG_IQK_RES_RY));1150	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe94 = 0x%x, 0xe9c = 0x%x\n",1151		rtw_read32(rtwdev, REG_IQK_RES_TX),1152		rtw_read32(rtwdev, REG_IQK_RES_TY));1153	rtw_dbg(rtwdev, RTW_DBG_RFK,1154		"[IQK] 0xe90(before IQK) = 0x%x, 0xe98(after IQK) = 0x%x\n",1155		rtw_read32(rtwdev, REG_IQK_RDY),1156		rtw_read32(rtwdev, 0xe98));1157 1158	tx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_TX_FAIL);1159	tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX);1160	tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY);1161 1162	if (!tx_fail && tx_x != IQK_TX_X_ERR && tx_y != IQK_TX_Y_ERR)1163		return IQK_TX_OK;1164 1165	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] A TX IQK failed\n");1166 1167	return 0;1168}1169 1170static u8 rtw8703b_iqk_check_rx_failed(struct rtw_dev *rtwdev)1171{1172	s32 rx_x, rx_y;1173	u32 rx_fail;1174 1175	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xea4 = 0x%x, 0xeac = 0x%x\n",1176		rtw_read32(rtwdev, REG_IQK_RES_RX),1177		rtw_read32(rtwdev, REG_IQK_RES_RY));1178 1179	rtw_dbg(rtwdev, RTW_DBG_RFK,1180		"[IQK] 0xea0(before IQK) = 0x%x, 0xea8(after IQK) = 0x%x\n",1181		rtw_read32(rtwdev, 0xea0),1182		rtw_read32(rtwdev, 0xea8));1183 1184	rx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_RX_FAIL);1185	rx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX);1186	rx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY);1187	rx_y = abs(iqkxy_to_s32(rx_y));1188 1189	if (!rx_fail && rx_x != IQK_RX_X_ERR && rx_y != IQK_RX_Y_ERR &&1190	    rx_x < IQK_RX_X_UPPER && rx_x > IQK_RX_X_LOWER &&1191	    rx_y < IQK_RX_Y_LMT)1192		return IQK_RX_OK;1193 1194	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] A RX IQK failed\n");1195 1196	return 0;1197}1198 1199static u8 rtw8703b_iqk_tx_path(struct rtw_dev *rtwdev,1200			       const struct rtw8723x_iqk_backup_regs *backup)1201{1202	u8 status;1203 1204	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK!\n");1205 1206	/* IQK setting */1207	rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00);1208	rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800);1209	rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c);1210	rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c);1211	rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);1212	rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);1213	rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8214030f);1214	rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000);1215	rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000);1216	rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000);1217 1218	/* LO calibration setting */1219	rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x00462911);1220 1221	/* leave IQK mode */1222	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000);1223 1224	/* PA, PAD setting */1225	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x1);1226	rtw_write_rf(rtwdev, RF_PATH_A, 0x55, 0x7f, 0x7);1227	rtw_write_rf(rtwdev, RF_PATH_A, 0x7f, RFREG_MASK, 0xd400);1228 1229	rtw8703b_iqk_one_shot(rtwdev, true);1230	status = rtw8703b_iqk_check_tx_failed(rtwdev);1231 1232	rtw8703b_iqk_txrx_path_post(rtwdev, backup);1233 1234	return status;1235}1236 1237static u8 rtw8703b_iqk_rx_path(struct rtw_dev *rtwdev,1238			       const struct rtw8723x_iqk_backup_regs *backup)1239{1240	u8 status;1241	u32 tx_x, tx_y;1242 1243	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step 1!\n");1244	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @A RX IQK1 = 0x%x\n",1245		rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));1246	rtw_write32(rtwdev, REG_BB_SEL_BTG, 0x99000000);1247 1248	/* disable IQC mode */1249	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);1250 1251	/* IQK setting */1252	rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00);1253	rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800);1254 1255	/* path IQK setting */1256	rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c);1257	rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c);1258	rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);1259	rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);1260	rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8216000f);1261	rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000);1262	rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x28110000);1263	rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000);1264 1265	/* LOK setting */1266	rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a911);1267 1268	/* RX IQK mode */1269	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1);1270	rtw_write_rf(rtwdev, RF_PATH_A, 0x30, RFREG_MASK, 0x30000);1271	rtw_write_rf(rtwdev, RF_PATH_A, 0x31, RFREG_MASK, 0x00007);1272	rtw_write_rf(rtwdev, RF_PATH_A, 0x32, RFREG_MASK, 0x57db7);1273 1274	rtw8703b_iqk_one_shot(rtwdev, true);1275	/* leave IQK mode */1276	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000);1277	status = rtw8703b_iqk_check_tx_failed(rtwdev);1278 1279	if (!status)1280		goto restore;1281 1282	/* second round */1283	tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX);1284	tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY);1285 1286	rtw_write32(rtwdev, REG_TXIQK_11N, BIT_SET_TXIQK_11N(tx_x, tx_y));1287	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe40 = 0x%x u4tmp = 0x%x\n",1288		rtw_read32(rtwdev, REG_TXIQK_11N),1289		BIT_SET_TXIQK_11N(tx_x, tx_y));1290 1291	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step 2!\n");1292	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @A RX IQK 2 = 0x%x\n",1293		rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));1294 1295	/* IQK setting */1296	rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800);1297	rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x38008c1c);1298	rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x18008c1c);1299	rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);1300	rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);1301	rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82110000);1302	rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160c1f);1303	rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000);1304	rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000);1305 1306	/* LO calibration setting */1307	rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a8d1);1308 1309	/* leave IQK mode */1310	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000);1311	/* modify RX IQK mode table */1312	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1);1313	/* RF_RCK_OS, RF_TXPA_G1, RF_TXPA_G2 */1314	rtw_write_rf(rtwdev, RF_PATH_A, 0x30, RFREG_MASK, 0x30000);1315	rtw_write_rf(rtwdev, RF_PATH_A, 0x31, RFREG_MASK, 0x00007);1316	rtw_write_rf(rtwdev, RF_PATH_A, 0x32, RFREG_MASK, 0xf7d77);1317 1318	/* PA, PAD setting */1319	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x1);1320	rtw_write_rf(rtwdev, RF_PATH_A, 0x55, 0x7f, 0x5);1321 1322	rtw8703b_iqk_one_shot(rtwdev, false);1323	status |= rtw8703b_iqk_check_rx_failed(rtwdev);1324 1325restore:1326	rtw8703b_iqk_txrx_path_post(rtwdev, backup);1327 1328	return status;1329}1330 1331static1332void rtw8703b_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t,1333			    const struct rtw8723x_iqk_backup_regs *backup)1334{1335	u32 i;1336	u8 a_ok;1337 1338	rtw_dbg(rtwdev, RTW_DBG_RFK,1339		"[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t);1340 1341	rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8703B);1342	rtw8703b_iqk_config_mac(rtwdev, backup);1343	rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf);1344	rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05600);1345	rtw_write32(rtwdev, REG_TRMUX_11N, 0x000800e4);1346	rtw_write32(rtwdev, REG_BB_PWR_SAV1_11N, 0x25204000);1347 1348	for (i = 0; i < PATH_IQK_RETRY; i++) {1349		a_ok = rtw8703b_iqk_tx_path(rtwdev, backup);1350		if (a_ok == IQK_TX_OK) {1351			rtw_dbg(rtwdev, RTW_DBG_RFK,1352				"[IQK] path A TX IQK success!\n");1353			result[t][IQK_S1_TX_X] =1354				rtw_read32_mask(rtwdev, REG_IQK_RES_TX,1355						BIT_MASK_RES_TX);1356			result[t][IQK_S1_TX_Y] =1357				rtw_read32_mask(rtwdev, REG_IQK_RES_TY,1358						BIT_MASK_RES_TY);1359			break;1360		}1361 1362		rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK fail!\n");1363		result[t][IQK_S1_TX_X] = 0x100;1364		result[t][IQK_S1_TX_Y] = 0x0;1365	}1366 1367	for (i = 0; i < PATH_IQK_RETRY; i++) {1368		a_ok = rtw8703b_iqk_rx_path(rtwdev, backup);1369		if (a_ok == (IQK_TX_OK | IQK_RX_OK)) {1370			rtw_dbg(rtwdev, RTW_DBG_RFK,1371				"[IQK] path A RX IQK success!\n");1372			result[t][IQK_S1_RX_X] =1373				rtw_read32_mask(rtwdev, REG_IQK_RES_RX,1374						BIT_MASK_RES_RX);1375			result[t][IQK_S1_RX_Y] =1376				rtw_read32_mask(rtwdev, REG_IQK_RES_RY,1377						BIT_MASK_RES_RY);1378			break;1379		}1380 1381		rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK fail!\n");1382		result[t][IQK_S1_RX_X] = 0x100;1383		result[t][IQK_S1_RX_Y] = 0x0;1384	}1385 1386	if (a_ok == 0x0)1387		rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A IQK fail!\n");1388 1389	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);1390	mdelay(1);1391}1392 1393static1394void rtw8703b_iqk_fill_a_matrix(struct rtw_dev *rtwdev, const s32 result[])1395{1396	u32 tmp_rx_iqi = 0x40000100 & GENMASK(31, 16);1397	s32 tx1_a, tx1_a_ext;1398	s32 tx1_c, tx1_c_ext;1399	s32 oldval_1;1400	s32 x, y;1401 1402	if (result[IQK_S1_TX_X] == 0)1403		return;1404 1405	oldval_1 = rtw_read32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE,1406				   BIT_MASK_TXIQ_ELM_D);1407 1408	x = iqkxy_to_s32(result[IQK_S1_TX_X]);1409	tx1_a = iqk_mult(x, oldval_1, &tx1_a_ext);1410	rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE,1411			 BIT_MASK_TXIQ_ELM_A, tx1_a);1412	rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD,1413			 BIT_MASK_OFDM0_EXT_A, tx1_a_ext);1414 1415	y = iqkxy_to_s32(result[IQK_S1_TX_Y]);1416	tx1_c = iqk_mult(y, oldval_1, &tx1_c_ext);1417	rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS,1418			 BIT_SET_TXIQ_ELM_C1(tx1_c));1419	rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE,1420			 BIT_MASK_TXIQ_ELM_C, BIT_SET_TXIQ_ELM_C2(tx1_c));1421	rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD,1422			 BIT_MASK_OFDM0_EXT_C, tx1_c_ext);1423 1424	rtw_dbg(rtwdev, RTW_DBG_RFK,1425		"[IQK] X = 0x%x, TX1_A = 0x%x, oldval_1 0x%x\n",1426		x, tx1_a, oldval_1);1427	rtw_dbg(rtwdev, RTW_DBG_RFK,1428		"[IQK] Y = 0x%x, TX1_C = 0x%x\n", y, tx1_c);1429 1430	if (result[IQK_S1_RX_X] == 0)1431		return;1432 1433	tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_X, result[IQK_S1_RX_X]);1434	tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_Y1, result[IQK_S1_RX_X]);1435	rtw_write32(rtwdev, REG_A_RXIQI, tmp_rx_iqi);1436	rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2,1437			 BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y]));1438}1439 1440static void rtw8703b_phy_calibration(struct rtw_dev *rtwdev)1441{1442	/* For some reason path A is called S1 and B S0 in shared1443	 * rtw88 calibration data.1444	 */1445	struct rtw_dm_info *dm_info = &rtwdev->dm_info;1446	struct rtw8723x_iqk_backup_regs backup;1447	u8 final_candidate = IQK_ROUND_INVALID;1448	s32 result[IQK_ROUND_SIZE][IQK_NR];1449	bool good;1450	u8 i, j;1451 1452	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Start!\n");1453 1454	memset(result, 0, sizeof(result));1455 1456	rtw8723x_iqk_backup_path_ctrl(rtwdev, &backup);1457	rtw8723x_iqk_backup_lte_path_gnt(rtwdev, &backup);1458	rtw8723x_iqk_backup_regs(rtwdev, &backup);1459 1460	for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) {1461		rtw8723x_iqk_config_path_ctrl(rtwdev);1462		rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8703B);1463 1464		rtw8703b_iqk_one_round(rtwdev, result, i, &backup);1465 1466		rtw_dbg(rtwdev, RTW_DBG_RFK,1467			"[IQK] back to BB mode, load original values!\n");1468		if (i > IQK_ROUND_0)1469			rtw8723x_iqk_restore_regs(rtwdev, &backup);1470		rtw8723x_iqk_restore_lte_path_gnt(rtwdev, &backup);1471		rtw8723x_iqk_restore_path_ctrl(rtwdev, &backup);1472 1473		for (j = IQK_ROUND_0; j < i; j++) {1474			good = rtw8723x_iqk_similarity_cmp(rtwdev, result, j, i);1475 1476			if (good) {1477				final_candidate = j;1478				rtw_dbg(rtwdev, RTW_DBG_RFK,1479					"[IQK] cmp %d:%d final_candidate is %x\n",1480					j, i, final_candidate);1481				goto iqk_done;1482			}1483		}1484	}1485 1486	if (final_candidate == IQK_ROUND_INVALID) {1487		s32 reg_tmp = 0;1488 1489		for (i = 0; i < IQK_NR; i++)1490			reg_tmp += result[IQK_ROUND_HYBRID][i];1491 1492		if (reg_tmp != 0) {1493			final_candidate = IQK_ROUND_HYBRID;1494		} else {1495			WARN(1, "IQK failed\n");1496			goto out;1497		}1498	}1499 1500iqk_done:1501	/* only path A is calibrated in rtl8703b */1502	rtw8703b_iqk_fill_a_matrix(rtwdev, result[final_candidate]);1503 1504	dm_info->iqk.result.s1_x = result[final_candidate][IQK_S1_TX_X];1505	dm_info->iqk.result.s1_y = result[final_candidate][IQK_S1_TX_Y];1506	dm_info->iqk.result.s0_x = result[final_candidate][IQK_S0_TX_X];1507	dm_info->iqk.result.s0_y = result[final_candidate][IQK_S0_TX_Y];1508	dm_info->iqk.done = true;1509 1510out:1511	rtw_write32(rtwdev, REG_BB_SEL_BTG, backup.bb_sel_btg);1512 1513	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] final_candidate is %x\n",1514		final_candidate);1515 1516	for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++)1517		rtw_dbg(rtwdev, RTW_DBG_RFK,1518			"[IQK] Result %u: rege94_s1=%x rege9c_s1=%x regea4_s1=%x regeac_s1=%x rege94_s0=%x rege9c_s0=%x regea4_s0=%x regeac_s0=%x %s\n",1519			i,1520			result[i][0], result[i][1], result[i][2], result[i][3],1521			result[i][4], result[i][5], result[i][6], result[i][7],1522			final_candidate == i ? "(final candidate)" : "");1523 1524	rtw_dbg(rtwdev, RTW_DBG_RFK,1525		"[IQK] 0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n",1526		rtw_read32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE),1527		rtw_read32(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N),1528		rtw_read32(rtwdev, REG_A_RXIQI),1529		rtw_read32(rtwdev, REG_RXIQK_MATRIX_LSB_11N));1530	rtw_dbg(rtwdev, RTW_DBG_RFK,1531		"[IQK] 0xcd0 = 0x%x 0xcd4 = 0x%x 0xcd8 = 0x%x\n",1532		rtw_read32(rtwdev, REG_TXIQ_AB_S0),1533		rtw_read32(rtwdev, REG_TXIQ_CD_S0),1534		rtw_read32(rtwdev, REG_RXIQ_AB_S0));1535 1536	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Finished.\n");1537}1538 1539static void rtw8703b_set_iqk_matrix_by_result(struct rtw_dev *rtwdev,1540					      u32 ofdm_swing, u8 rf_path)1541{1542	struct rtw_dm_info *dm_info = &rtwdev->dm_info;1543	s32 ele_A, ele_D, ele_C;1544	s32 ele_A_ext, ele_C_ext, ele_D_ext;1545	s32 iqk_result_x;1546	s32 iqk_result_y;1547	s32 value32;1548 1549	switch (rf_path) {1550	default:1551	case RF_PATH_A:1552		iqk_result_x = dm_info->iqk.result.s1_x;1553		iqk_result_y = dm_info->iqk.result.s1_y;1554		break;1555	case RF_PATH_B:1556		iqk_result_x = dm_info->iqk.result.s0_x;1557		iqk_result_y = dm_info->iqk.result.s0_y;1558		break;1559	}1560 1561	/* new element D */1562	ele_D = OFDM_SWING_D(ofdm_swing);1563	iqk_mult(iqk_result_x, ele_D, &ele_D_ext);1564	/* new element A */1565	iqk_result_x = iqkxy_to_s32(iqk_result_x);1566	ele_A = iqk_mult(iqk_result_x, ele_D, &ele_A_ext);1567	/* new element C */1568	iqk_result_y = iqkxy_to_s32(iqk_result_y);1569	ele_C = iqk_mult(iqk_result_y, ele_D, &ele_C_ext);1570 1571	switch (rf_path) {1572	case RF_PATH_A:1573	default:1574		/* write new elements A, C, D, and element B is always 0 */1575		value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D);1576		rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, value32);1577		value32 = BIT_SET_TXIQ_ELM_C1(ele_C);1578		rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS,1579				 value32);1580		value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD);1581		value32 &= ~BIT_MASK_OFDM0_EXTS;1582		value32 |= BIT_SET_OFDM0_EXTS(ele_A_ext, ele_C_ext, ele_D_ext);1583		rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32);1584		break;1585 1586	case RF_PATH_B:1587		/* write new elements A, C, D, and element B is always 0 */1588		value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D);1589		rtw_write32(rtwdev, REG_OFDM_0_XB_TX_IQ_IMBALANCE, value32);1590		value32 = BIT_SET_TXIQ_ELM_C1(ele_C);1591		rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXB_LSB2_11N, MASKH4BITS,1592				 value32);1593		value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD);1594		value32 &= ~BIT_MASK_OFDM0_EXTS_B;1595		value32 |= BIT_SET_OFDM0_EXTS_B(ele_A_ext, ele_C_ext, ele_D_ext);1596		rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32);1597		break;1598	}1599}1600 1601static void rtw8703b_set_iqk_matrix(struct rtw_dev *rtwdev, s8 ofdm_index,1602				    u8 rf_path)1603{1604	struct rtw_dm_info *dm_info = &rtwdev->dm_info;1605	s32 value32;1606	u32 ofdm_swing;1607 1608	ofdm_index = clamp_t(s8, ofdm_index, 0, RTW_OFDM_SWING_TABLE_SIZE - 1);1609 1610	ofdm_swing = rtw8703b_ofdm_swing_table[ofdm_index];1611 1612	if (dm_info->iqk.done) {1613		rtw8703b_set_iqk_matrix_by_result(rtwdev, ofdm_swing, rf_path);1614		return;1615	}1616 1617	switch (rf_path) {1618	case RF_PATH_A:1619	default:1620		rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ofdm_swing);1621		rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS,1622				 0x00);1623 1624		value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD);1625		value32 &= ~BIT_MASK_OFDM0_EXTS;1626		rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32);1627		break;1628 1629	case RF_PATH_B:1630		rtw_write32(rtwdev, REG_OFDM_0_XB_TX_IQ_IMBALANCE, ofdm_swing);1631		rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXB_LSB2_11N, MASKH4BITS,1632				 0x00);1633 1634		value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD);1635		value32 &= ~BIT_MASK_OFDM0_EXTS_B;1636		rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32);1637		break;1638	}1639}1640 1641static void rtw8703b_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx,1642					   s8 txagc_idx)1643{1644	struct rtw_dm_info *dm_info = &rtwdev->dm_info;1645 1646	dm_info->txagc_remnant_ofdm = txagc_idx;1647 1648	/* Only path A is calibrated for rtl8703b */1649	rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A);1650}1651 1652static void rtw8703b_pwrtrack_set_cck_pwr(struct rtw_dev *rtwdev, s8 swing_idx,1653					  s8 txagc_idx)1654{1655	struct rtw_dm_info *dm_info = &rtwdev->dm_info;1656 1657	dm_info->txagc_remnant_cck = txagc_idx;1658 1659	swing_idx = clamp_t(s8, swing_idx, 0, RTW_CCK_SWING_TABLE_SIZE - 1);1660 1661	BUILD_BUG_ON(ARRAY_SIZE(rtw8703b_cck_pwr_regs)1662		     != ARRAY_SIZE(rtw8703b_cck_swing_table[0]));1663 1664	for (int i = 0; i < ARRAY_SIZE(rtw8703b_cck_pwr_regs); i++)1665		rtw_write8(rtwdev, rtw8703b_cck_pwr_regs[i],1666			   rtw8703b_cck_swing_table[swing_idx][i]);1667}1668 1669static void rtw8703b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path)1670{1671	struct rtw_dm_info *dm_info = &rtwdev->dm_info;1672	struct rtw_hal *hal = &rtwdev->hal;1673	u8 limit_ofdm;1674	u8 limit_cck = 21;1675	s8 final_ofdm_swing_index;1676	s8 final_cck_swing_index;1677 1678	limit_ofdm = rtw8723x_pwrtrack_get_limit_ofdm(rtwdev);1679 1680	final_ofdm_swing_index = dm_info->default_ofdm_index +1681				 dm_info->delta_power_index[path];1682	final_cck_swing_index = dm_info->default_cck_index +1683				dm_info->delta_power_index[path];1684 1685	if (final_ofdm_swing_index > limit_ofdm)1686		rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, limit_ofdm,1687					       final_ofdm_swing_index - limit_ofdm);1688	else if (final_ofdm_swing_index < 0)1689		rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, 0,1690					       final_ofdm_swing_index);1691	else1692		rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, final_ofdm_swing_index, 0);1693 1694	if (final_cck_swing_index > limit_cck)1695		rtw8703b_pwrtrack_set_cck_pwr(rtwdev, limit_cck,1696					      final_cck_swing_index - limit_cck);1697	else if (final_cck_swing_index < 0)1698		rtw8703b_pwrtrack_set_cck_pwr(rtwdev, 0,1699					      final_cck_swing_index);1700	else1701		rtw8703b_pwrtrack_set_cck_pwr(rtwdev, final_cck_swing_index, 0);1702 1703	rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);1704}1705 1706static void rtw8703b_phy_pwrtrack(struct rtw_dev *rtwdev)1707{1708	struct rtw_dm_info *dm_info = &rtwdev->dm_info;1709	struct rtw_swing_table swing_table;1710	u8 thermal_value, delta, path;1711	bool do_iqk = false;1712 1713	rtw_phy_config_swing_table(rtwdev, &swing_table);1714 1715	if (rtwdev->efuse.thermal_meter[0] == 0xff)1716		return;1717 1718	thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00);1719 1720	rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);1721 1722	do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev);1723 1724	if (do_iqk)1725		rtw8723x_lck(rtwdev);1726 1727	if (dm_info->pwr_trk_init_trigger)1728		dm_info->pwr_trk_init_trigger = false;1729	else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value,1730						   RF_PATH_A))1731		goto iqk;1732 1733	delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A);1734 1735	delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1);1736 1737	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {1738		s8 delta_cur, delta_last;1739 1740		delta_last = dm_info->delta_power_index[path];1741		delta_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table,1742							path, RF_PATH_A, delta);1743		if (delta_last == delta_cur)1744			continue;1745 1746		dm_info->delta_power_index[path] = delta_cur;1747		rtw8703b_pwrtrack_set(rtwdev, path);1748	}1749 1750	rtw8723x_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta);1751 1752iqk:1753	if (do_iqk)1754		rtw8703b_phy_calibration(rtwdev);1755}1756 1757static void rtw8703b_pwr_track(struct rtw_dev *rtwdev)1758{1759	struct rtw_efuse *efuse = &rtwdev->efuse;1760	struct rtw_dm_info *dm_info = &rtwdev->dm_info;1761 1762	if (efuse->power_track_type != 0) {1763		rtw_warn(rtwdev, "unsupported power track type");1764		return;1765	}1766 1767	if (!dm_info->pwr_trk_triggered) {1768		rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,1769			     GENMASK(17, 16), 0x03);1770		dm_info->pwr_trk_triggered = true;1771		return;1772	}1773 1774	rtw8703b_phy_pwrtrack(rtwdev);1775	dm_info->pwr_trk_triggered = false;1776}1777 1778static void rtw8703b_coex_set_gnt_fix(struct rtw_dev *rtwdev)1779{1780}1781 1782static void rtw8703b_coex_set_gnt_debug(struct rtw_dev *rtwdev)1783{1784}1785 1786static void rtw8703b_coex_set_rfe_type(struct rtw_dev *rtwdev)1787{1788	struct rtw_coex *coex = &rtwdev->coex;1789	struct rtw_coex_rfe *coex_rfe = &coex->rfe;1790 1791	coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option;1792	coex_rfe->ant_switch_polarity = 0;1793	coex_rfe->ant_switch_exist = false;1794	coex_rfe->ant_switch_with_bt = false;1795	coex_rfe->ant_switch_diversity = false;1796	coex_rfe->wlg_at_btg = true;1797 1798	/* disable LTE coex on wifi side */1799	rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0);1800	rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff);1801	rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff);1802}1803 1804static void rtw8703b_coex_set_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)1805{1806}1807 1808static void rtw8703b_coex_set_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)1809{1810}1811 1812static const u8 rtw8703b_pwrtrk_2gb_n[] = {1813	0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,1814	7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 111815};1816 1817static const u8 rtw8703b_pwrtrk_2gb_p[] = {1818	0, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7,1819	8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 151820};1821 1822static const u8 rtw8703b_pwrtrk_2ga_n[] = {1823	0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,1824	7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 111825};1826 1827static const u8 rtw8703b_pwrtrk_2ga_p[] = {1828	0, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7,1829	8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 151830};1831 1832static const u8 rtw8703b_pwrtrk_2g_cck_b_n[] = {1833	0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,1834	7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 111835};1836 1837static const u8 rtw8703b_pwrtrk_2g_cck_b_p[] = {1838	0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6,1839	7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 131840};1841 1842static const u8 rtw8703b_pwrtrk_2g_cck_a_n[] = {1843	0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,1844	7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 111845};1846 1847static const u8 rtw8703b_pwrtrk_2g_cck_a_p[] = {1848	0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6,1849	7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 131850};1851 1852static const s8 rtw8703b_pwrtrk_xtal_n[] = {1853	0, 0, 0, -1, -1, -1, -1, -2, -2, -2, -3, -3, -3, -3, -3,1854	-4, -2, -2, -1, -1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 11855};1856 1857static const s8 rtw8703b_pwrtrk_xtal_p[] = {1858	0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 0, -1, -1, -1,1859	-2, -3, -7, -9, -10, -11, -14, -16, -18, -20, -22, -24, -26, -28, -301860};1861 1862static const struct rtw_pwr_track_tbl rtw8703b_rtw_pwr_track_tbl = {1863	.pwrtrk_2gb_n = rtw8703b_pwrtrk_2gb_n,1864	.pwrtrk_2gb_p = rtw8703b_pwrtrk_2gb_p,1865	.pwrtrk_2ga_n = rtw8703b_pwrtrk_2ga_n,1866	.pwrtrk_2ga_p = rtw8703b_pwrtrk_2ga_p,1867	.pwrtrk_2g_cckb_n = rtw8703b_pwrtrk_2g_cck_b_n,1868	.pwrtrk_2g_cckb_p = rtw8703b_pwrtrk_2g_cck_b_p,1869	.pwrtrk_2g_ccka_n = rtw8703b_pwrtrk_2g_cck_a_n,1870	.pwrtrk_2g_ccka_p = rtw8703b_pwrtrk_2g_cck_a_p,1871	.pwrtrk_xtal_n = rtw8703b_pwrtrk_xtal_n,1872	.pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p,1873};1874 1875/* Shared-Antenna Coex Table */1876static const struct coex_table_para table_sant_8703b[] = {1877	{0xffffffff, 0xffffffff}, /* case-0 */1878	{0x55555555, 0x55555555},1879	{0x66555555, 0x66555555},1880	{0xaaaaaaaa, 0xaaaaaaaa},1881	{0x5a5a5a5a, 0x5a5a5a5a},1882	{0xfafafafa, 0xfafafafa}, /* case-5 */1883	{0x6a5a5555, 0xaaaaaaaa},1884	{0x6a5a56aa, 0x6a5a56aa},1885	{0x6a5a5a5a, 0x6a5a5a5a},1886	{0x66555555, 0x5a5a5a5a},1887	{0x66555555, 0x6a5a5a5a}, /* case-10 */1888	{0x66555555, 0x6a5a5aaa},1889	{0x66555555, 0x5a5a5aaa},1890	{0x66555555, 0x6aaa5aaa},1891	{0x66555555, 0xaaaa5aaa},1892	{0x66555555, 0xaaaaaaaa}, /* case-15 */1893	{0xffff55ff, 0xfafafafa},1894	{0xffff55ff, 0x6afa5afa},1895	{0xaaffffaa, 0xfafafafa},1896	{0xaa5555aa, 0x5a5a5a5a},1897	{0xaa5555aa, 0x6a5a5a5a}, /* case-20 */1898	{0xaa5555aa, 0xaaaaaaaa},1899	{0xffffffff, 0x5a5a5a5a},1900	{0xffffffff, 0x5a5a5a5a},1901	{0xffffffff, 0x55555555},1902	{0xffffffff, 0x5a5a5aaa}, /* case-25 */1903	{0x55555555, 0x5a5a5a5a},1904	{0x55555555, 0xaaaaaaaa},1905	{0x55555555, 0x6a5a6a5a},1906	{0x66556655, 0x66556655},1907	{0x66556aaa, 0x6a5a6aaa}, /* case-30 */1908	{0xffffffff, 0x5aaa5aaa},1909	{0x56555555, 0x5a5a5aaa},1910};1911 1912/* Shared-Antenna TDMA */1913static const struct coex_tdma_para tdma_sant_8703b[] = {1914	{ {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */1915	{ {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */1916	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },1917	{ {0x61, 0x30, 0x03, 0x11, 0x11} },1918	{ {0x61, 0x20, 0x03, 0x11, 0x11} },1919	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */1920	{ {0x61, 0x45, 0x03, 0x11, 0x10} },1921	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },1922	{ {0x61, 0x30, 0x03, 0x11, 0x10} },1923	{ {0x61, 0x20, 0x03, 0x11, 0x10} },1924	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */1925	{ {0x61, 0x08, 0x03, 0x11, 0x14} },1926	{ {0x61, 0x08, 0x03, 0x10, 0x14} },1927	{ {0x51, 0x08, 0x03, 0x10, 0x54} },1928	{ {0x51, 0x08, 0x03, 0x10, 0x55} },1929	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */1930	{ {0x51, 0x45, 0x03, 0x10, 0x50} },1931	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },1932	{ {0x51, 0x30, 0x03, 0x10, 0x50} },1933	{ {0x51, 0x20, 0x03, 0x10, 0x50} },1934	{ {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */1935	{ {0x51, 0x4a, 0x03, 0x10, 0x50} },1936	{ {0x51, 0x0c, 0x03, 0x10, 0x54} },1937	{ {0x55, 0x08, 0x03, 0x10, 0x54} },1938	{ {0x65, 0x10, 0x03, 0x11, 0x10} },1939	{ {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */1940	{ {0x51, 0x08, 0x03, 0x10, 0x50} },1941	{ {0x61, 0x08, 0x03, 0x11, 0x11} },1942};1943 1944static struct rtw_chip_ops rtw8703b_ops = {1945	.mac_init		= rtw8723x_mac_init,1946	.dump_fw_crash		= NULL,1947	.shutdown		= NULL,1948	.read_efuse		= rtw8703b_read_efuse,1949	.phy_set_param		= rtw8703b_phy_set_param,1950	.set_channel		= rtw8703b_set_channel,1951	.query_rx_desc		= rtw8703b_query_rx_desc,1952	.read_rf		= rtw_phy_read_rf_sipi,1953	.write_rf		= rtw_phy_write_rf_reg_sipi,1954	.set_tx_power_index	= rtw8723x_set_tx_power_index,1955	.set_antenna		= NULL,1956	.cfg_ldo25		= rtw8723x_cfg_ldo25,1957	.efuse_grant		= rtw8723x_efuse_grant,1958	.false_alarm_statistics	= rtw8723x_false_alarm_statistics,1959	.phy_calibration	= rtw8703b_phy_calibration,1960	.dpk_track		= NULL,1961	/* 8723d uses REG_CSRATIO to set dm_info.cck_pd_default, which1962	 * is used in its cck_pd_set function. According to comments1963	 * in the vendor driver code it doesn't exist in this chip1964	 * generation, only 0xa0a ("ODM_CCK_PD_THRESH", which is only1965	 * *written* to).1966	 */1967	.cck_pd_set		= NULL,1968	.pwr_track		= rtw8703b_pwr_track,1969	.config_bfee		= NULL,1970	.set_gid_table		= NULL,1971	.cfg_csi_rate		= NULL,1972	.adaptivity_init	= NULL,1973	.adaptivity		= NULL,1974	.cfo_init		= NULL,1975	.cfo_track		= NULL,1976	.config_tx_path		= NULL,1977	.config_txrx_mode	= NULL,1978	.fill_txdesc_checksum	= rtw8723x_fill_txdesc_checksum,1979 1980	/* for coex */1981	.coex_set_init		= rtw8723x_coex_cfg_init,1982	.coex_set_ant_switch	= NULL,1983	.coex_set_gnt_fix	= rtw8703b_coex_set_gnt_fix,1984	.coex_set_gnt_debug	= rtw8703b_coex_set_gnt_debug,1985	.coex_set_rfe_type	= rtw8703b_coex_set_rfe_type,1986	.coex_set_wl_tx_power	= rtw8703b_coex_set_wl_tx_power,1987	.coex_set_wl_rx_gain	= rtw8703b_coex_set_wl_rx_gain,1988};1989 1990const struct rtw_chip_info rtw8703b_hw_spec = {1991	.ops = &rtw8703b_ops,1992	.id = RTW_CHIP_TYPE_8703B,1993 1994	.fw_name = "rtw88/rtw8703b_fw.bin",1995	.wlan_cpu = RTW_WCPU_11N,1996	.tx_pkt_desc_sz = 40,1997	.tx_buf_desc_sz = 16,1998	.rx_pkt_desc_sz = 24,1999	.rx_buf_desc_sz = 8,2000	.phy_efuse_size = 256,2001	.log_efuse_size = 512,2002	.ptct_efuse_size = 15,2003	.txff_size = 32768,2004	.rxff_size = 16384,2005	.rsvd_drv_pg_num = 8,2006	.band = RTW_BAND_2G,2007	.page_size = TX_PAGE_SIZE,2008	.csi_buf_pg_num = 0,2009	.dig_min = 0x20,2010	.txgi_factor = 1,2011	.is_pwr_by_rate_dec = true,2012	.rx_ldpc = false,2013	.tx_stbc = false,2014	.max_power_index = 0x3f,2015	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,2016	.usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */2017 2018	.path_div_supported = false,2019	.ht_supported = true,2020	.vht_supported = false,2021	.lps_deep_mode_supported = 0,2022 2023	.sys_func_en = 0xFD,2024	.pwr_on_seq = card_enable_flow_8703b,2025	.pwr_off_seq = card_disable_flow_8703b,2026	.rqpn_table = rqpn_table_8703b,2027	.prioq_addrs = &rtw8723x_common.prioq_addrs,2028	.page_table = page_table_8703b,2029	/* used only in pci.c, not needed for SDIO devices */2030	.intf_table = NULL,2031 2032	.dig = rtw8723x_common.dig,2033	.dig_cck = rtw8723x_common.dig_cck,2034 2035	.rf_sipi_addr = {0x840, 0x844},2036	.rf_sipi_read_addr = rtw8723x_common.rf_sipi_addr,2037	.fix_rf_phy_num = 2,2038	.ltecoex_addr = &rtw8723x_common.ltecoex_addr,2039 2040	.mac_tbl = &rtw8703b_mac_tbl,2041	.agc_tbl = &rtw8703b_agc_tbl,2042	.bb_tbl = &rtw8703b_bb_tbl,2043	.rf_tbl = {&rtw8703b_rf_a_tbl},2044 2045	.rfe_defs = rtw8703b_rfe_defs,2046	.rfe_defs_size = ARRAY_SIZE(rtw8703b_rfe_defs),2047 2048	.iqk_threshold = 8,2049	.pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl,2050 2051	/* WOWLAN firmware exists, but not implemented yet */2052	.wow_fw_name = "rtw88/rtw8703b_wow_fw.bin",2053	.wowlan_stub = NULL,2054	.max_scan_ie_len = IEEE80211_MAX_DATA_LEN,2055 2056	/* Vendor driver has a time-based format, converted from2057	 * 201803302058	 */2059	.coex_para_ver = 0x0133ed6a,2060	.bt_desired_ver = 0x1c,2061	.scbd_support = true,2062	.new_scbd10_def = true,2063	.ble_hid_profile_support = false,2064	.wl_mimo_ps_support = false,2065	.pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,2066	.bt_rssi_type = COEX_BTRSSI_RATIO,2067	.ant_isolation = 15,2068	.rssi_tolerance = 2,2069	.bt_rssi_step = bt_rssi_step_8703b,2070	.wl_rssi_step = wl_rssi_step_8703b,2071	/* sant -> shared antenna, nsant -> non-shared antenna2072	 * Not sure if 8703b versions with non-shard antenna even exist.2073	 */2074	.table_sant_num = ARRAY_SIZE(table_sant_8703b),2075	.table_sant = table_sant_8703b,2076	.table_nsant_num = 0,2077	.table_nsant = NULL,2078	.tdma_sant_num = ARRAY_SIZE(tdma_sant_8703b),2079	.tdma_sant = tdma_sant_8703b,2080	.tdma_nsant_num = 0,2081	.tdma_nsant = NULL,2082	.wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8703b),2083	.wl_rf_para_tx = rf_para_tx_8703b,2084	.wl_rf_para_rx = rf_para_rx_8703b,2085	.bt_afh_span_bw20 = 0x20,2086	.bt_afh_span_bw40 = 0x30,2087	.afh_5g_num = ARRAY_SIZE(afh_5g_8703b),2088	.afh_5g = afh_5g_8703b,2089	/* REG_BTG_SEL doesn't seem to have a counterpart in the2090	 * vendor driver. Mathematically it's REG_PAD_CTRL1 + 3.2091	 *2092	 * It is used in the cardemu_to_act power sequence by though2093	 * (by address, 0x0067), comment: "0x67[0] = 0 to disable2094	 * BT_GPS_SEL pins" That seems to fit.2095	 */2096	.btg_reg = NULL,2097	/* These registers are used to read (and print) from if2098	 * CONFIG_RTW88_DEBUGFS is enabled.2099	 */2100	.coex_info_hw_regs_num = 0,2101	.coex_info_hw_regs = NULL,2102};2103EXPORT_SYMBOL(rtw8703b_hw_spec);2104 2105MODULE_FIRMWARE("rtw88/rtw8703b_fw.bin");2106MODULE_FIRMWARE("rtw88/rtw8703b_wow_fw.bin");2107 2108MODULE_AUTHOR("Fiona Klute <fiona.klute@gmx.de>");2109MODULE_DESCRIPTION("Realtek 802.11n wireless 8703b driver");2110MODULE_LICENSE("Dual BSD/GPL");2111