/*
 * Copyright (c) 2014 Rene Griessl <rgriessl@cit-ec.uni-bielefeld.de>
 * based on the U-Boot Asix driver as well as information
 * from the Linux AX88179_178a driver
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <usb.h>
#include <net.h>
#include <linux/mii.h>
#include "usb_ether.h"
#include <malloc.h>
#include <memalign.h>
#include <errno.h>

/* ASIX AX88179 based USB 3.0 Ethernet Devices */
#define AX88179_PHY_ID				0x03
#define AX_EEPROM_LEN				0x100
#define AX88179_EEPROM_MAGIC			0x17900b95
#define AX_MCAST_FLTSIZE			8
#define AX_MAX_MCAST				64
#define AX_INT_PPLS_LINK			(1 << 16)
#define AX_RXHDR_L4_TYPE_MASK			0x1c
#define AX_RXHDR_L4_TYPE_UDP			4
#define AX_RXHDR_L4_TYPE_TCP			16
#define AX_RXHDR_L3CSUM_ERR			2
#define AX_RXHDR_L4CSUM_ERR			1
#define AX_RXHDR_CRC_ERR			(1 << 29)
#define AX_RXHDR_DROP_ERR			(1 << 31)
#define AX_ENDPOINT_INT				0x01
#define AX_ENDPOINT_IN				0x02
#define AX_ENDPOINT_OUT				0x03
#define AX_ACCESS_MAC				0x01
#define AX_ACCESS_PHY				0x02
#define AX_ACCESS_EEPROM			0x04
#define AX_ACCESS_EFUS				0x05
#define AX_PAUSE_WATERLVL_HIGH			0x54
#define AX_PAUSE_WATERLVL_LOW			0x55

#define PHYSICAL_LINK_STATUS			0x02
	#define	AX_USB_SS		(1 << 2)
	#define	AX_USB_HS		(1 << 1)

#define GENERAL_STATUS				0x03
	#define	AX_SECLD		(1 << 2)

#define AX_SROM_ADDR				0x07
#define AX_SROM_CMD				0x0a
	#define EEP_RD			(1 << 2)
	#define EEP_BUSY		(1 << 4)

#define AX_SROM_DATA_LOW			0x08
#define AX_SROM_DATA_HIGH			0x09

#define AX_RX_CTL				0x0b
	#define AX_RX_CTL_DROPCRCERR	(1 << 8)
	#define AX_RX_CTL_IPE		(1 << 9)
	#define AX_RX_CTL_START		(1 << 7)
	#define AX_RX_CTL_AP		(1 << 5)
	#define AX_RX_CTL_AM		(1 << 4)
	#define AX_RX_CTL_AB		(1 << 3)
	#define AX_RX_CTL_AMALL		(1 << 1)
	#define AX_RX_CTL_PRO		(1 << 0)
	#define AX_RX_CTL_STOP		0

#define AX_NODE_ID				0x10
#define AX_MULFLTARY				0x16

#define AX_MEDIUM_STATUS_MODE			0x22
	#define AX_MEDIUM_GIGAMODE	(1 << 0)
	#define AX_MEDIUM_FULL_DUPLEX	(1 << 1)
	#define AX_MEDIUM_EN_125MHZ	(1 << 3)
	#define AX_MEDIUM_RXFLOW_CTRLEN	(1 << 4)
	#define AX_MEDIUM_TXFLOW_CTRLEN	(1 << 5)
	#define AX_MEDIUM_RECEIVE_EN	(1 << 8)
	#define AX_MEDIUM_PS		(1 << 9)
	#define AX_MEDIUM_JUMBO_EN	0x8040

#define AX_MONITOR_MOD				0x24
	#define AX_MONITOR_MODE_RWLC	(1 << 1)
	#define AX_MONITOR_MODE_RWMP	(1 << 2)
	#define AX_MONITOR_MODE_PMEPOL	(1 << 5)
	#define AX_MONITOR_MODE_PMETYPE	(1 << 6)

#define AX_GPIO_CTRL				0x25
	#define AX_GPIO_CTRL_GPIO3EN	(1 << 7)
	#define AX_GPIO_CTRL_GPIO2EN	(1 << 6)
	#define AX_GPIO_CTRL_GPIO1EN	(1 << 5)

