/*
 * Copyright (c) 2013 Gerhard Sittig <gsi@denx.de>
 * based on the U-Boot Asix driver as well as information
 * from the Linux Moschip driver
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * MOSCHIP MCS7830 based (7730/7830/7832) USB 2.0 Ethernet Devices
 */

#include <common.h>
#include <errno.h>
#include <linux/mii.h>
#include <malloc.h>
#include <usb.h>

#include "usb_ether.h"

#define MCS7830_BASE_NAME	"mcs"

#define USBCALL_TIMEOUT		1000
#define LINKSTATUS_TIMEOUT	5000	/* link status, connect timeout */
#define LINKSTATUS_TIMEOUT_RES	50	/* link status, resolution in msec */

#define MCS7830_RX_URB_SIZE	2048

/* command opcodes */
#define MCS7830_WR_BREQ		0x0d
#define MCS7830_RD_BREQ		0x0e

/* register layout, numerical offset specs for USB API calls */
struct mcs7830_regs {
	uint8_t multicast_hashes[8];
	uint8_t packet_gap[2];
	uint8_t phy_data[2];
	uint8_t phy_command[2];
	uint8_t configuration;
	uint8_t ether_address[6];
	uint8_t frame_drop_count;
	uint8_t pause_threshold;
};
#define REG_MULTICAST_HASH	offsetof(struct mcs7830_regs, multicast_hashes)
#define REG_PHY_DATA		offsetof(struct mcs7830_regs, phy_data)
#define REG_PHY_CMD		offsetof(struct mcs7830_regs, phy_command)
#define REG_CONFIG		offsetof(struct mcs7830_regs, configuration)
#define REG_ETHER_ADDR		offsetof(struct mcs7830_regs, ether_address)
#define REG_FRAME_DROP_COUNTER	offsetof(struct mcs7830_regs, frame_drop_count)
#define REG_PAUSE_THRESHOLD	offsetof(struct mcs7830_regs, pause_threshold)

/* bit masks and default values for the above registers */
#define PHY_CMD1_READ		0x40
#define PHY_CMD1_WRITE		0x20
#define PHY_CMD1_PHYADDR	0x01

#define PHY_CMD2_PEND		0x80
#define PHY_CMD2_READY		0x40

#define CONF_CFG		0x80
#define CONF_SPEED100		0x40
#define CONF_FDX_ENABLE		0x20
#define CONF_RXENABLE		0x10
#define CONF_TXENABLE		0x08
#define CONF_SLEEPMODE		0x04
#define CONF_ALLMULTICAST	0x02
#define CONF_PROMISCUOUS	0x01

#define PAUSE_THRESHOLD_DEFAULT	0

/* bit masks for the status byte which follows received ethernet frames */
#define STAT_RX_FRAME_CORRECT	0x20
#define STAT_RX_LARGE_FRAME	0x10
#define STAT_RX_CRC_ERROR	0x08
#define STAT_RX_ALIGNMENT_ERROR	0x04
#define STAT_RX_LENGTH_ERROR	0x02
#define STAT_RX_SHORT_FRAME	0x01

/*
 * struct mcs7830_private - private driver data for an individual adapter
 * @config:	shadow for the network adapter's configuration register
 * @mchash:	shadow for the network adapter's multicast hash registers
 */
struct mcs7830_private {
	uint8_t config;
	uint8_t mchash[8];
};

/*
 * mcs7830_read_reg() - read a register of the network adapter
 * @dev:	network device to read from
 * @idx:	index of the register to start reading from
 * @size:	number of bytes to read
 * @data:	buffer to read into
 * Return: zero upon success, negative upon error
 */
