File Index
Files and directories
Sign in
FILE

hw.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/realtek/rtlwifi/rtl8192du/hw.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2024  Realtek Corporation.*/
   3
   4#include "../wifi.h"
   5#include "../cam.h"
   6#include "../usb.h"
   7#include "../rtl8192d/reg.h"
   8#include "../rtl8192d/def.h"
   9#include "../rtl8192d/dm_common.h"
  10#include "../rtl8192d/fw_common.h"
  11#include "../rtl8192d/hw_common.h"
  12#include "../rtl8192d/phy_common.h"
  13#include "phy.h"
  14#include "dm.h"
  15#include "fw.h"
  16#include "hw.h"
  17#include "trx.h"
  18
  19static void _rtl92du_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
  20				      u8 set_bits, u8 clear_bits)
  21{
  22	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
  23	struct rtl_priv *rtlpriv = rtl_priv(hw);
  24
  25	rtlusb->reg_bcn_ctrl_val |= set_bits;
  26	rtlusb->reg_bcn_ctrl_val &= ~clear_bits;
  27	rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val);
  28}
  29
  30static void _rtl92du_enable_bcn_sub_func(struct ieee80211_hw *hw)
  31{
  32	_rtl92du_set_bcn_ctrl_reg(hw, 0, BIT(1));
  33}
  34
  35static void _rtl92du_disable_bcn_sub_func(struct ieee80211_hw *hw)
  36{
  37	_rtl92du_set_bcn_ctrl_reg(hw, BIT(1), 0);
  38}
  39
  40void rtl92du_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
  41{
  42	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  43
  44	switch (variable) {
  45	case HW_VAR_RCR:
  46		*((u32 *)val) = mac->rx_conf;
  47		break;
  48	default:
  49		rtl92d_get_hw_reg(hw, variable, val);
  50		break;
  51	}
  52}
  53
  54void rtl92du_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
  55{
  56	struct rtl_priv *rtlpriv = rtl_priv(hw);
  57	struct rtl_mac *mac = rtl_mac(rtlpriv);
  58
  59	switch (variable) {
  60	case HW_VAR_AC_PARAM:
  61		rtl92d_dm_init_edca_turbo(hw);
  62		break;
  63	case HW_VAR_ACM_CTRL: {
  64		u8 e_aci = *val;
  65		union aci_aifsn *p_aci_aifsn =
  66		    (union aci_aifsn *)(&mac->ac[0].aifs);
  67		u8 acm = p_aci_aifsn->f.acm;
  68		u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
  69
  70		if (acm) {
  71			switch (e_aci) {
  72			case AC0_BE:
  73				acm_ctrl |= ACMHW_BEQEN;
  74				break;
  75			case AC2_VI:
  76				acm_ctrl |= ACMHW_VIQEN;
  77				break;
  78			case AC3_VO:
  79				acm_ctrl |= ACMHW_VOQEN;
  80				break;
  81			default:
  82				rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
  83					"HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
  84					acm);
  85				break;
  86			}
  87		} else {
  88			switch (e_aci) {
  89			case AC0_BE:
  90				acm_ctrl &= (~ACMHW_BEQEN);
  91				break;
  92			case AC2_VI:
  93				acm_ctrl &= (~ACMHW_VIQEN);
  94				break;
  95			case AC3_VO:
  96				acm_ctrl &= (~ACMHW_VOQEN);
  97				break;
  98			default:
  99				pr_err("%s:%d switch case %#x not processed\n",
 100				       __func__, __LINE__, e_aci);
 101				break;
 102			}
 103		}
 104		rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE,
 105			"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
 106			acm_ctrl);
 107		rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
 108		break;
 109	}
 110	case HW_VAR_RCR:
 111		mac->rx_conf = ((u32 *)val)[0];
 112		rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf);
 113		break;
 114	case HW_VAR_H2C_FW_JOINBSSRPT: {
 115		u8 tmp_regcr, tmp_reg422;
 116		bool recover = false;
 117		u8 mstatus = *val;
 118
 119		if (mstatus == RT_MEDIA_CONNECT) {
 120			rtlpriv->cfg->ops->set_hw_reg(hw,
 121						      HW_VAR_AID, NULL);
 122			tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
 123			rtl_write_byte(rtlpriv, REG_CR + 1,
 124				       tmp_regcr | ENSWBCN);
 125			_rtl92du_set_bcn_ctrl_reg(hw, 0, EN_BCN_FUNCTION);
 126			_rtl92du_set_bcn_ctrl_reg(hw, DIS_TSF_UDT, 0);
 127			tmp_reg422 = rtl_read_byte(rtlpriv,
 128						   REG_FWHW_TXQ_CTRL + 2);
 129			if (tmp_reg422 & (EN_BCNQ_DL >> 16))
 130				recover = true;
 131			rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
 132				       tmp_reg422 & ~(EN_BCNQ_DL >> 16));
 133
 134			/* We don't implement FW LPS so this is not needed. */
 135			/* rtl92d_set_fw_rsvdpagepkt(hw, 0); */
 136
 137			_rtl92du_set_bcn_ctrl_reg(hw, EN_BCN_FUNCTION, 0);
 138			_rtl92du_set_bcn_ctrl_reg(hw, 0, DIS_TSF_UDT);
 139			if (recover)
 140				rtl_write_byte(rtlpriv,
 141					       REG_FWHW_TXQ_CTRL + 2,
 142					       tmp_reg422);
 143			rtl_write_byte(rtlpriv, REG_CR + 1,
 144				       tmp_regcr & ~ENSWBCN);
 145		}
 146		rtl92d_set_fw_joinbss_report_cmd(hw, (*val));
 147		break;
 148	}
 149	case HW_VAR_CORRECT_TSF: {
 150		u8 btype_ibss = val[0];
 151
 152		if (btype_ibss)
 153			rtl92d_stop_tx_beacon(hw);
 154		_rtl92du_set_bcn_ctrl_reg(hw, 0, EN_BCN_FUNCTION);
 155		rtl_write_dword(rtlpriv, REG_TSFTR,
 156				(u32)(mac->tsf & 0xffffffff));
 157		rtl_write_dword(rtlpriv, REG_TSFTR + 4,
 158				(u32)((mac->tsf >> 32) & 0xffffffff));
 159		_rtl92du_set_bcn_ctrl_reg(hw, EN_BCN_FUNCTION, 0);
 160		if (btype_ibss)
 161			rtl92d_resume_tx_beacon(hw);
 162
 163		break;
 164	}
 165	case HW_VAR_KEEP_ALIVE:
 166		/* Avoid "switch case not processed" error. RTL8192DU doesn't
 167		 * need to do anything here, maybe.
 168		 */
 169		break;
 170	default:
 171		rtl92d_set_hw_reg(hw, variable, val);
 172		break;
 173	}
 174}
 175
 176static void _rtl92du_init_queue_reserved_page(struct ieee80211_hw *hw,
 177					      u8 out_ep_num,
 178					      u8 queue_sel)
 179{
 180	struct rtl_priv *rtlpriv = rtl_priv(hw);
 181	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 182	u32 txqpagenum, txqpageunit;
 183	u32 txqremainingpage;
 184	u32 value32 = 0;
 185	u32 numhq = 0;
 186	u32 numlq = 0;
 187	u32 numnq = 0;
 188	u32 numpubq;
 189
 190	if (rtlhal->macphymode != SINGLEMAC_SINGLEPHY) {
 191		numpubq = NORMAL_PAGE_NUM_PUBQ_92D_DUAL_MAC;
 192		txqpagenum = TX_TOTAL_PAGE_NUMBER_92D_DUAL_MAC - numpubq;
 193	} else {
 194		numpubq = TEST_PAGE_NUM_PUBQ_92DU;
 195		txqpagenum = TX_TOTAL_PAGE_NUMBER_92DU - numpubq;
 196	}
 197
 198	if (rtlhal->macphymode != SINGLEMAC_SINGLEPHY && out_ep_num == 3) {
 199		numhq = NORMAL_PAGE_NUM_HPQ_92D_DUAL_MAC;
 200		numlq = NORMAL_PAGE_NUM_LPQ_92D_DUAL_MAC;
 201		numnq = NORMAL_PAGE_NUM_NORMALQ_92D_DUAL_MAC;
 202	} else {
 203		txqpageunit = txqpagenum / out_ep_num;
 204		txqremainingpage = txqpagenum % out_ep_num;
 205
 206		if (queue_sel & TX_SELE_HQ)
 207			numhq = txqpageunit;
 208		if (queue_sel & TX_SELE_LQ)
 209			numlq = txqpageunit;
 210		if (queue_sel & TX_SELE_NQ)
 211			numnq = txqpageunit;
 212
 213		/* HIGH priority queue always present in the
 214		 * configuration of 2 or 3 out-ep. Remainder pages
 215		 * assigned to High queue
 216		 */
 217		if (out_ep_num > 1 && txqremainingpage)
 218			numhq += txqremainingpage;
 219	}
 220
 221	/* NOTE: This step done before writing REG_RQPN. */
 222	rtl_write_byte(rtlpriv, REG_RQPN_NPQ, (u8)numnq);
 223
 224	/* TX DMA */
 225	u32p_replace_bits(&value32, numhq, HPQ_MASK);
 226	u32p_replace_bits(&value32, numlq, LPQ_MASK);
 227	u32p_replace_bits(&value32, numpubq, PUBQ_MASK);
 228	value32 |= LD_RQPN;
 229	rtl_write_dword(rtlpriv, REG_RQPN, value32);
 230}
 231
 232static void _rtl92du_init_tx_buffer_boundary(struct ieee80211_hw *hw,
 233					     u8 txpktbuf_bndy)
 234{
 235	struct rtl_priv *rtlpriv = rtl_priv(hw);
 236
 237	rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
 238	rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
 239
 240	rtl_write_byte(rtlpriv, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);
 241
 242	/* TXRKTBUG_PG_BNDY */
 243	rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy);
 244
 245	/* Beacon Head for TXDMA */
 246	rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
 247}
 248
 249static bool _rtl92du_llt_table_init(struct ieee80211_hw *hw, u8 txpktbuf_bndy)
 250{
 251	struct rtl_priv *rtlpriv = rtl_priv(hw);
 252	unsigned short i;
 253	bool status;
 254	u8 maxpage;
 255
 256	if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY)
 257		maxpage = 255;
 258	else
 259		maxpage = 127;
 260
 261	for (i = 0; i < (txpktbuf_bndy - 1); i++) {
 262		status = rtl92d_llt_write(hw, i, i + 1);
 263		if (!status)
 264			return status;
 265	}
 266
 267	/* end of list */
 268	status = rtl92d_llt_write(hw, txpktbuf_bndy - 1, 0xFF);
 269	if (!status)
 270		return status;
 271
 272	/* Make the other pages as ring buffer
 273	 * This ring buffer is used as beacon buffer if we
 274	 * config this MAC as two MAC transfer.
 275	 * Otherwise used as local loopback buffer.
 276	 */
 277	for (i = txpktbuf_bndy; i < maxpage; i++) {
 278		status = rtl92d_llt_write(hw, i, i + 1);
 279		if (!status)
 280			return status;
 281	}
 282
 283	/* Let last entry point to the start entry of ring buffer */
 284	status = rtl92d_llt_write(hw, maxpage, txpktbuf_bndy);
 285	if (!status)
 286		return status;
 287
 288	return true;
 289}
 290
 291static void _rtl92du_init_chipn_reg_priority(struct ieee80211_hw *hw, u16 beq,
 292					     u16 bkq, u16 viq, u16 voq,
 293					     u16 mgtq, u16 hiq)
 294{
 295	struct rtl_priv *rtlpriv = rtl_priv(hw);
 296	u16 value16;
 297
 298	value16 = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0x7;
 299	u16p_replace_bits(&value16, beq, TXDMA_BEQ_MAP);
 300	u16p_replace_bits(&value16, bkq, TXDMA_BKQ_MAP);
 301	u16p_replace_bits(&value16, viq, TXDMA_VIQ_MAP);
 302	u16p_replace_bits(&value16, voq, TXDMA_VOQ_MAP);
 303	u16p_replace_bits(&value16, mgtq, TXDMA_MGQ_MAP);
 304	u16p_replace_bits(&value16, hiq, TXDMA_HIQ_MAP);
 305	rtl_write_word(rtlpriv,  REG_TRXDMA_CTRL, value16);
 306}
 307
 308static void _rtl92du_init_chipn_one_out_ep_priority(struct ieee80211_hw *hw,
 309						    u8 queue_sel)
 310{
 311	struct rtl_priv *rtlpriv = rtl_priv(hw);
 312	u16 value;
 313
 314	switch (queue_sel) {
 315	case TX_SELE_HQ:
 316		value = QUEUE_HIGH;
 317		break;
 318	case TX_SELE_LQ:
 319		value = QUEUE_LOW;
 320		break;
 321	case TX_SELE_NQ:
 322		value = QUEUE_NORMAL;
 323		break;
 324	default:
 325		WARN_ON(1); /* Shall not reach here! */
 326		return;
 327	}
 328	_rtl92du_init_chipn_reg_priority(hw, value, value, value, value,
 329					 value, value);
 330	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
 331		"Tx queue select: 0x%02x\n", queue_sel);
 332}
 333
 334static void _rtl92du_init_chipn_two_out_ep_priority(struct ieee80211_hw *hw,
 335						    u8 queue_sel)
 336{
 337	struct rtl_priv *rtlpriv = rtl_priv(hw);
 338	u16 beq, bkq, viq, voq, mgtq, hiq;
 339	u16 valuehi, valuelow;
 340
 341	switch (queue_sel) {
 342	default:
 343		WARN_ON(1);
 344		fallthrough;
 345	case (TX_SELE_HQ | TX_SELE_LQ):
 346		valuehi = QUEUE_HIGH;
 347		valuelow = QUEUE_LOW;
 348		break;
 349	case (TX_SELE_NQ | TX_SELE_LQ):
 350		valuehi = QUEUE_NORMAL;
 351		valuelow = QUEUE_LOW;
 352		break;
 353	case (TX_SELE_HQ | TX_SELE_NQ):
 354		valuehi = QUEUE_HIGH;
 355		valuelow = QUEUE_NORMAL;
 356		break;
 357	}
 358
 359	beq = valuelow;
 360	bkq = valuelow;
 361	viq = valuehi;
 362	voq = valuehi;
 363	mgtq = valuehi;
 364	hiq = valuehi;
 365
 366	_rtl92du_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq);
 367	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
 368		"Tx queue select: 0x%02x\n", queue_sel);
 369}
 370
 371static void _rtl92du_init_chipn_three_out_ep_priority(struct ieee80211_hw *hw,
 372						      u8 queue_sel)
 373{
 374	struct rtl_priv *rtlpriv = rtl_priv(hw);
 375	u16 beq, bkq, viq, voq, mgtq, hiq;
 376
 377	beq = QUEUE_LOW;
 378	bkq = QUEUE_LOW;
 379	viq = QUEUE_NORMAL;
 380	voq = QUEUE_HIGH;
 381	mgtq = QUEUE_HIGH;
 382	hiq = QUEUE_HIGH;
 383
 384	_rtl92du_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq);
 385	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
 386		"Tx queue select: 0x%02x\n", queue_sel);
 387}
 388
 389static void _rtl92du_init_queue_priority(struct ieee80211_hw *hw,
 390					 u8 out_ep_num,
 391					 u8 queue_sel)
 392{
 393	switch (out_ep_num) {
 394	case 1:
 395		_rtl92du_init_chipn_one_out_ep_priority(hw, queue_sel);
 396		break;
 397	case 2:
 398		_rtl92du_init_chipn_two_out_ep_priority(hw, queue_sel);
 399		break;
 400	case 3:
 401		_rtl92du_init_chipn_three_out_ep_priority(hw, queue_sel);
 402		break;
 403	default:
 404		WARN_ON(1); /* Shall not reach here! */
 405		break;
 406	}
 407}
 408
 409static void _rtl92du_init_wmac_setting(struct ieee80211_hw *hw)
 410{
 411	struct rtl_priv *rtlpriv = rtl_priv(hw);
 412	struct rtl_mac *mac = rtl_mac(rtlpriv);
 413
 414	mac->rx_conf = RCR_APM | RCR_AM | RCR_AB | RCR_ADF | RCR_APP_ICV |
 415		       RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_MIC |
 416		       RCR_APP_PHYST_RXFF | RCR_APPFCS;
 417
 418	rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf);
 419
 420	/* Set Multicast Address. */
 421	rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff);
 422	rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff);
 423}
 424
 425static void _rtl92du_init_adaptive_ctrl(struct ieee80211_hw *hw)
 426{
 427	struct rtl_priv *rtlpriv = rtl_priv(hw);
 428	u32 val32;
 429
 430	val32 = rtl_read_dword(rtlpriv, REG_RRSR);
 431	val32 &= ~0xfffff;
 432	if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G)
 433		val32 |= 0xffff0; /* No CCK */
 434	else
 435		val32 |= 0xffff1;
 436	rtl_write_dword(rtlpriv, REG_RRSR, val32);
 437
 438	/* Set Spec SIFS (used in NAV) */
 439	rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010);
 440
 441	/* Retry limit 0x30 */
 442	rtl_write_word(rtlpriv, REG_RL, 0x3030);
 443}
 444
 445static void _rtl92du_init_edca(struct ieee80211_hw *hw)
 446{
 447	struct rtl_priv *rtlpriv = rtl_priv(hw);
 448	u16 val16;
 449
 450	/* Disable EDCCA count down, to reduce collison and retry */
 451	val16 = rtl_read_word(rtlpriv, REG_RD_CTRL);
 452	val16 |= DIS_EDCA_CNT_DWN;
 453	rtl_write_word(rtlpriv, REG_RD_CTRL, val16);
 454
 455	/* CCK SIFS shall always be 10us. */
 456	rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x0a0a);
 457	/* Set SIFS for OFDM */
 458	rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010);
 459
 460	rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0204);
 461
 462	rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x014004);
 463
 464	/* TXOP */
 465	rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 0x005EA42B);
 466	rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0x0000A44F);
 467	rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x005EA324);
 468	rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x002FA226);
 469
 470	rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
 471
 472	rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
 473
 474	rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
 475
 476	rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x2);
 477	rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2);
 478}
 479
 480static void _rtl92du_init_retry_function(struct ieee80211_hw *hw)
 481{
 482	struct rtl_priv *rtlpriv = rtl_priv(hw);
 483	u8 val8;
 484
 485	val8 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL);
 486	val8 |= EN_AMPDU_RTY_NEW;
 487	rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL, val8);
 488
 489	rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
 490}
 491
 492static void _rtl92du_init_operation_mode(struct ieee80211_hw *hw)
 493{
 494	struct rtl_priv *rtlpriv = rtl_priv(hw);
 495	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 496
 497	rtl_write_byte(rtlpriv, REG_BWOPMODE, BW_OPMODE_20MHZ);
 498
 499	switch (rtlpriv->phy.rf_type) {
 500	case RF_1T2R:
 501	case RF_1T1R:
 502		rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3);
 503		break;
 504	case RF_2T2R:
 505	case RF_2T2R_GREEN:
 506		rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3);
 507		break;
 508	}
 509	rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, rtlhal->minspace_cfg);
 510}
 511
 512static void _rtl92du_init_beacon_parameters(struct ieee80211_hw *hw)
 513{
 514	struct rtl_priv *rtlpriv = rtl_priv(hw);
 515
 516	rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010);
 517
 518	rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x3c02);
 519	rtl_write_byte(rtlpriv, REG_DRVERLYINT, 0x05);
 520	rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x03);
 521
 522	rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
 523}
 524
 525static void _rtl92du_init_ampdu_aggregation(struct ieee80211_hw *hw)
 526{
 527	struct rtl_priv *rtlpriv = rtl_priv(hw);
 528	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 529
 530	/* Aggregation threshold */
 531	if (rtlhal->macphymode == DUALMAC_DUALPHY)
 532		rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x66525541);
 533	else if (rtlhal->macphymode == DUALMAC_SINGLEPHY)
 534		rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x44444441);
 535	else
 536		rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x88728841);
 537
 538	rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
 539}
 540
 541static bool _rtl92du_init_power_on(struct ieee80211_hw *hw)
 542{
 543	struct rtl_priv *rtlpriv = rtl_priv(hw);
 544	unsigned short wordtmp;
 545	unsigned char bytetmp;
 546	u16 retry = 0;
 547
 548	do {
 549		if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN)
 550			break;
 551
 552		if (retry++ > 1000)
 553			return false;
 554	} while (true);
 555
 556	/* Unlock ISO/CLK/Power control register */
 557	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
 558
 559	/* SPS0_CTRL 0x11[7:0] = 0x2b  enable SPS into PWM mode */
 560	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
 561
 562	msleep(1);
 563
 564	bytetmp = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL);
 565	if ((bytetmp & LDV12_EN) == 0) {
 566		bytetmp |= LDV12_EN;
 567		rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, bytetmp);
 568
 569		msleep(1);
 570
 571		bytetmp = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL);
 572		bytetmp &= ~ISO_MD2PP;
 573		rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, bytetmp);
 574	}
 575
 576	/* Auto enable WLAN */
 577	wordtmp = rtl_read_word(rtlpriv, REG_APS_FSMCO);
 578	wordtmp |= APFM_ONMAC;
 579	rtl_write_word(rtlpriv, REG_APS_FSMCO, wordtmp);
 580
 581	wordtmp = rtl_read_word(rtlpriv, REG_APS_FSMCO);
 582	retry = 0;
 583	while ((wordtmp & APFM_ONMAC) && retry < 1000) {
 584		retry++;
 585		wordtmp = rtl_read_word(rtlpriv, REG_APS_FSMCO);
 586	}
 587
 588	/* Release RF digital isolation */
 589	wordtmp = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL);
 590	wordtmp &= ~ISO_DIOR;
 591	rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, wordtmp);
 592
 593	/* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
 594	wordtmp = rtl_read_word(rtlpriv, REG_CR);
 595	wordtmp |= HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN |
 596		   PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | ENSEC;
 597	rtl_write_word(rtlpriv, REG_CR, wordtmp);
 598
 599	return true;
 600}
 601
 602static bool _rtl92du_init_mac(struct ieee80211_hw *hw)
 603{
 604	struct rtl_priv *rtlpriv = rtl_priv(hw);
 605	u8 val8;
 606
 607	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
 608
 609	val8 = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
 610	val8 &= ~(FEN_MREGEN >> 8);
 611	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, val8);
 612
 613	/* For s3/s4 may reset mac, Reg0xf8 may be set to 0,
 614	 * so reset macphy control reg here.
 615	 */
 616	rtl92d_phy_config_macphymode(hw);
 617
 618	rtl92du_phy_set_poweron(hw);
 619
 620	if (!_rtl92du_init_power_on(hw)) {
 621		pr_err("Failed to init power on!\n");
 622		return false;
 623	}
 624
 625	rtl92d_phy_config_maccoexist_rfpage(hw);
 626
 627	return true;
 628}
 629
 630int rtl92du_hw_init(struct ieee80211_hw *hw)
 631{
 632	struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
 633	struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
 634	struct rtl_priv *rtlpriv = rtl_priv(hw);
 635	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
 636	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 637	struct rtl_mac *mac = rtl_mac(rtlpriv);
 638	struct rtl_phy *rtlphy = &rtlpriv->phy;
 639	u8 val8, txpktbuf_bndy;
 640	int err, i;
 641	u32 val32;
 642	u16 val16;
 643
 644	mutex_lock(rtlpriv->mutex_for_hw_init);
 645
 646	/* we should do iqk after disable/enable */
 647	rtl92d_phy_reset_iqk_result(hw);
 648
 649	if (!_rtl92du_init_mac(hw)) {
 650		pr_err("Init MAC failed\n");
 651		mutex_unlock(rtlpriv->mutex_for_hw_init);
 652		return 1;
 653	}
 654
 655	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY)
 656		txpktbuf_bndy = 249;
 657	else
 658		txpktbuf_bndy = 123;
 659
 660	if (!_rtl92du_llt_table_init(hw, txpktbuf_bndy)) {
 661		pr_err("Init LLT failed\n");
 662		mutex_unlock(rtlpriv->mutex_for_hw_init);
 663		return 1;
 664	}
 665
 666	err = rtl92du_download_fw(hw);
 667
 668	/* return fail only when part number check fail */
 669	if (err && rtl_read_byte(rtlpriv, 0x1c5) == 0xe0) {
 670		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
 671			"Failed to download FW. Init HW without FW..\n");
 672		mutex_unlock(rtlpriv->mutex_for_hw_init);
 673		return 1;
 674	}
 675	rtlhal->last_hmeboxnum = 0;
 676	rtlpriv->psc.fw_current_inpsmode = false;
 677
 678	rtl92du_phy_mac_config(hw);
 679
 680	/* Set reserved page for each queue */
 681	_rtl92du_init_queue_reserved_page(hw, rtlusb->out_ep_nums,
 682					  rtlusb->out_queue_sel);
 683
 684	_rtl92du_init_tx_buffer_boundary(hw, txpktbuf_bndy);
 685
 686	_rtl92du_init_queue_priority(hw, rtlusb->out_ep_nums,
 687				     rtlusb->out_queue_sel);
 688
 689	/* Set Tx/Rx page size (Tx must be 128 Bytes,
 690	 * Rx can be 64, 128, 256, 512, 1024 bytes)
 691	 */
 692	rtl_write_byte(rtlpriv, REG_PBP, 0x11);
 693
 694	/* Get Rx PHY status in order to report RSSI and others. */
 695	rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
 696
 697	rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
 698	rtl_write_dword(rtlpriv, REG_HIMR, 0xffffffff);
 699
 700	val8 = rtl_read_byte(rtlpriv, MSR);
 701	val8 &= ~MSR_MASK;
 702	val8 |= MSR_INFRA;
 703	rtl_write_byte(rtlpriv, MSR, val8);
 704
 705	_rtl92du_init_wmac_setting(hw);
 706	_rtl92du_init_adaptive_ctrl(hw);
 707	_rtl92du_init_edca(hw);
 708
 709	rtl_write_dword(rtlpriv, REG_DARFRC, 0x00000000);
 710	rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x10080404);
 711	rtl_write_dword(rtlpriv, REG_RARFRC, 0x04030201);
 712	rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x08070605);
 713
 714	_rtl92du_init_retry_function(hw);
 715	/* _InitUsbAggregationSetting(padapter); no aggregation for now */
 716	_rtl92du_init_operation_mode(hw);
 717	_rtl92du_init_beacon_parameters(hw);
 718	_rtl92du_init_ampdu_aggregation(hw);
 719
 720	rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff);
 721
 722	/* unit: 256us. 256ms */
 723	rtl_write_word(rtlpriv, REG_PKT_VO_VI_LIFE_TIME, 0x0400);
 724	rtl_write_word(rtlpriv, REG_PKT_BE_BK_LIFE_TIME, 0x0400);
 725
 726	/* Hardware-controlled blinking. */
 727	rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8282);
 728	rtl_write_byte(rtlpriv, REG_LEDCFG2, 0x82);
 729
 730	val32 = rtl_read_dword(rtlpriv, REG_TXDMA_OFFSET_CHK);
 731	val32 |= DROP_DATA_EN;
 732	rtl_write_dword(rtlpriv, REG_TXDMA_OFFSET_CHK, val32);
 733
 734	if (mac->rdg_en) {
 735		rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xff);
 736		rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200);
 737		rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05);
 738	}
 739
 740	for (i = 0; i < 4; i++)
 741		rtl_write_dword(rtlpriv, REG_ARFR0 + i * 4, 0x1f8ffff0);
 742
 743	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) {
 744		if (rtlusb->out_ep_nums == 2)
 745			rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03066666);
 746		else
 747			rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0x8888);
 748	} else {
 749		rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0x5555);
 750	}
 751
 752	val8 = rtl_read_byte(rtlpriv, 0x605);
 753	val8 |= 0xf0;
 754	rtl_write_byte(rtlpriv, 0x605, val8);
 755
 756	rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x30);
 757	rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x30);
 758	rtl_write_byte(rtlpriv, 0x606, 0x30);
 759
 760	/* temp for high queue and mgnt Queue corrupt in time; it may
 761	 * cause hang when sw beacon use high_Q, other frame use mgnt_Q;
 762	 * or, sw beacon use mgnt_Q, other frame use high_Q;
 763	 */
 764	rtl_write_byte(rtlpriv, REG_DIS_TXREQ_CLR, 0x10);
 765	val16 = rtl_read_word(rtlpriv, REG_RD_CTRL);
 766	val16 |= BIT(12);
 767	rtl_write_word(rtlpriv, REG_RD_CTRL, val16);
 768
 769	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0);
 770
 771	/* usb suspend idle time count for bitfile0927 */
 772	val8 = rtl_read_byte(rtlpriv, 0xfe56);
 773	val8 |= BIT(0) | BIT(1);
 774	rtl_write_byte(rtlpriv, 0xfe56, val8);
 775
 776	if (rtlhal->earlymode_enable) {
 777		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
 778			"EarlyMode Enabled!!!\n");
 779
 780		val8 = rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL);
 781		val8 |= 0x1f;
 782		rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, val8);
 783
 784		rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL + 3, 0x80);
 785
 786		val8 = rtl_read_byte(rtlpriv, 0x605);
 787		val8 |= 0x40;
 788		rtl_write_byte(rtlpriv, 0x605, val8);
 789	} else {
 790		rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0);
 791	}
 792
 793	rtl92du_phy_bb_config(hw);
 794
 795	rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
 796	/* set before initialize RF */
 797	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
 798
 799	/* config RF */
 800	rtl92du_phy_rf_config(hw);
 801
 802	/* set default value after initialize RF */
 803	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0);
 804
 805	/* After load BB, RF params, we need to do more for 92D. */
 806	rtl92du_update_bbrf_configuration(hw);
 807
 808	rtlphy->rfreg_chnlval[0] =
 809		rtl_get_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK);
 810	rtlphy->rfreg_chnlval[1] =
 811		rtl_get_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK);
 812
 813	/*---- Set CCK and OFDM Block "ON"----*/
 814	if (rtlhal->current_bandtype == BAND_ON_2_4G)
 815		rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
 816	rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
 817
 818	/* reset hw sec */
 819	rtl_cam_reset_all_entry(hw);
 820	rtl92d_enable_hw_security_config(hw);
 821
 822	rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
 823
 824	/* schmitt trigger, improve tx evm for 92du */
 825	val8 = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL);
 826	val8 |= BIT(1);
 827	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, val8);
 828
 829	/* Disable bar */
 830	rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0xffff);
 831
 832	/* Nav limit */
 833	rtl_write_byte(rtlpriv, REG_NAV_CTRL + 2, 0);
 834	rtl_write_byte(rtlpriv, ROFDM0_XATXAFE + 3, 0x50);
 835
 836	/* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct
 837	 * TX power index for different rate set.
 838	 */
 839	rtl92d_phy_get_hw_reg_originalvalue(hw);
 840
 841	ppsc->rfpwr_state = ERFON;
 842
 843	/* do IQK for 2.4G for better scan result */
 844	if (rtlhal->current_bandtype == BAND_ON_2_4G)
 845		rtl92du_phy_iq_calibrate(hw);
 846
 847	rtl92du_phy_lc_calibrate(hw, IS_92D_SINGLEPHY(rtlhal->version));
 848
 849	rtl92du_phy_init_pa_bias(hw);
 850
 851	mutex_unlock(rtlpriv->mutex_for_hw_init);
 852
 853	rtl92du_dm_init(hw);
 854
 855	/* For 2 PORT TSF SYNC */
 856	rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1818);
 857	rtlusb->reg_bcn_ctrl_val = 0x18;
 858
 859	udelay(500);
 860
 861	if (rtlhal->macphymode != DUALMAC_DUALPHY) {
 862		rtl_write_dword(rtlpriv, RFPGA1_TXINFO,
 863				rtl_read_dword(rtlpriv, RFPGA1_TXINFO) & ~BIT(30));
 864
 865		rtl_write_dword(rtlpriv, RFPGA0_TXGAINSTAGE,
 866				rtl_read_dword(rtlpriv, RFPGA0_TXGAINSTAGE) & ~BIT(31));
 867
 868		rtl_write_dword(rtlpriv, ROFDM0_XBTXAFE, 0xa0e40000);
 869	}
 870
 871	val32 = rtl_read_dword(rtlpriv, REG_FWHW_TXQ_CTRL);
 872	val32 |= BIT(12);
 873	rtl_write_dword(rtlpriv, REG_FWHW_TXQ_CTRL, val32);
 874
 875	return err;
 876}
 877
 878static int _rtl92du_set_media_status(struct ieee80211_hw *hw,
 879				     enum nl80211_iftype type)
 880{
 881	struct rtl_priv *rtlpriv = rtl_priv(hw);
 882	enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
 883	u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
 884
 885	bt_msr &= 0xfc;
 886
 887	if (type == NL80211_IFTYPE_UNSPECIFIED ||
 888	    type == NL80211_IFTYPE_STATION) {
 889		rtl92d_stop_tx_beacon(hw);
 890		_rtl92du_enable_bcn_sub_func(hw);
 891	} else if (type == NL80211_IFTYPE_ADHOC ||
 892		   type == NL80211_IFTYPE_AP) {
 893		rtl92d_resume_tx_beacon(hw);
 894		_rtl92du_disable_bcn_sub_func(hw);
 895	} else {
 896		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
 897			"Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n",
 898			type);
 899	}
 900
 901	switch (type) {
 902	case NL80211_IFTYPE_UNSPECIFIED:
 903		bt_msr |= MSR_NOLINK;
 904		ledaction = LED_CTL_LINK;
 905		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 906			"Set Network type to NO LINK!\n");
 907		break;
 908	case NL80211_IFTYPE_ADHOC:
 909		bt_msr |= MSR_ADHOC;
 910		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 911			"Set Network type to Ad Hoc!\n");
 912		break;
 913	case NL80211_IFTYPE_STATION:
 914		bt_msr |= MSR_INFRA;
 915		ledaction = LED_CTL_LINK;
 916		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 917			"Set Network type to STA!\n");
 918		break;
 919	case NL80211_IFTYPE_AP:
 920		bt_msr |= MSR_AP;
 921		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 922			"Set Network type to AP!\n");
 923		break;
 924	default:
 925		pr_err("Network type %d not supported!\n", type);
 926		return 1;
 927	}
 928	rtl_write_byte(rtlpriv, MSR, bt_msr);
 929
 930	rtlpriv->cfg->ops->led_control(hw, ledaction);
 931
 932	if ((bt_msr & MSR_MASK) == MSR_AP)
 933		rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
 934	else
 935		rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
 936
 937	return 0;
 938}
 939
 940void rtl92du_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
 941{
 942	struct rtl_priv *rtlpriv = rtl_priv(hw);
 943	u32 reg_rcr;
 944
 945	if (rtlpriv->psc.rfpwr_state != ERFON)
 946		return;
 947
 948	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
 949
 950	if (check_bssid) {
 951		reg_rcr |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
 952		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)&reg_rcr);
 953		_rtl92du_set_bcn_ctrl_reg(hw, 0, DIS_TSF_UDT);
 954	} else if (!check_bssid) {
 955		reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 956		_rtl92du_set_bcn_ctrl_reg(hw, DIS_TSF_UDT, 0);
 957		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)&reg_rcr);
 958	}
 959}
 960
 961int rtl92du_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
 962{
 963	struct rtl_priv *rtlpriv = rtl_priv(hw);
 964
 965	if (_rtl92du_set_media_status(hw, type))
 966		return -EOPNOTSUPP;
 967
 968	/* check bssid */
 969	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
 970		if (type != NL80211_IFTYPE_AP)
 971			rtl92du_set_check_bssid(hw, true);
 972	} else {
 973		rtl92du_set_check_bssid(hw, false);
 974	}
 975
 976	return 0;
 977}
 978
 979/* do iqk or reload iqk */
 980/* windows just rtl92d_phy_reload_iqk_setting in set channel,
 981 * but it's very strict for time sequence so we add
 982 * rtl92d_phy_reload_iqk_setting here
 983 */
 984void rtl92du_linked_set_reg(struct ieee80211_hw *hw)
 985{
 986	struct rtl_priv *rtlpriv = rtl_priv(hw);
 987	struct rtl_phy *rtlphy = &rtlpriv->phy;
 988	u8 channel = rtlphy->current_channel;
 989	u8 indexforchannel;
 990
 991	indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
 992	if (!rtlphy->iqk_matrix[indexforchannel].iqk_done) {
 993		rtl_dbg(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG,
 994			"Do IQK for channel:%d\n", channel);
 995		rtl92du_phy_iq_calibrate(hw);
 996	}
 997}
 998
 999void rtl92du_enable_interrupt(struct ieee80211_hw *hw)
