Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  hw.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2024  Realtek Corporation.*/

#include "../wifi.h"
#include "../cam.h"
#include "../usb.h"
#include "../rtl8192d/reg.h"
#include "../rtl8192d/def.h"
#include "../rtl8192d/dm_common.h"
#include "../rtl8192d/fw_common.h"
#include "../rtl8192d/hw_common.h"
#include "../rtl8192d/phy_common.h"
#include "phy.h"
#include "dm.h"
#include "fw.h"
#include "hw.h"
#include "trx.h"

static void _rtl92du_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
          u8 set_bits, u8 clear_bits)
{
 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
 struct rtl_priv *rtlpriv = rtl_priv(hw);

 rtlusb->reg_bcn_ctrl_val |= set_bits;
 rtlusb->reg_bcn_ctrl_val &= ~clear_bits;
 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val);
}

static void _rtl92du_enable_bcn_sub_func(struct ieee80211_hw *hw)
{
 _rtl92du_set_bcn_ctrl_reg(hw, 0, BIT(1));
}

static void _rtl92du_disable_bcn_sub_func(struct ieee80211_hw *hw)
{
 _rtl92du_set_bcn_ctrl_reg(hw, BIT(1), 0);
}

void rtl92du_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
{
 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));

 switch (variable) {
 case HW_VAR_RCR:
  *((u32 *)val) = mac->rx_conf;
  break;
 default:
  rtl92d_get_hw_reg(hw, variable, val);
  break;
 }
}

void rtl92du_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 struct rtl_mac *mac = rtl_mac(rtlpriv);

 switch (variable) {
 case HW_VAR_AC_PARAM:
  rtl92d_dm_init_edca_turbo(hw);
  break;
 case HW_VAR_ACM_CTRL: {
  u8 e_aci = *val;
  union aci_aifsn *p_aci_aifsn =
      (union aci_aifsn *)(&mac->ac[0].aifs);
  u8 acm = p_aci_aifsn->f.acm;
  u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);

  if (acm) {
   switch (e_aci) {
   case AC0_BE:
    acm_ctrl |= ACMHW_BEQEN;
    break;
   case AC2_VI:
    acm_ctrl |= ACMHW_VIQEN;
    break;
   case AC3_VO:
    acm_ctrl |= ACMHW_VOQEN;
    break;
   default:
    rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
     "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
     acm);
    break;
   }
  } else {
   switch (e_aci) {
   case AC0_BE:
    acm_ctrl &= (~ACMHW_BEQEN);
    break;
   case AC2_VI:
    acm_ctrl &= (~ACMHW_VIQEN);
    break;
   case AC3_VO:
    acm_ctrl &= (~ACMHW_VOQEN);
    break;
   default:
    pr_err("%s:%d switch case %#x not processed\n",
           __func__, __LINE__, e_aci);
    break;
   }
  }
  rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE,
   "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
   acm_ctrl);
  rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
  break;
 }
 case HW_VAR_RCR:
  mac->rx_conf = ((u32 *)val)[0];
  rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf);
  break;
 case HW_VAR_H2C_FW_JOINBSSRPT: {
  u8 tmp_regcr, tmp_reg422;
  bool recover = false;
  u8 mstatus = *val;

  if (mstatus == RT_MEDIA_CONNECT) {
   rtlpriv->cfg->ops->set_hw_reg(hw,
            HW_VAR_AID, NULL);
   tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
   rtl_write_byte(rtlpriv, REG_CR + 1,
           tmp_regcr | ENSWBCN);
   _rtl92du_set_bcn_ctrl_reg(hw, 0, EN_BCN_FUNCTION);
   _rtl92du_set_bcn_ctrl_reg(hw, DIS_TSF_UDT, 0);
   tmp_reg422 = rtl_read_byte(rtlpriv,
         REG_FWHW_TXQ_CTRL + 2);
   if (tmp_reg422 & (EN_BCNQ_DL >> 16))
    recover = true;
   rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
           tmp_reg422 & ~(EN_BCNQ_DL >> 16));

   /* We don't implement FW LPS so this is not needed. */
   /* rtl92d_set_fw_rsvdpagepkt(hw, 0); */

   _rtl92du_set_bcn_ctrl_reg(hw, EN_BCN_FUNCTION, 0);
   _rtl92du_set_bcn_ctrl_reg(hw, 0, DIS_TSF_UDT);
   if (recover)
    rtl_write_byte(rtlpriv,
            REG_FWHW_TXQ_CTRL + 2,
            tmp_reg422);
   rtl_write_byte(rtlpriv, REG_CR + 1,
           tmp_regcr & ~ENSWBCN);
  }
  rtl92d_set_fw_joinbss_report_cmd(hw, (*val));
  break;
 }
 case HW_VAR_CORRECT_TSF: {
  u8 btype_ibss = val[0];

  if (btype_ibss)
   rtl92d_stop_tx_beacon(hw);
  _rtl92du_set_bcn_ctrl_reg(hw, 0, EN_BCN_FUNCTION);
  rtl_write_dword(rtlpriv, REG_TSFTR,
    (u32)(mac->tsf & 0xffffffff));
  rtl_write_dword(rtlpriv, REG_TSFTR + 4,
    (u32)((mac->tsf >> 32) & 0xffffffff));
  _rtl92du_set_bcn_ctrl_reg(hw, EN_BCN_FUNCTION, 0);
  if (btype_ibss)
   rtl92d_resume_tx_beacon(hw);

  break;
 }
 case HW_VAR_KEEP_ALIVE:
  /* Avoid "switch case not processed" error. RTL8192DU doesn't
 * need to do anything here, maybe.
 */

  break;
 default:
  rtl92d_set_hw_reg(hw, variable, val);
  break;
 }
}

