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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
Extension
.c
Size
38056 bytes
Lines
1577
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct net_device_ops brcmf_netdev_ops_pri = {
	.ndo_open = brcmf_netdev_open,
	.ndo_stop = brcmf_netdev_stop,
	.ndo_start_xmit = brcmf_netdev_start_xmit,
	.ndo_set_mac_address = brcmf_netdev_set_mac_address,
	.ndo_set_rx_mode = brcmf_netdev_set_multicast_list
};

int brcmf_net_attach(struct brcmf_if *ifp, bool locked)
{
	struct brcmf_pub *drvr = ifp->drvr;
	struct net_device *ndev;
	s32 err;

	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx,
		  ifp->mac_addr);
	ndev = ifp->ndev;

	/* set appropriate operations */
	ndev->netdev_ops = &brcmf_netdev_ops_pri;

	ndev->needed_headroom += drvr->hdrlen;
	ndev->ethtool_ops = &brcmf_ethtool_ops;

	/* set the mac address & netns */
	eth_hw_addr_set(ndev, ifp->mac_addr);
	dev_net_set(ndev, wiphy_net(cfg_to_wiphy(drvr->config)));

	INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
	INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable);

	if (locked)
		err = cfg80211_register_netdevice(ndev);
	else
		err = register_netdev(ndev);
	if (err != 0) {
		bphy_err(drvr, "couldn't register the net device\n");
		goto fail;
	}

	netif_carrier_off(ndev);

	ndev->priv_destructor = brcmf_cfg80211_free_vif;
	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
	return 0;

fail:
	drvr->iflist[ifp->bsscfgidx] = NULL;
	ndev->netdev_ops = NULL;
	return -EBADE;
}

void brcmf_net_detach(struct net_device *ndev, bool locked)
{
	if (ndev->reg_state == NETREG_REGISTERED) {
		if (locked)
			cfg80211_unregister_netdevice(ndev);
		else
			unregister_netdev(ndev);
	} else {
		brcmf_cfg80211_free_vif(ndev);
		free_netdev(ndev);
	}
}

static int brcmf_net_mon_open(struct net_device *ndev)
{
	struct brcmf_if *ifp = netdev_priv(ndev);
	struct brcmf_pub *drvr = ifp->drvr;
	u32 monitor;
	int err;

	brcmf_dbg(TRACE, "Enter\n");

	err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_MONITOR, &monitor);
	if (err) {
		bphy_err(drvr, "BRCMF_C_GET_MONITOR error (%d)\n", err);
		return err;
	} else if (monitor) {
		bphy_err(drvr, "Monitor mode is already enabled\n");
		return -EEXIST;
	}

	monitor = 3;
	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);
	if (err)
		bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);

	return err;
}

Annotation

Implementation Notes