linux/drivers/tty/nozomi.c

// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
 * nozomi.c  -- HSDPA driver Broadband Wireless Data Card - Globe Trotter
 *
 * Written by: Ulf Jakobsson,
 *             Jan Åkerfeldt,
 *             Stefan Thomasson,
 *
 * Maintained by: Paul Hardwick ([email protected])
 *
 * Patches:
 *          Locking code changes for Vodafone by Sphere Systems Ltd,
 *                              Andrew Bird ([email protected] )
 *                              & Phil Sanderson
 *
 * Source has been ported from an implementation made by Filip Aben @ Option
 *
 * --------------------------------------------------------------------------
 *
 * Copyright (c) 2005,2006 Option Wireless Sweden AB
 * Copyright (c) 2006 Sphere Systems Ltd
 * Copyright (c) 2006 Option Wireless n/v
 * All rights Reserved.
 *
 * --------------------------------------------------------------------------
 */

/* Enable this to have a lot of debug printouts */
#define DEBUG

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/sched.h>
#include <linux/serial.h>
#include <linux/interrupt.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/kfifo.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <asm/byteorder.h>

#include <linux/delay.h>

/* Default debug printout level */
#define NOZOMI_DEBUG_LEVEL
static int debug =;
module_param(debug, int, S_IRUGO | S_IWUSR);

/*    Macros definitions */
#define DBG_(lvl, fmt, args...)

#define DBG1(args...)
#define DBG2(args...)
#define DBG3(args...)
#define DBG4(args...)

#define TMP_BUF_MAX

/*    Defines */
#define NOZOMI_NAME
#define NOZOMI_NAME_TTY

#define NTTY_TTY_MAXMINORS
#define NTTY_FIFO_BUFFER_SIZE

/* Must be power of 2 */
#define FIFO_BUFFER_SIZE_UL

/* Size of tmp send buffer to card */
#define SEND_BUF_MAX
#define RECEIVE_BUF_MAX


#define R_IIR
#define R_FCR
#define R_IER

#define NOZOMI_CONFIG_MAGIC
#define TOGGLE_VALID

/* Definition of interrupt tokens */
#define MDM_DL1
#define MDM_UL1
#define MDM_DL2
#define MDM_UL2
#define DIAG_DL1
#define DIAG_DL2
#define DIAG_UL
#define APP1_DL
#define APP1_UL
#define APP2_DL
#define APP2_UL
#define CTRL_DL
#define CTRL_UL
#define RESET

#define MDM_DL
#define MDM_UL
#define DIAG_DL

/* modem signal definition */
#define CTRL_DSR
#define CTRL_DCD
#define CTRL_RI
#define CTRL_CTS

#define CTRL_DTR
#define CTRL_RTS

#define MAX_PORT
#define NOZOMI_MAX_PORTS
#define NOZOMI_MAX_CARDS

/*    Type definitions */

/*
 * There are two types of nozomi cards,
 * one with 2048 memory and with 8192 memory
 */
enum card_type {};

/* Initialization states a card can be in */
enum card_state {};

/* Two different toggle channels exist */
enum channel_type {};

/* Port definition for the card regarding flow control */
enum ctrl_port_type {};

/* Ports that the nozomi has */
enum port_type {};

#ifdef __BIG_ENDIAN
/* Big endian */

struct toggles {
	unsigned int enabled:5;	/*
				 * Toggle fields are valid if enabled is 0,
				 * else A-channels must always be used.
				 */
	unsigned int diag_dl:1;
	unsigned int mdm_dl:1;
	unsigned int mdm_ul:1;
} __attribute__ ((packed));

/* Configuration table to read at startup of card */
/* Is for now only needed during initialization phase */
struct config_table {
	u32 signature;
	u16 product_information;
	u16 version;
	u8 pad3[3];
	struct toggles toggle;
	u8 pad1[4];
	u16 dl_mdm_len1;	/*
				 * If this is 64, it can hold
				 * 60 bytes + 4 that is length field
				 */
	u16 dl_start;

	u16 dl_diag_len1;
	u16 dl_mdm_len2;	/*
				 * If this is 64, it can hold
				 * 60 bytes + 4 that is length field
				 */
	u16 dl_app1_len;

