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