#define AX_PHYPWR_RSTCTL			0x26
	#define AX_PHYPWR_RSTCTL_BZ	(1 << 4)
	#define AX_PHYPWR_RSTCTL_IPRL	(1 << 5)
	#define AX_PHYPWR_RSTCTL_AT	(1 << 12)

#define AX_RX_BULKIN_QCTRL			0x2e
#define AX_CLK_SELECT				0x33
	#define AX_CLK_SELECT_BCS	(1 << 0)
	#define AX_CLK_SELECT_ACS	(1 << 1)
	#define AX_CLK_SELECT_ULR	(1 << 3)

#define AX_RXCOE_CTL				0x34
	#define AX_RXCOE_IP		(1 << 0)
	#define AX_RXCOE_TCP		(1 << 1)
	#define AX_RXCOE_UDP		(1 << 2)
	#define AX_RXCOE_TCPV6		(1 << 5)
	#define AX_RXCOE_UDPV6		(1 << 6)

#define AX_TXCOE_CTL				0x35
	#define AX_TXCOE_IP		(1 << 0)
	#define AX_TXCOE_TCP		(1 << 1)
	#define AX_TXCOE_UDP		(1 << 2)
	#define AX_TXCOE_TCPV6		(1 << 5)
	#define AX_TXCOE_UDPV6		(1 << 6)

#define AX_LEDCTRL				0x73

#define GMII_PHY_PHYSR				0x11
	#define GMII_PHY_PHYSR_SMASK	0xc000
	#define GMII_PHY_PHYSR_GIGA	(1 << 15)
	#define GMII_PHY_PHYSR_100	(1 << 14)
	#define GMII_PHY_PHYSR_FULL	(1 << 13)
	#define GMII_PHY_PHYSR_LINK	(1 << 10)

#define GMII_LED_ACT				0x1a
	#define	GMII_LED_ACTIVE_MASK	0xff8f
	#define	GMII_LED0_ACTIVE	(1 << 4)
	#define	GMII_LED1_ACTIVE	(1 << 5)
	#define	GMII_LED2_ACTIVE	(1 << 6)

#define GMII_LED_LINK				0x1c
	#define	GMII_LED_LINK_MASK	0xf888
	#define	GMII_LED0_LINK_10	(1 << 0)
	#define	GMII_LED0_LINK_100	(1 << 1)
	#define	GMII_LED0_LINK_1000	(1 << 2)
	#define	GMII_LED1_LINK_10	(1 << 4)
	#define	GMII_LED1_LINK_100	(1 << 5)
	#define	GMII_LED1_LINK_1000	(1 << 6)
	#define	GMII_LED2_LINK_10	(1 << 8)
	#define	GMII_LED2_LINK_100	(1 << 9)
	#define	GMII_LED2_LINK_1000	(1 << 10)
	#define	LED0_ACTIVE		(1 << 0)
	#define	LED0_LINK_10		(1 << 1)
	#define	LED0_LINK_100		(1 << 2)
	#define	LED0_LINK_1000		(1 << 3)
	#define	LED0_FD			(1 << 4)
	#define	LED0_USB3_MASK		0x001f
	#define	LED1_ACTIVE		(1 << 5)
	#define	LED1_LINK_10		(1 << 6)
	#define	LED1_LINK_100		(1 << 7)
	#define	LED1_LINK_1000		(1 << 8)
	#define	LED1_FD			(1 << 9)
	#define	LED1_USB3_MASK		0x03e0
	#define	LED2_ACTIVE		(1 << 10)
	#define	LED2_LINK_1000		(1 << 13)
	#define	LED2_LINK_100		(1 << 12)
	#define	LED2_LINK_10		(1 << 11)
	#define	LED2_FD			(1 << 14)
	#define	LED_VALID		(1 << 15)
	#define	LED2_USB3_MASK		0x7c00

#define GMII_PHYPAGE				0x1e
#define GMII_PHY_PAGE_SELECT			0x1f
	#define GMII_PHY_PGSEL_EXT	0x0007
	#define GMII_PHY_PGSEL_PAGE0	0x0000

