2 * Copyright (c) 2010 Steven Stallion. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer in the documentation and/or other materials provided
13 * with the distribution.
14 * 3. Neither the name of the copyright owner nor the names of any
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/byteorder.h>
32 #include <sys/types.h>
33 #include <sys/errno.h>
34 #include <sys/varargs.h>
35 #include <sys/cmn_err.h>
39 #include <sys/devops.h>
40 #include <sys/modctl.h>
41 #include <sys/sysmacros.h>
43 #include <sys/ddi_intr.h>
44 #include <sys/sunddi.h>
45 #include <sys/stream.h>
46 #include <sys/strsun.h>
48 #include <sys/ethernet.h>
50 #include <sys/crc32.h>
53 #include <sys/mac_ether.h>
54 #include <sys/mac_provider.h>
58 /* Autoconfiguration entry points */
59 static int efe_attach(dev_info_t
*, ddi_attach_cmd_t
);
60 static int efe_detach(dev_info_t
*, ddi_detach_cmd_t
);
61 static int efe_quiesce(dev_info_t
*);
63 /* MII entry points */
64 static uint16_t efe_mii_read(void *, uint8_t, uint8_t);
65 static void efe_mii_write(void *, uint8_t, uint8_t, uint16_t);
66 static void efe_mii_notify(void *, link_state_t
);
68 /* MAC entry points */
69 static int efe_m_getstat(void *, uint_t
, uint64_t *);
70 static int efe_m_start(void *);
71 static void efe_m_stop(void *);
72 static int efe_m_setpromisc(void *, boolean_t
);
73 static int efe_m_multicst(void *, boolean_t
, const uint8_t *);
74 static int efe_m_unicst(void *, const uint8_t *);
75 static mblk_t
*efe_m_tx(void *, mblk_t
*);
76 static int efe_m_setprop(void *, const char *, mac_prop_id_t
, uint_t
,
78 static int efe_m_getprop(void *, const char *, mac_prop_id_t
, uint_t
,
80 static void efe_m_propinfo(void *, const char *, mac_prop_id_t
,
81 mac_prop_info_handle_t
);
83 /* ISR/periodic callbacks */
84 static uint_t
efe_intr(caddr_t
, caddr_t
);
86 /* Support functions */
87 static void efe_init(efe_t
*);
88 static void efe_init_rx_ring(efe_t
*);
89 static void efe_init_tx_ring(efe_t
*);
90 static void efe_reset(efe_t
*);
91 static void efe_start(efe_t
*);
92 static void efe_stop(efe_t
*);
93 static void efe_stop_dma(efe_t
*);
94 static inline void efe_restart(efe_t
*);
95 static int efe_suspend(efe_t
*);
96 static int efe_resume(efe_t
*);
98 static efe_ring_t
*efe_ring_alloc(dev_info_t
*, size_t);
99 static void efe_ring_free(efe_ring_t
**);
100 static efe_buf_t
*efe_buf_alloc(dev_info_t
*, size_t);
101 static void efe_buf_free(efe_buf_t
**);
103 static void efe_intr_enable(efe_t
*);
104 static void efe_intr_disable(efe_t
*);
106 static mblk_t
*efe_recv(efe_t
*);
107 static mblk_t
*efe_recv_pkt(efe_t
*, efe_desc_t
*);
109 static int efe_send(efe_t
*, mblk_t
*);
110 static void efe_send_done(efe_t
*);
112 static void efe_getaddr(efe_t
*, uint8_t *);
113 static void efe_setaddr(efe_t
*, uint8_t *);
114 static void efe_setmchash(efe_t
*, uint16_t *);
116 static void efe_eeprom_read(efe_t
*, uint8_t *, size_t, uint8_t);
117 static uint16_t efe_eeprom_readw(efe_t
*, int, uint8_t);
118 static inline int efe_eeprom_readbit(efe_t
*);
119 static inline void efe_eeprom_writebit(efe_t
*, int);
121 static void efe_dprintf(dev_info_t
*, int, const char *, ...);
124 #define efe_debug(dip, ...) \
125 efe_dprintf((dip), CE_CONT, __VA_ARGS__)
127 #define efe_debug(dip, ...) /*EMPTY*/
130 #define efe_error(dip, ...) \
131 efe_dprintf((dip), CE_WARN, __VA_ARGS__)
133 extern struct mod_ops mod_driverops
;
135 DDI_DEFINE_STREAM_OPS(efe_dev_ops
, nulldev
, nulldev
, efe_attach
, efe_detach
,
136 nodev
, NULL
, D_MP
, NULL
, efe_quiesce
);
138 static struct modldrv modldrv
= {
139 &mod_driverops
, /* drv_modops */
140 "EPIC/100 Fast Ethernet", /* drv_linkinfo */
141 &efe_dev_ops
/* drv_dev_ops */
144 static struct modlinkage modlinkage
= {
145 MODREV_1
, /* ml_rev */
146 { &modldrv
, NULL
} /* ml_linkage */
149 static ddi_device_acc_attr_t efe_regs_acc_attr
= {
150 DDI_DEVICE_ATTR_V0
, /* devacc_attr_version */
151 DDI_STRUCTURE_LE_ACC
, /* devacc_attr_endian_flags */
152 DDI_STRICTORDER_ACC
/* devacc_attr_dataorder */
155 static ddi_device_acc_attr_t efe_buf_acc_attr
= {
156 DDI_DEVICE_ATTR_V0
, /* devacc_attr_version */
157 DDI_NEVERSWAP_ACC
, /* devacc_attr_endian_flags */
158 DDI_STRICTORDER_ACC
/* devacc_attr_dataorder */
161 static ddi_dma_attr_t efe_dma_attr
= {
162 DMA_ATTR_V0
, /* dma_attr_version */
163 0, /* dma_attr_addr_lo */
164 0xFFFFFFFFUL
, /* dma_attr_addr_hi */
165 0x7FFFFFFFUL
, /* dma_attr_count_max */
166 4, /* dma_attr_align */
167 0x7F, /* dma_attr_burstsizes */
168 1, /* dma_attr_minxfer */
169 0xFFFFFFFFUL
, /* dma_attr_maxxfer */
170 0xFFFFFFFFUL
, /* dma_attr_seg */
171 1, /* dma_attr_sgllen */
172 1, /* dma_attr_granular */
173 0 /* dma_attr_flags */
176 static mii_ops_t efe_mii_ops
= {
177 MII_OPS_VERSION
, /* mii_version */
178 efe_mii_read
, /* mii_read */
179 efe_mii_write
, /* mii_write */
180 efe_mii_notify
/* mii_notify */
183 static mac_callbacks_t efe_m_callbacks
= {
184 MC_SETPROP
| MC_GETPROP
, /* mc_callbacks */
185 efe_m_getstat
, /* mc_getstat */
186 efe_m_start
, /* mc_start */
187 efe_m_stop
, /* mc_stop */
188 efe_m_setpromisc
, /* mc_setpromisc */
189 efe_m_multicst
, /* mc_multicst */
190 efe_m_unicst
, /* mc_unicst */
191 efe_m_tx
, /* mc_tx */
192 NULL
, /* mc_reserved */
194 NULL
, /* mc_getcapab */
197 efe_m_setprop
, /* mc_setprop */
198 efe_m_getprop
, /* mc_getprop */
199 efe_m_propinfo
/* mc_propinfo */
202 static uint8_t efe_broadcast
[] = {
203 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
206 static uint16_t efe_mchash_promisc
[] = {
207 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
211 * Loadable module entry points.
218 mac_init_ops(&efe_dev_ops
, "efe");
219 if ((error
= mod_install(&modlinkage
)) != DDI_SUCCESS
) {
220 mac_fini_ops(&efe_dev_ops
);
231 if ((error
= mod_remove(&modlinkage
)) == DDI_SUCCESS
) {
232 mac_fini_ops(&efe_dev_ops
);
239 _info(struct modinfo
*modinfop
)
241 return (mod_info(&modlinkage
, modinfop
));
245 * Autoconfiguration entry points.
248 efe_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
250 ddi_acc_handle_t pci
;
256 mac_register_t
*macp
;
263 efep
= ddi_get_driver_private(dip
);
264 return (efe_resume(efep
));
267 return (DDI_FAILURE
);
273 if (pci_config_setup(dip
, &pci
) != DDI_SUCCESS
) {
274 efe_error(dip
, "unable to setup PCI configuration!");
275 return (DDI_FAILURE
);
278 pci_config_put16(pci
, PCI_CONF_COMM
,
279 pci_config_get16(pci
, PCI_CONF_COMM
) | PCI_COMM_MAE
| PCI_COMM_ME
);
281 pci_config_teardown(&pci
);
283 if (ddi_intr_get_supported_types(dip
, &types
)
284 != DDI_SUCCESS
|| !(types
& DDI_INTR_TYPE_FIXED
)) {
285 efe_error(dip
, "fixed interrupts not supported!");
286 return (DDI_FAILURE
);
289 if (ddi_intr_get_nintrs(dip
, DDI_INTR_TYPE_FIXED
, &count
)
290 != DDI_SUCCESS
|| count
!= 1) {
291 efe_error(dip
, "no fixed interrupts available!");
292 return (DDI_FAILURE
);
296 * Initialize soft state.
298 efep
= kmem_zalloc(sizeof (efe_t
), KM_SLEEP
);
299 ddi_set_driver_private(dip
, efep
);
303 if (ddi_regs_map_setup(dip
, 1, (caddr_t
*)&efep
->efe_regs
, 0, 0,
304 &efe_regs_acc_attr
, &efep
->efe_regs_acch
) != DDI_SUCCESS
) {
305 efe_error(dip
, "unable to setup register mapping!");
309 efep
->efe_rx_ring
= efe_ring_alloc(efep
->efe_dip
, RXDESCL
);
310 if (efep
->efe_rx_ring
== NULL
) {
311 efe_error(efep
->efe_dip
, "unable to allocate rx ring!");
315 efep
->efe_tx_ring
= efe_ring_alloc(efep
->efe_dip
, TXDESCL
);
316 if (efep
->efe_tx_ring
== NULL
) {
317 efe_error(efep
->efe_dip
, "unable to allocate tx ring!");
321 if (ddi_intr_alloc(dip
, &efep
->efe_intrh
, DDI_INTR_TYPE_FIXED
, 0,
322 count
, &actual
, DDI_INTR_ALLOC_STRICT
) != DDI_SUCCESS
||
324 efe_error(dip
, "unable to allocate fixed interrupt!");
328 if (ddi_intr_get_pri(efep
->efe_intrh
, &pri
) != DDI_SUCCESS
||
329 pri
>= ddi_intr_get_hilevel_pri()) {
330 efe_error(dip
, "unable to get valid interrupt priority!");
334 mutex_init(&efep
->efe_intrlock
, NULL
, MUTEX_DRIVER
,
337 mutex_init(&efep
->efe_txlock
, NULL
, MUTEX_DRIVER
,
343 mutex_enter(&efep
->efe_intrlock
);
344 mutex_enter(&efep
->efe_txlock
);
348 mutex_exit(&efep
->efe_txlock
);
349 mutex_exit(&efep
->efe_intrlock
);
351 /* Use factory address as default */
352 efe_getaddr(efep
, efep
->efe_macaddr
);
357 if (ddi_intr_add_handler(efep
->efe_intrh
, efe_intr
, efep
, NULL
)
359 efe_error(dip
, "unable to add interrupt handler!");
363 if (ddi_intr_enable(efep
->efe_intrh
) != DDI_SUCCESS
) {
364 efe_error(dip
, "unable to enable interrupt!");
369 * Allocate MII resources.
371 if ((efep
->efe_miih
= mii_alloc(efep
, dip
, &efe_mii_ops
)) == NULL
) {
372 efe_error(dip
, "unable to allocate mii resources!");
377 * Allocate MAC resources.
379 if ((macp
= mac_alloc(MAC_VERSION
)) == NULL
) {
380 efe_error(dip
, "unable to allocate mac resources!");
384 macp
->m_type_ident
= MAC_PLUGIN_IDENT_ETHER
;
385 macp
->m_driver
= efep
;
387 macp
->m_src_addr
= efep
->efe_macaddr
;
388 macp
->m_callbacks
= &efe_m_callbacks
;
390 macp
->m_max_sdu
= ETHERMTU
;
391 macp
->m_margin
= VLAN_TAGSZ
;
393 if (mac_register(macp
, &efep
->efe_mh
) != 0) {
394 efe_error(dip
, "unable to register with mac!");
401 return (DDI_SUCCESS
);
408 if (efep
->efe_miih
!= NULL
) {
409 mii_free(efep
->efe_miih
);
412 if (efep
->efe_intrh
!= NULL
) {
413 (void) ddi_intr_disable(efep
->efe_intrh
);
414 (void) ddi_intr_remove_handler(efep
->efe_intrh
);
415 (void) ddi_intr_free(efep
->efe_intrh
);
418 mutex_destroy(&efep
->efe_txlock
);
419 mutex_destroy(&efep
->efe_intrlock
);
421 if (efep
->efe_tx_ring
!= NULL
) {
422 efe_ring_free(&efep
->efe_tx_ring
);
424 if (efep
->efe_rx_ring
!= NULL
) {
425 efe_ring_free(&efep
->efe_rx_ring
);
428 if (efep
->efe_regs_acch
!= NULL
) {
429 ddi_regs_map_free(&efep
->efe_regs_acch
);
432 kmem_free(efep
, sizeof (efe_t
));
434 return (DDI_FAILURE
);
438 efe_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
440 efe_t
*efep
= ddi_get_driver_private(dip
);
447 return (efe_suspend(efep
));
450 return (DDI_FAILURE
);
453 if (mac_unregister(efep
->efe_mh
) != 0) {
454 efe_error(dip
, "unable to unregister from mac!");
455 return (DDI_FAILURE
);
458 mii_free(efep
->efe_miih
);
460 (void) ddi_intr_disable(efep
->efe_intrh
);
461 (void) ddi_intr_remove_handler(efep
->efe_intrh
);
462 (void) ddi_intr_free(efep
->efe_intrh
);
464 mutex_destroy(&efep
->efe_txlock
);
465 mutex_destroy(&efep
->efe_intrlock
);
467 if (efep
->efe_tx_ring
!= NULL
) {
468 efe_ring_free(&efep
->efe_tx_ring
);
470 if (efep
->efe_rx_ring
!= NULL
) {
471 efe_ring_free(&efep
->efe_rx_ring
);
474 ddi_regs_map_free(&efep
->efe_regs_acch
);
476 kmem_free(efep
, sizeof (efe_t
));
478 return (DDI_SUCCESS
);
482 efe_quiesce(dev_info_t
*dip
)
484 efe_t
*efep
= ddi_get_driver_private(dip
);
486 PUTCSR(efep
, CSR_GENCTL
, GENCTL_RESET
);
487 drv_usecwait(RESET_DELAY
);
489 PUTCSR(efep
, CSR_GENCTL
, GENCTL_PWRDWN
);
491 return (DDI_SUCCESS
);
498 efe_mii_read(void *arg
, uint8_t phy
, uint8_t reg
)
502 PUTCSR(efep
, CSR_MMCTL
, MMCTL_READ
|
503 reg
<< MMCTL_PHYREG
| phy
<< MMCTL_PHYADDR
);
505 for (int i
= 0; i
< MII_DELAY_CYCLES
; ++i
) {
506 if (!(GETCSR(efep
, CSR_MMCTL
) & MMCTL_READ
)) {
507 return ((uint16_t)GETCSR(efep
, CSR_MMDATA
));
509 drv_usecwait(MII_DELAY
);
511 efe_error(efep
->efe_dip
, "timed out reading from MII!");
517 efe_mii_write(void *arg
, uint8_t phy
, uint8_t reg
, uint16_t data
)
521 PUTCSR(efep
, CSR_MMDATA
, data
);
523 PUTCSR(efep
, CSR_MMCTL
, MMCTL_WRITE
|
524 reg
<< MMCTL_PHYREG
| phy
<< MMCTL_PHYADDR
);
526 for (int i
= 0; i
< MII_DELAY_CYCLES
; ++i
) {
527 if (!(GETCSR(efep
, CSR_MMCTL
) & MMCTL_WRITE
)) {
530 drv_usecwait(MII_DELAY
);
532 efe_error(efep
->efe_dip
, "timed out writing to MII!");
536 efe_mii_notify(void *arg
, link_state_t link
)
540 mac_link_update(efep
->efe_mh
, link
);
547 efe_m_getstat(void *arg
, uint_t stat
, uint64_t *val
)
551 if (mii_m_getstat(efep
->efe_miih
, stat
, val
) == 0) {
556 case MAC_STAT_MULTIRCV
:
557 *val
= efep
->efe_multircv
;
560 case MAC_STAT_BRDCSTRCV
:
561 *val
= efep
->efe_brdcstrcv
;
564 case MAC_STAT_MULTIXMT
:
565 *val
= efep
->efe_multixmt
;
568 case MAC_STAT_BRDCSTXMT
:
569 *val
= efep
->efe_brdcstxmt
;
572 case MAC_STAT_NORCVBUF
:
573 *val
= efep
->efe_norcvbuf
;
576 case MAC_STAT_IERRORS
:
577 *val
= efep
->efe_ierrors
;
580 case MAC_STAT_NOXMTBUF
:
581 *val
= efep
->efe_noxmtbuf
;
584 case MAC_STAT_OERRORS
:
585 *val
= efep
->efe_oerrors
;
588 case MAC_STAT_COLLISIONS
:
589 *val
= efep
->efe_collisions
;
592 case MAC_STAT_RBYTES
:
593 *val
= efep
->efe_rbytes
;
596 case MAC_STAT_IPACKETS
:
597 *val
= efep
->efe_ipackets
;
600 case MAC_STAT_OBYTES
:
601 *val
= efep
->efe_obytes
;
604 case MAC_STAT_OPACKETS
:
605 *val
= efep
->efe_opackets
;
608 case MAC_STAT_UNDERFLOWS
:
609 *val
= efep
->efe_uflo
;
612 case MAC_STAT_OVERFLOWS
:
613 *val
= efep
->efe_oflo
;
616 case ETHER_STAT_ALIGN_ERRORS
:
617 *val
= efep
->efe_align_errors
;
620 case ETHER_STAT_FCS_ERRORS
:
621 *val
= efep
->efe_fcs_errors
;
624 case ETHER_STAT_FIRST_COLLISIONS
:
625 *val
= efep
->efe_first_collisions
;
628 case ETHER_STAT_TX_LATE_COLLISIONS
:
629 *val
= efep
->efe_tx_late_collisions
;
632 case ETHER_STAT_DEFER_XMTS
:
633 *val
= efep
->efe_defer_xmts
;
636 case ETHER_STAT_EX_COLLISIONS
:
637 *val
= efep
->efe_ex_collisions
;
640 case ETHER_STAT_MACXMT_ERRORS
:
641 *val
= efep
->efe_macxmt_errors
;
644 case ETHER_STAT_CARRIER_ERRORS
:
645 *val
= efep
->efe_carrier_errors
;
648 case ETHER_STAT_TOOLONG_ERRORS
:
649 *val
= efep
->efe_toolong_errors
;
652 case ETHER_STAT_MACRCV_ERRORS
:
653 *val
= efep
->efe_macrcv_errors
;
656 case ETHER_STAT_TOOSHORT_ERRORS
:
657 *val
= efep
->efe_runt_errors
;
660 case ETHER_STAT_JABBER_ERRORS
:
661 *val
= efep
->efe_jabber_errors
;
672 efe_m_start(void *arg
)
676 mutex_enter(&efep
->efe_intrlock
);
677 mutex_enter(&efep
->efe_txlock
);
680 efep
->efe_flags
|= FLAG_RUNNING
;
682 mutex_exit(&efep
->efe_txlock
);
683 mutex_exit(&efep
->efe_intrlock
);
685 mii_start(efep
->efe_miih
);
691 efe_m_stop(void *arg
)
695 mutex_enter(&efep
->efe_intrlock
);
696 mutex_enter(&efep
->efe_txlock
);
699 efep
->efe_flags
&= ~FLAG_RUNNING
;
701 mutex_exit(&efep
->efe_txlock
);
702 mutex_exit(&efep
->efe_intrlock
);
704 mii_stop(efep
->efe_miih
);
708 efe_m_setpromisc(void *arg
, boolean_t on
)
712 mutex_enter(&efep
->efe_intrlock
);
713 mutex_enter(&efep
->efe_txlock
);
715 if (efep
->efe_flags
& FLAG_SUSPENDED
) {
716 mutex_exit(&efep
->efe_txlock
);
717 mutex_exit(&efep
->efe_intrlock
);
721 efep
->efe_promisc
= on
;
723 if (efep
->efe_flags
& FLAG_RUNNING
) {
727 mutex_exit(&efep
->efe_txlock
);
728 mutex_exit(&efep
->efe_intrlock
);
734 efe_m_multicst(void *arg
, boolean_t add
, const uint8_t *macaddr
)
740 boolean_t restart
= B_FALSE
;
742 mutex_enter(&efep
->efe_intrlock
);
743 mutex_enter(&efep
->efe_txlock
);
745 if (efep
->efe_flags
& FLAG_SUSPENDED
) {
746 mutex_exit(&efep
->efe_txlock
);
747 mutex_exit(&efep
->efe_intrlock
);
751 CRC32(val
, macaddr
, ETHERADDRL
, -1U, crc32_table
);
754 index
= val
/ MCHASHSZ
;
755 bit
= 1U << (val
% MCHASHSZ
);
758 efep
->efe_mccount
[val
]++;
759 if (efep
->efe_mccount
[val
] == 1) {
760 efep
->efe_mchash
[index
] |= bit
;
765 efep
->efe_mccount
[val
]--;
766 if (efep
->efe_mccount
[val
] == 0) {
767 efep
->efe_mchash
[index
] &= ~bit
;
772 if (restart
&& efep
->efe_flags
& FLAG_RUNNING
) {
776 mutex_exit(&efep
->efe_txlock
);
777 mutex_exit(&efep
->efe_intrlock
);
783 efe_m_unicst(void *arg
, const uint8_t *macaddr
)
787 mutex_enter(&efep
->efe_intrlock
);
788 mutex_enter(&efep
->efe_txlock
);
790 if (efep
->efe_flags
& FLAG_SUSPENDED
) {
791 mutex_exit(&efep
->efe_txlock
);
792 mutex_exit(&efep
->efe_intrlock
);
796 bcopy(macaddr
, efep
->efe_macaddr
, ETHERADDRL
);
798 if (efep
->efe_flags
& FLAG_RUNNING
) {
802 mutex_exit(&efep
->efe_txlock
);
803 mutex_exit(&efep
->efe_intrlock
);
809 efe_m_tx(void *arg
, mblk_t
*mp
)
813 mutex_enter(&efep
->efe_txlock
);
815 if (efep
->efe_flags
& FLAG_SUSPENDED
) {
816 mutex_exit(&efep
->efe_txlock
);
821 mblk_t
*tmp
= mp
->b_next
;
824 if (efe_send(efep
, mp
) != DDI_SUCCESS
) {
831 /* Kick the transmitter */
832 PUTCSR(efep
, CSR_COMMAND
, COMMAND_TXQUEUED
);
834 mutex_exit(&efep
->efe_txlock
);
840 efe_m_setprop(void *arg
, const char *name
, mac_prop_id_t id
,
841 uint_t valsize
, const void *val
)
845 return (mii_m_setprop(efep
->efe_miih
, name
, id
, valsize
, val
));
849 efe_m_getprop(void *arg
, const char *name
, mac_prop_id_t id
,
850 uint_t valsize
, void *val
)
854 return (mii_m_getprop(efep
->efe_miih
, name
, id
, valsize
, val
));
858 efe_m_propinfo(void *arg
, const char *name
, mac_prop_id_t id
,
859 mac_prop_info_handle_t state
)
863 mii_m_propinfo(efep
->efe_miih
, name
, id
, state
);
867 * ISR/periodic callbacks.
870 efe_intr(caddr_t arg1
, caddr_t arg2
)
872 efe_t
*efep
= (void *)arg1
;
876 _NOTE(ARGUNUSED(arg2
));
878 mutex_enter(&efep
->efe_intrlock
);
880 if (efep
->efe_flags
& FLAG_SUSPENDED
) {
881 mutex_exit(&efep
->efe_intrlock
);
882 return (DDI_INTR_UNCLAIMED
);
885 status
= GETCSR(efep
, CSR_INTSTAT
);
886 if (!(status
& INTSTAT_ACTV
)) {
887 mutex_exit(&efep
->efe_intrlock
);
888 return (DDI_INTR_UNCLAIMED
);
890 PUTCSR(efep
, CSR_INTSTAT
, status
);
892 if (status
& INTSTAT_RCC
) {
896 if (status
& INTSTAT_RQE
) {
898 efep
->efe_macrcv_errors
++;
900 /* Kick the receiver */
901 PUTCSR(efep
, CSR_COMMAND
, COMMAND_RXQUEUED
);
904 if (status
& INTSTAT_TXC
) {
905 mutex_enter(&efep
->efe_txlock
);
909 mutex_exit(&efep
->efe_txlock
);
912 if (status
& INTSTAT_FATAL
) {
913 mutex_enter(&efep
->efe_txlock
);
915 efe_error(efep
->efe_dip
, "bus error; resetting!");
918 mutex_exit(&efep
->efe_txlock
);
921 mutex_exit(&efep
->efe_intrlock
);
924 mac_rx(efep
->efe_mh
, NULL
, mp
);
927 if (status
& INTSTAT_TXC
) {
928 mac_tx_update(efep
->efe_mh
);
931 if (status
& INTSTAT_FATAL
) {
932 mii_reset(efep
->efe_miih
);
935 return (DDI_INTR_CLAIMED
);
942 efe_init(efe_t
*efep
)
946 ASSERT(mutex_owned(&efep
->efe_intrlock
));
947 ASSERT(mutex_owned(&efep
->efe_txlock
));
951 val
= GENCTL_ONECOPY
| GENCTL_RFT_128
| GENCTL_MRM
;
954 #endif /* _BIG_ENDIAN */
956 PUTCSR(efep
, CSR_GENCTL
, val
);
957 PUTCSR(efep
, CSR_PBLCNT
, BURSTLEN
);
959 efe_init_rx_ring(efep
);
960 efe_init_tx_ring(efep
);
962 efe_setaddr(efep
, efep
->efe_macaddr
);
964 if (efep
->efe_promisc
) {
965 efe_setmchash(efep
, efe_mchash_promisc
);
967 efe_setmchash(efep
, efep
->efe_mchash
);
972 efe_init_rx_ring(efe_t
*efep
)
976 ASSERT(mutex_owned(&efep
->efe_intrlock
));
978 rp
= efep
->efe_rx_ring
;
980 for (int i
= 0; i
< DESCLEN(rp
); ++i
) {
981 efe_desc_t
*dp
= GETDESC(rp
, i
);
982 efe_buf_t
*bp
= GETBUF(rp
, i
);
984 PUTDESC16(rp
, &dp
->d_status
, RXSTAT_OWNER
);
985 PUTDESC16(rp
, &dp
->d_len
, 0);
986 PUTDESC32(rp
, &dp
->d_bufaddr
, BUFADDR(bp
));
987 PUTDESC16(rp
, &dp
->d_buflen
, BUFLEN(bp
));
988 PUTDESC16(rp
, &dp
->d_control
, 0);
989 PUTDESC32(rp
, &dp
->d_next
, NEXTDESCADDR(rp
, i
));
991 SYNCDESC(rp
, i
, DDI_DMA_SYNC_FORDEV
);
994 efep
->efe_rx_desc
= 0;
996 PUTCSR(efep
, CSR_PRCDAR
, DESCADDR(rp
, 0));
1000 efe_init_tx_ring(efe_t
*efep
)
1004 ASSERT(mutex_owned(&efep
->efe_txlock
));
1006 rp
= efep
->efe_tx_ring
;
1008 for (int i
= 0; i
< DESCLEN(rp
); ++i
) {
1009 efe_desc_t
*dp
= GETDESC(rp
, i
);
1010 efe_buf_t
*bp
= GETBUF(rp
, i
);
1012 PUTDESC16(rp
, &dp
->d_status
, 0);
1013 PUTDESC16(rp
, &dp
->d_len
, 0);
1014 PUTDESC32(rp
, &dp
->d_bufaddr
, BUFADDR(bp
));
1015 PUTDESC16(rp
, &dp
->d_buflen
, BUFLEN(bp
));
1016 PUTDESC16(rp
, &dp
->d_control
, 0);
1017 PUTDESC32(rp
, &dp
->d_next
, NEXTDESCADDR(rp
, i
));
1019 SYNCDESC(rp
, i
, DDI_DMA_SYNC_FORDEV
);
1022 efep
->efe_tx_desc
= 0;
1023 efep
->efe_tx_sent
= 0;
1025 PUTCSR(efep
, CSR_PTCDAR
, DESCADDR(rp
, 0));
1029 efe_reset(efe_t
*efep
)
1031 ASSERT(mutex_owned(&efep
->efe_intrlock
));
1032 ASSERT(mutex_owned(&efep
->efe_txlock
));
1034 PUTCSR(efep
, CSR_GENCTL
, GENCTL_RESET
);
1035 drv_usecwait(RESET_DELAY
);
1037 /* Assert internal clock source (AN 7.15) */
1038 for (int i
= 0; i
< RESET_TEST_CYCLES
; ++i
) {
1039 PUTCSR(efep
, CSR_TEST
, TEST_CLOCK
);
1044 efe_start(efe_t
*efep
)
1046 ASSERT(mutex_owned(&efep
->efe_intrlock
));
1047 ASSERT(mutex_owned(&efep
->efe_txlock
));
1051 PUTCSR(efep
, CSR_RXCON
,
1052 RXCON_SEP
| RXCON_RRF
| RXCON_RBF
| RXCON_RMF
|
1053 (efep
->efe_promisc
? RXCON_PROMISC
: 0));
1055 PUTCSR(efep
, CSR_TXCON
, TXCON_LB_3
);
1057 efe_intr_enable(efep
);
1059 SETBIT(efep
, CSR_COMMAND
,
1060 COMMAND_START_RX
| COMMAND_RXQUEUED
);
1064 efe_stop(efe_t
*efep
)
1066 ASSERT(mutex_owned(&efep
->efe_intrlock
));
1067 ASSERT(mutex_owned(&efep
->efe_txlock
));
1069 efe_intr_disable(efep
);
1071 PUTCSR(efep
, CSR_COMMAND
, COMMAND_STOP_RX
);
1075 PUTCSR(efep
, CSR_GENCTL
, GENCTL_RESET
);
1076 drv_usecwait(RESET_DELAY
);
1078 PUTCSR(efep
, CSR_GENCTL
, GENCTL_PWRDWN
);
1082 efe_stop_dma(efe_t
*efep
)
1084 ASSERT(mutex_owned(&efep
->efe_intrlock
));
1085 ASSERT(mutex_owned(&efep
->efe_txlock
));
1087 PUTCSR(efep
, CSR_COMMAND
,
1088 COMMAND_STOP_RDMA
| COMMAND_STOP_TDMA
);
1090 for (int i
= 0; i
< STOP_DELAY_CYCLES
; ++i
) {
1091 uint32_t status
= GETCSR(efep
, CSR_INTSTAT
);
1092 if (status
& INTSTAT_RXIDLE
&&
1093 status
& INTSTAT_TXIDLE
) {
1096 drv_usecwait(STOP_DELAY
);
1098 efe_error(efep
->efe_dip
, "timed out stopping DMA engine!");
1102 efe_restart(efe_t
*efep
)
1109 efe_suspend(efe_t
*efep
)
1111 mutex_enter(&efep
->efe_intrlock
);
1112 mutex_enter(&efep
->efe_txlock
);
1114 if (efep
->efe_flags
& FLAG_RUNNING
) {
1117 efep
->efe_flags
|= FLAG_SUSPENDED
;
1119 mutex_exit(&efep
->efe_txlock
);
1120 mutex_exit(&efep
->efe_intrlock
);
1122 mii_suspend(efep
->efe_miih
);
1124 return (DDI_SUCCESS
);
1128 efe_resume(efe_t
*efep
)
1130 mutex_enter(&efep
->efe_intrlock
);
1131 mutex_enter(&efep
->efe_txlock
);
1133 if (efep
->efe_flags
& FLAG_RUNNING
) {
1136 efep
->efe_flags
&= ~FLAG_SUSPENDED
;
1138 mutex_exit(&efep
->efe_txlock
);
1139 mutex_exit(&efep
->efe_intrlock
);
1141 mii_resume(efep
->efe_miih
);
1143 return (DDI_SUCCESS
);
1147 efe_ring_alloc(dev_info_t
*dip
, size_t len
)
1155 rp
= kmem_zalloc(sizeof (efe_ring_t
), KM_SLEEP
);
1158 if (ddi_dma_alloc_handle(dip
, &efe_dma_attr
, DDI_DMA_SLEEP
, NULL
,
1159 &rp
->r_dmah
) != DDI_SUCCESS
) {
1160 efe_error(dip
, "unable to allocate DMA handle!");
1164 if (ddi_dma_mem_alloc(rp
->r_dmah
, DESCSZ(len
), &efe_buf_acc_attr
,
1165 DDI_DMA_CONSISTENT
, DDI_DMA_SLEEP
, NULL
, (caddr_t
*)&rp
->r_descp
,
1166 &rlen
, &rp
->r_acch
) != DDI_SUCCESS
) {
1167 efe_error(dip
, "unable to allocate descriptors!");
1171 if (ddi_dma_addr_bind_handle(rp
->r_dmah
, NULL
, (caddr_t
)rp
->r_descp
,
1172 DESCSZ(len
), DDI_DMA_RDWR
| DDI_DMA_CONSISTENT
, DDI_DMA_SLEEP
,
1173 NULL
, &rp
->r_dmac
, &ccount
) != DDI_DMA_MAPPED
) {
1174 efe_error(dip
, "unable to bind DMA handle to descriptors!");
1178 rp
->r_bufpp
= kmem_zalloc(BUFPSZ(len
), KM_SLEEP
);
1180 for (int i
= 0; i
< len
; ++i
) {
1181 efe_buf_t
*bp
= efe_buf_alloc(dip
, BUFSZ
);
1185 rp
->r_bufpp
[i
] = bp
;
1197 efe_ring_free(efe_ring_t
**rpp
)
1199 efe_ring_t
*rp
= *rpp
;
1203 for (int i
= 0; i
< DESCLEN(rp
); ++i
) {
1204 efe_buf_t
*bp
= GETBUF(rp
, i
);
1209 kmem_free(rp
->r_bufpp
, BUFPSZ(DESCLEN(rp
)));
1211 if (rp
->r_descp
!= NULL
) {
1212 (void) ddi_dma_unbind_handle(rp
->r_dmah
);
1214 if (rp
->r_acch
!= NULL
) {
1215 ddi_dma_mem_free(&rp
->r_acch
);
1217 if (rp
->r_dmah
!= NULL
) {
1218 ddi_dma_free_handle(&rp
->r_dmah
);
1220 kmem_free(rp
, sizeof (efe_ring_t
));
1226 efe_buf_alloc(dev_info_t
*dip
, size_t len
)
1232 bp
= kmem_zalloc(sizeof (efe_buf_t
), KM_SLEEP
);
1235 if (ddi_dma_alloc_handle(dip
, &efe_dma_attr
, DDI_DMA_SLEEP
, NULL
,
1236 &bp
->b_dmah
) != DDI_SUCCESS
) {
1237 efe_error(dip
, "unable to allocate DMA handle!");
1241 if (ddi_dma_mem_alloc(bp
->b_dmah
, len
, &efe_buf_acc_attr
,
1242 DDI_DMA_STREAMING
, DDI_DMA_SLEEP
, NULL
, &bp
->b_kaddr
, &rlen
,
1243 &bp
->b_acch
) != DDI_SUCCESS
) {
1244 efe_error(dip
, "unable to allocate buffer!");
1248 if (ddi_dma_addr_bind_handle(bp
->b_dmah
, NULL
, bp
->b_kaddr
,
1249 len
, DDI_DMA_RDWR
| DDI_DMA_STREAMING
, DDI_DMA_SLEEP
, NULL
,
1250 &bp
->b_dmac
, &ccount
) != DDI_DMA_MAPPED
) {
1251 efe_error(dip
, "unable to bind DMA handle to buffer!");
1264 efe_buf_free(efe_buf_t
**bpp
)
1266 efe_buf_t
*bp
= *bpp
;
1270 if (bp
->b_kaddr
!= NULL
) {
1271 (void) ddi_dma_unbind_handle(bp
->b_dmah
);
1273 if (bp
->b_acch
!= NULL
) {
1274 ddi_dma_mem_free(&bp
->b_acch
);
1276 if (bp
->b_dmah
!= NULL
) {
1277 ddi_dma_free_handle(&bp
->b_dmah
);
1279 kmem_free(bp
, sizeof (efe_buf_t
));
1285 efe_intr_enable(efe_t
*efep
)
1287 PUTCSR(efep
, CSR_INTMASK
,
1288 INTMASK_RCC
| INTMASK_RQE
| INTMASK_TXC
| INTMASK_FATAL
);
1290 SETBIT(efep
, CSR_GENCTL
, GENCTL_INT
);
1294 efe_intr_disable(efe_t
*efep
)
1296 PUTCSR(efep
, CSR_INTMASK
, 0);
1298 CLRBIT(efep
, CSR_GENCTL
, GENCTL_INT
);
1302 efe_recv(efe_t
*efep
)
1308 ASSERT(mutex_owned(&efep
->efe_intrlock
));
1310 rp
= efep
->efe_rx_ring
;
1316 dp
= GETDESC(rp
, efep
->efe_rx_desc
);
1317 SYNCDESC(rp
, efep
->efe_rx_desc
, DDI_DMA_SYNC_FORKERNEL
);
1319 status
= GETDESC16(rp
, &dp
->d_status
);
1321 /* Stop if device owns descriptor */
1322 if (status
& RXSTAT_OWNER
) {
1326 if (status
& RXSTAT_PRI
) {
1327 mblk_t
*tmp
= efe_recv_pkt(efep
, dp
);
1334 efep
->efe_ierrors
++;
1336 if (status
& RXSTAT_FAE
) {
1337 efep
->efe_align_errors
++;
1339 if (status
& RXSTAT_CRC
) {
1340 efep
->efe_fcs_errors
++;
1342 if (status
& RXSTAT_MP
) {
1347 /* Release ownership to device */
1348 PUTDESC16(rp
, &dp
->d_status
, RXSTAT_OWNER
);
1350 SYNCDESC(rp
, efep
->efe_rx_desc
, DDI_DMA_SYNC_FORDEV
);
1352 efep
->efe_rx_desc
= NEXTDESC(rp
, efep
->efe_rx_desc
);
1359 efe_recv_pkt(efe_t
*efep
, efe_desc_t
*dp
)
1367 ASSERT(mutex_owned(&efep
->efe_intrlock
));
1369 rp
= efep
->efe_rx_ring
;
1371 len
= GETDESC16(rp
, &dp
->d_len
) - ETHERFCSL
;
1373 if (len
< ETHERMIN
) {
1374 efep
->efe_ierrors
++;
1375 efep
->efe_runt_errors
++;
1379 if (len
> ETHERMAX
+ VLAN_TAGSZ
) {
1380 efep
->efe_ierrors
++;
1381 efep
->efe_toolong_errors
++;
1385 mp
= allocb(len
, 0);
1387 efep
->efe_ierrors
++;
1388 efep
->efe_norcvbuf
++;
1391 mp
->b_wptr
= mp
->b_rptr
+ len
;
1393 bp
= GETBUF(rp
, efep
->efe_rx_desc
);
1394 SYNCBUF(bp
, DDI_DMA_SYNC_FORKERNEL
);
1396 bcopy(bp
->b_kaddr
, mp
->b_rptr
, len
);
1398 efep
->efe_ipackets
++;
1399 efep
->efe_rbytes
+= len
;
1401 status
= GETDESC16(rp
, &dp
->d_status
);
1403 if (status
& RXSTAT_BAR
) {
1404 efep
->efe_brdcstrcv
++;
1406 } else if (status
& RXSTAT_MAR
) {
1407 efep
->efe_multircv
++;
1414 efe_send(efe_t
*efep
, mblk_t
*mp
)
1422 ASSERT(mutex_owned(&efep
->efe_txlock
));
1424 rp
= efep
->efe_tx_ring
;
1428 if (len
> ETHERMAX
+ VLAN_TAGSZ
) {
1429 efep
->efe_oerrors
++;
1430 efep
->efe_macxmt_errors
++;
1432 return (DDI_SUCCESS
);
1435 dp
= GETDESC(rp
, efep
->efe_tx_desc
);
1436 SYNCDESC(rp
, efep
->efe_tx_desc
, DDI_DMA_SYNC_FORKERNEL
);
1438 status
= GETDESC16(efep
->efe_tx_ring
, &dp
->d_status
);
1440 /* Stop if device owns descriptor */
1441 if (status
& TXSTAT_OWNER
) {
1442 return (DDI_FAILURE
);
1445 bp
= GETBUF(rp
, efep
->efe_tx_desc
);
1447 mcopymsg(mp
, bp
->b_kaddr
);
1450 * Packets must contain at least ETHERMIN octets.
1451 * Padded octets are zeroed out prior to sending.
1453 if (len
< ETHERMIN
) {
1454 bzero(bp
->b_kaddr
+ len
, ETHERMIN
- len
);
1458 SYNCBUF(bp
, DDI_DMA_SYNC_FORDEV
);
1460 PUTDESC16(rp
, &dp
->d_status
, TXSTAT_OWNER
);
1461 PUTDESC16(rp
, &dp
->d_len
, len
);
1462 PUTDESC16(rp
, &dp
->d_control
, TXCTL_LASTDESCR
);
1464 SYNCDESC(rp
, efep
->efe_tx_desc
, DDI_DMA_SYNC_FORDEV
);
1466 efep
->efe_opackets
++;
1467 efep
->efe_obytes
+= len
;
1469 if (*bp
->b_kaddr
& 0x01) {
1470 if (bcmp(bp
->b_kaddr
, efe_broadcast
, ETHERADDRL
) == 0) {
1471 efep
->efe_brdcstxmt
++;
1473 efep
->efe_multixmt
++;
1477 efep
->efe_tx_desc
= NEXTDESC(rp
, efep
->efe_tx_desc
);
1479 return (DDI_SUCCESS
);
1483 efe_send_done(efe_t
*efep
)
1487 ASSERT(mutex_owned(&efep
->efe_txlock
));
1489 rp
= efep
->efe_tx_ring
;
1495 dp
= GETDESC(rp
, efep
->efe_tx_sent
);
1496 SYNCDESC(rp
, efep
->efe_tx_sent
, DDI_DMA_SYNC_FORKERNEL
);
1498 status
= GETDESC16(rp
, &dp
->d_status
);
1500 /* Stop if device owns descriptor */
1501 if (status
& TXSTAT_OWNER
) {
1505 if (status
& TXSTAT_PTX
) {
1506 if (!(status
& TXSTAT_ND
)) {
1507 efep
->efe_defer_xmts
++;
1509 if (status
& TXSTAT_COLL
) {
1510 efep
->efe_first_collisions
++;
1514 efep
->efe_oerrors
++;
1516 if (status
& TXSTAT_CSL
) {
1517 efep
->efe_carrier_errors
++;
1519 if (status
& TXSTAT_UFLO
) {
1522 if (status
& TXSTAT_OWC
) {
1523 efep
->efe_tx_late_collisions
++;
1525 if (status
& TXSTAT_DEFER
) {
1526 efep
->efe_jabber_errors
++;
1528 if (status
& TXSTAT_EXCOLL
) {
1529 efep
->efe_ex_collisions
++;
1533 efep
->efe_collisions
+=
1534 (status
>> TXSTAT_CCNT
) & TXSTAT_CCNTMASK
;
1536 efep
->efe_tx_sent
= NEXTDESC(rp
, efep
->efe_tx_sent
);
1541 efe_getaddr(efe_t
*efep
, uint8_t *macaddr
)
1543 efe_eeprom_read(efep
, macaddr
, ETHERADDRL
, 0x0);
1545 efe_debug(efep
->efe_dip
,
1546 "factory address is %02x:%02x:%02x:%02x:%02x:%02x\n",
1547 macaddr
[0], macaddr
[1], macaddr
[2], macaddr
[3],
1548 macaddr
[4], macaddr
[5]);
1552 efe_setaddr(efe_t
*efep
, uint8_t *macaddr
)
1556 bcopy(macaddr
, &val
, sizeof (uint16_t));
1557 PUTCSR(efep
, CSR_LAN0
, val
);
1558 macaddr
+= sizeof (uint16_t);
1560 bcopy(macaddr
, &val
, sizeof (uint16_t));
1561 PUTCSR(efep
, CSR_LAN1
, val
);
1562 macaddr
+= sizeof (uint16_t);
1564 bcopy(macaddr
, &val
, sizeof (uint16_t));
1565 PUTCSR(efep
, CSR_LAN2
, val
);
1569 efe_setmchash(efe_t
*efep
, uint16_t *mchash
)
1571 PUTCSR(efep
, CSR_MC0
, mchash
[0]);
1572 PUTCSR(efep
, CSR_MC1
, mchash
[1]);
1573 PUTCSR(efep
, CSR_MC2
, mchash
[2]);
1574 PUTCSR(efep
, CSR_MC3
, mchash
[3]);
1578 efe_eeprom_read(efe_t
*efep
, uint8_t *buf
, size_t len
, uint8_t addr
)
1582 ASSERT(len
& ~0x1); /* non-zero; word-aligned */
1584 PUTCSR(efep
, CSR_EECTL
, EECTL_ENABLE
| EECTL_EECS
);
1585 drv_usecwait(EEPROM_DELAY
);
1587 addrlen
= (GETCSR(efep
, CSR_EECTL
) & EECTL_SIZE
?
1588 AT93C46_ADDRLEN
: AT93C56_ADDRLEN
);
1590 for (int i
= 0; i
< len
/ sizeof (uint16_t); ++i
) {
1591 uint16_t val
= efe_eeprom_readw(efep
, addrlen
, addr
+ i
);
1592 bcopy(&val
, buf
, sizeof (uint16_t));
1593 buf
+= sizeof (uint16_t);
1598 efe_eeprom_readw(efe_t
*efep
, int addrlen
, uint8_t addr
)
1602 ASSERT(addrlen
> 0);
1604 /* Write Start Bit (SB) */
1605 efe_eeprom_writebit(efep
, 1);
1607 /* Write READ instruction */
1608 efe_eeprom_writebit(efep
, 1);
1609 efe_eeprom_writebit(efep
, 0);
1611 /* Write EEPROM address */
1612 for (int i
= addrlen
- 1; i
>= 0; --i
) {
1613 efe_eeprom_writebit(efep
, addr
& 1U << i
);
1616 /* Read EEPROM word */
1617 for (int i
= EEPROM_WORDSZ
- 1; i
>= 0; --i
) {
1618 val
|= efe_eeprom_readbit(efep
) << i
;
1621 PUTCSR(efep
, CSR_EECTL
, EECTL_ENABLE
);
1622 drv_usecwait(EEPROM_DELAY
);
1628 efe_eeprom_readbit(efe_t
*efep
)
1630 PUTCSR(efep
, CSR_EECTL
, EECTL_ENABLE
| EECTL_EECS
);
1631 drv_usecwait(EEPROM_DELAY
);
1633 PUTCSR(efep
, CSR_EECTL
, EECTL_ENABLE
| EECTL_EECS
|
1635 drv_usecwait(EEPROM_DELAY
);
1637 PUTCSR(efep
, CSR_EECTL
, EECTL_ENABLE
| EECTL_EECS
);
1638 drv_usecwait(EEPROM_DELAY
);
1640 return (!!(GETCSR(efep
, CSR_EECTL
) & EECTL_EEDO
));
1644 efe_eeprom_writebit(efe_t
*efep
, int bit
)
1646 PUTCSR(efep
, CSR_EECTL
, EECTL_ENABLE
| EECTL_EECS
);
1647 drv_usecwait(EEPROM_DELAY
);
1649 PUTCSR(efep
, CSR_EECTL
, EECTL_ENABLE
| EECTL_EECS
|
1650 EECTL_EESK
| (bit
? EECTL_EEDI
: 0));
1651 drv_usecwait(EEPROM_DELAY
);
1653 PUTCSR(efep
, CSR_EECTL
, EECTL_ENABLE
| EECTL_EECS
);
1654 drv_usecwait(EEPROM_DELAY
);
1658 efe_dprintf(dev_info_t
*dip
, int level
, const char *format
, ...)
1663 va_start(ap
, format
);
1665 (void) vsnprintf(buf
, sizeof (buf
), format
, ap
);
1667 cmn_err(level
, "?%s%d %s", ddi_driver_name(dip
),
1668 ddi_get_instance(dip
), buf
);