/*
 * IPWireless 3G PCMCIA Network Driver
 *
 * Original code
 *   by Stephen Blackheath <stephen@blacksapphire.com>,
 *      Ben Martel <benm@symmetric.co.nz>
 *
 * Copyrighted as follows:
 *   Copyright (C) 2004 by Symmetric Systems Ltd (NZ)
 *
 * Various driver changes and rewrites, port to new kernels
 *   Copyright (C) 2006-2007 Jiri Kosina
 *
 * Misc code cleanups and updates
 *   Copyright (C) 2007 David Sterba
 */

#include "hardware.h"
#include "network.h"
#include "main.h"
#include "tty.h"

#include <linux/delay.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>

#include <pcmcia/cisreg.h>
#include <pcmcia/device_id.h>
#include <pcmcia/ss.h>
#include <pcmcia/ds.h>
#include <pcmcia/cs.h>

static struct pcmcia_device_id ipw_ids[] = {
	PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0100),
	PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0200),
	PCMCIA_DEVICE_NULL
};
MODULE_DEVICE_TABLE(pcmcia, ipw_ids);

static void ipwireless_detach(struct pcmcia_device *link);

/*
 * Module params
 */
/* Debug mode: more verbose, print sent/recv bytes */
int ipwireless_debug;
int ipwireless_loopback;
int ipwireless_out_queue = 1;

module_param_named(debug, ipwireless_debug, int, 0);
module_param_named(loopback, ipwireless_loopback, int, 0);
module_param_named(out_queue, ipwireless_out_queue, int, 0);
MODULE_PARM_DESC(debug, "switch on debug messages [0]");
MODULE_PARM_DESC(loopback,
		"debug: enable ras_raw channel [0]");
MODULE_PARM_DESC(out_queue, "debug: set size of outgoing queue [1]");

/* Executes in process context. */
static void signalled_reboot_work(struct work_struct *work_reboot)
{
	struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev,
			work_reboot);
	struct pcmcia_device *link = ipw->link;
	int ret = pccard_reset_card(link->socket);

	if (ret != CS_SUCCESS)
		cs_error(link, ResetCard, ret);
}

static void signalled_reboot_callback(void *callback_data)
{
	struct ipw_dev *ipw = (struct ipw_dev *) callback_data;

	/* Delegate to process context. */
	schedule_work(&ipw->work_reboot);
}

