1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright(c) 2007-2010 Intel Corporation. All rights reserved.
24 */
25
26 /*
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Copyright 2013, Nexenta Systems, Inc. All rights reserved.
29 * Copyright 2014 Pluribus Networks Inc.
30 * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
31 */
32
33 #include "igb_sw.h"
34
35 int
36 igb_m_stat(void *arg, uint_t stat, uint64_t *val)
37 {
38 igb_t *igb = (igb_t *)arg;
39 struct e1000_hw *hw = &igb->hw;
40 igb_stat_t *igb_ks;
41 uint32_t low_val, high_val;
42
43 igb_ks = (igb_stat_t *)igb->igb_ks->ks_data;
44
45 mutex_enter(&igb->gen_lock);
46
47 if (igb->igb_state & IGB_SUSPENDED) {
48 mutex_exit(&igb->gen_lock);
49 return (ECANCELED);
50 }
51
52 switch (stat) {
53 case MAC_STAT_IFSPEED:
54 *val = igb->link_speed * 1000000ull;
55 break;
56
57 case MAC_STAT_MULTIRCV:
58 igb->stat_mprc += E1000_READ_REG(hw, E1000_MPRC);
59 *val = igb->stat_mprc;
60 break;
61
62 case MAC_STAT_BRDCSTRCV:
63 igb->stat_bprc += E1000_READ_REG(hw, E1000_BPRC);
64 *val = igb->stat_bprc;
65 break;
66
67 case MAC_STAT_MULTIXMT:
68 igb->stat_mptc += E1000_READ_REG(hw, E1000_MPTC);
69 *val = igb->stat_mptc;
70 break;
71
72 case MAC_STAT_BRDCSTXMT:
73 igb->stat_bptc += E1000_READ_REG(hw, E1000_BPTC);
74 *val = igb->stat_bptc;
75 break;
76
77 case MAC_STAT_NORCVBUF:
78 igb->stat_rnbc += E1000_READ_REG(hw, E1000_RNBC);
79 *val = igb->stat_rnbc;
80 break;
81
82 case MAC_STAT_IERRORS:
83 igb->stat_rxerrc += E1000_READ_REG(hw, E1000_RXERRC);
84 igb->stat_algnerrc += E1000_READ_REG(hw, E1000_ALGNERRC);
85 igb_ks->rlec.value.ui64 +=
86 E1000_READ_REG(hw, E1000_RLEC);
87 igb->stat_crcerrs += E1000_READ_REG(hw, E1000_CRCERRS);
88 igb->stat_cexterr += E1000_READ_REG(hw, E1000_CEXTERR);
89 *val = igb->stat_rxerrc +
90 igb->stat_algnerrc +
91 igb_ks->rlec.value.ui64 +
92 igb->stat_crcerrs +
93 igb->stat_cexterr;
94 break;
95
96 case MAC_STAT_NOXMTBUF:
97 *val = 0;
98 break;
99
100 case MAC_STAT_OERRORS:
101 igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL);
102 *val = igb->stat_ecol;
103 break;
104
105 case MAC_STAT_COLLISIONS:
106 igb->stat_colc += E1000_READ_REG(hw, E1000_COLC);
107 *val = igb->stat_colc;
108 break;
109
110 case MAC_STAT_RBYTES:
111 /*
112 * The 64-bit register will reset whenever the upper
113 * 32 bits are read. So we need to read the lower
114 * 32 bits first, then read the upper 32 bits.
115 */
116 low_val = E1000_READ_REG(hw, E1000_TORL);
117 high_val = E1000_READ_REG(hw, E1000_TORH);
118 igb->stat_tor += (uint64_t)high_val << 32 | (uint64_t)low_val;
119 *val = igb->stat_tor;
120 break;
121
122 case MAC_STAT_IPACKETS:
123 igb->stat_tpr += E1000_READ_REG(hw, E1000_TPR);
124 *val = igb->stat_tpr;
125 break;
126
127 case MAC_STAT_OBYTES:
128 /*
129 * The 64-bit register will reset whenever the upper
130 * 32 bits are read. So we need to read the lower
131 * 32 bits first, then read the upper 32 bits.
132 */
133 low_val = E1000_READ_REG(hw, E1000_TOTL);
134 high_val = E1000_READ_REG(hw, E1000_TOTH);
135 igb->stat_tot += (uint64_t)high_val << 32 | (uint64_t)low_val;
136 *val = igb->stat_tot;
137 break;
138
139 case MAC_STAT_OPACKETS:
140 igb->stat_tpt += E1000_READ_REG(hw, E1000_TPT);
141 *val = igb->stat_tpt;
142 break;
143
144 /* RFC 1643 stats */
145 case ETHER_STAT_ALIGN_ERRORS:
146 igb->stat_algnerrc += E1000_READ_REG(hw, E1000_ALGNERRC);
147 *val = igb->stat_algnerrc;
148 break;
149
150 case ETHER_STAT_FCS_ERRORS:
151 igb->stat_crcerrs += E1000_READ_REG(hw, E1000_CRCERRS);
152 *val = igb->stat_crcerrs;
153 break;
154
155 case ETHER_STAT_FIRST_COLLISIONS:
156 igb->stat_scc += E1000_READ_REG(hw, E1000_SCC);
157 *val = igb->stat_scc;
158 break;
159
160 case ETHER_STAT_MULTI_COLLISIONS:
161 igb->stat_mcc += E1000_READ_REG(hw, E1000_MCC);
162 *val = igb->stat_mcc;
163 break;
164
165 case ETHER_STAT_SQE_ERRORS:
166 igb->stat_sec += E1000_READ_REG(hw, E1000_SEC);
167 *val = igb->stat_sec;
168 break;
169
170 case ETHER_STAT_DEFER_XMTS:
171 igb->stat_dc += E1000_READ_REG(hw, E1000_DC);
172 *val = igb->stat_dc;
173 break;
174
175 case ETHER_STAT_TX_LATE_COLLISIONS:
176 igb->stat_latecol += E1000_READ_REG(hw, E1000_LATECOL);
177 *val = igb->stat_latecol;
178 break;
179
180 case ETHER_STAT_EX_COLLISIONS:
181 igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL);
182 *val = igb->stat_ecol;
183 break;
184
185 case ETHER_STAT_MACXMT_ERRORS:
186 igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL);
187 *val = igb->stat_ecol;
188 break;
189
190 case ETHER_STAT_CARRIER_ERRORS:
191 igb->stat_cexterr += E1000_READ_REG(hw, E1000_CEXTERR);
192 *val = igb->stat_cexterr;
193 break;
194
195 case ETHER_STAT_TOOLONG_ERRORS:
196 igb->stat_roc += E1000_READ_REG(hw, E1000_ROC);
197 *val = igb->stat_roc;
198 break;
199
200 case ETHER_STAT_MACRCV_ERRORS:
201 igb->stat_rxerrc += E1000_READ_REG(hw, E1000_RXERRC);
202 *val = igb->stat_rxerrc;
203 break;
204
205 /* MII/GMII stats */
206 case ETHER_STAT_XCVR_ADDR:
207 /* The Internal PHY's MDI address for each MAC is 1 */
208 *val = 1;
209 break;
210
211 case ETHER_STAT_XCVR_ID:
212 *val = hw->phy.id | hw->phy.revision;
213 break;
214
215 case ETHER_STAT_XCVR_INUSE:
216 switch (igb->link_speed) {
217 case SPEED_1000:
218 *val =
219 (hw->phy.media_type == e1000_media_type_copper) ?
220 XCVR_1000T : XCVR_1000X;
221 break;
222 case SPEED_100:
223 *val =
224 (hw->phy.media_type == e1000_media_type_copper) ?
225 (igb->param_100t4_cap == 1) ?
226 XCVR_100T4 : XCVR_100T2 : XCVR_100X;
227 break;
228 case SPEED_10:
229 *val = XCVR_10;
230 break;
231 default:
232 *val = XCVR_NONE;
233 break;
234 }
235 break;
236
237 case ETHER_STAT_CAP_1000FDX:
238 *val = igb->param_1000fdx_cap;
239 break;
240
241 case ETHER_STAT_CAP_1000HDX:
242 *val = igb->param_1000hdx_cap;
243 break;
244
245 case ETHER_STAT_CAP_100FDX:
246 *val = igb->param_100fdx_cap;
247 break;
248
249 case ETHER_STAT_CAP_100HDX:
250 *val = igb->param_100hdx_cap;
251 break;
252
253 case ETHER_STAT_CAP_10FDX:
254 *val = igb->param_10fdx_cap;
255 break;
256
257 case ETHER_STAT_CAP_10HDX:
258 *val = igb->param_10hdx_cap;
259 break;
260
261 case ETHER_STAT_CAP_ASMPAUSE:
262 *val = igb->param_asym_pause_cap;
263 break;
264
265 case ETHER_STAT_CAP_PAUSE:
266 *val = igb->param_pause_cap;
267 break;
268
269 case ETHER_STAT_CAP_AUTONEG:
270 *val = igb->param_autoneg_cap;
271 break;
272
273 case ETHER_STAT_ADV_CAP_1000FDX:
274 *val = igb->param_adv_1000fdx_cap;
275 break;
276
277 case ETHER_STAT_ADV_CAP_1000HDX:
278 *val = igb->param_adv_1000hdx_cap;
279 break;
280
281 case ETHER_STAT_ADV_CAP_100FDX:
282 *val = igb->param_adv_100fdx_cap;
283 break;
284
285 case ETHER_STAT_ADV_CAP_100HDX:
286 *val = igb->param_adv_100hdx_cap;
287 break;
288
289 case ETHER_STAT_ADV_CAP_10FDX:
290 *val = igb->param_adv_10fdx_cap;
291 break;
292
293 case ETHER_STAT_ADV_CAP_10HDX:
294 *val = igb->param_adv_10hdx_cap;
295 break;
296
297 case ETHER_STAT_ADV_CAP_ASMPAUSE:
298 *val = igb->param_adv_asym_pause_cap;
299 break;
300
301 case ETHER_STAT_ADV_CAP_PAUSE:
302 *val = igb->param_adv_pause_cap;
303 break;
304
305 case ETHER_STAT_ADV_CAP_AUTONEG:
306 *val = hw->mac.autoneg;
307 break;
308
309 case ETHER_STAT_LP_CAP_1000FDX:
310 *val = igb->param_lp_1000fdx_cap;
311 break;
312
313 case ETHER_STAT_LP_CAP_1000HDX:
314 *val = igb->param_lp_1000hdx_cap;
315 break;
316
317 case ETHER_STAT_LP_CAP_100FDX:
318 *val = igb->param_lp_100fdx_cap;
319 break;
320
321 case ETHER_STAT_LP_CAP_100HDX:
322 *val = igb->param_lp_100hdx_cap;
323 break;
324
325 case ETHER_STAT_LP_CAP_10FDX:
326 *val = igb->param_lp_10fdx_cap;
327 break;
328
329 case ETHER_STAT_LP_CAP_10HDX:
330 *val = igb->param_lp_10hdx_cap;
331 break;
332
333 case ETHER_STAT_LP_CAP_ASMPAUSE:
334 *val = igb->param_lp_asym_pause_cap;
335 break;
336
337 case ETHER_STAT_LP_CAP_PAUSE:
338 *val = igb->param_lp_pause_cap;
339 break;
340
341 case ETHER_STAT_LP_CAP_AUTONEG:
342 *val = igb->param_lp_autoneg_cap;
343 break;
344
345 case ETHER_STAT_LINK_ASMPAUSE:
346 *val = igb->param_asym_pause_cap;
347 break;
348
349 case ETHER_STAT_LINK_PAUSE:
350 *val = igb->param_pause_cap;
351 break;
352
353 case ETHER_STAT_LINK_AUTONEG:
354 *val = hw->mac.autoneg;
355 break;
356
357 case ETHER_STAT_LINK_DUPLEX:
358 *val = (igb->link_duplex == FULL_DUPLEX) ?
359 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
360 break;
361
362 case ETHER_STAT_TOOSHORT_ERRORS:
363 igb->stat_ruc += E1000_READ_REG(hw, E1000_RUC);
364 *val = igb->stat_ruc;
365 break;
366
367 case ETHER_STAT_CAP_REMFAULT:
368 *val = igb->param_rem_fault;
369 break;
370
371 case ETHER_STAT_ADV_REMFAULT:
372 *val = igb->param_adv_rem_fault;
373 break;
374
375 case ETHER_STAT_LP_REMFAULT:
376 *val = igb->param_lp_rem_fault;
377 break;
378
379 case ETHER_STAT_JABBER_ERRORS:
380 igb->stat_rjc += E1000_READ_REG(hw, E1000_RJC);
381 *val = igb->stat_rjc;
382 break;
383
384 case ETHER_STAT_CAP_100T4:
385 *val = igb->param_100t4_cap;
386 break;
387
388 case ETHER_STAT_ADV_CAP_100T4:
389 *val = igb->param_adv_100t4_cap;
390 break;
391
392 case ETHER_STAT_LP_CAP_100T4:
393 *val = igb->param_lp_100t4_cap;
394 break;
395
396 default:
397 mutex_exit(&igb->gen_lock);
398 return (ENOTSUP);
399 }
400
401 mutex_exit(&igb->gen_lock);
402
403 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) {
404 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED);
405 return (EIO);
406 }
407
408 return (0);
409 }
410
411 /*
412 * Bring the device out of the reset/quiesced state that it
413 * was in when the interface was registered.
414 */
415 int
416 igb_m_start(void *arg)
417 {
418 igb_t *igb = (igb_t *)arg;
419
420 mutex_enter(&igb->gen_lock);
421
422 if (igb->igb_state & IGB_SUSPENDED) {
423 mutex_exit(&igb->gen_lock);
424 return (ECANCELED);
425 }
426
427 if (igb_start(igb, B_TRUE) != IGB_SUCCESS) {
428 mutex_exit(&igb->gen_lock);
429 return (EIO);
430 }
431
432 atomic_or_32(&igb->igb_state, IGB_STARTED);
433
434 mutex_exit(&igb->gen_lock);
435
436 /*
437 * Enable and start the watchdog timer
438 */
439 igb_enable_watchdog_timer(igb);
440
441 return (0);
442 }
443
444 /*
445 * Stop the device and put it in a reset/quiesced state such
446 * that the interface can be unregistered.
447 */
448 void
449 igb_m_stop(void *arg)
450 {
451 igb_t *igb = (igb_t *)arg;
452
453 mutex_enter(&igb->gen_lock);
454
455 if (igb->igb_state & IGB_SUSPENDED) {
456 mutex_exit(&igb->gen_lock);
457 return;
458 }
459
460 atomic_and_32(&igb->igb_state, ~IGB_STARTED);
461
462 igb_stop(igb, B_TRUE);
463
464 mutex_exit(&igb->gen_lock);
465
466 /*
467 * Disable and stop the watchdog timer
468 */
469 igb_disable_watchdog_timer(igb);
470 }
471
472 /*
473 * Set the promiscuity of the device.
474 */
475 int
476 igb_m_promisc(void *arg, boolean_t on)
477 {
478 igb_t *igb = (igb_t *)arg;
479 uint32_t reg_val;
480
481 mutex_enter(&igb->gen_lock);
482
483 if (igb->igb_state & IGB_SUSPENDED) {
484 mutex_exit(&igb->gen_lock);
485 return (ECANCELED);
486 }
487
488 reg_val = E1000_READ_REG(&igb->hw, E1000_RCTL);
489
490 if (on)
491 reg_val |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
492 else
493 reg_val &= (~(E1000_RCTL_UPE | E1000_RCTL_MPE));
494
495 E1000_WRITE_REG(&igb->hw, E1000_RCTL, reg_val);
496
497 mutex_exit(&igb->gen_lock);
498
499 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) {
500 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED);
501 return (EIO);
502 }
503
504 return (0);
505 }
506
507 /*
508 * Add/remove the addresses to/from the set of multicast
509 * addresses for which the device will receive packets.
510 */
511 int
512 igb_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr)
513 {
514 igb_t *igb = (igb_t *)arg;
515 int result;
516
517 mutex_enter(&igb->gen_lock);
518
519 if (igb->igb_state & IGB_SUSPENDED) {
520 mutex_exit(&igb->gen_lock);
521 return (ECANCELED);
522 }
523
524 result = (add) ? igb_multicst_add(igb, mcst_addr)
525 : igb_multicst_remove(igb, mcst_addr);
526
527 mutex_exit(&igb->gen_lock);
528
529 return (result);
530 }
531
532 /*
533 * Pass on M_IOCTL messages passed to the DLD, and support
534 * private IOCTLs for debugging and ndd.
535 */
536 void
537 igb_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
538 {
539 igb_t *igb = (igb_t *)arg;
540 struct iocblk *iocp;
541 enum ioc_reply status;
542
543 iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
544 iocp->ioc_error = 0;
545
546 mutex_enter(&igb->gen_lock);
547 if (igb->igb_state & IGB_SUSPENDED) {
548 mutex_exit(&igb->gen_lock);
549 miocnak(q, mp, 0, EINVAL);
550 return;
551 }
552 mutex_exit(&igb->gen_lock);
553
554 switch (iocp->ioc_cmd) {
555 case LB_GET_INFO_SIZE:
556 case LB_GET_INFO:
557 case LB_GET_MODE:
558 case LB_SET_MODE:
559 status = igb_loopback_ioctl(igb, iocp, mp);
560 break;
561
562 default:
563 status = IOC_INVAL;
564 break;
565 }
566
567 /*
568 * Decide how to reply
569 */
570 switch (status) {
571 default:
572 case IOC_INVAL:
573 /*
574 * Error, reply with a NAK and EINVAL or the specified error
575 */
576 miocnak(q, mp, 0, iocp->ioc_error == 0 ?
577 EINVAL : iocp->ioc_error);
578 break;
579
580 case IOC_DONE:
581 /*
582 * OK, reply already sent
583 */
584 break;
585
586 case IOC_ACK:
587 /*
588 * OK, reply with an ACK
589 */
590 miocack(q, mp, 0, 0);
591 break;
592
593 case IOC_REPLY:
594 /*
595 * OK, send prepared reply as ACK or NAK
596 */
597 mp->b_datap->db_type = iocp->ioc_error == 0 ?
598 M_IOCACK : M_IOCNAK;
599 qreply(q, mp);
600 break;
601 }
602 }
603
604 /*
605 * Add a MAC address to the target RX group.
606 */
607 static int
608 igb_addmac(void *arg, const uint8_t *mac_addr)
609 {
610 igb_rx_group_t *rx_group = (igb_rx_group_t *)arg;
611 igb_t *igb = rx_group->igb;
612 struct e1000_hw *hw = &igb->hw;
613 int i, slot;
614
615 mutex_enter(&igb->gen_lock);
616
617 if (igb->igb_state & IGB_SUSPENDED) {
618 mutex_exit(&igb->gen_lock);
619 return (ECANCELED);
620 }
621
622 if (igb->unicst_avail == 0) {
623 /* no slots available */
624 mutex_exit(&igb->gen_lock);
625 return (ENOSPC);
626 }
627
628 /*
629 * The slots from 0 to igb->num_rx_groups are reserved slots which
630 * are 1 to 1 mapped with group index directly. The other slots are
631 * shared between the all of groups. While adding a MAC address,
632 * it will try to set the reserved slots first, then the shared slots.
633 */
634 slot = -1;
635 if (igb->unicst_addr[rx_group->index].mac.set == 1) {
636 /*
637 * The reserved slot for current group is used, find the free
638 * slots in the shared slots.
639 */
640 for (i = igb->num_rx_groups; i < igb->unicst_total; i++) {
641 if (igb->unicst_addr[i].mac.set == 0) {
642 slot = i;
643 break;
644 }
645 }
646 } else
647 slot = rx_group->index;
648
649 if (slot == -1) {
650 /* no slots available in the shared slots */
651 mutex_exit(&igb->gen_lock);
652 return (ENOSPC);
653 }
654
655 /* Set VMDq according to the mode supported by hardware. */
656 e1000_rar_set_vmdq(hw, mac_addr, slot, igb->vmdq_mode, rx_group->index);
657
658 bcopy(mac_addr, igb->unicst_addr[slot].mac.addr, ETHERADDRL);
659 igb->unicst_addr[slot].mac.group_index = rx_group->index;
660 igb->unicst_addr[slot].mac.set = 1;
661 igb->unicst_avail--;
662
663 mutex_exit(&igb->gen_lock);
664
665 return (0);
666 }
667
668 /*
669 * Remove a MAC address from the specified RX group.
670 */
671 static int
672 igb_remmac(void *arg, const uint8_t *mac_addr)
673 {
674 igb_rx_group_t *rx_group = (igb_rx_group_t *)arg;
675 igb_t *igb = rx_group->igb;
676 struct e1000_hw *hw = &igb->hw;
677 int slot;
678
679 mutex_enter(&igb->gen_lock);
680
681 if (igb->igb_state & IGB_SUSPENDED) {
682 mutex_exit(&igb->gen_lock);
683 return (ECANCELED);
684 }
685
686 slot = igb_unicst_find(igb, mac_addr);
687 if (slot == -1) {
688 mutex_exit(&igb->gen_lock);
689 return (EINVAL);
690 }
691
692 if (igb->unicst_addr[slot].mac.set == 0) {
693 mutex_exit(&igb->gen_lock);
694 return (EINVAL);
695 }
696
697 /* Clear the MAC ddress in the slot */
698 e1000_rar_clear(hw, slot);
699 igb->unicst_addr[slot].mac.set = 0;
700 igb->unicst_avail++;
701
702 mutex_exit(&igb->gen_lock);
703
704 return (0);
705 }
706
707 /*
708 * Enable interrupt on the specificed rx ring.
709 */
710 int
711 igb_rx_ring_intr_enable(mac_intr_handle_t intrh)
712 {
713 igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)intrh;
714 igb_t *igb = rx_ring->igb;
715 struct e1000_hw *hw = &igb->hw;
716 uint32_t index = rx_ring->index;
717
718 if (igb->intr_type == DDI_INTR_TYPE_MSIX) {
719 /* Interrupt enabling for MSI-X */
720 igb->eims_mask |= (E1000_EICR_RX_QUEUE0 << index);
721 E1000_WRITE_REG(hw, E1000_EIMS, igb->eims_mask);
722 E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask);
723 } else {
724 ASSERT(index == 0);
725 /* Interrupt enabling for MSI and legacy */
726 igb->ims_mask |= E1000_IMS_RXT0;
727 E1000_WRITE_REG(hw, E1000_IMS, igb->ims_mask);
728 }
729
730 E1000_WRITE_FLUSH(hw);
731
732 return (0);
733 }
734
735 /*
736 * Disable interrupt on the specificed rx ring.
737 */
738 int
739 igb_rx_ring_intr_disable(mac_intr_handle_t intrh)
740 {
741 igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)intrh;
742 igb_t *igb = rx_ring->igb;
743 struct e1000_hw *hw = &igb->hw;
744 uint32_t index = rx_ring->index;
745
746 if (igb->intr_type == DDI_INTR_TYPE_MSIX) {
747 /* Interrupt disabling for MSI-X */
748 igb->eims_mask &= ~(E1000_EICR_RX_QUEUE0 << index);
749 E1000_WRITE_REG(hw, E1000_EIMC,
750 (E1000_EICR_RX_QUEUE0 << index));
751 E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask);
752 } else {
753 ASSERT(index == 0);
754 /* Interrupt disabling for MSI and legacy */
755 igb->ims_mask &= ~E1000_IMS_RXT0;
756 E1000_WRITE_REG(hw, E1000_IMC, E1000_IMS_RXT0);
757 }
758
759 E1000_WRITE_FLUSH(hw);
760
761 return (0);
762 }
763
764 /*
765 * Get the global ring index by a ring index within a group.
766 */
767 int
768 igb_get_rx_ring_index(igb_t *igb, int gindex, int rindex)
769 {
770 igb_rx_ring_t *rx_ring;
771 int i;
772
773 for (i = 0; i < igb->num_rx_rings; i++) {
774 rx_ring = &igb->rx_rings[i];
775 if (rx_ring->group_index == gindex)
776 rindex--;
777 if (rindex < 0)
778 return (i);
779 }
780
781 return (-1);
782 }
783
784 static int
785 igb_ring_start(mac_ring_driver_t rh, uint64_t mr_gen_num)
786 {
787 igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)rh;
788
789 mutex_enter(&rx_ring->rx_lock);
790 rx_ring->ring_gen_num = mr_gen_num;
791 mutex_exit(&rx_ring->rx_lock);
792 return (0);
793 }
794
795 /*
796 * Callback funtion for MAC layer to register all rings.
797 */
798 /* ARGSUSED */
799 void
800 igb_fill_ring(void *arg, mac_ring_type_t rtype, const int rg_index,
801 const int index, mac_ring_info_t *infop, mac_ring_handle_t rh)
802 {
803 igb_t *igb = (igb_t *)arg;
804 mac_intr_t *mintr = &infop->mri_intr;
805
806 switch (rtype) {
807 case MAC_RING_TYPE_RX: {
808 igb_rx_ring_t *rx_ring;
809 int global_index;
810
811 /*
812 * 'index' is the ring index within the group.
813 * We need the global ring index by searching in group.
814 */
815 global_index = igb_get_rx_ring_index(igb, rg_index, index);
816
817 ASSERT(global_index >= 0);
818
819 rx_ring = &igb->rx_rings[global_index];
820 rx_ring->ring_handle = rh;
821
822 infop->mri_driver = (mac_ring_driver_t)rx_ring;
823 infop->mri_start = igb_ring_start;
824 infop->mri_stop = NULL;
825 infop->mri_poll = (mac_ring_poll_t)igb_rx_ring_poll;
826 infop->mri_stat = igb_rx_ring_stat;
827
828 mintr->mi_handle = (mac_intr_handle_t)rx_ring;
829 mintr->mi_enable = igb_rx_ring_intr_enable;
830 mintr->mi_disable = igb_rx_ring_intr_disable;
831 if (igb->intr_type & (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) {
832 mintr->mi_ddi_handle =
833 igb->htable[rx_ring->intr_vector];
834 }
835 break;
836 }
837 case MAC_RING_TYPE_TX: {
838 ASSERT(index < igb->num_tx_rings);
839
840 igb_tx_ring_t *tx_ring = &igb->tx_rings[index];
841 tx_ring->ring_handle = rh;
842
843 infop->mri_driver = (mac_ring_driver_t)tx_ring;
844 infop->mri_start = NULL;
845 infop->mri_stop = NULL;
846 infop->mri_tx = igb_tx_ring_send;
847 infop->mri_stat = igb_tx_ring_stat;
848 if (igb->intr_type & (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) {
849 mintr->mi_ddi_handle =
850 igb->htable[tx_ring->intr_vector];
851 }
852 break;
853 }
854 default:
855 break;
856 }
857 }
858
859 void
860 igb_fill_group(void *arg, mac_ring_type_t rtype, const int index,
861 mac_group_info_t *infop, mac_group_handle_t gh)
862 {
863 igb_t *igb = (igb_t *)arg;
864
865 switch (rtype) {
866 case MAC_RING_TYPE_RX: {
867 igb_rx_group_t *rx_group;
868
869 ASSERT((index >= 0) && (index < igb->num_rx_groups));
870
871 rx_group = &igb->rx_groups[index];
872 rx_group->group_handle = gh;
873
874 infop->mgi_driver = (mac_group_driver_t)rx_group;
875 infop->mgi_start = NULL;
876 infop->mgi_stop = NULL;
877 infop->mgi_addmac = igb_addmac;
878 infop->mgi_remmac = igb_remmac;
879 infop->mgi_count = (igb->num_rx_rings / igb->num_rx_groups);
880
881 break;
882 }
883 case MAC_RING_TYPE_TX:
884 break;
885 default:
886 break;
887 }
888 }
889
890 /*
891 * Obtain the MAC's capabilities and associated data from
892 * the driver.
893 */
894 boolean_t
895 igb_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
896 {
897 igb_t *igb = (igb_t *)arg;
898
899 switch (cap) {
900 case MAC_CAPAB_HCKSUM: {
901 uint32_t *tx_hcksum_flags = cap_data;
902
903 /*
904 * We advertise our capabilities only if tx hcksum offload is
905 * enabled. On receive, the stack will accept checksummed
906 * packets anyway, even if we haven't said we can deliver
907 * them.
908 */
909 if (!igb->tx_hcksum_enable)
910 return (B_FALSE);
911
912 *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM;
913 break;
914 }
915 case MAC_CAPAB_LSO: {
916 mac_capab_lso_t *cap_lso = cap_data;
917
918 if (igb->lso_enable) {
919 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
920 cap_lso->lso_basic_tcp_ipv4.lso_max = IGB_LSO_MAXLEN;
921 break;
922 } else {
923 return (B_FALSE);
924 }
925 }
926 case MAC_CAPAB_RINGS: {
927 mac_capab_rings_t *cap_rings = cap_data;
928
929 switch (cap_rings->mr_type) {
930 case MAC_RING_TYPE_RX:
931 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
932 cap_rings->mr_rnum = igb->num_rx_rings;
933 cap_rings->mr_gnum = igb->num_rx_groups;
934 cap_rings->mr_rget = igb_fill_ring;
935 cap_rings->mr_gget = igb_fill_group;
936 cap_rings->mr_gaddring = NULL;
937 cap_rings->mr_gremring = NULL;
938
939 break;
940 case MAC_RING_TYPE_TX:
941 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
942 cap_rings->mr_rnum = igb->num_tx_rings;
943 cap_rings->mr_gnum = 0;
944 cap_rings->mr_rget = igb_fill_ring;
945 cap_rings->mr_gget = NULL;
946
947 break;
948 default:
949 break;
950 }
951 break;
952 }
953
954 default:
955 return (B_FALSE);
956 }
957 return (B_TRUE);
958 }
959
960 int
961 igb_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
962 uint_t pr_valsize, const void *pr_val)
963 {
964 igb_t *igb = (igb_t *)arg;
965 struct e1000_hw *hw = &igb->hw;
966 int err = 0;
967 uint32_t flow_control;
968 uint32_t cur_mtu, new_mtu;
969 uint32_t rx_size;
970 uint32_t tx_size;
971
972 mutex_enter(&igb->gen_lock);
973 if (igb->igb_state & IGB_SUSPENDED) {
974 mutex_exit(&igb->gen_lock);
975 return (ECANCELED);
976 }
977
978 if (igb->loopback_mode != IGB_LB_NONE && igb_param_locked(pr_num)) {
979 /*
980 * All en_* parameters are locked (read-only)
981 * while the device is in any sort of loopback mode.
982 */
983 mutex_exit(&igb->gen_lock);
984 return (EBUSY);
985 }
986
987 switch (pr_num) {
988 case MAC_PROP_EN_1000FDX_CAP:
989 /* read/write on copper, read-only on serdes */
990 if (hw->phy.media_type != e1000_media_type_copper) {
991 err = ENOTSUP;
992 break;
993 }
994 igb->param_en_1000fdx_cap = *(uint8_t *)pr_val;
995 igb->param_adv_1000fdx_cap = *(uint8_t *)pr_val;
996 goto setup_link;
997 case MAC_PROP_EN_100FDX_CAP:
998 if (hw->phy.media_type != e1000_media_type_copper) {
999 err = ENOTSUP;
1000 break;
1001 }
1002 igb->param_en_100fdx_cap = *(uint8_t *)pr_val;
1003 igb->param_adv_100fdx_cap = *(uint8_t *)pr_val;
1004 goto setup_link;
1005 case MAC_PROP_EN_100HDX_CAP:
1006 if (hw->phy.media_type != e1000_media_type_copper) {
1007 err = ENOTSUP;
1008 break;
1009 }
1010 igb->param_en_100hdx_cap = *(uint8_t *)pr_val;
1011 igb->param_adv_100hdx_cap = *(uint8_t *)pr_val;
1012 goto setup_link;
1013 case MAC_PROP_EN_10FDX_CAP:
1014 if (hw->phy.media_type != e1000_media_type_copper) {
1015 err = ENOTSUP;
1016 break;
1017 }
1018 igb->param_en_10fdx_cap = *(uint8_t *)pr_val;
1019 igb->param_adv_10fdx_cap = *(uint8_t *)pr_val;
1020 goto setup_link;
1021 case MAC_PROP_EN_10HDX_CAP:
1022 if (hw->phy.media_type != e1000_media_type_copper) {
1023 err = ENOTSUP;
1024 break;
1025 }
1026 igb->param_en_10hdx_cap = *(uint8_t *)pr_val;
1027 igb->param_adv_10hdx_cap = *(uint8_t *)pr_val;
1028 goto setup_link;
1029 case MAC_PROP_AUTONEG:
1030 if (hw->phy.media_type != e1000_media_type_copper) {
1031 err = ENOTSUP;
1032 break;
1033 }
1034 igb->param_adv_autoneg_cap = *(uint8_t *)pr_val;
1035 goto setup_link;
1036 case MAC_PROP_FLOWCTRL:
1037 bcopy(pr_val, &flow_control, sizeof (flow_control));
1038
1039 switch (flow_control) {
1040 default:
1041 err = EINVAL;
1042 break;
1043 case LINK_FLOWCTRL_NONE:
1044 hw->fc.requested_mode = e1000_fc_none;
1045 break;
1046 case LINK_FLOWCTRL_RX:
1047 hw->fc.requested_mode = e1000_fc_rx_pause;
1048 break;
1049 case LINK_FLOWCTRL_TX:
1050 hw->fc.requested_mode = e1000_fc_tx_pause;
1051 break;
1052 case LINK_FLOWCTRL_BI:
1053 hw->fc.requested_mode = e1000_fc_full;
1054 break;
1055 }
1056 setup_link:
1057 if (err == 0) {
1058 if (igb_setup_link(igb, B_TRUE) != IGB_SUCCESS)
1059 err = EINVAL;
1060 }
1061 break;
1062 case MAC_PROP_ADV_1000FDX_CAP:
1063 case MAC_PROP_ADV_1000HDX_CAP:
1064 case MAC_PROP_ADV_100T4_CAP:
1065 case MAC_PROP_ADV_100FDX_CAP:
1066 case MAC_PROP_ADV_100HDX_CAP:
1067 case MAC_PROP_ADV_10FDX_CAP:
1068 case MAC_PROP_ADV_10HDX_CAP:
1069 case MAC_PROP_EN_1000HDX_CAP:
1070 case MAC_PROP_EN_100T4_CAP:
1071 case MAC_PROP_STATUS:
1072 case MAC_PROP_SPEED:
1073 case MAC_PROP_DUPLEX:
1074 err = ENOTSUP; /* read-only prop. Can't set this. */
1075 break;
1076 case MAC_PROP_MTU:
1077 /* adapter must be stopped for an MTU change */
1078 if (igb->igb_state & IGB_STARTED) {
1079 err = EBUSY;
1080 break;
1081 }
1082
1083 cur_mtu = igb->default_mtu;
1084 bcopy(pr_val, &new_mtu, sizeof (new_mtu));
1085 if (new_mtu == cur_mtu) {
1086 err = 0;
1087 break;
1088 }
1089
1090 if (new_mtu < MIN_MTU || new_mtu > MAX_MTU) {
1091 err = EINVAL;
1092 break;
1093 }
1094
1095 err = mac_maxsdu_update(igb->mac_hdl, new_mtu);
1096 if (err == 0) {
1097 igb->default_mtu = new_mtu;
1098 igb->max_frame_size = igb->default_mtu +
1099 sizeof (struct ether_vlan_header) + ETHERFCSL;
1100
1101 /*
1102 * Set rx buffer size
1103 */
1104 rx_size = igb->max_frame_size + IPHDR_ALIGN_ROOM;
1105 igb->rx_buf_size = ((rx_size >> 10) + ((rx_size &
1106 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
1107
1108 /*
1109 * Set tx buffer size
1110 */
1111 tx_size = igb->max_frame_size;
1112 igb->tx_buf_size = ((tx_size >> 10) + ((tx_size &
1113 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
1114 }
1115 break;
1116 case MAC_PROP_PRIVATE:
1117 err = igb_set_priv_prop(igb, pr_name, pr_valsize, pr_val);
1118 break;
1119 default:
1120 err = ENOTSUP;
1121 break;
1122 }
1123
1124 mutex_exit(&igb->gen_lock);
1125
1126 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) {
1127 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED);
1128 return (EIO);
1129 }
1130
1131 return (err);
1132 }
1133
1134 int
1135 igb_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
1136 uint_t pr_valsize, void *pr_val)
1137 {
1138 igb_t *igb = (igb_t *)arg;
1139 struct e1000_hw *hw = &igb->hw;
1140 int err = 0;
1141 uint32_t flow_control;
1142 uint64_t tmp = 0;
1143
1144 switch (pr_num) {
1145 case MAC_PROP_DUPLEX:
1146 ASSERT(pr_valsize >= sizeof (link_duplex_t));
1147 bcopy(&igb->link_duplex, pr_val, sizeof (link_duplex_t));
1148 break;
1149 case MAC_PROP_SPEED:
1150 ASSERT(pr_valsize >= sizeof (uint64_t));
1151 tmp = igb->link_speed * 1000000ull;
1152 bcopy(&tmp, pr_val, sizeof (tmp));
1153 break;
1154 case MAC_PROP_AUTONEG:
1155 ASSERT(pr_valsize >= sizeof (uint8_t));
1156 *(uint8_t *)pr_val = igb->param_adv_autoneg_cap;
1157 break;
1158 case MAC_PROP_FLOWCTRL:
1159 ASSERT(pr_valsize >= sizeof (uint32_t));
1160 switch (hw->fc.requested_mode) {
1161 case e1000_fc_none:
1162 flow_control = LINK_FLOWCTRL_NONE;
1163 break;
1164 case e1000_fc_rx_pause:
1165 flow_control = LINK_FLOWCTRL_RX;
1166 break;
1167 case e1000_fc_tx_pause:
1168 flow_control = LINK_FLOWCTRL_TX;
1169 break;
1170 case e1000_fc_full:
1171 flow_control = LINK_FLOWCTRL_BI;
1172 break;
1173 }
1174 bcopy(&flow_control, pr_val, sizeof (flow_control));
1175 break;
1176 case MAC_PROP_ADV_1000FDX_CAP:
1177 *(uint8_t *)pr_val = igb->param_adv_1000fdx_cap;
1178 break;
1179 case MAC_PROP_EN_1000FDX_CAP:
1180 *(uint8_t *)pr_val = igb->param_en_1000fdx_cap;
1181 break;
1182 case MAC_PROP_ADV_1000HDX_CAP:
1183 *(uint8_t *)pr_val = igb->param_adv_1000hdx_cap;
1184 break;
1185 case MAC_PROP_EN_1000HDX_CAP:
1186 *(uint8_t *)pr_val = igb->param_en_1000hdx_cap;
1187 break;
1188 case MAC_PROP_ADV_100T4_CAP:
1189 *(uint8_t *)pr_val = igb->param_adv_100t4_cap;
1190 break;
1191 case MAC_PROP_EN_100T4_CAP:
1192 *(uint8_t *)pr_val = igb->param_en_100t4_cap;
1193 break;
1194 case MAC_PROP_ADV_100FDX_CAP:
1195 *(uint8_t *)pr_val = igb->param_adv_100fdx_cap;
1196 break;
1197 case MAC_PROP_EN_100FDX_CAP:
1198 *(uint8_t *)pr_val = igb->param_en_100fdx_cap;
1199 break;
1200 case MAC_PROP_ADV_100HDX_CAP:
1201 *(uint8_t *)pr_val = igb->param_adv_100hdx_cap;
1202 break;
1203 case MAC_PROP_EN_100HDX_CAP:
1204 *(uint8_t *)pr_val = igb->param_en_100hdx_cap;
1205 break;
1206 case MAC_PROP_ADV_10FDX_CAP:
1207 *(uint8_t *)pr_val = igb->param_adv_10fdx_cap;
1208 break;
1209 case MAC_PROP_EN_10FDX_CAP:
1210 *(uint8_t *)pr_val = igb->param_en_10fdx_cap;
1211 break;
1212 case MAC_PROP_ADV_10HDX_CAP:
1213 *(uint8_t *)pr_val = igb->param_adv_10hdx_cap;
1214 break;
1215 case MAC_PROP_EN_10HDX_CAP:
1216 *(uint8_t *)pr_val = igb->param_en_10hdx_cap;
1217 break;
1218 case MAC_PROP_PRIVATE:
1219 err = igb_get_priv_prop(igb, pr_name, pr_valsize, pr_val);
1220 break;
1221 default:
1222 err = ENOTSUP;
1223 break;
1224 }
1225 return (err);
1226 }
1227
1228 void
1229 igb_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
1230 mac_prop_info_handle_t prh)
1231 {
1232 igb_t *igb = (igb_t *)arg;
1233 struct e1000_hw *hw = &igb->hw;
1234 uint16_t phy_status, phy_ext_status;
1235
1236 switch (pr_num) {
1237 case MAC_PROP_DUPLEX:
1238 case MAC_PROP_SPEED:
1239 case MAC_PROP_ADV_1000FDX_CAP:
1240 case MAC_PROP_ADV_1000HDX_CAP:
1241 case MAC_PROP_EN_1000HDX_CAP:
1242 case MAC_PROP_ADV_100T4_CAP:
1243 case MAC_PROP_EN_100T4_CAP:
1244 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1245 break;
1246
1247 case MAC_PROP_EN_1000FDX_CAP:
1248 if (hw->phy.media_type != e1000_media_type_copper) {
1249 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1250 } else {
1251 (void) e1000_read_phy_reg(hw, PHY_EXT_STATUS,
1252 &phy_ext_status);
1253 mac_prop_info_set_default_uint8(prh,
1254 ((phy_ext_status & IEEE_ESR_1000T_FD_CAPS) ||
1255 (phy_ext_status & IEEE_ESR_1000X_FD_CAPS)) ? 1 : 0);
1256 }
1257 break;
1258
1259 case MAC_PROP_ADV_100FDX_CAP:
1260 case MAC_PROP_EN_100FDX_CAP:
1261 if (hw->phy.media_type != e1000_media_type_copper) {
1262 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1263 } else {
1264 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1265 mac_prop_info_set_default_uint8(prh,
1266 ((phy_status & MII_SR_100X_FD_CAPS) ||
1267 (phy_status & MII_SR_100T2_FD_CAPS)) ? 1 : 0);
1268 }
1269 break;
1270
1271 case MAC_PROP_ADV_100HDX_CAP:
1272 case MAC_PROP_EN_100HDX_CAP:
1273 if (hw->phy.media_type != e1000_media_type_copper) {
1274 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1275 } else {
1276 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1277 mac_prop_info_set_default_uint8(prh,
1278 ((phy_status & MII_SR_100X_HD_CAPS) ||
1279 (phy_status & MII_SR_100T2_HD_CAPS)) ? 1 : 0);
1280 }
1281 break;
1282
1283 case MAC_PROP_ADV_10FDX_CAP:
1284 case MAC_PROP_EN_10FDX_CAP:
1285 if (hw->phy.media_type != e1000_media_type_copper) {
1286 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1287 } else {
1288 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1289 mac_prop_info_set_default_uint8(prh,
1290 (phy_status & MII_SR_10T_FD_CAPS) ? 1 : 0);
1291 }
1292 break;
1293
1294 case MAC_PROP_ADV_10HDX_CAP:
1295 case MAC_PROP_EN_10HDX_CAP:
1296 if (hw->phy.media_type != e1000_media_type_copper) {
1297 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1298 } else {
1299 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1300 mac_prop_info_set_default_uint8(prh,
1301 (phy_status & MII_SR_10T_HD_CAPS) ? 1 : 0);
1302 }
1303 break;
1304
1305 case MAC_PROP_AUTONEG:
1306 if (hw->phy.media_type != e1000_media_type_copper) {
1307 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1308 } else {
1309 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1310 mac_prop_info_set_default_uint8(prh,
1311 (phy_status & MII_SR_AUTONEG_CAPS) ? 1 : 0);
1312 }
1313 break;
1314
1315 case MAC_PROP_FLOWCTRL:
1316 mac_prop_info_set_default_link_flowctrl(prh, LINK_FLOWCTRL_BI);
1317 break;
1318
1319 case MAC_PROP_MTU:
1320 mac_prop_info_set_range_uint32(prh, MIN_MTU, MAX_MTU);
1321 break;
1322
1323 case MAC_PROP_PRIVATE:
1324 igb_priv_prop_info(igb, pr_name, prh);
1325 break;
1326 }
1327
1328 }
1329
1330 boolean_t
1331 igb_param_locked(mac_prop_id_t pr_num)
1332 {
1333 /*
1334 * All en_* parameters are locked (read-only) while
1335 * the device is in any sort of loopback mode ...
1336 */
1337 switch (pr_num) {
1338 case MAC_PROP_EN_1000FDX_CAP:
1339 case MAC_PROP_EN_1000HDX_CAP:
1340 case MAC_PROP_EN_100T4_CAP:
1341 case MAC_PROP_EN_100FDX_CAP:
1342 case MAC_PROP_EN_100HDX_CAP:
1343 case MAC_PROP_EN_10FDX_CAP:
1344 case MAC_PROP_EN_10HDX_CAP:
1345 case MAC_PROP_AUTONEG:
1346 case MAC_PROP_FLOWCTRL:
1347 return (B_TRUE);
1348 }
1349 return (B_FALSE);
1350 }
1351
1352 /* ARGSUSED */
1353 int
1354 igb_set_priv_prop(igb_t *igb, const char *pr_name,
1355 uint_t pr_valsize, const void *pr_val)
1356 {
1357 int err = 0;
1358 long result;
1359 struct e1000_hw *hw = &igb->hw;
1360 int i;
1361
1362 if (strcmp(pr_name, "_eee_support") == 0) {
1363 if (pr_val == NULL)
1364 return (EINVAL);
1365 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1366 switch (result) {
1367 case 0:
1368 case 1:
1369 /*
1370 * For now, only supported on I350/I354.
1371 * Add new mac.type values (or use < instead)
1372 * as new cards offer up EEE.
1373 */
1374 switch (hw->mac.type) {
1375 case e1000_i350:
1376 /* Must set this prior to the set call. */
1377 hw->dev_spec._82575.eee_disable = !result;
1378 if (e1000_set_eee_i350(hw) != E1000_SUCCESS)
1379 err = EIO;
1380 break;
1381 case e1000_i354:
1382 /* Must set this prior to the set call. */
1383 hw->dev_spec._82575.eee_disable = !result;
1384 if (e1000_set_eee_i354(hw) != E1000_SUCCESS)
1385 err = EIO;
1386 break;
1387 default:
1388 return (ENXIO);
1389 }
1390 break;
1391 default:
1392 err = EINVAL;
1393 /* FALLTHRU */
1394 }
1395 return (err);
1396 }
1397 if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
1398 if (pr_val == NULL) {
1399 err = EINVAL;
1400 return (err);
1401 }
1402 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1403 if (result < MIN_TX_COPY_THRESHOLD ||
1404 result > MAX_TX_COPY_THRESHOLD)
1405 err = EINVAL;
1406 else {
1407 igb->tx_copy_thresh = (uint32_t)result;
1408 }
1409 return (err);
1410 }
1411 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
1412 if (pr_val == NULL) {
1413 err = EINVAL;
1414 return (err);
1415 }
1416 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1417 if (result < MIN_TX_RECYCLE_THRESHOLD ||
1418 result > MAX_TX_RECYCLE_THRESHOLD)
1419 err = EINVAL;
1420 else {
1421 igb->tx_recycle_thresh = (uint32_t)result;
1422 }
1423 return (err);
1424 }
1425 if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
1426 if (pr_val == NULL) {
1427 err = EINVAL;
1428 return (err);
1429 }
1430 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1431 if (result < MIN_TX_OVERLOAD_THRESHOLD ||
1432 result > MAX_TX_OVERLOAD_THRESHOLD)
1433 err = EINVAL;
1434 else {
1435 igb->tx_overload_thresh = (uint32_t)result;
1436 }
1437 return (err);
1438 }
1439 if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
1440 if (pr_val == NULL) {
1441 err = EINVAL;
1442 return (err);
1443 }
1444 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1445 if (result < MIN_TX_RESCHED_THRESHOLD ||
1446 result > MAX_TX_RESCHED_THRESHOLD ||
1447 result > igb->tx_ring_size)
1448 err = EINVAL;
1449 else {
1450 igb->tx_resched_thresh = (uint32_t)result;
1451 }
1452 return (err);
1453 }
1454 if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
1455 if (pr_val == NULL) {
1456 err = EINVAL;
1457 return (err);
1458 }
1459 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1460 if (result < MIN_RX_COPY_THRESHOLD ||
1461 result > MAX_RX_COPY_THRESHOLD)
1462 err = EINVAL;
1463 else {
1464 igb->rx_copy_thresh = (uint32_t)result;
1465 }
1466 return (err);
1467 }
1468 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
1469 if (pr_val == NULL) {
1470 err = EINVAL;
1471 return (err);
1472 }
1473 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1474 if (result < MIN_RX_LIMIT_PER_INTR ||
1475 result > MAX_RX_LIMIT_PER_INTR)
1476 err = EINVAL;
1477 else {
1478 igb->rx_limit_per_intr = (uint32_t)result;
1479 }
1480 return (err);
1481 }
1482 if (strcmp(pr_name, "_intr_throttling") == 0) {
1483 if (pr_val == NULL) {
1484 err = EINVAL;
1485 return (err);
1486 }
1487 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1488
1489 if (result < igb->capab->min_intr_throttle ||
1490 result > igb->capab->max_intr_throttle)
1491 err = EINVAL;
1492 else {
1493 igb->intr_throttling[0] = (uint32_t)result;
1494
1495 for (i = 0; i < MAX_NUM_EITR; i++)
1496 igb->intr_throttling[i] =
1497 igb->intr_throttling[0];
1498
1499 /* Set interrupt throttling rate */
1500 for (i = 0; i < igb->intr_cnt; i++)
1501 E1000_WRITE_REG(hw, E1000_EITR(i),
1502 igb->intr_throttling[i]);
1503 }
1504 return (err);
1505 }
1506 return (ENOTSUP);
1507 }
1508
1509 int
1510 igb_get_priv_prop(igb_t *igb, const char *pr_name, uint_t pr_valsize,
1511 void *pr_val)
1512 {
1513 int value;
1514
1515 if (strcmp(pr_name, "_adv_pause_cap") == 0) {
1516 value = igb->param_adv_pause_cap;
1517 } else if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
1518 value = igb->param_adv_asym_pause_cap;
1519 } else if (strcmp(pr_name, "_eee_support") == 0) {
1520 /*
1521 * For now, only supported on I350. Add new mac.type values
1522 * (or use < instead) as new cards offer up EEE.
1523 */
1524 switch (igb->hw.mac.type) {
1525 case e1000_i350:
1526 case e1000_i354:
1527 value = !(igb->hw.dev_spec._82575.eee_disable);
1528 break;
1529 default:
1530 value = 0;
1531 }
1532 } else if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
1533 value = igb->tx_copy_thresh;
1534 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
1535 value = igb->tx_recycle_thresh;
1536 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
1537 value = igb->tx_overload_thresh;
1538 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
1539 value = igb->tx_resched_thresh;
1540 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
1541 value = igb->rx_copy_thresh;
1542 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
1543 value = igb->rx_limit_per_intr;
1544 } else if (strcmp(pr_name, "_intr_throttling") == 0) {
1545 value = igb->intr_throttling[0];
1546 } else {
1547 return (ENOTSUP);
1548 }
1549
1550 (void) snprintf(pr_val, pr_valsize, "%d", value);
1551 return (0);
1552 }
1553
1554 void
1555 igb_priv_prop_info(igb_t *igb, const char *pr_name, mac_prop_info_handle_t prh)
1556 {
1557 char valstr[64];
1558 int value;
1559
1560 if (strcmp(pr_name, "_adv_pause_cap") == 0 ||
1561 strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
1562 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1563 return;
1564 } else if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
1565 value = DEFAULT_TX_COPY_THRESHOLD;
1566 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
1567 value = DEFAULT_TX_RECYCLE_THRESHOLD;
1568 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
1569 value = DEFAULT_TX_OVERLOAD_THRESHOLD;
1570 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
1571 value = DEFAULT_TX_RESCHED_THRESHOLD;
1572 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
1573 value = DEFAULT_RX_COPY_THRESHOLD;
1574 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
1575 value = DEFAULT_RX_LIMIT_PER_INTR;
1576 } else if (strcmp(pr_name, "_intr_throttling") == 0) {
1577 value = igb->capab->def_intr_throttle;
1578 } else {
1579 return;
1580 }
1581
1582 (void) snprintf(valstr, sizeof (valstr), "%d", value);
1583 mac_prop_info_set_default_str(prh, valstr);
1584 }