/* $Id: hysdn_boot.c,v 1.4.6.4 2001/09/23 22:24:54 kai Exp $
 *
 * Linux driver for HYSDN cards
 * specific routines for booting and pof handling
 *
 * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
 * Copyright 1999 by Werner Cornelius (werner@titro.de)
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <asm/uaccess.h>

#include "hysdn_defs.h"
#include "hysdn_pof.h"

/********************************/
/* defines for pof read handler */
/********************************/
#define POF_READ_FILE_HEAD  0
#define POF_READ_TAG_HEAD   1
#define POF_READ_TAG_DATA   2

/************************************************************/
/* definition of boot specific data area. This data is only */
/* needed during boot and so allocated dynamically.         */
/************************************************************/
struct boot_data {
	word Cryptor;		/* for use with Decrypt function */
	word Nrecs;		/* records remaining in file */
	uchar pof_state;	/* actual state of read handler */
	uchar is_crypted;	/* card data is crypted */
	int BufSize;		/* actual number of bytes bufferd */
	int last_error;		/* last occurred error */
	word pof_recid;		/* actual pof recid */
	ulong pof_reclen;	/* total length of pof record data */
	ulong pof_recoffset;	/* actual offset inside pof record */
	union {
		uchar BootBuf[BOOT_BUF_SIZE];	/* buffer as byte count */
		tPofRecHdr PofRecHdr;	/* header for actual record/chunk */
		tPofFileHdr PofFileHdr;		/* header from POF file */
		tPofTimeStamp PofTime;	/* time information */
	} buf;
};

/*****************************************************/
/*  start decryption of successive POF file chuncks.  */
/*                                                   */
/*  to be called at start of POF file reading,       */
/*  before starting any decryption on any POF record. */
/*****************************************************/
static void
StartDecryption(struct boot_data *boot)
{
	boot->Cryptor = CRYPT_STARTTERM;
}				/* StartDecryption */


/***************************************************************/
/* decrypt complete BootBuf                                    */
/* NOTE: decryption must be applied to all or none boot tags - */
/*       to HI and LO boot loader and (all) seq tags, because  */
/*       global Cryptor is started for whole POF.              */
/***************************************************************/
static void
DecryptBuf(struct boot_data *boot, int cnt)
{
	uchar *bufp = boot->buf.BootBuf;

	while (cnt--) {
		boot->Cryptor = (boot->Cryptor >> 1) ^ ((boot->Cryptor & 1U) ? CRYPT_FEEDTERM : 0);
		*bufp++ ^= (uchar) boot->Cryptor;
	}
}				/* DecryptBuf */

/********************************************************************************/
/* pof_handle_data executes the required actions dependent on the active record */
/* id. If successful 0 is returned, a negative value shows an error.           */
/********************************************************************************/
static int
pof_handle_data(hysdn_card * card, int datlen)
{
	struct boot_data *boot = card->boot;	/* pointer to boot specific data */
	long l;
	uchar *imgp;
	int img_len;

	/* handle the different record types */
	switch (boot->pof_recid) {

		case TAG_TIMESTMP:
			if (card->debug_flags & LOG_POF_RECORD)
				hysdn_addlog(card, "POF created %s", boot->buf.PofTime.DateTimeText);
			break;

		case TAG_CBOOTDTA:
			DecryptBuf(boot, datlen);	/* we need to encrypt the buffer */
		case TAG_BOOTDTA:
			if (card->debug_flags & LOG_POF_RECORD)
				hysdn_addlog(card, "POF got %s len=%d offs=0x%lx",
					     (boot->pof_recid == TAG_CBOOTDTA) ? "CBOOTDATA" : "BOOTDTA",
					     datlen, boot->pof_recoffset);

			if (boot->pof_reclen != POF_BOOT_LOADER_TOTAL_SIZE) {
				boot->last_error = EPOF_BAD_IMG_SIZE;	/* invalid length */
				return (boot->last_error);
			}
			imgp = boot->buf.BootBuf;	/* start of buffer */
			img_len = datlen;	/* maximum length to transfer */

			l = POF_BOOT_LOADER_OFF_IN_PAGE -
			    (boot->pof_recoffset & (POF_BOOT_LOADER_PAGE_SIZE - 1));
			if (l > 0) {
				/* buffer needs to be truncated */
				imgp += l;	/* advance pointer */
				img_len -= l;	/* adjust len */
			}
			/* at this point no special handling for data wrapping over buffer */
			/* is necessary, because the boot image always will be adjusted to */
			/* match a page boundary inside the buffer.                        */
			/* The buffer for the boot image on the card is filled in 2 cycles */
			/* first the 1024 hi-words are put in the buffer, then the low 1024 */
			/* word are handled in the same way with different offset.         */

			if (img_len > 0) {
				/* data available for copy */
				if ((boot->last_error =
				     card->writebootimg(card, imgp,
							(boot->pof_recoffset > POF_BOOT_LOADER_PAGE_SIZE) ? 2 : 0)) < 0)
					return (boot->last_error);
			}
			break;	/* end of case boot image hi/lo */

		case TAG_CABSDATA:
			DecryptBuf(boot, datlen);	/* we need to encrypt the buffer */
		case TAG_ABSDATA:
			if (card->debug_flags & LOG_POF_RECORD)
				hysdn_addlog(card, "POF got %s len=%d offs=0x%lx",
					     (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
					     datlen, boot->pof_recoffset);

			if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen) < 0))
				return (boot->last_error);	/* error writing data */

			if (boot->pof_recoffset + datlen >= boot->pof_reclen)
				return (card->waitpofready(card));	/* data completely spooled, wait for ready */

			break;	/* end of case boot seq data */

		default:
			if (card->debug_flags & LOG_POF_RECORD)
				hysdn_addlog(card, "POF got data(id=0x%lx) len=%d offs=0x%lx", boot->pof_recid,
					     datlen, boot->pof_recoffset);

			break;	/* simply skip record */
	}			/* switch boot->pof_recid */

	return (0);
}				/* pof_handle_data */


/******************************************************************************/
/* pof_write_buffer is called when the buffer has been filled with the needed */
/* number of data bytes. The number delivered is additionally supplied for    */
/* verification. The functions handles the data and returns the needed number */
/* of bytes for the next action. If the returned value is 0 or less an error  */
/* occurred and booting must be aborted.                                       */
/******************************************************************************/
int
pof_write_buffer(hysdn_card * card, int datlen)
{
	struct boot_data *boot = card->boot;	/* pointer to boot specific data */

	if (!boot)
		return (-EFAULT);	/* invalid call */
	if (boot->last_error < 0)
		return (boot->last_error);	/* repeated error */

	if (card->debug_flags & LOG_POF_WRITE)
		hysdn_addlog(card, "POF write: got %d bytes ", datlen);

	switch (boot->pof_state) {
		case POF_READ_FILE_HEAD:
			if (card->debug_flags & LOG_POF_WRITE)
				hysdn_addlog(card, "POF write: checking file header");

			if (datlen != sizeof(tPofFileHdr)) {
				boot->last_error = -EPOF_INTERNAL;
				break;
			}
			if (boot->buf.PofFileHdr.Magic != TAGFILEMAGIC) {
				boot->last_error = -EPOF_BAD_MAGIC;
				break;
			}
			/* Setup the new state and vars */
			boot->Nrecs = (word) (boot->buf.PofFileHdr.N_PofRecs);	/* limited to 65535 */
			boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
			boot->last_error = sizeof(tPofRecHdr);	/* new length */
			break;

		case POF_READ_TAG_HEAD:
			if (card->debug_flags & LOG_POF_WRITE)
				hysdn_addlog(card, "POF write: checking tag header");

			if (datlen != sizeof(tPofRecHdr)) {
				boot->last_error = -EPOF_INTERNAL;
				break;
			}
			boot->pof_recid = boot->buf.PofRecHdr.PofRecId;		/* actual pof recid */
			boot->pof_reclen = boot->buf.PofRecHdr.PofRecDataLen;	/* total length */
			boot->pof_recoffset = 0;	/* no starting offset */

			if (card->debug_flags & LOG_POF_RECORD)
				hysdn_addlog(card, "POF: got record id=0x%lx length=%ld ",
				      boot->pof_recid, boot->pof_reclen);

			boot->pof_state = POF_READ_TAG_DATA;	/* now start with tag data */
			if (boot->pof_reclen < BOOT_BUF_SIZE)
				boot->last_error = boot->pof_reclen;	/* limit size */
			else
				boot->last_error = BOOT_BUF_SIZE;	/* maximum */

			if (!boot->last_error) {	/* no data inside record */
				boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
				boot->last_error = sizeof(tPofRecHdr);	/* new length */
			}
			break;

		case POF_READ_TAG_DATA:
			if (card->debug_flags & LOG_POF_WRITE)
				hysdn_addlog(card, "POF write: getting tag data");

			if (datlen != boot->last_error) {
				boot->last_error = -EPOF_INTERNAL;
				break;
			}
			if ((boot->last_error = pof_handle_data(card, datlen)) < 0)
				return (boot->last_error);	/* an error occurred */
			boot->pof_recoffset += datlen;
			if (boot->pof_recoffset >= boot->pof_reclen) {
				boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
				boot->last_error = sizeof(tPofRecHdr);	/* new length */
			} else {
				if (boot->pof_reclen - boot->pof_recoffset < BOOT_BUF_SIZE)
					boot->last_error = boot->pof_reclen - boot->pof_recoffset;	/* limit size */
				else
					boot->last_error = BOOT_BUF_SIZE;	/* maximum */
			}
			break;

		default:
			boot->last_error = -EPOF_INTERNAL;	/* unknown state */
			break;
	}			/* switch (boot->pof_state) */

	return (boot->last_error);
}				/* pof_write_buffer */


/*******************************************************************************/
/* pof_write_open is called when an open for boot on the cardlog device occurs. */
/* The function returns the needed number of bytes for the next operation. If  */
/* the returned number is less or equal 0 an error specified by this code      */
/* occurred. Additionally the pointer to the buffer data area is set on success */
/*******************************************************************************/
int
pof_write_open(hysdn_card * card, uchar ** bufp)
{
	struct boot_data *boot;	/* pointer to boot specific data */

	if (card->boot) {
		if (card->debug_flags & LOG_POF_OPEN)
			hysdn_addlog(card, "POF open: already opened for boot");
		return (-ERR_ALREADY_BOOT);	/* boot already active */
	}
	/* error no mem available */
	if (!(boot = kmalloc(sizeof(struct boot_data), GFP_KERNEL))) {
		if (card->debug_flags & LOG_MEM_ERR)
			hysdn_addlog(card, "POF open: unable to allocate mem");
		return (-EFAULT);
	}
	card->boot = boot;
	card->state = CARD_STATE_BOOTING;
	memset(boot, 0, sizeof(struct boot_data));

	card->stopcard(card);	/* first stop the card */
	if (card->testram(card)) {
		if (card->debug_flags & LOG_POF_OPEN)
			hysdn_addlog(card, "POF open: DPRAM test failure");
		boot->last_error = -ERR_BOARD_DPRAM;
		card->state = CARD_STATE_BOOTERR;	/* show boot error */
		return (boot->last_error);
	}
	boot->BufSize = 0;	/* Buffer is empty */
	boot->pof_state = POF_READ_FILE_HEAD;	/* read file header */
	StartDecryption(boot);	/* if POF File should be encrypted */

	if (card->debug_flags & LOG_POF_OPEN)
		hysdn_addlog(card, "POF open: success");

	*bufp = boot->buf.BootBuf;	/* point to buffer */
	return (sizeof(tPofFileHdr));
}				/* pof_write_open */

/********************************************************************************/
/* pof_write_close is called when an close of boot on the cardlog device occurs. */
/* The return value must be 0 if everything has happened as desired.            */
/********************************************************************************/
int
pof_write_close(hysdn_card * card)
{
	struct boot_data *boot = card->boot;	/* pointer to boot specific data */

	if (!boot)
		return (-EFAULT);	/* invalid call */

	card->boot = NULL;	/* no boot active */
	kfree(boot);

	if (card->state == CARD_STATE_RUN)
		card->set_errlog_state(card, 1);	/* activate error log */

	if (card->debug_flags & LOG_POF_OPEN)
		hysdn_addlog(card, "POF close: success");

	return (0);
}				/* pof_write_close */

/*********************************************************************************/
/* EvalSysrTokData checks additional records delivered with the Sysready Message */
/* when POF has been booted. A return value of 0 is used if no error occurred.    */
/*********************************************************************************/
int
EvalSysrTokData(hysdn_card * card, uchar * cp, int len)
{
	u_char *p;
	u_char crc;

	if (card->debug_flags & LOG_POF_RECORD)
		hysdn_addlog(card, "SysReady Token data length %d", len);

	if (len < 2) {
		hysdn_addlog(card, "SysReady Token Data to short");
		return (1);
	}
	for (p = cp, crc = 0; p < (cp + len - 2); p++)
		if ((crc & 0x80))
			crc = (((u_char) (crc << 1)) + 1) + *p;
		else
			crc = ((u_char) (crc << 1)) + *p;
	crc = ~crc;
	if (crc != *(cp + len - 1)) {
		hysdn_addlog(card, "SysReady Token Data invalid CRC");
		return (1);
	}
	len--;			/* don't check CRC byte */
	while (len > 0) {

		if (*cp == SYSR_TOK_END)
			return (0);	/* End of Token stream */

		if (len < (*(cp + 1) + 2)) {
			hysdn_addlog(card, "token 0x%x invalid length %d", *cp, *(cp + 1));
			return (1);
		}
		switch (*cp) {
			case SYSR_TOK_B_CHAN:	/* 1 */
				if (*(cp + 1) != 1)
					return (1);	/* length invalid */
				card->bchans = *(cp + 2);
				break;

			case SYSR_TOK_FAX_CHAN:	/* 2 */
				if (*(cp + 1) != 1)
					return (1);	/* length invalid */
				card->faxchans = *(cp + 2);
				break;

			case SYSR_TOK_MAC_ADDR:	/* 3 */
				if (*(cp + 1) != 6)
					return (1);	/* length invalid */
				memcpy(card->mac_addr, cp + 2, 6);
				break;

			default:
				hysdn_addlog(card, "unknown token 0x%02x length %d", *cp, *(cp + 1));
				break;
		}
		len -= (*(cp + 1) + 2);		/* adjust len */
		cp += (*(cp + 1) + 2);	/* and pointer */
	}

	hysdn_addlog(card, "no end token found");
	return (1);
}				/* EvalSysrTokData */