static void _rtl92du_init_queue_reserved_page(struct ieee80211_hw *hw,
           u8 out_ep_num,
           u8 queue_sel)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 u32 txqpagenum, txqpageunit;
 u32 txqremainingpage;
 u32 value32 = 0;
 u32 numhq = 0;
 u32 numlq = 0;
 u32 numnq = 0;
 u32 numpubq;

 if (rtlhal->macphymode != SINGLEMAC_SINGLEPHY) {
  numpubq = NORMAL_PAGE_NUM_PUBQ_92D_DUAL_MAC;
  txqpagenum = TX_TOTAL_PAGE_NUMBER_92D_DUAL_MAC - numpubq;
 } else {
  numpubq = TEST_PAGE_NUM_PUBQ_92DU;
  txqpagenum = TX_TOTAL_PAGE_NUMBER_92DU - numpubq;
 }

 if (rtlhal->macphymode != SINGLEMAC_SINGLEPHY && out_ep_num == 3) {
  numhq = NORMAL_PAGE_NUM_HPQ_92D_DUAL_MAC;
  numlq = NORMAL_PAGE_NUM_LPQ_92D_DUAL_MAC;
  numnq = NORMAL_PAGE_NUM_NORMALQ_92D_DUAL_MAC;
 } else {
  txqpageunit = txqpagenum / out_ep_num;
  txqremainingpage = txqpagenum % out_ep_num;

  if (queue_sel & TX_SELE_HQ)
   numhq = txqpageunit;
  if (queue_sel & TX_SELE_LQ)
   numlq = txqpageunit;
  if (queue_sel & TX_SELE_NQ)
   numnq = txqpageunit;

  /* HIGH priority queue always present in the
 * configuration of 2 or 3 out-ep. Remainder pages
 * assigned to High queue
 */

  if (out_ep_num > 1 && txqremainingpage)
   numhq += txqremainingpage;
 }

 /* NOTE: This step done before writing REG_RQPN. */
 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, (u8)numnq);

 /* TX DMA */
 u32p_replace_bits(&value32, numhq, HPQ_MASK);
 u32p_replace_bits(&value32, numlq, LPQ_MASK);
 u32p_replace_bits(&value32, numpubq, PUBQ_MASK);
 value32 |= LD_RQPN;
 rtl_write_dword(rtlpriv, REG_RQPN, value32);
}

static void _rtl92du_init_tx_buffer_boundary(struct ieee80211_hw *hw,
          u8 txpktbuf_bndy)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);

 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);

 rtl_write_byte(rtlpriv, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);

 /* TXRKTBUG_PG_BNDY */
 rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy);

 /* Beacon Head for TXDMA */
 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
}

static bool _rtl92du_llt_table_init(struct ieee80211_hw *hw, u8 txpktbuf_bndy)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 unsigned short i;
 bool status;
 u8 maxpage;

 if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY)
  maxpage = 255;
 else
  maxpage = 127;

 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
  status = rtl92d_llt_write(hw, i, i + 1);
  if (!status)
   return status;
 }

 /* end of list */
 status = rtl92d_llt_write(hw, txpktbuf_bndy - 1, 0xFF);
 if (!status)
  return status;

 /* Make the other pages as ring buffer
 * This ring buffer is used as beacon buffer if we
 * config this MAC as two MAC transfer.
 * Otherwise used as local loopback buffer.
 */

 for (i = txpktbuf_bndy; i < maxpage; i++) {
  status = rtl92d_llt_write(hw, i, i + 1);
  if (!status)
   return status;
 }

 /* Let last entry point to the start entry of ring buffer */
 status = rtl92d_llt_write(hw, maxpage, txpktbuf_bndy);
 if (!status)
  return status;

 return true;
}

static void _rtl92du_init_chipn_reg_priority(struct ieee80211_hw *hw, u16 beq,
          u16 bkq, u16 viq, u16 voq,
          u16 mgtq, u16 hiq)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 u16 value16;

 value16 = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0x7;
 u16p_replace_bits(&value16, beq, TXDMA_BEQ_MAP);
 u16p_replace_bits(&value16, bkq, TXDMA_BKQ_MAP);
 u16p_replace_bits(&value16, viq, TXDMA_VIQ_MAP);
 u16p_replace_bits(&value16, voq, TXDMA_VOQ_MAP);
 u16p_replace_bits(&value16, mgtq, TXDMA_MGQ_MAP);
 u16p_replace_bits(&value16, hiq, TXDMA_HIQ_MAP);
 rtl_write_word(rtlpriv,  REG_TRXDMA_CTRL, value16);
}

static void _rtl92du_init_chipn_one_out_ep_priority(struct ieee80211_hw *hw,
          u8 queue_sel)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 u16 value;

 switch (queue_sel) {
 case TX_SELE_HQ:
  value = QUEUE_HIGH;
  break;
 case TX_SELE_LQ:
  value = QUEUE_LOW;
  break;
 case TX_SELE_NQ:
  value = QUEUE_NORMAL;
  break;
 default:
  WARN_ON(1); /* Shall not reach here! */
  return;
 }
 _rtl92du_init_chipn_reg_priority(hw, value, value, value, value,
      value, value);
 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
  "Tx queue select: 0x%02x\n", queue_sel);
}

static void _rtl92du_init_chipn_two_out_ep_priority(struct ieee80211_hw *hw,
          u8 queue_sel)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 u16 beq, bkq, viq, voq, mgtq, hiq;
 u16 valuehi, valuelow;

 switch (queue_sel) {
 default:
  WARN_ON(1);
  fallthrough;
 case (TX_SELE_HQ | TX_SELE_LQ):
  valuehi = QUEUE_HIGH;
  valuelow = QUEUE_LOW;
  break;
 case (TX_SELE_NQ | TX_SELE_LQ):
  valuehi = QUEUE_NORMAL;
  valuelow = QUEUE_LOW;
  break;
 case (TX_SELE_HQ | TX_SELE_NQ):
  valuehi = QUEUE_HIGH;
  valuelow = QUEUE_NORMAL;
  break;
 }

 beq = valuelow;
 bkq = valuelow;
 viq = valuehi;
 voq = valuehi;
 mgtq = valuehi;
 hiq = valuehi;

 _rtl92du_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq);
 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
  "Tx queue select: 0x%02x\n", queue_sel);
}

static void _rtl92du_init_chipn_three_out_ep_priority(struct ieee80211_hw *hw,
            u8 queue_sel)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 u16 beq, bkq, viq, voq, mgtq, hiq;

 beq = QUEUE_LOW;
 bkq = QUEUE_LOW;
 viq = QUEUE_NORMAL;
 voq = QUEUE_HIGH;
 mgtq = QUEUE_HIGH;
 hiq = QUEUE_HIGH;

 _rtl92du_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq);
 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
  "Tx queue select: 0x%02x\n", queue_sel);
}

static void _rtl92du_init_queue_priority(struct ieee80211_hw *hw,
      u8 out_ep_num,
      u8 queue_sel)
{
 switch (out_ep_num) {
 case 1:
  _rtl92du_init_chipn_one_out_ep_priority(hw, queue_sel);
  break;
 case 2:
  _rtl92du_init_chipn_two_out_ep_priority(hw, queue_sel);
  break;
 case 3:
  _rtl92du_init_chipn_three_out_ep_priority(hw, queue_sel);
  break;
 default:
  WARN_ON(1); /* Shall not reach here! */
  break;
 }
}

static void _rtl92du_init_wmac_setting(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 struct rtl_mac *mac = rtl_mac(rtlpriv);

 mac->rx_conf = RCR_APM | RCR_AM | RCR_AB | RCR_ADF | RCR_APP_ICV |
         RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_MIC |
         RCR_APP_PHYST_RXFF | RCR_APPFCS;

 rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf);

 /* Set Multicast Address. */
 rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff);
 rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff);
}