static int config_ipwireless(struct ipw_dev *ipw)
{
	struct pcmcia_device *link = ipw->link;
	int ret;
	config_info_t conf;
	tuple_t tuple;
	unsigned short buf[64];
	cisparse_t parse;
	unsigned short cor_value;
	win_req_t request_attr_memory;
	win_req_t request_common_memory;
	memreq_t memreq_attr_memory;
	memreq_t memreq_common_memory;

	ipw->is_v2_card = 0;

	tuple.Attributes = 0;
	tuple.TupleData = (cisdata_t *) buf;
	tuple.TupleDataMax = sizeof(buf);
	tuple.TupleOffset = 0;

	tuple.DesiredTuple = RETURN_FIRST_TUPLE;

	ret = pcmcia_get_first_tuple(link, &tuple);

	while (ret == 0) {
		ret = pcmcia_get_tuple_data(link, &tuple);

		if (ret != CS_SUCCESS) {
			cs_error(link, GetTupleData, ret);
			goto exit0;
		}
		ret = pcmcia_get_next_tuple(link, &tuple);
	}

	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;

	ret = pcmcia_get_first_tuple(link, &tuple);

	if (ret != CS_SUCCESS) {
		cs_error(link, GetFirstTuple, ret);
		goto exit0;
	}

	ret = pcmcia_get_tuple_data(link, &tuple);

	if (ret != CS_SUCCESS) {
		cs_error(link, GetTupleData, ret);
		goto exit0;
	}

	ret = pcmcia_parse_tuple(link, &tuple, &parse);

	if (ret != CS_SUCCESS) {
		cs_error(link, ParseTuple, ret);
		goto exit0;
	}

	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
	link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
	link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
	link->io.IOAddrLines = 16;

	link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;

	/* 0x40 causes it to generate level mode interrupts. */
	/* 0x04 enables IREQ pin. */
	cor_value = parse.cftable_entry.index | 0x44;
	link->conf.ConfigIndex = cor_value;

	/* IRQ and I/O settings */
	tuple.DesiredTuple = CISTPL_CONFIG;

	ret = pcmcia_get_first_tuple(link, &tuple);

	if (ret != CS_SUCCESS) {
		cs_error(link, GetFirstTuple, ret);
		goto exit0;
	}

	ret = pcmcia_get_tuple_data(link, &tuple);

	if (ret != CS_SUCCESS) {
		cs_error(link, GetTupleData, ret);
		goto exit0;
	}

	ret = pcmcia_parse_tuple(link, &tuple, &parse);

	if (ret != CS_SUCCESS) {
		cs_error(link, GetTupleData, ret);
		goto exit0;
	}
	link->conf.Attributes = CONF_ENABLE_IRQ;
	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];
	link->conf.IntType = INT_MEMORY_AND_IO;

	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
	link->irq.Handler = ipwireless_interrupt;
	link->irq.Instance = ipw->hardware;

	ret = pcmcia_request_io(link, &link->io);

	if (ret != CS_SUCCESS) {
		cs_error(link, RequestIO, ret);
		goto exit0;
	}

	/* memory settings */

	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;

	ret = pcmcia_get_first_tuple(link, &tuple);

	if (ret != CS_SUCCESS) {
		cs_error(link, GetFirstTuple, ret);
		goto exit1;
	}

	ret = pcmcia_get_tuple_data(link, &tuple);

	if (ret != CS_SUCCESS) {
		cs_error(link, GetTupleData, ret);
		goto exit1;
	}

	ret = pcmcia_parse_tuple(link, &tuple, &parse);

	if (ret != CS_SUCCESS) {
		cs_error(link, ParseTuple, ret);
		goto exit1;
	}

	if (parse.cftable_entry.mem.nwin > 0) {
		request_common_memory.Attributes =
			WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
		request_common_memory.Base =
			parse.cftable_entry.mem.win[0].host_addr;
		request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
		if (request_common_memory.Size < 0x1000)
			request_common_memory.Size = 0x1000;
		request_common_memory.AccessSpeed = 0;

		ret = pcmcia_request_window(&link, &request_common_memory,
				&ipw->handle_common_memory);

		if (ret != CS_SUCCESS) {
			cs_error(link, RequestWindow, ret);
			goto exit1;
		}

		memreq_common_memory.CardOffset =
			parse.cftable_entry.mem.win[0].card_addr;
		memreq_common_memory.Page = 0;

		ret = pcmcia_map_mem_page(ipw->handle_common_memory,
				&memreq_common_memory);

		if (ret != CS_SUCCESS) {
			cs_error(link, MapMemPage, ret);
			goto exit1;
		}

		ipw->is_v2_card =
			parse.cftable_entry.mem.win[0].len == 0x100;

		ipw->common_memory = ioremap(request_common_memory.Base,
				request_common_memory.Size);

		request_attr_memory.Attributes =
			WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
		request_attr_memory.Base = 0;
		request_attr_memory.Size = 0;	/* this used to be 0x1000 */
		request_attr_memory.AccessSpeed = 0;

		ret = pcmcia_request_window(&link, &request_attr_memory,
				&ipw->handle_attr_memory);

		if (ret != CS_SUCCESS) {
			cs_error(link, RequestWindow, ret);
			goto exit2;
		}

		memreq_attr_memory.CardOffset = 0;
		memreq_attr_memory.Page = 0;

		ret = pcmcia_map_mem_page(ipw->handle_attr_memory,
				&memreq_attr_memory);

		if (ret != CS_SUCCESS) {
			cs_error(link, MapMemPage, ret);
			goto exit2;
		}

		ipw->attr_memory = ioremap(request_attr_memory.Base,
				request_attr_memory.Size);
	}

	INIT_WORK(&ipw->work_reboot, signalled_reboot_work);

	ipwireless_init_hardware_v1(ipw->hardware, link->io.BasePort1,
				    ipw->attr_memory, ipw->common_memory,
				    ipw->is_v2_card, signalled_reboot_callback,
				    ipw);

	ret = pcmcia_request_irq(link, &link->irq);

	if (ret != CS_SUCCESS) {
		cs_error(link, RequestIRQ, ret);
		goto exit3;
	}

	/* Look up current Vcc */

	ret = pcmcia_get_configuration_info(link, &conf);

	if (ret != CS_SUCCESS) {
		cs_error(link, GetConfigurationInfo, ret);
		goto exit4;
	}

	printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
			ipw->is_v2_card ? "V2/V3" : "V1");
	printk(KERN_INFO IPWIRELESS_PCCARD_NAME
			": I/O ports 0x%04x-0x%04x, irq %d\n",
			(unsigned int) link->io.BasePort1,
			(unsigned int) (link->io.BasePort1 +
				link->io.NumPorts1 - 1),
			(unsigned int) link->irq.AssignedIRQ);
	if (ipw->attr_memory && ipw->common_memory)
		printk(KERN_INFO IPWIRELESS_PCCARD_NAME
				": attr memory 0x%08lx-0x%08lx, "
				"common memory 0x%08lx-0x%08lx\n",
				request_attr_memory.Base,
				request_attr_memory.Base
				+ request_attr_memory.Size - 1,
				request_common_memory.Base,
				request_common_memory.Base
				+ request_common_memory.Size - 1);

	ipw->network = ipwireless_network_create(ipw->hardware);
	if (!ipw->network)
		goto exit3;

	ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network,
			ipw->nodes);
	if (!ipw->tty)
		goto exit3;

	ipwireless_init_hardware_v2_v3(ipw->hardware);

	/*
	 * Do the RequestConfiguration last, because it enables interrupts.
	 * Then we don't get any interrupts before we're ready for them.
	 */
	ret = pcmcia_request_configuration(link, &link->conf);

	if (ret != CS_SUCCESS) {
		cs_error(link, RequestConfiguration, ret);
		goto exit4;
	}

	link->dev_node = &ipw->nodes[0];

	return 0;

