/*
 * Common data handling layer for ser_gigaset and usb_gigaset
 *
 * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>,
 *                       Hansjoerg Lipp <hjlipp@web.de>,
 *                       Stefan Eilers.
 *
 * =====================================================================
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License as
 *	published by the Free Software Foundation; either version 2 of
 *	the License, or (at your option) any later version.
 * =====================================================================
 */

#include "gigaset.h"
#include <linux/crc-ccitt.h>
#include <linux/bitrev.h>

//#define GIG_M10x_STUFF_VOICE_DATA

/* check if byte must be stuffed/escaped
 * I'm not sure which data should be encoded.
 * Therefore I will go the hard way and decode every value
 * less than 0x20, the flag sequence and the control escape char.
 */
static inline int muststuff(unsigned char c)
{
	if (c < PPP_TRANS) return 1;
	if (c == PPP_FLAG) return 1;
	if (c == PPP_ESCAPE) return 1;
	/* other possible candidates: */
	/* 0x91: XON with parity set */
	/* 0x93: XOFF with parity set */
	return 0;
}

/* == data input =========================================================== */

/* process a block of received bytes in command mode (modem response)
 * Return value:
 *	number of processed bytes
 */
static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes,
			   struct inbuf_t *inbuf)
{
	struct cardstate *cs = inbuf->cs;
	unsigned cbytes      = cs->cbytes;
	int inputstate = inbuf->inputstate;
	int startbytes = numbytes;

	for (;;) {
		cs->respdata[cbytes] = c;
		if (c == 10 || c == 13) {
			gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)",
				__func__, cbytes);
			cs->cbytes = cbytes;
			gigaset_handle_modem_response(cs); /* can change
							      cs->dle */
			cbytes = 0;

			if (cs->dle &&
			    !(inputstate & INS_DLE_command)) {
				inputstate &= ~INS_command;
				break;
			}
		} else {
			/* advance in line buffer, checking for overflow */
			if (cbytes < MAX_RESP_SIZE - 1)
				cbytes++;
			else
				dev_warn(cs->dev, "response too large\n");
		}

		if (!numbytes)
			break;
		c = *src++;
		--numbytes;
		if (c == DLE_FLAG &&
		    (cs->dle || inputstate & INS_DLE_command)) {
			inputstate |= INS_DLE_char;
			break;
		}
	}

	cs->cbytes = cbytes;
	inbuf->inputstate = inputstate;

	return startbytes - numbytes;
}

/* process a block of received bytes in lock mode (tty i/f)
 * Return value:
 *	number of processed bytes
 */
static inline int lock_loop(unsigned char *src, int numbytes,
			    struct inbuf_t *inbuf)
{
	struct cardstate *cs = inbuf->cs;

	gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response",
			   numbytes, src);
	gigaset_if_receive(cs, src, numbytes);

	return numbytes;
}

/* process a block of received bytes in HDLC data mode
 * Collect HDLC frames, undoing byte stuffing and watching for DLE escapes.
 * When a frame is complete, check the FCS and pass valid frames to the LL.
 * If DLE is encountered, return immediately to let the caller handle it.
 * Return value:
 *	number of processed bytes
 *	numbytes (all bytes processed) on error --FIXME
 */
static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
			    struct inbuf_t *inbuf)
{
	struct cardstate *cs = inbuf->cs;
	struct bc_state *bcs = inbuf->bcs;
	int inputstate = bcs->inputstate;
	__u16 fcs = bcs->fcs;
	struct sk_buff *skb = bcs->skb;
	unsigned char error;
	struct sk_buff *compskb;
	int startbytes = numbytes;
	int l;