static void _rtl92du_init_adaptive_ctrl(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 u32 val32;

 val32 = rtl_read_dword(rtlpriv, REG_RRSR);
 val32 &= ~0xfffff;
 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G)
  val32 |= 0xffff0; /* No CCK */
 else
  val32 |= 0xffff1;
 rtl_write_dword(rtlpriv, REG_RRSR, val32);

 /* Set Spec SIFS (used in NAV) */
 rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010);

 /* Retry limit 0x30 */
 rtl_write_word(rtlpriv, REG_RL, 0x3030);
}

static void _rtl92du_init_edca(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 u16 val16;

 /* Disable EDCCA count down, to reduce collison and retry */
 val16 = rtl_read_word(rtlpriv, REG_RD_CTRL);
 val16 |= DIS_EDCA_CNT_DWN;
 rtl_write_word(rtlpriv, REG_RD_CTRL, val16);

 /* CCK SIFS shall always be 10us. */
 rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x0a0a);
 /* Set SIFS for OFDM */
 rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010);

 rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0204);

 rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x014004);

 /* TXOP */
 rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 0x005EA42B);
 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0x0000A44F);
 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x005EA324);
 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x002FA226);

 rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);

 rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);

 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);

 rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x2);
 rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2);
}

static void _rtl92du_init_retry_function(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 u8 val8;

 val8 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL);
 val8 |= EN_AMPDU_RTY_NEW;
 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL, val8);

 rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
}

static void _rtl92du_init_operation_mode(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);

 rtl_write_byte(rtlpriv, REG_BWOPMODE, BW_OPMODE_20MHZ);

 switch (rtlpriv->phy.rf_type) {
 case RF_1T2R:
 case RF_1T1R:
  rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3);
  break;
 case RF_2T2R:
 case RF_2T2R_GREEN:
  rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3);
  break;
 }
 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, rtlhal->minspace_cfg);
}

static void _rtl92du_init_beacon_parameters(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);

 rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010);

 rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x3c02);
 rtl_write_byte(rtlpriv, REG_DRVERLYINT, 0x05);
 rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x03);

 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
}

static void _rtl92du_init_ampdu_aggregation(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);

 /* Aggregation threshold */
 if (rtlhal->macphymode == DUALMAC_DUALPHY)
  rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x66525541);
 else if (rtlhal->macphymode == DUALMAC_SINGLEPHY)
  rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x44444441);
 else
  rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x88728841);

 rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
}

static bool _rtl92du_init_power_on(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 unsigned short wordtmp;
 unsigned char bytetmp;
 u16 retry = 0;

 do {
  if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN)
   break;

  if (retry++ > 1000)
   return false;
 } while (true);

 /* Unlock ISO/CLK/Power control register */
 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);

 /* SPS0_CTRL 0x11[7:0] = 0x2b  enable SPS into PWM mode */
 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);

 msleep(1);

 bytetmp = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL);
 if ((bytetmp & LDV12_EN) == 0) {
  bytetmp |= LDV12_EN;
  rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, bytetmp);

  msleep(1);

  bytetmp = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL);
  bytetmp &= ~ISO_MD2PP;
  rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, bytetmp);
 }

 /* Auto enable WLAN */
 wordtmp = rtl_read_word(rtlpriv, REG_APS_FSMCO);
 wordtmp |= APFM_ONMAC;
 rtl_write_word(rtlpriv, REG_APS_FSMCO, wordtmp);

 wordtmp = rtl_read_word(rtlpriv, REG_APS_FSMCO);
 retry = 0;
 while ((wordtmp & APFM_ONMAC) && retry < 1000) {
  retry++;
  wordtmp = rtl_read_word(rtlpriv, REG_APS_FSMCO);
 }

 /* Release RF digital isolation */
 wordtmp = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL);
 wordtmp &= ~ISO_DIOR;
 rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, wordtmp);

 /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
 wordtmp = rtl_read_word(rtlpriv, REG_CR);
 wordtmp |= HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN |
     PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | ENSEC;
 rtl_write_word(rtlpriv, REG_CR, wordtmp);

 return true;
}

static bool _rtl92du_init_mac(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 u8 val8;

 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);

 val8 = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
 val8 &= ~(FEN_MREGEN >> 8);
 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, val8);

 /* For s3/s4 may reset mac, Reg0xf8 may be set to 0,
 * so reset macphy control reg here.
 */

 rtl92d_phy_config_macphymode(hw);

 rtl92du_phy_set_poweron(hw);

 if (!_rtl92du_init_power_on(hw)) {
  pr_err("Failed to init power on!\n");
  return false;
 }

 rtl92d_phy_config_maccoexist_rfpage(hw);

 return true;
}

