/*
 * Driver for ST5481 USB ISDN modem
 *
 * Author       Frode Isaksen
 * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
 *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include <linux/init.h>
#include <linux/gfp.h>
#include <linux/usb.h>
#include <linux/netdevice.h>
#include <linux/bitrev.h>
#include "st5481.h"

static inline void B_L1L2(struct st5481_bcs *bcs, int pr, void *arg)
{
	struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if;

	ifc->l1l2(ifc, pr, arg);
}

/*
 * Encode and transmit next frame.
 */
static void usb_b_out(struct st5481_bcs *bcs, int buf_nr)
{
	struct st5481_b_out *b_out = &bcs->b_out;
	struct st5481_adapter *adapter = bcs->adapter;
	struct urb *urb;
	unsigned int packet_size, offset;
	int len, buf_size, bytes_sent;
	int i;
	struct sk_buff *skb;

	if (test_and_set_bit(buf_nr, &b_out->busy)) {
		DBG(4, "ep %d urb %d busy", (bcs->channel + 1) * 2, buf_nr);
		return;
	}
	urb = b_out->urb[buf_nr];

	// Adjust isoc buffer size according to flow state
	if (b_out->flow_event & (OUT_DOWN | OUT_UNDERRUN)) {
		buf_size = NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST;
		packet_size = SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST;
		DBG(4, "B%d,adjust flow,add %d bytes", bcs->channel + 1, B_FLOW_ADJUST);
	} else if (b_out->flow_event & OUT_UP) {
		buf_size = NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT - B_FLOW_ADJUST;
		packet_size = SIZE_ISO_PACKETS_B_OUT - B_FLOW_ADJUST;
		DBG(4, "B%d,adjust flow,remove %d bytes", bcs->channel + 1, B_FLOW_ADJUST);
	} else {
		buf_size = NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT;
		packet_size = 8;
	}
	b_out->flow_event = 0;

	len = 0;
	while (len < buf_size) {
		if ((skb = b_out->tx_skb)) {
			DBG_SKB(0x100, skb);
			DBG(4, "B%d,len=%d", bcs->channel + 1, skb->len);

			if (bcs->mode == L1_MODE_TRANS) {
				bytes_sent = buf_size - len;
				if (skb->len < bytes_sent)
					bytes_sent = skb->len;
				{	/* swap tx bytes to get hearable audio data */
					register unsigned char *src  = skb->data;
					register unsigned char *dest = urb->transfer_buffer + len;
					register unsigned int count;
					for (count = 0; count < bytes_sent; count++)
						*dest++ = bitrev8(*src++);
				}
				len += bytes_sent;
			} else {
				len += isdnhdlc_encode(&b_out->hdlc_state,
						       skb->data, skb->len, &bytes_sent,
						       urb->transfer_buffer + len, buf_size-len);
			}

			skb_pull(skb, bytes_sent);

			if (!skb->len) {
				// Frame sent
				b_out->tx_skb = NULL;
				B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long) skb->truesize);
				dev_kfree_skb_any(skb);

/*				if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */
/*					st5481B_sched_event(bcs, B_XMTBUFREADY); */
/*				} */
			}
		} else {
			if (bcs->mode == L1_MODE_TRANS) {
				memset(urb->transfer_buffer + len, 0xff, buf_size-len);
				len = buf_size;
			} else {
				// Send flags
				len += isdnhdlc_encode(&b_out->hdlc_state,
						       NULL, 0, &bytes_sent,
						       urb->transfer_buffer + len, buf_size-len);
			}
		}
	}

	// Prepare the URB
	for (i = 0, offset = 0; offset < len; i++) {
		urb->iso_frame_desc[i].offset = offset;
		urb->iso_frame_desc[i].length = packet_size;
		offset += packet_size;
		packet_size = SIZE_ISO_PACKETS_B_OUT;
	}
	urb->transfer_buffer_length = len;
	urb->number_of_packets = i;
	urb->dev = adapter->usb_dev;

	DBG_ISO_PACKET(0x200, urb);

	SUBMIT_URB(urb, GFP_NOIO);
}

/*
 * Start transferring (flags or data) on the B channel, since
 * FIFO counters has been set to a non-zero value.
 */
static void st5481B_start_xfer(void *context)
{
	struct st5481_bcs *bcs = context;

	DBG(4, "B%d", bcs->channel + 1);

	// Start transmitting (flags or data) on B channel

	usb_b_out(bcs, 0);
	usb_b_out(bcs, 1);
}

/*
 * If the adapter has only 2 LEDs, the green
 * LED will blink with a rate depending
 * on the number of channels opened.
 */
static void led_blink(struct st5481_adapter *adapter)
{
	u_char leds = adapter->leds;

	// 50 frames/sec for each channel
	if (++adapter->led_counter % 50) {
		return;
	}

	if (adapter->led_counter % 100) {
		leds |= GREEN_LED;
	} else {
		leds &= ~GREEN_LED;
	}

	st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, leds, NULL, NULL);
}

static void usb_b_out_complete(struct urb *urb)
{
	struct st5481_bcs *bcs = urb->context;
	struct st5481_b_out *b_out = &bcs->b_out;
	struct st5481_adapter *adapter = bcs->adapter;
	int buf_nr;

	buf_nr = get_buf_nr(b_out->urb, urb);
	test_and_clear_bit(buf_nr, &b_out->busy);

	if (unlikely(urb->status < 0)) {
		switch (urb->status) {
		case -ENOENT:
		case -ESHUTDOWN:
		case -ECONNRESET:
			DBG(4, "urb killed status %d", urb->status);
			return; // Give up
		default:
			WARNING("urb status %d", urb->status);
			if (b_out->busy == 0) {
				st5481_usb_pipe_reset(adapter, (bcs->channel + 1) * 2 | USB_DIR_OUT, NULL, NULL);
			}
			break;
		}
	}

	usb_b_out(bcs, buf_nr);

	if (adapter->number_of_leds == 2)
		led_blink(adapter);
}

/*
 * Start or stop the transfer on the B channel.
 */
static void st5481B_mode(struct st5481_bcs *bcs, int mode)
{
	struct st5481_b_out *b_out = &bcs->b_out;
	struct st5481_adapter *adapter = bcs->adapter;

	DBG(4, "B%d,mode=%d", bcs->channel + 1, mode);

	if (bcs->mode == mode)
		return;

	bcs->mode = mode;

	// Cancel all USB transfers on this B channel
	usb_unlink_urb(b_out->urb[0]);
	usb_unlink_urb(b_out->urb[1]);
	b_out->busy = 0;

	st5481_in_mode(&bcs->b_in, mode);
	if (bcs->mode != L1_MODE_NULL) {
		// Open the B channel
		if (bcs->mode != L1_MODE_TRANS) {
			u32 features = HDLC_BITREVERSE;
			if (bcs->mode == L1_MODE_HDLC_56K)
				features |= HDLC_56KBIT;
			isdnhdlc_out_init(&b_out->hdlc_state, features);
		}
		st5481_usb_pipe_reset(adapter, (bcs->channel + 1) * 2, NULL, NULL);

		// Enable B channel interrupts
		st5481_usb_device_ctrl_msg(adapter, FFMSK_B1 + (bcs->channel * 2),
					   OUT_UP + OUT_DOWN + OUT_UNDERRUN, NULL, NULL);

		// Enable B channel FIFOs
		st5481_usb_device_ctrl_msg(adapter, OUT_B1_COUNTER+(bcs->channel * 2), 32, st5481B_start_xfer, bcs);
		if (adapter->number_of_leds == 4) {
			if (bcs->channel == 0) {
				adapter->leds |= B1_LED;
			} else {
				adapter->leds |= B2_LED;
			}
		}
	} else {
		// Disable B channel interrupts
		st5481_usb_device_ctrl_msg(adapter, FFMSK_B1+(bcs->channel * 2), 0, NULL, NULL);

		// Disable B channel FIFOs
		st5481_usb_device_ctrl_msg(adapter, OUT_B1_COUNTER+(bcs->channel * 2), 0, NULL, NULL);

		if (adapter->number_of_leds == 4) {
			if (bcs->channel == 0) {
				adapter->leds &= ~B1_LED;
			} else {
				adapter->leds &= ~B2_LED;
			}
		} else {
			st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);
		}
		if (b_out->tx_skb) {
			dev_kfree_skb_any(b_out->tx_skb);
			b_out->tx_skb = NULL;
		}

	}
}

static int st5481_setup_b_out(struct st5481_bcs *bcs)
{
	struct usb_device *dev = bcs->adapter->usb_dev;
	struct usb_interface *intf;
	struct usb_host_interface *altsetting = NULL;
	struct usb_host_endpoint *endpoint;
	struct st5481_b_out *b_out = &bcs->b_out;

	DBG(4, "");

	intf = usb_ifnum_to_if(dev, 0);
	if (intf)
		altsetting = usb_altnum_to_altsetting(intf, 3);
	if (!altsetting)
		return -ENXIO;

	// Allocate URBs and buffers for the B channel out
	endpoint = &altsetting->endpoint[EP_B1_OUT - 1 + bcs->channel * 2];

	DBG(4, "endpoint address=%02x,packet size=%d",
	    endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize));

	// Allocate memory for 8000bytes/sec + extra bytes if underrun
	return st5481_setup_isocpipes(b_out->urb, dev,
				      usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress),
				      NUM_ISO_PACKETS_B, SIZE_ISO_PACKETS_B_OUT,
				      NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST,
				      usb_b_out_complete, bcs);
}

static void st5481_release_b_out(struct st5481_bcs *bcs)
{
	struct st5481_b_out *b_out = &bcs->b_out;

	DBG(4, "");

	st5481_release_isocpipes(b_out->urb);
}

int st5481_setup_b(struct st5481_bcs *bcs)
{
	int retval;

	DBG(4, "");

	retval = st5481_setup_b_out(bcs);
	if (retval)
		goto err;
	bcs->b_in.bufsize = HSCX_BUFMAX;
	bcs->b_in.num_packets = NUM_ISO_PACKETS_B;
	bcs->b_in.packet_size = SIZE_ISO_PACKETS_B_IN;
	bcs->b_in.ep = (bcs->channel ? EP_B2_IN : EP_B1_IN) | USB_DIR_IN;
	bcs->b_in.counter = bcs->channel ? IN_B2_COUNTER : IN_B1_COUNTER;
	bcs->b_in.adapter = bcs->adapter;
	bcs->b_in.hisax_if = &bcs->b_if.ifc;
	retval = st5481_setup_in(&bcs->b_in);
	if (retval)
		goto err_b_out;


	return 0;

err_b_out:
	st5481_release_b_out(bcs);
err:
	return retval;
}

/*
 * Release buffers and URBs for the B channels
 */
void st5481_release_b(struct st5481_bcs *bcs)
{
	DBG(4, "");

	st5481_release_in(&bcs->b_in);
	st5481_release_b_out(bcs);
}

/*
 * st5481_b_l2l1 is the entry point for upper layer routines that want to
 * transmit on the B channel.  PH_DATA | REQUEST is a normal packet that
 * we either start transmitting (if idle) or queue (if busy).
 * PH_PULL | REQUEST can be called to request a callback message
 * (PH_PULL | CONFIRM)
 * once the link is idle.  After a "pull" callback, the upper layer
 * routines can use PH_PULL | INDICATION to send data.
 */
void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
{
	struct st5481_bcs *bcs = ifc->priv;
	struct sk_buff *skb = arg;
	long mode;

	DBG(4, "");

	switch (pr) {
	case PH_DATA | REQUEST:
		BUG_ON(bcs->b_out.tx_skb);
		bcs->b_out.tx_skb = skb;
		break;
	case PH_ACTIVATE | REQUEST:
		mode = (long) arg;
		DBG(4, "B%d,PH_ACTIVATE_REQUEST %ld", bcs->channel + 1, mode);
		st5481B_mode(bcs, mode);
		B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
		break;
	case PH_DEACTIVATE | REQUEST:
		DBG(4, "B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);
		st5481B_mode(bcs, L1_MODE_NULL);
		B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL);
		break;
	default:
		WARNING("pr %#x\n", pr);
	}
}