/* local defines */
#define ASIX_BASE_NAME "axg"
#define USB_CTRL_SET_TIMEOUT 5000
#define USB_CTRL_GET_TIMEOUT 5000
#define USB_BULK_SEND_TIMEOUT 5000
#define USB_BULK_RECV_TIMEOUT 5000

#define AX_RX_URB_SIZE 1024 * 0x12
#define BLK_FRAME_SIZE 0x200
#define PHY_CONNECT_TIMEOUT 5000

#define TIMEOUT_RESOLUTION 50	/* ms */

#define FLAG_NONE			0
#define FLAG_TYPE_AX88179	(1U << 0)
#define FLAG_TYPE_AX88178a	(1U << 1)
#define FLAG_TYPE_DLINK_DUB1312	(1U << 2)
#define FLAG_TYPE_SITECOM	(1U << 3)
#define FLAG_TYPE_SAMSUNG	(1U << 4)
#define FLAG_TYPE_LENOVO	(1U << 5)

/* local vars */
static const struct {
	unsigned char ctrl, timer_l, timer_h, size, ifg;
} AX88179_BULKIN_SIZE[] =	{
	{7, 0x4f, 0,	0x02, 0xff},
	{7, 0x20, 3,	0x03, 0xff},
	{7, 0xae, 7,	0x04, 0xff},
	{7, 0xcc, 0x4c, 0x04, 8},
};

static int curr_eth_dev; /* index for name of next device detected */

/* driver private */
struct asix_private {
	int flags;
	int rx_urb_size;
	int maxpacketsize;
};

/*
 * Asix infrastructure commands
 */
static int asix_write_cmd(struct ueth_data *dev, u8 cmd, u16 value, u16 index,
			     u16 size, void *data)
{
	int len;
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, size);

	debug("asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
	      cmd, value, index, size);

	memcpy(buf, data, size);

	len = usb_control_msg(
		dev->pusb_dev,
		usb_sndctrlpipe(dev->pusb_dev, 0),
		cmd,
		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		value,
		index,
		buf,
		size,
		USB_CTRL_SET_TIMEOUT);

	return len == size ? 0 : ECOMM;
}

static int asix_read_cmd(struct ueth_data *dev, u8 cmd, u16 value, u16 index,
			    u16 size, void *data)
{
	int len;
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, size);

	debug("asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
	      cmd, value, index, size);

	len = usb_control_msg(
		dev->pusb_dev,
		usb_rcvctrlpipe(dev->pusb_dev, 0),
		cmd,
		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		value,
		index,
		buf,
		size,
		USB_CTRL_GET_TIMEOUT);

	memcpy(data, buf, size);

	return len == size ? 0 : ECOMM;
}

static int asix_read_mac(struct eth_device *eth)
{
	struct ueth_data *dev = (struct ueth_data *)eth->priv;
	u8 buf[ETH_ALEN];

	asix_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, 6, 6, buf);
	debug("asix_read_mac() returning %02x:%02x:%02x:%02x:%02x:%02x\n",
	      buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);

	memcpy(eth->enetaddr, buf, ETH_ALEN);

	return 0;
}

static int asix_write_mac(struct eth_device *eth)
{
	struct ueth_data *dev = (struct ueth_data *)eth->priv;
	int ret;

	ret = asix_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
				 ETH_ALEN, eth->enetaddr);
	if (ret < 0)
		debug("Failed to set MAC address: %02x\n", ret);

	return ret;
}

