drivers/net/ethernet/davicom/dm9000.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/davicom/dm9000.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/davicom/dm9000.c
Extension
.c
Size
42307 bytes
Lines
1812
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 dm9000_netdev_ops = {
	.ndo_open		= dm9000_open,
	.ndo_stop		= dm9000_stop,
	.ndo_start_xmit		= dm9000_start_xmit,
	.ndo_tx_timeout		= dm9000_timeout,
	.ndo_set_rx_mode	= dm9000_hash_table,
	.ndo_eth_ioctl		= dm9000_ioctl,
	.ndo_set_features	= dm9000_set_features,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= dm9000_poll_controller,
#endif
};

static struct dm9000_plat_data *dm9000_parse_dt(struct device *dev)
{
	struct dm9000_plat_data *pdata;
	struct device_node *np = dev->of_node;
	int ret;

	if (!IS_ENABLED(CONFIG_OF) || !np)
		return ERR_PTR(-ENXIO);

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return ERR_PTR(-ENOMEM);

	if (of_property_read_bool(np, "davicom,ext-phy"))
		pdata->flags |= DM9000_PLATF_EXT_PHY;
	if (of_property_read_bool(np, "davicom,no-eeprom"))
		pdata->flags |= DM9000_PLATF_NO_EEPROM;

	ret = of_get_mac_address(np, pdata->dev_addr);
	if (ret == -EPROBE_DEFER)
		return ERR_PTR(ret);

	return pdata;
}

/*
 * Search DM9000 board, allocate space and register it
 */
static int
dm9000_probe(struct platform_device *pdev)
{
	struct dm9000_plat_data *pdata = dev_get_platdata(&pdev->dev);
	struct board_info *db;	/* Point a board information structure */
	struct net_device *ndev;
	struct device *dev = &pdev->dev;
	const unsigned char *mac_src;
	int ret = 0;
	int iosize;
	int i;
	u32 id_val;
	struct gpio_desc *reset_gpio;
	struct regulator *power;
	bool inv_mac_addr = false;
	u8 addr[ETH_ALEN];

	power = devm_regulator_get(dev, "vcc");
	if (IS_ERR(power)) {
		if (PTR_ERR(power) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
		dev_dbg(dev, "no regulator provided\n");
	} else {
		ret = regulator_enable(power);
		if (ret != 0) {
			dev_err(dev,
				"Failed to enable power regulator: %d\n", ret);
			return ret;
		}
		dev_dbg(dev, "regulator enabled\n");
	}

	reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
	ret = PTR_ERR_OR_ZERO(reset_gpio);
	if (ret) {
		dev_err(dev, "failed to request reset gpio: %d\n", ret);
		goto out_regulator_disable;
	}

	if (reset_gpio) {
		ret = gpiod_set_consumer_name(reset_gpio, "dm9000_reset");
		if (ret) {
			dev_err(dev, "failed to set reset gpio name: %d\n",
				ret);
			goto out_regulator_disable;
		}

Annotation

Implementation Notes