drivers/net/ethernet/freescale/ucc_geth.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/freescale/ucc_geth.c
Extension
.c
Size
109851 bytes
Lines
3660
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 ucc_geth_netdev_ops = {
	.ndo_open		= ucc_geth_open,
	.ndo_stop		= ucc_geth_close,
	.ndo_start_xmit		= ucc_geth_start_xmit,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= ucc_geth_set_mac_addr,
	.ndo_set_rx_mode	= ucc_geth_set_multi,
	.ndo_tx_timeout		= ucc_geth_timeout,
	.ndo_eth_ioctl		= ucc_geth_ioctl,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= ucc_netpoll,
#endif
};

static int ucc_geth_parse_clock(struct device_node *np, const char *which,
				enum qe_clock *out)
{
	const char *sprop;
	char buf[24];

	snprintf(buf, sizeof(buf), "%s-clock-name", which);
	sprop = of_get_property(np, buf, NULL);
	if (sprop) {
		*out = qe_clock_source(sprop);
	} else {
		u32 val;

		snprintf(buf, sizeof(buf), "%s-clock", which);
		if (of_property_read_u32(np, buf, &val)) {
			/* If both *-clock-name and *-clock are missing,
			 * we want to tell people to use *-clock-name.
			 */
			pr_err("missing %s-clock-name property\n", buf);
			return -EINVAL;
		}
		*out = val;
	}
	if (*out < QE_CLK_NONE || *out > QE_CLK24) {
		pr_err("invalid %s property\n", buf);
		return -EINVAL;
	}
	return 0;
}

static const struct phylink_mac_ops ugeth_mac_ops = {
	.mac_link_up = ugeth_mac_link_up,
	.mac_link_down = ugeth_mac_link_down,
	.mac_config = ugeth_mac_config,
};

static int ucc_geth_probe(struct platform_device* ofdev)
{
	struct device *device = &ofdev->dev;
	struct device_node *np = ofdev->dev.of_node;
	struct net_device *dev = NULL;
	struct ucc_geth_private *ugeth = NULL;
	struct ucc_geth_info *ug_info;
	struct device_node *phy_node;
	struct phylink *phylink;
	struct resource res;
	int err, ucc_num;
	const unsigned int *prop;
	phy_interface_t phy_interface;

	ugeth_vdbg("%s: IN", __func__);

	prop = of_get_property(np, "cell-index", NULL);
	if (!prop) {
		prop = of_get_property(np, "device-id", NULL);
		if (!prop)
			return -ENODEV;
	}

	ucc_num = *prop - 1;
	if ((ucc_num < 0) || (ucc_num > 7))
		return -ENODEV;

	ug_info = devm_kmemdup(&ofdev->dev, &ugeth_primary_info,
			       sizeof(*ug_info), GFP_KERNEL);
	if (!ug_info)
		return -ENOMEM;

	ug_info->uf_info.ucc_num = ucc_num;

	err = ucc_geth_parse_clock(np, "rx", &ug_info->uf_info.rx_clock);
	if (err)
		return err;
	err = ucc_geth_parse_clock(np, "tx", &ug_info->uf_info.tx_clock);
	if (err)
		return err;

Annotation

Implementation Notes