1f1d2b4d3SLarry Finger /****************************************************************************** 2f1d2b4d3SLarry Finger * 3f1d2b4d3SLarry Finger * Copyright(c) 2009-2014 Realtek Corporation. 4f1d2b4d3SLarry Finger * 5f1d2b4d3SLarry Finger * This program is free software; you can redistribute it and/or modify it 6f1d2b4d3SLarry Finger * under the terms of version 2 of the GNU General Public License as 7f1d2b4d3SLarry Finger * published by the Free Software Foundation. 8f1d2b4d3SLarry Finger * 9f1d2b4d3SLarry Finger * This program is distributed in the hope that it will be useful, but WITHOUT 10f1d2b4d3SLarry Finger * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11f1d2b4d3SLarry Finger * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12f1d2b4d3SLarry Finger * more details. 13f1d2b4d3SLarry Finger * 14f1d2b4d3SLarry Finger * The full GNU General Public License is included in this distribution in the 15f1d2b4d3SLarry Finger * file called LICENSE. 16f1d2b4d3SLarry Finger * 17f1d2b4d3SLarry Finger * Contact Information: 18f1d2b4d3SLarry Finger * wlanfae <wlanfae@realtek.com> 19f1d2b4d3SLarry Finger * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, 20f1d2b4d3SLarry Finger * Hsinchu 300, Taiwan. 21f1d2b4d3SLarry Finger * 22f1d2b4d3SLarry Finger * Larry Finger <Larry.Finger@lwfinger.net> 23f1d2b4d3SLarry Finger * 24f1d2b4d3SLarry Finger *****************************************************************************/ 25f1d2b4d3SLarry Finger 26f1d2b4d3SLarry Finger #include "../wifi.h" 27f1d2b4d3SLarry Finger #include "../pci.h" 28f1d2b4d3SLarry Finger #include "../base.h" 29f1d2b4d3SLarry Finger #include "../core.h" 3089d32c90SLarry Finger #include "../efuse.h" 31f1d2b4d3SLarry Finger #include "reg.h" 32f1d2b4d3SLarry Finger #include "def.h" 33f1d2b4d3SLarry Finger #include "fw.h" 34f1d2b4d3SLarry Finger #include "dm.h" 35f1d2b4d3SLarry Finger 36f1d2b4d3SLarry Finger static void _rtl92ee_enable_fw_download(struct ieee80211_hw *hw, bool enable) 37f1d2b4d3SLarry Finger { 38f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 39f1d2b4d3SLarry Finger u8 tmp; 40f1d2b4d3SLarry Finger 41f1d2b4d3SLarry Finger if (enable) { 42f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x05); 43f1d2b4d3SLarry Finger 44f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); 45f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); 46f1d2b4d3SLarry Finger } else { 47f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); 48f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); 49f1d2b4d3SLarry Finger } 50f1d2b4d3SLarry Finger } 51f1d2b4d3SLarry Finger 52f1d2b4d3SLarry Finger static void _rtl92ee_write_fw(struct ieee80211_hw *hw, 53f1d2b4d3SLarry Finger enum version_8192e version, 54f1d2b4d3SLarry Finger u8 *buffer, u32 size) 55f1d2b4d3SLarry Finger { 56f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 57f1d2b4d3SLarry Finger u8 *bufferptr = (u8 *)buffer; 58f1d2b4d3SLarry Finger u32 pagenums, remainsize; 59f1d2b4d3SLarry Finger u32 page, offset; 60f1d2b4d3SLarry Finger 61f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "FW size is %d bytes,\n", size); 62f1d2b4d3SLarry Finger 6389d32c90SLarry Finger rtl_fill_dummy(bufferptr, &size); 64f1d2b4d3SLarry Finger 65f1d2b4d3SLarry Finger pagenums = size / FW_8192C_PAGE_SIZE; 66f1d2b4d3SLarry Finger remainsize = size % FW_8192C_PAGE_SIZE; 67f1d2b4d3SLarry Finger 68a44f59d6SLarry Finger if (pagenums > 8) 69a44f59d6SLarry Finger pr_err("Page numbers should not greater then 8\n"); 70f1d2b4d3SLarry Finger 71f1d2b4d3SLarry Finger for (page = 0; page < pagenums; page++) { 72f1d2b4d3SLarry Finger offset = page * FW_8192C_PAGE_SIZE; 7389d32c90SLarry Finger rtl_fw_page_write(hw, page, (bufferptr + offset), 74f1d2b4d3SLarry Finger FW_8192C_PAGE_SIZE); 75f1d2b4d3SLarry Finger udelay(2); 76f1d2b4d3SLarry Finger } 77f1d2b4d3SLarry Finger 78f1d2b4d3SLarry Finger if (remainsize) { 79f1d2b4d3SLarry Finger offset = pagenums * FW_8192C_PAGE_SIZE; 80f1d2b4d3SLarry Finger page = pagenums; 8189d32c90SLarry Finger rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize); 82f1d2b4d3SLarry Finger } 83f1d2b4d3SLarry Finger } 84f1d2b4d3SLarry Finger 85f1d2b4d3SLarry Finger static int _rtl92ee_fw_free_to_go(struct ieee80211_hw *hw) 86f1d2b4d3SLarry Finger { 87f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 88f1d2b4d3SLarry Finger int err = -EIO; 89f1d2b4d3SLarry Finger u32 counter = 0; 90f1d2b4d3SLarry Finger u32 value32; 91f1d2b4d3SLarry Finger 92f1d2b4d3SLarry Finger do { 93f1d2b4d3SLarry Finger value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); 94f1d2b4d3SLarry Finger } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && 95f1d2b4d3SLarry Finger (!(value32 & FWDL_CHKSUM_RPT))); 96f1d2b4d3SLarry Finger 97f1d2b4d3SLarry Finger if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { 98a44f59d6SLarry Finger pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n", 99f1d2b4d3SLarry Finger value32); 100f1d2b4d3SLarry Finger goto exit; 101f1d2b4d3SLarry Finger } 102f1d2b4d3SLarry Finger value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); 103f1d2b4d3SLarry Finger value32 |= MCUFWDL_RDY; 104f1d2b4d3SLarry Finger value32 &= ~WINTINI_RDY; 105f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); 106f1d2b4d3SLarry Finger 107f1d2b4d3SLarry Finger rtl92ee_firmware_selfreset(hw); 108f1d2b4d3SLarry Finger counter = 0; 109f1d2b4d3SLarry Finger 110f1d2b4d3SLarry Finger do { 111f1d2b4d3SLarry Finger value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); 112c93ac39dSLarry Finger if (value32 & WINTINI_RDY) 113c93ac39dSLarry Finger return 0; 114f1d2b4d3SLarry Finger 115f1d2b4d3SLarry Finger udelay(FW_8192C_POLLING_DELAY*10); 116f1d2b4d3SLarry Finger 117f1d2b4d3SLarry Finger } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); 118f1d2b4d3SLarry Finger 119a44f59d6SLarry Finger pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x. count = %d\n", 120f1d2b4d3SLarry Finger value32, counter); 121f1d2b4d3SLarry Finger 122f1d2b4d3SLarry Finger exit: 123f1d2b4d3SLarry Finger return err; 124f1d2b4d3SLarry Finger } 125f1d2b4d3SLarry Finger 126f1d2b4d3SLarry Finger int rtl92ee_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw) 127f1d2b4d3SLarry Finger { 128f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 129f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 130f1d2b4d3SLarry Finger struct rtlwifi_firmware_header *pfwheader; 131f1d2b4d3SLarry Finger u8 *pfwdata; 132f1d2b4d3SLarry Finger u32 fwsize; 133f1d2b4d3SLarry Finger int err; 134f1d2b4d3SLarry Finger enum version_8192e version = rtlhal->version; 135f1d2b4d3SLarry Finger 136f1d2b4d3SLarry Finger if (!rtlhal->pfirmware) 137f1d2b4d3SLarry Finger return 1; 138f1d2b4d3SLarry Finger 139f1d2b4d3SLarry Finger pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware; 140f1d2b4d3SLarry Finger rtlhal->fw_version = le16_to_cpu(pfwheader->version); 141f1d2b4d3SLarry Finger rtlhal->fw_subversion = pfwheader->subversion; 142f1d2b4d3SLarry Finger pfwdata = (u8 *)rtlhal->pfirmware; 143f1d2b4d3SLarry Finger fwsize = rtlhal->fwsize; 144f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 145f1d2b4d3SLarry Finger "normal Firmware SIZE %d\n" , fwsize); 146f1d2b4d3SLarry Finger 147f1d2b4d3SLarry Finger if (IS_FW_HEADER_EXIST(pfwheader)) { 148f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 149f1d2b4d3SLarry Finger "Firmware Version(%d), Signature(%#x),Size(%d)\n", 150f1d2b4d3SLarry Finger pfwheader->version, pfwheader->signature, 151f1d2b4d3SLarry Finger (int)sizeof(struct rtlwifi_firmware_header)); 152f1d2b4d3SLarry Finger 153f1d2b4d3SLarry Finger pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header); 154f1d2b4d3SLarry Finger fwsize = fwsize - sizeof(struct rtlwifi_firmware_header); 155f1d2b4d3SLarry Finger } else { 156f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 157f1d2b4d3SLarry Finger "Firmware no Header, Signature(%#x)\n", 158f1d2b4d3SLarry Finger pfwheader->signature); 159f1d2b4d3SLarry Finger } 160f1d2b4d3SLarry Finger 161f1d2b4d3SLarry Finger if (rtlhal->mac_func_enable) { 162f1d2b4d3SLarry Finger if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { 163f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); 164f1d2b4d3SLarry Finger rtl92ee_firmware_selfreset(hw); 165f1d2b4d3SLarry Finger } 166f1d2b4d3SLarry Finger } 167f1d2b4d3SLarry Finger _rtl92ee_enable_fw_download(hw, true); 168f1d2b4d3SLarry Finger _rtl92ee_write_fw(hw, version, pfwdata, fwsize); 169f1d2b4d3SLarry Finger _rtl92ee_enable_fw_download(hw, false); 170f1d2b4d3SLarry Finger 171f1d2b4d3SLarry Finger err = _rtl92ee_fw_free_to_go(hw); 172f1d2b4d3SLarry Finger 173f1d2b4d3SLarry Finger return 0; 174f1d2b4d3SLarry Finger } 175f1d2b4d3SLarry Finger 176f1d2b4d3SLarry Finger static bool _rtl92ee_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) 177f1d2b4d3SLarry Finger { 178f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 179f1d2b4d3SLarry Finger u8 val_hmetfr; 180f1d2b4d3SLarry Finger bool result = false; 181f1d2b4d3SLarry Finger 182f1d2b4d3SLarry Finger val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); 183f1d2b4d3SLarry Finger if (((val_hmetfr >> boxnum) & BIT(0)) == 0) 184f1d2b4d3SLarry Finger result = true; 185f1d2b4d3SLarry Finger return result; 186f1d2b4d3SLarry Finger } 187f1d2b4d3SLarry Finger 188f1d2b4d3SLarry Finger static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, 189f1d2b4d3SLarry Finger u32 cmd_len, u8 *cmdbuffer) 190f1d2b4d3SLarry Finger { 191f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 192f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 193f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 194f1d2b4d3SLarry Finger u8 boxnum; 195f1d2b4d3SLarry Finger u16 box_reg = 0, box_extreg = 0; 196f1d2b4d3SLarry Finger u8 u1b_tmp; 197f1d2b4d3SLarry Finger bool isfw_read = false; 198f1d2b4d3SLarry Finger u8 buf_index = 0; 199f1d2b4d3SLarry Finger bool bwrite_sucess = false; 200f1d2b4d3SLarry Finger u8 wait_h2c_limmit = 100; 201f1d2b4d3SLarry Finger u8 boxcontent[4], boxextcontent[4]; 202f1d2b4d3SLarry Finger u32 h2c_waitcounter = 0; 203f1d2b4d3SLarry Finger unsigned long flag; 204f1d2b4d3SLarry Finger u8 idx; 205f1d2b4d3SLarry Finger 206f1d2b4d3SLarry Finger if (ppsc->dot11_psmode != EACTIVE || 207f1d2b4d3SLarry Finger ppsc->inactive_pwrstate == ERFOFF) { 208f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , 209f1d2b4d3SLarry Finger "FillH2CCommand8192E(): Return because RF is off!!!\n"); 210f1d2b4d3SLarry Finger return; 211f1d2b4d3SLarry Finger } 212f1d2b4d3SLarry Finger 213f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , "come in\n"); 214f1d2b4d3SLarry Finger 215f1d2b4d3SLarry Finger /* 1. Prevent race condition in setting H2C cmd. 216f1d2b4d3SLarry Finger * (copy from MgntActSet_RF_State().) 217f1d2b4d3SLarry Finger */ 218f1d2b4d3SLarry Finger while (true) { 219f1d2b4d3SLarry Finger spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); 220f1d2b4d3SLarry Finger if (rtlhal->h2c_setinprogress) { 221f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , 222f1d2b4d3SLarry Finger "H2C set in progress! Wait to set..element_id(%d).\n", 223f1d2b4d3SLarry Finger element_id); 224f1d2b4d3SLarry Finger 225f1d2b4d3SLarry Finger while (rtlhal->h2c_setinprogress) { 226f1d2b4d3SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, 227f1d2b4d3SLarry Finger flag); 228f1d2b4d3SLarry Finger h2c_waitcounter++; 229f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , 230f1d2b4d3SLarry Finger "Wait 100 us (%d times)...\n", 231f1d2b4d3SLarry Finger h2c_waitcounter); 232f1d2b4d3SLarry Finger udelay(100); 233f1d2b4d3SLarry Finger 234f1d2b4d3SLarry Finger if (h2c_waitcounter > 1000) 235f1d2b4d3SLarry Finger return; 236f1d2b4d3SLarry Finger spin_lock_irqsave(&rtlpriv->locks.h2c_lock, 237f1d2b4d3SLarry Finger flag); 238f1d2b4d3SLarry Finger } 239f1d2b4d3SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); 240f1d2b4d3SLarry Finger } else { 241f1d2b4d3SLarry Finger rtlhal->h2c_setinprogress = true; 242f1d2b4d3SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); 243f1d2b4d3SLarry Finger break; 244f1d2b4d3SLarry Finger } 245f1d2b4d3SLarry Finger } 246f1d2b4d3SLarry Finger 247f1d2b4d3SLarry Finger while (!bwrite_sucess) { 248f1d2b4d3SLarry Finger /* 2. Find the last BOX number which has been writen. */ 249f1d2b4d3SLarry Finger boxnum = rtlhal->last_hmeboxnum; 250f1d2b4d3SLarry Finger switch (boxnum) { 251f1d2b4d3SLarry Finger case 0: 252f1d2b4d3SLarry Finger box_reg = REG_HMEBOX_0; 253f1d2b4d3SLarry Finger box_extreg = REG_HMEBOX_EXT_0; 254f1d2b4d3SLarry Finger break; 255f1d2b4d3SLarry Finger case 1: 256f1d2b4d3SLarry Finger box_reg = REG_HMEBOX_1; 257f1d2b4d3SLarry Finger box_extreg = REG_HMEBOX_EXT_1; 258f1d2b4d3SLarry Finger break; 259f1d2b4d3SLarry Finger case 2: 260f1d2b4d3SLarry Finger box_reg = REG_HMEBOX_2; 261f1d2b4d3SLarry Finger box_extreg = REG_HMEBOX_EXT_2; 262f1d2b4d3SLarry Finger break; 263f1d2b4d3SLarry Finger case 3: 264f1d2b4d3SLarry Finger box_reg = REG_HMEBOX_3; 265f1d2b4d3SLarry Finger box_extreg = REG_HMEBOX_EXT_3; 266f1d2b4d3SLarry Finger break; 267f1d2b4d3SLarry Finger default: 268f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 269ad574889SJoe Perches "switch case %#x not processed\n", boxnum); 270f1d2b4d3SLarry Finger break; 271f1d2b4d3SLarry Finger } 272f1d2b4d3SLarry Finger 273f1d2b4d3SLarry Finger /* 3. Check if the box content is empty. */ 274f1d2b4d3SLarry Finger isfw_read = false; 275f1d2b4d3SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_CR); 276f1d2b4d3SLarry Finger 277f1d2b4d3SLarry Finger if (u1b_tmp != 0xea) { 278f1d2b4d3SLarry Finger isfw_read = true; 279f1d2b4d3SLarry Finger } else { 280f1d2b4d3SLarry Finger if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS) == 0xea || 281f1d2b4d3SLarry Finger rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY) == 0xea) 282f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_CFG1 + 3, 0xff); 283f1d2b4d3SLarry Finger } 284f1d2b4d3SLarry Finger 285f1d2b4d3SLarry Finger if (isfw_read) { 286f1d2b4d3SLarry Finger wait_h2c_limmit = 100; 287f1d2b4d3SLarry Finger isfw_read = _rtl92ee_check_fw_read_last_h2c(hw, boxnum); 288f1d2b4d3SLarry Finger while (!isfw_read) { 289f1d2b4d3SLarry Finger wait_h2c_limmit--; 290f1d2b4d3SLarry Finger if (wait_h2c_limmit == 0) { 291f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , 292f1d2b4d3SLarry Finger "Waiting too long for FW read clear HMEBox(%d)!!!\n", 293f1d2b4d3SLarry Finger boxnum); 294f1d2b4d3SLarry Finger break; 295f1d2b4d3SLarry Finger } 296f1d2b4d3SLarry Finger udelay(10); 297f1d2b4d3SLarry Finger isfw_read = 298f1d2b4d3SLarry Finger _rtl92ee_check_fw_read_last_h2c(hw, boxnum); 299f1d2b4d3SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, 0x130); 300f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , 301f1d2b4d3SLarry Finger "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n", 302f1d2b4d3SLarry Finger boxnum, u1b_tmp); 303f1d2b4d3SLarry Finger } 304f1d2b4d3SLarry Finger } 305f1d2b4d3SLarry Finger 306f1d2b4d3SLarry Finger /* If Fw has not read the last 307f1d2b4d3SLarry Finger * H2C cmd, break and give up this H2C. 308f1d2b4d3SLarry Finger */ 309f1d2b4d3SLarry Finger if (!isfw_read) { 310f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , 311f1d2b4d3SLarry Finger "Write H2C reg BOX[%d] fail,Fw don't read.\n", 312f1d2b4d3SLarry Finger boxnum); 313f1d2b4d3SLarry Finger break; 314f1d2b4d3SLarry Finger } 315f1d2b4d3SLarry Finger /* 4. Fill the H2C cmd into box */ 316f1d2b4d3SLarry Finger memset(boxcontent, 0, sizeof(boxcontent)); 317f1d2b4d3SLarry Finger memset(boxextcontent, 0, sizeof(boxextcontent)); 318f1d2b4d3SLarry Finger boxcontent[0] = element_id; 319f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , 320f1d2b4d3SLarry Finger "Write element_id box_reg(%4x) = %2x\n", 321f1d2b4d3SLarry Finger box_reg, element_id); 322f1d2b4d3SLarry Finger 323f1d2b4d3SLarry Finger switch (cmd_len) { 324f1d2b4d3SLarry Finger case 1: 325f1d2b4d3SLarry Finger case 2: 326f1d2b4d3SLarry Finger case 3: 327f1d2b4d3SLarry Finger /*boxcontent[0] &= ~(BIT(7));*/ 328f1d2b4d3SLarry Finger memcpy((u8 *)(boxcontent) + 1, 329f1d2b4d3SLarry Finger cmdbuffer + buf_index, cmd_len); 330f1d2b4d3SLarry Finger 331f1d2b4d3SLarry Finger for (idx = 0; idx < 4; idx++) { 332f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, box_reg + idx, 333f1d2b4d3SLarry Finger boxcontent[idx]); 334f1d2b4d3SLarry Finger } 335f1d2b4d3SLarry Finger break; 336f1d2b4d3SLarry Finger case 4: 337f1d2b4d3SLarry Finger case 5: 338f1d2b4d3SLarry Finger case 6: 339f1d2b4d3SLarry Finger case 7: 340f1d2b4d3SLarry Finger /*boxcontent[0] |= (BIT(7));*/ 341f1d2b4d3SLarry Finger memcpy((u8 *)(boxextcontent), 342f1d2b4d3SLarry Finger cmdbuffer + buf_index+3, cmd_len-3); 343f1d2b4d3SLarry Finger memcpy((u8 *)(boxcontent) + 1, 344f1d2b4d3SLarry Finger cmdbuffer + buf_index, 3); 345f1d2b4d3SLarry Finger 346f1d2b4d3SLarry Finger for (idx = 0; idx < 4; idx++) { 347f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, box_extreg + idx, 348f1d2b4d3SLarry Finger boxextcontent[idx]); 349f1d2b4d3SLarry Finger } 350f1d2b4d3SLarry Finger 351f1d2b4d3SLarry Finger for (idx = 0; idx < 4; idx++) { 352f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, box_reg + idx, 353f1d2b4d3SLarry Finger boxcontent[idx]); 354f1d2b4d3SLarry Finger } 355f1d2b4d3SLarry Finger break; 356f1d2b4d3SLarry Finger default: 357f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 358ad574889SJoe Perches "switch case %#x not processed\n", cmd_len); 359f1d2b4d3SLarry Finger break; 360f1d2b4d3SLarry Finger } 361f1d2b4d3SLarry Finger 362f1d2b4d3SLarry Finger bwrite_sucess = true; 363f1d2b4d3SLarry Finger 364f1d2b4d3SLarry Finger rtlhal->last_hmeboxnum = boxnum + 1; 365f1d2b4d3SLarry Finger if (rtlhal->last_hmeboxnum == 4) 366f1d2b4d3SLarry Finger rtlhal->last_hmeboxnum = 0; 367f1d2b4d3SLarry Finger 368f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , 369f1d2b4d3SLarry Finger "pHalData->last_hmeboxnum = %d\n", 370f1d2b4d3SLarry Finger rtlhal->last_hmeboxnum); 371f1d2b4d3SLarry Finger } 372f1d2b4d3SLarry Finger 373f1d2b4d3SLarry Finger spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); 374f1d2b4d3SLarry Finger rtlhal->h2c_setinprogress = false; 375f1d2b4d3SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); 376f1d2b4d3SLarry Finger 377f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , "go out\n"); 378f1d2b4d3SLarry Finger } 379f1d2b4d3SLarry Finger 380f1d2b4d3SLarry Finger void rtl92ee_fill_h2c_cmd(struct ieee80211_hw *hw, 381f1d2b4d3SLarry Finger u8 element_id, u32 cmd_len, u8 *cmdbuffer) 382f1d2b4d3SLarry Finger { 383f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 384f1d2b4d3SLarry Finger u32 tmp_cmdbuf[2]; 385f1d2b4d3SLarry Finger 386f1d2b4d3SLarry Finger if (!rtlhal->fw_ready) { 387531940f9SLarry Finger WARN_ONCE(true, 388531940f9SLarry Finger "rtl8192ee: error H2C cmd because of Fw download fail!!!\n"); 389f1d2b4d3SLarry Finger return; 390f1d2b4d3SLarry Finger } 391f1d2b4d3SLarry Finger 392f1d2b4d3SLarry Finger memset(tmp_cmdbuf, 0, 8); 393f1d2b4d3SLarry Finger memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); 394f1d2b4d3SLarry Finger _rtl92ee_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); 395f1d2b4d3SLarry Finger } 396f1d2b4d3SLarry Finger 397f1d2b4d3SLarry Finger void rtl92ee_firmware_selfreset(struct ieee80211_hw *hw) 398f1d2b4d3SLarry Finger { 399f1d2b4d3SLarry Finger u8 u1b_tmp; 400f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 401f1d2b4d3SLarry Finger 402f1d2b4d3SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); 403f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0)))); 404f1d2b4d3SLarry Finger 405f1d2b4d3SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 406f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2)))); 407f1d2b4d3SLarry Finger 408f1d2b4d3SLarry Finger udelay(50); 409f1d2b4d3SLarry Finger 410f1d2b4d3SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); 411f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0))); 412f1d2b4d3SLarry Finger 413f1d2b4d3SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 414f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2))); 415f1d2b4d3SLarry Finger 416f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD , 417f1d2b4d3SLarry Finger " _8051Reset92E(): 8051 reset success .\n"); 418f1d2b4d3SLarry Finger } 419f1d2b4d3SLarry Finger 420f1d2b4d3SLarry Finger void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) 421f1d2b4d3SLarry Finger { 422f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 423f1d2b4d3SLarry Finger u8 u1_h2c_set_pwrmode[H2C_92E_PWEMODE_LENGTH] = { 0 }; 424f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 425f1d2b4d3SLarry Finger u8 rlbm , power_state = 0; 426f1d2b4d3SLarry Finger 427f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD , "FW LPS mode = %d\n", mode); 428f1d2b4d3SLarry Finger 429f1d2b4d3SLarry Finger SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0)); 430f1d2b4d3SLarry Finger rlbm = 0;/*YJ,temp,120316. FW now not support RLBM=2.*/ 431f1d2b4d3SLarry Finger SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm); 432f1d2b4d3SLarry Finger SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 433f1d2b4d3SLarry Finger (rtlpriv->mac80211.p2p) ? 434f1d2b4d3SLarry Finger ppsc->smart_ps : 1); 435f1d2b4d3SLarry Finger SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, 436f1d2b4d3SLarry Finger ppsc->reg_max_lps_awakeintvl); 437f1d2b4d3SLarry Finger SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0); 438f1d2b4d3SLarry Finger if (mode == FW_PS_ACTIVE_MODE) 439f1d2b4d3SLarry Finger power_state |= FW_PWR_STATE_ACTIVE; 440f1d2b4d3SLarry Finger else 441f1d2b4d3SLarry Finger power_state |= FW_PWR_STATE_RF_OFF; 442f1d2b4d3SLarry Finger SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state); 443f1d2b4d3SLarry Finger 444f1d2b4d3SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, 445f1d2b4d3SLarry Finger "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n", 446f1d2b4d3SLarry Finger u1_h2c_set_pwrmode, H2C_92E_PWEMODE_LENGTH); 447f1d2b4d3SLarry Finger rtl92ee_fill_h2c_cmd(hw, H2C_92E_SETPWRMODE, H2C_92E_PWEMODE_LENGTH, 448f1d2b4d3SLarry Finger u1_h2c_set_pwrmode); 449f1d2b4d3SLarry Finger } 450f1d2b4d3SLarry Finger 451f1d2b4d3SLarry Finger void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus) 452f1d2b4d3SLarry Finger { 453f1d2b4d3SLarry Finger u8 parm[3] = { 0 , 0 , 0 }; 454f1d2b4d3SLarry Finger /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect 455f1d2b4d3SLarry Finger * bit1=0-->update Media Status to MACID 456f1d2b4d3SLarry Finger * bit1=1-->update Media Status from MACID to MACID_End 457f1d2b4d3SLarry Finger * parm[1]: MACID, if this is INFRA_STA, MacID = 0 458f1d2b4d3SLarry Finger * parm[2]: MACID_End 459f1d2b4d3SLarry Finger */ 460f1d2b4d3SLarry Finger 461f1d2b4d3SLarry Finger SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus); 462f1d2b4d3SLarry Finger SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0); 463f1d2b4d3SLarry Finger 464f1d2b4d3SLarry Finger rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm); 465f1d2b4d3SLarry Finger } 466f1d2b4d3SLarry Finger 467f1d2b4d3SLarry Finger #define BEACON_PG 0 /* ->1 */ 468f1d2b4d3SLarry Finger #define PSPOLL_PG 2 469f1d2b4d3SLarry Finger #define NULL_PG 3 470f1d2b4d3SLarry Finger #define PROBERSP_PG 4 /* ->5 */ 471*74a7dfbcSPing-Ke Shih #define QOS_NULL_PG 6 472*74a7dfbcSPing-Ke Shih #define BT_QOS_NULL_PG 7 473f1d2b4d3SLarry Finger 474*74a7dfbcSPing-Ke Shih #define TOTAL_RESERVED_PKT_LEN 1024 475f1d2b4d3SLarry Finger 476f1d2b4d3SLarry Finger static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { 477f1d2b4d3SLarry Finger /* page 0 beacon */ 478f1d2b4d3SLarry Finger 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 479f1d2b4d3SLarry Finger 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, 480f1d2b4d3SLarry Finger 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00, 481f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 482f1d2b4d3SLarry Finger 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65, 483f1d2b4d3SLarry Finger 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B, 484f1d2b4d3SLarry Finger 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06, 485f1d2b4d3SLarry Finger 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32, 486f1d2b4d3SLarry Finger 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 487f1d2b4d3SLarry Finger 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 488f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 489f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 490f1d2b4d3SLarry Finger 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C, 491f1d2b4d3SLarry Finger 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50, 492f1d2b4d3SLarry Finger 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 493f1d2b4d3SLarry Finger 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00, 494f1d2b4d3SLarry Finger 495f1d2b4d3SLarry Finger /* page 1 beacon */ 496f1d2b4d3SLarry Finger 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00, 497f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 498f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 499f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 500f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 501f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 502f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 503f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 504f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 505f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 506f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 507f1d2b4d3SLarry Finger 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, 508f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 509f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 510f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 511f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 512f1d2b4d3SLarry Finger 513f1d2b4d3SLarry Finger /* page 2 ps-poll */ 514f1d2b4d3SLarry Finger 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B, 515f1d2b4d3SLarry Finger 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, 516f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 517f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 518f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 519f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 520f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 521f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 522f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 523f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 524f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 525f1d2b4d3SLarry Finger 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, 526f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 527f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 528f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 529f1d2b4d3SLarry Finger 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 530f1d2b4d3SLarry Finger 531f1d2b4d3SLarry Finger /* page 3 null */ 532f1d2b4d3SLarry Finger 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B, 533f1d2b4d3SLarry Finger 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, 534f1d2b4d3SLarry Finger 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00, 535f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 536f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 537f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 538f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 539f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 540f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 541f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 542f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 543f1d2b4d3SLarry Finger 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, 544f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 545f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 546f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 547f1d2b4d3SLarry Finger 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 548f1d2b4d3SLarry Finger 549f1d2b4d3SLarry Finger /* page 4 probe_resp */ 550f1d2b4d3SLarry Finger 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, 551f1d2b4d3SLarry Finger 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, 552f1d2b4d3SLarry Finger 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 553f1d2b4d3SLarry Finger 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, 554f1d2b4d3SLarry Finger 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, 555f1d2b4d3SLarry Finger 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, 556f1d2b4d3SLarry Finger 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, 557f1d2b4d3SLarry Finger 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, 558f1d2b4d3SLarry Finger 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, 559f1d2b4d3SLarry Finger 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, 560f1d2b4d3SLarry Finger 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 561f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 562f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 563f1d2b4d3SLarry Finger 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, 564f1d2b4d3SLarry Finger 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 565f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 566f1d2b4d3SLarry Finger 567f1d2b4d3SLarry Finger /* page 5 probe_resp */ 568f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 569f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 570f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 571f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 572f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 573f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 574f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 575*74a7dfbcSPing-Ke Shih 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, 576*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 577*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 578*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 579*74a7dfbcSPing-Ke Shih 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 580*74a7dfbcSPing-Ke Shih 581*74a7dfbcSPing-Ke Shih /* page 6 qos null data */ 582*74a7dfbcSPing-Ke Shih 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7, 583*74a7dfbcSPing-Ke Shih 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, 584*74a7dfbcSPing-Ke Shih 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00, 585*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 586*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 587*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 588*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 589*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 590*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 591*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 592*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 593*74a7dfbcSPing-Ke Shih 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, 594*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 595*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 596*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 597*74a7dfbcSPing-Ke Shih 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 598*74a7dfbcSPing-Ke Shih 599*74a7dfbcSPing-Ke Shih /* page 7 BT-qos null data */ 600*74a7dfbcSPing-Ke Shih 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7, 601*74a7dfbcSPing-Ke Shih 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, 602*74a7dfbcSPing-Ke Shih 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00, 603*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 604*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 605*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 606*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 607*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 608*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 609*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 610*74a7dfbcSPing-Ke Shih 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 611f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 612f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 613f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 614f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 615f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 616f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 617f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 618f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 619f1d2b4d3SLarry Finger 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 620f1d2b4d3SLarry Finger }; 621f1d2b4d3SLarry Finger 622f1d2b4d3SLarry Finger void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) 623f1d2b4d3SLarry Finger { 624f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 625f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 626f1d2b4d3SLarry Finger struct sk_buff *skb = NULL; 627f1d2b4d3SLarry Finger 628f1d2b4d3SLarry Finger u32 totalpacketlen; 629f1d2b4d3SLarry Finger u8 u1rsvdpageloc[5] = { 0 }; 630f1d2b4d3SLarry Finger bool b_dlok = false; 631f1d2b4d3SLarry Finger 632f1d2b4d3SLarry Finger u8 *beacon; 633f1d2b4d3SLarry Finger u8 *p_pspoll; 634f1d2b4d3SLarry Finger u8 *nullfunc; 635f1d2b4d3SLarry Finger u8 *p_probersp; 636*74a7dfbcSPing-Ke Shih u8 *qosnull; 637*74a7dfbcSPing-Ke Shih u8 *btqosnull; 638f1d2b4d3SLarry Finger /*--------------------------------------------------------- 639f1d2b4d3SLarry Finger * (1) beacon 640f1d2b4d3SLarry Finger *--------------------------------------------------------- 641f1d2b4d3SLarry Finger */ 642f1d2b4d3SLarry Finger beacon = &reserved_page_packet[BEACON_PG * 128]; 643f1d2b4d3SLarry Finger SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); 644f1d2b4d3SLarry Finger SET_80211_HDR_ADDRESS3(beacon, mac->bssid); 645f1d2b4d3SLarry Finger 646f1d2b4d3SLarry Finger /*------------------------------------------------------- 647f1d2b4d3SLarry Finger * (2) ps-poll 648f1d2b4d3SLarry Finger *-------------------------------------------------------- 649f1d2b4d3SLarry Finger */ 650f1d2b4d3SLarry Finger p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; 651f1d2b4d3SLarry Finger SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); 652f1d2b4d3SLarry Finger SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); 653f1d2b4d3SLarry Finger SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); 654f1d2b4d3SLarry Finger 655f1d2b4d3SLarry Finger SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG); 656f1d2b4d3SLarry Finger 657f1d2b4d3SLarry Finger /*-------------------------------------------------------- 658f1d2b4d3SLarry Finger * (3) null data 659f1d2b4d3SLarry Finger *--------------------------------------------------------- 660f1d2b4d3SLarry Finger */ 661f1d2b4d3SLarry Finger nullfunc = &reserved_page_packet[NULL_PG * 128]; 662f1d2b4d3SLarry Finger SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); 663f1d2b4d3SLarry Finger SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); 664f1d2b4d3SLarry Finger SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); 665f1d2b4d3SLarry Finger 666f1d2b4d3SLarry Finger SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG); 667f1d2b4d3SLarry Finger 668f1d2b4d3SLarry Finger /*--------------------------------------------------------- 669f1d2b4d3SLarry Finger * (4) probe response 670f1d2b4d3SLarry Finger *---------------------------------------------------------- 671f1d2b4d3SLarry Finger */ 672f1d2b4d3SLarry Finger p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; 673f1d2b4d3SLarry Finger SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); 674f1d2b4d3SLarry Finger SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); 675f1d2b4d3SLarry Finger SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); 676f1d2b4d3SLarry Finger 677f1d2b4d3SLarry Finger SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG); 678f1d2b4d3SLarry Finger 679*74a7dfbcSPing-Ke Shih /*--------------------------------------------------------- 680*74a7dfbcSPing-Ke Shih * (5) QoS null data 681*74a7dfbcSPing-Ke Shih *---------------------------------------------------------- 682*74a7dfbcSPing-Ke Shih */ 683*74a7dfbcSPing-Ke Shih qosnull = &reserved_page_packet[QOS_NULL_PG * 128]; 684*74a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS1(qosnull, mac->bssid); 685*74a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr); 686*74a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS3(qosnull, mac->bssid); 687*74a7dfbcSPing-Ke Shih 688*74a7dfbcSPing-Ke Shih SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG); 689*74a7dfbcSPing-Ke Shih 690*74a7dfbcSPing-Ke Shih /*--------------------------------------------------------- 691*74a7dfbcSPing-Ke Shih * (6) BT QoS null data 692*74a7dfbcSPing-Ke Shih *---------------------------------------------------------- 693*74a7dfbcSPing-Ke Shih */ 694*74a7dfbcSPing-Ke Shih btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128]; 695*74a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid); 696*74a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr); 697*74a7dfbcSPing-Ke Shih SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid); 698*74a7dfbcSPing-Ke Shih 699*74a7dfbcSPing-Ke Shih SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG); 700*74a7dfbcSPing-Ke Shih 701f1d2b4d3SLarry Finger totalpacketlen = TOTAL_RESERVED_PKT_LEN; 702f1d2b4d3SLarry Finger 703f1d2b4d3SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD , 704f1d2b4d3SLarry Finger "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", 705f1d2b4d3SLarry Finger &reserved_page_packet[0], totalpacketlen); 706f1d2b4d3SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD , 707f1d2b4d3SLarry Finger "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", 708f1d2b4d3SLarry Finger u1rsvdpageloc, 3); 709f1d2b4d3SLarry Finger 710f1d2b4d3SLarry Finger skb = dev_alloc_skb(totalpacketlen); 711f1d2b4d3SLarry Finger memcpy((u8 *)skb_put(skb, totalpacketlen), 712f1d2b4d3SLarry Finger &reserved_page_packet, totalpacketlen); 713f1d2b4d3SLarry Finger 714f1d2b4d3SLarry Finger b_dlok = true; 715f1d2b4d3SLarry Finger 716f1d2b4d3SLarry Finger if (b_dlok) { 717f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD , 718f1d2b4d3SLarry Finger "Set RSVD page location to Fw.\n"); 719f1d2b4d3SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD , 720f1d2b4d3SLarry Finger "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3); 721f1d2b4d3SLarry Finger rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSVDPAGE, 722f1d2b4d3SLarry Finger sizeof(u1rsvdpageloc), u1rsvdpageloc); 723f1d2b4d3SLarry Finger } else { 724f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 725f1d2b4d3SLarry Finger "Set RSVD page location to Fw FAIL!!!!!!.\n"); 726f1d2b4d3SLarry Finger } 727f1d2b4d3SLarry Finger } 728f1d2b4d3SLarry Finger 729f1d2b4d3SLarry Finger /*Shoud check FW support p2p or not.*/ 730f1d2b4d3SLarry Finger static void rtl92ee_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow) 731f1d2b4d3SLarry Finger { 732f1d2b4d3SLarry Finger u8 u1_ctwindow_period[1] = {ctwindow}; 733f1d2b4d3SLarry Finger 734f1d2b4d3SLarry Finger rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period); 735f1d2b4d3SLarry Finger } 736f1d2b4d3SLarry Finger 737f1d2b4d3SLarry Finger void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) 738f1d2b4d3SLarry Finger { 739f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 740f1d2b4d3SLarry Finger struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); 741f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 742f1d2b4d3SLarry Finger struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info; 743f1d2b4d3SLarry Finger struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; 744f1d2b4d3SLarry Finger u8 i; 745f1d2b4d3SLarry Finger u16 ctwindow; 746f1d2b4d3SLarry Finger u32 start_time, tsf_low; 747f1d2b4d3SLarry Finger 748f1d2b4d3SLarry Finger switch (p2p_ps_state) { 749f1d2b4d3SLarry Finger case P2P_PS_DISABLE: 750f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_DISABLE\n"); 751f1d2b4d3SLarry Finger memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload)); 752f1d2b4d3SLarry Finger break; 753f1d2b4d3SLarry Finger case P2P_PS_ENABLE: 754f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_ENABLE\n"); 755f1d2b4d3SLarry Finger /* update CTWindow value. */ 756f1d2b4d3SLarry Finger if (p2pinfo->ctwindow > 0) { 757f1d2b4d3SLarry Finger p2p_ps_offload->ctwindow_en = 1; 758f1d2b4d3SLarry Finger ctwindow = p2pinfo->ctwindow; 759f1d2b4d3SLarry Finger rtl92ee_set_p2p_ctw_period_cmd(hw, ctwindow); 760f1d2b4d3SLarry Finger } 761f1d2b4d3SLarry Finger /* hw only support 2 set of NoA */ 762f1d2b4d3SLarry Finger for (i = 0 ; i < p2pinfo->noa_num ; i++) { 763f1d2b4d3SLarry Finger /* To control the register setting for which NOA*/ 764f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); 765f1d2b4d3SLarry Finger if (i == 0) 766f1d2b4d3SLarry Finger p2p_ps_offload->noa0_en = 1; 767f1d2b4d3SLarry Finger else 768f1d2b4d3SLarry Finger p2p_ps_offload->noa1_en = 1; 769f1d2b4d3SLarry Finger /* config P2P NoA Descriptor Register */ 770f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, 0x5E0, 771f1d2b4d3SLarry Finger p2pinfo->noa_duration[i]); 772f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, 0x5E4, 773f1d2b4d3SLarry Finger p2pinfo->noa_interval[i]); 774f1d2b4d3SLarry Finger 775f1d2b4d3SLarry Finger /*Get Current TSF value */ 776f1d2b4d3SLarry Finger tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); 777f1d2b4d3SLarry Finger 778f1d2b4d3SLarry Finger start_time = p2pinfo->noa_start_time[i]; 779f1d2b4d3SLarry Finger if (p2pinfo->noa_count_type[i] != 1) { 780f1d2b4d3SLarry Finger while (start_time <= (tsf_low + (50 * 1024))) { 781f1d2b4d3SLarry Finger start_time += p2pinfo->noa_interval[i]; 782f1d2b4d3SLarry Finger if (p2pinfo->noa_count_type[i] != 255) 783f1d2b4d3SLarry Finger p2pinfo->noa_count_type[i]--; 784f1d2b4d3SLarry Finger } 785f1d2b4d3SLarry Finger } 786f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, 0x5E8, start_time); 787f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, 0x5EC, 788f1d2b4d3SLarry Finger p2pinfo->noa_count_type[i]); 789f1d2b4d3SLarry Finger } 790f1d2b4d3SLarry Finger if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) { 791f1d2b4d3SLarry Finger /* rst p2p circuit */ 792f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4)); 793f1d2b4d3SLarry Finger p2p_ps_offload->offload_en = 1; 794f1d2b4d3SLarry Finger 795f1d2b4d3SLarry Finger if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { 796f1d2b4d3SLarry Finger p2p_ps_offload->role = 1; 797f1d2b4d3SLarry Finger p2p_ps_offload->allstasleep = 0; 798f1d2b4d3SLarry Finger } else { 799f1d2b4d3SLarry Finger p2p_ps_offload->role = 0; 800f1d2b4d3SLarry Finger } 801f1d2b4d3SLarry Finger p2p_ps_offload->discovery = 0; 802f1d2b4d3SLarry Finger } 803f1d2b4d3SLarry Finger break; 804f1d2b4d3SLarry Finger case P2P_PS_SCAN: 805f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_SCAN\n"); 806f1d2b4d3SLarry Finger p2p_ps_offload->discovery = 1; 807f1d2b4d3SLarry Finger break; 808f1d2b4d3SLarry Finger case P2P_PS_SCAN_DONE: 809f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_SCAN_DONE\n"); 810f1d2b4d3SLarry Finger p2p_ps_offload->discovery = 0; 811f1d2b4d3SLarry Finger p2pinfo->p2p_ps_state = P2P_PS_ENABLE; 812f1d2b4d3SLarry Finger break; 813f1d2b4d3SLarry Finger default: 814f1d2b4d3SLarry Finger break; 815f1d2b4d3SLarry Finger } 816f1d2b4d3SLarry Finger rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_OFFLOAD, 1, 817f1d2b4d3SLarry Finger (u8 *)p2p_ps_offload); 818f1d2b4d3SLarry Finger } 819f1d2b4d3SLarry Finger 820f1d2b4d3SLarry Finger static void _rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw, 821f1d2b4d3SLarry Finger u8 *cmd_buf, u8 cmd_len) 822f1d2b4d3SLarry Finger { 823f1d2b4d3SLarry Finger u8 rate = cmd_buf[0] & 0x3F; 824f1d2b4d3SLarry Finger bool collision_state = cmd_buf[3] & BIT(0); 825f1d2b4d3SLarry Finger 826f1d2b4d3SLarry Finger rtl92ee_dm_dynamic_arfb_select(hw, rate, collision_state); 827f1d2b4d3SLarry Finger } 828f1d2b4d3SLarry Finger 829cceb0a59SPing-Ke Shih void rtl92ee_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id, 830f1d2b4d3SLarry Finger u8 c2h_cmd_len, u8 *tmp_buf) 831f1d2b4d3SLarry Finger { 832f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 833f1d2b4d3SLarry Finger 834f1d2b4d3SLarry Finger switch (c2h_cmd_id) { 835f1d2b4d3SLarry Finger case C2H_8192E_DBG: 836f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, 837f1d2b4d3SLarry Finger "[C2H], C2H_8723BE_DBG!!\n"); 838f1d2b4d3SLarry Finger break; 839f1d2b4d3SLarry Finger case C2H_8192E_TXBF: 840f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, 841f1d2b4d3SLarry Finger "[C2H], C2H_8192E_TXBF!!\n"); 842f1d2b4d3SLarry Finger break; 843f1d2b4d3SLarry Finger case C2H_8192E_TX_REPORT: 844f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE , 845f1d2b4d3SLarry Finger "[C2H], C2H_8723BE_TX_REPORT!\n"); 846f1d2b4d3SLarry Finger break; 847f1d2b4d3SLarry Finger case C2H_8192E_BT_INFO: 848f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, 849f1d2b4d3SLarry Finger "[C2H], C2H_8723BE_BT_INFO!!\n"); 850f1d2b4d3SLarry Finger rtlpriv->btcoexist.btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf, 851f1d2b4d3SLarry Finger c2h_cmd_len); 852f1d2b4d3SLarry Finger break; 853f1d2b4d3SLarry Finger case C2H_8192E_BT_MP: 854f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, 855f1d2b4d3SLarry Finger "[C2H], C2H_8723BE_BT_MP!!\n"); 856f1d2b4d3SLarry Finger break; 857f1d2b4d3SLarry Finger case C2H_8192E_RA_RPT: 858f1d2b4d3SLarry Finger _rtl92ee_c2h_ra_report_handler(hw, tmp_buf, c2h_cmd_len); 859f1d2b4d3SLarry Finger break; 860f1d2b4d3SLarry Finger default: 861f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, 862f1d2b4d3SLarry Finger "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id); 863f1d2b4d3SLarry Finger break; 864f1d2b4d3SLarry Finger } 865f1d2b4d3SLarry Finger } 866f1d2b4d3SLarry Finger 867f1d2b4d3SLarry Finger void rtl92ee_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len) 868f1d2b4d3SLarry Finger { 869f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw); 870f1d2b4d3SLarry Finger u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0; 871f1d2b4d3SLarry Finger u8 *tmp_buf = NULL; 872f1d2b4d3SLarry Finger 873f1d2b4d3SLarry Finger c2h_cmd_id = buffer[0]; 874f1d2b4d3SLarry Finger c2h_cmd_seq = buffer[1]; 875f1d2b4d3SLarry Finger c2h_cmd_len = len - 2; 876f1d2b4d3SLarry Finger tmp_buf = buffer + 2; 877f1d2b4d3SLarry Finger 878f1d2b4d3SLarry Finger RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, 879f1d2b4d3SLarry Finger "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n", 880f1d2b4d3SLarry Finger c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len); 881f1d2b4d3SLarry Finger 882f1d2b4d3SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE, 883f1d2b4d3SLarry Finger "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len); 884f1d2b4d3SLarry Finger 885cceb0a59SPing-Ke Shih switch (c2h_cmd_id) { 886cceb0a59SPing-Ke Shih case C2H_8192E_BT_INFO: 887cceb0a59SPing-Ke Shih case C2H_8192E_BT_MP: 888cceb0a59SPing-Ke Shih rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf); 889cceb0a59SPing-Ke Shih break; 890cceb0a59SPing-Ke Shih default: 891cceb0a59SPing-Ke Shih rtl92ee_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len, 892cceb0a59SPing-Ke Shih tmp_buf); 893cceb0a59SPing-Ke Shih break; 894cceb0a59SPing-Ke Shih } 895f1d2b4d3SLarry Finger } 896