static int mcs7830_read_reg(struct ueth_data *dev, uint8_t idx,
			    uint16_t size, void *data)
{
	int len;
	ALLOC_CACHE_ALIGN_BUFFER(uint8_t, buf, size);

	debug("%s() idx=0x%04X sz=%d\n", __func__, idx, size);

	len = usb_control_msg(dev->pusb_dev,
			      usb_rcvctrlpipe(dev->pusb_dev, 0),
			      MCS7830_RD_BREQ,
			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      0, idx, buf, size,
			      USBCALL_TIMEOUT);
	if (len != size) {
		debug("%s() len=%d != sz=%d\n", __func__, len, size);
		return -EIO;
	}
	memcpy(data, buf, size);
	return 0;
}

/*
 * mcs7830_write_reg() - write a register of the network adapter
 * @dev:	network device to write to
 * @idx:	index of the register to start writing to
 * @size:	number of bytes to write
 * @data:	buffer holding the data to write
 * Return: zero upon success, negative upon error
 */
static int mcs7830_write_reg(struct ueth_data *dev, uint8_t idx,
			     uint16_t size, void *data)
{
	int len;
	ALLOC_CACHE_ALIGN_BUFFER(uint8_t, buf, size);

	debug("%s() idx=0x%04X sz=%d\n", __func__, idx, size);

	memcpy(buf, data, size);
	len = usb_control_msg(dev->pusb_dev,
			      usb_sndctrlpipe(dev->pusb_dev, 0),
			      MCS7830_WR_BREQ,
			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      0, idx, buf, size,
			      USBCALL_TIMEOUT);
	if (len != size) {
		debug("%s() len=%d != sz=%d\n", __func__, len, size);
		return -EIO;
	}
	return 0;
}

/*
 * mcs7830_phy_emit_wait() - emit PHY read/write access, wait for its execution
 * @dev:	network device to talk to
 * @rwflag:	PHY_CMD1_READ or PHY_CMD1_WRITE opcode
 * @index:	number of the PHY register to read or write
 * Return: zero upon success, negative upon error
 */
static int mcs7830_phy_emit_wait(struct ueth_data *dev,
				 uint8_t rwflag, uint8_t index)
{
	int rc;
	int retry;
	uint8_t cmd[2];

	/* send the PHY read/write request */
	cmd[0] = rwflag | PHY_CMD1_PHYADDR;
	cmd[1] = PHY_CMD2_PEND | (index & 0x1f);
	rc = mcs7830_write_reg(dev, REG_PHY_CMD, sizeof(cmd), cmd);
	if (rc < 0)
		return rc;

	/* wait for the response to become available (usually < 1ms) */
	retry = 10;
	do {
		rc = mcs7830_read_reg(dev, REG_PHY_CMD, sizeof(cmd), cmd);
		if (rc < 0)
			return rc;
		if (cmd[1] & PHY_CMD2_READY)
			return 0;
		if (!retry--)
			return -ETIMEDOUT;
		mdelay(1);
	} while (1);
	/* UNREACH */
}

/*
 * mcs7830_read_phy() - read a PHY register of the network adapter
 * @dev:	network device to read from
 * @index:	index of the PHY register to read from
 * Return: non-negative 16bit register content, negative upon error
 */
static int mcs7830_read_phy(struct ueth_data *dev, uint8_t index)
{
	int rc;
	uint16_t val;

	/* issue the PHY read request and wait for its execution */
	rc = mcs7830_phy_emit_wait(dev, PHY_CMD1_READ, index);
	if (rc < 0)
		return rc;

	/* fetch the PHY data which was read */
	rc = mcs7830_read_reg(dev, REG_PHY_DATA, sizeof(val), &val);
	if (rc < 0)
		return rc;
	rc = le16_to_cpu(val);
	debug("%s(%s, %d) => 0x%04X\n", __func__, dev->eth_dev.name, index, rc);
	return rc;
}

/*
 * mcs7830_write_phy() - write a PHY register of the network adapter
 * @dev:	network device to write to
 * @index:	index of the PHY register to write to
 * @val:	value to write to the PHY register
 * Return: zero upon success, negative upon error
 */
