// SPDX-License-Identifier: GPL-2.0
/*
 * 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/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/ppp_defs.h>
#include <linux/if.h>
#include <linux/ppp-ioctl.h>
#include <linux/sched.h>
#include <linux/serial.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/uaccess.h>

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

#define IPWIRELESS_PCMCIA_START 	(0)
#define IPWIRELESS_PCMCIA_MINORS	(24)
#define IPWIRELESS_PCMCIA_MINOR_RANGE	(8)

#define TTYTYPE_MODEM    (0)
#define TTYTYPE_MONITOR  (1)
#define TTYTYPE_RAS_RAW  (2)

struct ipw_tty {
	struct tty_port port;
	int index;
	struct ipw_hardware *hardware;
	unsigned int channel_idx;
	unsigned int secondary_channel_idx;
	int tty_type;
	struct ipw_network *network;
	unsigned int control_lines;
	struct mutex ipw_tty_mutex;
	int tx_bytes_queued;
	int closing;
};

static struct ipw_tty *ttys[IPWIRELESS_PCMCIA_MINORS];

static struct tty_driver *ipw_tty_driver;

static char *tty_type_name(int tty_type)
{
	static char *channel_names[] = {
		"modem",
		"monitor",
		"RAS-raw"
	};

	return channel_names[tty_type];
}

static struct ipw_tty *get_tty(int index)
{
	/*
	 * The 'ras_raw' channel is only available when 'loopback' mode
	 * is enabled.
	 * Number of minor starts with 16 (_RANGE * _RAS_RAW).
	 */
	if (!ipwireless_loopback && index >=
			 IPWIRELESS_PCMCIA_MINOR_RANGE * TTYTYPE_RAS_RAW)
		return NULL;

	return ttys[index];
}

static int ipw_open(struct tty_struct *linux_tty, struct file *filp)
{
	struct ipw_tty *tty = get_tty(linux_tty->index);

	if (!tty)
		return -ENODEV;

	mutex_lock(&tty->ipw_tty_mutex);
	if (tty->port.count == 0)
		tty->tx_bytes_queued = 0;

	tty->port.count++;

	tty->port.tty = linux_tty;
	linux_tty->driver_data = tty;

	if (tty->tty_type == TTYTYPE_MODEM)
		ipwireless_ppp_open(tty->network);

	mutex_unlock(&tty->ipw_tty_mutex);

	return 0;
}

static void do_ipw_close(struct ipw_tty *tty)
{
	tty->port.count--;

	if (tty->port.count == 0) {
		struct tty_struct *linux_tty = tty->port.tty;

		if (linux_tty != NULL) {
			tty->port.tty = NULL;
			linux_tty->driver_data = NULL;

			if (tty->tty_type == TTYTYPE_MODEM)
				ipwireless_ppp_close(tty->network);
		}
	}
}

static void ipw_hangup(struct tty_struct *linux_tty)
{
	struct ipw_tty *tty = linux_tty->driver_data;

	if (!tty)
		return;

	mutex_lock(&tty->ipw_tty_mutex);
	if (tty->port.count == 0) {
		mutex_unlock(&tty->ipw_tty_mutex);
		return;
	}

	do_ipw_close(tty);

	mutex_unlock(&tty->ipw_tty_mutex);
}

static void ipw_close(struct tty_struct *linux_tty, struct file *filp)
{
	ipw_hangup(linux_tty);
}

/* Take data received from hardware, and send it out the tty */
void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data,
			unsigned int length)
{
	int work = 0;

	mutex_lock(&tty->ipw_tty_mutex);

	if (!tty->port.count) {
		mutex_unlock(&tty->ipw_tty_mutex);
		return;
	}
	mutex_unlock(&tty->ipw_tty_mutex);

	work = tty_insert_flip_string(&tty->port, data, length);

	if (work != length)
		printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME
				": %d chars not inserted to flip buffer!\n",
				length - work);

	if (work)
		tty_flip_buffer_push(&tty->port);
}

static void ipw_write_packet_sent_callback(void *callback_data,
					   unsigned int packet_length)
{
	struct ipw_tty *tty = callback_data;

	/*
	 * Packet has been sent, so we subtract the number of bytes from our
	 * tally of outstanding TX bytes.
	 */
	tty->tx_bytes_queued -= packet_length;
}

