drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c
Extension
.c
Size
11897 bytes
Lines
321
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

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

#include "../wifi.h"
#include "../pci.h"
#include "../base.h"
#include "../efuse.h"
#include "../rtl8192d/reg.h"
#include "../rtl8192d/def.h"
#include "../rtl8192d/fw_common.h"
#include "fw.h"
#include "sw.h"

int rtl92d_download_fw(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	u8 *pfwheader;
	u8 *pfwdata;
	u32 fwsize;
	int err;
	enum version_8192d version = rtlhal->version;
	u8 value;
	u32 count;
	bool fw_downloaded = false, fwdl_in_process = false;
	unsigned long flags;

	if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
		return 1;
	fwsize = rtlhal->fwsize;
	pfwheader = rtlhal->pfirmware;
	pfwdata = rtlhal->pfirmware;
	rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
	rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
		"FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",
		rtlhal->fw_version, rtlhal->fw_subversion,
		GET_FIRMWARE_HDR_SIGNATURE(pfwheader));
	if (IS_FW_HEADER_EXIST(pfwheader)) {
		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
			"Shift 32 bytes for FW header!!\n");
		pfwdata = pfwdata + 32;
		fwsize = fwsize - 32;
	}

	spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
	fw_downloaded = rtl92d_is_fw_downloaded(rtlpriv);
	if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
		fwdl_in_process = true;
	else
		fwdl_in_process = false;
	if (fw_downloaded) {
		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
		goto exit;
	} else if (fwdl_in_process) {
		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
		for (count = 0; count < 5000; count++) {
			udelay(500);
			spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
			fw_downloaded = rtl92d_is_fw_downloaded(rtlpriv);
			if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
				fwdl_in_process = true;
			else
				fwdl_in_process = false;
			spin_unlock_irqrestore(&globalmutex_for_fwdownload,
					       flags);
			if (fw_downloaded)
				goto exit;
			else if (!fwdl_in_process)
				break;
			else
				rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
					"Wait for another mac download fw\n");
		}
		spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
		value = rtl_read_byte(rtlpriv, 0x1f);
		value |= BIT(5);
		rtl_write_byte(rtlpriv, 0x1f, value);
		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
	} else {
		value = rtl_read_byte(rtlpriv, 0x1f);
		value |= BIT(5);
		rtl_write_byte(rtlpriv, 0x1f, value);
		spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
	}

	/* If 8051 is running in RAM code, driver should
	 * inform Fw to reset by itself, or it will cause
	 * download Fw fail.*/
	/* 8051 RAM code */

Annotation

Implementation Notes