/*
 * 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/version.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/uwb/debug.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
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);
	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->open = i1480u_open;
	net_dev->stop = i1480u_stop;
	net_dev->hard_start_xmit = i1480u_hard_start_xmit;
	net_dev->tx_timeout = i1480u_tx_timeout;
	net_dev->get_stats = i1480u_get_stats;
	net_dev->set_config = i1480u_set_config;
	net_dev->change_mtu = i1480u_change_mtu;

#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");