static int ipw_write(struct tty_struct *linux_tty,
		     const unsigned char *buf, int count)
{
	struct ipw_tty *tty = linux_tty->driver_data;
	int room, ret;

	if (!tty)
		return -ENODEV;

	mutex_lock(&tty->ipw_tty_mutex);
	if (!tty->port.count) {
		mutex_unlock(&tty->ipw_tty_mutex);
		return -EINVAL;
	}

	room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued;
	if (room < 0)
		room = 0;
	/* Don't allow caller to write any more than we have room for */
	if (count > room)
		count = room;

	if (count == 0) {
		mutex_unlock(&tty->ipw_tty_mutex);
		return 0;
	}

	ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS,
			       buf, count,
			       ipw_write_packet_sent_callback, tty);
	if (ret < 0) {
		mutex_unlock(&tty->ipw_tty_mutex);
		return 0;
	}

	tty->tx_bytes_queued += count;
	mutex_unlock(&tty->ipw_tty_mutex);

	return count;
}

static int ipw_write_room(struct tty_struct *linux_tty)
{
	struct ipw_tty *tty = linux_tty->driver_data;
	int room;

	/* FIXME: Exactly how is the tty object locked here .. */
	if (!tty)
		return -ENODEV;

	if (!tty->port.count)
		return -EINVAL;

	room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued;
	if (room < 0)
		room = 0;

	return room;
}

static int ipwireless_get_serial_info(struct tty_struct *linux_tty,
				      struct serial_struct *ss)
{
	struct ipw_tty *tty = linux_tty->driver_data;

	if (!tty)
		return -ENODEV;

	if (!tty->port.count)
		return -EINVAL;

	ss->type = PORT_UNKNOWN;
	ss->line = tty->index;
	ss->baud_base = 115200;
	return 0;
}

static int ipwireless_set_serial_info(struct tty_struct *linux_tty,
				      struct serial_struct *ss)
{
	return 0;	/* Keeps the PCMCIA scripts happy. */
}

static int ipw_chars_in_buffer(struct tty_struct *linux_tty)
{
	struct ipw_tty *tty = linux_tty->driver_data;

	if (!tty)
		return 0;

	if (!tty->port.count)
		return 0;

	return tty->tx_bytes_queued;
}

static int get_control_lines(struct ipw_tty *tty)
{
	unsigned int my = tty->control_lines;
	unsigned int out = 0;

	if (my & IPW_CONTROL_LINE_RTS)
		out |= TIOCM_RTS;
	if (my & IPW_CONTROL_LINE_DTR)
		out |= TIOCM_DTR;
	if (my & IPW_CONTROL_LINE_CTS)
		out |= TIOCM_CTS;
	if (my & IPW_CONTROL_LINE_DSR)
		out |= TIOCM_DSR;
	if (my & IPW_CONTROL_LINE_DCD)
		out |= TIOCM_CD;

	return out;
}

static int set_control_lines(struct ipw_tty *tty, unsigned int set,
			     unsigned int clear)
{
	int ret;

	if (set & TIOCM_RTS) {
		ret = ipwireless_set_RTS(tty->hardware, tty->channel_idx, 1);
		if (ret)
			return ret;
		if (tty->secondary_channel_idx != -1) {
			ret = ipwireless_set_RTS(tty->hardware,
					  tty->secondary_channel_idx, 1);
			if (ret)
				return ret;
		}
	}
	if (set & TIOCM_DTR) {
		ret = ipwireless_set_DTR(tty->hardware, tty->channel_idx, 1);
		if (ret)
			return ret;
		if (tty->secondary_channel_idx != -1) {
			ret = ipwireless_set_DTR(tty->hardware,
					  tty->secondary_channel_idx, 1);
			if (ret)
				return ret;
		}
	}
	if (clear & TIOCM_RTS) {
		ret = ipwireless_set_RTS(tty->hardware, tty->channel_idx, 0);
		if (tty->secondary_channel_idx != -1) {
			ret = ipwireless_set_RTS(tty->hardware,
					  tty->secondary_channel_idx, 0);
			if (ret)
				return ret;
		}
	}
	if (clear & TIOCM_DTR) {
		ret = ipwireless_set_DTR(tty->hardware, tty->channel_idx, 0);
		if (tty->secondary_channel_idx != -1) {
			ret = ipwireless_set_DTR(tty->hardware,
					  tty->secondary_channel_idx, 0);
			if (ret)
				return ret;
		}
	}
	return 0;
}

