162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 1999 - 2006 Intel Corporation. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "e1000.h" 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci/* This is the only thing that needs to be changed to adjust the 762306a36Sopenharmony_ci * maximum number of ports that the driver can manage. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#define E1000_MAX_NIC 32 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define OPTION_UNSET -1 1362306a36Sopenharmony_ci#define OPTION_DISABLED 0 1462306a36Sopenharmony_ci#define OPTION_ENABLED 1 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* All parameters are treated the same, as an integer array of values. 1762306a36Sopenharmony_ci * This macro just reduces the need to repeat the same declaration code 1862306a36Sopenharmony_ci * over and over (plus this helps to avoid typo bugs). 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET } 2262306a36Sopenharmony_ci#define E1000_PARAM(X, desc) \ 2362306a36Sopenharmony_ci static int X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \ 2462306a36Sopenharmony_ci static unsigned int num_##X; \ 2562306a36Sopenharmony_ci module_param_array_named(X, X, int, &num_##X, 0); \ 2662306a36Sopenharmony_ci MODULE_PARM_DESC(X, desc); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* Transmit Descriptor Count 2962306a36Sopenharmony_ci * 3062306a36Sopenharmony_ci * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers 3162306a36Sopenharmony_ci * Valid Range: 80-4096 for 82544 and newer 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci * Default Value: 256 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_ciE1000_PARAM(TxDescriptors, "Number of transmit descriptors"); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* Receive Descriptor Count 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers 4062306a36Sopenharmony_ci * Valid Range: 80-4096 for 82544 and newer 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * Default Value: 256 4362306a36Sopenharmony_ci */ 4462306a36Sopenharmony_ciE1000_PARAM(RxDescriptors, "Number of receive descriptors"); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* User Specified Speed Override 4762306a36Sopenharmony_ci * 4862306a36Sopenharmony_ci * Valid Range: 0, 10, 100, 1000 4962306a36Sopenharmony_ci * - 0 - auto-negotiate at all supported speeds 5062306a36Sopenharmony_ci * - 10 - only link at 10 Mbps 5162306a36Sopenharmony_ci * - 100 - only link at 100 Mbps 5262306a36Sopenharmony_ci * - 1000 - only link at 1000 Mbps 5362306a36Sopenharmony_ci * 5462306a36Sopenharmony_ci * Default Value: 0 5562306a36Sopenharmony_ci */ 5662306a36Sopenharmony_ciE1000_PARAM(Speed, "Speed setting"); 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/* User Specified Duplex Override 5962306a36Sopenharmony_ci * 6062306a36Sopenharmony_ci * Valid Range: 0-2 6162306a36Sopenharmony_ci * - 0 - auto-negotiate for duplex 6262306a36Sopenharmony_ci * - 1 - only link at half duplex 6362306a36Sopenharmony_ci * - 2 - only link at full duplex 6462306a36Sopenharmony_ci * 6562306a36Sopenharmony_ci * Default Value: 0 6662306a36Sopenharmony_ci */ 6762306a36Sopenharmony_ciE1000_PARAM(Duplex, "Duplex setting"); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* Auto-negotiation Advertisement Override 7062306a36Sopenharmony_ci * 7162306a36Sopenharmony_ci * Valid Range: 0x01-0x0F, 0x20-0x2F (copper); 0x20 (fiber) 7262306a36Sopenharmony_ci * 7362306a36Sopenharmony_ci * The AutoNeg value is a bit mask describing which speed and duplex 7462306a36Sopenharmony_ci * combinations should be advertised during auto-negotiation. 7562306a36Sopenharmony_ci * The supported speed and duplex modes are listed below 7662306a36Sopenharmony_ci * 7762306a36Sopenharmony_ci * Bit 7 6 5 4 3 2 1 0 7862306a36Sopenharmony_ci * Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10 7962306a36Sopenharmony_ci * Duplex Full Full Half Full Half 8062306a36Sopenharmony_ci * 8162306a36Sopenharmony_ci * Default Value: 0x2F (copper); 0x20 (fiber) 8262306a36Sopenharmony_ci */ 8362306a36Sopenharmony_ciE1000_PARAM(AutoNeg, "Advertised auto-negotiation setting"); 8462306a36Sopenharmony_ci#define AUTONEG_ADV_DEFAULT 0x2F 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* User Specified Flow Control Override 8762306a36Sopenharmony_ci * 8862306a36Sopenharmony_ci * Valid Range: 0-3 8962306a36Sopenharmony_ci * - 0 - No Flow Control 9062306a36Sopenharmony_ci * - 1 - Rx only, respond to PAUSE frames but do not generate them 9162306a36Sopenharmony_ci * - 2 - Tx only, generate PAUSE frames but ignore them on receive 9262306a36Sopenharmony_ci * - 3 - Full Flow Control Support 9362306a36Sopenharmony_ci * 9462306a36Sopenharmony_ci * Default Value: Read flow control settings from the EEPROM 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_ciE1000_PARAM(FlowControl, "Flow Control setting"); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci/* XsumRX - Receive Checksum Offload Enable/Disable 9962306a36Sopenharmony_ci * 10062306a36Sopenharmony_ci * Valid Range: 0, 1 10162306a36Sopenharmony_ci * - 0 - disables all checksum offload 10262306a36Sopenharmony_ci * - 1 - enables receive IP/TCP/UDP checksum offload 10362306a36Sopenharmony_ci * on 82543 and newer -based NICs 10462306a36Sopenharmony_ci * 10562306a36Sopenharmony_ci * Default Value: 1 10662306a36Sopenharmony_ci */ 10762306a36Sopenharmony_ciE1000_PARAM(XsumRX, "Disable or enable Receive Checksum offload"); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* Transmit Interrupt Delay in units of 1.024 microseconds 11062306a36Sopenharmony_ci * Tx interrupt delay needs to typically be set to something non zero 11162306a36Sopenharmony_ci * 11262306a36Sopenharmony_ci * Valid Range: 0-65535 11362306a36Sopenharmony_ci */ 11462306a36Sopenharmony_ciE1000_PARAM(TxIntDelay, "Transmit Interrupt Delay"); 11562306a36Sopenharmony_ci#define DEFAULT_TIDV 8 11662306a36Sopenharmony_ci#define MAX_TXDELAY 0xFFFF 11762306a36Sopenharmony_ci#define MIN_TXDELAY 0 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci/* Transmit Absolute Interrupt Delay in units of 1.024 microseconds 12062306a36Sopenharmony_ci * 12162306a36Sopenharmony_ci * Valid Range: 0-65535 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_ciE1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay"); 12462306a36Sopenharmony_ci#define DEFAULT_TADV 32 12562306a36Sopenharmony_ci#define MAX_TXABSDELAY 0xFFFF 12662306a36Sopenharmony_ci#define MIN_TXABSDELAY 0 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci/* Receive Interrupt Delay in units of 1.024 microseconds 12962306a36Sopenharmony_ci * hardware will likely hang if you set this to anything but zero. 13062306a36Sopenharmony_ci * 13162306a36Sopenharmony_ci * Valid Range: 0-65535 13262306a36Sopenharmony_ci */ 13362306a36Sopenharmony_ciE1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); 13462306a36Sopenharmony_ci#define DEFAULT_RDTR 0 13562306a36Sopenharmony_ci#define MAX_RXDELAY 0xFFFF 13662306a36Sopenharmony_ci#define MIN_RXDELAY 0 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci/* Receive Absolute Interrupt Delay in units of 1.024 microseconds 13962306a36Sopenharmony_ci * 14062306a36Sopenharmony_ci * Valid Range: 0-65535 14162306a36Sopenharmony_ci */ 14262306a36Sopenharmony_ciE1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); 14362306a36Sopenharmony_ci#define DEFAULT_RADV 8 14462306a36Sopenharmony_ci#define MAX_RXABSDELAY 0xFFFF 14562306a36Sopenharmony_ci#define MIN_RXABSDELAY 0 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci/* Interrupt Throttle Rate (interrupts/sec) 14862306a36Sopenharmony_ci * 14962306a36Sopenharmony_ci * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative) 15062306a36Sopenharmony_ci */ 15162306a36Sopenharmony_ciE1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); 15262306a36Sopenharmony_ci#define DEFAULT_ITR 3 15362306a36Sopenharmony_ci#define MAX_ITR 100000 15462306a36Sopenharmony_ci#define MIN_ITR 100 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci/* Enable Smart Power Down of the PHY 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * Valid Range: 0, 1 15962306a36Sopenharmony_ci * 16062306a36Sopenharmony_ci * Default Value: 0 (disabled) 16162306a36Sopenharmony_ci */ 16262306a36Sopenharmony_ciE1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down"); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_cistruct e1000_option { 16562306a36Sopenharmony_ci enum { enable_option, range_option, list_option } type; 16662306a36Sopenharmony_ci const char *name; 16762306a36Sopenharmony_ci const char *err; 16862306a36Sopenharmony_ci int def; 16962306a36Sopenharmony_ci union { 17062306a36Sopenharmony_ci struct { /* range_option info */ 17162306a36Sopenharmony_ci int min; 17262306a36Sopenharmony_ci int max; 17362306a36Sopenharmony_ci } r; 17462306a36Sopenharmony_ci struct { /* list_option info */ 17562306a36Sopenharmony_ci int nr; 17662306a36Sopenharmony_ci const struct e1000_opt_list { int i; char *str; } *p; 17762306a36Sopenharmony_ci } l; 17862306a36Sopenharmony_ci } arg; 17962306a36Sopenharmony_ci}; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cistatic int e1000_validate_option(unsigned int *value, 18262306a36Sopenharmony_ci const struct e1000_option *opt, 18362306a36Sopenharmony_ci struct e1000_adapter *adapter) 18462306a36Sopenharmony_ci{ 18562306a36Sopenharmony_ci if (*value == OPTION_UNSET) { 18662306a36Sopenharmony_ci *value = opt->def; 18762306a36Sopenharmony_ci return 0; 18862306a36Sopenharmony_ci } 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci switch (opt->type) { 19162306a36Sopenharmony_ci case enable_option: 19262306a36Sopenharmony_ci switch (*value) { 19362306a36Sopenharmony_ci case OPTION_ENABLED: 19462306a36Sopenharmony_ci e_dev_info("%s Enabled\n", opt->name); 19562306a36Sopenharmony_ci return 0; 19662306a36Sopenharmony_ci case OPTION_DISABLED: 19762306a36Sopenharmony_ci e_dev_info("%s Disabled\n", opt->name); 19862306a36Sopenharmony_ci return 0; 19962306a36Sopenharmony_ci } 20062306a36Sopenharmony_ci break; 20162306a36Sopenharmony_ci case range_option: 20262306a36Sopenharmony_ci if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { 20362306a36Sopenharmony_ci e_dev_info("%s set to %i\n", opt->name, *value); 20462306a36Sopenharmony_ci return 0; 20562306a36Sopenharmony_ci } 20662306a36Sopenharmony_ci break; 20762306a36Sopenharmony_ci case list_option: { 20862306a36Sopenharmony_ci int i; 20962306a36Sopenharmony_ci const struct e1000_opt_list *ent; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci for (i = 0; i < opt->arg.l.nr; i++) { 21262306a36Sopenharmony_ci ent = &opt->arg.l.p[i]; 21362306a36Sopenharmony_ci if (*value == ent->i) { 21462306a36Sopenharmony_ci if (ent->str[0] != '\0') 21562306a36Sopenharmony_ci e_dev_info("%s\n", ent->str); 21662306a36Sopenharmony_ci return 0; 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci } 21962306a36Sopenharmony_ci } 22062306a36Sopenharmony_ci break; 22162306a36Sopenharmony_ci default: 22262306a36Sopenharmony_ci BUG(); 22362306a36Sopenharmony_ci } 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci e_dev_info("Invalid %s value specified (%i) %s\n", 22662306a36Sopenharmony_ci opt->name, *value, opt->err); 22762306a36Sopenharmony_ci *value = opt->def; 22862306a36Sopenharmony_ci return -1; 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic void e1000_check_fiber_options(struct e1000_adapter *adapter); 23262306a36Sopenharmony_cistatic void e1000_check_copper_options(struct e1000_adapter *adapter); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci/** 23562306a36Sopenharmony_ci * e1000_check_options - Range Checking for Command Line Parameters 23662306a36Sopenharmony_ci * @adapter: board private structure 23762306a36Sopenharmony_ci * 23862306a36Sopenharmony_ci * This routine checks all command line parameters for valid user 23962306a36Sopenharmony_ci * input. If an invalid value is given, or if no user specified 24062306a36Sopenharmony_ci * value exists, a default value is used. The final value is stored 24162306a36Sopenharmony_ci * in a variable in the adapter structure. 24262306a36Sopenharmony_ci **/ 24362306a36Sopenharmony_civoid e1000_check_options(struct e1000_adapter *adapter) 24462306a36Sopenharmony_ci{ 24562306a36Sopenharmony_ci struct e1000_option opt; 24662306a36Sopenharmony_ci int bd = adapter->bd_number; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci if (bd >= E1000_MAX_NIC) { 24962306a36Sopenharmony_ci e_dev_warn("Warning: no configuration for board #%i " 25062306a36Sopenharmony_ci "using defaults for all values\n", bd); 25162306a36Sopenharmony_ci } 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci { /* Transmit Descriptor Count */ 25462306a36Sopenharmony_ci struct e1000_tx_ring *tx_ring = adapter->tx_ring; 25562306a36Sopenharmony_ci int i; 25662306a36Sopenharmony_ci e1000_mac_type mac_type = adapter->hw.mac_type; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci opt = (struct e1000_option) { 25962306a36Sopenharmony_ci .type = range_option, 26062306a36Sopenharmony_ci .name = "Transmit Descriptors", 26162306a36Sopenharmony_ci .err = "using default of " 26262306a36Sopenharmony_ci __MODULE_STRING(E1000_DEFAULT_TXD), 26362306a36Sopenharmony_ci .def = E1000_DEFAULT_TXD, 26462306a36Sopenharmony_ci .arg = { .r = { 26562306a36Sopenharmony_ci .min = E1000_MIN_TXD, 26662306a36Sopenharmony_ci .max = mac_type < e1000_82544 ? E1000_MAX_TXD : E1000_MAX_82544_TXD 26762306a36Sopenharmony_ci }} 26862306a36Sopenharmony_ci }; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci if (num_TxDescriptors > bd) { 27162306a36Sopenharmony_ci tx_ring->count = TxDescriptors[bd]; 27262306a36Sopenharmony_ci e1000_validate_option(&tx_ring->count, &opt, adapter); 27362306a36Sopenharmony_ci tx_ring->count = ALIGN(tx_ring->count, 27462306a36Sopenharmony_ci REQ_TX_DESCRIPTOR_MULTIPLE); 27562306a36Sopenharmony_ci } else { 27662306a36Sopenharmony_ci tx_ring->count = opt.def; 27762306a36Sopenharmony_ci } 27862306a36Sopenharmony_ci for (i = 0; i < adapter->num_tx_queues; i++) 27962306a36Sopenharmony_ci tx_ring[i].count = tx_ring->count; 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci { /* Receive Descriptor Count */ 28262306a36Sopenharmony_ci struct e1000_rx_ring *rx_ring = adapter->rx_ring; 28362306a36Sopenharmony_ci int i; 28462306a36Sopenharmony_ci e1000_mac_type mac_type = adapter->hw.mac_type; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci opt = (struct e1000_option) { 28762306a36Sopenharmony_ci .type = range_option, 28862306a36Sopenharmony_ci .name = "Receive Descriptors", 28962306a36Sopenharmony_ci .err = "using default of " 29062306a36Sopenharmony_ci __MODULE_STRING(E1000_DEFAULT_RXD), 29162306a36Sopenharmony_ci .def = E1000_DEFAULT_RXD, 29262306a36Sopenharmony_ci .arg = { .r = { 29362306a36Sopenharmony_ci .min = E1000_MIN_RXD, 29462306a36Sopenharmony_ci .max = mac_type < e1000_82544 ? E1000_MAX_RXD : 29562306a36Sopenharmony_ci E1000_MAX_82544_RXD 29662306a36Sopenharmony_ci }} 29762306a36Sopenharmony_ci }; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci if (num_RxDescriptors > bd) { 30062306a36Sopenharmony_ci rx_ring->count = RxDescriptors[bd]; 30162306a36Sopenharmony_ci e1000_validate_option(&rx_ring->count, &opt, adapter); 30262306a36Sopenharmony_ci rx_ring->count = ALIGN(rx_ring->count, 30362306a36Sopenharmony_ci REQ_RX_DESCRIPTOR_MULTIPLE); 30462306a36Sopenharmony_ci } else { 30562306a36Sopenharmony_ci rx_ring->count = opt.def; 30662306a36Sopenharmony_ci } 30762306a36Sopenharmony_ci for (i = 0; i < adapter->num_rx_queues; i++) 30862306a36Sopenharmony_ci rx_ring[i].count = rx_ring->count; 30962306a36Sopenharmony_ci } 31062306a36Sopenharmony_ci { /* Checksum Offload Enable/Disable */ 31162306a36Sopenharmony_ci opt = (struct e1000_option) { 31262306a36Sopenharmony_ci .type = enable_option, 31362306a36Sopenharmony_ci .name = "Checksum Offload", 31462306a36Sopenharmony_ci .err = "defaulting to Enabled", 31562306a36Sopenharmony_ci .def = OPTION_ENABLED 31662306a36Sopenharmony_ci }; 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci if (num_XsumRX > bd) { 31962306a36Sopenharmony_ci unsigned int rx_csum = XsumRX[bd]; 32062306a36Sopenharmony_ci e1000_validate_option(&rx_csum, &opt, adapter); 32162306a36Sopenharmony_ci adapter->rx_csum = rx_csum; 32262306a36Sopenharmony_ci } else { 32362306a36Sopenharmony_ci adapter->rx_csum = opt.def; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci } 32662306a36Sopenharmony_ci { /* Flow Control */ 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci static const struct e1000_opt_list fc_list[] = { 32962306a36Sopenharmony_ci { E1000_FC_NONE, "Flow Control Disabled" }, 33062306a36Sopenharmony_ci { E1000_FC_RX_PAUSE, "Flow Control Receive Only" }, 33162306a36Sopenharmony_ci { E1000_FC_TX_PAUSE, "Flow Control Transmit Only" }, 33262306a36Sopenharmony_ci { E1000_FC_FULL, "Flow Control Enabled" }, 33362306a36Sopenharmony_ci { E1000_FC_DEFAULT, "Flow Control Hardware Default" } 33462306a36Sopenharmony_ci }; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci opt = (struct e1000_option) { 33762306a36Sopenharmony_ci .type = list_option, 33862306a36Sopenharmony_ci .name = "Flow Control", 33962306a36Sopenharmony_ci .err = "reading default settings from EEPROM", 34062306a36Sopenharmony_ci .def = E1000_FC_DEFAULT, 34162306a36Sopenharmony_ci .arg = { .l = { .nr = ARRAY_SIZE(fc_list), 34262306a36Sopenharmony_ci .p = fc_list }} 34362306a36Sopenharmony_ci }; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci if (num_FlowControl > bd) { 34662306a36Sopenharmony_ci unsigned int fc = FlowControl[bd]; 34762306a36Sopenharmony_ci e1000_validate_option(&fc, &opt, adapter); 34862306a36Sopenharmony_ci adapter->hw.fc = adapter->hw.original_fc = fc; 34962306a36Sopenharmony_ci } else { 35062306a36Sopenharmony_ci adapter->hw.fc = adapter->hw.original_fc = opt.def; 35162306a36Sopenharmony_ci } 35262306a36Sopenharmony_ci } 35362306a36Sopenharmony_ci { /* Transmit Interrupt Delay */ 35462306a36Sopenharmony_ci opt = (struct e1000_option) { 35562306a36Sopenharmony_ci .type = range_option, 35662306a36Sopenharmony_ci .name = "Transmit Interrupt Delay", 35762306a36Sopenharmony_ci .err = "using default of " __MODULE_STRING(DEFAULT_TIDV), 35862306a36Sopenharmony_ci .def = DEFAULT_TIDV, 35962306a36Sopenharmony_ci .arg = { .r = { .min = MIN_TXDELAY, 36062306a36Sopenharmony_ci .max = MAX_TXDELAY }} 36162306a36Sopenharmony_ci }; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci if (num_TxIntDelay > bd) { 36462306a36Sopenharmony_ci adapter->tx_int_delay = TxIntDelay[bd]; 36562306a36Sopenharmony_ci e1000_validate_option(&adapter->tx_int_delay, &opt, 36662306a36Sopenharmony_ci adapter); 36762306a36Sopenharmony_ci } else { 36862306a36Sopenharmony_ci adapter->tx_int_delay = opt.def; 36962306a36Sopenharmony_ci } 37062306a36Sopenharmony_ci } 37162306a36Sopenharmony_ci { /* Transmit Absolute Interrupt Delay */ 37262306a36Sopenharmony_ci opt = (struct e1000_option) { 37362306a36Sopenharmony_ci .type = range_option, 37462306a36Sopenharmony_ci .name = "Transmit Absolute Interrupt Delay", 37562306a36Sopenharmony_ci .err = "using default of " __MODULE_STRING(DEFAULT_TADV), 37662306a36Sopenharmony_ci .def = DEFAULT_TADV, 37762306a36Sopenharmony_ci .arg = { .r = { .min = MIN_TXABSDELAY, 37862306a36Sopenharmony_ci .max = MAX_TXABSDELAY }} 37962306a36Sopenharmony_ci }; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci if (num_TxAbsIntDelay > bd) { 38262306a36Sopenharmony_ci adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; 38362306a36Sopenharmony_ci e1000_validate_option(&adapter->tx_abs_int_delay, &opt, 38462306a36Sopenharmony_ci adapter); 38562306a36Sopenharmony_ci } else { 38662306a36Sopenharmony_ci adapter->tx_abs_int_delay = opt.def; 38762306a36Sopenharmony_ci } 38862306a36Sopenharmony_ci } 38962306a36Sopenharmony_ci { /* Receive Interrupt Delay */ 39062306a36Sopenharmony_ci opt = (struct e1000_option) { 39162306a36Sopenharmony_ci .type = range_option, 39262306a36Sopenharmony_ci .name = "Receive Interrupt Delay", 39362306a36Sopenharmony_ci .err = "using default of " __MODULE_STRING(DEFAULT_RDTR), 39462306a36Sopenharmony_ci .def = DEFAULT_RDTR, 39562306a36Sopenharmony_ci .arg = { .r = { .min = MIN_RXDELAY, 39662306a36Sopenharmony_ci .max = MAX_RXDELAY }} 39762306a36Sopenharmony_ci }; 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci if (num_RxIntDelay > bd) { 40062306a36Sopenharmony_ci adapter->rx_int_delay = RxIntDelay[bd]; 40162306a36Sopenharmony_ci e1000_validate_option(&adapter->rx_int_delay, &opt, 40262306a36Sopenharmony_ci adapter); 40362306a36Sopenharmony_ci } else { 40462306a36Sopenharmony_ci adapter->rx_int_delay = opt.def; 40562306a36Sopenharmony_ci } 40662306a36Sopenharmony_ci } 40762306a36Sopenharmony_ci { /* Receive Absolute Interrupt Delay */ 40862306a36Sopenharmony_ci opt = (struct e1000_option) { 40962306a36Sopenharmony_ci .type = range_option, 41062306a36Sopenharmony_ci .name = "Receive Absolute Interrupt Delay", 41162306a36Sopenharmony_ci .err = "using default of " __MODULE_STRING(DEFAULT_RADV), 41262306a36Sopenharmony_ci .def = DEFAULT_RADV, 41362306a36Sopenharmony_ci .arg = { .r = { .min = MIN_RXABSDELAY, 41462306a36Sopenharmony_ci .max = MAX_RXABSDELAY }} 41562306a36Sopenharmony_ci }; 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci if (num_RxAbsIntDelay > bd) { 41862306a36Sopenharmony_ci adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; 41962306a36Sopenharmony_ci e1000_validate_option(&adapter->rx_abs_int_delay, &opt, 42062306a36Sopenharmony_ci adapter); 42162306a36Sopenharmony_ci } else { 42262306a36Sopenharmony_ci adapter->rx_abs_int_delay = opt.def; 42362306a36Sopenharmony_ci } 42462306a36Sopenharmony_ci } 42562306a36Sopenharmony_ci { /* Interrupt Throttling Rate */ 42662306a36Sopenharmony_ci opt = (struct e1000_option) { 42762306a36Sopenharmony_ci .type = range_option, 42862306a36Sopenharmony_ci .name = "Interrupt Throttling Rate (ints/sec)", 42962306a36Sopenharmony_ci .err = "using default of " __MODULE_STRING(DEFAULT_ITR), 43062306a36Sopenharmony_ci .def = DEFAULT_ITR, 43162306a36Sopenharmony_ci .arg = { .r = { .min = MIN_ITR, 43262306a36Sopenharmony_ci .max = MAX_ITR }} 43362306a36Sopenharmony_ci }; 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci if (num_InterruptThrottleRate > bd) { 43662306a36Sopenharmony_ci adapter->itr = InterruptThrottleRate[bd]; 43762306a36Sopenharmony_ci switch (adapter->itr) { 43862306a36Sopenharmony_ci case 0: 43962306a36Sopenharmony_ci e_dev_info("%s turned off\n", opt.name); 44062306a36Sopenharmony_ci break; 44162306a36Sopenharmony_ci case 1: 44262306a36Sopenharmony_ci e_dev_info("%s set to dynamic mode\n", 44362306a36Sopenharmony_ci opt.name); 44462306a36Sopenharmony_ci adapter->itr_setting = adapter->itr; 44562306a36Sopenharmony_ci adapter->itr = 20000; 44662306a36Sopenharmony_ci break; 44762306a36Sopenharmony_ci case 3: 44862306a36Sopenharmony_ci e_dev_info("%s set to dynamic conservative " 44962306a36Sopenharmony_ci "mode\n", opt.name); 45062306a36Sopenharmony_ci adapter->itr_setting = adapter->itr; 45162306a36Sopenharmony_ci adapter->itr = 20000; 45262306a36Sopenharmony_ci break; 45362306a36Sopenharmony_ci case 4: 45462306a36Sopenharmony_ci e_dev_info("%s set to simplified " 45562306a36Sopenharmony_ci "(2000-8000) ints mode\n", opt.name); 45662306a36Sopenharmony_ci adapter->itr_setting = adapter->itr; 45762306a36Sopenharmony_ci break; 45862306a36Sopenharmony_ci default: 45962306a36Sopenharmony_ci e1000_validate_option(&adapter->itr, &opt, 46062306a36Sopenharmony_ci adapter); 46162306a36Sopenharmony_ci /* save the setting, because the dynamic bits 46262306a36Sopenharmony_ci * change itr. 46362306a36Sopenharmony_ci * clear the lower two bits because they are 46462306a36Sopenharmony_ci * used as control 46562306a36Sopenharmony_ci */ 46662306a36Sopenharmony_ci adapter->itr_setting = adapter->itr & ~3; 46762306a36Sopenharmony_ci break; 46862306a36Sopenharmony_ci } 46962306a36Sopenharmony_ci } else { 47062306a36Sopenharmony_ci adapter->itr_setting = opt.def; 47162306a36Sopenharmony_ci adapter->itr = 20000; 47262306a36Sopenharmony_ci } 47362306a36Sopenharmony_ci } 47462306a36Sopenharmony_ci { /* Smart Power Down */ 47562306a36Sopenharmony_ci opt = (struct e1000_option) { 47662306a36Sopenharmony_ci .type = enable_option, 47762306a36Sopenharmony_ci .name = "PHY Smart Power Down", 47862306a36Sopenharmony_ci .err = "defaulting to Disabled", 47962306a36Sopenharmony_ci .def = OPTION_DISABLED 48062306a36Sopenharmony_ci }; 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci if (num_SmartPowerDownEnable > bd) { 48362306a36Sopenharmony_ci unsigned int spd = SmartPowerDownEnable[bd]; 48462306a36Sopenharmony_ci e1000_validate_option(&spd, &opt, adapter); 48562306a36Sopenharmony_ci adapter->smart_power_down = spd; 48662306a36Sopenharmony_ci } else { 48762306a36Sopenharmony_ci adapter->smart_power_down = opt.def; 48862306a36Sopenharmony_ci } 48962306a36Sopenharmony_ci } 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci switch (adapter->hw.media_type) { 49262306a36Sopenharmony_ci case e1000_media_type_fiber: 49362306a36Sopenharmony_ci case e1000_media_type_internal_serdes: 49462306a36Sopenharmony_ci e1000_check_fiber_options(adapter); 49562306a36Sopenharmony_ci break; 49662306a36Sopenharmony_ci case e1000_media_type_copper: 49762306a36Sopenharmony_ci e1000_check_copper_options(adapter); 49862306a36Sopenharmony_ci break; 49962306a36Sopenharmony_ci default: 50062306a36Sopenharmony_ci BUG(); 50162306a36Sopenharmony_ci } 50262306a36Sopenharmony_ci} 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci/** 50562306a36Sopenharmony_ci * e1000_check_fiber_options - Range Checking for Link Options, Fiber Version 50662306a36Sopenharmony_ci * @adapter: board private structure 50762306a36Sopenharmony_ci * 50862306a36Sopenharmony_ci * Handles speed and duplex options on fiber adapters 50962306a36Sopenharmony_ci **/ 51062306a36Sopenharmony_cistatic void e1000_check_fiber_options(struct e1000_adapter *adapter) 51162306a36Sopenharmony_ci{ 51262306a36Sopenharmony_ci int bd = adapter->bd_number; 51362306a36Sopenharmony_ci if (num_Speed > bd) { 51462306a36Sopenharmony_ci e_dev_info("Speed not valid for fiber adapters, parameter " 51562306a36Sopenharmony_ci "ignored\n"); 51662306a36Sopenharmony_ci } 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci if (num_Duplex > bd) { 51962306a36Sopenharmony_ci e_dev_info("Duplex not valid for fiber adapters, parameter " 52062306a36Sopenharmony_ci "ignored\n"); 52162306a36Sopenharmony_ci } 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci if ((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) { 52462306a36Sopenharmony_ci e_dev_info("AutoNeg other than 1000/Full is not valid for fiber" 52562306a36Sopenharmony_ci "adapters, parameter ignored\n"); 52662306a36Sopenharmony_ci } 52762306a36Sopenharmony_ci} 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci/** 53062306a36Sopenharmony_ci * e1000_check_copper_options - Range Checking for Link Options, Copper Version 53162306a36Sopenharmony_ci * @adapter: board private structure 53262306a36Sopenharmony_ci * 53362306a36Sopenharmony_ci * Handles speed and duplex options on copper adapters 53462306a36Sopenharmony_ci **/ 53562306a36Sopenharmony_cistatic void e1000_check_copper_options(struct e1000_adapter *adapter) 53662306a36Sopenharmony_ci{ 53762306a36Sopenharmony_ci struct e1000_option opt; 53862306a36Sopenharmony_ci unsigned int speed, dplx, an; 53962306a36Sopenharmony_ci int bd = adapter->bd_number; 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci { /* Speed */ 54262306a36Sopenharmony_ci static const struct e1000_opt_list speed_list[] = { 54362306a36Sopenharmony_ci { 0, "" }, 54462306a36Sopenharmony_ci { SPEED_10, "" }, 54562306a36Sopenharmony_ci { SPEED_100, "" }, 54662306a36Sopenharmony_ci { SPEED_1000, "" }}; 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci opt = (struct e1000_option) { 54962306a36Sopenharmony_ci .type = list_option, 55062306a36Sopenharmony_ci .name = "Speed", 55162306a36Sopenharmony_ci .err = "parameter ignored", 55262306a36Sopenharmony_ci .def = 0, 55362306a36Sopenharmony_ci .arg = { .l = { .nr = ARRAY_SIZE(speed_list), 55462306a36Sopenharmony_ci .p = speed_list }} 55562306a36Sopenharmony_ci }; 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci if (num_Speed > bd) { 55862306a36Sopenharmony_ci speed = Speed[bd]; 55962306a36Sopenharmony_ci e1000_validate_option(&speed, &opt, adapter); 56062306a36Sopenharmony_ci } else { 56162306a36Sopenharmony_ci speed = opt.def; 56262306a36Sopenharmony_ci } 56362306a36Sopenharmony_ci } 56462306a36Sopenharmony_ci { /* Duplex */ 56562306a36Sopenharmony_ci static const struct e1000_opt_list dplx_list[] = { 56662306a36Sopenharmony_ci { 0, "" }, 56762306a36Sopenharmony_ci { HALF_DUPLEX, "" }, 56862306a36Sopenharmony_ci { FULL_DUPLEX, "" }}; 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci opt = (struct e1000_option) { 57162306a36Sopenharmony_ci .type = list_option, 57262306a36Sopenharmony_ci .name = "Duplex", 57362306a36Sopenharmony_ci .err = "parameter ignored", 57462306a36Sopenharmony_ci .def = 0, 57562306a36Sopenharmony_ci .arg = { .l = { .nr = ARRAY_SIZE(dplx_list), 57662306a36Sopenharmony_ci .p = dplx_list }} 57762306a36Sopenharmony_ci }; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci if (num_Duplex > bd) { 58062306a36Sopenharmony_ci dplx = Duplex[bd]; 58162306a36Sopenharmony_ci e1000_validate_option(&dplx, &opt, adapter); 58262306a36Sopenharmony_ci } else { 58362306a36Sopenharmony_ci dplx = opt.def; 58462306a36Sopenharmony_ci } 58562306a36Sopenharmony_ci } 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci if ((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) { 58862306a36Sopenharmony_ci e_dev_info("AutoNeg specified along with Speed or Duplex, " 58962306a36Sopenharmony_ci "parameter ignored\n"); 59062306a36Sopenharmony_ci adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT; 59162306a36Sopenharmony_ci } else { /* Autoneg */ 59262306a36Sopenharmony_ci static const struct e1000_opt_list an_list[] = 59362306a36Sopenharmony_ci #define AA "AutoNeg advertising " 59462306a36Sopenharmony_ci {{ 0x01, AA "10/HD" }, 59562306a36Sopenharmony_ci { 0x02, AA "10/FD" }, 59662306a36Sopenharmony_ci { 0x03, AA "10/FD, 10/HD" }, 59762306a36Sopenharmony_ci { 0x04, AA "100/HD" }, 59862306a36Sopenharmony_ci { 0x05, AA "100/HD, 10/HD" }, 59962306a36Sopenharmony_ci { 0x06, AA "100/HD, 10/FD" }, 60062306a36Sopenharmony_ci { 0x07, AA "100/HD, 10/FD, 10/HD" }, 60162306a36Sopenharmony_ci { 0x08, AA "100/FD" }, 60262306a36Sopenharmony_ci { 0x09, AA "100/FD, 10/HD" }, 60362306a36Sopenharmony_ci { 0x0a, AA "100/FD, 10/FD" }, 60462306a36Sopenharmony_ci { 0x0b, AA "100/FD, 10/FD, 10/HD" }, 60562306a36Sopenharmony_ci { 0x0c, AA "100/FD, 100/HD" }, 60662306a36Sopenharmony_ci { 0x0d, AA "100/FD, 100/HD, 10/HD" }, 60762306a36Sopenharmony_ci { 0x0e, AA "100/FD, 100/HD, 10/FD" }, 60862306a36Sopenharmony_ci { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" }, 60962306a36Sopenharmony_ci { 0x20, AA "1000/FD" }, 61062306a36Sopenharmony_ci { 0x21, AA "1000/FD, 10/HD" }, 61162306a36Sopenharmony_ci { 0x22, AA "1000/FD, 10/FD" }, 61262306a36Sopenharmony_ci { 0x23, AA "1000/FD, 10/FD, 10/HD" }, 61362306a36Sopenharmony_ci { 0x24, AA "1000/FD, 100/HD" }, 61462306a36Sopenharmony_ci { 0x25, AA "1000/FD, 100/HD, 10/HD" }, 61562306a36Sopenharmony_ci { 0x26, AA "1000/FD, 100/HD, 10/FD" }, 61662306a36Sopenharmony_ci { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" }, 61762306a36Sopenharmony_ci { 0x28, AA "1000/FD, 100/FD" }, 61862306a36Sopenharmony_ci { 0x29, AA "1000/FD, 100/FD, 10/HD" }, 61962306a36Sopenharmony_ci { 0x2a, AA "1000/FD, 100/FD, 10/FD" }, 62062306a36Sopenharmony_ci { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" }, 62162306a36Sopenharmony_ci { 0x2c, AA "1000/FD, 100/FD, 100/HD" }, 62262306a36Sopenharmony_ci { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" }, 62362306a36Sopenharmony_ci { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" }, 62462306a36Sopenharmony_ci { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }}; 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci opt = (struct e1000_option) { 62762306a36Sopenharmony_ci .type = list_option, 62862306a36Sopenharmony_ci .name = "AutoNeg", 62962306a36Sopenharmony_ci .err = "parameter ignored", 63062306a36Sopenharmony_ci .def = AUTONEG_ADV_DEFAULT, 63162306a36Sopenharmony_ci .arg = { .l = { .nr = ARRAY_SIZE(an_list), 63262306a36Sopenharmony_ci .p = an_list }} 63362306a36Sopenharmony_ci }; 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci if (num_AutoNeg > bd) { 63662306a36Sopenharmony_ci an = AutoNeg[bd]; 63762306a36Sopenharmony_ci e1000_validate_option(&an, &opt, adapter); 63862306a36Sopenharmony_ci } else { 63962306a36Sopenharmony_ci an = opt.def; 64062306a36Sopenharmony_ci } 64162306a36Sopenharmony_ci adapter->hw.autoneg_advertised = an; 64262306a36Sopenharmony_ci } 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ci switch (speed + dplx) { 64562306a36Sopenharmony_ci case 0: 64662306a36Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 64762306a36Sopenharmony_ci if ((num_Speed > bd) && (speed != 0 || dplx != 0)) 64862306a36Sopenharmony_ci e_dev_info("Speed and duplex autonegotiation " 64962306a36Sopenharmony_ci "enabled\n"); 65062306a36Sopenharmony_ci break; 65162306a36Sopenharmony_ci case HALF_DUPLEX: 65262306a36Sopenharmony_ci e_dev_info("Half Duplex specified without Speed\n"); 65362306a36Sopenharmony_ci e_dev_info("Using Autonegotiation at Half Duplex only\n"); 65462306a36Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 65562306a36Sopenharmony_ci adapter->hw.autoneg_advertised = ADVERTISE_10_HALF | 65662306a36Sopenharmony_ci ADVERTISE_100_HALF; 65762306a36Sopenharmony_ci break; 65862306a36Sopenharmony_ci case FULL_DUPLEX: 65962306a36Sopenharmony_ci e_dev_info("Full Duplex specified without Speed\n"); 66062306a36Sopenharmony_ci e_dev_info("Using Autonegotiation at Full Duplex only\n"); 66162306a36Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 66262306a36Sopenharmony_ci adapter->hw.autoneg_advertised = ADVERTISE_10_FULL | 66362306a36Sopenharmony_ci ADVERTISE_100_FULL | 66462306a36Sopenharmony_ci ADVERTISE_1000_FULL; 66562306a36Sopenharmony_ci break; 66662306a36Sopenharmony_ci case SPEED_10: 66762306a36Sopenharmony_ci e_dev_info("10 Mbps Speed specified without Duplex\n"); 66862306a36Sopenharmony_ci e_dev_info("Using Autonegotiation at 10 Mbps only\n"); 66962306a36Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 67062306a36Sopenharmony_ci adapter->hw.autoneg_advertised = ADVERTISE_10_HALF | 67162306a36Sopenharmony_ci ADVERTISE_10_FULL; 67262306a36Sopenharmony_ci break; 67362306a36Sopenharmony_ci case SPEED_10 + HALF_DUPLEX: 67462306a36Sopenharmony_ci e_dev_info("Forcing to 10 Mbps Half Duplex\n"); 67562306a36Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 0; 67662306a36Sopenharmony_ci adapter->hw.forced_speed_duplex = e1000_10_half; 67762306a36Sopenharmony_ci adapter->hw.autoneg_advertised = 0; 67862306a36Sopenharmony_ci break; 67962306a36Sopenharmony_ci case SPEED_10 + FULL_DUPLEX: 68062306a36Sopenharmony_ci e_dev_info("Forcing to 10 Mbps Full Duplex\n"); 68162306a36Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 0; 68262306a36Sopenharmony_ci adapter->hw.forced_speed_duplex = e1000_10_full; 68362306a36Sopenharmony_ci adapter->hw.autoneg_advertised = 0; 68462306a36Sopenharmony_ci break; 68562306a36Sopenharmony_ci case SPEED_100: 68662306a36Sopenharmony_ci e_dev_info("100 Mbps Speed specified without Duplex\n"); 68762306a36Sopenharmony_ci e_dev_info("Using Autonegotiation at 100 Mbps only\n"); 68862306a36Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 68962306a36Sopenharmony_ci adapter->hw.autoneg_advertised = ADVERTISE_100_HALF | 69062306a36Sopenharmony_ci ADVERTISE_100_FULL; 69162306a36Sopenharmony_ci break; 69262306a36Sopenharmony_ci case SPEED_100 + HALF_DUPLEX: 69362306a36Sopenharmony_ci e_dev_info("Forcing to 100 Mbps Half Duplex\n"); 69462306a36Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 0; 69562306a36Sopenharmony_ci adapter->hw.forced_speed_duplex = e1000_100_half; 69662306a36Sopenharmony_ci adapter->hw.autoneg_advertised = 0; 69762306a36Sopenharmony_ci break; 69862306a36Sopenharmony_ci case SPEED_100 + FULL_DUPLEX: 69962306a36Sopenharmony_ci e_dev_info("Forcing to 100 Mbps Full Duplex\n"); 70062306a36Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 0; 70162306a36Sopenharmony_ci adapter->hw.forced_speed_duplex = e1000_100_full; 70262306a36Sopenharmony_ci adapter->hw.autoneg_advertised = 0; 70362306a36Sopenharmony_ci break; 70462306a36Sopenharmony_ci case SPEED_1000: 70562306a36Sopenharmony_ci e_dev_info("1000 Mbps Speed specified without Duplex\n"); 70662306a36Sopenharmony_ci goto full_duplex_only; 70762306a36Sopenharmony_ci case SPEED_1000 + HALF_DUPLEX: 70862306a36Sopenharmony_ci e_dev_info("Half Duplex is not supported at 1000 Mbps\n"); 70962306a36Sopenharmony_ci fallthrough; 71062306a36Sopenharmony_ci case SPEED_1000 + FULL_DUPLEX: 71162306a36Sopenharmony_cifull_duplex_only: 71262306a36Sopenharmony_ci e_dev_info("Using Autonegotiation at 1000 Mbps Full Duplex " 71362306a36Sopenharmony_ci "only\n"); 71462306a36Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 71562306a36Sopenharmony_ci adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL; 71662306a36Sopenharmony_ci break; 71762306a36Sopenharmony_ci default: 71862306a36Sopenharmony_ci BUG(); 71962306a36Sopenharmony_ci } 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci /* Speed, AutoNeg and MDI/MDI-X must all play nice */ 72262306a36Sopenharmony_ci if (e1000_validate_mdi_setting(&(adapter->hw)) < 0) { 72362306a36Sopenharmony_ci e_dev_info("Speed, AutoNeg and MDI-X specs are incompatible. " 72462306a36Sopenharmony_ci "Setting MDI-X to a compatible value.\n"); 72562306a36Sopenharmony_ci } 72662306a36Sopenharmony_ci} 72762306a36Sopenharmony_ci 728