1 /*
2 * Solaris driver for ethernet cards based on the Macronix 98715
3 *
4 * Copyright (c) 2007 by Garrett D'Amore <garrett@damore.org>.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
18 *
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.
30 */
31 /*
32 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
33 * Use is subject to license terms.
34 */
35
36
37 #include <sys/varargs.h>
38 #include <sys/types.h>
39 #include <sys/modctl.h>
40 #include <sys/conf.h>
41 #include <sys/devops.h>
42 #include <sys/stream.h>
43 #include <sys/strsun.h>
44 #include <sys/cmn_err.h>
45 #include <sys/dlpi.h>
46 #include <sys/ethernet.h>
47 #include <sys/kmem.h>
48 #include <sys/time.h>
49 #include <sys/miiregs.h>
50 #include <sys/strsun.h>
51 #include <sys/mac.h>
52 #include <sys/mac_ether.h>
53 #include <sys/ddi.h>
54 #include <sys/sunddi.h>
55 #include <sys/vlan.h>
56
57 #include "mxfe.h"
58 #include "mxfeimpl.h"
59
60 /*
61 * Driver globals.
62 */
63
64 /* patchable debug flag ... must not be static! */
65 #ifdef DEBUG
66 unsigned mxfe_debug = DWARN;
67 #endif
68
69 /* table of supported devices */
70 static mxfe_card_t mxfe_cards[] = {
71
72 /*
73 * Lite-On products
74 */
75 { 0x11ad, 0xc115, 0, 0, "Lite-On LC82C115", MXFE_PNICII },
76
77 /*
78 * Macronix chips
79 */
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 },
86
87 /*
88 * Compex (relabeled Macronix products)
89 */
90 { 0x11fc, 0x9881, 0x00, 0x00, "Compex 9881", MXFE_98713 },
91 { 0x11fc, 0x9881, 0x10, 0xff, "Compex 9881A", MXFE_98713A },
92 /*
93 * Models listed here
94 */
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 },
98 };
99
100 #define ETHERVLANMTU (ETHERMAX + 4)
101
102 /*
103 * Function prototypes
104 */
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,
117 void *);
118 static int mxfe_m_setprop(void *, const char *, mac_prop_id_t, uint_t,
119 const void *);
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 **);
167
168 #ifdef DEBUG
169 static void mxfe_dprintf(mxfe_t *, const char *, int, char *, ...);
170 #endif
171
172 #define KIOIP KSTAT_INTR_PTR(mxfep->mxfe_intrstat)
173
174 static mac_callbacks_t mxfe_m_callbacks = {
175 MC_SETPROP | MC_GETPROP | MC_PROPINFO,
176 mxfe_m_stat,
177 mxfe_m_start,
178 mxfe_m_stop,
179 mxfe_m_promisc,
180 mxfe_m_multicst,
181 mxfe_m_unicst,
182 mxfe_m_tx,
183 NULL,
184 NULL, /* mc_ioctl */
185 NULL, /* mc_getcapab */
186 NULL, /* mc_open */
187 NULL, /* mc_close */
188 mxfe_m_setprop,
189 mxfe_m_getprop,
190 mxfe_m_propinfo
191 };
192
193 /*
194 * Stream information
195 */
196 DDI_DEFINE_STREAM_OPS(mxfe_devops, nulldev, nulldev, mxfe_attach, mxfe_detach,
197 nodev, NULL, D_MP, NULL, mxfe_quiesce);
198
199 /*
200 * Module linkage information.
201 */
202
203 static struct modldrv mxfe_modldrv = {
204 &mod_driverops, /* drv_modops */
205 "Macronix Fast Ethernet", /* drv_linkinfo */
206 &mxfe_devops /* drv_dev_ops */
207 };
208
209 static struct modlinkage mxfe_modlinkage = {
210 MODREV_1, /* ml_rev */
211 { &mxfe_modldrv, NULL } /* ml_linkage */
212 };
213
214 /*
215 * Device attributes.
216 */
217 static ddi_device_acc_attr_t mxfe_devattr = {
218 DDI_DEVICE_ATTR_V0,
219 DDI_STRUCTURE_LE_ACC,
220 DDI_STRICTORDER_ACC
221 };
222
223 static ddi_device_acc_attr_t mxfe_bufattr = {
224 DDI_DEVICE_ATTR_V0,
225 DDI_NEVERSWAP_ACC,
226 DDI_STRICTORDER_ACC
227 };
228
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 */
242 };
243
244 /*
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.
248 */
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 */
262 };
263
264 /*
265 * Ethernet addresses.
266 */
267 static uchar_t mxfe_broadcast[ETHERADDRL] = {
268 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
269 };
270
271 /*
272 * DDI entry points.
273 */
274 int
_init(void)275 _init(void)
276 {
277 int rv;
278 mac_init_ops(&mxfe_devops, "mxfe");
279 if ((rv = mod_install(&mxfe_modlinkage)) != DDI_SUCCESS) {
280 mac_fini_ops(&mxfe_devops);
281 }
282 return (rv);
283 }
284
285 int
_fini(void)286 _fini(void)
287 {
288 int rv;
289 if ((rv = mod_remove(&mxfe_modlinkage)) == DDI_SUCCESS) {
290 mac_fini_ops(&mxfe_devops);
291 }
292 return (rv);
293 }
294
295 int
_info(struct modinfo * modinfop)296 _info(struct modinfo *modinfop)
297 {
298 return (mod_info(&mxfe_modlinkage, modinfop));
299 }
300
301 int
mxfe_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)302 mxfe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
303 {
304 mxfe_t *mxfep;
305 mac_register_t *macp;
306 int inst = ddi_get_instance(dip);
307 ddi_acc_handle_t pci;
308 uint16_t venid;
309 uint16_t devid;
310 uint16_t revid;
311 uint16_t svid;
312 uint16_t ssid;
313 uint16_t cachesize;
314 mxfe_card_t *cardp;
315 int i;
316
317 switch (cmd) {
318 case DDI_RESUME:
319 return (mxfe_resume(dip));
320
321 case DDI_ATTACH:
322 break;
323
324 default:
325 return (DDI_FAILURE);
326 }
327
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);
332 }
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);
337 }
338 if (pci_config_setup(dip, &pci) != DDI_SUCCESS) {
339 mxfe_error(dip, "unable to setup PCI config handle");
340 return (DDI_FAILURE);
341 }
342
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);
348
349 /*
350 * the last entry in the card table matches every possible
351 * card, so the for-loop always terminates properly.
352 */
353 cardp = NULL;
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];
360 }
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];
366 break;
367 }
368 }
369
370 if (cardp == NULL) {
371 pci_config_teardown(&pci);
372 mxfe_error(dip, "Unable to identify PCI card");
373 return (DDI_FAILURE);
374 }
375
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);
381 }
382
383 /*
384 * Grab the PCI cachesize -- we use this to program the
385 * cache-optimization bus access bits.
386 */
387 cachesize = pci_config_get8(pci, PCI_CLS);
388
389 /* this cannot fail */
390 mxfep = kmem_zalloc(sizeof (mxfe_t), KM_SLEEP);
391 ddi_set_driver_private(dip, mxfep);
392
393 /* get the interrupt block cookie */
394 if (ddi_get_iblock_cookie(dip, 0, &mxfep->mxfe_icookie)
395 != DDI_SUCCESS) {
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);
400 }
401
402 mxfep->mxfe_dip = dip;
403 mxfep->mxfe_cardp = cardp;
404 mxfep->mxfe_phyaddr = -1;
405 mxfep->mxfe_cachesize = cachesize;
406
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,
411 "adv_100T4_cap", 1);
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,
417 "adv_10fdx_cap", 1);
418 mxfep->mxfe_adv_10hdx = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
419 "adv_10hdx_cap", 1);
420
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));
427
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);
432
433 /*
434 * Enable bus master, IO space, and memory space accesses.
435 */
436 pci_config_put16(pci, PCI_CMD,
437 pci_config_get16(pci, PCI_CMD) |
438 PCI_CMD_BME | PCI_CMD_MAE | PCI_CMD_MWIE);
439
440 /* we're done with this now, drop it */
441 pci_config_teardown(&pci);
442
443 /*
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.
447 */
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");
452 goto failed;
453 }
454 kstat_install(mxfep->mxfe_intrstat);
455
456 /*
457 * Map in the device registers.
458 */
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");
462 goto failed;
463 }
464
465 /*
466 * Allocate DMA resources (descriptor rings and buffers).
467 */
468 if ((mxfe_allocrxring(mxfep) != DDI_SUCCESS) ||
469 (mxfe_alloctxring(mxfep) != DDI_SUCCESS)) {
470 mxfe_error(dip, "unable to allocate DMA resources");
471 goto failed;
472 }
473
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);
480 goto failed;
481 }
482 mutex_exit(&mxfep->mxfe_xmtlock);
483 mutex_exit(&mxfep->mxfe_intrlock);
484
485 /* Determine the number of address bits to our EEPROM. */
486 mxfep->mxfe_sromwidth = mxfe_sromwidth(mxfep);
487
488 /*
489 * Get the factory ethernet address. This becomes the current
490 * ethernet address (it can be overridden later via ifconfig).
491 */
492 mxfe_getfactaddr(mxfep, mxfep->mxfe_curraddr);
493 mxfep->mxfe_promisc = B_FALSE;
494
495 /*
496 * Establish interrupt handler.
497 */
498 if (ddi_add_intr(dip, 0, NULL, NULL, mxfe_intr, (caddr_t)mxfep) !=
499 DDI_SUCCESS) {
500 mxfe_error(dip, "unable to add interrupt");
501 goto failed;
502 }
503
504 /* TODO: do the power management stuff */
505
506 if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
507 mxfe_error(dip, "mac_alloc failed");
508 goto failed;
509 }
510
511 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
512 macp->m_driver = mxfep;
513 macp->m_dip = dip;
514 macp->m_src_addr = mxfep->mxfe_curraddr;
515 macp->m_callbacks = &mxfe_m_callbacks;
516 macp->m_min_sdu = 0;
517 macp->m_max_sdu = ETHERMTU;
518 macp->m_margin = VLAN_TAGSZ;
519
520 if (mac_register(macp, &mxfep->mxfe_mh) == DDI_SUCCESS) {
521 mac_free(macp);
522 return (DDI_SUCCESS);
523 }
524
525 /* failed to register with MAC */
526 mac_free(macp);
527 failed:
528 if (mxfep->mxfe_icookie != NULL) {
529 ddi_remove_intr(dip, 0, mxfep->mxfe_icookie);
530 }
531 if (mxfep->mxfe_intrstat) {
532 kstat_delete(mxfep->mxfe_intrstat);
533 }
534 mutex_destroy(&mxfep->mxfe_intrlock);
535 mutex_destroy(&mxfep->mxfe_xmtlock);
536
537 mxfe_freerxring(mxfep);
538 mxfe_freetxring(mxfep);
539
540 if (mxfep->mxfe_regshandle != NULL) {
541 ddi_regs_map_free(&mxfep->mxfe_regshandle);
542 }
543 kmem_free(mxfep, sizeof (mxfe_t));
544 return (DDI_FAILURE);
545 }
546
547 int
mxfe_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)548 mxfe_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
549 {
550 mxfe_t *mxfep;
551
552 mxfep = ddi_get_driver_private(dip);
553 if (mxfep == NULL) {
554 mxfe_error(dip, "no soft state in detach!");
555 return (DDI_FAILURE);
556 }
557
558 switch (cmd) {
559 case DDI_DETACH:
560
561 if (mac_unregister(mxfep->mxfe_mh) != 0) {
562 return (DDI_FAILURE);
563 }
564
565 /* make sure hardware is quiesced */
566 mutex_enter(&mxfep->mxfe_intrlock);
567 mutex_enter(&mxfep->mxfe_xmtlock);
568 mxfep->mxfe_flags &= ~MXFE_RUNNING;
569 mxfe_stopall(mxfep);
570 mutex_exit(&mxfep->mxfe_xmtlock);
571 mutex_exit(&mxfep->mxfe_intrlock);
572
573 /* clean up and shut down device */
574 ddi_remove_intr(dip, 0, mxfep->mxfe_icookie);
575
576 /* clean up kstats */
577 kstat_delete(mxfep->mxfe_intrstat);
578
579 ddi_prop_remove_all(dip);
580
581 /* free up any left over buffers or DMA resources */
582 mxfe_freerxring(mxfep);
583 mxfe_freetxring(mxfep);
584
585 ddi_regs_map_free(&mxfep->mxfe_regshandle);
586 mutex_destroy(&mxfep->mxfe_intrlock);
587 mutex_destroy(&mxfep->mxfe_xmtlock);
588
589 kmem_free(mxfep, sizeof (mxfe_t));
590 return (DDI_SUCCESS);
591
592 case DDI_SUSPEND:
593 /* quiesce the hardware */
594 mutex_enter(&mxfep->mxfe_intrlock);
595 mutex_enter(&mxfep->mxfe_xmtlock);
596 mxfep->mxfe_flags |= MXFE_SUSPENDED;
597 mxfe_stopall(mxfep);
598 mutex_exit(&mxfep->mxfe_xmtlock);
599 mutex_exit(&mxfep->mxfe_intrlock);
600 return (DDI_SUCCESS);
601 default:
602 return (DDI_FAILURE);
603 }
604 }
605
606 int
mxfe_resume(dev_info_t * dip)607 mxfe_resume(dev_info_t *dip)
608 {
609 mxfe_t *mxfep;
610
611 if ((mxfep = ddi_get_driver_private(dip)) == NULL) {
612 return (DDI_FAILURE);
613 }
614
615 mutex_enter(&mxfep->mxfe_intrlock);
616 mutex_enter(&mxfep->mxfe_xmtlock);
617
618 mxfep->mxfe_flags &= ~MXFE_SUSPENDED;
619
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);
627 }
628
629 /* start the chip */
630 if (mxfep->mxfe_flags & MXFE_RUNNING) {
631 mxfe_startall(mxfep);
632 }
633
634 /* drop locks */
635 mutex_exit(&mxfep->mxfe_xmtlock);
636 mutex_exit(&mxfep->mxfe_intrlock);
637
638 return (DDI_SUCCESS);
639 }
640
641 int
mxfe_quiesce(dev_info_t * dip)642 mxfe_quiesce(dev_info_t *dip)
643 {
644 mxfe_t *mxfep;
645
646 if ((mxfep = ddi_get_driver_private(dip)) == NULL) {
647 return (DDI_FAILURE);
648 }
649
650 /* just do a hard reset of everything */
651 SETBIT(mxfep, CSR_PAR, PAR_RESET);
652
653 return (DDI_SUCCESS);
654 }
655
656 /*ARGSUSED*/
657 int
mxfe_m_multicst(void * arg,boolean_t add,const uint8_t * macaddr)658 mxfe_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr)
659 {
660 /* we already receive all multicast frames */
661 return (0);
662 }
663
664 int
mxfe_m_promisc(void * arg,boolean_t on)665 mxfe_m_promisc(void *arg, boolean_t on)
666 {
667 mxfe_t *mxfep = arg;
668
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;
674
675 if ((mxfep->mxfe_flags & (MXFE_RUNNING|MXFE_SUSPENDED)) ==
676 MXFE_RUNNING) {
677 if (on)
678 SETBIT(mxfep, CSR_NAR, NAR_RX_PROMISC);
679 else
680 CLRBIT(mxfep, CSR_NAR, NAR_RX_PROMISC);
681 }
682
683 mutex_exit(&mxfep->mxfe_xmtlock);
684 mutex_exit(&mxfep->mxfe_intrlock);
685
686 return (0);
687 }
688
689 int
mxfe_m_unicst(void * arg,const uint8_t * macaddr)690 mxfe_m_unicst(void *arg, const uint8_t *macaddr)
691 {
692 mxfe_t *mxfep = arg;
693
694 mutex_enter(&mxfep->mxfe_intrlock);
695 mutex_enter(&mxfep->mxfe_xmtlock);
696 bcopy(macaddr, mxfep->mxfe_curraddr, ETHERADDRL);
697
698 mxfe_resetall(mxfep);
699
700 mutex_exit(&mxfep->mxfe_intrlock);
701 mutex_exit(&mxfep->mxfe_xmtlock);
702
703 return (0);
704 }
705
706 mblk_t *
mxfe_m_tx(void * arg,mblk_t * mp)707 mxfe_m_tx(void *arg, mblk_t *mp)
708 {
709 mxfe_t *mxfep = arg;
710 mblk_t *nmp;
711
712 mutex_enter(&mxfep->mxfe_xmtlock);
713
714 if (mxfep->mxfe_flags & MXFE_SUSPENDED) {
715 mutex_exit(&mxfep->mxfe_xmtlock);
716 return (mp);
717 }
718
719 while (mp != NULL) {
720 nmp = mp->b_next;
721 mp->b_next = NULL;
722
723 if (!mxfe_send(mxfep, mp)) {
724 mp->b_next = nmp;
725 break;
726 }
727 mp = nmp;
728 }
729 mutex_exit(&mxfep->mxfe_xmtlock);
730
731 return (mp);
732 }
733
734 /*
735 * Hardware management.
736 */
737 boolean_t
mxfe_initialize(mxfe_t * mxfep)738 mxfe_initialize(mxfe_t *mxfep)
739 {
740 int i;
741 unsigned val;
742 uint32_t par, nar;
743
744 ASSERT(mutex_owned(&mxfep->mxfe_intrlock));
745 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock));
746
747 DBG(DCHATTY, "resetting!");
748 SETBIT(mxfep, CSR_PAR, PAR_RESET);
749 for (i = 1; i < 10; i++) {
750 drv_usecwait(5);
751 val = GETCSR(mxfep, CSR_PAR);
752 if (!(val & PAR_RESET)) {
753 break;
754 }
755 }
756 if (i == 10) {
757 mxfe_error(mxfep->mxfe_dip, "timed out waiting for reset!");
758 return (B_FALSE);
759 }
760
761 /* initialize busctl register */
762 par = PAR_BAR | PAR_MRME | PAR_MRLE | PAR_MWIE;
763
764 /* set the cache alignment if its supported */
765 switch (mxfep->mxfe_cachesize) {
766 case 8:
767 par |= PAR_CALIGN_8;
768 break;
769 case 16:
770 par |= PAR_CALIGN_16;
771 break;
772 case 32:
773 par |= PAR_CALIGN_32;
774 break;
775 default:
776 par &= ~(PAR_MWIE | PAR_MRME | PAR_MRLE);
777 }
778
779 /* leave the burst length at zero, indicating infinite burst */
780 PUTCSR(mxfep, CSR_PAR, par);
781
782 mxfe_resetrings(mxfep);
783
784 /* clear the lost packet counter (cleared on read) */
785 (void) GETCSR(mxfep, CSR_LPC);
786
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 */
793
794 if (mxfep->mxfe_promisc) {
795 nar |= NAR_RX_PROMISC;
796 } else {
797 nar &= ~NAR_RX_PROMISC;
798 }
799 PUTCSR(mxfep, CSR_NAR, nar);
800
801 mxfe_send_setup(mxfep);
802
803 return (B_TRUE);
804 }
805
806 /*
807 * Serial EEPROM access - inspired by the FreeBSD implementation.
808 */
809
810 uint8_t
mxfe_sromwidth(mxfe_t * mxfep)811 mxfe_sromwidth(mxfe_t *mxfep)
812 {
813 int i;
814 int eeread;
815 uint8_t addrlen = 8;
816
817 eeread = SPR_SROM_READ | SPR_SROM_SEL | SPR_SROM_CHIP;
818
819 PUTCSR(mxfep, CSR_SPR, eeread & ~SPR_SROM_CHIP);
820 drv_usecwait(1);
821 PUTCSR(mxfep, CSR_SPR, eeread);
822
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);
827 drv_usecwait(1);
828 PUTCSR(mxfep, CSR_SPR, eeread | val | SPR_SROM_CLOCK);
829 drv_usecwait(1);
830 }
831
832 PUTCSR(mxfep, CSR_SPR, eeread);
833
834 for (addrlen = 1; addrlen <= 12; addrlen++) {
835 PUTCSR(mxfep, CSR_SPR, eeread | SPR_SROM_CLOCK);
836 drv_usecwait(1);
837 if (!(GETCSR(mxfep, CSR_SPR) & SPR_SROM_DOUT)) {
838 PUTCSR(mxfep, CSR_SPR, eeread);
839 drv_usecwait(1);
840 break;
841 }
842 PUTCSR(mxfep, CSR_SPR, eeread);
843 drv_usecwait(1);
844 }
845
846 /* turn off accesses to the EEPROM */
847 PUTCSR(mxfep, CSR_SPR, eeread &~ SPR_SROM_CHIP);
848
849 DBG(DSROM, "detected srom width = %d bits", addrlen);
850
851 return ((addrlen < 4 || addrlen > 12) ? 6 : addrlen);
852 }
853
854 /*
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.
858 */
859 uint16_t
mxfe_readsromword(mxfe_t * mxfep,unsigned romaddr)860 mxfe_readsromword(mxfe_t *mxfep, unsigned romaddr)
861 {
862 int i;
863 uint16_t word = 0;
864 uint16_t retval;
865 int eeread;
866 uint8_t addrlen;
867 int readcmd;
868 uchar_t *ptr;
869
870 eeread = SPR_SROM_READ | SPR_SROM_SEL | SPR_SROM_CHIP;
871 addrlen = mxfep->mxfe_sromwidth;
872 readcmd = (SROM_READCMD << addrlen) | romaddr;
873
874 if (romaddr >= (1 << addrlen)) {
875 /* too big to fit! */
876 return (0);
877 }
878
879 PUTCSR(mxfep, CSR_SPR, eeread & ~SPR_SROM_CHIP);
880 PUTCSR(mxfep, CSR_SPR, eeread);
881
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);
886 drv_usecwait(1);
887 PUTCSR(mxfep, CSR_SPR, eeread | val | SPR_SROM_CLOCK);
888 drv_usecwait(1);
889 }
890
891 PUTCSR(mxfep, CSR_SPR, eeread);
892
893 for (i = 0; i < 16; i++) {
894 PUTCSR(mxfep, CSR_SPR, eeread | SPR_SROM_CLOCK);
895 drv_usecwait(1);
896 word <<= 1;
897 if (GETCSR(mxfep, CSR_SPR) & SPR_SROM_DOUT) {
898 word |= 1;
899 }
900 PUTCSR(mxfep, CSR_SPR, eeread);
901 drv_usecwait(1);
902 }
903
904 /* turn off accesses to the EEPROM */
905 PUTCSR(mxfep, CSR_SPR, eeread &~ SPR_SROM_CHIP);
906
907 /*
908 * Fix up the endianness thing. Note that the values
909 * are stored in little endian format on the SROM.
910 */
911 DBG(DSROM, "got value %d from SROM (before swap)", word);
912 ptr = (uchar_t *)&word;
913 retval = (ptr[1] << 8) | ptr[0];
914 return (retval);
915 }
916
917 void
mxfe_readsrom(mxfe_t * mxfep,unsigned romaddr,unsigned len,void * dest)918 mxfe_readsrom(mxfe_t *mxfep, unsigned romaddr, unsigned len, void *dest)
919 {
920 char *ptr = dest;
921 int i;
922 uint16_t word;
923
924 for (i = 0; i < len; i++) {
925 word = mxfe_readsromword(mxfep, romaddr + i);
926 bcopy(&word, ptr, 2);
927 ptr += 2;
928 DBG(DSROM, "word at %d is 0x%x", romaddr + i, word);
929 }
930 }
931
932 void
mxfe_getfactaddr(mxfe_t * mxfep,uchar_t * eaddr)933 mxfe_getfactaddr(mxfe_t *mxfep, uchar_t *eaddr)
934 {
935 uint16_t word;
936 uchar_t *ptr;
937
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];
942
943 /* then read the actual mac address */
944 mxfe_readsrom(mxfep, word / 2, ETHERADDRL / 2, eaddr);
945 DBG(DMACID,
946 "factory ethernet address = %02x:%02x:%02x:%02x:%02x:%02x",
947 eaddr[0], eaddr[1], eaddr[2], eaddr[3], eaddr[4], eaddr[5]);
948 }
949
950 void
mxfe_startphy(mxfe_t * mxfep)951 mxfe_startphy(mxfe_t *mxfep)
952 {
953 switch (MXFE_MODEL(mxfep)) {
954 case MXFE_98713A:
955 mxfe_startphymii(mxfep);
956 break;
957 default:
958 mxfe_startphynway(mxfep);
959 break;
960 }
961 }
962
963 void
mxfe_stopphy(mxfe_t * mxfep)964 mxfe_stopphy(mxfe_t *mxfep)
965 {
966 uint32_t nar;
967 int i;
968
969 /* stop the phy timer */
970 PUTCSR(mxfep, CSR_TIMER, 0);
971
972 switch (MXFE_MODEL(mxfep)) {
973 case MXFE_98713A:
974 for (i = 0; i < 32; i++) {
975 mxfe_miiwrite(mxfep, mxfep->mxfe_phyaddr, MII_CONTROL,
976 MII_CONTROL_PWRDN | MII_CONTROL_ISOLATE);
977 }
978 break;
979 default:
980 DBG(DPHY, "resetting SIA");
981 PUTCSR(mxfep, CSR_SIA, SIA_RESET);
982 drv_usecwait(500);
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);
986 nar |= NAR_SPEED;
987 PUTCSR(mxfep, CSR_NAR, nar);
988 break;
989 }
990
991 /*
992 * mark the link state unknown
993 */
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);
1000 }
1001 }
1002
1003 /*
1004 * NWay support.
1005 */
1006 void
mxfe_startnway(mxfe_t * mxfep)1007 mxfe_startnway(mxfe_t *mxfep)
1008 {
1009 unsigned nar;
1010 unsigned tctl;
1011 unsigned restart;
1012
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);
1017 return;
1018 }
1019
1020 if (mxfep->mxfe_adv_aneg == 0) {
1021 /* not done for forced mode */
1022 return;
1023 }
1024
1025 nar = GETCSR(mxfep, CSR_NAR);
1026 restart = nar & (NAR_TX_ENABLE | NAR_RX_ENABLE);
1027 nar &= ~restart;
1028
1029 if (restart != 0)
1030 mxfe_stopmac(mxfep);
1031
1032 nar |= NAR_SCR | NAR_PCS | NAR_HBD;
1033 nar &= ~(NAR_FDX);
1034
1035 tctl = GETCSR(mxfep, CSR_TCTL);
1036 tctl &= ~(TCTL_100FDX | TCTL_100HDX | TCTL_HDX);
1037
1038 if (mxfep->mxfe_adv_100fdx) {
1039 tctl |= TCTL_100FDX;
1040 }
1041 if (mxfep->mxfe_adv_100hdx) {
1042 tctl |= TCTL_100HDX;
1043 }
1044 if (mxfep->mxfe_adv_10fdx) {
1045 nar |= NAR_FDX;
1046 }
1047 if (mxfep->mxfe_adv_10hdx) {
1048 tctl |= TCTL_HDX;
1049 }
1050 tctl |= TCTL_PWR | TCTL_ANE | TCTL_LTE | TCTL_RSQ;
1051
1052 /* possibly we should add in support for PAUSE frames */
1053 DBG(DPHY, "writing nar = 0x%x", nar);
1054 PUTCSR(mxfep, CSR_NAR, nar);
1055
1056 DBG(DPHY, "writing tctl = 0x%x", tctl);
1057 PUTCSR(mxfep, CSR_TCTL, tctl);
1058
1059 /* restart autonegotation */
1060 DBG(DPHY, "writing tstat = 0x%x", TSTAT_ANS_START);
1061 PUTCSR(mxfep, CSR_TSTAT, TSTAT_ANS_START);
1062
1063 /* restart tx/rx processes... */
1064 if (restart != 0)
1065 mxfe_startmac(mxfep);
1066
1067 /* Macronix initializations from Bolo Tsai */
1068 PUTCSR(mxfep, CSR_MXMAGIC, 0x0b2c0000);
1069 PUTCSR(mxfep, CSR_ACOMP, 0x11000);
1070
1071 mxfep->mxfe_nwaystate = MXFE_NWAYCHECK;
1072 }
1073
1074 void
mxfe_checklinknway(mxfe_t * mxfep)1075 mxfe_checklinknway(mxfe_t *mxfep)
1076 {
1077 unsigned tstat;
1078 uint16_t lpar;
1079
1080 DBG(DPHY, "NWay check, state %x", mxfep->mxfe_nwaystate);
1081 tstat = GETCSR(mxfep, CSR_TSTAT);
1082 lpar = TSTAT_LPAR(tstat);
1083
1084 mxfep->mxfe_anlpar = lpar;
1085 if (tstat & TSTAT_LPN) {
1086 mxfep->mxfe_aner |= MII_AN_EXP_LPCANAN;
1087 } else {
1088 mxfep->mxfe_aner &= ~(MII_AN_EXP_LPCANAN);
1089 }
1090
1091 DBG(DPHY, "tstat(CSR12) = 0x%x", tstat);
1092 DBG(DPHY, "ANEG state = 0x%x", (tstat & TSTAT_ANS) >> 12);
1093
1094 if ((tstat & TSTAT_ANS) != TSTAT_ANS_OK) {
1095 /* autoneg did not complete */
1096 mxfep->mxfe_bmsr &= ~MII_STATUS_ANDONE;
1097 } else {
1098 mxfep->mxfe_bmsr |= ~MII_STATUS_ANDONE;
1099 }
1100
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);
1108 return;
1109 }
1110
1111 /*
1112 * if the link is newly up, then we might need to set various
1113 * mode bits, or negotiate for parameters, etc.
1114 */
1115 if (mxfep->mxfe_adv_aneg) {
1116
1117 uint16_t anlpar;
1118
1119 mxfep->mxfe_linkup = LINK_STATE_UP;
1120 anlpar = mxfep->mxfe_anlpar;
1121
1122 if (tstat & TSTAT_LPN) {
1123 /* partner has NWay */
1124
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;
1141 } else {
1142 mxfep->mxfe_ifspeed = 0;
1143 }
1144 } else {
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;
1151 } else {
1152 mxfep->mxfe_ifspeed = 10000000;
1153 }
1154 }
1155 } else {
1156 /* forced modes */
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;
1170 } else {
1171 mxfep->mxfe_ifspeed = 0;
1172 }
1173 }
1174 mxfe_reportlink(mxfep);
1175 mxfep->mxfe_nwaystate = MXFE_GOODLINK;
1176 }
1177
1178 void
mxfe_startphynway(mxfe_t * mxfep)1179 mxfe_startphynway(mxfe_t *mxfep)
1180 {
1181 /* take NWay and PHY out of reset */
1182 PUTCSR(mxfep, CSR_SIA, SIA_NRESET);
1183 drv_usecwait(500);
1184
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;
1192
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;
1197
1198 /* 100-T4 not supported with NWay */
1199 mxfep->mxfe_adv_100T4 = 0;
1200 mxfep->mxfe_cap_100T4 = 0;
1201
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);
1213 return;
1214 }
1215
1216 if (mxfep->mxfe_adv_aneg == 0) {
1217 /* forced mode */
1218 unsigned nar;
1219 unsigned tctl;
1220
1221 nar = GETCSR(mxfep, CSR_NAR);
1222 tctl = GETCSR(mxfep, CSR_TCTL);
1223
1224 ASSERT((nar & (NAR_TX_ENABLE | NAR_RX_ENABLE)) == 0);
1225
1226 nar &= ~(NAR_FDX | NAR_PORTSEL | NAR_SCR | NAR_SPEED);
1227 tctl &= ~TCTL_ANE;
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 */
1235 nar |= NAR_SPEED;
1236 }
1237
1238 PUTCSR(mxfep, CSR_NAR, nar);
1239 PUTCSR(mxfep, CSR_TCTL, tctl);
1240
1241 /* Macronix initializations from Bolo Tsai */
1242 PUTCSR(mxfep, CSR_MXMAGIC, 0x0b2c0000);
1243 PUTCSR(mxfep, CSR_ACOMP, 0x11000);
1244 } else {
1245 mxfe_startnway(mxfep);
1246 }
1247 PUTCSR(mxfep, CSR_TIMER, TIMER_LOOP |
1248 (MXFE_LINKTIMER * 1000 / TIMER_USEC));
1249 }
1250
1251 /*
1252 * MII management.
1253 */
1254 void
mxfe_startphymii(mxfe_t * mxfep)1255 mxfe_startphymii(mxfe_t *mxfep)
1256 {
1257 unsigned phyaddr;
1258 unsigned bmcr;
1259 unsigned bmsr;
1260 unsigned anar;
1261 unsigned phyidr1;
1262 unsigned phyidr2;
1263 int retries;
1264 int cnt;
1265
1266 mxfep->mxfe_phyaddr = -1;
1267
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;
1273 break;
1274 }
1275 }
1276
1277 phyidr1 = mxfe_miiread(mxfep, phyaddr, MII_PHYIDH);
1278 phyidr2 = mxfe_miiread(mxfep, phyaddr, MII_PHYIDL);
1279 mxfep->mxfe_phyid = (phyidr1 << 16) | (phyidr2);
1280
1281 /*
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
1285 * enhanced.
1286 *
1287 * One could question the value of the XCVR_INUSE field in the
1288 * MII statistics.
1289 */
1290 if (bmsr & MII_STATUS_100_BASE_T4) {
1291 mxfep->mxfe_phyinuse = XCVR_100T4;
1292 } else {
1293 mxfep->mxfe_phyinuse = XCVR_100X;
1294 }
1295
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;
1300
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));
1310
1311 DBG(DPHY, "resetting phy");
1312
1313 /* we reset the phy block */
1314 mxfe_miiwrite(mxfep, phyaddr, MII_CONTROL, MII_CONTROL_RESET);
1315 /*
1316 * wait for it to complete -- 500usec is still to short to
1317 * bother getting the system clock involved.
1318 */
1319 drv_usecwait(500);
1320 for (retries = 0; retries < 10; retries++) {
1321 if (mxfe_miiread(mxfep, phyaddr, MII_CONTROL) &
1322 MII_CONTROL_RESET) {
1323 drv_usecwait(500);
1324 continue;
1325 }
1326 break;
1327 }
1328 if (retries == 100) {
1329 mxfe_error(mxfep->mxfe_dip, "timeout waiting on phy to reset");
1330 return;
1331 }
1332
1333 DBG(DPHY, "phy reset complete");
1334
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);
1338
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);
1342
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;
1347 }
1348 if (!(bmsr & MII_STATUS_100_BASEX_FD)) {
1349 mxfep->mxfe_adv_100fdx = 0;
1350 mxfep->mxfe_cap_100fdx = 0;
1351 }
1352 if (!(bmsr & MII_STATUS_100_BASEX)) {
1353 mxfep->mxfe_adv_100hdx = 0;
1354 mxfep->mxfe_cap_100hdx = 0;
1355 }
1356 if (!(bmsr & MII_STATUS_10_FD)) {
1357 mxfep->mxfe_adv_10fdx = 0;
1358 mxfep->mxfe_cap_10fdx = 0;
1359 }
1360 if (!(bmsr & MII_STATUS_10)) {
1361 mxfep->mxfe_adv_10hdx = 0;
1362 mxfep->mxfe_cap_10hdx = 0;
1363 }
1364 if (!(bmsr & MII_STATUS_CANAUTONEG)) {
1365 mxfep->mxfe_adv_aneg = 0;
1366 mxfep->mxfe_cap_aneg = 0;
1367 }
1368
1369 cnt = 0;
1370 if (mxfep->mxfe_adv_100T4) {
1371 anar |= MII_ABILITY_100BASE_T4;
1372 cnt++;
1373 }
1374 if (mxfep->mxfe_adv_100fdx) {
1375 anar |= MII_ABILITY_100BASE_TX_FD;
1376 cnt++;
1377 }
1378 if (mxfep->mxfe_adv_100hdx) {
1379 anar |= MII_ABILITY_100BASE_TX;
1380 cnt++;
1381 }
1382 if (mxfep->mxfe_adv_10fdx) {
1383 anar |= MII_ABILITY_10BASE_T_FD;
1384 cnt++;
1385 }
1386 if (mxfep->mxfe_adv_10hdx) {
1387 anar |= MII_ABILITY_10BASE_T;
1388 cnt++;
1389 }
1390
1391 /*
1392 * Make certain at least one valid link mode is selected.
1393 */
1394 if (!cnt) {
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);
1401 return;
1402 }
1403
1404 if ((mxfep->mxfe_adv_aneg) && (bmsr & MII_STATUS_CANAUTONEG)) {
1405 DBG(DPHY, "using autoneg mode");
1406 bmcr = (MII_CONTROL_ANE | MII_CONTROL_RSAN);
1407 } else {
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;
1415 } else {
1416 /* 10HDX */
1417 bmcr = 0;
1418 }
1419 }
1420
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);
1425
1426 /*
1427 * schedule a query of the link status
1428 */
1429 PUTCSR(mxfep, CSR_TIMER, TIMER_LOOP |
1430 (MXFE_LINKTIMER * 1000 / TIMER_USEC));
1431 }
1432
1433 void
mxfe_reportlink(mxfe_t * mxfep)1434 mxfe_reportlink(mxfe_t *mxfep)
1435 {
1436 int changed = 0;
1437
1438 if (mxfep->mxfe_ifspeed != mxfep->mxfe_lastifspeed) {
1439 mxfep->mxfe_lastifspeed = mxfep->mxfe_ifspeed;
1440 changed++;
1441 }
1442 if (mxfep->mxfe_duplex != mxfep->mxfe_lastduplex) {
1443 mxfep->mxfe_lastduplex = mxfep->mxfe_duplex;
1444 changed++;
1445 }
1446 if (mxfep->mxfe_linkup != mxfep->mxfe_lastlinkup) {
1447 mxfep->mxfe_lastlinkup = mxfep->mxfe_linkup;
1448 changed++;
1449 }
1450 if (changed)
1451 mac_link_update(mxfep->mxfe_mh, mxfep->mxfe_linkup);
1452 }
1453
1454 void
mxfe_checklink(mxfe_t * mxfep)1455 mxfe_checklink(mxfe_t *mxfep)
1456 {
1457 if ((mxfep->mxfe_flags & MXFE_RUNNING) == 0)
1458 return;
1459
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);
1466 return;
1467 }
1468
1469 switch (MXFE_MODEL(mxfep)) {
1470 case MXFE_98713A:
1471 mxfe_checklinkmii(mxfep);
1472 break;
1473 default:
1474 mxfe_checklinknway(mxfep);
1475 }
1476 }
1477
1478 void
mxfe_checklinkmii(mxfe_t * mxfep)1479 mxfe_checklinkmii(mxfe_t *mxfep)
1480 {
1481 /* read MII state registers */
1482 uint16_t bmsr;
1483 uint16_t bmcr;
1484 uint16_t anar;
1485 uint16_t anlpar;
1486 uint16_t aner;
1487
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);
1495
1496 mxfep->mxfe_bmsr = bmsr;
1497 mxfep->mxfe_anlpar = anlpar;
1498 mxfep->mxfe_aner = aner;
1499
1500 if (bmsr & MII_STATUS_REMFAULT) {
1501 mxfe_error(mxfep->mxfe_dip, "Remote fault detected.");
1502 }
1503 if (bmsr & MII_STATUS_JABBERING) {
1504 mxfe_error(mxfep->mxfe_dip, "Jabber condition detected.");
1505 }
1506 if ((bmsr & MII_STATUS_LINKUP) == 0) {
1507 /* no link */
1508 mxfep->mxfe_ifspeed = 0;
1509 mxfep->mxfe_duplex = LINK_DUPLEX_UNKNOWN;
1510 mxfep->mxfe_linkup = LINK_STATE_DOWN;
1511 mxfe_reportlink(mxfep);
1512 return;
1513 }
1514
1515 DBG(DCHATTY, "link up!");
1516 mxfep->mxfe_linkup = LINK_STATE_UP;
1517
1518 if (!(bmcr & MII_CONTROL_ANE)) {
1519 /* forced mode */
1520 if (bmcr & MII_CONTROL_100MB) {
1521 mxfep->mxfe_ifspeed = 100000000;
1522 } else {
1523 mxfep->mxfe_ifspeed = 10000000;
1524 }
1525 if (bmcr & MII_CONTROL_FDUPLEX) {
1526 mxfep->mxfe_duplex = LINK_DUPLEX_FULL;
1527 } else {
1528 mxfep->mxfe_duplex = LINK_DUPLEX_HALF;
1529 }
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;
1549 } else {
1550 mxfep->mxfe_ifspeed = 0;
1551 mxfep->mxfe_duplex = LINK_DUPLEX_UNKNOWN;
1552 }
1553
1554 mxfe_reportlink(mxfep);
1555 }
1556
1557 void
mxfe_miitristate(mxfe_t * mxfep)1558 mxfe_miitristate(mxfe_t *mxfep)
1559 {
1560 unsigned val = SPR_SROM_WRITE | SPR_MII_CTRL;
1561 PUTCSR(mxfep, CSR_SPR, val);
1562 drv_usecwait(1);
1563 PUTCSR(mxfep, CSR_SPR, val | SPR_MII_CLOCK);
1564 drv_usecwait(1);
1565 }
1566
1567 void
mxfe_miiwritebit(mxfe_t * mxfep,uint8_t bit)1568 mxfe_miiwritebit(mxfe_t *mxfep, uint8_t bit)
1569 {
1570 unsigned val = bit ? SPR_MII_DOUT : 0;
1571 PUTCSR(mxfep, CSR_SPR, val);
1572 drv_usecwait(1);
1573 PUTCSR(mxfep, CSR_SPR, val | SPR_MII_CLOCK);
1574 drv_usecwait(1);
1575 }
1576
1577 uint8_t
mxfe_miireadbit(mxfe_t * mxfep)1578 mxfe_miireadbit(mxfe_t *mxfep)
1579 {
1580 unsigned val = SPR_MII_CTRL | SPR_SROM_READ;
1581 uint8_t bit;
1582 PUTCSR(mxfep, CSR_SPR, val);
1583 drv_usecwait(1);
1584 bit = (GETCSR(mxfep, CSR_SPR) & SPR_MII_DIN) ? 1 : 0;
1585 PUTCSR(mxfep, CSR_SPR, val | SPR_MII_CLOCK);
1586 drv_usecwait(1);
1587 return (bit);
1588 }
1589
1590 uint16_t
mxfe_miiread(mxfe_t * mxfep,int phy,int reg)1591 mxfe_miiread(mxfe_t *mxfep, int phy, int reg)
1592 {
1593 switch (MXFE_MODEL(mxfep)) {
1594 case MXFE_98713A:
1595 return (mxfe_miiread98713(mxfep, phy, reg));
1596 default:
1597 return (0xffff);
1598 }
1599 }
1600
1601 uint16_t
mxfe_miireadgeneral(mxfe_t * mxfep,int phy,int reg)1602 mxfe_miireadgeneral(mxfe_t *mxfep, int phy, int reg)
1603 {
1604 uint16_t value = 0;
1605 int i;
1606
1607 /* send the 32 bit preamble */
1608 for (i = 0; i < 32; i++) {
1609 mxfe_miiwritebit(mxfep, 1);
1610 }
1611
1612 /* send the start code - 01b */
1613 mxfe_miiwritebit(mxfep, 0);
1614 mxfe_miiwritebit(mxfep, 1);
1615
1616 /* send the opcode for read, - 10b */
1617 mxfe_miiwritebit(mxfep, 1);
1618 mxfe_miiwritebit(mxfep, 0);
1619
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);
1623 }
1624
1625 /* the 5 bit register address goes next */
1626 for (i = 0x10; i > 0; i >>= 1) {
1627 mxfe_miiwritebit(mxfep, (reg & i) ? 1 : 0);
1628 }
1629
1630 /* turnaround - tristate followed by logic 0 */
1631 mxfe_miitristate(mxfep);
1632 mxfe_miiwritebit(mxfep, 0);
1633
1634 /* read the 16 bit register value */
1635 for (i = 0x8000; i > 0; i >>= 1) {
1636 value <<= 1;
1637 value |= mxfe_miireadbit(mxfep);
1638 }
1639 mxfe_miitristate(mxfep);
1640 return (value);
1641 }
1642
1643 uint16_t
mxfe_miiread98713(mxfe_t * mxfep,int phy,int reg)1644 mxfe_miiread98713(mxfe_t *mxfep, int phy, int reg)
1645 {
1646 unsigned nar;
1647 uint16_t retval;
1648 /*
1649 * like an ordinary MII, but we have to turn off portsel while
1650 * we read it.
1651 */
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);
1656 return (retval);
1657 }
1658
1659 void
mxfe_miiwrite(mxfe_t * mxfep,int phy,int reg,uint16_t val)1660 mxfe_miiwrite(mxfe_t *mxfep, int phy, int reg, uint16_t val)
1661 {
1662 switch (MXFE_MODEL(mxfep)) {
1663 case MXFE_98713A:
1664 mxfe_miiwrite98713(mxfep, phy, reg, val);
1665 break;
1666 default:
1667 break;
1668 }
1669 }
1670
1671 void
mxfe_miiwritegeneral(mxfe_t * mxfep,int phy,int reg,uint16_t val)1672 mxfe_miiwritegeneral(mxfe_t *mxfep, int phy, int reg, uint16_t val)
1673 {
1674 int i;
1675
1676 /* send the 32 bit preamble */
1677 for (i = 0; i < 32; i++) {
1678 mxfe_miiwritebit(mxfep, 1);
1679 }
1680
1681 /* send the start code - 01b */
1682 mxfe_miiwritebit(mxfep, 0);
1683 mxfe_miiwritebit(mxfep, 1);
1684
1685 /* send the opcode for write, - 01b */
1686 mxfe_miiwritebit(mxfep, 0);
1687 mxfe_miiwritebit(mxfep, 1);
1688
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);
1692 }
1693
1694 /* the 5 bit register address goes next */
1695 for (i = 0x10; i > 0; i >>= 1) {
1696 mxfe_miiwritebit(mxfep, (reg & i) ? 1 : 0);
1697 }
1698
1699 /* turnaround - tristate followed by logic 0 */
1700 mxfe_miitristate(mxfep);
1701 mxfe_miiwritebit(mxfep, 0);
1702
1703 /* now write out our data (16 bits) */
1704 for (i = 0x8000; i > 0; i >>= 1) {
1705 mxfe_miiwritebit(mxfep, (val & i) ? 1 : 0);
1706 }
1707
1708 /* idle mode */
1709 mxfe_miitristate(mxfep);
1710 }
1711
1712 void
mxfe_miiwrite98713(mxfe_t * mxfep,int phy,int reg,uint16_t val)1713 mxfe_miiwrite98713(mxfe_t *mxfep, int phy, int reg, uint16_t val)
1714 {
1715 unsigned nar;
1716 /*
1717 * like an ordinary MII, but we have to turn off portsel while
1718 * we read it.
1719 */
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);
1724 }
1725
1726 int
mxfe_m_start(void * arg)1727 mxfe_m_start(void *arg)
1728 {
1729 mxfe_t *mxfep = arg;
1730
1731 /* grab exclusive access to the card */
1732 mutex_enter(&mxfep->mxfe_intrlock);
1733 mutex_enter(&mxfep->mxfe_xmtlock);
1734
1735 mxfe_startall(mxfep);
1736 mxfep->mxfe_flags |= MXFE_RUNNING;
1737
1738 mutex_exit(&mxfep->mxfe_xmtlock);
1739 mutex_exit(&mxfep->mxfe_intrlock);
1740 return (0);
1741 }
1742
1743 void
mxfe_m_stop(void * arg)1744 mxfe_m_stop(void *arg)
1745 {
1746 mxfe_t *mxfep = arg;
1747
1748 /* exclusive access to the hardware! */
1749 mutex_enter(&mxfep->mxfe_intrlock);
1750 mutex_enter(&mxfep->mxfe_xmtlock);
1751
1752 mxfe_stopall(mxfep);
1753 mxfep->mxfe_flags &= ~MXFE_RUNNING;
1754
1755 mutex_exit(&mxfep->mxfe_xmtlock);
1756 mutex_exit(&mxfep->mxfe_intrlock);
1757 }
1758
1759 void
mxfe_startmac(mxfe_t * mxfep)1760 mxfe_startmac(mxfe_t *mxfep)
1761 {
1762 /* verify exclusive access to the card */
1763 ASSERT(mutex_owned(&mxfep->mxfe_intrlock));
1764 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock));
1765
1766 /* start the card */
1767 SETBIT(mxfep, CSR_NAR, NAR_TX_ENABLE | NAR_RX_ENABLE);
1768
1769 if (mxfep->mxfe_txavail != MXFE_TXRING)
1770 PUTCSR(mxfep, CSR_TDR, 0);
1771
1772 /* tell the mac that we are ready to go! */
1773 if (mxfep->mxfe_flags & MXFE_RUNNING)
1774 mac_tx_update(mxfep->mxfe_mh);
1775 }
1776
1777 void
mxfe_stopmac(mxfe_t * mxfep)1778 mxfe_stopmac(mxfe_t *mxfep)
1779 {
1780 int i;
1781
1782 /* exclusive access to the hardware! */
1783 ASSERT(mutex_owned(&mxfep->mxfe_intrlock));
1784 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock));
1785
1786 CLRBIT(mxfep, CSR_NAR, NAR_TX_ENABLE | NAR_RX_ENABLE);
1787
1788 /*
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.
1792 *
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.
1796 */
1797 for (i = 2000; i != 0; i -= 10) {
1798 if ((GETCSR(mxfep, CSR_SR) & (SR_TX_STATE | SR_RX_STATE)) == 0)
1799 break;
1800 drv_usecwait(10);
1801 }
1802
1803 /* prevent an interrupt */
1804 PUTCSR(mxfep, CSR_SR, INT_RXSTOPPED | INT_TXSTOPPED);
1805 }
1806
1807 void
mxfe_resetrings(mxfe_t * mxfep)1808 mxfe_resetrings(mxfe_t *mxfep)
1809 {
1810 int i;
1811
1812 /* now we need to reset the pointers... */
1813 PUTCSR(mxfep, CSR_RDB, 0);
1814 PUTCSR(mxfep, CSR_TDB, 0);
1815
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;
1821
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;
1828 }
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);
1834 }
1835 PUTCSR(mxfep, CSR_TDB, mxfep->mxfe_txdesc_paddr);
1836
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];
1841 unsigned control;
1842
1843 control = MXFE_BUFSZ & RXCTL_BUFLEN1;
1844 if (i == (MXFE_RXRING - 1)) {
1845 control |= RXCTL_ENDRING;
1846 }
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);
1852 }
1853 PUTCSR(mxfep, CSR_RDB, mxfep->mxfe_rxdesc_paddr);
1854 }
1855
1856 void
mxfe_stopall(mxfe_t * mxfep)1857 mxfe_stopall(mxfe_t *mxfep)
1858 {
1859 mxfe_disableinterrupts(mxfep);
1860
1861 mxfe_stopmac(mxfep);
1862
1863 /* stop the phy */
1864 mxfe_stopphy(mxfep);
1865 }
1866
1867 void
mxfe_startall(mxfe_t * mxfep)1868 mxfe_startall(mxfe_t *mxfep)
1869 {
1870 ASSERT(mutex_owned(&mxfep->mxfe_intrlock));
1871 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock));
1872
1873 /* make sure interrupts are disabled to begin */
1874 mxfe_disableinterrupts(mxfep);
1875
1876 /* initialize the chip */
1877 (void) mxfe_initialize(mxfep);
1878
1879 /* now we can enable interrupts */
1880 mxfe_enableinterrupts(mxfep);
1881
1882 /* start up the phy */
1883 mxfe_startphy(mxfep);
1884
1885 /* start up the mac */
1886 mxfe_startmac(mxfep);
1887 }
1888
1889 void
mxfe_resetall(mxfe_t * mxfep)1890 mxfe_resetall(mxfe_t *mxfep)
1891 {
1892 mxfep->mxfe_resetting = B_TRUE;
1893 mxfe_stopall(mxfep);
1894 mxfep->mxfe_resetting = B_FALSE;
1895 mxfe_startall(mxfep);
1896 }
1897
1898 mxfe_txbuf_t *
mxfe_alloctxbuf(mxfe_t * mxfep)1899 mxfe_alloctxbuf(mxfe_t *mxfep)
1900 {
1901 ddi_dma_cookie_t dmac;
1902 unsigned ncookies;
1903 mxfe_txbuf_t *txb;
1904 size_t len;
1905
1906 txb = kmem_zalloc(sizeof (*txb), KM_SLEEP);
1907
1908 if (ddi_dma_alloc_handle(mxfep->mxfe_dip, &mxfe_dma_txattr,
1909 DDI_DMA_SLEEP, NULL, &txb->txb_dmah) != DDI_SUCCESS) {
1910 return (NULL);
1911 }
1912
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) {
1916 return (NULL);
1917 }
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) {
1921 return (NULL);
1922 }
1923 txb->txb_paddr = dmac.dmac_address;
1924
1925 return (txb);
1926 }
1927
1928 void
mxfe_destroytxbuf(mxfe_txbuf_t * txb)1929 mxfe_destroytxbuf(mxfe_txbuf_t *txb)
1930 {
1931 if (txb != NULL) {
1932 if (txb->txb_paddr)
1933 (void) ddi_dma_unbind_handle(txb->txb_dmah);
1934 if (txb->txb_acch)
1935 ddi_dma_mem_free(&txb->txb_acch);
1936 if (txb->txb_dmah)
1937 ddi_dma_free_handle(&txb->txb_dmah);
1938 kmem_free(txb, sizeof (*txb));
1939 }
1940 }
1941
1942 mxfe_rxbuf_t *
mxfe_allocrxbuf(mxfe_t * mxfep)1943 mxfe_allocrxbuf(mxfe_t *mxfep)
1944 {
1945 mxfe_rxbuf_t *rxb;
1946 size_t len;
1947 unsigned ccnt;
1948 ddi_dma_cookie_t dmac;
1949
1950 rxb = kmem_zalloc(sizeof (*rxb), KM_SLEEP);
1951
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));
1955 return (NULL);
1956 }
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));
1962 return (NULL);
1963 }
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));
1970 return (NULL);
1971 }
1972 rxb->rxb_paddr = dmac.dmac_address;
1973
1974 return (rxb);
1975 }
1976
1977 void
mxfe_destroyrxbuf(mxfe_rxbuf_t * rxb)1978 mxfe_destroyrxbuf(mxfe_rxbuf_t *rxb)
1979 {
1980 if (rxb != NULL) {
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));
1985 }
1986 }
1987
1988 /*
1989 * Allocate receive resources.
1990 */
1991 int
mxfe_allocrxring(mxfe_t * mxfep)1992 mxfe_allocrxring(mxfe_t *mxfep)
1993 {
1994 int rval;
1995 int i;
1996 size_t size;
1997 size_t len;
1998 ddi_dma_cookie_t dmac;
1999 unsigned ncookies;
2000 caddr_t kaddr;
2001
2002 size = MXFE_RXRING * sizeof (mxfe_desc_t);
2003
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);
2010 }
2011
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);
2019 }
2020
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,
2023 &dmac, &ncookies);
2024 if (rval != DDI_DMA_MAPPED) {
2025 mxfe_error(mxfep->mxfe_dip,
2026 "unable to bind DMA for rx descriptors");
2027 return (DDI_FAILURE);
2028 }
2029
2030 /* because of mxfe_dma_attr */
2031 ASSERT(ncookies == 1);
2032
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;
2036
2037 /* allocate buffer pointers (not the buffers themselves, yet) */
2038 mxfep->mxfe_rxbufs = kmem_zalloc(MXFE_RXRING * sizeof (mxfe_rxbuf_t *),
2039 KM_SLEEP);
2040
2041 /* now allocate rx buffers */
2042 for (i = 0; i < MXFE_RXRING; i++) {
2043 mxfe_rxbuf_t *rxb = mxfe_allocrxbuf(mxfep);
2044 if (rxb == NULL)
2045 return (DDI_FAILURE);
2046 mxfep->mxfe_rxbufs[i] = rxb;
2047 }
2048
2049 return (DDI_SUCCESS);
2050 }
2051
2052 /*
2053 * Allocate transmit resources.
2054 */
2055 int
mxfe_alloctxring(mxfe_t * mxfep)2056 mxfe_alloctxring(mxfe_t *mxfep)
2057 {
2058 int rval;
2059 int i;
2060 size_t size;
2061 size_t len;
2062 ddi_dma_cookie_t dmac;
2063 unsigned ncookies;
2064 caddr_t kaddr;
2065
2066 size = MXFE_TXRING * sizeof (mxfe_desc_t);
2067
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);
2074 }
2075
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);
2083 }
2084
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,
2087 &dmac, &ncookies);
2088 if (rval != DDI_DMA_MAPPED) {
2089 mxfe_error(mxfep->mxfe_dip,
2090 "unable to bind DMA for tx descriptors");
2091 return (DDI_FAILURE);
2092 }
2093
2094 /* because of mxfe_dma_attr */
2095 ASSERT(ncookies == 1);
2096
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;
2100
2101 /* allocate buffer pointers (not the buffers themselves, yet) */
2102 mxfep->mxfe_txbufs = kmem_zalloc(MXFE_TXRING * sizeof (mxfe_txbuf_t *),
2103 KM_SLEEP);
2104
2105 /* now allocate tx buffers */
2106 for (i = 0; i < MXFE_TXRING; i++) {
2107 mxfe_txbuf_t *txb = mxfe_alloctxbuf(mxfep);
2108 if (txb == NULL)
2109 return (DDI_FAILURE);
2110 /* stick it in the stack */
2111 mxfep->mxfe_txbufs[i] = txb;
2112 }
2113
2114 return (DDI_SUCCESS);
2115 }
2116
2117 void
mxfe_freerxring(mxfe_t * mxfep)2118 mxfe_freerxring(mxfe_t *mxfep)
2119 {
2120 int i;
2121
2122 for (i = 0; i < MXFE_RXRING; i++) {
2123 mxfe_destroyrxbuf(mxfep->mxfe_rxbufs[i]);
2124 }
2125
2126 if (mxfep->mxfe_rxbufs) {
2127 kmem_free(mxfep->mxfe_rxbufs,
2128 MXFE_RXRING * sizeof (mxfe_rxbuf_t *));
2129 }
2130
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);
2137 }
2138
2139 void
mxfe_freetxring(mxfe_t * mxfep)2140 mxfe_freetxring(mxfe_t *mxfep)
2141 {
2142 int i;
2143
2144 for (i = 0; i < MXFE_TXRING; i++) {
2145 mxfe_destroytxbuf(mxfep->mxfe_txbufs[i]);
2146 }
2147
2148 if (mxfep->mxfe_txbufs) {
2149 kmem_free(mxfep->mxfe_txbufs,
2150 MXFE_TXRING * sizeof (mxfe_txbuf_t *));
2151 }
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);
2158 }
2159
2160 /*
2161 * Interrupt service routine.
2162 */
2163 unsigned
mxfe_intr(caddr_t arg)2164 mxfe_intr(caddr_t arg)
2165 {
2166 mxfe_t *mxfep = (void *)arg;
2167 uint32_t status;
2168 mblk_t *mp = NULL;
2169 boolean_t error = B_FALSE;
2170
2171 mutex_enter(&mxfep->mxfe_intrlock);
2172
2173 if (mxfep->mxfe_flags & MXFE_SUSPENDED) {
2174 /* we cannot receive interrupts! */
2175 mutex_exit(&mxfep->mxfe_intrlock);
2176 return (DDI_INTR_UNCLAIMED);
2177 }
2178
2179 /* check interrupt status bits, did we interrupt? */
2180 status = GETCSR(mxfep, CSR_SR) & INT_ALL;
2181
2182 if (status == 0) {
2183 KIOIP->intrs[KSTAT_INTR_SPURIOUS]++;
2184 mutex_exit(&mxfep->mxfe_intrlock);
2185 return (DDI_INTR_UNCLAIMED);
2186 }
2187 /* ack the interrupt */
2188 PUTCSR(mxfep, CSR_SR, status);
2189 KIOIP->intrs[KSTAT_INTR_HARD]++;
2190
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);
2195 }
2196
2197 if (status & INT_RXOK) {
2198 /* receive packets */
2199 if (mxfe_receive(mxfep, &mp)) {
2200 error = B_TRUE;
2201 }
2202 }
2203
2204 if (status & INT_TXOK) {
2205 /* transmit completed */
2206 mutex_enter(&mxfep->mxfe_xmtlock);
2207 mxfe_reclaim(mxfep);
2208 mutex_exit(&mxfep->mxfe_xmtlock);
2209 }
2210
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);
2218 }
2219
2220 if (status & (INT_RXSTOPPED|INT_TXSTOPPED|INT_RXNOBUF|
2221 INT_RXJABBER|INT_TXJABBER|INT_TXUNDERFLOW)) {
2222
2223 if (status & (INT_RXJABBER | INT_TXJABBER)) {
2224 mxfep->mxfe_jabber++;
2225 }
2226 DBG(DWARN, "error interrupt: status %x", status);
2227 error = B_TRUE;
2228 }
2229
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");
2234 break;
2235 case SR_BERR_TARGET_ABORT:
2236 mxfe_error(mxfep->mxfe_dip, "PCI target abort");
2237 break;
2238 case SR_BERR_MASTER_ABORT:
2239 mxfe_error(mxfep->mxfe_dip, "PCI master abort");
2240 break;
2241 default:
2242 mxfe_error(mxfep->mxfe_dip, "Unknown PCI error");
2243 break;
2244 }
2245
2246 error = B_TRUE;
2247 }
2248
2249 if (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);
2254 }
2255
2256 mutex_exit(&mxfep->mxfe_intrlock);
2257
2258 /*
2259 * Send up packets. We do this outside of the intrlock.
2260 */
2261 if (mp) {
2262 mac_rx(mxfep->mxfe_mh, NULL, mp);
2263 }
2264
2265 return (DDI_INTR_CLAIMED);
2266 }
2267
2268 void
mxfe_enableinterrupts(mxfe_t * mxfep)2269 mxfe_enableinterrupts(mxfe_t *mxfep)
2270 {
2271 unsigned mask = INT_WANTED;
2272
2273 if (mxfep->mxfe_wantw)
2274 mask |= INT_TXOK;
2275
2276 if (MXFE_MODEL(mxfep) != MXFE_98713A)
2277 mask |= INT_LINKSTATUS;
2278
2279 DBG(DINTR, "setting int mask to 0x%x", mask);
2280 PUTCSR(mxfep, CSR_IER, mask);
2281 }
2282
2283 void
mxfe_disableinterrupts(mxfe_t * mxfep)2284 mxfe_disableinterrupts(mxfe_t *mxfep)
2285 {
2286 /* disable further interrupts */
2287 PUTCSR(mxfep, CSR_IER, 0);
2288
2289 /* clear any pending interrupts */
2290 PUTCSR(mxfep, CSR_SR, INT_ALL);
2291 }
2292
2293 void
mxfe_send_setup(mxfe_t * mxfep)2294 mxfe_send_setup(mxfe_t *mxfep)
2295 {
2296 mxfe_txbuf_t *txb;
2297 mxfe_desc_t *tmdp;
2298
2299 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock));
2300
2301 /* setup frame -- must be at head of list -- guaranteed by caller! */
2302 ASSERT(mxfep->mxfe_txsend == 0);
2303
2304 txb = mxfep->mxfe_txbufs[0];
2305 tmdp = &mxfep->mxfe_txdescp[0];
2306
2307 bzero(txb->txb_buf, MXFE_SETUP_LEN);
2308
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];
2316
2317 /* make sure that the hardware can see it */
2318 SYNCTXBUF(txb, MXFE_SETUP_LEN, DDI_DMA_SYNC_FORDEV);
2319
2320 PUTTXDESC(mxfep, tmdp->desc_control,
2321 TXCTL_FIRST | TXCTL_LAST | TXCTL_INTCMPLTE | TXCTL_HASHPERF |
2322 TXCTL_SETUP | MXFE_SETUP_LEN);
2323
2324 PUTTXDESC(mxfep, tmdp->desc_buffer1, txb->txb_paddr);
2325 PUTTXDESC(mxfep, tmdp->desc_buffer2, 0);
2326 PUTTXDESC(mxfep, tmdp->desc_status, TXSTAT_OWN);
2327
2328 /* sync the descriptor out to the device */
2329 SYNCTXDESC(mxfep, 0, DDI_DMA_SYNC_FORDEV);
2330
2331 /*
2332 * wake up the chip ... inside the lock to protect against DR suspend,
2333 * etc.
2334 */
2335 PUTCSR(mxfep, CSR_TDR, 0);
2336 mxfep->mxfe_txsend++;
2337 mxfep->mxfe_txavail--;
2338
2339 /*
2340 * Program promiscuous mode.
2341 */
2342 if (mxfep->mxfe_promisc) {
2343 SETBIT(mxfep, CSR_NAR, NAR_RX_PROMISC);
2344 } else {
2345 CLRBIT(mxfep, CSR_NAR, NAR_RX_PROMISC);
2346 }
2347 }
2348
2349 boolean_t
mxfe_send(mxfe_t * mxfep,mblk_t * mp)2350 mxfe_send(mxfe_t *mxfep, mblk_t *mp)
2351 {
2352 size_t len;
2353 mxfe_txbuf_t *txb;
2354 mxfe_desc_t *tmd;
2355 uint32_t control;
2356 int txsend;
2357
2358 ASSERT(mutex_owned(&mxfep->mxfe_xmtlock));
2359 ASSERT(mp != NULL);
2360
2361 len = msgsize(mp);
2362 if (len > ETHERVLANMTU) {
2363 DBG(DXMIT, "frame too long: %d", len);
2364 mxfep->mxfe_macxmt_errors++;
2365 freemsg(mp);
2366 return (B_TRUE);
2367 }
2368
2369 if (mxfep->mxfe_txavail < MXFE_TXRECLAIM)
2370 mxfe_reclaim(mxfep);
2371
2372 if (mxfep->mxfe_txavail == 0) {
2373 /* no more tmds */
2374 mxfep->mxfe_wantw = B_TRUE;
2375 /* enable TX interrupt */
2376 mxfe_enableinterrupts(mxfep);
2377 return (B_FALSE);
2378 }
2379
2380 txsend = mxfep->mxfe_txsend;
2381
2382 /*
2383 * For simplicity, we just do a copy into a preallocated
2384 * DMA buffer.
2385 */
2386
2387 txb = mxfep->mxfe_txbufs[txsend];
2388 mcopymsg(mp, txb->txb_buf); /* frees mp! */
2389
2390 /*
2391 * Statistics.
2392 */
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++;
2398 else
2399 mxfep->mxfe_brdcstxmt++;
2400 }
2401
2402 /* note len is already known to be a small unsigned */
2403 control = len | TXCTL_FIRST | TXCTL_LAST | TXCTL_INTCMPLTE;
2404
2405 if (txsend == (MXFE_TXRING - 1))
2406 control |= TXCTL_ENDRING;
2407
2408 tmd = &mxfep->mxfe_txdescp[txsend];
2409
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);
2417
2418 /*
2419 * Note the new values of txavail and txsend.
2420 */
2421 mxfep->mxfe_txavail--;
2422 mxfep->mxfe_txsend = (txsend + 1) % MXFE_TXRING;
2423
2424 /*
2425 * It should never, ever take more than 5 seconds to drain
2426 * the ring. If it happens, then we are stuck!
2427 */
2428 mxfep->mxfe_txstall_time = gethrtime() + (5 * 1000000000ULL);
2429
2430 /*
2431 * wake up the chip ... inside the lock to protect against DR suspend,
2432 * etc.
2433 */
2434 PUTCSR(mxfep, CSR_TDR, 0);
2435
2436 return (B_TRUE);
2437 }
2438
2439 /*
2440 * Reclaim buffers that have completed transmission.
2441 */
2442 void
mxfe_reclaim(mxfe_t * mxfep)2443 mxfe_reclaim(mxfe_t *mxfep)
2444 {
2445 mxfe_desc_t *tmdp;
2446
2447 while (mxfep->mxfe_txavail != MXFE_TXRING) {
2448 uint32_t status;
2449 uint32_t control;
2450 int index = mxfep->mxfe_txreclaim;
2451
2452 tmdp = &mxfep->mxfe_txdescp[index];
2453
2454 /* sync it before we read it */
2455 SYNCTXDESC(mxfep, index, DDI_DMA_SYNC_FORKERNEL);
2456
2457 control = GETTXDESC(mxfep, tmdp->desc_control);
2458 status = GETTXDESC(mxfep, tmdp->desc_status);
2459
2460 if (status & TXSTAT_OWN) {
2461 /* chip is still working on it, we're done */
2462 break;
2463 }
2464
2465 mxfep->mxfe_txavail++;
2466 mxfep->mxfe_txreclaim = (index + 1) % MXFE_TXRING;
2467
2468 /* in the most common successful case, all bits are clear */
2469 if (status == 0)
2470 continue;
2471
2472 if (((control & TXCTL_SETUP) != 0) ||
2473 ((control & TXCTL_LAST) == 0)) {
2474 /* no interesting statistics here */
2475 continue;
2476 }
2477
2478 if (status & TXSTAT_TXERR) {
2479 mxfep->mxfe_errxmt++;
2480
2481 if (status & TXSTAT_JABBER) {
2482 /* transmit jabber timeout */
2483 mxfep->mxfe_macxmt_errors++;
2484 }
2485 if (status & (TXSTAT_CARRLOST | TXSTAT_NOCARR)) {
2486 mxfep->mxfe_carrier_errors++;
2487 }
2488 if (status & TXSTAT_UFLOW) {
2489 mxfep->mxfe_underflow++;
2490 }
2491 if (status & TXSTAT_LATECOL) {
2492 mxfep->mxfe_tx_late_collisions++;
2493 }
2494 if (status & TXSTAT_EXCOLL) {
2495 mxfep->mxfe_ex_collisions++;
2496 mxfep->mxfe_collisions += 16;
2497 }
2498 }
2499
2500 if (status & TXSTAT_DEFER) {
2501 mxfep->mxfe_defer_xmts++;
2502 }
2503
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);
2511 }
2512 }
2513
2514 if (mxfep->mxfe_txavail >= MXFE_TXRESCHED) {
2515 if (mxfep->mxfe_wantw) {
2516 /*
2517 * we were able to reclaim some packets, so
2518 * disable tx interrupts
2519 */
2520 mxfep->mxfe_wantw = B_FALSE;
2521 mxfe_enableinterrupts(mxfep);
2522 mac_tx_update(mxfep->mxfe_mh);
2523 }
2524 }
2525 }
2526
2527 boolean_t
mxfe_receive(mxfe_t * mxfep,mblk_t ** rxchain)2528 mxfe_receive(mxfe_t *mxfep, mblk_t **rxchain)
2529 {
2530 unsigned len;
2531 mxfe_rxbuf_t *rxb;
2532 mxfe_desc_t *rmd;
2533 uint32_t status;
2534 mblk_t *mpchain, **mpp, *mp;
2535 int head, cnt;
2536 boolean_t error = B_FALSE;
2537
2538 mpchain = NULL;
2539 mpp = &mpchain;
2540 head = mxfep->mxfe_rxhead;
2541
2542 /* limit the number of packets we process to a ring size */
2543 for (cnt = 0; cnt < MXFE_RXRING; cnt++) {
2544
2545 DBG(DRECV, "receive at index %d", head);
2546
2547 rmd = &mxfep->mxfe_rxdescp[head];
2548 rxb = mxfep->mxfe_rxbufs[head];
2549
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 */
2554 break;
2555 }
2556
2557 /* discard the ethernet frame checksum */
2558 len = RXLENGTH(status) - ETHERFCSL;
2559
2560 DBG(DRECV, "recv length %d, status %x", len, status);
2561
2562 if ((status & (RXSTAT_ERRS | RXSTAT_FIRST | RXSTAT_LAST)) !=
2563 (RXSTAT_FIRST | RXSTAT_LAST)) {
2564
2565 mxfep->mxfe_errrcv++;
2566
2567 /*
2568 * Abnormal status bits detected, analyze further.
2569 */
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++;
2576 }
2577 } else if (status & RXSTAT_DESCERR) {
2578 /* this should never occur! */
2579 mxfep->mxfe_macrcv_errors++;
2580 error = B_TRUE;
2581
2582 } else if (status & RXSTAT_RUNT) {
2583 mxfep->mxfe_runt++;
2584
2585 } else if (status & RXSTAT_COLLSEEN) {
2586 /* this should really be rx_late_collisions */
2587 mxfep->mxfe_macrcv_errors++;
2588
2589 } else if (status & RXSTAT_DRIBBLE) {
2590 mxfep->mxfe_align_errors++;
2591
2592 } else if (status & RXSTAT_CRCERR) {
2593 mxfep->mxfe_fcs_errors++;
2594
2595 } else if (status & RXSTAT_OFLOW) {
2596 /* this is a MAC FIFO error, need to reset */
2597 mxfep->mxfe_overflow++;
2598 error = B_TRUE;
2599 }
2600 }
2601
2602 else if (len > ETHERVLANMTU) {
2603 mxfep->mxfe_errrcv++;
2604 mxfep->mxfe_toolong_errors++;
2605 }
2606
2607 /*
2608 * At this point, the chip thinks the packet is OK.
2609 */
2610 else {
2611 mp = allocb(len + MXFE_HEADROOM, 0);
2612 if (mp == NULL) {
2613 mxfep->mxfe_errrcv++;
2614 mxfep->mxfe_norcvbuf++;
2615 goto skip;
2616 }
2617
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);
2623
2624 mxfep->mxfe_ipackets++;
2625 mxfep->mxfe_rbytes += len;
2626 if (status & RXSTAT_GROUP) {
2627 if (bcmp(mp->b_rptr, mxfe_broadcast,
2628 ETHERADDRL) == 0)
2629 mxfep->mxfe_brdcstrcv++;
2630 else
2631 mxfep->mxfe_multircv++;
2632 }
2633 *mpp = mp;
2634 mpp = &mp->b_next;
2635 }
2636
2637 skip:
2638 /* return ring entry to the hardware */
2639 PUTRXDESC(mxfep, rmd->desc_status, RXSTAT_OWN);
2640 SYNCRXDESC(mxfep, head, DDI_DMA_SYNC_FORDEV);
2641
2642 /* advance to next RMD */
2643 head = (head + 1) % MXFE_RXRING;
2644 }
2645
2646 mxfep->mxfe_rxhead = head;
2647
2648 *rxchain = mpchain;
2649 return (error);
2650 }
2651
2652 int
mxfe_m_stat(void * arg,uint_t stat,uint64_t * val)2653 mxfe_m_stat(void *arg, uint_t stat, uint64_t *val)
2654 {
2655 mxfe_t *mxfep = arg;
2656
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);
2661
2662 switch (stat) {
2663 case MAC_STAT_IFSPEED:
2664 *val = mxfep->mxfe_ifspeed;
2665 break;
2666
2667 case MAC_STAT_MULTIRCV:
2668 *val = mxfep->mxfe_multircv;
2669 break;
2670
2671 case MAC_STAT_BRDCSTRCV:
2672 *val = mxfep->mxfe_brdcstrcv;
2673 break;
2674
2675 case MAC_STAT_MULTIXMT:
2676 *val = mxfep->mxfe_multixmt;
2677 break;
2678
2679 case MAC_STAT_BRDCSTXMT:
2680 *val = mxfep->mxfe_brdcstxmt;
2681 break;
2682
2683 case MAC_STAT_IPACKETS:
2684 *val = mxfep->mxfe_ipackets;
2685 break;
2686
2687 case MAC_STAT_RBYTES:
2688 *val = mxfep->mxfe_rbytes;
2689 break;
2690
2691 case MAC_STAT_OPACKETS:
2692 *val = mxfep->mxfe_opackets;
2693 break;
2694
2695 case MAC_STAT_OBYTES:
2696 *val = mxfep->mxfe_obytes;
2697 break;
2698
2699 case MAC_STAT_NORCVBUF:
2700 *val = mxfep->mxfe_norcvbuf;
2701 break;
2702
2703 case MAC_STAT_NOXMTBUF:
2704 *val = mxfep->mxfe_noxmtbuf;
2705 break;
2706
2707 case MAC_STAT_COLLISIONS:
2708 *val = mxfep->mxfe_collisions;
2709 break;
2710
2711 case MAC_STAT_IERRORS:
2712 *val = mxfep->mxfe_errrcv;
2713 break;
2714
2715 case MAC_STAT_OERRORS:
2716 *val = mxfep->mxfe_errxmt;
2717 break;
2718
2719 case ETHER_STAT_LINK_DUPLEX:
2720 *val = mxfep->mxfe_duplex;
2721 break;
2722
2723 case ETHER_STAT_ALIGN_ERRORS:
2724 *val = mxfep->mxfe_align_errors;
2725 break;
2726
2727 case ETHER_STAT_FCS_ERRORS:
2728 *val = mxfep->mxfe_fcs_errors;
2729 break;
2730
2731 case ETHER_STAT_SQE_ERRORS:
2732 *val = mxfep->mxfe_sqe_errors;
2733 break;
2734
2735 case ETHER_STAT_DEFER_XMTS:
2736 *val = mxfep->mxfe_defer_xmts;
2737 break;
2738
2739 case ETHER_STAT_FIRST_COLLISIONS:
2740 *val = mxfep->mxfe_first_collisions;
2741 break;
2742
2743 case ETHER_STAT_MULTI_COLLISIONS:
2744 *val = mxfep->mxfe_multi_collisions;
2745 break;
2746
2747 case ETHER_STAT_TX_LATE_COLLISIONS:
2748 *val = mxfep->mxfe_tx_late_collisions;
2749 break;
2750
2751 case ETHER_STAT_EX_COLLISIONS:
2752 *val = mxfep->mxfe_ex_collisions;
2753 break;
2754
2755 case ETHER_STAT_MACXMT_ERRORS:
2756 *val = mxfep->mxfe_macxmt_errors;
2757 break;
2758
2759 case ETHER_STAT_CARRIER_ERRORS:
2760 *val = mxfep->mxfe_carrier_errors;
2761 break;
2762
2763 case ETHER_STAT_TOOLONG_ERRORS:
2764 *val = mxfep->mxfe_toolong_errors;
2765 break;
2766
2767 case ETHER_STAT_MACRCV_ERRORS:
2768 *val = mxfep->mxfe_macrcv_errors;
2769 break;
2770
2771 case MAC_STAT_OVERFLOWS:
2772 *val = mxfep->mxfe_overflow;
2773 break;
2774
2775 case MAC_STAT_UNDERFLOWS:
2776 *val = mxfep->mxfe_underflow;
2777 break;
2778
2779 case ETHER_STAT_TOOSHORT_ERRORS:
2780 *val = mxfep->mxfe_runt;
2781 break;
2782
2783 case ETHER_STAT_JABBER_ERRORS:
2784 *val = mxfep->mxfe_jabber;
2785 break;
2786
2787 case ETHER_STAT_ADV_CAP_100T4:
2788 *val = mxfep->mxfe_adv_100T4;
2789 break;
2790
2791 case ETHER_STAT_LP_CAP_100T4:
2792 *val = (mxfep->mxfe_anlpar & MII_ABILITY_100BASE_T4) ? 1 : 0;
2793 break;
2794
2795 case ETHER_STAT_CAP_100T4:
2796 *val = mxfep->mxfe_cap_100T4;
2797 break;
2798
2799 case ETHER_STAT_CAP_100FDX:
2800 *val = mxfep->mxfe_cap_100fdx;
2801 break;
2802
2803 case ETHER_STAT_CAP_100HDX:
2804 *val = mxfep->mxfe_cap_100hdx;
2805 break;
2806
2807 case ETHER_STAT_CAP_10FDX:
2808 *val = mxfep->mxfe_cap_10fdx;
2809 break;
2810
2811 case ETHER_STAT_CAP_10HDX:
2812 *val = mxfep->mxfe_cap_10hdx;
2813 break;
2814
2815 case ETHER_STAT_CAP_AUTONEG:
2816 *val = mxfep->mxfe_cap_aneg;
2817 break;
2818
2819 case ETHER_STAT_LINK_AUTONEG:
2820 *val = ((mxfep->mxfe_adv_aneg != 0) &&
2821 ((mxfep->mxfe_aner & MII_AN_EXP_LPCANAN) != 0));
2822 break;
2823
2824 case ETHER_STAT_ADV_CAP_100FDX:
2825 *val = mxfep->mxfe_adv_100fdx;
2826 break;
2827
2828 case ETHER_STAT_ADV_CAP_100HDX:
2829 *val = mxfep->mxfe_adv_100hdx;
2830 break;
2831
2832 case ETHER_STAT_ADV_CAP_10FDX:
2833 *val = mxfep->mxfe_adv_10fdx;
2834 break;
2835
2836 case ETHER_STAT_ADV_CAP_10HDX:
2837 *val = mxfep->mxfe_adv_10hdx;
2838 break;
2839
2840 case ETHER_STAT_ADV_CAP_AUTONEG:
2841 *val = mxfep->mxfe_adv_aneg;
2842 break;
2843
2844 case ETHER_STAT_LP_CAP_100FDX:
2845 *val = (mxfep->mxfe_anlpar & MII_ABILITY_100BASE_TX_FD) ? 1 : 0;
2846 break;
2847
2848 case ETHER_STAT_LP_CAP_100HDX:
2849 *val = (mxfep->mxfe_anlpar & MII_ABILITY_100BASE_TX) ? 1 : 0;
2850 break;
2851
2852 case ETHER_STAT_LP_CAP_10FDX:
2853 *val = (mxfep->mxfe_anlpar & MII_ABILITY_10BASE_T_FD) ? 1 : 0;
2854 break;
2855
2856 case ETHER_STAT_LP_CAP_10HDX:
2857 *val = (mxfep->mxfe_anlpar & MII_ABILITY_10BASE_T) ? 1 : 0;
2858 break;
2859
2860 case ETHER_STAT_LP_CAP_AUTONEG:
2861 *val = (mxfep->mxfe_aner & MII_AN_EXP_LPCANAN) ? 1 : 0;
2862 break;
2863
2864 case ETHER_STAT_XCVR_ADDR:
2865 *val = mxfep->mxfe_phyaddr;
2866 break;
2867
2868 case ETHER_STAT_XCVR_ID:
2869 *val = mxfep->mxfe_phyid;
2870 break;
2871
2872 case ETHER_STAT_XCVR_INUSE:
2873 *val = mxfep->mxfe_phyinuse;
2874 break;
2875
2876 default:
2877 return (ENOTSUP);
2878 }
2879 return (0);
2880 }
2881
2882 /*ARGSUSED*/
2883 int
mxfe_m_getprop(void * arg,const char * name,mac_prop_id_t num,uint_t sz,void * val)2884 mxfe_m_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
2885 void *val)
2886 {
2887 mxfe_t *mxfep = arg;
2888 int err = 0;
2889
2890 switch (num) {
2891 case MAC_PROP_DUPLEX:
2892 ASSERT(sz >= sizeof (link_duplex_t));
2893 bcopy(&mxfep->mxfe_duplex, val, sizeof (link_duplex_t));
2894 break;
2895
2896 case MAC_PROP_SPEED:
2897 ASSERT(sz >= sizeof (uint64_t));
2898 bcopy(&mxfep->mxfe_ifspeed, val, sizeof (uint64_t));
2899 break;
2900
2901 case MAC_PROP_AUTONEG:
2902 *(uint8_t *)val = mxfep->mxfe_adv_aneg;
2903 break;
2904
2905 case MAC_PROP_ADV_100FDX_CAP:
2906 case MAC_PROP_EN_100FDX_CAP:
2907 *(uint8_t *)val = mxfep->mxfe_adv_100fdx;
2908 break;
2909
2910 case MAC_PROP_ADV_100HDX_CAP:
2911 case MAC_PROP_EN_100HDX_CAP:
2912 *(uint8_t *)val = mxfep->mxfe_adv_100hdx;
2913 break;
2914
2915 case MAC_PROP_ADV_10FDX_CAP:
2916 case MAC_PROP_EN_10FDX_CAP:
2917 *(uint8_t *)val = mxfep->mxfe_adv_10fdx;
2918 break;
2919
2920 case MAC_PROP_ADV_10HDX_CAP:
2921 case MAC_PROP_EN_10HDX_CAP:
2922 *(uint8_t *)val = mxfep->mxfe_adv_10hdx;
2923 break;
2924
2925 case MAC_PROP_ADV_100T4_CAP:
2926 case MAC_PROP_EN_100T4_CAP:
2927 *(uint8_t *)val = mxfep->mxfe_adv_100T4;
2928 break;
2929
2930 default:
2931 err = ENOTSUP;
2932 }
2933
2934 return (err);
2935 }
2936
2937 /*ARGSUSED*/
2938 int
mxfe_m_setprop(void * arg,const char * name,mac_prop_id_t num,uint_t sz,const void * val)2939 mxfe_m_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
2940 const void *val)
2941 {
2942 mxfe_t *mxfep = arg;
2943 uint8_t *advp;
2944 uint8_t *capp;
2945
2946 switch (num) {
2947 case MAC_PROP_EN_100FDX_CAP:
2948 advp = &mxfep->mxfe_adv_100fdx;
2949 capp = &mxfep->mxfe_cap_100fdx;
2950 break;
2951
2952 case MAC_PROP_EN_100HDX_CAP:
2953 advp = &mxfep->mxfe_adv_100hdx;
2954 capp = &mxfep->mxfe_cap_100hdx;
2955 break;
2956
2957 case MAC_PROP_EN_10FDX_CAP:
2958 advp = &mxfep->mxfe_adv_10fdx;
2959 capp = &mxfep->mxfe_cap_10fdx;
2960 break;
2961
2962 case MAC_PROP_EN_10HDX_CAP:
2963 advp = &mxfep->mxfe_adv_10hdx;
2964 capp = &mxfep->mxfe_cap_10hdx;
2965 break;
2966
2967 case MAC_PROP_EN_100T4_CAP:
2968 advp = &mxfep->mxfe_adv_100T4;
2969 capp = &mxfep->mxfe_cap_100T4;
2970 break;
2971
2972 case MAC_PROP_AUTONEG:
2973 advp = &mxfep->mxfe_adv_aneg;
2974 capp = &mxfep->mxfe_cap_aneg;
2975 break;
2976
2977 default:
2978 return (ENOTSUP);
2979 }
2980
2981 if (*capp == 0) /* ensure phy can support value */
2982 return (ENOTSUP);
2983
2984 mutex_enter(&mxfep->mxfe_intrlock);
2985 mutex_enter(&mxfep->mxfe_xmtlock);
2986
2987 if (*advp != *(const uint8_t *)val) {
2988 *advp = *(const uint8_t *)val;
2989
2990 if ((mxfep->mxfe_flags & (MXFE_RUNNING|MXFE_SUSPENDED)) ==
2991 MXFE_RUNNING) {
2992 /*
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
2997 * progress.
2998 */
2999 mxfe_resetall(mxfep);
3000 }
3001 }
3002 mutex_exit(&mxfep->mxfe_xmtlock);
3003 mutex_exit(&mxfep->mxfe_intrlock);
3004
3005 return (0);
3006 }
3007
3008 static void
mxfe_m_propinfo(void * arg,const char * name,mac_prop_id_t num,mac_prop_info_handle_t mph)3009 mxfe_m_propinfo(void *arg, const char *name, mac_prop_id_t num,
3010 mac_prop_info_handle_t mph)
3011 {
3012 mxfe_t *mxfep = arg;
3013
3014 _NOTE(ARGUNUSED(name));
3015
3016 switch (num) {
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);
3025 break;
3026
3027 case MAC_PROP_AUTONEG:
3028 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_aneg);
3029 break;
3030
3031 case MAC_PROP_EN_100FDX_CAP:
3032 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_100fdx);
3033 break;
3034
3035 case MAC_PROP_EN_100HDX_CAP:
3036 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_100hdx);
3037 break;
3038
3039 case MAC_PROP_EN_10FDX_CAP:
3040 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_10fdx);
3041 break;
3042
3043 case MAC_PROP_EN_10HDX_CAP:
3044 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_10hdx);
3045 break;
3046
3047 case MAC_PROP_EN_100T4_CAP:
3048 mac_prop_info_set_default_uint8(mph, mxfep->mxfe_cap_100T4);
3049 break;
3050 }
3051 }
3052
3053 /*
3054 * Debugging and error reporting.
3055 */
3056 void
mxfe_error(dev_info_t * dip,char * fmt,...)3057 mxfe_error(dev_info_t *dip, char *fmt, ...)
3058 {
3059 va_list ap;
3060 char buf[256];
3061
3062 va_start(ap, fmt);
3063 (void) vsnprintf(buf, sizeof (buf), fmt, ap);
3064 va_end(ap);
3065
3066 if (dip) {
3067 cmn_err(CE_WARN, "%s%d: %s",
3068 ddi_driver_name(dip), ddi_get_instance(dip), buf);
3069 } else {
3070 cmn_err(CE_WARN, "mxfe: %s", buf);
3071 }
3072 }
3073
3074 #ifdef DEBUG
3075
3076 void
mxfe_dprintf(mxfe_t * mxfep,const char * func,int level,char * fmt,...)3077 mxfe_dprintf(mxfe_t *mxfep, const char *func, int level, char *fmt, ...)
3078 {
3079 va_list ap;
3080
3081 va_start(ap, fmt);
3082 if (mxfe_debug & level) {
3083 char tag[64];
3084 char buf[256];
3085
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));
3090 } else {
3091 (void) snprintf(tag, sizeof (tag), "mxfe");
3092 }
3093
3094 (void) snprintf(buf, sizeof (buf), "%s: %s: %s\n", tag,
3095 func, fmt);
3096
3097 vcmn_err(CE_CONT, buf, ap);
3098 }
3099 va_end(ap);
3100 }
3101
3102 #endif
3103