 /***************************************************************************
 *
 * Copyright (C) 2007-2010 SMSC
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *****************************************************************************/

#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/crc32.h>
#include <linux/usb/usbnet.h>
#include "smsc75xx.h"

#define SMSC_CHIPNAME			"smsc75xx"
#define SMSC_DRIVER_VERSION		"1.0.0"
#define HS_USB_PKT_SIZE			(512)
#define FS_USB_PKT_SIZE			(64)
#define DEFAULT_HS_BURST_CAP_SIZE	(16 * 1024 + 5 * HS_USB_PKT_SIZE)
#define DEFAULT_FS_BURST_CAP_SIZE	(6 * 1024 + 33 * FS_USB_PKT_SIZE)
#define DEFAULT_BULK_IN_DELAY		(0x00002000)
#define MAX_SINGLE_PACKET_SIZE		(9000)
#define LAN75XX_EEPROM_MAGIC		(0x7500)
#define EEPROM_MAC_OFFSET		(0x01)
#define DEFAULT_TX_CSUM_ENABLE		(true)
#define DEFAULT_RX_CSUM_ENABLE		(true)
#define DEFAULT_TSO_ENABLE		(true)
#define SMSC75XX_INTERNAL_PHY_ID	(1)
#define SMSC75XX_TX_OVERHEAD		(8)
#define MAX_RX_FIFO_SIZE		(20 * 1024)
#define MAX_TX_FIFO_SIZE		(12 * 1024)
#define USB_VENDOR_ID_SMSC		(0x0424)
#define USB_PRODUCT_ID_LAN7500		(0x7500)
#define USB_PRODUCT_ID_LAN7505		(0x7505)

#define check_warn(ret, fmt, args...) \
	({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })

#define check_warn_return(ret, fmt, args...) \
	({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } })

#define check_warn_goto_done(ret, fmt, args...) \
	({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } })

struct smsc75xx_priv {
	struct usbnet *dev;
	u32 rfe_ctl;
	u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN];
	bool use_rx_csum;
	struct mutex dataport_mutex;
	spinlock_t rfe_ctl_lock;
	struct work_struct set_multicast;
};

struct usb_context {
	struct usb_ctrlrequest req;
	struct usbnet *dev;
};

static int turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");

static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,
					  u32 *data)
{
	u32 *buf = kmalloc(4, GFP_KERNEL);
	int ret;

	BUG_ON(!dev);

	if (!buf)
		return -ENOMEM;

	ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
		USB_VENDOR_REQUEST_READ_REGISTER,
		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		00, index, buf, 4, USB_CTRL_GET_TIMEOUT);

	if (unlikely(ret < 0))
		netdev_warn(dev->net,
			"Failed to read register index 0x%08x", index);

	le32_to_cpus(buf);
	*data = *buf;
	kfree(buf);

	return ret;
}

static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
					   u32 data)
{
	u32 *buf = kmalloc(4, GFP_KERNEL);
	int ret;

	BUG_ON(!dev);

	if (!buf)
		return -ENOMEM;

	*buf = data;
	cpu_to_le32s(buf);

	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
		USB_VENDOR_REQUEST_WRITE_REGISTER,
		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
		00, index, buf, 4, USB_CTRL_SET_TIMEOUT);

	if (unlikely(ret < 0))
		netdev_warn(dev->net,
			"Failed to write register index 0x%08x", index);

	kfree(buf);

	return ret;
}

/* Loop until the read is completed with timeout
 * called with phy_mutex held */
static int smsc75xx_phy_wait_not_busy(struct usbnet *dev)
{
	unsigned long start_time = jiffies;
	u32 val;
	int ret;

	do {
		ret = smsc75xx_read_reg(dev, MII_ACCESS, &val);
		check_warn_return(ret, "Error reading MII_ACCESS");

		if (!(val & MII_ACCESS_BUSY))
			return 0;
	} while (!time_after(jiffies, start_time + HZ));

	return -EIO;
}

static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
{
	struct usbnet *dev = netdev_priv(netdev);
	u32 val, addr;
	int ret;

	mutex_lock(&dev->phy_mutex);

	/* confirm MII not busy */
	ret = smsc75xx_phy_wait_not_busy(dev);
	check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_read");

	/* set the address, index & direction (read from PHY) */
	phy_id &= dev->mii.phy_id_mask;
	idx &= dev->mii.reg_num_mask;
	addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
		| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
		| MII_ACCESS_READ;
	ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
	check_warn_goto_done(ret, "Error writing MII_ACCESS");

	ret = smsc75xx_phy_wait_not_busy(dev);
	check_warn_goto_done(ret, "Timed out reading MII reg %02X", idx);

	ret = smsc75xx_read_reg(dev, MII_DATA, &val);
	check_warn_goto_done(ret, "Error reading MII_DATA");

	ret = (u16)(val & 0xFFFF);

done:
	mutex_unlock(&dev->phy_mutex);
	return ret;
}

static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
				int regval)
{
	struct usbnet *dev = netdev_priv(netdev);
	u32 val, addr;
	int ret;

	mutex_lock(&dev->phy_mutex);

	/* confirm MII not busy */
	ret = smsc75xx_phy_wait_not_busy(dev);
	check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_write");

	val = regval;
	ret = smsc75xx_write_reg(dev, MII_DATA, val);
	check_warn_goto_done(ret, "Error writing MII_DATA");

	/* set the address, index & direction (write to PHY) */
	phy_id &= dev->mii.phy_id_mask;
	idx &= dev->mii.reg_num_mask;
	addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
		| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
		| MII_ACCESS_WRITE;
	ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
	check_warn_goto_done(ret, "Error writing MII_ACCESS");

	ret = smsc75xx_phy_wait_not_busy(dev);
	check_warn_goto_done(ret, "Timed out writing MII reg %02X", idx);

done:
	mutex_unlock(&dev->phy_mutex);
}

static int smsc75xx_wait_eeprom(struct usbnet *dev)
{
	unsigned long start_time = jiffies;
	u32 val;
	int ret;

	do {
		ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
		check_warn_return(ret, "Error reading E2P_CMD");

		if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT))
			break;
		udelay(40);
	} while (!time_after(jiffies, start_time + HZ));

	if (val & (E2P_CMD_TIMEOUT | E2P_CMD_BUSY)) {
		netdev_warn(dev->net, "EEPROM read operation timeout");
		return -EIO;
	}

	return 0;
}

static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev)
{
	unsigned long start_time = jiffies;
	u32 val;
	int ret;

	do {
		ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
		check_warn_return(ret, "Error reading E2P_CMD");

		if (!(val & E2P_CMD_BUSY))
			return 0;

		udelay(40);
	} while (!time_after(jiffies, start_time + HZ));

	netdev_warn(dev->net, "EEPROM is busy");
	return -EIO;
}

static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length,
				u8 *data)
{
	u32 val;
	int i, ret;

	BUG_ON(!dev);
	BUG_ON(!data);

	ret = smsc75xx_eeprom_confirm_not_busy(dev);
	if (ret)
		return ret;

	for (i = 0; i < length; i++) {
		val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR);
		ret = smsc75xx_write_reg(dev, E2P_CMD, val);
		check_warn_return(ret, "Error writing E2P_CMD");

		ret = smsc75xx_wait_eeprom(dev);
		if (ret < 0)
			return ret;

		ret = smsc75xx_read_reg(dev, E2P_DATA, &val);
		check_warn_return(ret, "Error reading E2P_DATA");

		data[i] = val & 0xFF;
		offset++;
	}

	return 0;
}

static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
				 u8 *data)
{
	u32 val;
	int i, ret;

	BUG_ON(!dev);
	BUG_ON(!data);

	ret = smsc75xx_eeprom_confirm_not_busy(dev);
	if (ret)
		return ret;

	/* Issue write/erase enable command */
	val = E2P_CMD_BUSY | E2P_CMD_EWEN;
	ret = smsc75xx_write_reg(dev, E2P_CMD, val);
	check_warn_return(ret, "Error writing E2P_CMD");

	ret = smsc75xx_wait_eeprom(dev);
	if (ret < 0)
		return ret;

	for (i = 0; i < length; i++) {

		/* Fill data register */
		val = data[i];
		ret = smsc75xx_write_reg(dev, E2P_DATA, val);
		check_warn_return(ret, "Error writing E2P_DATA");

		/* Send "write" command */
		val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR);
		ret = smsc75xx_write_reg(dev, E2P_CMD, val);
		check_warn_return(ret, "Error writing E2P_CMD");

		ret = smsc75xx_wait_eeprom(dev);
		if (ret < 0)
			return ret;

		offset++;
	}

	return 0;
}

static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev)
{
	int i, ret;

	for (i = 0; i < 100; i++) {
		u32 dp_sel;
		ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
		check_warn_return(ret, "Error reading DP_SEL");

		if (dp_sel & DP_SEL_DPRDY)
			return 0;

		udelay(40);
	}

	netdev_warn(dev->net, "smsc75xx_dataport_wait_not_busy timed out");

	return -EIO;
}

static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr,
				   u32 length, u32 *buf)
{
	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
	u32 dp_sel;
	int i, ret;

	mutex_lock(&pdata->dataport_mutex);

	ret = smsc75xx_dataport_wait_not_busy(dev);
	check_warn_goto_done(ret, "smsc75xx_dataport_write busy on entry");

	ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
	check_warn_goto_done(ret, "Error reading DP_SEL");

	dp_sel &= ~DP_SEL_RSEL;
	dp_sel |= ram_select;
	ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel);
	check_warn_goto_done(ret, "Error writing DP_SEL");

	for (i = 0; i < length; i++) {
		ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i);
		check_warn_goto_done(ret, "Error writing DP_ADDR");

		ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]);
		check_warn_goto_done(ret, "Error writing DP_DATA");

		ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE);
		check_warn_goto_done(ret, "Error writing DP_CMD");

		ret = smsc75xx_dataport_wait_not_busy(dev);
		check_warn_goto_done(ret, "smsc75xx_dataport_write timeout");
	}

done:
	mutex_unlock(&pdata->dataport_mutex);
	return ret;
}

/* returns hash bit number for given MAC address */
static u32 smsc75xx_hash(char addr[ETH_ALEN])
{
	return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff;
}

static void smsc75xx_deferred_multicast_write(struct work_struct *param)
{
	struct smsc75xx_priv *pdata =
		container_of(param, struct smsc75xx_priv, set_multicast);
	struct usbnet *dev = pdata->dev;
	int ret;

	netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x",
		pdata->rfe_ctl);

	smsc75xx_dataport_write(dev, DP_SEL_VHF, DP_SEL_VHF_VLAN_LEN,
		DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table);

	ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
	check_warn(ret, "Error writing RFE_CRL");
}

static void smsc75xx_set_multicast(struct net_device *netdev)
{
	struct usbnet *dev = netdev_priv(netdev);
	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
	unsigned long flags;
	int i;

	spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);

	pdata->rfe_ctl &=
		~(RFE_CTL_AU | RFE_CTL_AM | RFE_CTL_DPF | RFE_CTL_MHF);
	pdata->rfe_ctl |= RFE_CTL_AB;

	for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++)
		pdata->multicast_hash_table[i] = 0;

	if (dev->net->flags & IFF_PROMISC) {
		netif_dbg(dev, drv, dev->net, "promiscuous mode enabled");
		pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_AU;
	} else if (dev->net->flags & IFF_ALLMULTI) {
		netif_dbg(dev, drv, dev->net, "receive all multicast enabled");
		pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_DPF;
	} else if (!netdev_mc_empty(dev->net)) {
		struct dev_mc_list *mc_list;

		netif_dbg(dev, drv, dev->net, "receive multicast hash filter");

		pdata->rfe_ctl |= RFE_CTL_MHF | RFE_CTL_DPF;

		netdev_for_each_mc_addr(mc_list, netdev) {
			u32 bitnum = smsc75xx_hash(mc_list->dmi_addr);
			pdata->multicast_hash_table[bitnum / 32] |=
				(1 << (bitnum % 32));
		}
	} else {
		netif_dbg(dev, drv, dev->net, "receive own packets only");
		pdata->rfe_ctl |= RFE_CTL_DPF;
	}

	spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);

	/* defer register writes to a sleepable context */
	schedule_work(&pdata->set_multicast);
}

static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex,
					    u16 lcladv, u16 rmtadv)
{
	u32 flow = 0, fct_flow = 0;
	int ret;

	if (duplex == DUPLEX_FULL) {
		u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);

		if (cap & FLOW_CTRL_TX) {
			flow = (FLOW_TX_FCEN | 0xFFFF);
			/* set fct_flow thresholds to 20% and 80% */
			fct_flow = (8 << 8) | 32;
		}

		if (cap & FLOW_CTRL_RX)
			flow |= FLOW_RX_FCEN;

		netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s",
			(cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
			(cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
	} else {
		netif_dbg(dev, link, dev->net, "half duplex");
	}

	ret = smsc75xx_write_reg(dev, FLOW, flow);
	check_warn_return(ret, "Error writing FLOW");

	ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow);
	check_warn_return(ret, "Error writing FCT_FLOW");

	return 0;
}