	if (unlikely(inputstate & INS_byte_stuff)) {
		inputstate &= ~INS_byte_stuff;
		goto byte_stuff;
	}
	for (;;) {
		if (unlikely(c == PPP_ESCAPE)) {
			if (unlikely(!numbytes)) {
				inputstate |= INS_byte_stuff;
				break;
			}
			c = *src++;
			--numbytes;
			if (unlikely(c == DLE_FLAG &&
				     (cs->dle ||
				      inbuf->inputstate & INS_DLE_command))) {
				inbuf->inputstate |= INS_DLE_char;
				inputstate |= INS_byte_stuff;
				break;
			}
byte_stuff:
			c ^= PPP_TRANS;
#ifdef CONFIG_GIGASET_DEBUG
			if (unlikely(!muststuff(c)))
				gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c);
#endif
		} else if (unlikely(c == PPP_FLAG)) {
			if (unlikely(inputstate & INS_skip_frame)) {
				if (!(inputstate & INS_have_data)) { /* 7E 7E */
#ifdef CONFIG_GIGASET_DEBUG
					++bcs->emptycount;
#endif
				} else
					gig_dbg(DEBUG_HDLC,
					    "7e----------------------------");

				/* end of frame */
				error = 1;
				gigaset_rcv_error(NULL, cs, bcs);
			} else if (!(inputstate & INS_have_data)) { /* 7E 7E */
#ifdef CONFIG_GIGASET_DEBUG
				++bcs->emptycount;
#endif
				break;
			} else {
				gig_dbg(DEBUG_HDLC,
					"7e----------------------------");

				/* end of frame */
				error = 0;

				if (unlikely(fcs != PPP_GOODFCS)) {
					dev_err(cs->dev,
					    "Packet checksum at %lu failed, "
					    "packet is corrupted (%u bytes)!\n",
					    bcs->rcvbytes, skb->len);
					compskb = NULL;
					gigaset_rcv_error(compskb, cs, bcs);
					error = 1;
				} else {
					if (likely((l = skb->len) > 2)) {
						skb->tail -= 2;
						skb->len -= 2;
					} else {
						dev_kfree_skb(skb);
						skb = NULL;
						inputstate |= INS_skip_frame;
						if (l == 1) {
							dev_err(cs->dev,
						  "invalid packet size (1)!\n");
							error = 1;
							gigaset_rcv_error(NULL,
								cs, bcs);
						}
					}
					if (likely(!(error ||
						     (inputstate &
						      INS_skip_frame)))) {
						gigaset_rcv_skb(skb, cs, bcs);
					}
				}
			}

			if (unlikely(error))
				if (skb)
					dev_kfree_skb(skb);

			fcs = PPP_INITFCS;
			inputstate &= ~(INS_have_data | INS_skip_frame);
			if (unlikely(bcs->ignore)) {
				inputstate |= INS_skip_frame;
				skb = NULL;
			} else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) {
				skb_reserve(skb, HW_HDR_LEN);
			} else {
				dev_warn(cs->dev,
					 "could not allocate new skb\n");
				inputstate |= INS_skip_frame;
			}

			break;
#ifdef CONFIG_GIGASET_DEBUG
		} else if (unlikely(muststuff(c))) {
			/* Should not happen. Possible after ZDLE=1<CR><LF>. */
			gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c);
#endif
		}

		/* add character */

#ifdef CONFIG_GIGASET_DEBUG
		if (unlikely(!(inputstate & INS_have_data))) {
			gig_dbg(DEBUG_HDLC, "7e (%d x) ================",
				bcs->emptycount);
			bcs->emptycount = 0;
		}
#endif

		inputstate |= INS_have_data;

		if (likely(!(inputstate & INS_skip_frame))) {
			if (unlikely(skb->len == SBUFSIZE)) {
				dev_warn(cs->dev, "received packet too long\n");
				dev_kfree_skb_any(skb);
				skb = NULL;
				inputstate |= INS_skip_frame;
				break;
			}
			*__skb_put(skb, 1) = c;
			fcs = crc_ccitt_byte(fcs, c);
		}

		if (unlikely(!numbytes))
			break;
		c = *src++;
		--numbytes;
		if (unlikely(c == DLE_FLAG &&
			     (cs->dle ||
			      inbuf->inputstate & INS_DLE_command))) {
			inbuf->inputstate |= INS_DLE_char;
			break;
		}
	}
	bcs->inputstate = inputstate;
	bcs->fcs = fcs;
	bcs->skb = skb;
	return startbytes - numbytes;
}

/* process a block of received bytes in transparent data mode
 * Invert bytes, undoing byte stuffing and watching for DLE escapes.
 * If DLE is encountered, return immediately to let the caller handle it.
 * Return value:
 *	number of processed bytes
 *	numbytes (all bytes processed) on error --FIXME
 */
static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
			    struct inbuf_t *inbuf)
{
	struct cardstate *cs = inbuf->cs;
	struct bc_state *bcs = inbuf->bcs;
	int inputstate = bcs->inputstate;
	struct sk_buff *skb = bcs->skb;
	int startbytes = numbytes;