static int ipw_tiocmget(struct tty_struct *linux_tty)
{
	struct ipw_tty *tty = linux_tty->driver_data;
	/* FIXME: Exactly how is the tty object locked here .. */

	if (!tty)
		return -ENODEV;

	if (!tty->port.count)
		return -EINVAL;

	return get_control_lines(tty);
}

static int
ipw_tiocmset(struct tty_struct *linux_tty,
	     unsigned int set, unsigned int clear)
{
	struct ipw_tty *tty = linux_tty->driver_data;
	/* FIXME: Exactly how is the tty object locked here .. */

	if (!tty)
		return -ENODEV;

	if (!tty->port.count)
		return -EINVAL;

	return set_control_lines(tty, set, clear);
}

static int ipw_ioctl(struct tty_struct *linux_tty,
		     unsigned int cmd, unsigned long arg)
{
	struct ipw_tty *tty = linux_tty->driver_data;

	if (!tty)
		return -ENODEV;

	if (!tty->port.count)
		return -EINVAL;

	/* FIXME: Exactly how is the tty object locked here .. */
	if (tty->tty_type == TTYTYPE_MODEM) {
		switch (cmd) {
		case PPPIOCGCHAN:
			{
				int chan = ipwireless_ppp_channel_index(
							tty->network);

				if (chan < 0)
					return -ENODEV;
				if (put_user(chan, (int __user *) arg))
					return -EFAULT;
			}
			return 0;

		case PPPIOCGUNIT:
			{
				int unit = ipwireless_ppp_unit_number(
						tty->network);

				if (unit < 0)
					return -ENODEV;
				if (put_user(unit, (int __user *) arg))
					return -EFAULT;
			}
			return 0;

		case FIONREAD:
			{
				int val = 0;

				if (put_user(val, (int __user *) arg))
					return -EFAULT;
			}
			return 0;
		case TCFLSH:
			return tty_perform_flush(linux_tty, arg);
		}
	}
	return -ENOIOCTLCMD;
}

static int add_tty(int j,
		    struct ipw_hardware *hardware,
		    struct ipw_network *network, int channel_idx,
		    int secondary_channel_idx, int tty_type)
{
	ttys[j] = kzalloc(sizeof(struct ipw_tty), GFP_KERNEL);
	if (!ttys[j])
		return -ENOMEM;
	ttys[j]->index = j;
	ttys[j]->hardware = hardware;
	ttys[j]->channel_idx = channel_idx;
	ttys[j]->secondary_channel_idx = secondary_channel_idx;
	ttys[j]->network = network;
	ttys[j]->tty_type = tty_type;
	mutex_init(&ttys[j]->ipw_tty_mutex);
	tty_port_init(&ttys[j]->port);

	tty_port_register_device(&ttys[j]->port, ipw_tty_driver, j, NULL);
	ipwireless_associate_network_tty(network, channel_idx, ttys[j]);

	if (secondary_channel_idx != -1)
		ipwireless_associate_network_tty(network,
						 secondary_channel_idx,
						 ttys[j]);
	/* check if we provide raw device (if loopback is enabled) */
	if (get_tty(j))
		printk(KERN_INFO IPWIRELESS_PCCARD_NAME
		       ": registering %s device ttyIPWp%d\n",
		       tty_type_name(tty_type), j);

	return 0;
}

struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware,
				      struct ipw_network *network)
{
	int i, j;

	for (i = 0; i < IPWIRELESS_PCMCIA_MINOR_RANGE; i++) {
		int allfree = 1;

		for (j = i; j < IPWIRELESS_PCMCIA_MINORS;
				j += IPWIRELESS_PCMCIA_MINOR_RANGE)
			if (ttys[j] != NULL) {
				allfree = 0;
				break;
			}

		if (allfree) {
			j = i;

			if (add_tty(j, hardware, network,
					IPW_CHANNEL_DIALLER, IPW_CHANNEL_RAS,
					TTYTYPE_MODEM))
				return NULL;

			j += IPWIRELESS_PCMCIA_MINOR_RANGE;
			if (add_tty(j, hardware, network,
					IPW_CHANNEL_DIALLER, -1,
					TTYTYPE_MONITOR))
				return NULL;

			j += IPWIRELESS_PCMCIA_MINOR_RANGE;
			if (add_tty(j, hardware, network,
					IPW_CHANNEL_RAS, -1,
					TTYTYPE_RAS_RAW))
				return NULL;

			return ttys[i];
		}
	}
	return NULL;
}

/*
 * Must be called before ipwireless_network_free().
 */