static int asix_basic_reset(struct ueth_data *dev)
{
	struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv;
	u8 buf[5];
	u16 *tmp16;
	u8 *tmp;

	tmp16 = (u16 *)buf;
	tmp = (u8 *)buf;

	/* Power up ethernet PHY */
	*tmp16 = 0;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);

	*tmp16 = AX_PHYPWR_RSTCTL_IPRL;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
	mdelay(200);

	*tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
	mdelay(200);

	/* RX bulk configuration */
	memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);

	dev_priv->rx_urb_size = 128 * 20;

	/* Water Level configuration */
	*tmp = 0x34;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);

	*tmp = 0x52;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, 1, 1, tmp);

	/* Enable checksum offload */
	*tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
	       AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);

	*tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
	       AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);

	/* Configure RX control register => start operation */
	*tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
		 AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16);

	*tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
	       AX_MONITOR_MODE_RWMP;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);

	/* Configure default medium type => giga */
	*tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
		 AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX |
		 AX_MEDIUM_GIGAMODE | AX_MEDIUM_JUMBO_EN;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, tmp16);

	u16 adv = 0;
	adv = ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_LPACK |
	      ADVERTISE_NPAGE | ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP;
	asix_write_cmd(dev, AX_ACCESS_PHY, 0x03, MII_ADVERTISE, 2, &adv);

	adv = ADVERTISE_1000FULL;
	asix_write_cmd(dev, AX_ACCESS_PHY, 0x03, MII_CTRL1000, 2, &adv);

	return 0;
}

static int asix_wait_link(struct ueth_data *dev)
{
	int timeout = 0;
	int link_detected;
	u8 buf[2];
	u16 *tmp16;

	tmp16 = (u16 *)buf;

	do {
		asix_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
			      MII_BMSR, 2, buf);
		link_detected = *tmp16 & BMSR_LSTATUS;
		if (!link_detected) {
			if (timeout == 0)
				printf("Waiting for Ethernet connection... ");
			mdelay(TIMEOUT_RESOLUTION);
			timeout += TIMEOUT_RESOLUTION;
		}
	} while (!link_detected && timeout < PHY_CONNECT_TIMEOUT);

	if (link_detected) {
		if (timeout > 0)
			printf("done.\n");
		return 0;
	} else {
		printf("unable to connect.\n");
		return -ENETUNREACH;
	}
}

/*
 * Asix callbacks
 */
static int asix_init(struct eth_device *eth, bd_t *bd)
{
	struct ueth_data *dev = (struct ueth_data *)eth->priv;
	struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv;
	u8 buf[2], tmp[5], link_sts;
	u16 *tmp16, mode;


	tmp16 = (u16 *)buf;

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

	/* Configure RX control register => start operation */
	*tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
		 AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
	if (asix_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16) != 0)
		goto out_err;

	if (asix_wait_link(dev) != 0) {
		/*reset device and try again*/
		printf("Reset Ethernet Device\n");
		asix_basic_reset(dev);
		if (asix_wait_link(dev) != 0)
			goto out_err;
	}

	/* Configure link */
	mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
	       AX_MEDIUM_RXFLOW_CTRLEN;

	asix_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS,
		      1, 1, &link_sts);

	asix_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
		      GMII_PHY_PHYSR, 2, tmp16);

	if (!(*tmp16 & GMII_PHY_PHYSR_LINK)) {
		return 0;
	} else if (GMII_PHY_PHYSR_GIGA == (*tmp16 & GMII_PHY_PHYSR_SMASK)) {
		mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ |
			AX_MEDIUM_JUMBO_EN;

		if (link_sts & AX_USB_SS)
			memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
		else if (link_sts & AX_USB_HS)
			memcpy(tmp, &AX88179_BULKIN_SIZE[1], 5);
		else
			memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
	} else if (GMII_PHY_PHYSR_100 == (*tmp16 & GMII_PHY_PHYSR_SMASK)) {
		mode |= AX_MEDIUM_PS;

		if (link_sts & (AX_USB_SS | AX_USB_HS))
			memcpy(tmp, &AX88179_BULKIN_SIZE[2], 5);
		else
			memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
	} else {
		memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
	}

	/* RX bulk configuration */
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);

	dev_priv->rx_urb_size = (1024 * (tmp[3] + 2));
	if (*tmp16 & GMII_PHY_PHYSR_FULL)
		mode |= AX_MEDIUM_FULL_DUPLEX;
	asix_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
		       2, 2, &mode);

	return 0;
out_err:
	return -1;
}