static int mcs7830_write_phy(struct ueth_data *dev, uint8_t index, uint16_t val)
{
	int rc;

	debug("%s(%s, %d, 0x%04X)\n", __func__, dev->eth_dev.name, index, val);

	/* setup the PHY data which is to get written */
	val = cpu_to_le16(val);
	rc = mcs7830_write_reg(dev, REG_PHY_DATA, sizeof(val), &val);
	if (rc < 0)
		return rc;

	/* issue the PHY write request and wait for its execution */
	rc = mcs7830_phy_emit_wait(dev, PHY_CMD1_WRITE, index);
	if (rc < 0)
		return rc;

	return 0;
}

/*
 * mcs7830_write_config() - write to the network adapter's config register
 * @eth:	network device to write to
 * Return: zero upon success, negative upon error
 *
 * the data which gets written is taken from the shadow config register
 * within the device driver's private data
 */
static int mcs7830_write_config(struct ueth_data *dev)
{
	struct mcs7830_private *priv;
	int rc;

	debug("%s()\n", __func__);
	priv = dev->dev_priv;

	rc = mcs7830_write_reg(dev, REG_CONFIG,
			       sizeof(priv->config), &priv->config);
	if (rc < 0) {
		debug("writing config to adapter failed\n");
		return rc;
	}

	return 0;
}

/*
 * mcs7830_write_mchash() - write the network adapter's multicast filter
 * @eth:	network device to write to
 * Return: zero upon success, negative upon error
 *
 * the data which gets written is taken from the shadow multicast hashes
 * within the device driver's private data
 */
static int mcs7830_write_mchash(struct ueth_data *dev)
{
	struct mcs7830_private *priv;
	int rc;

	debug("%s()\n", __func__);
	priv = dev->dev_priv;

	rc = mcs7830_write_reg(dev, REG_MULTICAST_HASH,
			       sizeof(priv->mchash), &priv->mchash);
	if (rc < 0) {
		debug("writing multicast hash to adapter failed\n");
		return rc;
	}

	return 0;
}

/*
 * mcs7830_set_autoneg() - setup and trigger ethernet link autonegotiation
 * @eth:	network device to run link negotiation on
 * Return: zero upon success, negative upon error
 *
 * the routine advertises available media and starts autonegotiation
 */
static int mcs7830_set_autoneg(struct ueth_data *dev)
{
	int adv, flg;
	int rc;

	debug("%s()\n", __func__);

	/*
	 * algorithm taken from the Linux driver, which took it from
	 * "the original mcs7830 version 1.4 driver":
	 *
	 * enable all media, reset BMCR, enable auto neg, restart
	 * auto neg while keeping the enable auto neg flag set
	 */

	adv = ADVERTISE_PAUSE_CAP | ADVERTISE_ALL | ADVERTISE_CSMA;
	rc = mcs7830_write_phy(dev, MII_ADVERTISE, adv);

	flg = 0;
	if (!rc)
		rc = mcs7830_write_phy(dev, MII_BMCR, flg);

	flg |= BMCR_ANENABLE;
	if (!rc)
		rc = mcs7830_write_phy(dev, MII_BMCR, flg);

	flg |= BMCR_ANRESTART;
	if (!rc)
		rc = mcs7830_write_phy(dev, MII_BMCR, flg);

	return rc;
}

/*
 * mcs7830_get_rev() - identify a network adapter's chip revision
 * @eth:	network device to identify
 * Return: non-negative number, reflecting the revision number
 *
 * currently, only "rev C and higher" and "below rev C" are needed, so
 * the return value is #1 for "below rev C", and #2 for "rev C and above"
 */
static int mcs7830_get_rev(struct ueth_data *dev)
{
	uint8_t buf[2];
	int rc;
	int rev;

	/* register 22 is readable in rev C and higher */
	rc = mcs7830_read_reg(dev, REG_FRAME_DROP_COUNTER, sizeof(buf), buf);
	if (rc < 0)
		rev = 1;
	else
		rev = 2;
	debug("%s() rc=%d, rev=%d\n", __func__, rc, rev);
	return rev;
}

