net: smsc95xx: Add driver-model support
Add support for driver model, so that CONFIG_DM_ETH can be defined and used with this driver. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
		
							parent
							
								
									527298c4b5
								
							
						
					
					
						commit
						0990fcb772
					
				|  | @ -1,4 +1,5 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2015 Google, Inc | ||||
|  * Copyright (c) 2011 The Chromium OS Authors. | ||||
|  * Copyright (C) 2009 NVIDIA, Corporation | ||||
|  * Copyright (C) 2007-2008 SMSC (Steve Glendinning) | ||||
|  | @ -7,6 +8,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include <common.h> | ||||
| #include <dm.h> | ||||
| #include <errno.h> | ||||
| #include <malloc.h> | ||||
| #include <usb.h> | ||||
|  | @ -137,11 +139,16 @@ | |||
| 
 | ||||
| #define TURBO_MODE | ||||
| 
 | ||||
| #ifndef CONFIG_DM_ETH | ||||
| /* local vars */ | ||||
| static int curr_eth_dev; /* index for name of next device detected */ | ||||
| #endif | ||||
| 
 | ||||
| /* driver private */ | ||||
| struct smsc95xx_private { | ||||
| #ifdef CONFIG_DM_ETH | ||||
| 	struct ueth_data ueth; | ||||
| #endif | ||||
| 	size_t rx_urb_size;  /* maximum USB URB size */ | ||||
| 	u32 mac_cr;  /* MAC control register value */ | ||||
| 	int have_hwaddr;  /* 1 if we have a hardware MAC address */ | ||||
|  | @ -714,6 +721,7 @@ static int smsc95xx_send_common(struct ueth_data *dev, void *packet, int length) | |||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| #ifndef CONFIG_DM_ETH | ||||
| /*
 | ||||
|  * Smsc95xx callbacks | ||||
|  */ | ||||
|  | @ -931,3 +939,137 @@ int smsc95xx_eth_get_info(struct usb_device *dev, struct ueth_data *ss, | |||
| 	eth->priv = ss; | ||||
| 	return 1; | ||||
| } | ||||
| #endif /* !CONFIG_DM_ETH */ | ||||
| 
 | ||||
| #ifdef CONFIG_DM_ETH | ||||
| static int smsc95xx_eth_start(struct udevice *dev) | ||||
| { | ||||
| 	struct usb_device *udev = dev_get_parentdata(dev); | ||||
| 	struct smsc95xx_private *priv = dev_get_priv(dev); | ||||
| 	struct eth_pdata *pdata = dev_get_platdata(dev); | ||||
| 
 | ||||
| 	/* Driver-model Ethernet ensures we have this */ | ||||
| 	priv->have_hwaddr = 1; | ||||
| 
 | ||||
| 	return smsc95xx_init_common(udev, &priv->ueth, priv, pdata->enetaddr); | ||||
| } | ||||
| 
 | ||||
| void smsc95xx_eth_stop(struct udevice *dev) | ||||
| { | ||||
| 	debug("** %s()\n", __func__); | ||||
| } | ||||
| 
 | ||||
| int smsc95xx_eth_send(struct udevice *dev, void *packet, int length) | ||||
| { | ||||
| 	struct smsc95xx_private *priv = dev_get_priv(dev); | ||||
| 
 | ||||
| 	return smsc95xx_send_common(&priv->ueth, packet, length); | ||||
| } | ||||
| 
 | ||||
| int smsc95xx_eth_recv(struct udevice *dev, int flags, uchar **packetp) | ||||
| { | ||||
| 	struct smsc95xx_private *priv = dev_get_priv(dev); | ||||
| 	struct ueth_data *ueth = &priv->ueth; | ||||
| 	uint8_t *ptr; | ||||
| 	int ret, len; | ||||
| 	u32 packet_len; | ||||
| 
 | ||||
| 	len = usb_ether_get_rx_bytes(ueth, &ptr); | ||||
| 	debug("%s: first try, len=%d\n", __func__, len); | ||||
| 	if (!len) { | ||||
| 		if (!(flags & ETH_RECV_CHECK_DEVICE)) | ||||
| 			return -EAGAIN; | ||||
| 		ret = usb_ether_receive(ueth, RX_URB_SIZE); | ||||
| 		if (ret == -EAGAIN) | ||||
| 			return ret; | ||||
| 
 | ||||
| 		len = usb_ether_get_rx_bytes(ueth, &ptr); | ||||
| 		debug("%s: second try, len=%d\n", __func__, len); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 1st 4 bytes contain the length of the actual data plus error info. | ||||
| 	 * Extract data length. | ||||
| 	 */ | ||||
| 	if (len < sizeof(packet_len)) { | ||||
| 		debug("Rx: incomplete packet length\n"); | ||||
| 		goto err; | ||||
| 	} | ||||
| 	memcpy(&packet_len, ptr, sizeof(packet_len)); | ||||
| 	le32_to_cpus(&packet_len); | ||||
| 	if (packet_len & RX_STS_ES_) { | ||||
| 		debug("Rx: Error header=%#x", packet_len); | ||||
| 		goto err; | ||||
| 	} | ||||
| 	packet_len = ((packet_len & RX_STS_FL_) >> 16); | ||||
| 
 | ||||
| 	if (packet_len > len - sizeof(packet_len)) { | ||||
| 		debug("Rx: too large packet: %d\n", packet_len); | ||||
| 		goto err; | ||||
| 	} | ||||
| 
 | ||||
| 	*packetp = ptr + sizeof(packet_len); | ||||
| 	return packet_len; | ||||
| 
 | ||||
| err: | ||||
| 	usb_ether_advance_rxbuf(ueth, -1); | ||||
| 	return -EINVAL; | ||||
| } | ||||
| 
 | ||||
| static int smsc95xx_free_pkt(struct udevice *dev, uchar *packet, int packet_len) | ||||
| { | ||||
| 	struct smsc95xx_private *priv = dev_get_priv(dev); | ||||
| 
 | ||||
| 	packet_len = ALIGN(packet_len, 4); | ||||
| 	usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int smsc95xx_write_hwaddr(struct udevice *dev) | ||||
| { | ||||
| 	struct usb_device *udev = dev_get_parentdata(dev); | ||||
| 	struct eth_pdata *pdata = dev_get_platdata(dev); | ||||
| 	struct smsc95xx_private *priv = dev_get_priv(dev); | ||||
| 
 | ||||
| 	return smsc95xx_write_hwaddr_common(udev, priv, pdata->enetaddr); | ||||
| } | ||||
| 
 | ||||
| static int smsc95xx_eth_probe(struct udevice *dev) | ||||
| { | ||||
| 	struct smsc95xx_private *priv = dev_get_priv(dev); | ||||
| 	struct ueth_data *ueth = &priv->ueth; | ||||
| 
 | ||||
| 	return usb_ether_register(dev, ueth, RX_URB_SIZE); | ||||
| } | ||||
| 
 | ||||
| static const struct eth_ops smsc95xx_eth_ops = { | ||||
| 	.start	= smsc95xx_eth_start, | ||||
| 	.send	= smsc95xx_eth_send, | ||||
| 	.recv	= smsc95xx_eth_recv, | ||||
| 	.free_pkt = smsc95xx_free_pkt, | ||||
| 	.stop	= smsc95xx_eth_stop, | ||||
| 	.write_hwaddr = smsc95xx_write_hwaddr, | ||||
| }; | ||||
| 
 | ||||
| U_BOOT_DRIVER(smsc95xx_eth) = { | ||||
| 	.name	= "smsc95xx_eth", | ||||
| 	.id	= UCLASS_ETH, | ||||
| 	.probe = smsc95xx_eth_probe, | ||||
| 	.ops	= &smsc95xx_eth_ops, | ||||
| 	.priv_auto_alloc_size = sizeof(struct smsc95xx_private), | ||||
| 	.platdata_auto_alloc_size = sizeof(struct eth_pdata), | ||||
| }; | ||||
| 
 | ||||
| static const struct usb_device_id smsc95xx_eth_id_table[] = { | ||||
| 	{ USB_DEVICE(0x05ac, 0x1402) }, | ||||
| 	{ USB_DEVICE(0x0424, 0xec00) },	/* LAN9512/LAN9514 Ethernet */ | ||||
| 	{ USB_DEVICE(0x0424, 0x9500) },	/* LAN9500 Ethernet */ | ||||
| 	{ USB_DEVICE(0x0424, 0x9730) },	/* LAN9730 Ethernet (HSIC) */ | ||||
| 	{ USB_DEVICE(0x0424, 0x9900) },	/* SMSC9500 USB Ethernet (SAL10) */ | ||||
| 	{ USB_DEVICE(0x0424, 0x9e00) },	/* LAN9500A Ethernet */ | ||||
| 	{ }		/* Terminating entry */ | ||||
| }; | ||||
| 
 | ||||
| U_BOOT_USB_DEVICE(smsc95xx_eth, smsc95xx_eth_id_table); | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue