drivers/net/ethernet/broadcom/bnge/bnge_netdev.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
Extension
.c
Size
84396 bytes
Lines
3480
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 bnge_netdev_ops = {
	.ndo_open		= bnge_open,
	.ndo_stop		= bnge_close,
	.ndo_start_xmit		= bnge_start_xmit,
	.ndo_get_stats64	= bnge_get_stats64,
	.ndo_features_check	= bnge_features_check,
};

static void bnge_init_mac_addr(struct bnge_dev *bd)
{
	eth_hw_addr_set(bd->netdev, bd->pf.mac_addr);
}

static void bnge_set_tpa_flags(struct bnge_dev *bd)
{
	struct bnge_net *bn = netdev_priv(bd->netdev);

	bn->priv_flags &= ~BNGE_NET_EN_TPA;

	if (bd->netdev->features & NETIF_F_LRO)
		bn->priv_flags |= BNGE_NET_EN_LRO;
	else if (bd->netdev->features & NETIF_F_GRO_HW)
		bn->priv_flags |= BNGE_NET_EN_GRO;
}

static void bnge_init_l2_fltr_tbl(struct bnge_net *bn)
{
	int i;

	for (i = 0; i < BNGE_L2_FLTR_HASH_SIZE; i++)
		INIT_HLIST_HEAD(&bn->l2_fltr_hash_tbl[i]);
	get_random_bytes(&bn->hash_seed, sizeof(bn->hash_seed));
}

void bnge_set_ring_params(struct bnge_dev *bd)
{
	struct bnge_net *bn = netdev_priv(bd->netdev);
	u32 ring_size, rx_size, rx_space, max_rx_cmpl;
	u32 agg_factor = 0, agg_ring_size = 0;

	/* 8 for CRC and VLAN */
	rx_size = SKB_DATA_ALIGN(bn->netdev->mtu + ETH_HLEN + NET_IP_ALIGN + 8);

	rx_space = rx_size + ALIGN(NET_SKB_PAD, 8) +
		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));

	ring_size = bn->rx_ring_size;
	bn->rx_agg_ring_size = 0;
	bn->rx_agg_nr_pages = 0;

	if (bn->priv_flags & BNGE_NET_EN_TPA)
		agg_factor = min_t(u32, 4, 65536 / BNGE_RX_PAGE_SIZE);

	bn->priv_flags &= ~BNGE_NET_EN_JUMBO;
	if (rx_space > PAGE_SIZE) {
		u32 jumbo_factor;

		bn->priv_flags |= BNGE_NET_EN_JUMBO;
		jumbo_factor = PAGE_ALIGN(bn->netdev->mtu - 40) >> PAGE_SHIFT;
		if (jumbo_factor > agg_factor)
			agg_factor = jumbo_factor;
	}
	if (agg_factor) {
		if (ring_size > BNGE_MAX_RX_DESC_CNT_JUM_ENA) {
			ring_size = BNGE_MAX_RX_DESC_CNT_JUM_ENA;
			netdev_warn(bn->netdev, "RX ring size reduced from %d to %d due to jumbo ring\n",
				    bn->rx_ring_size, ring_size);
			bn->rx_ring_size = ring_size;
		}
		agg_ring_size = ring_size * agg_factor;

		bn->rx_agg_nr_pages = bnge_adjust_pow_two(agg_ring_size,
							  RX_DESC_CNT);
		if (bn->rx_agg_nr_pages > MAX_RX_AGG_PAGES) {
			u32 tmp = agg_ring_size;

			bn->rx_agg_nr_pages = MAX_RX_AGG_PAGES;
			agg_ring_size = MAX_RX_AGG_PAGES * RX_DESC_CNT - 1;
			netdev_warn(bn->netdev, "RX agg ring size %d reduced to %d.\n",
				    tmp, agg_ring_size);
		}
		bn->rx_agg_ring_size = agg_ring_size;
		bn->rx_agg_ring_mask = (bn->rx_agg_nr_pages * RX_DESC_CNT) - 1;

		rx_size = max3(BNGE_DEFAULT_RX_COPYBREAK,
			       bn->rx_copybreak,
			       bn->netdev->cfg_pending->hds_thresh);
		rx_size = SKB_DATA_ALIGN(rx_size + NET_IP_ALIGN);
		rx_space = rx_size + NET_SKB_PAD +
			SKB_DATA_ALIGN(sizeof(struct skb_shared_info));

Annotation

Implementation Notes