/*
 * mcs7830_apply_fixup() - identify an adapter and potentially apply fixups
 * @eth:	network device to identify and apply fixups to
 * Return: zero upon success (no errors emitted from here)
 *
 * this routine identifies the network adapter's chip revision, and applies
 * fixups for known issues
 */
static int mcs7830_apply_fixup(struct ueth_data *dev)
{
	int rev;
	int i;
	uint8_t thr;

	rev = mcs7830_get_rev(dev);
	debug("%s() rev=%d\n", __func__, rev);

	/*
	 * rev C requires setting the pause threshold (the Linux driver
	 * is inconsistent, the implementation does it for "rev C
	 * exactly", the introductory comment says "rev C and above")
	 */
	if (rev == 2) {
		debug("%s: applying rev C fixup\n", dev->eth_dev.name);
		thr = PAUSE_THRESHOLD_DEFAULT;
		for (i = 0; i < 2; i++) {
			(void)mcs7830_write_reg(dev, REG_PAUSE_THRESHOLD,
						sizeof(thr), &thr);
			mdelay(1);
		}
	}

	return 0;
}

/*
 * mcs7830_basic_reset() - bring the network adapter into a known first state
 * @eth:	network device to act upon
 * Return: zero upon success, negative upon error
 *
 * this routine initializes the network adapter such that subsequent invocations
 * of the interface callbacks can exchange ethernet frames; link negotiation is
 * triggered from here already and continues in background
 */
static int mcs7830_basic_reset(struct ueth_data *dev)
{
	struct mcs7830_private *priv;
	int rc;

	debug("%s()\n", __func__);
	priv = dev->dev_priv;

	/*
	 * comment from the respective Linux driver, which
	 * unconditionally sets the ALLMULTICAST flag as well:
	 * should not be needed, but does not work otherwise
	 */
	priv->config = CONF_TXENABLE;
	priv->config |= CONF_ALLMULTICAST;

	rc = mcs7830_set_autoneg(dev);
	if (rc < 0) {
		error("setting autoneg failed\n");
		return rc;
	}

	rc = mcs7830_write_mchash(dev);
	if (rc < 0) {
		error("failed to set multicast hash\n");
		return rc;
	}

	rc = mcs7830_write_config(dev);
	if (rc < 0) {
		error("failed to set configuration\n");
		return rc;
	}

	rc = mcs7830_apply_fixup(dev);
	if (rc < 0) {
		error("fixup application failed\n");
		return rc;
	}

	return 0;
}

/*
 * mcs7830_read_mac() - read an ethernet adapter's MAC address
 * @eth:	network device to read from
 * Return: zero upon success, negative upon error
 *
 * this routine fetches the MAC address stored within the ethernet adapter,
 * and stores it in the ethernet interface's data structure
 */
static int mcs7830_read_mac(struct eth_device *eth)
{
	struct ueth_data *dev;
	int rc;
	uint8_t buf[ETH_ALEN];

	debug("%s()\n", __func__);
	dev = eth->priv;

	rc = mcs7830_read_reg(dev, REG_ETHER_ADDR, ETH_ALEN, buf);
	if (rc < 0) {
		debug("reading MAC from adapter failed\n");
		return rc;
	}

	memcpy(&eth->enetaddr[0], buf, ETH_ALEN);
	return 0;
}

/*
 * mcs7830_write_mac() - write an ethernet adapter's MAC address
 * @eth:	network device to write to
 * Return: zero upon success, negative upon error
 *
 * this routine takes the MAC address from the ethernet interface's data
 * structure, and writes it into the ethernet adapter such that subsequent
 * exchange of ethernet frames uses this address
 */