exit4:
	pcmcia_disable_device(link);
exit3:
	if (ipw->attr_memory) {
		iounmap(ipw->attr_memory);
		pcmcia_release_window(ipw->handle_attr_memory);
		pcmcia_disable_device(link);
	}
exit2:
	if (ipw->common_memory) {
		iounmap(ipw->common_memory);
		pcmcia_release_window(ipw->handle_common_memory);
	}
exit1:
	pcmcia_disable_device(link);
exit0:
	return -1;
}

static void release_ipwireless(struct ipw_dev *ipw)
{
	struct pcmcia_device *link = ipw->link;

	pcmcia_disable_device(link);

	if (ipw->common_memory)
		iounmap(ipw->common_memory);
	if (ipw->attr_memory)
		iounmap(ipw->attr_memory);
	if (ipw->common_memory)
		pcmcia_release_window(ipw->handle_common_memory);
	if (ipw->attr_memory)
		pcmcia_release_window(ipw->handle_attr_memory);
	pcmcia_disable_device(link);
}

/*
 * ipwireless_attach() creates an "instance" of the driver, allocating
 * local data structures for one device (one interface).  The device
 * is registered with Card Services.
 *
 * The pcmcia_device structure is initialized, but we don't actually
 * configure the card at this point -- we wait until we receive a
 * card insertion event.
 */
static int ipwireless_attach(struct pcmcia_device *link)
{
	struct ipw_dev *ipw;
	int ret;

	ipw = kzalloc(sizeof(struct ipw_dev), GFP_KERNEL);
	if (!ipw)
		return -ENOMEM;

	ipw->link = link;
	link->priv = ipw;
	link->irq.Instance = ipw;

	/* Link this device into our device list. */
	link->dev_node = &ipw->nodes[0];

	ipw->hardware = ipwireless_hardware_create();
	if (!ipw->hardware) {
		kfree(ipw);
		return -ENOMEM;
	}
	/* RegisterClient will call config_ipwireless */

	ret = config_ipwireless(ipw);

	if (ret != 0) {
		cs_error(link, RegisterClient, ret);
		ipwireless_detach(link);
		return ret;
	}

	return 0;
}

/*
 * This deletes a driver "instance".  The device is de-registered with
 * Card Services.  If it has been released, all local data structures
 * are freed.  Otherwise, the structures will be freed when the device
 * is released.
 */
static void ipwireless_detach(struct pcmcia_device *link)
{
	struct ipw_dev *ipw = link->priv;

	release_ipwireless(ipw);

	/* Break the link with Card Services */
	if (link)
		pcmcia_disable_device(link);

	if (ipw->tty != NULL)
		ipwireless_tty_free(ipw->tty);
	if (ipw->network != NULL)
		ipwireless_network_free(ipw->network);
	if (ipw->hardware != NULL)
		ipwireless_hardware_free(ipw->hardware);
	kfree(ipw);
}

static struct pcmcia_driver me = {
	.owner		= THIS_MODULE,
	.probe          = ipwireless_attach,
	.remove         = ipwireless_detach,
	.drv = { .name  = IPWIRELESS_PCCARD_NAME },
	.id_table       = ipw_ids
};

/*
 * Module insertion : initialisation of the module.
 * Register the card with cardmgr...
 */
static int __init init_ipwireless(void)
{
	int ret;

	printk(KERN_INFO IPWIRELESS_PCCARD_NAME " "
	       IPWIRELESS_PCMCIA_VERSION " by " IPWIRELESS_PCMCIA_AUTHOR "\n");

	ret = ipwireless_tty_init();
	if (ret != 0)
		return ret;

	ret = pcmcia_register_driver(&me);
	if (ret != 0)
		ipwireless_tty_release();

	return ret;
}

/*
 * Module removal
 */
static void __exit exit_ipwireless(void)
{
	printk(KERN_INFO IPWIRELESS_PCCARD_NAME " "
			IPWIRELESS_PCMCIA_VERSION " removed\n");

	pcmcia_unregister_driver(&me);
	ipwireless_tty_release();
}

module_init(init_ipwireless);
module_exit(exit_ipwireless);

MODULE_AUTHOR(IPWIRELESS_PCMCIA_AUTHOR);
MODULE_DESCRIPTION(IPWIRELESS_PCCARD_NAME " " IPWIRELESS_PCMCIA_VERSION);
MODULE_LICENSE("GPL");