	u16 dl_diag_len2;
	u16 dl_ctrl_len;
	u16 dl_app2_len;
	u8 pad2[16];
	u16 ul_mdm_len1;
	u16 ul_start;
	u16 ul_diag_len;
	u16 ul_mdm_len2;
	u16 ul_app1_len;
	u16 ul_app2_len;
	u16 ul_ctrl_len;
} __attribute__ ((packed));

/* This stores all control downlink flags */
struct ctrl_dl {
	u8 port;
	unsigned int reserved:4;
	unsigned int CTS:1;
	unsigned int RI:1;
	unsigned int DCD:1;
	unsigned int DSR:1;
} __attribute__ ((packed));

/* This stores all control uplink flags */
struct ctrl_ul {
	u8 port;
	unsigned int reserved:6;
	unsigned int RTS:1;
	unsigned int DTR:1;
} __attribute__ ((packed));

#else
/* Little endian */

/* This represents the toggle information */
struct toggles {} __attribute__ ((packed));

/* Configuration table to read at startup of card */
struct config_table {} __attribute__ ((packed));

/* This stores all control downlink flags */
struct ctrl_dl {} __attribute__ ((packed));

/* This stores all control uplink flags */
struct ctrl_ul {} __attribute__ ((packed));
#endif

/* This holds all information that is needed regarding a port */
struct port {};

/* Private data one for each card in the system */
struct nozomi {};

/* Global variables */
static const struct pci_device_id nozomi_pci_tbl[] =;

MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl);

static struct nozomi *ndevs[NOZOMI_MAX_CARDS];
static struct tty_driver *ntty_driver;

static const struct tty_port_operations noz_tty_port_ops;

/*
 * find card by tty_index
 */
static inline struct nozomi *get_dc_by_tty(const struct tty_struct *tty)
{}

static inline struct port *get_port_by_tty(const struct tty_struct *tty)
{}

/*
 * TODO:
 * -Optimize
 * -Rewrite cleaner
 */

static void read_mem32(u32 *buf, const void __iomem *mem_addr_start,
			u32 size_bytes)
{}

/*
 * TODO:
 * -Optimize
 * -Rewrite cleaner
 */
static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf,
			u32 size_bytes)
{}

/* Setup pointers to different channels and also setup buffer sizes. */
static void nozomi_setup_memory(struct nozomi *dc)
{}

/* Dump config table under initalization phase */
#ifdef DEBUG
static void dump_table(const struct nozomi *dc)
{}
#else
static inline void dump_table(const struct nozomi *dc) { }
#endif

/*
 * Read configuration table from card under intalization phase
 * Returns 1 if ok, else 0
 */
static int nozomi_read_config_table(struct nozomi *dc)
{}

/* Enable uplink interrupts  */
static void enable_transmit_ul(enum port_type port, struct nozomi *dc)
{}

/* Disable uplink interrupts  */
static void disable_transmit_ul(enum port_type port, struct nozomi *dc)
{}

/* Enable downlink interrupts */
static void enable_transmit_dl(enum port_type port, struct nozomi *dc)
{}

/* Disable downlink interrupts */
static void disable_transmit_dl(enum port_type port, struct nozomi *dc)
{}

/*
 * Return 1 - send buffer to card and ack.
 * Return 0 - don't ack, don't send buffer to card.
 */
static int send_data(enum port_type index, struct nozomi *dc)
{}

/* If all data has been read, return 1, else 0 */
static int receive_data(enum port_type index, struct nozomi *dc)
{}

/* Debug for interrupts */
#ifdef DEBUG
static char *interrupt2str(u16 interrupt)
{}
#endif

/*
 * Receive flow control
 * Return 1 - If ok, else 0
 */
static int receive_flow_control(struct nozomi *dc)
{}

static enum ctrl_port_type port2ctrl(enum port_type port,
					const struct nozomi *dc)
{}

/*
 * Send flow control, can only update one channel at a time
 * Return 0 - If we have updated all flow control
 * Return 1 - If we need to update more flow control, ack current enable more
 */
static int send_flow_control(struct nozomi *dc)
{}

