/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
/*
 * aoecmd.c
 * Filesystem request handling methods
 */

#include <linux/hdreg.h>
#include <linux/blkdev.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include "aoe.h"

#define TIMERTICK (HZ / 10)
#define MINTIMER (2 * TIMERTICK)
#define MAXTIMER (HZ << 1)
#define MAXWAIT (60 * 3)	/* After MAXWAIT seconds, give up and fail dev */

static struct sk_buff *
new_skb(struct net_device *if_dev, ulong len)
{
	struct sk_buff *skb;

	skb = alloc_skb(len, GFP_ATOMIC);
	if (skb) {
		skb->nh.raw = skb->mac.raw = skb->data;
		skb->dev = if_dev;
		skb->protocol = __constant_htons(ETH_P_AOE);
		skb->priority = 0;
		skb_put(skb, len);
		skb->next = skb->prev = NULL;

		/* tell the network layer not to perform IP checksums
		 * or to get the NIC to do it
		 */
		skb->ip_summed = CHECKSUM_NONE;
	}
	return skb;
}

static struct sk_buff *
skb_prepare(struct aoedev *d, struct frame *f)
{
	struct sk_buff *skb;
	char *p;

	skb = new_skb(d->ifp, f->ndata + f->writedatalen);
	if (!skb) {
		printk(KERN_INFO "aoe: skb_prepare: failure to allocate skb\n");
		return NULL;
	}

	p = skb->mac.raw;
	memcpy(p, f->data, f->ndata);

	if (f->writedatalen) {
		p += sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr);
		memcpy(p, f->bufaddr, f->writedatalen);
	}

	return skb;
}

static struct frame *
getframe(struct aoedev *d, int tag)
{
	struct frame *f, *e;

	f = d->frames;
	e = f + d->nframes;
	for (; f<e; f++)
		if (f->tag == tag)
			return f;
	return NULL;
}

/*
 * Leave the top bit clear so we have tagspace for userland.
 * The bottom 16 bits are the xmit tick for rexmit/rttavg processing.
 * This driver reserves tag -1 to mean "unused frame."
 */
static int
newtag(struct aoedev *d)
{
	register ulong n;

	n = jiffies & 0xffff;
	return n |= (++d->lasttag & 0x7fff) << 16;
}

static int
aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h)
{
	u32 host_tag = newtag(d);

	memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
	memcpy(h->dst, d->addr, sizeof h->dst);
	h->type = __constant_cpu_to_be16(ETH_P_AOE);
	h->verfl = AOE_HVER;
	h->major = cpu_to_be16(d->aoemajor);
	h->minor = d->aoeminor;
	h->cmd = AOECMD_ATA;
	h->tag = cpu_to_be32(host_tag);

	return host_tag;
}

static void
aoecmd_ata_rw(struct aoedev *d, struct frame *f)
{
	struct aoe_hdr *h;
	struct aoe_atahdr *ah;
	struct buf *buf;
	struct sk_buff *skb;
	ulong bcnt;
	register sector_t sector;
	char writebit, extbit;

	writebit = 0x10;
	extbit = 0x4;

	buf = d->inprocess;

	sector = buf->sector;
	bcnt = buf->bv_resid;
	if (bcnt > MAXATADATA)
		bcnt = MAXATADATA;

	/* initialize the headers & frame */
	h = (struct aoe_hdr *) f->data;
	ah = (struct aoe_atahdr *) (h+1);
	f->ndata = sizeof *h + sizeof *ah;
	memset(h, 0, f->ndata);
	f->tag = aoehdr_atainit(d, h);
	f->waited = 0;
	f->buf = buf;
	f->bufaddr = buf->bufaddr;

	/* set up ata header */
	ah->scnt = bcnt >> 9;
	ah->lba0 = sector;
	ah->lba1 = sector >>= 8;
	ah->lba2 = sector >>= 8;
	ah->lba3 = sector >>= 8;
	if (d->flags & DEVFL_EXT) {
		ah->aflags |= AOEAFL_EXT;
		ah->lba4 = sector >>= 8;
		ah->lba5 = sector >>= 8;
	} else {
		extbit = 0;
		ah->lba3 &= 0x0f;
		ah->lba3 |= 0xe0;	/* LBA bit + obsolete 0xa0 */
	}

	if (bio_data_dir(buf->bio) == WRITE) {
		ah->aflags |= AOEAFL_WRITE;
		f->writedatalen = bcnt;
	} else {
		writebit = 0;
		f->writedatalen = 0;
	}

	ah->cmdstat = WIN_READ | writebit | extbit;

	/* mark all tracking fields and load out */
	buf->nframesout += 1;
	buf->bufaddr += bcnt;
	buf->bv_resid -= bcnt;
/* printk(KERN_INFO "aoe: bv_resid=%ld\n", buf->bv_resid); */
	buf->resid -= bcnt;
	buf->sector += bcnt >> 9;
	if (buf->resid == 0) {
		d->inprocess = NULL;
	} else if (buf->bv_resid == 0) {
		buf->bv++;
		buf->bv_resid = buf->bv->bv_len;
		buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
	}

	skb = skb_prepare(d, f);
	if (skb) {
		skb->next = NULL;
		if (d->sendq_hd)
			d->sendq_tl->next = skb;
		else
			d->sendq_hd = skb;
		d->sendq_tl = skb;
	}
}

/* enters with d->lock held */
void
aoecmd_work(struct aoedev *d)
{
	struct frame *f;
	struct buf *buf;
loop:
	f = getframe(d, FREETAG);
	if (f == NULL)
		return;
	if (d->inprocess == NULL) {
		if (list_empty(&d->bufq))
			return;
		buf = container_of(d->bufq.next, struct buf, bufs);
		list_del(d->bufq.next);
/*printk(KERN_INFO "aoecmd_work: bi_size=%ld\n", buf->bio->bi_size); */
		d->inprocess = buf;
	}
	aoecmd_ata_rw(d, f);
	goto loop;
}

static void
rexmit(struct aoedev *d, struct frame *f)
{
	struct sk_buff *skb;
	struct aoe_hdr *h;
	char buf[128];
	u32 n;

	n = newtag(d);

	snprintf(buf, sizeof buf,
		"%15s e%ld.%ld oldtag=%08x@%08lx newtag=%08x\n",
		"retransmit",
		d->aoemajor, d->aoeminor, f->tag, jiffies, n);
	aoechr_error(buf);

	h = (struct aoe_hdr *) f->data;
	f->tag = n;
	h->tag = cpu_to_be32(n);

	skb = skb_prepare(d, f);
	if (skb) {
		skb->next = NULL;
		if (d->sendq_hd)
			d->sendq_tl->next = skb;
		else
			d->sendq_hd = skb;
		d->sendq_tl = skb;
	}
}

static int
tsince(int tag)
{
	int n;

	n = jiffies & 0xffff;
	n -= tag & 0xffff;
	if (n < 0)
		n += 1<<16;
	return n;
}

static void
rexmit_timer(ulong vp)
{
	struct aoedev *d;
	struct frame *f, *e;
	struct sk_buff *sl;
	register long timeout;
	ulong flags, n;

	d = (struct aoedev *) vp;
	sl = NULL;

	/* timeout is always ~150% of the moving average */
	timeout = d->rttavg;
	timeout += timeout >> 1;

	spin_lock_irqsave(&d->lock, flags);

	if (d->flags & DEVFL_TKILL) {
tdie:		spin_unlock_irqrestore(&d->lock, flags);
		return;
	}
	f = d->frames;
	e = f + d->nframes;
	for (; f<e; f++) {
		if (f->tag != FREETAG && tsince(f->tag) >= timeout) {
			n = f->waited += timeout;
			n /= HZ;
			if (n > MAXWAIT) { /* waited too long.  device failure. */
				aoedev_downdev(d);
				goto tdie;
			}
			rexmit(d, f);
		}
	}

	sl = d->sendq_hd;
	d->sendq_hd = d->sendq_tl = NULL;
	if (sl) {
		n = d->rttavg <<= 1;
		if (n > MAXTIMER)
			d->rttavg = MAXTIMER;
	}

	d->timer.expires = jiffies + TIMERTICK;
	add_timer(&d->timer);

	spin_unlock_irqrestore(&d->lock, flags);

	aoenet_xmit(sl);
}

static void
ataid_complete(struct aoedev *d, unsigned char *id)
{
	u64 ssize;
	u16 n;

	/* word 83: command set supported */
	n = le16_to_cpup((__le16 *) &id[83<<1]);

	/* word 86: command set/feature enabled */
	n |= le16_to_cpup((__le16 *) &id[86<<1]);

	if (n & (1<<10)) {	/* bit 10: LBA 48 */
		d->flags |= DEVFL_EXT;

		/* word 100: number lba48 sectors */
		ssize = le64_to_cpup((__le64 *) &id[100<<1]);

		/* set as in ide-disk.c:init_idedisk_capacity */
		d->geo.cylinders = ssize;
		d->geo.cylinders /= (255 * 63);
		d->geo.heads = 255;
		d->geo.sectors = 63;
	} else {
		d->flags &= ~DEVFL_EXT;

		/* number lba28 sectors */
		ssize = le32_to_cpup((__le32 *) &id[60<<1]);

		/* NOTE: obsolete in ATA 6 */
		d->geo.cylinders = le16_to_cpup((__le16 *) &id[54<<1]);
		d->geo.heads = le16_to_cpup((__le16 *) &id[55<<1]);
		d->geo.sectors = le16_to_cpup((__le16 *) &id[56<<1]);
	}
	d->ssize = ssize;
	d->geo.start = 0;
	if (d->gd != NULL) {
		d->gd->capacity = ssize;
		d->flags |= DEVFL_UP;
		return;
	}
	if (d->flags & DEVFL_WORKON) {
		printk(KERN_INFO "aoe: ataid_complete: can't schedule work, it's already on!  "
			"(This really shouldn't happen).\n");
		return;
	}
	INIT_WORK(&d->work, aoeblk_gdalloc, d);
	schedule_work(&d->work);
	d->flags |= DEVFL_WORKON;
}

static void
calc_rttavg(struct aoedev *d, int rtt)
{
	register long n;

	n = rtt;
	if (n < MINTIMER)
		n = MINTIMER;
	else if (n > MAXTIMER)
		n = MAXTIMER;

	/* g == .25; cf. Congestion Avoidance and Control, Jacobson & Karels; 1988 */
	n -= d->rttavg;
	d->rttavg += n >> 2;
}

void
aoecmd_ata_rsp(struct sk_buff *skb)
{
	struct aoedev *d;
	struct aoe_hdr *hin;
	struct aoe_atahdr *ahin, *ahout;
	struct frame *f;
	struct buf *buf;
	struct sk_buff *sl;
	register long n;
	ulong flags;
	char ebuf[128];
	u16 aoemajor;

	hin = (struct aoe_hdr *) skb->mac.raw;
	aoemajor = be16_to_cpu(hin->major);
	d = aoedev_by_aoeaddr(aoemajor, hin->minor);
	if (d == NULL) {
		snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
			"for unknown device %d.%d\n",
			 aoemajor, hin->minor);
		aoechr_error(ebuf);
		return;
	}

	spin_lock_irqsave(&d->lock, flags);

	f = getframe(d, be32_to_cpu(hin->tag));
	if (f == NULL) {
		spin_unlock_irqrestore(&d->lock, flags);
		snprintf(ebuf, sizeof ebuf,
			"%15s e%d.%d    tag=%08x@%08lx\n",
			"unexpected rsp",
			be16_to_cpu(hin->major),
			hin->minor,
			be32_to_cpu(hin->tag),
			jiffies);
		aoechr_error(ebuf);
		return;
	}

	calc_rttavg(d, tsince(f->tag));

	ahin = (struct aoe_atahdr *) (hin+1);
	ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr));
	buf = f->buf;

	if (ahin->cmdstat & 0xa9) {	/* these bits cleared on success */
		printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh "
			"stat=%2.2Xh from e%ld.%ld\n", 
			ahout->cmdstat, ahin->cmdstat,
			d->aoemajor, d->aoeminor);
		if (buf)
			buf->flags |= BUFFL_FAIL;
	} else {
		switch (ahout->cmdstat) {
		case WIN_READ:
		case WIN_READ_EXT:
			n = ahout->scnt << 9;
			if (skb->len - sizeof *hin - sizeof *ahin < n) {
				printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt "
					"ata data size in read.  skb->len=%d\n",
					skb->len);
				/* fail frame f?  just returning will rexmit. */
				spin_unlock_irqrestore(&d->lock, flags);
				return;
			}
			memcpy(f->bufaddr, ahin+1, n);
		case WIN_WRITE:
		case WIN_WRITE_EXT:
			break;
		case WIN_IDENTIFY:
			if (skb->len - sizeof *hin - sizeof *ahin < 512) {
				printk(KERN_INFO "aoe: aoecmd_ata_rsp: runt data size "
					"in ataid.  skb->len=%d\n", skb->len);
				spin_unlock_irqrestore(&d->lock, flags);
				return;
			}
			ataid_complete(d, (char *) (ahin+1));
			/* d->flags |= DEVFL_WC_UPDATE; */
			break;
		default:
			printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized "
			       "outbound ata command %2.2Xh for %d.%d\n", 
			       ahout->cmdstat,
			       be16_to_cpu(hin->major),
			       hin->minor);
		}
	}

	if (buf) {
		buf->nframesout -= 1;
		if (buf->nframesout == 0 && buf->resid == 0) {
			unsigned long duration = jiffies - buf->start_time;
			unsigned long n_sect = buf->bio->bi_size >> 9;
			struct gendisk *disk = d->gd;

			if (bio_data_dir(buf->bio) == WRITE) {
				disk_stat_inc(disk, writes);
				disk_stat_add(disk, write_ticks, duration);
				disk_stat_add(disk, write_sectors, n_sect);
			} else {
				disk_stat_inc(disk, reads);
				disk_stat_add(disk, read_ticks, duration);
				disk_stat_add(disk, read_sectors, n_sect);
			}
			disk_stat_add(disk, io_ticks, duration);
			n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
			bio_endio(buf->bio, buf->bio->bi_size, n);
			mempool_free(buf, d->bufpool);
		}
	}

	f->buf = NULL;
	f->tag = FREETAG;

	aoecmd_work(d);

	sl = d->sendq_hd;
	d->sendq_hd = d->sendq_tl = NULL;

	spin_unlock_irqrestore(&d->lock, flags);

	aoenet_xmit(sl);
}

