/* $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 <linux/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 {
	unsigned short Cryptor;	/* for use with Decrypt function */
	unsigned short Nrecs;	/* records remaining in file */
	unsigned char pof_state;/* actual state of read handler */
	unsigned char is_crypted;/* card data is crypted */
	int BufSize;		/* actual number of bytes bufferd */
	int last_error;		/* last occurred error */
	unsigned short pof_recid;/* actual pof recid */
	unsigned long pof_reclen;/* total length of pof record data */
	unsigned long pof_recoffset;/* actual offset inside pof record */
	union {
		unsigned char 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)
{
	unsigned char *bufp = boot->buf.BootBuf;

	while (cnt--) {
		boot->Cryptor = (boot->Cryptor >> 1) ^ ((boot->Cryptor & 1U) ? CRYPT_FEEDTERM : 0);
		*bufp++ ^= (unsigned char)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;
	unsigned char *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 = (unsigned short)(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, unsigned char **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 = kzalloc(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;

	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, unsigned char *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 */
