// SPDX-License-Identifier: GPL-2.0 /******************************************************************************* Intel(R) Gigabit Ethernet Linux driver Copyright(c) 2007-2013 Intel Corporation. Contact Information: e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ #include #include "igb.h" /* This is the only thing that needs to be changed to adjust the * maximum number of ports that the driver can manage. */ #define IGB_MAX_NIC 32 #define OPTION_UNSET -1 #define OPTION_DISABLED 0 #define OPTION_ENABLED 1 #define MAX_NUM_LIST_OPTS 15 /* All parameters are treated the same, as an integer array of values. * This macro just reduces the need to repeat the same declaration code * over and over (plus this helps to avoid typo bugs). */ #define IGB_PARAM_INIT { [0 ... IGB_MAX_NIC] = OPTION_UNSET } #ifndef module_param_array /* Module Parameters are always initialized to -1, so that the driver * can tell the difference between no user specified value or the * user asking for the default value. * The true default values are loaded in when igb_check_options is called. * * This is a GCC extension to ANSI C. * See the item "Labeled Elements in Initializers" in the section * "Extensions to the C Language Family" of the GCC documentation. */ #define IGB_PARAM(X, desc) \ static const int X[IGB_MAX_NIC+1] = IGB_PARAM_INIT; \ MODULE_PARM(X, "1-" __MODULE_STRING(IGB_MAX_NIC) "i"); \ MODULE_PARM_DESC(X, desc); #else #define IGB_PARAM(X, desc) \ static int X[IGB_MAX_NIC+1] = IGB_PARAM_INIT; \ static unsigned int num_##X; \ module_param_array_named(X, X, int, &num_##X, 0); \ MODULE_PARM_DESC(X, desc); #endif /* Interrupt Throttle Rate (interrupts/sec) * * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative) */ IGB_PARAM(InterruptThrottleRate, "Maximum interrupts per second, per vector, (max 100000), default 3=adaptive"); #define DEFAULT_ITR 3 #define MAX_ITR 100000 /* #define MIN_ITR 120 */ #define MIN_ITR 0 /* IntMode (Interrupt Mode) * * Valid Range: 0 - 2 * * Default Value: 2 (MSI-X) */ IGB_PARAM(IntMode, "Change Interrupt Mode (0=Legacy, 1=MSI, 2=MSI-X), default 2"); #define MAX_INTMODE IGB_INT_MODE_MSIX #define MIN_INTMODE IGB_INT_MODE_LEGACY IGB_PARAM(Node, "set the starting node to allocate memory on, default -1"); /* LLIPort (Low Latency Interrupt TCP Port) * * Valid Range: 0 - 65535 * * Default Value: 0 (disabled) */ IGB_PARAM(LLIPort, "Low Latency Interrupt TCP Port (0-65535), default 0=off"); #define DEFAULT_LLIPORT 0 #define MAX_LLIPORT 0xFFFF #define MIN_LLIPORT 0 /* LLIPush (Low Latency Interrupt on TCP Push flag) * * Valid Range: 0, 1 * * Default Value: 0 (disabled) */ IGB_PARAM(LLIPush, "Low Latency Interrupt on TCP Push flag (0,1), default 0=off"); #define DEFAULT_LLIPUSH 0 #define MAX_LLIPUSH 1 #define MIN_LLIPUSH 0 /* LLISize (Low Latency Interrupt on Packet Size) * * Valid Range: 0 - 1500 * * Default Value: 0 (disabled) */ IGB_PARAM(LLISize, "Low Latency Interrupt on Packet Size (0-1500), default 0=off"); #define DEFAULT_LLISIZE 0 #define MAX_LLISIZE 1500 #define MIN_LLISIZE 0 /* RSS (Enable RSS multiqueue receive) * * Valid Range: 0 - 8 * * Default Value: 1 */ IGB_PARAM(RSS, "Number of Receive-Side Scaling Descriptor Queues (0-8), default 1, 0=number of cpus"); #define DEFAULT_RSS 1 #define MAX_RSS 8 #define MIN_RSS 0 /* VMDQ (Enable VMDq multiqueue receive) * * Valid Range: 0 - 8 * * Default Value: 0 */ IGB_PARAM(VMDQ, "Number of Virtual Machine Device Queues: 0-1 = disable, 2-8 enable, default 0"); #define DEFAULT_VMDQ 0 #define MAX_VMDQ MAX_RSS #define MIN_VMDQ 0 /* max_vfs (Enable SR-IOV VF devices) * * Valid Range: 0 - 7 * * Default Value: 0 */ IGB_PARAM(max_vfs, "Number of Virtual Functions: 0 = disable, 1-7 enable, default 0"); #define DEFAULT_SRIOV 0 #define MAX_SRIOV 7 #define MIN_SRIOV 0 /* MDD (Enable Malicious Driver Detection) * * Only available when SR-IOV is enabled - max_vfs is greater than 0 * * Valid Range: 0, 1 * * Default Value: 1 */ IGB_PARAM(MDD, "Malicious Driver Detection (0/1), default 1 = enabled. " "Only available when max_vfs is greater than 0"); #ifdef DEBUG /* Disable Hardware Reset on Tx Hang * * Valid Range: 0, 1 * * Default Value: 0 (disabled, i.e. h/w will reset) */ IGB_PARAM(DisableHwReset, "Disable reset of hardware on Tx hang"); /* Dump Transmit and Receive buffers * * Valid Range: 0, 1 * * Default Value: 0 */ IGB_PARAM(DumpBuffers, "Dump Tx/Rx buffers on Tx hang or by request"); #endif /* DEBUG */ /* QueuePairs (Enable TX/RX queue pairs for interrupt handling) * * Valid Range: 0 - 1 * * Default Value: 1 */ IGB_PARAM(QueuePairs, "Enable Tx/Rx queue pairs for interrupt handling (0,1), default 1=on"); #define DEFAULT_QUEUE_PAIRS 1 #define MAX_QUEUE_PAIRS 1 #define MIN_QUEUE_PAIRS 0 /* Enable/disable EEE (a.k.a. IEEE802.3az) * * Valid Range: 0, 1 * * Default Value: 1 */ IGB_PARAM(EEE, "Enable/disable on parts that support the feature"); /* Enable/disable DMA Coalescing * * Valid Values: 0(off), 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, * 9000, 10000(msec), 250(usec), 500(usec) * * Default Value: 0 */ IGB_PARAM(DMAC, "Disable or set latency for DMA Coalescing ((0=off, 1000-10000(msec), 250, 500 (usec))"); #ifndef IGB_NO_LRO /* Enable/disable Large Receive Offload * * Valid Values: 0(off), 1(on) * * Default Value: 0 */ IGB_PARAM(LRO, "Large Receive Offload (0,1), default 0=off"); #endif struct igb_opt_list { int i; char *str; }; struct igb_option { enum { enable_option, range_option, list_option } type; const char *name; const char *err; int def; union { struct { /* range_option info */ int min; int max; } r; struct { /* list_option info */ int nr; struct igb_opt_list *p; } l; } arg; }; static int igb_validate_option(unsigned int *value, struct igb_option *opt, struct igb_adapter *adapter) { if (*value == OPTION_UNSET) { *value = opt->def; return 0; } switch (opt->type) { case enable_option: switch (*value) { case OPTION_ENABLED: DPRINTK(PROBE, INFO, "%s Enabled\n", opt->name); return 0; case OPTION_DISABLED: DPRINTK(PROBE, INFO, "%s Disabled\n", opt->name); return 0; } break; case range_option: if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { DPRINTK(PROBE, INFO, "%s set to %d\n", opt->name, *value); return 0; } break; case list_option: { int i; struct igb_opt_list *ent; for (i = 0; i < opt->arg.l.nr; i++) { ent = &opt->arg.l.p[i]; if (*value == ent->i) { if (ent->str[0] != '\0') DPRINTK(PROBE, INFO, "%s\n", ent->str); return 0; } } } break; default: BUG(); } DPRINTK(PROBE, INFO, "Invalid %s value specified (%d) %s\n", opt->name, *value, opt->err); *value = opt->def; return -1; } /** * igb_check_options - Range Checking for Command Line Parameters * @adapter: board private structure * * This routine checks all command line parameters for valid user * input. If an invalid value is given, or if no user specified * value exists, a default value is used. The final value is stored * in a variable in the adapter structure. **/ void igb_check_options(struct igb_adapter *adapter) { int bd = adapter->bd_number; struct e1000_hw *hw = &adapter->hw; if (bd >= IGB_MAX_NIC) { DPRINTK(PROBE, NOTICE, "Warning: no configuration for board #%d\n", bd); DPRINTK(PROBE, NOTICE, "Using defaults for all values\n"); #ifndef module_param_array bd = IGB_MAX_NIC; #endif } { /* Interrupt Throttling Rate */ struct igb_option opt = { .type = range_option, .name = "Interrupt Throttling Rate (ints/sec)", .err = "using default of " __MODULE_STRING(DEFAULT_ITR), .def = DEFAULT_ITR, .arg = { .r = { .min = MIN_ITR, .max = MAX_ITR } } }; #ifdef module_param_array if (num_InterruptThrottleRate > bd) { #endif unsigned int itr = InterruptThrottleRate[bd]; switch (itr) { case 0: DPRINTK(PROBE, INFO, "%s turned off\n", opt.name); if (hw->mac.type >= e1000_i350) adapter->dmac = IGB_DMAC_DISABLE; adapter->rx_itr_setting = itr; break; case 1: DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", opt.name); adapter->rx_itr_setting = itr; break; case 3: DPRINTK(PROBE, INFO, "%s set to dynamic conservative mode\n", opt.name); adapter->rx_itr_setting = itr; break; default: igb_validate_option(&itr, &opt, adapter); /* Save the setting, because the dynamic bits * change itr. In case of invalid user value, * default to conservative mode, else need to * clear the lower two bits because they are * used as control */ if (itr == 3) { adapter->rx_itr_setting = itr; } else { adapter->rx_itr_setting = 1000000000 / (itr * 256); adapter->rx_itr_setting &= ~3; } break; } #ifdef module_param_array } else { adapter->rx_itr_setting = opt.def; } #endif adapter->tx_itr_setting = adapter->rx_itr_setting; } { /* Interrupt Mode */ struct igb_option opt = { .type = range_option, .name = "Interrupt Mode", .err = "defaulting to 2 (MSI-X)", .def = IGB_INT_MODE_MSIX, .arg = { .r = { .min = MIN_INTMODE, .max = MAX_INTMODE } } }; #ifdef module_param_array if (num_IntMode > bd) { #endif unsigned int int_mode = IntMode[bd]; igb_validate_option(&int_mode, &opt, adapter); adapter->int_mode = int_mode; #ifdef module_param_array } else { adapter->int_mode = opt.def; } #endif } { /* Low Latency Interrupt TCP Port */ struct igb_option opt = { .type = range_option, .name = "Low Latency Interrupt TCP Port", .err = "using default of " __MODULE_STRING(DEFAULT_LLIPORT), .def = DEFAULT_LLIPORT, .arg = { .r = { .min = MIN_LLIPORT, .max = MAX_LLIPORT } } }; #ifdef module_param_array if (num_LLIPort > bd) { #endif adapter->lli_port = LLIPort[bd]; if (adapter->lli_port) { igb_validate_option(&adapter->lli_port, &opt, adapter); } else { DPRINTK(PROBE, INFO, "%s turned off\n", opt.name); } #ifdef module_param_array } else { adapter->lli_port = opt.def; } #endif } { /* Low Latency Interrupt on Packet Size */ struct igb_option opt = { .type = range_option, .name = "Low Latency Interrupt on Packet Size", .err = "using default of " __MODULE_STRING(DEFAULT_LLISIZE), .def = DEFAULT_LLISIZE, .arg = { .r = { .min = MIN_LLISIZE, .max = MAX_LLISIZE } } }; #ifdef module_param_array if (num_LLISize > bd) { #endif adapter->lli_size = LLISize[bd]; if (adapter->lli_size) { igb_validate_option(&adapter->lli_size, &opt, adapter); } else { DPRINTK(PROBE, INFO, "%s turned off\n", opt.name); } #ifdef module_param_array } else { adapter->lli_size = opt.def; } #endif } { /* Low Latency Interrupt on TCP Push flag */ struct igb_option opt = { .type = enable_option, .name = "Low Latency Interrupt on TCP Push flag", .err = "defaulting to Disabled", .def = OPTION_DISABLED }; #ifdef module_param_array if (num_LLIPush > bd) { #endif unsigned int lli_push = LLIPush[bd]; igb_validate_option(&lli_push, &opt, adapter); adapter->flags |= lli_push ? IGB_FLAG_LLI_PUSH : 0; #ifdef module_param_array } else { adapter->flags |= opt.def ? IGB_FLAG_LLI_PUSH : 0; } #endif } { /* SRIOV - Enable SR-IOV VF devices */ struct igb_option opt = { .type = range_option, .name = "max_vfs - SR-IOV VF devices", .err = "using default of " __MODULE_STRING(DEFAULT_SRIOV), .def = DEFAULT_SRIOV, .arg = { .r = { .min = MIN_SRIOV, .max = MAX_SRIOV } } }; #ifdef module_param_array if (num_max_vfs > bd) { #endif adapter->vfs_allocated_count = max_vfs[bd]; igb_validate_option(&adapter->vfs_allocated_count, &opt, adapter); #ifdef module_param_array } else { adapter->vfs_allocated_count = opt.def; } #endif if (adapter->vfs_allocated_count) { switch (hw->mac.type) { case e1000_82575: case e1000_82580: case e1000_i210: case e1000_i211: case e1000_i354: adapter->vfs_allocated_count = 0; DPRINTK(PROBE, INFO, "SR-IOV option max_vfs not supported.\n"); default: break; } } } { /* VMDQ - Enable VMDq multiqueue receive */ struct igb_option opt = { .type = range_option, .name = "VMDQ - VMDq multiqueue queue count", .err = "using default of " __MODULE_STRING(DEFAULT_VMDQ), .def = DEFAULT_VMDQ, .arg = { .r = { .min = MIN_VMDQ, .max = (MAX_VMDQ - adapter->vfs_allocated_count) } } }; if ((hw->mac.type != e1000_i210) || (hw->mac.type != e1000_i211)) { #ifdef module_param_array if (num_VMDQ > bd) { #endif adapter->vmdq_pools = (VMDQ[bd] == 1 ? 0 : VMDQ[bd]); if (adapter->vfs_allocated_count && !adapter->vmdq_pools) { DPRINTK(PROBE, INFO, "Enabling SR-IOV requires VMDq be set to at least 1\n"); adapter->vmdq_pools = 1; } igb_validate_option(&adapter->vmdq_pools, &opt, adapter); #ifdef module_param_array } else { if (!adapter->vfs_allocated_count) adapter->vmdq_pools = (opt.def == 1 ? 0 : opt.def); else adapter->vmdq_pools = 1; } #endif #ifdef CONFIG_IGB_VMDQ_NETDEV if (hw->mac.type == e1000_82575 && adapter->vmdq_pools) { DPRINTK(PROBE, INFO, "VMDq not supported on this part.\n"); adapter->vmdq_pools = 0; } #endif } else { DPRINTK(PROBE, INFO, "VMDq option is not supported.\n"); adapter->vmdq_pools = opt.def; } } { /* RSS - Enable RSS multiqueue receives */ struct igb_option opt = { .type = range_option, .name = "RSS - RSS multiqueue receive count", .err = "using default of " __MODULE_STRING(DEFAULT_RSS), .def = DEFAULT_RSS, .arg = { .r = { .min = MIN_RSS, .max = MAX_RSS } } }; switch (hw->mac.type) { case e1000_82575: #ifndef CONFIG_IGB_VMDQ_NETDEV if (!!adapter->vmdq_pools) { if (adapter->vmdq_pools <= 2) { if (adapter->vmdq_pools == 2) opt.arg.r.max = 3; } else { opt.arg.r.max = 1; } } else { opt.arg.r.max = 4; } #else opt.arg.r.max = !!adapter->vmdq_pools ? 1 : 4; #endif /* CONFIG_IGB_VMDQ_NETDEV */ break; case e1000_i210: opt.arg.r.max = 4; break; case e1000_i211: opt.arg.r.max = 2; break; case e1000_82576: #ifndef CONFIG_IGB_VMDQ_NETDEV if (!!adapter->vmdq_pools) opt.arg.r.max = 2; break; #endif /* CONFIG_IGB_VMDQ_NETDEV */ case e1000_82580: case e1000_i350: case e1000_i354: default: if (!!adapter->vmdq_pools) opt.arg.r.max = 1; break; } if (adapter->int_mode != IGB_INT_MODE_MSIX) { DPRINTK(PROBE, INFO, "RSS is not supported when in MSI/Legacy Interrupt mode, %s\n", opt.err); opt.arg.r.max = 1; } #ifdef module_param_array if (num_RSS > bd) { #endif adapter->rss_queues = RSS[bd]; switch (adapter->rss_queues) { case 1: break; default: igb_validate_option(&adapter->rss_queues, &opt, adapter); if (adapter->rss_queues) break; case 0: adapter->rss_queues = min_t(u32, opt.arg.r.max, num_online_cpus()); break; } #ifdef module_param_array } else { adapter->rss_queues = opt.def; } #endif } { /* QueuePairs - Enable Tx/Rx queue pairs for interrupt handling */ struct igb_option opt = { .type = enable_option, .name = "QueuePairs - Tx/Rx queue pairs for interrupt handling", .err = "defaulting to Enabled", .def = OPTION_ENABLED }; #ifdef module_param_array if (num_QueuePairs > bd) { #endif unsigned int qp = QueuePairs[bd]; /* * We must enable queue pairs if the number of queues * exceeds the number of available interrupts. We are * limited to 10, or 3 per unallocated vf. On I210 and * I211 devices, we are limited to 5 interrupts. * However, since I211 only supports 2 queues, we do not * need to check and override the user option. */ if (qp == OPTION_DISABLED) { if (adapter->rss_queues > 4) qp = OPTION_ENABLED; if (adapter->vmdq_pools > 4) qp = OPTION_ENABLED; if (adapter->rss_queues > 1 && (adapter->vmdq_pools > 3 || adapter->vfs_allocated_count > 6)) qp = OPTION_ENABLED; if (hw->mac.type == e1000_i210 && adapter->rss_queues > 2) qp = OPTION_ENABLED; if (qp == OPTION_ENABLED) DPRINTK(PROBE, INFO, "Number of queues exceeds available interrupts, %s\n", opt.err); } igb_validate_option(&qp, &opt, adapter); adapter->flags |= qp ? IGB_FLAG_QUEUE_PAIRS : 0; #ifdef module_param_array } else { adapter->flags |= opt.def ? IGB_FLAG_QUEUE_PAIRS : 0; } #endif } { /* EEE - Enable EEE for capable adapters */ if (hw->mac.type >= e1000_i350) { struct igb_option opt = { .type = enable_option, .name = "EEE Support", .err = "defaulting to Enabled", .def = OPTION_ENABLED }; #ifdef module_param_array if (num_EEE > bd) { #endif unsigned int eee = EEE[bd]; igb_validate_option(&eee, &opt, adapter); adapter->flags |= eee ? IGB_FLAG_EEE : 0; if (eee) hw->dev_spec._82575.eee_disable = false; else hw->dev_spec._82575.eee_disable = true; #ifdef module_param_array } else { adapter->flags |= opt.def ? IGB_FLAG_EEE : 0; if (adapter->flags & IGB_FLAG_EEE) hw->dev_spec._82575.eee_disable = false; else hw->dev_spec._82575.eee_disable = true; } #endif } } { /* DMAC - Enable DMA Coalescing for capable adapters */ if (hw->mac.type >= e1000_i350) { struct igb_opt_list list [] = { { IGB_DMAC_DISABLE, "DMAC Disable"}, { IGB_DMAC_MIN, "DMAC 250 usec"}, { IGB_DMAC_500, "DMAC 500 usec"}, { IGB_DMAC_EN_DEFAULT, "DMAC 1000 usec"}, { IGB_DMAC_2000, "DMAC 2000 usec"}, { IGB_DMAC_3000, "DMAC 3000 usec"}, { IGB_DMAC_4000, "DMAC 4000 usec"}, { IGB_DMAC_5000, "DMAC 5000 usec"}, { IGB_DMAC_6000, "DMAC 6000 usec"}, { IGB_DMAC_7000, "DMAC 7000 usec"}, { IGB_DMAC_8000, "DMAC 8000 usec"}, { IGB_DMAC_9000, "DMAC 9000 usec"}, { IGB_DMAC_MAX, "DMAC 10000 usec"} }; struct igb_option opt = { .type = list_option, .name = "DMA Coalescing", .err = "using default of "__MODULE_STRING(IGB_DMAC_DISABLE), .def = IGB_DMAC_DISABLE, .arg = { .l = { .nr = 13, .p = list } } }; #ifdef module_param_array if (num_DMAC > bd) { #endif unsigned int dmac = DMAC[bd]; if (adapter->rx_itr_setting == IGB_DMAC_DISABLE) dmac = IGB_DMAC_DISABLE; igb_validate_option(&dmac, &opt, adapter); switch (dmac) { case IGB_DMAC_DISABLE: adapter->dmac = dmac; break; case IGB_DMAC_MIN: adapter->dmac = dmac; break; case IGB_DMAC_500: adapter->dmac = dmac; break; case IGB_DMAC_EN_DEFAULT: adapter->dmac = dmac; break; case IGB_DMAC_2000: adapter->dmac = dmac; break; case IGB_DMAC_3000: adapter->dmac = dmac; break; case IGB_DMAC_4000: adapter->dmac = dmac; break; case IGB_DMAC_5000: adapter->dmac = dmac; break; case IGB_DMAC_6000: adapter->dmac = dmac; break; case IGB_DMAC_7000: adapter->dmac = dmac; break; case IGB_DMAC_8000: adapter->dmac = dmac; break; case IGB_DMAC_9000: adapter->dmac = dmac; break; case IGB_DMAC_MAX: adapter->dmac = dmac; break; default: adapter->dmac = opt.def; DPRINTK(PROBE, INFO, "Invalid DMAC setting, " "resetting DMAC to %d\n", opt.def); } #ifdef module_param_array } else adapter->dmac = opt.def; #endif } } #ifndef IGB_NO_LRO { /* LRO - Enable Large Receive Offload */ struct igb_option opt = { .type = enable_option, .name = "LRO - Large Receive Offload", .err = "defaulting to Disabled", .def = OPTION_DISABLED }; struct net_device *netdev = adapter->netdev; #ifdef module_param_array if (num_LRO > bd) { #endif unsigned int lro = LRO[bd]; igb_validate_option(&lro, &opt, adapter); netdev->features |= lro ? NETIF_F_LRO : 0; #ifdef module_param_array } else if (opt.def == OPTION_ENABLED) { netdev->features |= NETIF_F_LRO; } #endif } #endif /* IGB_NO_LRO */ { /* MDD - Enable Malicious Driver Detection. Only available when SR-IOV is enabled. */ struct igb_option opt = { .type = enable_option, .name = "Malicious Driver Detection", .err = "defaulting to 1", .def = OPTION_ENABLED, .arg = { .r = { .min = OPTION_DISABLED, .max = OPTION_ENABLED } } }; #ifdef module_param_array if (num_MDD > bd) { #endif adapter->mdd = MDD[bd]; igb_validate_option((uint *)&adapter->mdd, &opt, adapter); #ifdef module_param_array } else { adapter->mdd = opt.def; } #endif } }