ixgb_param.c 12.4 KB
Newer Older
L
Linus Torvalds 已提交
1 2
/*******************************************************************************

3
  Intel PRO/10GbE Linux driver
4
  Copyright(c) 1999 - 2008 Intel Corporation.
5 6 7 8 9 10 11 12

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
L
Linus Torvalds 已提交
13
  more details.
14

L
Linus Torvalds 已提交
15
  You should have received a copy of the GNU General Public License along with
16 17 18 19 20 21
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

L
Linus Torvalds 已提交
22 23
  Contact Information:
  Linux NICS <linux.nics@intel.com>
24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
L
Linus Torvalds 已提交
25 26 27 28
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497

*******************************************************************************/

29 30
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

L
Linus Torvalds 已提交
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
#include "ixgb.h"

/* This is the only thing that needs to be changed to adjust the
 * maximum number of ports that the driver can manage.
 */

#define IXGB_MAX_NIC 8

#define OPTION_UNSET	-1
#define OPTION_DISABLED 0
#define OPTION_ENABLED  1

/* 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 IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET }
S
Stephen Hemminger 已提交
49 50 51 52 53
#define IXGB_PARAM(X, desc)					\
	static int __devinitdata X[IXGB_MAX_NIC+1]		\
		= IXGB_PARAM_INIT;				\
	static unsigned int num_##X = 0;			\
	module_param_array_named(X, X, int, &num_##X, 0);	\
L
Linus Torvalds 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
	MODULE_PARM_DESC(X, desc);

/* Transmit Descriptor Count
 *
 * Valid Range: 64-4096
 *
 * Default Value: 256
 */

IXGB_PARAM(TxDescriptors, "Number of transmit descriptors");

/* Receive Descriptor Count
 *
 * Valid Range: 64-4096
 *
 * Default Value: 1024
 */

IXGB_PARAM(RxDescriptors, "Number of receive descriptors");

/* User Specified Flow Control Override
 *
 * Valid Range: 0-3
 *  - 0 - No Flow Control
 *  - 1 - Rx only, respond to PAUSE frames but do not generate them
 *  - 2 - Tx only, generate PAUSE frames but ignore them on receive
 *  - 3 - Full Flow Control Support
 *
A
Auke Kok 已提交
82
 * Default Value: 2 - Tx only (silicon bug avoidance)
L
Linus Torvalds 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
 */

IXGB_PARAM(FlowControl, "Flow Control setting");

/* XsumRX - Receive Checksum Offload Enable/Disable
 *
 * Valid Range: 0, 1
 *  - 0 - disables all checksum offload
 *  - 1 - enables receive IP/TCP/UDP checksum offload
 *        on 82597 based NICs
 *
 * Default Value: 1
 */

IXGB_PARAM(XsumRX, "Disable or enable Receive Checksum offload");

/* Transmit Interrupt Delay in units of 0.8192 microseconds
 *
 * Valid Range: 0-65535
 *
 * Default Value: 32
 */

IXGB_PARAM(TxIntDelay, "Transmit Interrupt Delay");

/* Receive Interrupt Delay in units of 0.8192 microseconds
 *
 * Valid Range: 0-65535
 *
 * Default Value: 72
 */

IXGB_PARAM(RxIntDelay, "Receive Interrupt Delay");

/* Receive Flow control high threshold (when we send a pause frame)
 * (FCRTH)
 *
 * Valid Range: 1,536 - 262,136 (0x600 - 0x3FFF8, 8 byte granularity)
 *
 * Default Value: 196,608 (0x30000)
 */

IXGB_PARAM(RxFCHighThresh, "Receive Flow Control High Threshold");

/* Receive Flow control low threshold (when we send a resume frame)
 * (FCRTL)
 *
 * Valid Range: 64 - 262,136 (0x40 - 0x3FFF8, 8 byte granularity)
 *              must be less than high threshold by at least 8 bytes
 *
 * Default Value:  163,840 (0x28000)
 */

IXGB_PARAM(RxFCLowThresh, "Receive Flow Control Low Threshold");

/* Flow control request timeout (how long to pause the link partner's tx)
 * (PAP 15:0)
 *
J
Jesse Brandeburg 已提交
141
 * Valid Range: 1 - 65535
L
Linus Torvalds 已提交
142
 *
A
Auke Kok 已提交
143
 * Default Value:  65535 (0xffff) (we'll send an xon if we recover)
L
Linus Torvalds 已提交
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
 */

IXGB_PARAM(FCReqTimeout, "Flow Control Request Timeout");

