/*
 * 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 <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/ppp_channel.h>
#include <linux/ppp_defs.h>
#include <linux/if_ppp.h>
#include <linux/skbuff.h>

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

#define MAX_OUTGOING_PACKETS_QUEUED   ipwireless_out_queue
#define MAX_ASSOCIATED_TTYS 2

#define SC_RCV_BITS     (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)

struct ipw_network {
	/* Hardware context, used for calls to hardware layer. */
	struct ipw_hardware *hardware;
	/* Context for kernel 'generic_ppp' functionality */
	struct ppp_channel *ppp_channel;
	/* tty context connected with IPW console */
	struct ipw_tty *associated_ttys[NO_OF_IPW_CHANNELS][MAX_ASSOCIATED_TTYS];
	/* True if ppp needs waking up once we're ready to xmit */
	int ppp_blocked;
	/* Number of packets queued up in hardware module. */
	int outgoing_packets_queued;
	/* Spinlock to avoid interrupts during shutdown */
	spinlock_t spinlock;
	struct mutex close_lock;

	/* PPP ioctl data, not actually used anywere */
	unsigned int flags;
	unsigned int rbits;
	u32 xaccm[8];
	u32 raccm;
	int mru;

	int shutting_down;
	unsigned int ras_control_lines;

	struct work_struct work_go_online;
	struct work_struct work_go_offline;
};


#ifdef IPWIRELESS_STATE_DEBUG
int ipwireless_dump_network_state(char *p, size_t limit,
				  struct ipw_network *network)
{
	return snprintf(p, limit,
			"debug: ppp_blocked=%d\n"
			"debug: outgoing_packets_queued=%d\n"
			"debug: network.shutting_down=%d\n",
			network->ppp_blocked,
			network->outgoing_packets_queued,
			network->shutting_down);
}
#endif

static void notify_packet_sent(void *callback_data, unsigned int packet_length)
{
	struct ipw_network *network = callback_data;
	unsigned long flags;

	spin_lock_irqsave(&network->spinlock, flags);
	network->outgoing_packets_queued--;
	if (network->ppp_channel != NULL) {
		if (network->ppp_blocked) {
			network->ppp_blocked = 0;
			spin_unlock_irqrestore(&network->spinlock, flags);
			ppp_output_wakeup(network->ppp_channel);
			if (ipwireless_debug)
				printk(KERN_INFO IPWIRELESS_PCCARD_NAME
				       ": ppp unblocked\n");
		} else
			spin_unlock_irqrestore(&network->spinlock, flags);
	} else
		spin_unlock_irqrestore(&network->spinlock, flags);
}

/*
 * Called by the ppp system when it has a packet to send to the hardware.
 */
static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel,
				     struct sk_buff *skb)
{
	struct ipw_network *network = ppp_channel->private;
	unsigned long flags;

	spin_lock_irqsave(&network->spinlock, flags);
	if (network->outgoing_packets_queued < MAX_OUTGOING_PACKETS_QUEUED) {
		unsigned char *buf;
		static unsigned char header[] = {
			PPP_ALLSTATIONS, /* 0xff */
			PPP_UI,		 /* 0x03 */
		};
		int ret;

		network->outgoing_packets_queued++;
		spin_unlock_irqrestore(&network->spinlock, flags);

		/*
		 * If we have the requested amount of headroom in the skb we
		 * were handed, then we can add the header efficiently.
		 */
		if (skb_headroom(skb) >= 2) {
			memcpy(skb_push(skb, 2), header, 2);
			ret = ipwireless_send_packet(network->hardware,
					       IPW_CHANNEL_RAS, skb->data,
					       skb->len,
					       notify_packet_sent,
					       network);
			if (ret == -1) {
				skb_pull(skb, 2);
				return 0;
			}
		} else {
			/* Otherwise (rarely) we do it inefficiently. */
			buf = kmalloc(skb->len + 2, GFP_ATOMIC);
			if (!buf)
				return 0;
			memcpy(buf + 2, skb->data, skb->len);
			memcpy(buf, header, 2);
			ret = ipwireless_send_packet(network->hardware,
					       IPW_CHANNEL_RAS, buf,
					       skb->len + 2,
					       notify_packet_sent,
					       network);
			kfree(buf);
			if (ret == -1)
				return 0;
		}
		kfree_skb(skb);
		return 1;
	} else {
		/*
		 * Otherwise reject the packet, and flag that the ppp system
		 * needs to be unblocked once we are ready to send.
		 */
		network->ppp_blocked = 1;
		spin_unlock_irqrestore(&network->spinlock, flags);
		return 0;
	}
}