int rtl92du_hw_init(struct ieee80211_hw *hw)
{
 struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
 struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 struct rtl_mac *mac = rtl_mac(rtlpriv);
 struct rtl_phy *rtlphy = &rtlpriv->phy;
 u8 val8, txpktbuf_bndy;
 int err, i;
 u32 val32;
 u16 val16;

 mutex_lock(rtlpriv->mutex_for_hw_init);

 /* we should do iqk after disable/enable */
 rtl92d_phy_reset_iqk_result(hw);

 if (!_rtl92du_init_mac(hw)) {
  pr_err("Init MAC failed\n");
  mutex_unlock(rtlpriv->mutex_for_hw_init);
  return 1;
 }

 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY)
  txpktbuf_bndy = 249;
 else
  txpktbuf_bndy = 123;

 if (!_rtl92du_llt_table_init(hw, txpktbuf_bndy)) {
  pr_err("Init LLT failed\n");
  mutex_unlock(rtlpriv->mutex_for_hw_init);
  return 1;
 }

 err = rtl92du_download_fw(hw);

 /* return fail only when part number check fail */
 if (err && rtl_read_byte(rtlpriv, 0x1c5) == 0xe0) {
  rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
   "Failed to download FW. Init HW without FW..\n");
  mutex_unlock(rtlpriv->mutex_for_hw_init);
  return 1;
 }
 rtlhal->last_hmeboxnum = 0;
 rtlpriv->psc.fw_current_inpsmode = false;

 rtl92du_phy_mac_config(hw);

 /* Set reserved page for each queue */
 _rtl92du_init_queue_reserved_page(hw, rtlusb->out_ep_nums,
       rtlusb->out_queue_sel);

 _rtl92du_init_tx_buffer_boundary(hw, txpktbuf_bndy);

 _rtl92du_init_queue_priority(hw, rtlusb->out_ep_nums,
         rtlusb->out_queue_sel);

 /* Set Tx/Rx page size (Tx must be 128 Bytes,
 * Rx can be 64, 128, 256, 512, 1024 bytes)
 */

 rtl_write_byte(rtlpriv, REG_PBP, 0x11);

 /* Get Rx PHY status in order to report RSSI and others. */
 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);

 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
 rtl_write_dword(rtlpriv, REG_HIMR, 0xffffffff);

 val8 = rtl_read_byte(rtlpriv, MSR);
 val8 &= ~MSR_MASK;
 val8 |= MSR_INFRA;
 rtl_write_byte(rtlpriv, MSR, val8);

 _rtl92du_init_wmac_setting(hw);
 _rtl92du_init_adaptive_ctrl(hw);
 _rtl92du_init_edca(hw);

 rtl_write_dword(rtlpriv, REG_DARFRC, 0x00000000);
 rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x10080404);
 rtl_write_dword(rtlpriv, REG_RARFRC, 0x04030201);
 rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x08070605);

 _rtl92du_init_retry_function(hw);
 /* _InitUsbAggregationSetting(padapter); no aggregation for now */
 _rtl92du_init_operation_mode(hw);
 _rtl92du_init_beacon_parameters(hw);
 _rtl92du_init_ampdu_aggregation(hw);

 rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff);

 /* unit: 256us. 256ms */
 rtl_write_word(rtlpriv, REG_PKT_VO_VI_LIFE_TIME, 0x0400);
 rtl_write_word(rtlpriv, REG_PKT_BE_BK_LIFE_TIME, 0x0400);

 /* Hardware-controlled blinking. */
 rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8282);
 rtl_write_byte(rtlpriv, REG_LEDCFG2, 0x82);

 val32 = rtl_read_dword(rtlpriv, REG_TXDMA_OFFSET_CHK);
 val32 |= DROP_DATA_EN;
 rtl_write_dword(rtlpriv, REG_TXDMA_OFFSET_CHK, val32);

 if (mac->rdg_en) {
  rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xff);
  rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200);
  rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05);
 }

 for (i = 0; i < 4; i++)
  rtl_write_dword(rtlpriv, REG_ARFR0 + i * 4, 0x1f8ffff0);

 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) {
  if (rtlusb->out_ep_nums == 2)
   rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03066666);
  else
   rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0x8888);
 } else {
  rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0x5555);
 }

 val8 = rtl_read_byte(rtlpriv, 0x605);
 val8 |= 0xf0;
 rtl_write_byte(rtlpriv, 0x605, val8);

 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x30);
 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x30);
 rtl_write_byte(rtlpriv, 0x606, 0x30);

 /* temp for high queue and mgnt Queue corrupt in time; it may
 * cause hang when sw beacon use high_Q, other frame use mgnt_Q;
 * or, sw beacon use mgnt_Q, other frame use high_Q;
 */

 rtl_write_byte(rtlpriv, REG_DIS_TXREQ_CLR, 0x10);
 val16 = rtl_read_word(rtlpriv, REG_RD_CTRL);
 val16 |= BIT(12);
 rtl_write_word(rtlpriv, REG_RD_CTRL, val16);

 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0);

 /* usb suspend idle time count for bitfile0927 */
 val8 = rtl_read_byte(rtlpriv, 0xfe56);
 val8 |= BIT(0) | BIT(1);
 rtl_write_byte(rtlpriv, 0xfe56, val8);

 if (rtlhal->earlymode_enable) {
  rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
   "EarlyMode Enabled!!!\n");

  val8 = rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL);
  val8 |= 0x1f;
  rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, val8);

  rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL + 3, 0x80);

  val8 = rtl_read_byte(rtlpriv, 0x605);
  val8 |= 0x40;
  rtl_write_byte(rtlpriv, 0x605, val8);
 } else {
  rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0);
 }

 rtl92du_phy_bb_config(hw);

 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
 /* set before initialize RF */
 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);

 /* config RF */
 rtl92du_phy_rf_config(hw);

 /* set default value after initialize RF */
 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0);

 /* After load BB, RF params, we need to do more for 92D. */
 rtl92du_update_bbrf_configuration(hw);

 rtlphy->rfreg_chnlval[0] =
  rtl_get_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK);
 rtlphy->rfreg_chnlval[1] =
  rtl_get_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK);

 /*---- Set CCK and OFDM Block "ON"----*/
 if (rtlhal->current_bandtype == BAND_ON_2_4G)
  rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);

 /* reset hw sec */
 rtl_cam_reset_all_entry(hw);
 rtl92d_enable_hw_security_config(hw);

 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);

 /* schmitt trigger, improve tx evm for 92du */
 val8 = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL);
 val8 |= BIT(1);
 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, val8);

 /* Disable bar */
 rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0xffff);

 /* Nav limit */
 rtl_write_byte(rtlpriv, REG_NAV_CTRL + 2, 0);
 rtl_write_byte(rtlpriv, ROFDM0_XATXAFE + 3, 0x50);

 /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct
 * TX power index for different rate set.
 */

 rtl92d_phy_get_hw_reg_originalvalue(hw);

 ppsc->rfpwr_state = ERFON;

 /* do IQK for 2.4G for better scan result */
 if (rtlhal->current_bandtype == BAND_ON_2_4G)
  rtl92du_phy_iq_calibrate(hw);

 rtl92du_phy_lc_calibrate(hw, IS_92D_SINGLEPHY(rtlhal->version));

 rtl92du_phy_init_pa_bias(hw);

 mutex_unlock(rtlpriv->mutex_for_hw_init);

 rtl92du_dm_init(hw);

 /* For 2 PORT TSF SYNC */
 rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1818);
 rtlusb->reg_bcn_ctrl_val = 0x18;

 udelay(500);

 if (rtlhal->macphymode != DUALMAC_DUALPHY) {
  rtl_write_dword(rtlpriv, RFPGA1_TXINFO,
    rtl_read_dword(rtlpriv, RFPGA1_TXINFO) & ~BIT(30));

  rtl_write_dword(rtlpriv, RFPGA0_TXGAINSTAGE,
    rtl_read_dword(rtlpriv, RFPGA0_TXGAINSTAGE) & ~BIT(31));

  rtl_write_dword(rtlpriv, ROFDM0_XBTXAFE, 0xa0e40000);
 }

 val32 = rtl_read_dword(rtlpriv, REG_FWHW_TXQ_CTRL);
 val32 |= BIT(12);
 rtl_write_dword(rtlpriv, REG_FWHW_TXQ_CTRL, val32);

 return err;
}

