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