/*
 * Copyright(c) 2007 Atheros Corporation. All rights reserved.
 *
 * Derived from Intel e1000 driver
 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <linux/netdevice.h>

#include "atl1e.h"

/* This is the only thing that needs to be changed to adjust the
 * maximum number of ports that the driver can manage.
 */

#define ATL1E_MAX_NIC 32

#define OPTION_UNSET    -1
#define OPTION_DISABLED 0
#define OPTION_ENABLED  1

/* All parameters are treated the same, as an integer array of values.
 * This macro just reduces the need to repeat the same declaration code
 * over and over (plus this helps to avoid typo bugs).
 */
#define ATL1E_PARAM_INIT { [0 ... ATL1E_MAX_NIC] = OPTION_UNSET }

#define ATL1E_PARAM(x, desc) \
	static int __devinitdata x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
	static unsigned int num_##x; \
	module_param_array_named(x, x, int, &num_##x, 0); \
	MODULE_PARM_DESC(x, desc);

/* Transmit Memory count
 *
 * Valid Range: 64-2048
 *
 * Default Value: 128
 */
#define ATL1E_MIN_TX_DESC_CNT		32
#define ATL1E_MAX_TX_DESC_CNT		1020
#define ATL1E_DEFAULT_TX_DESC_CNT	128
ATL1E_PARAM(tx_desc_cnt, "Transmit description count");

/* Receive Memory Block Count
 *
 * Valid Range: 16-512
 *
 * Default Value: 128
 */
#define ATL1E_MIN_RX_MEM_SIZE		8    /* 8KB   */
#define ATL1E_MAX_RX_MEM_SIZE		1024 /* 1MB   */
#define ATL1E_DEFAULT_RX_MEM_SIZE	256  /* 128KB */
ATL1E_PARAM(rx_mem_size, "memory size of rx buffer(KB)");

/* User Specified MediaType Override
 *
 * Valid Range: 0-5
 *  - 0    - auto-negotiate at all supported speeds
 *  - 1    - only link at 100Mbps Full Duplex
 *  - 2    - only link at 100Mbps Half Duplex
 *  - 3    - only link at 10Mbps Full Duplex
 *  - 4    - only link at 10Mbps Half Duplex
 * Default Value: 0
 */

ATL1E_PARAM(media_type, "MediaType Select");

/* Interrupt Moderate Timer in units of 2 us
 *
 * Valid Range: 10-65535
 *
 * Default Value: 45000(90ms)
 */
#define INT_MOD_DEFAULT_CNT             100 /* 200us */
#define INT_MOD_MAX_CNT                 65000
#define INT_MOD_MIN_CNT                 50
ATL1E_PARAM(int_mod_timer, "Interrupt Moderator Timer");

#define AUTONEG_ADV_DEFAULT  0x2F
#define AUTONEG_ADV_MASK     0x2F
#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL

#define FLASH_VENDOR_DEFAULT    0
#define FLASH_VENDOR_MIN        0
#define FLASH_VENDOR_MAX        2

struct atl1e_option {
	enum { enable_option, range_option, list_option } type;
	char *name;
	char *err;
	int  def;
	union {
		struct { /* range_option info */
			int min;
			int max;
		} r;
		struct { /* list_option info */
			int nr;
			struct atl1e_opt_list { int i; char *str; } *p;
		} l;
	} arg;
};

static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt, struct pci_dev *pdev)
{
	if (*value == OPTION_UNSET) {
		*value = opt->def;
		return 0;
	}

	switch (opt->type) {
	case enable_option:
		switch (*value) {
		case OPTION_ENABLED:
			dev_info(&pdev->dev, "%s Enabled\n", opt->name);
			return 0;
		case OPTION_DISABLED:
			dev_info(&pdev->dev, "%s Disabled\n", opt->name);
			return 0;
		}
		break;
	case range_option:
		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
			dev_info(&pdev->dev, "%s set to %i\n", opt->name, *value);
			return 0;
		}
		break;
	case list_option:{
			int i;
			struct atl1e_opt_list *ent;

			for (i = 0; i < opt->arg.l.nr; i++) {
				ent = &opt->arg.l.p[i];
				if (*value == ent->i) {
					if (ent->str[0] != '\0')
						dev_info(&pdev->dev, "%s\n",
							ent->str);
					return 0;
				}
			}
			break;
		}
	default:
		BUG();
	}

	dev_info(&pdev->dev, "Invalid %s specified (%i) %s\n",
			opt->name, *value, opt->err);
	*value = opt->def;
	return -1;
}