static int asix_send(struct eth_device *eth, void *packet, int length)
{
	struct ueth_data *dev = (struct ueth_data *)eth->priv;
	struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv;

	int err;
	u32 packet_len, tx_hdr2;
	int actual_len, framesize;
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
				 PKTSIZE + (2 * sizeof(packet_len)));

	debug("** %s(), len %d\n", __func__, length);

	packet_len = length;
	cpu_to_le32s(&packet_len);

	memcpy(msg, &packet_len, sizeof(packet_len));
	framesize = dev_priv->maxpacketsize;
	tx_hdr2 = 0;
	if (((length + 8) % framesize) == 0)
		tx_hdr2 |= 0x80008000;	/* Enable padding */

	cpu_to_le32s(&tx_hdr2);

	memcpy(msg + sizeof(packet_len), &tx_hdr2, sizeof(tx_hdr2));

	memcpy(msg + sizeof(packet_len) + sizeof(tx_hdr2),
	       (void *)packet, length);

	err = usb_bulk_msg(dev->pusb_dev,
				usb_sndbulkpipe(dev->pusb_dev, dev->ep_out),
				(void *)msg,
				length + sizeof(packet_len) + sizeof(tx_hdr2),
				&actual_len,
				USB_BULK_SEND_TIMEOUT);
	debug("Tx: len = %u, actual = %u, err = %d\n",
	      length + sizeof(packet_len), actual_len, err);

	return err;
}

static int asix_recv(struct eth_device *eth)
{
	struct ueth_data *dev = (struct ueth_data *)eth->priv;
	struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv;

	u16 frame_pos;
	int err;
	int actual_len;

	int pkt_cnt;
	u32 rx_hdr;
	u16 hdr_off;
	u32 *pkt_hdr;
	ALLOC_CACHE_ALIGN_BUFFER(u8, recv_buf, dev_priv->rx_urb_size);

	actual_len = -1;

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

	err = usb_bulk_msg(dev->pusb_dev,
				usb_rcvbulkpipe(dev->pusb_dev, dev->ep_in),
				(void *)recv_buf,
				dev_priv->rx_urb_size,
				&actual_len,
				USB_BULK_RECV_TIMEOUT);
	debug("Rx: len = %u, actual = %u, err = %d\n", dev_priv->rx_urb_size,
	      actual_len, err);

	if (err != 0) {
		debug("Rx: failed to receive\n");
		return -ECOMM;
	}
	if (actual_len > dev_priv->rx_urb_size) {
		debug("Rx: received too many bytes %d\n", actual_len);
		return -EMSGSIZE;
	}


	rx_hdr = *(u32 *)(recv_buf + actual_len - 4);
	le32_to_cpus(&pkt_hdr);

	pkt_cnt = (u16)rx_hdr;
	hdr_off = (u16)(rx_hdr >> 16);
	pkt_hdr = (u32 *)(recv_buf + hdr_off);


	frame_pos = 0;

	while (pkt_cnt--) {
		u16 pkt_len;

		le32_to_cpus(pkt_hdr);
		pkt_len = (*pkt_hdr >> 16) & 0x1fff;

		frame_pos += 2;

		net_process_received_packet(recv_buf + frame_pos, pkt_len);

		pkt_hdr++;
		frame_pos += ((pkt_len + 7) & 0xFFF8)-2;

		if (pkt_cnt == 0)
			return 0;
	}
	return err;
}

static void asix_halt(struct eth_device *eth)
{
	debug("** %s()\n", __func__);
}

/*
 * Asix probing functions
 */
void ax88179_eth_before_probe(void)
{
	curr_eth_dev = 0;
}

struct asix_dongle {
	unsigned short vendor;
	unsigned short product;
	int flags;
};

static const struct asix_dongle asix_dongles[] = {
	{ 0x0b95, 0x1790, FLAG_TYPE_AX88179 },
	{ 0x0b95, 0x178a, FLAG_TYPE_AX88178a },
	{ 0x2001, 0x4a00, FLAG_TYPE_DLINK_DUB1312 },
	{ 0x0df6, 0x0072, FLAG_TYPE_SITECOM },
	{ 0x04e8, 0xa100, FLAG_TYPE_SAMSUNG },
	{ 0x17ef, 0x304b, FLAG_TYPE_LENOVO },
	{ 0x0000, 0x0000, FLAG_NONE }	/* END - Do not remove */
};

