e1000e: 82571 Serdes can fail to get link
[linux-2.6.git] / drivers / net / e1000e / param.c
index 8effc31..3d36911 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2008 Intel Corporation.
+  Copyright(c) 1999 - 2010 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -91,7 +91,6 @@ E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
  * Valid Range: 0-65535
  */
 E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
-#define DEFAULT_RDTR 0
 #define MAX_RXDELAY 0xFFFF
 #define MIN_RXDELAY 0
 
@@ -101,7 +100,6 @@ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
  * Valid Range: 0-65535
  */
 E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
-#define DEFAULT_RADV 8
 #define MAX_RXABSDELAY 0xFFFF
 #define MIN_RXABSDELAY 0
 
@@ -114,6 +112,15 @@ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
 #define DEFAULT_ITR 3
 #define MAX_ITR 100000
 #define MIN_ITR 100
+/* IntMode (Interrupt Mode)
+ *
+ * Valid Range: 0 - 2
+ *
+ * Default Value: 2 (MSI-X)
+ */
+E1000_PARAM(IntMode, "Interrupt Mode");
+#define MAX_INTMODE    2
+#define MIN_INTMODE    0
 
 /*
  * Enable Smart Power Down of the PHY
@@ -133,6 +140,25 @@ E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
  */
 E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");
 
+/*
+ * Write Protect NVM
+ *
+ * Valid Range: 0, 1
+ *
+ * Default Value: 1 (enabled)
+ */
+E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]");
+
+/*
+ * Enable CRC Stripping
+ *
+ * Valid Range: 0, 1
+ *
+ * Default Value: 1 (enabled)
+ */
+E1000_PARAM(CrcStripping, "Enable CRC Stripping, disable if your BMC needs " \
+                          "the CRC");
+
 struct e1000_option {
        enum { enable_option, range_option, list_option } type;
        const char *name;
@@ -220,7 +246,7 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
        }
 
        { /* Transmit Interrupt Delay */
-               const struct e1000_option opt = {
+               static const struct e1000_option opt = {
                        .type = range_option,
                        .name = "Transmit Interrupt Delay",
                        .err  = "using default of "
@@ -239,7 +265,7 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                }
        }
        { /* Transmit Absolute Interrupt Delay */
-               const struct e1000_option opt = {
+               static const struct e1000_option opt = {
                        .type = range_option,
                        .name = "Transmit Absolute Interrupt Delay",
                        .err  = "using default of "
@@ -258,7 +284,7 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                }
        }
        { /* Receive Interrupt Delay */
-               struct e1000_option opt = {
+               static struct e1000_option opt = {
                        .type = range_option,
                        .name = "Receive Interrupt Delay",
                        .err  = "using default of "
@@ -277,7 +303,7 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                }
        }
        { /* Receive Absolute Interrupt Delay */
-               const struct e1000_option opt = {
+               static const struct e1000_option opt = {
                        .type = range_option,
                        .name = "Receive Absolute Interrupt Delay",
                        .err  = "using default of "
@@ -296,7 +322,7 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                }
        }
        { /* Interrupt Throttling Rate */
-               const struct e1000_option opt = {
+               static const struct e1000_option opt = {
                        .type = range_option,
                        .name = "Interrupt Throttling Rate (ints/sec)",
                        .err  = "using default of "
@@ -323,15 +349,33 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                                adapter->itr_setting = adapter->itr;
                                adapter->itr = 20000;
                                break;
+                       case 4:
+                               e_info("%s set to simplified (2000-8000 ints) "
+                                      "mode\n", opt.name);
+                               adapter->itr_setting = 4;
+                               break;
                        default:
-                               e1000_validate_option(&adapter->itr, &opt,
-                                       adapter);
                                /*
-                                * save the setting, because the dynamic bits
-                                * change itr. clear the lower two bits
-                                * because they are used as control
+                                * Save the setting, because the dynamic bits
+                                * change itr.
                                 */
-                               adapter->itr_setting = adapter->itr & ~3;
+                               if (e1000_validate_option(&adapter->itr, &opt,
+                                                         adapter) &&
+                                   (adapter->itr == 3)) {
+                                       /*
+                                        * In case of invalid user value,
+                                        * default to conservative mode.
+                                        */
+                                       adapter->itr_setting = adapter->itr;
+                                       adapter->itr = 20000;
+                               } else {
+                                       /*
+                                        * Clear the lower two bits because
+                                        * they are used as control.
+                                        */
+                                       adapter->itr_setting =
+                                               adapter->itr & ~3;
+                               }
                                break;
                        }
                } else {
@@ -339,8 +383,26 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                        adapter->itr = 20000;
                }
        }
+       { /* Interrupt Mode */
+               static struct e1000_option opt = {
+                       .type = range_option,
+                       .name = "Interrupt Mode",
+                       .err  = "defaulting to 2 (MSI-X)",
+                       .def  = E1000E_INT_MODE_MSIX,
+                       .arg  = { .r = { .min = MIN_INTMODE,
+                                        .max = MAX_INTMODE } }
+               };
+
+               if (num_IntMode > bd) {
+                       unsigned int int_mode = IntMode[bd];
+                       e1000_validate_option(&int_mode, &opt, adapter);
+                       adapter->int_mode = int_mode;
+               } else {
+                       adapter->int_mode = opt.def;
+               }
+       }
        { /* Smart Power Down */
-               const struct e1000_option opt = {
+               static const struct e1000_option opt = {
                        .type = enable_option,
                        .name = "PHY Smart Power Down",
                        .err  = "defaulting to Disabled",
@@ -355,8 +417,25 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                                adapter->flags |= FLAG_SMART_POWER_DOWN;
                }
        }
+       { /* CRC Stripping */
+               static const struct e1000_option opt = {
+                       .type = enable_option,
+                       .name = "CRC Stripping",
+                       .err  = "defaulting to enabled",
+                       .def  = OPTION_ENABLED
+               };
+
+               if (num_CrcStripping > bd) {
+                       unsigned int crc_stripping = CrcStripping[bd];
+                       e1000_validate_option(&crc_stripping, &opt, adapter);
+                       if (crc_stripping == OPTION_ENABLED)
+                               adapter->flags2 |= FLAG2_CRC_STRIPPING;
+               } else {
+                       adapter->flags2 |= FLAG2_CRC_STRIPPING;
+               }
+       }
        { /* Kumeran Lock Loss Workaround */
-               const struct e1000_option opt = {
+               static const struct e1000_option opt = {
                        .type = enable_option,
                        .name = "Kumeran Lock Loss Workaround",
                        .err  = "defaulting to Enabled",
@@ -375,4 +454,25 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                                                                       opt.def);
                }
        }
+       { /* Write-protect NVM */
+               static const struct e1000_option opt = {
+                       .type = enable_option,
+                       .name = "Write-protect NVM",
+                       .err  = "defaulting to Enabled",
+                       .def  = OPTION_ENABLED
+               };
+
+               if (adapter->flags & FLAG_IS_ICH) {
+                       if (num_WriteProtectNVM > bd) {
+                               unsigned int write_protect_nvm = WriteProtectNVM[bd];
+                               e1000_validate_option(&write_protect_nvm, &opt,
+                                                     adapter);
+                               if (write_protect_nvm)
+                                       adapter->flags |= FLAG_READ_ONLY_NVM;
+                       } else {
+                               if (opt.def)
+                                       adapter->flags |= FLAG_READ_ONLY_NVM;
+                       }
+               }
+       }
 }