1000{
1001	/* Nothing to do. */
1002}
1003
1004void rtl92du_disable_interrupt(struct ieee80211_hw *hw)
1005{
1006	/* Nothing to do. */
1007}
1008
1009static void _rtl92du_poweroff_adapter(struct ieee80211_hw *hw)
1010{
1011	struct rtl_priv *rtlpriv = rtl_priv(hw);
1012	u8 retry = 100;
1013	u8 u1b_tmp;
1014	u16 val16;
1015	u32 val32;
1016
1017	rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04);
1018
1019	rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
1020
1021	/* IF fw in RAM code, do reset */
1022	if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) {
1023		rtl_write_byte(rtlpriv, REG_FSIMR, 0);
1024
1025		/* We need to disable other HRCV INT to influence 8051 reset. */
1026		rtl_write_byte(rtlpriv, REG_FWIMR, 0x20);
1027
1028		/* Close mask to prevent incorrect FW write operation. */
1029		rtl_write_byte(rtlpriv, REG_FTIMR, 0);
1030
1031		rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
1032
1033		/* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */
1034		rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
1035		val16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
1036		while (val16 & FEN_CPUEN) {
1037			retry--;
1038			if (retry == 0)
1039				break;
1040			udelay(50);
1041			val16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
1042		}
1043
1044		if (retry == 0) {
1045			rtl_write_byte(rtlpriv, REG_FWIMR, 0);
1046
1047			/* if 8051 reset fail, reset MAC directly. */
1048			rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x50);
1049
1050			mdelay(10);
1051		}
1052	}
1053
1054	/* reset MCU, MAC register, DCORE */
1055	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x54);
1056
1057	/* reset MCU ready status */
1058	rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1059
1060	/* Pull GPIO PIN to balance level and LED control */
1061
1062	/* Disable GPIO[7:0] */
1063	rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL + 2, 0x0000);
1064	val32 = rtl_read_dword(rtlpriv, REG_GPIO_PIN_CTRL);
1065	u32p_replace_bits(&val32, val32 & 0xff, 0x0000ff00);
1066	u32p_replace_bits(&val32, 0xff, 0x00ff0000);
1067	rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, val32);
1068
1069	/* Disable GPIO[10:8] */
1070	rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, 0);
1071	val16 = rtl_read_word(rtlpriv, REG_GPIO_IO_SEL);
1072	u16p_replace_bits(&val16, val16 & 0xf, 0x00f0);
1073	u16p_replace_bits(&val16, 0xf, 0x0780);
1074	rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, val16);
1075
1076	/* Disable LED 0, 1, and 2 */
1077	rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8888);
1078	rtl_write_byte(rtlpriv, REG_LEDCFG2, 0x88);
1079
1080	/* Disable analog sequence */
1081
1082	/* enter PFM mode */
1083	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
1084
1085	rtl_write_word(rtlpriv, REG_APS_FSMCO,
1086		       APDM_HOST | AFSM_HSUS | PFM_ALDN);
1087
1088	/* lock ISO/CLK/Power control register */
1089	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1090
1091	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1092		"In PowerOff,reg0x%x=%X\n",
1093		REG_SPS0_CTRL, rtl_read_byte(rtlpriv, REG_SPS0_CTRL));
1094
1095	/* 0x17[7] 1b': power off in process  0b' : power off over */
1096	if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) {
1097		mutex_lock(rtlpriv->mutex_for_power_on_off);
1098		u1b_tmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
1099		u1b_tmp &= ~BIT(7);
1100		rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1b_tmp);
1101		mutex_unlock(rtlpriv->mutex_for_power_on_off);
1102	}
1103
1104	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<=======\n");
1105}
1106
1107void rtl92du_card_disable(struct ieee80211_hw *hw)
1108{
1109	struct rtl_priv *rtlpriv = rtl_priv(hw);
1110	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1111	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1112	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1113	enum nl80211_iftype opmode;
1114	u32 val32;
1115	u16 val16;
1116	u8 val8;
1117
1118	mac->link_state = MAC80211_NOLINK;
1119	opmode = NL80211_IFTYPE_UNSPECIFIED;
1120	_rtl92du_set_media_status(hw, opmode);
1121
1122	RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1123	/* Power sequence for each MAC. */
1124	/* a. stop tx DMA  */
1125	/* b. close RF */
1126	/* c. clear rx buf */
1127	/* d. stop rx DMA */
1128	/* e. reset MAC */
1129
1130	val16 = rtl_read_word(rtlpriv, REG_GPIO_MUXCFG);
1131	val16 &= ~BIT(12);
1132	rtl_write_word(rtlpriv, REG_GPIO_MUXCFG, val16);
1133
1134	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xff);
1135	udelay(500);
1136	rtl_write_byte(rtlpriv, REG_CR, 0);
1137
1138	/* RF OFF sequence */
1139	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
1140	rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x00);
1141
1142	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1143
1144	val8 = FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTN;
1145	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, val8);
1146
1147	/* Mac0 can not do Global reset. Mac1 can do. */
1148	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY ||
1149	    rtlhal->interfaceindex == 1) {
1150		/* before BB reset should do clock gated */
1151		val32 = rtl_read_dword(rtlpriv, RFPGA0_XCD_RFPARAMETER);
1152		val32 |= BIT(31);
1153		rtl_write_dword(rtlpriv, RFPGA0_XCD_RFPARAMETER, val32);
1154
1155		val8 &= ~FEN_BB_GLB_RSTN;
1156		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, val8);
1157	}
1158
1159	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==> Do power off.......\n");
1160	if (!rtl92du_phy_check_poweroff(hw))
1161		return;
1162
1163	_rtl92du_poweroff_adapter(hw);
1164}
1165
1166void rtl92du_set_beacon_related_registers(struct ieee80211_hw *hw)
1167{
1168	struct rtl_priv *rtlpriv = rtl_priv(hw);
1169	struct rtl_mac *mac = rtl_mac(rtlpriv);
1170	u16 bcn_interval, atim_window;
1171
1172	bcn_interval = mac->beacon_interval;
1173	atim_window = 2;
1174	rtl92du_disable_interrupt(hw);
1175	rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1176	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1177	rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1178	rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x20);
1179	if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G)
1180		rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x30);
1181	else
1182		rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x20);
1183	rtl_write_byte(rtlpriv, 0x606, 0x30);
1184}
1185
1186void rtl92du_set_beacon_interval(struct ieee80211_hw *hw)
1187{
1188	struct rtl_priv *rtlpriv = rtl_priv(hw);
1189	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1190	u16 bcn_interval = mac->beacon_interval;
1191
1192	rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG,
1193		"beacon_interval:%d\n", bcn_interval);
1194	rtl92du_disable_interrupt(hw);
1195	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1196	rtl92du_enable_interrupt(hw);
1197}
1198
1199void rtl92du_update_interrupt_mask(struct ieee80211_hw *hw,
1200				   u32 add_msr, u32 rm_msr)
1201{
1202	/* Nothing to do here. */
1203}
1204
1205void rtl92du_read_chip_version(struct ieee80211_hw *hw)
1206{
1207	struct rtl_priv *rtlpriv = rtl_priv(hw);
1208
1209	/* Chip version reading is done in rtl92d_read_eeprom_info. */
1210
1211	rtlpriv->rtlhal.hw_type = HARDWARE_TYPE_RTL8192DU;
1212}
~/ Read-only file preview.