static int smsc75xx_link_reset(struct usbnet *dev)
{
	struct mii_if_info *mii = &dev->mii;
	struct ethtool_cmd ecmd;
	u16 lcladv, rmtadv;
	int ret;

	/* clear interrupt status */
	ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
	check_warn_return(ret, "Error reading PHY_INT_SRC");

	ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
	check_warn_return(ret, "Error writing INT_STS");

	mii_check_media(mii, 1, 1);
	mii_ethtool_gset(&dev->mii, &ecmd);
	lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
	rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA);

	netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x"
		" rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv);

	return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
}

static void smsc75xx_status(struct usbnet *dev, struct urb *urb)
{
	u32 intdata;

	if (urb->actual_length != 4) {
		netdev_warn(dev->net,
			"unexpected urb length %d", urb->actual_length);
		return;
	}

	memcpy(&intdata, urb->transfer_buffer, 4);
	le32_to_cpus(&intdata);

	netif_dbg(dev, link, dev->net, "intdata: 0x%08X", intdata);

	if (intdata & INT_ENP_PHY_INT)
		usbnet_defer_kevent(dev, EVENT_LINK_RESET);
	else
		netdev_warn(dev->net,
			"unexpected interrupt, intdata=0x%08X", intdata);
}

/* Enable or disable Rx checksum offload engine */
static int smsc75xx_set_rx_csum_offload(struct usbnet *dev)
{
	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);

	if (pdata->use_rx_csum)
		pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM;
	else
		pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM);

	spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);

	ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
	check_warn_return(ret, "Error writing RFE_CTL");

	return 0;
}

static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net)
{
	return MAX_EEPROM_SIZE;
}

static int smsc75xx_ethtool_get_eeprom(struct net_device *netdev,
				       struct ethtool_eeprom *ee, u8 *data)
{
	struct usbnet *dev = netdev_priv(netdev);

	ee->magic = LAN75XX_EEPROM_MAGIC;

	return smsc75xx_read_eeprom(dev, ee->offset, ee->len, data);
}

static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev,
				       struct ethtool_eeprom *ee, u8 *data)
{
	struct usbnet *dev = netdev_priv(netdev);

	if (ee->magic != LAN75XX_EEPROM_MAGIC) {
		netdev_warn(dev->net,
			"EEPROM: magic value mismatch: 0x%x", ee->magic);
		return -EINVAL;
	}

	return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data);
}

static u32 smsc75xx_ethtool_get_rx_csum(struct net_device *netdev)
{
	struct usbnet *dev = netdev_priv(netdev);
	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);

	return pdata->use_rx_csum;
}

static int smsc75xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
{
	struct usbnet *dev = netdev_priv(netdev);
	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);

	pdata->use_rx_csum = !!val;

	return smsc75xx_set_rx_csum_offload(dev);
}

static int smsc75xx_ethtool_set_tso(struct net_device *netdev, u32 data)
{
	if (data)
		netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
	else
		netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);

	return 0;
}

static const struct ethtool_ops smsc75xx_ethtool_ops = {
	.get_link	= usbnet_get_link,
	.nway_reset	= usbnet_nway_reset,
	.get_drvinfo	= usbnet_get_drvinfo,
	.get_msglevel	= usbnet_get_msglevel,
	.set_msglevel	= usbnet_set_msglevel,
	.get_settings	= usbnet_get_settings,
	.set_settings	= usbnet_set_settings,
	.get_eeprom_len	= smsc75xx_ethtool_get_eeprom_len,
	.get_eeprom	= smsc75xx_ethtool_get_eeprom,
	.set_eeprom	= smsc75xx_ethtool_set_eeprom,
	.get_tx_csum	= ethtool_op_get_tx_csum,
	.set_tx_csum	= ethtool_op_set_tx_hw_csum,
	.get_rx_csum	= smsc75xx_ethtool_get_rx_csum,
	.set_rx_csum	= smsc75xx_ethtool_set_rx_csum,
	.get_tso	= ethtool_op_get_tso,
	.set_tso	= smsc75xx_ethtool_set_tso,
};

static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
{
	struct usbnet *dev = netdev_priv(netdev);

	if (!netif_running(netdev))
		return -EINVAL;

	return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
}