static int _rtl92du_set_media_status(struct ieee80211_hw *hw,
         enum nl80211_iftype type)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
 u8 bt_msr = rtl_read_byte(rtlpriv, MSR);

 bt_msr &= 0xfc;

 if (type == NL80211_IFTYPE_UNSPECIFIED ||
     type == NL80211_IFTYPE_STATION) {
  rtl92d_stop_tx_beacon(hw);
  _rtl92du_enable_bcn_sub_func(hw);
 } else if (type == NL80211_IFTYPE_ADHOC ||
     type == NL80211_IFTYPE_AP) {
  rtl92d_resume_tx_beacon(hw);
  _rtl92du_disable_bcn_sub_func(hw);
 } else {
  rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
   "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n",
   type);
 }

 switch (type) {
 case NL80211_IFTYPE_UNSPECIFIED:
  bt_msr |= MSR_NOLINK;
  ledaction = LED_CTL_LINK;
  rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
   "Set Network type to NO LINK!\n");
  break;
 case NL80211_IFTYPE_ADHOC:
  bt_msr |= MSR_ADHOC;
  rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
   "Set Network type to Ad Hoc!\n");
  break;
 case NL80211_IFTYPE_STATION:
  bt_msr |= MSR_INFRA;
  ledaction = LED_CTL_LINK;
  rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
   "Set Network type to STA!\n");
  break;
 case NL80211_IFTYPE_AP:
  bt_msr |= MSR_AP;
  rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
   "Set Network type to AP!\n");
  break;
 default:
  pr_err("Network type %d not supported!\n", type);
  return 1;
 }
 rtl_write_byte(rtlpriv, MSR, bt_msr);

 rtlpriv->cfg->ops->led_control(hw, ledaction);

 if ((bt_msr & MSR_MASK) == MSR_AP)
  rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
 else
  rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);

 return 0;
}

