1ae06c70bSJeff Kirsher // SPDX-License-Identifier: GPL-2.0
251dce24bSJeff Kirsher /* Copyright(c) 1999 - 2018 Intel Corporation. */
3dee1ad47SJeff Kirsher 
4dee1ad47SJeff Kirsher #include <linux/netdevice.h>
59d9779e7SPaul Gortmaker #include <linux/module.h>
6dee1ad47SJeff Kirsher #include <linux/pci.h>
7dee1ad47SJeff Kirsher 
8dee1ad47SJeff Kirsher #include "e1000.h"
9dee1ad47SJeff Kirsher 
10e921eb1aSBruce Allan /* This is the only thing that needs to be changed to adjust the
11dee1ad47SJeff Kirsher  * maximum number of ports that the driver can manage.
12dee1ad47SJeff Kirsher  */
13dee1ad47SJeff Kirsher #define E1000_MAX_NIC 32
14dee1ad47SJeff Kirsher 
15dee1ad47SJeff Kirsher #define OPTION_UNSET   -1
16dee1ad47SJeff Kirsher #define OPTION_DISABLED 0
17dee1ad47SJeff Kirsher #define OPTION_ENABLED  1
18dee1ad47SJeff Kirsher 
19dee1ad47SJeff Kirsher #define COPYBREAK_DEFAULT 256
20dee1ad47SJeff Kirsher unsigned int copybreak = COPYBREAK_DEFAULT;
21dee1ad47SJeff Kirsher module_param(copybreak, uint, 0644);
22dee1ad47SJeff Kirsher MODULE_PARM_DESC(copybreak,
23dee1ad47SJeff Kirsher 		 "Maximum size of packet that is copied to a new buffer on receive");
24dee1ad47SJeff Kirsher 
25e921eb1aSBruce Allan /* All parameters are treated the same, as an integer array of values.
26dee1ad47SJeff Kirsher  * This macro just reduces the need to repeat the same declaration code
27dee1ad47SJeff Kirsher  * over and over (plus this helps to avoid typo bugs).
28dee1ad47SJeff Kirsher  */
29dee1ad47SJeff Kirsher #define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
30dee1ad47SJeff Kirsher #define E1000_PARAM(X, desc)					\
3155c5f55eSBruce Allan 	static int X[E1000_MAX_NIC+1] = E1000_PARAM_INIT;	\
32dee1ad47SJeff Kirsher 	static unsigned int num_##X;				\
33dee1ad47SJeff Kirsher 	module_param_array_named(X, X, int, &num_##X, 0);	\
34dee1ad47SJeff Kirsher 	MODULE_PARM_DESC(X, desc);
35dee1ad47SJeff Kirsher 
36e921eb1aSBruce Allan /* Transmit Interrupt Delay in units of 1.024 microseconds
37dee1ad47SJeff Kirsher  * Tx interrupt delay needs to typically be set to something non-zero
38dee1ad47SJeff Kirsher  *
39dee1ad47SJeff Kirsher  * Valid Range: 0-65535
40dee1ad47SJeff Kirsher  */
41dee1ad47SJeff Kirsher E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay");
42dee1ad47SJeff Kirsher #define DEFAULT_TIDV 8
43dee1ad47SJeff Kirsher #define MAX_TXDELAY 0xFFFF
44dee1ad47SJeff Kirsher #define MIN_TXDELAY 0
45dee1ad47SJeff Kirsher 
46e921eb1aSBruce Allan /* Transmit Absolute Interrupt Delay in units of 1.024 microseconds
47dee1ad47SJeff Kirsher  *
48dee1ad47SJeff Kirsher  * Valid Range: 0-65535
49dee1ad47SJeff Kirsher  */
50dee1ad47SJeff Kirsher E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
51dee1ad47SJeff Kirsher #define DEFAULT_TADV 32
52dee1ad47SJeff Kirsher #define MAX_TXABSDELAY 0xFFFF
53dee1ad47SJeff Kirsher #define MIN_TXABSDELAY 0
54dee1ad47SJeff Kirsher 
55e921eb1aSBruce Allan /* Receive Interrupt Delay in units of 1.024 microseconds
56dee1ad47SJeff Kirsher  * hardware will likely hang if you set this to anything but zero.
57dee1ad47SJeff Kirsher  *
5848072ae1SWillem de Bruijn  * Burst variant is used as default if device has FLAG2_DMA_BURST.
5948072ae1SWillem de Bruijn  *
60dee1ad47SJeff Kirsher  * Valid Range: 0-65535
61dee1ad47SJeff Kirsher  */
62dee1ad47SJeff Kirsher E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
6348072ae1SWillem de Bruijn #define DEFAULT_RDTR	0
6448072ae1SWillem de Bruijn #define BURST_RDTR	0x20
65dee1ad47SJeff Kirsher #define MAX_RXDELAY 0xFFFF
66dee1ad47SJeff Kirsher #define MIN_RXDELAY 0
67dee1ad47SJeff Kirsher 
68e921eb1aSBruce Allan /* Receive Absolute Interrupt Delay in units of 1.024 microseconds
69dee1ad47SJeff Kirsher  *
7048072ae1SWillem de Bruijn  * Burst variant is used as default if device has FLAG2_DMA_BURST.
7148072ae1SWillem de Bruijn  *
72dee1ad47SJeff Kirsher  * Valid Range: 0-65535
73dee1ad47SJeff Kirsher  */
74dee1ad47SJeff Kirsher E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
7548072ae1SWillem de Bruijn #define DEFAULT_RADV	8
7648072ae1SWillem de Bruijn #define BURST_RADV	0x20
77dee1ad47SJeff Kirsher #define MAX_RXABSDELAY 0xFFFF
78dee1ad47SJeff Kirsher #define MIN_RXABSDELAY 0
79dee1ad47SJeff Kirsher 
80e921eb1aSBruce Allan /* Interrupt Throttle Rate (interrupts/sec)
81dee1ad47SJeff Kirsher  *
82727c356fSJeff Kirsher  * Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative
83dee1ad47SJeff Kirsher  */
84dee1ad47SJeff Kirsher E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
85dee1ad47SJeff Kirsher #define DEFAULT_ITR 3
86dee1ad47SJeff Kirsher #define MAX_ITR 100000
87dee1ad47SJeff Kirsher #define MIN_ITR 100
88dee1ad47SJeff Kirsher 
89e921eb1aSBruce Allan /* IntMode (Interrupt Mode)
90dee1ad47SJeff Kirsher  *
91b6fbca2aSBruce Allan  * Valid Range: varies depending on kernel configuration & hardware support
92dee1ad47SJeff Kirsher  *
93b6fbca2aSBruce Allan  * legacy=0, MSI=1, MSI-X=2
94b6fbca2aSBruce Allan  *
95b6fbca2aSBruce Allan  * When MSI/MSI-X support is enabled in kernel-
96b6fbca2aSBruce Allan  *   Default Value: 2 (MSI-X) when supported by hardware, 1 (MSI) otherwise
97b6fbca2aSBruce Allan  * When MSI/MSI-X support is not enabled in kernel-
98b6fbca2aSBruce Allan  *   Default Value: 0 (legacy)
99b6fbca2aSBruce Allan  *
100b6fbca2aSBruce Allan  * When a mode is specified that is not allowed/supported, it will be
101b6fbca2aSBruce Allan  * demoted to the most advanced interrupt mode available.
102dee1ad47SJeff Kirsher  */
103dee1ad47SJeff Kirsher E1000_PARAM(IntMode, "Interrupt Mode");
104dee1ad47SJeff Kirsher 
105e921eb1aSBruce Allan /* Enable Smart Power Down of the PHY
106dee1ad47SJeff Kirsher  *
107dee1ad47SJeff Kirsher  * Valid Range: 0, 1
108dee1ad47SJeff Kirsher  *
109dee1ad47SJeff Kirsher  * Default Value: 0 (disabled)
110dee1ad47SJeff Kirsher  */
111dee1ad47SJeff Kirsher E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
112dee1ad47SJeff Kirsher 
113e921eb1aSBruce Allan /* Enable Kumeran Lock Loss workaround
114dee1ad47SJeff Kirsher  *
115dee1ad47SJeff Kirsher  * Valid Range: 0, 1
116dee1ad47SJeff Kirsher  *
117dee1ad47SJeff Kirsher  * Default Value: 1 (enabled)
118dee1ad47SJeff Kirsher  */
119dee1ad47SJeff Kirsher E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");
120dee1ad47SJeff Kirsher 
121e921eb1aSBruce Allan /* Write Protect NVM
122dee1ad47SJeff Kirsher  *
123dee1ad47SJeff Kirsher  * Valid Range: 0, 1
124dee1ad47SJeff Kirsher  *
125dee1ad47SJeff Kirsher  * Default Value: 1 (enabled)
126dee1ad47SJeff Kirsher  */
127c29c3ba5SBruce Allan E1000_PARAM(WriteProtectNVM,
128c29c3ba5SBruce Allan 	    "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]");
129dee1ad47SJeff Kirsher 
130e921eb1aSBruce Allan /* Enable CRC Stripping
131dee1ad47SJeff Kirsher  *
132dee1ad47SJeff Kirsher  * Valid Range: 0, 1
133dee1ad47SJeff Kirsher  *
134dee1ad47SJeff Kirsher  * Default Value: 1 (enabled)
135dee1ad47SJeff Kirsher  */
1366ad65145SBruce Allan E1000_PARAM(CrcStripping,
1376ad65145SBruce Allan 	    "Enable CRC Stripping, disable if your BMC needs the CRC");
138dee1ad47SJeff Kirsher 
139dee1ad47SJeff Kirsher struct e1000_option {
140dee1ad47SJeff Kirsher 	enum { enable_option, range_option, list_option } type;
141dee1ad47SJeff Kirsher 	const char *name;
142dee1ad47SJeff Kirsher 	const char *err;
143dee1ad47SJeff Kirsher 	int def;
144dee1ad47SJeff Kirsher 	union {
14533550cecSBruce Allan 		/* range_option info */
14633550cecSBruce Allan 		struct {
147dee1ad47SJeff Kirsher 			int min;
148dee1ad47SJeff Kirsher 			int max;
149dee1ad47SJeff Kirsher 		} r;
15033550cecSBruce Allan 		/* list_option info */
15133550cecSBruce Allan 		struct {
152dee1ad47SJeff Kirsher 			int nr;
153bbf44127SBruce Allan 			struct e1000_opt_list {
154bbf44127SBruce Allan 				int i;
155bbf44127SBruce Allan 				char *str;
156bbf44127SBruce Allan 			} *p;
157dee1ad47SJeff Kirsher 		} l;
158dee1ad47SJeff Kirsher 	} arg;
159dee1ad47SJeff Kirsher };
160dee1ad47SJeff Kirsher 
e1000_validate_option(unsigned int * value,const struct e1000_option * opt,struct e1000_adapter * adapter)1619f9a12f8SBill Pemberton static int e1000_validate_option(unsigned int *value,
162dee1ad47SJeff Kirsher 				 const struct e1000_option *opt,
163dee1ad47SJeff Kirsher 				 struct e1000_adapter *adapter)
164dee1ad47SJeff Kirsher {
165dee1ad47SJeff Kirsher 	if (*value == OPTION_UNSET) {
166dee1ad47SJeff Kirsher 		*value = opt->def;
167dee1ad47SJeff Kirsher 		return 0;
168dee1ad47SJeff Kirsher 	}
169dee1ad47SJeff Kirsher 
170dee1ad47SJeff Kirsher 	switch (opt->type) {
171dee1ad47SJeff Kirsher 	case enable_option:
172dee1ad47SJeff Kirsher 		switch (*value) {
173dee1ad47SJeff Kirsher 		case OPTION_ENABLED:
174185095fbSBruce Allan 			dev_info(&adapter->pdev->dev, "%s Enabled\n",
175185095fbSBruce Allan 				 opt->name);
176dee1ad47SJeff Kirsher 			return 0;
177dee1ad47SJeff Kirsher 		case OPTION_DISABLED:
178185095fbSBruce Allan 			dev_info(&adapter->pdev->dev, "%s Disabled\n",
179185095fbSBruce Allan 				 opt->name);
180dee1ad47SJeff Kirsher 			return 0;
181dee1ad47SJeff Kirsher 		}
182dee1ad47SJeff Kirsher 		break;
183dee1ad47SJeff Kirsher 	case range_option:
184dee1ad47SJeff Kirsher 		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
185185095fbSBruce Allan 			dev_info(&adapter->pdev->dev, "%s set to %i\n",
186185095fbSBruce Allan 				 opt->name, *value);
187dee1ad47SJeff Kirsher 			return 0;
188dee1ad47SJeff Kirsher 		}
189dee1ad47SJeff Kirsher 		break;
190dee1ad47SJeff Kirsher 	case list_option: {
191dee1ad47SJeff Kirsher 		int i;
192dee1ad47SJeff Kirsher 		struct e1000_opt_list *ent;
193dee1ad47SJeff Kirsher 
194dee1ad47SJeff Kirsher 		for (i = 0; i < opt->arg.l.nr; i++) {
195dee1ad47SJeff Kirsher 			ent = &opt->arg.l.p[i];
196dee1ad47SJeff Kirsher 			if (*value == ent->i) {
197dee1ad47SJeff Kirsher 				if (ent->str[0] != '\0')
198185095fbSBruce Allan 					dev_info(&adapter->pdev->dev, "%s\n",
199185095fbSBruce Allan 						 ent->str);
200dee1ad47SJeff Kirsher 				return 0;
201dee1ad47SJeff Kirsher 			}
202dee1ad47SJeff Kirsher 		}
203dee1ad47SJeff Kirsher 	}
204dee1ad47SJeff Kirsher 		break;
205dee1ad47SJeff Kirsher 	default:
206dee1ad47SJeff Kirsher 		BUG();
207dee1ad47SJeff Kirsher 	}
208dee1ad47SJeff Kirsher 
209185095fbSBruce Allan 	dev_info(&adapter->pdev->dev, "Invalid %s value specified (%i) %s\n",
210185095fbSBruce Allan 		 opt->name, *value, opt->err);
211dee1ad47SJeff Kirsher 	*value = opt->def;
212dee1ad47SJeff Kirsher 	return -1;
213dee1ad47SJeff Kirsher }
214dee1ad47SJeff Kirsher 
215dee1ad47SJeff Kirsher /**
216dee1ad47SJeff Kirsher  * e1000e_check_options - Range Checking for Command Line Parameters
217dee1ad47SJeff Kirsher  * @adapter: board private structure
218dee1ad47SJeff Kirsher  *
219dee1ad47SJeff Kirsher  * This routine checks all command line parameters for valid user
220dee1ad47SJeff Kirsher  * input.  If an invalid value is given, or if no user specified
221dee1ad47SJeff Kirsher  * value exists, a default value is used.  The final value is stored
222dee1ad47SJeff Kirsher  * in a variable in the adapter structure.
223dee1ad47SJeff Kirsher  **/
e1000e_check_options(struct e1000_adapter * adapter)2249f9a12f8SBill Pemberton void e1000e_check_options(struct e1000_adapter *adapter)
225dee1ad47SJeff Kirsher {
226dee1ad47SJeff Kirsher 	struct e1000_hw *hw = &adapter->hw;
227dee1ad47SJeff Kirsher 	int bd = adapter->bd_number;
228dee1ad47SJeff Kirsher 
229dee1ad47SJeff Kirsher 	if (bd >= E1000_MAX_NIC) {
230185095fbSBruce Allan 		dev_notice(&adapter->pdev->dev,
231185095fbSBruce Allan 			   "Warning: no configuration for board #%i\n", bd);
232185095fbSBruce Allan 		dev_notice(&adapter->pdev->dev,
233185095fbSBruce Allan 			   "Using defaults for all values\n");
234dee1ad47SJeff Kirsher 	}
235dee1ad47SJeff Kirsher 
23633550cecSBruce Allan 	/* Transmit Interrupt Delay */
23733550cecSBruce Allan 	{
238dee1ad47SJeff Kirsher 		static const struct e1000_option opt = {
239dee1ad47SJeff Kirsher 			.type = range_option,
240dee1ad47SJeff Kirsher 			.name = "Transmit Interrupt Delay",
241dee1ad47SJeff Kirsher 			.err  = "using default of "
242dee1ad47SJeff Kirsher 				__MODULE_STRING(DEFAULT_TIDV),
243dee1ad47SJeff Kirsher 			.def  = DEFAULT_TIDV,
244dee1ad47SJeff Kirsher 			.arg  = { .r = { .min = MIN_TXDELAY,
245dee1ad47SJeff Kirsher 					 .max = MAX_TXDELAY } }
246dee1ad47SJeff Kirsher 		};
247dee1ad47SJeff Kirsher 
248dee1ad47SJeff Kirsher 		if (num_TxIntDelay > bd) {
249dee1ad47SJeff Kirsher 			adapter->tx_int_delay = TxIntDelay[bd];
250dee1ad47SJeff Kirsher 			e1000_validate_option(&adapter->tx_int_delay, &opt,
251dee1ad47SJeff Kirsher 					      adapter);
252dee1ad47SJeff Kirsher 		} else {
253dee1ad47SJeff Kirsher 			adapter->tx_int_delay = opt.def;
254dee1ad47SJeff Kirsher 		}
255dee1ad47SJeff Kirsher 	}
25633550cecSBruce Allan 	/* Transmit Absolute Interrupt Delay */
25733550cecSBruce Allan 	{
258dee1ad47SJeff Kirsher 		static const struct e1000_option opt = {
259dee1ad47SJeff Kirsher 			.type = range_option,
260dee1ad47SJeff Kirsher 			.name = "Transmit Absolute Interrupt Delay",
261dee1ad47SJeff Kirsher 			.err  = "using default of "
262dee1ad47SJeff Kirsher 				__MODULE_STRING(DEFAULT_TADV),
263dee1ad47SJeff Kirsher 			.def  = DEFAULT_TADV,
264dee1ad47SJeff Kirsher 			.arg  = { .r = { .min = MIN_TXABSDELAY,
265dee1ad47SJeff Kirsher 					 .max = MAX_TXABSDELAY } }
266dee1ad47SJeff Kirsher 		};
267dee1ad47SJeff Kirsher 
268dee1ad47SJeff Kirsher 		if (num_TxAbsIntDelay > bd) {
269dee1ad47SJeff Kirsher 			adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
270dee1ad47SJeff Kirsher 			e1000_validate_option(&adapter->tx_abs_int_delay, &opt,
271dee1ad47SJeff Kirsher 					      adapter);
272dee1ad47SJeff Kirsher 		} else {
273dee1ad47SJeff Kirsher 			adapter->tx_abs_int_delay = opt.def;
274dee1ad47SJeff Kirsher 		}
275dee1ad47SJeff Kirsher 	}
27633550cecSBruce Allan 	/* Receive Interrupt Delay */
27733550cecSBruce Allan 	{
278dee1ad47SJeff Kirsher 		static struct e1000_option opt = {
279dee1ad47SJeff Kirsher 			.type = range_option,
280dee1ad47SJeff Kirsher 			.name = "Receive Interrupt Delay",
281dee1ad47SJeff Kirsher 			.err  = "using default of "
282dee1ad47SJeff Kirsher 				__MODULE_STRING(DEFAULT_RDTR),
283dee1ad47SJeff Kirsher 			.def  = DEFAULT_RDTR,
284dee1ad47SJeff Kirsher 			.arg  = { .r = { .min = MIN_RXDELAY,
285dee1ad47SJeff Kirsher 					 .max = MAX_RXDELAY } }
286dee1ad47SJeff Kirsher 		};
287dee1ad47SJeff Kirsher 
28848072ae1SWillem de Bruijn 		if (adapter->flags2 & FLAG2_DMA_BURST)
28948072ae1SWillem de Bruijn 			opt.def = BURST_RDTR;
29048072ae1SWillem de Bruijn 
291dee1ad47SJeff Kirsher 		if (num_RxIntDelay > bd) {
292dee1ad47SJeff Kirsher 			adapter->rx_int_delay = RxIntDelay[bd];
293dee1ad47SJeff Kirsher 			e1000_validate_option(&adapter->rx_int_delay, &opt,
294dee1ad47SJeff Kirsher 					      adapter);
295dee1ad47SJeff Kirsher 		} else {
296dee1ad47SJeff Kirsher 			adapter->rx_int_delay = opt.def;
297dee1ad47SJeff Kirsher 		}
298dee1ad47SJeff Kirsher 	}
29933550cecSBruce Allan 	/* Receive Absolute Interrupt Delay */
30033550cecSBruce Allan 	{
30148072ae1SWillem de Bruijn 		static struct e1000_option opt = {
302dee1ad47SJeff Kirsher 			.type = range_option,
303dee1ad47SJeff Kirsher 			.name = "Receive Absolute Interrupt Delay",
304dee1ad47SJeff Kirsher 			.err  = "using default of "
305dee1ad47SJeff Kirsher 				__MODULE_STRING(DEFAULT_RADV),
306dee1ad47SJeff Kirsher 			.def  = DEFAULT_RADV,
307dee1ad47SJeff Kirsher 			.arg  = { .r = { .min = MIN_RXABSDELAY,
308dee1ad47SJeff Kirsher 					 .max = MAX_RXABSDELAY } }
309dee1ad47SJeff Kirsher 		};
310dee1ad47SJeff Kirsher 
31148072ae1SWillem de Bruijn 		if (adapter->flags2 & FLAG2_DMA_BURST)
31248072ae1SWillem de Bruijn 			opt.def = BURST_RADV;
31348072ae1SWillem de Bruijn 
314dee1ad47SJeff Kirsher 		if (num_RxAbsIntDelay > bd) {
315dee1ad47SJeff Kirsher 			adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
316dee1ad47SJeff Kirsher 			e1000_validate_option(&adapter->rx_abs_int_delay, &opt,
317dee1ad47SJeff Kirsher 					      adapter);
318dee1ad47SJeff Kirsher 		} else {
319dee1ad47SJeff Kirsher 			adapter->rx_abs_int_delay = opt.def;
320dee1ad47SJeff Kirsher 		}
321dee1ad47SJeff Kirsher 	}
32233550cecSBruce Allan 	/* Interrupt Throttling Rate */
32333550cecSBruce Allan 	{
324dee1ad47SJeff Kirsher 		static const struct e1000_option opt = {
325dee1ad47SJeff Kirsher 			.type = range_option,
326dee1ad47SJeff Kirsher 			.name = "Interrupt Throttling Rate (ints/sec)",
327dee1ad47SJeff Kirsher 			.err  = "using default of "
328dee1ad47SJeff Kirsher 				__MODULE_STRING(DEFAULT_ITR),
329dee1ad47SJeff Kirsher 			.def  = DEFAULT_ITR,
330dee1ad47SJeff Kirsher 			.arg  = { .r = { .min = MIN_ITR,
331dee1ad47SJeff Kirsher 					 .max = MAX_ITR } }
332dee1ad47SJeff Kirsher 		};
333dee1ad47SJeff Kirsher 
334dee1ad47SJeff Kirsher 		if (num_InterruptThrottleRate > bd) {
335dee1ad47SJeff Kirsher 			adapter->itr = InterruptThrottleRate[bd];
3362e7d21c5SJeff Kirsher 
337e921eb1aSBruce Allan 			/* Make sure a message is printed for non-special
3382e7d21c5SJeff Kirsher 			 * values. And in case of an invalid option, display
3392e7d21c5SJeff Kirsher 			 * warning, use default and go through itr/itr_setting
3402e7d21c5SJeff Kirsher 			 * adjustment logic below
341dee1ad47SJeff Kirsher 			 */
3422e7d21c5SJeff Kirsher 			if ((adapter->itr > 4) &&
3432e7d21c5SJeff Kirsher 			    e1000_validate_option(&adapter->itr, &opt, adapter))
3442e7d21c5SJeff Kirsher 				adapter->itr = opt.def;
345dee1ad47SJeff Kirsher 		} else {
346e921eb1aSBruce Allan 			/* If no option specified, use default value and go
347727c356fSJeff Kirsher 			 * through the logic below to adjust itr/itr_setting
348727c356fSJeff Kirsher 			 */
349727c356fSJeff Kirsher 			adapter->itr = opt.def;
350727c356fSJeff Kirsher 
351e921eb1aSBruce Allan 			/* Make sure a message is printed for non-special
352727c356fSJeff Kirsher 			 * default values
353727c356fSJeff Kirsher 			 */
3542e7d21c5SJeff Kirsher 			if (adapter->itr > 4)
355185095fbSBruce Allan 				dev_info(&adapter->pdev->dev,
356185095fbSBruce Allan 					 "%s set to default %d\n", opt.name,
357727c356fSJeff Kirsher 					 adapter->itr);
358727c356fSJeff Kirsher 		}
359727c356fSJeff Kirsher 
360727c356fSJeff Kirsher 		adapter->itr_setting = adapter->itr;
361dee1ad47SJeff Kirsher 		switch (adapter->itr) {
362dee1ad47SJeff Kirsher 		case 0:
363185095fbSBruce Allan 			dev_info(&adapter->pdev->dev, "%s turned off\n",
364185095fbSBruce Allan 				 opt.name);
365dee1ad47SJeff Kirsher 			break;
366dee1ad47SJeff Kirsher 		case 1:
367185095fbSBruce Allan 			dev_info(&adapter->pdev->dev,
368185095fbSBruce Allan 				 "%s set to dynamic mode\n", opt.name);
369dee1ad47SJeff Kirsher 			adapter->itr = 20000;
370dee1ad47SJeff Kirsher 			break;
3715bb73176SDavid Ertman 		case 2:
3725bb73176SDavid Ertman 			dev_info(&adapter->pdev->dev,
3735bb73176SDavid Ertman 				 "%s Invalid mode - setting default\n",
3745bb73176SDavid Ertman 				 opt.name);
3755bb73176SDavid Ertman 			adapter->itr_setting = opt.def;
3765463fce6SJeff Kirsher 			fallthrough;
377dee1ad47SJeff Kirsher 		case 3:
378185095fbSBruce Allan 			dev_info(&adapter->pdev->dev,
379185095fbSBruce Allan 				 "%s set to dynamic conservative mode\n",
380dee1ad47SJeff Kirsher 				 opt.name);
381dee1ad47SJeff Kirsher 			adapter->itr = 20000;
382dee1ad47SJeff Kirsher 			break;
383dee1ad47SJeff Kirsher 		case 4:
384185095fbSBruce Allan 			dev_info(&adapter->pdev->dev,
385185095fbSBruce Allan 				 "%s set to simplified (2000-8000 ints) mode\n",
386727c356fSJeff Kirsher 				 opt.name);
387dee1ad47SJeff Kirsher 			break;
388dee1ad47SJeff Kirsher 		default:
389e921eb1aSBruce Allan 			/* Save the setting, because the dynamic bits
390dee1ad47SJeff Kirsher 			 * change itr.
391727c356fSJeff Kirsher 			 *
392dee1ad47SJeff Kirsher 			 * Clear the lower two bits because
393dee1ad47SJeff Kirsher 			 * they are used as control.
394dee1ad47SJeff Kirsher 			 */
395727c356fSJeff Kirsher 			adapter->itr_setting &= ~3;
396dee1ad47SJeff Kirsher 			break;
397dee1ad47SJeff Kirsher 		}
398dee1ad47SJeff Kirsher 	}
39933550cecSBruce Allan 	/* Interrupt Mode */
40033550cecSBruce Allan 	{
401dee1ad47SJeff Kirsher 		static struct e1000_option opt = {
402dee1ad47SJeff Kirsher 			.type = range_option,
403dee1ad47SJeff Kirsher 			.name = "Interrupt Mode",
404b6fbca2aSBruce Allan #ifndef CONFIG_PCI_MSI
405b6fbca2aSBruce Allan 			.err  = "defaulting to 0 (legacy)",
406b6fbca2aSBruce Allan 			.def  = E1000E_INT_MODE_LEGACY,
407b6fbca2aSBruce Allan 			.arg  = { .r = { .min = 0,
408b6fbca2aSBruce Allan 					 .max = 0 } }
409b6fbca2aSBruce Allan #endif
410dee1ad47SJeff Kirsher 		};
411dee1ad47SJeff Kirsher 
412b6fbca2aSBruce Allan #ifdef CONFIG_PCI_MSI
413b6fbca2aSBruce Allan 		if (adapter->flags & FLAG_HAS_MSIX) {
414b6fbca2aSBruce Allan 			opt.err = kstrdup("defaulting to 2 (MSI-X)",
415b6fbca2aSBruce Allan 					  GFP_KERNEL);
416b6fbca2aSBruce Allan 			opt.def = E1000E_INT_MODE_MSIX;
417b6fbca2aSBruce Allan 			opt.arg.r.max = E1000E_INT_MODE_MSIX;
418b6fbca2aSBruce Allan 		} else {
419b6fbca2aSBruce Allan 			opt.err = kstrdup("defaulting to 1 (MSI)", GFP_KERNEL);
420b6fbca2aSBruce Allan 			opt.def = E1000E_INT_MODE_MSI;
421b6fbca2aSBruce Allan 			opt.arg.r.max = E1000E_INT_MODE_MSI;
422b6fbca2aSBruce Allan 		}
423b6fbca2aSBruce Allan 
424b6fbca2aSBruce Allan 		if (!opt.err) {
425b6fbca2aSBruce Allan 			dev_err(&adapter->pdev->dev,
426b6fbca2aSBruce Allan 				"Failed to allocate memory\n");
427b6fbca2aSBruce Allan 			return;
428b6fbca2aSBruce Allan 		}
429b6fbca2aSBruce Allan #endif
430b6fbca2aSBruce Allan 
431dee1ad47SJeff Kirsher 		if (num_IntMode > bd) {
432dee1ad47SJeff Kirsher 			unsigned int int_mode = IntMode[bd];
4336cf08d1cSDavid Ertman 
434dee1ad47SJeff Kirsher 			e1000_validate_option(&int_mode, &opt, adapter);
435dee1ad47SJeff Kirsher 			adapter->int_mode = int_mode;
436dee1ad47SJeff Kirsher 		} else {
437dee1ad47SJeff Kirsher 			adapter->int_mode = opt.def;
438dee1ad47SJeff Kirsher 		}
439b6fbca2aSBruce Allan 
440b6fbca2aSBruce Allan #ifdef CONFIG_PCI_MSI
441b6fbca2aSBruce Allan 		kfree(opt.err);
442b6fbca2aSBruce Allan #endif
443dee1ad47SJeff Kirsher 	}
44433550cecSBruce Allan 	/* Smart Power Down */
44533550cecSBruce Allan 	{
446dee1ad47SJeff Kirsher 		static const struct e1000_option opt = {
447dee1ad47SJeff Kirsher 			.type = enable_option,
448dee1ad47SJeff Kirsher 			.name = "PHY Smart Power Down",
449dee1ad47SJeff Kirsher 			.err  = "defaulting to Disabled",
450dee1ad47SJeff Kirsher 			.def  = OPTION_DISABLED
451dee1ad47SJeff Kirsher 		};
452dee1ad47SJeff Kirsher 
453dee1ad47SJeff Kirsher 		if (num_SmartPowerDownEnable > bd) {
454dee1ad47SJeff Kirsher 			unsigned int spd = SmartPowerDownEnable[bd];
4556cf08d1cSDavid Ertman 
456dee1ad47SJeff Kirsher 			e1000_validate_option(&spd, &opt, adapter);
4571860ac84SBruce Allan 			if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) && spd)
458dee1ad47SJeff Kirsher 				adapter->flags |= FLAG_SMART_POWER_DOWN;
459dee1ad47SJeff Kirsher 		}
460dee1ad47SJeff Kirsher 	}
46133550cecSBruce Allan 	/* CRC Stripping */
46233550cecSBruce Allan 	{
463dee1ad47SJeff Kirsher 		static const struct e1000_option opt = {
464dee1ad47SJeff Kirsher 			.type = enable_option,
465dee1ad47SJeff Kirsher 			.name = "CRC Stripping",
466dee1ad47SJeff Kirsher 			.err  = "defaulting to Enabled",
467dee1ad47SJeff Kirsher 			.def  = OPTION_ENABLED
468dee1ad47SJeff Kirsher 		};
469dee1ad47SJeff Kirsher 
470dee1ad47SJeff Kirsher 		if (num_CrcStripping > bd) {
471dee1ad47SJeff Kirsher 			unsigned int crc_stripping = CrcStripping[bd];
4726cf08d1cSDavid Ertman 
473dee1ad47SJeff Kirsher 			e1000_validate_option(&crc_stripping, &opt, adapter);
4740184039aSBen Greear 			if (crc_stripping == OPTION_ENABLED) {
475dee1ad47SJeff Kirsher 				adapter->flags2 |= FLAG2_CRC_STRIPPING;
4760184039aSBen Greear 				adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING;
4770184039aSBen Greear 			}
478dee1ad47SJeff Kirsher 		} else {
479dee1ad47SJeff Kirsher 			adapter->flags2 |= FLAG2_CRC_STRIPPING;
4800184039aSBen Greear 			adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING;
481dee1ad47SJeff Kirsher 		}
482dee1ad47SJeff Kirsher 	}
48333550cecSBruce Allan 	/* Kumeran Lock Loss Workaround */
48433550cecSBruce Allan 	{
485dee1ad47SJeff Kirsher 		static const struct e1000_option opt = {
486dee1ad47SJeff Kirsher 			.type = enable_option,
487dee1ad47SJeff Kirsher 			.name = "Kumeran Lock Loss Workaround",
488dee1ad47SJeff Kirsher 			.err  = "defaulting to Enabled",
489dee1ad47SJeff Kirsher 			.def  = OPTION_ENABLED
490dee1ad47SJeff Kirsher 		};
49117e813ecSBruce Allan 		bool enabled = opt.def;
492dee1ad47SJeff Kirsher 
493dee1ad47SJeff Kirsher 		if (num_KumeranLockLoss > bd) {
494dee1ad47SJeff Kirsher 			unsigned int kmrn_lock_loss = KumeranLockLoss[bd];
4956cf08d1cSDavid Ertman 
496dee1ad47SJeff Kirsher 			e1000_validate_option(&kmrn_lock_loss, &opt, adapter);
49717e813ecSBruce Allan 			enabled = kmrn_lock_loss;
498dee1ad47SJeff Kirsher 		}
49917e813ecSBruce Allan 
50017e813ecSBruce Allan 		if (hw->mac.type == e1000_ich8lan)
50117e813ecSBruce Allan 			e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw,
50217e813ecSBruce Allan 								     enabled);
503dee1ad47SJeff Kirsher 	}
50433550cecSBruce Allan 	/* Write-protect NVM */
50533550cecSBruce Allan 	{
506dee1ad47SJeff Kirsher 		static const struct e1000_option opt = {
507dee1ad47SJeff Kirsher 			.type = enable_option,
508dee1ad47SJeff Kirsher 			.name = "Write-protect NVM",
509dee1ad47SJeff Kirsher 			.err  = "defaulting to Enabled",
510dee1ad47SJeff Kirsher 			.def  = OPTION_ENABLED
511dee1ad47SJeff Kirsher 		};
512dee1ad47SJeff Kirsher 
513dee1ad47SJeff Kirsher 		if (adapter->flags & FLAG_IS_ICH) {
514dee1ad47SJeff Kirsher 			if (num_WriteProtectNVM > bd) {
515c29c3ba5SBruce Allan 				unsigned int write_protect_nvm =
516c29c3ba5SBruce Allan 				    WriteProtectNVM[bd];
517dee1ad47SJeff Kirsher 				e1000_validate_option(&write_protect_nvm, &opt,
518dee1ad47SJeff Kirsher 						      adapter);
519dee1ad47SJeff Kirsher 				if (write_protect_nvm)
520dee1ad47SJeff Kirsher 					adapter->flags |= FLAG_READ_ONLY_NVM;
521dee1ad47SJeff Kirsher 			} else {
522dee1ad47SJeff Kirsher 				if (opt.def)
523dee1ad47SJeff Kirsher 					adapter->flags |= FLAG_READ_ONLY_NVM;
524dee1ad47SJeff Kirsher 			}
525dee1ad47SJeff Kirsher 		}
526dee1ad47SJeff Kirsher 	}
527dee1ad47SJeff Kirsher }
528