#include <common.h>
#include <usb/usb.h>
#include <usb/usbnet.h>
#include <asm/byteorder.h>
#include <errno.h>
#include <malloc.h>

static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
{
	return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
}

/* handles CDC Ethernet and many other network "bulk data" interfaces */
int usbnet_get_endpoints(struct usbnet *dev)
{
	struct usb_device	*udev = dev->udev;
	int				tmp;
	struct usb_interface_descriptor	*alt = NULL;
	struct usb_endpoint_descriptor	*in = NULL, *out = NULL;
	struct usb_endpoint_descriptor	*status = NULL;

	for (tmp = 0; tmp < udev->config.no_of_if; tmp++) {
		unsigned	ep;

		in = out = status = NULL;
		alt = &udev->config.if_desc[tmp];

		/* take the first altsetting with in-bulk + out-bulk;
		 * remember any status endpoint, just in case;
		 * ignore other endpoints and altsetttings.
		 */
		for (ep = 0; ep < alt->bNumEndpoints; ep++) {
			struct usb_endpoint_descriptor	*e;
			int				intr = 0;

			e = &alt->ep_desc[ep];
			switch (e->bmAttributes) {
			case USB_ENDPOINT_XFER_INT:
				if (!usb_endpoint_dir_in(e))
					continue;
				intr = 1;
				/* FALLTHROUGH */
			case USB_ENDPOINT_XFER_BULK:
				break;
			default:
				continue;
			}
			if (usb_endpoint_dir_in(e)) {
				if (!intr && !in)
					in = e;
				else if (intr && !status)
					status = e;
			} else {
				if (!out)
					out = e;
			}
		}
		if (in && out)
			break;
	}

	if (!alt || !in || !out)
		return -EINVAL;

	if (alt->bAlternateSetting != 0
			|| !(dev->driver_info->flags & FLAG_NO_SETINT)) {
		tmp = usb_set_interface (dev->udev, alt->bInterfaceNumber,
				alt->bAlternateSetting);
		if (tmp < 0)
			return tmp;
	}

	dev->in = usb_rcvbulkpipe (dev->udev,
			in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
	dev->out = usb_sndbulkpipe (dev->udev,
			out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
	dev_dbg(&dev->edev.dev, "found endpoints: IN=%d OUT=%d\n",
			in->bEndpointAddress, out->bEndpointAddress);

	return 0;
}
EXPORT_SYMBOL(usbnet_get_endpoints);

char tx_buffer[4096];

static int usbnet_send(struct eth_device *edev, void *eth_data, int data_length)
{
	struct usbnet		*dev = edev->priv;
	struct driver_info	*info = dev->driver_info;
	int			len, alen, ret;

	dev_dbg(&edev->dev, "%s\n",__func__);

	/* some devices want funky USB-level framing, for
	 * win32 driver (usually) and/or hardware quirks
	 */
        if(info->tx_fixup) {
                if(info->tx_fixup(dev, eth_data, data_length, tx_buffer, &len)) {
			dev_dbg(&edev->dev, "can't tx_fixup packet");
                        return 0;
                }
        } else {
                len = data_length;
                memmove(tx_buffer, (void*) eth_data, len);
        }

	/* don't assume the hardware handles USB_ZERO_PACKET
	 * NOTE:  strictly conforming cdc-ether devices should expect
	 * the ZLP here, but ignore the one-byte packet.
	 */
	if ((len % dev->maxpacket) == 0)
		tx_buffer[len++] = 0;

	ret = usb_bulk_msg(dev->udev, dev->out, tx_buffer, len, &alen, 1000);
	dev_dbg(&edev->dev, "%s: ret: %d len: %d alen: %d\n", __func__, ret, len, alen);

	return ret;
}

static char rx_buf[4096];

static int usbnet_recv(struct eth_device *edev)
{
	struct usbnet		*dev = (struct usbnet*) edev->priv;
	struct driver_info	*info = dev->driver_info;
	int len, ret, alen = 0;

	dev_dbg(&edev->dev, "%s\n",__func__);

	len = dev->rx_urb_size;

	ret = usb_bulk_msg(dev->udev, dev->in, rx_buf, len, &alen, 1000);
	if (ret)
		return ret;

	if (alen) {
		if (info->rx_fixup)
			return info->rx_fixup(dev, rx_buf, alen);
		else
			net_receive(rx_buf, alen);
	}

        return 0;
}

static int usbnet_init(struct eth_device *edev)
{
	struct usbnet		*dev = (struct usbnet*) edev->priv;
	struct driver_info      *info = dev->driver_info;
	int ret = 0;

	dev_dbg(&edev->dev, "%s\n",__func__);

	/* put into "known safe" state */
	if (info->reset)
		ret = info->reset(dev);

	if (ret) {
                dev_info(&edev->dev, "open reset fail (%d)", ret);
                return ret;
        }

	miidev_restart_aneg(&dev->miidev);

	return 0;
}

static int usbnet_open(struct eth_device *edev)
{
	struct usbnet		*dev = (struct usbnet*)edev->priv;

	dev_dbg(&edev->dev, "%s\n",__func__);

	if (miidev_wait_aneg(&dev->miidev))
		return -1;

	miidev_print_status(&dev->miidev);

	return 0;
}

static void usbnet_halt(struct eth_device *edev)
{
	dev_dbg(&edev->dev, "%s\n",__func__);
}

int usbnet_probe(struct usb_device *usbdev, const struct usb_device_id *prod)
{
	struct usbnet *undev;
	struct eth_device *edev;
	struct driver_info *info;
	int status;

	dev_dbg(&usbdev->dev, "%s\n", __func__);

	undev = xzalloc(sizeof (*undev));

	usbdev->drv_data = undev;

	edev = &undev->edev;
	undev->udev = usbdev;

	edev->open = usbnet_open,
	edev->init = usbnet_init,
	edev->send = usbnet_send,
	edev->recv = usbnet_recv,
	edev->halt = usbnet_halt,
	edev->priv = undev;

	info = (struct driver_info *)prod->driver_info;
	undev->driver_info = info;

	if (info->bind) {
		status = info->bind (undev);
		if (status < 0)
			goto out1;
	}

	if (!undev->rx_urb_size)
		undev->rx_urb_size = 1514; /* FIXME: What to put here? */
	undev->maxpacket = usb_maxpacket(undev->udev, undev->out);

	eth_register(edev);

	return 0;
out1:
	dev_dbg(&edev->dev, "err: %d\n", status);
	return status;
}

void usbnet_disconnect(struct usb_device *usbdev)
{
	struct usbnet *undev = usbdev->drv_data;
	struct eth_device *edev = &undev->edev;
	struct driver_info *info;

	eth_unregister(edev);
	unregister_device(&edev->dev);

	info = undev->driver_info;
	if (info->unbind)
		info->unbind(undev);

	free(undev);
}