/* Interrupt Delay Enable
 *
 * Valid Range: 0, 1
 *
 *  - 0 - disables transmit interrupt delay
 *  - 1 - enables transmmit interrupt delay
 *
 * Default Value: 1
 */

IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable");


#define DEFAULT_TIDV	   		     32
#define MAX_TIDV			 0xFFFF
#define MIN_TIDV			      0

#define DEFAULT_RDTR		   	     72
#define MAX_RDTR			 0xFFFF
#define MIN_RDTR			      0

#define XSUMRX_DEFAULT		 OPTION_ENABLED

#define DEFAULT_FCRTL	  		0x28000
#define DEFAULT_FCRTH			0x30000
#define MIN_FCRTL			      0
#define MAX_FCRTL			0x3FFE8
#define MIN_FCRTH			      8
#define MAX_FCRTH			0x3FFF0

#define MIN_FCPAUSE			      1
#define MAX_FCPAUSE			 0xffff
A
Auke Kok 已提交
180
#define DEFAULT_FCPAUSE		  	 0xFFFF /* this may be too long */
L
Linus Torvalds 已提交
181 182 183

struct ixgb_option {
	enum { enable_option, range_option, list_option } type;
S
Stephen Hemminger 已提交
184 185
	const char *name;
	const char *err;
L
Linus Torvalds 已提交
186 187 188 189 190 191 192 193
	int def;
	union {
		struct {	/* range_option info */
			int min;
			int max;
		} r;
		struct {	/* list_option info */
			int nr;
194
			const struct ixgb_opt_list {
L
Linus Torvalds 已提交
195
				int i;
196
				const char *str;
L
Linus Torvalds 已提交
197 198 199 200 201 202
			} *p;
		} l;
	} arg;
};

static int __devinit
S
Stephen Hemminger 已提交
203
ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt)
L
Linus Torvalds 已提交
204
{
205
	if (*value == OPTION_UNSET) {
L
Linus Torvalds 已提交
206 207 208 209 210 211 212 213
		*value = opt->def;
		return 0;
	}

	switch (opt->type) {
	case enable_option:
		switch (*value) {
		case OPTION_ENABLED:
214
			pr_info("%s Enabled\n", opt->name);
L
Linus Torvalds 已提交
215 216
			return 0;
		case OPTION_DISABLED:
217
			pr_info("%s Disabled\n", opt->name);
L
Linus Torvalds 已提交
218 219 220 221
			return 0;
		}
		break;
	case range_option:
222
		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
223
			pr_info("%s set to %i\n", opt->name, *value);
L
Linus Torvalds 已提交
224 225 226 227 228
			return 0;
		}
		break;
	case list_option: {
		int i;
229
		const struct ixgb_opt_list *ent;
L
Linus Torvalds 已提交
230

231
		for (i = 0; i < opt->arg.l.nr; i++) {
L
Linus Torvalds 已提交
232
			ent = &opt->arg.l.p[i];
233 234
			if (*value == ent->i) {
				if (ent->str[0] != '\0')
235
					pr_info("%s\n", ent->str);
L
Linus Torvalds 已提交
236 237 238 239 240 241 242 243 244
				return 0;
			}
		}
	}
		break;
	default:
		BUG();
	}

245
	pr_info("Invalid %s specified (%i) %s\n", opt->name, *value, opt->err);
L
Linus Torvalds 已提交
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
	*value = opt->def;
	return -1;
}

/**
 * ixgb_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 __devinit
ixgb_check_options(struct ixgb_adapter *adapter)
{
	int bd = adapter->bd_number;
264
	if (bd >= IXGB_MAX_NIC) {
265 266
		pr_notice("Warning: no configuration for board #%i\n", bd);
		pr_notice("Using defaults for all values\n");
L
Linus Torvalds 已提交
267 268 269
	}

	{ /* Transmit Descriptor Count */
S
Stephen Hemminger 已提交
270
		const struct ixgb_option opt = {
L
Linus Torvalds 已提交
271 272 273 274 275 276 277 278 279
			.type = range_option,
			.name = "Transmit Descriptors",
			.err  = "using default of " __MODULE_STRING(DEFAULT_TXD),
			.def  = DEFAULT_TXD,
			.arg  = { .r = { .min = MIN_TXD,
					 .max = MAX_TXD}}
		};
		struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;

280
		if (num_TxDescriptors > bd) {
L
Linus Torvalds 已提交
281 282 283 284 285
			tx_ring->count = TxDescriptors[bd];
			ixgb_validate_option(&tx_ring->count, &opt);
		} else {
			tx_ring->count = opt.def;
		}
