/*
 * Copyright 2002-2005, Instant802 Networks, Inc.
 * Copyright 2005, Devicescape Software, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/compiler.h>

#include <net/mac80211.h>
#include "ieee80211_i.h"
#include "ieee80211_rate.h"
#include "debugfs.h"


/* This is a minimal implementation of TX rate controlling that can be used
 * as the default when no improved mechanisms are available. */


#define RATE_CONTROL_EMERG_DEC 2
#define RATE_CONTROL_INTERVAL (HZ / 20)
#define RATE_CONTROL_MIN_TX 10

MODULE_ALIAS("rc80211_default");

static void rate_control_rate_inc(struct ieee80211_local *local,
				  struct sta_info *sta)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_hw_mode *mode;
	int i = sta->txrate;
	int maxrate;

	sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
	if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) {
		/* forced unicast rate - do not change STA rate */
		return;
	}

	mode = local->oper_hw_mode;
	maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1;

	if (i > mode->num_rates)
		i = mode->num_rates - 2;

	while (i + 1 < mode->num_rates) {
		i++;
		if (sta->supp_rates & BIT(i) &&
		    mode->rates[i].flags & IEEE80211_RATE_SUPPORTED &&
		    (maxrate < 0 || i <= maxrate)) {
			sta->txrate = i;
			break;
		}
	}
}


static void rate_control_rate_dec(struct ieee80211_local *local,
				  struct sta_info *sta)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_hw_mode *mode;
	int i = sta->txrate;

	sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
	if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) {
		/* forced unicast rate - do not change STA rate */
		return;
	}

	mode = local->oper_hw_mode;
	if (i > mode->num_rates)
		i = mode->num_rates;

	while (i > 0) {
		i--;
		if (sta->supp_rates & BIT(i) &&
		    mode->rates[i].flags & IEEE80211_RATE_SUPPORTED) {
			sta->txrate = i;
			break;
		}
	}
}


static struct ieee80211_rate *
rate_control_lowest_rate(struct ieee80211_local *local,
			 struct ieee80211_hw_mode *mode)
{
	int i;

	for (i = 0; i < mode->num_rates; i++) {
		struct ieee80211_rate *rate = &mode->rates[i];

		if (rate->flags & IEEE80211_RATE_SUPPORTED)
			return rate;
	}

	printk(KERN_DEBUG "rate_control_lowest_rate - no supported rates "
	       "found\n");
	return &mode->rates[0];
}


struct global_rate_control {
	int dummy;
};

struct sta_rate_control {
	unsigned long last_rate_change;
	u32 tx_num_failures;
	u32 tx_num_xmit;

	unsigned long avg_rate_update;
	u32 tx_avg_rate_sum;
	u32 tx_avg_rate_num;

#ifdef CONFIG_MAC80211_DEBUGFS
	struct dentry *tx_avg_rate_sum_dentry;
	struct dentry *tx_avg_rate_num_dentry;
#endif
};


static void rate_control_simple_tx_status(void *priv, struct net_device *dev,
					  struct sk_buff *skb,
					  struct ieee80211_tx_status *status)
{
	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	struct sta_info *sta;
	struct sta_rate_control *srctrl;

	sta = sta_info_get(local, hdr->addr1);

	if (!sta)
	    return;

	srctrl = sta->rate_ctrl_priv;
	srctrl->tx_num_xmit++;
	if (status->excessive_retries) {
		sta->antenna_sel_tx = sta->antenna_sel_tx == 1 ? 2 : 1;
		sta->antenna_sel_rx = sta->antenna_sel_rx == 1 ? 2 : 1;
		if (local->sta_antenna_sel == STA_ANTENNA_SEL_SW_CTRL_DEBUG) {
			printk(KERN_DEBUG "%s: " MAC_FMT " TX antenna --> %d "
			       "RX antenna --> %d (@%lu)\n",
			       dev->name, MAC_ARG(hdr->addr1),
			       sta->antenna_sel_tx, sta->antenna_sel_rx, jiffies);
		}
		srctrl->tx_num_failures++;
		sta->tx_retry_failed++;
		sta->tx_num_consecutive_failures++;
		sta->tx_num_mpdu_fail++;
	} else {
		sta->last_ack_rssi[0] = sta->last_ack_rssi[1];
		sta->last_ack_rssi[1] = sta->last_ack_rssi[2];
		sta->last_ack_rssi[2] = status->ack_signal;
		sta->tx_num_consecutive_failures = 0;
		sta->tx_num_mpdu_ok++;
	}
	sta->tx_retry_count += status->retry_count;
	sta->tx_num_mpdu_fail += status->retry_count;