/*
 * Handle downlink data, ports that are handled are modem and diagnostics
 * Return 1 - ok
 * Return 0 - toggle fields are out of sync
 */
static int handle_data_dl(struct nozomi *dc, enum port_type port, u8 *toggle,
			u16 read_iir, u16 mask1, u16 mask2)
{}

/*
 * Handle uplink data, this is currently for the modem port
 * Return 1 - ok
 * Return 0 - toggle field are out of sync
 */
static int handle_data_ul(struct nozomi *dc, enum port_type port, u16 read_iir)
{}

static irqreturn_t interrupt_handler(int irq, void *dev_id)
{}

static void nozomi_get_card_type(struct nozomi *dc)
{}

static void nozomi_setup_private_data(struct nozomi *dc)
{}

static ssize_t card_type_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{}
static DEVICE_ATTR_RO(card_type);

static ssize_t open_ttys_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{}
static DEVICE_ATTR_RO(open_ttys);

static void make_sysfs_files(struct nozomi *dc)
{}

static void remove_sysfs_files(struct nozomi *dc)
{}

/* Allocate memory for one device */
static int nozomi_card_init(struct pci_dev *pdev,
				      const struct pci_device_id *ent)
{}

static void tty_exit(struct nozomi *dc)
{}

/* Deallocate memory for one device */
static void nozomi_card_exit(struct pci_dev *pdev)
{}

static void set_rts(const struct tty_struct *tty, int rts)
{}

static void set_dtr(const struct tty_struct *tty, int dtr)
{}

/*
 * ----------------------------------------------------------------------------
 * TTY code
 * ----------------------------------------------------------------------------
 */

static int ntty_install(struct tty_driver *driver, struct tty_struct *tty)
{}

static void ntty_cleanup(struct tty_struct *tty)
{}

static int ntty_activate(struct tty_port *tport, struct tty_struct *tty)
{}

static int ntty_open(struct tty_struct *tty, struct file *filp)
{}

static void ntty_shutdown(struct tty_port *tport)
{}

static void ntty_close(struct tty_struct *tty, struct file *filp)
{}

static void ntty_hangup(struct tty_struct *tty)
{}

/*
 * called when the userspace process writes to the tty (/dev/noz*).
 * Data is inserted into a fifo, which is then read and transferred to the modem.
 */
static ssize_t ntty_write(struct tty_struct *tty, const u8 *buffer,
			  size_t count)
{}

/*
 * Calculate how much is left in device
 * This method is called by the upper tty layer.
 *   #according to sources N_TTY.c it expects a value >= 0 and
 *    does not check for negative values.
 *
 * If the port is unplugged report lots of room and let the bits
 * dribble away so we don't block anything.
 */
static unsigned int ntty_write_room(struct tty_struct *tty)
{}

/* Gets io control parameters */
static int ntty_tiocmget(struct tty_struct *tty)
{}

/* Sets io controls parameters */
static int ntty_tiocmset(struct tty_struct *tty,
					unsigned int set, unsigned int clear)
{}

static int ntty_cflags_changed(struct port *port, unsigned long flags,
		struct async_icount *cprev)
{}

static int ntty_tiocgicount(struct tty_struct *tty,
				struct serial_icounter_struct *icount)
{}

static int ntty_ioctl(struct tty_struct *tty,
		      unsigned int cmd, unsigned long arg)
{}

/*
 * Called by the upper tty layer when tty buffers are ready
 * to receive data again after a call to throttle.
 */
static void ntty_unthrottle(struct tty_struct *tty)
{}

/*
 * Called by the upper tty layer when the tty buffers are almost full.
 * The driver should stop send more data.
 */
static void ntty_throttle(struct tty_struct *tty)
{}

/* Returns number of chars in buffer, called by tty layer */
static unsigned int ntty_chars_in_buffer(struct tty_struct *tty)
{}

static const struct tty_port_operations noz_tty_port_ops =;

static const struct tty_operations tty_ops =;

/* Module initialization */
static struct pci_driver nozomi_driver =;

static __init int nozomi_init(void)
{}

static __exit void nozomi_exit(void)
{}

module_init();
module_exit(nozomi_exit);

MODULE_LICENSE();
MODULE_DESCRIPTION();