/*
 * WUSB Wire Adapter: WLP interface
 * Driver for the Linux Network stack.
 *
 * Copyright (C) 2005-2006 Intel Corporation
 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 *
 * FIXME: docs
 *
 * This implements a very simple network driver for the WLP USB
 * device that is associated to a UWB (Ultra Wide Band) host.
 *
 * This is seen as an interface of a composite device. Once the UWB
 * host has an association to another WLP capable device, the
 * networking interface (aka WLP) can start to send packets back and
 * forth.
 *
 * Limitations:
 *
 *  - Hand cranked; can't ifup the interface until there is an association
 *
 *  - BW allocation very simplistic [see i1480u_mas_set() and callees].
 *
 *
 * ROADMAP:
 *
 *   ENTRY POINTS (driver model):
 *
 *     i1480u_driver_{exit,init}(): initialization of the driver.
 *
 *     i1480u_probe(): called by the driver code when a device
 *                     matching 'i1480u_id_table' is connected.
 *
 *                     This allocs a netdev instance, inits with
 *                     i1480u_add(), then registers_netdev().
 *         i1480u_init()
 *         i1480u_add()
 *
 *     i1480u_disconnect(): device has been disconnected/module
 *                          is being removed.
 *         i1480u_rm()
 */
#include <linux/if_arp.h>
#include <linux/etherdevice.h>

#include "i1480u-wlp.h"



static inline
void i1480u_init(struct i1480u *i1480u)
{
	/* nothing so far... doesn't it suck? */
	spin_lock_init(&i1480u->lock);
	INIT_LIST_HEAD(&i1480u->tx_list);
	spin_lock_init(&i1480u->tx_list_lock);
	wlp_options_init(&i1480u->options);
	edc_init(&i1480u->tx_errors);
	edc_init(&i1480u->rx_errors);
#ifdef i1480u_FLOW_CONTROL
	edc_init(&i1480u->notif_edc);
#endif
	stats_init(&i1480u->lqe_stats);
	stats_init(&i1480u->rssi_stats);
	wlp_init(&i1480u->wlp);
}

/**
 * Fill WLP device information structure
 *
 * The structure will contain a few character arrays, each ending with a
 * null terminated string. Each string has to fit (excluding terminating
 * character) into a specified range obtained from the WLP substack.
 *
 * It is still not clear exactly how this device information should be
 * obtained. Until we find out we use the USB device descriptor as backup, some
 * information elements have intuitive mappings, other not.
 */
static
void i1480u_fill_device_info(struct wlp *wlp, struct wlp_device_info *dev_info)
{
	struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
	struct usb_device *usb_dev = i1480u->usb_dev;
	/* Treat device name and model name the same */
	if (usb_dev->descriptor.iProduct) {
		usb_string(usb_dev, usb_dev->descriptor.iProduct,
			   dev_info->name, sizeof(dev_info->name));
		usb_string(usb_dev, usb_dev->descriptor.iProduct,
			   dev_info->model_name, sizeof(dev_info->model_name));
	}
	if (usb_dev->descriptor.iManufacturer)
		usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
			   dev_info->manufacturer,
			   sizeof(dev_info->manufacturer));
	scnprintf(dev_info->model_nr, sizeof(dev_info->model_nr), "%04x",
		  __le16_to_cpu(usb_dev->descriptor.bcdDevice));
	if (usb_dev->descriptor.iSerialNumber)
		usb_string(usb_dev, usb_dev->descriptor.iSerialNumber,
			   dev_info->serial, sizeof(dev_info->serial));
	/* FIXME: where should we obtain category? */
	dev_info->prim_dev_type.category = cpu_to_le16(WLP_DEV_CAT_OTHER);
	/* FIXME: Complete OUI and OUIsubdiv attributes */
}

#ifdef i1480u_FLOW_CONTROL
/**
 * Callback for the notification endpoint
 *
 * This mostly controls the xon/xoff protocol. In case of hard error,
 * we stop the queue. If not, we always retry.
 */
static
void i1480u_notif_cb(struct urb *urb, struct pt_regs *regs)
{
	struct i1480u *i1480u = urb->context;
	struct usb_interface *usb_iface = i1480u->usb_iface;
	struct device *dev = &usb_iface->dev;
	int result;

	switch (urb->status) {
	case 0:				/* Got valid data, do xon/xoff */
		switch (i1480u->notif_buffer[0]) {
		case 'N':
			dev_err(dev, "XOFF STOPPING queue at %lu\n", jiffies);
			netif_stop_queue(i1480u->net_dev);
			break;
		case 'A':
			dev_err(dev, "XON STARTING queue at %lu\n", jiffies);
			netif_start_queue(i1480u->net_dev);
			break;
		default:
			dev_err(dev, "NEP: unknown data 0x%02hhx\n",
				i1480u->notif_buffer[0]);
		}
		break;
	case -ECONNRESET:		/* Controlled situation ... */
	case -ENOENT:			/* we killed the URB... */
		dev_err(dev, "NEP: URB reset/noent %d\n", urb->status);
		goto error;
	case -ESHUTDOWN:		/* going away! */
		dev_err(dev, "NEP: URB down %d\n", urb->status);
		goto error;
	default:			/* Retry unless it gets ugly */
		if (edc_inc(&i1480u->notif_edc, EDC_MAX_ERRORS,
			    EDC_ERROR_TIMEFRAME)) {
			dev_err(dev, "NEP: URB max acceptable errors "
				"exceeded; resetting device\n");
			goto error_reset;
		}
		dev_err(dev, "NEP: URB error %d\n", urb->status);
		break;
	}
	result = usb_submit_urb(urb, GFP_ATOMIC);
	if (result < 0) {
		dev_err(dev, "NEP: Can't resubmit URB: %d; resetting device\n",
			result);
		goto error_reset;
	}
	return;

error_reset:
	wlp_reset_all(&i1480-wlp);
error:
	netif_stop_queue(i1480u->net_dev);
	return;
}
#endif

static const struct net_device_ops i1480u_netdev_ops = {
	.ndo_open	= i1480u_open,
	.ndo_stop 	= i1480u_stop,
	.ndo_start_xmit = i1480u_hard_start_xmit,
	.ndo_tx_timeout = i1480u_tx_timeout,
	.ndo_set_config = i1480u_set_config,
	.ndo_change_mtu = i1480u_change_mtu,
};

static
int i1480u_add(struct i1480u *i1480u, struct usb_interface *iface)
{
	int result = -ENODEV;
	struct wlp *wlp = &i1480u->wlp;
	struct usb_device *usb_dev = interface_to_usbdev(iface);
	struct net_device *net_dev = i1480u->net_dev;
	struct uwb_rc *rc;
	struct uwb_dev *uwb_dev;
#ifdef i1480u_FLOW_CONTROL
	struct usb_endpoint_descriptor *epd;
#endif

	i1480u->usb_dev = usb_get_dev(usb_dev);
	i1480u->usb_iface = iface;
	rc = uwb_rc_get_by_grandpa(&i1480u->usb_dev->dev);
	if (rc == NULL) {
		dev_err(&iface->dev, "Cannot get associated UWB Radio "
			"Controller\n");
		goto out;
	}
	wlp->xmit_frame = i1480u_xmit_frame;
	wlp->fill_device_info = i1480u_fill_device_info;
	wlp->stop_queue = i1480u_stop_queue;
	wlp->start_queue = i1480u_start_queue;
	result = wlp_setup(wlp, rc, net_dev);
	if (result < 0) {
		dev_err(&iface->dev, "Cannot setup WLP\n");
		goto error_wlp_setup;
	}
	result = 0;
	ether_setup(net_dev);			/* make it an etherdevice */
	uwb_dev = &rc->uwb_dev;
	/* FIXME: hookup address change notifications? */

	memcpy(net_dev->dev_addr, uwb_dev->mac_addr.data,
	       sizeof(net_dev->dev_addr));

	net_dev->hard_header_len = sizeof(struct untd_hdr_cmp)
		+ sizeof(struct wlp_tx_hdr)
		+ WLP_DATA_HLEN
		+ ETH_HLEN;
	net_dev->mtu = 3500;
	net_dev->tx_queue_len = 20;		/* FIXME: maybe use 1000? */

/*	net_dev->flags &= ~IFF_BROADCAST;	FIXME: BUG in firmware */
	/* FIXME: multicast disabled */
	net_dev->flags &= ~IFF_MULTICAST;
	net_dev->features &= ~NETIF_F_SG;
	net_dev->features &= ~NETIF_F_FRAGLIST;
	/* All NETIF_F_*_CSUM disabled */
	net_dev->features |= NETIF_F_HIGHDMA;
	net_dev->watchdog_timeo = 5*HZ;		/* FIXME: a better default? */

	net_dev->netdev_ops = &i1480u_netdev_ops;

#ifdef i1480u_FLOW_CONTROL
	/* Notification endpoint setup (submitted when we open the device) */
	i1480u->notif_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (i1480u->notif_urb == NULL) {
		dev_err(&iface->dev, "Unable to allocate notification URB\n");
		result = -ENOMEM;
		goto error_urb_alloc;
	}
	epd = &iface->cur_altsetting->endpoint[0].desc;
	usb_fill_int_urb(i1480u->notif_urb, usb_dev,
			 usb_rcvintpipe(usb_dev, epd->bEndpointAddress),
			 i1480u->notif_buffer, sizeof(i1480u->notif_buffer),
			 i1480u_notif_cb, i1480u, epd->bInterval);

#endif

	i1480u->tx_inflight.max = i1480u_TX_INFLIGHT_MAX;
	i1480u->tx_inflight.threshold = i1480u_TX_INFLIGHT_THRESHOLD;
	i1480u->tx_inflight.restart_ts = jiffies;
	usb_set_intfdata(iface, i1480u);
	return result;

#ifdef i1480u_FLOW_CONTROL
error_urb_alloc:
#endif
	wlp_remove(wlp);
error_wlp_setup:
	uwb_rc_put(rc);
out:
	usb_put_dev(i1480u->usb_dev);
	return result;
}

