162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2012 Realtek Corporation.*/ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "../wifi.h" 562306a36Sopenharmony_ci#include "../pci.h" 662306a36Sopenharmony_ci#include "../base.h" 762306a36Sopenharmony_ci#include "../efuse.h" 862306a36Sopenharmony_ci#include "reg.h" 962306a36Sopenharmony_ci#include "def.h" 1062306a36Sopenharmony_ci#include "fw.h" 1162306a36Sopenharmony_ci#include "sw.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistatic bool _rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv) 1462306a36Sopenharmony_ci{ 1562306a36Sopenharmony_ci return (rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) ? 1662306a36Sopenharmony_ci true : false; 1762306a36Sopenharmony_ci} 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistatic void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable) 2062306a36Sopenharmony_ci{ 2162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2262306a36Sopenharmony_ci u8 tmp; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci if (enable) { 2562306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 2662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04); 2762306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); 2862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); 2962306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); 3062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); 3162306a36Sopenharmony_ci } else { 3262306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); 3362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); 3462306a36Sopenharmony_ci /* Reserved for fw extension. 3562306a36Sopenharmony_ci * 0x81[7] is used for mac0 status , 3662306a36Sopenharmony_ci * so don't write this reg here 3762306a36Sopenharmony_ci * rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);*/ 3862306a36Sopenharmony_ci } 3962306a36Sopenharmony_ci} 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic void _rtl92d_write_fw(struct ieee80211_hw *hw, 4262306a36Sopenharmony_ci enum version_8192d version, u8 *buffer, u32 size) 4362306a36Sopenharmony_ci{ 4462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 4662306a36Sopenharmony_ci u8 *bufferptr = buffer; 4762306a36Sopenharmony_ci u32 pagenums, remainsize; 4862306a36Sopenharmony_ci u32 page, offset; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); 5162306a36Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) 5262306a36Sopenharmony_ci rtl_fill_dummy(bufferptr, &size); 5362306a36Sopenharmony_ci pagenums = size / FW_8192D_PAGE_SIZE; 5462306a36Sopenharmony_ci remainsize = size % FW_8192D_PAGE_SIZE; 5562306a36Sopenharmony_ci if (pagenums > 8) 5662306a36Sopenharmony_ci pr_err("Page numbers should not greater then 8\n"); 5762306a36Sopenharmony_ci for (page = 0; page < pagenums; page++) { 5862306a36Sopenharmony_ci offset = page * FW_8192D_PAGE_SIZE; 5962306a36Sopenharmony_ci rtl_fw_page_write(hw, page, (bufferptr + offset), 6062306a36Sopenharmony_ci FW_8192D_PAGE_SIZE); 6162306a36Sopenharmony_ci } 6262306a36Sopenharmony_ci if (remainsize) { 6362306a36Sopenharmony_ci offset = pagenums * FW_8192D_PAGE_SIZE; 6462306a36Sopenharmony_ci page = pagenums; 6562306a36Sopenharmony_ci rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize); 6662306a36Sopenharmony_ci } 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7262306a36Sopenharmony_ci u32 counter = 0; 7362306a36Sopenharmony_ci u32 value32; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci do { 7662306a36Sopenharmony_ci value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); 7762306a36Sopenharmony_ci } while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) && 7862306a36Sopenharmony_ci (!(value32 & FWDL_CHKSUM_RPT))); 7962306a36Sopenharmony_ci if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) { 8062306a36Sopenharmony_ci pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n", 8162306a36Sopenharmony_ci value32); 8262306a36Sopenharmony_ci return -EIO; 8362306a36Sopenharmony_ci } 8462306a36Sopenharmony_ci value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); 8562306a36Sopenharmony_ci value32 |= MCUFWDL_RDY; 8662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); 8762306a36Sopenharmony_ci return 0; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_civoid rtl92d_firmware_selfreset(struct ieee80211_hw *hw) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 9362306a36Sopenharmony_ci u8 u1b_tmp; 9462306a36Sopenharmony_ci u8 delay = 100; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci /* Set (REG_HMETFR + 3) to 0x20 is reset 8051 */ 9762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); 9862306a36Sopenharmony_ci u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 9962306a36Sopenharmony_ci while (u1b_tmp & BIT(2)) { 10062306a36Sopenharmony_ci delay--; 10162306a36Sopenharmony_ci if (delay == 0) 10262306a36Sopenharmony_ci break; 10362306a36Sopenharmony_ci udelay(50); 10462306a36Sopenharmony_ci u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci WARN_ONCE((delay <= 0), "rtl8192de: 8051 reset failed!\n"); 10762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, 10862306a36Sopenharmony_ci "=====> 8051 reset success (%d)\n", delay); 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic int _rtl92d_fw_init(struct ieee80211_hw *hw) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11462306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 11562306a36Sopenharmony_ci u32 counter; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n"); 11862306a36Sopenharmony_ci /* polling for FW ready */ 11962306a36Sopenharmony_ci counter = 0; 12062306a36Sopenharmony_ci do { 12162306a36Sopenharmony_ci if (rtlhal->interfaceindex == 0) { 12262306a36Sopenharmony_ci if (rtl_read_byte(rtlpriv, FW_MAC0_READY) & 12362306a36Sopenharmony_ci MAC0_READY) { 12462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, 12562306a36Sopenharmony_ci "Polling FW ready success!! REG_MCUFWDL: 0x%x\n", 12662306a36Sopenharmony_ci rtl_read_byte(rtlpriv, 12762306a36Sopenharmony_ci FW_MAC0_READY)); 12862306a36Sopenharmony_ci return 0; 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci udelay(5); 13162306a36Sopenharmony_ci } else { 13262306a36Sopenharmony_ci if (rtl_read_byte(rtlpriv, FW_MAC1_READY) & 13362306a36Sopenharmony_ci MAC1_READY) { 13462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, 13562306a36Sopenharmony_ci "Polling FW ready success!! REG_MCUFWDL: 0x%x\n", 13662306a36Sopenharmony_ci rtl_read_byte(rtlpriv, 13762306a36Sopenharmony_ci FW_MAC1_READY)); 13862306a36Sopenharmony_ci return 0; 13962306a36Sopenharmony_ci } 14062306a36Sopenharmony_ci udelay(5); 14162306a36Sopenharmony_ci } 14262306a36Sopenharmony_ci } while (counter++ < POLLING_READY_TIMEOUT_COUNT); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci if (rtlhal->interfaceindex == 0) { 14562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, 14662306a36Sopenharmony_ci "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n", 14762306a36Sopenharmony_ci rtl_read_byte(rtlpriv, FW_MAC0_READY)); 14862306a36Sopenharmony_ci } else { 14962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, 15062306a36Sopenharmony_ci "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n", 15162306a36Sopenharmony_ci rtl_read_byte(rtlpriv, FW_MAC1_READY)); 15262306a36Sopenharmony_ci } 15362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, 15462306a36Sopenharmony_ci "Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", 15562306a36Sopenharmony_ci rtl_read_dword(rtlpriv, REG_MCUFWDL)); 15662306a36Sopenharmony_ci return -1; 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ciint rtl92d_download_fw(struct ieee80211_hw *hw) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 16262306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 16362306a36Sopenharmony_ci u8 *pfwheader; 16462306a36Sopenharmony_ci u8 *pfwdata; 16562306a36Sopenharmony_ci u32 fwsize; 16662306a36Sopenharmony_ci int err; 16762306a36Sopenharmony_ci enum version_8192d version = rtlhal->version; 16862306a36Sopenharmony_ci u8 value; 16962306a36Sopenharmony_ci u32 count; 17062306a36Sopenharmony_ci bool fw_downloaded = false, fwdl_in_process = false; 17162306a36Sopenharmony_ci unsigned long flags; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) 17462306a36Sopenharmony_ci return 1; 17562306a36Sopenharmony_ci fwsize = rtlhal->fwsize; 17662306a36Sopenharmony_ci pfwheader = rtlhal->pfirmware; 17762306a36Sopenharmony_ci pfwdata = rtlhal->pfirmware; 17862306a36Sopenharmony_ci rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader); 17962306a36Sopenharmony_ci rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader); 18062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 18162306a36Sopenharmony_ci "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n", 18262306a36Sopenharmony_ci rtlhal->fw_version, rtlhal->fw_subversion, 18362306a36Sopenharmony_ci GET_FIRMWARE_HDR_SIGNATURE(pfwheader)); 18462306a36Sopenharmony_ci if (IS_FW_HEADER_EXIST(pfwheader)) { 18562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 18662306a36Sopenharmony_ci "Shift 32 bytes for FW header!!\n"); 18762306a36Sopenharmony_ci pfwdata = pfwdata + 32; 18862306a36Sopenharmony_ci fwsize = fwsize - 32; 18962306a36Sopenharmony_ci } 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci spin_lock_irqsave(&globalmutex_for_fwdownload, flags); 19262306a36Sopenharmony_ci fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv); 19362306a36Sopenharmony_ci if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5)) 19462306a36Sopenharmony_ci fwdl_in_process = true; 19562306a36Sopenharmony_ci else 19662306a36Sopenharmony_ci fwdl_in_process = false; 19762306a36Sopenharmony_ci if (fw_downloaded) { 19862306a36Sopenharmony_ci spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); 19962306a36Sopenharmony_ci goto exit; 20062306a36Sopenharmony_ci } else if (fwdl_in_process) { 20162306a36Sopenharmony_ci spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); 20262306a36Sopenharmony_ci for (count = 0; count < 5000; count++) { 20362306a36Sopenharmony_ci udelay(500); 20462306a36Sopenharmony_ci spin_lock_irqsave(&globalmutex_for_fwdownload, flags); 20562306a36Sopenharmony_ci fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv); 20662306a36Sopenharmony_ci if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5)) 20762306a36Sopenharmony_ci fwdl_in_process = true; 20862306a36Sopenharmony_ci else 20962306a36Sopenharmony_ci fwdl_in_process = false; 21062306a36Sopenharmony_ci spin_unlock_irqrestore(&globalmutex_for_fwdownload, 21162306a36Sopenharmony_ci flags); 21262306a36Sopenharmony_ci if (fw_downloaded) 21362306a36Sopenharmony_ci goto exit; 21462306a36Sopenharmony_ci else if (!fwdl_in_process) 21562306a36Sopenharmony_ci break; 21662306a36Sopenharmony_ci else 21762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, 21862306a36Sopenharmony_ci "Wait for another mac download fw\n"); 21962306a36Sopenharmony_ci } 22062306a36Sopenharmony_ci spin_lock_irqsave(&globalmutex_for_fwdownload, flags); 22162306a36Sopenharmony_ci value = rtl_read_byte(rtlpriv, 0x1f); 22262306a36Sopenharmony_ci value |= BIT(5); 22362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x1f, value); 22462306a36Sopenharmony_ci spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); 22562306a36Sopenharmony_ci } else { 22662306a36Sopenharmony_ci value = rtl_read_byte(rtlpriv, 0x1f); 22762306a36Sopenharmony_ci value |= BIT(5); 22862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x1f, value); 22962306a36Sopenharmony_ci spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); 23062306a36Sopenharmony_ci } 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci /* If 8051 is running in RAM code, driver should 23362306a36Sopenharmony_ci * inform Fw to reset by itself, or it will cause 23462306a36Sopenharmony_ci * download Fw fail.*/ 23562306a36Sopenharmony_ci /* 8051 RAM code */ 23662306a36Sopenharmony_ci if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { 23762306a36Sopenharmony_ci rtl92d_firmware_selfreset(hw); 23862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); 23962306a36Sopenharmony_ci } 24062306a36Sopenharmony_ci _rtl92d_enable_fw_download(hw, true); 24162306a36Sopenharmony_ci _rtl92d_write_fw(hw, version, pfwdata, fwsize); 24262306a36Sopenharmony_ci _rtl92d_enable_fw_download(hw, false); 24362306a36Sopenharmony_ci spin_lock_irqsave(&globalmutex_for_fwdownload, flags); 24462306a36Sopenharmony_ci err = _rtl92d_fw_free_to_go(hw); 24562306a36Sopenharmony_ci /* download fw over,clear 0x1f[5] */ 24662306a36Sopenharmony_ci value = rtl_read_byte(rtlpriv, 0x1f); 24762306a36Sopenharmony_ci value &= (~BIT(5)); 24862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x1f, value); 24962306a36Sopenharmony_ci spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); 25062306a36Sopenharmony_ci if (err) 25162306a36Sopenharmony_ci pr_err("fw is not ready to run!\n"); 25262306a36Sopenharmony_ciexit: 25362306a36Sopenharmony_ci err = _rtl92d_fw_init(hw); 25462306a36Sopenharmony_ci return err; 25562306a36Sopenharmony_ci} 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cistatic bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) 25862306a36Sopenharmony_ci{ 25962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 26062306a36Sopenharmony_ci u8 val_hmetfr; 26162306a36Sopenharmony_ci bool result = false; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); 26462306a36Sopenharmony_ci if (((val_hmetfr >> boxnum) & BIT(0)) == 0) 26562306a36Sopenharmony_ci result = true; 26662306a36Sopenharmony_ci return result; 26762306a36Sopenharmony_ci} 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_cistatic void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, 27062306a36Sopenharmony_ci u8 element_id, u32 cmd_len, u8 *cmdbuffer) 27162306a36Sopenharmony_ci{ 27262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 27362306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 27462306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 27562306a36Sopenharmony_ci u8 boxnum; 27662306a36Sopenharmony_ci u16 box_reg = 0, box_extreg = 0; 27762306a36Sopenharmony_ci u8 u1b_tmp; 27862306a36Sopenharmony_ci bool isfw_read = false; 27962306a36Sopenharmony_ci u8 buf_index = 0; 28062306a36Sopenharmony_ci bool bwrite_success = false; 28162306a36Sopenharmony_ci u8 wait_h2c_limmit = 100; 28262306a36Sopenharmony_ci u8 wait_writeh2c_limmit = 100; 28362306a36Sopenharmony_ci u8 boxcontent[4], boxextcontent[2]; 28462306a36Sopenharmony_ci u32 h2c_waitcounter = 0; 28562306a36Sopenharmony_ci unsigned long flag; 28662306a36Sopenharmony_ci u8 idx; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) { 28962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 29062306a36Sopenharmony_ci "Return as RF is off!!!\n"); 29162306a36Sopenharmony_ci return; 29262306a36Sopenharmony_ci } 29362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); 29462306a36Sopenharmony_ci while (true) { 29562306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); 29662306a36Sopenharmony_ci if (rtlhal->h2c_setinprogress) { 29762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 29862306a36Sopenharmony_ci "H2C set in progress! Wait to set..element_id(%d)\n", 29962306a36Sopenharmony_ci element_id); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci while (rtlhal->h2c_setinprogress) { 30262306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, 30362306a36Sopenharmony_ci flag); 30462306a36Sopenharmony_ci h2c_waitcounter++; 30562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 30662306a36Sopenharmony_ci "Wait 100 us (%d times)...\n", 30762306a36Sopenharmony_ci h2c_waitcounter); 30862306a36Sopenharmony_ci udelay(100); 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci if (h2c_waitcounter > 1000) 31162306a36Sopenharmony_ci return; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.h2c_lock, 31462306a36Sopenharmony_ci flag); 31562306a36Sopenharmony_ci } 31662306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); 31762306a36Sopenharmony_ci } else { 31862306a36Sopenharmony_ci rtlhal->h2c_setinprogress = true; 31962306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); 32062306a36Sopenharmony_ci break; 32162306a36Sopenharmony_ci } 32262306a36Sopenharmony_ci } 32362306a36Sopenharmony_ci while (!bwrite_success) { 32462306a36Sopenharmony_ci wait_writeh2c_limmit--; 32562306a36Sopenharmony_ci if (wait_writeh2c_limmit == 0) { 32662306a36Sopenharmony_ci pr_err("Write H2C fail because no trigger for FW INT!\n"); 32762306a36Sopenharmony_ci break; 32862306a36Sopenharmony_ci } 32962306a36Sopenharmony_ci boxnum = rtlhal->last_hmeboxnum; 33062306a36Sopenharmony_ci switch (boxnum) { 33162306a36Sopenharmony_ci case 0: 33262306a36Sopenharmony_ci box_reg = REG_HMEBOX_0; 33362306a36Sopenharmony_ci box_extreg = REG_HMEBOX_EXT_0; 33462306a36Sopenharmony_ci break; 33562306a36Sopenharmony_ci case 1: 33662306a36Sopenharmony_ci box_reg = REG_HMEBOX_1; 33762306a36Sopenharmony_ci box_extreg = REG_HMEBOX_EXT_1; 33862306a36Sopenharmony_ci break; 33962306a36Sopenharmony_ci case 2: 34062306a36Sopenharmony_ci box_reg = REG_HMEBOX_2; 34162306a36Sopenharmony_ci box_extreg = REG_HMEBOX_EXT_2; 34262306a36Sopenharmony_ci break; 34362306a36Sopenharmony_ci case 3: 34462306a36Sopenharmony_ci box_reg = REG_HMEBOX_3; 34562306a36Sopenharmony_ci box_extreg = REG_HMEBOX_EXT_3; 34662306a36Sopenharmony_ci break; 34762306a36Sopenharmony_ci default: 34862306a36Sopenharmony_ci pr_err("switch case %#x not processed\n", 34962306a36Sopenharmony_ci boxnum); 35062306a36Sopenharmony_ci break; 35162306a36Sopenharmony_ci } 35262306a36Sopenharmony_ci isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); 35362306a36Sopenharmony_ci while (!isfw_read) { 35462306a36Sopenharmony_ci wait_h2c_limmit--; 35562306a36Sopenharmony_ci if (wait_h2c_limmit == 0) { 35662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 35762306a36Sopenharmony_ci "Waiting too long for FW read clear HMEBox(%d)!\n", 35862306a36Sopenharmony_ci boxnum); 35962306a36Sopenharmony_ci break; 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci udelay(10); 36262306a36Sopenharmony_ci isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); 36362306a36Sopenharmony_ci u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); 36462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 36562306a36Sopenharmony_ci "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", 36662306a36Sopenharmony_ci boxnum, u1b_tmp); 36762306a36Sopenharmony_ci } 36862306a36Sopenharmony_ci if (!isfw_read) { 36962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 37062306a36Sopenharmony_ci "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n", 37162306a36Sopenharmony_ci boxnum); 37262306a36Sopenharmony_ci break; 37362306a36Sopenharmony_ci } 37462306a36Sopenharmony_ci memset(boxcontent, 0, sizeof(boxcontent)); 37562306a36Sopenharmony_ci memset(boxextcontent, 0, sizeof(boxextcontent)); 37662306a36Sopenharmony_ci boxcontent[0] = element_id; 37762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 37862306a36Sopenharmony_ci "Write element_id box_reg(%4x) = %2x\n", 37962306a36Sopenharmony_ci box_reg, element_id); 38062306a36Sopenharmony_ci switch (cmd_len) { 38162306a36Sopenharmony_ci case 1: 38262306a36Sopenharmony_ci boxcontent[0] &= ~(BIT(7)); 38362306a36Sopenharmony_ci memcpy(boxcontent + 1, cmdbuffer + buf_index, 1); 38462306a36Sopenharmony_ci for (idx = 0; idx < 4; idx++) 38562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, box_reg + idx, 38662306a36Sopenharmony_ci boxcontent[idx]); 38762306a36Sopenharmony_ci break; 38862306a36Sopenharmony_ci case 2: 38962306a36Sopenharmony_ci boxcontent[0] &= ~(BIT(7)); 39062306a36Sopenharmony_ci memcpy(boxcontent + 1, cmdbuffer + buf_index, 2); 39162306a36Sopenharmony_ci for (idx = 0; idx < 4; idx++) 39262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, box_reg + idx, 39362306a36Sopenharmony_ci boxcontent[idx]); 39462306a36Sopenharmony_ci break; 39562306a36Sopenharmony_ci case 3: 39662306a36Sopenharmony_ci boxcontent[0] &= ~(BIT(7)); 39762306a36Sopenharmony_ci memcpy(boxcontent + 1, cmdbuffer + buf_index, 3); 39862306a36Sopenharmony_ci for (idx = 0; idx < 4; idx++) 39962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, box_reg + idx, 40062306a36Sopenharmony_ci boxcontent[idx]); 40162306a36Sopenharmony_ci break; 40262306a36Sopenharmony_ci case 4: 40362306a36Sopenharmony_ci boxcontent[0] |= (BIT(7)); 40462306a36Sopenharmony_ci memcpy(boxextcontent, cmdbuffer + buf_index, 2); 40562306a36Sopenharmony_ci memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 2); 40662306a36Sopenharmony_ci for (idx = 0; idx < 2; idx++) 40762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, box_extreg + idx, 40862306a36Sopenharmony_ci boxextcontent[idx]); 40962306a36Sopenharmony_ci for (idx = 0; idx < 4; idx++) 41062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, box_reg + idx, 41162306a36Sopenharmony_ci boxcontent[idx]); 41262306a36Sopenharmony_ci break; 41362306a36Sopenharmony_ci case 5: 41462306a36Sopenharmony_ci boxcontent[0] |= (BIT(7)); 41562306a36Sopenharmony_ci memcpy(boxextcontent, cmdbuffer + buf_index, 2); 41662306a36Sopenharmony_ci memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 3); 41762306a36Sopenharmony_ci for (idx = 0; idx < 2; idx++) 41862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, box_extreg + idx, 41962306a36Sopenharmony_ci boxextcontent[idx]); 42062306a36Sopenharmony_ci for (idx = 0; idx < 4; idx++) 42162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, box_reg + idx, 42262306a36Sopenharmony_ci boxcontent[idx]); 42362306a36Sopenharmony_ci break; 42462306a36Sopenharmony_ci default: 42562306a36Sopenharmony_ci pr_err("switch case %#x not processed\n", 42662306a36Sopenharmony_ci cmd_len); 42762306a36Sopenharmony_ci break; 42862306a36Sopenharmony_ci } 42962306a36Sopenharmony_ci bwrite_success = true; 43062306a36Sopenharmony_ci rtlhal->last_hmeboxnum = boxnum + 1; 43162306a36Sopenharmony_ci if (rtlhal->last_hmeboxnum == 4) 43262306a36Sopenharmony_ci rtlhal->last_hmeboxnum = 0; 43362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 43462306a36Sopenharmony_ci "pHalData->last_hmeboxnum = %d\n", 43562306a36Sopenharmony_ci rtlhal->last_hmeboxnum); 43662306a36Sopenharmony_ci } 43762306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); 43862306a36Sopenharmony_ci rtlhal->h2c_setinprogress = false; 43962306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); 44062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_civoid rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, 44462306a36Sopenharmony_ci u8 element_id, u32 cmd_len, u8 *cmdbuffer) 44562306a36Sopenharmony_ci{ 44662306a36Sopenharmony_ci u32 tmp_cmdbuf[2]; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci memset(tmp_cmdbuf, 0, 8); 44962306a36Sopenharmony_ci memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); 45062306a36Sopenharmony_ci _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); 45162306a36Sopenharmony_ci return; 45262306a36Sopenharmony_ci} 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_cistatic bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw, 45562306a36Sopenharmony_ci struct sk_buff *skb) 45662306a36Sopenharmony_ci{ 45762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 45862306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 45962306a36Sopenharmony_ci struct rtl8192_tx_ring *ring; 46062306a36Sopenharmony_ci struct rtl_tx_desc *pdesc; 46162306a36Sopenharmony_ci u8 idx = 0; 46262306a36Sopenharmony_ci unsigned long flags; 46362306a36Sopenharmony_ci struct sk_buff *pskb; 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci ring = &rtlpci->tx_ring[BEACON_QUEUE]; 46662306a36Sopenharmony_ci pskb = __skb_dequeue(&ring->queue); 46762306a36Sopenharmony_ci kfree_skb(pskb); 46862306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); 46962306a36Sopenharmony_ci pdesc = &ring->desc[idx]; 47062306a36Sopenharmony_ci /* discard output from call below */ 47162306a36Sopenharmony_ci rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN); 47262306a36Sopenharmony_ci rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); 47362306a36Sopenharmony_ci __skb_queue_tail(&ring->queue, skb); 47462306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); 47562306a36Sopenharmony_ci rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); 47662306a36Sopenharmony_ci return true; 47762306a36Sopenharmony_ci} 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci#define BEACON_PG 0 /*->1 */ 48062306a36Sopenharmony_ci#define PSPOLL_PG 2 48162306a36Sopenharmony_ci#define NULL_PG 3 48262306a36Sopenharmony_ci#define PROBERSP_PG 4 /*->5 */ 48362306a36Sopenharmony_ci#define TOTAL_RESERVED_PKT_LEN 768 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_cistatic u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { 48662306a36Sopenharmony_ci /* page 0 beacon */ 48762306a36Sopenharmony_ci 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 48862306a36Sopenharmony_ci 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, 48962306a36Sopenharmony_ci 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, 49062306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49162306a36Sopenharmony_ci 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, 49262306a36Sopenharmony_ci 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, 49362306a36Sopenharmony_ci 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, 49462306a36Sopenharmony_ci 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, 49562306a36Sopenharmony_ci 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, 49662306a36Sopenharmony_ci 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, 49762306a36Sopenharmony_ci 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50062306a36Sopenharmony_ci 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, 50162306a36Sopenharmony_ci 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci /* page 1 beacon */ 50562306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50762306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51062306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51362306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51562306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51762306a36Sopenharmony_ci 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, 51862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51962306a36Sopenharmony_ci 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52062306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci /* page 2 ps-poll */ 52362306a36Sopenharmony_ci 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, 52462306a36Sopenharmony_ci 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, 52562306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52762306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53062306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53362306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53562306a36Sopenharmony_ci 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, 53662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 53762306a36Sopenharmony_ci 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci /* page 3 null */ 54162306a36Sopenharmony_ci 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, 54262306a36Sopenharmony_ci 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, 54362306a36Sopenharmony_ci 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 54462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54562306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54762306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55062306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55362306a36Sopenharmony_ci 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, 55462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 55562306a36Sopenharmony_ci 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci /* page 4 probe_resp */ 55962306a36Sopenharmony_ci 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, 56062306a36Sopenharmony_ci 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, 56162306a36Sopenharmony_ci 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 56262306a36Sopenharmony_ci 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, 56362306a36Sopenharmony_ci 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, 56462306a36Sopenharmony_ci 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, 56562306a36Sopenharmony_ci 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, 56662306a36Sopenharmony_ci 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, 56762306a36Sopenharmony_ci 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, 56862306a36Sopenharmony_ci 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, 56962306a36Sopenharmony_ci 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57062306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57262306a36Sopenharmony_ci 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, 57362306a36Sopenharmony_ci 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci /* page 5 probe_resp */ 57762306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58062306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58362306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58562306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58762306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59062306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59362306a36Sopenharmony_ci}; 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_civoid rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) 59662306a36Sopenharmony_ci{ 59762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 59862306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 59962306a36Sopenharmony_ci struct sk_buff *skb = NULL; 60062306a36Sopenharmony_ci u32 totalpacketlen; 60162306a36Sopenharmony_ci bool rtstatus; 60262306a36Sopenharmony_ci u8 u1rsvdpageloc[3] = { 0 }; 60362306a36Sopenharmony_ci bool dlok = false; 60462306a36Sopenharmony_ci u8 *beacon; 60562306a36Sopenharmony_ci u8 *p_pspoll; 60662306a36Sopenharmony_ci u8 *nullfunc; 60762306a36Sopenharmony_ci u8 *p_probersp; 60862306a36Sopenharmony_ci /*--------------------------------------------------------- 60962306a36Sopenharmony_ci (1) beacon 61062306a36Sopenharmony_ci ---------------------------------------------------------*/ 61162306a36Sopenharmony_ci beacon = &reserved_page_packet[BEACON_PG * 128]; 61262306a36Sopenharmony_ci SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); 61362306a36Sopenharmony_ci SET_80211_HDR_ADDRESS3(beacon, mac->bssid); 61462306a36Sopenharmony_ci /*------------------------------------------------------- 61562306a36Sopenharmony_ci (2) ps-poll 61662306a36Sopenharmony_ci --------------------------------------------------------*/ 61762306a36Sopenharmony_ci p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; 61862306a36Sopenharmony_ci SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); 61962306a36Sopenharmony_ci SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); 62062306a36Sopenharmony_ci SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); 62162306a36Sopenharmony_ci SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG); 62262306a36Sopenharmony_ci /*-------------------------------------------------------- 62362306a36Sopenharmony_ci (3) null data 62462306a36Sopenharmony_ci ---------------------------------------------------------*/ 62562306a36Sopenharmony_ci nullfunc = &reserved_page_packet[NULL_PG * 128]; 62662306a36Sopenharmony_ci SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); 62762306a36Sopenharmony_ci SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); 62862306a36Sopenharmony_ci SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); 62962306a36Sopenharmony_ci SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG); 63062306a36Sopenharmony_ci /*--------------------------------------------------------- 63162306a36Sopenharmony_ci (4) probe response 63262306a36Sopenharmony_ci ----------------------------------------------------------*/ 63362306a36Sopenharmony_ci p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; 63462306a36Sopenharmony_ci SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); 63562306a36Sopenharmony_ci SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); 63662306a36Sopenharmony_ci SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); 63762306a36Sopenharmony_ci SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG); 63862306a36Sopenharmony_ci totalpacketlen = TOTAL_RESERVED_PKT_LEN; 63962306a36Sopenharmony_ci RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, 64062306a36Sopenharmony_ci "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", 64162306a36Sopenharmony_ci &reserved_page_packet[0], totalpacketlen); 64262306a36Sopenharmony_ci RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, 64362306a36Sopenharmony_ci "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", 64462306a36Sopenharmony_ci u1rsvdpageloc, 3); 64562306a36Sopenharmony_ci skb = dev_alloc_skb(totalpacketlen); 64662306a36Sopenharmony_ci if (!skb) { 64762306a36Sopenharmony_ci dlok = false; 64862306a36Sopenharmony_ci } else { 64962306a36Sopenharmony_ci skb_put_data(skb, &reserved_page_packet, totalpacketlen); 65062306a36Sopenharmony_ci rtstatus = _rtl92d_cmd_send_packet(hw, skb); 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci if (rtstatus) 65362306a36Sopenharmony_ci dlok = true; 65462306a36Sopenharmony_ci } 65562306a36Sopenharmony_ci if (dlok) { 65662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 65762306a36Sopenharmony_ci "Set RSVD page location to Fw\n"); 65862306a36Sopenharmony_ci RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, 65962306a36Sopenharmony_ci "H2C_RSVDPAGE", u1rsvdpageloc, 3); 66062306a36Sopenharmony_ci rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE, 66162306a36Sopenharmony_ci sizeof(u1rsvdpageloc), u1rsvdpageloc); 66262306a36Sopenharmony_ci } else 66362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 66462306a36Sopenharmony_ci "Set RSVD page location to Fw FAIL!!!!!!\n"); 66562306a36Sopenharmony_ci} 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_civoid rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) 66862306a36Sopenharmony_ci{ 66962306a36Sopenharmony_ci u8 u1_joinbssrpt_parm[1] = {0}; 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); 67262306a36Sopenharmony_ci rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); 67362306a36Sopenharmony_ci} 674