drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
Extension
.c
Size
14181 bytes
Lines
596
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

struct brcmf_pno_info {
	int n_reqs;
	struct cfg80211_sched_scan_request *reqs[BRCMF_PNO_MAX_BUCKETS];
	struct mutex req_lock;
};

#define ifp_to_pno(_ifp)	((_ifp)->drvr->config->pno)

static int brcmf_pno_store_request(struct brcmf_pno_info *pi,
				   struct cfg80211_sched_scan_request *req)
{
	if (WARN(pi->n_reqs == BRCMF_PNO_MAX_BUCKETS,
		 "pno request storage full\n"))
		return -ENOSPC;

	brcmf_dbg(SCAN, "reqid=%llu\n", req->reqid);
	mutex_lock(&pi->req_lock);
	pi->reqs[pi->n_reqs++] = req;
	mutex_unlock(&pi->req_lock);
	return 0;
}

static int brcmf_pno_remove_request(struct brcmf_pno_info *pi, u64 reqid)
{
	int i, err = 0;

	mutex_lock(&pi->req_lock);

	/* Nothing to do if we have no requests */
	if (pi->n_reqs == 0)
		goto done;

	/* find request */
	for (i = 0; i < pi->n_reqs; i++) {
		if (pi->reqs[i]->reqid == reqid)
			break;
	}
	/* request not found */
	if (WARN(i == pi->n_reqs, "reqid not found\n")) {
		err = -ENOENT;
		goto done;
	}

	brcmf_dbg(SCAN, "reqid=%llu\n", reqid);
	pi->n_reqs--;

	/* if last we are done */
	if (!pi->n_reqs || i == pi->n_reqs)
		goto done;

	/* fill the gap with remaining requests */
	while (i <= pi->n_reqs - 1) {
		pi->reqs[i] = pi->reqs[i + 1];
		i++;
	}

done:
	mutex_unlock(&pi->req_lock);
	return err;
}

static int brcmf_pno_channel_config(struct brcmf_if *ifp,
				    struct brcmf_pno_config_le *cfg)
{
	cfg->reporttype = 0;
	cfg->flags = 0;

	return brcmf_fil_iovar_data_set(ifp, "pfn_cfg", cfg, sizeof(*cfg));
}

static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
			    u32 mscan, u32 bestn)
{
	struct brcmf_pub *drvr = ifp->drvr;
	struct brcmf_pno_param_le pfn_param;
	u16 flags;
	u32 pfnmem;
	s32 err;

	memset(&pfn_param, 0, sizeof(pfn_param));
	pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);

	/* set extra pno params */
	flags = BIT(BRCMF_PNO_IMMEDIATE_SCAN_BIT) |
		BIT(BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
	pfn_param.repeat = BRCMF_PNO_REPEAT;
	pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;

	/* set up pno scan fr */
	pfn_param.scan_freq = cpu_to_le32(scan_freq);

Annotation

Implementation Notes