static int mcs7830_write_mac(struct eth_device *eth)
{
	struct ueth_data *dev;
	int rc;

	debug("%s()\n", __func__);
	dev = eth->priv;

	if (sizeof(eth->enetaddr) != ETH_ALEN)
		return -EINVAL;
	rc = mcs7830_write_reg(dev, REG_ETHER_ADDR, ETH_ALEN, eth->enetaddr);
	if (rc < 0) {
		debug("writing MAC to adapter failed\n");
		return rc;
	}
	return 0;
}

/*
 * mcs7830_init() - network interface's init callback
 * @eth:	network device to initialize
 * @bd:		board information
 * Return: zero upon success, negative upon error
 *
 * after initial setup during probe() and get_info(), this init() callback
 * ensures that the link is up and subsequent send() and recv() calls can
 * exchange ethernet frames
 */
static int mcs7830_init(struct eth_device *eth, bd_t *bd)
{
	struct ueth_data *dev;
	int timeout;
	int have_link;

	debug("%s()\n", __func__);
	dev = eth->priv;

	timeout = 0;
	do {
		have_link = mcs7830_read_phy(dev, MII_BMSR) & BMSR_LSTATUS;
		if (have_link)
			break;
		udelay(LINKSTATUS_TIMEOUT_RES * 1000);
		timeout += LINKSTATUS_TIMEOUT_RES;
	} while (timeout < LINKSTATUS_TIMEOUT);
	if (!have_link) {
		debug("ethernet link is down\n");
		return -ETIMEDOUT;
	}
	return 0;
}

/*
 * mcs7830_send() - network interface's send callback
 * @eth:	network device to send the frame from
 * @packet:	ethernet frame content
 * @length:	ethernet frame length
 * Return: zero upon success, negative upon error
 *
 * this routine send an ethernet frame out of the network interface
 */
static int mcs7830_send(struct eth_device *eth, void *packet, int length)
{
	struct ueth_data *dev;
	int rc;
	int gotlen;
	/* there is a status byte after the ethernet frame */
	ALLOC_CACHE_ALIGN_BUFFER(uint8_t, buf, PKTSIZE + sizeof(uint8_t));

	dev = eth->priv;

	memcpy(buf, packet, length);
	rc = usb_bulk_msg(dev->pusb_dev,
			  usb_sndbulkpipe(dev->pusb_dev, dev->ep_out),
			  &buf[0], length, &gotlen,
			  USBCALL_TIMEOUT);
	debug("%s() TX want len %d, got len %d, rc %d\n",
	      __func__, length, gotlen, rc);
	return rc;
}

/*
 * mcs7830_recv() - network interface's recv callback
 * @eth:	network device to receive frames from
 * Return: zero upon success, negative upon error
 *
 * this routine checks for available ethernet frames that the network
 * interface might have received, and notifies the network stack
 */
static int mcs7830_recv(struct eth_device *eth)
{
	struct ueth_data *dev;
	ALLOC_CACHE_ALIGN_BUFFER(uint8_t, buf, MCS7830_RX_URB_SIZE);
	int rc, wantlen, gotlen;
	uint8_t sts;

	debug("%s()\n", __func__);
	dev = eth->priv;

	/* fetch input data from the adapter */
	wantlen = MCS7830_RX_URB_SIZE;
	rc = usb_bulk_msg(dev->pusb_dev,
			  usb_rcvbulkpipe(dev->pusb_dev, dev->ep_in),
			  &buf[0], wantlen, &gotlen,
			  USBCALL_TIMEOUT);
	debug("%s() RX want len %d, got len %d, rc %d\n",
	      __func__, wantlen, gotlen, rc);
	if (rc != 0) {
		error("RX: failed to receive\n");
		return rc;
	}
	if (gotlen > wantlen) {
		error("RX: got too many bytes (%d)\n", gotlen);
		return -EIO;
	}

	/*
	 * the bulk message that we received from USB contains exactly
	 * one ethernet frame and a trailing status byte
	 */
	if (gotlen < sizeof(sts))
		return -EIO;
	gotlen -= sizeof(sts);
	sts = buf[gotlen];

	if (sts == STAT_RX_FRAME_CORRECT) {
		debug("%s() got a frame, len=%d\n", __func__, gotlen);
		net_process_received_packet(buf, gotlen);
		return 0;
	}

	debug("RX: frame error (sts 0x%02X, %s %s %s %s %s)\n",
	      sts,
	      (sts & STAT_RX_LARGE_FRAME) ? "large" : "-",
	      (sts & STAT_RX_LENGTH_ERROR) ?  "length" : "-",
	      (sts & STAT_RX_SHORT_FRAME) ? "short" : "-",
	      (sts & STAT_RX_CRC_ERROR) ? "crc" : "-",
	      (sts & STAT_RX_ALIGNMENT_ERROR) ?  "align" : "-");
	return -EIO;
}