/* Probe to see if a new device is actually an asix device */
int ax88179_eth_probe(struct usb_device *dev, unsigned int ifnum,
		      struct ueth_data *ss)
{
	struct usb_interface *iface;
	struct usb_interface_descriptor *iface_desc;
	struct asix_private *dev_priv;
	int ep_in_found = 0, ep_out_found = 0;
	int i;

	/* let's examine the device now */
	iface = &dev->config.if_desc[ifnum];
	iface_desc = &dev->config.if_desc[ifnum].desc;

	for (i = 0; asix_dongles[i].vendor != 0; i++) {
		if (dev->descriptor.idVendor == asix_dongles[i].vendor &&
		    dev->descriptor.idProduct == asix_dongles[i].product)
			/* Found a supported dongle */
			break;
	}

	if (asix_dongles[i].vendor == 0)
		return 0;

	memset(ss, 0, sizeof(struct ueth_data));

	/* At this point, we know we've got a live one */
	debug("\n\nUSB Ethernet device detected: %#04x:%#04x\n",
	      dev->descriptor.idVendor, dev->descriptor.idProduct);

	/* Initialize the ueth_data structure with some useful info */
	ss->ifnum = ifnum;
	ss->pusb_dev = dev;
	ss->subclass = iface_desc->bInterfaceSubClass;
	ss->protocol = iface_desc->bInterfaceProtocol;

	/* alloc driver private */
	ss->dev_priv = calloc(1, sizeof(struct asix_private));
	if (!ss->dev_priv)
		return 0;
	dev_priv = ss->dev_priv;
	dev_priv->flags = asix_dongles[i].flags;

	/*
	 * We are expecting a minimum of 3 endpoints - in, out (bulk), and
	 * int. We will ignore any others.
	 */
	for (i = 0; i < iface_desc->bNumEndpoints; i++) {
		/* is it an interrupt endpoint? */
		if ((iface->ep_desc[i].bmAttributes &
		    USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
			ss->ep_int = iface->ep_desc[i].bEndpointAddress &
				USB_ENDPOINT_NUMBER_MASK;
			ss->irqinterval = iface->ep_desc[i].bInterval;
			continue;
		}

		/* is it an BULK endpoint? */
		if (!((iface->ep_desc[i].bmAttributes &
		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK))
			continue;

		u8 ep_addr = iface->ep_desc[i].bEndpointAddress;
		if ((ep_addr & USB_DIR_IN) && !ep_in_found) {
			ss->ep_in = ep_addr &
				USB_ENDPOINT_NUMBER_MASK;
			ep_in_found = 1;
		}
		if (!(ep_addr & USB_DIR_IN) && !ep_out_found) {
			ss->ep_out = ep_addr &
				USB_ENDPOINT_NUMBER_MASK;
			dev_priv->maxpacketsize =
				dev->epmaxpacketout[AX_ENDPOINT_OUT];
			ep_out_found = 1;
		}
	}
	debug("Endpoints In %d Out %d Int %d\n",
	      ss->ep_in, ss->ep_out, ss->ep_int);

	/* Do some basic sanity checks, and bail if we find a problem */
	if (usb_set_interface(dev, iface_desc->bInterfaceNumber, 0) ||
	    !ss->ep_in || !ss->ep_out || !ss->ep_int) {
		debug("Problems with device\n");
		return 0;
	}
	dev->privptr = (void *)ss;
	return 1;
}

int ax88179_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
				struct eth_device *eth)
{
	if (!eth) {
		debug("%s: missing parameter.\n", __func__);
		return 0;
	}
	sprintf(eth->name, "%s%d", ASIX_BASE_NAME, curr_eth_dev++);
	eth->init = asix_init;
	eth->send = asix_send;
	eth->recv = asix_recv;
	eth->halt = asix_halt;
	eth->write_hwaddr = asix_write_mac;
	eth->priv = ss;

	if (asix_basic_reset(ss))
		return 0;

	/* Get the MAC address */
	if (asix_read_mac(eth))
		return 0;
	debug("MAC %pM\n", eth->enetaddr);

	return 1;
}
