xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/intel/ixgb/ixgb_param.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* Copyright(c) 1999 - 2008 Intel Corporation. */
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include "ixgb.h"
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun /* This is the only thing that needs to be changed to adjust the
9*4882a593Smuzhiyun  * maximum number of ports that the driver can manage.
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #define IXGB_MAX_NIC 8
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #define OPTION_UNSET	-1
15*4882a593Smuzhiyun #define OPTION_DISABLED 0
16*4882a593Smuzhiyun #define OPTION_ENABLED  1
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun /* All parameters are treated the same, as an integer array of values.
19*4882a593Smuzhiyun  * This macro just reduces the need to repeat the same declaration code
20*4882a593Smuzhiyun  * over and over (plus this helps to avoid typo bugs).
21*4882a593Smuzhiyun  */
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET }
24*4882a593Smuzhiyun #define IXGB_PARAM(X, desc)					\
25*4882a593Smuzhiyun 	static int X[IXGB_MAX_NIC+1]		\
26*4882a593Smuzhiyun 		= IXGB_PARAM_INIT;				\
27*4882a593Smuzhiyun 	static unsigned int num_##X = 0;			\
28*4882a593Smuzhiyun 	module_param_array_named(X, X, int, &num_##X, 0);	\
29*4882a593Smuzhiyun 	MODULE_PARM_DESC(X, desc);
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun /* Transmit Descriptor Count
32*4882a593Smuzhiyun  *
33*4882a593Smuzhiyun  * Valid Range: 64-4096
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * Default Value: 256
36*4882a593Smuzhiyun  */
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun IXGB_PARAM(TxDescriptors, "Number of transmit descriptors");
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /* Receive Descriptor Count
41*4882a593Smuzhiyun  *
42*4882a593Smuzhiyun  * Valid Range: 64-4096
43*4882a593Smuzhiyun  *
44*4882a593Smuzhiyun  * Default Value: 1024
45*4882a593Smuzhiyun  */
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun IXGB_PARAM(RxDescriptors, "Number of receive descriptors");
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /* User Specified Flow Control Override
50*4882a593Smuzhiyun  *
51*4882a593Smuzhiyun  * Valid Range: 0-3
52*4882a593Smuzhiyun  *  - 0 - No Flow Control
53*4882a593Smuzhiyun  *  - 1 - Rx only, respond to PAUSE frames but do not generate them
54*4882a593Smuzhiyun  *  - 2 - Tx only, generate PAUSE frames but ignore them on receive
55*4882a593Smuzhiyun  *  - 3 - Full Flow Control Support
56*4882a593Smuzhiyun  *
57*4882a593Smuzhiyun  * Default Value: 2 - Tx only (silicon bug avoidance)
58*4882a593Smuzhiyun  */
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun IXGB_PARAM(FlowControl, "Flow Control setting");
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun /* XsumRX - Receive Checksum Offload Enable/Disable
63*4882a593Smuzhiyun  *
64*4882a593Smuzhiyun  * Valid Range: 0, 1
65*4882a593Smuzhiyun  *  - 0 - disables all checksum offload
66*4882a593Smuzhiyun  *  - 1 - enables receive IP/TCP/UDP checksum offload
67*4882a593Smuzhiyun  *        on 82597 based NICs
68*4882a593Smuzhiyun  *
69*4882a593Smuzhiyun  * Default Value: 1
70*4882a593Smuzhiyun  */
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun IXGB_PARAM(XsumRX, "Disable or enable Receive Checksum offload");
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun /* Transmit Interrupt Delay in units of 0.8192 microseconds
75*4882a593Smuzhiyun  *
76*4882a593Smuzhiyun  * Valid Range: 0-65535
77*4882a593Smuzhiyun  *
78*4882a593Smuzhiyun  * Default Value: 32
79*4882a593Smuzhiyun  */
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun IXGB_PARAM(TxIntDelay, "Transmit Interrupt Delay");
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun /* Receive Interrupt Delay in units of 0.8192 microseconds
84*4882a593Smuzhiyun  *
85*4882a593Smuzhiyun  * Valid Range: 0-65535
86*4882a593Smuzhiyun  *
87*4882a593Smuzhiyun  * Default Value: 72
88*4882a593Smuzhiyun  */
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun IXGB_PARAM(RxIntDelay, "Receive Interrupt Delay");
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /* Receive Flow control high threshold (when we send a pause frame)
93*4882a593Smuzhiyun  * (FCRTH)
94*4882a593Smuzhiyun  *
95*4882a593Smuzhiyun  * Valid Range: 1,536 - 262,136 (0x600 - 0x3FFF8, 8 byte granularity)
96*4882a593Smuzhiyun  *
97*4882a593Smuzhiyun  * Default Value: 196,608 (0x30000)
98*4882a593Smuzhiyun  */
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun IXGB_PARAM(RxFCHighThresh, "Receive Flow Control High Threshold");
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun /* Receive Flow control low threshold (when we send a resume frame)
103*4882a593Smuzhiyun  * (FCRTL)
104*4882a593Smuzhiyun  *
105*4882a593Smuzhiyun  * Valid Range: 64 - 262,136 (0x40 - 0x3FFF8, 8 byte granularity)
106*4882a593Smuzhiyun  *              must be less than high threshold by at least 8 bytes
107*4882a593Smuzhiyun  *
108*4882a593Smuzhiyun  * Default Value:  163,840 (0x28000)
109*4882a593Smuzhiyun  */
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun IXGB_PARAM(RxFCLowThresh, "Receive Flow Control Low Threshold");
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun /* Flow control request timeout (how long to pause the link partner's tx)
114*4882a593Smuzhiyun  * (PAP 15:0)
115*4882a593Smuzhiyun  *
116*4882a593Smuzhiyun  * Valid Range: 1 - 65535
117*4882a593Smuzhiyun  *
118*4882a593Smuzhiyun  * Default Value:  65535 (0xffff) (we'll send an xon if we recover)
119*4882a593Smuzhiyun  */
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun IXGB_PARAM(FCReqTimeout, "Flow Control Request Timeout");
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun /* Interrupt Delay Enable
124*4882a593Smuzhiyun  *
125*4882a593Smuzhiyun  * Valid Range: 0, 1
126*4882a593Smuzhiyun  *
127*4882a593Smuzhiyun  *  - 0 - disables transmit interrupt delay
128*4882a593Smuzhiyun  *  - 1 - enables transmmit interrupt delay
129*4882a593Smuzhiyun  *
130*4882a593Smuzhiyun  * Default Value: 1
131*4882a593Smuzhiyun  */
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable");
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun #define DEFAULT_TIDV	   		     32
137*4882a593Smuzhiyun #define MAX_TIDV			 0xFFFF
138*4882a593Smuzhiyun #define MIN_TIDV			      0
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun #define DEFAULT_RDTR		   	     72
141*4882a593Smuzhiyun #define MAX_RDTR			 0xFFFF
142*4882a593Smuzhiyun #define MIN_RDTR			      0
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun #define XSUMRX_DEFAULT		 OPTION_ENABLED
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun #define DEFAULT_FCRTL	  		0x28000
147*4882a593Smuzhiyun #define DEFAULT_FCRTH			0x30000
148*4882a593Smuzhiyun #define MIN_FCRTL			      0
149*4882a593Smuzhiyun #define MAX_FCRTL			0x3FFE8
150*4882a593Smuzhiyun #define MIN_FCRTH			      8
151*4882a593Smuzhiyun #define MAX_FCRTH			0x3FFF0
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun #define MIN_FCPAUSE			      1
154*4882a593Smuzhiyun #define MAX_FCPAUSE			 0xffff
155*4882a593Smuzhiyun #define DEFAULT_FCPAUSE		  	 0xFFFF /* this may be too long */
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun struct ixgb_option {
158*4882a593Smuzhiyun 	enum { enable_option, range_option, list_option } type;
159*4882a593Smuzhiyun 	const char *name;
160*4882a593Smuzhiyun 	const char *err;
161*4882a593Smuzhiyun 	int def;
162*4882a593Smuzhiyun 	union {
163*4882a593Smuzhiyun 		struct {	/* range_option info */
164*4882a593Smuzhiyun 			int min;
165*4882a593Smuzhiyun 			int max;
166*4882a593Smuzhiyun 		} r;
167*4882a593Smuzhiyun 		struct {	/* list_option info */
168*4882a593Smuzhiyun 			int nr;
169*4882a593Smuzhiyun 			const struct ixgb_opt_list {
170*4882a593Smuzhiyun 				int i;
171*4882a593Smuzhiyun 				const char *str;
172*4882a593Smuzhiyun 			} *p;
173*4882a593Smuzhiyun 		} l;
174*4882a593Smuzhiyun 	} arg;
175*4882a593Smuzhiyun };
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun static int
ixgb_validate_option(unsigned int * value,const struct ixgb_option * opt)178*4882a593Smuzhiyun ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun 	if (*value == OPTION_UNSET) {
181*4882a593Smuzhiyun 		*value = opt->def;
182*4882a593Smuzhiyun 		return 0;
183*4882a593Smuzhiyun 	}
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	switch (opt->type) {
186*4882a593Smuzhiyun 	case enable_option:
187*4882a593Smuzhiyun 		switch (*value) {
188*4882a593Smuzhiyun 		case OPTION_ENABLED:
189*4882a593Smuzhiyun 			pr_info("%s Enabled\n", opt->name);
190*4882a593Smuzhiyun 			return 0;
191*4882a593Smuzhiyun 		case OPTION_DISABLED:
192*4882a593Smuzhiyun 			pr_info("%s Disabled\n", opt->name);
193*4882a593Smuzhiyun 			return 0;
194*4882a593Smuzhiyun 		}
195*4882a593Smuzhiyun 		break;
196*4882a593Smuzhiyun 	case range_option:
197*4882a593Smuzhiyun 		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
198*4882a593Smuzhiyun 			pr_info("%s set to %i\n", opt->name, *value);
199*4882a593Smuzhiyun 			return 0;
200*4882a593Smuzhiyun 		}
201*4882a593Smuzhiyun 		break;
202*4882a593Smuzhiyun 	case list_option: {
203*4882a593Smuzhiyun 		int i;
204*4882a593Smuzhiyun 		const struct ixgb_opt_list *ent;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 		for (i = 0; i < opt->arg.l.nr; i++) {
207*4882a593Smuzhiyun 			ent = &opt->arg.l.p[i];
208*4882a593Smuzhiyun 			if (*value == ent->i) {
209*4882a593Smuzhiyun 				if (ent->str[0] != '\0')
210*4882a593Smuzhiyun 					pr_info("%s\n", ent->str);
211*4882a593Smuzhiyun 				return 0;
212*4882a593Smuzhiyun 			}
213*4882a593Smuzhiyun 		}
214*4882a593Smuzhiyun 	}
215*4882a593Smuzhiyun 		break;
216*4882a593Smuzhiyun 	default:
217*4882a593Smuzhiyun 		BUG();
218*4882a593Smuzhiyun 	}
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	pr_info("Invalid %s specified (%i) %s\n", opt->name, *value, opt->err);
221*4882a593Smuzhiyun 	*value = opt->def;
222*4882a593Smuzhiyun 	return -1;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun /**
226*4882a593Smuzhiyun  * ixgb_check_options - Range Checking for Command Line Parameters
227*4882a593Smuzhiyun  * @adapter: board private structure
228*4882a593Smuzhiyun  *
229*4882a593Smuzhiyun  * This routine checks all command line parameters for valid user
230*4882a593Smuzhiyun  * input.  If an invalid value is given, or if no user specified
231*4882a593Smuzhiyun  * value exists, a default value is used.  The final value is stored
232*4882a593Smuzhiyun  * in a variable in the adapter structure.
233*4882a593Smuzhiyun  **/
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun void
ixgb_check_options(struct ixgb_adapter * adapter)236*4882a593Smuzhiyun ixgb_check_options(struct ixgb_adapter *adapter)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	int bd = adapter->bd_number;
239*4882a593Smuzhiyun 	if (bd >= IXGB_MAX_NIC) {
240*4882a593Smuzhiyun 		pr_notice("Warning: no configuration for board #%i\n", bd);
241*4882a593Smuzhiyun 		pr_notice("Using defaults for all values\n");
242*4882a593Smuzhiyun 	}
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	{ /* Transmit Descriptor Count */
245*4882a593Smuzhiyun 		static const struct ixgb_option opt = {
246*4882a593Smuzhiyun 			.type = range_option,
247*4882a593Smuzhiyun 			.name = "Transmit Descriptors",
248*4882a593Smuzhiyun 			.err  = "using default of " __MODULE_STRING(DEFAULT_TXD),
249*4882a593Smuzhiyun 			.def  = DEFAULT_TXD,
250*4882a593Smuzhiyun 			.arg  = { .r = { .min = MIN_TXD,
251*4882a593Smuzhiyun 					 .max = MAX_TXD}}
252*4882a593Smuzhiyun 		};
253*4882a593Smuzhiyun 		struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 		if (num_TxDescriptors > bd) {
256*4882a593Smuzhiyun 			tx_ring->count = TxDescriptors[bd];
257*4882a593Smuzhiyun 			ixgb_validate_option(&tx_ring->count, &opt);
258*4882a593Smuzhiyun 		} else {
259*4882a593Smuzhiyun 			tx_ring->count = opt.def;
260*4882a593Smuzhiyun 		}
261*4882a593Smuzhiyun 		tx_ring->count = ALIGN(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
262*4882a593Smuzhiyun 	}
263*4882a593Smuzhiyun 	{ /* Receive Descriptor Count */
264*4882a593Smuzhiyun 		static const struct ixgb_option opt = {
265*4882a593Smuzhiyun 			.type = range_option,
266*4882a593Smuzhiyun 			.name = "Receive Descriptors",
267*4882a593Smuzhiyun 			.err  = "using default of " __MODULE_STRING(DEFAULT_RXD),
268*4882a593Smuzhiyun 			.def  = DEFAULT_RXD,
269*4882a593Smuzhiyun 			.arg  = { .r = { .min = MIN_RXD,
270*4882a593Smuzhiyun 					 .max = MAX_RXD}}
271*4882a593Smuzhiyun 		};
272*4882a593Smuzhiyun 		struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 		if (num_RxDescriptors > bd) {
275*4882a593Smuzhiyun 			rx_ring->count = RxDescriptors[bd];
276*4882a593Smuzhiyun 			ixgb_validate_option(&rx_ring->count, &opt);
277*4882a593Smuzhiyun 		} else {
278*4882a593Smuzhiyun 			rx_ring->count = opt.def;
279*4882a593Smuzhiyun 		}
280*4882a593Smuzhiyun 		rx_ring->count = ALIGN(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
281*4882a593Smuzhiyun 	}
282*4882a593Smuzhiyun 	{ /* Receive Checksum Offload Enable */
283*4882a593Smuzhiyun 		static const struct ixgb_option opt = {
284*4882a593Smuzhiyun 			.type = enable_option,
285*4882a593Smuzhiyun 			.name = "Receive Checksum Offload",
286*4882a593Smuzhiyun 			.err  = "defaulting to Enabled",
287*4882a593Smuzhiyun 			.def  = OPTION_ENABLED
288*4882a593Smuzhiyun 		};
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 		if (num_XsumRX > bd) {
291*4882a593Smuzhiyun 			unsigned int rx_csum = XsumRX[bd];
292*4882a593Smuzhiyun 			ixgb_validate_option(&rx_csum, &opt);
293*4882a593Smuzhiyun 			adapter->rx_csum = rx_csum;
294*4882a593Smuzhiyun 		} else {
295*4882a593Smuzhiyun 			adapter->rx_csum = opt.def;
296*4882a593Smuzhiyun 		}
297*4882a593Smuzhiyun 	}
298*4882a593Smuzhiyun 	{ /* Flow Control */
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 		static const struct ixgb_opt_list fc_list[] = {
301*4882a593Smuzhiyun 		       { ixgb_fc_none, "Flow Control Disabled" },
302*4882a593Smuzhiyun 		       { ixgb_fc_rx_pause, "Flow Control Receive Only" },
303*4882a593Smuzhiyun 		       { ixgb_fc_tx_pause, "Flow Control Transmit Only" },
304*4882a593Smuzhiyun 		       { ixgb_fc_full, "Flow Control Enabled" },
305*4882a593Smuzhiyun 		       { ixgb_fc_default, "Flow Control Hardware Default" }
306*4882a593Smuzhiyun 		};
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 		static const struct ixgb_option opt = {
309*4882a593Smuzhiyun 			.type = list_option,
310*4882a593Smuzhiyun 			.name = "Flow Control",
311*4882a593Smuzhiyun 			.err  = "reading default settings from EEPROM",
312*4882a593Smuzhiyun 			.def  = ixgb_fc_tx_pause,
313*4882a593Smuzhiyun 			.arg  = { .l = { .nr = ARRAY_SIZE(fc_list),
314*4882a593Smuzhiyun 					 .p = fc_list }}
315*4882a593Smuzhiyun 		};
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 		if (num_FlowControl > bd) {
318*4882a593Smuzhiyun 			unsigned int fc = FlowControl[bd];
319*4882a593Smuzhiyun 			ixgb_validate_option(&fc, &opt);
320*4882a593Smuzhiyun 			adapter->hw.fc.type = fc;
321*4882a593Smuzhiyun 		} else {
322*4882a593Smuzhiyun 			adapter->hw.fc.type = opt.def;
323*4882a593Smuzhiyun 		}
324*4882a593Smuzhiyun 	}
325*4882a593Smuzhiyun 	{ /* Receive Flow Control High Threshold */
326*4882a593Smuzhiyun 		static const struct ixgb_option opt = {
327*4882a593Smuzhiyun 			.type = range_option,
328*4882a593Smuzhiyun 			.name = "Rx Flow Control High Threshold",
329*4882a593Smuzhiyun 			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTH),
330*4882a593Smuzhiyun 			.def  = DEFAULT_FCRTH,
331*4882a593Smuzhiyun 			.arg  = { .r = { .min = MIN_FCRTH,
332*4882a593Smuzhiyun 					 .max = MAX_FCRTH}}
333*4882a593Smuzhiyun 		};
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 		if (num_RxFCHighThresh > bd) {
336*4882a593Smuzhiyun 			adapter->hw.fc.high_water = RxFCHighThresh[bd];
337*4882a593Smuzhiyun 			ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
338*4882a593Smuzhiyun 		} else {
339*4882a593Smuzhiyun 			adapter->hw.fc.high_water = opt.def;
340*4882a593Smuzhiyun 		}
341*4882a593Smuzhiyun 		if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
342*4882a593Smuzhiyun 			pr_info("Ignoring RxFCHighThresh when no RxFC\n");
343*4882a593Smuzhiyun 	}
344*4882a593Smuzhiyun 	{ /* Receive Flow Control Low Threshold */
345*4882a593Smuzhiyun 		static const struct ixgb_option opt = {
346*4882a593Smuzhiyun 			.type = range_option,
347*4882a593Smuzhiyun 			.name = "Rx Flow Control Low Threshold",
348*4882a593Smuzhiyun 			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTL),
349*4882a593Smuzhiyun 			.def  = DEFAULT_FCRTL,
350*4882a593Smuzhiyun 			.arg  = { .r = { .min = MIN_FCRTL,
351*4882a593Smuzhiyun 					 .max = MAX_FCRTL}}
352*4882a593Smuzhiyun 		};
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 		if (num_RxFCLowThresh > bd) {
355*4882a593Smuzhiyun 			adapter->hw.fc.low_water = RxFCLowThresh[bd];
356*4882a593Smuzhiyun 			ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
357*4882a593Smuzhiyun 		} else {
358*4882a593Smuzhiyun 			adapter->hw.fc.low_water = opt.def;
359*4882a593Smuzhiyun 		}
360*4882a593Smuzhiyun 		if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
361*4882a593Smuzhiyun 			pr_info("Ignoring RxFCLowThresh when no RxFC\n");
362*4882a593Smuzhiyun 	}
363*4882a593Smuzhiyun 	{ /* Flow Control Pause Time Request*/
364*4882a593Smuzhiyun 		static const struct ixgb_option opt = {
365*4882a593Smuzhiyun 			.type = range_option,
366*4882a593Smuzhiyun 			.name = "Flow Control Pause Time Request",
367*4882a593Smuzhiyun 			.err  = "using default of "__MODULE_STRING(DEFAULT_FCPAUSE),
368*4882a593Smuzhiyun 			.def  = DEFAULT_FCPAUSE,
369*4882a593Smuzhiyun 			.arg = { .r = { .min = MIN_FCPAUSE,
370*4882a593Smuzhiyun 					.max = MAX_FCPAUSE}}
371*4882a593Smuzhiyun 		};
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 		if (num_FCReqTimeout > bd) {
374*4882a593Smuzhiyun 			unsigned int pause_time = FCReqTimeout[bd];
375*4882a593Smuzhiyun 			ixgb_validate_option(&pause_time, &opt);
376*4882a593Smuzhiyun 			adapter->hw.fc.pause_time = pause_time;
377*4882a593Smuzhiyun 		} else {
378*4882a593Smuzhiyun 			adapter->hw.fc.pause_time = opt.def;
379*4882a593Smuzhiyun 		}
380*4882a593Smuzhiyun 		if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
381*4882a593Smuzhiyun 			pr_info("Ignoring FCReqTimeout when no RxFC\n");
382*4882a593Smuzhiyun 	}
383*4882a593Smuzhiyun 	/* high low and spacing check for rx flow control thresholds */
384*4882a593Smuzhiyun 	if (adapter->hw.fc.type & ixgb_fc_tx_pause) {
385*4882a593Smuzhiyun 		/* high must be greater than low */
386*4882a593Smuzhiyun 		if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) {
387*4882a593Smuzhiyun 			/* set defaults */
388*4882a593Smuzhiyun 			pr_info("RxFCHighThresh must be >= (RxFCLowThresh + 8), Using Defaults\n");
389*4882a593Smuzhiyun 			adapter->hw.fc.high_water = DEFAULT_FCRTH;
390*4882a593Smuzhiyun 			adapter->hw.fc.low_water  = DEFAULT_FCRTL;
391*4882a593Smuzhiyun 		}
392*4882a593Smuzhiyun 	}
393*4882a593Smuzhiyun 	{ /* Receive Interrupt Delay */
394*4882a593Smuzhiyun 		static const struct ixgb_option opt = {
395*4882a593Smuzhiyun 			.type = range_option,
396*4882a593Smuzhiyun 			.name = "Receive Interrupt Delay",
397*4882a593Smuzhiyun 			.err  = "using default of " __MODULE_STRING(DEFAULT_RDTR),
398*4882a593Smuzhiyun 			.def  = DEFAULT_RDTR,
399*4882a593Smuzhiyun 			.arg  = { .r = { .min = MIN_RDTR,
400*4882a593Smuzhiyun 					 .max = MAX_RDTR}}
401*4882a593Smuzhiyun 		};
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 		if (num_RxIntDelay > bd) {
404*4882a593Smuzhiyun 			adapter->rx_int_delay = RxIntDelay[bd];
405*4882a593Smuzhiyun 			ixgb_validate_option(&adapter->rx_int_delay, &opt);
406*4882a593Smuzhiyun 		} else {
407*4882a593Smuzhiyun 			adapter->rx_int_delay = opt.def;
408*4882a593Smuzhiyun 		}
409*4882a593Smuzhiyun 	}
410*4882a593Smuzhiyun 	{ /* Transmit Interrupt Delay */
411*4882a593Smuzhiyun 		static const struct ixgb_option opt = {
412*4882a593Smuzhiyun 			.type = range_option,
413*4882a593Smuzhiyun 			.name = "Transmit Interrupt Delay",
414*4882a593Smuzhiyun 			.err  = "using default of " __MODULE_STRING(DEFAULT_TIDV),
415*4882a593Smuzhiyun 			.def  = DEFAULT_TIDV,
416*4882a593Smuzhiyun 			.arg  = { .r = { .min = MIN_TIDV,
417*4882a593Smuzhiyun 					 .max = MAX_TIDV}}
418*4882a593Smuzhiyun 		};
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun 		if (num_TxIntDelay > bd) {
421*4882a593Smuzhiyun 			adapter->tx_int_delay = TxIntDelay[bd];
422*4882a593Smuzhiyun 			ixgb_validate_option(&adapter->tx_int_delay, &opt);
423*4882a593Smuzhiyun 		} else {
424*4882a593Smuzhiyun 			adapter->tx_int_delay = opt.def;
425*4882a593Smuzhiyun 		}
426*4882a593Smuzhiyun 	}
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	{ /* Transmit Interrupt Delay Enable */
429*4882a593Smuzhiyun 		static const struct ixgb_option opt = {
430*4882a593Smuzhiyun 			.type = enable_option,
431*4882a593Smuzhiyun 			.name = "Tx Interrupt Delay Enable",
432*4882a593Smuzhiyun 			.err  = "defaulting to Enabled",
433*4882a593Smuzhiyun 			.def  = OPTION_ENABLED
434*4882a593Smuzhiyun 		};
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 		if (num_IntDelayEnable > bd) {
437*4882a593Smuzhiyun 			unsigned int ide = IntDelayEnable[bd];
438*4882a593Smuzhiyun 			ixgb_validate_option(&ide, &opt);
439*4882a593Smuzhiyun 			adapter->tx_int_delay_enable = ide;
440*4882a593Smuzhiyun 		} else {
441*4882a593Smuzhiyun 			adapter->tx_int_delay_enable = opt.def;
442*4882a593Smuzhiyun 		}
443*4882a593Smuzhiyun 	}
444*4882a593Smuzhiyun }
445