static void smsc75xx_init_mac_address(struct usbnet *dev)
{
	/* try reading mac address from EEPROM */
	if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
			dev->net->dev_addr) == 0) {
		if (is_valid_ether_addr(dev->net->dev_addr)) {
			/* eeprom values are valid so use them */
			netif_dbg(dev, ifup, dev->net,
				"MAC address read from EEPROM");
			return;
		}
	}

	/* no eeprom, or eeprom values are invalid. generate random MAC */
	random_ether_addr(dev->net->dev_addr);
	netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr");
}

static int smsc75xx_set_mac_address(struct usbnet *dev)
{
	u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 |
		dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24;
	u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8;

	int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi);
	check_warn_return(ret, "Failed to write RX_ADDRH: %d", ret);

	ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo);
	check_warn_return(ret, "Failed to write RX_ADDRL: %d", ret);

	addr_hi |= ADDR_FILTX_FB_VALID;
	ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi);
	check_warn_return(ret, "Failed to write ADDR_FILTX: %d", ret);

	ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo);
	check_warn_return(ret, "Failed to write ADDR_FILTX+4: %d", ret);

	return 0;
}

static int smsc75xx_phy_initialize(struct usbnet *dev)
{
	int bmcr, timeout = 0;

	/* Initialize MII structure */
	dev->mii.dev = dev->net;
	dev->mii.mdio_read = smsc75xx_mdio_read;
	dev->mii.mdio_write = smsc75xx_mdio_write;
	dev->mii.phy_id_mask = 0x1f;
	dev->mii.reg_num_mask = 0x1f;
	dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;

	/* reset phy and wait for reset to complete */
	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);

	do {
		msleep(10);
		bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
		check_warn_return(bmcr, "Error reading MII_BMCR");
		timeout++;
	} while ((bmcr & MII_BMCR) && (timeout < 100));

	if (timeout >= 100) {
		netdev_warn(dev->net, "timeout on PHY Reset");
		return -EIO;
	}

	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
		ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
		ADVERTISE_PAUSE_ASYM);

	/* read to clear */
	smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
	check_warn_return(bmcr, "Error reading PHY_INT_SRC");

	smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
		PHY_INT_MASK_DEFAULT);
	mii_nway_restart(&dev->mii);

	netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
	return 0;
}

static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size)
{
	int ret = 0;
	u32 buf;
	bool rxenabled;

	ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
	check_warn_return(ret, "Failed to read MAC_RX: %d", ret);

	rxenabled = ((buf & MAC_RX_RXEN) != 0);

	if (rxenabled) {
		buf &= ~MAC_RX_RXEN;
		ret = smsc75xx_write_reg(dev, MAC_RX, buf);
		check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
	}

	/* add 4 to size for FCS */
	buf &= ~MAC_RX_MAX_SIZE;
	buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE);

	ret = smsc75xx_write_reg(dev, MAC_RX, buf);
	check_warn_return(ret, "Failed to write MAC_RX: %d", ret);

	if (rxenabled) {
		buf |= MAC_RX_RXEN;
		ret = smsc75xx_write_reg(dev, MAC_RX, buf);
		check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
	}

	return 0;
}

static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
{
	struct usbnet *dev = netdev_priv(netdev);

	int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu);
	check_warn_return(ret, "Failed to set mac rx frame length");

	return usbnet_change_mtu(netdev, new_mtu);
}