void
aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
{
	struct aoe_hdr *h;
	struct aoe_cfghdr *ch;
	struct sk_buff *skb, *sl;
	struct net_device *ifp;

	sl = NULL;

	read_lock(&dev_base_lock);
	for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
		dev_hold(ifp);
		if (!is_aoe_netif(ifp))
			continue;

		skb = new_skb(ifp, sizeof *h + sizeof *ch);
		if (skb == NULL) {
			printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n");
			continue;
		}
		h = (struct aoe_hdr *) skb->mac.raw;
		memset(h, 0, sizeof *h + sizeof *ch);

		memset(h->dst, 0xff, sizeof h->dst);
		memcpy(h->src, ifp->dev_addr, sizeof h->src);
		h->type = __constant_cpu_to_be16(ETH_P_AOE);
		h->verfl = AOE_HVER;
		h->major = cpu_to_be16(aoemajor);
		h->minor = aoeminor;
		h->cmd = AOECMD_CFG;

		skb->next = sl;
		sl = skb;
	}
	read_unlock(&dev_base_lock);

	aoenet_xmit(sl);
}
 
/*
 * Since we only call this in one place (and it only prepares one frame)
 * we just return the skb.  Usually we'd chain it up to the aoedev sendq.
 */
static struct sk_buff *
aoecmd_ata_id(struct aoedev *d)
{
	struct aoe_hdr *h;
	struct aoe_atahdr *ah;
	struct frame *f;
	struct sk_buff *skb;

	f = getframe(d, FREETAG);
	if (f == NULL) {
		printk(KERN_CRIT "aoe: aoecmd_ata_id: can't get a frame.  "
			"This shouldn't happen.\n");
		return NULL;
	}

	/* initialize the headers & frame */
	h = (struct aoe_hdr *) f->data;
	ah = (struct aoe_atahdr *) (h+1);
	f->ndata = sizeof *h + sizeof *ah;
	memset(h, 0, f->ndata);
	f->tag = aoehdr_atainit(d, h);
	f->waited = 0;
	f->writedatalen = 0;

	/* this message initializes the device, so we reset the rttavg */
	d->rttavg = MAXTIMER;

	/* set up ata header */
	ah->scnt = 1;
	ah->cmdstat = WIN_IDENTIFY;
	ah->lba3 = 0xa0;

	skb = skb_prepare(d, f);

	/* we now want to start the rexmit tracking */
	d->flags &= ~DEVFL_TKILL;
	d->timer.data = (ulong) d;
	d->timer.function = rexmit_timer;
	d->timer.expires = jiffies + TIMERTICK;
	add_timer(&d->timer);

	return skb;
}
 
void
aoecmd_cfg_rsp(struct sk_buff *skb)
{
	struct aoedev *d;
	struct aoe_hdr *h;
	struct aoe_cfghdr *ch;
	ulong flags, sysminor, aoemajor;
	u16 bufcnt;
	struct sk_buff *sl;
	enum { MAXFRAMES = 8 };

	h = (struct aoe_hdr *) skb->mac.raw;
	ch = (struct aoe_cfghdr *) (h+1);

	/*
	 * Enough people have their dip switches set backwards to
	 * warrant a loud message for this special case.
	 */
	aoemajor = be16_to_cpu(h->major);
	if (aoemajor == 0xfff) {
		printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf "
			"address is all ones.  Check shelf dip switches\n");
		return;
	}

	sysminor = SYSMINOR(aoemajor, h->minor);
	if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
		printk(KERN_INFO
			"aoe: e%ld.%d: minor number too large\n", 
			aoemajor, (int) h->minor);
		return;
	}

	bufcnt = be16_to_cpu(ch->bufcnt);
	if (bufcnt > MAXFRAMES)	/* keep it reasonable */
		bufcnt = MAXFRAMES;

	d = aoedev_set(sysminor, h->src, skb->dev, bufcnt);
	if (d == NULL) {
		printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device set failure\n");
		return;
	}

	spin_lock_irqsave(&d->lock, flags);

	if (d->flags & (DEVFL_UP | DEVFL_CLOSEWAIT)) {
		spin_unlock_irqrestore(&d->lock, flags);
		return;
	}

	d->fw_ver = be16_to_cpu(ch->fwver);

	/* we get here only if the device is new */
	sl = aoecmd_ata_id(d);

	spin_unlock_irqrestore(&d->lock, flags);

	aoenet_xmit(sl);
}