/* Handle an ioctl call that has come in via ppp. (copy of ppp_async_ioctl() */
static int ipwireless_ppp_ioctl(struct ppp_channel *ppp_channel,
				unsigned int cmd, unsigned long arg)
{
	struct ipw_network *network = ppp_channel->private;
	int err, val;
	u32 accm[8];
	int __user *user_arg = (int __user *) arg;

	err = -EFAULT;
	switch (cmd) {
	case PPPIOCGFLAGS:
		val = network->flags | network->rbits;
		if (put_user(val, user_arg))
			break;
		err = 0;
		break;

	case PPPIOCSFLAGS:
		if (get_user(val, user_arg))
			break;
		network->flags = val & ~SC_RCV_BITS;
		network->rbits = val & SC_RCV_BITS;
		err = 0;
		break;

	case PPPIOCGASYNCMAP:
		if (put_user(network->xaccm[0], user_arg))
			break;
		err = 0;
		break;

	case PPPIOCSASYNCMAP:
		if (get_user(network->xaccm[0], user_arg))
			break;
		err = 0;
		break;

	case PPPIOCGRASYNCMAP:
		if (put_user(network->raccm, user_arg))
			break;
		err = 0;
		break;

	case PPPIOCSRASYNCMAP:
		if (get_user(network->raccm, user_arg))
			break;
		err = 0;
		break;

	case PPPIOCGXASYNCMAP:
		if (copy_to_user((void __user *) arg, network->xaccm,
					sizeof(network->xaccm)))
			break;
		err = 0;
		break;

	case PPPIOCSXASYNCMAP:
		if (copy_from_user(accm, (void __user *) arg, sizeof(accm)))
			break;
		accm[2] &= ~0x40000000U;	/* can't escape 0x5e */
		accm[3] |= 0x60000000U;	/* must escape 0x7d, 0x7e */
		memcpy(network->xaccm, accm, sizeof(network->xaccm));
		err = 0;
		break;

	case PPPIOCGMRU:
		if (put_user(network->mru, user_arg))
			break;
		err = 0;
		break;

	case PPPIOCSMRU:
		if (get_user(val, user_arg))
			break;
		if (val < PPP_MRU)
			val = PPP_MRU;
		network->mru = val;
		err = 0;
		break;

	default:
		err = -ENOTTY;
	}

	return err;
}

static struct ppp_channel_ops ipwireless_ppp_channel_ops = {
	.start_xmit = ipwireless_ppp_start_xmit,
	.ioctl      = ipwireless_ppp_ioctl
};

static void do_go_online(struct work_struct *work_go_online)
{
	struct ipw_network *network =
		container_of(work_go_online, struct ipw_network,
				work_go_online);
	unsigned long flags;

	spin_lock_irqsave(&network->spinlock, flags);
	if (!network->ppp_channel) {
		struct ppp_channel *channel;

		spin_unlock_irqrestore(&network->spinlock, flags);
		channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL);
		if (!channel) {
			printk(KERN_ERR IPWIRELESS_PCCARD_NAME
					": unable to allocate PPP channel\n");
			return;
		}
		channel->private = network;
		channel->mtu = 16384;	/* Wild guess */
		channel->hdrlen = 2;
		channel->ops = &ipwireless_ppp_channel_ops;

		network->flags = 0;
		network->rbits = 0;
		network->mru = PPP_MRU;
		memset(network->xaccm, 0, sizeof(network->xaccm));
		network->xaccm[0] = ~0U;
		network->xaccm[3] = 0x60000000U;
		network->raccm = ~0U;
		ppp_register_channel(channel);
		spin_lock_irqsave(&network->spinlock, flags);
		network->ppp_channel = channel;
	}
	spin_unlock_irqrestore(&network->spinlock, flags);
}

static void do_go_offline(struct work_struct *work_go_offline)
{
	struct ipw_network *network =
		container_of(work_go_offline, struct ipw_network,
				work_go_offline);
	unsigned long flags;

	mutex_lock(&network->close_lock);
	spin_lock_irqsave(&network->spinlock, flags);
	if (network->ppp_channel != NULL) {
		struct ppp_channel *channel = network->ppp_channel;

		network->ppp_channel = NULL;
		spin_unlock_irqrestore(&network->spinlock, flags);
		mutex_unlock(&network->close_lock);
		ppp_unregister_channel(channel);
	} else {
		spin_unlock_irqrestore(&network->spinlock, flags);
		mutex_unlock(&network->close_lock);
	}
}

void ipwireless_network_notify_control_line_change(struct ipw_network *network,
						   unsigned int channel_idx,
						   unsigned int control_lines,
						   unsigned int changed_mask)
{
	int i;

	if (channel_idx == IPW_CHANNEL_RAS)
		network->ras_control_lines = control_lines;

	for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) {
		struct ipw_tty *tty =
			network->associated_ttys[channel_idx][i];

		/*
		 * If it's associated with a tty (other than the RAS channel
		 * when we're online), then send the data to that tty.  The RAS
		 * channel's data is handled above - it always goes through
		 * ppp_generic.
		 */
		if (tty)
			ipwireless_tty_notify_control_line_change(tty,
								  channel_idx,
								  control_lines,
								  changed_mask);
	}
}