static int smsc75xx_reset(struct usbnet *dev)
{
	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
	u32 buf;
	int ret = 0, timeout;

	netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset");

	ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
	check_warn_return(ret, "Failed to read HW_CFG: %d", ret);

	buf |= HW_CFG_LRST;

	ret = smsc75xx_write_reg(dev, HW_CFG, buf);
	check_warn_return(ret, "Failed to write HW_CFG: %d", ret);

	timeout = 0;
	do {
		msleep(10);
		ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
		check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
		timeout++;
	} while ((buf & HW_CFG_LRST) && (timeout < 100));

	if (timeout >= 100) {
		netdev_warn(dev->net, "timeout on completion of Lite Reset");
		return -EIO;
	}

	netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY");

	ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
	check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);

	buf |= PMT_CTL_PHY_RST;

	ret = smsc75xx_write_reg(dev, PMT_CTL, buf);
	check_warn_return(ret, "Failed to write PMT_CTL: %d", ret);

	timeout = 0;
	do {
		msleep(10);
		ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
		check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
		timeout++;
	} while ((buf & PMT_CTL_PHY_RST) && (timeout < 100));

	if (timeout >= 100) {
		netdev_warn(dev->net, "timeout waiting for PHY Reset");
		return -EIO;
	}

	netif_dbg(dev, ifup, dev->net, "PHY reset complete");

	smsc75xx_init_mac_address(dev);

	ret = smsc75xx_set_mac_address(dev);
	check_warn_return(ret, "Failed to set mac address");

	netif_dbg(dev, ifup, dev->net, "MAC Address: %pM", dev->net->dev_addr);

	ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
	check_warn_return(ret, "Failed to read HW_CFG: %d", ret);

	netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x", buf);

	buf |= HW_CFG_BIR;

	ret = smsc75xx_write_reg(dev, HW_CFG, buf);
	check_warn_return(ret, "Failed to write HW_CFG: %d", ret);

	ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
	check_warn_return(ret, "Failed to read HW_CFG: %d", ret);

	netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after "
			"writing HW_CFG_BIR: 0x%08x", buf);

	if (!turbo_mode) {
		buf = 0;
		dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
	} else if (dev->udev->speed == USB_SPEED_HIGH) {
		buf = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
		dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
	} else {
		buf = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
		dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
	}

	netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld",
		(ulong)dev->rx_urb_size);

	ret = smsc75xx_write_reg(dev, BURST_CAP, buf);
	check_warn_return(ret, "Failed to write BURST_CAP: %d", ret);

	ret = smsc75xx_read_reg(dev, BURST_CAP, &buf);
	check_warn_return(ret, "Failed to read BURST_CAP: %d", ret);

	netif_dbg(dev, ifup, dev->net,
		"Read Value from BURST_CAP after writing: 0x%08x", buf);

	ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
	check_warn_return(ret, "Failed to write BULK_IN_DLY: %d", ret);

	ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf);
	check_warn_return(ret, "Failed to read BULK_IN_DLY: %d", ret);

	netif_dbg(dev, ifup, dev->net,
		"Read Value from BULK_IN_DLY after writing: 0x%08x", buf);

	if (turbo_mode) {
		ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
		check_warn_return(ret, "Failed to read HW_CFG: %d", ret);

		netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);

		buf |= (HW_CFG_MEF | HW_CFG_BCE);

		ret = smsc75xx_write_reg(dev, HW_CFG, buf);
		check_warn_return(ret, "Failed to write HW_CFG: %d", ret);

		ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
		check_warn_return(ret, "Failed to read HW_CFG: %d", ret);

		netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
	}

	/* set FIFO sizes */
	buf = (MAX_RX_FIFO_SIZE - 512) / 512;
	ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf);
	check_warn_return(ret, "Failed to write FCT_RX_FIFO_END: %d", ret);

	netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x", buf);

	buf = (MAX_TX_FIFO_SIZE - 512) / 512;
	ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf);
	check_warn_return(ret, "Failed to write FCT_TX_FIFO_END: %d", ret);

	netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x", buf);

	ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
	check_warn_return(ret, "Failed to write INT_STS: %d", ret);

	ret = smsc75xx_read_reg(dev, ID_REV, &buf);
	check_warn_return(ret, "Failed to read ID_REV: %d", ret);

	netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x", buf);

	/* Configure GPIO pins as LED outputs */
	ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf);
	check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret);

	buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL);
	buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL;

	ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf);
	check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret);

	ret = smsc75xx_write_reg(dev, FLOW, 0);
	check_warn_return(ret, "Failed to write FLOW: %d", ret);

	ret = smsc75xx_write_reg(dev, FCT_FLOW, 0);
	check_warn_return(ret, "Failed to write FCT_FLOW: %d", ret);

	/* Don't need rfe_ctl_lock during initialisation */
	ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
	check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);

	pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF;

	ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
	check_warn_return(ret, "Failed to write RFE_CTL: %d", ret);

	ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
	check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);

	netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl);

	/* Enable or disable checksum offload engines */
	ethtool_op_set_tx_hw_csum(dev->net, DEFAULT_TX_CSUM_ENABLE);
	ret = smsc75xx_set_rx_csum_offload(dev);
	check_warn_return(ret, "Failed to set rx csum offload: %d", ret);

	smsc75xx_ethtool_set_tso(dev->net, DEFAULT_TSO_ENABLE);

	smsc75xx_set_multicast(dev->net);

	ret = smsc75xx_phy_initialize(dev);
	check_warn_return(ret, "Failed to initialize PHY: %d", ret);

	ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf);
	check_warn_return(ret, "Failed to read INT_EP_CTL: %d", ret);

	/* enable PHY interrupts */
	buf |= INT_ENP_PHY_INT;

	ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
	check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret);

	ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
	check_warn_return(ret, "Failed to read MAC_TX: %d", ret);

	buf |= MAC_TX_TXEN;

	ret = smsc75xx_write_reg(dev, MAC_TX, buf);
	check_warn_return(ret, "Failed to write MAC_TX: %d", ret);

	netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x", buf);

	ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf);
	check_warn_return(ret, "Failed to read FCT_TX_CTL: %d", ret);

	buf |= FCT_TX_CTL_EN;

	ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf);
	check_warn_return(ret, "Failed to write FCT_TX_CTL: %d", ret);

	netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf);

	ret = smsc75xx_set_rx_max_frame_length(dev, 1514);
	check_warn_return(ret, "Failed to set max rx frame length");

	ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
	check_warn_return(ret, "Failed to read MAC_RX: %d", ret);

	buf |= MAC_RX_RXEN;

	ret = smsc75xx_write_reg(dev, MAC_RX, buf);
	check_warn_return(ret, "Failed to write MAC_RX: %d", ret);

	netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x", buf);

	ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf);
	check_warn_return(ret, "Failed to read FCT_RX_CTL: %d", ret);

	buf |= FCT_RX_CTL_EN;

	ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf);
	check_warn_return(ret, "Failed to write FCT_RX_CTL: %d", ret);

	netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x", buf);

	netif_dbg(dev, ifup, dev->net, "smsc75xx_reset, return 0");
	return 0;
}

