brintos

brintos / linux-shallow public Read only

0
0
Text · 11.6 KiB · c8444a7 Raw
321 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 2009-2012  Realtek Corporation.*/3 4#include "../wifi.h"5#include "../pci.h"6#include "../base.h"7#include "../efuse.h"8#include "../rtl8192d/reg.h"9#include "../rtl8192d/def.h"10#include "../rtl8192d/fw_common.h"11#include "fw.h"12#include "sw.h"13 14int rtl92d_download_fw(struct ieee80211_hw *hw)15{16	struct rtl_priv *rtlpriv = rtl_priv(hw);17	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));18	u8 *pfwheader;19	u8 *pfwdata;20	u32 fwsize;21	int err;22	enum version_8192d version = rtlhal->version;23	u8 value;24	u32 count;25	bool fw_downloaded = false, fwdl_in_process = false;26	unsigned long flags;27 28	if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)29		return 1;30	fwsize = rtlhal->fwsize;31	pfwheader = rtlhal->pfirmware;32	pfwdata = rtlhal->pfirmware;33	rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);34	rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);35	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,36		"FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",37		rtlhal->fw_version, rtlhal->fw_subversion,38		GET_FIRMWARE_HDR_SIGNATURE(pfwheader));39	if (IS_FW_HEADER_EXIST(pfwheader)) {40		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,41			"Shift 32 bytes for FW header!!\n");42		pfwdata = pfwdata + 32;43		fwsize = fwsize - 32;44	}45 46	spin_lock_irqsave(&globalmutex_for_fwdownload, flags);47	fw_downloaded = rtl92d_is_fw_downloaded(rtlpriv);48	if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))49		fwdl_in_process = true;50	else51		fwdl_in_process = false;52	if (fw_downloaded) {53		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);54		goto exit;55	} else if (fwdl_in_process) {56		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);57		for (count = 0; count < 5000; count++) {58			udelay(500);59			spin_lock_irqsave(&globalmutex_for_fwdownload, flags);60			fw_downloaded = rtl92d_is_fw_downloaded(rtlpriv);61			if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))62				fwdl_in_process = true;63			else64				fwdl_in_process = false;65			spin_unlock_irqrestore(&globalmutex_for_fwdownload,66					       flags);67			if (fw_downloaded)68				goto exit;69			else if (!fwdl_in_process)70				break;71			else72				rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,73					"Wait for another mac download fw\n");74		}75		spin_lock_irqsave(&globalmutex_for_fwdownload, flags);76		value = rtl_read_byte(rtlpriv, 0x1f);77		value |= BIT(5);78		rtl_write_byte(rtlpriv, 0x1f, value);79		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);80	} else {81		value = rtl_read_byte(rtlpriv, 0x1f);82		value |= BIT(5);83		rtl_write_byte(rtlpriv, 0x1f, value);84		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);85	}86 87	/* If 8051 is running in RAM code, driver should88	 * inform Fw to reset by itself, or it will cause89	 * download Fw fail.*/90	/* 8051 RAM code */91	if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {92		rtl92d_firmware_selfreset(hw);93		rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);94	}95	rtl92d_enable_fw_download(hw, true);96	rtl92d_write_fw(hw, version, pfwdata, fwsize);97	rtl92d_enable_fw_download(hw, false);98	spin_lock_irqsave(&globalmutex_for_fwdownload, flags);99	err = rtl92d_fw_free_to_go(hw);100	/* download fw over,clear 0x1f[5] */101	value = rtl_read_byte(rtlpriv, 0x1f);102	value &= (~BIT(5));103	rtl_write_byte(rtlpriv, 0x1f, value);104	spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);105	if (err)106		pr_err("fw is not ready to run!\n");107exit:108	err = rtl92d_fw_init(hw);109	return err;110}111 112static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,113				    struct sk_buff *skb)114{115	struct rtl_priv *rtlpriv = rtl_priv(hw);116	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));117	struct rtl8192_tx_ring *ring;118	struct rtl_tx_desc *pdesc;119	u8 idx = 0;120	unsigned long flags;121	struct sk_buff *pskb;122 123	ring = &rtlpci->tx_ring[BEACON_QUEUE];124	pskb = __skb_dequeue(&ring->queue);125	kfree_skb(pskb);126	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);127	pdesc = &ring->desc[idx];128	/* discard output from call below */129	rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN);130	rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, skb);131	__skb_queue_tail(&ring->queue, skb);132	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);133	rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);134	return true;135}136 137#define BEACON_PG		0	/*->1 */138#define PSPOLL_PG		2139#define NULL_PG			3140#define PROBERSP_PG		4	/*->5 */141#define TOTAL_RESERVED_PKT_LEN	768142 143static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {144	/* page 0 beacon */145	0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,146	0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,147	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,148	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,149	0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,150	0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,151	0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,152	0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,153	0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,154	0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,155	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,156	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,157	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,158	0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,159	0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,160	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,161 162	/* page 1 beacon */163	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,164	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,165	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,166	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,167	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,168	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,169	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,170	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,171	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,172	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,173	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,174	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,175	0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,176	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,177	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,178	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,179 180	/* page 2  ps-poll */181	0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,182	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,183	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,184	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,185	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,186	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,187	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,188	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,189	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,190	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,191	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,192	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,193	0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,194	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,195	0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,196	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,197 198	/* page 3  null */199	0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,200	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,201	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,202	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,203	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,204	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,205	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,206	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,207	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,208	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,209	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,210	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,211	0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,212	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,213	0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,214	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,215 216	/* page 4  probe_resp */217	0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,218	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,219	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,220	0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,221	0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,222	0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,223	0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,224	0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,225	0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,226	0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,227	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,228	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,229	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,230	0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,231	0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,232	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,233 234	/* page 5  probe_resp */235	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,236	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,237	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,238	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,239	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,240	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,241	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,242	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,243	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,244	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,245	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,246	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,247	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,248	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,249	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,250	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,251};252 253void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)254{255	struct rtl_priv *rtlpriv = rtl_priv(hw);256	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));257	struct sk_buff *skb = NULL;258	u32 totalpacketlen;259	bool rtstatus;260	u8 u1rsvdpageloc[3] = { PROBERSP_PG, PSPOLL_PG, NULL_PG };261	bool dlok = false;262	u8 *beacon;263	u8 *p_pspoll;264	u8 *nullfunc;265	u8 *p_probersp;266	/*---------------------------------------------------------267						(1) beacon268	---------------------------------------------------------*/269	beacon = &reserved_page_packet[BEACON_PG * 128];270	SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);271	SET_80211_HDR_ADDRESS3(beacon, mac->bssid);272	/*-------------------------------------------------------273						(2) ps-poll274	--------------------------------------------------------*/275	p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];276	SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));277	SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);278	SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);279	/*--------------------------------------------------------280						(3) null data281	---------------------------------------------------------*/282	nullfunc = &reserved_page_packet[NULL_PG * 128];283	SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);284	SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);285	SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);286	/*---------------------------------------------------------287						(4) probe response288	----------------------------------------------------------*/289	p_probersp = &reserved_page_packet[PROBERSP_PG * 128];290	SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);291	SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);292	SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);293	totalpacketlen = TOTAL_RESERVED_PKT_LEN;294	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,295		      "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",296		      &reserved_page_packet[0], totalpacketlen);297	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,298		      "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",299		      u1rsvdpageloc, 3);300	skb = dev_alloc_skb(totalpacketlen);301	if (!skb) {302		dlok = false;303	} else {304		skb_put_data(skb, &reserved_page_packet, totalpacketlen);305		rtstatus = _rtl92d_cmd_send_packet(hw, skb);306 307		if (rtstatus)308			dlok = true;309	}310	if (dlok) {311		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,312			"Set RSVD page location to Fw\n");313		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,314			      "H2C_RSVDPAGE", u1rsvdpageloc, 3);315		rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,316			sizeof(u1rsvdpageloc), u1rsvdpageloc);317	} else318		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,319			"Set RSVD page location to Fw FAIL!!!!!!\n");320}321