drivers/net/ethernet/freescale/fec_main.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/freescale/fec_main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/freescale/fec_main.c
Extension
.c
Size
148751 bytes
Lines
5685
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 fec_netdev_ops = {
	.ndo_open		= fec_enet_open,
	.ndo_stop		= fec_enet_close,
	.ndo_start_xmit		= fec_enet_start_xmit,
	.ndo_select_queue       = fec_enet_select_queue,
	.ndo_set_rx_mode	= set_multicast_list,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_tx_timeout		= fec_timeout,
	.ndo_set_mac_address	= fec_set_mac_address,
	.ndo_change_mtu		= fec_change_mtu,
	.ndo_eth_ioctl		= phy_do_ioctl_running,
	.ndo_set_features	= fec_set_features,
	.ndo_bpf		= fec_enet_bpf,
	.ndo_xdp_xmit		= fec_enet_xdp_xmit,
	.ndo_xsk_wakeup		= fec_enet_xsk_wakeup,
	.ndo_hwtstamp_get	= fec_hwtstamp_get,
	.ndo_hwtstamp_set	= fec_hwtstamp_set,
};

static const unsigned short offset_des_active_rxq[] = {
	FEC_R_DES_ACTIVE_0, FEC_R_DES_ACTIVE_1, FEC_R_DES_ACTIVE_2
};

static const unsigned short offset_des_active_txq[] = {
	FEC_X_DES_ACTIVE_0, FEC_X_DES_ACTIVE_1, FEC_X_DES_ACTIVE_2
};

 /*
  * XXX:  We need to clean up on failure exits here.
  *
  */
static int fec_enet_init(struct net_device *ndev)
{
	struct fec_enet_private *fep = netdev_priv(ndev);
	struct bufdesc *cbd_base;
	dma_addr_t bd_dma;
	int bd_size;
	unsigned int i;
	unsigned dsize = fep->bufdesc_ex ? sizeof(struct bufdesc_ex) :
			sizeof(struct bufdesc);
	unsigned dsize_log2 = __fls(dsize);
	int ret;

	WARN_ON(dsize != (1 << dsize_log2));
#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
	fep->tx_align = 0xf;
#else
	fep->tx_align = 0x3;
#endif
	fep->rx_pkts_itr = FEC_ITR_ICFT_DEFAULT;
	fep->tx_pkts_itr = FEC_ITR_ICFT_DEFAULT;
	fep->rx_time_itr = FEC_ITR_ICTT_DEFAULT;
	fep->tx_time_itr = FEC_ITR_ICTT_DEFAULT;

	/* Check mask of the streaming and coherent API */
	ret = dma_set_mask_and_coherent(&fep->pdev->dev, DMA_BIT_MASK(32));
	if (ret < 0) {
		dev_warn(&fep->pdev->dev, "No suitable DMA available\n");
		return ret;
	}

	ret = fec_enet_alloc_queue(ndev);
	if (ret)
		return ret;

	bd_size = (fep->total_tx_ring_size + fep->total_rx_ring_size) * dsize;

	/* Allocate memory for buffer descriptors. */
	cbd_base = fec_dmam_alloc(&fep->pdev->dev, bd_size, &bd_dma,
				  GFP_KERNEL);
	if (!cbd_base) {
		ret = -ENOMEM;
		goto free_queue_mem;
	}

	/* Get the Ethernet address */
	ret = fec_get_mac(ndev);
	if (ret)
		goto free_queue_mem;

	/* Set receive and transmit descriptor base. */
	for (i = 0; i < fep->num_rx_queues; i++) {
		struct fec_enet_priv_rx_q *rxq = fep->rx_queue[i];
		unsigned size = dsize * rxq->bd.ring_size;

		rxq->bd.qid = i;
		rxq->bd.base = cbd_base;
		rxq->bd.cur = cbd_base;
		rxq->bd.dma = bd_dma;
		rxq->bd.dsize = dsize;

Annotation

Implementation Notes