static const struct net_device_ops smsc75xx_netdev_ops = {
	.ndo_open		= usbnet_open,
	.ndo_stop		= usbnet_stop,
	.ndo_start_xmit		= usbnet_start_xmit,
	.ndo_tx_timeout		= usbnet_tx_timeout,
	.ndo_change_mtu		= smsc75xx_change_mtu,
	.ndo_set_mac_address 	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_do_ioctl 		= smsc75xx_ioctl,
	.ndo_set_multicast_list = smsc75xx_set_multicast,
};

static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
{
	struct smsc75xx_priv *pdata = NULL;
	int ret;

	printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");

	ret = usbnet_get_endpoints(dev, intf);
	check_warn_return(ret, "usbnet_get_endpoints failed: %d", ret);

	dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv),
		GFP_KERNEL);

	pdata = (struct smsc75xx_priv *)(dev->data[0]);
	if (!pdata) {
		netdev_warn(dev->net, "Unable to allocate smsc75xx_priv");
		return -ENOMEM;
	}

	pdata->dev = dev;

	spin_lock_init(&pdata->rfe_ctl_lock);
	mutex_init(&pdata->dataport_mutex);

	INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write);

	pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;

	/* We have to advertise SG otherwise TSO cannot be enabled */
	dev->net->features |= NETIF_F_SG;

	/* Init all registers */
	ret = smsc75xx_reset(dev);

	dev->net->netdev_ops = &smsc75xx_netdev_ops;
	dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
	dev->net->flags |= IFF_MULTICAST;
	dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
	return 0;
}

static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
{
	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
	if (pdata) {
		netif_dbg(dev, ifdown, dev->net, "free pdata");
		kfree(pdata);
		pdata = NULL;
		dev->data[0] = 0;
	}
}

static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a,
				     u32 rx_cmd_b)
{
	if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) {
		skb->ip_summed = CHECKSUM_NONE;
	} else {
		skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT));
		skb->ip_summed = CHECKSUM_COMPLETE;
	}
}