void rtl92du_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 u32 reg_rcr;

 if (rtlpriv->psc.rfpwr_state != ERFON)
  return;

 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr));

 if (check_bssid) {
  reg_rcr |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
  rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)®_rcr);
  _rtl92du_set_bcn_ctrl_reg(hw, 0, DIS_TSF_UDT);
 } else if (!check_bssid) {
  reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
  _rtl92du_set_bcn_ctrl_reg(hw, DIS_TSF_UDT, 0);
  rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)®_rcr);
 }
}

int rtl92du_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);

 if (_rtl92du_set_media_status(hw, type))
  return -EOPNOTSUPP;

 /* check bssid */
 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
  if (type != NL80211_IFTYPE_AP)
   rtl92du_set_check_bssid(hw, true);
 } else {
  rtl92du_set_check_bssid(hw, false);
 }

 return 0;
}

/* do iqk or reload iqk */
/* windows just rtl92d_phy_reload_iqk_setting in set channel,
 * but it's very strict for time sequence so we add
 * rtl92d_phy_reload_iqk_setting here
 */

void rtl92du_linked_set_reg(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 struct rtl_phy *rtlphy = &rtlpriv->phy;
 u8 channel = rtlphy->current_channel;
 u8 indexforchannel;

 indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
 if (!rtlphy->iqk_matrix[indexforchannel].iqk_done) {
  rtl_dbg(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG,
   "Do IQK for channel:%d\n", channel);
  rtl92du_phy_iq_calibrate(hw);
 }
}

void rtl92du_enable_interrupt(struct ieee80211_hw *hw)
{
 /* Nothing to do. */
}

void rtl92du_disable_interrupt(struct ieee80211_hw *hw)
{
 /* Nothing to do. */
}