/*
 * atl1e_check_options - Range Checking for Command Line Parameters
 * @adapter: board private structure
 *
 * This routine checks all command line parameters for valid user
 * input.  If an invalid value is given, or if no user specified
 * value exists, a default value is used.  The final value is stored
 * in a variable in the adapter structure.
 */
void __devinit atl1e_check_options(struct atl1e_adapter *adapter)
{
	struct pci_dev *pdev = adapter->pdev;
	int bd = adapter->bd_number;
	if (bd >= ATL1E_MAX_NIC) {
		dev_notice(&pdev->dev, "no configuration for board #%i\n", bd);
		dev_notice(&pdev->dev, "Using defaults for all values\n");
	}

	{ 		/* Transmit Ring Size */
		struct atl1e_option opt = {
			.type = range_option,
			.name = "Transmit Ddescription Count",
			.err  = "using default of "
				__MODULE_STRING(ATL1E_DEFAULT_TX_DESC_CNT),
			.def  = ATL1E_DEFAULT_TX_DESC_CNT,
			.arg  = { .r = { .min = ATL1E_MIN_TX_DESC_CNT,
					 .max = ATL1E_MAX_TX_DESC_CNT} }
		};
		int val;
		if (num_tx_desc_cnt > bd) {
			val = tx_desc_cnt[bd];
			atl1e_validate_option(&val, &opt, pdev);
			adapter->tx_ring.count = (u16) val & 0xFFFC;
		} else
			adapter->tx_ring.count = (u16)opt.def;
	}

	{ 		/* Receive Memory Block Count */
		struct atl1e_option opt = {
			.type = range_option,
			.name = "Memory size of rx buffer(KB)",
			.err  = "using default of "
				__MODULE_STRING(ATL1E_DEFAULT_RX_MEM_SIZE),
			.def  = ATL1E_DEFAULT_RX_MEM_SIZE,
			.arg  = { .r = { .min = ATL1E_MIN_RX_MEM_SIZE,
					 .max = ATL1E_MAX_RX_MEM_SIZE} }
		};
		int val;
		if (num_rx_mem_size > bd) {
			val = rx_mem_size[bd];
			atl1e_validate_option(&val, &opt, pdev);
			adapter->rx_ring.page_size = (u32)val * 1024;
		} else {
			adapter->rx_ring.page_size = (u32)opt.def * 1024;
		}
	}

	{ 		/* Interrupt Moderate Timer */
		struct atl1e_option opt = {
			.type = range_option,
			.name = "Interrupt Moderate Timer",
			.err  = "using default of "
				__MODULE_STRING(INT_MOD_DEFAULT_CNT),
			.def  = INT_MOD_DEFAULT_CNT,
			.arg  = { .r = { .min = INT_MOD_MIN_CNT,
					 .max = INT_MOD_MAX_CNT} }
		} ;
		int val;
		if (num_int_mod_timer > bd) {
			val = int_mod_timer[bd];
			atl1e_validate_option(&val, &opt, pdev);
			adapter->hw.imt = (u16) val;
		} else
			adapter->hw.imt = (u16)(opt.def);
	}

	{ 		/* MediaType */
		struct atl1e_option opt = {
			.type = range_option,
			.name = "Speed/Duplex Selection",
			.err  = "using default of "
				__MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR),
			.def  = MEDIA_TYPE_AUTO_SENSOR,
			.arg  = { .r = { .min = MEDIA_TYPE_AUTO_SENSOR,
					 .max = MEDIA_TYPE_10M_HALF} }
		} ;
		int val;
		if (num_media_type > bd) {
			val = media_type[bd];
			atl1e_validate_option(&val, &opt, pdev);
			adapter->hw.media_type = (u16) val;
		} else
			adapter->hw.media_type = (u16)(opt.def);

	}
}