	for (;;) {
		/* add character */
		inputstate |= INS_have_data;

		if (likely(!(inputstate & INS_skip_frame))) {
			if (unlikely(skb->len == SBUFSIZE)) {
				//FIXME just pass skb up and allocate a new one
				dev_warn(cs->dev, "received packet too long\n");
				dev_kfree_skb_any(skb);
				skb = NULL;
				inputstate |= INS_skip_frame;
				break;
			}
			*__skb_put(skb, 1) = bitrev8(c);
		}

		if (unlikely(!numbytes))
			break;
		c = *src++;
		--numbytes;
		if (unlikely(c == DLE_FLAG &&
			     (cs->dle ||
			      inbuf->inputstate & INS_DLE_command))) {
			inbuf->inputstate |= INS_DLE_char;
			break;
		}
	}

	/* pass data up */
	if (likely(inputstate & INS_have_data)) {
		if (likely(!(inputstate & INS_skip_frame))) {
			gigaset_rcv_skb(skb, cs, bcs);
		}
		inputstate &= ~(INS_have_data | INS_skip_frame);
		if (unlikely(bcs->ignore)) {
			inputstate |= INS_skip_frame;
			skb = NULL;
		} else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN))
				  != NULL)) {
			skb_reserve(skb, HW_HDR_LEN);
		} else {
			dev_warn(cs->dev, "could not allocate new skb\n");
			inputstate |= INS_skip_frame;
		}
	}

	bcs->inputstate = inputstate;
	bcs->skb = skb;
	return startbytes - numbytes;
}

/* process a block of data received from the device
 */
void gigaset_m10x_input(struct inbuf_t *inbuf)
{
	struct cardstate *cs;
	unsigned tail, head, numbytes;
	unsigned char *src, c;
	int procbytes;

	head = atomic_read(&inbuf->head);
	tail = atomic_read(&inbuf->tail);
	gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);

	if (head != tail) {
		cs = inbuf->cs;
		src = inbuf->data + head;
		numbytes = (head > tail ? RBUFSIZE : tail) - head;
		gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);

		while (numbytes) {
			if (atomic_read(&cs->mstate) == MS_LOCKED) {
				procbytes = lock_loop(src, numbytes, inbuf);
				src += procbytes;
				numbytes -= procbytes;
			} else {
				c = *src++;
				--numbytes;
				if (c == DLE_FLAG && (cs->dle ||
				    inbuf->inputstate & INS_DLE_command)) {
					if (!(inbuf->inputstate & INS_DLE_char)) {
						inbuf->inputstate |= INS_DLE_char;
						goto nextbyte;
					}
					/* <DLE> <DLE> => <DLE> in data stream */
					inbuf->inputstate &= ~INS_DLE_char;
				}

				if (!(inbuf->inputstate & INS_DLE_char)) {

					/* FIXME use function pointers?  */
					if (inbuf->inputstate & INS_command)
						procbytes = cmd_loop(c, src, numbytes, inbuf);
					else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC)
						procbytes = hdlc_loop(c, src, numbytes, inbuf);
					else
						procbytes = iraw_loop(c, src, numbytes, inbuf);

					src += procbytes;
					numbytes -= procbytes;
				} else {  /* DLE char */
					inbuf->inputstate &= ~INS_DLE_char;
					switch (c) {
					case 'X': /*begin of command*/
#ifdef CONFIG_GIGASET_DEBUG
						if (inbuf->inputstate & INS_command)
							dev_err(cs->dev,
					"received <DLE> 'X' in command mode\n");
#endif
						inbuf->inputstate |=
							INS_command | INS_DLE_command;
						break;
					case '.': /*end of command*/
#ifdef CONFIG_GIGASET_DEBUG
						if (!(inbuf->inputstate & INS_command))
							dev_err(cs->dev,
					"received <DLE> '.' in hdlc mode\n");
#endif
						inbuf->inputstate &= cs->dle ?
							~(INS_DLE_command|INS_command)
							: ~INS_DLE_command;
						break;
					//case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */
					default:
						dev_err(cs->dev,
						      "received 0x10 0x%02x!\n",
							(int) c);
						/* FIXME: reset driver?? */
					}
				}
			}
nextbyte:
			if (!numbytes) {
				/* end of buffer, check for wrap */
				if (head > tail) {
					head = 0;
					src = inbuf->data;
					numbytes = tail;
				} else {
					head = tail;
					break;
				}
			}
		}

		gig_dbg(DEBUG_INTR, "setting head to %u", head);
		atomic_set(&inbuf->head, head);
	}
}
EXPORT_SYMBOL_GPL(gigaset_m10x_input);


/* == data output ========================================================== */

/* Encoding of a PPP packet into an octet stuffed HDLC frame
 * with FCS, opening and closing flags.
 * parameters:
 *	skb	skb containing original packet (freed upon return)
 *	head	number of headroom bytes to allocate in result skb
 *	tail	number of tailroom bytes to allocate in result skb
 * Return value:
 *	pointer to newly allocated skb containing the result frame
 */
