/* $Id: packet.c,v 1.5.8.1 2001/09/23 22:24:59 kai Exp $
 *
 * Copyright (C) 1996  SpellCaster Telecommunications Inc.
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 * For more information, please contact gpl-info@spellcast.com or write:
 *
 *     SpellCaster Telecommunications Inc.
 *     5621 Finch Avenue East, Unit #3
 *     Scarborough, Ontario  Canada
 *     M1B 2T9
 *     +1 (416) 297-8565
 *     +1 (416) 297-6433 Facsimile
 */

#include "includes.h"
#include "hardware.h"
#include "message.h"
#include "card.h"

int sndpkt(int devId, int channel, int ack, struct sk_buff *data)
{
	LLData	ReqLnkWrite;
	int status;
	int card;
	unsigned long len;

	card = get_card_from_id(devId);

	if(!IS_VALID_CARD(card)) {
		pr_debug("invalid param: %d is not a valid card id\n", card);
		return -ENODEV;
	}

	pr_debug("%s: sndpkt: frst = 0x%lx nxt = %d  f = %d n = %d\n",
		sc_adapter[card]->devicename,
		sc_adapter[card]->channel[channel].first_sendbuf,
		sc_adapter[card]->channel[channel].next_sendbuf,
		sc_adapter[card]->channel[channel].free_sendbufs,
		sc_adapter[card]->channel[channel].num_sendbufs);

	if(!sc_adapter[card]->channel[channel].free_sendbufs) {
		pr_debug("%s: out of TX buffers\n",
				sc_adapter[card]->devicename);
		return -EINVAL;
	}

	if(data->len > BUFFER_SIZE) {
		pr_debug("%s: data overflows buffer size (data > buffer)\n",
			sc_adapter[card]->devicename);
		return -EINVAL;
	}

	ReqLnkWrite.buff_offset = sc_adapter[card]->channel[channel].next_sendbuf *
		BUFFER_SIZE + sc_adapter[card]->channel[channel].first_sendbuf;
	ReqLnkWrite.msg_len = data->len; /* sk_buff size */
	pr_debug("%s: writing %d bytes to buffer offset 0x%lx\n",
			sc_adapter[card]->devicename,
			ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset);
	memcpy_toshmem(card, (char *)ReqLnkWrite.buff_offset, data->data, ReqLnkWrite.msg_len);

	/*
	 * sendmessage
	 */
	pr_debug("%s: sndpkt size=%d, buf_offset=0x%lx buf_indx=%d\n",
		sc_adapter[card]->devicename,
		ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset,
		sc_adapter[card]->channel[channel].next_sendbuf);

	status = sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkWrite,
				channel+1, sizeof(LLData), (unsigned int*)&ReqLnkWrite);
	len = data->len;
	if(status) {
		pr_debug("%s: failed to send packet, status = %d\n",
				sc_adapter[card]->devicename, status);
		return -1;
	}
	else {
		sc_adapter[card]->channel[channel].free_sendbufs--;
		sc_adapter[card]->channel[channel].next_sendbuf =
			++sc_adapter[card]->channel[channel].next_sendbuf ==
			sc_adapter[card]->channel[channel].num_sendbufs ? 0 :
			sc_adapter[card]->channel[channel].next_sendbuf;
			pr_debug("%s: packet sent successfully\n", sc_adapter[card]->devicename);
		dev_kfree_skb(data);
		indicate_status(card,ISDN_STAT_BSENT,channel, (char *)&len);
	}
	return len;
}

void rcvpkt(int card, RspMessage *rcvmsg)
{
	LLData newll;
	struct sk_buff *skb;

	if(!IS_VALID_CARD(card)) {
		pr_debug("invalid param: %d is not a valid card id\n", card);
		return;
	}

	switch(rcvmsg->rsp_status){
	case 0x01:
	case 0x02:
	case 0x70:
		pr_debug("%s: error status code: 0x%x\n",
			sc_adapter[card]->devicename, rcvmsg->rsp_status);
		return;
	case 0x00: 
	    if (!(skb = dev_alloc_skb(rcvmsg->msg_data.response.msg_len))) {
			printk(KERN_WARNING "%s: rcvpkt out of memory, dropping packet\n",
				sc_adapter[card]->devicename);
			return;
		}
		skb_put(skb, rcvmsg->msg_data.response.msg_len);
		pr_debug("%s: getting data from offset: 0x%lx\n",
			sc_adapter[card]->devicename,
			rcvmsg->msg_data.response.buff_offset);
		memcpy_fromshmem(card,
			skb_put(skb, rcvmsg->msg_data.response.msg_len),
		 	(char *)rcvmsg->msg_data.response.buff_offset,
			rcvmsg->msg_data.response.msg_len);
		sc_adapter[card]->card->rcvcallb_skb(sc_adapter[card]->driverId,
			rcvmsg->phy_link_no-1, skb);

	case 0x03:
		/*
	 	 * Recycle the buffer
	 	 */
		pr_debug("%s: buffer size : %d\n",
				sc_adapter[card]->devicename, BUFFER_SIZE);
/*		memset_shmem(card, rcvmsg->msg_data.response.buff_offset, 0, BUFFER_SIZE); */
		newll.buff_offset = rcvmsg->msg_data.response.buff_offset;
		newll.msg_len = BUFFER_SIZE;
		pr_debug("%s: recycled buffer at offset 0x%lx size %d\n",
			sc_adapter[card]->devicename,
			newll.buff_offset, newll.msg_len);
		sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead,
			rcvmsg->phy_link_no, sizeof(LLData), (unsigned int *)&newll);
	}

}

int setup_buffers(int card, int c)
{
	unsigned int nBuffers, i, cBase;
	unsigned int buffer_size;
	LLData	RcvBuffOffset;

	if(!IS_VALID_CARD(card)) {
		pr_debug("invalid param: %d is not a valid card id\n", card);
		return -ENODEV;
	}

	/*
	 * Calculate the buffer offsets (send/recv/send/recv)
	 */
	pr_debug("%s: setting up channel buffer space in shared RAM\n",
			sc_adapter[card]->devicename);
	buffer_size = BUFFER_SIZE;
	nBuffers = ((sc_adapter[card]->ramsize - BUFFER_BASE) / buffer_size) / 2;
	nBuffers = nBuffers > BUFFERS_MAX ? BUFFERS_MAX : nBuffers;
	pr_debug("%s: calculating buffer space: %d buffers, %d big\n",
		sc_adapter[card]->devicename,
		nBuffers, buffer_size);
	if(nBuffers < 2) {
		pr_debug("%s: not enough buffer space\n",
			sc_adapter[card]->devicename);
		return -1;
	}
	cBase = (nBuffers * buffer_size) * (c - 1);
	pr_debug("%s: channel buffer offset from shared RAM: 0x%x\n",
			sc_adapter[card]->devicename, cBase);
	sc_adapter[card]->channel[c-1].first_sendbuf = BUFFER_BASE + cBase;
	sc_adapter[card]->channel[c-1].num_sendbufs = nBuffers / 2;
	sc_adapter[card]->channel[c-1].free_sendbufs = nBuffers / 2;
	sc_adapter[card]->channel[c-1].next_sendbuf = 0;
	pr_debug("%s: send buffer setup complete: first=0x%lx n=%d f=%d, nxt=%d\n",
				sc_adapter[card]->devicename,
				sc_adapter[card]->channel[c-1].first_sendbuf,
				sc_adapter[card]->channel[c-1].num_sendbufs,
				sc_adapter[card]->channel[c-1].free_sendbufs,
				sc_adapter[card]->channel[c-1].next_sendbuf);

	/*
	 * Prep the receive buffers
	 */
	pr_debug("%s: adding %d RecvBuffers:\n",
			sc_adapter[card]->devicename, nBuffers /2);
	for (i = 0 ; i < nBuffers / 2; i++) {
		RcvBuffOffset.buff_offset = 
			((sc_adapter[card]->channel[c-1].first_sendbuf +
			(nBuffers / 2) * buffer_size) + (buffer_size * i));
		RcvBuffOffset.msg_len = buffer_size;
		pr_debug("%s: adding RcvBuffer #%d offset=0x%lx sz=%d bufsz:%d\n",
				sc_adapter[card]->devicename,
				i + 1, RcvBuffOffset.buff_offset, 
				RcvBuffOffset.msg_len,buffer_size);
		sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead,
				c, sizeof(LLData), (unsigned int *)&RcvBuffOffset);
	} 
	return 0;
}

