Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fba1400a authored by Arend van Spriel's avatar Arend van Spriel Committed by John W. Linville
Browse files

brcmfmac: add firmware-signalling cleanup function



Add a cleanup function releasing any queued packet buffers in
the mac descriptor entries.

Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: default avatarHante Meuleman <meuleman@broadcom.com>
Reviewed-by: default avatarPiotr Haber <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 43fa635e
Loading
Loading
Loading
Loading
+46 −5
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@ struct brcmf_fws_info {
	struct brcmf_pub *drvr;
	struct brcmf_fws_stats stats;
	struct brcmf_fws_mac_descriptor nodes[BRCMF_FWS_MAC_DESC_TABLE_SIZE];
	struct brcmf_fws_mac_descriptor other;
	int fifo_credit[NL80211_NUM_ACS+1+1];
};

@@ -264,6 +265,38 @@ brcmf_fws_mac_descriptor_lookup(struct brcmf_fws_info *fws, u8 *ea)
	return ERR_PTR(-ENOENT);
}

static void brcmf_fws_mac_desc_cleanup(struct brcmf_fws_mac_descriptor *entry,
				       bool (*fn)(struct sk_buff *, void *),
				       int ifidx)
{
	brcmf_dbg(TRACE, "enter: entry=(ea=%pM,ifid=%d), ifidx=%d\n",
		  entry->ea, entry->interface_id, ifidx);
	if (entry->occupied && (fn == NULL || (ifidx == entry->interface_id))) {
		brcmf_dbg(TRACE, "flush delayQ: ifidx=%d, qlen=%d\n",
			  ifidx, entry->psq.len);
		/* release packets held in DELAYQ */
		brcmu_pktq_flush(&entry->psq, true, fn, &ifidx);
		entry->occupied = !!(entry->psq.len);
	}
}

static void brcmf_fws_cleanup(struct brcmf_fws_info *fws, int ifidx)
{
	int i;
	struct brcmf_fws_mac_descriptor *table;

	brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
	if (fws == NULL)
		return;

	/* cleanup individual nodes */
	table = &fws->nodes[0];
	for (i = 0; i < ARRAY_SIZE(fws->nodes); i++)
		brcmf_fws_mac_desc_cleanup(&table[i], NULL, ifidx);

	brcmf_fws_mac_desc_cleanup(&fws->other, NULL, ifidx);
}

static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi)
{
	brcmf_dbg(CTL, "rssi %d\n", rssi);
@@ -394,12 +427,12 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
		goto fail;
	}

	/* set linkage back */
	drvr->fws->drvr = drvr;

	/* create debugfs file for statistics */
	brcmf_debugfs_create_fws_stats(drvr, &drvr->fws->stats);

	/* set linkage back */
	drvr->fws->drvr = drvr;

	/* TODO: remove upon feature delivery */
	brcmf_err("%s bdcv2 tlv signaling [%x]\n",
		  drvr->fw_signals ? "enabled" : "disabled", tlv);
@@ -414,9 +447,17 @@ int brcmf_fws_init(struct brcmf_pub *drvr)

void brcmf_fws_deinit(struct brcmf_pub *drvr)
{
	/* free top structure */
	kfree(drvr->fws);
	struct brcmf_fws_info *fws = drvr->fws;
	ulong flags;

	/* cleanup */
	brcmf_fws_lock(drvr, flags);
	brcmf_fws_cleanup(fws, -1);
	drvr->fws = NULL;
	brcmf_fws_unlock(drvr, flags);

	/* free top structure */
	kfree(fws);
}

int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,