286
		tx_ring->count = ALIGN(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
L
Linus Torvalds 已提交
287 288
	}
	{ /* Receive Descriptor Count */
S
Stephen Hemminger 已提交
289
		const struct ixgb_option opt = {
L
Linus Torvalds 已提交
290 291 292 293 294 295 296 297 298
			.type = range_option,
			.name = "Receive Descriptors",
			.err  = "using default of " __MODULE_STRING(DEFAULT_RXD),
			.def  = DEFAULT_RXD,
			.arg  = { .r = { .min = MIN_RXD,
					 .max = MAX_RXD}}
		};
		struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;

299
		if (num_RxDescriptors > bd) {
L
Linus Torvalds 已提交
300 301 302 303 304
			rx_ring->count = RxDescriptors[bd];
			ixgb_validate_option(&rx_ring->count, &opt);
		} else {
			rx_ring->count = opt.def;
		}
305
		rx_ring->count = ALIGN(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
L
Linus Torvalds 已提交
306 307
	}
	{ /* Receive Checksum Offload Enable */
S
Stephen Hemminger 已提交
308
		const struct ixgb_option opt = {
L
Linus Torvalds 已提交
309 310 311 312 313 314
			.type = enable_option,
			.name = "Receive Checksum Offload",
			.err  = "defaulting to Enabled",
			.def  = OPTION_ENABLED
		};

315
		if (num_XsumRX > bd) {
S
Stephen Hemminger 已提交
316
			unsigned int rx_csum = XsumRX[bd];
L
Linus Torvalds 已提交
317 318 319 320 321 322 323 324
			ixgb_validate_option(&rx_csum, &opt);
			adapter->rx_csum = rx_csum;
		} else {
			adapter->rx_csum = opt.def;
		}
	}
	{ /* Flow Control */

325 326 327 328 329 330 331
		static const struct ixgb_opt_list fc_list[] = {
		       { ixgb_fc_none, "Flow Control Disabled" },
		       { ixgb_fc_rx_pause, "Flow Control Receive Only" },
		       { ixgb_fc_tx_pause, "Flow Control Transmit Only" },
		       { ixgb_fc_full, "Flow Control Enabled" },
		       { ixgb_fc_default, "Flow Control Hardware Default" }
		};
L
Linus Torvalds 已提交
332

333
		static const struct ixgb_option opt = {
L
Linus Torvalds 已提交
334 335 336
			.type = list_option,
			.name = "Flow Control",
			.err  = "reading default settings from EEPROM",
A
Auke Kok 已提交
337
			.def  = ixgb_fc_tx_pause,
338
			.arg  = { .l = { .nr = ARRAY_SIZE(fc_list),
L
Linus Torvalds 已提交
339 340 341
					 .p = fc_list }}
		};

342
		if (num_FlowControl > bd) {
S
Stephen Hemminger 已提交
343
			unsigned int fc = FlowControl[bd];
L
Linus Torvalds 已提交
344 345 346 347 348 349 350
			ixgb_validate_option(&fc, &opt);
			adapter->hw.fc.type = fc;
		} else {
			adapter->hw.fc.type = opt.def;
		}
	}
	{ /* Receive Flow Control High Threshold */
S
Stephen Hemminger 已提交
351
		const struct ixgb_option opt = {
L
Linus Torvalds 已提交
352 353 354 355 356 357 358 359
			.type = range_option,
			.name = "Rx Flow Control High Threshold",
			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTH),
			.def  = DEFAULT_FCRTH,
			.arg  = { .r = { .min = MIN_FCRTH,
					 .max = MAX_FCRTH}}
		};

360
		if (num_RxFCHighThresh > bd) {
L
Linus Torvalds 已提交
361 362 363 364 365
			adapter->hw.fc.high_water = RxFCHighThresh[bd];
			ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
		} else {
			adapter->hw.fc.high_water = opt.def;
		}
A
Auke Kok 已提交
366
		if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
367
			pr_info("Ignoring RxFCHighThresh when no RxFC\n");
L
Linus Torvalds 已提交
368 369
	}
	{ /* Receive Flow Control Low Threshold */
S
Stephen Hemminger 已提交
370
		const struct ixgb_option opt = {
L
Linus Torvalds 已提交
371 372 373 374 375 376 377 378
			.type = range_option,
			.name = "Rx Flow Control Low Threshold",
			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTL),
			.def  = DEFAULT_FCRTL,
			.arg  = { .r = { .min = MIN_FCRTL,
					 .max = MAX_FCRTL}}
		};

