/*
 * Copyright (c) 2011 The Chromium OS Authors.
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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 <common.h>
#include <usb.h>

#include "usb_ether.h"

typedef void (*usb_eth_before_probe)(void);
typedef int (*usb_eth_probe)(struct usb_device *dev, unsigned int ifnum,
			struct ueth_data *ss);
typedef int (*usb_eth_get_info)(struct usb_device *dev, struct ueth_data *ss,
			struct eth_device *dev_desc);

struct usb_eth_prob_dev {
	usb_eth_before_probe	before_probe; /* optional */
	usb_eth_probe			probe;
	usb_eth_get_info		get_info;
};

/* driver functions go here, each bracketed by #ifdef CONFIG_USB_ETHER_xxx */
static const struct usb_eth_prob_dev prob_dev[] = {
#ifdef CONFIG_USB_ETHER_ASIX
	{
		.before_probe = asix_eth_before_probe,
		.probe = asix_eth_probe,
		.get_info = asix_eth_get_info,
	},
#endif
	{ },		/* END */
};

static int usb_max_eth_dev; /* number of highest available usb eth device */
static struct ueth_data usb_eth[USB_MAX_ETH_DEV];

/*******************************************************************************
 * tell if current ethernet device is a usb dongle
 */
int is_eth_dev_on_usb_host(void)
{
	int i;
	struct eth_device *dev = eth_get_dev();

	if (dev) {
		for (i = 0; i < usb_max_eth_dev; i++)
			if (&usb_eth[i].eth_dev == dev)
				return 1;
	}
	return 0;
}

/*
 * Given a USB device, ask each driver if it can support it, and attach it
 * to the first driver that says 'yes'
 */
static void probe_valid_drivers(struct usb_device *dev)
{
	int j;

	for (j = 0; prob_dev[j].probe && prob_dev[j].get_info; j++) {
		if (!prob_dev[j].probe(dev, 0, &usb_eth[usb_max_eth_dev]))
			continue;
		/*
		 * ok, it is a supported eth device. Get info and fill it in
		 */
		if (prob_dev[j].get_info(dev,
			&usb_eth[usb_max_eth_dev],
			&usb_eth[usb_max_eth_dev].eth_dev)) {
			/* found proper driver */
			/* register with networking stack */
			usb_max_eth_dev++;

			/*
			 * usb_max_eth_dev must be incremented prior to this
			 * call since eth_current_changed (internally called)
			 * relies on it
			 */
			eth_register(&usb_eth[usb_max_eth_dev - 1].eth_dev);
			break;
			}
		}
	}

/*******************************************************************************
 * scan the usb and reports device info
 * to the user if mode = 1
 * returns current device or -1 if no
 */
int usb_host_eth_scan(int mode)
{
	int i, old_async;
	struct usb_device *dev;


	if (mode == 1)
		printf("       scanning bus for ethernet devices... ");

	old_async = usb_disable_asynch(1); /* asynch transfer not allowed */

	for (i = 0; i < USB_MAX_ETH_DEV; i++)
		memset(&usb_eth[i], 0, sizeof(usb_eth[i]));

	for (i = 0; prob_dev[i].probe; i++) {
		if (prob_dev[i].before_probe)
			prob_dev[i].before_probe();
	}

	usb_max_eth_dev = 0;
	for (i = 0; i < USB_MAX_DEVICE; i++) {
		dev = usb_get_dev_index(i); /* get device */
		debug("i=%d\n", i);
		if (dev == NULL)
			break; /* no more devices avaiable */

		/* find valid usb_ether driver for this device, if any */
		probe_valid_drivers(dev);

		/* check limit */
		if (usb_max_eth_dev == USB_MAX_ETH_DEV) {
			printf("max USB Ethernet Device reached: %d stopping\n",
				usb_max_eth_dev);
			break;
		}
	} /* for */

	usb_disable_asynch(old_async); /* restore asynch value */
	printf("%d Ethernet Device(s) found\n", usb_max_eth_dev);
	if (usb_max_eth_dev > 0)
		return 0;
	return -1;
}
