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