/*
 * mcs7830_halt() - network interface's halt callback
 * @eth:	network device to cease operation of
 * Return: none
 *
 * this routine is supposed to undo the effect of previous initialization and
 * ethernet frames exchange; in this implementation it's a NOP
 */
static void mcs7830_halt(struct eth_device *eth)
{
	debug("%s()\n", __func__);
}

/*
 * mcs7830_iface_idx - index of detected network interfaces
 *
 * this counter keeps track of identified supported interfaces,
 * to assign unique names as more interfaces are found
 */
static int mcs7830_iface_idx;

/*
 * mcs7830_eth_before_probe() - network driver's before_probe callback
 * Return: none
 *
 * this routine initializes driver's internal data in preparation of
 * subsequent probe callbacks
 */
void mcs7830_eth_before_probe(void)
{
	mcs7830_iface_idx = 0;
}

/*
 * struct mcs7830_dongle - description of a supported Moschip ethernet dongle
 * @vendor:	16bit USB vendor identification
 * @product:	16bit USB product identification
 *
 * this structure describes a supported USB ethernet dongle by means of the
 * vendor and product codes found during USB enumeration; no flags are held
 * here since all supported dongles have identical behaviour, and required
 * fixups get determined at runtime, such that no manual configuration is
 * needed
 */
struct mcs7830_dongle {
	uint16_t vendor;
	uint16_t product;
};

/*
 * mcs7830_dongles - the list of supported Moschip based USB ethernet dongles
 */
static const struct mcs7830_dongle mcs7830_dongles[] = {
	{ 0x9710, 0x7832, },	/* Moschip 7832 */
	{ 0x9710, 0x7830, },	/* Moschip 7830 */
	{ 0x9710, 0x7730, },	/* Moschip 7730 */
	{ 0x0df6, 0x0021, },	/* Sitecom LN 30 */
};

/*
 * mcs7830_eth_probe() - network driver's probe callback
 * @dev:	detected USB device to check
 * @ifnum:	detected USB interface to check
 * @ss:		USB ethernet data structure to fill in upon match
 * Return: #1 upon match, #0 upon mismatch or error
 *
 * this routine checks whether the found USB device is supported by
 * this ethernet driver, and upon match fills in the USB ethernet
 * data structure which later is passed to the get_info callback
 */
int mcs7830_eth_probe(struct usb_device *dev, unsigned int ifnum,
		      struct ueth_data *ss)
{
	struct usb_interface *iface;
	struct usb_interface_descriptor *iface_desc;
	int i;
	struct mcs7830_private *priv;
	int ep_in_found, ep_out_found, ep_intr_found;

	debug("%s()\n", __func__);

