drivers/net/ethernet/broadcom/tg3.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/broadcom/tg3.c
Extension
.c
Size
483310 bytes
Lines
18437
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 tg3_netdev_ops = {
	.ndo_open		= tg3_open,
	.ndo_stop		= tg3_close,
	.ndo_start_xmit		= tg3_start_xmit,
	.ndo_get_stats64	= tg3_get_stats64,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_rx_mode	= tg3_set_rx_mode,
	.ndo_set_mac_address	= tg3_set_mac_addr,
	.ndo_eth_ioctl		= tg3_ioctl,
	.ndo_tx_timeout		= tg3_tx_timeout,
	.ndo_change_mtu		= tg3_change_mtu,
	.ndo_fix_features	= tg3_fix_features,
	.ndo_set_features	= tg3_set_features,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= tg3_poll_controller,
#endif
	.ndo_hwtstamp_get	= tg3_hwtstamp_get,
	.ndo_hwtstamp_set	= tg3_hwtstamp_set,
};

static void tg3_get_eeprom_size(struct tg3 *tp)
{
	u32 cursize, val, magic;

	tp->nvram_size = EEPROM_CHIP_SIZE;

	if (tg3_nvram_read(tp, 0, &magic) != 0)
		return;

	if ((magic != TG3_EEPROM_MAGIC) &&
	    ((magic & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW) &&
	    ((magic & TG3_EEPROM_MAGIC_HW_MSK) != TG3_EEPROM_MAGIC_HW))
		return;

	/*
	 * Size the chip by reading offsets at increasing powers of two.
	 * When we encounter our validation signature, we know the addressing
	 * has wrapped around, and thus have our chip size.
	 */
	cursize = 0x10;

	while (cursize < tp->nvram_size) {
		if (tg3_nvram_read(tp, cursize, &val) != 0)
			return;

		if (val == magic)
			break;

		cursize <<= 1;
	}

	tp->nvram_size = cursize;
}

static void tg3_get_nvram_size(struct tg3 *tp)
{
	u32 val;

	if (tg3_flag(tp, NO_NVRAM) || tg3_nvram_read(tp, 0, &val) != 0)
		return;

	/* Selfboot format */
	if (val != TG3_EEPROM_MAGIC) {
		tg3_get_eeprom_size(tp);
		return;
	}

	if (tg3_nvram_read(tp, 0xf0, &val) == 0) {
		if (val != 0) {
			/* This is confusing.  We want to operate on the
			 * 16-bit value at offset 0xf2.  The tg3_nvram_read()
			 * call will read from NVRAM and byteswap the data
			 * according to the byteswapping settings for all
			 * other register accesses.  This ensures the data we
			 * want will always reside in the lower 16-bits.
			 * However, the data in NVRAM is in LE format, which
			 * means the data from the NVRAM read will always be
			 * opposite the endianness of the CPU.  The 16-bit
			 * byteswap then brings the data to CPU endianness.
			 */
			tp->nvram_size = swab16((u16)(val & 0x0000ffff)) * 1024;
			return;
		}
	}
	tp->nvram_size = TG3_NVRAM_SIZE_512KB;
}

static void tg3_get_nvram_info(struct tg3 *tp)
{
	u32 nvcfg1;

Annotation

Implementation Notes