static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);

	while (skb->len > 0) {
		u32 rx_cmd_a, rx_cmd_b, align_count, size;
		struct sk_buff *ax_skb;
		unsigned char *packet;

		memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a));
		le32_to_cpus(&rx_cmd_a);
		skb_pull(skb, 4);

		memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
		le32_to_cpus(&rx_cmd_b);
		skb_pull(skb, 4 + NET_IP_ALIGN);

		packet = skb->data;

		/* get the packet length */
		size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN;
		align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;

		if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
			netif_dbg(dev, rx_err, dev->net,
				"Error rx_cmd_a=0x%08x", rx_cmd_a);
			dev->net->stats.rx_errors++;
			dev->net->stats.rx_dropped++;

			if (rx_cmd_a & RX_CMD_A_FCS)
				dev->net->stats.rx_crc_errors++;
			else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT))
				dev->net->stats.rx_frame_errors++;
		} else {
			/* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
			if (unlikely(size > (ETH_FRAME_LEN + 12))) {
				netif_dbg(dev, rx_err, dev->net,
					"size err rx_cmd_a=0x%08x", rx_cmd_a);
				return 0;
			}

			/* last frame in this batch */
			if (skb->len == size) {
				if (pdata->use_rx_csum)
					smsc75xx_rx_csum_offload(skb, rx_cmd_a,
						rx_cmd_b);
				else
					skb->ip_summed = CHECKSUM_NONE;

				skb_trim(skb, skb->len - 4); /* remove fcs */
				skb->truesize = size + sizeof(struct sk_buff);

				return 1;
			}

			ax_skb = skb_clone(skb, GFP_ATOMIC);
			if (unlikely(!ax_skb)) {
				netdev_warn(dev->net, "Error allocating skb");
				return 0;
			}

			ax_skb->len = size;
			ax_skb->data = packet;
			skb_set_tail_pointer(ax_skb, size);

			if (pdata->use_rx_csum)
				smsc75xx_rx_csum_offload(ax_skb, rx_cmd_a,
					rx_cmd_b);
			else
				ax_skb->ip_summed = CHECKSUM_NONE;

			skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
			ax_skb->truesize = size + sizeof(struct sk_buff);

			usbnet_skb_return(dev, ax_skb);
		}

		skb_pull(skb, size);

		/* padding bytes before the next frame starts */
		if (skb->len)
			skb_pull(skb, align_count);
	}

	if (unlikely(skb->len < 0)) {
		netdev_warn(dev->net, "invalid rx length<0 %d", skb->len);
		return 0;
	}

	return 1;
}

static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev,
					 struct sk_buff *skb, gfp_t flags)
{
	u32 tx_cmd_a, tx_cmd_b;

	skb_linearize(skb);

	if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) {
		struct sk_buff *skb2 =
			skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags);
		dev_kfree_skb_any(skb);
		skb = skb2;
		if (!skb)
			return NULL;
	}

	tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS;

	if (skb->ip_summed == CHECKSUM_PARTIAL)
		tx_cmd_a |= TX_CMD_A_IPE | TX_CMD_A_TPE;

	if (skb_is_gso(skb)) {
		u16 mss = max(skb_shinfo(skb)->gso_size, TX_MSS_MIN);
		tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT) & TX_CMD_B_MSS;

		tx_cmd_a |= TX_CMD_A_LSO;
	} else {
		tx_cmd_b = 0;
	}

	skb_push(skb, 4);
	cpu_to_le32s(&tx_cmd_b);
	memcpy(skb->data, &tx_cmd_b, 4);

	skb_push(skb, 4);
	cpu_to_le32s(&tx_cmd_a);
	memcpy(skb->data, &tx_cmd_a, 4);

	return skb;
}

static const struct driver_info smsc75xx_info = {
	.description	= "smsc75xx USB 2.0 Gigabit Ethernet",
	.bind		= smsc75xx_bind,
	.unbind		= smsc75xx_unbind,
	.link_reset	= smsc75xx_link_reset,
	.reset		= smsc75xx_reset,
	.rx_fixup	= smsc75xx_rx_fixup,
	.tx_fixup	= smsc75xx_tx_fixup,
	.status		= smsc75xx_status,
	.flags		= FLAG_ETHER | FLAG_SEND_ZLP,
};

static const struct usb_device_id products[] = {
	{
		/* SMSC7500 USB Gigabit Ethernet Device */
		USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7500),
		.driver_info = (unsigned long) &smsc75xx_info,
	},
	{
		/* SMSC7500 USB Gigabit Ethernet Device */
		USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7505),
		.driver_info = (unsigned long) &smsc75xx_info,
	},
	{ },		/* END */
};
MODULE_DEVICE_TABLE(usb, products);

static struct usb_driver smsc75xx_driver = {
	.name		= SMSC_CHIPNAME,
	.id_table	= products,
	.probe		= usbnet_probe,
	.suspend	= usbnet_suspend,
	.resume		= usbnet_resume,
	.disconnect	= usbnet_disconnect,
};

static int __init smsc75xx_init(void)
{
	return usb_register(&smsc75xx_driver);
}
module_init(smsc75xx_init);

static void __exit smsc75xx_exit(void)
{
	usb_deregister(&smsc75xx_driver);
}
module_exit(smsc75xx_exit);

MODULE_AUTHOR("Nancy Lin");
MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
MODULE_DESCRIPTION("SMSC75XX USB 2.0 Gigabit Ethernet Devices");
MODULE_LICENSE("GPL");