static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
{
	struct sk_buff *hdlc_skb;
	__u16 fcs;
	unsigned char c;
	unsigned char *cp;
	int len;
	unsigned int stuf_cnt;

	stuf_cnt = 0;
	fcs = PPP_INITFCS;
	cp = skb->data;
	len = skb->len;
	while (len--) {
		if (muststuff(*cp))
			stuf_cnt++;
		fcs = crc_ccitt_byte(fcs, *cp++);
	}
	fcs ^= 0xffff;			/* complement */

	/* size of new buffer: original size + number of stuffing bytes
	 * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes
	 */
	hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head);
	if (!hdlc_skb) {
		dev_kfree_skb(skb);
		return NULL;
	}
	skb_reserve(hdlc_skb, head);

	/* Copy acknowledge request into new skb */
	memcpy(hdlc_skb->head, skb->head, 2);

	/* Add flag sequence in front of everything.. */
	*(skb_put(hdlc_skb, 1)) = PPP_FLAG;

	/* Perform byte stuffing while copying data. */
	while (skb->len--) {
		if (muststuff(*skb->data)) {
			*(skb_put(hdlc_skb, 1)) = PPP_ESCAPE;
			*(skb_put(hdlc_skb, 1)) = (*skb->data++) ^ PPP_TRANS;
		} else
			*(skb_put(hdlc_skb, 1)) = *skb->data++;
	}

	/* Finally add FCS (byte stuffed) and flag sequence */
	c = (fcs & 0x00ff);	/* least significant byte first */
	if (muststuff(c)) {
		*(skb_put(hdlc_skb, 1)) = PPP_ESCAPE;
		c ^= PPP_TRANS;
	}
	*(skb_put(hdlc_skb, 1)) = c;

	c = ((fcs >> 8) & 0x00ff);
	if (muststuff(c)) {
		*(skb_put(hdlc_skb, 1)) = PPP_ESCAPE;
		c ^= PPP_TRANS;
	}
	*(skb_put(hdlc_skb, 1)) = c;

	*(skb_put(hdlc_skb, 1)) = PPP_FLAG;

	dev_kfree_skb(skb);
	return hdlc_skb;
}

/* Encoding of a raw packet into an octet stuffed bit inverted frame
 * parameters:
 *	skb	skb containing original packet (freed upon return)
 *	head	number of headroom bytes to allocate in result skb
 *	tail	number of tailroom bytes to allocate in result skb
 * Return value:
 *	pointer to newly allocated skb containing the result frame
 */
static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
{
	struct sk_buff *iraw_skb;
	unsigned char c;
	unsigned char *cp;
	int len;

	/* worst case: every byte must be stuffed */
	iraw_skb = dev_alloc_skb(2*skb->len + tail + head);
	if (!iraw_skb) {
		dev_kfree_skb(skb);
		return NULL;
	}
	skb_reserve(iraw_skb, head);

	cp = skb->data;
	len = skb->len;
	while (len--) {
		c = bitrev8(*cp++);
		if (c == DLE_FLAG)
			*(skb_put(iraw_skb, 1)) = c;
		*(skb_put(iraw_skb, 1)) = c;
	}
	dev_kfree_skb(skb);
	return iraw_skb;
}

/* gigaset_send_skb
 * called by common.c to queue an skb for sending
 * and start transmission if necessary
 * parameters:
 *	B Channel control structure
 *	skb
 * Return value:
 *	number of bytes accepted for sending
 *	(skb->len if ok, 0 if out of buffer space)
 *	or error code (< 0, eg. -EINVAL)
 */
int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
{
	unsigned len = skb->len;
	unsigned long flags;

	if (bcs->proto2 == ISDN_PROTO_L2_HDLC)
		skb = HDLC_Encode(skb, HW_HDR_LEN, 0);
	else
		skb = iraw_encode(skb, HW_HDR_LEN, 0);
	if (!skb) {
		err("unable to allocate memory for encoding!\n");
		return -ENOMEM;
	}

	skb_queue_tail(&bcs->squeue, skb);
	spin_lock_irqsave(&bcs->cs->lock, flags);
	if (bcs->cs->connected)
		tasklet_schedule(&bcs->cs->write_tasklet);
	spin_unlock_irqrestore(&bcs->cs->lock, flags);

	return len;	/* ok so far */
}
EXPORT_SYMBOL_GPL(gigaset_m10x_send_skb);
