/*
 * 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/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)->gso_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)->gso_size + hdr_len);
	if (skbs_per_page > 1){
		ctx->num_pages = (skb_shinfo(skb)->gso_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)->gso_size + hdr_len +
				     PAGE_SIZE) >> PAGE_SHIFT;
		ctx->num_pages = ctx->elements_per_skb *
				 (skb_shinfo(skb)->gso_segs + 1);
	}
	ctx->num_elements = ctx->elements_per_skb *
			    (skb_shinfo(skb)->gso_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;
}