void ipwireless_tty_free(struct ipw_tty *tty)
{
	int j;
	struct ipw_network *network = ttys[tty->index]->network;

	for (j = tty->index; j < IPWIRELESS_PCMCIA_MINORS;
			j += IPWIRELESS_PCMCIA_MINOR_RANGE) {
		struct ipw_tty *ttyj = ttys[j];

		if (ttyj) {
			mutex_lock(&ttyj->ipw_tty_mutex);
			if (get_tty(j))
				printk(KERN_INFO IPWIRELESS_PCCARD_NAME
				       ": deregistering %s device ttyIPWp%d\n",
				       tty_type_name(ttyj->tty_type), j);
			ttyj->closing = 1;
			if (ttyj->port.tty != NULL) {
				mutex_unlock(&ttyj->ipw_tty_mutex);
				tty_vhangup(ttyj->port.tty);
				/* FIXME: Exactly how is the tty object locked here
				   against a parallel ioctl etc */
				/* FIXME2: hangup does not mean all processes
				 * are gone */
				mutex_lock(&ttyj->ipw_tty_mutex);
			}
			while (ttyj->port.count)
				do_ipw_close(ttyj);
			ipwireless_disassociate_network_ttys(network,
							     ttyj->channel_idx);
			tty_unregister_device(ipw_tty_driver, j);
			tty_port_destroy(&ttyj->port);
			ttys[j] = NULL;
			mutex_unlock(&ttyj->ipw_tty_mutex);
			kfree(ttyj);
		}
	}
}

static const struct tty_operations tty_ops = {
	.open = ipw_open,
	.close = ipw_close,
	.hangup = ipw_hangup,
	.write = ipw_write,
	.write_room = ipw_write_room,
	.ioctl = ipw_ioctl,
	.chars_in_buffer = ipw_chars_in_buffer,
	.tiocmget = ipw_tiocmget,
	.tiocmset = ipw_tiocmset,
	.set_serial = ipwireless_set_serial_info,
	.get_serial = ipwireless_get_serial_info,
};

int ipwireless_tty_init(void)
{
	int result;

	ipw_tty_driver = alloc_tty_driver(IPWIRELESS_PCMCIA_MINORS);
	if (!ipw_tty_driver)
		return -ENOMEM;

	ipw_tty_driver->driver_name = IPWIRELESS_PCCARD_NAME;
	ipw_tty_driver->name = "ttyIPWp";
	ipw_tty_driver->major = 0;
	ipw_tty_driver->minor_start = IPWIRELESS_PCMCIA_START;
	ipw_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
	ipw_tty_driver->subtype = SERIAL_TYPE_NORMAL;
	ipw_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
	ipw_tty_driver->init_termios = tty_std_termios;
	ipw_tty_driver->init_termios.c_cflag =
	    B9600 | CS8 | CREAD | HUPCL | CLOCAL;
	ipw_tty_driver->init_termios.c_ispeed = 9600;
	ipw_tty_driver->init_termios.c_ospeed = 9600;
	tty_set_operations(ipw_tty_driver, &tty_ops);
	result = tty_register_driver(ipw_tty_driver);
	if (result) {
		printk(KERN_ERR IPWIRELESS_PCCARD_NAME
		       ": failed to register tty driver\n");
		put_tty_driver(ipw_tty_driver);
		return result;
	}

	return 0;
}

void ipwireless_tty_release(void)
{
	int ret;

	ret = tty_unregister_driver(ipw_tty_driver);
	put_tty_driver(ipw_tty_driver);
	if (ret != 0)
		printk(KERN_ERR IPWIRELESS_PCCARD_NAME
			": tty_unregister_driver failed with code %d\n", ret);
}

int ipwireless_tty_is_modem(struct ipw_tty *tty)
{
	return tty->tty_type == TTYTYPE_MODEM;
}

void
ipwireless_tty_notify_control_line_change(struct ipw_tty *tty,
					  unsigned int channel_idx,
					  unsigned int control_lines,
					  unsigned int changed_mask)
{
	unsigned int old_control_lines = tty->control_lines;

	tty->control_lines = (tty->control_lines & ~changed_mask)
		| (control_lines & changed_mask);

	/*
	 * If DCD is de-asserted, we close the tty so pppd can tell that we
	 * have gone offline.
	 */
	if ((old_control_lines & IPW_CONTROL_LINE_DCD)
			&& !(tty->control_lines & IPW_CONTROL_LINE_DCD)
			&& tty->port.tty) {
		tty_hangup(tty->port.tty);
	}
}

