/* ar-skbuff.c: socket buffer destruction handling
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include "ar-internal.h"

/*
 * set up for the ACK at the end of the receive phase when we discard the final
 * receive phase data packet
 * - called with softirqs disabled
 */
static void rxrpc_request_final_ACK(struct rxrpc_call *call)
{
	/* the call may be aborted before we have a chance to ACK it */
	write_lock(&call->state_lock);

	switch (call->state) {
	case RXRPC_CALL_CLIENT_RECV_REPLY:
		call->state = RXRPC_CALL_CLIENT_FINAL_ACK;
		_debug("request final ACK");

		/* get an extra ref on the call for the final-ACK generator to
		 * release */
		rxrpc_get_call(call);
		set_bit(RXRPC_CALL_EV_ACK_FINAL, &call->events);
		if (try_to_del_timer_sync(&call->ack_timer) >= 0)
			rxrpc_queue_call(call);
		break;

	case RXRPC_CALL_SERVER_RECV_REQUEST:
		call->state = RXRPC_CALL_SERVER_ACK_REQUEST;
	default:
		break;
	}

	write_unlock(&call->state_lock);
}

/*
 * drop the bottom ACK off of the call ACK window and advance the window
 */
static void rxrpc_hard_ACK_data(struct rxrpc_call *call,
				struct rxrpc_skb_priv *sp)
{
	int loop;
	u32 seq;

	spin_lock_bh(&call->lock);

	_debug("hard ACK #%u", sp->hdr.seq);

	for (loop = 0; loop < RXRPC_ACKR_WINDOW_ASZ; loop++) {
		call->ackr_window[loop] >>= 1;
		call->ackr_window[loop] |=
			call->ackr_window[loop + 1] << (BITS_PER_LONG - 1);
	}

	seq = sp->hdr.seq;
	ASSERTCMP(seq, ==, call->rx_data_eaten + 1);
	call->rx_data_eaten = seq;

	if (call->ackr_win_top < UINT_MAX)
		call->ackr_win_top++;

	ASSERTIFCMP(call->state <= RXRPC_CALL_COMPLETE,
		    call->rx_data_post, >=, call->rx_data_recv);
	ASSERTIFCMP(call->state <= RXRPC_CALL_COMPLETE,
		    call->rx_data_recv, >=, call->rx_data_eaten);

	if (sp->hdr.flags & RXRPC_LAST_PACKET) {
		rxrpc_request_final_ACK(call);
	} else if (atomic_dec_and_test(&call->ackr_not_idle) &&
		   test_and_clear_bit(RXRPC_CALL_TX_SOFT_ACK, &call->flags)) {
		/* We previously soft-ACK'd some received packets that have now
		 * been consumed, so send a hard-ACK if no more packets are
		 * immediately forthcoming to allow the transmitter to free up
		 * its Tx bufferage.
		 */
		_debug("send Rx idle ACK");
		__rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, sp->hdr.serial,
				    false);
	}

	spin_unlock_bh(&call->lock);
}

/**
 * rxrpc_kernel_data_consumed - Record consumption of data message
 * @call: The call to which the message pertains.
 * @skb: Message holding data
 *
 * Record the consumption of a data message and generate an ACK if appropriate.
 * The call state is shifted if this was the final packet.  The caller must be
 * in process context with no spinlocks held.
 *
 * TODO: Actually generate the ACK here rather than punting this to the
 * workqueue.
 */
void rxrpc_kernel_data_consumed(struct rxrpc_call *call, struct sk_buff *skb)
{
	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);

	_enter("%d,%p{%u}", call->debug_id, skb, sp->hdr.seq);

	ASSERTCMP(sp->call, ==, call);
	ASSERTCMP(sp->hdr.type, ==, RXRPC_PACKET_TYPE_DATA);

	/* TODO: Fix the sequence number tracking */
	ASSERTCMP(sp->hdr.seq, >=, call->rx_data_recv);
	ASSERTCMP(sp->hdr.seq, <=, call->rx_data_recv + 1);
	ASSERTCMP(sp->hdr.seq, >, call->rx_data_eaten);

	call->rx_data_recv = sp->hdr.seq;
	rxrpc_hard_ACK_data(call, sp);
}
EXPORT_SYMBOL(rxrpc_kernel_data_consumed);

/*
 * Destroy a packet that has an RxRPC control buffer
 */
void rxrpc_packet_destructor(struct sk_buff *skb)
{
	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
	struct rxrpc_call *call = sp->call;

	_enter("%p{%p}", skb, call);

	if (call) {
		if (atomic_dec_return(&call->skb_count) < 0)
			BUG();
		rxrpc_put_call(call);
		sp->call = NULL;
	}

	if (skb->sk)
		sock_rfree(skb);
	_leave("");
}

/**
 * rxrpc_kernel_free_skb - Free an RxRPC socket buffer
 * @skb: The socket buffer to be freed
 *
 * Let RxRPC free its own socket buffer, permitting it to maintain debug
 * accounting.
 */
void rxrpc_kernel_free_skb(struct sk_buff *skb)
{
	rxrpc_free_skb(skb);
}
EXPORT_SYMBOL(rxrpc_kernel_free_skb);
