1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 1366 petede * Common Development and Distribution License (the "License"). 6 1366 petede * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 10306 Vitezslav * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel /* 27 0 stevel * SunOS MT STREAMS ERI(PCI) 10/100 Mb Ethernet Device Driver 28 0 stevel */ 29 0 stevel 30 0 stevel #include <sys/types.h> 31 0 stevel #include <sys/debug.h> 32 0 stevel #include <sys/stropts.h> 33 0 stevel #include <sys/stream.h> 34 0 stevel #include <sys/strsubr.h> 35 0 stevel #include <sys/kmem.h> 36 0 stevel #include <sys/crc32.h> 37 0 stevel #include <sys/ddi.h> 38 0 stevel #include <sys/sunddi.h> 39 0 stevel #include <sys/strsun.h> 40 0 stevel #include <sys/stat.h> 41 0 stevel #include <sys/cpu.h> 42 0 stevel #include <sys/kstat.h> 43 0 stevel #include <inet/common.h> 44 0 stevel #include <sys/pattr.h> 45 0 stevel #include <inet/mi.h> 46 0 stevel #include <inet/nd.h> 47 0 stevel #include <sys/ethernet.h> 48 5895 yz147064 #include <sys/vlan.h> 49 0 stevel #include <sys/policy.h> 50 8275 Eric #include <sys/mac_provider.h> 51 4404 gd78059 #include <sys/mac_ether.h> 52 4404 gd78059 #include <sys/dlpi.h> 53 0 stevel 54 0 stevel #include <sys/pci.h> 55 0 stevel 56 6833 gd78059 #include "eri_phy.h" 57 6833 gd78059 #include "eri_mac.h" 58 6833 gd78059 #include "eri.h" 59 6833 gd78059 #include "eri_common.h" 60 6833 gd78059 61 6833 gd78059 #include "eri_msg.h" 62 6833 gd78059 63 0 stevel /* 64 0 stevel * **** Function Prototypes ***** 65 0 stevel */ 66 0 stevel /* 67 0 stevel * Entry points (man9e) 68 0 stevel */ 69 0 stevel static int eri_attach(dev_info_t *, ddi_attach_cmd_t); 70 0 stevel static int eri_detach(dev_info_t *, ddi_detach_cmd_t); 71 4404 gd78059 static uint_t eri_intr(caddr_t); 72 0 stevel 73 0 stevel /* 74 0 stevel * I/O (Input/Output) Functions 75 0 stevel */ 76 4404 gd78059 static boolean_t eri_send_msg(struct eri *, mblk_t *); 77 4404 gd78059 static mblk_t *eri_read_dma(struct eri *, volatile struct rmd *, 78 4404 gd78059 volatile int, uint64_t flags); 79 0 stevel 80 0 stevel /* 81 0 stevel * Initialization Functions 82 0 stevel */ 83 4404 gd78059 static boolean_t eri_init(struct eri *); 84 0 stevel static int eri_allocthings(struct eri *); 85 0 stevel static int eri_init_xfer_params(struct eri *); 86 0 stevel static void eri_statinit(struct eri *); 87 0 stevel static int eri_burstsize(struct eri *); 88 0 stevel 89 0 stevel static void eri_setup_mac_address(struct eri *, dev_info_t *); 90 0 stevel 91 0 stevel static uint32_t eri_init_rx_channel(struct eri *); 92 0 stevel static void eri_init_rx(struct eri *); 93 0 stevel static void eri_init_txmac(struct eri *); 94 0 stevel 95 0 stevel /* 96 0 stevel * Un-init Functions 97 0 stevel */ 98 0 stevel static uint32_t eri_txmac_disable(struct eri *); 99 0 stevel static uint32_t eri_rxmac_disable(struct eri *); 100 0 stevel static int eri_stop(struct eri *); 101 0 stevel static void eri_uninit(struct eri *erip); 102 0 stevel static int eri_freebufs(struct eri *); 103 4404 gd78059 static boolean_t eri_reclaim(struct eri *, uint32_t); 104 0 stevel 105 0 stevel /* 106 0 stevel * Transceiver (xcvr) Functions 107 0 stevel */ 108 0 stevel static int eri_new_xcvr(struct eri *); /* Initializes & detects xcvrs */ 109 0 stevel static int eri_reset_xcvr(struct eri *); 110 0 stevel 111 0 stevel #ifdef ERI_10_10_FORCE_SPEED_WORKAROUND 112 0 stevel static void eri_xcvr_force_mode(struct eri *, uint32_t *); 113 0 stevel #endif 114 0 stevel 115 0 stevel static void eri_mif_poll(struct eri *, soft_mif_enable_t); 116 0 stevel static void eri_check_link(struct eri *); 117 2534 carlsonj static uint32_t eri_check_link_noind(struct eri *); 118 4404 gd78059 static link_state_t eri_mif_check(struct eri *, uint16_t, uint16_t); 119 0 stevel static void eri_mii_write(struct eri *, uint8_t, uint16_t); 120 0 stevel static uint32_t eri_mii_read(struct eri *, uint8_t, uint16_t *); 121 0 stevel 122 0 stevel /* 123 0 stevel * Reset Functions 124 0 stevel */ 125 0 stevel static uint32_t eri_etx_reset(struct eri *); 126 0 stevel static uint32_t eri_erx_reset(struct eri *); 127 0 stevel 128 0 stevel /* 129 0 stevel * Error Functions 130 0 stevel */ 131 0 stevel static void eri_fatal_err(struct eri *, uint32_t); 132 0 stevel static void eri_nonfatal_err(struct eri *, uint32_t); 133 0 stevel 134 0 stevel #ifdef ERI_TX_HUNG 135 0 stevel static int eri_check_txhung(struct eri *); 136 0 stevel #endif 137 0 stevel 138 0 stevel /* 139 0 stevel * Hardening Functions 140 0 stevel */ 141 4404 gd78059 static void eri_fault_msg(struct eri *, uint_t, msg_t, const char *, ...); 142 0 stevel 143 0 stevel /* 144 0 stevel * Misc Functions 145 0 stevel */ 146 0 stevel static void eri_savecntrs(struct eri *); 147 0 stevel 148 0 stevel static void eri_stop_timer(struct eri *erip); 149 0 stevel static void eri_start_timer(struct eri *erip, fptrv_t func, clock_t msec); 150 0 stevel 151 0 stevel static void eri_bb_force_idle(struct eri *); 152 0 stevel 153 0 stevel /* 154 0 stevel * Utility Functions 155 0 stevel */ 156 0 stevel static mblk_t *eri_allocb(size_t size); 157 0 stevel static mblk_t *eri_allocb_sp(size_t size); 158 0 stevel static int eri_param_get(queue_t *q, mblk_t *mp, caddr_t cp); 159 0 stevel static int eri_param_set(queue_t *, mblk_t *, char *, caddr_t); 160 0 stevel 161 0 stevel /* 162 0 stevel * Functions to support ndd 163 0 stevel */ 164 0 stevel static void eri_nd_free(caddr_t *nd_pparam); 165 0 stevel 166 0 stevel static boolean_t eri_nd_load(caddr_t *nd_pparam, char *name, 167 0 stevel pfi_t get_pfi, pfi_t set_pfi, caddr_t data); 168 0 stevel 169 0 stevel static int eri_nd_getset(queue_t *q, caddr_t nd_param, MBLKP mp); 170 0 stevel static void eri_param_cleanup(struct eri *); 171 0 stevel static int eri_param_register(struct eri *, param_t *, int); 172 4404 gd78059 static void eri_process_ndd_ioctl(struct eri *, queue_t *, mblk_t *, int); 173 4404 gd78059 static int eri_mk_mblk_tail_space(mblk_t *, mblk_t **, size_t); 174 4404 gd78059 175 4404 gd78059 176 4404 gd78059 static void eri_loopback(struct eri *, queue_t *, mblk_t *); 177 4404 gd78059 178 4404 gd78059 static uint32_t eri_ladrf_bit(const uint8_t *); 179 4404 gd78059 180 4404 gd78059 181 4404 gd78059 /* 182 4404 gd78059 * Nemo (GLDv3) Functions. 183 4404 gd78059 */ 184 4404 gd78059 static int eri_m_stat(void *, uint_t, uint64_t *); 185 4404 gd78059 static int eri_m_start(void *); 186 4404 gd78059 static void eri_m_stop(void *); 187 4404 gd78059 static int eri_m_promisc(void *, boolean_t); 188 4404 gd78059 static int eri_m_multicst(void *, boolean_t, const uint8_t *); 189 4404 gd78059 static int eri_m_unicst(void *, const uint8_t *); 190 4404 gd78059 static void eri_m_ioctl(void *, queue_t *, mblk_t *); 191 4404 gd78059 static boolean_t eri_m_getcapab(void *, mac_capab_t, void *); 192 4404 gd78059 static mblk_t *eri_m_tx(void *, mblk_t *); 193 4404 gd78059 194 4404 gd78059 static mac_callbacks_t eri_m_callbacks = { 195 4404 gd78059 MC_IOCTL | MC_GETCAPAB, 196 4404 gd78059 eri_m_stat, 197 4404 gd78059 eri_m_start, 198 4404 gd78059 eri_m_stop, 199 4404 gd78059 eri_m_promisc, 200 4404 gd78059 eri_m_multicst, 201 4404 gd78059 eri_m_unicst, 202 4404 gd78059 eri_m_tx, 203 4404 gd78059 eri_m_ioctl, 204 4404 gd78059 eri_m_getcapab 205 4404 gd78059 }; 206 0 stevel 207 0 stevel /* 208 0 stevel * Define PHY Vendors: Matches to IEEE 209 0 stevel * Organizationally Unique Identifier (OUI) 210 0 stevel */ 211 0 stevel /* 212 0 stevel * The first two are supported as Internal XCVRs 213 0 stevel */ 214 0 stevel #define PHY_VENDOR_LUCENT 0x601d 215 0 stevel 216 0 stevel #define PHY_LINK_NONE 0 /* Not attempted yet or retry */ 217 0 stevel #define PHY_LINK_DOWN 1 /* Not being used */ 218 0 stevel #define PHY_LINK_UP 2 /* Not being used */ 219 0 stevel 220 0 stevel #define AUTO_SPEED 0 221 0 stevel #define FORCE_SPEED 1 222 0 stevel 223 0 stevel /* 224 0 stevel * MIB II broadcast/multicast packets 225 0 stevel */ 226 4404 gd78059 227 4404 gd78059 #define IS_BROADCAST(pkt) (bcmp(pkt, ðerbroadcastaddr, ETHERADDRL) == 0) 228 4404 gd78059 #define IS_MULTICAST(pkt) ((pkt[0] & 01) == 1) 229 4404 gd78059 230 4404 gd78059 #define BUMP_InNUcast(erip, pkt) \ 231 4404 gd78059 if (IS_BROADCAST(pkt)) { \ 232 0 stevel HSTAT(erip, brdcstrcv); \ 233 4404 gd78059 } else if (IS_MULTICAST(pkt)) { \ 234 0 stevel HSTAT(erip, multircv); \ 235 0 stevel } 236 0 stevel 237 4404 gd78059 #define BUMP_OutNUcast(erip, pkt) \ 238 4404 gd78059 if (IS_BROADCAST(pkt)) { \ 239 0 stevel HSTAT(erip, brdcstxmt); \ 240 4404 gd78059 } else if (IS_MULTICAST(pkt)) { \ 241 0 stevel HSTAT(erip, multixmt); \ 242 0 stevel } 243 0 stevel 244 0 stevel #define NEXTTMDP(tbasep, tmdlimp, tmdp) (((tmdp) + 1) == tmdlimp \ 245 0 stevel ? tbasep : ((tmdp) + 1)) 246 0 stevel 247 0 stevel #define ETHERHEADER_SIZE (sizeof (struct ether_header)) 248 0 stevel 249 0 stevel #ifdef ERI_RCV_CKSUM 250 0 stevel #define ERI_PROCESS_READ(erip, bp, sum) \ 251 0 stevel { \ 252 0 stevel t_uscalar_t type; \ 253 0 stevel uint_t start_offset, end_offset; \ 254 0 stevel \ 255 0 stevel *(bp->b_wptr) = 0; /* pad byte */ \ 256 0 stevel \ 257 0 stevel /* \ 258 0 stevel * update MIB II statistics \ 259 0 stevel */ \ 260 0 stevel HSTAT(erip, ipackets64); \ 261 0 stevel HSTATN(erip, rbytes64, len); \ 262 4404 gd78059 BUMP_InNUcast(erip, bp->b_rptr); \ 263 4404 gd78059 type = get_ether_type(bp->b_rptr); \ 264 4404 gd78059 if (type == ETHERTYPE_IP || type == ETHERTYPE_IPV6) { \ 265 0 stevel start_offset = 0; \ 266 6990 gd78059 end_offset = MBLKL(bp) - ETHERHEADER_SIZE; \ 267 4404 gd78059 (void) hcksum_assoc(bp, NULL, NULL, \ 268 4404 gd78059 start_offset, 0, end_offset, sum, \ 269 4404 gd78059 HCK_PARTIALCKSUM, 0); \ 270 0 stevel } else { \ 271 0 stevel /* \ 272 0 stevel * Strip the PADS for 802.3 \ 273 0 stevel */ \ 274 0 stevel if (type <= ETHERMTU) \ 275 0 stevel bp->b_wptr = bp->b_rptr + \ 276 0 stevel ETHERHEADER_SIZE + type; \ 277 0 stevel } \ 278 0 stevel } 279 0 stevel #else 280 0 stevel 281 0 stevel #define ERI_PROCESS_READ(erip, bp) \ 282 0 stevel { \ 283 0 stevel t_uscalar_t type; \ 284 4404 gd78059 type = get_ether_type(bp->b_rptr); \ 285 4404 gd78059 \ 286 4404 gd78059 /* \ 287 4404 gd78059 * update MIB II statistics \ 288 4404 gd78059 */ \ 289 4404 gd78059 HSTAT(erip, ipackets64); \ 290 4404 gd78059 HSTATN(erip, rbytes64, len); \ 291 4404 gd78059 BUMP_InNUcast(erip, bp->b_rptr); \ 292 4404 gd78059 /* \ 293 4404 gd78059 * Strip the PADS for 802.3 \ 294 4404 gd78059 */ \ 295 4404 gd78059 if (type <= ETHERMTU) \ 296 4404 gd78059 bp->b_wptr = bp->b_rptr + ETHERHEADER_SIZE + \ 297 4404 gd78059 type; \ 298 0 stevel } 299 0 stevel #endif /* ERI_RCV_CKSUM */ 300 0 stevel 301 0 stevel /* 302 0 stevel * TX Interrupt Rate 303 0 stevel */ 304 0 stevel static int tx_interrupt_rate = 16; 305 0 stevel 306 0 stevel /* 307 0 stevel * Ethernet broadcast address definition. 308 0 stevel */ 309 4404 gd78059 static uint8_t etherbroadcastaddr[] = { 310 0 stevel 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 311 0 stevel }; 312 0 stevel 313 0 stevel /* 314 0 stevel * The following variables are used for configuring various features 315 0 stevel */ 316 0 stevel #define ERI_DESC_HANDLE_ALLOC 0x0001 317 0 stevel #define ERI_DESC_MEM_ALLOC 0x0002 318 0 stevel #define ERI_DESC_MEM_MAP 0x0004 319 0 stevel #define ERI_RCV_HANDLE_ALLOC 0x0020 320 0 stevel #define ERI_RCV_HANDLE_BIND 0x0040 321 0 stevel #define ERI_XMIT_DVMA_ALLOC 0x0100 322 0 stevel #define ERI_RCV_DVMA_ALLOC 0x0200 323 0 stevel #define ERI_XBUFS_HANDLE_ALLOC 0x0400 324 0 stevel #define ERI_XBUFS_KMEM_ALLOC 0x0800 325 0 stevel #define ERI_XBUFS_KMEM_DMABIND 0x1000 326 0 stevel 327 0 stevel 328 0 stevel #define ERI_DONT_STRIP_CRC 329 0 stevel /* 330 0 stevel * Translate a kernel virtual address to i/o address. 331 0 stevel */ 332 0 stevel #define ERI_IOPBIOADDR(erip, a) \ 333 0 stevel ((erip)->iopbiobase + ((uintptr_t)a - (erip)->iopbkbase)) 334 0 stevel 335 0 stevel /* 336 0 stevel * ERI Configuration Register Value 337 0 stevel * Used to configure parameters that define DMA burst 338 0 stevel * and internal arbitration behavior. 339 0 stevel * for equal TX and RX bursts, set the following in global 340 0 stevel * configuration register. 341 0 stevel * static int global_config = 0x42; 342 0 stevel */ 343 0 stevel 344 0 stevel /* 345 0 stevel * ERI ERX Interrupt Blanking Time 346 0 stevel * Each count is about 16 us (2048 clocks) for 66 MHz PCI. 347 0 stevel */ 348 0 stevel static int intr_blank_time = 6; /* for about 96 us */ 349 0 stevel static int intr_blank_packets = 8; /* */ 350 0 stevel 351 0 stevel /* 352 0 stevel * ERX PAUSE Threshold Register value 353 0 stevel * The following value is for an OFF Threshold of about 15.5 Kbytes 354 0 stevel * and an ON Threshold of 4K bytes. 355 0 stevel */ 356 0 stevel static int rx_pause_threshold = 0xf8 | (0x40 << 12); 357 0 stevel static int eri_reinit_fatal = 0; 358 0 stevel #ifdef DEBUG 359 0 stevel static int noteri = 0; 360 0 stevel #endif 361 0 stevel 362 0 stevel #ifdef ERI_TX_HUNG 363 0 stevel static int eri_reinit_txhung = 0; 364 0 stevel #endif 365 0 stevel 366 0 stevel #ifdef ERI_HDX_BUG_WORKAROUND 367 0 stevel /* 368 0 stevel * By default enable padding in hdx mode to 97 bytes. 369 0 stevel * To disabled, in /etc/system: 370 0 stevel * set eri:eri_hdx_pad_enable=0 371 0 stevel */ 372 0 stevel static uchar_t eri_hdx_pad_enable = 1; 373 0 stevel #endif 374 0 stevel 375 0 stevel /* 376 0 stevel * Default values to initialize the cache line size and latency timer 377 0 stevel * registers in the PCI configuration space. 378 0 stevel * ERI_G_CACHE_LINE_SIZE_16 is defined as 16 since RIO expects in units 379 0 stevel * of 4 bytes. 380 0 stevel */ 381 0 stevel #ifdef ERI_PM_WORKAROUND_PCI 382 0 stevel static int eri_pci_cache_line = ERI_G_CACHE_LINE_SIZE_32; /* 128 bytes */ 383 0 stevel static int eri_pci_latency_timer = 0xff; /* 255 PCI cycles */ 384 0 stevel #else 385 0 stevel static int eri_pci_cache_line = ERI_G_CACHE_LINE_SIZE_16; /* 64 bytes */ 386 0 stevel static int eri_pci_latency_timer = 0x40; /* 64 PCI cycles */ 387 0 stevel #endif 388 0 stevel #define ERI_CACHE_LINE_SIZE (eri_pci_cache_line << ERI_G_CACHE_BIT) 389 0 stevel 390 0 stevel /* 391 0 stevel * Claim the device is ultra-capable of burst in the beginning. Use 392 0 stevel * the value returned by ddi_dma_burstsizes() to actually set the ERI 393 0 stevel * global configuration register later. 394 0 stevel * 395 0 stevel * PCI_ERI supports Infinite burst or 64-byte-multiple bursts. 396 0 stevel */ 397 0 stevel #define ERI_LIMADDRLO ((uint64_t)0x00000000) 398 0 stevel #define ERI_LIMADDRHI ((uint64_t)0xffffffff) 399 0 stevel 400 0 stevel static ddi_dma_attr_t dma_attr = { 401 0 stevel DMA_ATTR_V0, /* version number. */ 402 0 stevel (uint64_t)ERI_LIMADDRLO, /* low address */ 403 0 stevel (uint64_t)ERI_LIMADDRHI, /* high address */ 404 0 stevel (uint64_t)0x00ffffff, /* address counter max */ 405 0 stevel (uint64_t)1, /* alignment */ 406 0 stevel (uint_t)0xe000e0, /* dlim_burstsizes for 32 4 bit xfers */ 407 0 stevel (uint32_t)0x1, /* minimum transfer size */ 408 0 stevel (uint64_t)0x7fffffff, /* maximum transfer size */ 409 0 stevel (uint64_t)0x00ffffff, /* maximum segment size */ 410 0 stevel 1, /* scatter/gather list length */ 411 0 stevel (uint32_t)1, /* granularity */ 412 0 stevel (uint_t)0 /* attribute flags */ 413 0 stevel }; 414 0 stevel 415 0 stevel static ddi_dma_attr_t desc_dma_attr = { 416 0 stevel DMA_ATTR_V0, /* version number. */ 417 0 stevel (uint64_t)ERI_LIMADDRLO, /* low address */ 418 0 stevel (uint64_t)ERI_LIMADDRHI, /* high address */ 419 0 stevel (uint64_t)0x00ffffff, /* address counter max */ 420 0 stevel (uint64_t)8, /* alignment */ 421 0 stevel (uint_t)0xe000e0, /* dlim_burstsizes for 32 4 bit xfers */ 422 0 stevel (uint32_t)0x1, /* minimum transfer size */ 423 0 stevel (uint64_t)0x7fffffff, /* maximum transfer size */ 424 0 stevel (uint64_t)0x00ffffff, /* maximum segment size */ 425 0 stevel 1, /* scatter/gather list length */ 426 0 stevel 16, /* granularity */ 427 0 stevel 0 /* attribute flags */ 428 0 stevel }; 429 0 stevel 430 7394 gdamore static ddi_device_acc_attr_t buf_attr = { 431 7394 gdamore DDI_DEVICE_ATTR_V0, /* devacc_attr_version */ 432 7394 gdamore DDI_NEVERSWAP_ACC, /* devacc_attr_endian_flags */ 433 7394 gdamore DDI_STRICTORDER_ACC, /* devacc_attr_dataorder */ 434 7394 gdamore DDI_DEFAULT_ACC, /* devacc_attr_access */ 435 7394 gdamore }; 436 7394 gdamore 437 0 stevel ddi_dma_lim_t eri_dma_limits = { 438 0 stevel (uint64_t)ERI_LIMADDRLO, /* dlim_addr_lo */ 439 0 stevel (uint64_t)ERI_LIMADDRHI, /* dlim_addr_hi */ 440 0 stevel (uint64_t)ERI_LIMADDRHI, /* dlim_cntr_max */ 441 0 stevel (uint_t)0x00e000e0, /* dlim_burstsizes for 32 and 64 bit xfers */ 442 0 stevel (uint32_t)0x1, /* dlim_minxfer */ 443 0 stevel 1024 /* dlim_speed */ 444 0 stevel }; 445 0 stevel 446 0 stevel /* 447 0 stevel * Link Configuration variables 448 0 stevel * 449 0 stevel * On Motherboard implementations, 10/100 Mbps speeds may be supported 450 0 stevel * by using both the Serial Link and the MII on Non-serial-link interface. 451 0 stevel * When both links are present, the driver automatically tries to bring up 452 0 stevel * both. If both are up, the Gigabit Serial Link is selected for use, by 453 0 stevel * default. The following configuration variable is used to force the selection 454 0 stevel * of one of the links when both are up. 455 0 stevel * To change the default selection to the MII link when both the Serial 456 0 stevel * Link and the MII link are up, change eri_default_link to 1. 457 0 stevel * 458 0 stevel * Once a link is in use, the driver will continue to use that link till it 459 0 stevel * goes down. When it goes down, the driver will look at the status of both the 460 0 stevel * links again for link selection. 461 0 stevel * 462 0 stevel * Currently the standard is not stable w.r.t. gigabit link configuration 463 0 stevel * using auto-negotiation procedures. Meanwhile, the link may be configured 464 0 stevel * in "forced" mode using the "autonegotiation enable" bit (bit-12) in the 465 0 stevel * PCS MII Command Register. In this mode the PCS sends "idles" until sees 466 0 stevel * "idles" as initialization instead of the Link Configuration protocol 467 0 stevel * where a Config register is exchanged. In this mode, the ERI is programmed 468 0 stevel * for full-duplex operation with both pauseTX and pauseRX (for flow control) 469 0 stevel * enabled. 470 0 stevel */ 471 0 stevel 472 0 stevel static int select_link = 0; /* automatic selection */ 473 0 stevel static int default_link = 0; /* Select Serial link if both are up */ 474 0 stevel 475 0 stevel /* 476 0 stevel * The following variables are used for configuring link-operation 477 0 stevel * for all the "eri" interfaces in the system. 478 0 stevel * Later these parameters may be changed per interface using "ndd" command 479 0 stevel * These parameters may also be specified as properties using the .conf 480 0 stevel * file mechanism for each interface. 481 0 stevel */ 482 0 stevel 483 0 stevel /* 484 0 stevel * The following variable value will be overridden by "link-pulse-disabled" 485 0 stevel * property which may be created by OBP or eri.conf file. This property is 486 0 stevel * applicable only for 10 Mbps links. 487 0 stevel */ 488 0 stevel static int link_pulse_disabled = 0; /* link pulse disabled */ 489 0 stevel 490 0 stevel /* For MII-based FastEthernet links */ 491 0 stevel static int adv_autoneg_cap = 1; 492 0 stevel static int adv_100T4_cap = 0; 493 0 stevel static int adv_100fdx_cap = 1; 494 0 stevel static int adv_100hdx_cap = 1; 495 0 stevel static int adv_10fdx_cap = 1; 496 0 stevel static int adv_10hdx_cap = 1; 497 0 stevel static int adv_pauseTX_cap = 0; 498 0 stevel static int adv_pauseRX_cap = 0; 499 0 stevel 500 0 stevel /* 501 0 stevel * The following gap parameters are in terms of byte times. 502 0 stevel */ 503 0 stevel static int ipg0 = 8; 504 0 stevel static int ipg1 = 8; 505 0 stevel static int ipg2 = 4; 506 0 stevel 507 0 stevel static int lance_mode = 1; /* to enable LANCE mode */ 508 0 stevel static int mifpoll_enable = 0; /* to enable mif poll */ 509 0 stevel static int ngu_enable = 0; /* to enable Never Give Up mode */ 510 0 stevel 511 0 stevel static int eri_force_mlf = 0; /* to enable mif poll */ 512 0 stevel static int eri_phy_mintrans = 1; /* Lu3X31T mintrans algorithm */ 513 0 stevel /* 514 0 stevel * For the MII interface, the External Transceiver is selected when present. 515 0 stevel * The following variable is used to select the Internal Transceiver even 516 0 stevel * when the External Transceiver is present. 517 0 stevel */ 518 0 stevel static int use_int_xcvr = 0; 519 0 stevel static int pace_size = 0; /* Do not use pacing for now */ 520 0 stevel 521 0 stevel static int eri_use_dvma_rx = 0; /* =1:use dvma */ 522 0 stevel static int eri_rx_bcopy_max = RX_BCOPY_MAX; /* =1:use bcopy() */ 523 0 stevel static int eri_overflow_reset = 1; /* global reset if rx_fifo_overflow */ 524 0 stevel static int eri_tx_ring_size = 2048; /* number of entries in tx ring */ 525 0 stevel static int eri_rx_ring_size = 1024; /* number of entries in rx ring */ 526 0 stevel /* 527 0 stevel * The following parameters may be configured by the user. If they are not 528 0 stevel * configured by the user, the values will be based on the capabilities of 529 0 stevel * the transceiver. 530 0 stevel * The value "ERI_NOTUSR" is ORed with the parameter value to indicate values 531 0 stevel * which are NOT configured by the user. 532 0 stevel */ 533 0 stevel 534 0 stevel #define ERI_NOTUSR 0x0f000000 535 0 stevel #define ERI_MASK_1BIT 0x1 536 0 stevel #define ERI_MASK_2BIT 0x3 537 0 stevel #define ERI_MASK_8BIT 0xff 538 0 stevel 539 0 stevel 540 0 stevel /* 541 0 stevel * Note: 542 0 stevel * ERI has all of the above capabilities. 543 0 stevel * Only when an External Transceiver is selected for MII-based FastEthernet 544 0 stevel * link operation, the capabilities depend upon the capabilities of the 545 0 stevel * External Transceiver. 546 0 stevel */ 547 0 stevel 548 0 stevel /* ------------------------------------------------------------------------- */ 549 0 stevel 550 0 stevel static param_t param_arr[] = { 551 4404 gd78059 /* min max value r/w/hidden+name */ 552 4404 gd78059 { 0, 2, 2, "-transceiver_inuse"}, 553 4404 gd78059 { 0, 1, 0, "-link_status"}, 554 4404 gd78059 { 0, 1, 0, "-link_speed"}, 555 4404 gd78059 { 0, 1, 0, "-link_mode"}, 556 4404 gd78059 { 0, 255, 8, "+ipg1"}, 557 4404 gd78059 { 0, 255, 4, "+ipg2"}, 558 4404 gd78059 { 0, 1, 0, "+use_int_xcvr"}, 559 4404 gd78059 { 0, 255, 0, "+pace_size"}, 560 4404 gd78059 { 0, 1, 1, "+adv_autoneg_cap"}, 561 4404 gd78059 { 0, 1, 1, "+adv_100T4_cap"}, 562 4404 gd78059 { 0, 1, 1, "+adv_100fdx_cap"}, 563 4404 gd78059 { 0, 1, 1, "+adv_100hdx_cap"}, 564 4404 gd78059 { 0, 1, 1, "+adv_10fdx_cap"}, 565 4404 gd78059 { 0, 1, 1, "+adv_10hdx_cap"}, 566 4404 gd78059 { 0, 1, 1, "-autoneg_cap"}, 567 4404 gd78059 { 0, 1, 1, "-100T4_cap"}, 568 4404 gd78059 { 0, 1, 1, "-100fdx_cap"}, 569 4404 gd78059 { 0, 1, 1, "-100hdx_cap"}, 570 4404 gd78059 { 0, 1, 1, "-10fdx_cap"}, 571 4404 gd78059 { 0, 1, 1, "-10hdx_cap"}, 572 4404 gd78059 { 0, 1, 0, "-lp_autoneg_cap"}, 573 4404 gd78059 { 0, 1, 0, "-lp_100T4_cap"}, 574 4404 gd78059 { 0, 1, 0, "-lp_100fdx_cap"}, 575 4404 gd78059 { 0, 1, 0, "-lp_100hdx_cap"}, 576 4404 gd78059 { 0, 1, 0, "-lp_10fdx_cap"}, 577 4404 gd78059 { 0, 1, 0, "-lp_10hdx_cap"}, 578 4404 gd78059 { 0, 1, 1, "+lance_mode"}, 579 4404 gd78059 { 0, 31, 8, "+ipg0"}, 580 4404 gd78059 { 0, 127, 6, "+intr_blank_time"}, 581 4404 gd78059 { 0, 255, 8, "+intr_blank_packets"}, 582 4404 gd78059 { 0, 1, 1, "!serial-link"}, 583 4404 gd78059 { 0, 2, 1, "!non-serial-link"}, 584 4404 gd78059 { 0, 1, 0, "%select-link"}, 585 4404 gd78059 { 0, 1, 0, "%default-link"}, 586 4404 gd78059 { 0, 2, 0, "!link-in-use"}, 587 4404 gd78059 { 0, 1, 1, "%adv_asm_dir_cap"}, 588 4404 gd78059 { 0, 1, 1, "%adv_pause_cap"}, 589 4404 gd78059 { 0, 1, 0, "!asm_dir_cap"}, 590 4404 gd78059 { 0, 1, 0, "!pause_cap"}, 591 4404 gd78059 { 0, 1, 0, "!lp_asm_dir_cap"}, 592 4404 gd78059 { 0, 1, 0, "!lp_pause_cap"}, 593 4404 gd78059 }; 594 4404 gd78059 595 4404 gd78059 DDI_DEFINE_STREAM_OPS(eri_dev_ops, nulldev, nulldev, eri_attach, eri_detach, 596 7656 Sherry nodev, NULL, D_MP, NULL, ddi_quiesce_not_supported); 597 0 stevel 598 0 stevel /* 599 0 stevel * This is the loadable module wrapper. 600 0 stevel */ 601 0 stevel #include <sys/modctl.h> 602 0 stevel 603 0 stevel /* 604 0 stevel * Module linkage information for the kernel. 605 0 stevel */ 606 0 stevel static struct modldrv modldrv = { 607 0 stevel &mod_driverops, /* Type of module. This one is a driver */ 608 4404 gd78059 "Sun RIO 10/100 Mb Ethernet", 609 4404 gd78059 &eri_dev_ops, /* driver ops */ 610 0 stevel }; 611 0 stevel 612 0 stevel static struct modlinkage modlinkage = { 613 0 stevel MODREV_1, &modldrv, NULL 614 0 stevel }; 615 0 stevel 616 0 stevel /* 617 0 stevel * Hardware Independent Functions 618 0 stevel * New Section 619 0 stevel */ 620 0 stevel 621 0 stevel int 622 0 stevel _init(void) 623 0 stevel { 624 0 stevel int status; 625 0 stevel 626 4404 gd78059 mac_init_ops(&eri_dev_ops, "eri"); 627 4404 gd78059 if ((status = mod_install(&modlinkage)) != 0) { 628 4404 gd78059 mac_fini_ops(&eri_dev_ops); 629 4404 gd78059 } 630 0 stevel return (status); 631 0 stevel } 632 0 stevel 633 0 stevel int 634 0 stevel _fini(void) 635 0 stevel { 636 4404 gd78059 int status; 637 0 stevel 638 0 stevel status = mod_remove(&modlinkage); 639 4404 gd78059 if (status == 0) { 640 4404 gd78059 mac_fini_ops(&eri_dev_ops); 641 4404 gd78059 } 642 4404 gd78059 return (status); 643 4404 gd78059 } 644 0 stevel 645 0 stevel int 646 0 stevel _info(struct modinfo *modinfop) 647 0 stevel { 648 4404 gd78059 return (mod_info(&modlinkage, modinfop)); 649 0 stevel } 650 0 stevel 651 0 stevel 652 0 stevel /* 653 0 stevel * Interface exists: make available by filling in network interface 654 0 stevel * record. System will initialize the interface when it is ready 655 0 stevel * to accept packets. 656 0 stevel */ 657 0 stevel static int 658 0 stevel eri_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 659 0 stevel { 660 4404 gd78059 struct eri *erip = NULL; 661 4404 gd78059 mac_register_t *macp = NULL; 662 0 stevel int regno; 663 4404 gd78059 boolean_t doinit; 664 4404 gd78059 boolean_t mutex_inited = B_FALSE; 665 4404 gd78059 boolean_t intr_add = B_FALSE; 666 0 stevel 667 0 stevel switch (cmd) { 668 0 stevel case DDI_ATTACH: 669 0 stevel break; 670 0 stevel 671 0 stevel case DDI_RESUME: 672 0 stevel if ((erip = ddi_get_driver_private(dip)) == NULL) 673 0 stevel return (DDI_FAILURE); 674 0 stevel 675 4404 gd78059 mutex_enter(&erip->intrlock); 676 0 stevel erip->flags &= ~ERI_SUSPENDED; 677 0 stevel erip->init_macregs = 1; 678 0 stevel param_linkup = 0; 679 4404 gd78059 erip->stats.link_up = LINK_STATE_DOWN; 680 0 stevel erip->linkcheck = 0; 681 4404 gd78059 682 4404 gd78059 doinit = (erip->flags & ERI_STARTED) ? B_TRUE : B_FALSE; 683 4404 gd78059 mutex_exit(&erip->intrlock); 684 4404 gd78059 685 4404 gd78059 if (doinit && !eri_init(erip)) { 686 4404 gd78059 return (DDI_FAILURE); 687 0 stevel } 688 0 stevel return (DDI_SUCCESS); 689 0 stevel 690 0 stevel default: 691 0 stevel return (DDI_FAILURE); 692 0 stevel } 693 0 stevel 694 0 stevel /* 695 0 stevel * Allocate soft device data structure 696 0 stevel */ 697 4404 gd78059 erip = kmem_zalloc(sizeof (struct eri), KM_SLEEP); 698 0 stevel 699 0 stevel /* 700 0 stevel * Initialize as many elements as possible. 701 0 stevel */ 702 0 stevel ddi_set_driver_private(dip, erip); 703 0 stevel erip->dip = dip; /* dip */ 704 0 stevel erip->instance = ddi_get_instance(dip); /* instance */ 705 0 stevel erip->flags = 0; 706 4404 gd78059 erip->multi_refcnt = 0; 707 4404 gd78059 erip->promisc = B_FALSE; 708 4404 gd78059 709 4404 gd78059 if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 710 4404 gd78059 ERI_FAULT_MSG1(erip, SEVERITY_HIGH, ERI_VERB_MSG, 711 4404 gd78059 "mac_alloc failed"); 712 4404 gd78059 goto attach_fail; 713 4404 gd78059 } 714 4404 gd78059 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 715 4404 gd78059 macp->m_driver = erip; 716 4404 gd78059 macp->m_dip = dip; 717 4404 gd78059 macp->m_src_addr = erip->ouraddr; 718 4404 gd78059 macp->m_callbacks = &eri_m_callbacks; 719 4404 gd78059 macp->m_min_sdu = 0; 720 4404 gd78059 macp->m_max_sdu = ETHERMTU; 721 5895 yz147064 macp->m_margin = VLAN_TAGSZ; 722 0 stevel 723 0 stevel /* 724 0 stevel * Map in the device registers. 725 0 stevel * Separate pointers will be set up for the following 726 0 stevel * register groups within the GEM Register Space: 727 0 stevel * Global register set 728 0 stevel * ETX register set 729 0 stevel * ERX register set 730 0 stevel * BigMAC register set. 731 0 stevel * MIF register set 732 0 stevel */ 733 0 stevel 734 0 stevel if (ddi_dev_nregs(dip, ®no) != (DDI_SUCCESS)) { 735 0 stevel ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG, 736 4404 gd78059 "ddi_dev_nregs failed, returned %d", regno); 737 0 stevel goto attach_fail; 738 0 stevel } 739 0 stevel 740 0 stevel /* 741 0 stevel * Map the PCI config space 742 0 stevel */ 743 4404 gd78059 if (pci_config_setup(dip, &erip->pci_config_handle) != DDI_SUCCESS) { 744 0 stevel ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG, 745 4404 gd78059 "%s pci_config_setup()", config_space_fatal_msg); 746 0 stevel goto attach_fail; 747 0 stevel } 748 0 stevel 749 0 stevel /* 750 0 stevel * Initialize device attributes structure 751 0 stevel */ 752 0 stevel erip->dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 753 0 stevel erip->dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 754 0 stevel erip->dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 755 0 stevel 756 4404 gd78059 if (ddi_regs_map_setup(dip, 1, (caddr_t *)&(erip->globregp), 0, 0, 757 4404 gd78059 &erip->dev_attr, &erip->globregh)) { 758 4404 gd78059 goto attach_fail; 759 0 stevel } 760 0 stevel erip->etxregh = erip->globregh; 761 0 stevel erip->erxregh = erip->globregh; 762 0 stevel erip->bmacregh = erip->globregh; 763 0 stevel erip->mifregh = erip->globregh; 764 0 stevel 765 0 stevel erip->etxregp = (void *)(((caddr_t)erip->globregp) + 0x2000); 766 0 stevel erip->erxregp = (void *)(((caddr_t)erip->globregp) + 0x4000); 767 0 stevel erip->bmacregp = (void *)(((caddr_t)erip->globregp) + 0x6000); 768 0 stevel erip->mifregp = (void *)(((caddr_t)erip->globregp) + 0x6200); 769 0 stevel 770 0 stevel /* 771 0 stevel * Map the software reset register. 772 0 stevel */ 773 4404 gd78059 if (ddi_regs_map_setup(dip, 1, (caddr_t *)&(erip->sw_reset_reg), 774 4404 gd78059 0x1010, 4, &erip->dev_attr, &erip->sw_reset_regh)) { 775 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_MID, ERI_VERB_MSG, 776 4404 gd78059 mregs_4soft_reset_fail_msg); 777 4404 gd78059 goto attach_fail; 778 0 stevel } 779 0 stevel 780 0 stevel /* 781 0 stevel * Try and stop the device. 782 0 stevel * This is done until we want to handle interrupts. 783 0 stevel */ 784 0 stevel if (eri_stop(erip)) 785 0 stevel goto attach_fail; 786 0 stevel 787 0 stevel /* 788 0 stevel * set PCI latency timer register. 789 0 stevel */ 790 0 stevel pci_config_put8(erip->pci_config_handle, PCI_CONF_LATENCY_TIMER, 791 4404 gd78059 (uchar_t)eri_pci_latency_timer); 792 0 stevel 793 0 stevel if (ddi_intr_hilevel(dip, 0)) { 794 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, 795 0 stevel " high-level interrupts are not supported"); 796 0 stevel goto attach_fail; 797 0 stevel } 798 0 stevel 799 0 stevel /* 800 0 stevel * Get the interrupt cookie so the mutexes can be 801 0 stevel * Initialized. 802 0 stevel */ 803 0 stevel if (ddi_get_iblock_cookie(dip, 0, &erip->cookie) != DDI_SUCCESS) 804 0 stevel goto attach_fail; 805 0 stevel 806 0 stevel /* 807 0 stevel * Initialize mutex's for this device. 808 0 stevel */ 809 0 stevel mutex_init(&erip->xmitlock, NULL, MUTEX_DRIVER, (void *)erip->cookie); 810 0 stevel mutex_init(&erip->intrlock, NULL, MUTEX_DRIVER, (void *)erip->cookie); 811 0 stevel mutex_init(&erip->linklock, NULL, MUTEX_DRIVER, (void *)erip->cookie); 812 0 stevel mutex_init(&erip->xcvrlock, NULL, MUTEX_DRIVER, (void *)erip->cookie); 813 0 stevel 814 4404 gd78059 mutex_inited = B_TRUE; 815 0 stevel 816 0 stevel /* 817 0 stevel * Add interrupt to system 818 0 stevel */ 819 4404 gd78059 if (ddi_add_intr(dip, 0, &erip->cookie, 0, eri_intr, (caddr_t)erip) == 820 4404 gd78059 DDI_SUCCESS) 821 4404 gd78059 intr_add = B_TRUE; 822 0 stevel else { 823 4404 gd78059 goto attach_fail; 824 4404 gd78059 } 825 4404 gd78059 826 0 stevel /* 827 0 stevel * Set up the ethernet mac address. 828 0 stevel */ 829 0 stevel (void) eri_setup_mac_address(erip, dip); 830 0 stevel 831 0 stevel if (eri_init_xfer_params(erip)) 832 0 stevel goto attach_fail; 833 0 stevel 834 0 stevel if (eri_burstsize(erip) == DDI_FAILURE) { 835 0 stevel goto attach_fail; 836 0 stevel } 837 0 stevel 838 0 stevel /* 839 0 stevel * Setup fewer receive bufers. 840 0 stevel */ 841 0 stevel ERI_RPENDING = eri_rx_ring_size; 842 0 stevel ERI_TPENDING = eri_tx_ring_size; 843 0 stevel 844 0 stevel erip->rpending_mask = ERI_RPENDING - 1; 845 0 stevel erip->rmdmax_mask = ERI_RPENDING - 1; 846 0 stevel erip->mif_config = (ERI_PHY_BMSR << ERI_MIF_CFGPR_SHIFT); 847 0 stevel 848 0 stevel erip->stats.pmcap = ERI_PMCAP_NONE; 849 0 stevel if (pci_report_pmcap(dip, PCI_PM_IDLESPEED, (void *)4000) == 850 4404 gd78059 DDI_SUCCESS) 851 0 stevel erip->stats.pmcap = ERI_PMCAP_4MHZ; 852 0 stevel 853 4404 gd78059 if (mac_register(macp, &erip->mh) != 0) 854 4404 gd78059 goto attach_fail; 855 4404 gd78059 856 4404 gd78059 mac_free(macp); 857 4404 gd78059 858 0 stevel return (DDI_SUCCESS); 859 0 stevel 860 0 stevel attach_fail: 861 0 stevel if (erip->pci_config_handle) 862 0 stevel (void) pci_config_teardown(&erip->pci_config_handle); 863 0 stevel 864 0 stevel if (mutex_inited) { 865 0 stevel mutex_destroy(&erip->xmitlock); 866 0 stevel mutex_destroy(&erip->intrlock); 867 0 stevel mutex_destroy(&erip->linklock); 868 0 stevel mutex_destroy(&erip->xcvrlock); 869 4404 gd78059 } 870 4404 gd78059 871 4404 gd78059 ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, attach_fail_msg); 872 0 stevel 873 0 stevel if (intr_add) 874 0 stevel ddi_remove_intr(dip, 0, erip->cookie); 875 0 stevel 876 0 stevel if (erip->globregh) 877 0 stevel ddi_regs_map_free(&erip->globregh); 878 0 stevel 879 4404 gd78059 if (macp != NULL) 880 4404 gd78059 mac_free(macp); 881 4404 gd78059 if (erip != NULL) 882 4404 gd78059 kmem_free(erip, sizeof (*erip)); 883 4404 gd78059 884 0 stevel return (DDI_FAILURE); 885 0 stevel } 886 0 stevel 887 0 stevel static int 888 0 stevel eri_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 889 0 stevel { 890 4404 gd78059 struct eri *erip; 891 0 stevel int i; 892 0 stevel 893 0 stevel if ((erip = ddi_get_driver_private(dip)) == NULL) { 894 0 stevel /* 895 0 stevel * No resources allocated. 896 0 stevel */ 897 0 stevel return (DDI_FAILURE); 898 0 stevel } 899 0 stevel 900 0 stevel switch (cmd) { 901 0 stevel case DDI_DETACH: 902 0 stevel break; 903 0 stevel 904 0 stevel case DDI_SUSPEND: 905 0 stevel erip->flags |= ERI_SUSPENDED; 906 0 stevel eri_uninit(erip); 907 0 stevel return (DDI_SUCCESS); 908 0 stevel 909 0 stevel default: 910 0 stevel return (DDI_FAILURE); 911 0 stevel } 912 0 stevel 913 0 stevel if (erip->flags & (ERI_RUNNING | ERI_SUSPENDED)) { 914 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, busy_msg); 915 0 stevel return (DDI_FAILURE); 916 0 stevel } 917 0 stevel 918 4404 gd78059 if (mac_unregister(erip->mh) != 0) { 919 4404 gd78059 return (DDI_FAILURE); 920 4404 gd78059 } 921 4404 gd78059 922 0 stevel /* 923 0 stevel * Make the device quiescent 924 0 stevel */ 925 0 stevel (void) eri_stop(erip); 926 0 stevel 927 0 stevel /* 928 0 stevel * Remove instance of the intr 929 0 stevel */ 930 0 stevel ddi_remove_intr(dip, 0, erip->cookie); 931 0 stevel 932 0 stevel if (erip->pci_config_handle) 933 0 stevel (void) pci_config_teardown(&erip->pci_config_handle); 934 0 stevel 935 0 stevel /* 936 0 stevel * Destroy all mutexes and data structures allocated during 937 0 stevel * attach time. 938 0 stevel */ 939 0 stevel 940 0 stevel if (erip->globregh) 941 0 stevel ddi_regs_map_free(&erip->globregh); 942 0 stevel 943 0 stevel erip->etxregh = NULL; 944 0 stevel erip->erxregh = NULL; 945 0 stevel erip->bmacregh = NULL; 946 0 stevel erip->mifregh = NULL; 947 0 stevel erip->globregh = NULL; 948 0 stevel 949 0 stevel if (erip->sw_reset_regh) 950 0 stevel ddi_regs_map_free(&erip->sw_reset_regh); 951 0 stevel 952 0 stevel if (erip->ksp) 953 0 stevel kstat_delete(erip->ksp); 954 0 stevel 955 0 stevel eri_stop_timer(erip); /* acquire linklock */ 956 0 stevel eri_start_timer(erip, eri_check_link, 0); 957 0 stevel mutex_destroy(&erip->xmitlock); 958 0 stevel mutex_destroy(&erip->intrlock); 959 0 stevel mutex_destroy(&erip->linklock); 960 0 stevel mutex_destroy(&erip->xcvrlock); 961 0 stevel 962 0 stevel if (erip->md_h) { 963 0 stevel if (ddi_dma_unbind_handle(erip->md_h) == 964 0 stevel DDI_FAILURE) 965 0 stevel return (DDI_FAILURE); 966 0 stevel ddi_dma_mem_free(&erip->mdm_h); 967 0 stevel ddi_dma_free_handle(&erip->md_h); 968 0 stevel } 969 0 stevel 970 0 stevel if (eri_freebufs(erip)) 971 0 stevel return (DDI_FAILURE); 972 0 stevel 973 0 stevel /* dvma handle case */ 974 0 stevel 975 0 stevel if (erip->eri_dvmarh) { 976 0 stevel (void) dvma_release(erip->eri_dvmarh); 977 0 stevel erip->eri_dvmarh = NULL; 978 0 stevel } 979 0 stevel /* 980 0 stevel * xmit_dma_mode, erip->ndmaxh[i]=NULL for dvma 981 0 stevel */ 982 0 stevel else { 983 0 stevel for (i = 0; i < ERI_RPENDING; i++) 984 0 stevel if (erip->ndmarh[i]) 985 0 stevel ddi_dma_free_handle(&erip->ndmarh[i]); 986 0 stevel } 987 0 stevel /* 988 7394 gdamore * Release TX buffer 989 0 stevel */ 990 0 stevel if (erip->tbuf_ioaddr != 0) { 991 0 stevel (void) ddi_dma_unbind_handle(erip->tbuf_handle); 992 0 stevel erip->tbuf_ioaddr = 0; 993 0 stevel } 994 0 stevel if (erip->tbuf_kaddr != NULL) { 995 7394 gdamore ddi_dma_mem_free(&erip->tbuf_acch); 996 0 stevel erip->tbuf_kaddr = NULL; 997 0 stevel } 998 0 stevel if (erip->tbuf_handle != NULL) { 999 0 stevel ddi_dma_free_handle(&erip->tbuf_handle); 1000 0 stevel erip->tbuf_handle = NULL; 1001 0 stevel } 1002 0 stevel 1003 0 stevel eri_param_cleanup(erip); 1004 0 stevel 1005 0 stevel ddi_set_driver_private(dip, NULL); 1006 0 stevel kmem_free((caddr_t)erip, sizeof (struct eri)); 1007 0 stevel 1008 0 stevel return (DDI_SUCCESS); 1009 0 stevel } 1010 0 stevel 1011 0 stevel /* 1012 0 stevel * To set up the mac address for the network interface: 1013 0 stevel * The adapter card may support a local mac address which is published 1014 0 stevel * in a device node property "local-mac-address". This mac address is 1015 0 stevel * treated as the factory-installed mac address for DLPI interface. 1016 0 stevel * If the adapter firmware has used the device for diskless boot 1017 0 stevel * operation it publishes a property called "mac-address" for use by 1018 0 stevel * inetboot and the device driver. 1019 0 stevel * If "mac-address" is not found, the system options property 1020 0 stevel * "local-mac-address" is used to select the mac-address. If this option 1021 0 stevel * is set to "true", and "local-mac-address" has been found, then 1022 0 stevel * local-mac-address is used; otherwise the system mac address is used 1023 0 stevel * by calling the "localetheraddr()" function. 1024 0 stevel */ 1025 0 stevel 1026 0 stevel static void 1027 0 stevel eri_setup_mac_address(struct eri *erip, dev_info_t *dip) 1028 0 stevel { 1029 4404 gd78059 uchar_t *prop; 1030 4404 gd78059 char *uselocal; 1031 4404 gd78059 unsigned prop_len; 1032 4404 gd78059 uint32_t addrflags = 0; 1033 4404 gd78059 struct ether_addr factaddr; 1034 0 stevel 1035 0 stevel /* 1036 0 stevel * Check if it is an adapter with its own local mac address 1037 0 stevel * If it is present, save it as the "factory-address" 1038 0 stevel * for this adapter. 1039 0 stevel */ 1040 4404 gd78059 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1041 4404 gd78059 "local-mac-address", &prop, &prop_len) == DDI_PROP_SUCCESS) { 1042 0 stevel if (prop_len == ETHERADDRL) { 1043 4404 gd78059 addrflags = ERI_FACTADDR_PRESENT; 1044 4404 gd78059 bcopy(prop, &factaddr, ETHERADDRL); 1045 0 stevel ERI_FAULT_MSG2(erip, SEVERITY_NONE, ERI_VERB_MSG, 1046 4404 gd78059 lether_addr_msg, ether_sprintf(&factaddr)); 1047 4404 gd78059 } 1048 4404 gd78059 ddi_prop_free(prop); 1049 0 stevel } 1050 0 stevel /* 1051 0 stevel * Check if the adapter has published "mac-address" property. 1052 0 stevel * If it is present, use it as the mac address for this device. 1053 0 stevel */ 1054 4404 gd78059 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1055 4404 gd78059 "mac-address", &prop, &prop_len) == DDI_PROP_SUCCESS) { 1056 0 stevel if (prop_len >= ETHERADDRL) { 1057 4404 gd78059 bcopy(prop, erip->ouraddr, ETHERADDRL); 1058 4472 gd78059 ddi_prop_free(prop); 1059 0 stevel return; 1060 0 stevel } 1061 4404 gd78059 ddi_prop_free(prop); 1062 4404 gd78059 } 1063 4404 gd78059 1064 4404 gd78059 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, "local-mac-address?", 1065 4404 gd78059 &uselocal) == DDI_PROP_SUCCESS) { 1066 4404 gd78059 if ((strcmp("true", uselocal) == 0) && 1067 4404 gd78059 (addrflags & ERI_FACTADDR_PRESENT)) { 1068 4404 gd78059 addrflags |= ERI_FACTADDR_USE; 1069 4404 gd78059 bcopy(&factaddr, erip->ouraddr, ETHERADDRL); 1070 4404 gd78059 ddi_prop_free(uselocal); 1071 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, 1072 4404 gd78059 lmac_addr_msg); 1073 4404 gd78059 return; 1074 4404 gd78059 } 1075 4404 gd78059 ddi_prop_free(uselocal); 1076 0 stevel } 1077 0 stevel 1078 0 stevel /* 1079 0 stevel * Get the system ethernet address. 1080 0 stevel */ 1081 4404 gd78059 (void) localetheraddr(NULL, &factaddr); 1082 4404 gd78059 bcopy(&factaddr, erip->ouraddr, ETHERADDRL); 1083 4404 gd78059 } 1084 0 stevel 1085 0 stevel 1086 0 stevel /* 1087 0 stevel * Calculate the bit in the multicast address filter that selects the given 1088 0 stevel * address. 1089 0 stevel * Note: For ERI, the last 8-bits are used. 1090 0 stevel */ 1091 0 stevel 1092 0 stevel static uint32_t 1093 4404 gd78059 eri_ladrf_bit(const uint8_t *addr) 1094 0 stevel { 1095 0 stevel uint32_t crc; 1096 0 stevel 1097 0 stevel CRC32(crc, addr, ETHERADDRL, -1U, crc32_table); 1098 0 stevel 1099 0 stevel /* 1100 0 stevel * Just want the 8 most significant bits. 1101 0 stevel */ 1102 0 stevel return ((~crc) >> 24); 1103 0 stevel } 1104 0 stevel 1105 4404 gd78059 static void 1106 4404 gd78059 eri_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) 1107 4404 gd78059 { 1108 4404 gd78059 struct eri *erip = arg; 1109 4404 gd78059 struct iocblk *iocp = (void *)mp->b_rptr; 1110 4404 gd78059 int err; 1111 4404 gd78059 1112 4404 gd78059 ASSERT(erip != NULL); 1113 4404 gd78059 1114 4404 gd78059 /* 1115 4404 gd78059 * Privilege checks. 1116 4404 gd78059 */ 1117 0 stevel switch (iocp->ioc_cmd) { 1118 4404 gd78059 case ERI_SET_LOOP_MODE: 1119 4404 gd78059 case ERI_ND_SET: 1120 4404 gd78059 err = secpolicy_net_config(iocp->ioc_cr, B_FALSE); 1121 4404 gd78059 if (err != 0) { 1122 4404 gd78059 miocnak(wq, mp, 0, err); 1123 4404 gd78059 return; 1124 4404 gd78059 } 1125 4404 gd78059 break; 1126 4404 gd78059 default: 1127 4404 gd78059 break; 1128 4404 gd78059 } 1129 4404 gd78059 1130 4404 gd78059 switch (iocp->ioc_cmd) { 1131 0 stevel case ERI_ND_GET: 1132 0 stevel case ERI_ND_SET: 1133 4404 gd78059 eri_process_ndd_ioctl(erip, wq, mp, iocp->ioc_cmd); 1134 0 stevel break; 1135 0 stevel 1136 0 stevel case ERI_SET_LOOP_MODE: 1137 0 stevel case ERI_GET_LOOP_MODE: 1138 4404 gd78059 /* 1139 4404 gd78059 * XXX: Consider updating this to the new netlb ioctls. 1140 4404 gd78059 */ 1141 4404 gd78059 eri_loopback(erip, wq, mp); 1142 0 stevel break; 1143 0 stevel 1144 0 stevel default: 1145 0 stevel miocnak(wq, mp, 0, EINVAL); 1146 0 stevel break; 1147 0 stevel } 1148 0 stevel 1149 4404 gd78059 ASSERT(!MUTEX_HELD(&erip->linklock)); 1150 4404 gd78059 } 1151 4404 gd78059 1152 4404 gd78059 static void 1153 4404 gd78059 eri_loopback(struct eri *erip, queue_t *wq, mblk_t *mp) 1154 4404 gd78059 { 1155 4404 gd78059 struct iocblk *iocp = (void *)mp->b_rptr; 1156 0 stevel loopback_t *al; 1157 0 stevel 1158 4404 gd78059 if (mp->b_cont == NULL || MBLKL(mp->b_cont) < sizeof (loopback_t)) { 1159 0 stevel miocnak(wq, mp, 0, EINVAL); 1160 0 stevel return; 1161 0 stevel } 1162 0 stevel 1163 4404 gd78059 al = (void *)mp->b_cont->b_rptr; 1164 0 stevel 1165 0 stevel switch (iocp->ioc_cmd) { 1166 0 stevel case ERI_SET_LOOP_MODE: 1167 0 stevel switch (al->loopback) { 1168 0 stevel case ERI_LOOPBACK_OFF: 1169 4404 gd78059 erip->flags &= (~ERI_MACLOOPBACK & ~ERI_SERLOOPBACK); 1170 0 stevel /* force link status to go down */ 1171 0 stevel param_linkup = 0; 1172 4404 gd78059 erip->stats.link_up = LINK_STATE_DOWN; 1173 4404 gd78059 erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; 1174 0 stevel (void) eri_init(erip); 1175 0 stevel break; 1176 0 stevel 1177 0 stevel case ERI_MAC_LOOPBACK_ON: 1178 0 stevel erip->flags |= ERI_MACLOOPBACK; 1179 4404 gd78059 erip->flags &= ~ERI_SERLOOPBACK; 1180 4404 gd78059 param_linkup = 0; 1181 4404 gd78059 erip->stats.link_up = LINK_STATE_DOWN; 1182 4404 gd78059 erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; 1183 0 stevel (void) eri_init(erip); 1184 0 stevel break; 1185 0 stevel 1186 0 stevel case ERI_PCS_LOOPBACK_ON: 1187 0 stevel break; 1188 0 stevel 1189 0 stevel case ERI_SER_LOOPBACK_ON: 1190 0 stevel erip->flags |= ERI_SERLOOPBACK; 1191 4404 gd78059 erip->flags &= ~ERI_MACLOOPBACK; 1192 0 stevel /* force link status to go down */ 1193 0 stevel param_linkup = 0; 1194 4404 gd78059 erip->stats.link_up = LINK_STATE_DOWN; 1195 4404 gd78059 erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; 1196 0 stevel (void) eri_init(erip); 1197 0 stevel break; 1198 0 stevel 1199 0 stevel default: 1200 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, 1201 4404 gd78059 loopback_val_default); 1202 0 stevel miocnak(wq, mp, 0, EINVAL); 1203 0 stevel return; 1204 0 stevel } 1205 0 stevel miocnak(wq, mp, 0, 0); 1206 0 stevel break; 1207 0 stevel 1208 0 stevel case ERI_GET_LOOP_MODE: 1209 4404 gd78059 al->loopback = ERI_MAC_LOOPBACK_ON | ERI_PCS_LOOPBACK_ON | 1210 4404 gd78059 ERI_SER_LOOPBACK_ON; 1211 0 stevel miocack(wq, mp, sizeof (loopback_t), 0); 1212 0 stevel break; 1213 0 stevel 1214 0 stevel default: 1215 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, 1216 4404 gd78059 loopback_cmd_default); 1217 4404 gd78059 } 1218 4404 gd78059 } 1219 4404 gd78059 1220 4404 gd78059 static int 1221 4404 gd78059 eri_m_promisc(void *arg, boolean_t on) 1222 4404 gd78059 { 1223 4404 gd78059 struct eri *erip = arg; 1224 4404 gd78059 1225 4404 gd78059 mutex_enter(&erip->intrlock); 1226 4404 gd78059 erip->promisc = on; 1227 4404 gd78059 eri_init_rx(erip); 1228 4404 gd78059 mutex_exit(&erip->intrlock); 1229 4404 gd78059 return (0); 1230 0 stevel } 1231 0 stevel 1232 0 stevel /* 1233 0 stevel * This is to support unlimited number of members 1234 0 stevel * in Multicast. 1235 0 stevel */ 1236 4404 gd78059 static int 1237 4404 gd78059 eri_m_multicst(void *arg, boolean_t add, const uint8_t *mca) 1238 4404 gd78059 { 1239 4404 gd78059 struct eri *erip = arg; 1240 4404 gd78059 uint32_t ladrf_bit; 1241 0 stevel 1242 0 stevel /* 1243 0 stevel * If this address's bit was not already set in the local address 1244 0 stevel * filter, add it and re-initialize the Hardware. 1245 0 stevel */ 1246 4404 gd78059 ladrf_bit = eri_ladrf_bit(mca); 1247 4404 gd78059 1248 4404 gd78059 mutex_enter(&erip->intrlock); 1249 4404 gd78059 if (add) { 1250 4404 gd78059 erip->ladrf_refcnt[ladrf_bit]++; 1251 4404 gd78059 if (erip->ladrf_refcnt[ladrf_bit] == 1) { 1252 4404 gd78059 LADRF_SET(erip, ladrf_bit); 1253 4404 gd78059 erip->multi_refcnt++; 1254 4404 gd78059 eri_init_rx(erip); 1255 4404 gd78059 } 1256 4404 gd78059 } else { 1257 4404 gd78059 erip->ladrf_refcnt[ladrf_bit]--; 1258 4404 gd78059 if (erip->ladrf_refcnt[ladrf_bit] == 0) { 1259 4404 gd78059 LADRF_CLR(erip, ladrf_bit); 1260 4404 gd78059 erip->multi_refcnt--; 1261 4404 gd78059 eri_init_rx(erip); 1262 4404 gd78059 } 1263 4404 gd78059 } 1264 4404 gd78059 mutex_exit(&erip->intrlock); 1265 4404 gd78059 return (0); 1266 4404 gd78059 } 1267 4404 gd78059 1268 4404 gd78059 static int 1269 4404 gd78059 eri_m_unicst(void *arg, const uint8_t *macaddr) 1270 4404 gd78059 { 1271 4404 gd78059 struct eri *erip = arg; 1272 0 stevel 1273 0 stevel /* 1274 0 stevel * Set new interface local address and re-init device. 1275 0 stevel * This is destructive to any other streams attached 1276 0 stevel * to this device. 1277 0 stevel */ 1278 4404 gd78059 mutex_enter(&erip->intrlock); 1279 4404 gd78059 bcopy(macaddr, &erip->ouraddr, ETHERADDRL); 1280 4404 gd78059 eri_init_rx(erip); 1281 4404 gd78059 mutex_exit(&erip->intrlock); 1282 4404 gd78059 return (0); 1283 4404 gd78059 } 1284 4404 gd78059 1285 4404 gd78059 /*ARGSUSED*/ 1286 4404 gd78059 static boolean_t 1287 4404 gd78059 eri_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 1288 4404 gd78059 { 1289 4404 gd78059 switch (cap) { 1290 4404 gd78059 case MAC_CAPAB_HCKSUM: { 1291 4404 gd78059 uint32_t *hcksum_txflags = cap_data; 1292 4404 gd78059 *hcksum_txflags = HCKSUM_INET_PARTIAL; 1293 4404 gd78059 return (B_TRUE); 1294 4404 gd78059 } 1295 4404 gd78059 default: 1296 4404 gd78059 return (B_FALSE); 1297 4404 gd78059 } 1298 4404 gd78059 } 1299 4404 gd78059 1300 4404 gd78059 static int 1301 4404 gd78059 eri_m_start(void *arg) 1302 4404 gd78059 { 1303 4404 gd78059 struct eri *erip = arg; 1304 4404 gd78059 1305 4404 gd78059 mutex_enter(&erip->intrlock); 1306 4404 gd78059 erip->flags |= ERI_STARTED; 1307 4404 gd78059 mutex_exit(&erip->intrlock); 1308 4404 gd78059 1309 4404 gd78059 if (!eri_init(erip)) { 1310 4404 gd78059 mutex_enter(&erip->intrlock); 1311 4404 gd78059 erip->flags &= ~ERI_STARTED; 1312 4404 gd78059 mutex_exit(&erip->intrlock); 1313 4404 gd78059 return (EIO); 1314 4404 gd78059 } 1315 4404 gd78059 return (0); 1316 4404 gd78059 } 1317 4404 gd78059 1318 4404 gd78059 static void 1319 4404 gd78059 eri_m_stop(void *arg) 1320 4404 gd78059 { 1321 4404 gd78059 struct eri *erip = arg; 1322 4404 gd78059 1323 4404 gd78059 mutex_enter(&erip->intrlock); 1324 4404 gd78059 erip->flags &= ~ERI_STARTED; 1325 4404 gd78059 mutex_exit(&erip->intrlock); 1326 4404 gd78059 eri_uninit(erip); 1327 4404 gd78059 } 1328 4404 gd78059 1329 4404 gd78059 static int 1330 4404 gd78059 eri_m_stat(void *arg, uint_t stat, uint64_t *val) 1331 4404 gd78059 { 1332 4404 gd78059 struct eri *erip = arg; 1333 4404 gd78059 struct stats *esp; 1334 4404 gd78059 boolean_t macupdate = B_FALSE; 1335 4404 gd78059 1336 4404 gd78059 esp = &erip->stats; 1337 4404 gd78059 1338 4404 gd78059 mutex_enter(&erip->xmitlock); 1339 4404 gd78059 if ((erip->flags & ERI_RUNNING) && (erip->flags & ERI_TXINIT)) { 1340 4404 gd78059 erip->tx_completion = 1341 4404 gd78059 GET_ETXREG(tx_completion) & ETX_COMPLETION_MASK; 1342 4404 gd78059 macupdate |= eri_reclaim(erip, erip->tx_completion); 1343 4404 gd78059 } 1344 4404 gd78059 mutex_exit(&erip->xmitlock); 1345 4404 gd78059 if (macupdate) 1346 4404 gd78059 mac_tx_update(erip->mh); 1347 4404 gd78059 1348 4404 gd78059 eri_savecntrs(erip); 1349 4404 gd78059 1350 4404 gd78059 switch (stat) { 1351 4404 gd78059 case MAC_STAT_IFSPEED: 1352 4404 gd78059 *val = esp->ifspeed * 1000000ULL; 1353 4404 gd78059 break; 1354 4404 gd78059 case MAC_STAT_MULTIRCV: 1355 4404 gd78059 *val = esp->multircv; 1356 4404 gd78059 break; 1357 4404 gd78059 case MAC_STAT_BRDCSTRCV: 1358 4404 gd78059 *val = esp->brdcstrcv; 1359 4404 gd78059 break; 1360 4404 gd78059 case MAC_STAT_IPACKETS: 1361 4404 gd78059 *val = esp->ipackets64; 1362 4404 gd78059 break; 1363 4404 gd78059 case MAC_STAT_RBYTES: 1364 4404 gd78059 *val = esp->rbytes64; 1365 4404 gd78059 break; 1366 4404 gd78059 case MAC_STAT_OBYTES: 1367 4404 gd78059 *val = esp->obytes64; 1368 4404 gd78059 break; 1369 4404 gd78059 case MAC_STAT_OPACKETS: 1370 4404 gd78059 *val = esp->opackets64; 1371 4404 gd78059 break; 1372 4404 gd78059 case MAC_STAT_IERRORS: 1373 4404 gd78059 *val = esp->ierrors; 1374 4404 gd78059 break; 1375 4404 gd78059 case MAC_STAT_OERRORS: 1376 4404 gd78059 *val = esp->oerrors; 1377 4404 gd78059 break; 1378 4404 gd78059 case MAC_STAT_MULTIXMT: 1379 4404 gd78059 *val = esp->multixmt; 1380 4404 gd78059 break; 1381 4404 gd78059 case MAC_STAT_BRDCSTXMT: 1382 4404 gd78059 *val = esp->brdcstxmt; 1383 4404 gd78059 break; 1384 4404 gd78059 case MAC_STAT_NORCVBUF: 1385 4404 gd78059 *val = esp->norcvbuf; 1386 4404 gd78059 break; 1387 4404 gd78059 case MAC_STAT_NOXMTBUF: 1388 4404 gd78059 *val = esp->noxmtbuf; 1389 4404 gd78059 break; 1390 4404 gd78059 case MAC_STAT_UNDERFLOWS: 1391 4404 gd78059 *val = esp->txmac_urun; 1392 4404 gd78059 break; 1393 4404 gd78059 case MAC_STAT_OVERFLOWS: 1394 4404 gd78059 *val = esp->rx_overflow; 1395 4404 gd78059 break; 1396 4404 gd78059 case MAC_STAT_COLLISIONS: 1397 4404 gd78059 *val = esp->collisions; 1398 4404 gd78059 break; 1399 4404 gd78059 case ETHER_STAT_ALIGN_ERRORS: 1400 4404 gd78059 *val = esp->rx_align_err; 1401 4404 gd78059 break; 1402 4404 gd78059 case ETHER_STAT_FCS_ERRORS: 1403 4404 gd78059 *val = esp->rx_crc_err; 1404 4404 gd78059 break; 1405 4404 gd78059 case ETHER_STAT_EX_COLLISIONS: 1406 4404 gd78059 *val = esp->excessive_coll; 1407 4404 gd78059 break; 1408 4404 gd78059 case ETHER_STAT_TX_LATE_COLLISIONS: 1409 4404 gd78059 *val = esp->late_coll; 1410 4404 gd78059 break; 1411 4404 gd78059 case ETHER_STAT_FIRST_COLLISIONS: 1412 4404 gd78059 *val = esp->first_coll; 1413 4404 gd78059 break; 1414 4404 gd78059 case ETHER_STAT_LINK_DUPLEX: 1415 4404 gd78059 *val = esp->link_duplex; 1416 4404 gd78059 break; 1417 4404 gd78059 case ETHER_STAT_TOOLONG_ERRORS: 1418 4404 gd78059 *val = esp->rx_toolong_pkts; 1419 4404 gd78059 break; 1420 4404 gd78059 case ETHER_STAT_TOOSHORT_ERRORS: 1421 4404 gd78059 *val = esp->rx_runt; 1422 4404 gd78059 break; 1423 4404 gd78059 1424 4404 gd78059 case ETHER_STAT_XCVR_ADDR: 1425 4404 gd78059 *val = erip->phyad; 1426 4404 gd78059 break; 1427 4404 gd78059 1428 4404 gd78059 case ETHER_STAT_XCVR_INUSE: 1429 4404 gd78059 *val = XCVR_100X; /* should always be 100X for now */ 1430 4404 gd78059 break; 1431 4404 gd78059 1432 4404 gd78059 case ETHER_STAT_CAP_100FDX: 1433 4404 gd78059 *val = param_bmsr_100fdx; 1434 4404 gd78059 break; 1435 4404 gd78059 case ETHER_STAT_CAP_100HDX: 1436 4404 gd78059 *val = param_bmsr_100hdx; 1437 4404 gd78059 break; 1438 4404 gd78059 case ETHER_STAT_CAP_10FDX: 1439 4404 gd78059 *val = param_bmsr_10fdx; 1440 4404 gd78059 break; 1441 4404 gd78059 case ETHER_STAT_CAP_10HDX: 1442 4404 gd78059 *val = param_bmsr_10hdx; 1443 4404 gd78059 break; 1444 4404 gd78059 case ETHER_STAT_CAP_AUTONEG: 1445 4404 gd78059 *val = param_bmsr_ancap; 1446 4404 gd78059 break; 1447 4404 gd78059 case ETHER_STAT_CAP_ASMPAUSE: 1448 4404 gd78059 *val = param_bmsr_asm_dir; 1449 4404 gd78059 break; 1450 4404 gd78059 case ETHER_STAT_CAP_PAUSE: 1451 4404 gd78059 *val = param_bmsr_pause; 1452 4404 gd78059 break; 1453 4404 gd78059 case ETHER_STAT_ADV_CAP_100FDX: 1454 4404 gd78059 *val = param_anar_100fdx; 1455 4404 gd78059 break; 1456 4404 gd78059 case ETHER_STAT_ADV_CAP_100HDX: 1457 4404 gd78059 *val = param_anar_100hdx; 1458 4404 gd78059 break; 1459 4404 gd78059 case ETHER_STAT_ADV_CAP_10FDX: 1460 4404 gd78059 *val = param_anar_10fdx; 1461 4404 gd78059 break; 1462 4404 gd78059 case ETHER_STAT_ADV_CAP_10HDX: 1463 4404 gd78059 *val = param_anar_10hdx; 1464 4404 gd78059 break; 1465 4404 gd78059 case ETHER_STAT_ADV_CAP_AUTONEG: 1466 4404 gd78059 *val = param_autoneg; 1467 4404 gd78059 break; 1468 4404 gd78059 case ETHER_STAT_ADV_CAP_ASMPAUSE: 1469 4404 gd78059 *val = param_anar_asm_dir; 1470 4404 gd78059 break; 1471 4404 gd78059 case ETHER_STAT_ADV_CAP_PAUSE: 1472 4404 gd78059 *val = param_anar_pause; 1473 4404 gd78059 break; 1474 4404 gd78059 case ETHER_STAT_LP_CAP_100FDX: 1475 4404 gd78059 *val = param_anlpar_100fdx; 1476 4404 gd78059 break; 1477 4404 gd78059 case ETHER_STAT_LP_CAP_100HDX: 1478 4404 gd78059 *val = param_anlpar_100hdx; 1479 4404 gd78059 break; 1480 4404 gd78059 case ETHER_STAT_LP_CAP_10FDX: 1481 4404 gd78059 *val = param_anlpar_10fdx; 1482 4404 gd78059 break; 1483 4404 gd78059 case ETHER_STAT_LP_CAP_10HDX: 1484 4404 gd78059 *val = param_anlpar_10hdx; 1485 4404 gd78059 break; 1486 4404 gd78059 case ETHER_STAT_LP_CAP_AUTONEG: 1487 4404 gd78059 *val = param_aner_lpancap; 1488 4404 gd78059 break; 1489 4404 gd78059 case ETHER_STAT_LP_CAP_ASMPAUSE: 1490 4404 gd78059 *val = param_anlpar_pauseTX; 1491 4404 gd78059 break; 1492 4404 gd78059 case ETHER_STAT_LP_CAP_PAUSE: 1493 4404 gd78059 *val = param_anlpar_pauseRX; 1494 4404 gd78059 break; 1495 4404 gd78059 case ETHER_STAT_LINK_PAUSE: 1496 4404 gd78059 *val = esp->pausing; 1497 4404 gd78059 break; 1498 4404 gd78059 case ETHER_STAT_LINK_ASMPAUSE: 1499 4404 gd78059 *val = param_anar_asm_dir && 1500 4404 gd78059 param_anlpar_pauseTX && 1501 4404 gd78059 (param_anar_pause != param_anlpar_pauseRX); 1502 4404 gd78059 break; 1503 4404 gd78059 case ETHER_STAT_LINK_AUTONEG: 1504 4404 gd78059 *val = param_autoneg && param_aner_lpancap; 1505 4404 gd78059 break; 1506 4404 gd78059 } 1507 4404 gd78059 return (0); 1508 4404 gd78059 } 1509 0 stevel 1510 0 stevel /* 1511 0 stevel * Hardware Functions 1512 0 stevel * New Section 1513 0 stevel */ 1514 0 stevel 1515 0 stevel /* 1516 0 stevel * Initialize the MAC registers. Some of of the MAC registers are initialized 1517 0 stevel * just once since Global Reset or MAC reset doesn't clear them. Others (like 1518 0 stevel * Host MAC Address Registers) are cleared on every reset and have to be 1519 0 stevel * reinitialized. 1520 0 stevel */ 1521 0 stevel static void 1522 0 stevel eri_init_macregs_generic(struct eri *erip) 1523 4404 gd78059 { 1524 0 stevel /* 1525 0 stevel * set up the MAC parameter registers once 1526 0 stevel * after power cycle. SUSPEND/RESUME also requires 1527 0 stevel * setting these registers. 1528 0 stevel */ 1529 0 stevel if ((erip->stats.inits == 1) || (erip->init_macregs)) { 1530 0 stevel erip->init_macregs = 0; 1531 0 stevel PUT_MACREG(ipg0, param_ipg0); 1532 0 stevel PUT_MACREG(ipg1, param_ipg1); 1533 0 stevel PUT_MACREG(ipg2, param_ipg2); 1534 0 stevel PUT_MACREG(macmin, BMAC_MIN_FRAME_SIZE); 1535 0 stevel #ifdef ERI_RX_TAG_ERROR_WORKAROUND 1536 0 stevel PUT_MACREG(macmax, BMAC_MAX_FRAME_SIZE_TAG | BMAC_MAX_BURST); 1537 0 stevel #else 1538 0 stevel PUT_MACREG(macmax, BMAC_MAX_FRAME_SIZE | BMAC_MAX_BURST); 1539 0 stevel #endif 1540 0 stevel PUT_MACREG(palen, BMAC_PREAMBLE_SIZE); 1541 0 stevel PUT_MACREG(jam, BMAC_JAM_SIZE); 1542 0 stevel PUT_MACREG(alimit, BMAC_ATTEMPT_LIMIT); 1543 0 stevel PUT_MACREG(macctl_type, BMAC_CONTROL_TYPE); 1544 0 stevel PUT_MACREG(rseed, 1545 4404 gd78059 ((erip->ouraddr[0] & 0x3) << 8) | erip->ouraddr[1]); 1546 0 stevel 1547 0 stevel PUT_MACREG(madd3, BMAC_ADDRESS_3); 1548 0 stevel PUT_MACREG(madd4, BMAC_ADDRESS_4); 1549 0 stevel PUT_MACREG(madd5, BMAC_ADDRESS_5); 1550 0 stevel 1551 0 stevel /* Program MAC Control address */ 1552 0 stevel PUT_MACREG(madd6, BMAC_ADDRESS_6); 1553 0 stevel PUT_MACREG(madd7, BMAC_ADDRESS_7); 1554 0 stevel PUT_MACREG(madd8, BMAC_ADDRESS_8); 1555 0 stevel 1556 0 stevel PUT_MACREG(afr0, BMAC_AF_0); 1557 0 stevel PUT_MACREG(afr1, BMAC_AF_1); 1558 0 stevel PUT_MACREG(afr2, BMAC_AF_2); 1559 0 stevel PUT_MACREG(afmr1_2, BMAC_AF21_MASK); 1560 0 stevel PUT_MACREG(afmr0, BMAC_AF0_MASK); 1561 0 stevel } 1562 0 stevel 1563 0 stevel /* The counters need to be zeroed */ 1564 0 stevel PUT_MACREG(nccnt, 0); 1565 0 stevel PUT_MACREG(fccnt, 0); 1566 0 stevel PUT_MACREG(excnt, 0); 1567 0 stevel PUT_MACREG(ltcnt, 0); 1568 0 stevel PUT_MACREG(dcnt, 0); 1569 0 stevel PUT_MACREG(frcnt, 0); 1570 0 stevel PUT_MACREG(lecnt, 0); 1571 0 stevel PUT_MACREG(aecnt, 0); 1572 0 stevel PUT_MACREG(fecnt, 0); 1573 0 stevel PUT_MACREG(rxcv, 0); 1574 0 stevel 1575 0 stevel if (erip->pauseTX) 1576 0 stevel PUT_MACREG(spcmd, BMAC_SEND_PAUSE_CMD); 1577 0 stevel else 1578 0 stevel PUT_MACREG(spcmd, 0); 1579 4728 gd78059 1580 4728 gd78059 /* 1581 4728 gd78059 * Program BigMAC with local individual ethernet address. 1582 4728 gd78059 */ 1583 4728 gd78059 1584 4728 gd78059 PUT_MACREG(madd0, (erip->ouraddr[4] << 8) | erip->ouraddr[5]); 1585 4728 gd78059 PUT_MACREG(madd1, (erip->ouraddr[2] << 8) | erip->ouraddr[3]); 1586 4728 gd78059 PUT_MACREG(madd2, (erip->ouraddr[0] << 8) | erip->ouraddr[1]); 1587 4728 gd78059 1588 4728 gd78059 /* 1589 4728 gd78059 * Install multicast address filter. 1590 4728 gd78059 */ 1591 4728 gd78059 1592 4728 gd78059 PUT_MACREG(hash0, erip->ladrf[0]); 1593 4728 gd78059 PUT_MACREG(hash1, erip->ladrf[1]); 1594 4728 gd78059 PUT_MACREG(hash2, erip->ladrf[2]); 1595 4728 gd78059 PUT_MACREG(hash3, erip->ladrf[3]); 1596 4728 gd78059 PUT_MACREG(hash4, erip->ladrf[4]); 1597 4728 gd78059 PUT_MACREG(hash5, erip->ladrf[5]); 1598 4728 gd78059 PUT_MACREG(hash6, erip->ladrf[6]); 1599 4728 gd78059 PUT_MACREG(hash7, erip->ladrf[7]); 1600 4728 gd78059 PUT_MACREG(hash8, erip->ladrf[8]); 1601 4728 gd78059 PUT_MACREG(hash9, erip->ladrf[9]); 1602 4728 gd78059 PUT_MACREG(hash10, erip->ladrf[10]); 1603 4728 gd78059 PUT_MACREG(hash11, erip->ladrf[11]); 1604 4728 gd78059 PUT_MACREG(hash12, erip->ladrf[12]); 1605 4728 gd78059 PUT_MACREG(hash13, erip->ladrf[13]); 1606 4728 gd78059 PUT_MACREG(hash14, erip->ladrf[14]); 1607 4404 gd78059 } 1608 4404 gd78059 1609 4404 gd78059 static int 1610 4404 gd78059 eri_flush_rxbufs(struct eri *erip) 1611 4404 gd78059 { 1612 4404 gd78059 uint_t i; 1613 4404 gd78059 int status = 0; 1614 4404 gd78059 /* 1615 4404 gd78059 * Free and dvma_unload pending recv buffers. 1616 4404 gd78059 * Maintaining the 1-to-1 ordered sequence of 1617 4404 gd78059 * dvma_load() followed by dvma_unload() is critical. 1618 4404 gd78059 * Always unload anything before loading it again. 1619 4404 gd78059 * Never unload anything twice. Always unload 1620 4404 gd78059 * before freeing the buffer. We satisfy these 1621 4404 gd78059 * requirements by unloading only those descriptors 1622 4404 gd78059 * which currently have an mblk associated with them. 1623 4404 gd78059 */ 1624 4404 gd78059 for (i = 0; i < ERI_RPENDING; i++) { 1625 4404 gd78059 if (erip->rmblkp[i]) { 1626 4404 gd78059 if (erip->eri_dvmarh) 1627 4404 gd78059 dvma_unload(erip->eri_dvmarh, 2 * i, 1628 4404 gd78059 DDI_DMA_SYNC_FORCPU); 1629 4404 gd78059 else if ((ddi_dma_unbind_handle(erip->ndmarh[i]) == 1630 4404 gd78059 DDI_FAILURE)) 1631 4404 gd78059 status = -1; 1632 4404 gd78059 freeb(erip->rmblkp[i]); 1633 4404 gd78059 erip->rmblkp[i] = NULL; 1634 4404 gd78059 } 1635 4404 gd78059 } 1636 4404 gd78059 return (status); 1637 4404 gd78059 } 1638 4404 gd78059 1639 4404 gd78059 static void 1640 4404 gd78059 eri_init_txbufs(struct eri *erip) 1641 4404 gd78059 { 1642 4404 gd78059 /* 1643 4404 gd78059 * Clear TX descriptors. 1644 4404 gd78059 */ 1645 4404 gd78059 bzero((caddr_t)erip->eri_tmdp, ERI_TPENDING * sizeof (struct eri_tmd)); 1646 4404 gd78059 1647 4404 gd78059 /* 1648 4404 gd78059 * sync TXDMA descriptors. 1649 4404 gd78059 */ 1650 4404 gd78059 ERI_SYNCIOPB(erip, erip->eri_tmdp, 1651 4404 gd78059 (ERI_TPENDING * sizeof (struct eri_tmd)), DDI_DMA_SYNC_FORDEV); 1652 4404 gd78059 /* 1653 4404 gd78059 * Reset TMD 'walking' pointers. 1654 4404 gd78059 */ 1655 4404 gd78059 erip->tcurp = erip->eri_tmdp; 1656 4404 gd78059 erip->tnextp = erip->eri_tmdp; 1657 4404 gd78059 erip->tx_cur_cnt = 0; 1658 4404 gd78059 erip->tx_kick = 0; 1659 4404 gd78059 erip->tx_completion = 0; 1660 4404 gd78059 } 1661 4404 gd78059 1662 4404 gd78059 static int 1663 4404 gd78059 eri_init_rxbufs(struct eri *erip) 1664 4404 gd78059 { 1665 4404 gd78059 1666 4404 gd78059 ddi_dma_cookie_t dma_cookie; 1667 4404 gd78059 mblk_t *bp; 1668 4404 gd78059 int i, status = 0; 1669 4404 gd78059 uint32_t ccnt; 1670 4404 gd78059 1671 4404 gd78059 /* 1672 4404 gd78059 * clear rcv descriptors 1673 4404 gd78059 */ 1674 4404 gd78059 bzero((caddr_t)erip->rmdp, ERI_RPENDING * sizeof (struct rmd)); 1675 4404 gd78059 1676 4404 gd78059 for (i = 0; i < ERI_RPENDING; i++) { 1677 4404 gd78059 if ((bp = eri_allocb(ERI_BUFSIZE)) == NULL) { 1678 4404 gd78059 status = -1; 1679 4404 gd78059 continue; 1680 4404 gd78059 } 1681 4404 gd78059 /* Load data buffer to DVMA space */ 1682 4404 gd78059 if (erip->eri_dvmarh) 1683 4404 gd78059 dvma_kaddr_load(erip->eri_dvmarh, 1684 4404 gd78059 (caddr_t)bp->b_rptr, ERI_BUFSIZE, 1685 4404 gd78059 2 * i, &dma_cookie); 1686 4404 gd78059 /* 1687 4404 gd78059 * Bind data buffer to DMA handle 1688 4404 gd78059 */ 1689 4404 gd78059 else if (ddi_dma_addr_bind_handle(erip->ndmarh[i], NULL, 1690 4404 gd78059 (caddr_t)bp->b_rptr, ERI_BUFSIZE, 1691 4404 gd78059 DDI_DMA_READ | DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0, 1692 4404 gd78059 &dma_cookie, &ccnt) != DDI_DMA_MAPPED) 1693 4404 gd78059 status = -1; 1694 4404 gd78059 1695 4404 gd78059 PUT_RMD((&erip->rmdp[i]), dma_cookie); 1696 4404 gd78059 erip->rmblkp[i] = bp; /* save for later use */ 1697 4404 gd78059 } 1698 4404 gd78059 1699 4404 gd78059 /* 1700 4404 gd78059 * sync RXDMA descriptors. 1701 4404 gd78059 */ 1702 4404 gd78059 ERI_SYNCIOPB(erip, erip->rmdp, (ERI_RPENDING * sizeof (struct rmd)), 1703 4404 gd78059 DDI_DMA_SYNC_FORDEV); 1704 4404 gd78059 /* 1705 4404 gd78059 * Reset RMD 'walking' pointers. 1706 4404 gd78059 */ 1707 4404 gd78059 erip->rnextp = erip->rmdp; 1708 4404 gd78059 erip->rx_completion = 0; 1709 4404 gd78059 erip->rx_kick = ERI_RPENDING - 4; 1710 4404 gd78059 return (status); 1711 4404 gd78059 } 1712 4404 gd78059 1713 4404 gd78059 static uint32_t 1714 4404 gd78059 eri_txmac_disable(struct eri *erip) 1715 4404 gd78059 { 1716 4404 gd78059 int n; 1717 4404 gd78059 1718 4404 gd78059 PUT_MACREG(txcfg, GET_MACREG(txcfg) & ~BMAC_TXCFG_ENAB); 1719 4404 gd78059 n = (BMACTXRSTDELAY * 10) / ERI_WAITPERIOD; 1720 4404 gd78059 1721 4404 gd78059 while (--n > 0) { 1722 4404 gd78059 drv_usecwait(ERI_WAITPERIOD); 1723 4404 gd78059 if ((GET_MACREG(txcfg) & 1) == 0) 1724 4404 gd78059 return (0); 1725 4404 gd78059 } 1726 4404 gd78059 return (1); 1727 4404 gd78059 } 1728 4404 gd78059 1729 4404 gd78059 static uint32_t 1730 4404 gd78059 eri_rxmac_disable(struct eri *erip) 1731 4404 gd78059 { 1732 4404 gd78059 int n; 1733 4404 gd78059 PUT_MACREG(rxcfg, GET_MACREG(rxcfg) & ~BMAC_RXCFG_ENAB); 1734 4404 gd78059 n = BMACRXRSTDELAY / ERI_WAITPERIOD; 1735 4404 gd78059 1736 4404 gd78059 while (--n > 0) { 1737 4404 gd78059 drv_usecwait(ERI_WAITPERIOD); 1738 4404 gd78059 if ((GET_MACREG(rxcfg) & 1) == 0) 1739 4404 gd78059 return (0); 1740 4404 gd78059 } 1741 4404 gd78059 return (1); 1742 4404 gd78059 } 1743 4404 gd78059 1744 4404 gd78059 /* 1745 4404 gd78059 * Return 0 upon success, 1 on failure. 1746 4404 gd78059 */ 1747 4404 gd78059 static int 1748 4404 gd78059 eri_stop(struct eri *erip) 1749 4404 gd78059 { 1750 4404 gd78059 (void) eri_erx_reset(erip); 1751 4404 gd78059 (void) eri_etx_reset(erip); 1752 4404 gd78059 1753 4404 gd78059 /* 1754 4404 gd78059 * set up cache line to 16 for 64 bytes of pci burst size 1755 4404 gd78059 */ 1756 4404 gd78059 PUT_SWRSTREG(reset, ERI_G_RESET_GLOBAL | ERI_CACHE_LINE_SIZE); 1757 4404 gd78059 1758 4404 gd78059 if (erip->linkcheck) { 1759 4404 gd78059 erip->linkcheck = 0; 1760 4404 gd78059 erip->global_reset_issued = 2; 1761 4404 gd78059 } else { 1762 4404 gd78059 param_linkup = 0; 1763 4404 gd78059 erip->stats.link_up = LINK_STATE_DOWN; 1764 4404 gd78059 erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; 1765 4404 gd78059 erip->global_reset_issued = -1; 1766 4404 gd78059 } 1767 4404 gd78059 1768 4404 gd78059 ERI_DELAY((GET_SWRSTREG(reset) == ERI_CACHE_LINE_SIZE), 1769 4404 gd78059 ERI_MAX_RST_DELAY); 1770 4404 gd78059 erip->rx_reset_issued = -1; 1771 4404 gd78059 erip->tx_reset_issued = -1; 1772 4404 gd78059 1773 4404 gd78059 /* 1774 4404 gd78059 * workaround for RIO not resetting the interrupt mask 1775 4404 gd78059 * register to default value 0xffffffff. 1776 4404 gd78059 */ 1777 4404 gd78059 PUT_GLOBREG(intmask, ERI_G_MASK_ALL); 1778 4404 gd78059 1779 4404 gd78059 if (GET_SWRSTREG(reset) == ERI_CACHE_LINE_SIZE) { 1780 4404 gd78059 return (0); 1781 4404 gd78059 } else { 1782 4404 gd78059 return (1); 1783 4404 gd78059 } 1784 4404 gd78059 } 1785 4404 gd78059 1786 4404 gd78059 /* 1787 4404 gd78059 * Reset Just the RX Portion 1788 4404 gd78059 * Return 0 upon success, 1 on failure. 1789 4404 gd78059 * 1790 4404 gd78059 * Resetting the rxdma while there is a rx dma transaction going on the 1791 4404 gd78059 * bus, will cause bus hang or parity errors. To avoid this, we would first 1792 4404 gd78059 * disable the rxdma by clearing the ENABLE bit (bit 0). To make sure it is 1793 4404 gd78059 * disabled, we will poll it until it realy clears. Furthermore, to verify 1794 4404 gd78059 * any RX DMA activity is subsided, we delay for 5 msec. 1795 4404 gd78059 */ 1796 4404 gd78059 static uint32_t 1797 4404 gd78059 eri_erx_reset(struct eri *erip) 1798 4404 gd78059 { 1799 4404 gd78059 (void) eri_rxmac_disable(erip); /* Disable the RX MAC */ 1800 4404 gd78059 1801 4404 gd78059 /* Disable the RX DMA */ 1802 4404 gd78059 PUT_ERXREG(config, GET_ERXREG(config) & ~GET_CONFIG_RXDMA_EN); 1803 4404 gd78059 ERI_DELAY(((GET_ERXREG(config) & 1) == 0), ERI_MAX_RST_DELAY); 1804 4404 gd78059 if ((GET_ERXREG(config) & 1) != 0) 1805 4404 gd78059 ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, 1806 4404 gd78059 disable_erx_msg); 1807 4404 gd78059 1808 4404 gd78059 drv_usecwait(5000); /* Delay to insure no RX DMA activity */ 1809 4404 gd78059 1810 4404 gd78059 PUT_SWRSTREG(reset, ERI_G_RESET_ERX | ERI_CACHE_LINE_SIZE); 1811 4404 gd78059 /* 1812 4404 gd78059 * Wait until the reset is completed which is indicated by 1813 4404 gd78059 * the reset bit cleared or time out.. 1814 4404 gd78059 */ 1815 4404 gd78059 ERI_DELAY(((GET_SWRSTREG(reset) & (ERI_G_RESET_ERX)) == 1816 4404 gd78059 ERI_CACHE_LINE_SIZE), ERI_MAX_RST_DELAY); 1817 4404 gd78059 erip->rx_reset_issued = -1; 1818 4404 gd78059 1819 4404 gd78059 return ((GET_SWRSTREG(reset) & (ERI_G_RESET_ERX)) ? 1 : 0); 1820 4404 gd78059 } 1821 4404 gd78059 1822 4404 gd78059 /* 1823 4404 gd78059 * Reset Just the TX Portion 1824 4404 gd78059 * Return 0 upon success, 1 on failure. 1825 4404 gd78059 * Resetting the txdma while there is a tx dma transaction on the bus, may cause 1826 4404 gd78059 * bus hang or parity errors. To avoid this we would first disable the txdma by 1827 4404 gd78059 * clearing the ENABLE bit (bit 0). To make sure it is disabled, we will poll 1828 4404 gd78059 * it until it realy clears. Furthermore, to any TX DMA activity is subsided, 1829 4404 gd78059 * we delay for 1 msec. 1830 4404 gd78059 */ 1831 4404 gd78059 static uint32_t 1832 4404 gd78059 eri_etx_reset(struct eri *erip) 1833 4404 gd78059 { 1834 4404 gd78059 (void) eri_txmac_disable(erip); 1835 4404 gd78059 1836 4404 gd78059 /* Disable the TX DMA */ 1837 4404 gd78059 PUT_ETXREG(config, GET_ETXREG(config) & ~GET_CONFIG_TXDMA_EN); 1838 4404 gd78059 #ifdef ORIG 1839 4404 gd78059 ERI_DELAY(((GET_ETXREG(config) & 1) == 0), ERI_MAX_RST_DELAY); 1840 4404 gd78059 if ((GET_ETXREG(config) & 1) != 0) 1841 4404 gd78059 ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, 1842 4404 gd78059 disable_etx_msg); 1843 4404 gd78059 drv_usecwait(5000); /* Delay to ensure DMA completed (if any). */ 1844 4404 gd78059 #endif 1845 4404 gd78059 drv_usecwait(5000); /* Delay to ensure DMA completed (if any). */ 1846 4404 gd78059 ERI_DELAY(((GET_ETXREG(config) & 1) == 0), ERI_MAX_RST_DELAY); 1847 4404 gd78059 if ((GET_ETXREG(config) & 1) != 0) 1848 4404 gd78059 ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, 1849 4404 gd78059 disable_etx_msg); 1850 4404 gd78059 1851 4404 gd78059 PUT_SWRSTREG(reset, ERI_G_RESET_ETX | ERI_CACHE_LINE_SIZE); 1852 4404 gd78059 1853 4404 gd78059 /* 1854 4404 gd78059 * Wait until the reset is completed which is indicated by the reset bit 1855 4404 gd78059 * cleared or time out.. 1856 4404 gd78059 */ 1857 4404 gd78059 ERI_DELAY(((GET_SWRSTREG(reset) & (ERI_G_RESET_ETX)) == 1858 4404 gd78059 ERI_CACHE_LINE_SIZE), ERI_MAX_RST_DELAY); 1859 4404 gd78059 erip->tx_reset_issued = -1; 1860 4404 gd78059 1861 4404 gd78059 if (GET_SWRSTREG(reset) & (ERI_G_RESET_ETX)) { 1862 4404 gd78059 return (1); 1863 4404 gd78059 } else 1864 4404 gd78059 return (0); 1865 4404 gd78059 } 1866 4404 gd78059 1867 4404 gd78059 1868 4404 gd78059 /* 1869 4404 gd78059 * Initialize the TX DMA registers and Enable the TX DMA. 1870 4404 gd78059 */ 1871 4404 gd78059 static uint32_t 1872 4404 gd78059 eri_init_txregs(struct eri *erip) 1873 4404 gd78059 { 1874 4404 gd78059 1875 4404 gd78059 uint32_t i; 1876 4404 gd78059 uint64_t tx_ring; 1877 4404 gd78059 1878 4404 gd78059 /* 1879 4404 gd78059 * Initialize ETX Registers: 1880 4404 gd78059 * config, txring_lo, txring_hi 1881 4404 gd78059 */ 1882 4404 gd78059 tx_ring = ERI_IOPBIOADDR(erip, erip->eri_tmdp); 1883 4404 gd78059 PUT_ETXREG(txring_lo, (uint32_t)(tx_ring)); 1884 4404 gd78059 PUT_ETXREG(txring_hi, (uint32_t)(tx_ring >> 32)); 1885 4404 gd78059 1886 4404 gd78059 /* 1887 4404 gd78059 * Get TX Ring Size Masks. 1888 4404 gd78059 * The ring size ERI_TPENDING is defined in eri_mac.h. 1889 4404 gd78059 */ 1890 4404 gd78059 switch (ERI_TPENDING) { 1891 4404 gd78059 case 32: i = ETX_RINGSZ_32; 1892 4404 gd78059 break; 1893 4404 gd78059 case 64: i = ETX_RINGSZ_64; 1894 4404 gd78059 break; 1895 4404 gd78059 case 128: i = ETX_RINGSZ_128; 1896 4404 gd78059 break; 1897 4404 gd78059 case 256: i = ETX_RINGSZ_256; 1898 4404 gd78059 break; 1899 4404 gd78059 case 512: i = ETX_RINGSZ_512; 1900 4404 gd78059 break; 1901 4404 gd78059 case 1024: i = ETX_RINGSZ_1024; 1902 4404 gd78059 break; 1903 4404 gd78059 case 2048: i = ETX_RINGSZ_2048; 1904 4404 gd78059 break; 1905 4404 gd78059 case 4096: i = ETX_RINGSZ_4096; 1906 4404 gd78059 break; 1907 4404 gd78059 default: 1908 4404 gd78059 ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG, 1909 4404 gd78059 unk_tx_descr_sze_msg, ERI_TPENDING); 1910 4404 gd78059 return (1); 1911 4404 gd78059 } 1912 4404 gd78059 1913 4404 gd78059 i <<= ERI_TX_RINGSZ_SHIFT; 1914 4404 gd78059 PUT_ETXREG(config, ETX_CONFIG_THRESHOLD | i); 1915 4404 gd78059 ENABLE_TXDMA(erip); 1916 4404 gd78059 ENABLE_MAC(erip); 1917 4404 gd78059 return (0); 1918 4404 gd78059 } 1919 4404 gd78059 1920 4404 gd78059 1921 4404 gd78059 /* 1922 4404 gd78059 * Initialize the RX DMA registers and Enable the RX DMA. 1923 4404 gd78059 */ 1924 4404 gd78059 static uint32_t 1925 4404 gd78059 eri_init_rxregs(struct eri *erip) 1926 4404 gd78059 { 1927 4404 gd78059 int i; 1928 4404 gd78059 uint64_t rx_ring; 1929 4404 gd78059 1930 4404 gd78059 /* 1931 4404 gd78059 * Initialize ERX Registers: 1932 4404 gd78059 * rxring_lo, rxring_hi, config, rx_blanking, rx_pause_threshold. 1933 4404 gd78059 * Also, rx_kick 1934 4404 gd78059 * Read and save rxfifo_size. 1935 4404 gd78059 * XXX: Use this to properly configure PAUSE threshold values. 1936 4404 gd78059 */ 1937 4404 gd78059 rx_ring = ERI_IOPBIOADDR(erip, erip->rmdp); 1938 4404 gd78059 PUT_ERXREG(rxring_lo, (uint32_t)(rx_ring)); 1939 4404 gd78059 PUT_ERXREG(rxring_hi, (uint32_t)(rx_ring >> 32)); 1940 4404 gd78059 PUT_ERXREG(rx_kick, erip->rx_kick); 1941 4404 gd78059 1942 4404 gd78059 /* 1943 4404 gd78059 * The Max ring size, ERI_RMDMAX is defined in eri_mac.h. 1944 4404 gd78059 * More ERI_RPENDING will provide better performance but requires more 1945 4404 gd78059 * system DVMA memory. 1946 4404 gd78059 * eri_rx_ring_size can be used to tune this value from /etc/system 1947 4404 gd78059 * eri_rx_ring_size cannot be NDD'able due to non-recoverable errors 1948 4404 gd78059 * which cannot be detected from NDD operations 1949 4404 gd78059 */ 1950 4404 gd78059 1951 4404 gd78059 /* 1952 4404 gd78059 * get the rxring size bits 1953 4404 gd78059 */ 1954 4404 gd78059 switch (ERI_RPENDING) { 1955 4404 gd78059 case 32: i = ERX_RINGSZ_32; 1956 4404 gd78059 break; 1957 4404 gd78059 case 64: i = ERX_RINGSZ_64; 1958 4404 gd78059 break; 1959 4404 gd78059 case 128: i = ERX_RINGSZ_128; 1960 4404 gd78059 break; 1961 4404 gd78059 case 256: i = ERX_RINGSZ_256; 1962 4404 gd78059 break; 1963 4404 gd78059 case 512: i = ERX_RINGSZ_512; 1964 4404 gd78059 break; 1965 4404 gd78059 case 1024: i = ERX_RINGSZ_1024; 1966 4404 gd78059 break; 1967 4404 gd78059 case 2048: i = ERX_RINGSZ_2048; 1968 4404 gd78059 break; 1969 4404 gd78059 case 4096: i = ERX_RINGSZ_4096; 1970 4404 gd78059 break; 1971 4404 gd78059 default: 1972 4404 gd78059 ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG, 1973 4404 gd78059 unk_rx_descr_sze_msg, ERI_RPENDING); 1974 4404 gd78059 return (1); 1975 4404 gd78059 } 1976 4404 gd78059 1977 4404 gd78059 i <<= ERI_RX_RINGSZ_SHIFT; 1978 4404 gd78059 i |= (ERI_FSTBYTE_OFFSET << ERI_RX_CONFIG_FBO_SHIFT) | 1979 4404 gd78059 (ETHERHEADER_SIZE << ERI_RX_CONFIG_RX_CSSTART_SHIFT) | 1980 4404 gd78059 (ERI_RX_FIFOTH_1024 << ERI_RX_CONFIG_RXFIFOTH_SHIFT); 1981 4404 gd78059 1982 4404 gd78059 PUT_ERXREG(config, i); 1983 4404 gd78059 PUT_ERXREG(rx_blanking, 1984 4404 gd78059 (param_intr_blank_time << ERI_RX_BLNK_INTR_TIME_SHIFT) | 1985 4404 gd78059 param_intr_blank_packets); 1986 4404 gd78059 1987 4404 gd78059 PUT_ERXREG(rx_pause_threshold, rx_pause_threshold); 1988 4404 gd78059 erip->rxfifo_size = GET_ERXREG(rxfifo_size); 1989 4404 gd78059 ENABLE_RXDMA(erip); 1990 4404 gd78059 return (0); 1991 4404 gd78059 } 1992 4404 gd78059 1993 4404 gd78059 static int 1994 4404 gd78059 eri_freebufs(struct eri *erip) 1995 4404 gd78059 { 1996 4404 gd78059 int status = 0; 1997 4404 gd78059 1998 7394 gdamore status = eri_flush_rxbufs(erip); 1999 4404 gd78059 return (status); 2000 4404 gd78059 } 2001 4404 gd78059 2002 4404 gd78059 static void 2003 4404 gd78059 eri_update_rxbufs(struct eri *erip) 2004 4404 gd78059 { 2005 4404 gd78059 int i; 2006 4404 gd78059 volatile struct rmd *rmdp, *rmdpbase; 2007 4404 gd78059 2008 4404 gd78059 /* 2009 4404 gd78059 * Hang out receive buffers. 2010 4404 gd78059 */ 2011 4404 gd78059 rmdpbase = erip->rmdp; 2012 4404 gd78059 for (i = 0; i < ERI_RPENDING; i++) { 2013 4404 gd78059 rmdp = rmdpbase + i; 2014 4404 gd78059 UPDATE_RMD(rmdp); 2015 4404 gd78059 } 2016 4404 gd78059 2017 4404 gd78059 /* 2018 4404 gd78059 * sync RXDMA descriptors. 2019 4404 gd78059 */ 2020 4404 gd78059 ERI_SYNCIOPB(erip, erip->rmdp, (ERI_RPENDING * sizeof (struct rmd)), 2021 4404 gd78059 DDI_DMA_SYNC_FORDEV); 2022 4404 gd78059 /* 2023 4404 gd78059 * Reset RMD 'walking' pointers. 2024 4404 gd78059 */ 2025 4404 gd78059 erip->rnextp = erip->rmdp; 2026 4404 gd78059 erip->rx_completion = 0; 2027 4404 gd78059 erip->rx_kick = ERI_RPENDING - 4; 2028 4404 gd78059 } 2029 4404 gd78059 2030 4404 gd78059 /* 2031 4404 gd78059 * This routine is used to reset the RX DMA only. In the case of RX 2032 4404 gd78059 * failures such as RX Tag Error, RX hang etc... we don't want to 2033 4404 gd78059 * do global reset which takes down the link and clears the FIFO's 2034 4404 gd78059 * By doing RX only reset, we leave the TX and the link intact. 2035 4404 gd78059 */ 2036 4404 gd78059 static uint32_t 2037 4404 gd78059 eri_init_rx_channel(struct eri *erip) 2038 4404 gd78059 { 2039 4404 gd78059 erip->flags &= ~ERI_RXINIT; 2040 4404 gd78059 (void) eri_erx_reset(erip); 2041 4404 gd78059 eri_update_rxbufs(erip); 2042 4404 gd78059 if (eri_init_rxregs(erip)) 2043 4404 gd78059 return (1); 2044 4404 gd78059 PUT_MACREG(rxmask, BMAC_RXINTR_MASK); 2045 4404 gd78059 PUT_MACREG(rxcfg, GET_MACREG(rxcfg) | BMAC_RXCFG_ENAB); 2046 4404 gd78059 erip->rx_reset_issued = 0; 2047 4404 gd78059 HSTAT(erip, rx_inits); 2048 4404 gd78059 erip->flags |= ERI_RXINIT; 2049 4404 gd78059 return (0); 2050 4404 gd78059 } 2051 4404 gd78059 2052 4404 gd78059 static void 2053 4404 gd78059 eri_init_rx(struct eri *erip) 2054 4404 gd78059 { 2055 4404 gd78059 uint16_t *ladrf; 2056 4404 gd78059 2057 4404 gd78059 /* 2058 4404 gd78059 * First of all make sure the Receive MAC is stop. 2059 4404 gd78059 */ 2060 4404 gd78059 (void) eri_rxmac_disable(erip); /* Disable the RX MAC */ 2061 4404 gd78059 2062 0 stevel /* 2063 0 stevel * Program BigMAC with local individual ethernet address. 2064 0 stevel */ 2065 4404 gd78059 2066 4404 gd78059 PUT_MACREG(madd0, (erip->ouraddr[4] << 8) | erip->ouraddr[5]); 2067 4404 gd78059 PUT_MACREG(madd1, (erip->ouraddr[2] << 8) | erip->ouraddr[3]); 2068 4404 gd78059 PUT_MACREG(madd2, (erip->ouraddr[0] << 8) | erip->ouraddr[1]); 2069 0 stevel 2070 0 stevel /* 2071 0 stevel * Set up multicast address filter by passing all multicast 2072 0 stevel * addresses through a crc generator, and then using the 2073 0 stevel * low order 8 bits as a index into the 256 bit logical 2074 0 stevel * address filter. The high order four bits select the word, 2075 0 stevel * while the rest of the bits select the bit within the word. 2076 0 stevel */ 2077 0 stevel 2078 4404 gd78059 ladrf = erip->ladrf; 2079 0 stevel 2080 0 stevel PUT_MACREG(hash0, ladrf[0]); 2081 0 stevel PUT_MACREG(hash1, ladrf[1]); 2082 0 stevel PUT_MACREG(hash2, ladrf[2]); 2083 0 stevel PUT_MACREG(hash3, ladrf[3]); 2084 0 stevel PUT_MACREG(hash4, ladrf[4]); 2085 0 stevel PUT_MACREG(hash5, ladrf[5]); 2086 0 stevel PUT_MACREG(hash6, ladrf[6]); 2087 0 stevel PUT_MACREG(hash7, ladrf[7]); 2088 0 stevel PUT_MACREG(hash8, ladrf[8]); 2089 0 stevel PUT_MACREG(hash9, ladrf[9]); 2090 0 stevel PUT_MACREG(hash10, ladrf[10]); 2091 0 stevel PUT_MACREG(hash11, ladrf[11]); 2092 0 stevel PUT_MACREG(hash12, ladrf[12]); 2093 0 stevel PUT_MACREG(hash13, ladrf[13]); 2094 0 stevel PUT_MACREG(hash14, ladrf[14]); 2095 0 stevel PUT_MACREG(hash15, ladrf[15]); 2096 0 stevel 2097 0 stevel #ifdef ERI_DONT_STRIP_CRC 2098 0 stevel PUT_MACREG(rxcfg, 2099 4404 gd78059 ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) | 2100 4404 gd78059 (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) | 2101 0 stevel BMAC_RXCFG_ENAB)); 2102 0 stevel #else 2103 0 stevel PUT_MACREG(rxcfg, 2104 4404 gd78059 ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) | 2105 4404 gd78059 (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) | 2106 0 stevel BMAC_RXCFG_ENAB | BMAC_RXCFG_STRIP_CRC)); 2107 0 stevel #endif 2108 0 stevel /* wait after setting Hash Enable bit */ 2109 0 stevel /* drv_usecwait(10); */ 2110 0 stevel 2111 0 stevel HSTAT(erip, rx_inits); 2112 4404 gd78059 } 2113 0 stevel 2114 0 stevel /* 2115 0 stevel * This routine is used to init the TX MAC only. 2116 0 stevel * &erip->xmitlock is held before calling this routine. 2117 0 stevel */ 2118 0 stevel void 2119 0 stevel eri_init_txmac(struct eri *erip) 2120 0 stevel { 2121 0 stevel uint32_t carrier_ext = 0; 2122 0 stevel 2123 0 stevel erip->flags &= ~ERI_TXINIT; 2124 0 stevel /* 2125 0 stevel * Stop the Transmit MAC. 2126 0 stevel */ 2127 0 stevel (void) eri_txmac_disable(erip); 2128 0 stevel 2129 0 stevel /* 2130 0 stevel * Must be Internal Transceiver 2131 0 stevel */ 2132 0 stevel if (param_mode) 2133 0 stevel PUT_MACREG(xifc, ((param_transceiver == EXTERNAL_XCVR ? 2134 0 stevel BMAC_XIFC_MIIBUF_OE : 0) | BMAC_XIFC_TX_MII_OE)); 2135 0 stevel else 2136 0 stevel PUT_MACREG(xifc, ((param_transceiver == EXTERNAL_XCVR ? 2137 0 stevel BMAC_XIFC_MIIBUF_OE : 0) | BMAC_XIFC_TX_MII_OE | 2138 0 stevel BMAC_XIFC_DIS_ECHO)); 2139 0 stevel 2140 0 stevel /* 2141 0 stevel * Initialize the interpacket gap registers 2142 0 stevel */ 2143 0 stevel PUT_MACREG(ipg1, param_ipg1); 2144 0 stevel PUT_MACREG(ipg2, param_ipg2); 2145 0 stevel 2146 0 stevel if (erip->ngu_enable) 2147 4404 gd78059 PUT_MACREG(txcfg, ((param_mode ? BMAC_TXCFG_FDX: 0) | 2148 4404 gd78059 ((param_lance_mode && (erip->lance_mode_enable)) ? 2149 4404 gd78059 BMAC_TXCFG_ENIPG0 : 0) | 2150 4404 gd78059 (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0) | 2151 4404 gd78059 BMAC_TXCFG_NGU)); 2152 4404 gd78059 else 2153 4404 gd78059 PUT_MACREG(txcfg, ((param_mode ? BMAC_TXCFG_FDX: 0) | 2154 4404 gd78059 ((param_lance_mode && (erip->lance_mode_enable)) ? 2155 4404 gd78059 BMAC_TXCFG_ENIPG0 : 0) | 2156 4404 gd78059 (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0))); 2157 0 stevel 2158 0 stevel ENABLE_TXDMA(erip); 2159 0 stevel ENABLE_TXMAC(erip); 2160 0 stevel 2161 0 stevel HSTAT(erip, tx_inits); 2162 0 stevel erip->flags |= ERI_TXINIT; 2163 0 stevel } 2164 0 stevel 2165 0 stevel static void 2166 0 stevel eri_unallocthings(struct eri *erip) 2167 0 stevel { 2168 0 stevel uint32_t flag; 2169 0 stevel uint32_t i; 2170 0 stevel 2171 0 stevel flag = erip->alloc_flag; 2172 0 stevel 2173 0 stevel if (flag & ERI_DESC_MEM_MAP) 2174 0 stevel (void) ddi_dma_unbind_handle(erip->md_h); 2175 0 stevel 2176 0 stevel if (flag & ERI_DESC_MEM_ALLOC) { 2177 0 stevel ddi_dma_mem_free(&erip->mdm_h); 2178 0 stevel erip->rmdp = NULL; 2179 0 stevel erip->eri_tmdp = NULL; 2180 0 stevel } 2181 0 stevel 2182 0 stevel if (flag & ERI_DESC_HANDLE_ALLOC) 2183 0 stevel ddi_dma_free_handle(&erip->md_h); 2184 0 stevel 2185 0 stevel (void) eri_freebufs(erip); 2186 0 stevel 2187 0 stevel if (flag & ERI_RCV_HANDLE_ALLOC) 2188 0 stevel for (i = 0; i < erip->rcv_handle_cnt; i++) 2189 0 stevel ddi_dma_free_handle(&erip->ndmarh[i]); 2190 0 stevel 2191 0 stevel if (flag & ERI_RCV_DVMA_ALLOC) { 2192 0 stevel (void) dvma_release(erip->eri_dvmarh); 2193 0 stevel erip->eri_dvmarh = NULL; 2194 0 stevel } 2195 0 stevel 2196 0 stevel if (flag & ERI_XBUFS_KMEM_DMABIND) { 2197 0 stevel (void) ddi_dma_unbind_handle(erip->tbuf_handle); 2198 0 stevel erip->tbuf_ioaddr = 0; 2199 0 stevel } 2200 0 stevel 2201 0 stevel if (flag & ERI_XBUFS_KMEM_ALLOC) { 2202 7394 gdamore ddi_dma_mem_free(&erip->tbuf_acch); 2203 0 stevel erip->tbuf_kaddr = NULL; 2204 0 stevel } 2205 0 stevel 2206 0 stevel if (flag & ERI_XBUFS_HANDLE_ALLOC) { 2207 0 stevel ddi_dma_free_handle(&erip->tbuf_handle); 2208 0 stevel erip->tbuf_handle = NULL; 2209 0 stevel } 2210 0 stevel 2211 0 stevel } 2212 0 stevel 2213 0 stevel /* 2214 0 stevel * Initialize channel. 2215 4404 gd78059 * Return true on success, false on error. 2216 0 stevel * 2217 0 stevel * The recommended sequence for initialization is: 2218 0 stevel * 1. Issue a Global Reset command to the Ethernet Channel. 2219 0 stevel * 2. Poll the Global_Reset bits until the execution of the reset has been 2220 0 stevel * completed. 2221 0 stevel * 2(a). Use the MIF Frame/Output register to reset the transceiver. 2222 0 stevel * Poll Register 0 to till the Resetbit is 0. 2223 0 stevel * 2(b). Use the MIF Frame/Output register to set the PHY in in Normal-Op, 2224 0 stevel * 100Mbps and Non-Isolated mode. The main point here is to bring the 2225 0 stevel * PHY out of Isolate mode so that it can generate the rx_clk and tx_clk 2226 0 stevel * to the MII interface so that the Bigmac core can correctly reset 2227 0 stevel * upon a software reset. 2228 0 stevel * 2(c). Issue another Global Reset command to the Ethernet Channel and poll 2229 0 stevel * the Global_Reset bits till completion. 2230 0 stevel * 3. Set up all the data structures in the host memory. 2231 0 stevel * 4. Program the TX_MAC registers/counters (excluding the TX_MAC Configuration 2232 0 stevel * Register). 2233 0 stevel * 5. Program the RX_MAC registers/counters (excluding the RX_MAC Configuration 2234 0 stevel * Register). 2235 0 stevel * 6. Program the Transmit Descriptor Ring Base Address in the ETX. 2236 0 stevel * 7. Program the Receive Descriptor Ring Base Address in the ERX. 2237 0 stevel * 8. Program the Global Configuration and the Global Interrupt Mask Registers. 2238 0 stevel * 9. Program the ETX Configuration register (enable the Transmit DMA channel). 2239 0 stevel * 10. Program the ERX Configuration register (enable the Receive DMA channel). 2240 0 stevel * 11. Program the XIF Configuration Register (enable the XIF). 2241 0 stevel * 12. Program the RX_MAC Configuration Register (Enable the RX_MAC). 2242 0 stevel * 13. Program the TX_MAC Configuration Register (Enable the TX_MAC). 2243 0 stevel */ 2244 0 stevel /* 2245 0 stevel * lock order: 2246 4404 gd78059 * intrlock->linklock->xmitlock->xcvrlock 2247 4404 gd78059 */ 2248 4404 gd78059 static boolean_t 2249 0 stevel eri_init(struct eri *erip) 2250 0 stevel { 2251 0 stevel uint32_t init_stat = 0; 2252 0 stevel uint32_t partial_init = 0; 2253 0 stevel uint32_t carrier_ext = 0; 2254 0 stevel uint32_t mac_ctl = 0; 2255 4404 gd78059 boolean_t ret; 2256 4404 gd78059 uint32_t link_timeout = ERI_LINKCHECK_TIMER; 2257 4404 gd78059 link_state_t linkupdate = LINK_STATE_UNKNOWN; 2258 4404 gd78059 2259 4404 gd78059 /* 2260 4404 gd78059 * Just return successfully if device is suspended. 2261 0 stevel * eri_init() will be called again from resume. 2262 0 stevel */ 2263 4404 gd78059 ASSERT(erip != NULL); 2264 4404 gd78059 2265 4404 gd78059 if (erip->flags & ERI_SUSPENDED) { 2266 4404 gd78059 ret = B_TRUE; 2267 0 stevel goto init_exit; 2268 4404 gd78059 } 2269 0 stevel 2270 0 stevel mutex_enter(&erip->intrlock); 2271 0 stevel eri_stop_timer(erip); /* acquire linklock */ 2272 4404 gd78059 mutex_enter(&erip->xmitlock); 2273 4404 gd78059 erip->flags &= (ERI_DLPI_LINKUP | ERI_STARTED); 2274 4404 gd78059 erip->wantw = B_FALSE; 2275 0 stevel HSTAT(erip, inits); 2276 0 stevel erip->txhung = 0; 2277 0 stevel 2278 4728 gd78059 if ((erip->stats.inits > 1) && (erip->init_macregs == 0)) 2279 0 stevel eri_savecntrs(erip); 2280 0 stevel 2281 0 stevel mutex_enter(&erip->xcvrlock); 2282 0 stevel if (!param_linkup || erip->linkcheck) { 2283 2534 carlsonj if (!erip->linkcheck) 2284 4404 gd78059 linkupdate = LINK_STATE_DOWN; 2285 0 stevel (void) eri_stop(erip); 2286 0 stevel } 2287 0 stevel if (!(erip->flags & ERI_DLPI_LINKUP) || !param_linkup) { 2288 0 stevel erip->flags |= ERI_DLPI_LINKUP; 2289 0 stevel eri_mif_poll(erip, MIF_POLL_STOP); 2290 0 stevel (void) eri_new_xcvr(erip); 2291 4404 gd78059 ERI_DEBUG_MSG1(erip, XCVR_MSG, "New transceiver detected."); 2292 0 stevel if (param_transceiver != NO_XCVR) { 2293 0 stevel /* 2294 0 stevel * Reset the new PHY and bring up the 2295 0 stevel * link 2296 0 stevel */ 2297 0 stevel if (eri_reset_xcvr(erip)) { 2298 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_NONE, 2299 0 stevel ERI_VERB_MSG, "In Init after reset"); 2300 0 stevel mutex_exit(&erip->xcvrlock); 2301 0 stevel link_timeout = 0; 2302 0 stevel goto done; 2303 0 stevel } 2304 4404 gd78059 if (erip->stats.link_up == LINK_STATE_UP) 2305 4404 gd78059 linkupdate = LINK_STATE_UP; 2306 0 stevel } else { 2307 0 stevel erip->flags |= (ERI_RUNNING | ERI_INITIALIZED); 2308 0 stevel param_linkup = 0; 2309 4404 gd78059 erip->stats.link_up = LINK_STATE_DOWN; 2310 4404 gd78059 erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; 2311 4404 gd78059 linkupdate = LINK_STATE_DOWN; 2312 0 stevel /* 2313 0 stevel * Still go on and complete the MAC initialization as 2314 0 stevel * xcvr might show up later. 2315 0 stevel * you must return to their mutex ordering. 2316 0 stevel */ 2317 0 stevel } 2318 0 stevel eri_mif_poll(erip, MIF_POLL_START); 2319 0 stevel } 2320 0 stevel 2321 0 stevel mutex_exit(&erip->xcvrlock); 2322 0 stevel 2323 0 stevel /* 2324 0 stevel * Allocate data structures. 2325 0 stevel */ 2326 0 stevel if (erip->global_reset_issued) { 2327 0 stevel if (erip->global_reset_issued == 2) { /* fast path */ 2328 7394 gdamore 2329 0 stevel /* 2330 0 stevel * Hang out/Initialize descriptors and buffers. 2331 0 stevel */ 2332 0 stevel eri_init_txbufs(erip); 2333 0 stevel 2334 0 stevel eri_update_rxbufs(erip); 2335 0 stevel } else { 2336 0 stevel init_stat = eri_allocthings(erip); 2337 0 stevel if (init_stat) 2338 0 stevel goto done; 2339 0 stevel 2340 0 stevel if (eri_freebufs(erip)) 2341 0 stevel goto done; 2342 0 stevel /* 2343 0 stevel * Hang out/Initialize descriptors and buffers. 2344 0 stevel */ 2345 0 stevel eri_init_txbufs(erip); 2346 0 stevel if (eri_init_rxbufs(erip)) 2347 0 stevel goto done; 2348 0 stevel } 2349 0 stevel } 2350 0 stevel 2351 0 stevel /* 2352 0 stevel * BigMAC requires that we confirm that tx, rx and hash are in 2353 0 stevel * quiescent state. 2354 0 stevel * MAC will not reset successfully if the transceiver is not reset and 2355 0 stevel * brought out of Isolate mode correctly. TXMAC reset may fail if the 2356 0 stevel * ext. transceiver is just disconnected. If it fails, try again by 2357 0 stevel * checking the transceiver. 2358 0 stevel */ 2359 0 stevel if (eri_txmac_disable(erip)) { 2360 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, 2361 4404 gd78059 disable_txmac_msg); 2362 0 stevel param_linkup = 0; /* force init again */ 2363 4404 gd78059 erip->stats.link_up = LINK_STATE_DOWN; 2364 4404 gd78059 erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; 2365 4404 gd78059 linkupdate = LINK_STATE_DOWN; 2366 0 stevel goto done; 2367 0 stevel } 2368 0 stevel 2369 0 stevel if (eri_rxmac_disable(erip)) { 2370 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG, 2371 4404 gd78059 disable_rxmac_msg); 2372 0 stevel param_linkup = 0; /* force init again */ 2373 4404 gd78059 erip->stats.link_up = LINK_STATE_DOWN; 2374 4404 gd78059 erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; 2375 4404 gd78059 linkupdate = LINK_STATE_DOWN; 2376 0 stevel goto done; 2377 0 stevel } 2378 0 stevel 2379 0 stevel eri_init_macregs_generic(erip); 2380 0 stevel 2381 0 stevel /* 2382 0 stevel * Initialize ERI Global registers : 2383 0 stevel * config 2384 0 stevel * For PCI : err_mask, bif_cfg 2385 0 stevel * 2386 0 stevel * Use user-configurable parameter for enabling 64-bit transfers. 2387 0 stevel * Note:For PCI, burst sizes are in multiples of 64-bytes. 2388 0 stevel */ 2389 0 stevel 2390 0 stevel /* 2391 0 stevel * Significant performance improvements can be achieved by 2392 0 stevel * disabling transmit interrupt. Thus TMD's are reclaimed 2393 0 stevel * only very infrequently. 2394 0 stevel * The PCS Interrupt is masked here. It is enabled only when 2395 0 stevel * a PCS link is brought up because there is no second level 2396 0 stevel * mask for this interrupt.. 2397 0 stevel * Init GLOBAL, TXMAC, RXMAC and MACCTL interrupt masks here. 2398 0 stevel */ 2399 0 stevel if (! partial_init) { 2400 0 stevel PUT_GLOBREG(intmask, ERI_G_MASK_INTR); 2401 0 stevel erip->tx_int_me = 0; 2402 0 stevel PUT_MACREG(txmask, BMAC_TXINTR_MASK); 2403 0 stevel PUT_MACREG(rxmask, BMAC_RXINTR_MASK); 2404 0 stevel PUT_MACREG(macctl_mask, ERI_MACCTL_INTR_MASK); 2405 0 stevel } 2406 0 stevel 2407 0 stevel if (erip->global_reset_issued) { 2408 0 stevel /* 2409 0 stevel * Initialize ETX Registers: 2410 0 stevel * config, txring_lo, txring_hi 2411 0 stevel */ 2412 0 stevel if (eri_init_txregs(erip)) 2413 4404 gd78059 goto done; 2414 0 stevel /* 2415 0 stevel * Initialize ERX Registers: 2416 0 stevel * rxring_lo, rxring_hi, config, rx_blanking, 2417 0 stevel * rx_pause_threshold. Also, rx_kick 2418 0 stevel * Read and save rxfifo_size. 2419 0 stevel */ 2420 0 stevel if (eri_init_rxregs(erip)) 2421 0 stevel goto done; 2422 0 stevel } 2423 0 stevel 2424 0 stevel PUT_MACREG(macctl_mask, ERI_MACCTL_INTR_MASK); 2425 0 stevel 2426 0 stevel /* 2427 0 stevel * Set up the slottime,and rxconfig, txconfig without enabling 2428 0 stevel * the latter two at this time 2429 0 stevel */ 2430 0 stevel PUT_MACREG(slot, BMAC_SLOT_TIME); 2431 0 stevel carrier_ext = 0; 2432 0 stevel 2433 0 stevel #ifdef ERI_DONT_STRIP_CRC 2434 0 stevel PUT_MACREG(rxcfg, 2435 4404 gd78059 ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) | 2436 4404 gd78059 (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) | 2437 0 stevel (carrier_ext ? BMAC_RXCFG_CARR_EXT : 0))); 2438 0 stevel #else 2439 0 stevel PUT_MACREG(rxcfg, 2440 4404 gd78059 ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) | 2441 4404 gd78059 (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) | 2442 0 stevel BMAC_RXCFG_STRIP_CRC | 2443 0 stevel (carrier_ext ? BMAC_RXCFG_CARR_EXT : 0))); 2444 0 stevel #endif 2445 0 stevel drv_usecwait(10); /* wait after setting Hash Enable bit */ 2446 0 stevel 2447 0 stevel if (erip->ngu_enable) 2448 0 stevel PUT_MACREG(txcfg, 2449 0 stevel ((param_mode ? BMAC_TXCFG_FDX: 0) | 2450 0 stevel ((param_lance_mode && (erip->lance_mode_enable)) ? 2451 0 stevel BMAC_TXCFG_ENIPG0 : 0) | 2452 0 stevel (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0) | 2453 0 stevel BMAC_TXCFG_NGU)); 2454 0 stevel else 2455 0 stevel PUT_MACREG(txcfg, 2456 0 stevel ((param_mode ? BMAC_TXCFG_FDX: 0) | 2457 0 stevel ((param_lance_mode && (erip->lance_mode_enable)) ? 2458 0 stevel BMAC_TXCFG_ENIPG0 : 0) | 2459 0 stevel (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0))); 2460 0 stevel 2461 0 stevel if (erip->pauseRX) 2462 0 stevel mac_ctl = ERI_MCTLCFG_RXPAUSE; 2463 0 stevel if (erip->pauseTX) 2464 0 stevel mac_ctl |= ERI_MCTLCFG_TXPAUSE; 2465 0 stevel 2466 0 stevel PUT_MACREG(macctl_cfg, mac_ctl); 2467 0 stevel 2468 0 stevel /* 2469 0 stevel * Must be Internal Transceiver 2470 0 stevel */ 2471 0 stevel if (param_mode) 2472 0 stevel PUT_MACREG(xifc, ((param_transceiver == EXTERNAL_XCVR ? 2473 0 stevel BMAC_XIFC_MIIBUF_OE : 0) | BMAC_XIFC_TX_MII_OE)); 2474 0 stevel else { 2475 0 stevel PUT_MACREG(xifc, ((param_transceiver == EXTERNAL_XCVR ? 2476 0 stevel BMAC_XIFC_MIIBUF_OE : 0) | BMAC_XIFC_TX_MII_OE | 2477 0 stevel BMAC_XIFC_DIS_ECHO)); 2478 0 stevel 2479 0 stevel link_timeout = ERI_CHECK_HANG_TIMER; 2480 0 stevel } 2481 0 stevel 2482 0 stevel /* 2483 0 stevel * if MAC int loopback flag is set, put xifc reg in mii loopback 2484 0 stevel * mode {DIAG} 2485 0 stevel */ 2486 0 stevel if (erip->flags & ERI_MACLOOPBACK) { 2487 0 stevel PUT_MACREG(xifc, GET_MACREG(xifc) | BMAC_XIFC_MIILPBK); 2488 0 stevel } 2489 0 stevel 2490 0 stevel /* 2491 0 stevel * Enable TX and RX MACs. 2492 0 stevel */ 2493 0 stevel ENABLE_MAC(erip); 2494 0 stevel erip->flags |= (ERI_RUNNING | ERI_INITIALIZED | 2495 4404 gd78059 ERI_TXINIT | ERI_RXINIT); 2496 4404 gd78059 mac_tx_update(erip->mh); 2497 0 stevel erip->global_reset_issued = 0; 2498 0 stevel 2499 0 stevel #ifdef ERI_10_10_FORCE_SPEED_WORKAROUND 2500 0 stevel eri_xcvr_force_mode(erip, &link_timeout); 2501 0 stevel #endif 2502 0 stevel 2503 0 stevel done: 2504 0 stevel if (init_stat) 2505 0 stevel eri_unallocthings(erip); 2506 0 stevel 2507 0 stevel mutex_exit(&erip->xmitlock); 2508 0 stevel eri_start_timer(erip, eri_check_link, link_timeout); 2509 0 stevel mutex_exit(&erip->intrlock); 2510 0 stevel 2511 4404 gd78059 if (linkupdate != LINK_STATE_UNKNOWN) 2512 4404 gd78059 mac_link_update(erip->mh, linkupdate); 2513 4404 gd78059 2514 4404 gd78059 ret = (erip->flags & ERI_RUNNING) ? B_TRUE : B_FALSE; 2515 4404 gd78059 if (!ret) { 2516 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, 2517 4404 gd78059 "eri_init failed"); 2518 0 stevel } 2519 0 stevel 2520 0 stevel init_exit: 2521 0 stevel ASSERT(!MUTEX_HELD(&erip->linklock)); 2522 0 stevel return (ret); 2523 0 stevel } 2524 0 stevel 2525 0 stevel /* 2526 0 stevel * 0 as burstsize upon failure as it signifies no burst size. 2527 0 stevel */ 2528 0 stevel static int 2529 0 stevel eri_burstsize(struct eri *erip) 2530 0 stevel { 2531 0 stevel ddi_dma_handle_t handle; 2532 0 stevel 2533 4404 gd78059 if (ddi_dma_alloc_handle(erip->dip, &dma_attr, DDI_DMA_DONTWAIT, 2534 4404 gd78059 NULL, &handle)) 2535 0 stevel return (DDI_FAILURE); 2536 0 stevel 2537 0 stevel erip->burstsizes = ddi_dma_burstsizes(handle); 2538 0 stevel ddi_dma_free_handle(&handle); 2539 0 stevel 2540 0 stevel if (erip->burstsizes) 2541 0 stevel return (DDI_SUCCESS); 2542 0 stevel 2543 0 stevel return (DDI_FAILURE); 2544 0 stevel } 2545 0 stevel 2546 0 stevel /* 2547 0 stevel * Un-initialize (STOP) ERI channel. 2548 0 stevel */ 2549 0 stevel static void 2550 0 stevel eri_uninit(struct eri *erip) 2551 0 stevel { 2552 2534 carlsonj boolean_t needind; 2553 2534 carlsonj 2554 0 stevel /* 2555 0 stevel * Allow up to 'ERI_DRAINTIME' for pending xmit's to complete. 2556 0 stevel */ 2557 0 stevel ERI_DELAY((erip->tcurp == erip->tnextp), ERI_DRAINTIME); 2558 0 stevel 2559 0 stevel mutex_enter(&erip->intrlock); 2560 0 stevel eri_stop_timer(erip); /* acquire linklock */ 2561 0 stevel mutex_enter(&erip->xmitlock); 2562 0 stevel mutex_enter(&erip->xcvrlock); 2563 0 stevel eri_mif_poll(erip, MIF_POLL_STOP); 2564 0 stevel erip->flags &= ~ERI_DLPI_LINKUP; 2565 0 stevel mutex_exit(&erip->xcvrlock); 2566 0 stevel 2567 2534 carlsonj needind = !erip->linkcheck; 2568 0 stevel (void) eri_stop(erip); 2569 0 stevel erip->flags &= ~ERI_RUNNING; 2570 0 stevel 2571 0 stevel mutex_exit(&erip->xmitlock); 2572 0 stevel eri_start_timer(erip, eri_check_link, 0); 2573 0 stevel mutex_exit(&erip->intrlock); 2574 2534 carlsonj 2575 2534 carlsonj if (needind) 2576 4404 gd78059 mac_link_update(erip->mh, LINK_STATE_DOWN); 2577 0 stevel } 2578 0 stevel 2579 0 stevel /* 2580 0 stevel * Allocate CONSISTENT memory for rmds and tmds with appropriate alignment and 2581 0 stevel * map it in IO space. 2582 0 stevel * 2583 0 stevel * The driver allocates STREAMS buffers which will be mapped in DVMA 2584 0 stevel * space using DDI DMA resources. 2585 0 stevel * 2586 0 stevel */ 2587 0 stevel static int 2588 0 stevel eri_allocthings(struct eri *erip) 2589 0 stevel { 2590 0 stevel 2591 0 stevel uintptr_t a; 2592 0 stevel int size; 2593 0 stevel uint32_t rval; 2594 0 stevel int i; 2595 0 stevel size_t real_len; 2596 0 stevel uint32_t cookiec; 2597 0 stevel int alloc_stat = 0; 2598 0 stevel ddi_dma_cookie_t dma_cookie; 2599 0 stevel 2600 0 stevel /* 2601 0 stevel * Return if resources are already allocated. 2602 0 stevel */ 2603 0 stevel if (erip->rmdp) 2604 0 stevel return (alloc_stat); 2605 0 stevel 2606 0 stevel erip->alloc_flag = 0; 2607 0 stevel 2608 0 stevel /* 2609 0 stevel * Allocate the TMD and RMD descriptors and extra for alignments. 2610 0 stevel */ 2611 4404 gd78059 size = (ERI_RPENDING * sizeof (struct rmd) + 2612 4404 gd78059 ERI_TPENDING * sizeof (struct eri_tmd)) + ERI_GMDALIGN; 2613 0 stevel 2614 0 stevel rval = ddi_dma_alloc_handle(erip->dip, &desc_dma_attr, 2615 4404 gd78059 DDI_DMA_DONTWAIT, 0, &erip->md_h); 2616 0 stevel if (rval != DDI_SUCCESS) { 2617 0 stevel return (++alloc_stat); 2618 0 stevel } 2619 0 stevel erip->alloc_flag |= ERI_DESC_HANDLE_ALLOC; 2620 0 stevel 2621 0 stevel rval = ddi_dma_mem_alloc(erip->md_h, size, &erip->dev_attr, 2622 4404 gd78059 DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0, 2623 4404 gd78059 (caddr_t *)&erip->iopbkbase, &real_len, &erip->mdm_h); 2624 0 stevel if (rval != DDI_SUCCESS) { 2625 0 stevel return (++alloc_stat); 2626 0 stevel } 2627 0 stevel erip->alloc_flag |= ERI_DESC_MEM_ALLOC; 2628 0 stevel 2629 0 stevel rval = ddi_dma_addr_bind_handle(erip->md_h, NULL, 2630 4404 gd78059 (caddr_t)erip->iopbkbase, size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 2631 4404 gd78059 DDI_DMA_DONTWAIT, 0, &erip->md_c, &cookiec); 2632 0 stevel 2633 0 stevel if (rval != DDI_DMA_MAPPED) 2634 0 stevel return (++alloc_stat); 2635 0 stevel 2636 0 stevel erip->alloc_flag |= ERI_DESC_MEM_MAP; 2637 0 stevel 2638 0 stevel if (cookiec != 1) 2639 0 stevel return (++alloc_stat); 2640 0 stevel 2641 0 stevel erip->iopbiobase = erip->md_c.dmac_address; 2642 0 stevel 2643 0 stevel a = erip->iopbkbase; 2644 0 stevel a = ROUNDUP(a, ERI_GMDALIGN); 2645 0 stevel erip->rmdp = (struct rmd *)a; 2646 0 stevel a += ERI_RPENDING * sizeof (struct rmd); 2647 0 stevel erip->eri_tmdp = (struct eri_tmd *)a; 2648 0 stevel /* 2649 0 stevel * Specifically we reserve n (ERI_TPENDING + ERI_RPENDING) 2650 0 stevel * pagetable entries. Therefore we have 2 ptes for each 2651 0 stevel * descriptor. Since the ethernet buffers are 1518 bytes 2652 0 stevel * so they can at most use 2 ptes. 2653 0 stevel * Will do a ddi_dma_addr_setup for each bufer 2654 0 stevel */ 2655 0 stevel /* 2656 0 stevel * In the current implementation, we use the ddi compliant 2657 7394 gdamore * dma interface. We allocate ERI_RPENDING dma handles for receive 2658 7394 gdamore * activity. The actual dma mapping is done in the io function 2659 7394 gdamore * eri_read_dma(), by calling the ddi_dma_addr_bind_handle. 2660 0 stevel * Dma resources are deallocated by calling ddi_dma_unbind_handle 2661 0 stevel * in eri_reclaim() for transmit and eri_read_dma(), for receive io. 2662 0 stevel */ 2663 0 stevel 2664 0 stevel if (eri_use_dvma_rx && 2665 0 stevel (dvma_reserve(erip->dip, &eri_dma_limits, (ERI_RPENDING * 2), 2666 0 stevel &erip->eri_dvmarh)) == DDI_SUCCESS) { 2667 0 stevel erip->alloc_flag |= ERI_RCV_DVMA_ALLOC; 2668 0 stevel } else { 2669 0 stevel erip->eri_dvmarh = NULL; 2670 0 stevel 2671 0 stevel for (i = 0; i < ERI_RPENDING; i++) { 2672 0 stevel rval = ddi_dma_alloc_handle(erip->dip, 2673 0 stevel &dma_attr, DDI_DMA_DONTWAIT, 2674 0 stevel 0, &erip->ndmarh[i]); 2675 0 stevel 2676 0 stevel if (rval != DDI_SUCCESS) { 2677 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_HIGH, 2678 0 stevel ERI_VERB_MSG, alloc_rx_dmah_msg); 2679 0 stevel alloc_stat++; 2680 0 stevel break; 2681 0 stevel } 2682 0 stevel } 2683 0 stevel 2684 0 stevel erip->rcv_handle_cnt = i; 2685 0 stevel 2686 0 stevel if (i) 2687 0 stevel erip->alloc_flag |= ERI_RCV_HANDLE_ALLOC; 2688 0 stevel 2689 0 stevel if (alloc_stat) 2690 0 stevel return (alloc_stat); 2691 0 stevel 2692 0 stevel } 2693 0 stevel 2694 0 stevel /* 2695 7394 gdamore * Allocate TX buffer 2696 7394 gdamore * Note: buffers must always be allocated in the native 2697 0 stevel * ordering of the CPU (always big-endian for Sparc). 2698 0 stevel * ddi_dma_mem_alloc returns memory in the native ordering 2699 0 stevel * of the bus (big endian for SBus, little endian for PCI). 2700 0 stevel * So we cannot use ddi_dma_mem_alloc(, &erip->ge_dev_attr) 2701 0 stevel * because we'll get little endian memory on PCI. 2702 0 stevel */ 2703 4404 gd78059 if (ddi_dma_alloc_handle(erip->dip, &desc_dma_attr, DDI_DMA_DONTWAIT, 2704 4404 gd78059 0, &erip->tbuf_handle) != DDI_SUCCESS) { 2705 4404 gd78059 ERI_FAULT_MSG1(erip, SEVERITY_HIGH, ERI_VERB_MSG, 2706 4404 gd78059 alloc_tx_dmah_msg); 2707 4404 gd78059 return (++alloc_stat); 2708 0 stevel } 2709 0 stevel erip->alloc_flag |= ERI_XBUFS_HANDLE_ALLOC; 2710 7394 gdamore size = ERI_TPENDING * ERI_BUFSIZE; 2711 7394 gdamore if (ddi_dma_mem_alloc(erip->tbuf_handle, size, &buf_attr, 2712 7394 gdamore DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, &erip->tbuf_kaddr, 2713 7394 gdamore &real_len, &erip->tbuf_acch) != DDI_SUCCESS) { 2714 0 stevel ERI_FAULT_MSG1(erip, SEVERITY_HIGH, ERI_VERB_MSG, 2715 4404 gd78059 alloc_tx_dmah_msg); 2716 0 stevel return (++alloc_stat); 2717 0 stevel } 2718 0 stevel erip->alloc_flag |= ERI_XBUFS_KMEM_ALLOC; 2719 0 stevel if (ddi_dma_addr_bind_handle(erip->tbuf_handle, NULL, 2720 4404 gd78059 erip->tbuf_kaddr, size, DDI_DMA_WRITE | DDI_DMA_CONSISTENT, 2721 4404 gd78059 DDI_DMA_DONTWAIT, 0, &dma_cookie, &cookiec) != DDI_DMA_MAPPED) { 2722 0 stevel return (++alloc_stat); 2723 0 stevel } 2724 0 stevel erip->tbuf_ioaddr = dma_cookie.dmac_address; 2725 0 stevel erip->alloc_flag |= ERI_XBUFS_KMEM_DMABIND; 2726 0 stevel if (cookiec != 1) 2727 0 stevel return (++alloc_stat); 2728 0 stevel 2729 0 stevel /* 2730 0 stevel * Keep handy limit values for RMD, TMD, and Buffers. 2731 0 stevel */ 2732 0 stevel erip->rmdlimp = &((erip->rmdp)[ERI_RPENDING]); 2733 0 stevel erip->eri_tmdlimp = &((erip->eri_tmdp)[ERI_TPENDING]); 2734 0 stevel 2735 0 stevel /* 2736 7394 gdamore * Zero out RCV holders. 2737 7394 gdamore */ 2738 0 stevel bzero((caddr_t)erip->rmblkp, sizeof (erip->rmblkp)); 2739 0 stevel return (alloc_stat); 2740 0 stevel } 2741 0 stevel 2742 0 stevel /* <<<<<<<<<<<<<<<<< INTERRUPT HANDLING FUNCTION >>>>>>>>>>>>>>>>>>>> */ 2743 0 stevel /* 2744 0 stevel * First check to see if it is our device interrupting. 2745 0 stevel */ 2746 0 stevel static uint_t 2747 4404 gd78059 eri_intr(caddr_t arg) 2748 4404 gd78059 { 2749 4404 gd78059 struct eri *erip = (void *)arg; 2750 0 stevel uint32_t erisbits; 2751 0 stevel uint32_t mif_status; 2752 0 stevel uint32_t serviced = DDI_INTR_UNCLAIMED; 2753 4404 gd78059 link_state_t linkupdate = LINK_STATE_UNKNOWN; 2754 4404 gd78059 boolean_t macupdate = B_FALSE; 2755 4404 gd78059 mblk_t *mp; 2756 4404 gd78059 mblk_t *head; 2757 4404 gd78059 mblk_t **tail; 2758 4404 gd78059 2759 4404 gd78059 head = NULL; 2760 4404 gd78059 tail = &head; 2761 2534 carlsonj 2762 0 stevel mutex_enter(&erip->intrlock); 2763 0 stevel 2764 0 stevel erisbits = GET_GLOBREG(status); 2765 0 stevel 2766 0 stevel /* 2767 0 stevel * Check if it is only the RX_DONE interrupt, which is 2768 0 stevel * the most frequent one. 2769 0 stevel */ 2770 0 stevel if (((erisbits & ERI_G_STATUS_RX_INT) == ERI_G_STATUS_RX_DONE) && 2771 4404 gd78059 (erip->flags & ERI_RUNNING)) { 2772 0 stevel serviced = DDI_INTR_CLAIMED; 2773 0 stevel goto rx_done_int; 2774 0 stevel } 2775 0 stevel 2776 0 stevel /* Claim the first interrupt after initialization */ 2777 0 stevel if (erip->flags & ERI_INITIALIZED) { 2778 0 stevel erip->flags &= ~ERI_INITIALIZED; 2779 0 stevel serviced = DDI_INTR_CLAIMED; 2780 0 stevel } 2781 0 stevel 2782 0 stevel /* Check for interesting events */ 2783 0 stevel if ((erisbits & ERI_G_STATUS_INTR) == 0) { 2784 2534 carlsonj #ifdef ESTAR_WORKAROUND 2785 4404 gd78059 uint32_t linkupdate; 2786 2534 carlsonj #endif 2787 2534 carlsonj 2788 0 stevel ERI_DEBUG_MSG2(erip, DIAG_MSG, 2789 4404 gd78059 "eri_intr: Interrupt Not Claimed gsbits %X", erisbits); 2790 0 stevel #ifdef DEBUG 2791 0 stevel noteri++; 2792 0 stevel #endif 2793 4404 gd78059 ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:MIF Config = 0x%X", 2794 4404 gd78059 GET_MIFREG(mif_cfg)); 2795 4404 gd78059 ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:MIF imask = 0x%X", 2796 4404 gd78059 GET_MIFREG(mif_imask)); 2797 4404 gd78059 ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:INT imask = 0x%X", 2798 4404 gd78059 GET_GLOBREG(intmask)); 2799 4404 gd78059 ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:alias %X", 2800 4404 gd78059 GET_GLOBREG(status_alias)); 2801 0 stevel #ifdef ESTAR_WORKAROUND 2802 4404 gd78059 linkupdate = eri_check_link_noind(erip); 2803 0 stevel #endif 2804 0 stevel mutex_exit(&erip->intrlock); 2805 2534 carlsonj #ifdef ESTAR_WORKAROUND 2806 4404 gd78059 if (linkupdate != LINK_STATE_UNKNOWN) 2807 4404 gd78059 mac_link_update(erip->mh, linkupdate); 2808 2534 carlsonj #endif 2809 0 stevel return (serviced); 2810 0 stevel } 2811 0 stevel serviced = DDI_INTR_CLAIMED; 2812 0 stevel 2813 0 stevel if (!(erip->flags & ERI_RUNNING)) { 2814 0 stevel mutex_exit(&erip->intrlock); 2815 0 stevel eri_uninit(erip); 2816 0 stevel return (serviced); 2817 0 stevel } 2818 0 stevel 2819 0 stevel if (erisbits & ERI_G_STATUS_FATAL_ERR) { 2820 0 stevel ERI_DEBUG_MSG2(erip, INTR_MSG, 2821 4404 gd78059 "eri_intr: fatal error: erisbits = %X", erisbits); 2822 0 stevel (void) eri_fatal_err(erip, erisbits); 2823 0 stevel eri_reinit_fatal++; 2824 0 stevel 2825 0 stevel if (erip->rx_reset_issued) { 2826 0 stevel erip->rx_reset_issued = 0; 2827 0 stevel (void) eri_init_rx_channel(erip); 2828 0 stevel mutex_exit(&erip->intrlock); 2829 0 stevel } else { 2830 0 stevel param_linkup = 0; 2831 4404 gd78059 erip->stats.link_up = LINK_STATE_DOWN; 2832 4404 gd78059 erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN; 2833 0 stevel DISABLE_MAC(erip); 2834 0 stevel mutex_exit(&erip->intrlock); 2835 0 stevel (void) eri_init(erip); 2836 0 stevel } 2837 0 stevel return (serviced); 2838 0 stevel } 2839 0 stevel 2840 0 stevel if (erisbits & ERI_G_STATUS_NONFATAL_ERR) { 2841 0 stevel ERI_DEBUG_MSG2(erip, INTR_MSG, 2842 4404 gd78059 "eri_intr: non-fatal error: erisbits = %X", erisbits); 2843 0 stevel (void) eri_nonfatal_err(erip, erisbits); 2844 0 stevel if (erip->linkcheck) { 2845 0 stevel mutex_exit(&erip->intrlock); 2846 0 stevel (void) eri_init(erip); 2847 0 stevel return (serviced); 2848 0 stevel } 2849 0 stevel } 2850 0 stevel 2851 0 stevel if (erisbits & ERI_G_STATUS_MIF_INT) { 2852 0 stevel uint16_t stat; 2853 0 stevel ERI_DEBUG_MSG2(erip, XCVR_MSG, 2854 4404 gd78059 "eri_intr:MIF Interrupt:mii_status %X", erip->mii_status); 2855 0 stevel eri_stop_timer(erip); /* acquire linklock */ 2856 0 stevel 2857 0 stevel mutex_enter(&erip->xmitlock); 2858 0 stevel mutex_enter(&erip->xcvrlock); 2859 0 stevel #ifdef ERI_MIF_POLL_STATUS_WORKAROUND 2860 0 stevel mif_status = GET_MIFREG(mif_bsts); 2861 0 stevel eri_mif_poll(erip, MIF_POLL_STOP); 2862 0 stevel ERI_DEBUG_MSG3(erip, XCVR_MSG, 2863 4404 gd78059 "eri_intr: new MIF interrupt status %X XCVR status %X", 2864 4404 gd78059 mif_status, erip->mii_status); 2865 0 stevel (void) eri_mii_read(erip, ERI_PHY_BMSR, &stat); 2866 4404 gd78059 linkupdate = eri_mif_check(erip, stat, stat); 2867 0 stevel 2868 0 stevel #else 2869 0 stevel mif_status = GET_MIFREG(mif_bsts); 2870 0 stevel eri_mif_poll(erip, MIF_POLL_STOP); 2871 4404 gd78059 linkupdate = eri_mif_check(erip, (uint16_t)mif_status, 2872 4404 gd78059 (uint16_t)(mif_status >> 16)); 2873 0 stevel #endif 2874 0 stevel eri_mif_poll(erip, MIF_POLL_START); 2875 0 stevel mutex_exit(&erip->xcvrlock); 2876 0 stevel mutex_exit(&erip->xmitlock); 2877 0 stevel 2878 0 stevel if (!erip->openloop_autoneg) 2879 0 stevel eri_start_timer(erip, eri_check_link, 2880 4404 gd78059 ERI_LINKCHECK_TIMER); 2881 0 stevel else 2882 0 stevel eri_start_timer(erip, eri_check_link, 2883 4404 gd78059 ERI_P_FAULT_TIMER); 2884 0 stevel } 2885 0 stevel 2886 0 stevel ERI_DEBUG_MSG2(erip, INTR_MSG, 2887 4404 gd78059 "eri_intr:May have Read Interrupt status:status %X", erisbits); 2888 0 stevel 2889 0 stevel rx_done_int: 2890 0 stevel if ((erisbits & (ERI_G_STATUS_TX_INT_ME)) || 2891 0 stevel (erip->tx_cur_cnt >= tx_interrupt_rate)) { 2892 0 stevel mutex_enter(&erip->xmitlock); 2893 0 stevel erip->tx_completion = (uint32_t)(GET_ETXREG(tx_completion) & 2894 0 stevel ETX_COMPLETION_MASK); 2895 0 stevel 2896 4404 gd78059 macupdate |= eri_reclaim(erip, erip->tx_completion); 2897 10306 Vitezslav if (macupdate) 2898 10306 Vitezslav erip->wantw = B_FALSE; 2899 10306 Vitezslav 2900 0 stevel mutex_exit(&erip->xmitlock); 2901 0 stevel } 2902 0 stevel 2903 0 stevel if (erisbits & ERI_G_STATUS_RX_DONE) { 2904 0 stevel volatile struct rmd *rmdp, *rmdpbase; 2905 0 stevel volatile uint32_t rmdi; 2906 0 stevel uint8_t loop_limit = 0x20; 2907 0 stevel uint64_t flags; 2908 0 stevel uint32_t rmdmax_mask = erip->rmdmax_mask; 2909 0 stevel 2910 0 stevel rmdpbase = erip->rmdp; 2911 0 stevel rmdi = erip->rx_completion; 2912 0 stevel rmdp = rmdpbase + rmdi; 2913 0 stevel 2914 0 stevel /* 2915 0 stevel * Sync RMD before looking at it. 2916 0 stevel */ 2917 0 stevel ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), 2918 4404 gd78059 DDI_DMA_SYNC_FORCPU); 2919 0 stevel /* 2920 0 stevel * Loop through each RMD. 2921 0 stevel */ 2922 0 stevel 2923 0 stevel flags = GET_RMD_FLAGS(rmdp); 2924 0 stevel while (((flags & ERI_RMD_OWN) == 0) && (loop_limit)) { 2925 0 stevel /* process one packet */ 2926 4404 gd78059 mp = eri_read_dma(erip, rmdp, rmdi, flags); 2927 0 stevel rmdi = (rmdi + 1) & rmdmax_mask; 2928 0 stevel rmdp = rmdpbase + rmdi; 2929 4404 gd78059 2930 4404 gd78059 if (mp != NULL) { 2931 4404 gd78059 *tail = mp; 2932 4404 gd78059 tail = &mp->b_next; 2933 4404 gd78059 } 2934 0 stevel 2935 0 stevel /* 2936 0 stevel * ERI RCV DMA fetches or updates four descriptors 2937 0 stevel * a time. Also we don't want to update the desc. 2938 0 stevel * batch we just received packet on. So we update 2939 0 stevel * descriptors for every 4 packets and we update 2940 0 stevel * the group of 4 after the current batch. 2941 0 stevel */ 2942 0 stevel 2943 0 stevel if (!(rmdi % 4)) { 2944 0 stevel if (eri_overflow_reset && 2945 0 stevel (GET_GLOBREG(status_alias) & 2946 0 stevel ERI_G_STATUS_NONFATAL_ERR)) { 2947 0 stevel loop_limit = 1; 2948 0 stevel } else { 2949 0 stevel erip->rx_kick = 2950 4404 gd78059 (rmdi + ERI_RPENDING - 4) & 2951 4404 gd78059 rmdmax_mask; 2952 0 stevel PUT_ERXREG(rx_kick, erip->rx_kick); 2953 0 stevel } 2954 0 stevel } 2955 0 stevel 2956 0 stevel /* 2957 0 stevel * Sync the next RMD before looking at it. 2958 0 stevel */ 2959 0 stevel ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd), 2960 4404 gd78059 DDI_DMA_SYNC_FORCPU); 2961 0 stevel flags = GET_RMD_FLAGS(rmdp); 2962 0 stevel loop_limit--; 2963 0 stevel } 2964 0 stevel erip->rx_completion = rmdi; 2965 0 stevel } 2966 4404 gd78059 2967 4404 gd78059 mutex_exit(&erip->intrlock); 2968 4404 gd78059 2969 4404 gd78059 if (head) 2970 4404 gd78059 mac_rx(erip->mh, NULL, head); 2971 4404 gd78059 2972 4404 gd78059 if (macupdate) 2973 4404 gd78059 mac_tx_update(erip->mh); 2974 4404 gd78059 2975 4404 gd78059 if (linkupdate != LINK_STATE_UNKNOWN) 2976 4404 gd78059 mac_link_update(erip->mh, linkupdate); 2977 0 stevel 2978 0 stevel return (serviced); 2979 0 stevel } 2980 0 stevel 2981 0 stevel /* 2982 0 stevel * Handle interrupts for fatal errors 2983 0 stevel * Need reinitialization. 2984 0 stevel */ 2985 0 stevel #define PCI_DATA_PARITY_REP (1 << 8) 2986 0 stevel #define PCI_SING_TARGET_ABORT (1 << 11) 2987 0 stevel #define PCI_RCV_TARGET_ABORT (1 << 12) 2988 0 stevel #define PCI_RCV_MASTER_ABORT (1 << 13) 2989 0 stevel #define PCI_SING_SYSTEM_ERR (1 << 14) 2990 0 stevel #define PCI_DATA_PARITY_ERR (1 << 15) 2991 0 stevel 2992 0 stevel /* called with intrlock held */ 2993 0 stevel static void 2994 0 stevel eri_fatal_err(struct eri *erip, uint32_t erisbits) 2995 0 stevel { 2996 0 stevel uint16_t pci_status; 2997 0 stevel uint32_t pci_error_int = 0; 2998 0 stevel 2999 0 stevel if (erisbits & ERI_G_STATUS_RX_TAG_ERR) { 3000 0 stevel erip->rx_reset_issued = 1; 3001 0 stevel HSTAT(erip, rxtag_err); 3002 0 stevel } else { 3003 0 stevel erip->global_reset_issued = 1; 3004 0 stevel if (erisbits & ERI_G_STATUS_BUS_ERR_INT) { 3005 0 stevel pci_error_int = 1; 3006 0 stevel HSTAT(erip, pci_error_int); 3007 0 stevel } else if (erisbits & ERI_G_STATUS_PERR_INT) { 3008 0 stevel HSTAT(erip, parity_error); 3009 0 stevel } else { 3010 0 stevel HSTAT(erip, unknown_fatal); 3011 0 stevel } 3012 0 stevel } 3013 0 stevel 3014 0 stevel /* 3015 0 stevel * PCI bus error 3016 0 stevel */ 3017 0 stevel if (pci_error_int && erip->pci_config_handle) { 3018 0 stevel pci_status = pci_config_get16(erip->pci_config_handle, 3019 4404 gd78059 PCI_CONF_STAT); 3020 4404 gd78059 ERI_DEBUG_MSG2(erip, FATAL_ERR_MSG, "Bus Error Status %x", 3021 4404 gd78059 pci_status); 3022 0 stevel if (pci_status & PCI_DATA_PARITY_REP) 3023 0 stevel HSTAT(erip, pci_data_parity_err); 3024 0 stevel if (pci_status & PCI_SING_TARGET_ABORT) 3025 0 stevel HSTAT(erip, pci_signal_target_abort); 3026 0 stevel if (pci_status & PCI_RCV_TARGET_ABORT) 3027 0 stevel HSTAT(erip, pci_rcvd_target_abort); 3028 0 stevel if (pci_status & PCI_RCV_MASTER_ABORT) 3029 0 stevel HSTAT(erip, pci_rcvd_master_abort); 3030 0 stevel if (pci_status & PCI_SING_SYSTEM_ERR) 3031 0 stevel HSTAT(erip, pci_signal_system_err); 3032 0 stevel if (pci_status & PCI_DATA_PARITY_ERR) 3033 0 stevel HSTAT(erip, pci_signal_system_err); 3034 0 stevel /* 3035 0 stevel * clear it by writing the value that was read back. 3036 0 stevel */ 3037 4404 gd78059 pci_config_put16(erip->pci_config_handle, PCI_CONF_STAT, 3038 4404 gd78059 pci_status); 3039 0 stevel } 3040 0 stevel } 3041 0 stevel 3042 0 stevel /* 3043 0 stevel * Handle interrupts regarding non-fatal events. 3044 0 stevel * TXMAC, RXMAC and MACCTL events 3045 0 stevel */ 3046 0 stevel static void 3047 0 stevel eri_nonfatal_err(struct eri *erip, uint32_t erisbits) 3048 0 stevel { 3049 0 stevel 3050 0 stevel uint32_t txmac_sts, rxmac_sts, macctl_sts, pause_time; 3051 0 stevel 3052 0 stevel #ifdef ERI_PM_WORKAROUND 3053 0 stevel if (pci_report_pmcap(erip->dip, PCI_PM_IDLESPEED, 3054 0 stevel PCI_PM_IDLESPEED_NONE) == DDI_SUCCESS) 3055 0 stevel erip->stats.pmcap = ERI_PMCAP_NONE; 3056 0 stevel #endif 3057 0 stevel 3058 0 stevel if (erisbits & ERI_G_STATUS_TX_MAC_INT) { 3059 0 stevel txmac_sts = GET_MACREG(txsts); 3060 0 stevel if (txmac_sts & BMAC_TXSTS_TX_URUN) { 3061 0 stevel erip->linkcheck = 1; 3062 0 stevel HSTAT(erip, txmac_urun); 3063 0 stevel HSTAT(erip, oerrors); 3064 0 stevel } 3065 0 stevel 3066 0 stevel if (txmac_sts & BMAC_TXSTS_MAXPKT_ERR) { 3067 0 stevel erip->linkcheck = 1; 3068 0 stevel HSTAT(erip, txmac_maxpkt_err); 3069 0 stevel HSTAT(erip, oerrors); 3070 0 stevel } 3071 0 stevel if (txmac_sts & BMAC_TXSTS_NCC_EXP) { 3072 0 stevel erip->stats.collisions += 0x10000; 3073 0 stevel } 3074 0 stevel 3075 0 stevel if (txmac_sts & BMAC_TXSTS_ECC_EXP) { 3076 0 stevel erip->stats.excessive_coll += 0x10000; 3077 0 stevel } 3078 0 stevel 3079 0 stevel if (txmac_sts & BMAC_TXSTS_LCC_EXP) { 3080 0 stevel erip->stats.late_coll += 0x10000; 3081 0 stevel } 3082 0 stevel 3083 0 stevel if (txmac_sts & BMAC_TXSTS_FCC_EXP) { 3084 0 stevel erip->stats.first_coll += 0x10000; 3085 0 stevel } 3086 0 stevel 3087 0 stevel if (txmac_sts & BMAC_TXSTS_DEFER_EXP) { 3088 0 stevel HSTAT(erip, defer_timer_exp); 3089 0 stevel } 3090 0 stevel 3091 0 stevel if (txmac_sts & BMAC_TXSTS_PEAK_EXP) { 3092 0 stevel erip->stats.peak_attempt_cnt += 0x100; 3093 0 stevel } 3094 0 stevel } 3095 0 stevel 3096 0 stevel if (erisbits & ERI_G_STATUS_RX_NO_BUF) { 3097 4404 gd78059 ERI_DEBUG_MSG1(erip, NONFATAL_MSG, "rx dropped/no free desc"); 3098 0 stevel 3099 0 stevel if (eri_overflow_reset) 3100 0 stevel erip->linkcheck = 1; 3101 0 stevel 3102 0 stevel HSTAT(erip, no_free_rx_desc); 3103 0 stevel HSTAT(erip, ierrors); 3104 0 stevel } 3105 0 stevel if (erisbits & ERI_G_STATUS_RX_MAC_INT) { 3106 0 stevel rxmac_sts = GET_MACREG(rxsts); 3107 0 stevel if (rxmac_sts & BMAC_RXSTS_RX_OVF) { 3108 0 stevel #ifndef ERI_RMAC_HANG_WORKAROUND 3109 0 stevel eri_stop_timer(erip); /* acquire linklock */ 3110 0 stevel erip->check_rmac_hang ++; 3111 0 stevel erip->check2_rmac_hang = 0; 3112 0 stevel erip->rxfifo_wr_ptr = GET_ERXREG(rxfifo_wr_ptr); 3113 0 stevel erip->rxfifo_rd_ptr = GET_ERXREG(rxfifo_rd_ptr); 3114 0 stevel 3115 4404 gd78059 ERI_DEBUG_MSG5(erip, NONFATAL_MSG, 3116 0 stevel "overflow intr %d: %8x wr:%2x rd:%2x", 3117 0 stevel erip->check_rmac_hang, 3118 0 stevel GET_MACREG(macsm), 3119 0 stevel GET_ERXREG(rxfifo_wr_ptr), 3120 0 stevel GET_ERXREG(rxfifo_rd_ptr)); 3121 0 stevel 3122 0 stevel eri_start_timer(erip, eri_check_link, 3123