	/* iterate the list of supported dongles */
	iface = &dev->config.if_desc[ifnum];
	iface_desc = &iface->desc;
	for (i = 0; i < ARRAY_SIZE(mcs7830_dongles); i++) {
		if (dev->descriptor.idVendor == mcs7830_dongles[i].vendor &&
		    dev->descriptor.idProduct == mcs7830_dongles[i].product)
			break;
	}
	if (i == ARRAY_SIZE(mcs7830_dongles))
		return 0;
	debug("detected USB ethernet device: %04X:%04X\n",
	      dev->descriptor.idVendor, dev->descriptor.idProduct);

	/* fill in driver private data */
	priv = calloc(1, sizeof(*priv));
	if (!priv)
		return 0;

	/* fill in the ueth_data structure, attach private data */
	memset(ss, 0, sizeof(*ss));
	ss->ifnum = ifnum;
	ss->pusb_dev = dev;
	ss->subclass = iface_desc->bInterfaceSubClass;
	ss->protocol = iface_desc->bInterfaceProtocol;
	ss->dev_priv = priv;

	/*
	 * a minimum of three endpoints is expected: in (bulk),
	 * out (bulk), and interrupt; ignore all others
	 */
	ep_in_found = ep_out_found = ep_intr_found = 0;
	for (i = 0; i < iface_desc->bNumEndpoints; i++) {
		uint8_t eptype, epaddr;
		bool is_input;

		eptype = iface->ep_desc[i].bmAttributes;
		eptype &= USB_ENDPOINT_XFERTYPE_MASK;

		epaddr = iface->ep_desc[i].bEndpointAddress;
		is_input = epaddr & USB_DIR_IN;
		epaddr &= USB_ENDPOINT_NUMBER_MASK;

		if (eptype == USB_ENDPOINT_XFER_BULK) {
			if (is_input && !ep_in_found) {
				ss->ep_in = epaddr;
				ep_in_found++;
			}
			if (!is_input && !ep_out_found) {
				ss->ep_out = epaddr;
				ep_out_found++;
			}
		}

		if (eptype == USB_ENDPOINT_XFER_INT) {
			if (is_input && !ep_intr_found) {
				ss->ep_int = epaddr;
				ss->irqinterval = iface->ep_desc[i].bInterval;
				ep_intr_found++;
			}
		}
	}
	debug("endpoints: in %d, out %d, intr %d\n",
	      ss->ep_in, ss->ep_out, ss->ep_int);

	/* apply basic sanity checks */
	if (usb_set_interface(dev, iface_desc->bInterfaceNumber, 0) ||
	    !ss->ep_in || !ss->ep_out || !ss->ep_int) {
		debug("device probe incomplete\n");
		return 0;
	}

	dev->privptr = ss;
	return 1;
}

/*
 * mcs7830_eth_get_info() - network driver's get_info callback
 * @dev:	detected USB device
 * @ss:		USB ethernet data structure filled in at probe()
 * @eth:	ethernet interface data structure to fill in
 * Return: #1 upon success, #0 upon error
 *
 * this routine registers the mandatory init(), send(), recv(), and
 * halt() callbacks with the ethernet interface, can register the
 * optional write_hwaddr() callback with the ethernet interface,
 * and initiates configuration of the interface such that subsequent
 * calls to those callbacks results in network communication
 */
int mcs7830_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
			 struct eth_device *eth)
{
	debug("%s()\n", __func__);
	if (!eth) {
		debug("%s: missing parameter.\n", __func__);
		return 0;
	}

	snprintf(eth->name, sizeof(eth->name), "%s%d",
		 MCS7830_BASE_NAME, mcs7830_iface_idx++);
	eth->init = mcs7830_init;
	eth->send = mcs7830_send;
	eth->recv = mcs7830_recv;
	eth->halt = mcs7830_halt;
	eth->write_hwaddr = mcs7830_write_mac;
	eth->priv = ss;

	if (mcs7830_basic_reset(ss))
		return 0;

	if (mcs7830_read_mac(eth))
		return 0;
	debug("MAC %pM\n", eth->enetaddr);

	return 1;
}