/*
 * Some versions of firmware stuff packets with 0xff 0x03 (PPP: ALLSTATIONS, UI)
 * bytes, which are required on sent packet, but not always present on received
 * packets
 */
static struct sk_buff *ipw_packet_received_skb(unsigned char *data,
					       unsigned int length)
{
	struct sk_buff *skb;

	if (length > 2 && data[0] == PPP_ALLSTATIONS && data[1] == PPP_UI) {
		length -= 2;
		data += 2;
	}

	skb = dev_alloc_skb(length + 4);
	skb_reserve(skb, 2);
	memcpy(skb_put(skb, length), data, length);

	return skb;
}

void ipwireless_network_packet_received(struct ipw_network *network,
					unsigned int channel_idx,
					unsigned char *data,
					unsigned int length)
{
	int i;
	unsigned long flags;

	for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) {
		struct ipw_tty *tty = network->associated_ttys[channel_idx][i];

		if (!tty)
			continue;

		/*
		 * If it's associated with a tty (other than the RAS channel
		 * when we're online), then send the data to that tty.  The RAS
		 * channel's data is handled above - it always goes through
		 * ppp_generic.
		 */
		if (channel_idx == IPW_CHANNEL_RAS
				&& (network->ras_control_lines &
					IPW_CONTROL_LINE_DCD) != 0
				&& ipwireless_tty_is_modem(tty)) {
			/*
			 * If data came in on the RAS channel and this tty is
			 * the modem tty, and we are online, then we send it to
			 * the PPP layer.
			 */
			mutex_lock(&network->close_lock);
			spin_lock_irqsave(&network->spinlock, flags);
			if (network->ppp_channel != NULL) {
				struct sk_buff *skb;

				spin_unlock_irqrestore(&network->spinlock,
						flags);

				/* Send the data to the ppp_generic module. */
				skb = ipw_packet_received_skb(data, length);
				ppp_input(network->ppp_channel, skb);
			} else
				spin_unlock_irqrestore(&network->spinlock,
						flags);
			mutex_unlock(&network->close_lock);
		}
		/* Otherwise we send it out the tty. */
		else
			ipwireless_tty_received(tty, data, length);
	}
}

struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw)
{
	struct ipw_network *network =
		kzalloc(sizeof(struct ipw_network), GFP_ATOMIC);

	if (!network)
		return NULL;

	spin_lock_init(&network->spinlock);
	mutex_init(&network->close_lock);

	network->hardware = hw;

	INIT_WORK(&network->work_go_online, do_go_online);
	INIT_WORK(&network->work_go_offline, do_go_offline);

	ipwireless_associate_network(hw, network);

	return network;
}

void ipwireless_network_free(struct ipw_network *network)
{
	network->shutting_down = 1;

	ipwireless_ppp_close(network);
	flush_scheduled_work();

	ipwireless_stop_interrupts(network->hardware);
	ipwireless_associate_network(network->hardware, NULL);

	kfree(network);
}

void ipwireless_associate_network_tty(struct ipw_network *network,
				      unsigned int channel_idx,
				      struct ipw_tty *tty)
{
	int i;

	for (i = 0; i < MAX_ASSOCIATED_TTYS; i++)
		if (network->associated_ttys[channel_idx][i] == NULL) {
			network->associated_ttys[channel_idx][i] = tty;
			break;
		}
}

void ipwireless_disassociate_network_ttys(struct ipw_network *network,
					  unsigned int channel_idx)
{
	int i;

	for (i = 0; i < MAX_ASSOCIATED_TTYS; i++)
		network->associated_ttys[channel_idx][i] = NULL;
}

void ipwireless_ppp_open(struct ipw_network *network)
{
	if (ipwireless_debug)
		printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": online\n");
	schedule_work(&network->work_go_online);
}

void ipwireless_ppp_close(struct ipw_network *network)
{
	/* Disconnect from the wireless network. */
	if (ipwireless_debug)
		printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": offline\n");
	schedule_work(&network->work_go_offline);
}

int ipwireless_ppp_channel_index(struct ipw_network *network)
{
	int ret = -1;
	unsigned long flags;

	spin_lock_irqsave(&network->spinlock, flags);
	if (network->ppp_channel != NULL)
		ret = ppp_channel_index(network->ppp_channel);
	spin_unlock_irqrestore(&network->spinlock, flags);

	return ret;
}

int ipwireless_ppp_unit_number(struct ipw_network *network)
{
	int ret = -1;
	unsigned long flags;

	spin_lock_irqsave(&network->spinlock, flags);
	if (network->ppp_channel != NULL)
		ret = ppp_unit_number(network->ppp_channel);
	spin_unlock_irqrestore(&network->spinlock, flags);

	return ret;
}