static void i1480u_rm(struct i1480u *i1480u)
{
	struct uwb_rc *rc = i1480u->wlp.rc;
	usb_set_intfdata(i1480u->usb_iface, NULL);
#ifdef i1480u_FLOW_CONTROL
	usb_kill_urb(i1480u->notif_urb);
	usb_free_urb(i1480u->notif_urb);
#endif
	wlp_remove(&i1480u->wlp);
	uwb_rc_put(rc);
	usb_put_dev(i1480u->usb_dev);
}

/** Just setup @net_dev's i1480u private data */
static void i1480u_netdev_setup(struct net_device *net_dev)
{
	struct i1480u *i1480u = netdev_priv(net_dev);
	/* Initialize @i1480u */
	memset(i1480u, 0, sizeof(*i1480u));
	i1480u_init(i1480u);
}

/**
 * Probe a i1480u interface and register it
 *
 * @iface:   USB interface to link to
 * @id:      USB class/subclass/protocol id
 * @returns: 0 if ok, < 0 errno code on error.
 *
 * Does basic housekeeping stuff and then allocs a netdev with space
 * for the i1480u  data. Initializes, registers in i1480u, registers in
 * netdev, ready to go.
 */
static int i1480u_probe(struct usb_interface *iface,
			const struct usb_device_id *id)
{
	int result;
	struct net_device *net_dev;
	struct device *dev = &iface->dev;
	struct i1480u *i1480u;

	/* Allocate instance [calls i1480u_netdev_setup() on it] */
	result = -ENOMEM;
	net_dev = alloc_netdev(sizeof(*i1480u), "wlp%d", i1480u_netdev_setup);
	if (net_dev == NULL) {
		dev_err(dev, "no memory for network device instance\n");
		goto error_alloc_netdev;
	}
	SET_NETDEV_DEV(net_dev, dev);
	i1480u = netdev_priv(net_dev);
	i1480u->net_dev = net_dev;
	result = i1480u_add(i1480u, iface);	/* Now setup all the wlp stuff */
	if (result < 0) {
		dev_err(dev, "cannot add i1480u device: %d\n", result);
		goto error_i1480u_add;
	}
	result = register_netdev(net_dev);	/* Okey dokey, bring it up */
	if (result < 0) {
		dev_err(dev, "cannot register network device: %d\n", result);
		goto error_register_netdev;
	}
	i1480u_sysfs_setup(i1480u);
	if (result < 0)
		goto error_sysfs_init;
	return 0;

error_sysfs_init:
	unregister_netdev(net_dev);
error_register_netdev:
	i1480u_rm(i1480u);
error_i1480u_add:
	free_netdev(net_dev);
error_alloc_netdev:
	return result;
}


/**
 * Disconect a i1480u from the system.
 *
 * i1480u_stop() has been called before, so al the rx and tx contexts
 * have been taken down already. Make sure the queue is stopped,
 * unregister netdev and i1480u, free and kill.
 */
static void i1480u_disconnect(struct usb_interface *iface)
{
	struct i1480u *i1480u;
	struct net_device *net_dev;

	i1480u = usb_get_intfdata(iface);
	net_dev = i1480u->net_dev;
	netif_stop_queue(net_dev);
#ifdef i1480u_FLOW_CONTROL
	usb_kill_urb(i1480u->notif_urb);
#endif
	i1480u_sysfs_release(i1480u);
	unregister_netdev(net_dev);
	i1480u_rm(i1480u);
	free_netdev(net_dev);
}

static struct usb_device_id i1480u_id_table[] = {
	{
		.match_flags = USB_DEVICE_ID_MATCH_DEVICE \
				|  USB_DEVICE_ID_MATCH_DEV_INFO \
				|  USB_DEVICE_ID_MATCH_INT_INFO,
		.idVendor = 0x8086,
		.idProduct = 0x0c3b,
		.bDeviceClass = 0xef,
		.bDeviceSubClass = 0x02,
		.bDeviceProtocol = 0x02,
		.bInterfaceClass = 0xff,
		.bInterfaceSubClass = 0xff,
		.bInterfaceProtocol = 0xff,
	},
	{},
};
MODULE_DEVICE_TABLE(usb, i1480u_id_table);

static struct usb_driver i1480u_driver = {
	.name =		KBUILD_MODNAME,
	.probe =	i1480u_probe,
	.disconnect =	i1480u_disconnect,
	.id_table =	i1480u_id_table,
};

static int __init i1480u_driver_init(void)
{
	return usb_register(&i1480u_driver);
}
module_init(i1480u_driver_init);


static void __exit i1480u_driver_exit(void)
{
	usb_deregister(&i1480u_driver);
}
module_exit(i1480u_driver_exit);

MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
MODULE_DESCRIPTION("i1480 Wireless UWB Link WLP networking for USB");
MODULE_LICENSE("GPL");
