1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010-2013, by Broadcom, Inc.
24 * All Rights Reserved.
25 */
26
27 /*
28 * Copyright (c) 2002, 2010, Oracle and/or its affiliates.
29 * All rights reserved.
30 */
31
32 #include "bge_impl.h"
33 #include <sys/sdt.h>
34 #include <sys/mac_provider.h>
35 #include <sys/mac.h>
36 #include <sys/mac_flow.h>
37
38
39 #ifndef STRINGIFY
40 #define XSTRINGIFY(x) #x
41 #define STRINGIFY(x) XSTRINGIFY(x)
42 #endif
43
44 /*
45 * This is the string displayed by modinfo, etc.
46 */
47 static char bge_ident[] = "Broadcom Gb Ethernet";
48
49 /*
50 * Property names
51 */
52 static char debug_propname[] = "bge-debug-flags";
53 static char clsize_propname[] = "cache-line-size";
54 static char latency_propname[] = "latency-timer";
55 static char localmac_boolname[] = "local-mac-address?";
56 static char localmac_propname[] = "local-mac-address";
57 static char macaddr_propname[] = "mac-address";
58 static char subdev_propname[] = "subsystem-id";
59 static char subven_propname[] = "subsystem-vendor-id";
60 static char rxrings_propname[] = "bge-rx-rings";
61 static char txrings_propname[] = "bge-tx-rings";
62 static char eee_propname[] = "bge-eee";
63 static char fm_cap[] = "fm-capable";
64 static char default_mtu[] = "default_mtu";
65
66 static int bge_add_intrs(bge_t *, int);
67 static void bge_rem_intrs(bge_t *);
68 static int bge_unicst_set(void *, const uint8_t *, int);
69 static int bge_addmac(void *, const uint8_t *);
70 static int bge_remmac(void *, const uint8_t *);
71
72 /*
73 * Describes the chip's DMA engine
74 */
75 static ddi_dma_attr_t dma_attr = {
76 DMA_ATTR_V0, /* dma_attr_version */
77 0x0000000000000000ull, /* dma_attr_addr_lo */
78 0xFFFFFFFFFFFFFFFFull, /* dma_attr_addr_hi */
79 0x00000000FFFFFFFFull, /* dma_attr_count_max */
80 0x0000000000000001ull, /* dma_attr_align */
81 0x00000FFF, /* dma_attr_burstsizes */
82 0x00000001, /* dma_attr_minxfer */
83 0x000000000000FFFFull, /* dma_attr_maxxfer */
84 0x00000000FFFFFFFFull, /* dma_attr_seg */
85 1, /* dma_attr_sgllen */
86 0x00000001, /* dma_attr_granular */
87 DDI_DMA_FLAGERR /* dma_attr_flags */
88 };
89
90 /*
91 * PIO access attributes for registers
92 */
93 static ddi_device_acc_attr_t bge_reg_accattr = {
94 DDI_DEVICE_ATTR_V1,
95 DDI_NEVERSWAP_ACC,
96 DDI_STRICTORDER_ACC,
97 DDI_FLAGERR_ACC
98 };
99
100 /*
101 * DMA access attributes for descriptors: NOT to be byte swapped.
102 */
103 static ddi_device_acc_attr_t bge_desc_accattr = {
104 DDI_DEVICE_ATTR_V0,
105 DDI_NEVERSWAP_ACC,
106 DDI_STRICTORDER_ACC
107 };
108
109 /*
110 * DMA access attributes for data: NOT to be byte swapped.
111 */
112 static ddi_device_acc_attr_t bge_data_accattr = {
113 DDI_DEVICE_ATTR_V0,
114 DDI_NEVERSWAP_ACC,
115 DDI_STRICTORDER_ACC
116 };
117
118 static int bge_m_start(void *);
119 static void bge_m_stop(void *);
120 static int bge_m_promisc(void *, boolean_t);
121 static int bge_m_unicst(void * pArg, const uint8_t *);
122 static int bge_m_multicst(void *, boolean_t, const uint8_t *);
123 static void bge_m_resources(void * arg);
124 static void bge_m_ioctl(void *, queue_t *, mblk_t *);
125 static boolean_t bge_m_getcapab(void *, mac_capab_t, void *);
126 static int bge_unicst_set(void *, const uint8_t *,
127 int);
128 static int bge_m_setprop(void *, const char *, mac_prop_id_t,
129 uint_t, const void *);
130 static int bge_m_getprop(void *, const char *, mac_prop_id_t,
131 uint_t, void *);
132 static void bge_m_propinfo(void *, const char *, mac_prop_id_t,
133 mac_prop_info_handle_t);
134 static int bge_set_priv_prop(bge_t *, const char *, uint_t,
135 const void *);
136 static int bge_get_priv_prop(bge_t *, const char *, uint_t,
137 void *);
138 static void bge_priv_propinfo(const char *,
139 mac_prop_info_handle_t);
140
141 static mac_callbacks_t bge_m_callbacks = {
142 MC_IOCTL
143 #ifdef MC_RESOURCES
144 | MC_RESOURCES
145 #endif
146 #ifdef MC_SETPROP
147 | MC_SETPROP
148 #endif
149 #ifdef MC_GETPROP
150 | MC_GETPROP
151 #endif
152 #ifdef MC_PROPINFO
153 | MC_PROPINFO
154 #endif
155 | MC_GETCAPAB,
156 bge_m_stat,
157 bge_m_start,
158 bge_m_stop,
159 bge_m_promisc,
160 bge_m_multicst,
161 bge_m_unicst,
162 bge_m_tx,
163 #ifdef MC_RESOURCES
164 bge_m_resources,
165 #else
166 NULL,
167 #endif
168 bge_m_ioctl,
169 bge_m_getcapab,
170 #ifdef MC_OPEN
171 NULL,
172 NULL,
173 #endif
174 #ifdef MC_SETPROP
175 bge_m_setprop,
176 #endif
177 #ifdef MC_GETPROP
178 bge_m_getprop,
179 #endif
180 #ifdef MC_PROPINFO
181 bge_m_propinfo
182 #endif
183 };
184
185 char *bge_priv_prop[] = {
186 "_adv_asym_pause_cap",
187 "_adv_pause_cap",
188 "_drain_max",
189 "_msi_cnt",
190 "_rx_intr_coalesce_blank_time",
191 "_tx_intr_coalesce_blank_time",
192 "_rx_intr_coalesce_pkt_cnt",
193 "_tx_intr_coalesce_pkt_cnt",
194 NULL
195 };
196
197 uint8_t zero_addr[6] = {0, 0, 0, 0, 0, 0};
198 /*
199 * ========== Transmit and receive ring reinitialisation ==========
200 */
201
202 /*
203 * These <reinit> routines each reset the specified ring to an initial
204 * state, assuming that the corresponding <init> routine has already
205 * been called exactly once.
206 */
207
208 static void
209 bge_reinit_send_ring(send_ring_t *srp)
210 {
211 bge_queue_t *txbuf_queue;
212 bge_queue_item_t *txbuf_head;
213 sw_txbuf_t *txbuf;
214 sw_sbd_t *ssbdp;
215 uint32_t slot;
216
217 /*
218 * Reinitialise control variables ...
219 */
220 srp->tx_flow = 0;
221 srp->tx_next = 0;
222 srp->txfill_next = 0;
223 srp->tx_free = srp->desc.nslots;
224 ASSERT(mutex_owned(srp->tc_lock));
225 srp->tc_next = 0;
226 srp->txpkt_next = 0;
227 srp->tx_block = 0;
228 srp->tx_nobd = 0;
229 srp->tx_nobuf = 0;
230
231 /*
232 * Initialize the tx buffer push queue
233 */
234 mutex_enter(srp->freetxbuf_lock);
235 mutex_enter(srp->txbuf_lock);
236 txbuf_queue = &srp->freetxbuf_queue;
237 txbuf_queue->head = NULL;
238 txbuf_queue->count = 0;
239 txbuf_queue->lock = srp->freetxbuf_lock;
240 srp->txbuf_push_queue = txbuf_queue;
241
242 /*
243 * Initialize the tx buffer pop queue
244 */
245 txbuf_queue = &srp->txbuf_queue;
246 txbuf_queue->head = NULL;
247 txbuf_queue->count = 0;
248 txbuf_queue->lock = srp->txbuf_lock;
249 srp->txbuf_pop_queue = txbuf_queue;
250 txbuf_head = srp->txbuf_head;
251 txbuf = srp->txbuf;
252 for (slot = 0; slot < srp->tx_buffers; ++slot) {
253 txbuf_head->item = txbuf;
254 txbuf_head->next = txbuf_queue->head;
255 txbuf_queue->head = txbuf_head;
256 txbuf_queue->count++;
257 txbuf++;
258 txbuf_head++;
259 }
260 mutex_exit(srp->txbuf_lock);
261 mutex_exit(srp->freetxbuf_lock);
262
263 /*
264 * Zero and sync all the h/w Send Buffer Descriptors
265 */
266 DMA_ZERO(srp->desc);
267 DMA_SYNC(srp->desc, DDI_DMA_SYNC_FORDEV);
268 bzero(srp->pktp, BGE_SEND_BUF_MAX * sizeof (*srp->pktp));
269 ssbdp = srp->sw_sbds;
270 for (slot = 0; slot < srp->desc.nslots; ++ssbdp, ++slot)
271 ssbdp->pbuf = NULL;
272 }
273
274 static void
275 bge_reinit_recv_ring(recv_ring_t *rrp)
276 {
277 /*
278 * Reinitialise control variables ...
279 */
280 rrp->rx_next = 0;
281 }
282
283 static void
284 bge_reinit_buff_ring(buff_ring_t *brp, uint32_t ring)
285 {
286 bge_rbd_t *hw_rbd_p;
287 sw_rbd_t *srbdp;
288 uint32_t bufsize;
289 uint32_t nslots;
290 uint32_t slot;
291
292 static uint16_t ring_type_flag[BGE_BUFF_RINGS_MAX] = {
293 RBD_FLAG_STD_RING,
294 RBD_FLAG_JUMBO_RING,
295 RBD_FLAG_MINI_RING
296 };
297
298 /*
299 * Zero, initialise and sync all the h/w Receive Buffer Descriptors
300 * Note: all the remaining fields (<type>, <flags>, <ip_cksum>,
301 * <tcp_udp_cksum>, <error_flag>, <vlan_tag>, and <reserved>)
302 * should be zeroed, and so don't need to be set up specifically
303 * once the whole area has been cleared.
304 */
305 DMA_ZERO(brp->desc);
306
307 hw_rbd_p = DMA_VPTR(brp->desc);
308 nslots = brp->desc.nslots;
309 ASSERT(brp->buf[0].nslots == nslots/BGE_SPLIT);
310 bufsize = brp->buf[0].size;
311 srbdp = brp->sw_rbds;
312 for (slot = 0; slot < nslots; ++hw_rbd_p, ++srbdp, ++slot) {
313 hw_rbd_p->host_buf_addr = srbdp->pbuf.cookie.dmac_laddress;
314 hw_rbd_p->index = (uint16_t)slot;
315 hw_rbd_p->len = (uint16_t)bufsize;
316 hw_rbd_p->opaque = srbdp->pbuf.token;
317 hw_rbd_p->flags |= ring_type_flag[ring];
318 }
319
320 DMA_SYNC(brp->desc, DDI_DMA_SYNC_FORDEV);
321
322 /*
323 * Finally, reinitialise the ring control variables ...
324 */
325 brp->rf_next = (nslots != 0) ? (nslots-1) : 0;
326 }
327
328 /*
329 * Reinitialize all rings
330 */
331 static void
332 bge_reinit_rings(bge_t *bgep)
333 {
334 uint32_t ring;
335
336 ASSERT(mutex_owned(bgep->genlock));
337
338 /*
339 * Send Rings ...
340 */
341 for (ring = 0; ring < bgep->chipid.tx_rings; ++ring)
342 bge_reinit_send_ring(&bgep->send[ring]);
343
344 /*
345 * Receive Return Rings ...
346 */
347 for (ring = 0; ring < bgep->chipid.rx_rings; ++ring)
348 bge_reinit_recv_ring(&bgep->recv[ring]);
349
350 /*
351 * Receive Producer Rings ...
352 */
353 for (ring = 0; ring < BGE_BUFF_RINGS_USED; ++ring)
354 bge_reinit_buff_ring(&bgep->buff[ring], ring);
355 }
356
357 /*
358 * ========== Internal state management entry points ==========
359 */
360
361 #undef BGE_DBG
362 #define BGE_DBG BGE_DBG_NEMO /* debug flag for this code */
363
364 /*
365 * These routines provide all the functionality required by the
366 * corresponding GLD entry points, but don't update the GLD state
367 * so they can be called internally without disturbing our record
368 * of what GLD thinks we should be doing ...
369 */
370
371 /*
372 * bge_reset() -- reset h/w & rings to initial state
373 */
374 static int
375 #ifdef BGE_IPMI_ASF
376 bge_reset(bge_t *bgep, uint_t asf_mode)
377 #else
378 bge_reset(bge_t *bgep)
379 #endif
380 {
381 uint32_t ring;
382 int retval;
383
384 BGE_TRACE(("bge_reset($%p)", (void *)bgep));
385
386 ASSERT(mutex_owned(bgep->genlock));
387
388 /*
389 * Grab all the other mutexes in the world (this should
390 * ensure no other threads are manipulating driver state)
391 */
392 for (ring = 0; ring < BGE_RECV_RINGS_MAX; ++ring)
393 mutex_enter(bgep->recv[ring].rx_lock);
394 for (ring = 0; ring < BGE_BUFF_RINGS_MAX; ++ring)
395 mutex_enter(bgep->buff[ring].rf_lock);
396 rw_enter(bgep->errlock, RW_WRITER);
397 for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
398 mutex_enter(bgep->send[ring].tx_lock);
399 for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
400 mutex_enter(bgep->send[ring].tc_lock);
401
402 #ifdef BGE_IPMI_ASF
403 retval = bge_chip_reset(bgep, B_TRUE, asf_mode);
404 #else
405 retval = bge_chip_reset(bgep, B_TRUE);
406 #endif
407 bge_reinit_rings(bgep);
408
409 /*
410 * Free the world ...
411 */
412 for (ring = BGE_SEND_RINGS_MAX; ring-- > 0; )
413 mutex_exit(bgep->send[ring].tc_lock);
414 for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
415 mutex_exit(bgep->send[ring].tx_lock);
416 rw_exit(bgep->errlock);
417 for (ring = BGE_BUFF_RINGS_MAX; ring-- > 0; )
418 mutex_exit(bgep->buff[ring].rf_lock);
419 for (ring = BGE_RECV_RINGS_MAX; ring-- > 0; )
420 mutex_exit(bgep->recv[ring].rx_lock);
421
422 BGE_DEBUG(("bge_reset($%p) done", (void *)bgep));
423 return (retval);
424 }
425
426 /*
427 * bge_stop() -- stop processing, don't reset h/w or rings
428 */
429 static void
430 bge_stop(bge_t *bgep)
431 {
432 BGE_TRACE(("bge_stop($%p)", (void *)bgep));
433
434 ASSERT(mutex_owned(bgep->genlock));
435
436 #ifdef BGE_IPMI_ASF
437 if (bgep->asf_enabled) {
438 bgep->asf_pseudostop = B_TRUE;
439 } else {
440 #endif
441 bge_chip_stop(bgep, B_FALSE);
442 #ifdef BGE_IPMI_ASF
443 }
444 #endif
445
446 BGE_DEBUG(("bge_stop($%p) done", (void *)bgep));
447 }
448
449 /*
450 * bge_start() -- start transmitting/receiving
451 */
452 static int
453 bge_start(bge_t *bgep, boolean_t reset_phys)
454 {
455 int retval;
456
457 BGE_TRACE(("bge_start($%p, %d)", (void *)bgep, reset_phys));
458
459 ASSERT(mutex_owned(bgep->genlock));
460
461 /*
462 * Start chip processing, including enabling interrupts
463 */
464 retval = bge_chip_start(bgep, reset_phys);
465
466 BGE_DEBUG(("bge_start($%p, %d) done", (void *)bgep, reset_phys));
467 return (retval);
468 }
469
470 /*
471 * bge_restart - restart transmitting/receiving after error or suspend
472 */
473 int
474 bge_restart(bge_t *bgep, boolean_t reset_phys)
475 {
476 int retval = DDI_SUCCESS;
477 ASSERT(mutex_owned(bgep->genlock));
478
479 #ifdef BGE_IPMI_ASF
480 if (bgep->asf_enabled) {
481 if (bge_reset(bgep, ASF_MODE_POST_INIT) != DDI_SUCCESS)
482 retval = DDI_FAILURE;
483 } else
484 if (bge_reset(bgep, ASF_MODE_NONE) != DDI_SUCCESS)
485 retval = DDI_FAILURE;
486 #else
487 if (bge_reset(bgep) != DDI_SUCCESS)
488 retval = DDI_FAILURE;
489 #endif
490 if (bgep->bge_mac_state == BGE_MAC_STARTED) {
491 if (bge_start(bgep, reset_phys) != DDI_SUCCESS)
492 retval = DDI_FAILURE;
493 bgep->watchdog = 0;
494 ddi_trigger_softintr(bgep->drain_id);
495 }
496
497 BGE_DEBUG(("bge_restart($%p, %d) done", (void *)bgep, reset_phys));
498 return (retval);
499 }
500
501
502 /*
503 * ========== Nemo-required management entry points ==========
504 */
505
506 #undef BGE_DBG
507 #define BGE_DBG BGE_DBG_NEMO /* debug flag for this code */
508
509 /*
510 * bge_m_stop() -- stop transmitting/receiving
511 */
512 static void
513 bge_m_stop(void *arg)
514 {
515 bge_t *bgep = arg; /* private device info */
516 send_ring_t *srp;
517 uint32_t ring;
518
519 BGE_TRACE(("bge_m_stop($%p)", arg));
520
521 /*
522 * Just stop processing, then record new GLD state
523 */
524 mutex_enter(bgep->genlock);
525 if (!(bgep->progress & PROGRESS_INTR)) {
526 /* can happen during autorecovery */
527 bgep->bge_chip_state = BGE_CHIP_STOPPED;
528 } else
529 bge_stop(bgep);
530
531 bgep->link_state = LINK_STATE_UNKNOWN;
532 mac_link_update(bgep->mh, bgep->link_state);
533
534 /*
535 * Free the possible tx buffers allocated in tx process.
536 */
537 #ifdef BGE_IPMI_ASF
538 if (!bgep->asf_pseudostop)
539 #endif
540 {
541 rw_enter(bgep->errlock, RW_WRITER);
542 for (ring = 0; ring < bgep->chipid.tx_rings; ++ring) {
543 srp = &bgep->send[ring];
544 mutex_enter(srp->tx_lock);
545 if (srp->tx_array > 1)
546 bge_free_txbuf_arrays(srp);
547 mutex_exit(srp->tx_lock);
548 }
549 rw_exit(bgep->errlock);
550 }
551 bgep->bge_mac_state = BGE_MAC_STOPPED;
552 BGE_DEBUG(("bge_m_stop($%p) done", arg));
553 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
554 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
555 mutex_exit(bgep->genlock);
556 }
557
558 /*
559 * bge_m_start() -- start transmitting/receiving
560 */
561 static int
562 bge_m_start(void *arg)
563 {
564 bge_t *bgep = arg; /* private device info */
565
566 BGE_TRACE(("bge_m_start($%p)", arg));
567
568 /*
569 * Start processing and record new GLD state
570 */
571 mutex_enter(bgep->genlock);
572 if (!(bgep->progress & PROGRESS_INTR)) {
573 /* can happen during autorecovery */
574 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
575 mutex_exit(bgep->genlock);
576 return (EIO);
577 }
578 #ifdef BGE_IPMI_ASF
579 if (bgep->asf_enabled) {
580 if ((bgep->asf_status == ASF_STAT_RUN) &&
581 (bgep->asf_pseudostop)) {
582 bgep->bge_mac_state = BGE_MAC_STARTED;
583 /* forcing a mac link update here */
584 bge_phys_check(bgep);
585 bgep->link_state = (bgep->param_link_up) ? LINK_STATE_UP :
586 LINK_STATE_DOWN;
587 mac_link_update(bgep->mh, bgep->link_state);
588 mutex_exit(bgep->genlock);
589 return (0);
590 }
591 }
592 if (bge_reset(bgep, ASF_MODE_INIT) != DDI_SUCCESS) {
593 #else
594 if (bge_reset(bgep) != DDI_SUCCESS) {
595 #endif
596 (void) bge_check_acc_handle(bgep, bgep->cfg_handle);
597 (void) bge_check_acc_handle(bgep, bgep->io_handle);
598 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
599 mutex_exit(bgep->genlock);
600 return (EIO);
601 }
602 if (bge_start(bgep, B_TRUE) != DDI_SUCCESS) {
603 (void) bge_check_acc_handle(bgep, bgep->cfg_handle);
604 (void) bge_check_acc_handle(bgep, bgep->io_handle);
605 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
606 mutex_exit(bgep->genlock);
607 return (EIO);
608 }
609 bgep->watchdog = 0;
610 bgep->bge_mac_state = BGE_MAC_STARTED;
611 BGE_DEBUG(("bge_m_start($%p) done", arg));
612
613 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
614 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
615 mutex_exit(bgep->genlock);
616 return (EIO);
617 }
618 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
619 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
620 mutex_exit(bgep->genlock);
621 return (EIO);
622 }
623 #ifdef BGE_IPMI_ASF
624 if (bgep->asf_enabled) {
625 if (bgep->asf_status != ASF_STAT_RUN) {
626 /* start ASF heart beat */
627 bgep->asf_timeout_id = timeout(bge_asf_heartbeat,
628 (void *)bgep,
629 drv_usectohz(BGE_ASF_HEARTBEAT_INTERVAL));
630 bgep->asf_status = ASF_STAT_RUN;
631 }
632 }
633 #endif
634 mutex_exit(bgep->genlock);
635
636 return (0);
637 }
638
639 /*
640 * bge_unicst_set() -- set the physical network address
641 */
642 static int
643 bge_unicst_set(void *arg, const uint8_t *macaddr, int slot)
644 {
645 bge_t *bgep = arg; /* private device info */
646
647 BGE_TRACE(("bge_unicst_set($%p, %s)", arg,
648 ether_sprintf((void *)macaddr)));
649 /*
650 * Remember the new current address in the driver state
651 * Sync the chip's idea of the address too ...
652 */
653 mutex_enter(bgep->genlock);
654 if (!(bgep->progress & PROGRESS_INTR)) {
655 /* can happen during autorecovery */
656 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
657 mutex_exit(bgep->genlock);
658 return (EIO);
659 }
660 ethaddr_copy(macaddr, bgep->curr_addr[slot].addr);
661 #ifdef BGE_IPMI_ASF
662 if (bge_chip_sync(bgep, B_FALSE) == DDI_FAILURE) {
663 #else
664 if (bge_chip_sync(bgep) == DDI_FAILURE) {
665 #endif
666 (void) bge_check_acc_handle(bgep, bgep->cfg_handle);
667 (void) bge_check_acc_handle(bgep, bgep->io_handle);
668 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
669 mutex_exit(bgep->genlock);
670 return (EIO);
671 }
672 #ifdef BGE_IPMI_ASF
673 if (bgep->asf_enabled) {
674 /*
675 * The above bge_chip_sync() function wrote the ethernet MAC
676 * addresses registers which destroyed the IPMI/ASF sideband.
677 * Here, we have to reset chip to make IPMI/ASF sideband work.
678 */
679 if (bgep->asf_status == ASF_STAT_RUN) {
680 /*
681 * We must stop ASF heart beat before bge_chip_stop(),
682 * otherwise some computers (ex. IBM HS20 blade server)
683 * may crash.
684 */
685 bge_asf_update_status(bgep);
686 bge_asf_stop_timer(bgep);
687 bgep->asf_status = ASF_STAT_STOP;
688
689 bge_asf_pre_reset_operations(bgep, BGE_INIT_RESET);
690 }
691 bge_chip_stop(bgep, B_FALSE);
692
693 if (bge_restart(bgep, B_FALSE) == DDI_FAILURE) {
694 (void) bge_check_acc_handle(bgep, bgep->cfg_handle);
695 (void) bge_check_acc_handle(bgep, bgep->io_handle);
696 ddi_fm_service_impact(bgep->devinfo,
697 DDI_SERVICE_DEGRADED);
698 mutex_exit(bgep->genlock);
699 return (EIO);
700 }
701
702 /*
703 * Start our ASF heartbeat counter as soon as possible.
704 */
705 if (bgep->asf_status != ASF_STAT_RUN) {
706 /* start ASF heart beat */
707 bgep->asf_timeout_id = timeout(bge_asf_heartbeat,
708 (void *)bgep,
709 drv_usectohz(BGE_ASF_HEARTBEAT_INTERVAL));
710 bgep->asf_status = ASF_STAT_RUN;
711 }
712 }
713 #endif
714 BGE_DEBUG(("bge_unicst_set($%p) done", arg));
715 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
716 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
717 mutex_exit(bgep->genlock);
718 return (EIO);
719 }
720 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
721 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
722 mutex_exit(bgep->genlock);
723 return (EIO);
724 }
725 mutex_exit(bgep->genlock);
726
727 return (0);
728 }
729
730 extern void bge_wake_factotum(bge_t *);
731
732 static boolean_t
733 bge_param_locked(mac_prop_id_t pr_num)
734 {
735 /*
736 * All adv_* parameters are locked (read-only) while
737 * the device is in any sort of loopback mode ...
738 */
739 switch (pr_num) {
740 case MAC_PROP_ADV_1000FDX_CAP:
741 case MAC_PROP_EN_1000FDX_CAP:
742 case MAC_PROP_ADV_1000HDX_CAP:
743 case MAC_PROP_EN_1000HDX_CAP:
744 case MAC_PROP_ADV_100FDX_CAP:
745 case MAC_PROP_EN_100FDX_CAP:
746 case MAC_PROP_ADV_100HDX_CAP:
747 case MAC_PROP_EN_100HDX_CAP:
748 case MAC_PROP_ADV_10FDX_CAP:
749 case MAC_PROP_EN_10FDX_CAP:
750 case MAC_PROP_ADV_10HDX_CAP:
751 case MAC_PROP_EN_10HDX_CAP:
752 case MAC_PROP_AUTONEG:
753 case MAC_PROP_FLOWCTRL:
754 return (B_TRUE);
755 }
756 return (B_FALSE);
757 }
758 /*
759 * callback functions for set/get of properties
760 */
761 static int
762 bge_m_setprop(void *barg, const char *pr_name, mac_prop_id_t pr_num,
763 uint_t pr_valsize, const void *pr_val)
764 {
765 bge_t *bgep = barg;
766 int err = 0;
767 uint32_t cur_mtu, new_mtu;
768 link_flowctrl_t fl;
769
770 mutex_enter(bgep->genlock);
771 if (bgep->param_loop_mode != BGE_LOOP_NONE &&
772 bge_param_locked(pr_num)) {
773 /*
774 * All adv_* parameters are locked (read-only)
775 * while the device is in any sort of loopback mode.
776 */
777 mutex_exit(bgep->genlock);
778 return (EBUSY);
779 }
780 if ((bgep->chipid.flags & CHIP_FLAG_SERDES) &&
781 ((pr_num == MAC_PROP_EN_100FDX_CAP) ||
782 (pr_num == MAC_PROP_EN_100HDX_CAP) ||
783 (pr_num == MAC_PROP_EN_10FDX_CAP) ||
784 (pr_num == MAC_PROP_EN_10HDX_CAP))) {
785 /*
786 * these properties are read/write on copper,
787 * read-only and 0 on serdes
788 */
789 mutex_exit(bgep->genlock);
790 return (ENOTSUP);
791 }
792 if (DEVICE_5906_SERIES_CHIPSETS(bgep) &&
793 ((pr_num == MAC_PROP_EN_1000FDX_CAP) ||
794 (pr_num == MAC_PROP_EN_1000HDX_CAP))) {
795 mutex_exit(bgep->genlock);
796 return (ENOTSUP);
797 }
798
799 switch (pr_num) {
800 case MAC_PROP_EN_1000FDX_CAP:
801 bgep->param_en_1000fdx = *(uint8_t *)pr_val;
802 bgep->param_adv_1000fdx = *(uint8_t *)pr_val;
803 goto reprogram;
804 case MAC_PROP_EN_1000HDX_CAP:
805 bgep->param_en_1000hdx = *(uint8_t *)pr_val;
806 bgep->param_adv_1000hdx = *(uint8_t *)pr_val;
807 goto reprogram;
808 case MAC_PROP_EN_100FDX_CAP:
809 bgep->param_en_100fdx = *(uint8_t *)pr_val;
810 bgep->param_adv_100fdx = *(uint8_t *)pr_val;
811 goto reprogram;
812 case MAC_PROP_EN_100HDX_CAP:
813 bgep->param_en_100hdx = *(uint8_t *)pr_val;
814 bgep->param_adv_100hdx = *(uint8_t *)pr_val;
815 goto reprogram;
816 case MAC_PROP_EN_10FDX_CAP:
817 bgep->param_en_10fdx = *(uint8_t *)pr_val;
818 bgep->param_adv_10fdx = *(uint8_t *)pr_val;
819 goto reprogram;
820 case MAC_PROP_EN_10HDX_CAP:
821 bgep->param_en_10hdx = *(uint8_t *)pr_val;
822 bgep->param_adv_10hdx = *(uint8_t *)pr_val;
823 reprogram:
824 if (err == 0 && bge_reprogram(bgep) == IOC_INVAL)
825 err = EINVAL;
826 break;
827 case MAC_PROP_ADV_1000FDX_CAP:
828 case MAC_PROP_ADV_1000HDX_CAP:
829 case MAC_PROP_ADV_100FDX_CAP:
830 case MAC_PROP_ADV_100HDX_CAP:
831 case MAC_PROP_ADV_10FDX_CAP:
832 case MAC_PROP_ADV_10HDX_CAP:
833 case MAC_PROP_STATUS:
834 case MAC_PROP_SPEED:
835 case MAC_PROP_DUPLEX:
836 err = ENOTSUP; /* read-only prop. Can't set this */
837 break;
838 case MAC_PROP_AUTONEG:
839 bgep->param_adv_autoneg = *(uint8_t *)pr_val;
840 if (bge_reprogram(bgep) == IOC_INVAL)
841 err = EINVAL;
842 break;
843 case MAC_PROP_MTU:
844 cur_mtu = bgep->chipid.default_mtu;
845 bcopy(pr_val, &new_mtu, sizeof (new_mtu));
846
847 if (new_mtu == cur_mtu) {
848 err = 0;
849 break;
850 }
851 if (new_mtu < BGE_DEFAULT_MTU ||
852 new_mtu > BGE_MAXIMUM_MTU) {
853 err = EINVAL;
854 break;
855 }
856 if ((new_mtu > BGE_DEFAULT_MTU) &&
857 (bgep->chipid.flags & CHIP_FLAG_NO_JUMBO)) {
858 err = EINVAL;
859 break;
860 }
861 if (bgep->bge_mac_state == BGE_MAC_STARTED) {
862 err = EBUSY;
863 break;
864 }
865 bgep->chipid.default_mtu = new_mtu;
866 if (bge_chip_id_init(bgep)) {
867 err = EINVAL;
868 break;
869 }
870 bgep->bge_dma_error = B_TRUE;
871 bgep->manual_reset = B_TRUE;
872 bge_chip_stop(bgep, B_TRUE);
873 bge_wake_factotum(bgep);
874 err = 0;
875 break;
876 case MAC_PROP_FLOWCTRL:
877 bcopy(pr_val, &fl, sizeof (fl));
878 switch (fl) {
879 default:
880 err = ENOTSUP;
881 break;
882 case LINK_FLOWCTRL_NONE:
883 bgep->param_adv_pause = 0;
884 bgep->param_adv_asym_pause = 0;
885
886 bgep->param_link_rx_pause = B_FALSE;
887 bgep->param_link_tx_pause = B_FALSE;
888 break;
889 case LINK_FLOWCTRL_RX:
890 bgep->param_adv_pause = 1;
891 bgep->param_adv_asym_pause = 1;
892
893 bgep->param_link_rx_pause = B_TRUE;
894 bgep->param_link_tx_pause = B_FALSE;
895 break;
896 case LINK_FLOWCTRL_TX:
897 bgep->param_adv_pause = 0;
898 bgep->param_adv_asym_pause = 1;
899
900 bgep->param_link_rx_pause = B_FALSE;
901 bgep->param_link_tx_pause = B_TRUE;
902 break;
903 case LINK_FLOWCTRL_BI:
904 bgep->param_adv_pause = 1;
905 bgep->param_adv_asym_pause = 0;
906
907 bgep->param_link_rx_pause = B_TRUE;
908 bgep->param_link_tx_pause = B_TRUE;
909 break;
910 }
911
912 if (err == 0) {
913 if (bge_reprogram(bgep) == IOC_INVAL)
914 err = EINVAL;
915 }
916
917 break;
918 case MAC_PROP_PRIVATE:
919 err = bge_set_priv_prop(bgep, pr_name, pr_valsize,
920 pr_val);
921 break;
922 default:
923 err = ENOTSUP;
924 break;
925 }
926 mutex_exit(bgep->genlock);
927 return (err);
928 }
929
930 /* ARGSUSED */
931 static int
932 bge_m_getprop(void *barg, const char *pr_name, mac_prop_id_t pr_num,
933 uint_t pr_valsize, void *pr_val)
934 {
935 bge_t *bgep = barg;
936 int err = 0;
937
938 switch (pr_num) {
939 case MAC_PROP_DUPLEX:
940 ASSERT(pr_valsize >= sizeof (link_duplex_t));
941 bcopy(&bgep->param_link_duplex, pr_val,
942 sizeof (link_duplex_t));
943 break;
944 case MAC_PROP_SPEED: {
945 uint64_t speed = bgep->param_link_speed * 1000000ull;
946
947 ASSERT(pr_valsize >= sizeof (speed));
948 bcopy(&speed, pr_val, sizeof (speed));
949 break;
950 }
951 case MAC_PROP_STATUS:
952 ASSERT(pr_valsize >= sizeof (link_state_t));
953 bcopy(&bgep->link_state, pr_val,
954 sizeof (link_state_t));
955 break;
956 case MAC_PROP_AUTONEG:
957 *(uint8_t *)pr_val = bgep->param_adv_autoneg;
958 break;
959 case MAC_PROP_FLOWCTRL: {
960 link_flowctrl_t fl;
961
962 ASSERT(pr_valsize >= sizeof (fl));
963
964 if (bgep->param_link_rx_pause &&
965 !bgep->param_link_tx_pause)
966 fl = LINK_FLOWCTRL_RX;
967
968 if (!bgep->param_link_rx_pause &&
969 !bgep->param_link_tx_pause)
970 fl = LINK_FLOWCTRL_NONE;
971
972 if (!bgep->param_link_rx_pause &&
973 bgep->param_link_tx_pause)
974 fl = LINK_FLOWCTRL_TX;
975
976 if (bgep->param_link_rx_pause &&
977 bgep->param_link_tx_pause)
978 fl = LINK_FLOWCTRL_BI;
979 bcopy(&fl, pr_val, sizeof (fl));
980 break;
981 }
982 case MAC_PROP_ADV_1000FDX_CAP:
983 *(uint8_t *)pr_val = bgep->param_adv_1000fdx;
984 break;
985 case MAC_PROP_EN_1000FDX_CAP:
986 *(uint8_t *)pr_val = bgep->param_en_1000fdx;
987 break;
988 case MAC_PROP_ADV_1000HDX_CAP:
989 *(uint8_t *)pr_val = bgep->param_adv_1000hdx;
990 break;
991 case MAC_PROP_EN_1000HDX_CAP:
992 *(uint8_t *)pr_val = bgep->param_en_1000hdx;
993 break;
994 case MAC_PROP_ADV_100FDX_CAP:
995 *(uint8_t *)pr_val = bgep->param_adv_100fdx;
996 break;
997 case MAC_PROP_EN_100FDX_CAP:
998 *(uint8_t *)pr_val = bgep->param_en_100fdx;
999 break;
1000 case MAC_PROP_ADV_100HDX_CAP:
1001 *(uint8_t *)pr_val = bgep->param_adv_100hdx;
1002 break;
1003 case MAC_PROP_EN_100HDX_CAP:
1004 *(uint8_t *)pr_val = bgep->param_en_100hdx;
1005 break;
1006 case MAC_PROP_ADV_10FDX_CAP:
1007 *(uint8_t *)pr_val = bgep->param_adv_10fdx;
1008 break;
1009 case MAC_PROP_EN_10FDX_CAP:
1010 *(uint8_t *)pr_val = bgep->param_en_10fdx;
1011 break;
1012 case MAC_PROP_ADV_10HDX_CAP:
1013 *(uint8_t *)pr_val = bgep->param_adv_10hdx;
1014 break;
1015 case MAC_PROP_EN_10HDX_CAP:
1016 *(uint8_t *)pr_val = bgep->param_en_10hdx;
1017 break;
1018 case MAC_PROP_ADV_100T4_CAP:
1019 case MAC_PROP_EN_100T4_CAP:
1020 *(uint8_t *)pr_val = 0;
1021 break;
1022 case MAC_PROP_PRIVATE:
1023 err = bge_get_priv_prop(bgep, pr_name,
1024 pr_valsize, pr_val);
1025 return (err);
1026 default:
1027 return (ENOTSUP);
1028 }
1029 return (0);
1030 }
1031
1032 static void
1033 bge_m_propinfo(void *barg, const char *pr_name, mac_prop_id_t pr_num,
1034 mac_prop_info_handle_t prh)
1035 {
1036 bge_t *bgep = barg;
1037 int flags = bgep->chipid.flags;
1038
1039 /*
1040 * By default permissions are read/write unless specified
1041 * otherwise by the driver.
1042 */
1043
1044 switch (pr_num) {
1045 case MAC_PROP_DUPLEX:
1046 case MAC_PROP_SPEED:
1047 case MAC_PROP_STATUS:
1048 case MAC_PROP_ADV_1000FDX_CAP:
1049 case MAC_PROP_ADV_1000HDX_CAP:
1050 case MAC_PROP_ADV_100FDX_CAP:
1051 case MAC_PROP_ADV_100HDX_CAP:
1052 case MAC_PROP_ADV_10FDX_CAP:
1053 case MAC_PROP_ADV_10HDX_CAP:
1054 case MAC_PROP_ADV_100T4_CAP:
1055 case MAC_PROP_EN_100T4_CAP:
1056 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1057 break;
1058
1059 case MAC_PROP_EN_1000FDX_CAP:
1060 case MAC_PROP_EN_1000HDX_CAP:
1061 if (DEVICE_5906_SERIES_CHIPSETS(bgep))
1062 mac_prop_info_set_default_uint8(prh, 0);
1063 else
1064 mac_prop_info_set_default_uint8(prh, 1);
1065 break;
1066
1067 case MAC_PROP_EN_100FDX_CAP:
1068 case MAC_PROP_EN_100HDX_CAP:
1069 case MAC_PROP_EN_10FDX_CAP:
1070 case MAC_PROP_EN_10HDX_CAP:
1071 mac_prop_info_set_default_uint8(prh,
1072 (flags & CHIP_FLAG_SERDES) ? 0 : 1);
1073 break;
1074
1075 case MAC_PROP_AUTONEG:
1076 mac_prop_info_set_default_uint8(prh, 1);
1077 break;
1078
1079 case MAC_PROP_FLOWCTRL:
1080 mac_prop_info_set_default_link_flowctrl(prh,
1081 LINK_FLOWCTRL_BI);
1082 break;
1083
1084 case MAC_PROP_MTU:
1085 mac_prop_info_set_range_uint32(prh, BGE_DEFAULT_MTU,
1086 (flags & CHIP_FLAG_NO_JUMBO) ?
1087 BGE_DEFAULT_MTU : BGE_MAXIMUM_MTU);
1088 break;
1089
1090 case MAC_PROP_PRIVATE:
1091 bge_priv_propinfo(pr_name, prh);
1092 break;
1093 }
1094
1095 mutex_enter(bgep->genlock);
1096 if ((bgep->param_loop_mode != BGE_LOOP_NONE &&
1097 bge_param_locked(pr_num)) ||
1098 ((bgep->chipid.flags & CHIP_FLAG_SERDES) &&
1099 ((pr_num == MAC_PROP_EN_100FDX_CAP) ||
1100 (pr_num == MAC_PROP_EN_100HDX_CAP) ||
1101 (pr_num == MAC_PROP_EN_10FDX_CAP) ||
1102 (pr_num == MAC_PROP_EN_10HDX_CAP))) ||
1103 (DEVICE_5906_SERIES_CHIPSETS(bgep) &&
1104 ((pr_num == MAC_PROP_EN_1000FDX_CAP) ||
1105 (pr_num == MAC_PROP_EN_1000HDX_CAP))))
1106 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1107 mutex_exit(bgep->genlock);
1108 }
1109
1110 /* ARGSUSED */
1111 static int
1112 bge_set_priv_prop(bge_t *bgep, const char *pr_name, uint_t pr_valsize,
1113 const void *pr_val)
1114 {
1115 int err = 0;
1116 long result;
1117
1118 if (strcmp(pr_name, "_adv_pause_cap") == 0) {
1119 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1120 if (result > 1 || result < 0) {
1121 err = EINVAL;
1122 } else {
1123 bgep->param_adv_pause = (uint32_t)result;
1124 if (bge_reprogram(bgep) == IOC_INVAL)
1125 err = EINVAL;
1126 }
1127 return (err);
1128 }
1129 if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
1130 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1131 if (result > 1 || result < 0) {
1132 err = EINVAL;
1133 } else {
1134 bgep->param_adv_asym_pause = (uint32_t)result;
1135 if (bge_reprogram(bgep) == IOC_INVAL)
1136 err = EINVAL;
1137 }
1138 return (err);
1139 }
1140 if (strcmp(pr_name, "_drain_max") == 0) {
1141
1142 /*
1143 * on the Tx side, we need to update the h/w register for
1144 * real packet transmission per packet. The drain_max parameter
1145 * is used to reduce the register access. This parameter
1146 * controls the max number of packets that we will hold before
1147 * updating the bge h/w to trigger h/w transmit. The bge
1148 * chipset usually has a max of 512 Tx descriptors, thus
1149 * the upper bound on drain_max is 512.
1150 */
1151 if (pr_val == NULL) {
1152 err = EINVAL;
1153 return (err);
1154 }
1155 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1156 if (result > 512 || result < 1)
1157 err = EINVAL;
1158 else {
1159 bgep->param_drain_max = (uint32_t)result;
1160 if (bge_reprogram(bgep) == IOC_INVAL)
1161 err = EINVAL;
1162 }
1163 return (err);
1164 }
1165 if (strcmp(pr_name, "_msi_cnt") == 0) {
1166
1167 if (pr_val == NULL) {
1168 err = EINVAL;
1169 return (err);
1170 }
1171 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1172 if (result > 7 || result < 0)
1173 err = EINVAL;
1174 else {
1175 bgep->param_msi_cnt = (uint32_t)result;
1176 if (bge_reprogram(bgep) == IOC_INVAL)
1177 err = EINVAL;
1178 }
1179 return (err);
1180 }
1181 if (strcmp(pr_name, "_rx_intr_coalesce_blank_time") == 0) {
1182 if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0)
1183 return (EINVAL);
1184 if (result < 0)
1185 err = EINVAL;
1186 else {
1187 bgep->chipid.rx_ticks_norm = (uint32_t)result;
1188 bge_chip_coalesce_update(bgep);
1189 }
1190 return (err);
1191 }
1192
1193 if (strcmp(pr_name, "_rx_intr_coalesce_pkt_cnt") == 0) {
1194 if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0)
1195 return (EINVAL);
1196
1197 if (result < 0)
1198 err = EINVAL;
1199 else {
1200 bgep->chipid.rx_count_norm = (uint32_t)result;
1201 bge_chip_coalesce_update(bgep);
1202 }
1203 return (err);
1204 }
1205 if (strcmp(pr_name, "_tx_intr_coalesce_blank_time") == 0) {
1206 if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0)
1207 return (EINVAL);
1208 if (result < 0)
1209 err = EINVAL;
1210 else {
1211 bgep->chipid.tx_ticks_norm = (uint32_t)result;
1212 bge_chip_coalesce_update(bgep);
1213 }
1214 return (err);
1215 }
1216
1217 if (strcmp(pr_name, "_tx_intr_coalesce_pkt_cnt") == 0) {
1218 if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0)
1219 return (EINVAL);
1220
1221 if (result < 0)
1222 err = EINVAL;
1223 else {
1224 bgep->chipid.tx_count_norm = (uint32_t)result;
1225 bge_chip_coalesce_update(bgep);
1226 }
1227 return (err);
1228 }
1229 return (ENOTSUP);
1230 }
1231
1232 static int
1233 bge_get_priv_prop(bge_t *bge, const char *pr_name, uint_t pr_valsize,
1234 void *pr_val)
1235 {
1236 int value;
1237
1238 if (strcmp(pr_name, "_adv_pause_cap") == 0)
1239 value = bge->param_adv_pause;
1240 else if (strcmp(pr_name, "_adv_asym_pause_cap") == 0)
1241 value = bge->param_adv_asym_pause;
1242 else if (strcmp(pr_name, "_drain_max") == 0)
1243 value = bge->param_drain_max;
1244 else if (strcmp(pr_name, "_msi_cnt") == 0)
1245 value = bge->param_msi_cnt;
1246 else if (strcmp(pr_name, "_rx_intr_coalesce_blank_time") == 0)
1247 value = bge->chipid.rx_ticks_norm;
1248 else if (strcmp(pr_name, "_tx_intr_coalesce_blank_time") == 0)
1249 value = bge->chipid.tx_ticks_norm;
1250 else if (strcmp(pr_name, "_rx_intr_coalesce_pkt_cnt") == 0)
1251 value = bge->chipid.rx_count_norm;
1252 else if (strcmp(pr_name, "_tx_intr_coalesce_pkt_cnt") == 0)
1253 value = bge->chipid.tx_count_norm;
1254 else
1255 return (ENOTSUP);
1256
1257 (void) snprintf(pr_val, pr_valsize, "%d", value);
1258 return (0);
1259 }
1260
1261 static void
1262 bge_priv_propinfo(const char *pr_name, mac_prop_info_handle_t mph)
1263 {
1264 char valstr[64];
1265 int value;
1266
1267 if (strcmp(pr_name, "_adv_pause_cap") == 0)
1268 value = 1;
1269 else if (strcmp(pr_name, "_adv_asym_pause_cap") == 0)
1270 value = 1;
1271 else if (strcmp(pr_name, "_drain_max") == 0)
1272 value = 64;
1273 else if (strcmp(pr_name, "_msi_cnt") == 0)
1274 value = 0;
1275 else if (strcmp(pr_name, "_rx_intr_coalesce_blank_time") == 0)
1276 value = bge_rx_ticks_norm;
1277 else if (strcmp(pr_name, "_tx_intr_coalesce_blank_time") == 0)
1278 value = bge_tx_ticks_norm;
1279 else if (strcmp(pr_name, "_rx_intr_coalesce_pkt_cnt") == 0)
1280 value = bge_rx_count_norm;
1281 else if (strcmp(pr_name, "_tx_intr_coalesce_pkt_cnt") == 0)
1282 value = bge_tx_count_norm;
1283 else
1284 return;
1285
1286 (void) snprintf(valstr, sizeof (valstr), "%d", value);
1287 mac_prop_info_set_default_str(mph, valstr);
1288 }
1289
1290
1291 static int
1292 bge_m_unicst(void * arg, const uint8_t * mac_addr)
1293 {
1294 bge_t *bgep = arg;
1295 int i;
1296
1297 /* XXX sets the mac address for all ring slots... OK? */
1298 for (i = 0; i < MIN(bgep->chipid.rx_rings, MAC_ADDRESS_REGS_MAX); i++)
1299 bge_addmac(&bgep->recv[i], mac_addr);
1300
1301 return (0);
1302 }
1303
1304
1305 /*
1306 * Compute the index of the required bit in the multicast hash map.
1307 * This must mirror the way the hardware actually does it!
1308 * See Broadcom document 570X-PG102-R page 125.
1309 */
1310 static uint32_t
1311 bge_hash_index(const uint8_t *mca)
1312 {
1313 uint32_t hash;
1314
1315 CRC32(hash, mca, ETHERADDRL, -1U, crc32_table);
1316
1317 return (hash);
1318 }
1319
1320 /*
1321 * bge_m_multicst_add() -- enable/disable a multicast address
1322 */
1323 static int
1324 bge_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
1325 {
1326 bge_t *bgep = arg; /* private device info */
1327 uint32_t hash;
1328 uint32_t index;
1329 uint32_t word;
1330 uint32_t bit;
1331 uint8_t *refp;
1332
1333 BGE_TRACE(("bge_m_multicst($%p, %s, %s)", arg,
1334 (add) ? "add" : "remove", ether_sprintf((void *)mca)));
1335
1336 /*
1337 * Precalculate all required masks, pointers etc ...
1338 */
1339 hash = bge_hash_index(mca);
1340 index = hash % BGE_HASH_TABLE_SIZE;
1341 word = index/32u;
1342 bit = 1 << (index % 32u);
1343 refp = &bgep->mcast_refs[index];
1344
1345 BGE_DEBUG(("bge_m_multicst: hash 0x%x index %d (%d:0x%x) = %d",
1346 hash, index, word, bit, *refp));
1347
1348 /*
1349 * We must set the appropriate bit in the hash map (and the
1350 * corresponding h/w register) when the refcount goes from 0
1351 * to >0, and clear it when the last ref goes away (refcount
1352 * goes from >0 back to 0). If we change the hash map, we
1353 * must also update the chip's hardware map registers.
1354 */
1355 mutex_enter(bgep->genlock);
1356 if (!(bgep->progress & PROGRESS_INTR)) {
1357 /* can happen during autorecovery */
1358 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1359 mutex_exit(bgep->genlock);
1360 return (EIO);
1361 }
1362 if (add) {
1363 if ((*refp)++ == 0) {
1364 bgep->mcast_hash[word] |= bit;
1365 #ifdef BGE_IPMI_ASF
1366 if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
1367 #else
1368 if (bge_chip_sync(bgep) == DDI_FAILURE) {
1369 #endif
1370 (void) bge_check_acc_handle(bgep,
1371 bgep->cfg_handle);
1372 (void) bge_check_acc_handle(bgep,
1373 bgep->io_handle);
1374 ddi_fm_service_impact(bgep->devinfo,
1375 DDI_SERVICE_DEGRADED);
1376 mutex_exit(bgep->genlock);
1377 return (EIO);
1378 }
1379 }
1380 } else {
1381 if (--(*refp) == 0) {
1382 bgep->mcast_hash[word] &= ~bit;
1383 #ifdef BGE_IPMI_ASF
1384 if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
1385 #else
1386 if (bge_chip_sync(bgep) == DDI_FAILURE) {
1387 #endif
1388 (void) bge_check_acc_handle(bgep,
1389 bgep->cfg_handle);
1390 (void) bge_check_acc_handle(bgep,
1391 bgep->io_handle);
1392 ddi_fm_service_impact(bgep->devinfo,
1393 DDI_SERVICE_DEGRADED);
1394 mutex_exit(bgep->genlock);
1395 return (EIO);
1396 }
1397 }
1398 }
1399 BGE_DEBUG(("bge_m_multicst($%p) done", arg));
1400 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
1401 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1402 mutex_exit(bgep->genlock);
1403 return (EIO);
1404 }
1405 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
1406 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1407 mutex_exit(bgep->genlock);
1408 return (EIO);
1409 }
1410 mutex_exit(bgep->genlock);
1411
1412 return (0);
1413 }
1414
1415 /*
1416 * bge_m_promisc() -- set or reset promiscuous mode on the board
1417 *
1418 * Program the hardware to enable/disable promiscuous and/or
1419 * receive-all-multicast modes.
1420 */
1421 static int
1422 bge_m_promisc(void *arg, boolean_t on)
1423 {
1424 bge_t *bgep = arg;
1425
1426 BGE_TRACE(("bge_m_promisc_set($%p, %d)", arg, on));
1427
1428 /*
1429 * Store MAC layer specified mode and pass to chip layer to update h/w
1430 */
1431 mutex_enter(bgep->genlock);
1432 if (!(bgep->progress & PROGRESS_INTR)) {
1433 /* can happen during autorecovery */
1434 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1435 mutex_exit(bgep->genlock);
1436 return (EIO);
1437 }
1438 bgep->promisc = on;
1439 #ifdef BGE_IPMI_ASF
1440 if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
1441 #else
1442 if (bge_chip_sync(bgep) == DDI_FAILURE) {
1443 #endif
1444 (void) bge_check_acc_handle(bgep, bgep->cfg_handle);
1445 (void) bge_check_acc_handle(bgep, bgep->io_handle);
1446 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1447 mutex_exit(bgep->genlock);
1448 return (EIO);
1449 }
1450 BGE_DEBUG(("bge_m_promisc_set($%p) done", arg));
1451 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
1452 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1453 mutex_exit(bgep->genlock);
1454 return (EIO);
1455 }
1456 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
1457 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1458 mutex_exit(bgep->genlock);
1459 return (EIO);
1460 }
1461 mutex_exit(bgep->genlock);
1462 return (0);
1463 }
1464
1465 #ifdef MC_RESOURCES
1466
1467 static void
1468 bge_blank(void * arg, time_t tick_cnt, uint_t pkt_cnt)
1469 {
1470 (void)arg;
1471 (void)tick_cnt;
1472 (void)pkt_cnt;
1473 }
1474
1475 static void
1476 bge_m_resources(void * arg)
1477 {
1478 bge_t *bgep = arg;
1479 mac_rx_fifo_t mrf;
1480 int i;
1481
1482 mrf.mrf_type = MAC_RX_FIFO;
1483 mrf.mrf_blank = bge_blank;
1484 mrf.mrf_arg = (void *)bgep;
1485 mrf.mrf_normal_blank_time = 25;
1486 mrf.mrf_normal_pkt_count = 8;
1487
1488 for (i = 0; i < BGE_RECV_RINGS_MAX; i++) {
1489 bgep->macRxResourceHandles[i] =
1490 mac_resource_add(bgep->mh, (mac_resource_t *)&mrf);
1491 }
1492 }
1493
1494 #endif /* MC_RESOURCES */
1495
1496 /*
1497 * Find the slot for the specified unicast address
1498 */
1499 int
1500 bge_unicst_find(bge_t *bgep, const uint8_t *mac_addr)
1501 {
1502 int slot;
1503
1504 ASSERT(mutex_owned(bgep->genlock));
1505
1506 for (slot = 0; slot < bgep->unicst_addr_total; slot++) {
1507 if (bcmp(bgep->curr_addr[slot].addr, mac_addr, ETHERADDRL) == 0)
1508 return (slot);
1509 }
1510
1511 return (-1);
1512 }
1513
1514 /*
1515 * Programs the classifier to start steering packets matching 'mac_addr' to the
1516 * specified ring 'arg'.
1517 */
1518 static int
1519 bge_addmac(void *arg, const uint8_t * mac_addr)
1520 {
1521 recv_ring_t *rrp = (recv_ring_t *)arg;
1522 bge_t *bgep = rrp->bgep;
1523 bge_recv_rule_t *rulep = bgep->recv_rules;
1524 bge_rule_info_t *rinfop = NULL;
1525 uint8_t ring = (uint8_t)(rrp - bgep->recv) + 1;
1526 int i;
1527 uint16_t tmp16;
1528 uint32_t tmp32;
1529 int slot;
1530 int err;
1531
1532 mutex_enter(bgep->genlock);
1533 if (bgep->unicst_addr_avail == 0) {
1534 mutex_exit(bgep->genlock);
1535 return (ENOSPC);
1536 }
1537
1538 /*
1539 * First add the unicast address to a available slot.
1540 */
1541 slot = bge_unicst_find(bgep, mac_addr);
1542 ASSERT(slot == -1);
1543
1544 for (slot = 0; slot < bgep->unicst_addr_total; slot++) {
1545 if (!bgep->curr_addr[slot].set) {
1546 bgep->curr_addr[slot].set = B_TRUE;
1547 break;
1548 }
1549 }
1550
1551 ASSERT(slot < bgep->unicst_addr_total);
1552 bgep->unicst_addr_avail--;
1553 mutex_exit(bgep->genlock);
1554
1555 if ((err = bge_unicst_set(bgep, mac_addr, slot)) != 0)
1556 goto fail;
1557
1558 /* A rule is already here. Deny this. */
1559 if (rrp->mac_addr_rule != NULL) {
1560 err = ether_cmp(mac_addr, rrp->mac_addr_val) ? EEXIST : EBUSY;
1561 goto fail;
1562 }
1563
1564 /*
1565 * Allocate a bge_rule_info_t to keep track of which rule slots
1566 * are being used.
1567 */
1568 rinfop = kmem_zalloc(sizeof (bge_rule_info_t), KM_NOSLEEP);
1569 if (rinfop == NULL) {
1570 err = ENOMEM;
1571 goto fail;
1572 }
1573
1574 /*
1575 * Look for the starting slot to place the rules.
1576 * The two slots we reserve must be contiguous.
1577 */
1578 for (i = 0; i + 1 < RECV_RULES_NUM_MAX; i++)
1579 if ((rulep[i].control & RECV_RULE_CTL_ENABLE) == 0 &&
1580 (rulep[i+1].control & RECV_RULE_CTL_ENABLE) == 0)
1581 break;
1582
1583 ASSERT(i + 1 < RECV_RULES_NUM_MAX);
1584
1585 bcopy(mac_addr, &tmp32, sizeof (tmp32));
1586 rulep[i].mask_value = ntohl(tmp32);
1587 rulep[i].control = RULE_DEST_MAC_1(ring) | RECV_RULE_CTL_AND;
1588 bge_reg_put32(bgep, RECV_RULE_MASK_REG(i), rulep[i].mask_value);
1589 bge_reg_put32(bgep, RECV_RULE_CONTROL_REG(i), rulep[i].control);
1590
1591 bcopy(mac_addr + 4, &tmp16, sizeof (tmp16));
1592 rulep[i+1].mask_value = 0xffff0000 | ntohs(tmp16);
1593 rulep[i+1].control = RULE_DEST_MAC_2(ring);
1594 bge_reg_put32(bgep, RECV_RULE_MASK_REG(i+1), rulep[i+1].mask_value);
1595 bge_reg_put32(bgep, RECV_RULE_CONTROL_REG(i+1), rulep[i+1].control);
1596 rinfop->start = i;
1597 rinfop->count = 2;
1598
1599 rrp->mac_addr_rule = rinfop;
1600 bcopy(mac_addr, rrp->mac_addr_val, ETHERADDRL);
1601
1602 return (0);
1603
1604 fail:
1605 /* Clear the address just set */
1606 (void) bge_unicst_set(bgep, zero_addr, slot);
1607 mutex_enter(bgep->genlock);
1608 bgep->curr_addr[slot].set = B_FALSE;
1609 bgep->unicst_addr_avail++;
1610 mutex_exit(bgep->genlock);
1611
1612 return (err);
1613 }
1614
1615 /*
1616 * Stop classifying packets matching the MAC address to the specified ring.
1617 */
1618 static int
1619 bge_remmac(void *arg, const uint8_t *mac_addr)
1620 {
1621 recv_ring_t *rrp = (recv_ring_t *)arg;
1622 bge_t *bgep = rrp->bgep;
1623 bge_recv_rule_t *rulep = bgep->recv_rules;
1624 bge_rule_info_t *rinfop = rrp->mac_addr_rule;
1625 int start;
1626 int slot;
1627 int err;
1628
1629 /*
1630 * Remove the MAC address from its slot.
1631 */
1632 mutex_enter(bgep->genlock);
1633 slot = bge_unicst_find(bgep, mac_addr);
1634 if (slot == -1) {
1635 mutex_exit(bgep->genlock);
1636 return (EINVAL);
1637 }
1638
1639 ASSERT(bgep->curr_addr[slot].set);
1640 mutex_exit(bgep->genlock);
1641
1642 if ((err = bge_unicst_set(bgep, zero_addr, slot)) != 0)
1643 return (err);
1644
1645 if (rinfop == NULL || ether_cmp(mac_addr, rrp->mac_addr_val) != 0)
1646 return (EINVAL);
1647
1648 start = rinfop->start;
1649 rulep[start].mask_value = 0;
1650 rulep[start].control = 0;
1651 bge_reg_put32(bgep, RECV_RULE_MASK_REG(start), rulep[start].mask_value);
1652 bge_reg_put32(bgep, RECV_RULE_CONTROL_REG(start), rulep[start].control);
1653 start++;
1654 rulep[start].mask_value = 0;
1655 rulep[start].control = 0;
1656 bge_reg_put32(bgep, RECV_RULE_MASK_REG(start), rulep[start].mask_value);
1657 bge_reg_put32(bgep, RECV_RULE_CONTROL_REG(start), rulep[start].control);
1658
1659 kmem_free(rinfop, sizeof (bge_rule_info_t));
1660 rrp->mac_addr_rule = NULL;
1661 bzero(rrp->mac_addr_val, ETHERADDRL);
1662
1663 mutex_enter(bgep->genlock);
1664 bgep->curr_addr[slot].set = B_FALSE;
1665 bgep->unicst_addr_avail++;
1666 mutex_exit(bgep->genlock);
1667
1668 return (0);
1669 }
1670
1671
1672 static int
1673 bge_flag_intr_enable(mac_ring_driver_t ih)
1674 {
1675 recv_ring_t *rrp = (recv_ring_t *)ih;
1676 bge_t *bgep = rrp->bgep;
1677
1678 mutex_enter(bgep->genlock);
1679 rrp->poll_flag = 0;
1680 mutex_exit(bgep->genlock);
1681
1682 return (0);
1683 }
1684
1685 static int
1686 bge_flag_intr_disable(mac_ring_driver_t ih)
1687 {
1688 recv_ring_t *rrp = (recv_ring_t *)ih;
1689 bge_t *bgep = rrp->bgep;
1690
1691 mutex_enter(bgep->genlock);
1692 rrp->poll_flag = 1;
1693 mutex_exit(bgep->genlock);
1694
1695 return (0);
1696 }
1697
1698 static int
1699 bge_ring_start(mac_ring_driver_t rh, uint64_t mr_gen_num)
1700 {
1701 recv_ring_t *rx_ring;
1702
1703 rx_ring = (recv_ring_t *)rh;
1704 mutex_enter(rx_ring->rx_lock);
1705 rx_ring->ring_gen_num = mr_gen_num;
1706 mutex_exit(rx_ring->rx_lock);
1707 return (0);
1708 }
1709
1710
1711 /*
1712 * Callback funtion for MAC layer to register all rings
1713 * for given ring_group, noted by rg_index.
1714 */
1715 void
1716 bge_fill_ring(void *arg, mac_ring_type_t rtype, const int rg_index,
1717 const int index, mac_ring_info_t *infop, mac_ring_handle_t rh)
1718 {
1719 bge_t *bgep = arg;
1720 mac_intr_t *mintr;
1721
1722 switch (rtype) {
1723 case MAC_RING_TYPE_RX: {
1724 recv_ring_t *rx_ring;
1725 ASSERT(rg_index >= 0 && rg_index < MIN(bgep->chipid.rx_rings,
1726 MAC_ADDRESS_REGS_MAX) && index == 0);
1727
1728 rx_ring = &bgep->recv[rg_index];
1729 rx_ring->ring_handle = rh;
1730
1731 infop->mri_driver = (mac_ring_driver_t)rx_ring;
1732 infop->mri_start = bge_ring_start;
1733 infop->mri_stop = NULL;
1734 infop->mri_poll = bge_poll_ring;
1735 infop->mri_stat = bge_rx_ring_stat;
1736
1737 mintr = &infop->mri_intr;
1738 mintr->mi_enable = (mac_intr_enable_t)bge_flag_intr_enable;
1739 mintr->mi_disable = (mac_intr_disable_t)bge_flag_intr_disable;
1740
1741 break;
1742 }
1743 case MAC_RING_TYPE_TX:
1744 default:
1745 ASSERT(0);
1746 break;
1747 }
1748 }
1749
1750 /*
1751 * Fill infop passed as argument
1752 * fill in respective ring_group info
1753 * Each group has a single ring in it. We keep it simple
1754 * and use the same internal handle for rings and groups.
1755 */
1756 void
1757 bge_fill_group(void *arg, mac_ring_type_t rtype, const int rg_index,
1758 mac_group_info_t * infop, mac_group_handle_t gh)
1759 {
1760 bge_t *bgep = arg;
1761
1762 switch (rtype) {
1763 case MAC_RING_TYPE_RX: {
1764 recv_ring_t *rx_ring;
1765
1766 ASSERT(rg_index >= 0 && rg_index < MIN(bgep->chipid.rx_rings,
1767 MAC_ADDRESS_REGS_MAX));
1768 rx_ring = &bgep->recv[rg_index];
1769 rx_ring->ring_group_handle = gh;
1770
1771 infop->mgi_driver = (mac_group_driver_t)rx_ring;
1772 infop->mgi_start = NULL;
1773 infop->mgi_stop = NULL;
1774 infop->mgi_addmac = bge_addmac;
1775 infop->mgi_remmac = bge_remmac;
1776 infop->mgi_count = 1;
1777 break;
1778 }
1779 case MAC_RING_TYPE_TX:
1780 default:
1781 ASSERT(0);
1782 break;
1783 }
1784 }
1785
1786
1787 /*ARGSUSED*/
1788 static boolean_t
1789 bge_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
1790 {
1791 bge_t *bgep = arg;
1792 mac_capab_rings_t *cap_rings;
1793
1794 switch (cap) {
1795 case MAC_CAPAB_HCKSUM: {
1796 uint32_t *txflags = cap_data;
1797
1798 *txflags = HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM;
1799 break;
1800 }
1801
1802 case MAC_CAPAB_RINGS:
1803 cap_rings = (mac_capab_rings_t *)cap_data;
1804
1805 /* Temporarily disable multiple tx rings. */
1806 if (cap_rings->mr_type != MAC_RING_TYPE_RX)
1807 return (B_FALSE);
1808
1809 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
1810 cap_rings->mr_rnum =
1811 cap_rings->mr_gnum =
1812 MIN(bgep->chipid.rx_rings, MAC_ADDRESS_REGS_MAX);
1813 cap_rings->mr_rget = bge_fill_ring;
1814 cap_rings->mr_gget = bge_fill_group;
1815 break;
1816
1817 default:
1818 return (B_FALSE);
1819 }
1820 return (B_TRUE);
1821 }
1822
1823 #ifdef NOT_SUPPORTED_XXX
1824
1825 /*
1826 * Loopback ioctl code
1827 */
1828
1829 static lb_property_t loopmodes[] = {
1830 { normal, "normal", BGE_LOOP_NONE },
1831 { external, "1000Mbps", BGE_LOOP_EXTERNAL_1000 },
1832 { external, "100Mbps", BGE_LOOP_EXTERNAL_100 },
1833 { external, "10Mbps", BGE_LOOP_EXTERNAL_10 },
1834 { internal, "PHY", BGE_LOOP_INTERNAL_PHY },
1835 { internal, "MAC", BGE_LOOP_INTERNAL_MAC }
1836 };
1837
1838 static enum ioc_reply
1839 bge_set_loop_mode(bge_t *bgep, uint32_t mode)
1840 {
1841 /*
1842 * If the mode isn't being changed, there's nothing to do ...
1843 */
1844 if (mode == bgep->param_loop_mode)
1845 return (IOC_ACK);
1846
1847 /*
1848 * Validate the requested mode and prepare a suitable message
1849 * to explain the link down/up cycle that the change will
1850 * probably induce ...
1851 */
1852 switch (mode) {
1853 default:
1854 return (IOC_INVAL);
1855
1856 case BGE_LOOP_NONE:
1857 case BGE_LOOP_EXTERNAL_1000:
1858 case BGE_LOOP_EXTERNAL_100:
1859 case BGE_LOOP_EXTERNAL_10:
1860 case BGE_LOOP_INTERNAL_PHY:
1861 case BGE_LOOP_INTERNAL_MAC:
1862 break;
1863 }
1864
1865 /*
1866 * All OK; tell the caller to reprogram
1867 * the PHY and/or MAC for the new mode ...
1868 */
1869 bgep->param_loop_mode = mode;
1870 return (IOC_RESTART_ACK);
1871 }
1872
1873 static enum ioc_reply
1874 bge_loop_ioctl(bge_t *bgep, queue_t *wq, mblk_t *mp, struct iocblk *iocp)
1875 {
1876 lb_info_sz_t *lbsp;
1877 lb_property_t *lbpp;
1878 uint32_t *lbmp;
1879 int cmd;
1880
1881 _NOTE(ARGUNUSED(wq))
1882
1883 /*
1884 * Validate format of ioctl
1885 */
1886 if (mp->b_cont == NULL)
1887 return (IOC_INVAL);
1888
1889 cmd = iocp->ioc_cmd;
1890 switch (cmd) {
1891 default:
1892 /* NOTREACHED */
1893 bge_error(bgep, "bge_loop_ioctl: invalid cmd 0x%x", cmd);
1894 return (IOC_INVAL);
1895
1896 case LB_GET_INFO_SIZE:
1897 if (iocp->ioc_count != sizeof (lb_info_sz_t))
1898 return (IOC_INVAL);
1899 lbsp = (void *)mp->b_cont->b_rptr;
1900 *lbsp = sizeof (loopmodes);
1901 return (IOC_REPLY);
1902
1903 case LB_GET_INFO:
1904 if (iocp->ioc_count != sizeof (loopmodes))
1905 return (IOC_INVAL);
1906 lbpp = (void *)mp->b_cont->b_rptr;
1907 bcopy(loopmodes, lbpp, sizeof (loopmodes));
1908 return (IOC_REPLY);
1909
1910 case LB_GET_MODE:
1911 if (iocp->ioc_count != sizeof (uint32_t))
1912 return (IOC_INVAL);
1913 lbmp = (void *)mp->b_cont->b_rptr;
1914 *lbmp = bgep->param_loop_mode;
1915 return (IOC_REPLY);
1916
1917 case LB_SET_MODE:
1918 if (iocp->ioc_count != sizeof (uint32_t))
1919 return (IOC_INVAL);
1920 lbmp = (void *)mp->b_cont->b_rptr;
1921 return (bge_set_loop_mode(bgep, *lbmp));
1922 }
1923 }
1924
1925 #endif /* NOT_SUPPORTED_XXX */
1926
1927 /*
1928 * Specific bge IOCTLs, the gld module handles the generic ones.
1929 */
1930 static void
1931 bge_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
1932 {
1933 bge_t *bgep = arg;
1934 struct iocblk *iocp;
1935 enum ioc_reply status;
1936 boolean_t need_privilege;
1937 int err;
1938 int cmd;
1939
1940 /*
1941 * Validate the command before bothering with the mutex ...
1942 */
1943 iocp = (void *)mp->b_rptr;
1944 iocp->ioc_error = 0;
1945 need_privilege = B_TRUE;
1946 cmd = iocp->ioc_cmd;
1947 switch (cmd) {
1948 default:
1949 miocnak(wq, mp, 0, EINVAL);
1950 return;
1951
1952 case BGE_MII_READ:
1953 case BGE_MII_WRITE:
1954 case BGE_SEE_READ:
1955 case BGE_SEE_WRITE:
1956 case BGE_FLASH_READ:
1957 case BGE_FLASH_WRITE:
1958 case BGE_DIAG:
1959 case BGE_PEEK:
1960 case BGE_POKE:
1961 case BGE_PHY_RESET:
1962 case BGE_SOFT_RESET:
1963 case BGE_HARD_RESET:
1964 break;
1965
1966 #ifdef NOT_SUPPORTED_XXX
1967 case LB_GET_INFO_SIZE:
1968 case LB_GET_INFO:
1969 case LB_GET_MODE:
1970 need_privilege = B_FALSE;
1971 /* FALLTHRU */
1972 case LB_SET_MODE:
1973 break;
1974 #endif
1975
1976 }
1977
1978 if (need_privilege) {
1979 /*
1980 * Check for specific net_config privilege on Solaris 10+.
1981 */
1982 err = secpolicy_net_config(iocp->ioc_cr, B_FALSE);
1983 if (err != 0) {
1984 miocnak(wq, mp, 0, err);
1985 return;
1986 }
1987 }
1988
1989 mutex_enter(bgep->genlock);
1990 if (!(bgep->progress & PROGRESS_INTR)) {
1991 /* can happen during autorecovery */
1992 mutex_exit(bgep->genlock);
1993 miocnak(wq, mp, 0, EIO);
1994 return;
1995 }
1996
1997 switch (cmd) {
1998 default:
1999 _NOTE(NOTREACHED)
2000 status = IOC_INVAL;
2001 break;
2002
2003 case BGE_MII_READ:
2004 case BGE_MII_WRITE:
2005 case BGE_SEE_READ:
2006 case BGE_SEE_WRITE:
2007 case BGE_FLASH_READ:
2008 case BGE_FLASH_WRITE:
2009 case BGE_DIAG:
2010 case BGE_PEEK:
2011 case BGE_POKE:
2012 case BGE_PHY_RESET:
2013 case BGE_SOFT_RESET:
2014 case BGE_HARD_RESET:
2015 status = bge_chip_ioctl(bgep, wq, mp, iocp);
2016 break;
2017
2018 #ifdef NOT_SUPPORTED_XXX
2019 case LB_GET_INFO_SIZE:
2020 case LB_GET_INFO:
2021 case LB_GET_MODE:
2022 case LB_SET_MODE:
2023 status = bge_loop_ioctl(bgep, wq, mp, iocp);
2024 break;
2025 #endif
2026
2027 }
2028
2029 /*
2030 * Do we need to reprogram the PHY and/or the MAC?
2031 * Do it now, while we still have the mutex.
2032 *
2033 * Note: update the PHY first, 'cos it controls the
2034 * speed/duplex parameters that the MAC code uses.
2035 */
2036 switch (status) {
2037 case IOC_RESTART_REPLY:
2038 case IOC_RESTART_ACK:
2039 if (bge_reprogram(bgep) == IOC_INVAL)
2040 status = IOC_INVAL;
2041 break;
2042 }
2043
2044 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
2045 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
2046 status = IOC_INVAL;
2047 }
2048 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
2049 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
2050 status = IOC_INVAL;
2051 }
2052 mutex_exit(bgep->genlock);
2053
2054 /*
2055 * Finally, decide how to reply
2056 */
2057 switch (status) {
2058 default:
2059 case IOC_INVAL:
2060 /*
2061 * Error, reply with a NAK and EINVAL or the specified error
2062 */
2063 miocnak(wq, mp, 0, iocp->ioc_error == 0 ?
2064 EINVAL : iocp->ioc_error);
2065 break;
2066
2067 case IOC_DONE:
2068 /*
2069 * OK, reply already sent
2070 */
2071 break;
2072
2073 case IOC_RESTART_ACK:
2074 case IOC_ACK:
2075 /*
2076 * OK, reply with an ACK
2077 */
2078 miocack(wq, mp, 0, 0);
2079 break;
2080
2081 case IOC_RESTART_REPLY:
2082 case IOC_REPLY:
2083 /*
2084 * OK, send prepared reply as ACK or NAK
2085 */
2086 mp->b_datap->db_type = iocp->ioc_error == 0 ?
2087 M_IOCACK : M_IOCNAK;
2088 qreply(wq, mp);
2089 break;
2090 }
2091 }
2092
2093 /*
2094 * ========== Per-instance setup/teardown code ==========
2095 */
2096
2097 #undef BGE_DBG
2098 #define BGE_DBG BGE_DBG_MEM /* debug flag for this code */
2099 /*
2100 * Allocate an area of memory and a DMA handle for accessing it
2101 */
2102 static int
2103 bge_alloc_dma_mem(bge_t *bgep, size_t memsize, ddi_device_acc_attr_t *attr_p,
2104 uint_t dma_flags, dma_area_t *dma_p)
2105 {
2106 caddr_t va;
2107 int err;
2108
2109 BGE_TRACE(("bge_alloc_dma_mem($%p, %ld, $%p, 0x%x, $%p)",
2110 (void *)bgep, memsize, attr_p, dma_flags, dma_p));
2111
2112 /*
2113 * Allocate handle
2114 */
2115 err = ddi_dma_alloc_handle(bgep->devinfo, &dma_attr,
2116 DDI_DMA_DONTWAIT, NULL, &dma_p->dma_hdl);
2117 if (err != DDI_SUCCESS)
2118 return (DDI_FAILURE);
2119
2120 /*
2121 * Allocate memory
2122 */
2123 err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
2124 dma_flags, DDI_DMA_DONTWAIT, NULL, &va, &dma_p->alength,
2125 &dma_p->acc_hdl);
2126 if (err != DDI_SUCCESS)
2127 return (DDI_FAILURE);
2128
2129 /*
2130 * Bind the two together
2131 */
2132 dma_p->mem_va = va;
2133 err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
2134 va, dma_p->alength, dma_flags, DDI_DMA_DONTWAIT, NULL,
2135 &dma_p->cookie, &dma_p->ncookies);
2136
2137 BGE_DEBUG(("bge_alloc_dma_mem(): bind %d bytes; err %d, %d cookies",
2138 dma_p->alength, err, dma_p->ncookies));
2139
2140 if (err != DDI_DMA_MAPPED || dma_p->ncookies != 1)
2141 return (DDI_FAILURE);
2142
2143 dma_p->nslots = ~0U;
2144 dma_p->size = ~0U;
2145 dma_p->token = ~0U;
2146 dma_p->offset = 0;
2147 return (DDI_SUCCESS);
2148 }
2149
2150 /*
2151 * Free one allocated area of DMAable memory
2152 */
2153 static void
2154 bge_free_dma_mem(dma_area_t *dma_p)
2155 {
2156 if (dma_p->dma_hdl != NULL) {
2157 if (dma_p->ncookies) {
2158 (void) ddi_dma_unbind_handle(dma_p->dma_hdl);
2159 dma_p->ncookies = 0;
2160 }
2161 ddi_dma_free_handle(&dma_p->dma_hdl);
2162 dma_p->dma_hdl = NULL;
2163 }
2164
2165 if (dma_p->acc_hdl != NULL) {
2166 ddi_dma_mem_free(&dma_p->acc_hdl);
2167 dma_p->acc_hdl = NULL;
2168 }
2169 }
2170 /*
2171 * Utility routine to carve a slice off a chunk of allocated memory,
2172 * updating the chunk descriptor accordingly. The size of the slice
2173 * is given by the product of the <qty> and <size> parameters.
2174 */
2175 static void
2176 bge_slice_chunk(dma_area_t *slice, dma_area_t *chunk,
2177 uint32_t qty, uint32_t size)
2178 {
2179 static uint32_t sequence = 0xbcd5704a;
2180 size_t totsize;
2181
2182 totsize = qty*size;
2183 ASSERT(totsize <= chunk->alength);
2184
2185 *slice = *chunk;
2186 slice->nslots = qty;
2187 slice->size = size;
2188 slice->alength = totsize;
2189 slice->token = ++sequence;
2190
2191 chunk->mem_va = (caddr_t)chunk->mem_va + totsize;
2192 chunk->alength -= totsize;
2193 chunk->offset += totsize;
2194 chunk->cookie.dmac_laddress += totsize;
2195 chunk->cookie.dmac_size -= totsize;
2196 }
2197
2198 /*
2199 * Initialise the specified Receive Producer (Buffer) Ring, using
2200 * the information in the <dma_area> descriptors that it contains
2201 * to set up all the other fields. This routine should be called
2202 * only once for each ring.
2203 */
2204 static void
2205 bge_init_buff_ring(bge_t *bgep, uint64_t ring)
2206 {
2207 buff_ring_t *brp;
2208 bge_status_t *bsp;
2209 sw_rbd_t *srbdp;
2210 dma_area_t pbuf;
2211 uint32_t bufsize;
2212 uint32_t nslots;
2213 uint32_t slot;
2214 uint32_t split;
2215
2216 static bge_regno_t nic_ring_addrs[BGE_BUFF_RINGS_MAX] = {
2217 NIC_MEM_SHADOW_BUFF_STD,
2218 NIC_MEM_SHADOW_BUFF_JUMBO,
2219 NIC_MEM_SHADOW_BUFF_MINI
2220 };
2221 static bge_regno_t mailbox_regs[BGE_BUFF_RINGS_MAX] = {
2222 RECV_STD_PROD_INDEX_REG,
2223 RECV_JUMBO_PROD_INDEX_REG,
2224 RECV_MINI_PROD_INDEX_REG
2225 };
2226 static bge_regno_t buff_cons_xref[BGE_BUFF_RINGS_MAX] = {
2227 STATUS_STD_BUFF_CONS_INDEX,
2228 STATUS_JUMBO_BUFF_CONS_INDEX,
2229 STATUS_MINI_BUFF_CONS_INDEX
2230 };
2231
2232 BGE_TRACE(("bge_init_buff_ring($%p, %d)",
2233 (void *)bgep, ring));
2234
2235 brp = &bgep->buff[ring];
2236 nslots = brp->desc.nslots;
2237 ASSERT(brp->buf[0].nslots == nslots/BGE_SPLIT);
2238 bufsize = brp->buf[0].size;
2239
2240 /*
2241 * Set up the copy of the h/w RCB
2242 *
2243 * Note: unlike Send & Receive Return Rings, (where the max_len
2244 * field holds the number of slots), in a Receive Buffer Ring
2245 * this field indicates the size of each buffer in the ring.
2246 */
2247 brp->hw_rcb.host_ring_addr = brp->desc.cookie.dmac_laddress;
2248 brp->hw_rcb.max_len = (uint16_t)bufsize;
2249 brp->hw_rcb.flags = nslots > 0 ? 0 : RCB_FLAG_RING_DISABLED;
2250 brp->hw_rcb.nic_ring_addr = nic_ring_addrs[ring];
2251
2252 /*
2253 * Other one-off initialisation of per-ring data
2254 */
2255 brp->bgep = bgep;
2256 bsp = DMA_VPTR(bgep->status_block);
2257 brp->cons_index_p = &bsp->buff_cons_index[buff_cons_xref[ring]];
2258 brp->chip_mbx_reg = mailbox_regs[ring];
2259 mutex_init(brp->rf_lock, NULL, MUTEX_DRIVER,
2260 DDI_INTR_PRI(bgep->intr_pri));
2261
2262 /*
2263 * Allocate the array of s/w Receive Buffer Descriptors
2264 */
2265 srbdp = kmem_zalloc(nslots*sizeof (*srbdp), KM_SLEEP);
2266 brp->sw_rbds = srbdp;
2267
2268 /*
2269 * Now initialise each array element once and for all
2270 */
2271 for (split = 0; split < BGE_SPLIT; ++split) {
2272 pbuf = brp->buf[split];
2273 for (slot = 0; slot < nslots/BGE_SPLIT; ++srbdp, ++slot)
2274 bge_slice_chunk(&srbdp->pbuf, &pbuf, 1, bufsize);
2275 ASSERT(pbuf.alength == 0);
2276 }
2277 }
2278
2279 /*
2280 * Clean up initialisation done above before the memory is freed
2281 */
2282 static void
2283 bge_fini_buff_ring(bge_t *bgep, uint64_t ring)
2284 {
2285 buff_ring_t *brp;
2286 sw_rbd_t *srbdp;
2287
2288 BGE_TRACE(("bge_fini_buff_ring($%p, %d)",
2289 (void *)bgep, ring));
2290
2291 brp = &bgep->buff[ring];
2292 srbdp = brp->sw_rbds;
2293 kmem_free(srbdp, brp->desc.nslots*sizeof (*srbdp));
2294
2295 mutex_destroy(brp->rf_lock);
2296 }
2297
2298 /*
2299 * Initialise the specified Receive (Return) Ring, using the
2300 * information in the <dma_area> descriptors that it contains
2301 * to set up all the other fields. This routine should be called
2302 * only once for each ring.
2303 */
2304 static void
2305 bge_init_recv_ring(bge_t *bgep, uint64_t ring)
2306 {
2307 recv_ring_t *rrp;
2308 bge_status_t *bsp;
2309 uint32_t nslots;
2310
2311 BGE_TRACE(("bge_init_recv_ring($%p, %d)",
2312 (void *)bgep, ring));
2313
2314 /*
2315 * The chip architecture requires that receive return rings have
2316 * 512 or 1024 or 2048 elements per ring. See 570X-PG108-R page 103.
2317 */
2318 rrp = &bgep->recv[ring];
2319 nslots = rrp->desc.nslots;
2320 ASSERT(nslots == 0 || nslots == 512 ||
2321 nslots == 1024 || nslots == 2048);
2322
2323 /*
2324 * Set up the copy of the h/w RCB
2325 */
2326 rrp->hw_rcb.host_ring_addr = rrp->desc.cookie.dmac_laddress;
2327 rrp->hw_rcb.max_len = (uint16_t)nslots;
2328 rrp->hw_rcb.flags = nslots > 0 ? 0 : RCB_FLAG_RING_DISABLED;
2329 rrp->hw_rcb.nic_ring_addr = 0;
2330
2331 /*
2332 * Other one-off initialisation of per-ring data
2333 */
2334 rrp->bgep = bgep;
2335 bsp = DMA_VPTR(bgep->status_block);
2336 rrp->prod_index_p = RECV_INDEX_P(bsp, ring);
2337 rrp->chip_mbx_reg = RECV_RING_CONS_INDEX_REG(ring);
2338 mutex_init(rrp->rx_lock, NULL, MUTEX_DRIVER,
2339 DDI_INTR_PRI(bgep->intr_pri));
2340 }
2341
2342
2343 /*
2344 * Clean up initialisation done above before the memory is freed
2345 */
2346 static void
2347 bge_fini_recv_ring(bge_t *bgep, uint64_t ring)
2348 {
2349 recv_ring_t *rrp;
2350
2351 BGE_TRACE(("bge_fini_recv_ring($%p, %d)",
2352 (void *)bgep, ring));
2353
2354 rrp = &bgep->recv[ring];
2355 if (rrp->rx_softint)
2356 ddi_remove_softintr(rrp->rx_softint);
2357 mutex_destroy(rrp->rx_lock);
2358 }
2359
2360 /*
2361 * Initialise the specified Send Ring, using the information in the
2362 * <dma_area> descriptors that it contains to set up all the other
2363 * fields. This routine should be called only once for each ring.
2364 */
2365 static void
2366 bge_init_send_ring(bge_t *bgep, uint64_t ring)
2367 {
2368 send_ring_t *srp;
2369 bge_status_t *bsp;
2370 sw_sbd_t *ssbdp;
2371 dma_area_t desc;
2372 dma_area_t pbuf;
2373 uint32_t nslots;
2374 uint32_t slot;
2375 uint32_t split;
2376 sw_txbuf_t *txbuf;
2377
2378 BGE_TRACE(("bge_init_send_ring($%p, %d)",
2379 (void *)bgep, ring));
2380
2381 /*
2382 * The chip architecture requires that host-based send rings
2383 * have 512 elements per ring. See 570X-PG102-R page 56.
2384 */
2385 srp = &bgep->send[ring];
2386 nslots = srp->desc.nslots;
2387 ASSERT(nslots == 0 || nslots == 512);
2388
2389 /*
2390 * Set up the copy of the h/w RCB
2391 */
2392 srp->hw_rcb.host_ring_addr = srp->desc.cookie.dmac_laddress;
2393 srp->hw_rcb.max_len = (uint16_t)nslots;
2394 srp->hw_rcb.flags = nslots > 0 ? 0 : RCB_FLAG_RING_DISABLED;
2395 srp->hw_rcb.nic_ring_addr = NIC_MEM_SHADOW_SEND_RING(ring, nslots);
2396
2397 /*
2398 * Other one-off initialisation of per-ring data
2399 */
2400 srp->bgep = bgep;
2401 bsp = DMA_VPTR(bgep->status_block);
2402 srp->cons_index_p = SEND_INDEX_P(bsp, ring);
2403 srp->chip_mbx_reg = SEND_RING_HOST_INDEX_REG(ring);
2404 mutex_init(srp->tx_lock, NULL, MUTEX_DRIVER,
2405 DDI_INTR_PRI(bgep->intr_pri));
2406 mutex_init(srp->txbuf_lock, NULL, MUTEX_DRIVER,
2407 DDI_INTR_PRI(bgep->intr_pri));
2408 mutex_init(srp->freetxbuf_lock, NULL, MUTEX_DRIVER,
2409 DDI_INTR_PRI(bgep->intr_pri));
2410 mutex_init(srp->tc_lock, NULL, MUTEX_DRIVER,
2411 DDI_INTR_PRI(bgep->intr_pri));
2412 if (nslots == 0)
2413 return;
2414
2415 /*
2416 * Allocate the array of s/w Send Buffer Descriptors
2417 */
2418 ssbdp = kmem_zalloc(nslots*sizeof (*ssbdp), KM_SLEEP);
2419 txbuf = kmem_zalloc(BGE_SEND_BUF_MAX*sizeof (*txbuf), KM_SLEEP);
2420 srp->txbuf_head =
2421 kmem_zalloc(BGE_SEND_BUF_MAX*sizeof (bge_queue_item_t), KM_SLEEP);
2422 srp->pktp = kmem_zalloc(BGE_SEND_BUF_MAX*sizeof (send_pkt_t), KM_SLEEP);
2423 srp->sw_sbds = ssbdp;
2424 srp->txbuf = txbuf;
2425 srp->tx_buffers = BGE_SEND_BUF_NUM;
2426 srp->tx_buffers_low = srp->tx_buffers / 4;
2427 if (bgep->chipid.snd_buff_size > BGE_SEND_BUFF_SIZE_DEFAULT)
2428 srp->tx_array_max = BGE_SEND_BUF_ARRAY_JUMBO;
2429 else
2430 srp->tx_array_max = BGE_SEND_BUF_ARRAY;
2431 srp->tx_array = 1;
2432
2433 /*
2434 * Chunk tx desc area
2435 */
2436 desc = srp->desc;
2437 for (slot = 0; slot < nslots; ++ssbdp, ++slot) {
2438 bge_slice_chunk(&ssbdp->desc, &desc, 1,
2439 sizeof (bge_sbd_t));
2440 }
2441 ASSERT(desc.alength == 0);
2442
2443 /*
2444 * Chunk tx buffer area
2445 */
2446 for (split = 0; split < BGE_SPLIT; ++split) {
2447 pbuf = srp->buf[0][split];
2448 for (slot = 0; slot < BGE_SEND_BUF_NUM/BGE_SPLIT; ++slot) {
2449 bge_slice_chunk(&txbuf->buf, &pbuf, 1,
2450 bgep->chipid.snd_buff_size);
2451 txbuf++;
2452 }
2453 ASSERT(pbuf.alength == 0);
2454 }
2455 }
2456
2457 /*
2458 * Clean up initialisation done above before the memory is freed
2459 */
2460 static void
2461 bge_fini_send_ring(bge_t *bgep, uint64_t ring)
2462 {
2463 send_ring_t *srp;
2464 uint32_t array;
2465 uint32_t split;
2466 uint32_t nslots;
2467
2468 BGE_TRACE(("bge_fini_send_ring($%p, %d)",
2469 (void *)bgep, ring));
2470
2471 srp = &bgep->send[ring];
2472 mutex_destroy(srp->tc_lock);
2473 mutex_destroy(srp->freetxbuf_lock);
2474 mutex_destroy(srp->txbuf_lock);
2475 mutex_destroy(srp->tx_lock);
2476 nslots = srp->desc.nslots;
2477 if (nslots == 0)
2478 return;
2479
2480 for (array = 1; array < srp->tx_array; ++array)
2481 for (split = 0; split < BGE_SPLIT; ++split)
2482 bge_free_dma_mem(&srp->buf[array][split]);
2483 kmem_free(srp->sw_sbds, nslots*sizeof (*srp->sw_sbds));
2484 kmem_free(srp->txbuf_head, BGE_SEND_BUF_MAX*sizeof (*srp->txbuf_head));
2485 kmem_free(srp->txbuf, BGE_SEND_BUF_MAX*sizeof (*srp->txbuf));
2486 kmem_free(srp->pktp, BGE_SEND_BUF_MAX*sizeof (*srp->pktp));
2487 srp->sw_sbds = NULL;
2488 srp->txbuf_head = NULL;
2489 srp->txbuf = NULL;
2490 srp->pktp = NULL;
2491 }
2492
2493 /*
2494 * Initialise all transmit, receive, and buffer rings.
2495 */
2496 void
2497 bge_init_rings(bge_t *bgep)
2498 {
2499 uint32_t ring;
2500
2501 BGE_TRACE(("bge_init_rings($%p)", (void *)bgep));
2502
2503 /*
2504 * Perform one-off initialisation of each ring ...
2505 */
2506 for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
2507 bge_init_send_ring(bgep, ring);
2508 for (ring = 0; ring < BGE_RECV_RINGS_MAX; ++ring)
2509 bge_init_recv_ring(bgep, ring);
2510 for (ring = 0; ring < BGE_BUFF_RINGS_MAX; ++ring)
2511 bge_init_buff_ring(bgep, ring);
2512 }
2513
2514 /*
2515 * Undo the work of bge_init_rings() above before the memory is freed
2516 */
2517 void
2518 bge_fini_rings(bge_t *bgep)
2519 {
2520 uint32_t ring;
2521
2522 BGE_TRACE(("bge_fini_rings($%p)", (void *)bgep));
2523
2524 for (ring = 0; ring < BGE_BUFF_RINGS_MAX; ++ring)
2525 bge_fini_buff_ring(bgep, ring);
2526 for (ring = 0; ring < BGE_RECV_RINGS_MAX; ++ring)
2527 bge_fini_recv_ring(bgep, ring);
2528 for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
2529 bge_fini_send_ring(bgep, ring);
2530 }
2531
2532 /*
2533 * Called from the bge_m_stop() to free the tx buffers which are
2534 * allocated from the tx process.
2535 */
2536 void
2537 bge_free_txbuf_arrays(send_ring_t *srp)
2538 {
2539 uint32_t array;
2540 uint32_t split;
2541
2542 ASSERT(mutex_owned(srp->tx_lock));
2543
2544 /*
2545 * Free the extra tx buffer DMA area
2546 */
2547 for (array = 1; array < srp->tx_array; ++array)
2548 for (split = 0; split < BGE_SPLIT; ++split)
2549 bge_free_dma_mem(&srp->buf[array][split]);
2550
2551 /*
2552 * Restore initial tx buffer numbers
2553 */
2554 srp->tx_array = 1;
2555 srp->tx_buffers = BGE_SEND_BUF_NUM;
2556 srp->tx_buffers_low = srp->tx_buffers / 4;
2557 srp->tx_flow = 0;
2558 bzero(srp->pktp, BGE_SEND_BUF_MAX * sizeof (*srp->pktp));
2559 }
2560
2561 /*
2562 * Called from tx process to allocate more tx buffers
2563 */
2564 bge_queue_item_t *
2565 bge_alloc_txbuf_array(bge_t *bgep, send_ring_t *srp)
2566 {
2567 bge_queue_t *txbuf_queue;
2568 bge_queue_item_t *txbuf_item_last;
2569 bge_queue_item_t *txbuf_item;
2570 bge_queue_item_t *txbuf_item_rtn;
2571 sw_txbuf_t *txbuf;
2572 dma_area_t area;
2573 size_t txbuffsize;
2574 uint32_t slot;
2575 uint32_t array;
2576 uint32_t split;
2577 uint32_t err;
2578
2579 ASSERT(mutex_owned(srp->tx_lock));
2580
2581 array = srp->tx_array;
2582 if (array >= srp->tx_array_max)
2583 return (NULL);
2584
2585 /*
2586 * Allocate memory & handles for TX buffers
2587 */
2588 txbuffsize = BGE_SEND_BUF_NUM*bgep->chipid.snd_buff_size;
2589 ASSERT((txbuffsize % BGE_SPLIT) == 0);
2590 for (split = 0; split < BGE_SPLIT; ++split) {
2591 err = bge_alloc_dma_mem(bgep, txbuffsize/BGE_SPLIT,
2592 &bge_data_accattr, DDI_DMA_WRITE | BGE_DMA_MODE,
2593 &srp->buf[array][split]);
2594 if (err != DDI_SUCCESS) {
2595 /* Free the last already allocated OK chunks */
2596 for (slot = 0; slot <= split; ++slot)
2597 bge_free_dma_mem(&srp->buf[array][slot]);
2598 srp->tx_alloc_fail++;
2599 return (NULL);
2600 }
2601 }
2602
2603 /*
2604 * Chunk tx buffer area
2605 */
2606 txbuf = srp->txbuf + array*BGE_SEND_BUF_NUM;
2607 for (split = 0; split < BGE_SPLIT; ++split) {
2608 area = srp->buf[array][split];
2609 for (slot = 0; slot < BGE_SEND_BUF_NUM/BGE_SPLIT; ++slot) {
2610 bge_slice_chunk(&txbuf->buf, &area, 1,
2611 bgep->chipid.snd_buff_size);
2612 txbuf++;
2613 }
2614 }
2615
2616 /*
2617 * Add above buffers to the tx buffer pop queue
2618 */
2619 txbuf_item = srp->txbuf_head + array*BGE_SEND_BUF_NUM;
2620 txbuf = srp->txbuf + array*BGE_SEND_BUF_NUM;
2621 txbuf_item_last = NULL;
2622 for (slot = 0; slot < BGE_SEND_BUF_NUM; ++slot) {
2623 txbuf_item->item = txbuf;
2624 txbuf_item->next = txbuf_item_last;
2625 txbuf_item_last = txbuf_item;
2626 txbuf++;
2627 txbuf_item++;
2628 }
2629 txbuf_item = srp->txbuf_head + array*BGE_SEND_BUF_NUM;
2630 txbuf_item_rtn = txbuf_item;
2631 txbuf_item++;
2632 txbuf_queue = srp->txbuf_pop_queue;
2633 mutex_enter(txbuf_queue->lock);
2634 txbuf_item->next = txbuf_queue->head;
2635 txbuf_queue->head = txbuf_item_last;
2636 txbuf_queue->count += BGE_SEND_BUF_NUM - 1;
2637 mutex_exit(txbuf_queue->lock);
2638
2639 srp->tx_array++;
2640 srp->tx_buffers += BGE_SEND_BUF_NUM;
2641 srp->tx_buffers_low = srp->tx_buffers / 4;
2642
2643 return (txbuf_item_rtn);
2644 }
2645
2646 /*
2647 * This function allocates all the transmit and receive buffers
2648 * and descriptors, in four chunks.
2649 */
2650 int
2651 bge_alloc_bufs(bge_t *bgep)
2652 {
2653 dma_area_t area;
2654 size_t rxbuffsize;
2655 size_t txbuffsize;
2656 size_t rxbuffdescsize;
2657 size_t rxdescsize;
2658 size_t txdescsize;
2659 uint32_t ring;
2660 uint32_t rx_rings = bgep->chipid.rx_rings;
2661 uint32_t tx_rings = bgep->chipid.tx_rings;
2662 int split;
2663 int err;
2664
2665 BGE_TRACE(("bge_alloc_bufs($%p)",
2666 (void *)bgep));
2667
2668 rxbuffsize = BGE_STD_SLOTS_USED*bgep->chipid.std_buf_size;
2669 rxbuffsize += bgep->chipid.jumbo_slots*bgep->chipid.recv_jumbo_size;
2670 rxbuffsize += BGE_MINI_SLOTS_USED*BGE_MINI_BUFF_SIZE;
2671
2672 txbuffsize = BGE_SEND_BUF_NUM*bgep->chipid.snd_buff_size;
2673 txbuffsize *= tx_rings;
2674
2675 rxdescsize = rx_rings*bgep->chipid.recv_slots;
2676 rxdescsize *= sizeof (bge_rbd_t);
2677
2678 rxbuffdescsize = BGE_STD_SLOTS_USED;
2679 rxbuffdescsize += bgep->chipid.jumbo_slots;
2680 rxbuffdescsize += BGE_MINI_SLOTS_USED;
2681 rxbuffdescsize *= sizeof (bge_rbd_t);
2682
2683 txdescsize = tx_rings*BGE_SEND_SLOTS_USED;
2684 txdescsize *= sizeof (bge_sbd_t);
2685 txdescsize += sizeof (bge_statistics_t);
2686 txdescsize += sizeof (bge_status_t);
2687 txdescsize += BGE_STATUS_PADDING;
2688
2689 /*
2690 * Enable PCI relaxed ordering only for RX/TX data buffers
2691 */
2692 if (!(DEVICE_5717_SERIES_CHIPSETS(bgep) ||
2693 DEVICE_5725_SERIES_CHIPSETS(bgep))) {
2694 if (bge_relaxed_ordering)
2695 dma_attr.dma_attr_flags |= DDI_DMA_RELAXED_ORDERING;
2696 }
2697
2698 /*
2699 * Allocate memory & handles for RX buffers
2700 */
2701 ASSERT((rxbuffsize % BGE_SPLIT) == 0);
2702 for (split = 0; split < BGE_SPLIT; ++split) {
2703 err = bge_alloc_dma_mem(bgep, rxbuffsize/BGE_SPLIT,
2704 &bge_data_accattr, DDI_DMA_READ | BGE_DMA_MODE,
2705 &bgep->rx_buff[split]);
2706 if (err != DDI_SUCCESS)
2707 return (DDI_FAILURE);
2708 }
2709 BGE_DEBUG(("DMA ALLOC: allocated %d chunks for Rx Buffers (rxbuffsize = %d)",
2710 rxbuffsize/BGE_SPLIT,
2711 rxbuffsize));
2712
2713 /*
2714 * Allocate memory & handles for TX buffers
2715 */
2716 ASSERT((txbuffsize % BGE_SPLIT) == 0);
2717 for (split = 0; split < BGE_SPLIT; ++split) {
2718 err = bge_alloc_dma_mem(bgep, txbuffsize/BGE_SPLIT,
2719 &bge_data_accattr, DDI_DMA_WRITE | BGE_DMA_MODE,
2720 &bgep->tx_buff[split]);
2721 if (err != DDI_SUCCESS)
2722 return (DDI_FAILURE);
2723 }
2724 BGE_DEBUG(("DMA ALLOC: allocated %d chunks for Tx Buffers (txbuffsize = %d)",
2725 txbuffsize/BGE_SPLIT,
2726 txbuffsize));
2727
2728 if (!(DEVICE_5717_SERIES_CHIPSETS(bgep) ||
2729 DEVICE_5725_SERIES_CHIPSETS(bgep))) {
2730 /* no relaxed ordering for descriptors rings? */
2731 dma_attr.dma_attr_flags &= ~DDI_DMA_RELAXED_ORDERING;
2732 }
2733
2734 /*
2735 * Allocate memory & handles for receive return rings
2736 */
2737 ASSERT((rxdescsize % rx_rings) == 0);
2738 for (split = 0; split < rx_rings; ++split) {
2739 err = bge_alloc_dma_mem(bgep, rxdescsize/rx_rings,
2740 &bge_desc_accattr, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2741 &bgep->rx_desc[split]);
2742 if (err != DDI_SUCCESS)
2743 return (DDI_FAILURE);
2744 }
2745 BGE_DEBUG(("DMA ALLOC: allocated %d chunks for Rx Descs cons (rx_rings = %d, rxdescsize = %d)",
2746 rxdescsize/rx_rings,
2747 rx_rings,
2748 rxdescsize));
2749
2750 /*
2751 * Allocate memory & handles for buffer (producer) descriptor rings.
2752 * Note that split=rx_rings.
2753 */
2754 err = bge_alloc_dma_mem(bgep, rxbuffdescsize, &bge_desc_accattr,
2755 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, &bgep->rx_desc[split]);
2756 if (err != DDI_SUCCESS)
2757 return (DDI_FAILURE);
2758 BGE_DEBUG(("DMA ALLOC: allocated 1 chunks for Rx Descs prod (rxbuffdescsize = %d)",
2759 rxdescsize));
2760
2761 /*
2762 * Allocate memory & handles for TX descriptor rings,
2763 * status block, and statistics area
2764 */
2765 err = bge_alloc_dma_mem(bgep, txdescsize, &bge_desc_accattr,
2766 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, &bgep->tx_desc);
2767 if (err != DDI_SUCCESS)
2768 return (DDI_FAILURE);
2769 BGE_DEBUG(("DMA ALLOC: allocated 1 chunks for Tx Descs / Status Block / Stats (txdescdize = %d)",
2770 txdescsize));
2771
2772 /*
2773 * Now carve up each of the allocated areas ...
2774 */
2775
2776 /* rx buffers */
2777 for (split = 0; split < BGE_SPLIT; ++split) {
2778 area = bgep->rx_buff[split];
2779
2780 BGE_DEBUG(("RXB CHNK %d INIT: va=%p alen=%d off=%d pa=%llx psz=%d",
2781 split,
2782 area.mem_va,
2783 area.alength,
2784 area.offset,
2785 area.cookie.dmac_laddress,
2786 area.cookie.dmac_size));
2787
2788 bge_slice_chunk(&bgep->buff[BGE_STD_BUFF_RING].buf[split],
2789 &area, BGE_STD_SLOTS_USED/BGE_SPLIT,
2790 bgep->chipid.std_buf_size);
2791
2792 BGE_DEBUG(("RXB SLCE %d STND: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2793 split,
2794 bgep->buff[BGE_STD_BUFF_RING].buf[split].mem_va,
2795 bgep->buff[BGE_STD_BUFF_RING].buf[split].alength,
2796 bgep->buff[BGE_STD_BUFF_RING].buf[split].offset,
2797 bgep->buff[BGE_STD_BUFF_RING].buf[split].cookie.dmac_laddress,
2798 bgep->buff[BGE_STD_BUFF_RING].buf[split].cookie.dmac_size,
2799 BGE_STD_SLOTS_USED/BGE_SPLIT,
2800 bgep->chipid.std_buf_size));
2801
2802 bge_slice_chunk(&bgep->buff[BGE_JUMBO_BUFF_RING].buf[split],
2803 &area, bgep->chipid.jumbo_slots/BGE_SPLIT,
2804 bgep->chipid.recv_jumbo_size);
2805
2806 if ((bgep->chipid.jumbo_slots / BGE_SPLIT) > 0)
2807 {
2808 BGE_DEBUG(("RXB SLCE %d JUMB: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2809 split,
2810 bgep->buff[BGE_JUMBO_BUFF_RING].buf[split].mem_va,
2811 bgep->buff[BGE_JUMBO_BUFF_RING].buf[split].alength,
2812 bgep->buff[BGE_JUMBO_BUFF_RING].buf[split].offset,
2813 bgep->buff[BGE_JUMBO_BUFF_RING].buf[split].cookie.dmac_laddress,
2814 bgep->buff[BGE_JUMBO_BUFF_RING].buf[split].cookie.dmac_size,
2815 bgep->chipid.jumbo_slots/BGE_SPLIT,
2816 bgep->chipid.recv_jumbo_size));
2817 }
2818
2819 bge_slice_chunk(&bgep->buff[BGE_MINI_BUFF_RING].buf[split],
2820 &area, BGE_MINI_SLOTS_USED/BGE_SPLIT,
2821 BGE_MINI_BUFF_SIZE);
2822
2823 if ((BGE_MINI_SLOTS_USED / BGE_SPLIT) > 0)
2824 {
2825 BGE_DEBUG(("RXB SLCE %d MINI: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2826 split,
2827 bgep->buff[BGE_MINI_BUFF_RING].buf[split].mem_va,
2828 bgep->buff[BGE_MINI_BUFF_RING].buf[split].alength,
2829 bgep->buff[BGE_MINI_BUFF_RING].buf[split].offset,
2830 bgep->buff[BGE_MINI_BUFF_RING].buf[split].cookie.dmac_laddress,
2831 bgep->buff[BGE_MINI_BUFF_RING].buf[split].cookie.dmac_size,
2832 BGE_MINI_SLOTS_USED/BGE_SPLIT,
2833 BGE_MINI_BUFF_SIZE));
2834 }
2835
2836 BGE_DEBUG(("RXB CHNK %d DONE: va=%p alen=%d off=%d pa=%llx psz=%d",
2837 split,
2838 area.mem_va,
2839 area.alength,
2840 area.offset,
2841 area.cookie.dmac_laddress,
2842 area.cookie.dmac_size));
2843 }
2844
2845 /* tx buffers */
2846 for (split = 0; split < BGE_SPLIT; ++split) {
2847 area = bgep->tx_buff[split];
2848
2849 BGE_DEBUG(("TXB CHNK %d INIT: va=%p alen=%d off=%d pa=%llx psz=%d",
2850 split,
2851 area.mem_va,
2852 area.alength,
2853 area.offset,
2854 area.cookie.dmac_laddress,
2855 area.cookie.dmac_size));
2856
2857 for (ring = 0; ring < tx_rings; ++ring) {
2858 bge_slice_chunk(&bgep->send[ring].buf[0][split],
2859 &area, BGE_SEND_BUF_NUM/BGE_SPLIT,
2860 bgep->chipid.snd_buff_size);
2861
2862 BGE_DEBUG(("TXB SLCE %d RING %d: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2863 split, ring,
2864 bgep->send[ring].buf[0][split].mem_va,
2865 bgep->send[ring].buf[0][split].alength,
2866 bgep->send[ring].buf[0][split].offset,
2867 bgep->send[ring].buf[0][split].cookie.dmac_laddress,
2868 bgep->send[ring].buf[0][split].cookie.dmac_size,
2869 BGE_SEND_BUF_NUM/BGE_SPLIT,
2870 bgep->chipid.snd_buff_size));
2871 }
2872
2873 for (; ring < BGE_SEND_RINGS_MAX; ++ring) {
2874 bge_slice_chunk(&bgep->send[ring].buf[0][split],
2875 &area, 0, bgep->chipid.snd_buff_size);
2876 }
2877
2878 BGE_DEBUG(("TXB CHNK %d DONE: va=%p alen=%d off=%d pa=%llx psz=%d",
2879 split,
2880 area.mem_va,
2881 area.alength,
2882 area.offset,
2883 area.cookie.dmac_laddress,
2884 area.cookie.dmac_size));
2885 }
2886
2887 for (ring = 0; ring < rx_rings; ++ring) {
2888 bge_slice_chunk(&bgep->recv[ring].desc, &bgep->rx_desc[ring],
2889 bgep->chipid.recv_slots, sizeof (bge_rbd_t));
2890
2891 BGE_DEBUG(("RXD CONS RING %d: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2892 ring,
2893 bgep->recv[ring].desc.mem_va,
2894 bgep->recv[ring].desc.alength,
2895 bgep->recv[ring].desc.offset,
2896 bgep->recv[ring].desc.cookie.dmac_laddress,
2897 bgep->recv[ring].desc.cookie.dmac_size,
2898 bgep->chipid.recv_slots,
2899 sizeof(bge_rbd_t)));
2900 }
2901
2902 /* dma alloc for rxbuffdescsize is located at bgep->rx_desc[#rings] */
2903 area = bgep->rx_desc[rx_rings]; /* note rx_rings = one beyond rings */
2904
2905 for (; ring < BGE_RECV_RINGS_MAX; ++ring) /* skip unused rings */
2906 bge_slice_chunk(&bgep->recv[ring].desc, &area,
2907 0, sizeof (bge_rbd_t));
2908
2909 BGE_DEBUG(("RXD PROD INIT: va=%p alen=%d off=%d pa=%llx psz=%d",
2910 area.mem_va,
2911 area.alength,
2912 area.offset,
2913 area.cookie.dmac_laddress,
2914 area.cookie.dmac_size));
2915
2916 bge_slice_chunk(&bgep->buff[BGE_STD_BUFF_RING].desc, &area,
2917 BGE_STD_SLOTS_USED, sizeof (bge_rbd_t));
2918 BGE_DEBUG(("RXD PROD STND: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2919 bgep->buff[BGE_STD_BUFF_RING].desc.mem_va,
2920 bgep->buff[BGE_STD_BUFF_RING].desc.alength,
2921 bgep->buff[BGE_STD_BUFF_RING].desc.offset,
2922 bgep->buff[BGE_STD_BUFF_RING].desc.cookie.dmac_laddress,
2923 bgep->buff[BGE_STD_BUFF_RING].desc.cookie.dmac_size,
2924 BGE_STD_SLOTS_USED,
2925 sizeof(bge_rbd_t)));
2926
2927 bge_slice_chunk(&bgep->buff[BGE_JUMBO_BUFF_RING].desc, &area,
2928 bgep->chipid.jumbo_slots, sizeof (bge_rbd_t));
2929 BGE_DEBUG(("RXD PROD JUMB: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2930 bgep->buff[BGE_JUMBO_BUFF_RING].desc.mem_va,
2931 bgep->buff[BGE_JUMBO_BUFF_RING].desc.alength,
2932 bgep->buff[BGE_JUMBO_BUFF_RING].desc.offset,
2933 bgep->buff[BGE_JUMBO_BUFF_RING].desc.cookie.dmac_laddress,
2934 bgep->buff[BGE_JUMBO_BUFF_RING].desc.cookie.dmac_size,
2935 bgep->chipid.jumbo_slots,
2936 sizeof(bge_rbd_t)));
2937
2938 bge_slice_chunk(&bgep->buff[BGE_MINI_BUFF_RING].desc, &area,
2939 BGE_MINI_SLOTS_USED, sizeof (bge_rbd_t));
2940 BGE_DEBUG(("RXD PROD MINI: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2941 bgep->buff[BGE_MINI_BUFF_RING].desc.mem_va,
2942 bgep->buff[BGE_MINI_BUFF_RING].desc.alength,
2943 bgep->buff[BGE_MINI_BUFF_RING].desc.offset,
2944 bgep->buff[BGE_MINI_BUFF_RING].desc.cookie.dmac_laddress,
2945 bgep->buff[BGE_MINI_BUFF_RING].desc.cookie.dmac_size,
2946 BGE_MINI_SLOTS_USED,
2947 sizeof(bge_rbd_t)));
2948
2949 BGE_DEBUG(("RXD PROD DONE: va=%p alen=%d off=%d pa=%llx psz=%d",
2950 area.mem_va,
2951 area.alength,
2952 area.offset,
2953 area.cookie.dmac_laddress,
2954 area.cookie.dmac_size));
2955
2956 ASSERT(area.alength == 0);
2957
2958 area = bgep->tx_desc;
2959
2960 BGE_DEBUG(("TXD INIT: va=%p alen=%d off=%d pa=%llx psz=%d",
2961 area.mem_va,
2962 area.alength,
2963 area.offset,
2964 area.cookie.dmac_laddress,
2965 area.cookie.dmac_size));
2966
2967 for (ring = 0; ring < tx_rings; ++ring) {
2968 bge_slice_chunk(&bgep->send[ring].desc, &area,
2969 BGE_SEND_SLOTS_USED, sizeof (bge_sbd_t));
2970
2971 BGE_DEBUG(("TXD RING %d: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2972 ring,
2973 bgep->send[ring].desc.mem_va,
2974 bgep->send[ring].desc.alength,
2975 bgep->send[ring].desc.offset,
2976 bgep->send[ring].desc.cookie.dmac_laddress,
2977 bgep->send[ring].desc.cookie.dmac_size,
2978 BGE_SEND_SLOTS_USED,
2979 sizeof(bge_sbd_t)));
2980 }
2981
2982 for (; ring < BGE_SEND_RINGS_MAX; ++ring) /* skip unused rings */
2983 bge_slice_chunk(&bgep->send[ring].desc, &area,
2984 0, sizeof (bge_sbd_t));
2985
2986 bge_slice_chunk(&bgep->statistics, &area, 1, sizeof (bge_statistics_t));
2987 BGE_DEBUG(("TXD STATISTICS: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2988 bgep->statistics.mem_va,
2989 bgep->statistics.alength,
2990 bgep->statistics.offset,
2991 bgep->statistics.cookie.dmac_laddress,
2992 bgep->statistics.cookie.dmac_size,
2993 1,
2994 sizeof(bge_statistics_t)));
2995
2996 bge_slice_chunk(&bgep->status_block, &area, 1, sizeof (bge_status_t));
2997 BGE_DEBUG(("TXD STATUS BLOCK: va=%p alen=%d off=%d pa=%llx psz=%d (nslots=%d slotlen=%d)",
2998 bgep->status_block.mem_va,
2999 bgep->status_block.alength,
3000 bgep->status_block.offset,
3001 bgep->status_block.cookie.dmac_laddress,
3002 bgep->status_block.cookie.dmac_size,
3003 1,
3004 sizeof(bge_status_t)));
3005
3006 BGE_DEBUG(("TXD DONE: va=%p alen=%d off=%d pa=%llx psz=%d",
3007 area.mem_va,
3008 area.alength,
3009 area.offset,
3010 area.cookie.dmac_laddress,
3011 area.cookie.dmac_size));
3012
3013 ASSERT(area.alength == BGE_STATUS_PADDING);
3014
3015 DMA_ZERO(bgep->status_block);
3016
3017 return (DDI_SUCCESS);
3018 }
3019
3020 #undef BGE_DBG
3021 #define BGE_DBG BGE_DBG_INIT /* debug flag for this code */
3022
3023 /*
3024 * This routine frees the transmit and receive buffers and descriptors.
3025 * Make sure the chip is stopped before calling it!
3026 */
3027 void
3028 bge_free_bufs(bge_t *bgep)
3029 {
3030 int split;
3031
3032 BGE_TRACE(("bge_free_bufs($%p)",
3033 (void *)bgep));
3034
3035 bge_free_dma_mem(&bgep->tx_desc);
3036 for (split = 0; split < BGE_RECV_RINGS_SPLIT; ++split)
3037 bge_free_dma_mem(&bgep->rx_desc[split]);
3038 for (split = 0; split < BGE_SPLIT; ++split)
3039 bge_free_dma_mem(&bgep->tx_buff[split]);
3040 for (split = 0; split < BGE_SPLIT; ++split)
3041 bge_free_dma_mem(&bgep->rx_buff[split]);
3042 }
3043
3044 /*
3045 * Determine (initial) MAC address ("BIA") to use for this interface
3046 */
3047
3048 static void
3049 bge_find_mac_address(bge_t *bgep, chip_id_t *cidp)
3050 {
3051 struct ether_addr sysaddr;
3052 char propbuf[8]; /* "true" or "false", plus NUL */
3053 uchar_t *bytes;
3054 int *ints;
3055 uint_t nelts;
3056 int err;
3057
3058 BGE_TRACE(("bge_find_mac_address($%p)",
3059 (void *)bgep));
3060
3061 BGE_DEBUG(("bge_find_mac_address: hw_mac_addr %012llx, => %s (%sset)",
3062 cidp->hw_mac_addr,
3063 ether_sprintf((void *)cidp->vendor_addr.addr),
3064 cidp->vendor_addr.set ? "" : "not "));
3065
3066 /*
3067 * The "vendor's factory-set address" may already have
3068 * been extracted from the chip, but if the property
3069 * "local-mac-address" is set we use that instead. It
3070 * will normally be set by OBP, but it could also be
3071 * specified in a .conf file(!)
3072 *
3073 * There doesn't seem to be a way to define byte-array
3074 * properties in a .conf, so we check whether it looks
3075 * like an array of 6 ints instead.
3076 *
3077 * Then, we check whether it looks like an array of 6
3078 * bytes (which it should, if OBP set it). If we can't
3079 * make sense of it either way, we'll ignore it.
3080 */
3081 err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, bgep->devinfo,
3082 DDI_PROP_DONTPASS, localmac_propname, &ints, &nelts);
3083 if (err == DDI_PROP_SUCCESS) {
3084 if (nelts == ETHERADDRL) {
3085 while (nelts--)
3086 cidp->vendor_addr.addr[nelts] = ints[nelts];
3087 cidp->vendor_addr.set = B_TRUE;
3088 }
3089 ddi_prop_free(ints);
3090 }
3091
3092 err = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, bgep->devinfo,
3093 DDI_PROP_DONTPASS, localmac_propname, &bytes, &nelts);
3094 if (err == DDI_PROP_SUCCESS) {
3095 if (nelts == ETHERADDRL) {
3096 while (nelts--)
3097 cidp->vendor_addr.addr[nelts] = bytes[nelts];
3098 cidp->vendor_addr.set = B_TRUE;
3099 }
3100 ddi_prop_free(bytes);
3101 }
3102
3103 BGE_DEBUG(("bge_find_mac_address: +local %s (%sset)",
3104 ether_sprintf((void *)cidp->vendor_addr.addr),
3105 cidp->vendor_addr.set ? "" : "not "));
3106
3107 /*
3108 * Look up the OBP property "local-mac-address?". Note that even
3109 * though its value is a string (which should be "true" or "false"),
3110 * it can't be decoded by ddi_prop_lookup_string(9F). So, we zero
3111 * the buffer first and then fetch the property as an untyped array;
3112 * this may or may not include a final NUL, but since there will
3113 * always be one left at the end of the buffer we can now treat it
3114 * as a string anyway.
3115 */
3116 nelts = sizeof (propbuf);
3117 bzero(propbuf, nelts--);
3118 err = ddi_getlongprop_buf(DDI_DEV_T_ANY, bgep->devinfo,
3119 DDI_PROP_CANSLEEP, localmac_boolname, propbuf, (int *)&nelts);
3120
3121 /*
3122 * Now, if the address still isn't set from the hardware (SEEPROM)
3123 * or the OBP or .conf property, OR if the user has foolishly set
3124 * 'local-mac-address? = false', use "the system address" instead
3125 * (but only if it's non-null i.e. has been set from the IDPROM).
3126 */
3127 if (cidp->vendor_addr.set == B_FALSE || strcmp(propbuf, "false") == 0)
3128 if (localetheraddr(NULL, &sysaddr) != 0) {
3129 ethaddr_copy(&sysaddr, cidp->vendor_addr.addr);
3130 cidp->vendor_addr.set = B_TRUE;
3131 }
3132
3133 BGE_DEBUG(("bge_find_mac_address: +system %s (%sset)",
3134 ether_sprintf((void *)cidp->vendor_addr.addr),
3135 cidp->vendor_addr.set ? "" : "not "));
3136
3137 /*
3138 * Finally(!), if there's a valid "mac-address" property (created
3139 * if we netbooted from this interface), we must use this instead
3140 * of any of the above to ensure that the NFS/install server doesn't
3141 * get confused by the address changing as Solaris takes over!
3142 */
3143 err = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, bgep->devinfo,
3144 DDI_PROP_DONTPASS, macaddr_propname, &bytes, &nelts);
3145 if (err == DDI_PROP_SUCCESS) {
3146 if (nelts == ETHERADDRL) {
3147 while (nelts--)
3148 cidp->vendor_addr.addr[nelts] = bytes[nelts];
3149 cidp->vendor_addr.set = B_TRUE;
3150 }
3151 ddi_prop_free(bytes);
3152 }
3153
3154 BGE_DEBUG(("bge_find_mac_address: =final %s (%sset)",
3155 ether_sprintf((void *)cidp->vendor_addr.addr),
3156 cidp->vendor_addr.set ? "" : "not "));
3157 }
3158
3159 /*ARGSUSED*/
3160 int
3161 bge_check_acc_handle(bge_t *bgep, ddi_acc_handle_t handle)
3162 {
3163 ddi_fm_error_t de;
3164
3165 ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
3166 ddi_fm_acc_err_clear(handle, DDI_FME_VERSION);
3167 return (de.fme_status);
3168 }
3169
3170 /*ARGSUSED*/
3171 int
3172 bge_check_dma_handle(bge_t *bgep, ddi_dma_handle_t handle)
3173 {
3174 ddi_fm_error_t de;
3175
3176 ASSERT(bgep->progress & PROGRESS_BUFS);
3177 ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
3178 return (de.fme_status);
3179 }
3180
3181 /*
3182 * The IO fault service error handling callback function
3183 */
3184 /*ARGSUSED*/
3185 static int
3186 bge_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
3187 {
3188 /*
3189 * as the driver can always deal with an error in any dma or
3190 * access handle, we can just return the fme_status value.
3191 */
3192 pci_ereport_post(dip, err, NULL);
3193 return (err->fme_status);
3194 }
3195
3196 static void
3197 bge_fm_init(bge_t *bgep)
3198 {
3199 ddi_iblock_cookie_t iblk;
3200
3201 /* Only register with IO Fault Services if we have some capability */
3202 if (bgep->fm_capabilities) {
3203 bge_reg_accattr.devacc_attr_access = DDI_FLAGERR_ACC;
3204 dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
3205
3206 /* Register capabilities with IO Fault Services */
3207 ddi_fm_init(bgep->devinfo, &bgep->fm_capabilities, &iblk);
3208
3209 /*
3210 * Initialize pci ereport capabilities if ereport capable
3211 */
3212 if (DDI_FM_EREPORT_CAP(bgep->fm_capabilities) ||
3213 DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
3214 pci_ereport_setup(bgep->devinfo);
3215
3216 /*
3217 * Register error callback if error callback capable
3218 */
3219 if (DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
3220 ddi_fm_handler_register(bgep->devinfo,
3221 bge_fm_error_cb, (void*) bgep);
3222 } else {
3223 /*
3224 * These fields have to be cleared of FMA if there are no
3225 * FMA capabilities at runtime.
3226 */
3227 bge_reg_accattr.devacc_attr_access = DDI_DEFAULT_ACC;
3228 dma_attr.dma_attr_flags = 0;
3229 }
3230 }
3231
3232 static void
3233 bge_fm_fini(bge_t *bgep)
3234 {
3235 /* Only unregister FMA capabilities if we registered some */
3236 if (bgep->fm_capabilities) {
3237
3238 /*
3239 * Release any resources allocated by pci_ereport_setup()
3240 */
3241 if (DDI_FM_EREPORT_CAP(bgep->fm_capabilities) ||
3242 DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
3243 pci_ereport_teardown(bgep->devinfo);
3244
3245 /*
3246 * Un-register error callback if error callback capable
3247 */
3248 if (DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
3249 ddi_fm_handler_unregister(bgep->devinfo);
3250
3251 /* Unregister from IO Fault Services */
3252 ddi_fm_fini(bgep->devinfo);
3253 }
3254 }
3255
3256 static void
3257 #ifdef BGE_IPMI_ASF
3258 bge_unattach(bge_t *bgep, uint_t asf_mode)
3259 #else
3260 bge_unattach(bge_t *bgep)
3261 #endif
3262 {
3263 BGE_TRACE(("bge_unattach($%p)",
3264 (void *)bgep));
3265
3266 /*
3267 * Flag that no more activity may be initiated
3268 */
3269 bgep->progress &= ~PROGRESS_READY;
3270
3271 /*
3272 * Quiesce the PHY and MAC (leave it reset but still powered).
3273 * Clean up and free all BGE data structures
3274 */
3275 if (bgep->periodic_id != NULL) {
3276 ddi_periodic_delete(bgep->periodic_id);
3277 bgep->periodic_id = NULL;
3278 }
3279
3280 if (bgep->progress & PROGRESS_KSTATS)
3281 bge_fini_kstats(bgep);
3282 if (bgep->progress & PROGRESS_PHY)
3283 bge_phys_reset(bgep);
3284 if (bgep->progress & PROGRESS_HWINT) {
3285 mutex_enter(bgep->genlock);
3286 #ifdef BGE_IPMI_ASF
3287 if (bge_chip_reset(bgep, B_FALSE, asf_mode) != DDI_SUCCESS)
3288 #else
3289 if (bge_chip_reset(bgep, B_FALSE) != DDI_SUCCESS)
3290 #endif
3291 ddi_fm_service_impact(bgep->devinfo,
3292 DDI_SERVICE_UNAFFECTED);
3293 #ifdef BGE_IPMI_ASF
3294 if (bgep->asf_enabled) {
3295 /*
3296 * This register has been overlaid. We restore its
3297 * initial value here.
3298 */
3299 bge_nic_put32(bgep, BGE_NIC_DATA_SIG_ADDR,
3300 BGE_NIC_DATA_SIG);
3301 }
3302 #endif
3303 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK)
3304 ddi_fm_service_impact(bgep->devinfo,
3305 DDI_SERVICE_UNAFFECTED);
3306 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
3307 ddi_fm_service_impact(bgep->devinfo,
3308 DDI_SERVICE_UNAFFECTED);
3309 mutex_exit(bgep->genlock);
3310 }
3311 if (bgep->progress & PROGRESS_INTR) {
3312 bge_intr_disable(bgep);
3313 bge_fini_rings(bgep);
3314 }
3315 if (bgep->progress & PROGRESS_HWINT) {
3316 bge_rem_intrs(bgep);
3317 rw_destroy(bgep->errlock);
3318 mutex_destroy(bgep->softintrlock);
3319 mutex_destroy(bgep->genlock);
3320 }
3321 if (bgep->progress & PROGRESS_FACTOTUM)
3322 ddi_remove_softintr(bgep->factotum_id);
3323 if (bgep->progress & PROGRESS_RESCHED)
3324 ddi_remove_softintr(bgep->drain_id);
3325 if (bgep->progress & PROGRESS_BUFS)
3326 bge_free_bufs(bgep);
3327 if (bgep->progress & PROGRESS_REGS) {
3328 ddi_regs_map_free(&bgep->io_handle);
3329 if (bgep->ape_enabled)
3330 ddi_regs_map_free(&bgep->ape_handle);
3331 }
3332 if (bgep->progress & PROGRESS_CFG)
3333 pci_config_teardown(&bgep->cfg_handle);
3334
3335 bge_fm_fini(bgep);
3336
3337 ddi_remove_minor_node(bgep->devinfo, NULL);
3338 kmem_free(bgep->pstats, sizeof (bge_statistics_reg_t));
3339 kmem_free(bgep, sizeof (*bgep));
3340 }
3341
3342 static int
3343 bge_resume(dev_info_t *devinfo)
3344 {
3345 bge_t *bgep; /* Our private data */
3346 chip_id_t *cidp;
3347 chip_id_t chipid;
3348
3349 bgep = ddi_get_driver_private(devinfo);
3350 if (bgep == NULL)
3351 return (DDI_FAILURE);
3352
3353 /*
3354 * Refuse to resume if the data structures aren't consistent
3355 */
3356 if (bgep->devinfo != devinfo)
3357 return (DDI_FAILURE);
3358
3359 #ifdef BGE_IPMI_ASF
3360 /*
3361 * Power management hasn't been supported in BGE now. If you
3362 * want to implement it, please add the ASF/IPMI related
3363 * code here.
3364 */
3365
3366 #endif
3367
3368 /*
3369 * Read chip ID & set up config space command register(s)
3370 * Refuse to resume if the chip has changed its identity!
3371 */
3372 cidp = &bgep->chipid;
3373 mutex_enter(bgep->genlock);
3374 bge_chip_cfg_init(bgep, &chipid, B_FALSE);
3375 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
3376 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3377 mutex_exit(bgep->genlock);
3378 return (DDI_FAILURE);
3379 }
3380 mutex_exit(bgep->genlock);
3381 if (chipid.vendor != cidp->vendor)
3382 return (DDI_FAILURE);
3383 if (chipid.device != cidp->device)
3384 return (DDI_FAILURE);
3385 if (chipid.revision != cidp->revision)
3386 return (DDI_FAILURE);
3387 if (chipid.asic_rev != cidp->asic_rev)
3388 return (DDI_FAILURE);
3389
3390 /*
3391 * All OK, reinitialise h/w & kick off GLD scheduling
3392 */
3393 mutex_enter(bgep->genlock);
3394 if (bge_restart(bgep, B_TRUE) != DDI_SUCCESS) {
3395 (void) bge_check_acc_handle(bgep, bgep->cfg_handle);
3396 (void) bge_check_acc_handle(bgep, bgep->io_handle);
3397 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3398 mutex_exit(bgep->genlock);
3399 return (DDI_FAILURE);
3400 }
3401 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
3402 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3403 mutex_exit(bgep->genlock);
3404 return (DDI_FAILURE);
3405 }
3406 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
3407 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3408 mutex_exit(bgep->genlock);
3409 return (DDI_FAILURE);
3410 }
3411 mutex_exit(bgep->genlock);
3412 return (DDI_SUCCESS);
3413 }
3414
3415 static int
3416 bge_fw_img_is_valid(bge_t *bgep, uint32_t offset)
3417 {
3418 uint32_t val;
3419
3420 if (bge_nvmem_read32(bgep, offset, &val) ||
3421 (val & 0xfc000000) != 0x0c000000 ||
3422 bge_nvmem_read32(bgep, offset + 4, &val) ||
3423 val != 0)
3424 return (0);
3425
3426 return (1);
3427 }
3428
3429 static void
3430 bge_read_mgmtfw_ver(bge_t *bgep)
3431 {
3432 uint32_t val;
3433 uint32_t offset;
3434 uint32_t start;
3435 int i, vlen;
3436
3437 for (offset = NVM_DIR_START;
3438 offset < NVM_DIR_END;
3439 offset += NVM_DIRENT_SIZE) {
3440 if (bge_nvmem_read32(bgep, offset, &val))
3441 return;
3442
3443 if ((val >> NVM_DIRTYPE_SHIFT) == NVM_DIRTYPE_ASFINI)
3444 break;
3445 }
3446
3447 if (offset == NVM_DIR_END)
3448 return;
3449
3450 if (bge_nvmem_read32(bgep, offset - 4, &start))
3451 return;
3452
3453 if (bge_nvmem_read32(bgep, offset + 4, &offset) ||
3454 !bge_fw_img_is_valid(bgep, offset) ||
3455 bge_nvmem_read32(bgep, offset + 8, &val))
3456 return;
3457
3458 offset += val - start;
3459
3460 vlen = strlen(bgep->fw_version);
3461
3462 bgep->fw_version[vlen++] = ',';
3463 bgep->fw_version[vlen++] = ' ';
3464
3465 for (i = 0; i < 4; i++) {
3466 uint32_t v;
3467
3468 if (bge_nvmem_read32(bgep, offset, &v))
3469 return;
3470
3471 v = BE_32(v);
3472
3473 offset += sizeof(v);
3474
3475 if (vlen > BGE_FW_VER_SIZE - sizeof(v)) {
3476 memcpy(&bgep->fw_version[vlen], &v, BGE_FW_VER_SIZE - vlen);
3477 break;
3478 }
3479
3480 memcpy(&bgep->fw_version[vlen], &v, sizeof(v));
3481 vlen += sizeof(v);
3482 }
3483 }
3484
3485 static void
3486 bge_read_dash_ver(bge_t *bgep)
3487 {
3488 int vlen;
3489 uint32_t apedata;
3490 char *fwtype;
3491
3492 if (!bgep->ape_enabled || !bgep->asf_enabled)
3493 return;
3494
3495 apedata = bge_ape_get32(bgep, BGE_APE_SEG_SIG);
3496 if (apedata != APE_SEG_SIG_MAGIC)
3497 return;
3498
3499 apedata = bge_ape_get32(bgep, BGE_APE_FW_STATUS);
3500 if (!(apedata & APE_FW_STATUS_READY))
3501 return;
3502
3503 apedata = bge_ape_get32(bgep, BGE_APE_FW_VERSION);
3504
3505 if (bge_ape_get32(bgep, BGE_APE_FW_FEATURES) &
3506 BGE_APE_FW_FEATURE_NCSI) {
3507 bgep->ape_has_ncsi = B_TRUE;
3508 fwtype = "NCSI";
3509 } else if ((bgep->chipid.device == DEVICE_ID_5725) ||
3510 (bgep->chipid.device == DEVICE_ID_5727)) {
3511 fwtype = "SMASH";
3512 } else {
3513 fwtype = "DASH";
3514 }
3515
3516 vlen = strlen(bgep->fw_version);
3517
3518 snprintf(&bgep->fw_version[vlen], BGE_FW_VER_SIZE - vlen,
3519 " %s v%d.%d.%d.%d", fwtype,
3520 (apedata & APE_FW_VERSION_MAJMSK) >> APE_FW_VERSION_MAJSFT,
3521 (apedata & APE_FW_VERSION_MINMSK) >> APE_FW_VERSION_MINSFT,
3522 (apedata & APE_FW_VERSION_REVMSK) >> APE_FW_VERSION_REVSFT,
3523 (apedata & APE_FW_VERSION_BLDMSK));
3524 }
3525
3526 static void
3527 bge_read_bc_ver(bge_t *bgep)
3528 {
3529 uint32_t val;
3530 uint32_t offset;
3531 uint32_t start;
3532 uint32_t ver_offset;
3533 int i, dst_off;
3534 uint32_t major;
3535 uint32_t minor;
3536 boolean_t newver = B_FALSE;
3537
3538 if (bge_nvmem_read32(bgep, 0xc, &offset) ||
3539 bge_nvmem_read32(bgep, 0x4, &start))
3540 return;
3541
3542 if (bge_nvmem_read32(bgep, offset, &val))
3543 return;
3544
3545 if ((val & 0xfc000000) == 0x0c000000) {
3546 if (bge_nvmem_read32(bgep, offset + 4, &val))
3547 return;
3548
3549 if (val == 0)
3550 newver = B_TRUE;
3551 }
3552
3553 dst_off = strlen(bgep->fw_version);
3554
3555 if (newver) {
3556 if (((BGE_FW_VER_SIZE - dst_off) < 16) ||
3557 bge_nvmem_read32(bgep, offset + 8, &ver_offset))
3558 return;
3559
3560 offset = offset + ver_offset - start;
3561 for (i = 0; i < 16; i += 4) {
3562 if (bge_nvmem_read32(bgep, offset + i, &val))
3563 return;
3564 val = BE_32(val);
3565 memcpy(bgep->fw_version + dst_off + i, &val,
3566 sizeof(val));
3567 }
3568 } else {
3569 if (bge_nvmem_read32(bgep, NVM_PTREV_BCVER, &ver_offset))
3570 return;
3571
3572 major = (ver_offset & NVM_BCVER_MAJMSK) >> NVM_BCVER_MAJSFT;
3573 minor = ver_offset & NVM_BCVER_MINMSK;
3574 snprintf(&bgep->fw_version[dst_off], BGE_FW_VER_SIZE - dst_off,
3575 "v%d.%02d", major, minor);
3576 }
3577 }
3578
3579 static void
3580 bge_read_fw_ver(bge_t *bgep)
3581 {
3582 uint32_t val;
3583 uint32_t magic;
3584
3585 *bgep->fw_version = 0;
3586
3587 if ((bgep->chipid.nvtype == BGE_NVTYPE_NONE) ||
3588 (bgep->chipid.nvtype == BGE_NVTYPE_UNKNOWN)) {
3589 snprintf(bgep->fw_version, sizeof(bgep->fw_version), "sb");
3590 return;
3591 }
3592
3593 mutex_enter(bgep->genlock);
3594
3595 bge_nvmem_read32(bgep, 0, &magic);
3596
3597 if (magic == EEPROM_MAGIC) {
3598 bge_read_bc_ver(bgep);
3599 } else {
3600 /* ignore other configs for now */
3601 mutex_exit(bgep->genlock);
3602 return;
3603 }
3604
3605 if (bgep->ape_enabled) {
3606 if (bgep->asf_enabled) {
3607 bge_read_dash_ver(bgep);
3608 }
3609 } else if (bgep->asf_enabled) {
3610 bge_read_mgmtfw_ver(bgep);
3611 }
3612
3613 mutex_exit(bgep->genlock);
3614
3615 bgep->fw_version[BGE_FW_VER_SIZE - 1] = 0; /* safety */
3616 }
3617
3618 /*
3619 * attach(9E) -- Attach a device to the system
3620 *
3621 * Called once for each board successfully probed.
3622 */
3623 static int
3624 bge_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
3625 {
3626 bge_t *bgep; /* Our private data */
3627 mac_register_t *macp;
3628 chip_id_t *cidp;
3629 caddr_t regs;
3630 int instance;
3631 int err;
3632 int intr_types;
3633 int *props = NULL;
3634 uint_t numProps;
3635 uint32_t regval;
3636 uint32_t pci_state_reg;
3637 #ifdef BGE_IPMI_ASF
3638 uint32_t mhcrValue;
3639 #ifdef __sparc
3640 uint16_t value16;
3641 #endif
3642 #ifdef BGE_NETCONSOLE
3643 int retval;
3644 #endif
3645 #endif
3646
3647 instance = ddi_get_instance(devinfo);
3648
3649 BGE_GTRACE(("bge_attach($%p, %d) instance %d",
3650 (void *)devinfo, cmd, instance));
3651 BGE_BRKPT(NULL, "bge_attach");
3652
3653 switch (cmd) {
3654 default:
3655 return (DDI_FAILURE);
3656
3657 case DDI_RESUME:
3658 return (bge_resume(devinfo));
3659
3660 case DDI_ATTACH:
3661 break;
3662 }
3663
3664 bgep = kmem_zalloc(sizeof (*bgep), KM_SLEEP);
3665 bgep->pstats = kmem_zalloc(sizeof (bge_statistics_reg_t), KM_SLEEP);
3666 ddi_set_driver_private(devinfo, bgep);
3667 bgep->bge_guard = BGE_GUARD;
3668 bgep->devinfo = devinfo;
3669 bgep->param_drain_max = 64;
3670 bgep->param_msi_cnt = 0;
3671 bgep->param_loop_mode = 0;
3672
3673 /*
3674 * Initialize more fields in BGE private data
3675 */
3676 bgep->debug = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3677 DDI_PROP_DONTPASS, debug_propname, bge_debug);
3678 (void) snprintf(bgep->ifname, sizeof (bgep->ifname), "%s%d",
3679 BGE_DRIVER_NAME, instance);
3680
3681 /*
3682 * Initialize for fma support
3683 */
3684 bgep->fm_capabilities = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3685 DDI_PROP_DONTPASS, fm_cap,
3686 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
3687 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
3688 BGE_DEBUG(("bgep->fm_capabilities = %d", bgep->fm_capabilities));
3689 bge_fm_init(bgep);
3690
3691 /*
3692 * Look up the IOMMU's page size for DVMA mappings (must be
3693 * a power of 2) and convert to a mask. This can be used to
3694 * determine whether a message buffer crosses a page boundary.
3695 * Note: in 2s complement binary notation, if X is a power of
3696 * 2, then -X has the representation "11...1100...00".
3697 */
3698 bgep->pagemask = dvma_pagesize(devinfo);
3699 ASSERT(ddi_ffs(bgep->pagemask) == ddi_fls(bgep->pagemask));
3700 bgep->pagemask = -bgep->pagemask;
3701
3702 /*
3703 * Map config space registers
3704 * Read chip ID & set up config space command register(s)
3705 *
3706 * Note: this leaves the chip accessible by Memory Space
3707 * accesses, but with interrupts and Bus Mastering off.
3708 * This should ensure that nothing untoward will happen
3709 * if it has been left active by the (net-)bootloader.
3710 * We'll re-enable Bus Mastering once we've reset the chip,
3711 * and allow interrupts only when everything else is set up.
3712 */
3713 err = pci_config_setup(devinfo, &bgep->cfg_handle);
3714 #ifdef BGE_IPMI_ASF
3715 #ifdef __sparc
3716 /*
3717 * We need to determine the type of chipset for accessing some configure
3718 * registers. (This information will be used by bge_ind_put32,
3719 * bge_ind_get32 and bge_nic_read32)
3720 */
3721 bgep->chipid.device = pci_config_get16(bgep->cfg_handle,
3722 PCI_CONF_DEVID);
3723 value16 = pci_config_get16(bgep->cfg_handle, PCI_CONF_COMM);
3724 value16 = value16 | (PCI_COMM_MAE | PCI_COMM_ME);
3725 pci_config_put16(bgep->cfg_handle, PCI_CONF_COMM, value16);
3726 mhcrValue = MHCR_ENABLE_INDIRECT_ACCESS |
3727 MHCR_ENABLE_TAGGED_STATUS_MODE |
3728 MHCR_MASK_INTERRUPT_MODE |
3729 MHCR_MASK_PCI_INT_OUTPUT |
3730 MHCR_CLEAR_INTERRUPT_INTA |
3731 MHCR_ENABLE_ENDIAN_WORD_SWAP |
3732 MHCR_ENABLE_ENDIAN_BYTE_SWAP;
3733 /*
3734 * For some chipsets (e.g., BCM5718), if MHCR_ENABLE_ENDIAN_BYTE_SWAP
3735 * has been set in PCI_CONF_COMM already, we need to write the
3736 * byte-swapped value to it. So we just write zero first for simplicity.
3737 */
3738 if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
3739 DEVICE_5725_SERIES_CHIPSETS(bgep))
3740 pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, 0);
3741 #else
3742 mhcrValue = MHCR_ENABLE_INDIRECT_ACCESS |
3743 MHCR_ENABLE_TAGGED_STATUS_MODE |
3744 MHCR_MASK_INTERRUPT_MODE |
3745 MHCR_MASK_PCI_INT_OUTPUT |
3746 MHCR_CLEAR_INTERRUPT_INTA;
3747 #endif
3748 pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, mhcrValue);
3749 bge_ind_put32(bgep, MEMORY_ARBITER_MODE_REG,
3750 bge_ind_get32(bgep, MEMORY_ARBITER_MODE_REG) |
3751 MEMORY_ARBITER_ENABLE);
3752 if (mhcrValue & MHCR_ENABLE_ENDIAN_WORD_SWAP) {
3753 bgep->asf_wordswapped = B_TRUE;
3754 } else {
3755 bgep->asf_wordswapped = B_FALSE;
3756 }
3757 bge_asf_get_config(bgep);
3758 #endif
3759 if (err != DDI_SUCCESS) {
3760 bge_problem(bgep, "pci_config_setup() failed");
3761 goto attach_fail;
3762 }
3763 bgep->progress |= PROGRESS_CFG;
3764 cidp = &bgep->chipid;
3765 bzero(cidp, sizeof(*cidp));
3766 bge_chip_cfg_init(bgep, cidp, B_FALSE);
3767 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
3768 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3769 goto attach_fail;
3770 }
3771
3772 #ifdef BGE_IPMI_ASF
3773 if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
3774 DEVICE_5714_SERIES_CHIPSETS(bgep)) {
3775 bgep->asf_newhandshake = B_TRUE;
3776 } else {
3777 bgep->asf_newhandshake = B_FALSE;
3778 }
3779 #endif
3780
3781 /*
3782 * Update those parts of the chip ID derived from volatile
3783 * registers with the values seen by OBP (in case the chip
3784 * has been reset externally and therefore lost them).
3785 */
3786 cidp->subven = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3787 DDI_PROP_DONTPASS, subven_propname, cidp->subven);
3788 cidp->subdev = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3789 DDI_PROP_DONTPASS, subdev_propname, cidp->subdev);
3790 cidp->clsize = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3791 DDI_PROP_DONTPASS, clsize_propname, cidp->clsize);
3792 cidp->latency = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3793 DDI_PROP_DONTPASS, latency_propname, cidp->latency);
3794 cidp->rx_rings = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3795 DDI_PROP_DONTPASS, rxrings_propname, cidp->rx_rings);
3796 cidp->tx_rings = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3797 DDI_PROP_DONTPASS, txrings_propname, cidp->tx_rings);
3798 cidp->eee = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3799 DDI_PROP_DONTPASS, eee_propname, cidp->eee);
3800
3801 cidp->default_mtu = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3802 DDI_PROP_DONTPASS, default_mtu, BGE_DEFAULT_MTU);
3803 if ((cidp->default_mtu < BGE_DEFAULT_MTU) ||
3804 (cidp->default_mtu > BGE_MAXIMUM_MTU)) {
3805 cidp->default_mtu = BGE_DEFAULT_MTU;
3806 }
3807
3808 /*
3809 * Map operating registers
3810 */
3811 err = ddi_regs_map_setup(devinfo, BGE_PCI_OPREGS_RNUMBER,
3812 ®s, 0, 0, &bge_reg_accattr, &bgep->io_handle);
3813 if (err != DDI_SUCCESS) {
3814 bge_problem(bgep, "ddi_regs_map_setup() failed");
3815 goto attach_fail;
3816 }
3817 bgep->io_regs = regs;
3818
3819 bgep->ape_enabled = B_FALSE;
3820 bgep->ape_regs = NULL;
3821 if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
3822 DEVICE_5725_SERIES_CHIPSETS(bgep)) {
3823 err = ddi_regs_map_setup(devinfo, BGE_PCI_APEREGS_RNUMBER,
3824 ®s, 0, 0, &bge_reg_accattr, &bgep->ape_handle);
3825 if (err != DDI_SUCCESS) {
3826 ddi_regs_map_free(&bgep->io_handle);
3827 bge_problem(bgep, "ddi_regs_map_setup() failed");
3828 goto attach_fail;
3829 }
3830 bgep->ape_regs = regs;
3831 bgep->ape_enabled = B_TRUE;
3832
3833 /*
3834 * Allow reads and writes to the
3835 * APE register and memory space.
3836 */
3837
3838 pci_state_reg = pci_config_get32(bgep->cfg_handle,
3839 PCI_CONF_BGE_PCISTATE);
3840 pci_state_reg |= PCISTATE_ALLOW_APE_CTLSPC_WR |
3841 PCISTATE_ALLOW_APE_SHMEM_WR | PCISTATE_ALLOW_APE_PSPACE_WR;
3842 pci_config_put32(bgep->cfg_handle,
3843 PCI_CONF_BGE_PCISTATE, pci_state_reg);
3844
3845 bge_ape_lock_init(bgep);
3846 }
3847
3848 bgep->progress |= PROGRESS_REGS;
3849
3850 /*
3851 * Characterise the device, so we know its requirements.
3852 * Then allocate the appropriate TX and RX descriptors & buffers.
3853 */
3854 if (bge_chip_id_init(bgep) == EIO) {
3855 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3856 goto attach_fail;
3857 }
3858
3859 err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, bgep->devinfo,
3860 0, "reg", &props, &numProps);
3861 if ((err == DDI_PROP_SUCCESS) && (numProps > 0)) {
3862 bgep->pci_bus = PCI_REG_BUS_G(props[0]);
3863 bgep->pci_dev = PCI_REG_DEV_G(props[0]);
3864 bgep->pci_func = PCI_REG_FUNC_G(props[0]);
3865 ddi_prop_free(props);
3866 }
3867
3868 if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
3869 DEVICE_5725_SERIES_CHIPSETS(bgep)) {
3870 regval = bge_reg_get32(bgep, CPMU_STATUS_REG);
3871 if ((bgep->chipid.device == DEVICE_ID_5719) ||
3872 (bgep->chipid.device == DEVICE_ID_5720)) {
3873 bgep->pci_func =
3874 ((regval & CPMU_STATUS_FUNC_NUM_5719) >>
3875 CPMU_STATUS_FUNC_NUM_5719_SHIFT);
3876 } else {
3877 bgep->pci_func = ((regval & CPMU_STATUS_FUNC_NUM) >>
3878 CPMU_STATUS_FUNC_NUM_SHIFT);
3879 }
3880 }
3881
3882 err = bge_alloc_bufs(bgep);
3883 if (err != DDI_SUCCESS) {
3884 bge_problem(bgep, "DMA buffer allocation failed");
3885 goto attach_fail;
3886 }
3887 bgep->progress |= PROGRESS_BUFS;
3888
3889 /*
3890 * Add the softint handlers:
3891 *
3892 * Both of these handlers are used to avoid restrictions on the
3893 * context and/or mutexes required for some operations. In
3894 * particular, the hardware interrupt handler and its subfunctions
3895 * can detect a number of conditions that we don't want to handle
3896 * in that context or with that set of mutexes held. So, these
3897 * softints are triggered instead:
3898 *
3899 * the <resched> softint is triggered if we have previously
3900 * had to refuse to send a packet because of resource shortage
3901 * (we've run out of transmit buffers), but the send completion
3902 * interrupt handler has now detected that more buffers have
3903 * become available.
3904 *
3905 * the <factotum> is triggered if the h/w interrupt handler
3906 * sees the <link state changed> or <error> bits in the status
3907 * block. It's also triggered periodically to poll the link
3908 * state, just in case we aren't getting link status change
3909 * interrupts ...
3910 */
3911 err = ddi_add_softintr(devinfo, DDI_SOFTINT_LOW, &bgep->drain_id,
3912 NULL, NULL, bge_send_drain, (caddr_t)bgep);
3913 if (err != DDI_SUCCESS) {
3914 bge_problem(bgep, "ddi_add_softintr() failed");
3915 goto attach_fail;
3916 }
3917 bgep->progress |= PROGRESS_RESCHED;
3918 err = ddi_add_softintr(devinfo, DDI_SOFTINT_LOW, &bgep->factotum_id,
3919 NULL, NULL, bge_chip_factotum, (caddr_t)bgep);
3920 if (err != DDI_SUCCESS) {
3921 bge_problem(bgep, "ddi_add_softintr() failed");
3922 goto attach_fail;
3923 }
3924 bgep->progress |= PROGRESS_FACTOTUM;
3925
3926 /* Get supported interrupt types */
3927 if (ddi_intr_get_supported_types(devinfo, &intr_types) != DDI_SUCCESS) {
3928 bge_error(bgep, "ddi_intr_get_supported_types failed\n");
3929
3930 goto attach_fail;
3931 }
3932
3933 BGE_DEBUG(("%s: ddi_intr_get_supported_types() returned: %x",
3934 bgep->ifname, intr_types));
3935
3936 if ((intr_types & DDI_INTR_TYPE_MSI) && bgep->chipid.msi_enabled) {
3937 if (bge_add_intrs(bgep, DDI_INTR_TYPE_MSI) != DDI_SUCCESS) {
3938 bge_error(bgep, "MSI registration failed, "
3939 "trying FIXED interrupt type\n");
3940 } else {
3941 BGE_DEBUG(("%s: Using MSI interrupt type",
3942 bgep->ifname));
3943 bgep->intr_type = DDI_INTR_TYPE_MSI;
3944 bgep->progress |= PROGRESS_HWINT;
3945 }
3946 }
3947
3948 if (!(bgep->progress & PROGRESS_HWINT) &&
3949 (intr_types & DDI_INTR_TYPE_FIXED)) {
3950 if (bge_add_intrs(bgep, DDI_INTR_TYPE_FIXED) != DDI_SUCCESS) {
3951 bge_error(bgep, "FIXED interrupt "
3952 "registration failed\n");
3953 goto attach_fail;
3954 }
3955
3956 BGE_DEBUG(("%s: Using FIXED interrupt type", bgep->ifname));
3957
3958 bgep->intr_type = DDI_INTR_TYPE_FIXED;
3959 bgep->progress |= PROGRESS_HWINT;
3960 }
3961
3962 if (!(bgep->progress & PROGRESS_HWINT)) {
3963 bge_error(bgep, "No interrupts registered\n");
3964 goto attach_fail;
3965 }
3966
3967 /*
3968 * Note that interrupts are not enabled yet as
3969 * mutex locks are not initialized. Initialize mutex locks.
3970 */
3971 mutex_init(bgep->genlock, NULL, MUTEX_DRIVER,
3972 DDI_INTR_PRI(bgep->intr_pri));
3973 mutex_init(bgep->softintrlock, NULL, MUTEX_DRIVER,
3974 DDI_INTR_PRI(bgep->intr_pri));
3975 rw_init(bgep->errlock, NULL, RW_DRIVER,
3976 DDI_INTR_PRI(bgep->intr_pri));
3977
3978 /*
3979 * Initialize rings.
3980 */
3981 bge_init_rings(bgep);
3982
3983 /*
3984 * Now that mutex locks are initialized, enable interrupts.
3985 */
3986 bge_intr_enable(bgep);
3987 bgep->progress |= PROGRESS_INTR;
3988
3989 /*
3990 * Initialise link state variables
3991 * Stop, reset & reinitialise the chip.
3992 * Initialise the (internal) PHY.
3993 */
3994 bgep->link_state = LINK_STATE_UNKNOWN;
3995
3996 mutex_enter(bgep->genlock);
3997
3998 /*
3999 * Reset chip & rings to initial state; also reset address
4000 * filtering, promiscuity, loopback mode.
4001 */
4002 #ifdef BGE_IPMI_ASF
4003 #ifdef BGE_NETCONSOLE
4004 if (bge_reset(bgep, ASF_MODE_INIT) != DDI_SUCCESS) {
4005 #else
4006 if (bge_reset(bgep, ASF_MODE_SHUTDOWN) != DDI_SUCCESS) {
4007 #endif
4008 #else
4009 if (bge_reset(bgep) != DDI_SUCCESS) {
4010 #endif
4011 (void) bge_check_acc_handle(bgep, bgep->cfg_handle);
4012 (void) bge_check_acc_handle(bgep, bgep->io_handle);
4013 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
4014 mutex_exit(bgep->genlock);
4015 goto attach_fail;
4016 }
4017
4018 #ifdef BGE_IPMI_ASF
4019 if (bgep->asf_enabled) {
4020 bgep->asf_status = ASF_STAT_RUN_INIT;
4021 }
4022 #endif
4023
4024 bzero(bgep->mcast_hash, sizeof (bgep->mcast_hash));
4025 bzero(bgep->mcast_refs, sizeof (bgep->mcast_refs));
4026 bgep->promisc = B_FALSE;
4027 bgep->param_loop_mode = BGE_LOOP_NONE;
4028 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
4029 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
4030 mutex_exit(bgep->genlock);
4031 goto attach_fail;
4032 }
4033 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
4034 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
4035 mutex_exit(bgep->genlock);
4036 goto attach_fail;
4037 }
4038
4039 mutex_exit(bgep->genlock);
4040
4041 if (bge_phys_init(bgep) == EIO) {
4042 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
4043 goto attach_fail;
4044 }
4045 bgep->progress |= PROGRESS_PHY;
4046
4047 /*
4048 * initialize NDD-tweakable parameters
4049 */
4050 if (bge_nd_init(bgep)) {
4051 bge_problem(bgep, "bge_nd_init() failed");
4052 goto attach_fail;
4053 }
4054 bgep->progress |= PROGRESS_NDD;
4055
4056 /*
4057 * Create & initialise named kstats
4058 */
4059 bge_init_kstats(bgep, instance);
4060 bgep->progress |= PROGRESS_KSTATS;
4061
4062 /*
4063 * Determine whether to override the chip's own MAC address
4064 */
4065 bge_find_mac_address(bgep, cidp);
4066 {
4067 int slot;
4068 for (slot = 0; slot < MAC_ADDRESS_REGS_MAX; slot++) {
4069 ethaddr_copy(cidp->vendor_addr.addr,
4070 bgep->curr_addr[slot].addr);
4071 bgep->curr_addr[slot].set = 1;
4072 }
4073 }
4074
4075 bge_read_fw_ver(bgep);
4076
4077 bgep->unicst_addr_total = MAC_ADDRESS_REGS_MAX;
4078 bgep->unicst_addr_avail = MAC_ADDRESS_REGS_MAX;
4079
4080 if ((macp = mac_alloc(MAC_VERSION)) == NULL)
4081 goto attach_fail;
4082 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
4083 macp->m_driver = bgep;
4084 macp->m_dip = devinfo;
4085 macp->m_src_addr = cidp->vendor_addr.addr;
4086 macp->m_callbacks = &bge_m_callbacks;
4087 macp->m_min_sdu = 0;
4088 macp->m_max_sdu = cidp->ethmax_size - sizeof (struct ether_header);
4089 macp->m_margin = VLAN_TAGSZ;
4090 macp->m_priv_props = bge_priv_prop;
4091
4092 #if defined(ILLUMOS)
4093 bge_m_unicst(bgep, cidp->vendor_addr.addr);
4094 #endif
4095
4096 /*
4097 * Finally, we're ready to register ourselves with the MAC layer
4098 * interface; if this succeeds, we're all ready to start()
4099 */
4100 err = mac_register(macp, &bgep->mh);
4101 mac_free(macp);
4102 if (err != 0)
4103 goto attach_fail;
4104
4105 mac_link_update(bgep->mh, LINK_STATE_UNKNOWN);
4106
4107 /*
4108 * Register a periodical handler.
4109 * bge_chip_cyclic() is invoked in kernel context.
4110 */
4111 bgep->periodic_id = ddi_periodic_add(bge_chip_cyclic, bgep,
4112 BGE_CYCLIC_PERIOD, DDI_IPL_0);
4113
4114 bgep->progress |= PROGRESS_READY;
4115 ASSERT(bgep->bge_guard == BGE_GUARD);
4116 #ifdef BGE_IPMI_ASF
4117 #ifdef BGE_NETCONSOLE
4118 if (bgep->asf_enabled) {
4119 mutex_enter(bgep->genlock);
4120 retval = bge_chip_start(bgep, B_TRUE);
4121 mutex_exit(bgep->genlock);
4122 if (retval != DDI_SUCCESS)
4123 goto attach_fail;
4124 }
4125 #endif
4126 #endif
4127
4128 ddi_report_dev(devinfo);
4129
4130 return (DDI_SUCCESS);
4131
4132 attach_fail:
4133 #ifdef BGE_IPMI_ASF
4134 bge_unattach(bgep, ASF_MODE_SHUTDOWN);
4135 #else
4136 bge_unattach(bgep);
4137 #endif
4138 return (DDI_FAILURE);
4139 }
4140
4141 /*
4142 * bge_suspend() -- suspend transmit/receive for powerdown
4143 */
4144 static int
4145 bge_suspend(bge_t *bgep)
4146 {
4147 /*
4148 * Stop processing and idle (powerdown) the PHY ...
4149 */
4150 mutex_enter(bgep->genlock);
4151 #ifdef BGE_IPMI_ASF
4152 /*
4153 * Power management hasn't been supported in BGE now. If you
4154 * want to implement it, please add the ASF/IPMI related
4155 * code here.
4156 */
4157 #endif
4158 bge_stop(bgep);
4159 if (bge_phys_idle(bgep) != DDI_SUCCESS) {
4160 (void) bge_check_acc_handle(bgep, bgep->io_handle);
4161 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
4162 mutex_exit(bgep->genlock);
4163 return (DDI_FAILURE);
4164 }
4165 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
4166 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
4167 mutex_exit(bgep->genlock);
4168 return (DDI_FAILURE);
4169 }
4170 mutex_exit(bgep->genlock);
4171
4172 return (DDI_SUCCESS);
4173 }
4174
4175 /*
4176 * quiesce(9E) entry point.
4177 *
4178 * This function is called when the system is single-threaded at high
4179 * PIL with preemption disabled. Therefore, this function must not be
4180 * blocked.
4181 *
4182 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
4183 * DDI_FAILURE indicates an error condition and should almost never happen.
4184 */
4185 #ifdef __sparc
4186 #define bge_quiesce ddi_quiesce_not_supported
4187 #else
4188 static int
4189 bge_quiesce(dev_info_t *devinfo)
4190 {
4191 bge_t *bgep = ddi_get_driver_private(devinfo);
4192
4193 if (bgep == NULL)
4194 return (DDI_FAILURE);
4195
4196 if (bgep->intr_type == DDI_INTR_TYPE_FIXED) {
4197 bge_reg_set32(bgep, PCI_CONF_BGE_MHCR,
4198 MHCR_MASK_PCI_INT_OUTPUT);
4199 } else {
4200 bge_reg_clr32(bgep, MSI_MODE_REG, MSI_MSI_ENABLE);
4201 }
4202
4203 /* Stop the chip */
4204 bge_chip_stop_nonblocking(bgep);
4205
4206 return (DDI_SUCCESS);
4207 }
4208 #endif
4209
4210 /*
4211 * detach(9E) -- Detach a device from the system
4212 */
4213 static int
4214 bge_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
4215 {
4216 bge_t *bgep;
4217 #ifdef BGE_IPMI_ASF
4218 uint_t asf_mode;
4219 asf_mode = ASF_MODE_NONE;
4220 #endif
4221
4222 BGE_GTRACE(("bge_detach($%p, %d)", (void *)devinfo, cmd));
4223
4224 bgep = ddi_get_driver_private(devinfo);
4225
4226 switch (cmd) {
4227 default:
4228 return (DDI_FAILURE);
4229
4230 case DDI_SUSPEND:
4231 return (bge_suspend(bgep));
4232
4233 case DDI_DETACH:
4234 break;
4235 }
4236
4237 #ifdef BGE_IPMI_ASF
4238 mutex_enter(bgep->genlock);
4239 if (bgep->asf_enabled && ((bgep->asf_status == ASF_STAT_RUN) ||
4240 (bgep->asf_status == ASF_STAT_RUN_INIT))) {
4241
4242 bge_asf_update_status(bgep);
4243 if (bgep->asf_status == ASF_STAT_RUN) {
4244 bge_asf_stop_timer(bgep);
4245 }
4246 bgep->asf_status = ASF_STAT_STOP;
4247
4248 bge_asf_pre_reset_operations(bgep, BGE_SHUTDOWN_RESET);
4249
4250 if (bgep->asf_pseudostop) {
4251 bge_chip_stop(bgep, B_FALSE);
4252 bgep->bge_mac_state = BGE_MAC_STOPPED;
4253 bgep->asf_pseudostop = B_FALSE;
4254 }
4255
4256 asf_mode = ASF_MODE_POST_SHUTDOWN;
4257
4258 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK)
4259 ddi_fm_service_impact(bgep->devinfo,
4260 DDI_SERVICE_UNAFFECTED);
4261 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
4262 ddi_fm_service_impact(bgep->devinfo,
4263 DDI_SERVICE_UNAFFECTED);
4264 }
4265 mutex_exit(bgep->genlock);
4266 #endif
4267
4268 /*
4269 * Unregister from the GLD subsystem. This can fail, in
4270 * particular if there are DLPI style-2 streams still open -
4271 * in which case we just return failure without shutting
4272 * down chip operations.
4273 */
4274 if (mac_unregister(bgep->mh) != 0)
4275 return (DDI_FAILURE);
4276
4277 /*
4278 * All activity stopped, so we can clean up & exit
4279 */
4280 #ifdef BGE_IPMI_ASF
4281 bge_unattach(bgep, asf_mode);
4282 #else
4283 bge_unattach(bgep);
4284 #endif
4285 return (DDI_SUCCESS);
4286 }
4287
4288
4289 /*
4290 * ========== Module Loading Data & Entry Points ==========
4291 */
4292
4293 #undef BGE_DBG
4294 #define BGE_DBG BGE_DBG_INIT /* debug flag for this code */
4295
4296 DDI_DEFINE_STREAM_OPS(bge_dev_ops,
4297 nulldev, /* identify */
4298 nulldev, /* probe */
4299 bge_attach, /* attach */
4300 bge_detach, /* detach */
4301 nodev, /* reset */
4302 NULL, /* cb_ops */
4303 D_MP, /* bus_ops */
4304 NULL, /* power */
4305 bge_quiesce /* quiesce */
4306 );
4307
4308 static struct modldrv bge_modldrv = {
4309 &mod_driverops, /* Type of module. This one is a driver */
4310 bge_ident, /* short description */
4311 &bge_dev_ops /* driver specific ops */
4312 };
4313
4314 static struct modlinkage modlinkage = {
4315 MODREV_1, { (void *)&bge_modldrv, NULL }
4316 };
4317
4318
4319 int
4320 _info(struct modinfo *modinfop)
4321 {
4322 return (mod_info(&modlinkage, modinfop));
4323 }
4324
4325 int
4326 _init(void)
4327 {
4328 int status;
4329
4330 mac_init_ops(&bge_dev_ops, "bge");
4331 status = mod_install(&modlinkage);
4332 if (status == DDI_SUCCESS)
4333 mutex_init(bge_log_mutex, NULL, MUTEX_DRIVER, NULL);
4334 else
4335 mac_fini_ops(&bge_dev_ops);
4336 return (status);
4337 }
4338
4339 int
4340 _fini(void)
4341 {
4342 int status;
4343
4344 status = mod_remove(&modlinkage);
4345 if (status == DDI_SUCCESS) {
4346 mac_fini_ops(&bge_dev_ops);
4347 mutex_destroy(bge_log_mutex);
4348 }
4349 return (status);
4350 }
4351
4352
4353 /*
4354 * bge_add_intrs:
4355 *
4356 * Register FIXED or MSI interrupts.
4357 */
4358 static int
4359 bge_add_intrs(bge_t *bgep, int intr_type)
4360 {
4361 dev_info_t *dip = bgep->devinfo;
4362 int avail, actual, intr_size, count = 0;
4363 int i, flag, ret;
4364
4365 BGE_DEBUG(("bge_add_intrs($%p, 0x%x)", (void *)bgep, intr_type));
4366
4367 /* Get number of interrupts */
4368 ret = ddi_intr_get_nintrs(dip, intr_type, &count);
4369 if ((ret != DDI_SUCCESS) || (count == 0)) {
4370 bge_error(bgep, "ddi_intr_get_nintrs() failure, ret: %d, "
4371 "count: %d", ret, count);
4372
4373 return (DDI_FAILURE);
4374 }
4375
4376 /* Get number of available interrupts */
4377 ret = ddi_intr_get_navail(dip, intr_type, &avail);
4378 if ((ret != DDI_SUCCESS) || (avail == 0)) {
4379 bge_error(bgep, "ddi_intr_get_navail() failure, "
4380 "ret: %d, avail: %d\n", ret, avail);
4381
4382 return (DDI_FAILURE);
4383 }
4384
4385 if (avail < count) {
4386 BGE_DEBUG(("%s: nintrs() returned %d, navail returned %d",
4387 bgep->ifname, count, avail));
4388 }
4389
4390 /*
4391 * BGE hardware generates only single MSI even though it claims
4392 * to support multiple MSIs. So, hard code MSI count value to 1.
4393 */
4394 if (intr_type == DDI_INTR_TYPE_MSI) {
4395 count = 1;
4396 flag = DDI_INTR_ALLOC_STRICT;
4397 } else {
4398 flag = DDI_INTR_ALLOC_NORMAL;
4399 }
4400
4401 /* Allocate an array of interrupt handles */
4402 intr_size = count * sizeof (ddi_intr_handle_t);
4403 bgep->htable = kmem_alloc(intr_size, KM_SLEEP);
4404
4405 /* Call ddi_intr_alloc() */
4406 ret = ddi_intr_alloc(dip, bgep->htable, intr_type, 0,
4407 count, &actual, flag);
4408
4409 if ((ret != DDI_SUCCESS) || (actual == 0)) {
4410 bge_error(bgep, "ddi_intr_alloc() failed %d\n", ret);
4411
4412 kmem_free(bgep->htable, intr_size);
4413 return (DDI_FAILURE);
4414 }
4415
4416 if (actual < count) {
4417 BGE_DEBUG(("%s: Requested: %d, Received: %d",
4418 bgep->ifname, count, actual));
4419 }
4420
4421 bgep->intr_cnt = actual;
4422
4423 /*
4424 * Get priority for first msi, assume remaining are all the same
4425 */
4426 if ((ret = ddi_intr_get_pri(bgep->htable[0], &bgep->intr_pri)) !=
4427 DDI_SUCCESS) {
4428 bge_error(bgep, "ddi_intr_get_pri() failed %d\n", ret);
4429
4430 /* Free already allocated intr */
4431 for (i = 0; i < actual; i++) {
4432 (void) ddi_intr_free(bgep->htable[i]);
4433 }
4434
4435 kmem_free(bgep->htable, intr_size);
4436 return (DDI_FAILURE);
4437 }
4438
4439 /* Call ddi_intr_add_handler() */
4440 for (i = 0; i < actual; i++) {
4441 if ((ret = ddi_intr_add_handler(bgep->htable[i], bge_intr,
4442 (caddr_t)bgep, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
4443 bge_error(bgep, "ddi_intr_add_handler() "
4444 "failed %d\n", ret);
4445
4446 /* Free already allocated intr */
4447 for (i = 0; i < actual; i++) {
4448 (void) ddi_intr_free(bgep->htable[i]);
4449 }
4450
4451 kmem_free(bgep->htable, intr_size);
4452 return (DDI_FAILURE);
4453 }
4454 }
4455
4456 if ((ret = ddi_intr_get_cap(bgep->htable[0], &bgep->intr_cap))
4457 != DDI_SUCCESS) {
4458 bge_error(bgep, "ddi_intr_get_cap() failed %d\n", ret);
4459
4460 for (i = 0; i < actual; i++) {
4461 (void) ddi_intr_remove_handler(bgep->htable[i]);
4462 (void) ddi_intr_free(bgep->htable[i]);
4463 }
4464
4465 kmem_free(bgep->htable, intr_size);
4466 return (DDI_FAILURE);
4467 }
4468
4469 return (DDI_SUCCESS);
4470 }
4471
4472 /*
4473 * bge_rem_intrs:
4474 *
4475 * Unregister FIXED or MSI interrupts
4476 */
4477 static void
4478 bge_rem_intrs(bge_t *bgep)
4479 {
4480 int i;
4481
4482 BGE_DEBUG(("bge_rem_intrs($%p)", (void *)bgep));
4483
4484 /* Call ddi_intr_remove_handler() */
4485 for (i = 0; i < bgep->intr_cnt; i++) {
4486 (void) ddi_intr_remove_handler(bgep->htable[i]);
4487 (void) ddi_intr_free(bgep->htable[i]);
4488 }
4489
4490 kmem_free(bgep->htable, bgep->intr_cnt * sizeof (ddi_intr_handle_t));
4491 }
4492
4493
4494 void
4495 bge_intr_enable(bge_t *bgep)
4496 {
4497 int i;
4498
4499 if (bgep->intr_cap & DDI_INTR_FLAG_BLOCK) {
4500 /* Call ddi_intr_block_enable() for MSI interrupts */
4501 (void) ddi_intr_block_enable(bgep->htable, bgep->intr_cnt);
4502 } else {
4503 /* Call ddi_intr_enable for MSI or FIXED interrupts */
4504 for (i = 0; i < bgep->intr_cnt; i++) {
4505 (void) ddi_intr_enable(bgep->htable[i]);
4506 }
4507 }
4508 }
4509
4510
4511 void
4512 bge_intr_disable(bge_t *bgep)
4513 {
4514 int i;
4515
4516 if (bgep->intr_cap & DDI_INTR_FLAG_BLOCK) {
4517 /* Call ddi_intr_block_disable() */
4518 (void) ddi_intr_block_disable(bgep->htable, bgep->intr_cnt);
4519 } else {
4520 for (i = 0; i < bgep->intr_cnt; i++) {
4521 (void) ddi_intr_disable(bgep->htable[i]);
4522 }
4523 }
4524 }
4525
4526 int
4527 bge_reprogram(bge_t *bgep)
4528 {
4529 int status = 0;
4530
4531 ASSERT(mutex_owned(bgep->genlock));
4532
4533 if (bge_phys_update(bgep) != DDI_SUCCESS) {
4534 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
4535 status = IOC_INVAL;
4536 }
4537 #ifdef BGE_IPMI_ASF
4538 if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
4539 #else
4540 if (bge_chip_sync(bgep) == DDI_FAILURE) {
4541 #endif
4542 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
4543 status = IOC_INVAL;
4544 }
4545 if (bgep->intr_type == DDI_INTR_TYPE_MSI)
4546 bge_chip_msi_trig(bgep);
4547 return (status);
4548 }