	if (time_after(jiffies,
		       srctrl->last_rate_change + RATE_CONTROL_INTERVAL) &&
		srctrl->tx_num_xmit > RATE_CONTROL_MIN_TX) {
		u32 per_failed;
		srctrl->last_rate_change = jiffies;

		per_failed = (100 * sta->tx_num_mpdu_fail) /
			(sta->tx_num_mpdu_fail + sta->tx_num_mpdu_ok);
		/* TODO: calculate average per_failed to make adjusting
		 * parameters easier */
#if 0
		if (net_ratelimit()) {
			printk(KERN_DEBUG "MPDU fail=%d ok=%d per_failed=%d\n",
			       sta->tx_num_mpdu_fail, sta->tx_num_mpdu_ok,
			       per_failed);
		}
#endif

		/*
		 * XXX: Make these configurable once we have an
		 * interface to the rate control algorithms
		 */
		if (per_failed > RATE_CONTROL_NUM_DOWN) {
			rate_control_rate_dec(local, sta);
		} else if (per_failed < RATE_CONTROL_NUM_UP) {
			rate_control_rate_inc(local, sta);
		}
		srctrl->tx_avg_rate_sum += status->control.rate->rate;
		srctrl->tx_avg_rate_num++;
		srctrl->tx_num_failures = 0;
		srctrl->tx_num_xmit = 0;
	} else if (sta->tx_num_consecutive_failures >=
		   RATE_CONTROL_EMERG_DEC) {
		rate_control_rate_dec(local, sta);
	}

	if (srctrl->avg_rate_update + 60 * HZ < jiffies) {
		srctrl->avg_rate_update = jiffies;
		if (srctrl->tx_avg_rate_num > 0) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
			printk(KERN_DEBUG "%s: STA " MAC_FMT " Average rate: "
			       "%d (%d/%d)\n",
			       dev->name, MAC_ARG(sta->addr),
			       srctrl->tx_avg_rate_sum /
			       srctrl->tx_avg_rate_num,
			       srctrl->tx_avg_rate_sum,
			       srctrl->tx_avg_rate_num);
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
			srctrl->tx_avg_rate_sum = 0;
			srctrl->tx_avg_rate_num = 0;
		}
	}

	sta_info_put(sta);
}


static struct ieee80211_rate *
rate_control_simple_get_rate(void *priv, struct net_device *dev,
			     struct sk_buff *skb,
			     struct rate_control_extra *extra)
{
	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	struct ieee80211_hw_mode *mode = extra->mode;
	struct sta_info *sta;
	int rateidx, nonerp_idx;
	u16 fc;

	memset(extra, 0, sizeof(*extra));

	fc = le16_to_cpu(hdr->frame_control);
	if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
	    (hdr->addr1[0] & 0x01)) {
		/* Send management frames and broadcast/multicast data using
		 * lowest rate. */
		/* TODO: this could probably be improved.. */
		return rate_control_lowest_rate(local, mode);
	}

	sta = sta_info_get(local, hdr->addr1);

	if (!sta)
		return rate_control_lowest_rate(local, mode);

	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
		sta->txrate = sdata->bss->force_unicast_rateidx;

	rateidx = sta->txrate;

	if (rateidx >= mode->num_rates)
		rateidx = mode->num_rates - 1;

	sta->last_txrate = rateidx;
	nonerp_idx = rateidx;
	while (nonerp_idx > 0 &&
	       ((mode->rates[nonerp_idx].flags & IEEE80211_RATE_ERP) ||
		!(mode->rates[nonerp_idx].flags & IEEE80211_RATE_SUPPORTED) ||
		!(sta->supp_rates & BIT(nonerp_idx))))
		nonerp_idx--;
	extra->nonerp = &mode->rates[nonerp_idx];

	sta_info_put(sta);

	return &mode->rates[rateidx];
}