static void _rtl92du_poweroff_adapter(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 u8 retry = 100;
 u8 u1b_tmp;
 u16 val16;
 u32 val32;

 rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04);

 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);

 /* IF fw in RAM code, do reset */
 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) {
  rtl_write_byte(rtlpriv, REG_FSIMR, 0);

  /* We need to disable other HRCV INT to influence 8051 reset. */
  rtl_write_byte(rtlpriv, REG_FWIMR, 0x20);

  /* Close mask to prevent incorrect FW write operation. */
  rtl_write_byte(rtlpriv, REG_FTIMR, 0);

  rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);

  /* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */
  rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
  val16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
  while (val16 & FEN_CPUEN) {
   retry--;
   if (retry == 0)
    break;
   udelay(50);
   val16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
  }

  if (retry == 0) {
   rtl_write_byte(rtlpriv, REG_FWIMR, 0);

   /* if 8051 reset fail, reset MAC directly. */
   rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x50);

   mdelay(10);
  }
 }

 /* reset MCU, MAC register, DCORE */
 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x54);

 /* reset MCU ready status */
 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);

 /* Pull GPIO PIN to balance level and LED control */

 /* Disable GPIO[7:0] */
 rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL + 2, 0x0000);
 val32 = rtl_read_dword(rtlpriv, REG_GPIO_PIN_CTRL);
 u32p_replace_bits(&val32, val32 & 0xff, 0x0000ff00);
 u32p_replace_bits(&val32, 0xff, 0x00ff0000);
 rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, val32);

 /* Disable GPIO[10:8] */
 rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, 0);
 val16 = rtl_read_word(rtlpriv, REG_GPIO_IO_SEL);
 u16p_replace_bits(&val16, val16 & 0xf, 0x00f0);
 u16p_replace_bits(&val16, 0xf, 0x0780);
 rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, val16);

 /* Disable LED 0, 1, and 2 */
 rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8888);
 rtl_write_byte(rtlpriv, REG_LEDCFG2, 0x88);

 /* Disable analog sequence */

 /* enter PFM mode */
 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);

 rtl_write_word(rtlpriv, REG_APS_FSMCO,
         APDM_HOST | AFSM_HSUS | PFM_ALDN);

 /* lock ISO/CLK/Power control register */
 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);

 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
  "In PowerOff,reg0x%x=%X\n",
  REG_SPS0_CTRL, rtl_read_byte(rtlpriv, REG_SPS0_CTRL));

 /* 0x17[7] 1b': power off in process  0b' : power off over */
 if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) {
  mutex_lock(rtlpriv->mutex_for_power_on_off);
  u1b_tmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
  u1b_tmp &= ~BIT(7);
  rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1b_tmp);
  mutex_unlock(rtlpriv->mutex_for_power_on_off);
 }

 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<=======\n");
}

void rtl92du_card_disable(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 enum nl80211_iftype opmode;
 u32 val32;
 u16 val16;
 u8 val8;

 mac->link_state = MAC80211_NOLINK;
 opmode = NL80211_IFTYPE_UNSPECIFIED;
 _rtl92du_set_media_status(hw, opmode);

 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 /* Power sequence for each MAC. */
 /* a. stop tx DMA  */
 /* b. close RF */
 /* c. clear rx buf */
 /* d. stop rx DMA */
 /* e. reset MAC */

 val16 = rtl_read_word(rtlpriv, REG_GPIO_MUXCFG);
 val16 &= ~BIT(12);
 rtl_write_word(rtlpriv, REG_GPIO_MUXCFG, val16);

 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xff);
 udelay(500);
 rtl_write_byte(rtlpriv, REG_CR, 0);

 /* RF OFF sequence */
 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
 rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x00);

 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);

 val8 = FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTN;
 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, val8);

 /* Mac0 can not do Global reset. Mac1 can do. */
 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY ||
     rtlhal->interfaceindex == 1) {
  /* before BB reset should do clock gated */
  val32 = rtl_read_dword(rtlpriv, RFPGA0_XCD_RFPARAMETER);
  val32 |= BIT(31);
  rtl_write_dword(rtlpriv, RFPGA0_XCD_RFPARAMETER, val32);

  val8 &= ~FEN_BB_GLB_RSTN;
  rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, val8);
 }

 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==> Do power off.......\n");
 if (!rtl92du_phy_check_poweroff(hw))
  return;

 _rtl92du_poweroff_adapter(hw);
}

void rtl92du_set_beacon_related_registers(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 struct rtl_mac *mac = rtl_mac(rtlpriv);
 u16 bcn_interval, atim_window;

 bcn_interval = mac->beacon_interval;
 atim_window = 2;
 rtl92du_disable_interrupt(hw);
 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x20);
 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G)
  rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x30);
 else
  rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x20);
 rtl_write_byte(rtlpriv, 0x606, 0x30);
}

void rtl92du_set_beacon_interval(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);
 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 u16 bcn_interval = mac->beacon_interval;

 rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG,
  "beacon_interval:%d\n", bcn_interval);
 rtl92du_disable_interrupt(hw);
 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
 rtl92du_enable_interrupt(hw);
}

void rtl92du_update_interrupt_mask(struct ieee80211_hw *hw,
       u32 add_msr, u32 rm_msr)
{
 /* Nothing to do here. */
}

void rtl92du_read_chip_version(struct ieee80211_hw *hw)
{
 struct rtl_priv *rtlpriv = rtl_priv(hw);

 /* Chip version reading is done in rtl92d_read_eeprom_info. */

 rtlpriv->rtlhal.hw_type = HARDWARE_TYPE_RTL8192DU;
}

Messung V0.5
C=95 H=99 G=96

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge