/*
 * linux/drivers/s390/net/qeth_eddp.c
 *
 * Enhanced Device Driver Packing (EDDP) support for the qeth driver.
 *
 * Copyright 2004 IBM Corporation
 *
 *    Author(s): Thomas Spatzier <tspat@de.ibm.com>
 *
 */
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/ip.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <linux/kernel.h>
#include <linux/tcp.h>
#include <net/tcp.h>
#include <linux/skbuff.h>

#include <net/ip.h>

#include "qeth.h"
#include "qeth_mpc.h"
#include "qeth_eddp.h"

int
qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
				    struct qeth_eddp_context *ctx)
{
	int index = queue->next_buf_to_fill;
	int elements_needed = ctx->num_elements;
	int elements_in_buffer;
	int skbs_in_buffer;
	int buffers_needed = 0;

	QETH_DBF_TEXT(trace, 5, "eddpcbfc");
	while(elements_needed > 0) {
		buffers_needed++;
		if (atomic_read(&queue->bufs[index].state) !=
				QETH_QDIO_BUF_EMPTY)
			return -EBUSY;

		elements_in_buffer = QETH_MAX_BUFFER_ELEMENTS(queue->card) -
				     queue->bufs[index].next_element_to_fill;
		skbs_in_buffer = elements_in_buffer / ctx->elements_per_skb;
		elements_needed -= skbs_in_buffer * ctx->elements_per_skb;
		index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
	}
	return buffers_needed;
}

static inline void
qeth_eddp_free_context(struct qeth_eddp_context *ctx)
{
	int i;

	QETH_DBF_TEXT(trace, 5, "eddpfctx");
	for (i = 0; i < ctx->num_pages; ++i)
		free_page((unsigned long)ctx->pages[i]);
	kfree(ctx->pages);
	kfree(ctx->elements);
	kfree(ctx);
}


static inline void
qeth_eddp_get_context(struct qeth_eddp_context *ctx)
{
	atomic_inc(&ctx->refcnt);
}

void
qeth_eddp_put_context(struct qeth_eddp_context *ctx)
{
	if (atomic_dec_return(&ctx->refcnt) == 0)
		qeth_eddp_free_context(ctx);
}

void
qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
{
	struct qeth_eddp_context_reference *ref;
	
	QETH_DBF_TEXT(trace, 6, "eddprctx");
	while (!list_empty(&buf->ctx_list)){
		ref = list_entry(buf->ctx_list.next,
				 struct qeth_eddp_context_reference, list);
		qeth_eddp_put_context(ref->ctx);
		list_del(&ref->list);
		kfree(ref);
	}
}

static inline int
qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf,
			  struct qeth_eddp_context *ctx)
{
	struct qeth_eddp_context_reference *ref;

	QETH_DBF_TEXT(trace, 6, "eddprfcx");
	ref = kmalloc(sizeof(struct qeth_eddp_context_reference), GFP_ATOMIC);
	if (ref == NULL)
		return -ENOMEM;
	qeth_eddp_get_context(ctx);
	ref->ctx = ctx;
	list_add_tail(&ref->list, &buf->ctx_list);
	return 0;
}

int
qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
		      struct qeth_eddp_context *ctx,
		      int index)
{
	struct qeth_qdio_out_buffer *buf = NULL;
	struct qdio_buffer *buffer;
	int elements = ctx->num_elements;
	int element = 0;
	int flush_cnt = 0;
	int must_refcnt = 1;
	int i;

	QETH_DBF_TEXT(trace, 5, "eddpfibu");
	while (elements > 0) {
		buf = &queue->bufs[index];
		if (atomic_read(&buf->state) != QETH_QDIO_BUF_EMPTY){
			/* normally this should not happen since we checked for
			 * available elements in qeth_check_elements_for_context
			 */
			if (element == 0)
				return -EBUSY;
			else {
				PRINT_WARN("could only partially fill eddp "
					   "buffer!\n");
				goto out;
			}
		}		
		/* check if the whole next skb fits into current buffer */
		if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) -
					buf->next_element_to_fill)
				< ctx->elements_per_skb){
			/* no -> go to next buffer */
			atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
			index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
			flush_cnt++;
			/* new buffer, so we have to add ctx to buffer'ctx_list
			 * and increment ctx's refcnt */
			must_refcnt = 1;
			continue;
		}	
		if (must_refcnt){
			must_refcnt = 0;
			if (qeth_eddp_buf_ref_context(buf, ctx)){
				PRINT_WARN("no memory to create eddp context "
					   "reference\n");
				goto out_check;
			}
		}
		buffer = buf->buffer;
		/* fill one skb into buffer */
		for (i = 0; i < ctx->elements_per_skb; ++i){
			buffer->element[buf->next_element_to_fill].addr =
				ctx->elements[element].addr;
			buffer->element[buf->next_element_to_fill].length =
				ctx->elements[element].length;
			buffer->element[buf->next_element_to_fill].flags =
				ctx->elements[element].flags;
			buf->next_element_to_fill++;
			element++;
			elements--;
		}
	}
out_check:
	if (!queue->do_pack) {
		QETH_DBF_TEXT(trace, 6, "fillbfnp");
		/* set state to PRIMED -> will be flushed */
		if (buf->next_element_to_fill > 0){
			atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
			flush_cnt++;
		}
	} else {
#ifdef CONFIG_QETH_PERF_STATS
		queue->card->perf_stats.skbs_sent_pack++;
#endif
		QETH_DBF_TEXT(trace, 6, "fillbfpa");
		if (buf->next_element_to_fill >=
				QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
			/*
			 * packed buffer if full -> set state PRIMED
			 * -> will be flushed
			 */
			atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
			flush_cnt++;
		}
	}
out:
	return flush_cnt;
}

static inline void
qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
			      struct qeth_eddp_data *eddp, int data_len)
{
	u8 *page;
	int page_remainder;
	int page_offset;
	int pkt_len;
	struct qeth_eddp_element *element;

	QETH_DBF_TEXT(trace, 5, "eddpcrsh");
	page = ctx->pages[ctx->offset >> PAGE_SHIFT];
	page_offset = ctx->offset % PAGE_SIZE;
	element = &ctx->elements[ctx->num_elements];
	pkt_len = eddp->nhl + eddp->thl + data_len;
	/* FIXME: layer2 and VLAN !!! */
	if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
		pkt_len += ETH_HLEN;
	if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
		pkt_len += VLAN_HLEN;
	/* does complete packet fit in current page ? */
	page_remainder = PAGE_SIZE - page_offset;
	if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)){
		/* no -> go to start of next page */
		ctx->offset += page_remainder;
		page = ctx->pages[ctx->offset >> PAGE_SHIFT];
		page_offset = 0;
	}
	memcpy(page + page_offset, &eddp->qh, sizeof(struct qeth_hdr));
	element->addr = page + page_offset;
	element->length = sizeof(struct qeth_hdr);
	ctx->offset += sizeof(struct qeth_hdr);
	page_offset += sizeof(struct qeth_hdr);
	/* add mac header (?) */
	if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
		memcpy(page + page_offset, &eddp->mac, ETH_HLEN);
		element->length += ETH_HLEN;
		ctx->offset += ETH_HLEN;
		page_offset += ETH_HLEN;
	}
	/* add VLAN tag */
	if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)){
		memcpy(page + page_offset, &eddp->vlan, VLAN_HLEN);
		element->length += VLAN_HLEN;
		ctx->offset += VLAN_HLEN;
		page_offset += VLAN_HLEN;
	}
	/* add network header */
	memcpy(page + page_offset, (u8 *)&eddp->nh, eddp->nhl);
	element->length += eddp->nhl;
	eddp->nh_in_ctx = page + page_offset;
	ctx->offset += eddp->nhl;
	page_offset += eddp->nhl;
	/* add transport header */
	memcpy(page + page_offset, (u8 *)&eddp->th, eddp->thl);
	element->length += eddp->thl;
	eddp->th_in_ctx = page + page_offset;
	ctx->offset += eddp->thl;
}

static inline void
qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
			u32 *hcsum)
{
	struct skb_frag_struct *frag;
	int left_in_frag;
	int copy_len;
	u8 *src;
	
	QETH_DBF_TEXT(trace, 5, "eddpcdtc");
	if (skb_shinfo(eddp->skb)->nr_frags == 0) {
		memcpy(dst, eddp->skb->data + eddp->skb_offset, len);
		*hcsum = csum_partial(eddp->skb->data + eddp->skb_offset, len,
				      *hcsum);
		eddp->skb_offset += len;
	} else {
		while (len > 0) {
			if (eddp->frag < 0) {
				/* we're in skb->data */
				left_in_frag = (eddp->skb->len - eddp->skb->data_len)
						- eddp->skb_offset;
				src = eddp->skb->data + eddp->skb_offset;
			} else {
				frag = &skb_shinfo(eddp->skb)->
					frags[eddp->frag];
				left_in_frag = frag->size - eddp->frag_offset;
				src = (u8 *)(
					(page_to_pfn(frag->page) << PAGE_SHIFT)+
					frag->page_offset + eddp->frag_offset);
			}
			if (left_in_frag <= 0) {
				eddp->frag++;
				eddp->frag_offset = 0;
				continue;
			}
			copy_len = min(left_in_frag, len);
			memcpy(dst, src, copy_len);
			*hcsum = csum_partial(src, copy_len, *hcsum);
			dst += copy_len;
			eddp->frag_offset += copy_len;
			eddp->skb_offset += copy_len;
			len -= copy_len;
		}
	}
}

static inline void
qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
				  struct qeth_eddp_data *eddp, int data_len,
				  u32 hcsum)
{
	u8 *page;
	int page_remainder;
	int page_offset;
	struct qeth_eddp_element *element;
	int first_lap = 1;

	QETH_DBF_TEXT(trace, 5, "eddpcsdt");
	page = ctx->pages[ctx->offset >> PAGE_SHIFT];
	page_offset = ctx->offset % PAGE_SIZE;
	element = &ctx->elements[ctx->num_elements];
	while (data_len){
		page_remainder = PAGE_SIZE - page_offset;
		if (page_remainder < data_len){
			qeth_eddp_copy_data_tcp(page + page_offset, eddp,
						page_remainder, &hcsum);
			element->length += page_remainder;
			if (first_lap)
				element->flags = SBAL_FLAGS_FIRST_FRAG;
			else
				element->flags = SBAL_FLAGS_MIDDLE_FRAG;
			ctx->num_elements++;
			element++;
			data_len -= page_remainder;
			ctx->offset += page_remainder;
			page = ctx->pages[ctx->offset >> PAGE_SHIFT];
			page_offset = 0;
			element->addr = page + page_offset;
		} else {
			qeth_eddp_copy_data_tcp(page + page_offset, eddp,
						data_len, &hcsum);
			element->length += data_len;
			if (!first_lap)
				element->flags = SBAL_FLAGS_LAST_FRAG;
			ctx->num_elements++;
			ctx->offset += data_len;
			data_len = 0;
		}
		first_lap = 0;
	}
	((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum);
}

static inline u32
qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len)
{
	u32 phcsum; /* pseudo header checksum */

	QETH_DBF_TEXT(trace, 5, "eddpckt4");
	eddp->th.tcp.h.check = 0;
	/* compute pseudo header checksum */
	phcsum = csum_tcpudp_nofold(eddp->nh.ip4.h.saddr, eddp->nh.ip4.h.daddr,
				    eddp->thl + data_len, IPPROTO_TCP, 0);
	/* compute checksum of tcp header */
	return csum_partial((u8 *)&eddp->th, eddp->thl, phcsum);
}

static inline u32
qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len)
{
	u32 proto;
	u32 phcsum; /* pseudo header checksum */

	QETH_DBF_TEXT(trace, 5, "eddpckt6");
	eddp->th.tcp.h.check = 0;
	/* compute pseudo header checksum */
	phcsum = csum_partial((u8 *)&eddp->nh.ip6.h.saddr,
			      sizeof(struct in6_addr), 0);
	phcsum = csum_partial((u8 *)&eddp->nh.ip6.h.daddr,
			      sizeof(struct in6_addr), phcsum);
	proto = htonl(IPPROTO_TCP);
	phcsum = csum_partial((u8 *)&proto, sizeof(u32), phcsum);
	return phcsum;
}

static inline struct qeth_eddp_data *
qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl)
{
	struct qeth_eddp_data *eddp;

	QETH_DBF_TEXT(trace, 5, "eddpcrda");
	eddp = kzalloc(sizeof(struct qeth_eddp_data), GFP_ATOMIC);
	if (eddp){
		eddp->nhl = nhl;
		eddp->thl = thl;
		memcpy(&eddp->qh, qh, sizeof(struct qeth_hdr));
		memcpy(&eddp->nh, nh, nhl);
		memcpy(&eddp->th, th, thl);
		eddp->frag = -1; /* initially we're in skb->data */
	}
	return eddp;
}

static inline void
__qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
			     struct qeth_eddp_data *eddp)
{
	struct tcphdr *tcph;
	int data_len;
	u32 hcsum;
	
	QETH_DBF_TEXT(trace, 5, "eddpftcp");
	eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
       if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
               eddp->skb_offset += sizeof(struct ethhdr);
#ifdef CONFIG_QETH_VLAN
               if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
                       eddp->skb_offset += VLAN_HLEN;
#endif /* CONFIG_QETH_VLAN */
       }
	tcph = eddp->skb->h.th;
	while (eddp->skb_offset < eddp->skb->len) {
		data_len = min((int)skb_shinfo(eddp->skb)->tso_size,
			       (int)(eddp->skb->len - eddp->skb_offset));
		/* prepare qdio hdr */
		if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
			eddp->qh.hdr.l2.pkt_length = data_len + ETH_HLEN +
						     eddp->nhl + eddp->thl -
						     sizeof(struct qeth_hdr);
#ifdef CONFIG_QETH_VLAN
			if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
				eddp->qh.hdr.l2.pkt_length += VLAN_HLEN;
#endif /* CONFIG_QETH_VLAN */
		} else
			eddp->qh.hdr.l3.length = data_len + eddp->nhl +
						 eddp->thl;
		/* prepare ip hdr */
		if (eddp->skb->protocol == ETH_P_IP){
			eddp->nh.ip4.h.tot_len = data_len + eddp->nhl +
						 eddp->thl;
			eddp->nh.ip4.h.check = 0;
			eddp->nh.ip4.h.check =
				ip_fast_csum((u8 *)&eddp->nh.ip4.h,
						eddp->nh.ip4.h.ihl);
		} else
			eddp->nh.ip6.h.payload_len = data_len + eddp->thl;
		/* prepare tcp hdr */
		if (data_len == (eddp->skb->len - eddp->skb_offset)){
			/* last segment -> set FIN and PSH flags */
			eddp->th.tcp.h.fin = tcph->fin;
			eddp->th.tcp.h.psh = tcph->psh;
		}
		if (eddp->skb->protocol == ETH_P_IP)
			hcsum = qeth_eddp_check_tcp4_hdr(eddp, data_len);
		else
			hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len);
		/* fill the next segment into the context */
		qeth_eddp_create_segment_hdrs(ctx, eddp, data_len);
		qeth_eddp_create_segment_data_tcp(ctx, eddp, data_len, hcsum);
		if (eddp->skb_offset >= eddp->skb->len)
			break;
		/* prepare headers for next round */
		if (eddp->skb->protocol == ETH_P_IP)
			eddp->nh.ip4.h.id++;
		eddp->th.tcp.h.seq += data_len;
	}
}
			   
static inline int
qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
			   struct sk_buff *skb, struct qeth_hdr *qhdr)
{
	struct qeth_eddp_data *eddp = NULL;
	
	QETH_DBF_TEXT(trace, 5, "eddpficx");
	/* create our segmentation headers and copy original headers */
	if (skb->protocol == ETH_P_IP)
		eddp = qeth_eddp_create_eddp_data(qhdr, (u8 *)skb->nh.iph,
				skb->nh.iph->ihl*4,
				(u8 *)skb->h.th, skb->h.th->doff*4);
	else
		eddp = qeth_eddp_create_eddp_data(qhdr, (u8 *)skb->nh.ipv6h,
				sizeof(struct ipv6hdr),
				(u8 *)skb->h.th, skb->h.th->doff*4);

	if (eddp == NULL) {
		QETH_DBF_TEXT(trace, 2, "eddpfcnm");
		return -ENOMEM;
	}
	if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
		skb->mac.raw = (skb->data) + sizeof(struct qeth_hdr);
		memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN);
#ifdef CONFIG_QETH_VLAN
		if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
			eddp->vlan[0] = __constant_htons(skb->protocol);
			eddp->vlan[1] = htons(vlan_tx_tag_get(skb));
		}
#endif /* CONFIG_QETH_VLAN */
	}
	/* the next flags will only be set on the last segment */
	eddp->th.tcp.h.fin = 0;
	eddp->th.tcp.h.psh = 0;
	eddp->skb = skb;
	/* begin segmentation and fill context */
	__qeth_eddp_fill_context_tcp(ctx, eddp);
	kfree(eddp);
	return 0;
}