static void rate_control_simple_rate_init(void *priv, void *priv_sta,
					  struct ieee80211_local *local,
					  struct sta_info *sta)
{
	struct ieee80211_hw_mode *mode;
	int i;
	sta->txrate = 0;
	mode = local->oper_hw_mode;
	/* TODO: This routine should consider using RSSI from previous packets
	 * as we need to have IEEE 802.1X auth succeed immediately after assoc..
	 * Until that method is implemented, we will use the lowest supported rate
	 * as a workaround, */
	for (i = 0; i < mode->num_rates; i++) {
		if ((sta->supp_rates & BIT(i)) &&
		    (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) {
			sta->txrate = i;
			break;
		}
	}
}


static void * rate_control_simple_alloc(struct ieee80211_local *local)
{
	struct global_rate_control *rctrl;

	rctrl = kzalloc(sizeof(*rctrl), GFP_ATOMIC);

	return rctrl;
}


static void rate_control_simple_free(void *priv)
{
	struct global_rate_control *rctrl = priv;
	kfree(rctrl);
}


static void rate_control_simple_clear(void *priv)
{
}


static void * rate_control_simple_alloc_sta(void *priv, gfp_t gfp)
{
	struct sta_rate_control *rctrl;

	rctrl = kzalloc(sizeof(*rctrl), gfp);

	return rctrl;
}


static void rate_control_simple_free_sta(void *priv, void *priv_sta)
{
	struct sta_rate_control *rctrl = priv_sta;
	kfree(rctrl);
}

#ifdef CONFIG_MAC80211_DEBUGFS

static int open_file_generic(struct inode *inode, struct file *file)
{
	file->private_data = inode->i_private;
	return 0;
}

static ssize_t sta_tx_avg_rate_sum_read(struct file *file,
					char __user *userbuf,
					size_t count, loff_t *ppos)
{
	struct sta_rate_control *srctrl = file->private_data;
	char buf[20];

	sprintf(buf, "%d\n", srctrl->tx_avg_rate_sum);
	return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
}

static const struct file_operations sta_tx_avg_rate_sum_ops = {
	.read = sta_tx_avg_rate_sum_read,
	.open = open_file_generic,
};

static ssize_t sta_tx_avg_rate_num_read(struct file *file,
					char __user *userbuf,
					size_t count, loff_t *ppos)
{
	struct sta_rate_control *srctrl = file->private_data;
	char buf[20];

	sprintf(buf, "%d\n", srctrl->tx_avg_rate_num);
	return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
}

static const struct file_operations sta_tx_avg_rate_num_ops = {
	.read = sta_tx_avg_rate_num_read,
	.open = open_file_generic,
};

static void rate_control_simple_add_sta_debugfs(void *priv, void *priv_sta,
						struct dentry *dir)
{
	struct sta_rate_control *srctrl = priv_sta;

	srctrl->tx_avg_rate_num_dentry =
		debugfs_create_file("rc_simple_sta_tx_avg_rate_num", 0400,
				    dir, srctrl, &sta_tx_avg_rate_num_ops);
	srctrl->tx_avg_rate_sum_dentry =
		debugfs_create_file("rc_simple_sta_tx_avg_rate_sum", 0400,
				    dir, srctrl, &sta_tx_avg_rate_sum_ops);
}

static void rate_control_simple_remove_sta_debugfs(void *priv, void *priv_sta)
{
	struct sta_rate_control *srctrl = priv_sta;

	debugfs_remove(srctrl->tx_avg_rate_sum_dentry);
	debugfs_remove(srctrl->tx_avg_rate_num_dentry);
}
#endif

static struct rate_control_ops rate_control_simple = {
	.module = THIS_MODULE,
	.name = "simple",
	.tx_status = rate_control_simple_tx_status,
	.get_rate = rate_control_simple_get_rate,
	.rate_init = rate_control_simple_rate_init,
	.clear = rate_control_simple_clear,
	.alloc = rate_control_simple_alloc,
	.free = rate_control_simple_free,
	.alloc_sta = rate_control_simple_alloc_sta,
	.free_sta = rate_control_simple_free_sta,
#ifdef CONFIG_MAC80211_DEBUGFS
	.add_sta_debugfs = rate_control_simple_add_sta_debugfs,
	.remove_sta_debugfs = rate_control_simple_remove_sta_debugfs,
#endif
};


static int __init rate_control_simple_init(void)
{
	return ieee80211_rate_control_register(&rate_control_simple);
}


static void __exit rate_control_simple_exit(void)
{
	ieee80211_rate_control_unregister(&rate_control_simple);
}


module_init(rate_control_simple_init);
module_exit(rate_control_simple_exit);

MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211");
MODULE_LICENSE("GPL");
