1dee1ad47SJeff Kirsher /*******************************************************************************
2dee1ad47SJeff Kirsher 
3dee1ad47SJeff Kirsher   Intel PRO/1000 Linux driver
4dee1ad47SJeff Kirsher   Copyright(c) 1999 - 2006 Intel Corporation.
5dee1ad47SJeff Kirsher 
6dee1ad47SJeff Kirsher   This program is free software; you can redistribute it and/or modify it
7dee1ad47SJeff Kirsher   under the terms and conditions of the GNU General Public License,
8dee1ad47SJeff Kirsher   version 2, as published by the Free Software Foundation.
9dee1ad47SJeff Kirsher 
10dee1ad47SJeff Kirsher   This program is distributed in the hope it will be useful, but WITHOUT
11dee1ad47SJeff Kirsher   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12dee1ad47SJeff Kirsher   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13dee1ad47SJeff Kirsher   more details.
14dee1ad47SJeff Kirsher 
15dee1ad47SJeff Kirsher   You should have received a copy of the GNU General Public License along with
16dee1ad47SJeff Kirsher   this program; if not, write to the Free Software Foundation, Inc.,
17dee1ad47SJeff Kirsher   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18dee1ad47SJeff Kirsher 
19dee1ad47SJeff Kirsher   The full GNU General Public License is included in this distribution in
20dee1ad47SJeff Kirsher   the file called "COPYING".
21dee1ad47SJeff Kirsher 
22dee1ad47SJeff Kirsher   Contact Information:
23dee1ad47SJeff Kirsher   Linux NICS <linux.nics@intel.com>
24dee1ad47SJeff Kirsher   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
25dee1ad47SJeff Kirsher   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26dee1ad47SJeff Kirsher 
27dee1ad47SJeff Kirsher *******************************************************************************/
28dee1ad47SJeff Kirsher 
29dee1ad47SJeff Kirsher #include "e1000.h"
30dee1ad47SJeff Kirsher 
31dee1ad47SJeff Kirsher /* This is the only thing that needs to be changed to adjust the
32dee1ad47SJeff Kirsher  * maximum number of ports that the driver can manage.
33dee1ad47SJeff Kirsher  */
34dee1ad47SJeff Kirsher 
35dee1ad47SJeff Kirsher #define E1000_MAX_NIC 32
36dee1ad47SJeff Kirsher 
37dee1ad47SJeff Kirsher #define OPTION_UNSET   -1
38dee1ad47SJeff Kirsher #define OPTION_DISABLED 0
39dee1ad47SJeff Kirsher #define OPTION_ENABLED  1
40dee1ad47SJeff Kirsher 
41dee1ad47SJeff Kirsher /* All parameters are treated the same, as an integer array of values.
42dee1ad47SJeff Kirsher  * This macro just reduces the need to repeat the same declaration code
43dee1ad47SJeff Kirsher  * over and over (plus this helps to avoid typo bugs).
44dee1ad47SJeff Kirsher  */
45dee1ad47SJeff Kirsher 
46dee1ad47SJeff Kirsher #define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
47dee1ad47SJeff Kirsher #define E1000_PARAM(X, desc) \
48dee1ad47SJeff Kirsher 	static int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \
49dee1ad47SJeff Kirsher 	static unsigned int num_##X; \
50dee1ad47SJeff Kirsher 	module_param_array_named(X, X, int, &num_##X, 0); \
51dee1ad47SJeff Kirsher 	MODULE_PARM_DESC(X, desc);
52dee1ad47SJeff Kirsher 
53dee1ad47SJeff Kirsher /* Transmit Descriptor Count
54dee1ad47SJeff Kirsher  *
55dee1ad47SJeff Kirsher  * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers
56dee1ad47SJeff Kirsher  * Valid Range: 80-4096 for 82544 and newer
57dee1ad47SJeff Kirsher  *
58dee1ad47SJeff Kirsher  * Default Value: 256
59dee1ad47SJeff Kirsher  */
60dee1ad47SJeff Kirsher E1000_PARAM(TxDescriptors, "Number of transmit descriptors");
61dee1ad47SJeff Kirsher 
62dee1ad47SJeff Kirsher /* Receive Descriptor Count
63dee1ad47SJeff Kirsher  *
64dee1ad47SJeff Kirsher  * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers
65dee1ad47SJeff Kirsher  * Valid Range: 80-4096 for 82544 and newer
66dee1ad47SJeff Kirsher  *
67dee1ad47SJeff Kirsher  * Default Value: 256
68dee1ad47SJeff Kirsher  */
69dee1ad47SJeff Kirsher E1000_PARAM(RxDescriptors, "Number of receive descriptors");
70dee1ad47SJeff Kirsher 
71dee1ad47SJeff Kirsher /* User Specified Speed Override
72dee1ad47SJeff Kirsher  *
73dee1ad47SJeff Kirsher  * Valid Range: 0, 10, 100, 1000
74dee1ad47SJeff Kirsher  *  - 0    - auto-negotiate at all supported speeds
75dee1ad47SJeff Kirsher  *  - 10   - only link at 10 Mbps
76dee1ad47SJeff Kirsher  *  - 100  - only link at 100 Mbps
77dee1ad47SJeff Kirsher  *  - 1000 - only link at 1000 Mbps
78dee1ad47SJeff Kirsher  *
79dee1ad47SJeff Kirsher  * Default Value: 0
80dee1ad47SJeff Kirsher  */
81dee1ad47SJeff Kirsher E1000_PARAM(Speed, "Speed setting");
82dee1ad47SJeff Kirsher 
83dee1ad47SJeff Kirsher /* User Specified Duplex Override
84dee1ad47SJeff Kirsher  *
85dee1ad47SJeff Kirsher  * Valid Range: 0-2
86dee1ad47SJeff Kirsher  *  - 0 - auto-negotiate for duplex
87dee1ad47SJeff Kirsher  *  - 1 - only link at half duplex
88dee1ad47SJeff Kirsher  *  - 2 - only link at full duplex
89dee1ad47SJeff Kirsher  *
90dee1ad47SJeff Kirsher  * Default Value: 0
91dee1ad47SJeff Kirsher  */
92dee1ad47SJeff Kirsher E1000_PARAM(Duplex, "Duplex setting");
93dee1ad47SJeff Kirsher 
94dee1ad47SJeff Kirsher /* Auto-negotiation Advertisement Override
95dee1ad47SJeff Kirsher  *
96dee1ad47SJeff Kirsher  * Valid Range: 0x01-0x0F, 0x20-0x2F (copper); 0x20 (fiber)
97dee1ad47SJeff Kirsher  *
98dee1ad47SJeff Kirsher  * The AutoNeg value is a bit mask describing which speed and duplex
99dee1ad47SJeff Kirsher  * combinations should be advertised during auto-negotiation.
100dee1ad47SJeff Kirsher  * The supported speed and duplex modes are listed below
101dee1ad47SJeff Kirsher  *
102dee1ad47SJeff Kirsher  * Bit           7     6     5      4      3     2     1      0
103dee1ad47SJeff Kirsher  * Speed (Mbps)  N/A   N/A   1000   N/A    100   100   10     10
104dee1ad47SJeff Kirsher  * Duplex                    Full          Full  Half  Full   Half
105dee1ad47SJeff Kirsher  *
106dee1ad47SJeff Kirsher  * Default Value: 0x2F (copper); 0x20 (fiber)
107dee1ad47SJeff Kirsher  */
108dee1ad47SJeff Kirsher E1000_PARAM(AutoNeg, "Advertised auto-negotiation setting");
109dee1ad47SJeff Kirsher #define AUTONEG_ADV_DEFAULT  0x2F
110dee1ad47SJeff Kirsher #define AUTONEG_ADV_MASK     0x2F
111dee1ad47SJeff Kirsher 
112dee1ad47SJeff Kirsher /* User Specified Flow Control Override
113dee1ad47SJeff Kirsher  *
114dee1ad47SJeff Kirsher  * Valid Range: 0-3
115dee1ad47SJeff Kirsher  *  - 0 - No Flow Control
116dee1ad47SJeff Kirsher  *  - 1 - Rx only, respond to PAUSE frames but do not generate them
117dee1ad47SJeff Kirsher  *  - 2 - Tx only, generate PAUSE frames but ignore them on receive
118dee1ad47SJeff Kirsher  *  - 3 - Full Flow Control Support
119dee1ad47SJeff Kirsher  *
120dee1ad47SJeff Kirsher  * Default Value: Read flow control settings from the EEPROM
121dee1ad47SJeff Kirsher  */
122dee1ad47SJeff Kirsher E1000_PARAM(FlowControl, "Flow Control setting");
123dee1ad47SJeff Kirsher #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
124dee1ad47SJeff Kirsher 
125dee1ad47SJeff Kirsher /* XsumRX - Receive Checksum Offload Enable/Disable
126dee1ad47SJeff Kirsher  *
127dee1ad47SJeff Kirsher  * Valid Range: 0, 1
128dee1ad47SJeff Kirsher  *  - 0 - disables all checksum offload
129dee1ad47SJeff Kirsher  *  - 1 - enables receive IP/TCP/UDP checksum offload
130dee1ad47SJeff Kirsher  *        on 82543 and newer -based NICs
131dee1ad47SJeff Kirsher  *
132dee1ad47SJeff Kirsher  * Default Value: 1
133dee1ad47SJeff Kirsher  */
134dee1ad47SJeff Kirsher E1000_PARAM(XsumRX, "Disable or enable Receive Checksum offload");
135dee1ad47SJeff Kirsher 
136dee1ad47SJeff Kirsher /* Transmit Interrupt Delay in units of 1.024 microseconds
137dee1ad47SJeff Kirsher  *  Tx interrupt delay needs to typically be set to something non zero
138dee1ad47SJeff Kirsher  *
139dee1ad47SJeff Kirsher  * Valid Range: 0-65535
140dee1ad47SJeff Kirsher  */
141dee1ad47SJeff Kirsher E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay");
142dee1ad47SJeff Kirsher #define DEFAULT_TIDV                   8
143dee1ad47SJeff Kirsher #define MAX_TXDELAY               0xFFFF
144dee1ad47SJeff Kirsher #define MIN_TXDELAY                    0
145dee1ad47SJeff Kirsher 
146dee1ad47SJeff Kirsher /* Transmit Absolute Interrupt Delay in units of 1.024 microseconds
147dee1ad47SJeff Kirsher  *
148dee1ad47SJeff Kirsher  * Valid Range: 0-65535
149dee1ad47SJeff Kirsher  */
150dee1ad47SJeff Kirsher E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
151dee1ad47SJeff Kirsher #define DEFAULT_TADV                  32
152dee1ad47SJeff Kirsher #define MAX_TXABSDELAY            0xFFFF
153dee1ad47SJeff Kirsher #define MIN_TXABSDELAY                 0
154dee1ad47SJeff Kirsher 
155dee1ad47SJeff Kirsher /* Receive Interrupt Delay in units of 1.024 microseconds
156dee1ad47SJeff Kirsher  *   hardware will likely hang if you set this to anything but zero.
157dee1ad47SJeff Kirsher  *
158dee1ad47SJeff Kirsher  * Valid Range: 0-65535
159dee1ad47SJeff Kirsher  */
160dee1ad47SJeff Kirsher E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
161dee1ad47SJeff Kirsher #define DEFAULT_RDTR                   0
162dee1ad47SJeff Kirsher #define MAX_RXDELAY               0xFFFF
163dee1ad47SJeff Kirsher #define MIN_RXDELAY                    0
164dee1ad47SJeff Kirsher 
165dee1ad47SJeff Kirsher /* Receive Absolute Interrupt Delay in units of 1.024 microseconds
166dee1ad47SJeff Kirsher  *
167dee1ad47SJeff Kirsher  * Valid Range: 0-65535
168dee1ad47SJeff Kirsher  */
169dee1ad47SJeff Kirsher E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
170dee1ad47SJeff Kirsher #define DEFAULT_RADV                   8
171dee1ad47SJeff Kirsher #define MAX_RXABSDELAY            0xFFFF
172dee1ad47SJeff Kirsher #define MIN_RXABSDELAY                 0
173dee1ad47SJeff Kirsher 
174dee1ad47SJeff Kirsher /* Interrupt Throttle Rate (interrupts/sec)
175dee1ad47SJeff Kirsher  *
176dee1ad47SJeff Kirsher  * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative)
177dee1ad47SJeff Kirsher  */
178dee1ad47SJeff Kirsher E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
179dee1ad47SJeff Kirsher #define DEFAULT_ITR                    3
180dee1ad47SJeff Kirsher #define MAX_ITR                   100000
181dee1ad47SJeff Kirsher #define MIN_ITR                      100
182dee1ad47SJeff Kirsher 
183dee1ad47SJeff Kirsher /* Enable Smart Power Down of the PHY
184dee1ad47SJeff Kirsher  *
185dee1ad47SJeff Kirsher  * Valid Range: 0, 1
186dee1ad47SJeff Kirsher  *
187dee1ad47SJeff Kirsher  * Default Value: 0 (disabled)
188dee1ad47SJeff Kirsher  */
189dee1ad47SJeff Kirsher E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
190dee1ad47SJeff Kirsher 
191dee1ad47SJeff Kirsher struct e1000_option {
192dee1ad47SJeff Kirsher 	enum { enable_option, range_option, list_option } type;
193dee1ad47SJeff Kirsher 	const char *name;
194dee1ad47SJeff Kirsher 	const char *err;
195dee1ad47SJeff Kirsher 	int def;
196dee1ad47SJeff Kirsher 	union {
197dee1ad47SJeff Kirsher 		struct { /* range_option info */
198dee1ad47SJeff Kirsher 			int min;
199dee1ad47SJeff Kirsher 			int max;
200dee1ad47SJeff Kirsher 		} r;
201dee1ad47SJeff Kirsher 		struct { /* list_option info */
202dee1ad47SJeff Kirsher 			int nr;
203dee1ad47SJeff Kirsher 			const struct e1000_opt_list { int i; char *str; } *p;
204dee1ad47SJeff Kirsher 		} l;
205dee1ad47SJeff Kirsher 	} arg;
206dee1ad47SJeff Kirsher };
207dee1ad47SJeff Kirsher 
208dee1ad47SJeff Kirsher static int __devinit e1000_validate_option(unsigned int *value,
209dee1ad47SJeff Kirsher 					   const struct e1000_option *opt,
210dee1ad47SJeff Kirsher 					   struct e1000_adapter *adapter)
211dee1ad47SJeff Kirsher {
212dee1ad47SJeff Kirsher 	if (*value == OPTION_UNSET) {
213dee1ad47SJeff Kirsher 		*value = opt->def;
214dee1ad47SJeff Kirsher 		return 0;
215dee1ad47SJeff Kirsher 	}
216dee1ad47SJeff Kirsher 
217dee1ad47SJeff Kirsher 	switch (opt->type) {
218dee1ad47SJeff Kirsher 	case enable_option:
219dee1ad47SJeff Kirsher 		switch (*value) {
220dee1ad47SJeff Kirsher 		case OPTION_ENABLED:
221dee1ad47SJeff Kirsher 			e_dev_info("%s Enabled\n", opt->name);
222dee1ad47SJeff Kirsher 			return 0;
223dee1ad47SJeff Kirsher 		case OPTION_DISABLED:
224dee1ad47SJeff Kirsher 			e_dev_info("%s Disabled\n", opt->name);
225dee1ad47SJeff Kirsher 			return 0;
226dee1ad47SJeff Kirsher 		}
227dee1ad47SJeff Kirsher 		break;
228dee1ad47SJeff Kirsher 	case range_option:
229dee1ad47SJeff Kirsher 		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
230dee1ad47SJeff Kirsher 			e_dev_info("%s set to %i\n", opt->name, *value);
231dee1ad47SJeff Kirsher 			return 0;
232dee1ad47SJeff Kirsher 		}
233dee1ad47SJeff Kirsher 		break;
234dee1ad47SJeff Kirsher 	case list_option: {
235dee1ad47SJeff Kirsher 		int i;
236dee1ad47SJeff Kirsher 		const struct e1000_opt_list *ent;
237dee1ad47SJeff Kirsher 
238dee1ad47SJeff Kirsher 		for (i = 0; i < opt->arg.l.nr; i++) {
239dee1ad47SJeff Kirsher 			ent = &opt->arg.l.p[i];
240dee1ad47SJeff Kirsher 			if (*value == ent->i) {
241dee1ad47SJeff Kirsher 				if (ent->str[0] != '\0')
242dee1ad47SJeff Kirsher 					e_dev_info("%s\n", ent->str);
243dee1ad47SJeff Kirsher 				return 0;
244dee1ad47SJeff Kirsher 			}
245dee1ad47SJeff Kirsher 		}
246dee1ad47SJeff Kirsher 	}
247dee1ad47SJeff Kirsher 		break;
248dee1ad47SJeff Kirsher 	default:
249dee1ad47SJeff Kirsher 		BUG();
250dee1ad47SJeff Kirsher 	}
251dee1ad47SJeff Kirsher 
252dee1ad47SJeff Kirsher 	e_dev_info("Invalid %s value specified (%i) %s\n",
253dee1ad47SJeff Kirsher 	       opt->name, *value, opt->err);
254dee1ad47SJeff Kirsher 	*value = opt->def;
255dee1ad47SJeff Kirsher 	return -1;
256dee1ad47SJeff Kirsher }
257dee1ad47SJeff Kirsher 
258dee1ad47SJeff Kirsher static void e1000_check_fiber_options(struct e1000_adapter *adapter);
259dee1ad47SJeff Kirsher static void e1000_check_copper_options(struct e1000_adapter *adapter);
260dee1ad47SJeff Kirsher 
261dee1ad47SJeff Kirsher /**
262dee1ad47SJeff Kirsher  * e1000_check_options - Range Checking for Command Line Parameters
263dee1ad47SJeff Kirsher  * @adapter: board private structure
264dee1ad47SJeff Kirsher  *
265dee1ad47SJeff Kirsher  * This routine checks all command line parameters for valid user
266dee1ad47SJeff Kirsher  * input.  If an invalid value is given, or if no user specified
267dee1ad47SJeff Kirsher  * value exists, a default value is used.  The final value is stored
268dee1ad47SJeff Kirsher  * in a variable in the adapter structure.
269dee1ad47SJeff Kirsher  **/
270dee1ad47SJeff Kirsher 
271dee1ad47SJeff Kirsher void __devinit e1000_check_options(struct e1000_adapter *adapter)
272dee1ad47SJeff Kirsher {
273dee1ad47SJeff Kirsher 	struct e1000_option opt;
274dee1ad47SJeff Kirsher 	int bd = adapter->bd_number;
275dee1ad47SJeff Kirsher 
276dee1ad47SJeff Kirsher 	if (bd >= E1000_MAX_NIC) {
277dee1ad47SJeff Kirsher 		e_dev_warn("Warning: no configuration for board #%i "
278dee1ad47SJeff Kirsher 			   "using defaults for all values\n", bd);
279dee1ad47SJeff Kirsher 	}
280dee1ad47SJeff Kirsher 
281dee1ad47SJeff Kirsher 	{ /* Transmit Descriptor Count */
282dee1ad47SJeff Kirsher 		struct e1000_tx_ring *tx_ring = adapter->tx_ring;
283dee1ad47SJeff Kirsher 		int i;
284dee1ad47SJeff Kirsher 		e1000_mac_type mac_type = adapter->hw.mac_type;
285dee1ad47SJeff Kirsher 
286dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
287dee1ad47SJeff Kirsher 			.type = range_option,
288dee1ad47SJeff Kirsher 			.name = "Transmit Descriptors",
289dee1ad47SJeff Kirsher 			.err  = "using default of "
290dee1ad47SJeff Kirsher 				__MODULE_STRING(E1000_DEFAULT_TXD),
291dee1ad47SJeff Kirsher 			.def  = E1000_DEFAULT_TXD,
292dee1ad47SJeff Kirsher 			.arg  = { .r = {
293dee1ad47SJeff Kirsher 				.min = E1000_MIN_TXD,
294dee1ad47SJeff Kirsher 				.max = mac_type < e1000_82544 ? E1000_MAX_TXD : E1000_MAX_82544_TXD
295dee1ad47SJeff Kirsher 				}}
296dee1ad47SJeff Kirsher 		};
297dee1ad47SJeff Kirsher 
298dee1ad47SJeff Kirsher 		if (num_TxDescriptors > bd) {
299dee1ad47SJeff Kirsher 			tx_ring->count = TxDescriptors[bd];
300dee1ad47SJeff Kirsher 			e1000_validate_option(&tx_ring->count, &opt, adapter);
301dee1ad47SJeff Kirsher 			tx_ring->count = ALIGN(tx_ring->count,
302dee1ad47SJeff Kirsher 						REQ_TX_DESCRIPTOR_MULTIPLE);
303dee1ad47SJeff Kirsher 		} else {
304dee1ad47SJeff Kirsher 			tx_ring->count = opt.def;
305dee1ad47SJeff Kirsher 		}
306dee1ad47SJeff Kirsher 		for (i = 0; i < adapter->num_tx_queues; i++)
307dee1ad47SJeff Kirsher 			tx_ring[i].count = tx_ring->count;
308dee1ad47SJeff Kirsher 	}
309dee1ad47SJeff Kirsher 	{ /* Receive Descriptor Count */
310dee1ad47SJeff Kirsher 		struct e1000_rx_ring *rx_ring = adapter->rx_ring;
311dee1ad47SJeff Kirsher 		int i;
312dee1ad47SJeff Kirsher 		e1000_mac_type mac_type = adapter->hw.mac_type;
313dee1ad47SJeff Kirsher 
314dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
315dee1ad47SJeff Kirsher 			.type = range_option,
316dee1ad47SJeff Kirsher 			.name = "Receive Descriptors",
317dee1ad47SJeff Kirsher 			.err  = "using default of "
318dee1ad47SJeff Kirsher 				__MODULE_STRING(E1000_DEFAULT_RXD),
319dee1ad47SJeff Kirsher 			.def  = E1000_DEFAULT_RXD,
320dee1ad47SJeff Kirsher 			.arg  = { .r = {
321dee1ad47SJeff Kirsher 				.min = E1000_MIN_RXD,
322dee1ad47SJeff Kirsher 				.max = mac_type < e1000_82544 ? E1000_MAX_RXD : E1000_MAX_82544_RXD
323dee1ad47SJeff Kirsher 			}}
324dee1ad47SJeff Kirsher 		};
325dee1ad47SJeff Kirsher 
326dee1ad47SJeff Kirsher 		if (num_RxDescriptors > bd) {
327dee1ad47SJeff Kirsher 			rx_ring->count = RxDescriptors[bd];
328dee1ad47SJeff Kirsher 			e1000_validate_option(&rx_ring->count, &opt, adapter);
329dee1ad47SJeff Kirsher 			rx_ring->count = ALIGN(rx_ring->count,
330dee1ad47SJeff Kirsher 						REQ_RX_DESCRIPTOR_MULTIPLE);
331dee1ad47SJeff Kirsher 		} else {
332dee1ad47SJeff Kirsher 			rx_ring->count = opt.def;
333dee1ad47SJeff Kirsher 		}
334dee1ad47SJeff Kirsher 		for (i = 0; i < adapter->num_rx_queues; i++)
335dee1ad47SJeff Kirsher 			rx_ring[i].count = rx_ring->count;
336dee1ad47SJeff Kirsher 	}
337dee1ad47SJeff Kirsher 	{ /* Checksum Offload Enable/Disable */
338dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
339dee1ad47SJeff Kirsher 			.type = enable_option,
340dee1ad47SJeff Kirsher 			.name = "Checksum Offload",
341dee1ad47SJeff Kirsher 			.err  = "defaulting to Enabled",
342dee1ad47SJeff Kirsher 			.def  = OPTION_ENABLED
343dee1ad47SJeff Kirsher 		};
344dee1ad47SJeff Kirsher 
345dee1ad47SJeff Kirsher 		if (num_XsumRX > bd) {
346dee1ad47SJeff Kirsher 			unsigned int rx_csum = XsumRX[bd];
347dee1ad47SJeff Kirsher 			e1000_validate_option(&rx_csum, &opt, adapter);
348dee1ad47SJeff Kirsher 			adapter->rx_csum = rx_csum;
349dee1ad47SJeff Kirsher 		} else {
350dee1ad47SJeff Kirsher 			adapter->rx_csum = opt.def;
351dee1ad47SJeff Kirsher 		}
352dee1ad47SJeff Kirsher 	}
353dee1ad47SJeff Kirsher 	{ /* Flow Control */
354dee1ad47SJeff Kirsher 
355dee1ad47SJeff Kirsher 		static const struct e1000_opt_list fc_list[] = {
356dee1ad47SJeff Kirsher 		       { E1000_FC_NONE, "Flow Control Disabled" },
357dee1ad47SJeff Kirsher 		       { E1000_FC_RX_PAUSE, "Flow Control Receive Only" },
358dee1ad47SJeff Kirsher 		       { E1000_FC_TX_PAUSE, "Flow Control Transmit Only" },
359dee1ad47SJeff Kirsher 		       { E1000_FC_FULL, "Flow Control Enabled" },
360dee1ad47SJeff Kirsher 		       { E1000_FC_DEFAULT, "Flow Control Hardware Default" }
361dee1ad47SJeff Kirsher 		};
362dee1ad47SJeff Kirsher 
363dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
364dee1ad47SJeff Kirsher 			.type = list_option,
365dee1ad47SJeff Kirsher 			.name = "Flow Control",
366dee1ad47SJeff Kirsher 			.err  = "reading default settings from EEPROM",
367dee1ad47SJeff Kirsher 			.def  = E1000_FC_DEFAULT,
368dee1ad47SJeff Kirsher 			.arg  = { .l = { .nr = ARRAY_SIZE(fc_list),
369dee1ad47SJeff Kirsher 					 .p = fc_list }}
370dee1ad47SJeff Kirsher 		};
371dee1ad47SJeff Kirsher 
372dee1ad47SJeff Kirsher 		if (num_FlowControl > bd) {
373dee1ad47SJeff Kirsher 			unsigned int fc = FlowControl[bd];
374dee1ad47SJeff Kirsher 			e1000_validate_option(&fc, &opt, adapter);
375dee1ad47SJeff Kirsher 			adapter->hw.fc = adapter->hw.original_fc = fc;
376dee1ad47SJeff Kirsher 		} else {
377dee1ad47SJeff Kirsher 			adapter->hw.fc = adapter->hw.original_fc = opt.def;
378dee1ad47SJeff Kirsher 		}
379dee1ad47SJeff Kirsher 	}
380dee1ad47SJeff Kirsher 	{ /* Transmit Interrupt Delay */
381dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
382dee1ad47SJeff Kirsher 			.type = range_option,
383dee1ad47SJeff Kirsher 			.name = "Transmit Interrupt Delay",
384dee1ad47SJeff Kirsher 			.err  = "using default of " __MODULE_STRING(DEFAULT_TIDV),
385dee1ad47SJeff Kirsher 			.def  = DEFAULT_TIDV,
386dee1ad47SJeff Kirsher 			.arg  = { .r = { .min = MIN_TXDELAY,
387dee1ad47SJeff Kirsher 					 .max = MAX_TXDELAY }}
388dee1ad47SJeff Kirsher 		};
389dee1ad47SJeff Kirsher 
390dee1ad47SJeff Kirsher 		if (num_TxIntDelay > bd) {
391dee1ad47SJeff Kirsher 			adapter->tx_int_delay = TxIntDelay[bd];
392dee1ad47SJeff Kirsher 			e1000_validate_option(&adapter->tx_int_delay, &opt,
393dee1ad47SJeff Kirsher 			                      adapter);
394dee1ad47SJeff Kirsher 		} else {
395dee1ad47SJeff Kirsher 			adapter->tx_int_delay = opt.def;
396dee1ad47SJeff Kirsher 		}
397dee1ad47SJeff Kirsher 	}
398dee1ad47SJeff Kirsher 	{ /* Transmit Absolute Interrupt Delay */
399dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
400dee1ad47SJeff Kirsher 			.type = range_option,
401dee1ad47SJeff Kirsher 			.name = "Transmit Absolute Interrupt Delay",
402dee1ad47SJeff Kirsher 			.err  = "using default of " __MODULE_STRING(DEFAULT_TADV),
403dee1ad47SJeff Kirsher 			.def  = DEFAULT_TADV,
404dee1ad47SJeff Kirsher 			.arg  = { .r = { .min = MIN_TXABSDELAY,
405dee1ad47SJeff Kirsher 					 .max = MAX_TXABSDELAY }}
406dee1ad47SJeff Kirsher 		};
407dee1ad47SJeff Kirsher 
408dee1ad47SJeff Kirsher 		if (num_TxAbsIntDelay > bd) {
409dee1ad47SJeff Kirsher 			adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
410dee1ad47SJeff Kirsher 			e1000_validate_option(&adapter->tx_abs_int_delay, &opt,
411dee1ad47SJeff Kirsher 			                      adapter);
412dee1ad47SJeff Kirsher 		} else {
413dee1ad47SJeff Kirsher 			adapter->tx_abs_int_delay = opt.def;
414dee1ad47SJeff Kirsher 		}
415dee1ad47SJeff Kirsher 	}
416dee1ad47SJeff Kirsher 	{ /* Receive Interrupt Delay */
417dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
418dee1ad47SJeff Kirsher 			.type = range_option,
419dee1ad47SJeff Kirsher 			.name = "Receive Interrupt Delay",
420dee1ad47SJeff Kirsher 			.err  = "using default of " __MODULE_STRING(DEFAULT_RDTR),
421dee1ad47SJeff Kirsher 			.def  = DEFAULT_RDTR,
422dee1ad47SJeff Kirsher 			.arg  = { .r = { .min = MIN_RXDELAY,
423dee1ad47SJeff Kirsher 					 .max = MAX_RXDELAY }}
424dee1ad47SJeff Kirsher 		};
425dee1ad47SJeff Kirsher 
426dee1ad47SJeff Kirsher 		if (num_RxIntDelay > bd) {
427dee1ad47SJeff Kirsher 			adapter->rx_int_delay = RxIntDelay[bd];
428dee1ad47SJeff Kirsher 			e1000_validate_option(&adapter->rx_int_delay, &opt,
429dee1ad47SJeff Kirsher 			                      adapter);
430dee1ad47SJeff Kirsher 		} else {
431dee1ad47SJeff Kirsher 			adapter->rx_int_delay = opt.def;
432dee1ad47SJeff Kirsher 		}
433dee1ad47SJeff Kirsher 	}
434dee1ad47SJeff Kirsher 	{ /* Receive Absolute Interrupt Delay */
435dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
436dee1ad47SJeff Kirsher 			.type = range_option,
437dee1ad47SJeff Kirsher 			.name = "Receive Absolute Interrupt Delay",
438dee1ad47SJeff Kirsher 			.err  = "using default of " __MODULE_STRING(DEFAULT_RADV),
439dee1ad47SJeff Kirsher 			.def  = DEFAULT_RADV,
440dee1ad47SJeff Kirsher 			.arg  = { .r = { .min = MIN_RXABSDELAY,
441dee1ad47SJeff Kirsher 					 .max = MAX_RXABSDELAY }}
442dee1ad47SJeff Kirsher 		};
443dee1ad47SJeff Kirsher 
444dee1ad47SJeff Kirsher 		if (num_RxAbsIntDelay > bd) {
445dee1ad47SJeff Kirsher 			adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
446dee1ad47SJeff Kirsher 			e1000_validate_option(&adapter->rx_abs_int_delay, &opt,
447dee1ad47SJeff Kirsher 			                      adapter);
448dee1ad47SJeff Kirsher 		} else {
449dee1ad47SJeff Kirsher 			adapter->rx_abs_int_delay = opt.def;
450dee1ad47SJeff Kirsher 		}
451dee1ad47SJeff Kirsher 	}
452dee1ad47SJeff Kirsher 	{ /* Interrupt Throttling Rate */
453dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
454dee1ad47SJeff Kirsher 			.type = range_option,
455dee1ad47SJeff Kirsher 			.name = "Interrupt Throttling Rate (ints/sec)",
456dee1ad47SJeff Kirsher 			.err  = "using default of " __MODULE_STRING(DEFAULT_ITR),
457dee1ad47SJeff Kirsher 			.def  = DEFAULT_ITR,
458dee1ad47SJeff Kirsher 			.arg  = { .r = { .min = MIN_ITR,
459dee1ad47SJeff Kirsher 					 .max = MAX_ITR }}
460dee1ad47SJeff Kirsher 		};
461dee1ad47SJeff Kirsher 
462dee1ad47SJeff Kirsher 		if (num_InterruptThrottleRate > bd) {
463dee1ad47SJeff Kirsher 			adapter->itr = InterruptThrottleRate[bd];
464dee1ad47SJeff Kirsher 			switch (adapter->itr) {
465dee1ad47SJeff Kirsher 			case 0:
466dee1ad47SJeff Kirsher 				e_dev_info("%s turned off\n", opt.name);
467dee1ad47SJeff Kirsher 				break;
468dee1ad47SJeff Kirsher 			case 1:
469dee1ad47SJeff Kirsher 				e_dev_info("%s set to dynamic mode\n",
470dee1ad47SJeff Kirsher 					   opt.name);
471dee1ad47SJeff Kirsher 				adapter->itr_setting = adapter->itr;
472dee1ad47SJeff Kirsher 				adapter->itr = 20000;
473dee1ad47SJeff Kirsher 				break;
474dee1ad47SJeff Kirsher 			case 3:
475dee1ad47SJeff Kirsher 				e_dev_info("%s set to dynamic conservative "
476dee1ad47SJeff Kirsher 					   "mode\n", opt.name);
477dee1ad47SJeff Kirsher 				adapter->itr_setting = adapter->itr;
478dee1ad47SJeff Kirsher 				adapter->itr = 20000;
479dee1ad47SJeff Kirsher 				break;
480dee1ad47SJeff Kirsher 			case 4:
481dee1ad47SJeff Kirsher 				e_dev_info("%s set to simplified "
482dee1ad47SJeff Kirsher 				           "(2000-8000) ints mode\n", opt.name);
483dee1ad47SJeff Kirsher 				adapter->itr_setting = adapter->itr;
484dee1ad47SJeff Kirsher 				break;
485dee1ad47SJeff Kirsher 			default:
486dee1ad47SJeff Kirsher 				e1000_validate_option(&adapter->itr, &opt,
487dee1ad47SJeff Kirsher 				        adapter);
488dee1ad47SJeff Kirsher 				/* save the setting, because the dynamic bits
489dee1ad47SJeff Kirsher 				 * change itr.
490dee1ad47SJeff Kirsher 				 * clear the lower two bits because they are
491dee1ad47SJeff Kirsher 				 * used as control */
492dee1ad47SJeff Kirsher 				adapter->itr_setting = adapter->itr & ~3;
493dee1ad47SJeff Kirsher 				break;
494dee1ad47SJeff Kirsher 			}
495dee1ad47SJeff Kirsher 		} else {
496dee1ad47SJeff Kirsher 			adapter->itr_setting = opt.def;
497dee1ad47SJeff Kirsher 			adapter->itr = 20000;
498dee1ad47SJeff Kirsher 		}
499dee1ad47SJeff Kirsher 	}
500dee1ad47SJeff Kirsher 	{ /* Smart Power Down */
501dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
502dee1ad47SJeff Kirsher 			.type = enable_option,
503dee1ad47SJeff Kirsher 			.name = "PHY Smart Power Down",
504dee1ad47SJeff Kirsher 			.err  = "defaulting to Disabled",
505dee1ad47SJeff Kirsher 			.def  = OPTION_DISABLED
506dee1ad47SJeff Kirsher 		};
507dee1ad47SJeff Kirsher 
508dee1ad47SJeff Kirsher 		if (num_SmartPowerDownEnable > bd) {
509dee1ad47SJeff Kirsher 			unsigned int spd = SmartPowerDownEnable[bd];
510dee1ad47SJeff Kirsher 			e1000_validate_option(&spd, &opt, adapter);
511dee1ad47SJeff Kirsher 			adapter->smart_power_down = spd;
512dee1ad47SJeff Kirsher 		} else {
513dee1ad47SJeff Kirsher 			adapter->smart_power_down = opt.def;
514dee1ad47SJeff Kirsher 		}
515dee1ad47SJeff Kirsher 	}
516dee1ad47SJeff Kirsher 
517dee1ad47SJeff Kirsher 	switch (adapter->hw.media_type) {
518dee1ad47SJeff Kirsher 	case e1000_media_type_fiber:
519dee1ad47SJeff Kirsher 	case e1000_media_type_internal_serdes:
520dee1ad47SJeff Kirsher 		e1000_check_fiber_options(adapter);
521dee1ad47SJeff Kirsher 		break;
522dee1ad47SJeff Kirsher 	case e1000_media_type_copper:
523dee1ad47SJeff Kirsher 		e1000_check_copper_options(adapter);
524dee1ad47SJeff Kirsher 		break;
525dee1ad47SJeff Kirsher 	default:
526dee1ad47SJeff Kirsher 		BUG();
527dee1ad47SJeff Kirsher 	}
528dee1ad47SJeff Kirsher }
529dee1ad47SJeff Kirsher 
530dee1ad47SJeff Kirsher /**
531dee1ad47SJeff Kirsher  * e1000_check_fiber_options - Range Checking for Link Options, Fiber Version
532dee1ad47SJeff Kirsher  * @adapter: board private structure
533dee1ad47SJeff Kirsher  *
534dee1ad47SJeff Kirsher  * Handles speed and duplex options on fiber adapters
535dee1ad47SJeff Kirsher  **/
536dee1ad47SJeff Kirsher 
537dee1ad47SJeff Kirsher static void __devinit e1000_check_fiber_options(struct e1000_adapter *adapter)
538dee1ad47SJeff Kirsher {
539dee1ad47SJeff Kirsher 	int bd = adapter->bd_number;
540dee1ad47SJeff Kirsher 	if (num_Speed > bd) {
541dee1ad47SJeff Kirsher 		e_dev_info("Speed not valid for fiber adapters, parameter "
542dee1ad47SJeff Kirsher 			   "ignored\n");
543dee1ad47SJeff Kirsher 	}
544dee1ad47SJeff Kirsher 
545dee1ad47SJeff Kirsher 	if (num_Duplex > bd) {
546dee1ad47SJeff Kirsher 		e_dev_info("Duplex not valid for fiber adapters, parameter "
547dee1ad47SJeff Kirsher 			   "ignored\n");
548dee1ad47SJeff Kirsher 	}
549dee1ad47SJeff Kirsher 
550dee1ad47SJeff Kirsher 	if ((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) {
551dee1ad47SJeff Kirsher 		e_dev_info("AutoNeg other than 1000/Full is not valid for fiber"
552dee1ad47SJeff Kirsher 			   "adapters, parameter ignored\n");
553dee1ad47SJeff Kirsher 	}
554dee1ad47SJeff Kirsher }
555dee1ad47SJeff Kirsher 
556dee1ad47SJeff Kirsher /**
557dee1ad47SJeff Kirsher  * e1000_check_copper_options - Range Checking for Link Options, Copper Version
558dee1ad47SJeff Kirsher  * @adapter: board private structure
559dee1ad47SJeff Kirsher  *
560dee1ad47SJeff Kirsher  * Handles speed and duplex options on copper adapters
561dee1ad47SJeff Kirsher  **/
562dee1ad47SJeff Kirsher 
563dee1ad47SJeff Kirsher static void __devinit e1000_check_copper_options(struct e1000_adapter *adapter)
564dee1ad47SJeff Kirsher {
565dee1ad47SJeff Kirsher 	struct e1000_option opt;
566dee1ad47SJeff Kirsher 	unsigned int speed, dplx, an;
567dee1ad47SJeff Kirsher 	int bd = adapter->bd_number;
568dee1ad47SJeff Kirsher 
569dee1ad47SJeff Kirsher 	{ /* Speed */
570dee1ad47SJeff Kirsher 		static const struct e1000_opt_list speed_list[] = {
571dee1ad47SJeff Kirsher 			{          0, "" },
572dee1ad47SJeff Kirsher 			{   SPEED_10, "" },
573dee1ad47SJeff Kirsher 			{  SPEED_100, "" },
574dee1ad47SJeff Kirsher 			{ SPEED_1000, "" }};
575dee1ad47SJeff Kirsher 
576dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
577dee1ad47SJeff Kirsher 			.type = list_option,
578dee1ad47SJeff Kirsher 			.name = "Speed",
579dee1ad47SJeff Kirsher 			.err  = "parameter ignored",
580dee1ad47SJeff Kirsher 			.def  = 0,
581dee1ad47SJeff Kirsher 			.arg  = { .l = { .nr = ARRAY_SIZE(speed_list),
582dee1ad47SJeff Kirsher 					 .p = speed_list }}
583dee1ad47SJeff Kirsher 		};
584dee1ad47SJeff Kirsher 
585dee1ad47SJeff Kirsher 		if (num_Speed > bd) {
586dee1ad47SJeff Kirsher 			speed = Speed[bd];
587dee1ad47SJeff Kirsher 			e1000_validate_option(&speed, &opt, adapter);
588dee1ad47SJeff Kirsher 		} else {
589dee1ad47SJeff Kirsher 			speed = opt.def;
590dee1ad47SJeff Kirsher 		}
591dee1ad47SJeff Kirsher 	}
592dee1ad47SJeff Kirsher 	{ /* Duplex */
593dee1ad47SJeff Kirsher 		static const struct e1000_opt_list dplx_list[] = {
594dee1ad47SJeff Kirsher 			{           0, "" },
595dee1ad47SJeff Kirsher 			{ HALF_DUPLEX, "" },
596dee1ad47SJeff Kirsher 			{ FULL_DUPLEX, "" }};
597dee1ad47SJeff Kirsher 
598dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
599dee1ad47SJeff Kirsher 			.type = list_option,
600dee1ad47SJeff Kirsher 			.name = "Duplex",
601dee1ad47SJeff Kirsher 			.err  = "parameter ignored",
602dee1ad47SJeff Kirsher 			.def  = 0,
603dee1ad47SJeff Kirsher 			.arg  = { .l = { .nr = ARRAY_SIZE(dplx_list),
604dee1ad47SJeff Kirsher 					 .p = dplx_list }}
605dee1ad47SJeff Kirsher 		};
606dee1ad47SJeff Kirsher 
607dee1ad47SJeff Kirsher 		if (num_Duplex > bd) {
608dee1ad47SJeff Kirsher 			dplx = Duplex[bd];
609dee1ad47SJeff Kirsher 			e1000_validate_option(&dplx, &opt, adapter);
610dee1ad47SJeff Kirsher 		} else {
611dee1ad47SJeff Kirsher 			dplx = opt.def;
612dee1ad47SJeff Kirsher 		}
613dee1ad47SJeff Kirsher 	}
614dee1ad47SJeff Kirsher 
615dee1ad47SJeff Kirsher 	if ((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) {
616dee1ad47SJeff Kirsher 		e_dev_info("AutoNeg specified along with Speed or Duplex, "
617dee1ad47SJeff Kirsher 			   "parameter ignored\n");
618dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT;
619dee1ad47SJeff Kirsher 	} else { /* Autoneg */
620dee1ad47SJeff Kirsher 		static const struct e1000_opt_list an_list[] =
621dee1ad47SJeff Kirsher 			#define AA "AutoNeg advertising "
622dee1ad47SJeff Kirsher 			{{ 0x01, AA "10/HD" },
623dee1ad47SJeff Kirsher 			 { 0x02, AA "10/FD" },
624dee1ad47SJeff Kirsher 			 { 0x03, AA "10/FD, 10/HD" },
625dee1ad47SJeff Kirsher 			 { 0x04, AA "100/HD" },
626dee1ad47SJeff Kirsher 			 { 0x05, AA "100/HD, 10/HD" },
627dee1ad47SJeff Kirsher 			 { 0x06, AA "100/HD, 10/FD" },
628dee1ad47SJeff Kirsher 			 { 0x07, AA "100/HD, 10/FD, 10/HD" },
629dee1ad47SJeff Kirsher 			 { 0x08, AA "100/FD" },
630dee1ad47SJeff Kirsher 			 { 0x09, AA "100/FD, 10/HD" },
631dee1ad47SJeff Kirsher 			 { 0x0a, AA "100/FD, 10/FD" },
632dee1ad47SJeff Kirsher 			 { 0x0b, AA "100/FD, 10/FD, 10/HD" },
633dee1ad47SJeff Kirsher 			 { 0x0c, AA "100/FD, 100/HD" },
634dee1ad47SJeff Kirsher 			 { 0x0d, AA "100/FD, 100/HD, 10/HD" },
635dee1ad47SJeff Kirsher 			 { 0x0e, AA "100/FD, 100/HD, 10/FD" },
636dee1ad47SJeff Kirsher 			 { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" },
637dee1ad47SJeff Kirsher 			 { 0x20, AA "1000/FD" },
638dee1ad47SJeff Kirsher 			 { 0x21, AA "1000/FD, 10/HD" },
639dee1ad47SJeff Kirsher 			 { 0x22, AA "1000/FD, 10/FD" },
640dee1ad47SJeff Kirsher 			 { 0x23, AA "1000/FD, 10/FD, 10/HD" },
641dee1ad47SJeff Kirsher 			 { 0x24, AA "1000/FD, 100/HD" },
642dee1ad47SJeff Kirsher 			 { 0x25, AA "1000/FD, 100/HD, 10/HD" },
643dee1ad47SJeff Kirsher 			 { 0x26, AA "1000/FD, 100/HD, 10/FD" },
644dee1ad47SJeff Kirsher 			 { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" },
645dee1ad47SJeff Kirsher 			 { 0x28, AA "1000/FD, 100/FD" },
646dee1ad47SJeff Kirsher 			 { 0x29, AA "1000/FD, 100/FD, 10/HD" },
647dee1ad47SJeff Kirsher 			 { 0x2a, AA "1000/FD, 100/FD, 10/FD" },
648dee1ad47SJeff Kirsher 			 { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" },
649dee1ad47SJeff Kirsher 			 { 0x2c, AA "1000/FD, 100/FD, 100/HD" },
650dee1ad47SJeff Kirsher 			 { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" },
651dee1ad47SJeff Kirsher 			 { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" },
652dee1ad47SJeff Kirsher 			 { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }};
653dee1ad47SJeff Kirsher 
654dee1ad47SJeff Kirsher 		opt = (struct e1000_option) {
655dee1ad47SJeff Kirsher 			.type = list_option,
656dee1ad47SJeff Kirsher 			.name = "AutoNeg",
657dee1ad47SJeff Kirsher 			.err  = "parameter ignored",
658dee1ad47SJeff Kirsher 			.def  = AUTONEG_ADV_DEFAULT,
659dee1ad47SJeff Kirsher 			.arg  = { .l = { .nr = ARRAY_SIZE(an_list),
660dee1ad47SJeff Kirsher 					 .p = an_list }}
661dee1ad47SJeff Kirsher 		};
662dee1ad47SJeff Kirsher 
663dee1ad47SJeff Kirsher 		if (num_AutoNeg > bd) {
664dee1ad47SJeff Kirsher 			an = AutoNeg[bd];
665dee1ad47SJeff Kirsher 			e1000_validate_option(&an, &opt, adapter);
666dee1ad47SJeff Kirsher 		} else {
667dee1ad47SJeff Kirsher 			an = opt.def;
668dee1ad47SJeff Kirsher 		}
669dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = an;
670dee1ad47SJeff Kirsher 	}
671dee1ad47SJeff Kirsher 
672dee1ad47SJeff Kirsher 	switch (speed + dplx) {
673dee1ad47SJeff Kirsher 	case 0:
674dee1ad47SJeff Kirsher 		adapter->hw.autoneg = adapter->fc_autoneg = 1;
675dee1ad47SJeff Kirsher 		if ((num_Speed > bd) && (speed != 0 || dplx != 0))
676dee1ad47SJeff Kirsher 			e_dev_info("Speed and duplex autonegotiation "
677dee1ad47SJeff Kirsher 				   "enabled\n");
678dee1ad47SJeff Kirsher 		break;
679dee1ad47SJeff Kirsher 	case HALF_DUPLEX:
680dee1ad47SJeff Kirsher 		e_dev_info("Half Duplex specified without Speed\n");
681dee1ad47SJeff Kirsher 		e_dev_info("Using Autonegotiation at Half Duplex only\n");
682dee1ad47SJeff Kirsher 		adapter->hw.autoneg = adapter->fc_autoneg = 1;
683dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
684dee1ad47SJeff Kirsher 		                                 ADVERTISE_100_HALF;
685dee1ad47SJeff Kirsher 		break;
686dee1ad47SJeff Kirsher 	case FULL_DUPLEX:
687dee1ad47SJeff Kirsher 		e_dev_info("Full Duplex specified without Speed\n");
688dee1ad47SJeff Kirsher 		e_dev_info("Using Autonegotiation at Full Duplex only\n");
689dee1ad47SJeff Kirsher 		adapter->hw.autoneg = adapter->fc_autoneg = 1;
690dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = ADVERTISE_10_FULL |
691dee1ad47SJeff Kirsher 		                                 ADVERTISE_100_FULL |
692dee1ad47SJeff Kirsher 		                                 ADVERTISE_1000_FULL;
693dee1ad47SJeff Kirsher 		break;
694dee1ad47SJeff Kirsher 	case SPEED_10:
695dee1ad47SJeff Kirsher 		e_dev_info("10 Mbps Speed specified without Duplex\n");
696dee1ad47SJeff Kirsher 		e_dev_info("Using Autonegotiation at 10 Mbps only\n");
697dee1ad47SJeff Kirsher 		adapter->hw.autoneg = adapter->fc_autoneg = 1;
698dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
699dee1ad47SJeff Kirsher 		                                 ADVERTISE_10_FULL;
700dee1ad47SJeff Kirsher 		break;
701dee1ad47SJeff Kirsher 	case SPEED_10 + HALF_DUPLEX:
702dee1ad47SJeff Kirsher 		e_dev_info("Forcing to 10 Mbps Half Duplex\n");
703dee1ad47SJeff Kirsher 		adapter->hw.autoneg = adapter->fc_autoneg = 0;
704dee1ad47SJeff Kirsher 		adapter->hw.forced_speed_duplex = e1000_10_half;
705dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = 0;
706dee1ad47SJeff Kirsher 		break;
707dee1ad47SJeff Kirsher 	case SPEED_10 + FULL_DUPLEX:
708dee1ad47SJeff Kirsher 		e_dev_info("Forcing to 10 Mbps Full Duplex\n");
709dee1ad47SJeff Kirsher 		adapter->hw.autoneg = adapter->fc_autoneg = 0;
710dee1ad47SJeff Kirsher 		adapter->hw.forced_speed_duplex = e1000_10_full;
711dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = 0;
712dee1ad47SJeff Kirsher 		break;
713dee1ad47SJeff Kirsher 	case SPEED_100:
714dee1ad47SJeff Kirsher 		e_dev_info("100 Mbps Speed specified without Duplex\n");
715dee1ad47SJeff Kirsher 		e_dev_info("Using Autonegotiation at 100 Mbps only\n");
716dee1ad47SJeff Kirsher 		adapter->hw.autoneg = adapter->fc_autoneg = 1;
717dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = ADVERTISE_100_HALF |
718dee1ad47SJeff Kirsher 		                                 ADVERTISE_100_FULL;
719dee1ad47SJeff Kirsher 		break;
720dee1ad47SJeff Kirsher 	case SPEED_100 + HALF_DUPLEX:
721dee1ad47SJeff Kirsher 		e_dev_info("Forcing to 100 Mbps Half Duplex\n");
722dee1ad47SJeff Kirsher 		adapter->hw.autoneg = adapter->fc_autoneg = 0;
723dee1ad47SJeff Kirsher 		adapter->hw.forced_speed_duplex = e1000_100_half;
724dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = 0;
725dee1ad47SJeff Kirsher 		break;
726dee1ad47SJeff Kirsher 	case SPEED_100 + FULL_DUPLEX:
727dee1ad47SJeff Kirsher 		e_dev_info("Forcing to 100 Mbps Full Duplex\n");
728dee1ad47SJeff Kirsher 		adapter->hw.autoneg = adapter->fc_autoneg = 0;
729dee1ad47SJeff Kirsher 		adapter->hw.forced_speed_duplex = e1000_100_full;
730dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = 0;
731dee1ad47SJeff Kirsher 		break;
732dee1ad47SJeff Kirsher 	case SPEED_1000:
733dee1ad47SJeff Kirsher 		e_dev_info("1000 Mbps Speed specified without Duplex\n");
734dee1ad47SJeff Kirsher 		goto full_duplex_only;
735dee1ad47SJeff Kirsher 	case SPEED_1000 + HALF_DUPLEX:
736dee1ad47SJeff Kirsher 		e_dev_info("Half Duplex is not supported at 1000 Mbps\n");
737dee1ad47SJeff Kirsher 		/* fall through */
738dee1ad47SJeff Kirsher 	case SPEED_1000 + FULL_DUPLEX:
739dee1ad47SJeff Kirsher full_duplex_only:
740dee1ad47SJeff Kirsher 		e_dev_info("Using Autonegotiation at 1000 Mbps Full Duplex "
741dee1ad47SJeff Kirsher 			   "only\n");
742dee1ad47SJeff Kirsher 		adapter->hw.autoneg = adapter->fc_autoneg = 1;
743dee1ad47SJeff Kirsher 		adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
744dee1ad47SJeff Kirsher 		break;
745dee1ad47SJeff Kirsher 	default:
746dee1ad47SJeff Kirsher 		BUG();
747dee1ad47SJeff Kirsher 	}
748dee1ad47SJeff Kirsher 
749dee1ad47SJeff Kirsher 	/* Speed, AutoNeg and MDI/MDI-X must all play nice */
750dee1ad47SJeff Kirsher 	if (e1000_validate_mdi_setting(&(adapter->hw)) < 0) {
751dee1ad47SJeff Kirsher 		e_dev_info("Speed, AutoNeg and MDI-X specs are incompatible. "
752dee1ad47SJeff Kirsher 			   "Setting MDI-X to a compatible value.\n");
753dee1ad47SJeff Kirsher 	}
754dee1ad47SJeff Kirsher }
755dee1ad47SJeff Kirsher 
756