drivers/net/wireless/realtek/rtlwifi/core.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/realtek/rtlwifi/core.c
Extension
.c
Size
56028 bytes
Lines
1959
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (rtlpriv->cfg->alt_fw_name) {
			err = request_firmware(&firmware,
					       rtlpriv->cfg->alt_fw_name,
					       rtlpriv->io.dev);
			pr_info("Loading alternative firmware %s\n",
				rtlpriv->cfg->alt_fw_name);
			if (!err)
				goto found_alt;
		}
		pr_err("Selected firmware is not available\n");
		rtlpriv->max_fw_size = 0;
		goto exit;
	}
found_alt:
	if (firmware->size > rtlpriv->max_fw_size) {
		pr_err("Firmware is too big!\n");
		release_firmware(firmware);
		goto exit;
	}
	if (!is_wow) {
		memcpy(rtlpriv->rtlhal.pfirmware, firmware->data,
		       firmware->size);
		rtlpriv->rtlhal.fwsize = firmware->size;
	} else {
		memcpy(rtlpriv->rtlhal.wowlan_firmware, firmware->data,
		       firmware->size);
		rtlpriv->rtlhal.wowlan_fwsize = firmware->size;
	}
	release_firmware(firmware);

exit:
	complete(&rtlpriv->firmware_loading_complete);
}

void rtl_fw_cb(const struct firmware *firmware, void *context)
{
	rtl_fw_do_work(firmware, context, false);
}
EXPORT_SYMBOL(rtl_fw_cb);

void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context)
{
	rtl_fw_do_work(firmware, context, true);
}
EXPORT_SYMBOL(rtl_wowlan_fw_cb);

/*mutex for start & stop is must here. */
static int rtl_op_start(struct ieee80211_hw *hw)
{
	int err = 0;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));

	if (!is_hal_stop(rtlhal))
		return 0;
	if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
		return 0;
	mutex_lock(&rtlpriv->locks.conf_mutex);
	err = rtlpriv->intf_ops->adapter_start(hw);
	if (!err)
		rtl_watch_dog_timer_callback(&rtlpriv->works.watchdog_timer);
	mutex_unlock(&rtlpriv->locks.conf_mutex);
	return err;
}

static void rtl_op_stop(struct ieee80211_hw *hw, bool suspend)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
	bool support_remote_wakeup = false;

	if (is_hal_stop(rtlhal))
		return;

	rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
				      (u8 *)(&support_remote_wakeup));
	/* here is must, because adhoc do stop and start,
	 * but stop with RFOFF may cause something wrong,
	 * like adhoc TP
	 */
	if (unlikely(ppsc->rfpwr_state == ERFOFF))
		rtl_ips_nic_on(hw);

	mutex_lock(&rtlpriv->locks.conf_mutex);
	/* if wowlan supported, DON'T clear connected info */
	if (!(support_remote_wakeup &&
	      rtlhal->enter_pnp_sleep)) {
		mac->link_state = MAC80211_NOLINK;

Annotation

Implementation Notes