brintos

brintos / linux-shallow public Read only

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