379
		if (num_RxFCLowThresh > bd) {
L
Linus Torvalds 已提交
380 381 382 383 384
			adapter->hw.fc.low_water = RxFCLowThresh[bd];
			ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
		} else {
			adapter->hw.fc.low_water = opt.def;
		}
A
Auke Kok 已提交
385
		if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
386
			pr_info("Ignoring RxFCLowThresh when no RxFC\n");
L
Linus Torvalds 已提交
387 388
	}
	{ /* Flow Control Pause Time Request*/
S
Stephen Hemminger 已提交
389
		const struct ixgb_option opt = {
L
Linus Torvalds 已提交
390 391 392 393 394 395 396 397
			.type = range_option,
			.name = "Flow Control Pause Time Request",
			.err  = "using default of "__MODULE_STRING(DEFAULT_FCPAUSE),
			.def  = DEFAULT_FCPAUSE,
			.arg = { .r = { .min = MIN_FCPAUSE,
					.max = MAX_FCPAUSE}}
		};

398
		if (num_FCReqTimeout > bd) {
S
Stephen Hemminger 已提交
399
			unsigned int pause_time = FCReqTimeout[bd];
L
Linus Torvalds 已提交
400 401 402 403 404
			ixgb_validate_option(&pause_time, &opt);
			adapter->hw.fc.pause_time = pause_time;
		} else {
			adapter->hw.fc.pause_time = opt.def;
		}
A
Auke Kok 已提交
405
		if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
406
			pr_info("Ignoring FCReqTimeout when no RxFC\n");
L
Linus Torvalds 已提交
407 408
	}
	/* high low and spacing check for rx flow control thresholds */
A
Auke Kok 已提交
409
	if (adapter->hw.fc.type & ixgb_fc_tx_pause) {
L
Linus Torvalds 已提交
410 411 412
		/* high must be greater than low */
		if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) {
			/* set defaults */
413
			pr_info("RxFCHighThresh must be >= (RxFCLowThresh + 8), Using Defaults\n");
L
Linus Torvalds 已提交
414 415 416 417 418
			adapter->hw.fc.high_water = DEFAULT_FCRTH;
			adapter->hw.fc.low_water  = DEFAULT_FCRTL;
		}
	}
	{ /* Receive Interrupt Delay */
S
Stephen Hemminger 已提交
419
		const struct ixgb_option opt = {
L
Linus Torvalds 已提交
420 421 422 423 424 425 426 427
			.type = range_option,
			.name = "Receive Interrupt Delay",
			.err  = "using default of " __MODULE_STRING(DEFAULT_RDTR),
			.def  = DEFAULT_RDTR,
			.arg  = { .r = { .min = MIN_RDTR,
					 .max = MAX_RDTR}}
		};

428
		if (num_RxIntDelay > bd) {
L
Linus Torvalds 已提交
429 430 431 432 433 434 435
			adapter->rx_int_delay = RxIntDelay[bd];
			ixgb_validate_option(&adapter->rx_int_delay, &opt);
		} else {
			adapter->rx_int_delay = opt.def;
		}
	}
	{ /* Transmit Interrupt Delay */
S
Stephen Hemminger 已提交
436
		const struct ixgb_option opt = {
L
Linus Torvalds 已提交
437 438 439 440 441 442 443 444
			.type = range_option,
			.name = "Transmit Interrupt Delay",
			.err  = "using default of " __MODULE_STRING(DEFAULT_TIDV),
			.def  = DEFAULT_TIDV,
			.arg  = { .r = { .min = MIN_TIDV,
					 .max = MAX_TIDV}}
		};

445
		if (num_TxIntDelay > bd) {
L
Linus Torvalds 已提交
446 447 448 449 450 451 452 453
			adapter->tx_int_delay = TxIntDelay[bd];
			ixgb_validate_option(&adapter->tx_int_delay, &opt);
		} else {
			adapter->tx_int_delay = opt.def;
		}
	}

	{ /* Transmit Interrupt Delay Enable */
S
Stephen Hemminger 已提交
454
		const struct ixgb_option opt = {
L
Linus Torvalds 已提交
455 456 457 458 459 460
			.type = enable_option,
			.name = "Tx Interrupt Delay Enable",
			.err  = "defaulting to Enabled",
			.def  = OPTION_ENABLED
		};

461
		if (num_IntDelayEnable > bd) {
S
Stephen Hemminger 已提交
462
			unsigned int ide = IntDelayEnable[bd];
L
Linus Torvalds 已提交
463 464 465 466 467 468 469
			ixgb_validate_option(&ide, &opt);
			adapter->tx_int_delay_enable = ide;
		} else {
			adapter->tx_int_delay_enable = opt.def;
		}
	}
}