static inline void
qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
			 int hdr_len)
{
	int skbs_per_page;
	
	QETH_DBF_TEXT(trace, 5, "eddpcanp");
	/* can we put multiple skbs in one page? */
	skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
	if (skbs_per_page > 1){
		ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) /
				 skbs_per_page + 1;
		ctx->elements_per_skb = 1;
	} else {
		/* no -> how many elements per skb? */
		ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len +
				     PAGE_SIZE) >> PAGE_SHIFT;
		ctx->num_pages = ctx->elements_per_skb *
				 (skb_shinfo(skb)->tso_segs + 1);
	}
	ctx->num_elements = ctx->elements_per_skb *
			    (skb_shinfo(skb)->tso_segs + 1);
}

static inline struct qeth_eddp_context *
qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb,
				 int hdr_len)
{
	struct qeth_eddp_context *ctx = NULL;
	u8 *addr;
	int i;

	QETH_DBF_TEXT(trace, 5, "creddpcg");
	/* create the context and allocate pages */
	ctx = kzalloc(sizeof(struct qeth_eddp_context), GFP_ATOMIC);
	if (ctx == NULL){
		QETH_DBF_TEXT(trace, 2, "ceddpcn1");
		return NULL;
	}
	ctx->type = QETH_LARGE_SEND_EDDP;
	qeth_eddp_calc_num_pages(ctx, skb, hdr_len);
	if (ctx->elements_per_skb > QETH_MAX_BUFFER_ELEMENTS(card)){
		QETH_DBF_TEXT(trace, 2, "ceddpcis");
		kfree(ctx);
		return NULL;
	}
	ctx->pages = kcalloc(ctx->num_pages, sizeof(u8 *), GFP_ATOMIC);
	if (ctx->pages == NULL){
		QETH_DBF_TEXT(trace, 2, "ceddpcn2");
		kfree(ctx);
		return NULL;
	}
	for (i = 0; i < ctx->num_pages; ++i){
		addr = (u8 *)__get_free_page(GFP_ATOMIC);
		if (addr == NULL){
			QETH_DBF_TEXT(trace, 2, "ceddpcn3");
			ctx->num_pages = i;
			qeth_eddp_free_context(ctx);
			return NULL;
		}
		memset(addr, 0, PAGE_SIZE);
		ctx->pages[i] = addr;
	}
	ctx->elements = kcalloc(ctx->num_elements,
				sizeof(struct qeth_eddp_element), GFP_ATOMIC);
	if (ctx->elements == NULL){
		QETH_DBF_TEXT(trace, 2, "ceddpcn4");
		qeth_eddp_free_context(ctx);
		return NULL;
	}
	/* reset num_elements; will be incremented again in fill_buffer to
	 * reflect number of actually used elements */
	ctx->num_elements = 0;
	return ctx;
}

static inline struct qeth_eddp_context *
qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
			     struct qeth_hdr *qhdr)
{
	struct qeth_eddp_context *ctx = NULL;
	
	QETH_DBF_TEXT(trace, 5, "creddpct");
	if (skb->protocol == ETH_P_IP)
		ctx = qeth_eddp_create_context_generic(card, skb,
			sizeof(struct qeth_hdr) + skb->nh.iph->ihl*4 +
			skb->h.th->doff*4);
	else if (skb->protocol == ETH_P_IPV6)
		ctx = qeth_eddp_create_context_generic(card, skb,
			sizeof(struct qeth_hdr) + sizeof(struct ipv6hdr) +
			skb->h.th->doff*4);
	else
		QETH_DBF_TEXT(trace, 2, "cetcpinv");

	if (ctx == NULL) {
		QETH_DBF_TEXT(trace, 2, "creddpnl");
		return NULL;
	}
	if (qeth_eddp_fill_context_tcp(ctx, skb, qhdr)){
		QETH_DBF_TEXT(trace, 2, "ceddptfe");
		qeth_eddp_free_context(ctx);
		return NULL;
	}
	atomic_set(&ctx->refcnt, 1);
	return ctx;
}

struct qeth_eddp_context *
qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb,
			 struct qeth_hdr *qhdr)
{
	QETH_DBF_TEXT(trace, 5, "creddpc");
	switch (skb->sk->sk_protocol){
	case IPPROTO_TCP:
		return qeth_eddp_create_context_tcp(card, skb, qhdr);
	default:
		QETH_DBF_TEXT(trace, 2, "eddpinvp");
	}
	return NULL;
}


