drivers/net/wireless/ath/wcn36xx/main.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/wcn36xx/main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/wcn36xx/main.c
Extension
.c
Size
47123 bytes
Lines
1691
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

if (wcn36xx_firmware_get_feat_caps(wcn->fw_feat_caps, i)) {
			wcn36xx_dbg(WCN36XX_DBG_MAC, "FW Cap %s\n",
				    wcn36xx_firmware_get_cap_name(i));
		}
	}
}

static int wcn36xx_start(struct ieee80211_hw *hw)
{
	struct wcn36xx *wcn = hw->priv;
	int ret;

	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac start\n");

	/* SMD initialization */
	ret = wcn36xx_smd_open(wcn);
	if (ret) {
		wcn36xx_err("Failed to open smd channel: %d\n", ret);
		goto out_err;
	}

	/* Allocate memory pools for Mgmt BD headers and Data BD headers */
	ret = wcn36xx_dxe_allocate_mem_pools(wcn);
	if (ret) {
		wcn36xx_err("Failed to alloc DXE mempool: %d\n", ret);
		goto out_smd_close;
	}

	ret = wcn36xx_dxe_alloc_ctl_blks(wcn);
	if (ret) {
		wcn36xx_err("Failed to alloc DXE ctl blocks: %d\n", ret);
		goto out_free_dxe_pool;
	}

	ret = wcn36xx_smd_load_nv(wcn);
	if (ret) {
		wcn36xx_err("Failed to push NV to chip\n");
		goto out_free_dxe_ctl;
	}

	ret = wcn36xx_smd_start(wcn);
	if (ret) {
		wcn36xx_err("Failed to start chip\n");
		goto out_free_dxe_ctl;
	}

	if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) {
		ret = wcn36xx_smd_feature_caps_exchange(wcn);
		if (ret)
			wcn36xx_warn("Exchange feature caps failed\n");
		else
			wcn36xx_feat_caps_info(wcn);
	}

	/* DMA channel initialization */
	ret = wcn36xx_dxe_init(wcn);
	if (ret) {
		wcn36xx_err("DXE init failed\n");
		goto out_smd_stop;
	}

	wcn36xx_debugfs_init(wcn);

	INIT_LIST_HEAD(&wcn->vif_list);
	spin_lock_init(&wcn->dxe_lock);
	spin_lock_init(&wcn->survey_lock);

	return 0;

out_smd_stop:
	wcn36xx_smd_stop(wcn);
out_free_dxe_ctl:
	wcn36xx_dxe_free_ctl_blks(wcn);
out_free_dxe_pool:
	wcn36xx_dxe_free_mem_pools(wcn);
out_smd_close:
	wcn36xx_smd_close(wcn);
out_err:
	return ret;
}

static void wcn36xx_stop(struct ieee80211_hw *hw, bool suspend)
{
	struct wcn36xx *wcn = hw->priv;

	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac stop\n");

	mutex_lock(&wcn->scan_lock);
	if (wcn->scan_req) {
		struct cfg80211_scan_info scan_info = {

Annotation

Implementation Notes