Print this page
3014 Intel X540 Support
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/ixgbe/ixgbe_gld.c
+++ new/usr/src/uts/common/io/ixgbe/ixgbe_gld.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
|
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright(c) 2007-2010 Intel Corporation. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 + * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
28 29 */
29 30
30 31 #include "ixgbe_sw.h"
31 32
32 33 /*
33 34 * Bring the device out of the reset/quiesced state that it
34 35 * was in when the interface was registered.
35 36 */
36 37 int
37 38 ixgbe_m_start(void *arg)
38 39 {
39 40 ixgbe_t *ixgbe = (ixgbe_t *)arg;
40 41
41 42 mutex_enter(&ixgbe->gen_lock);
42 43
43 44 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
44 45 mutex_exit(&ixgbe->gen_lock);
45 46 return (ECANCELED);
46 47 }
47 48
48 49 if (ixgbe_start(ixgbe, B_TRUE) != IXGBE_SUCCESS) {
49 50 mutex_exit(&ixgbe->gen_lock);
50 51 return (EIO);
51 52 }
52 53
53 54 atomic_or_32(&ixgbe->ixgbe_state, IXGBE_STARTED);
54 55
55 56 mutex_exit(&ixgbe->gen_lock);
56 57
57 58 /*
58 59 * Enable and start the watchdog timer
59 60 */
60 61 ixgbe_enable_watchdog_timer(ixgbe);
61 62
62 63 return (0);
63 64 }
64 65
65 66 /*
66 67 * Stop the device and put it in a reset/quiesced state such
67 68 * that the interface can be unregistered.
68 69 */
69 70 void
70 71 ixgbe_m_stop(void *arg)
71 72 {
72 73 ixgbe_t *ixgbe = (ixgbe_t *)arg;
73 74
74 75 mutex_enter(&ixgbe->gen_lock);
75 76
76 77 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
77 78 mutex_exit(&ixgbe->gen_lock);
78 79 return;
79 80 }
80 81
81 82 atomic_and_32(&ixgbe->ixgbe_state, ~IXGBE_STARTED);
82 83
83 84 ixgbe_stop(ixgbe, B_TRUE);
84 85
85 86 mutex_exit(&ixgbe->gen_lock);
86 87
87 88 /*
88 89 * Disable and stop the watchdog timer
89 90 */
90 91 ixgbe_disable_watchdog_timer(ixgbe);
91 92 }
92 93
93 94 /*
94 95 * Set the promiscuity of the device.
95 96 */
96 97 int
97 98 ixgbe_m_promisc(void *arg, boolean_t on)
98 99 {
99 100 ixgbe_t *ixgbe = (ixgbe_t *)arg;
100 101 uint32_t reg_val;
101 102 struct ixgbe_hw *hw = &ixgbe->hw;
102 103
103 104 mutex_enter(&ixgbe->gen_lock);
104 105
105 106 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
106 107 mutex_exit(&ixgbe->gen_lock);
107 108 return (ECANCELED);
108 109 }
109 110 reg_val = IXGBE_READ_REG(hw, IXGBE_FCTRL);
110 111
111 112 if (on)
112 113 reg_val |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
113 114 else
114 115 reg_val &= (~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE));
115 116
116 117 IXGBE_WRITE_REG(&ixgbe->hw, IXGBE_FCTRL, reg_val);
117 118
118 119 mutex_exit(&ixgbe->gen_lock);
119 120
120 121 return (0);
121 122 }
122 123
123 124 /*
124 125 * Add/remove the addresses to/from the set of multicast
125 126 * addresses for which the device will receive packets.
126 127 */
127 128 int
128 129 ixgbe_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr)
129 130 {
130 131 ixgbe_t *ixgbe = (ixgbe_t *)arg;
131 132 int result;
132 133
133 134 mutex_enter(&ixgbe->gen_lock);
134 135
135 136 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
136 137 mutex_exit(&ixgbe->gen_lock);
137 138 return (ECANCELED);
138 139 }
139 140
140 141 result = (add) ? ixgbe_multicst_add(ixgbe, mcst_addr)
141 142 : ixgbe_multicst_remove(ixgbe, mcst_addr);
142 143
143 144 mutex_exit(&ixgbe->gen_lock);
144 145
145 146 return (result);
146 147 }
147 148
148 149 /*
149 150 * Pass on M_IOCTL messages passed to the DLD, and support
150 151 * private IOCTLs for debugging and ndd.
151 152 */
152 153 void
153 154 ixgbe_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
154 155 {
155 156 ixgbe_t *ixgbe = (ixgbe_t *)arg;
156 157 struct iocblk *iocp;
157 158 enum ioc_reply status;
158 159
159 160 iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
160 161 iocp->ioc_error = 0;
161 162
162 163 mutex_enter(&ixgbe->gen_lock);
163 164 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
164 165 mutex_exit(&ixgbe->gen_lock);
165 166 miocnak(q, mp, 0, EINVAL);
166 167 return;
167 168 }
168 169 mutex_exit(&ixgbe->gen_lock);
169 170
170 171 switch (iocp->ioc_cmd) {
171 172 case LB_GET_INFO_SIZE:
172 173 case LB_GET_INFO:
173 174 case LB_GET_MODE:
174 175 case LB_SET_MODE:
175 176 status = ixgbe_loopback_ioctl(ixgbe, iocp, mp);
176 177 break;
177 178
178 179 default:
179 180 status = IOC_INVAL;
180 181 break;
181 182 }
182 183
183 184 /*
184 185 * Decide how to reply
185 186 */
186 187 switch (status) {
187 188 default:
188 189 case IOC_INVAL:
189 190 /*
190 191 * Error, reply with a NAK and EINVAL or the specified error
191 192 */
192 193 miocnak(q, mp, 0, iocp->ioc_error == 0 ?
193 194 EINVAL : iocp->ioc_error);
194 195 break;
195 196
196 197 case IOC_DONE:
197 198 /*
198 199 * OK, reply already sent
199 200 */
200 201 break;
201 202
202 203 case IOC_ACK:
203 204 /*
204 205 * OK, reply with an ACK
205 206 */
206 207 miocack(q, mp, 0, 0);
207 208 break;
208 209
209 210 case IOC_REPLY:
210 211 /*
211 212 * OK, send prepared reply as ACK or NAK
212 213 */
213 214 mp->b_datap->db_type = iocp->ioc_error == 0 ?
214 215 M_IOCACK : M_IOCNAK;
215 216 qreply(q, mp);
216 217 break;
217 218 }
218 219 }
219 220
220 221 /*
221 222 * Obtain the MAC's capabilities and associated data from
222 223 * the driver.
223 224 */
224 225 boolean_t
225 226 ixgbe_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
226 227 {
227 228 ixgbe_t *ixgbe = (ixgbe_t *)arg;
228 229
229 230 switch (cap) {
230 231 case MAC_CAPAB_HCKSUM: {
231 232 uint32_t *tx_hcksum_flags = cap_data;
232 233
233 234 /*
234 235 * We advertise our capabilities only if tx hcksum offload is
235 236 * enabled. On receive, the stack will accept checksummed
236 237 * packets anyway, even if we haven't said we can deliver
237 238 * them.
238 239 */
239 240 if (!ixgbe->tx_hcksum_enable)
240 241 return (B_FALSE);
241 242
242 243 *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM;
243 244 break;
244 245 }
245 246 case MAC_CAPAB_LSO: {
246 247 mac_capab_lso_t *cap_lso = cap_data;
247 248
248 249 if (ixgbe->lso_enable) {
249 250 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
250 251 cap_lso->lso_basic_tcp_ipv4.lso_max = IXGBE_LSO_MAXLEN;
251 252 break;
252 253 } else {
253 254 return (B_FALSE);
254 255 }
255 256 }
256 257 case MAC_CAPAB_RINGS: {
257 258 mac_capab_rings_t *cap_rings = cap_data;
258 259
259 260 switch (cap_rings->mr_type) {
260 261 case MAC_RING_TYPE_RX:
261 262 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
262 263 cap_rings->mr_rnum = ixgbe->num_rx_rings;
263 264 cap_rings->mr_gnum = ixgbe->num_rx_groups;
264 265 cap_rings->mr_rget = ixgbe_fill_ring;
265 266 cap_rings->mr_gget = ixgbe_fill_group;
266 267 cap_rings->mr_gaddring = NULL;
267 268 cap_rings->mr_gremring = NULL;
268 269 break;
269 270 case MAC_RING_TYPE_TX:
270 271 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
271 272 cap_rings->mr_rnum = ixgbe->num_tx_rings;
272 273 cap_rings->mr_gnum = 0;
273 274 cap_rings->mr_rget = ixgbe_fill_ring;
274 275 cap_rings->mr_gget = NULL;
275 276 break;
276 277 default:
277 278 break;
278 279 }
279 280 break;
280 281 }
281 282 default:
282 283 return (B_FALSE);
283 284 }
284 285 return (B_TRUE);
285 286 }
286 287
287 288 int
288 289 ixgbe_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
289 290 uint_t pr_valsize, const void *pr_val)
290 291 {
291 292 ixgbe_t *ixgbe = (ixgbe_t *)arg;
292 293 struct ixgbe_hw *hw = &ixgbe->hw;
293 294 int err = 0;
294 295 uint32_t flow_control;
295 296 uint32_t cur_mtu, new_mtu;
296 297 uint32_t rx_size;
297 298 uint32_t tx_size;
298 299
299 300 mutex_enter(&ixgbe->gen_lock);
300 301 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
301 302 mutex_exit(&ixgbe->gen_lock);
302 303 return (ECANCELED);
303 304 }
304 305
305 306 if (ixgbe->loopback_mode != IXGBE_LB_NONE &&
306 307 ixgbe_param_locked(pr_num)) {
307 308 /*
308 309 * All en_* parameters are locked (read-only)
309 310 * while the device is in any sort of loopback mode.
310 311 */
311 312 mutex_exit(&ixgbe->gen_lock);
312 313 return (EBUSY);
313 314 }
314 315
315 316 switch (pr_num) {
316 317 case MAC_PROP_EN_10GFDX_CAP:
317 318 /* read/write on copper, read-only on serdes */
318 319 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
319 320 err = ENOTSUP;
320 321 break;
321 322 } else {
322 323 ixgbe->param_en_10000fdx_cap = *(uint8_t *)pr_val;
323 324 ixgbe->param_adv_10000fdx_cap = *(uint8_t *)pr_val;
324 325 goto setup_link;
325 326 }
326 327 case MAC_PROP_EN_1000FDX_CAP:
327 328 /* read/write on copper, read-only on serdes */
328 329 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
329 330 err = ENOTSUP;
330 331 break;
331 332 } else {
332 333 ixgbe->param_en_1000fdx_cap = *(uint8_t *)pr_val;
333 334 ixgbe->param_adv_1000fdx_cap = *(uint8_t *)pr_val;
334 335 goto setup_link;
335 336 }
336 337 case MAC_PROP_EN_100FDX_CAP:
337 338 /* read/write on copper, read-only on serdes */
338 339 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
339 340 err = ENOTSUP;
340 341 break;
341 342 } else {
342 343 ixgbe->param_en_100fdx_cap = *(uint8_t *)pr_val;
343 344 ixgbe->param_adv_100fdx_cap = *(uint8_t *)pr_val;
344 345 goto setup_link;
345 346 }
346 347 case MAC_PROP_AUTONEG:
347 348 /* read/write on copper, read-only on serdes */
348 349 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
349 350 err = ENOTSUP;
350 351 break;
351 352 } else {
352 353 ixgbe->param_adv_autoneg_cap = *(uint8_t *)pr_val;
353 354 goto setup_link;
354 355 }
355 356 case MAC_PROP_FLOWCTRL:
356 357 bcopy(pr_val, &flow_control, sizeof (flow_control));
357 358
358 359 switch (flow_control) {
359 360 default:
360 361 err = EINVAL;
361 362 break;
362 363 case LINK_FLOWCTRL_NONE:
363 364 hw->fc.requested_mode = ixgbe_fc_none;
364 365 break;
365 366 case LINK_FLOWCTRL_RX:
366 367 hw->fc.requested_mode = ixgbe_fc_rx_pause;
367 368 break;
368 369 case LINK_FLOWCTRL_TX:
369 370 hw->fc.requested_mode = ixgbe_fc_tx_pause;
370 371 break;
371 372 case LINK_FLOWCTRL_BI:
372 373 hw->fc.requested_mode = ixgbe_fc_full;
373 374 break;
374 375 }
375 376 setup_link:
376 377 if (err == 0) {
377 378 if (ixgbe_driver_setup_link(ixgbe, B_TRUE) !=
378 379 IXGBE_SUCCESS)
379 380 err = EINVAL;
380 381 }
381 382 break;
382 383 case MAC_PROP_ADV_10GFDX_CAP:
383 384 case MAC_PROP_ADV_1000FDX_CAP:
384 385 case MAC_PROP_ADV_100FDX_CAP:
385 386 case MAC_PROP_STATUS:
386 387 case MAC_PROP_SPEED:
387 388 case MAC_PROP_DUPLEX:
388 389 err = ENOTSUP; /* read-only prop. Can't set this. */
389 390 break;
390 391 case MAC_PROP_MTU:
391 392 cur_mtu = ixgbe->default_mtu;
392 393 bcopy(pr_val, &new_mtu, sizeof (new_mtu));
393 394 if (new_mtu == cur_mtu) {
394 395 err = 0;
395 396 break;
396 397 }
397 398
398 399 if (new_mtu < DEFAULT_MTU || new_mtu > ixgbe->capab->max_mtu) {
399 400 err = EINVAL;
400 401 break;
401 402 }
402 403
403 404 if (ixgbe->ixgbe_state & IXGBE_STARTED) {
404 405 err = EBUSY;
405 406 break;
406 407 }
407 408
408 409 err = mac_maxsdu_update(ixgbe->mac_hdl, new_mtu);
409 410 if (err == 0) {
410 411 ixgbe->default_mtu = new_mtu;
411 412 ixgbe->max_frame_size = ixgbe->default_mtu +
412 413 sizeof (struct ether_vlan_header) + ETHERFCSL;
413 414
414 415 /*
415 416 * Set rx buffer size
416 417 */
417 418 rx_size = ixgbe->max_frame_size + IPHDR_ALIGN_ROOM;
418 419 ixgbe->rx_buf_size = ((rx_size >> 10) + ((rx_size &
419 420 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
420 421
421 422 /*
422 423 * Set tx buffer size
423 424 */
424 425 tx_size = ixgbe->max_frame_size;
425 426 ixgbe->tx_buf_size = ((tx_size >> 10) + ((tx_size &
426 427 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
427 428 }
428 429 break;
429 430 case MAC_PROP_PRIVATE:
430 431 err = ixgbe_set_priv_prop(ixgbe, pr_name, pr_valsize, pr_val);
431 432 break;
432 433 default:
433 434 err = EINVAL;
434 435 break;
435 436 }
436 437 mutex_exit(&ixgbe->gen_lock);
437 438 return (err);
438 439 }
439 440
440 441 int
441 442 ixgbe_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
442 443 uint_t pr_valsize, void *pr_val)
443 444 {
444 445 ixgbe_t *ixgbe = (ixgbe_t *)arg;
445 446 struct ixgbe_hw *hw = &ixgbe->hw;
446 447 int err = 0;
447 448 uint32_t flow_control;
448 449 uint64_t tmp = 0;
449 450
450 451 switch (pr_num) {
451 452 case MAC_PROP_DUPLEX:
452 453 ASSERT(pr_valsize >= sizeof (link_duplex_t));
453 454 bcopy(&ixgbe->link_duplex, pr_val,
454 455 sizeof (link_duplex_t));
455 456 break;
456 457 case MAC_PROP_SPEED:
457 458 ASSERT(pr_valsize >= sizeof (uint64_t));
458 459 tmp = ixgbe->link_speed * 1000000ull;
459 460 bcopy(&tmp, pr_val, sizeof (tmp));
460 461 break;
461 462 case MAC_PROP_AUTONEG:
462 463 *(uint8_t *)pr_val = ixgbe->param_adv_autoneg_cap;
463 464 break;
464 465 case MAC_PROP_FLOWCTRL:
465 466 ASSERT(pr_valsize >= sizeof (uint32_t));
466 467
467 468 switch (hw->fc.requested_mode) {
468 469 case ixgbe_fc_none:
469 470 flow_control = LINK_FLOWCTRL_NONE;
470 471 break;
471 472 case ixgbe_fc_rx_pause:
472 473 flow_control = LINK_FLOWCTRL_RX;
473 474 break;
474 475 case ixgbe_fc_tx_pause:
475 476 flow_control = LINK_FLOWCTRL_TX;
476 477 break;
477 478 case ixgbe_fc_full:
478 479 flow_control = LINK_FLOWCTRL_BI;
479 480 break;
480 481 }
481 482 bcopy(&flow_control, pr_val, sizeof (flow_control));
482 483 break;
483 484 case MAC_PROP_ADV_10GFDX_CAP:
484 485 *(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap;
485 486 break;
486 487 case MAC_PROP_EN_10GFDX_CAP:
487 488 *(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap;
488 489 break;
489 490 case MAC_PROP_ADV_1000FDX_CAP:
490 491 *(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap;
491 492 break;
492 493 case MAC_PROP_EN_1000FDX_CAP:
493 494 *(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap;
494 495 break;
495 496 case MAC_PROP_ADV_100FDX_CAP:
496 497 *(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap;
497 498 break;
498 499 case MAC_PROP_EN_100FDX_CAP:
499 500 *(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap;
500 501 break;
501 502 case MAC_PROP_PRIVATE:
502 503 err = ixgbe_get_priv_prop(ixgbe, pr_name,
503 504 pr_valsize, pr_val);
504 505 break;
505 506 default:
506 507 err = EINVAL;
507 508 break;
508 509 }
509 510 return (err);
510 511 }
511 512
512 513 void
513 514 ixgbe_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
514 515 mac_prop_info_handle_t prh)
515 516 {
516 517 ixgbe_t *ixgbe = (ixgbe_t *)arg;
517 518 uint_t perm;
518 519
519 520 switch (pr_num) {
520 521 case MAC_PROP_DUPLEX:
521 522 case MAC_PROP_SPEED:
522 523 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
523 524 break;
524 525
525 526 case MAC_PROP_ADV_100FDX_CAP:
526 527 case MAC_PROP_ADV_1000FDX_CAP:
527 528 case MAC_PROP_ADV_10GFDX_CAP:
528 529 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
529 530 mac_prop_info_set_default_uint8(prh, 1);
530 531 break;
531 532
532 533 case MAC_PROP_AUTONEG:
533 534 case MAC_PROP_EN_10GFDX_CAP:
534 535 case MAC_PROP_EN_1000FDX_CAP:
535 536 case MAC_PROP_EN_100FDX_CAP:
536 537 perm = (ixgbe->hw.phy.media_type == ixgbe_media_type_copper) ?
537 538 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
538 539 mac_prop_info_set_perm(prh, perm);
539 540 mac_prop_info_set_default_uint8(prh, 1);
540 541 break;
541 542
542 543 case MAC_PROP_FLOWCTRL:
543 544 mac_prop_info_set_default_link_flowctrl(prh,
544 545 LINK_FLOWCTRL_NONE);
545 546 break;
546 547
547 548 case MAC_PROP_MTU:
548 549 mac_prop_info_set_range_uint32(prh,
549 550 DEFAULT_MTU, ixgbe->capab->max_mtu);
550 551 break;
551 552
552 553 case MAC_PROP_PRIVATE: {
553 554 char valstr[64];
554 555 int value;
555 556
556 557 bzero(valstr, sizeof (valstr));
557 558
558 559 if (strcmp(pr_name, "_adv_pause_cap") == 0 ||
559 560 strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
560 561 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
561 562 return;
562 563 }
563 564
564 565 if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
565 566 value = DEFAULT_TX_COPY_THRESHOLD;
566 567 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
567 568 value = DEFAULT_TX_RECYCLE_THRESHOLD;
568 569 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
569 570 value = DEFAULT_TX_OVERLOAD_THRESHOLD;
570 571 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
571 572 value = DEFAULT_TX_RESCHED_THRESHOLD;
572 573 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
573 574 value = DEFAULT_RX_COPY_THRESHOLD;
574 575 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
575 576 value = DEFAULT_RX_LIMIT_PER_INTR;
576 577 } if (strcmp(pr_name, "_intr_throttling") == 0) {
577 578 value = ixgbe->capab->def_intr_throttle;
578 579 } else {
579 580 return;
580 581 }
581 582
582 583 (void) snprintf(valstr, sizeof (valstr), "%x", value);
583 584 }
584 585 }
585 586 }
586 587
587 588 boolean_t
588 589 ixgbe_param_locked(mac_prop_id_t pr_num)
589 590 {
590 591 /*
591 592 * All en_* parameters are locked (read-only) while
592 593 * the device is in any sort of loopback mode ...
593 594 */
594 595 switch (pr_num) {
595 596 case MAC_PROP_EN_10GFDX_CAP:
596 597 case MAC_PROP_EN_1000FDX_CAP:
597 598 case MAC_PROP_EN_100FDX_CAP:
598 599 case MAC_PROP_AUTONEG:
599 600 case MAC_PROP_FLOWCTRL:
600 601 return (B_TRUE);
601 602 }
602 603 return (B_FALSE);
603 604 }
604 605
605 606 /* ARGSUSED */
606 607 int
607 608 ixgbe_set_priv_prop(ixgbe_t *ixgbe, const char *pr_name,
608 609 uint_t pr_valsize, const void *pr_val)
609 610 {
610 611 int err = 0;
611 612 long result;
612 613 struct ixgbe_hw *hw = &ixgbe->hw;
613 614 int i;
614 615
615 616 if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
616 617 if (pr_val == NULL) {
617 618 err = EINVAL;
618 619 return (err);
619 620 }
620 621 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
621 622 if (result < MIN_TX_COPY_THRESHOLD ||
622 623 result > MAX_TX_COPY_THRESHOLD)
623 624 err = EINVAL;
624 625 else {
625 626 ixgbe->tx_copy_thresh = (uint32_t)result;
626 627 }
627 628 return (err);
628 629 }
629 630 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
630 631 if (pr_val == NULL) {
631 632 err = EINVAL;
632 633 return (err);
633 634 }
634 635 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
635 636 if (result < MIN_TX_RECYCLE_THRESHOLD ||
636 637 result > MAX_TX_RECYCLE_THRESHOLD)
637 638 err = EINVAL;
638 639 else {
639 640 ixgbe->tx_recycle_thresh = (uint32_t)result;
640 641 }
641 642 return (err);
642 643 }
643 644 if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
644 645 if (pr_val == NULL) {
645 646 err = EINVAL;
646 647 return (err);
647 648 }
648 649 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
649 650 if (result < MIN_TX_OVERLOAD_THRESHOLD ||
650 651 result > MAX_TX_OVERLOAD_THRESHOLD)
651 652 err = EINVAL;
652 653 else {
653 654 ixgbe->tx_overload_thresh = (uint32_t)result;
654 655 }
655 656 return (err);
656 657 }
657 658 if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
658 659 if (pr_val == NULL) {
659 660 err = EINVAL;
660 661 return (err);
661 662 }
662 663 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
663 664 if (result < MIN_TX_RESCHED_THRESHOLD ||
664 665 result > MAX_TX_RESCHED_THRESHOLD)
665 666 err = EINVAL;
666 667 else {
667 668 ixgbe->tx_resched_thresh = (uint32_t)result;
668 669 }
669 670 return (err);
670 671 }
671 672 if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
672 673 if (pr_val == NULL) {
673 674 err = EINVAL;
674 675 return (err);
675 676 }
676 677 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
677 678 if (result < MIN_RX_COPY_THRESHOLD ||
678 679 result > MAX_RX_COPY_THRESHOLD)
679 680 err = EINVAL;
680 681 else {
681 682 ixgbe->rx_copy_thresh = (uint32_t)result;
682 683 }
683 684 return (err);
684 685 }
685 686 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
686 687 if (pr_val == NULL) {
687 688 err = EINVAL;
688 689 return (err);
689 690 }
690 691 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
691 692 if (result < MIN_RX_LIMIT_PER_INTR ||
692 693 result > MAX_RX_LIMIT_PER_INTR)
693 694 err = EINVAL;
694 695 else {
695 696 ixgbe->rx_limit_per_intr = (uint32_t)result;
696 697 }
697 698 return (err);
698 699 }
699 700 if (strcmp(pr_name, "_intr_throttling") == 0) {
700 701 if (pr_val == NULL) {
701 702 err = EINVAL;
702 703 return (err);
|
↓ open down ↓ |
665 lines elided |
↑ open up ↑ |
703 704 }
704 705 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
705 706
706 707 if (result < ixgbe->capab->min_intr_throttle ||
707 708 result > ixgbe->capab->max_intr_throttle)
708 709 err = EINVAL;
709 710 else {
710 711 ixgbe->intr_throttling[0] = (uint32_t)result;
711 712
712 713 /*
713 - * 82599 requires the interupt throttling rate is
714 - * a multiple of 8. This is enforced by the register
715 - * definiton.
714 + * 82599 and X540 require the interupt throttling
715 + * rate is a multiple of 8. This is enforced by the
716 + * register definiton.
716 717 */
717 - if (hw->mac.type == ixgbe_mac_82599EB)
718 + if (hw->mac.type == ixgbe_mac_82599EB ||
719 + hw->mac.type == ixgbe_mac_X540) {
718 720 ixgbe->intr_throttling[0] =
719 721 ixgbe->intr_throttling[0] & 0xFF8;
722 + }
720 723
721 724 for (i = 0; i < MAX_INTR_VECTOR; i++)
722 725 ixgbe->intr_throttling[i] =
723 726 ixgbe->intr_throttling[0];
724 727
725 728 /* Set interrupt throttling rate */
726 729 for (i = 0; i < ixgbe->intr_cnt; i++)
727 730 IXGBE_WRITE_REG(hw, IXGBE_EITR(i),
728 731 ixgbe->intr_throttling[i]);
729 732 }
730 733 return (err);
731 734 }
732 735 return (ENOTSUP);
733 736 }
734 737
735 738 int
736 739 ixgbe_get_priv_prop(ixgbe_t *ixgbe, const char *pr_name,
737 740 uint_t pr_valsize, void *pr_val)
738 741 {
739 742 int err = ENOTSUP;
740 743 int value;
741 744
742 745 if (strcmp(pr_name, "_adv_pause_cap") == 0) {
743 746 value = ixgbe->param_adv_pause_cap;
744 747 err = 0;
745 748 goto done;
746 749 }
747 750 if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
748 751 value = ixgbe->param_adv_asym_pause_cap;
749 752 err = 0;
750 753 goto done;
751 754 }
752 755 if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
753 756 value = ixgbe->tx_copy_thresh;
754 757 err = 0;
755 758 goto done;
756 759 }
757 760 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
758 761 value = ixgbe->tx_recycle_thresh;
759 762 err = 0;
760 763 goto done;
761 764 }
762 765 if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
763 766 value = ixgbe->tx_overload_thresh;
764 767 err = 0;
765 768 goto done;
766 769 }
767 770 if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
768 771 value = ixgbe->tx_resched_thresh;
769 772 err = 0;
770 773 goto done;
771 774 }
772 775 if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
773 776 value = ixgbe->rx_copy_thresh;
774 777 err = 0;
775 778 goto done;
776 779 }
777 780 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
778 781 value = ixgbe->rx_limit_per_intr;
779 782 err = 0;
780 783 goto done;
781 784 }
782 785 if (strcmp(pr_name, "_intr_throttling") == 0) {
783 786 value = ixgbe->intr_throttling[0];
784 787 err = 0;
785 788 goto done;
786 789 }
787 790 done:
788 791 if (err == 0) {
789 792 (void) snprintf(pr_val, pr_valsize, "%d", value);
790 793 }
791 794 return (err);
792 795 }
|
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX