diff options
Diffstat (limited to 'drivers/net/atl1e/atl1e_param.c')
| -rw-r--r-- | drivers/net/atl1e/atl1e_param.c | 263 | 
1 files changed, 263 insertions, 0 deletions
diff --git a/drivers/net/atl1e/atl1e_param.c b/drivers/net/atl1e/atl1e_param.c new file mode 100644 index 00000000000..f72abb34b0c --- /dev/null +++ b/drivers/net/atl1e/atl1e_param.c @@ -0,0 +1,263 @@ +/* + * 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 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); + +	} +}  |