diff options
Diffstat (limited to 'drivers/net/e1000/e1000_param.c')
-rw-r--r-- | drivers/net/e1000/e1000_param.c | 199 |
1 files changed, 100 insertions, 99 deletions
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c index e55f8969a0fb..0ef413172c68 100644 --- a/drivers/net/e1000/e1000_param.c +++ b/drivers/net/e1000/e1000_param.c | |||
@@ -45,6 +45,16 @@ | |||
45 | */ | 45 | */ |
46 | 46 | ||
47 | #define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET } | 47 | #define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET } |
48 | /* Module Parameters are always initialized to -1, so that the driver | ||
49 | * can tell the difference between no user specified value or the | ||
50 | * user asking for the default value. | ||
51 | * The true default values are loaded in when e1000_check_options is called. | ||
52 | * | ||
53 | * This is a GCC extension to ANSI C. | ||
54 | * See the item "Labeled Elements in Initializers" in the section | ||
55 | * "Extensions to the C Language Family" of the GCC documentation. | ||
56 | */ | ||
57 | |||
48 | #define E1000_PARAM(X, desc) \ | 58 | #define E1000_PARAM(X, desc) \ |
49 | static int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \ | 59 | static int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \ |
50 | static int num_##X = 0; \ | 60 | static int num_##X = 0; \ |
@@ -183,6 +193,24 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); | |||
183 | 193 | ||
184 | E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); | 194 | E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); |
185 | 195 | ||
196 | /* Enable Smart Power Down of the PHY | ||
197 | * | ||
198 | * Valid Range: 0, 1 | ||
199 | * | ||
200 | * Default Value: 0 (disabled) | ||
201 | */ | ||
202 | |||
203 | E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down"); | ||
204 | |||
205 | /* Enable Kumeran Lock Loss workaround | ||
206 | * | ||
207 | * Valid Range: 0, 1 | ||
208 | * | ||
209 | * Default Value: 1 (enabled) | ||
210 | */ | ||
211 | |||
212 | E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); | ||
213 | |||
186 | #define AUTONEG_ADV_DEFAULT 0x2F | 214 | #define AUTONEG_ADV_DEFAULT 0x2F |
187 | #define AUTONEG_ADV_MASK 0x2F | 215 | #define AUTONEG_ADV_MASK 0x2F |
188 | #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL | 216 | #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL |
@@ -296,6 +324,7 @@ e1000_check_options(struct e1000_adapter *adapter) | |||
296 | DPRINTK(PROBE, NOTICE, | 324 | DPRINTK(PROBE, NOTICE, |
297 | "Warning: no configuration for board #%i\n", bd); | 325 | "Warning: no configuration for board #%i\n", bd); |
298 | DPRINTK(PROBE, NOTICE, "Using defaults for all values\n"); | 326 | DPRINTK(PROBE, NOTICE, "Using defaults for all values\n"); |
327 | bd = E1000_MAX_NIC; | ||
299 | } | 328 | } |
300 | 329 | ||
301 | { /* Transmit Descriptor Count */ | 330 | { /* Transmit Descriptor Count */ |
@@ -313,14 +342,9 @@ e1000_check_options(struct e1000_adapter *adapter) | |||
313 | opt.arg.r.max = mac_type < e1000_82544 ? | 342 | opt.arg.r.max = mac_type < e1000_82544 ? |
314 | E1000_MAX_TXD : E1000_MAX_82544_TXD; | 343 | E1000_MAX_TXD : E1000_MAX_82544_TXD; |
315 | 344 | ||
316 | if (num_TxDescriptors > bd) { | 345 | tx_ring->count = TxDescriptors[bd]; |
317 | tx_ring->count = TxDescriptors[bd]; | 346 | e1000_validate_option(&tx_ring->count, &opt, adapter); |
318 | e1000_validate_option(&tx_ring->count, &opt, adapter); | 347 | E1000_ROUNDUP(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE); |
319 | E1000_ROUNDUP(tx_ring->count, | ||
320 | REQ_TX_DESCRIPTOR_MULTIPLE); | ||
321 | } else { | ||
322 | tx_ring->count = opt.def; | ||
323 | } | ||
324 | for (i = 0; i < adapter->num_tx_queues; i++) | 348 | for (i = 0; i < adapter->num_tx_queues; i++) |
325 | tx_ring[i].count = tx_ring->count; | 349 | tx_ring[i].count = tx_ring->count; |
326 | } | 350 | } |
@@ -339,14 +363,9 @@ e1000_check_options(struct e1000_adapter *adapter) | |||
339 | opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD : | 363 | opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD : |
340 | E1000_MAX_82544_RXD; | 364 | E1000_MAX_82544_RXD; |
341 | 365 | ||
342 | if (num_RxDescriptors > bd) { | 366 | rx_ring->count = RxDescriptors[bd]; |
343 | rx_ring->count = RxDescriptors[bd]; | 367 | e1000_validate_option(&rx_ring->count, &opt, adapter); |
344 | e1000_validate_option(&rx_ring->count, &opt, adapter); | 368 | E1000_ROUNDUP(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE); |
345 | E1000_ROUNDUP(rx_ring->count, | ||
346 | REQ_RX_DESCRIPTOR_MULTIPLE); | ||
347 | } else { | ||
348 | rx_ring->count = opt.def; | ||
349 | } | ||
350 | for (i = 0; i < adapter->num_rx_queues; i++) | 369 | for (i = 0; i < adapter->num_rx_queues; i++) |
351 | rx_ring[i].count = rx_ring->count; | 370 | rx_ring[i].count = rx_ring->count; |
352 | } | 371 | } |
@@ -358,13 +377,9 @@ e1000_check_options(struct e1000_adapter *adapter) | |||
358 | .def = OPTION_ENABLED | 377 | .def = OPTION_ENABLED |
359 | }; | 378 | }; |
360 | 379 | ||
361 | if (num_XsumRX > bd) { | 380 | int rx_csum = XsumRX[bd]; |
362 | int rx_csum = XsumRX[bd]; | 381 | e1000_validate_option(&rx_csum, &opt, adapter); |
363 | e1000_validate_option(&rx_csum, &opt, adapter); | 382 | adapter->rx_csum = rx_csum; |
364 | adapter->rx_csum = rx_csum; | ||
365 | } else { | ||
366 | adapter->rx_csum = opt.def; | ||
367 | } | ||
368 | } | 383 | } |
369 | { /* Flow Control */ | 384 | { /* Flow Control */ |
370 | 385 | ||
@@ -384,13 +399,9 @@ e1000_check_options(struct e1000_adapter *adapter) | |||
384 | .p = fc_list }} | 399 | .p = fc_list }} |
385 | }; | 400 | }; |
386 | 401 | ||
387 | if (num_FlowControl > bd) { | 402 | int fc = FlowControl[bd]; |
388 | int fc = FlowControl[bd]; | 403 | e1000_validate_option(&fc, &opt, adapter); |
389 | e1000_validate_option(&fc, &opt, adapter); | 404 | adapter->hw.fc = adapter->hw.original_fc = fc; |
390 | adapter->hw.fc = adapter->hw.original_fc = fc; | ||
391 | } else { | ||
392 | adapter->hw.fc = adapter->hw.original_fc = opt.def; | ||
393 | } | ||
394 | } | 405 | } |
395 | { /* Transmit Interrupt Delay */ | 406 | { /* Transmit Interrupt Delay */ |
396 | struct e1000_option opt = { | 407 | struct e1000_option opt = { |
@@ -402,13 +413,8 @@ e1000_check_options(struct e1000_adapter *adapter) | |||
402 | .max = MAX_TXDELAY }} | 413 | .max = MAX_TXDELAY }} |
403 | }; | 414 | }; |
404 | 415 | ||
405 | if (num_TxIntDelay > bd) { | 416 | adapter->tx_int_delay = TxIntDelay[bd]; |
406 | adapter->tx_int_delay = TxIntDelay[bd]; | 417 | e1000_validate_option(&adapter->tx_int_delay, &opt, adapter); |
407 | e1000_validate_option(&adapter->tx_int_delay, &opt, | ||
408 | adapter); | ||
409 | } else { | ||
410 | adapter->tx_int_delay = opt.def; | ||
411 | } | ||
412 | } | 418 | } |
413 | { /* Transmit Absolute Interrupt Delay */ | 419 | { /* Transmit Absolute Interrupt Delay */ |
414 | struct e1000_option opt = { | 420 | struct e1000_option opt = { |
@@ -420,13 +426,9 @@ e1000_check_options(struct e1000_adapter *adapter) | |||
420 | .max = MAX_TXABSDELAY }} | 426 | .max = MAX_TXABSDELAY }} |
421 | }; | 427 | }; |
422 | 428 | ||
423 | if (num_TxAbsIntDelay > bd) { | 429 | adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; |
424 | adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; | 430 | e1000_validate_option(&adapter->tx_abs_int_delay, &opt, |
425 | e1000_validate_option(&adapter->tx_abs_int_delay, &opt, | 431 | adapter); |
426 | adapter); | ||
427 | } else { | ||
428 | adapter->tx_abs_int_delay = opt.def; | ||
429 | } | ||
430 | } | 432 | } |
431 | { /* Receive Interrupt Delay */ | 433 | { /* Receive Interrupt Delay */ |
432 | struct e1000_option opt = { | 434 | struct e1000_option opt = { |
@@ -438,13 +440,8 @@ e1000_check_options(struct e1000_adapter *adapter) | |||
438 | .max = MAX_RXDELAY }} | 440 | .max = MAX_RXDELAY }} |
439 | }; | 441 | }; |
440 | 442 | ||
441 | if (num_RxIntDelay > bd) { | 443 | adapter->rx_int_delay = RxIntDelay[bd]; |
442 | adapter->rx_int_delay = RxIntDelay[bd]; | 444 | e1000_validate_option(&adapter->rx_int_delay, &opt, adapter); |
443 | e1000_validate_option(&adapter->rx_int_delay, &opt, | ||
444 | adapter); | ||
445 | } else { | ||
446 | adapter->rx_int_delay = opt.def; | ||
447 | } | ||
448 | } | 445 | } |
449 | { /* Receive Absolute Interrupt Delay */ | 446 | { /* Receive Absolute Interrupt Delay */ |
450 | struct e1000_option opt = { | 447 | struct e1000_option opt = { |
@@ -456,13 +453,9 @@ e1000_check_options(struct e1000_adapter *adapter) | |||
456 | .max = MAX_RXABSDELAY }} | 453 | .max = MAX_RXABSDELAY }} |
457 | }; | 454 | }; |
458 | 455 | ||
459 | if (num_RxAbsIntDelay > bd) { | 456 | adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; |
460 | adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; | 457 | e1000_validate_option(&adapter->rx_abs_int_delay, &opt, |
461 | e1000_validate_option(&adapter->rx_abs_int_delay, &opt, | 458 | adapter); |
462 | adapter); | ||
463 | } else { | ||
464 | adapter->rx_abs_int_delay = opt.def; | ||
465 | } | ||
466 | } | 459 | } |
467 | { /* Interrupt Throttling Rate */ | 460 | { /* Interrupt Throttling Rate */ |
468 | struct e1000_option opt = { | 461 | struct e1000_option opt = { |
@@ -474,26 +467,44 @@ e1000_check_options(struct e1000_adapter *adapter) | |||
474 | .max = MAX_ITR }} | 467 | .max = MAX_ITR }} |
475 | }; | 468 | }; |
476 | 469 | ||
477 | if (num_InterruptThrottleRate > bd) { | 470 | adapter->itr = InterruptThrottleRate[bd]; |
478 | adapter->itr = InterruptThrottleRate[bd]; | 471 | switch (adapter->itr) { |
479 | switch (adapter->itr) { | 472 | case 0: |
480 | case 0: | 473 | DPRINTK(PROBE, INFO, "%s turned off\n", opt.name); |
481 | DPRINTK(PROBE, INFO, "%s turned off\n", | 474 | break; |
482 | opt.name); | 475 | case 1: |
483 | break; | 476 | DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", |
484 | case 1: | 477 | opt.name); |
485 | DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", | 478 | break; |
486 | opt.name); | 479 | default: |
487 | break; | 480 | e1000_validate_option(&adapter->itr, &opt, adapter); |
488 | default: | 481 | break; |
489 | e1000_validate_option(&adapter->itr, &opt, | ||
490 | adapter); | ||
491 | break; | ||
492 | } | ||
493 | } else { | ||
494 | adapter->itr = opt.def; | ||
495 | } | 482 | } |
496 | } | 483 | } |
484 | { /* Smart Power Down */ | ||
485 | struct e1000_option opt = { | ||
486 | .type = enable_option, | ||
487 | .name = "PHY Smart Power Down", | ||
488 | .err = "defaulting to Disabled", | ||
489 | .def = OPTION_DISABLED | ||
490 | }; | ||
491 | |||
492 | int spd = SmartPowerDownEnable[bd]; | ||
493 | e1000_validate_option(&spd, &opt, adapter); | ||
494 | adapter->smart_power_down = spd; | ||
495 | } | ||
496 | { /* Kumeran Lock Loss Workaround */ | ||
497 | struct e1000_option opt = { | ||
498 | .type = enable_option, | ||
499 | .name = "Kumeran Lock Loss Workaround", | ||
500 | .err = "defaulting to Enabled", | ||
501 | .def = OPTION_ENABLED | ||
502 | }; | ||
503 | |||
504 | int kmrn_lock_loss = KumeranLockLoss[bd]; | ||
505 | e1000_validate_option(&kmrn_lock_loss, &opt, adapter); | ||
506 | adapter->hw.kmrn_lock_loss_workaround_disabled = !kmrn_lock_loss; | ||
507 | } | ||
497 | 508 | ||
498 | switch (adapter->hw.media_type) { | 509 | switch (adapter->hw.media_type) { |
499 | case e1000_media_type_fiber: | 510 | case e1000_media_type_fiber: |
@@ -519,17 +530,18 @@ static void __devinit | |||
519 | e1000_check_fiber_options(struct e1000_adapter *adapter) | 530 | e1000_check_fiber_options(struct e1000_adapter *adapter) |
520 | { | 531 | { |
521 | int bd = adapter->bd_number; | 532 | int bd = adapter->bd_number; |
522 | if (num_Speed > bd) { | 533 | bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd; |
534 | if ((Speed[bd] != OPTION_UNSET)) { | ||
523 | DPRINTK(PROBE, INFO, "Speed not valid for fiber adapters, " | 535 | DPRINTK(PROBE, INFO, "Speed not valid for fiber adapters, " |
524 | "parameter ignored\n"); | 536 | "parameter ignored\n"); |
525 | } | 537 | } |
526 | 538 | ||
527 | if (num_Duplex > bd) { | 539 | if ((Duplex[bd] != OPTION_UNSET)) { |
528 | DPRINTK(PROBE, INFO, "Duplex not valid for fiber adapters, " | 540 | DPRINTK(PROBE, INFO, "Duplex not valid for fiber adapters, " |
529 | "parameter ignored\n"); | 541 | "parameter ignored\n"); |
530 | } | 542 | } |
531 | 543 | ||
532 | if ((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) { | 544 | if ((AutoNeg[bd] != OPTION_UNSET) && (AutoNeg[bd] != 0x20)) { |
533 | DPRINTK(PROBE, INFO, "AutoNeg other than 1000/Full is " | 545 | DPRINTK(PROBE, INFO, "AutoNeg other than 1000/Full is " |
534 | "not valid for fiber adapters, " | 546 | "not valid for fiber adapters, " |
535 | "parameter ignored\n"); | 547 | "parameter ignored\n"); |
@@ -548,6 +560,7 @@ e1000_check_copper_options(struct e1000_adapter *adapter) | |||
548 | { | 560 | { |
549 | int speed, dplx, an; | 561 | int speed, dplx, an; |
550 | int bd = adapter->bd_number; | 562 | int bd = adapter->bd_number; |
563 | bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd; | ||
551 | 564 | ||
552 | { /* Speed */ | 565 | { /* Speed */ |
553 | struct e1000_opt_list speed_list[] = {{ 0, "" }, | 566 | struct e1000_opt_list speed_list[] = {{ 0, "" }, |
@@ -564,12 +577,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter) | |||
564 | .p = speed_list }} | 577 | .p = speed_list }} |
565 | }; | 578 | }; |
566 | 579 | ||
567 | if (num_Speed > bd) { | 580 | speed = Speed[bd]; |
568 | speed = Speed[bd]; | 581 | e1000_validate_option(&speed, &opt, adapter); |
569 | e1000_validate_option(&speed, &opt, adapter); | ||
570 | } else { | ||
571 | speed = opt.def; | ||
572 | } | ||
573 | } | 582 | } |
574 | { /* Duplex */ | 583 | { /* Duplex */ |
575 | struct e1000_opt_list dplx_list[] = {{ 0, "" }, | 584 | struct e1000_opt_list dplx_list[] = {{ 0, "" }, |
@@ -591,15 +600,11 @@ e1000_check_copper_options(struct e1000_adapter *adapter) | |||
591 | "Speed/Duplex/AutoNeg parameter ignored.\n"); | 600 | "Speed/Duplex/AutoNeg parameter ignored.\n"); |
592 | return; | 601 | return; |
593 | } | 602 | } |
594 | if (num_Duplex > bd) { | 603 | dplx = Duplex[bd]; |
595 | dplx = Duplex[bd]; | 604 | e1000_validate_option(&dplx, &opt, adapter); |
596 | e1000_validate_option(&dplx, &opt, adapter); | ||
597 | } else { | ||
598 | dplx = opt.def; | ||
599 | } | ||
600 | } | 605 | } |
601 | 606 | ||
602 | if ((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) { | 607 | if (AutoNeg[bd] != OPTION_UNSET && (speed != 0 || dplx != 0)) { |
603 | DPRINTK(PROBE, INFO, | 608 | DPRINTK(PROBE, INFO, |
604 | "AutoNeg specified along with Speed or Duplex, " | 609 | "AutoNeg specified along with Speed or Duplex, " |
605 | "parameter ignored\n"); | 610 | "parameter ignored\n"); |
@@ -648,19 +653,15 @@ e1000_check_copper_options(struct e1000_adapter *adapter) | |||
648 | .p = an_list }} | 653 | .p = an_list }} |
649 | }; | 654 | }; |
650 | 655 | ||
651 | if (num_AutoNeg > bd) { | 656 | an = AutoNeg[bd]; |
652 | an = AutoNeg[bd]; | 657 | e1000_validate_option(&an, &opt, adapter); |
653 | e1000_validate_option(&an, &opt, adapter); | ||
654 | } else { | ||
655 | an = opt.def; | ||
656 | } | ||
657 | adapter->hw.autoneg_advertised = an; | 658 | adapter->hw.autoneg_advertised = an; |
658 | } | 659 | } |
659 | 660 | ||
660 | switch (speed + dplx) { | 661 | switch (speed + dplx) { |
661 | case 0: | 662 | case 0: |
662 | adapter->hw.autoneg = adapter->fc_autoneg = 1; | 663 | adapter->hw.autoneg = adapter->fc_autoneg = 1; |
663 | if ((num_Speed > bd) && (speed != 0 || dplx != 0)) | 664 | if (Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET) |
664 | DPRINTK(PROBE, INFO, | 665 | DPRINTK(PROBE, INFO, |
665 | "Speed and duplex autonegotiation enabled\n"); | 666 | "Speed and duplex autonegotiation enabled\n"); |
666 | break; | 667 | break; |