2 * Solaris driver for ethernet cards based on the Macronix 98715
4 * Copyright (c) 2007 by Garrett D'Amore <garrett@damore.org>.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the author nor the names of any co-contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
33 * Use is subject to license terms.
37 #include <sys/varargs.h>
38 #include <sys/types.h>
39 #include <sys/modctl.h>
41 #include <sys/devops.h>
42 #include <sys/stream.h>
43 #include <sys/strsun.h>
44 #include <sys/cmn_err.h>
46 #include <sys/ethernet.h>
49 #include <sys/miiregs.h>
50 #include <sys/strsun.h>
52 #include <sys/mac_ether.h>
54 #include <sys/sunddi.h>
64 /* patchable debug flag ... must not be static! */
66 unsigned mxfe_debug
= DWARN
;
69 /* table of supported devices */
70 static mxfe_card_t mxfe_cards
[] = {
75 { 0x11ad, 0xc115, 0, 0, "Lite-On LC82C115", MXFE_PNICII
},
80 { 0x10d9, 0x0531, 0x25, 0xff, "Macronix MX98715AEC", MXFE_98715AEC
},
81 { 0x10d9, 0x0531, 0x20, 0xff, "Macronix MX98715A", MXFE_98715A
},
82 { 0x10d9, 0x0531, 0x60, 0xff, "Macronix MX98715B", MXFE_98715B
},
83 { 0x10d9, 0x0531, 0x30, 0xff, "Macronix MX98725", MXFE_98725
},
84 { 0x10d9, 0x0531, 0x00, 0xff, "Macronix MX98715", MXFE_98715
},
85 { 0x10d9, 0x0512, 0, 0, "Macronix MX98713", MXFE_98713
},
88 * Compex (relabeled Macronix products)
90 { 0x11fc, 0x9881, 0x00, 0x00, "Compex 9881", MXFE_98713
},
91 { 0x11fc, 0x9881, 0x10, 0xff, "Compex 9881A", MXFE_98713A
},
95 { 0x11ad, 0xc001, 0, 0, "Linksys LNE100TX", MXFE_PNICII
},
96 { 0x2646, 0x000b, 0, 0, "Kingston KNE111TX", MXFE_PNICII
},
97 { 0x1154, 0x0308, 0, 0, "Buffalo LGY-PCI-TXL", MXFE_98715AEC
},
100 #define ETHERVLANMTU (ETHERMAX + 4)
103 * Function prototypes
105 static int mxfe_attach(dev_info_t
*, ddi_attach_cmd_t
);
106 static int mxfe_detach(dev_info_t
*, ddi_detach_cmd_t
);
107 static int mxfe_resume(dev_info_t
*);
108 static int mxfe_quiesce(dev_info_t
*);
109 static int mxfe_m_unicst(void *, const uint8_t *);
110 static int mxfe_m_multicst(void *, boolean_t
, const uint8_t *);
111 static int mxfe_m_promisc(void *, boolean_t
);
112 static mblk_t
*mxfe_m_tx(void *, mblk_t
*);
113 static int mxfe_m_stat(void *, uint_t
, uint64_t *);
114 static int mxfe_m_start(void *);
115 static void mxfe_m_stop(void *);
116 static int mxfe_m_getprop(void *, const char *, mac_prop_id_t
, uint_t
,
118 static int mxfe_m_setprop(void *, const char *, mac_prop_id_t
, uint_t
,
120 static void mxfe_m_propinfo(void *, const char *, mac_prop_id_t
,
121 mac_prop_info_handle_t
);
122 static unsigned mxfe_intr(caddr_t
);
123 static void mxfe_startmac(mxfe_t
*);
124 static void mxfe_stopmac(mxfe_t
*);
125 static void mxfe_resetrings(mxfe_t
*);
126 static boolean_t
mxfe_initialize(mxfe_t
*);
127 static void mxfe_startall(mxfe_t
*);
128 static void mxfe_stopall(mxfe_t
*);
129 static void mxfe_resetall(mxfe_t
*);
130 static mxfe_txbuf_t
*mxfe_alloctxbuf(mxfe_t
*);
131 static void mxfe_destroytxbuf(mxfe_txbuf_t
*);
132 static mxfe_rxbuf_t
*mxfe_allocrxbuf(mxfe_t
*);
133 static void mxfe_destroyrxbuf(mxfe_rxbuf_t
*);
134 static void mxfe_send_setup(mxfe_t
*);
135 static boolean_t
mxfe_send(mxfe_t
*, mblk_t
*);
136 static int mxfe_allocrxring(mxfe_t
*);
137 static void mxfe_freerxring(mxfe_t
*);
138 static int mxfe_alloctxring(mxfe_t
*);
139 static void mxfe_freetxring(mxfe_t
*);
140 static void mxfe_error(dev_info_t
*, char *, ...);
141 static uint8_t mxfe_sromwidth(mxfe_t
*);
142 static uint16_t mxfe_readsromword(mxfe_t
*, unsigned);
143 static void mxfe_readsrom(mxfe_t
*, unsigned, unsigned, void *);
144 static void mxfe_getfactaddr(mxfe_t
*, uchar_t
*);
145 static uint8_t mxfe_miireadbit(mxfe_t
*);
146 static void mxfe_miiwritebit(mxfe_t
*, uint8_t);
147 static void mxfe_miitristate(mxfe_t
*);
148 static uint16_t mxfe_miiread(mxfe_t
*, int, int);
149 static void mxfe_miiwrite(mxfe_t
*, int, int, uint16_t);
150 static uint16_t mxfe_miireadgeneral(mxfe_t
*, int, int);
151 static void mxfe_miiwritegeneral(mxfe_t
*, int, int, uint16_t);
152 static uint16_t mxfe_miiread98713(mxfe_t
*, int, int);
153 static void mxfe_miiwrite98713(mxfe_t
*, int, int, uint16_t);
154 static void mxfe_startphy(mxfe_t
*);
155 static void mxfe_stopphy(mxfe_t
*);
156 static void mxfe_startphymii(mxfe_t
*);
157 static void mxfe_startphynway(mxfe_t
*);
158 static void mxfe_startnway(mxfe_t
*);
159 static void mxfe_reportlink(mxfe_t
*);
160 static void mxfe_checklink(mxfe_t
*);
161 static void mxfe_checklinkmii(mxfe_t
*);
162 static void mxfe_checklinknway(mxfe_t
*);
163 static void mxfe_disableinterrupts(mxfe_t
*);
164 static void mxfe_enableinterrupts(mxfe_t
*);
165 static void mxfe_reclaim(mxfe_t
*);
166 static boolean_t
mxfe_receive(mxfe_t
*, mblk_t
**);
169 static void mxfe_dprintf(mxfe_t
*, const char *, int, char *, ...);
172 #define KIOIP KSTAT_INTR_PTR(mxfep->mxfe_intrstat)
174 static mac_callbacks_t mxfe_m_callbacks
= {
175 MC_SETPROP
| MC_GETPROP
| MC_PROPINFO
,
185 NULL
, /* mc_getcapab */
196 DDI_DEFINE_STREAM_OPS(mxfe_devops
, nulldev
, nulldev
, mxfe_attach
, mxfe_detach
,
197 nodev
, NULL
, D_MP
, NULL
, mxfe_quiesce
);
200 * Module linkage information.
203 static struct modldrv mxfe_modldrv
= {
204 &mod_driverops
, /* drv_modops */
205 "Macronix Fast Ethernet", /* drv_linkinfo */
206 &mxfe_devops
/* drv_dev_ops */
209 static struct modlinkage mxfe_modlinkage
= {
210 MODREV_1
, /* ml_rev */
211 { &mxfe_modldrv
, NULL
} /* ml_linkage */
217 static ddi_device_acc_attr_t mxfe_devattr
= {
219 DDI_STRUCTURE_LE_ACC
,
223 static ddi_device_acc_attr_t mxfe_bufattr
= {
229 static ddi_dma_attr_t mxfe_dma_attr
= {
230 DMA_ATTR_V0
, /* dma_attr_version */
231 0, /* dma_attr_addr_lo */
232 0xFFFFFFFFU
, /* dma_attr_addr_hi */
233 0x7FFFFFFFU
, /* dma_attr_count_max */
234 4, /* dma_attr_align */
235 0x3F, /* dma_attr_burstsizes */
236 1, /* dma_attr_minxfer */
237 0xFFFFFFFFU
, /* dma_attr_maxxfer */
238 0xFFFFFFFFU
, /* dma_attr_seg */
239 1, /* dma_attr_sgllen */
240 1, /* dma_attr_granular */
241 0 /* dma_attr_flags */
245 * Tx buffers can be arbitrarily aligned. Additionally, they can
246 * cross a page boundary, so we use the two buffer addresses of the
247 * chip to provide a two-entry scatter-gather list.
249 static ddi_dma_attr_t mxfe_dma_txattr
= {
250 DMA_ATTR_V0
, /* dma_attr_version */
251 0, /* dma_attr_addr_lo */
252 0xFFFFFFFFU
, /* dma_attr_addr_hi */
253 0x7FFFFFFFU
, /* dma_attr_count_max */
254 1, /* dma_attr_align */
255 0x3F, /* dma_attr_burstsizes */
256 1, /* dma_attr_minxfer */
257 0xFFFFFFFFU
, /* dma_attr_maxxfer */
258 0xFFFFFFFFU
, /* dma_attr_seg */
259 2, /* dma_attr_sgllen */
260 1, /* dma_attr_granular */
261 0 /* dma_attr_flags */
265 * Ethernet addresses.
267 static uchar_t mxfe_broadcast
[ETHERADDRL
] = {
268 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
278 mac_init_ops(&mxfe_devops
, "mxfe");
279 if ((rv
= mod_install(&mxfe_modlinkage
)) != DDI_SUCCESS
) {
280 mac_fini_ops(&mxfe_devops
);
289 if ((rv
= mod_remove(&mxfe_modlinkage
)) == DDI_SUCCESS
) {
290 mac_fini_ops(&mxfe_devops
);
296 _info(struct modinfo
*modinfop
)
298 return (mod_info(&mxfe_modlinkage
, modinfop
));
302 mxfe_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
305 mac_register_t
*macp
;
306 int inst
= ddi_get_instance(dip
);
307 ddi_acc_handle_t pci
;
319 return (mxfe_resume(dip
));
325 return (DDI_FAILURE
);
328 /* this card is a bus master, reject any slave-only slot */
329 if (ddi_slaveonly(dip
) == DDI_SUCCESS
) {
330 mxfe_error(dip
, "slot does not support PCI bus-master");
331 return (DDI_FAILURE
);
333 /* PCI devices shouldn't generate hilevel interrupts */
334 if (ddi_intr_hilevel(dip
, 0) != 0) {
335 mxfe_error(dip
, "hilevel interrupts not supported");
336 return (DDI_FAILURE
);
338 if (pci_config_setup(dip
, &pci
) != DDI_SUCCESS
) {
339 mxfe_error(dip
, "unable to setup PCI config handle");
340 return (DDI_FAILURE
);
343 venid
= pci_config_get16(pci
, PCI_VID
);
344 devid
= pci_config_get16(pci
, PCI_DID
);
345 revid
= pci_config_get16(pci
, PCI_RID
);
346 svid
= pci_config_get16(pci
, PCI_SVID
);
347 ssid
= pci_config_get16(pci
, PCI_SSID
);
350 * the last entry in the card table matches every possible
351 * card, so the for-loop always terminates properly.
354 for (i
= 0; i
< (sizeof (mxfe_cards
) / sizeof (mxfe_card_t
)); i
++) {
355 if ((venid
== mxfe_cards
[i
].card_venid
) &&
356 (devid
== mxfe_cards
[i
].card_devid
) &&
357 ((revid
& mxfe_cards
[i
].card_revmask
) ==
358 mxfe_cards
[i
].card_revid
)) {
359 cardp
= &mxfe_cards
[i
];
361 if ((svid
== mxfe_cards
[i
].card_venid
) &&
362 (ssid
== mxfe_cards
[i
].card_devid
) &&
363 ((revid
& mxfe_cards
[i
].card_revmask
) ==
364 mxfe_cards
[i
].card_revid
)) {
365 cardp
= &mxfe_cards
[i
];
371 pci_config_teardown(&pci
);
372 mxfe_error(dip
, "Unable to identify PCI card");
373 return (DDI_FAILURE
);
376 if (ddi_prop_update_string(DDI_DEV_T_NONE
, dip
, "model",
377 cardp
->card_cardname
) != DDI_PROP_SUCCESS
) {
378 pci_config_teardown(&pci
);
379 mxfe_error(dip
, "Unable to create model property");
380 return (DDI_FAILURE
);
384 * Grab the PCI cachesize -- we use this to program the
385 * cache-optimization bus access bits.
387 cachesize
= pci_config_get8(pci
, PCI_CLS
);
389 /* this cannot fail */
390 mxfep
= kmem_zalloc(sizeof (mxfe_t
), KM_SLEEP
);
391 ddi_set_driver_private(dip
, mxfep
);
393 /* get the interrupt block cookie */
394 if (ddi_get_iblock_cookie(dip
, 0, &mxfep
->mxfe_icookie
)
396 mxfe_error(dip
, "ddi_get_iblock_cookie failed");
397 pci_config_teardown(&pci
);
398 kmem_free(mxfep
, sizeof (mxfe_t
));
399 return (DDI_FAILURE
);
402 mxfep
->mxfe_dip
= dip
;
403 mxfep
->mxfe_cardp
= cardp
;
404 mxfep
->mxfe_phyaddr
= -1;
405 mxfep
->mxfe_cachesize
= cachesize
;
407 /* default properties */
408 mxfep
->mxfe_adv_aneg
= ddi_prop_get_int(DDI_DEV_T_ANY
, dip
, 0,
409 "adv_autoneg_cap", 1);
410 mxfep
->mxfe_adv_100T4
= ddi_prop_get_int(DDI_DEV_T_ANY
, dip
, 0,
412 mxfep
->mxfe_adv_100fdx
= ddi_prop_get_int(DDI_DEV_T_ANY
, dip
, 0,
413 "adv_100fdx_cap", 1);
414 mxfep
->mxfe_adv_100hdx
= ddi_prop_get_int(DDI_DEV_T_ANY
, dip
, 0,
415 "adv_100hdx_cap", 1);
416 mxfep
->mxfe_adv_10fdx
= ddi_prop_get_int(DDI_DEV_T_ANY
, dip
, 0,
418 mxfep
->mxfe_adv_10hdx
= ddi_prop_get_int(DDI_DEV_T_ANY
, dip
, 0,
421 DBG(DPCI
, "PCI vendor id = %x", venid
);
422 DBG(DPCI
, "PCI device id = %x", devid
);
423 DBG(DPCI
, "PCI revision id = %x", revid
);
424 DBG(DPCI
, "PCI cachesize = %d", cachesize
);
425 DBG(DPCI
, "PCI COMM = %x", pci_config_get8(pci
, PCI_CMD
));
426 DBG(DPCI
, "PCI STAT = %x", pci_config_get8(pci
, PCI_STAT
));
428 mutex_init(&mxfep
->mxfe_xmtlock
, NULL
, MUTEX_DRIVER
,
429 mxfep
->mxfe_icookie
);
430 mutex_init(&mxfep
->mxfe_intrlock
, NULL
, MUTEX_DRIVER
,
431 mxfep
->mxfe_icookie
);
434 * Enable bus master, IO space, and memory space accesses.
436 pci_config_put16(pci
, PCI_CMD
,
437 pci_config_get16(pci
, PCI_CMD
) |
438 PCI_CMD_BME
| PCI_CMD_MAE
| PCI_CMD_MWIE
);
440 /* we're done with this now, drop it */
441 pci_config_teardown(&pci
);
444 * Initialize interrupt kstat. This should not normally fail, since
445 * we don't use a persistent stat. We do it this way to avoid having
446 * to test for it at run time on the hot path.
448 mxfep
->mxfe_intrstat
= kstat_create("mxfe", inst
, "intr", "controller",
449 KSTAT_TYPE_INTR
, 1, 0);
450 if (mxfep
->mxfe_intrstat
== NULL
) {
451 mxfe_error(dip
, "kstat_create failed");
454 kstat_install(mxfep
->mxfe_intrstat
);
457 * Map in the device registers.
459 if (ddi_regs_map_setup(dip
, 1, (caddr_t
*)&mxfep
->mxfe_regs
,
460 0, 0, &mxfe_devattr
, &mxfep
->mxfe_regshandle
)) {
461 mxfe_error(dip
, "ddi_regs_map_setup failed");
466 * Allocate DMA resources (descriptor rings and buffers).
468 if ((mxfe_allocrxring(mxfep
) != DDI_SUCCESS
) ||
469 (mxfe_alloctxring(mxfep
) != DDI_SUCCESS
)) {
470 mxfe_error(dip
, "unable to allocate DMA resources");
474 /* Initialize the chip. */
475 mutex_enter(&mxfep
->mxfe_intrlock
);
476 mutex_enter(&mxfep
->mxfe_xmtlock
);
477 if (!mxfe_initialize(mxfep
)) {
478 mutex_exit(&mxfep
->mxfe_xmtlock
);
479 mutex_exit(&mxfep
->mxfe_intrlock
);
482 mutex_exit(&mxfep
->mxfe_xmtlock
);
483 mutex_exit(&mxfep
->mxfe_intrlock
);
485 /* Determine the number of address bits to our EEPROM. */
486 mxfep
->mxfe_sromwidth
= mxfe_sromwidth(mxfep
);
489 * Get the factory ethernet address. This becomes the current
490 * ethernet address (it can be overridden later via ifconfig).
492 mxfe_getfactaddr(mxfep
, mxfep
->mxfe_curraddr
);
493 mxfep
->mxfe_promisc
= B_FALSE
;
496 * Establish interrupt handler.
498 if (ddi_add_intr(dip
, 0, NULL
, NULL
, mxfe_intr
, (caddr_t
)mxfep
) !=
500 mxfe_error(dip
, "unable to add interrupt");
504 /* TODO: do the power management stuff */
506 if ((macp
= mac_alloc(MAC_VERSION
)) == NULL
) {
507 mxfe_error(dip
, "mac_alloc failed");
511 macp
->m_type_ident
= MAC_PLUGIN_IDENT_ETHER
;
512 macp
->m_driver
= mxfep
;
514 macp
->m_src_addr
= mxfep
->mxfe_curraddr
;
515 macp
->m_callbacks
= &mxfe_m_callbacks
;
517 macp
->m_max_sdu
= ETHERMTU
;
518 macp
->m_margin
= VLAN_TAGSZ
;
520 if (mac_register(macp
, &mxfep
->mxfe_mh
) == DDI_SUCCESS
) {
522 return (DDI_SUCCESS
);
525 /* failed to register with MAC */
528 if (mxfep
->mxfe_icookie
!= NULL
) {
529 ddi_remove_intr(dip
, 0, mxfep
->mxfe_icookie
);
531 if (mxfep
->mxfe_intrstat
) {
532 kstat_delete(mxfep
->mxfe_intrstat
);
534 mutex_destroy(&mxfep
->mxfe_intrlock
);
535 mutex_destroy(&mxfep
->mxfe_xmtlock
);
537 mxfe_freerxring(mxfep
);
538 mxfe_freetxring(mxfep
);
540 if (mxfep
->mxfe_regshandle
!= NULL
) {
541 ddi_regs_map_free(&mxfep
->mxfe_regshandle
);
543 kmem_free(mxfep
, sizeof (mxfe_t
));
544 return (DDI_FAILURE
);
548 mxfe_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
552 mxfep
= ddi_get_driver_private(dip
);
554 mxfe_error(dip
, "no soft state in detach!");
555 return (DDI_FAILURE
);
561 if (mac_unregister(mxfep
->mxfe_mh
) != 0) {
562 return (DDI_FAILURE
);
565 /* make sure hardware is quiesced */
566 mutex_enter(&mxfep
->mxfe_intrlock
);
567 mutex_enter(&mxfep
->mxfe_xmtlock
);
568 mxfep
->mxfe_flags
&= ~MXFE_RUNNING
;
570 mutex_exit(&mxfep
->mxfe_xmtlock
);
571 mutex_exit(&mxfep
->mxfe_intrlock
);
573 /* clean up and shut down device */
574 ddi_remove_intr(dip
, 0, mxfep
->mxfe_icookie
);
576 /* clean up kstats */
577 kstat_delete(mxfep
->mxfe_intrstat
);
579 ddi_prop_remove_all(dip
);
581 /* free up any left over buffers or DMA resources */
582 mxfe_freerxring(mxfep
);
583 mxfe_freetxring(mxfep
);
585 ddi_regs_map_free(&mxfep
->mxfe_regshandle
);
586 mutex_destroy(&mxfep
->mxfe_intrlock
);
587 mutex_destroy(&mxfep
->mxfe_xmtlock
);
589 kmem_free(mxfep
, sizeof (mxfe_t
));
590 return (DDI_SUCCESS
);
593 /* quiesce the hardware */
594 mutex_enter(&mxfep
->mxfe_intrlock
);
595 mutex_enter(&mxfep
->mxfe_xmtlock
);
596 mxfep
->mxfe_flags
|= MXFE_SUSPENDED
;
598 mutex_exit(&mxfep
->mxfe_xmtlock
);
599 mutex_exit(&mxfep
->mxfe_intrlock
);
600 return (DDI_SUCCESS
);
602 return (DDI_FAILURE
);
607 mxfe_resume(dev_info_t
*dip
)
611 if ((mxfep
= ddi_get_driver_private(dip
)) == NULL
) {
612 return (DDI_FAILURE
);
615 mutex_enter(&mxfep
->mxfe_intrlock
);
616 mutex_enter(&mxfep
->mxfe_xmtlock
);
618 mxfep
->mxfe_flags
&= ~MXFE_SUSPENDED
;
620 /* re-initialize chip */
621 if (!mxfe_initialize(mxfep
)) {
622 mxfe_error(mxfep
->mxfe_dip
, "unable to resume chip!");
623 mxfep
->mxfe_flags
|= MXFE_SUSPENDED
;
624 mutex_exit(&mxfep
->mxfe_intrlock
);
625 mutex_exit(&mxfep
->mxfe_xmtlock
);
626 return (DDI_SUCCESS
);
630 if (mxfep
->mxfe_flags
& MXFE_RUNNING
) {
631 mxfe_startall(mxfep
);
635 mutex_exit(&mxfep
->mxfe_xmtlock
);
636 mutex_exit(&mxfep
->mxfe_intrlock
);
638 return (DDI_SUCCESS
);
642 mxfe_quiesce(dev_info_t
*dip
)
646 if ((mxfep
= ddi_get_driver_private(dip
)) == NULL
) {
647 return (DDI_FAILURE
);
650 /* just do a hard reset of everything */
651 SETBIT(mxfep
, CSR_PAR
, PAR_RESET
);
653 return (DDI_SUCCESS
);
658 mxfe_m_multicst(void *arg
, boolean_t add
, const uint8_t *macaddr
)
660 /* we already receive all multicast frames */
665 mxfe_m_promisc(void *arg
, boolean_t on
)
669 /* exclusive access to the card while we reprogram it */
670 mutex_enter(&mxfep
->mxfe_intrlock
);
671 mutex_enter(&mxfep
->mxfe_xmtlock
);
672 /* save current promiscuous mode state for replay in resume */
673 mxfep
->mxfe_promisc
= on
;
675 if ((mxfep
->mxfe_flags
& (MXFE_RUNNING
|MXFE_SUSPENDED
)) ==
678 SETBIT(mxfep
, CSR_NAR
, NAR_RX_PROMISC
);
680 CLRBIT(mxfep
, CSR_NAR
, NAR_RX_PROMISC
);
683 mutex_exit(&mxfep
->mxfe_xmtlock
);
684 mutex_exit(&mxfep
->mxfe_intrlock
);
690 mxfe_m_unicst(void *arg
, const uint8_t *macaddr
)
694 mutex_enter(&mxfep
->mxfe_intrlock
);
695 mutex_enter(&mxfep
->mxfe_xmtlock
);
696 bcopy(macaddr
, mxfep
->mxfe_curraddr
, ETHERADDRL
);
698 mxfe_resetall(mxfep
);
700 mutex_exit(&mxfep
->mxfe_intrlock
);
701 mutex_exit(&mxfep
->mxfe_xmtlock
);
707 mxfe_m_tx(void *arg
, mblk_t
*mp
)
712 mutex_enter(&mxfep
->mxfe_xmtlock
);
714 if (mxfep
->mxfe_flags
& MXFE_SUSPENDED
) {
715 mutex_exit(&mxfep
->mxfe_xmtlock
);
723 if (!mxfe_send(mxfep
, mp
)) {
729 mutex_exit(&mxfep
->mxfe_xmtlock
);
735 * Hardware management.
738 mxfe_initialize(mxfe_t
*mxfep
)
744 ASSERT(mutex_owned(&mxfep
->mxfe_intrlock
));
745 ASSERT(mutex_owned(&mxfep
->mxfe_xmtlock
));
747 DBG(DCHATTY
, "resetting!");
748 SETBIT(mxfep
, CSR_PAR
, PAR_RESET
);
749 for (i
= 1; i
< 10; i
++) {
751 val
= GETCSR(mxfep
, CSR_PAR
);
752 if (!(val
& PAR_RESET
)) {
757 mxfe_error(mxfep
->mxfe_dip
, "timed out waiting for reset!");
761 /* initialize busctl register */
762 par
= PAR_BAR
| PAR_MRME
| PAR_MRLE
| PAR_MWIE
;
764 /* set the cache alignment if its supported */
765 switch (mxfep
->mxfe_cachesize
) {
770 par
|= PAR_CALIGN_16
;
773 par
|= PAR_CALIGN_32
;
776 par
&= ~(PAR_MWIE
| PAR_MRME
| PAR_MRLE
);
779 /* leave the burst length at zero, indicating infinite burst */
780 PUTCSR(mxfep
, CSR_PAR
, par
);
782 mxfe_resetrings(mxfep
);
784 /* clear the lost packet counter (cleared on read) */
785 (void) GETCSR(mxfep
, CSR_LPC
);
787 /* a few other NAR bits */
788 nar
= GETCSR(mxfep
, CSR_NAR
);
789 nar
&= ~NAR_RX_HO
; /* disable hash only filtering */
790 nar
|= NAR_RX_HP
; /* hash perfect forwarding */
791 nar
|= NAR_RX_MULTI
; /* receive all multicast */
792 nar
|= NAR_SF
; /* store-and-forward */
794 if (mxfep
->mxfe_promisc
) {
795 nar
|= NAR_RX_PROMISC
;
797 nar
&= ~NAR_RX_PROMISC
;
799 PUTCSR(mxfep
, CSR_NAR
, nar
);
801 mxfe_send_setup(mxfep
);
807 * Serial EEPROM access - inspired by the FreeBSD implementation.
811 mxfe_sromwidth(mxfe_t
*mxfep
)
817 eeread
= SPR_SROM_READ
| SPR_SROM_SEL
| SPR_SROM_CHIP
;
819 PUTCSR(mxfep
, CSR_SPR
, eeread
& ~SPR_SROM_CHIP
);
821 PUTCSR(mxfep
, CSR_SPR
, eeread
);
823 /* command bits first */
824 for (i
= 4; i
!= 0; i
>>= 1) {
825 unsigned val
= (SROM_READCMD
& i
) ? SPR_SROM_DIN
: 0;
826 PUTCSR(mxfep
, CSR_SPR
, eeread
| val
);
828 PUTCSR(mxfep
, CSR_SPR
, eeread
| val
| SPR_SROM_CLOCK
);
832 PUTCSR(mxfep
, CSR_SPR
, eeread
);
834 for (addrlen
= 1; addrlen
<= 12; addrlen
++) {
835 PUTCSR(mxfep
, CSR_SPR
, eeread
| SPR_SROM_CLOCK
);
837 if (!(GETCSR(mxfep
, CSR_SPR
) & SPR_SROM_DOUT
)) {
838 PUTCSR(mxfep
, CSR_SPR
, eeread
);
842 PUTCSR(mxfep
, CSR_SPR
, eeread
);
846 /* turn off accesses to the EEPROM */
847 PUTCSR(mxfep
, CSR_SPR
, eeread
&~ SPR_SROM_CHIP
);
849 DBG(DSROM
, "detected srom width = %d bits", addrlen
);
851 return ((addrlen
< 4 || addrlen
> 12) ? 6 : addrlen
);
855 * The words in EEPROM are stored in little endian order. We
856 * shift bits out in big endian order, though. This requires
857 * a byte swap on some platforms.
860 mxfe_readsromword(mxfe_t
*mxfep
, unsigned romaddr
)
870 eeread
= SPR_SROM_READ
| SPR_SROM_SEL
| SPR_SROM_CHIP
;
871 addrlen
= mxfep
->mxfe_sromwidth
;
872 readcmd
= (SROM_READCMD
<< addrlen
) | romaddr
;
874 if (romaddr
>= (1 << addrlen
)) {
875 /* too big to fit! */
879 PUTCSR(mxfep
, CSR_SPR
, eeread
& ~SPR_SROM_CHIP
);
880 PUTCSR(mxfep
, CSR_SPR
, eeread
);
882 /* command and address bits */
883 for (i
= 4 + addrlen
; i
>= 0; i
--) {
884 short val
= (readcmd
& (1 << i
)) ? SPR_SROM_DIN
: 0;
885 PUTCSR(mxfep
, CSR_SPR
, eeread
| val
);
887 PUTCSR(mxfep
, CSR_SPR
, eeread
| val
| SPR_SROM_CLOCK
);
891 PUTCSR(mxfep
, CSR_SPR
, eeread
);
893 for (i
= 0; i
< 16; i
++) {
894 PUTCSR(mxfep
, CSR_SPR
, eeread
| SPR_SROM_CLOCK
);
897 if (GETCSR(mxfep
, CSR_SPR
) & SPR_SROM_DOUT
) {
900 PUTCSR(mxfep
, CSR_SPR
, eeread
);
904 /* turn off accesses to the EEPROM */
905 PUTCSR(mxfep
, CSR_SPR
, eeread
&~ SPR_SROM_CHIP
);
908 * Fix up the endianness thing. Note that the values
909 * are stored in little endian format on the SROM.
911 DBG(DSROM
, "got value %d from SROM (before swap)", word
);
912 ptr
= (uchar_t
*)&word
;
913 retval
= (ptr
[1] << 8) | ptr
[0];
918 mxfe_readsrom(mxfe_t
*mxfep
, unsigned romaddr
, unsigned len
, void *dest
)
924 for (i
= 0; i
< len
; i
++) {
925 word
= mxfe_readsromword(mxfep
, romaddr
+ i
);
926 bcopy(&word
, ptr
, 2);
928 DBG(DSROM
, "word at %d is 0x%x", romaddr
+ i
, word
);
933 mxfe_getfactaddr(mxfe_t
*mxfep
, uchar_t
*eaddr
)
938 /* first read to get the location of mac address in srom */
939 word
= mxfe_readsromword(mxfep
, SROM_ENADDR
/ 2);
940 ptr
= (uchar_t
*)&word
;
941 word
= (ptr
[1] << 8) | ptr
[0];
943 /* then read the actual mac address */
944 mxfe_readsrom(mxfep
, word
/ 2, ETHERADDRL
/ 2, eaddr
);
946 "factory ethernet address = %02x:%02x:%02x:%02x:%02x:%02x",
947 eaddr
[0], eaddr
[1], eaddr
[2], eaddr
[3], eaddr
[4], eaddr
[5]);
951 mxfe_startphy(mxfe_t
*mxfep
)
953 switch (MXFE_MODEL(mxfep
)) {
955 mxfe_startphymii(mxfep
);
958 mxfe_startphynway(mxfep
);
964 mxfe_stopphy(mxfe_t
*mxfep
)
969 /* stop the phy timer */
970 PUTCSR(mxfep
, CSR_TIMER
, 0);
972 switch (MXFE_MODEL(mxfep
)) {
974 for (i
= 0; i
< 32; i
++) {
975 mxfe_miiwrite(mxfep
, mxfep
->mxfe_phyaddr
, MII_CONTROL
,
976 MII_CONTROL_PWRDN
| MII_CONTROL_ISOLATE
);
980 DBG(DPHY
, "resetting SIA");
981 PUTCSR(mxfep
, CSR_SIA
, SIA_RESET
);
983 CLRBIT(mxfep
, CSR_TCTL
, TCTL_PWR
| TCTL_ANE
);
984 nar
= GETCSR(mxfep
, CSR_NAR
);
985 nar
&= ~(NAR_PORTSEL
| NAR_PCS
| NAR_SCR
| NAR_FDX
);
987 PUTCSR(mxfep
, CSR_NAR
, nar
);
992 * mark the link state unknown
994 if (!mxfep
->mxfe_resetting
) {
995 mxfep
->mxfe_linkup
= LINK_STATE_UNKNOWN
;
996 mxfep
->mxfe_ifspeed
= 0;
997 mxfep
->mxfe_duplex
= LINK_DUPLEX_UNKNOWN
;
998 if (mxfep
->mxfe_flags
& MXFE_RUNNING
)
999 mxfe_reportlink(mxfep
);
1007 mxfe_startnway(mxfe_t
*mxfep
)
1013 /* this should not happen in a healthy system */
1014 if (mxfep
->mxfe_nwaystate
!= MXFE_NOLINK
) {
1015 DBG(DWARN
, "link start called out of state (%x)",
1016 mxfep
->mxfe_nwaystate
);
1020 if (mxfep
->mxfe_adv_aneg
== 0) {
1021 /* not done for forced mode */
1025 nar
= GETCSR(mxfep
, CSR_NAR
);
1026 restart
= nar
& (NAR_TX_ENABLE
| NAR_RX_ENABLE
);
1030 mxfe_stopmac(mxfep
);
1032 nar
|= NAR_SCR
| NAR_PCS
| NAR_HBD
;
1035 tctl
= GETCSR(mxfep
, CSR_TCTL
);
1036 tctl
&= ~(TCTL_100FDX
| TCTL_100HDX
| TCTL_HDX
);
1038 if (mxfep
->mxfe_adv_100fdx
) {
1039 tctl
|= TCTL_100FDX
;
1041 if (mxfep
->mxfe_adv_100hdx
) {
1042 tctl
|= TCTL_100HDX
;
1044 if (mxfep
->mxfe_adv_10fdx
) {
1047 if (mxfep
->mxfe_adv_10hdx
) {
1050 tctl
|= TCTL_PWR
| TCTL_ANE
| TCTL_LTE
| TCTL_RSQ
;
1052 /* possibly we should add in support for PAUSE frames */
1053 DBG(DPHY
, "writing nar = 0x%x", nar
);
1054 PUTCSR(mxfep
, CSR_NAR
, nar
);
1056 DBG(DPHY
, "writing tctl = 0x%x", tctl
);
1057 PUTCSR(mxfep
, CSR_TCTL
, tctl
);
1059 /* restart autonegotation */
1060 DBG(DPHY
, "writing tstat = 0x%x", TSTAT_ANS_START
);
1061 PUTCSR(mxfep
, CSR_TSTAT
, TSTAT_ANS_START
);
1063 /* restart tx/rx processes... */
1065 mxfe_startmac(mxfep
);
1067 /* Macronix initializations from Bolo Tsai */
1068 PUTCSR(mxfep
, CSR_MXMAGIC
, 0x0b2c0000);
1069 PUTCSR(mxfep
, CSR_ACOMP
, 0x11000);
1071 mxfep
->mxfe_nwaystate
= MXFE_NWAYCHECK
;
1075 mxfe_checklinknway(mxfe_t
*mxfep
)
1080 DBG(DPHY
, "NWay check, state %x", mxfep
->mxfe_nwaystate
);
1081 tstat
= GETCSR(mxfep
, CSR_TSTAT
);
1082 lpar
= TSTAT_LPAR(tstat
);
1084 mxfep
->mxfe_anlpar
= lpar
;
1085 if (tstat
& TSTAT_LPN
) {
1086 mxfep
->mxfe_aner
|= MII_AN_EXP_LPCANAN
;
1088 mxfep
->mxfe_aner
&= ~(MII_AN_EXP_LPCANAN
);
1091 DBG(DPHY
, "tstat(CSR12) = 0x%x", tstat
);
1092 DBG(DPHY
, "ANEG state = 0x%x", (tstat
& TSTAT_ANS
) >> 12);
1094 if ((tstat
& TSTAT_ANS
) != TSTAT_ANS_OK
) {
1095 /* autoneg did not complete */
1096 mxfep
->mxfe_bmsr
&= ~MII_STATUS_ANDONE
;
1098 mxfep
->mxfe_bmsr
|= ~MII_STATUS_ANDONE
;
1101 if ((tstat
& TSTAT_100F
) && (tstat
& TSTAT_10F
)) {
1102 mxfep
->mxfe_linkup
= LINK_STATE_DOWN
;
1103 mxfep
->mxfe_ifspeed
= 0;
1104 mxfep
->mxfe_duplex
= LINK_DUPLEX_UNKNOWN
;
1105 mxfep
->mxfe_nwaystate
= MXFE_NOLINK
;
1106 mxfe_reportlink(mxfep
);
1107 mxfe_startnway(mxfep
);
1112 * if the link is newly up, then we might need to set various
1113 * mode bits, or negotiate for parameters, etc.
1115 if (mxfep
->mxfe_adv_aneg
) {
1119 mxfep
->mxfe_linkup
= LINK_STATE_UP
;
1120 anlpar
= mxfep
->mxfe_anlpar
;
1122 if (tstat
& TSTAT_LPN
) {
1123 /* partner has NWay */
1125 if ((anlpar
& MII_ABILITY_100BASE_TX_FD
) &&
1126 mxfep
->mxfe_adv_100fdx
) {
1127 mxfep
->mxfe_ifspeed
= 100000000;
1128 mxfep
->mxfe_duplex
= LINK_DUPLEX_FULL
;
1129 } else if ((anlpar
& MII_ABILITY_100BASE_TX
) &&
1130 mxfep
->mxfe_adv_100hdx
) {
1131 mxfep
->mxfe_ifspeed
= 100000000;
1132 mxfep
->mxfe_duplex
= LINK_DUPLEX_HALF
;
1133 } else if ((anlpar
& MII_ABILITY_10BASE_T_FD
) &&
1134 mxfep
->mxfe_adv_10fdx
) {
1135 mxfep
->mxfe_ifspeed
= 10000000;
1136 mxfep
->mxfe_duplex
= LINK_DUPLEX_FULL
;
1137 } else if ((anlpar
& MII_ABILITY_10BASE_T
) &&
1138 mxfep
->mxfe_adv_10hdx
) {
1139 mxfep
->mxfe_ifspeed
= 10000000;
1140 mxfep
->mxfe_duplex
= LINK_DUPLEX_HALF
;
1142 mxfep
->mxfe_ifspeed
= 0;
1145 /* link partner does not have NWay */
1146 /* just assume half duplex, since we can't detect */
1147 mxfep
->mxfe_duplex
= LINK_DUPLEX_HALF
;
1148 if (!(tstat
& TSTAT_100F
)) {
1149 DBG(DPHY
, "Partner doesn't have NWAY");
1150 mxfep
->mxfe_ifspeed
= 100000000;
1152 mxfep
->mxfe_ifspeed
= 10000000;
1157 mxfep
->mxfe_linkup
= LINK_STATE_UP
;
1158 if (mxfep
->mxfe_adv_100fdx
) {
1159 mxfep
->mxfe_ifspeed
= 100000000;
1160 mxfep
->mxfe_duplex
= LINK_DUPLEX_FULL
;
1161 } else if (mxfep
->mxfe_adv_100hdx
) {
1162 mxfep
->mxfe_ifspeed
= 100000000;
1163 mxfep
->mxfe_duplex
= LINK_DUPLEX_HALF
;
1164 } else if (mxfep
->mxfe_adv_10fdx
) {
1165 mxfep
->mxfe_ifspeed
= 10000000;
1166 mxfep
->mxfe_duplex
= LINK_DUPLEX_FULL
;
1167 } else if (mxfep
->mxfe_adv_10hdx
) {
1168 mxfep
->mxfe_ifspeed
= 10000000;
1169 mxfep
->mxfe_duplex
= LINK_DUPLEX_HALF
;
1171 mxfep
->mxfe_ifspeed
= 0;
1174 mxfe_reportlink(mxfep
);
1175 mxfep
->mxfe_nwaystate
= MXFE_GOODLINK
;
1179 mxfe_startphynway(mxfe_t
*mxfep
)
1181 /* take NWay and PHY out of reset */
1182 PUTCSR(mxfep
, CSR_SIA
, SIA_NRESET
);
1185 mxfep
->mxfe_nwaystate
= MXFE_NOLINK
;
1186 mxfep
->mxfe_bmsr
= MII_STATUS_CANAUTONEG
|
1187 MII_STATUS_100_BASEX_FD
| MII_STATUS_100_BASEX
|
1188 MII_STATUS_10_FD
| MII_STATUS_10
;
1189 mxfep
->mxfe_cap_aneg
=
1190 mxfep
->mxfe_cap_100fdx
= mxfep
->mxfe_cap_100hdx
=
1191 mxfep
->mxfe_cap_10fdx
= mxfep
->mxfe_cap_10hdx
= 1;
1193 /* lie about the transceiver... its not really 802.3u compliant */
1194 mxfep
->mxfe_phyaddr
= 0;
1195 mxfep
->mxfe_phyinuse
= XCVR_100X
;
1196 mxfep
->mxfe_phyid
= 0;
1198 /* 100-T4 not supported with NWay */
1199 mxfep
->mxfe_adv_100T4
= 0;
1200 mxfep
->mxfe_cap_100T4
= 0;
1202 /* make sure at least one valid mode is selected */
1203 if ((!mxfep
->mxfe_adv_100fdx
) &&
1204 (!mxfep
->mxfe_adv_100hdx
) &&
1205 (!mxfep
->mxfe_adv_10fdx
) &&
1206 (!mxfep
->mxfe_adv_10hdx
)) {
1207 mxfe_error(mxfep
->mxfe_dip
, "No valid link mode selected.");
1208 mxfe_error(mxfep
->mxfe_dip
, "Powering down PHY.");
1209 mxfe_stopphy(mxfep
);
1210 mxfep
->mxfe_linkup
= LINK_STATE_DOWN
;
1211 if (mxfep
->mxfe_flags
& MXFE_RUNNING
)
1212 mxfe_reportlink(mxfep
);
1216 if (mxfep
->mxfe_adv_aneg
== 0) {
1221 nar
= GETCSR(mxfep
, CSR_NAR
);
1222 tctl
= GETCSR(mxfep
, CSR_TCTL
);
1224 ASSERT((nar
& (NAR_TX_ENABLE
| NAR_RX_ENABLE
)) == 0);
1226 nar
&= ~(NAR_FDX
| NAR_PORTSEL
| NAR_SCR
| NAR_SPEED
);
1228 if (mxfep
->mxfe_adv_100fdx
) {
1229 nar
|= NAR_PORTSEL
| NAR_PCS
| NAR_SCR
| NAR_FDX
;
1230 } else if (mxfep
->mxfe_adv_100hdx
) {
1231 nar
|= NAR_PORTSEL
| NAR_PCS
| NAR_SCR
;
1232 } else if (mxfep
->mxfe_adv_10fdx
) {
1233 nar
|= NAR_FDX
| NAR_SPEED
;
1234 } else { /* mxfep->mxfe_adv_10hdx */
1238 PUTCSR(mxfep
, CSR_NAR
, nar
);
1239 PUTCSR(mxfep
, CSR_TCTL
, tctl
);
1241 /* Macronix initializations from Bolo Tsai */
1242 PUTCSR(mxfep
, CSR_MXMAGIC
, 0x0b2c0000);
1243 PUTCSR(mxfep
, CSR_ACOMP
, 0x11000);
1245 mxfe_startnway(mxfep
);
1247 PUTCSR(mxfep
, CSR_TIMER
, TIMER_LOOP
|
1248 (MXFE_LINKTIMER
* 1000 / TIMER_USEC
));
1255 mxfe_startphymii(mxfe_t
*mxfep
)
1266 mxfep
->mxfe_phyaddr
= -1;
1268 /* search for first PHY we can find */
1269 for (phyaddr
= 0; phyaddr
< 32; phyaddr
++) {
1270 bmsr
= mxfe_miiread(mxfep
, phyaddr
, MII_STATUS
);
1271 if ((bmsr
!= 0) && (bmsr
!= 0xffff)) {
1272 mxfep
->mxfe_phyaddr
= phyaddr
;
1277 phyidr1
= mxfe_miiread(mxfep
, phyaddr
, MII_PHYIDH
);
1278 phyidr2
= mxfe_miiread(mxfep
, phyaddr
, MII_PHYIDL
);
1279 mxfep
->mxfe_phyid
= (phyidr1
<< 16) | (phyidr2
);
1282 * Generally, all Macronix based devices use an internal
1283 * 100BASE-TX internal transceiver. If we ever run into a
1284 * variation on this, then the following logic will need to be
1287 * One could question the value of the XCVR_INUSE field in the
1290 if (bmsr
& MII_STATUS_100_BASE_T4
) {
1291 mxfep
->mxfe_phyinuse
= XCVR_100T4
;
1293 mxfep
->mxfe_phyinuse
= XCVR_100X
;
1296 /* assume we support everything to start */
1297 mxfep
->mxfe_cap_aneg
= mxfep
->mxfe_cap_100T4
=
1298 mxfep
->mxfe_cap_100fdx
= mxfep
->mxfe_cap_100hdx
=
1299 mxfep
->mxfe_cap_10fdx
= mxfep
->mxfe_cap_10hdx
= 1;
1301 DBG(DPHY
, "phy at %d: %x,%x", phyaddr
, phyidr1
, phyidr2
);
1302 DBG(DPHY
, "bmsr = %x", mxfe_miiread(mxfep
,
1303 mxfep
->mxfe_phyaddr
, MII_STATUS
));
1304 DBG(DPHY
, "anar = %x", mxfe_miiread(mxfep
,
1305 mxfep
->mxfe_phyaddr
, MII_AN_ADVERT
));
1306 DBG(DPHY
, "anlpar = %x", mxfe_miiread(mxfep
,
1307 mxfep
->mxfe_phyaddr
, MII_AN_LPABLE
));
1308 DBG(DPHY
, "aner = %x", mxfe_miiread(mxfep
,
1309 mxfep
->mxfe_phyaddr
, MII_AN_EXPANSION
));
1311 DBG(DPHY
, "resetting phy");
1313 /* we reset the phy block */
1314 mxfe_miiwrite(mxfep
, phyaddr
, MII_CONTROL
, MII_CONTROL_RESET
);
1316 * wait for it to complete -- 500usec is still to short to
1317 * bother getting the system clock involved.
1320 for (retries
= 0; retries
< 10; retries
++) {
1321 if (mxfe_miiread(mxfep
, phyaddr
, MII_CONTROL
) &
1322 MII_CONTROL_RESET
) {
1328 if (retries
== 100) {
1329 mxfe_error(mxfep
->mxfe_dip
, "timeout waiting on phy to reset");
1333 DBG(DPHY
, "phy reset complete");
1335 bmsr
= mxfe_miiread(mxfep
, phyaddr
, MII_STATUS
);
1336 bmcr
= mxfe_miiread(mxfep
, phyaddr
, MII_CONTROL
);
1337 anar
= mxfe_miiread(mxfep
, phyaddr
, MII_AN_ADVERT
);
1339 anar
&= ~(MII_ABILITY_100BASE_T4
|
1340 MII_ABILITY_100BASE_TX_FD
| MII_ABILITY_100BASE_TX
|
1341 MII_ABILITY_10BASE_T_FD
| MII_ABILITY_10BASE_T
);
1343 /* disable modes not supported in hardware */
1344 if (!(bmsr
& MII_STATUS_100_BASE_T4
)) {
1345 mxfep
->mxfe_adv_100T4
= 0;
1346 mxfep
->mxfe_cap_100T4
= 0;
1348 if (!(bmsr
& MII_STATUS_100_BASEX_FD
)) {
1349 mxfep
->mxfe_adv_100fdx
= 0;
1350 mxfep
->mxfe_cap_100fdx
= 0;
1352 if (!(bmsr
& MII_STATUS_100_BASEX
)) {
1353 mxfep
->mxfe_adv_100hdx
= 0;
1354 mxfep
->mxfe_cap_100hdx
= 0;
1356 if (!(bmsr
& MII_STATUS_10_FD
)) {
1357 mxfep
->mxfe_adv_10fdx
= 0;
1358 mxfep
->mxfe_cap_10fdx
= 0;
1360 if (!(bmsr
& MII_STATUS_10
)) {
1361 mxfep
->mxfe_adv_10hdx
= 0;
1362 mxfep
->mxfe_cap_10hdx
= 0;
1364 if (!(bmsr
& MII_STATUS_CANAUTONEG
)) {
1365 mxfep
->mxfe_adv_aneg
= 0;
1366 mxfep
->mxfe_cap_aneg
= 0;
1370 if (mxfep
->mxfe_adv_100T4
) {
1371 anar
|= MII_ABILITY_100BASE_T4
;
1374 if (mxfep
->mxfe_adv_100fdx
) {
1375 anar
|= MII_ABILITY_100BASE_TX_FD
;
1378 if (mxfep
->mxfe_adv_100hdx
) {
1379 anar
|= MII_ABILITY_100BASE_TX
;
1382 if (mxfep
->mxfe_adv_10fdx
) {
1383 anar
|= MII_ABILITY_10BASE_T_FD
;
1386 if (mxfep
->mxfe_adv_10hdx
) {
1387 anar
|= MII_ABILITY_10BASE_T
;
1392 * Make certain at least one valid link mode is selected.
1395 mxfe_error(mxfep
->mxfe_dip
, "No valid link mode selected.");
1396 mxfe_error(mxfep
->mxfe_dip
, "Powering down PHY.");
1397 mxfe_stopphy(mxfep
);
1398 mxfep
->mxfe_linkup
= LINK_STATE_DOWN
;
1399 if (mxfep
->mxfe_flags
& MXFE_RUNNING
)
1400 mxfe_reportlink(mxfep
);
1404 if ((mxfep
->mxfe_adv_aneg
) && (bmsr
& MII_STATUS_CANAUTONEG
)) {
1405 DBG(DPHY
, "using autoneg mode");
1406 bmcr
= (MII_CONTROL_ANE
| MII_CONTROL_RSAN
);
1408 DBG(DPHY
, "using forced mode");
1409 if (mxfep
->mxfe_adv_100fdx
) {
1410 bmcr
= (MII_CONTROL_100MB
| MII_CONTROL_FDUPLEX
);
1411 } else if (mxfep
->mxfe_adv_100hdx
) {
1412 bmcr
= MII_CONTROL_100MB
;
1413 } else if (mxfep
->mxfe_adv_10fdx
) {
1414 bmcr
= MII_CONTROL_FDUPLEX
;
1421 DBG(DPHY
, "programming anar to 0x%x", anar
);
1422 mxfe_miiwrite(mxfep
, phyaddr
, MII_AN_ADVERT
, anar
);
1423 DBG(DPHY
, "programming bmcr to 0x%x", bmcr
);
1424 mxfe_miiwrite(mxfep
, phyaddr
, MII_CONTROL
, bmcr
);
1427 * schedule a query of the link status
1429 PUTCSR(mxfep
, CSR_TIMER
, TIMER_LOOP
|
1430 (MXFE_LINKTIMER
* 1000 / TIMER_USEC
));
1434 mxfe_reportlink(mxfe_t
*mxfep
)
1438 if (mxfep
->mxfe_ifspeed
!= mxfep
->mxfe_lastifspeed
) {
1439 mxfep
->mxfe_lastifspeed
= mxfep
->mxfe_ifspeed
;
1442 if (mxfep
->mxfe_duplex
!= mxfep
->mxfe_lastduplex
) {
1443 mxfep
->mxfe_lastduplex
= mxfep
->mxfe_duplex
;
1446 if (mxfep
->mxfe_linkup
!= mxfep
->mxfe_lastlinkup
) {
1447 mxfep
->mxfe_lastlinkup
= mxfep
->mxfe_linkup
;
1451 mac_link_update(mxfep
->mxfe_mh
, mxfep
->mxfe_linkup
);
1455 mxfe_checklink(mxfe_t
*mxfep
)
1457 if ((mxfep
->mxfe_flags
& MXFE_RUNNING
) == 0)
1460 if ((mxfep
->mxfe_txstall_time
!= 0) &&
1461 (gethrtime() > mxfep
->mxfe_txstall_time
) &&
1462 (mxfep
->mxfe_txavail
!= MXFE_TXRING
)) {
1463 mxfep
->mxfe_txstall_time
= 0;
1464 mxfe_error(mxfep
->mxfe_dip
, "TX stall detected!");
1465 mxfe_resetall(mxfep
);
1469 switch (MXFE_MODEL(mxfep
)) {
1471 mxfe_checklinkmii(mxfep
);
1474 mxfe_checklinknway(mxfep
);
1479 mxfe_checklinkmii(mxfe_t
*mxfep
)
1481 /* read MII state registers */
1488 /* read this twice, to clear latched link state */
1489 bmsr
= mxfe_miiread(mxfep
, mxfep
->mxfe_phyaddr
, MII_STATUS
);
1490 bmsr
= mxfe_miiread(mxfep
, mxfep
->mxfe_phyaddr
, MII_STATUS
);
1491 bmcr
= mxfe_miiread(mxfep
, mxfep
->mxfe_phyaddr
, MII_CONTROL
);
1492 anar
= mxfe_miiread(mxfep
, mxfep
->mxfe_phyaddr
, MII_AN_ADVERT
);
1493 anlpar
= mxfe_miiread(mxfep
, mxfep
->mxfe_phyaddr
, MII_AN_LPABLE
);
1494 aner
= mxfe_miiread(mxfep
, mxfep
->mxfe_phyaddr
, MII_AN_EXPANSION
);
1496 mxfep
->mxfe_bmsr
= bmsr
;
1497 mxfep
->mxfe_anlpar
= anlpar
;
1498 mxfep
->mxfe_aner
= aner
;
1500 if (bmsr
& MII_STATUS_REMFAULT
) {
1501 mxfe_error(mxfep
->mxfe_dip
, "Remote fault detected.");
1503 if (bmsr
& MII_STATUS_JABBERING
) {
1504 mxfe_error(mxfep
->mxfe_dip
, "Jabber condition detected.");
1506 if ((bmsr
& MII_STATUS_LINKUP
) == 0) {
1508 mxfep
->mxfe_ifspeed
= 0;
1509 mxfep
->mxfe_duplex
= LINK_DUPLEX_UNKNOWN
;
1510 mxfep
->mxfe_linkup
= LINK_STATE_DOWN
;
1511 mxfe_reportlink(mxfep
);
1515 DBG(DCHATTY
, "link up!");
1516 mxfep
->mxfe_linkup
= LINK_STATE_UP
;
1518 if (!(bmcr
& MII_CONTROL_ANE
)) {
1520 if (bmcr
& MII_CONTROL_100MB
) {
1521 mxfep
->mxfe_ifspeed
= 100000000;
1523 mxfep
->mxfe_ifspeed
= 10000000;
1525 if (bmcr
& MII_CONTROL_FDUPLEX
) {
1526 mxfep
->mxfe_duplex
= LINK_DUPLEX_FULL
;
1528 mxfep
->mxfe_duplex
= LINK_DUPLEX_HALF
;
1530 } else if ((!(bmsr
& MII_STATUS_CANAUTONEG
)) ||
1531 (!(bmsr
& MII_STATUS_ANDONE
))) {
1532 mxfep
->mxfe_ifspeed
= 0;
1533 mxfep
->mxfe_duplex
= LINK_DUPLEX_UNKNOWN
;
1534 } else if (anar
& anlpar
& MII_ABILITY_100BASE_TX_FD
) {
1535 mxfep
->mxfe_ifspeed
= 100000000;
1536 mxfep
->mxfe_duplex
= LINK_DUPLEX_FULL
;
1537 } else if (anar
& anlpar
& MII_ABILITY_100BASE_T4
) {
1538 mxfep
->mxfe_ifspeed
= 100000000;
1539 mxfep
->mxfe_duplex
= LINK_DUPLEX_HALF
;
1540 } else if (anar
& anlpar
& MII_ABILITY_100BASE_TX
) {
1541 mxfep
->mxfe_ifspeed
= 100000000;
1542 mxfep
->mxfe_duplex
= LINK_DUPLEX_HALF
;
1543 } else if (anar
& anlpar
& MII_ABILITY_10BASE_T_FD
) {
1544 mxfep
->mxfe_ifspeed
= 10000000;
1545 mxfep
->mxfe_duplex
= LINK_DUPLEX_FULL
;
1546 } else if (anar
& anlpar
& MII_ABILITY_10BASE_T
) {
1547 mxfep
->mxfe_ifspeed
= 10000000;
1548 mxfep
->mxfe_duplex
= LINK_DUPLEX_HALF
;
1550 mxfep
->mxfe_ifspeed
= 0;
1551 mxfep
->mxfe_duplex
= LINK_DUPLEX_UNKNOWN
;
1554 mxfe_reportlink(mxfep
);
1558 mxfe_miitristate(mxfe_t
*mxfep
)
1560 unsigned val
= SPR_SROM_WRITE
| SPR_MII_CTRL
;
1561 PUTCSR(mxfep
, CSR_SPR
, val
);
1563 PUTCSR(mxfep
, CSR_SPR
, val
| SPR_MII_CLOCK
);
1568 mxfe_miiwritebit(mxfe_t
*mxfep
, uint8_t bit
)
1570 unsigned val
= bit
? SPR_MII_DOUT
: 0;
1571 PUTCSR(mxfep
, CSR_SPR
, val
);
1573 PUTCSR(mxfep
, CSR_SPR
, val
| SPR_MII_CLOCK
);
1578 mxfe_miireadbit(mxfe_t
*mxfep
)
1580 unsigned val
= SPR_MII_CTRL
| SPR_SROM_READ
;
1582 PUTCSR(mxfep
, CSR_SPR
, val
);
1584 bit
= (GETCSR(mxfep
, CSR_SPR
) & SPR_MII_DIN
) ? 1 : 0;
1585 PUTCSR(mxfep
, CSR_SPR
, val
| SPR_MII_CLOCK
);
1591 mxfe_miiread(mxfe_t
*mxfep
, int phy
, int reg
)
1593 switch (MXFE_MODEL(mxfep
)) {
1595 return (mxfe_miiread98713(mxfep
, phy
, reg
));
1602 mxfe_miireadgeneral(mxfe_t
*mxfep
, int phy
, int reg
)
1607 /* send the 32 bit preamble */
1608 for (i
= 0; i
< 32; i
++) {
1609 mxfe_miiwritebit(mxfep
, 1);
1612 /* send the start code - 01b */
1613 mxfe_miiwritebit(mxfep
, 0);
1614 mxfe_miiwritebit(mxfep
, 1);
1616 /* send the opcode for read, - 10b */
1617 mxfe_miiwritebit(mxfep
, 1);
1618 mxfe_miiwritebit(mxfep
, 0);
1620 /* next we send the 5 bit phy address */
1621 for (i
= 0x10; i
> 0; i
>>= 1) {
1622 mxfe_miiwritebit(mxfep
, (phy
& i
) ? 1 : 0);
1625 /* the 5 bit register address goes next */
1626 for (i
= 0x10; i
> 0; i
>>= 1) {
1627 mxfe_miiwritebit(mxfep
, (reg
& i
) ? 1 : 0);
1630 /* turnaround - tristate followed by logic 0 */
1631 mxfe_miitristate(mxfep
);
1632 mxfe_miiwritebit(mxfep
, 0);
1634 /* read the 16 bit register value */
1635 for (i
= 0x8000; i
> 0; i
>>= 1) {
1637 value
|= mxfe_miireadbit(mxfep
);
1639 mxfe_miitristate(mxfep
);
1644 mxfe_miiread98713(mxfe_t
*mxfep
, int phy
, int reg
)
1649 * like an ordinary MII, but we have to turn off portsel while
1652 nar
= GETCSR(mxfep
, CSR_NAR
);
1653 PUTCSR(mxfep
, CSR_NAR
, nar
& ~NAR_PORTSEL
);
1654 retval
= mxfe_miireadgeneral(mxfep
, phy
, reg
);
1655 PUTCSR(mxfep
, CSR_NAR
, nar
);
1660 mxfe_miiwrite(mxfe_t
*mxfep
, int phy
, int reg
, uint16_t val
)
1662 switch (MXFE_MODEL(mxfep
)) {
1664 mxfe_miiwrite98713(mxfep
, phy
, reg
, val
);
1672 mxfe_miiwritegeneral(mxfe_t
*mxfep
, int phy
, int reg
, uint16_t val
)
1676 /* send the 32 bit preamble */
1677 for (i
= 0; i
< 32; i
++) {
1678 mxfe_miiwritebit(mxfep
, 1);
1681 /* send the start code - 01b */
1682 mxfe_miiwritebit(mxfep
, 0);
1683 mxfe_miiwritebit(mxfep
, 1);
1685 /* send the opcode for write, - 01b */
1686 mxfe_miiwritebit(mxfep
, 0);
1687 mxfe_miiwritebit(mxfep
, 1);
1689 /* next we send the 5 bit phy address */
1690 for (i
= 0x10; i
> 0; i
>>= 1) {
1691 mxfe_miiwritebit(mxfep
, (phy
& i
) ? 1 : 0);
1694 /* the 5 bit register address goes next */
1695 for (i
= 0x10; i
> 0; i
>>= 1) {
1696 mxfe_miiwritebit(mxfep
, (reg
& i
) ? 1 : 0);
1699 /* turnaround - tristate followed by logic 0 */
1700 mxfe_miitristate(mxfep
);
1701 mxfe_miiwritebit(mxfep
, 0);
1703 /* now write out our data (16 bits) */
1704 for (i
= 0x8000; i
> 0; i
>>= 1) {
1705 mxfe_miiwritebit(mxfep
, (val
& i
) ? 1 : 0);
1709 mxfe_miitristate(mxfep
);
1713 mxfe_miiwrite98713(mxfe_t
*mxfep
, int phy
, int reg
, uint16_t val
)
1717 * like an ordinary MII, but we have to turn off portsel while
1720 nar
= GETCSR(mxfep
, CSR_NAR
);
1721 PUTCSR(mxfep
, CSR_NAR
, nar
& ~NAR_PORTSEL
);
1722 mxfe_miiwritegeneral(mxfep
, phy
, reg
, val
);
1723 PUTCSR(mxfep
, CSR_NAR
, nar
);
1727 mxfe_m_start(void *arg
)
1729 mxfe_t
*mxfep
= arg
;
1731 /* grab exclusive access to the card */
1732 mutex_enter(&mxfep
->mxfe_intrlock
);
1733 mutex_enter(&mxfep
->mxfe_xmtlock
);
1735 mxfe_startall(mxfep
);
1736 mxfep
->mxfe_flags
|= MXFE_RUNNING
;
1738 mutex_exit(&mxfep
->mxfe_xmtlock
);
1739 mutex_exit(&mxfep
->mxfe_intrlock
);
1744 mxfe_m_stop(void *arg
)
1746 mxfe_t
*mxfep
= arg
;
1748 /* exclusive access to the hardware! */
1749 mutex_enter(&mxfep
->mxfe_intrlock
);
1750 mutex_enter(&mxfep
->mxfe_xmtlock
);
1752 mxfe_stopall(mxfep
);
1753 mxfep
->mxfe_flags
&= ~MXFE_RUNNING
;
1755 mutex_exit(&mxfep
->mxfe_xmtlock
);
1756 mutex_exit(&mxfep
->mxfe_intrlock
);
1760 mxfe_startmac(mxfe_t
*mxfep
)
1762 /* verify exclusive access to the card */
1763 ASSERT(mutex_owned(&mxfep
->mxfe_intrlock
));
1764 ASSERT(mutex_owned(&mxfep
->mxfe_xmtlock
));
1766 /* start the card */
1767 SETBIT(mxfep
, CSR_NAR
, NAR_TX_ENABLE
| NAR_RX_ENABLE
);
1769 if (mxfep
->mxfe_txavail
!= MXFE_TXRING
)
1770 PUTCSR(mxfep
, CSR_TDR
, 0);
1772 /* tell the mac that we are ready to go! */
1773 if (mxfep
->mxfe_flags
& MXFE_RUNNING
)
1774 mac_tx_update(mxfep
->mxfe_mh
);
1778 mxfe_stopmac(mxfe_t
*mxfep
)
1782 /* exclusive access to the hardware! */
1783 ASSERT(mutex_owned(&mxfep
->mxfe_intrlock
));
1784 ASSERT(mutex_owned(&mxfep
->mxfe_xmtlock
));
1786 CLRBIT(mxfep
, CSR_NAR
, NAR_TX_ENABLE
| NAR_RX_ENABLE
);
1789 * A 1518 byte frame at 10Mbps takes about 1.2 msec to drain.
1790 * We just add up to the nearest msec (2), which should be
1791 * plenty to complete.
1793 * Note that some chips never seem to indicate the transition to
1794 * the stopped state properly. Experience shows that we can safely
1795 * proceed anyway, after waiting the requisite timeout.
1797 for (i
= 2000; i
!= 0; i
-= 10) {
1798 if ((GETCSR(mxfep
, CSR_SR
) & (SR_TX_STATE
| SR_RX_STATE
)) == 0)
1803 /* prevent an interrupt */
1804 PUTCSR(mxfep
, CSR_SR
, INT_RXSTOPPED
| INT_TXSTOPPED
);
1808 mxfe_resetrings(mxfe_t
*mxfep
)
1812 /* now we need to reset the pointers... */
1813 PUTCSR(mxfep
, CSR_RDB
, 0);
1814 PUTCSR(mxfep
, CSR_TDB
, 0);
1816 /* reset the descriptor ring pointers */
1817 mxfep
->mxfe_rxhead
= 0;
1818 mxfep
->mxfe_txreclaim
= 0;
1819 mxfep
->mxfe_txsend
= 0;
1820 mxfep
->mxfe_txavail
= MXFE_TXRING
;
1822 /* set up transmit descriptor ring */
1823 for (i
= 0; i
< MXFE_TXRING
; i
++) {
1824 mxfe_desc_t
*tmdp
= &mxfep
->mxfe_txdescp
[i
];
1825 unsigned control
= 0;
1826 if (i
== (MXFE_TXRING
- 1)) {
1827 control
|= TXCTL_ENDRING
;
1829 PUTTXDESC(mxfep
, tmdp
->desc_status
, 0);
1830 PUTTXDESC(mxfep
, tmdp
->desc_control
, control
);
1831 PUTTXDESC(mxfep
, tmdp
->desc_buffer1
, 0);
1832 PUTTXDESC(mxfep
, tmdp
->desc_buffer2
, 0);
1833 SYNCTXDESC(mxfep
, i
, DDI_DMA_SYNC_FORDEV
);
1835 PUTCSR(mxfep
, CSR_TDB
, mxfep
->mxfe_txdesc_paddr
);
1837 /* make the receive buffers available */
1838 for (i
= 0; i
< MXFE_RXRING
; i
++) {
1839 mxfe_rxbuf_t
*rxb
= mxfep
->mxfe_rxbufs
[i
];
1840 mxfe_desc_t
*rmdp
= &mxfep
->mxfe_rxdescp
[i
];
1843 control
= MXFE_BUFSZ
& RXCTL_BUFLEN1
;
1844 if (i
== (MXFE_RXRING
- 1)) {
1845 control
|= RXCTL_ENDRING
;
1847 PUTRXDESC(mxfep
, rmdp
->desc_buffer1
, rxb
->rxb_paddr
);
1848 PUTRXDESC(mxfep
, rmdp
->desc_buffer2
, 0);
1849 PUTRXDESC(mxfep
, rmdp
->desc_control
, control
);
1850 PUTRXDESC(mxfep
, rmdp
->desc_status
, RXSTAT_OWN
);
1851 SYNCRXDESC(mxfep
, i
, DDI_DMA_SYNC_FORDEV
);
1853 PUTCSR(mxfep
, CSR_RDB
, mxfep
->mxfe_rxdesc_paddr
);
1857 mxfe_stopall(mxfe_t
*mxfep
)
1859 mxfe_disableinterrupts(mxfep
);
1861 mxfe_stopmac(mxfep
);
1864 mxfe_stopphy(mxfep
);
1868 mxfe_startall(mxfe_t
*mxfep
)
1870 ASSERT(mutex_owned(&mxfep
->mxfe_intrlock
));
1871 ASSERT(mutex_owned(&mxfep
->mxfe_xmtlock
));
1873 /* make sure interrupts are disabled to begin */
1874 mxfe_disableinterrupts(mxfep
);
1876 /* initialize the chip */
1877 (void) mxfe_initialize(mxfep
);
1879 /* now we can enable interrupts */
1880 mxfe_enableinterrupts(mxfep
);
1882 /* start up the phy */
1883 mxfe_startphy(mxfep
);
1885 /* start up the mac */
1886 mxfe_startmac(mxfep
);
1890 mxfe_resetall(mxfe_t
*mxfep
)
1892 mxfep
->mxfe_resetting
= B_TRUE
;
1893 mxfe_stopall(mxfep
);
1894 mxfep
->mxfe_resetting
= B_FALSE
;
1895 mxfe_startall(mxfep
);
1899 mxfe_alloctxbuf(mxfe_t
*mxfep
)
1901 ddi_dma_cookie_t dmac
;
1906 txb
= kmem_zalloc(sizeof (*txb
), KM_SLEEP
);
1908 if (ddi_dma_alloc_handle(mxfep
->mxfe_dip
, &mxfe_dma_txattr
,
1909 DDI_DMA_SLEEP
, NULL
, &txb
->txb_dmah
) != DDI_SUCCESS
) {
1913 if (ddi_dma_mem_alloc(txb
->txb_dmah
, MXFE_BUFSZ
, &mxfe_bufattr
,
1914 DDI_DMA_STREAMING
, DDI_DMA_SLEEP
, NULL
, &txb
->txb_buf
,
1915 &len
, &txb
->txb_acch
) != DDI_SUCCESS
) {
1918 if (ddi_dma_addr_bind_handle(txb
->txb_dmah
, NULL
, txb
->txb_buf
,
1919 len
, DDI_DMA_WRITE
| DDI_DMA_STREAMING
, DDI_DMA_SLEEP
, NULL
,
1920 &dmac
, &ncookies
) != DDI_DMA_MAPPED
) {
1923 txb
->txb_paddr
= dmac
.dmac_address
;
1929 mxfe_destroytxbuf(mxfe_txbuf_t
*txb
)
1933 (void) ddi_dma_unbind_handle(txb
->txb_dmah
);
1935 ddi_dma_mem_free(&txb
->txb_acch
);
1937 ddi_dma_free_handle(&txb
->txb_dmah
);
1938 kmem_free(txb
, sizeof (*txb
));
1943 mxfe_allocrxbuf(mxfe_t
*mxfep
)
1948 ddi_dma_cookie_t dmac
;
1950 rxb
= kmem_zalloc(sizeof (*rxb
), KM_SLEEP
);
1952 if (ddi_dma_alloc_handle(mxfep
->mxfe_dip
, &mxfe_dma_attr
,
1953 DDI_DMA_SLEEP
, NULL
, &rxb
->rxb_dmah
) != DDI_SUCCESS
) {
1954 kmem_free(rxb
, sizeof (*rxb
));
1957 if (ddi_dma_mem_alloc(rxb
->rxb_dmah
, MXFE_BUFSZ
, &mxfe_bufattr
,
1958 DDI_DMA_STREAMING
, DDI_DMA_SLEEP
, NULL
,
1959 &rxb
->rxb_buf
, &len
, &rxb
->rxb_acch
) != DDI_SUCCESS
) {
1960 ddi_dma_free_handle(&rxb
->rxb_dmah
);
1961 kmem_free(rxb
, sizeof (*rxb
));
1964 if (ddi_dma_addr_bind_handle(rxb
->rxb_dmah
, NULL
, rxb
->rxb_buf
, len
,
1965 DDI_DMA_READ
| DDI_DMA_STREAMING
, DDI_DMA_SLEEP
, NULL
, &dmac
,
1966 &ccnt
) != DDI_DMA_MAPPED
) {
1967 ddi_dma_mem_free(&rxb
->rxb_acch
);
1968 ddi_dma_free_handle(&rxb
->rxb_dmah
);
1969 kmem_free(rxb
, sizeof (*rxb
));
1972 rxb
->rxb_paddr
= dmac
.dmac_address
;
1978 mxfe_destroyrxbuf(mxfe_rxbuf_t
*rxb
)
1981 (void) ddi_dma_unbind_handle(rxb
->rxb_dmah
);
1982 ddi_dma_mem_free(&rxb
->rxb_acch
);
1983 ddi_dma_free_handle(&rxb
->rxb_dmah
);
1984 kmem_free(rxb
, sizeof (*rxb
));
1989 * Allocate receive resources.
1992 mxfe_allocrxring(mxfe_t
*mxfep
)
1998 ddi_dma_cookie_t dmac
;
2002 size
= MXFE_RXRING
* sizeof (mxfe_desc_t
);
2004 rval
= ddi_dma_alloc_handle(mxfep
->mxfe_dip
, &mxfe_dma_attr
,
2005 DDI_DMA_SLEEP
, NULL
, &mxfep
->mxfe_rxdesc_dmah
);
2006 if (rval
!= DDI_SUCCESS
) {
2007 mxfe_error(mxfep
->mxfe_dip
,
2008 "unable to allocate DMA handle for rx descriptors");
2009 return (DDI_FAILURE
);
2012 rval
= ddi_dma_mem_alloc(mxfep
->mxfe_rxdesc_dmah
, size
, &mxfe_devattr
,
2013 DDI_DMA_CONSISTENT
, DDI_DMA_SLEEP
, NULL
, &kaddr
, &len
,
2014 &mxfep
->mxfe_rxdesc_acch
);
2015 if (rval
!= DDI_SUCCESS
) {
2016 mxfe_error(mxfep
->mxfe_dip
,
2017 "unable to allocate DMA memory for rx descriptors");
2018 return (DDI_FAILURE
);
2021 rval
= ddi_dma_addr_bind_handle(mxfep
->mxfe_rxdesc_dmah
, NULL
, kaddr
,
2022 size
, DDI_DMA_RDWR
| DDI_DMA_CONSISTENT
, DDI_DMA_SLEEP
, NULL
,
2024 if (rval
!= DDI_DMA_MAPPED
) {
2025 mxfe_error(mxfep
->mxfe_dip
,
2026 "unable to bind DMA for rx descriptors");
2027 return (DDI_FAILURE
);
2030 /* because of mxfe_dma_attr */
2031 ASSERT(ncookies
== 1);
2033 /* we take the 32-bit physical address out of the cookie */
2034 mxfep
->mxfe_rxdesc_paddr
= dmac
.dmac_address
;
2035 mxfep
->mxfe_rxdescp
= (void *)kaddr
;
2037 /* allocate buffer pointers (not the buffers themselves, yet) */
2038 mxfep
->mxfe_rxbufs
= kmem_zalloc(MXFE_RXRING
* sizeof (mxfe_rxbuf_t
*),
2041 /* now allocate rx buffers */
2042 for (i
= 0; i
< MXFE_RXRING
; i
++) {
2043 mxfe_rxbuf_t
*rxb
= mxfe_allocrxbuf(mxfep
);
2045 return (DDI_FAILURE
);
2046 mxfep
->mxfe_rxbufs
[i
] = rxb
;
2049 return (DDI_SUCCESS
);
2053 * Allocate transmit resources.
2056 mxfe_alloctxring(mxfe_t
*mxfep
)
2062 ddi_dma_cookie_t dmac
;
2066 size
= MXFE_TXRING
* sizeof (mxfe_desc_t
);
2068 rval
= ddi_dma_alloc_handle(mxfep
->mxfe_dip
, &mxfe_dma_attr
,
2069 DDI_DMA_SLEEP
, NULL
, &mxfep
->mxfe_txdesc_dmah
);
2070 if (rval
!= DDI_SUCCESS
) {
2071 mxfe_error(mxfep
->mxfe_dip
,
2072 "unable to allocate DMA handle for tx descriptors");
2073 return (DDI_FAILURE
);
2076 rval
= ddi_dma_mem_alloc(mxfep
->mxfe_txdesc_dmah
, size
, &mxfe_devattr
,
2077 DDI_DMA_CONSISTENT
, DDI_DMA_SLEEP
, NULL
, &kaddr
, &len
,
2078 &mxfep
->mxfe_txdesc_acch
);
2079 if (rval
!= DDI_SUCCESS
) {
2080 mxfe_error(mxfep
->mxfe_dip
,
2081 "unable to allocate DMA memory for tx descriptors");
2082 return (DDI_FAILURE
);
2085 rval
= ddi_dma_addr_bind_handle(mxfep
->mxfe_txdesc_dmah
, NULL
, kaddr
,
2086 size
, DDI_DMA_RDWR
| DDI_DMA_CONSISTENT
, DDI_DMA_SLEEP
, NULL
,
2088 if (rval
!= DDI_DMA_MAPPED
) {
2089 mxfe_error(mxfep
->mxfe_dip
,
2090 "unable to bind DMA for tx descriptors");
2091 return (DDI_FAILURE
);
2094 /* because of mxfe_dma_attr */
2095 ASSERT(ncookies
== 1);
2097 /* we take the 32-bit physical address out of the cookie */
2098 mxfep
->mxfe_txdesc_paddr
= dmac
.dmac_address
;
2099 mxfep
->mxfe_txdescp
= (void *)kaddr
;
2101 /* allocate buffer pointers (not the buffers themselves, yet) */
2102 mxfep
->mxfe_txbufs
= kmem_zalloc(MXFE_TXRING
* sizeof (mxfe_txbuf_t
*),
2105 /* now allocate tx buffers */
2106 for (i
= 0; i
< MXFE_TXRING
; i
++) {
2107 mxfe_txbuf_t
*txb
= mxfe_alloctxbuf(mxfep
);
2109 return (DDI_FAILURE
);
2110 /* stick it in the stack */
2111 mxfep
->mxfe_txbufs
[i
] = txb
;
2114 return (DDI_SUCCESS
);
2118 mxfe_freerxring(mxfe_t
*mxfep
)
2122 for (i
= 0; i
< MXFE_RXRING
; i
++) {
2123 mxfe_destroyrxbuf(mxfep
->mxfe_rxbufs
[i
]);
2126 if (mxfep
->mxfe_rxbufs
) {
2127 kmem_free(mxfep
->mxfe_rxbufs
,
2128 MXFE_RXRING
* sizeof (mxfe_rxbuf_t
*));
2131 if (mxfep
->mxfe_rxdesc_paddr
)
2132 (void) ddi_dma_unbind_handle(mxfep
->mxfe_rxdesc_dmah
);
2133 if (mxfep
->mxfe_rxdesc_acch
)
2134 ddi_dma_mem_free(&mxfep
->mxfe_rxdesc_acch
);
2135 if (mxfep
->mxfe_rxdesc_dmah
)
2136 ddi_dma_free_handle(&mxfep
->mxfe_rxdesc_dmah
);
2140 mxfe_freetxring(mxfe_t
*mxfep
)
2144 for (i
= 0; i
< MXFE_TXRING
; i
++) {
2145 mxfe_destroytxbuf(mxfep
->mxfe_txbufs
[i
]);
2148 if (mxfep
->mxfe_txbufs
) {
2149 kmem_free(mxfep
->mxfe_txbufs
,
2150 MXFE_TXRING
* sizeof (mxfe_txbuf_t
*));
2152 if (mxfep
->mxfe_txdesc_paddr
)
2153 (void) ddi_dma_unbind_handle(mxfep
->mxfe_txdesc_dmah
);
2154 if (mxfep
->mxfe_txdesc_acch
)
2155 ddi_dma_mem_free(&mxfep
->mxfe_txdesc_acch
);
2156 if (mxfep
->mxfe_txdesc_dmah
)
2157 ddi_dma_free_handle(&mxfep
->mxfe_txdesc_dmah
);
2161 * Interrupt service routine.
2164 mxfe_intr(caddr_t arg
)
2166 mxfe_t
*mxfep
= (void *)arg
;
2169 boolean_t error
= B_FALSE
;
2171 mutex_enter(&mxfep
->mxfe_intrlock
);
2173 if (mxfep
->mxfe_flags
& MXFE_SUSPENDED
) {
2174 /* we cannot receive interrupts! */
2175 mutex_exit(&mxfep
->mxfe_intrlock
);
2176 return (DDI_INTR_UNCLAIMED
);
2179 /* check interrupt status bits, did we interrupt? */
2180 status
= GETCSR(mxfep
, CSR_SR
) & INT_ALL
;
2183 KIOIP
->intrs
[KSTAT_INTR_SPURIOUS
]++;
2184 mutex_exit(&mxfep
->mxfe_intrlock
);
2185 return (DDI_INTR_UNCLAIMED
);
2187 /* ack the interrupt */
2188 PUTCSR(mxfep
, CSR_SR
, status
);
2189 KIOIP
->intrs
[KSTAT_INTR_HARD
]++;
2191 if (!(mxfep
->mxfe_flags
& MXFE_RUNNING
)) {
2192 /* not running, don't touch anything */
2193 mutex_exit(&mxfep
->mxfe_intrlock
);
2194 return (DDI_INTR_CLAIMED
);
2197 if (status
& INT_RXOK
) {
2198 /* receive packets */
2199 if (mxfe_receive(mxfep
, &mp
)) {
2204 if (status
& INT_TXOK
) {
2205 /* transmit completed */
2206 mutex_enter(&mxfep
->mxfe_xmtlock
);
2207 mxfe_reclaim(mxfep
);
2208 mutex_exit(&mxfep
->mxfe_xmtlock
);
2211 if (((status
& (INT_TIMER
|INT_ANEG
)) != 0) ||
2212 ((mxfep
->mxfe_linkup
== LINK_STATE_UP
) &&
2213 ((status
& (INT_10LINK
|INT_100LINK
)) != 0))) {
2214 /* rescan the link */
2215 mutex_enter(&mxfep
->mxfe_xmtlock
);
2216 mxfe_checklink(mxfep
);
2217 mutex_exit(&mxfep
->mxfe_xmtlock
);
2220 if (status
& (INT_RXSTOPPED
|INT_TXSTOPPED
|INT_RXNOBUF
|
2221 INT_RXJABBER
|INT_TXJABBER
|INT_TXUNDERFLOW
)) {
2223 if (status
& (INT_RXJABBER
| INT_TXJABBER
)) {
2224 mxfep
->mxfe_jabber
++;
2226 DBG(DWARN
, "error interrupt: status %x", status
);
2230 if (status
& INT_BUSERR
) {
2231 switch (status
& SR_BERR_TYPE
) {
2232 case SR_BERR_PARITY
:
2233 mxfe_error(mxfep
->mxfe_dip
, "PCI parity error");
2235 case SR_BERR_TARGET_ABORT
:
2236 mxfe_error(mxfep
->mxfe_dip
, "PCI target abort");
2238 case SR_BERR_MASTER_ABORT
:
2239 mxfe_error(mxfep
->mxfe_dip
, "PCI master abort");
2242 mxfe_error(mxfep
->mxfe_dip
, "Unknown PCI error");
2250 /* reset the chip in an attempt to fix things */
2251 mutex_enter(&mxfep
->mxfe_xmtlock
);
2252 mxfe_resetall(mxfep
);
2253 mutex_exit(&mxfep
->mxfe_xmtlock
);
2256 mutex_exit(&mxfep
->mxfe_intrlock
);
2259 * Send up packets. We do this outside of the intrlock.
2262 mac_rx(mxfep
->mxfe_mh
, NULL
, mp
);
2265 return (DDI_INTR_CLAIMED
);
2269 mxfe_enableinterrupts(mxfe_t
*mxfep
)
2271 unsigned mask
= INT_WANTED
;
2273 if (mxfep
->mxfe_wantw
)
2276 if (MXFE_MODEL(mxfep
) != MXFE_98713A
)
2277 mask
|= INT_LINKSTATUS
;
2279 DBG(DINTR
, "setting int mask to 0x%x", mask
);
2280 PUTCSR(mxfep
, CSR_IER
, mask
);
2284 mxfe_disableinterrupts(mxfe_t
*mxfep
)
2286 /* disable further interrupts */
2287 PUTCSR(mxfep
, CSR_IER
, 0);
2289 /* clear any pending interrupts */
2290 PUTCSR(mxfep
, CSR_SR
, INT_ALL
);
2294 mxfe_send_setup(mxfe_t
*mxfep
)
2299 ASSERT(mutex_owned(&mxfep
->mxfe_xmtlock
));
2301 /* setup frame -- must be at head of list -- guaranteed by caller! */
2302 ASSERT(mxfep
->mxfe_txsend
== 0);
2304 txb
= mxfep
->mxfe_txbufs
[0];
2305 tmdp
= &mxfep
->mxfe_txdescp
[0];
2307 bzero(txb
->txb_buf
, MXFE_SETUP_LEN
);
2309 /* program the unicast address */
2310 txb
->txb_buf
[156] = mxfep
->mxfe_curraddr
[0];
2311 txb
->txb_buf
[157] = mxfep
->mxfe_curraddr
[1];
2312 txb
->txb_buf
[160] = mxfep
->mxfe_curraddr
[2];
2313 txb
->txb_buf
[161] = mxfep
->mxfe_curraddr
[3];
2314 txb
->txb_buf
[164] = mxfep
->mxfe_curraddr
[4];
2315 txb
->txb_buf
[165] = mxfep
->mxfe_curraddr
[5];
2317 /* make sure that the hardware can see it */
2318 SYNCTXBUF(txb
, MXFE_SETUP_LEN
, DDI_DMA_SYNC_FORDEV
);
2320 PUTTXDESC(mxfep
, tmdp
->desc_control
,
2321 TXCTL_FIRST
| TXCTL_LAST
| TXCTL_INTCMPLTE
| TXCTL_HASHPERF
|
2322 TXCTL_SETUP
| MXFE_SETUP_LEN
);
2324 PUTTXDESC(mxfep
, tmdp
->desc_buffer1
, txb
->txb_paddr
);
2325 PUTTXDESC(mxfep
, tmdp
->desc_buffer2
, 0);
2326 PUTTXDESC(mxfep
, tmdp
->desc_status
, TXSTAT_OWN
);
2328 /* sync the descriptor out to the device */
2329 SYNCTXDESC(mxfep
, 0, DDI_DMA_SYNC_FORDEV
);
2332 * wake up the chip ... inside the lock to protect against DR suspend,
2335 PUTCSR(mxfep
, CSR_TDR
, 0);
2336 mxfep
->mxfe_txsend
++;
2337 mxfep
->mxfe_txavail
--;
2340 * Program promiscuous mode.
2342 if (mxfep
->mxfe_promisc
) {
2343 SETBIT(mxfep
, CSR_NAR
, NAR_RX_PROMISC
);
2345 CLRBIT(mxfep
, CSR_NAR
, NAR_RX_PROMISC
);
2350 mxfe_send(mxfe_t
*mxfep
, mblk_t
*mp
)
2358 ASSERT(mutex_owned(&mxfep
->mxfe_xmtlock
));
2362 if (len
> ETHERVLANMTU
) {
2363 DBG(DXMIT
, "frame too long: %d", len
);
2364 mxfep
->mxfe_macxmt_errors
++;
2369 if (mxfep
->mxfe_txavail
< MXFE_TXRECLAIM
)
2370 mxfe_reclaim(mxfep
);
2372 if (mxfep
->mxfe_txavail
== 0) {
2374 mxfep
->mxfe_wantw
= B_TRUE
;
2375 /* enable TX interrupt */
2376 mxfe_enableinterrupts(mxfep
);
2380 txsend
= mxfep
->mxfe_txsend
;
2383 * For simplicity, we just do a copy into a preallocated
2387 txb
= mxfep
->mxfe_txbufs
[txsend
];
2388 mcopymsg(mp
, txb
->txb_buf
); /* frees mp! */
2393 mxfep
->mxfe_opackets
++;
2394 mxfep
->mxfe_obytes
+= len
;
2395 if (txb
->txb_buf
[0] & 0x1) {
2396 if (bcmp(txb
->txb_buf
, mxfe_broadcast
, ETHERADDRL
) != 0)
2397 mxfep
->mxfe_multixmt
++;
2399 mxfep
->mxfe_brdcstxmt
++;
2402 /* note len is already known to be a small unsigned */
2403 control
= len
| TXCTL_FIRST
| TXCTL_LAST
| TXCTL_INTCMPLTE
;
2405 if (txsend
== (MXFE_TXRING
- 1))
2406 control
|= TXCTL_ENDRING
;
2408 tmd
= &mxfep
->mxfe_txdescp
[txsend
];
2410 SYNCTXBUF(txb
, len
, DDI_DMA_SYNC_FORDEV
);
2411 PUTTXDESC(mxfep
, tmd
->desc_control
, control
);
2412 PUTTXDESC(mxfep
, tmd
->desc_buffer1
, txb
->txb_paddr
);
2413 PUTTXDESC(mxfep
, tmd
->desc_buffer2
, 0);
2414 PUTTXDESC(mxfep
, tmd
->desc_status
, TXSTAT_OWN
);
2415 /* sync the descriptor out to the device */
2416 SYNCTXDESC(mxfep
, txsend
, DDI_DMA_SYNC_FORDEV
);
2419 * Note the new values of txavail and txsend.
2421 mxfep
->mxfe_txavail
--;
2422 mxfep
->mxfe_txsend
= (txsend
+ 1) % MXFE_TXRING
;
2425 * It should never, ever take more than 5 seconds to drain
2426 * the ring. If it happens, then we are stuck!
2428 mxfep
->mxfe_txstall_time
= gethrtime() + (5 * 1000000000ULL);
2431 * wake up the chip ... inside the lock to protect against DR suspend,
2434 PUTCSR(mxfep
, CSR_TDR
, 0);
2440 * Reclaim buffers that have completed transmission.
2443 mxfe_reclaim(mxfe_t
*mxfep
)
2447 while (mxfep
->mxfe_txavail
!= MXFE_TXRING
) {
2450 int index
= mxfep
->mxfe_txreclaim
;
2452 tmdp
= &mxfep
->mxfe_txdescp
[index
];
2454 /* sync it before we read it */
2455 SYNCTXDESC(mxfep
, index
, DDI_DMA_SYNC_FORKERNEL
);
2457 control
= GETTXDESC(mxfep
, tmdp
->desc_control
);
2458 status
= GETTXDESC(mxfep
, tmdp
->desc_status
);
2460 if (status
& TXSTAT_OWN
) {
2461 /* chip is still working on it, we're done */
2465 mxfep
->mxfe_txavail
++;
2466 mxfep
->mxfe_txreclaim
= (index
+ 1) % MXFE_TXRING
;
2468 /* in the most common successful case, all bits are clear */
2472 if (((control
& TXCTL_SETUP
) != 0) ||
2473 ((control
& TXCTL_LAST
) == 0)) {
2474 /* no interesting statistics here */
2478 if (status
& TXSTAT_TXERR
) {
2479 mxfep
->mxfe_errxmt
++;
2481 if (status
& TXSTAT_JABBER
) {
2482 /* transmit jabber timeout */
2483 mxfep
->mxfe_macxmt_errors
++;
2485 if (status
& (TXSTAT_CARRLOST
| TXSTAT_NOCARR
)) {
2486 mxfep
->mxfe_carrier_errors
++;
2488 if (status
& TXSTAT_UFLOW
) {
2489 mxfep
->mxfe_underflow
++;
2491 if (status
& TXSTAT_LATECOL
) {
2492 mxfep
->mxfe_tx_late_collisions
++;
2494 if (status
& TXSTAT_EXCOLL
) {
2495 mxfep
->mxfe_ex_collisions
++;
2496 mxfep
->mxfe_collisions
+= 16;
2500 if (status
& TXSTAT_DEFER
) {
2501 mxfep
->mxfe_defer_xmts
++;
2504 /* collision counting */
2505 if (TXCOLLCNT(status
) == 1) {
2506 mxfep
->mxfe_collisions
++;
2507 mxfep
->mxfe_first_collisions
++;
2508 } else if (TXCOLLCNT(status
)) {
2509 mxfep
->mxfe_collisions
+= TXCOLLCNT(status
);
2510 mxfep
->mxfe_multi_collisions
+= TXCOLLCNT(status
);
2514 if (mxfep
->mxfe_txavail
>= MXFE_TXRESCHED
) {
2515 if (mxfep
->mxfe_wantw
) {
2517 * we were able to reclaim some packets, so
2518 * disable tx interrupts
2520 mxfep
->mxfe_wantw
= B_FALSE
;
2521 mxfe_enableinterrupts(mxfep
);
2522 mac_tx_update(mxfep
->mxfe_mh
);
2528 mxfe_receive(mxfe_t
*mxfep
, mblk_t
**rxchain
)
2534 mblk_t
*mpchain
, **mpp
, *mp
;
2536 boolean_t error
= B_FALSE
;
2540 head
= mxfep
->mxfe_rxhead
;
2542 /* limit the number of packets we process to a ring size */
2543 for (cnt
= 0; cnt
< MXFE_RXRING
; cnt
++) {
2545 DBG(DRECV
, "receive at index %d", head
);
2547 rmd
= &mxfep
->mxfe_rxdescp
[head
];
2548 rxb
= mxfep
->mxfe_rxbufs
[head
];
2550 SYNCRXDESC(mxfep
, head
, DDI_DMA_SYNC_FORKERNEL
);
2551 status
= GETRXDESC(mxfep
, rmd
->desc_status
);
2552 if (status
& RXSTAT_OWN
) {
2553 /* chip is still chewing on it */
2557 /* discard the ethernet frame checksum */
2558 len
= RXLENGTH(status
) - ETHERFCSL
;
2560 DBG(DRECV
, "recv length %d, status %x", len
, status
);
2562 if ((status
& (RXSTAT_ERRS
| RXSTAT_FIRST
| RXSTAT_LAST
)) !=
2563 (RXSTAT_FIRST
| RXSTAT_LAST
)) {
2565 mxfep
->mxfe_errrcv
++;
2568 * Abnormal status bits detected, analyze further.
2570 if ((status
& (RXSTAT_LAST
|RXSTAT_FIRST
)) !=
2571 (RXSTAT_LAST
|RXSTAT_FIRST
)) {
2572 /* someone trying to send jumbo frames? */
2573 DBG(DRECV
, "rx packet overspill");
2574 if (status
& RXSTAT_FIRST
) {
2575 mxfep
->mxfe_toolong_errors
++;
2577 } else if (status
& RXSTAT_DESCERR
) {
2578 /* this should never occur! */
2579 mxfep
->mxfe_macrcv_errors
++;
2582 } else if (status
& RXSTAT_RUNT
) {
2585 } else if (status
& RXSTAT_COLLSEEN
) {
2586 /* this should really be rx_late_collisions */
2587 mxfep
->mxfe_macrcv_errors
++;
2589 } else if (status
& RXSTAT_DRIBBLE
) {
2590 mxfep
->mxfe_align_errors
++;
2592 } else if (status
& RXSTAT_CRCERR
) {
2593 mxfep
->mxfe_fcs_errors
++;
2595 } else if (status
& RXSTAT_OFLOW
) {
2596 /* this is a MAC FIFO error, need to reset */
2597 mxfep
->mxfe_overflow
++;
2602 else if (len
> ETHERVLANMTU
) {
2603 mxfep
->mxfe_errrcv
++;
2604 mxfep
->mxfe_toolong_errors
++;
2608 * At this point, the chip thinks the packet is OK.
2611 mp
= allocb(len
+ MXFE_HEADROOM
, 0);
2613 mxfep
->mxfe_errrcv
++;
2614 mxfep
->mxfe_norcvbuf
++;
2618 /* sync the buffer before we look at it */
2619 SYNCRXBUF(rxb
, len
, DDI_DMA_SYNC_FORKERNEL
);
2620 mp
->b_rptr
+= MXFE_HEADROOM
;
2621 mp
->b_wptr
= mp
->b_rptr
+ len
;
2622 bcopy((char *)rxb
->rxb_buf
, mp
->b_rptr
, len
);
2624 mxfep
->mxfe_ipackets
++;
2625 mxfep
->mxfe_rbytes
+= len
;
2626 if (status
& RXSTAT_GROUP
) {
2627 if (bcmp(mp
->b_rptr
, mxfe_broadcast
,
2629 mxfep
->mxfe_brdcstrcv
++;
2631 mxfep
->mxfe_multircv
++;
2638 /* return ring entry to the hardware */
2639 PUTRXDESC(mxfep
, rmd
->desc_status
, RXSTAT_OWN
);
2640 SYNCRXDESC(mxfep
, head
, DDI_DMA_SYNC_FORDEV
);
2642 /* advance to next RMD */
2643 head
= (head
+ 1) % MXFE_RXRING
;
2646 mxfep
->mxfe_rxhead
= head
;
2653 mxfe_m_stat(void *arg
, uint_t stat
, uint64_t *val
)
2655 mxfe_t
*mxfep
= arg
;
2657 mutex_enter(&mxfep
->mxfe_xmtlock
);
2658 if ((mxfep
->mxfe_flags
& (MXFE_RUNNING
|MXFE_SUSPENDED
)) == MXFE_RUNNING
)
2659 mxfe_reclaim(mxfep
);
2660 mutex_exit(&mxfep
->mxfe_xmtlock
);
2663 case MAC_STAT_IFSPEED
:
2664 *val
= mxfep
->mxfe_ifspeed
;
2667 case MAC_STAT_MULTIRCV
:
2668 *val
= mxfep
->mxfe_multircv
;
2671 case MAC_STAT_BRDCSTRCV
:
2672 *val
= mxfep
->mxfe_brdcstrcv
;
2675 case MAC_STAT_MULTIXMT
:
2676 *val
= mxfep
->mxfe_multixmt
;
2679 case MAC_STAT_BRDCSTXMT
:
2680 *val
= mxfep
->mxfe_brdcstxmt
;
2683 case MAC_STAT_IPACKETS
:
2684 *val
= mxfep
->mxfe_ipackets
;
2687 case MAC_STAT_RBYTES
:
2688 *val
= mxfep
->mxfe_rbytes
;
2691 case MAC_STAT_OPACKETS
:
2692 *val
= mxfep
->mxfe_opackets
;
2695 case MAC_STAT_OBYTES
:
2696 *val
= mxfep
->mxfe_obytes
;
2699 case MAC_STAT_NORCVBUF
:
2700 *val
= mxfep
->mxfe_norcvbuf
;
2703 case MAC_STAT_NOXMTBUF
:
2704 *val
= mxfep
->mxfe_noxmtbuf
;
2707 case MAC_STAT_COLLISIONS
:
2708 *val
= mxfep
->mxfe_collisions
;
2711 case MAC_STAT_IERRORS
:
2712 *val
= mxfep
->mxfe_errrcv
;
2715 case MAC_STAT_OERRORS
:
2716 *val
= mxfep
->mxfe_errxmt
;
2719 case ETHER_STAT_LINK_DUPLEX
:
2720 *val
= mxfep
->mxfe_duplex
;
2723 case ETHER_STAT_ALIGN_ERRORS
:
2724 *val
= mxfep
->mxfe_align_errors
;
2727 case ETHER_STAT_FCS_ERRORS
:
2728 *val
= mxfep
->mxfe_fcs_errors
;
2731 case ETHER_STAT_SQE_ERRORS
:
2732 *val
= mxfep
->mxfe_sqe_errors
;
2735 case ETHER_STAT_DEFER_XMTS
:
2736 *val
= mxfep
->mxfe_defer_xmts
;
2739 case ETHER_STAT_FIRST_COLLISIONS
:
2740 *val
= mxfep
->mxfe_first_collisions
;
2743 case ETHER_STAT_MULTI_COLLISIONS
:
2744 *val
= mxfep
->mxfe_multi_collisions
;
2747 case ETHER_STAT_TX_LATE_COLLISIONS
:
2748 *val
= mxfep
->mxfe_tx_late_collisions
;
2751 case ETHER_STAT_EX_COLLISIONS
:
2752 *val
= mxfep
->mxfe_ex_collisions
;
2755 case ETHER_STAT_MACXMT_ERRORS
:
2756 *val
= mxfep
->mxfe_macxmt_errors
;
2759 case ETHER_STAT_CARRIER_ERRORS
:
2760 *val
= mxfep
->mxfe_carrier_errors
;
2763 case ETHER_STAT_TOOLONG_ERRORS
:
2764 *val
= mxfep
->mxfe_toolong_errors
;
2767 case ETHER_STAT_MACRCV_ERRORS
:
2768 *val
= mxfep
->mxfe_macrcv_errors
;
2771 case MAC_STAT_OVERFLOWS
:
2772 *val
= mxfep
->mxfe_overflow
;
2775 case MAC_STAT_UNDERFLOWS
:
2776 *val
= mxfep
->mxfe_underflow
;
2779 case ETHER_STAT_TOOSHORT_ERRORS
:
2780 *val
= mxfep
->mxfe_runt
;
2783 case ETHER_STAT_JABBER_ERRORS
:
2784 *val
= mxfep
->mxfe_jabber
;
2787 case ETHER_STAT_ADV_CAP_100T4
:
2788 *val
= mxfep
->mxfe_adv_100T4
;
2791 case ETHER_STAT_LP_CAP_100T4
:
2792 *val
= (mxfep
->mxfe_anlpar
& MII_ABILITY_100BASE_T4
) ? 1 : 0;
2795 case ETHER_STAT_CAP_100T4
:
2796 *val
= mxfep
->mxfe_cap_100T4
;
2799 case ETHER_STAT_CAP_100FDX
:
2800 *val
= mxfep
->mxfe_cap_100fdx
;
2803 case ETHER_STAT_CAP_100HDX
:
2804 *val
= mxfep
->mxfe_cap_100hdx
;
2807 case ETHER_STAT_CAP_10FDX
:
2808 *val
= mxfep
->mxfe_cap_10fdx
;
2811 case ETHER_STAT_CAP_10HDX
:
2812 *val
= mxfep
->mxfe_cap_10hdx
;
2815 case ETHER_STAT_CAP_AUTONEG
:
2816 *val
= mxfep
->mxfe_cap_aneg
;
2819 case ETHER_STAT_LINK_AUTONEG
:
2820 *val
= ((mxfep
->mxfe_adv_aneg
!= 0) &&
2821 ((mxfep
->mxfe_aner
& MII_AN_EXP_LPCANAN
) != 0));
2824 case ETHER_STAT_ADV_CAP_100FDX
:
2825 *val
= mxfep
->mxfe_adv_100fdx
;
2828 case ETHER_STAT_ADV_CAP_100HDX
:
2829 *val
= mxfep
->mxfe_adv_100hdx
;
2832 case ETHER_STAT_ADV_CAP_10FDX
:
2833 *val
= mxfep
->mxfe_adv_10fdx
;
2836 case ETHER_STAT_ADV_CAP_10HDX
:
2837 *val
= mxfep
->mxfe_adv_10hdx
;
2840 case ETHER_STAT_ADV_CAP_AUTONEG
:
2841 *val
= mxfep
->mxfe_adv_aneg
;
2844 case ETHER_STAT_LP_CAP_100FDX
:
2845 *val
= (mxfep
->mxfe_anlpar
& MII_ABILITY_100BASE_TX_FD
) ? 1 : 0;
2848 case ETHER_STAT_LP_CAP_100HDX
:
2849 *val
= (mxfep
->mxfe_anlpar
& MII_ABILITY_100BASE_TX
) ? 1 : 0;
2852 case ETHER_STAT_LP_CAP_10FDX
:
2853 *val
= (mxfep
->mxfe_anlpar
& MII_ABILITY_10BASE_T_FD
) ? 1 : 0;
2856 case ETHER_STAT_LP_CAP_10HDX
:
2857 *val
= (mxfep
->mxfe_anlpar
& MII_ABILITY_10BASE_T
) ? 1 : 0;
2860 case ETHER_STAT_LP_CAP_AUTONEG
:
2861 *val
= (mxfep
->mxfe_aner
& MII_AN_EXP_LPCANAN
) ? 1 : 0;
2864 case ETHER_STAT_XCVR_ADDR
:
2865 *val
= mxfep
->mxfe_phyaddr
;
2868 case ETHER_STAT_XCVR_ID
:
2869 *val
= mxfep
->mxfe_phyid
;
2872 case ETHER_STAT_XCVR_INUSE
:
2873 *val
= mxfep
->mxfe_phyinuse
;
2884 mxfe_m_getprop(void *arg
, const char *name
, mac_prop_id_t num
, uint_t sz
,
2887 mxfe_t
*mxfep
= arg
;
2891 case MAC_PROP_DUPLEX
:
2892 ASSERT(sz
>= sizeof (link_duplex_t
));
2893 bcopy(&mxfep
->mxfe_duplex
, val
, sizeof (link_duplex_t
));
2896 case MAC_PROP_SPEED
:
2897 ASSERT(sz
>= sizeof (uint64_t));
2898 bcopy(&mxfep
->mxfe_ifspeed
, val
, sizeof (uint64_t));
2901 case MAC_PROP_AUTONEG
:
2902 *(uint8_t *)val
= mxfep
->mxfe_adv_aneg
;
2905 case MAC_PROP_ADV_100FDX_CAP
:
2906 case MAC_PROP_EN_100FDX_CAP
:
2907 *(uint8_t *)val
= mxfep
->mxfe_adv_100fdx
;
2910 case MAC_PROP_ADV_100HDX_CAP
:
2911 case MAC_PROP_EN_100HDX_CAP
:
2912 *(uint8_t *)val
= mxfep
->mxfe_adv_100hdx
;
2915 case MAC_PROP_ADV_10FDX_CAP
:
2916 case MAC_PROP_EN_10FDX_CAP
:
2917 *(uint8_t *)val
= mxfep
->mxfe_adv_10fdx
;
2920 case MAC_PROP_ADV_10HDX_CAP
:
2921 case MAC_PROP_EN_10HDX_CAP
:
2922 *(uint8_t *)val
= mxfep
->mxfe_adv_10hdx
;
2925 case MAC_PROP_ADV_100T4_CAP
:
2926 case MAC_PROP_EN_100T4_CAP
:
2927 *(uint8_t *)val
= mxfep
->mxfe_adv_100T4
;
2939 mxfe_m_setprop(void *arg
, const char *name
, mac_prop_id_t num
, uint_t sz
,
2942 mxfe_t
*mxfep
= arg
;
2947 case MAC_PROP_EN_100FDX_CAP
:
2948 advp
= &mxfep
->mxfe_adv_100fdx
;
2949 capp
= &mxfep
->mxfe_cap_100fdx
;
2952 case MAC_PROP_EN_100HDX_CAP
:
2953 advp
= &mxfep
->mxfe_adv_100hdx
;
2954 capp
= &mxfep
->mxfe_cap_100hdx
;
2957 case MAC_PROP_EN_10FDX_CAP
:
2958 advp
= &mxfep
->mxfe_adv_10fdx
;
2959 capp
= &mxfep
->mxfe_cap_10fdx
;
2962 case MAC_PROP_EN_10HDX_CAP
:
2963 advp
= &mxfep
->mxfe_adv_10hdx
;
2964 capp
= &mxfep
->mxfe_cap_10hdx
;
2967 case MAC_PROP_EN_100T4_CAP
:
2968 advp
= &mxfep
->mxfe_adv_100T4
;
2969 capp
= &mxfep
->mxfe_cap_100T4
;
2972 case MAC_PROP_AUTONEG
:
2973 advp
= &mxfep
->mxfe_adv_aneg
;
2974 capp
= &mxfep
->mxfe_cap_aneg
;
2981 if (*capp
== 0) /* ensure phy can support value */
2984 mutex_enter(&mxfep
->mxfe_intrlock
);
2985 mutex_enter(&mxfep
->mxfe_xmtlock
);
2987 if (*advp
!= *(const uint8_t *)val
) {
2988 *advp
= *(const uint8_t *)val
;
2990 if ((mxfep
->mxfe_flags
& (MXFE_RUNNING
|MXFE_SUSPENDED
)) ==
2993 * This re-initializes the phy, but it also
2994 * restarts transmit and receive rings.
2995 * Needless to say, changing the link
2996 * parameters is destructive to traffic in
2999 mxfe_resetall(mxfep
);
3002 mutex_exit(&mxfep
->mxfe_xmtlock
);
3003 mutex_exit(&mxfep
->mxfe_intrlock
);
3009 mxfe_m_propinfo(void *arg
, const char *name
, mac_prop_id_t num
,
3010 mac_prop_info_handle_t mph
)
3012 mxfe_t
*mxfep
= arg
;
3014 _NOTE(ARGUNUSED(name
));
3017 case MAC_PROP_DUPLEX
:
3018 case MAC_PROP_SPEED
:
3019 case MAC_PROP_ADV_100FDX_CAP
:
3020 case MAC_PROP_ADV_100HDX_CAP
:
3021 case MAC_PROP_ADV_10FDX_CAP
:
3022 case MAC_PROP_ADV_10HDX_CAP
:
3023 case MAC_PROP_ADV_100T4_CAP
:
3024 mac_prop_info_set_perm(mph
, MAC_PROP_PERM_READ
);
3027 case MAC_PROP_AUTONEG
:
3028 mac_prop_info_set_default_uint8(mph
, mxfep
->mxfe_cap_aneg
);
3031 case MAC_PROP_EN_100FDX_CAP
:
3032 mac_prop_info_set_default_uint8(mph
, mxfep
->mxfe_cap_100fdx
);
3035 case MAC_PROP_EN_100HDX_CAP
:
3036 mac_prop_info_set_default_uint8(mph
, mxfep
->mxfe_cap_100hdx
);
3039 case MAC_PROP_EN_10FDX_CAP
:
3040 mac_prop_info_set_default_uint8(mph
, mxfep
->mxfe_cap_10fdx
);
3043 case MAC_PROP_EN_10HDX_CAP
:
3044 mac_prop_info_set_default_uint8(mph
, mxfep
->mxfe_cap_10hdx
);
3047 case MAC_PROP_EN_100T4_CAP
:
3048 mac_prop_info_set_default_uint8(mph
, mxfep
->mxfe_cap_100T4
);
3054 * Debugging and error reporting.
3057 mxfe_error(dev_info_t
*dip
, char *fmt
, ...)
3063 (void) vsnprintf(buf
, sizeof (buf
), fmt
, ap
);
3067 cmn_err(CE_WARN
, "%s%d: %s",
3068 ddi_driver_name(dip
), ddi_get_instance(dip
), buf
);
3070 cmn_err(CE_WARN
, "mxfe: %s", buf
);
3077 mxfe_dprintf(mxfe_t
*mxfep
, const char *func
, int level
, char *fmt
, ...)
3082 if (mxfe_debug
& level
) {
3086 if (mxfep
&& mxfep
->mxfe_dip
) {
3087 (void) snprintf(tag
, sizeof (tag
),
3088 "%s%d", ddi_driver_name(mxfep
->mxfe_dip
),
3089 ddi_get_instance(mxfep
->mxfe_dip
));
3091 (void) snprintf(tag
, sizeof (tag
), "mxfe");
3094 (void) snprintf(buf
, sizeof (buf
), "%s: %s: %s\n", tag
,
3097 vcmn_err(CE_CONT
, buf
, ap
);