18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright(c) 1999 - 2006 Intel Corporation. */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "e1000.h" 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci/* This is the only thing that needs to be changed to adjust the 78c2ecf20Sopenharmony_ci * maximum number of ports that the driver can manage. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#define E1000_MAX_NIC 32 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#define OPTION_UNSET -1 138c2ecf20Sopenharmony_ci#define OPTION_DISABLED 0 148c2ecf20Sopenharmony_ci#define OPTION_ENABLED 1 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* All parameters are treated the same, as an integer array of values. 178c2ecf20Sopenharmony_ci * This macro just reduces the need to repeat the same declaration code 188c2ecf20Sopenharmony_ci * over and over (plus this helps to avoid typo bugs). 198c2ecf20Sopenharmony_ci */ 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET } 228c2ecf20Sopenharmony_ci#define E1000_PARAM(X, desc) \ 238c2ecf20Sopenharmony_ci static int X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \ 248c2ecf20Sopenharmony_ci static unsigned int num_##X; \ 258c2ecf20Sopenharmony_ci module_param_array_named(X, X, int, &num_##X, 0); \ 268c2ecf20Sopenharmony_ci MODULE_PARM_DESC(X, desc); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/* Transmit Descriptor Count 298c2ecf20Sopenharmony_ci * 308c2ecf20Sopenharmony_ci * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers 318c2ecf20Sopenharmony_ci * Valid Range: 80-4096 for 82544 and newer 328c2ecf20Sopenharmony_ci * 338c2ecf20Sopenharmony_ci * Default Value: 256 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_ciE1000_PARAM(TxDescriptors, "Number of transmit descriptors"); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* Receive Descriptor Count 388c2ecf20Sopenharmony_ci * 398c2ecf20Sopenharmony_ci * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers 408c2ecf20Sopenharmony_ci * Valid Range: 80-4096 for 82544 and newer 418c2ecf20Sopenharmony_ci * 428c2ecf20Sopenharmony_ci * Default Value: 256 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ciE1000_PARAM(RxDescriptors, "Number of receive descriptors"); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci/* User Specified Speed Override 478c2ecf20Sopenharmony_ci * 488c2ecf20Sopenharmony_ci * Valid Range: 0, 10, 100, 1000 498c2ecf20Sopenharmony_ci * - 0 - auto-negotiate at all supported speeds 508c2ecf20Sopenharmony_ci * - 10 - only link at 10 Mbps 518c2ecf20Sopenharmony_ci * - 100 - only link at 100 Mbps 528c2ecf20Sopenharmony_ci * - 1000 - only link at 1000 Mbps 538c2ecf20Sopenharmony_ci * 548c2ecf20Sopenharmony_ci * Default Value: 0 558c2ecf20Sopenharmony_ci */ 568c2ecf20Sopenharmony_ciE1000_PARAM(Speed, "Speed setting"); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci/* User Specified Duplex Override 598c2ecf20Sopenharmony_ci * 608c2ecf20Sopenharmony_ci * Valid Range: 0-2 618c2ecf20Sopenharmony_ci * - 0 - auto-negotiate for duplex 628c2ecf20Sopenharmony_ci * - 1 - only link at half duplex 638c2ecf20Sopenharmony_ci * - 2 - only link at full duplex 648c2ecf20Sopenharmony_ci * 658c2ecf20Sopenharmony_ci * Default Value: 0 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_ciE1000_PARAM(Duplex, "Duplex setting"); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci/* Auto-negotiation Advertisement Override 708c2ecf20Sopenharmony_ci * 718c2ecf20Sopenharmony_ci * Valid Range: 0x01-0x0F, 0x20-0x2F (copper); 0x20 (fiber) 728c2ecf20Sopenharmony_ci * 738c2ecf20Sopenharmony_ci * The AutoNeg value is a bit mask describing which speed and duplex 748c2ecf20Sopenharmony_ci * combinations should be advertised during auto-negotiation. 758c2ecf20Sopenharmony_ci * The supported speed and duplex modes are listed below 768c2ecf20Sopenharmony_ci * 778c2ecf20Sopenharmony_ci * Bit 7 6 5 4 3 2 1 0 788c2ecf20Sopenharmony_ci * Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10 798c2ecf20Sopenharmony_ci * Duplex Full Full Half Full Half 808c2ecf20Sopenharmony_ci * 818c2ecf20Sopenharmony_ci * Default Value: 0x2F (copper); 0x20 (fiber) 828c2ecf20Sopenharmony_ci */ 838c2ecf20Sopenharmony_ciE1000_PARAM(AutoNeg, "Advertised auto-negotiation setting"); 848c2ecf20Sopenharmony_ci#define AUTONEG_ADV_DEFAULT 0x2F 858c2ecf20Sopenharmony_ci#define AUTONEG_ADV_MASK 0x2F 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/* User Specified Flow Control Override 888c2ecf20Sopenharmony_ci * 898c2ecf20Sopenharmony_ci * Valid Range: 0-3 908c2ecf20Sopenharmony_ci * - 0 - No Flow Control 918c2ecf20Sopenharmony_ci * - 1 - Rx only, respond to PAUSE frames but do not generate them 928c2ecf20Sopenharmony_ci * - 2 - Tx only, generate PAUSE frames but ignore them on receive 938c2ecf20Sopenharmony_ci * - 3 - Full Flow Control Support 948c2ecf20Sopenharmony_ci * 958c2ecf20Sopenharmony_ci * Default Value: Read flow control settings from the EEPROM 968c2ecf20Sopenharmony_ci */ 978c2ecf20Sopenharmony_ciE1000_PARAM(FlowControl, "Flow Control setting"); 988c2ecf20Sopenharmony_ci#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci/* XsumRX - Receive Checksum Offload Enable/Disable 1018c2ecf20Sopenharmony_ci * 1028c2ecf20Sopenharmony_ci * Valid Range: 0, 1 1038c2ecf20Sopenharmony_ci * - 0 - disables all checksum offload 1048c2ecf20Sopenharmony_ci * - 1 - enables receive IP/TCP/UDP checksum offload 1058c2ecf20Sopenharmony_ci * on 82543 and newer -based NICs 1068c2ecf20Sopenharmony_ci * 1078c2ecf20Sopenharmony_ci * Default Value: 1 1088c2ecf20Sopenharmony_ci */ 1098c2ecf20Sopenharmony_ciE1000_PARAM(XsumRX, "Disable or enable Receive Checksum offload"); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci/* Transmit Interrupt Delay in units of 1.024 microseconds 1128c2ecf20Sopenharmony_ci * Tx interrupt delay needs to typically be set to something non zero 1138c2ecf20Sopenharmony_ci * 1148c2ecf20Sopenharmony_ci * Valid Range: 0-65535 1158c2ecf20Sopenharmony_ci */ 1168c2ecf20Sopenharmony_ciE1000_PARAM(TxIntDelay, "Transmit Interrupt Delay"); 1178c2ecf20Sopenharmony_ci#define DEFAULT_TIDV 8 1188c2ecf20Sopenharmony_ci#define MAX_TXDELAY 0xFFFF 1198c2ecf20Sopenharmony_ci#define MIN_TXDELAY 0 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci/* Transmit Absolute Interrupt Delay in units of 1.024 microseconds 1228c2ecf20Sopenharmony_ci * 1238c2ecf20Sopenharmony_ci * Valid Range: 0-65535 1248c2ecf20Sopenharmony_ci */ 1258c2ecf20Sopenharmony_ciE1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay"); 1268c2ecf20Sopenharmony_ci#define DEFAULT_TADV 32 1278c2ecf20Sopenharmony_ci#define MAX_TXABSDELAY 0xFFFF 1288c2ecf20Sopenharmony_ci#define MIN_TXABSDELAY 0 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci/* Receive Interrupt Delay in units of 1.024 microseconds 1318c2ecf20Sopenharmony_ci * hardware will likely hang if you set this to anything but zero. 1328c2ecf20Sopenharmony_ci * 1338c2ecf20Sopenharmony_ci * Valid Range: 0-65535 1348c2ecf20Sopenharmony_ci */ 1358c2ecf20Sopenharmony_ciE1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); 1368c2ecf20Sopenharmony_ci#define DEFAULT_RDTR 0 1378c2ecf20Sopenharmony_ci#define MAX_RXDELAY 0xFFFF 1388c2ecf20Sopenharmony_ci#define MIN_RXDELAY 0 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci/* Receive Absolute Interrupt Delay in units of 1.024 microseconds 1418c2ecf20Sopenharmony_ci * 1428c2ecf20Sopenharmony_ci * Valid Range: 0-65535 1438c2ecf20Sopenharmony_ci */ 1448c2ecf20Sopenharmony_ciE1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); 1458c2ecf20Sopenharmony_ci#define DEFAULT_RADV 8 1468c2ecf20Sopenharmony_ci#define MAX_RXABSDELAY 0xFFFF 1478c2ecf20Sopenharmony_ci#define MIN_RXABSDELAY 0 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci/* Interrupt Throttle Rate (interrupts/sec) 1508c2ecf20Sopenharmony_ci * 1518c2ecf20Sopenharmony_ci * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative) 1528c2ecf20Sopenharmony_ci */ 1538c2ecf20Sopenharmony_ciE1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); 1548c2ecf20Sopenharmony_ci#define DEFAULT_ITR 3 1558c2ecf20Sopenharmony_ci#define MAX_ITR 100000 1568c2ecf20Sopenharmony_ci#define MIN_ITR 100 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci/* Enable Smart Power Down of the PHY 1598c2ecf20Sopenharmony_ci * 1608c2ecf20Sopenharmony_ci * Valid Range: 0, 1 1618c2ecf20Sopenharmony_ci * 1628c2ecf20Sopenharmony_ci * Default Value: 0 (disabled) 1638c2ecf20Sopenharmony_ci */ 1648c2ecf20Sopenharmony_ciE1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down"); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_cistruct e1000_option { 1678c2ecf20Sopenharmony_ci enum { enable_option, range_option, list_option } type; 1688c2ecf20Sopenharmony_ci const char *name; 1698c2ecf20Sopenharmony_ci const char *err; 1708c2ecf20Sopenharmony_ci int def; 1718c2ecf20Sopenharmony_ci union { 1728c2ecf20Sopenharmony_ci struct { /* range_option info */ 1738c2ecf20Sopenharmony_ci int min; 1748c2ecf20Sopenharmony_ci int max; 1758c2ecf20Sopenharmony_ci } r; 1768c2ecf20Sopenharmony_ci struct { /* list_option info */ 1778c2ecf20Sopenharmony_ci int nr; 1788c2ecf20Sopenharmony_ci const struct e1000_opt_list { int i; char *str; } *p; 1798c2ecf20Sopenharmony_ci } l; 1808c2ecf20Sopenharmony_ci } arg; 1818c2ecf20Sopenharmony_ci}; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistatic int e1000_validate_option(unsigned int *value, 1848c2ecf20Sopenharmony_ci const struct e1000_option *opt, 1858c2ecf20Sopenharmony_ci struct e1000_adapter *adapter) 1868c2ecf20Sopenharmony_ci{ 1878c2ecf20Sopenharmony_ci if (*value == OPTION_UNSET) { 1888c2ecf20Sopenharmony_ci *value = opt->def; 1898c2ecf20Sopenharmony_ci return 0; 1908c2ecf20Sopenharmony_ci } 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci switch (opt->type) { 1938c2ecf20Sopenharmony_ci case enable_option: 1948c2ecf20Sopenharmony_ci switch (*value) { 1958c2ecf20Sopenharmony_ci case OPTION_ENABLED: 1968c2ecf20Sopenharmony_ci e_dev_info("%s Enabled\n", opt->name); 1978c2ecf20Sopenharmony_ci return 0; 1988c2ecf20Sopenharmony_ci case OPTION_DISABLED: 1998c2ecf20Sopenharmony_ci e_dev_info("%s Disabled\n", opt->name); 2008c2ecf20Sopenharmony_ci return 0; 2018c2ecf20Sopenharmony_ci } 2028c2ecf20Sopenharmony_ci break; 2038c2ecf20Sopenharmony_ci case range_option: 2048c2ecf20Sopenharmony_ci if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { 2058c2ecf20Sopenharmony_ci e_dev_info("%s set to %i\n", opt->name, *value); 2068c2ecf20Sopenharmony_ci return 0; 2078c2ecf20Sopenharmony_ci } 2088c2ecf20Sopenharmony_ci break; 2098c2ecf20Sopenharmony_ci case list_option: { 2108c2ecf20Sopenharmony_ci int i; 2118c2ecf20Sopenharmony_ci const struct e1000_opt_list *ent; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci for (i = 0; i < opt->arg.l.nr; i++) { 2148c2ecf20Sopenharmony_ci ent = &opt->arg.l.p[i]; 2158c2ecf20Sopenharmony_ci if (*value == ent->i) { 2168c2ecf20Sopenharmony_ci if (ent->str[0] != '\0') 2178c2ecf20Sopenharmony_ci e_dev_info("%s\n", ent->str); 2188c2ecf20Sopenharmony_ci return 0; 2198c2ecf20Sopenharmony_ci } 2208c2ecf20Sopenharmony_ci } 2218c2ecf20Sopenharmony_ci } 2228c2ecf20Sopenharmony_ci break; 2238c2ecf20Sopenharmony_ci default: 2248c2ecf20Sopenharmony_ci BUG(); 2258c2ecf20Sopenharmony_ci } 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci e_dev_info("Invalid %s value specified (%i) %s\n", 2288c2ecf20Sopenharmony_ci opt->name, *value, opt->err); 2298c2ecf20Sopenharmony_ci *value = opt->def; 2308c2ecf20Sopenharmony_ci return -1; 2318c2ecf20Sopenharmony_ci} 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_cistatic void e1000_check_fiber_options(struct e1000_adapter *adapter); 2348c2ecf20Sopenharmony_cistatic void e1000_check_copper_options(struct e1000_adapter *adapter); 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci/** 2378c2ecf20Sopenharmony_ci * e1000_check_options - Range Checking for Command Line Parameters 2388c2ecf20Sopenharmony_ci * @adapter: board private structure 2398c2ecf20Sopenharmony_ci * 2408c2ecf20Sopenharmony_ci * This routine checks all command line parameters for valid user 2418c2ecf20Sopenharmony_ci * input. If an invalid value is given, or if no user specified 2428c2ecf20Sopenharmony_ci * value exists, a default value is used. The final value is stored 2438c2ecf20Sopenharmony_ci * in a variable in the adapter structure. 2448c2ecf20Sopenharmony_ci **/ 2458c2ecf20Sopenharmony_civoid e1000_check_options(struct e1000_adapter *adapter) 2468c2ecf20Sopenharmony_ci{ 2478c2ecf20Sopenharmony_ci struct e1000_option opt; 2488c2ecf20Sopenharmony_ci int bd = adapter->bd_number; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci if (bd >= E1000_MAX_NIC) { 2518c2ecf20Sopenharmony_ci e_dev_warn("Warning: no configuration for board #%i " 2528c2ecf20Sopenharmony_ci "using defaults for all values\n", bd); 2538c2ecf20Sopenharmony_ci } 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci { /* Transmit Descriptor Count */ 2568c2ecf20Sopenharmony_ci struct e1000_tx_ring *tx_ring = adapter->tx_ring; 2578c2ecf20Sopenharmony_ci int i; 2588c2ecf20Sopenharmony_ci e1000_mac_type mac_type = adapter->hw.mac_type; 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 2618c2ecf20Sopenharmony_ci .type = range_option, 2628c2ecf20Sopenharmony_ci .name = "Transmit Descriptors", 2638c2ecf20Sopenharmony_ci .err = "using default of " 2648c2ecf20Sopenharmony_ci __MODULE_STRING(E1000_DEFAULT_TXD), 2658c2ecf20Sopenharmony_ci .def = E1000_DEFAULT_TXD, 2668c2ecf20Sopenharmony_ci .arg = { .r = { 2678c2ecf20Sopenharmony_ci .min = E1000_MIN_TXD, 2688c2ecf20Sopenharmony_ci .max = mac_type < e1000_82544 ? E1000_MAX_TXD : E1000_MAX_82544_TXD 2698c2ecf20Sopenharmony_ci }} 2708c2ecf20Sopenharmony_ci }; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci if (num_TxDescriptors > bd) { 2738c2ecf20Sopenharmony_ci tx_ring->count = TxDescriptors[bd]; 2748c2ecf20Sopenharmony_ci e1000_validate_option(&tx_ring->count, &opt, adapter); 2758c2ecf20Sopenharmony_ci tx_ring->count = ALIGN(tx_ring->count, 2768c2ecf20Sopenharmony_ci REQ_TX_DESCRIPTOR_MULTIPLE); 2778c2ecf20Sopenharmony_ci } else { 2788c2ecf20Sopenharmony_ci tx_ring->count = opt.def; 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci for (i = 0; i < adapter->num_tx_queues; i++) 2818c2ecf20Sopenharmony_ci tx_ring[i].count = tx_ring->count; 2828c2ecf20Sopenharmony_ci } 2838c2ecf20Sopenharmony_ci { /* Receive Descriptor Count */ 2848c2ecf20Sopenharmony_ci struct e1000_rx_ring *rx_ring = adapter->rx_ring; 2858c2ecf20Sopenharmony_ci int i; 2868c2ecf20Sopenharmony_ci e1000_mac_type mac_type = adapter->hw.mac_type; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 2898c2ecf20Sopenharmony_ci .type = range_option, 2908c2ecf20Sopenharmony_ci .name = "Receive Descriptors", 2918c2ecf20Sopenharmony_ci .err = "using default of " 2928c2ecf20Sopenharmony_ci __MODULE_STRING(E1000_DEFAULT_RXD), 2938c2ecf20Sopenharmony_ci .def = E1000_DEFAULT_RXD, 2948c2ecf20Sopenharmony_ci .arg = { .r = { 2958c2ecf20Sopenharmony_ci .min = E1000_MIN_RXD, 2968c2ecf20Sopenharmony_ci .max = mac_type < e1000_82544 ? E1000_MAX_RXD : 2978c2ecf20Sopenharmony_ci E1000_MAX_82544_RXD 2988c2ecf20Sopenharmony_ci }} 2998c2ecf20Sopenharmony_ci }; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci if (num_RxDescriptors > bd) { 3028c2ecf20Sopenharmony_ci rx_ring->count = RxDescriptors[bd]; 3038c2ecf20Sopenharmony_ci e1000_validate_option(&rx_ring->count, &opt, adapter); 3048c2ecf20Sopenharmony_ci rx_ring->count = ALIGN(rx_ring->count, 3058c2ecf20Sopenharmony_ci REQ_RX_DESCRIPTOR_MULTIPLE); 3068c2ecf20Sopenharmony_ci } else { 3078c2ecf20Sopenharmony_ci rx_ring->count = opt.def; 3088c2ecf20Sopenharmony_ci } 3098c2ecf20Sopenharmony_ci for (i = 0; i < adapter->num_rx_queues; i++) 3108c2ecf20Sopenharmony_ci rx_ring[i].count = rx_ring->count; 3118c2ecf20Sopenharmony_ci } 3128c2ecf20Sopenharmony_ci { /* Checksum Offload Enable/Disable */ 3138c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 3148c2ecf20Sopenharmony_ci .type = enable_option, 3158c2ecf20Sopenharmony_ci .name = "Checksum Offload", 3168c2ecf20Sopenharmony_ci .err = "defaulting to Enabled", 3178c2ecf20Sopenharmony_ci .def = OPTION_ENABLED 3188c2ecf20Sopenharmony_ci }; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci if (num_XsumRX > bd) { 3218c2ecf20Sopenharmony_ci unsigned int rx_csum = XsumRX[bd]; 3228c2ecf20Sopenharmony_ci e1000_validate_option(&rx_csum, &opt, adapter); 3238c2ecf20Sopenharmony_ci adapter->rx_csum = rx_csum; 3248c2ecf20Sopenharmony_ci } else { 3258c2ecf20Sopenharmony_ci adapter->rx_csum = opt.def; 3268c2ecf20Sopenharmony_ci } 3278c2ecf20Sopenharmony_ci } 3288c2ecf20Sopenharmony_ci { /* Flow Control */ 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci static const struct e1000_opt_list fc_list[] = { 3318c2ecf20Sopenharmony_ci { E1000_FC_NONE, "Flow Control Disabled" }, 3328c2ecf20Sopenharmony_ci { E1000_FC_RX_PAUSE, "Flow Control Receive Only" }, 3338c2ecf20Sopenharmony_ci { E1000_FC_TX_PAUSE, "Flow Control Transmit Only" }, 3348c2ecf20Sopenharmony_ci { E1000_FC_FULL, "Flow Control Enabled" }, 3358c2ecf20Sopenharmony_ci { E1000_FC_DEFAULT, "Flow Control Hardware Default" } 3368c2ecf20Sopenharmony_ci }; 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 3398c2ecf20Sopenharmony_ci .type = list_option, 3408c2ecf20Sopenharmony_ci .name = "Flow Control", 3418c2ecf20Sopenharmony_ci .err = "reading default settings from EEPROM", 3428c2ecf20Sopenharmony_ci .def = E1000_FC_DEFAULT, 3438c2ecf20Sopenharmony_ci .arg = { .l = { .nr = ARRAY_SIZE(fc_list), 3448c2ecf20Sopenharmony_ci .p = fc_list }} 3458c2ecf20Sopenharmony_ci }; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci if (num_FlowControl > bd) { 3488c2ecf20Sopenharmony_ci unsigned int fc = FlowControl[bd]; 3498c2ecf20Sopenharmony_ci e1000_validate_option(&fc, &opt, adapter); 3508c2ecf20Sopenharmony_ci adapter->hw.fc = adapter->hw.original_fc = fc; 3518c2ecf20Sopenharmony_ci } else { 3528c2ecf20Sopenharmony_ci adapter->hw.fc = adapter->hw.original_fc = opt.def; 3538c2ecf20Sopenharmony_ci } 3548c2ecf20Sopenharmony_ci } 3558c2ecf20Sopenharmony_ci { /* Transmit Interrupt Delay */ 3568c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 3578c2ecf20Sopenharmony_ci .type = range_option, 3588c2ecf20Sopenharmony_ci .name = "Transmit Interrupt Delay", 3598c2ecf20Sopenharmony_ci .err = "using default of " __MODULE_STRING(DEFAULT_TIDV), 3608c2ecf20Sopenharmony_ci .def = DEFAULT_TIDV, 3618c2ecf20Sopenharmony_ci .arg = { .r = { .min = MIN_TXDELAY, 3628c2ecf20Sopenharmony_ci .max = MAX_TXDELAY }} 3638c2ecf20Sopenharmony_ci }; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci if (num_TxIntDelay > bd) { 3668c2ecf20Sopenharmony_ci adapter->tx_int_delay = TxIntDelay[bd]; 3678c2ecf20Sopenharmony_ci e1000_validate_option(&adapter->tx_int_delay, &opt, 3688c2ecf20Sopenharmony_ci adapter); 3698c2ecf20Sopenharmony_ci } else { 3708c2ecf20Sopenharmony_ci adapter->tx_int_delay = opt.def; 3718c2ecf20Sopenharmony_ci } 3728c2ecf20Sopenharmony_ci } 3738c2ecf20Sopenharmony_ci { /* Transmit Absolute Interrupt Delay */ 3748c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 3758c2ecf20Sopenharmony_ci .type = range_option, 3768c2ecf20Sopenharmony_ci .name = "Transmit Absolute Interrupt Delay", 3778c2ecf20Sopenharmony_ci .err = "using default of " __MODULE_STRING(DEFAULT_TADV), 3788c2ecf20Sopenharmony_ci .def = DEFAULT_TADV, 3798c2ecf20Sopenharmony_ci .arg = { .r = { .min = MIN_TXABSDELAY, 3808c2ecf20Sopenharmony_ci .max = MAX_TXABSDELAY }} 3818c2ecf20Sopenharmony_ci }; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci if (num_TxAbsIntDelay > bd) { 3848c2ecf20Sopenharmony_ci adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; 3858c2ecf20Sopenharmony_ci e1000_validate_option(&adapter->tx_abs_int_delay, &opt, 3868c2ecf20Sopenharmony_ci adapter); 3878c2ecf20Sopenharmony_ci } else { 3888c2ecf20Sopenharmony_ci adapter->tx_abs_int_delay = opt.def; 3898c2ecf20Sopenharmony_ci } 3908c2ecf20Sopenharmony_ci } 3918c2ecf20Sopenharmony_ci { /* Receive Interrupt Delay */ 3928c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 3938c2ecf20Sopenharmony_ci .type = range_option, 3948c2ecf20Sopenharmony_ci .name = "Receive Interrupt Delay", 3958c2ecf20Sopenharmony_ci .err = "using default of " __MODULE_STRING(DEFAULT_RDTR), 3968c2ecf20Sopenharmony_ci .def = DEFAULT_RDTR, 3978c2ecf20Sopenharmony_ci .arg = { .r = { .min = MIN_RXDELAY, 3988c2ecf20Sopenharmony_ci .max = MAX_RXDELAY }} 3998c2ecf20Sopenharmony_ci }; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci if (num_RxIntDelay > bd) { 4028c2ecf20Sopenharmony_ci adapter->rx_int_delay = RxIntDelay[bd]; 4038c2ecf20Sopenharmony_ci e1000_validate_option(&adapter->rx_int_delay, &opt, 4048c2ecf20Sopenharmony_ci adapter); 4058c2ecf20Sopenharmony_ci } else { 4068c2ecf20Sopenharmony_ci adapter->rx_int_delay = opt.def; 4078c2ecf20Sopenharmony_ci } 4088c2ecf20Sopenharmony_ci } 4098c2ecf20Sopenharmony_ci { /* Receive Absolute Interrupt Delay */ 4108c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 4118c2ecf20Sopenharmony_ci .type = range_option, 4128c2ecf20Sopenharmony_ci .name = "Receive Absolute Interrupt Delay", 4138c2ecf20Sopenharmony_ci .err = "using default of " __MODULE_STRING(DEFAULT_RADV), 4148c2ecf20Sopenharmony_ci .def = DEFAULT_RADV, 4158c2ecf20Sopenharmony_ci .arg = { .r = { .min = MIN_RXABSDELAY, 4168c2ecf20Sopenharmony_ci .max = MAX_RXABSDELAY }} 4178c2ecf20Sopenharmony_ci }; 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci if (num_RxAbsIntDelay > bd) { 4208c2ecf20Sopenharmony_ci adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; 4218c2ecf20Sopenharmony_ci e1000_validate_option(&adapter->rx_abs_int_delay, &opt, 4228c2ecf20Sopenharmony_ci adapter); 4238c2ecf20Sopenharmony_ci } else { 4248c2ecf20Sopenharmony_ci adapter->rx_abs_int_delay = opt.def; 4258c2ecf20Sopenharmony_ci } 4268c2ecf20Sopenharmony_ci } 4278c2ecf20Sopenharmony_ci { /* Interrupt Throttling Rate */ 4288c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 4298c2ecf20Sopenharmony_ci .type = range_option, 4308c2ecf20Sopenharmony_ci .name = "Interrupt Throttling Rate (ints/sec)", 4318c2ecf20Sopenharmony_ci .err = "using default of " __MODULE_STRING(DEFAULT_ITR), 4328c2ecf20Sopenharmony_ci .def = DEFAULT_ITR, 4338c2ecf20Sopenharmony_ci .arg = { .r = { .min = MIN_ITR, 4348c2ecf20Sopenharmony_ci .max = MAX_ITR }} 4358c2ecf20Sopenharmony_ci }; 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci if (num_InterruptThrottleRate > bd) { 4388c2ecf20Sopenharmony_ci adapter->itr = InterruptThrottleRate[bd]; 4398c2ecf20Sopenharmony_ci switch (adapter->itr) { 4408c2ecf20Sopenharmony_ci case 0: 4418c2ecf20Sopenharmony_ci e_dev_info("%s turned off\n", opt.name); 4428c2ecf20Sopenharmony_ci break; 4438c2ecf20Sopenharmony_ci case 1: 4448c2ecf20Sopenharmony_ci e_dev_info("%s set to dynamic mode\n", 4458c2ecf20Sopenharmony_ci opt.name); 4468c2ecf20Sopenharmony_ci adapter->itr_setting = adapter->itr; 4478c2ecf20Sopenharmony_ci adapter->itr = 20000; 4488c2ecf20Sopenharmony_ci break; 4498c2ecf20Sopenharmony_ci case 3: 4508c2ecf20Sopenharmony_ci e_dev_info("%s set to dynamic conservative " 4518c2ecf20Sopenharmony_ci "mode\n", opt.name); 4528c2ecf20Sopenharmony_ci adapter->itr_setting = adapter->itr; 4538c2ecf20Sopenharmony_ci adapter->itr = 20000; 4548c2ecf20Sopenharmony_ci break; 4558c2ecf20Sopenharmony_ci case 4: 4568c2ecf20Sopenharmony_ci e_dev_info("%s set to simplified " 4578c2ecf20Sopenharmony_ci "(2000-8000) ints mode\n", opt.name); 4588c2ecf20Sopenharmony_ci adapter->itr_setting = adapter->itr; 4598c2ecf20Sopenharmony_ci break; 4608c2ecf20Sopenharmony_ci default: 4618c2ecf20Sopenharmony_ci e1000_validate_option(&adapter->itr, &opt, 4628c2ecf20Sopenharmony_ci adapter); 4638c2ecf20Sopenharmony_ci /* save the setting, because the dynamic bits 4648c2ecf20Sopenharmony_ci * change itr. 4658c2ecf20Sopenharmony_ci * clear the lower two bits because they are 4668c2ecf20Sopenharmony_ci * used as control 4678c2ecf20Sopenharmony_ci */ 4688c2ecf20Sopenharmony_ci adapter->itr_setting = adapter->itr & ~3; 4698c2ecf20Sopenharmony_ci break; 4708c2ecf20Sopenharmony_ci } 4718c2ecf20Sopenharmony_ci } else { 4728c2ecf20Sopenharmony_ci adapter->itr_setting = opt.def; 4738c2ecf20Sopenharmony_ci adapter->itr = 20000; 4748c2ecf20Sopenharmony_ci } 4758c2ecf20Sopenharmony_ci } 4768c2ecf20Sopenharmony_ci { /* Smart Power Down */ 4778c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 4788c2ecf20Sopenharmony_ci .type = enable_option, 4798c2ecf20Sopenharmony_ci .name = "PHY Smart Power Down", 4808c2ecf20Sopenharmony_ci .err = "defaulting to Disabled", 4818c2ecf20Sopenharmony_ci .def = OPTION_DISABLED 4828c2ecf20Sopenharmony_ci }; 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci if (num_SmartPowerDownEnable > bd) { 4858c2ecf20Sopenharmony_ci unsigned int spd = SmartPowerDownEnable[bd]; 4868c2ecf20Sopenharmony_ci e1000_validate_option(&spd, &opt, adapter); 4878c2ecf20Sopenharmony_ci adapter->smart_power_down = spd; 4888c2ecf20Sopenharmony_ci } else { 4898c2ecf20Sopenharmony_ci adapter->smart_power_down = opt.def; 4908c2ecf20Sopenharmony_ci } 4918c2ecf20Sopenharmony_ci } 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci switch (adapter->hw.media_type) { 4948c2ecf20Sopenharmony_ci case e1000_media_type_fiber: 4958c2ecf20Sopenharmony_ci case e1000_media_type_internal_serdes: 4968c2ecf20Sopenharmony_ci e1000_check_fiber_options(adapter); 4978c2ecf20Sopenharmony_ci break; 4988c2ecf20Sopenharmony_ci case e1000_media_type_copper: 4998c2ecf20Sopenharmony_ci e1000_check_copper_options(adapter); 5008c2ecf20Sopenharmony_ci break; 5018c2ecf20Sopenharmony_ci default: 5028c2ecf20Sopenharmony_ci BUG(); 5038c2ecf20Sopenharmony_ci } 5048c2ecf20Sopenharmony_ci} 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci/** 5078c2ecf20Sopenharmony_ci * e1000_check_fiber_options - Range Checking for Link Options, Fiber Version 5088c2ecf20Sopenharmony_ci * @adapter: board private structure 5098c2ecf20Sopenharmony_ci * 5108c2ecf20Sopenharmony_ci * Handles speed and duplex options on fiber adapters 5118c2ecf20Sopenharmony_ci **/ 5128c2ecf20Sopenharmony_cistatic void e1000_check_fiber_options(struct e1000_adapter *adapter) 5138c2ecf20Sopenharmony_ci{ 5148c2ecf20Sopenharmony_ci int bd = adapter->bd_number; 5158c2ecf20Sopenharmony_ci if (num_Speed > bd) { 5168c2ecf20Sopenharmony_ci e_dev_info("Speed not valid for fiber adapters, parameter " 5178c2ecf20Sopenharmony_ci "ignored\n"); 5188c2ecf20Sopenharmony_ci } 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci if (num_Duplex > bd) { 5218c2ecf20Sopenharmony_ci e_dev_info("Duplex not valid for fiber adapters, parameter " 5228c2ecf20Sopenharmony_ci "ignored\n"); 5238c2ecf20Sopenharmony_ci } 5248c2ecf20Sopenharmony_ci 5258c2ecf20Sopenharmony_ci if ((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) { 5268c2ecf20Sopenharmony_ci e_dev_info("AutoNeg other than 1000/Full is not valid for fiber" 5278c2ecf20Sopenharmony_ci "adapters, parameter ignored\n"); 5288c2ecf20Sopenharmony_ci } 5298c2ecf20Sopenharmony_ci} 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci/** 5328c2ecf20Sopenharmony_ci * e1000_check_copper_options - Range Checking for Link Options, Copper Version 5338c2ecf20Sopenharmony_ci * @adapter: board private structure 5348c2ecf20Sopenharmony_ci * 5358c2ecf20Sopenharmony_ci * Handles speed and duplex options on copper adapters 5368c2ecf20Sopenharmony_ci **/ 5378c2ecf20Sopenharmony_cistatic void e1000_check_copper_options(struct e1000_adapter *adapter) 5388c2ecf20Sopenharmony_ci{ 5398c2ecf20Sopenharmony_ci struct e1000_option opt; 5408c2ecf20Sopenharmony_ci unsigned int speed, dplx, an; 5418c2ecf20Sopenharmony_ci int bd = adapter->bd_number; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci { /* Speed */ 5448c2ecf20Sopenharmony_ci static const struct e1000_opt_list speed_list[] = { 5458c2ecf20Sopenharmony_ci { 0, "" }, 5468c2ecf20Sopenharmony_ci { SPEED_10, "" }, 5478c2ecf20Sopenharmony_ci { SPEED_100, "" }, 5488c2ecf20Sopenharmony_ci { SPEED_1000, "" }}; 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 5518c2ecf20Sopenharmony_ci .type = list_option, 5528c2ecf20Sopenharmony_ci .name = "Speed", 5538c2ecf20Sopenharmony_ci .err = "parameter ignored", 5548c2ecf20Sopenharmony_ci .def = 0, 5558c2ecf20Sopenharmony_ci .arg = { .l = { .nr = ARRAY_SIZE(speed_list), 5568c2ecf20Sopenharmony_ci .p = speed_list }} 5578c2ecf20Sopenharmony_ci }; 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci if (num_Speed > bd) { 5608c2ecf20Sopenharmony_ci speed = Speed[bd]; 5618c2ecf20Sopenharmony_ci e1000_validate_option(&speed, &opt, adapter); 5628c2ecf20Sopenharmony_ci } else { 5638c2ecf20Sopenharmony_ci speed = opt.def; 5648c2ecf20Sopenharmony_ci } 5658c2ecf20Sopenharmony_ci } 5668c2ecf20Sopenharmony_ci { /* Duplex */ 5678c2ecf20Sopenharmony_ci static const struct e1000_opt_list dplx_list[] = { 5688c2ecf20Sopenharmony_ci { 0, "" }, 5698c2ecf20Sopenharmony_ci { HALF_DUPLEX, "" }, 5708c2ecf20Sopenharmony_ci { FULL_DUPLEX, "" }}; 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 5738c2ecf20Sopenharmony_ci .type = list_option, 5748c2ecf20Sopenharmony_ci .name = "Duplex", 5758c2ecf20Sopenharmony_ci .err = "parameter ignored", 5768c2ecf20Sopenharmony_ci .def = 0, 5778c2ecf20Sopenharmony_ci .arg = { .l = { .nr = ARRAY_SIZE(dplx_list), 5788c2ecf20Sopenharmony_ci .p = dplx_list }} 5798c2ecf20Sopenharmony_ci }; 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ci if (num_Duplex > bd) { 5828c2ecf20Sopenharmony_ci dplx = Duplex[bd]; 5838c2ecf20Sopenharmony_ci e1000_validate_option(&dplx, &opt, adapter); 5848c2ecf20Sopenharmony_ci } else { 5858c2ecf20Sopenharmony_ci dplx = opt.def; 5868c2ecf20Sopenharmony_ci } 5878c2ecf20Sopenharmony_ci } 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci if ((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) { 5908c2ecf20Sopenharmony_ci e_dev_info("AutoNeg specified along with Speed or Duplex, " 5918c2ecf20Sopenharmony_ci "parameter ignored\n"); 5928c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT; 5938c2ecf20Sopenharmony_ci } else { /* Autoneg */ 5948c2ecf20Sopenharmony_ci static const struct e1000_opt_list an_list[] = 5958c2ecf20Sopenharmony_ci #define AA "AutoNeg advertising " 5968c2ecf20Sopenharmony_ci {{ 0x01, AA "10/HD" }, 5978c2ecf20Sopenharmony_ci { 0x02, AA "10/FD" }, 5988c2ecf20Sopenharmony_ci { 0x03, AA "10/FD, 10/HD" }, 5998c2ecf20Sopenharmony_ci { 0x04, AA "100/HD" }, 6008c2ecf20Sopenharmony_ci { 0x05, AA "100/HD, 10/HD" }, 6018c2ecf20Sopenharmony_ci { 0x06, AA "100/HD, 10/FD" }, 6028c2ecf20Sopenharmony_ci { 0x07, AA "100/HD, 10/FD, 10/HD" }, 6038c2ecf20Sopenharmony_ci { 0x08, AA "100/FD" }, 6048c2ecf20Sopenharmony_ci { 0x09, AA "100/FD, 10/HD" }, 6058c2ecf20Sopenharmony_ci { 0x0a, AA "100/FD, 10/FD" }, 6068c2ecf20Sopenharmony_ci { 0x0b, AA "100/FD, 10/FD, 10/HD" }, 6078c2ecf20Sopenharmony_ci { 0x0c, AA "100/FD, 100/HD" }, 6088c2ecf20Sopenharmony_ci { 0x0d, AA "100/FD, 100/HD, 10/HD" }, 6098c2ecf20Sopenharmony_ci { 0x0e, AA "100/FD, 100/HD, 10/FD" }, 6108c2ecf20Sopenharmony_ci { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" }, 6118c2ecf20Sopenharmony_ci { 0x20, AA "1000/FD" }, 6128c2ecf20Sopenharmony_ci { 0x21, AA "1000/FD, 10/HD" }, 6138c2ecf20Sopenharmony_ci { 0x22, AA "1000/FD, 10/FD" }, 6148c2ecf20Sopenharmony_ci { 0x23, AA "1000/FD, 10/FD, 10/HD" }, 6158c2ecf20Sopenharmony_ci { 0x24, AA "1000/FD, 100/HD" }, 6168c2ecf20Sopenharmony_ci { 0x25, AA "1000/FD, 100/HD, 10/HD" }, 6178c2ecf20Sopenharmony_ci { 0x26, AA "1000/FD, 100/HD, 10/FD" }, 6188c2ecf20Sopenharmony_ci { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" }, 6198c2ecf20Sopenharmony_ci { 0x28, AA "1000/FD, 100/FD" }, 6208c2ecf20Sopenharmony_ci { 0x29, AA "1000/FD, 100/FD, 10/HD" }, 6218c2ecf20Sopenharmony_ci { 0x2a, AA "1000/FD, 100/FD, 10/FD" }, 6228c2ecf20Sopenharmony_ci { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" }, 6238c2ecf20Sopenharmony_ci { 0x2c, AA "1000/FD, 100/FD, 100/HD" }, 6248c2ecf20Sopenharmony_ci { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" }, 6258c2ecf20Sopenharmony_ci { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" }, 6268c2ecf20Sopenharmony_ci { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }}; 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci opt = (struct e1000_option) { 6298c2ecf20Sopenharmony_ci .type = list_option, 6308c2ecf20Sopenharmony_ci .name = "AutoNeg", 6318c2ecf20Sopenharmony_ci .err = "parameter ignored", 6328c2ecf20Sopenharmony_ci .def = AUTONEG_ADV_DEFAULT, 6338c2ecf20Sopenharmony_ci .arg = { .l = { .nr = ARRAY_SIZE(an_list), 6348c2ecf20Sopenharmony_ci .p = an_list }} 6358c2ecf20Sopenharmony_ci }; 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci if (num_AutoNeg > bd) { 6388c2ecf20Sopenharmony_ci an = AutoNeg[bd]; 6398c2ecf20Sopenharmony_ci e1000_validate_option(&an, &opt, adapter); 6408c2ecf20Sopenharmony_ci } else { 6418c2ecf20Sopenharmony_ci an = opt.def; 6428c2ecf20Sopenharmony_ci } 6438c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = an; 6448c2ecf20Sopenharmony_ci } 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_ci switch (speed + dplx) { 6478c2ecf20Sopenharmony_ci case 0: 6488c2ecf20Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 6498c2ecf20Sopenharmony_ci if ((num_Speed > bd) && (speed != 0 || dplx != 0)) 6508c2ecf20Sopenharmony_ci e_dev_info("Speed and duplex autonegotiation " 6518c2ecf20Sopenharmony_ci "enabled\n"); 6528c2ecf20Sopenharmony_ci break; 6538c2ecf20Sopenharmony_ci case HALF_DUPLEX: 6548c2ecf20Sopenharmony_ci e_dev_info("Half Duplex specified without Speed\n"); 6558c2ecf20Sopenharmony_ci e_dev_info("Using Autonegotiation at Half Duplex only\n"); 6568c2ecf20Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 6578c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = ADVERTISE_10_HALF | 6588c2ecf20Sopenharmony_ci ADVERTISE_100_HALF; 6598c2ecf20Sopenharmony_ci break; 6608c2ecf20Sopenharmony_ci case FULL_DUPLEX: 6618c2ecf20Sopenharmony_ci e_dev_info("Full Duplex specified without Speed\n"); 6628c2ecf20Sopenharmony_ci e_dev_info("Using Autonegotiation at Full Duplex only\n"); 6638c2ecf20Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 6648c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = ADVERTISE_10_FULL | 6658c2ecf20Sopenharmony_ci ADVERTISE_100_FULL | 6668c2ecf20Sopenharmony_ci ADVERTISE_1000_FULL; 6678c2ecf20Sopenharmony_ci break; 6688c2ecf20Sopenharmony_ci case SPEED_10: 6698c2ecf20Sopenharmony_ci e_dev_info("10 Mbps Speed specified without Duplex\n"); 6708c2ecf20Sopenharmony_ci e_dev_info("Using Autonegotiation at 10 Mbps only\n"); 6718c2ecf20Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 6728c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = ADVERTISE_10_HALF | 6738c2ecf20Sopenharmony_ci ADVERTISE_10_FULL; 6748c2ecf20Sopenharmony_ci break; 6758c2ecf20Sopenharmony_ci case SPEED_10 + HALF_DUPLEX: 6768c2ecf20Sopenharmony_ci e_dev_info("Forcing to 10 Mbps Half Duplex\n"); 6778c2ecf20Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 0; 6788c2ecf20Sopenharmony_ci adapter->hw.forced_speed_duplex = e1000_10_half; 6798c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = 0; 6808c2ecf20Sopenharmony_ci break; 6818c2ecf20Sopenharmony_ci case SPEED_10 + FULL_DUPLEX: 6828c2ecf20Sopenharmony_ci e_dev_info("Forcing to 10 Mbps Full Duplex\n"); 6838c2ecf20Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 0; 6848c2ecf20Sopenharmony_ci adapter->hw.forced_speed_duplex = e1000_10_full; 6858c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = 0; 6868c2ecf20Sopenharmony_ci break; 6878c2ecf20Sopenharmony_ci case SPEED_100: 6888c2ecf20Sopenharmony_ci e_dev_info("100 Mbps Speed specified without Duplex\n"); 6898c2ecf20Sopenharmony_ci e_dev_info("Using Autonegotiation at 100 Mbps only\n"); 6908c2ecf20Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 6918c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = ADVERTISE_100_HALF | 6928c2ecf20Sopenharmony_ci ADVERTISE_100_FULL; 6938c2ecf20Sopenharmony_ci break; 6948c2ecf20Sopenharmony_ci case SPEED_100 + HALF_DUPLEX: 6958c2ecf20Sopenharmony_ci e_dev_info("Forcing to 100 Mbps Half Duplex\n"); 6968c2ecf20Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 0; 6978c2ecf20Sopenharmony_ci adapter->hw.forced_speed_duplex = e1000_100_half; 6988c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = 0; 6998c2ecf20Sopenharmony_ci break; 7008c2ecf20Sopenharmony_ci case SPEED_100 + FULL_DUPLEX: 7018c2ecf20Sopenharmony_ci e_dev_info("Forcing to 100 Mbps Full Duplex\n"); 7028c2ecf20Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 0; 7038c2ecf20Sopenharmony_ci adapter->hw.forced_speed_duplex = e1000_100_full; 7048c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = 0; 7058c2ecf20Sopenharmony_ci break; 7068c2ecf20Sopenharmony_ci case SPEED_1000: 7078c2ecf20Sopenharmony_ci e_dev_info("1000 Mbps Speed specified without Duplex\n"); 7088c2ecf20Sopenharmony_ci goto full_duplex_only; 7098c2ecf20Sopenharmony_ci case SPEED_1000 + HALF_DUPLEX: 7108c2ecf20Sopenharmony_ci e_dev_info("Half Duplex is not supported at 1000 Mbps\n"); 7118c2ecf20Sopenharmony_ci fallthrough; 7128c2ecf20Sopenharmony_ci case SPEED_1000 + FULL_DUPLEX: 7138c2ecf20Sopenharmony_cifull_duplex_only: 7148c2ecf20Sopenharmony_ci e_dev_info("Using Autonegotiation at 1000 Mbps Full Duplex " 7158c2ecf20Sopenharmony_ci "only\n"); 7168c2ecf20Sopenharmony_ci adapter->hw.autoneg = adapter->fc_autoneg = 1; 7178c2ecf20Sopenharmony_ci adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL; 7188c2ecf20Sopenharmony_ci break; 7198c2ecf20Sopenharmony_ci default: 7208c2ecf20Sopenharmony_ci BUG(); 7218c2ecf20Sopenharmony_ci } 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci /* Speed, AutoNeg and MDI/MDI-X must all play nice */ 7248c2ecf20Sopenharmony_ci if (e1000_validate_mdi_setting(&(adapter->hw)) < 0) { 7258c2ecf20Sopenharmony_ci e_dev_info("Speed, AutoNeg and MDI-X specs are incompatible. " 7268c2ecf20Sopenharmony_ci "Setting MDI-X to a compatible value.\n"); 7278c2ecf20Sopenharmony_ci } 7288c2ecf20Sopenharmony_ci} 7298c2ecf20Sopenharmony_ci 730