ixgb_param.c (11637B)
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright(c) 1999 - 2008 Intel Corporation. */ 3 4#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 5 6#include "ixgb.h" 7 8/* This is the only thing that needs to be changed to adjust the 9 * maximum number of ports that the driver can manage. 10 */ 11 12#define IXGB_MAX_NIC 8 13 14#define OPTION_UNSET -1 15#define OPTION_DISABLED 0 16#define OPTION_ENABLED 1 17 18/* All parameters are treated the same, as an integer array of values. 19 * This macro just reduces the need to repeat the same declaration code 20 * over and over (plus this helps to avoid typo bugs). 21 */ 22 23#define IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET } 24#define IXGB_PARAM(X, desc) \ 25 static int X[IXGB_MAX_NIC+1] \ 26 = IXGB_PARAM_INIT; \ 27 static unsigned int num_##X = 0; \ 28 module_param_array_named(X, X, int, &num_##X, 0); \ 29 MODULE_PARM_DESC(X, desc); 30 31/* Transmit Descriptor Count 32 * 33 * Valid Range: 64-4096 34 * 35 * Default Value: 256 36 */ 37 38IXGB_PARAM(TxDescriptors, "Number of transmit descriptors"); 39 40/* Receive Descriptor Count 41 * 42 * Valid Range: 64-4096 43 * 44 * Default Value: 1024 45 */ 46 47IXGB_PARAM(RxDescriptors, "Number of receive descriptors"); 48 49/* User Specified Flow Control Override 50 * 51 * Valid Range: 0-3 52 * - 0 - No Flow Control 53 * - 1 - Rx only, respond to PAUSE frames but do not generate them 54 * - 2 - Tx only, generate PAUSE frames but ignore them on receive 55 * - 3 - Full Flow Control Support 56 * 57 * Default Value: 2 - Tx only (silicon bug avoidance) 58 */ 59 60IXGB_PARAM(FlowControl, "Flow Control setting"); 61 62/* XsumRX - Receive Checksum Offload Enable/Disable 63 * 64 * Valid Range: 0, 1 65 * - 0 - disables all checksum offload 66 * - 1 - enables receive IP/TCP/UDP checksum offload 67 * on 82597 based NICs 68 * 69 * Default Value: 1 70 */ 71 72IXGB_PARAM(XsumRX, "Disable or enable Receive Checksum offload"); 73 74/* Transmit Interrupt Delay in units of 0.8192 microseconds 75 * 76 * Valid Range: 0-65535 77 * 78 * Default Value: 32 79 */ 80 81IXGB_PARAM(TxIntDelay, "Transmit Interrupt Delay"); 82 83/* Receive Interrupt Delay in units of 0.8192 microseconds 84 * 85 * Valid Range: 0-65535 86 * 87 * Default Value: 72 88 */ 89 90IXGB_PARAM(RxIntDelay, "Receive Interrupt Delay"); 91 92/* Receive Flow control high threshold (when we send a pause frame) 93 * (FCRTH) 94 * 95 * Valid Range: 1,536 - 262,136 (0x600 - 0x3FFF8, 8 byte granularity) 96 * 97 * Default Value: 196,608 (0x30000) 98 */ 99 100IXGB_PARAM(RxFCHighThresh, "Receive Flow Control High Threshold"); 101 102/* Receive Flow control low threshold (when we send a resume frame) 103 * (FCRTL) 104 * 105 * Valid Range: 64 - 262,136 (0x40 - 0x3FFF8, 8 byte granularity) 106 * must be less than high threshold by at least 8 bytes 107 * 108 * Default Value: 163,840 (0x28000) 109 */ 110 111IXGB_PARAM(RxFCLowThresh, "Receive Flow Control Low Threshold"); 112 113/* Flow control request timeout (how long to pause the link partner's tx) 114 * (PAP 15:0) 115 * 116 * Valid Range: 1 - 65535 117 * 118 * Default Value: 65535 (0xffff) (we'll send an xon if we recover) 119 */ 120 121IXGB_PARAM(FCReqTimeout, "Flow Control Request Timeout"); 122 123/* Interrupt Delay Enable 124 * 125 * Valid Range: 0, 1 126 * 127 * - 0 - disables transmit interrupt delay 128 * - 1 - enables transmmit interrupt delay 129 * 130 * Default Value: 1 131 */ 132 133IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable"); 134 135 136#define DEFAULT_TIDV 32 137#define MAX_TIDV 0xFFFF 138#define MIN_TIDV 0 139 140#define DEFAULT_RDTR 72 141#define MAX_RDTR 0xFFFF 142#define MIN_RDTR 0 143 144#define XSUMRX_DEFAULT OPTION_ENABLED 145 146#define DEFAULT_FCRTL 0x28000 147#define DEFAULT_FCRTH 0x30000 148#define MIN_FCRTL 0 149#define MAX_FCRTL 0x3FFE8 150#define MIN_FCRTH 8 151#define MAX_FCRTH 0x3FFF0 152 153#define MIN_FCPAUSE 1 154#define MAX_FCPAUSE 0xffff 155#define DEFAULT_FCPAUSE 0xFFFF /* this may be too long */ 156 157struct ixgb_option { 158 enum { enable_option, range_option, list_option } type; 159 const char *name; 160 const char *err; 161 int def; 162 union { 163 struct { /* range_option info */ 164 int min; 165 int max; 166 } r; 167 struct { /* list_option info */ 168 int nr; 169 const struct ixgb_opt_list { 170 int i; 171 const char *str; 172 } *p; 173 } l; 174 } arg; 175}; 176 177static int 178ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt) 179{ 180 if (*value == OPTION_UNSET) { 181 *value = opt->def; 182 return 0; 183 } 184 185 switch (opt->type) { 186 case enable_option: 187 switch (*value) { 188 case OPTION_ENABLED: 189 pr_info("%s Enabled\n", opt->name); 190 return 0; 191 case OPTION_DISABLED: 192 pr_info("%s Disabled\n", opt->name); 193 return 0; 194 } 195 break; 196 case range_option: 197 if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { 198 pr_info("%s set to %i\n", opt->name, *value); 199 return 0; 200 } 201 break; 202 case list_option: { 203 int i; 204 const struct ixgb_opt_list *ent; 205 206 for (i = 0; i < opt->arg.l.nr; i++) { 207 ent = &opt->arg.l.p[i]; 208 if (*value == ent->i) { 209 if (ent->str[0] != '\0') 210 pr_info("%s\n", ent->str); 211 return 0; 212 } 213 } 214 } 215 break; 216 default: 217 BUG(); 218 } 219 220 pr_info("Invalid %s specified (%i) %s\n", opt->name, *value, opt->err); 221 *value = opt->def; 222 return -1; 223} 224 225/** 226 * ixgb_check_options - Range Checking for Command Line Parameters 227 * @adapter: board private structure 228 * 229 * This routine checks all command line parameters for valid user 230 * input. If an invalid value is given, or if no user specified 231 * value exists, a default value is used. The final value is stored 232 * in a variable in the adapter structure. 233 **/ 234 235void 236ixgb_check_options(struct ixgb_adapter *adapter) 237{ 238 int bd = adapter->bd_number; 239 if (bd >= IXGB_MAX_NIC) { 240 pr_notice("Warning: no configuration for board #%i\n", bd); 241 pr_notice("Using defaults for all values\n"); 242 } 243 244 { /* Transmit Descriptor Count */ 245 static const struct ixgb_option opt = { 246 .type = range_option, 247 .name = "Transmit Descriptors", 248 .err = "using default of " __MODULE_STRING(DEFAULT_TXD), 249 .def = DEFAULT_TXD, 250 .arg = { .r = { .min = MIN_TXD, 251 .max = MAX_TXD}} 252 }; 253 struct ixgb_desc_ring *tx_ring = &adapter->tx_ring; 254 255 if (num_TxDescriptors > bd) { 256 tx_ring->count = TxDescriptors[bd]; 257 ixgb_validate_option(&tx_ring->count, &opt); 258 } else { 259 tx_ring->count = opt.def; 260 } 261 tx_ring->count = ALIGN(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE); 262 } 263 { /* Receive Descriptor Count */ 264 static const struct ixgb_option opt = { 265 .type = range_option, 266 .name = "Receive Descriptors", 267 .err = "using default of " __MODULE_STRING(DEFAULT_RXD), 268 .def = DEFAULT_RXD, 269 .arg = { .r = { .min = MIN_RXD, 270 .max = MAX_RXD}} 271 }; 272 struct ixgb_desc_ring *rx_ring = &adapter->rx_ring; 273 274 if (num_RxDescriptors > bd) { 275 rx_ring->count = RxDescriptors[bd]; 276 ixgb_validate_option(&rx_ring->count, &opt); 277 } else { 278 rx_ring->count = opt.def; 279 } 280 rx_ring->count = ALIGN(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE); 281 } 282 { /* Receive Checksum Offload Enable */ 283 static const struct ixgb_option opt = { 284 .type = enable_option, 285 .name = "Receive Checksum Offload", 286 .err = "defaulting to Enabled", 287 .def = OPTION_ENABLED 288 }; 289 290 if (num_XsumRX > bd) { 291 unsigned int rx_csum = XsumRX[bd]; 292 ixgb_validate_option(&rx_csum, &opt); 293 adapter->rx_csum = rx_csum; 294 } else { 295 adapter->rx_csum = opt.def; 296 } 297 } 298 { /* Flow Control */ 299 300 static const struct ixgb_opt_list fc_list[] = { 301 { ixgb_fc_none, "Flow Control Disabled" }, 302 { ixgb_fc_rx_pause, "Flow Control Receive Only" }, 303 { ixgb_fc_tx_pause, "Flow Control Transmit Only" }, 304 { ixgb_fc_full, "Flow Control Enabled" }, 305 { ixgb_fc_default, "Flow Control Hardware Default" } 306 }; 307 308 static const struct ixgb_option opt = { 309 .type = list_option, 310 .name = "Flow Control", 311 .err = "reading default settings from EEPROM", 312 .def = ixgb_fc_tx_pause, 313 .arg = { .l = { .nr = ARRAY_SIZE(fc_list), 314 .p = fc_list }} 315 }; 316 317 if (num_FlowControl > bd) { 318 unsigned int fc = FlowControl[bd]; 319 ixgb_validate_option(&fc, &opt); 320 adapter->hw.fc.type = fc; 321 } else { 322 adapter->hw.fc.type = opt.def; 323 } 324 } 325 { /* Receive Flow Control High Threshold */ 326 static const struct ixgb_option opt = { 327 .type = range_option, 328 .name = "Rx Flow Control High Threshold", 329 .err = "using default of " __MODULE_STRING(DEFAULT_FCRTH), 330 .def = DEFAULT_FCRTH, 331 .arg = { .r = { .min = MIN_FCRTH, 332 .max = MAX_FCRTH}} 333 }; 334 335 if (num_RxFCHighThresh > bd) { 336 adapter->hw.fc.high_water = RxFCHighThresh[bd]; 337 ixgb_validate_option(&adapter->hw.fc.high_water, &opt); 338 } else { 339 adapter->hw.fc.high_water = opt.def; 340 } 341 if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) 342 pr_info("Ignoring RxFCHighThresh when no RxFC\n"); 343 } 344 { /* Receive Flow Control Low Threshold */ 345 static const struct ixgb_option opt = { 346 .type = range_option, 347 .name = "Rx Flow Control Low Threshold", 348 .err = "using default of " __MODULE_STRING(DEFAULT_FCRTL), 349 .def = DEFAULT_FCRTL, 350 .arg = { .r = { .min = MIN_FCRTL, 351 .max = MAX_FCRTL}} 352 }; 353 354 if (num_RxFCLowThresh > bd) { 355 adapter->hw.fc.low_water = RxFCLowThresh[bd]; 356 ixgb_validate_option(&adapter->hw.fc.low_water, &opt); 357 } else { 358 adapter->hw.fc.low_water = opt.def; 359 } 360 if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) 361 pr_info("Ignoring RxFCLowThresh when no RxFC\n"); 362 } 363 { /* Flow Control Pause Time Request*/ 364 static const struct ixgb_option opt = { 365 .type = range_option, 366 .name = "Flow Control Pause Time Request", 367 .err = "using default of "__MODULE_STRING(DEFAULT_FCPAUSE), 368 .def = DEFAULT_FCPAUSE, 369 .arg = { .r = { .min = MIN_FCPAUSE, 370 .max = MAX_FCPAUSE}} 371 }; 372 373 if (num_FCReqTimeout > bd) { 374 unsigned int pause_time = FCReqTimeout[bd]; 375 ixgb_validate_option(&pause_time, &opt); 376 adapter->hw.fc.pause_time = pause_time; 377 } else { 378 adapter->hw.fc.pause_time = opt.def; 379 } 380 if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) ) 381 pr_info("Ignoring FCReqTimeout when no RxFC\n"); 382 } 383 /* high low and spacing check for rx flow control thresholds */ 384 if (adapter->hw.fc.type & ixgb_fc_tx_pause) { 385 /* high must be greater than low */ 386 if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) { 387 /* set defaults */ 388 pr_info("RxFCHighThresh must be >= (RxFCLowThresh + 8), Using Defaults\n"); 389 adapter->hw.fc.high_water = DEFAULT_FCRTH; 390 adapter->hw.fc.low_water = DEFAULT_FCRTL; 391 } 392 } 393 { /* Receive Interrupt Delay */ 394 static const struct ixgb_option opt = { 395 .type = range_option, 396 .name = "Receive Interrupt Delay", 397 .err = "using default of " __MODULE_STRING(DEFAULT_RDTR), 398 .def = DEFAULT_RDTR, 399 .arg = { .r = { .min = MIN_RDTR, 400 .max = MAX_RDTR}} 401 }; 402 403 if (num_RxIntDelay > bd) { 404 adapter->rx_int_delay = RxIntDelay[bd]; 405 ixgb_validate_option(&adapter->rx_int_delay, &opt); 406 } else { 407 adapter->rx_int_delay = opt.def; 408 } 409 } 410 { /* Transmit Interrupt Delay */ 411 static const struct ixgb_option opt = { 412 .type = range_option, 413 .name = "Transmit Interrupt Delay", 414 .err = "using default of " __MODULE_STRING(DEFAULT_TIDV), 415 .def = DEFAULT_TIDV, 416 .arg = { .r = { .min = MIN_TIDV, 417 .max = MAX_TIDV}} 418 }; 419 420 if (num_TxIntDelay > bd) { 421 adapter->tx_int_delay = TxIntDelay[bd]; 422 ixgb_validate_option(&adapter->tx_int_delay, &opt); 423 } else { 424 adapter->tx_int_delay = opt.def; 425 } 426 } 427 428 { /* Transmit Interrupt Delay Enable */ 429 static const struct ixgb_option opt = { 430 .type = enable_option, 431 .name = "Tx Interrupt Delay Enable", 432 .err = "defaulting to Enabled", 433 .def = OPTION_ENABLED 434 }; 435 436 if (num_IntDelayEnable > bd) { 437 unsigned int ide = IntDelayEnable[bd]; 438 ixgb_validate_option(&ide, &opt); 439 adapter->tx_int_delay_enable = ide; 440 } else { 441 adapter->tx_int_delay_enable = opt.def; 442 } 443 } 444}