16f3e57acSmx205022 /* 247693af9Smx205022 * CDDL HEADER START 347693af9Smx205022 * 447693af9Smx205022 * The contents of this file are subject to the terms of the 547693af9Smx205022 * Common Development and Distribution License (the "License"). 647693af9Smx205022 * You may not use this file except in compliance with the License. 747693af9Smx205022 * 847693af9Smx205022 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 947693af9Smx205022 * or http://www.opensolaris.org/os/licensing. 1047693af9Smx205022 * See the License for the specific language governing permissions 1147693af9Smx205022 * and limitations under the License. 1247693af9Smx205022 * 1347693af9Smx205022 * When distributing Covered Code, include this CDDL HEADER in each 1447693af9Smx205022 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1547693af9Smx205022 * If applicable, add the following below this CDDL HEADER, with the 1647693af9Smx205022 * fields enclosed by brackets "[]" replaced with your own identifying 1747693af9Smx205022 * information: Portions Copyright [yyyy] [name of copyright owner] 1847693af9Smx205022 * 1947693af9Smx205022 * CDDL HEADER END 206f3e57acSmx205022 */ 216f3e57acSmx205022 226f3e57acSmx205022 /* 23a01a4735SWinson Wang - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2447693af9Smx205022 * Use is subject to license terms. 256f3e57acSmx205022 */ 266f3e57acSmx205022 276f3e57acSmx205022 #ifndef _SYS_NGE_H 286f3e57acSmx205022 #define _SYS_NGE_H 296f3e57acSmx205022 306f3e57acSmx205022 #ifdef __cplusplus 316f3e57acSmx205022 extern "C" { 326f3e57acSmx205022 #endif 336f3e57acSmx205022 346f3e57acSmx205022 356f3e57acSmx205022 #include <sys/types.h> 366f3e57acSmx205022 #include <sys/stream.h> 376f3e57acSmx205022 #include <sys/strsun.h> 386f3e57acSmx205022 #include <sys/strsubr.h> 396f3e57acSmx205022 #include <sys/stat.h> 406f3e57acSmx205022 #include <sys/pci.h> 416f3e57acSmx205022 #include <sys/note.h> 426f3e57acSmx205022 #include <sys/modctl.h> 436f3e57acSmx205022 #include <sys/kstat.h> 446f3e57acSmx205022 #include <sys/ethernet.h> 456f3e57acSmx205022 #include <sys/pattr.h> 466f3e57acSmx205022 #include <sys/errno.h> 476f3e57acSmx205022 #include <sys/dlpi.h> 486f3e57acSmx205022 #include <sys/devops.h> 496f3e57acSmx205022 #include <sys/debug.h> 506f3e57acSmx205022 #include <sys/conf.h> 516f3e57acSmx205022 #include <sys/callb.h> 526f3e57acSmx205022 536f3e57acSmx205022 #include <netinet/ip6.h> 546f3e57acSmx205022 556f3e57acSmx205022 #include <inet/common.h> 566f3e57acSmx205022 #include <inet/ip.h> 576f3e57acSmx205022 #include <netinet/udp.h> 586f3e57acSmx205022 #include <inet/mi.h> 596f3e57acSmx205022 #include <inet/nd.h> 606f3e57acSmx205022 616f3e57acSmx205022 #include <sys/ddi.h> 626f3e57acSmx205022 #include <sys/sunddi.h> 636f3e57acSmx205022 64da14cebeSEric Cheng #include <sys/mac_provider.h> 656f3e57acSmx205022 #include <sys/mac_ether.h> 666f3e57acSmx205022 676f3e57acSmx205022 /* 686f3e57acSmx205022 * Reconfiguring the network devices requires the net_config privilege 696f3e57acSmx205022 * in Solaris 10+. 706f3e57acSmx205022 */ 716f3e57acSmx205022 extern int secpolicy_net_config(const cred_t *, boolean_t); 726f3e57acSmx205022 736f3e57acSmx205022 #include <sys/netlb.h> 746f3e57acSmx205022 #include <sys/miiregs.h> 756f3e57acSmx205022 766f3e57acSmx205022 #include "nge_chip.h" 776f3e57acSmx205022 786f3e57acSmx205022 #define PIO_ADDR(ngep, offset) ((void *)((caddr_t)(ngep)->io_regs+(offset))) 796f3e57acSmx205022 /* 806f3e57acSmx205022 * Copy an ethernet address 816f3e57acSmx205022 */ 826f3e57acSmx205022 #define ethaddr_copy(src, dst) bcopy((src), (dst), ETHERADDRL) 836f3e57acSmx205022 #define ether_eq(a, b) (bcmp((caddr_t)(a), (caddr_t)(b), (ETHERADDRL)) == 0) 846f3e57acSmx205022 856f3e57acSmx205022 #define BIS(w, b) (((w) & (b)) ? B_TRUE : B_FALSE) 866f3e57acSmx205022 #define BIC(w, b) (((w) & (b)) ? B_FALSE : B_TRUE) 876f3e57acSmx205022 #define UPORDOWN(x) ((x) ? "up" : "down") 886f3e57acSmx205022 896f3e57acSmx205022 #define NGE_DRIVER_NAME "nge" 906f3e57acSmx205022 916f3e57acSmx205022 /* 926f3e57acSmx205022 * 'Progress' bit flags ... 936f3e57acSmx205022 */ 946f3e57acSmx205022 #define PROGRESS_CFG 0x0001 /* config space mapped */ 956f3e57acSmx205022 #define PROGRESS_REGS 0x0002 /* registers mapped */ 966f3e57acSmx205022 #define PROGRESS_BUFS 0x0004 /* registers mapped */ 976f3e57acSmx205022 #define PROGRESS_RESCHED 0x0008 /* resched softint registered */ 986f3e57acSmx205022 #define PROGRESS_FACTOTUM 0x0010 /* factotum softint registered */ 996f3e57acSmx205022 #define PROGRESS_SWINT 0x0020 /* s/w interrupt registered */ 1006f3e57acSmx205022 #define PROGRESS_INTR 0x0040 /* h/w interrupt registered */ 1016f3e57acSmx205022 /* and mutexen initialised */ 1026f3e57acSmx205022 #define PROGRESS_HWINT 0x0080 1036f3e57acSmx205022 #define PROGRESS_PHY 0x0100 /* PHY initialised */ 1046f3e57acSmx205022 #define PROGRESS_NDD 0x0200 /* NDD parameters set up */ 1056f3e57acSmx205022 #define PROGRESS_KSTATS 0x0400 /* kstats created */ 1066f3e57acSmx205022 #define PROGRESS_READY 0x0800 /* ready for work */ 1076f3e57acSmx205022 1086f3e57acSmx205022 #define NGE_HW_ERR 0x00 1096f3e57acSmx205022 #define NGE_HW_LINK 0x01 1106f3e57acSmx205022 #define NGE_HW_BM 0x02 1116f3e57acSmx205022 #define NGE_HW_RCHAN 0x03 1126f3e57acSmx205022 #define NGE_HW_TCHAN 0x04 1136f3e57acSmx205022 #define NGE_HW_ROM 0x05 1146f3e57acSmx205022 #define NGE_SW_PROBLEM_ID 0x06 1156f3e57acSmx205022 1166f3e57acSmx205022 1176f3e57acSmx205022 /* 1186f3e57acSmx205022 * NOTES: 1196f3e57acSmx205022 * 1206f3e57acSmx205022 * #defines: 1216f3e57acSmx205022 * 1226f3e57acSmx205022 * NGE_PCI_CONFIG_RNUMBER and NGE_PCI_OPREGS_RNUMBER are the 1236f3e57acSmx205022 * register-set numbers to use for the config space registers 1246f3e57acSmx205022 * and the operating registers respectively. On an OBP-based 1256f3e57acSmx205022 * machine, regset 0 refers to CONFIG space, and regset 1 will 1266f3e57acSmx205022 * be the operating registers in MEMORY space. If an expansion 1276f3e57acSmx205022 * ROM is fitted, it may appear as a further register set. 1286f3e57acSmx205022 * 1296f3e57acSmx205022 * NGE_DMA_MODE defines the mode (STREAMING/CONSISTENT) used 1306f3e57acSmx205022 * for the data buffers. The descriptors are always set up 1316f3e57acSmx205022 * in CONSISTENT mode. 1326f3e57acSmx205022 * 1336f3e57acSmx205022 * NGE_HEADROOM defines how much space we'll leave in allocated 1346f3e57acSmx205022 * mblks before the first valid data byte. This should be chosen 1356f3e57acSmx205022 * to be 2 modulo 4, so that once the ethernet header (14 bytes) 1366f3e57acSmx205022 * has been stripped off, the packet data will be 4-byte aligned. 1376f3e57acSmx205022 * The remaining space can be used by upstream modules to prepend 1386f3e57acSmx205022 * any headers required. 1396f3e57acSmx205022 */ 1406f3e57acSmx205022 1416f3e57acSmx205022 1426f3e57acSmx205022 #define NGE_PCI_OPREGS_RNUMBER 1 1436f3e57acSmx205022 #define NGE_DMA_MODE DDI_DMA_STREAMING 1446f3e57acSmx205022 #define NGE_HEADROOM 6 1456f3e57acSmx205022 #define ETHER_HEAD_LEN 14 1466f3e57acSmx205022 #ifndef VTAG_SIZE 1476f3e57acSmx205022 #define VTAG_SIZE 4 1486f3e57acSmx205022 #endif 1496f3e57acSmx205022 150*51fc88a8SWinson Wang - Sun Microsystems - Beijing China #define NGE_CYCLIC_PERIOD (1000000000) 1516f3e57acSmx205022 1526f3e57acSmx205022 #define NGE_DEFAULT_MTU 1500 1536f3e57acSmx205022 #define NGE_DEFAULT_SDU 1518 1546f3e57acSmx205022 #define NGE_MTU_2500 2500 1556f3e57acSmx205022 #define NGE_MTU_4500 4500 1566f3e57acSmx205022 #define NGE_MAX_MTU 9000 1576f3e57acSmx205022 #define NGE_MAX_SDU 9018 1586f3e57acSmx205022 15902d51d0dSjj146644 #define NGE_DESC_MIN 0x200 1606f3e57acSmx205022 1616f3e57acSmx205022 #define NGE_STD_BUFSZ 1792 1626f3e57acSmx205022 #define NGE_JB2500_BUFSZ (3*1024) 1636f3e57acSmx205022 #define NGE_JB4500_BUFSZ (5*1024) 1646f3e57acSmx205022 #define NGE_JB9000_BUFSZ (9*1024) 1656f3e57acSmx205022 1666f3e57acSmx205022 #define NGE_SEND_SLOTS_DESC_1024 1024 1676f3e57acSmx205022 #define NGE_SEND_SLOTS_DESC_3072 3072 1686f3e57acSmx205022 #define NGE_SEND_JB2500_SLOTS_DESC 3072 1696f3e57acSmx205022 #define NGE_SEND_JB4500_SLOTS_DESC 2048 1706f3e57acSmx205022 #define NGE_SEND_JB9000_SLOTS_DESC 1024 1716f3e57acSmx205022 #define NGE_SEND_LOWMEM_SLOTS_DESC 1024 1726f3e57acSmx205022 #define NGE_SEND_SLOTS_BUF 3072 1736f3e57acSmx205022 1746f3e57acSmx205022 #define NGE_RECV_SLOTS_DESC_1024 1024 1756f3e57acSmx205022 #define NGE_RECV_SLOTS_DESC_3072 3072 1766f3e57acSmx205022 #define NGE_RECV_JB2500_SLOTS_DESC 3072 1776f3e57acSmx205022 #define NGE_RECV_JB4500_SLOTS_DESC 2048 1786f3e57acSmx205022 #define NGE_RECV_JB9000_SLOTS_DESC 1024 1796f3e57acSmx205022 #define NGE_RECV_LOWMEM_SLOTS_DESC 1024 1806f3e57acSmx205022 #define NGE_RECV_SLOTS_BUF 6144 1816f3e57acSmx205022 1826f3e57acSmx205022 #define NGE_SPLIT_32 32 1836f3e57acSmx205022 #define NGE_SPLIT_96 96 1846f3e57acSmx205022 #define NGE_SPLIT_256 256 1856f3e57acSmx205022 1866f3e57acSmx205022 #define NGE_RX_COPY_SIZE 512 1876f3e57acSmx205022 #define NGE_TX_COPY_SIZE 512 1886f3e57acSmx205022 #define NGE_MAP_FRAGS 3 1896f3e57acSmx205022 #define NGE_MAX_COOKIES 3 1906f3e57acSmx205022 #define NGE_MAX_DMA_HDR (4*1024) 1916f3e57acSmx205022 19202d51d0dSjj146644 /* Used by interrupt moderation */ 193*51fc88a8SWinson Wang - Sun Microsystems - Beijing China #define NGE_TFINT_DEFAULT 32 194*51fc88a8SWinson Wang - Sun Microsystems - Beijing China #define NGE_POLL_TUNE 80000 195*51fc88a8SWinson Wang - Sun Microsystems - Beijing China #define NGE_POLL_ENTER 10000 196*51fc88a8SWinson Wang - Sun Microsystems - Beijing China #define NGE_POLL_MAX 1280000 19702d51d0dSjj146644 #define NGE_POLL_QUIET_TIME 100 19802d51d0dSjj146644 #define NGE_POLL_BUSY_TIME 2 1996f3e57acSmx205022 2006f3e57acSmx205022 /* 2016f3e57acSmx205022 * NGE-specific ioctls ... 2026f3e57acSmx205022 */ 2036f3e57acSmx205022 #define NGE_IOC ((((('N' << 8) + 'G') << 8) + 'E') << 8) 2046f3e57acSmx205022 2056f3e57acSmx205022 /* 2066f3e57acSmx205022 * PHY register read/write ioctls, used by cable test software 2076f3e57acSmx205022 */ 2086f3e57acSmx205022 #define NGE_MII_READ (NGE_IOC|1) 2096f3e57acSmx205022 #define NGE_MII_WRITE (NGE_IOC|2) 2106f3e57acSmx205022 2116f3e57acSmx205022 /* 2126f3e57acSmx205022 * SEEPROM read/write ioctls, for use by SEEPROM upgrade utility 2136f3e57acSmx205022 * 2146f3e57acSmx205022 * Note: SEEPROMs can only be accessed as 32-bit words, so <see_addr> 2156f3e57acSmx205022 * must be a multiple of 4. Not all systems have a SEEPROM fitted! 2166f3e57acSmx205022 */ 2176f3e57acSmx205022 #define NGE_SEE_READ (NGE_IOC|3) 2186f3e57acSmx205022 #define NGE_SEE_WRITE (NGE_IOC|4) 2196f3e57acSmx205022 2206f3e57acSmx205022 2216f3e57acSmx205022 /* 2226f3e57acSmx205022 * These diagnostic IOCTLS are enabled only in DEBUG drivers 2236f3e57acSmx205022 */ 2246f3e57acSmx205022 #define NGE_DIAG (NGE_IOC|5) /* currently a no-op */ 2256f3e57acSmx205022 #define NGE_PEEK (NGE_IOC|6) 2266f3e57acSmx205022 #define NGE_POKE (NGE_IOC|7) 2276f3e57acSmx205022 #define NGE_PHY_RESET (NGE_IOC|8) 2286f3e57acSmx205022 #define NGE_SOFT_RESET (NGE_IOC|9) 2296f3e57acSmx205022 #define NGE_HARD_RESET (NGE_IOC|10) 2306f3e57acSmx205022 2316f3e57acSmx205022 2326f3e57acSmx205022 enum NGE_HW_OP { 2336f3e57acSmx205022 NGE_CLEAR = 0, 2346f3e57acSmx205022 NGE_SET 2356f3e57acSmx205022 }; 2366f3e57acSmx205022 2376f3e57acSmx205022 /* 2386f3e57acSmx205022 * Required state according to GLD 2396f3e57acSmx205022 */ 2406f3e57acSmx205022 enum nge_mac_state { 2416f3e57acSmx205022 NGE_MAC_UNKNOWN, 2426f3e57acSmx205022 NGE_MAC_RESET, 2436f3e57acSmx205022 NGE_MAC_STOPPED, 2446f3e57acSmx205022 NGE_MAC_STARTED, 2456f3e57acSmx205022 NGE_MAC_UNATTACH 2466f3e57acSmx205022 }; 2476f3e57acSmx205022 enum loop_type { 2486f3e57acSmx205022 NGE_LOOP_NONE = 0, 2496f3e57acSmx205022 NGE_LOOP_EXTERNAL_100, 2506f3e57acSmx205022 NGE_LOOP_EXTERNAL_10, 2516f3e57acSmx205022 NGE_LOOP_INTERNAL_PHY, 2526f3e57acSmx205022 }; 2536f3e57acSmx205022 2546f3e57acSmx205022 /* 2556f3e57acSmx205022 * (Internal) return values from send_msg subroutines 2566f3e57acSmx205022 */ 2576f3e57acSmx205022 enum send_status { 2586f3e57acSmx205022 SEND_COPY_FAIL = -1, /* => GLD_NORESOURCES */ 2596f3e57acSmx205022 SEND_MAP_FAIL, /* => GLD_NORESOURCES */ 2606f3e57acSmx205022 SEND_COPY_SUCESS, /* OK, msg queued */ 2616f3e57acSmx205022 SEND_MAP_SUCCESS /* OK, free msg */ 2626f3e57acSmx205022 }; 2636f3e57acSmx205022 2646f3e57acSmx205022 /* 2656f3e57acSmx205022 * (Internal) return values from ioctl subroutines 2666f3e57acSmx205022 */ 2676f3e57acSmx205022 enum ioc_reply { 2686f3e57acSmx205022 IOC_INVAL = -1, /* bad, NAK with EINVAL */ 2696f3e57acSmx205022 IOC_DONE, /* OK, reply sent */ 2706f3e57acSmx205022 IOC_ACK, /* OK, just send ACK */ 2716f3e57acSmx205022 IOC_REPLY, /* OK, just send reply */ 2726f3e57acSmx205022 IOC_RESTART_ACK, /* OK, restart & ACK */ 2736f3e57acSmx205022 IOC_RESTART_REPLY /* OK, restart & reply */ 2746f3e57acSmx205022 }; 2756f3e57acSmx205022 2766f3e57acSmx205022 enum nge_pp_type { 2776f3e57acSmx205022 NGE_PP_SPACE_CFG = 0, 2786f3e57acSmx205022 NGE_PP_SPACE_REG, 2796f3e57acSmx205022 NGE_PP_SPACE_NIC, 2806f3e57acSmx205022 NGE_PP_SPACE_MII, 2816f3e57acSmx205022 NGE_PP_SPACE_NGE, 2826f3e57acSmx205022 NGE_PP_SPACE_TXDESC, 2836f3e57acSmx205022 NGE_PP_SPACE_TXBUFF, 2846f3e57acSmx205022 NGE_PP_SPACE_RXDESC, 2856f3e57acSmx205022 NGE_PP_SPACE_RXBUFF, 2866f3e57acSmx205022 NGE_PP_SPACE_STATISTICS, 2876f3e57acSmx205022 NGE_PP_SPACE_SEEPROM, 2886f3e57acSmx205022 NGE_PP_SPACE_FLASH 2896f3e57acSmx205022 }; 2906f3e57acSmx205022 2916f3e57acSmx205022 /* 2926f3e57acSmx205022 * Flag to kstat type 2936f3e57acSmx205022 */ 2946f3e57acSmx205022 enum nge_kstat_type { 2956f3e57acSmx205022 NGE_KSTAT_RAW = 0, 2966f3e57acSmx205022 NGE_KSTAT_STATS, 2976f3e57acSmx205022 NGE_KSTAT_CHIPID, 2986f3e57acSmx205022 NGE_KSTAT_DEBUG, 2996f3e57acSmx205022 NGE_KSTAT_COUNT 3006f3e57acSmx205022 }; 3016f3e57acSmx205022 3026f3e57acSmx205022 3036f3e57acSmx205022 /* 3046f3e57acSmx205022 * Actual state of the nvidia's chip 3056f3e57acSmx205022 */ 3066f3e57acSmx205022 enum nge_chip_state { 3076f3e57acSmx205022 NGE_CHIP_FAULT = -2, /* fault, need reset */ 3086f3e57acSmx205022 NGE_CHIP_ERROR, /* error, want reset */ 3096f3e57acSmx205022 NGE_CHIP_INITIAL, /* Initial state only */ 3106f3e57acSmx205022 NGE_CHIP_RESET, /* reset, need init */ 3116f3e57acSmx205022 NGE_CHIP_STOPPED, /* Tx/Rx stopped */ 3126f3e57acSmx205022 NGE_CHIP_RUNNING /* with interrupts */ 3136f3e57acSmx205022 }; 3146f3e57acSmx205022 3156f3e57acSmx205022 enum nge_eeprom_size { 3166f3e57acSmx205022 EEPROM_1K = 0, 3176f3e57acSmx205022 EEPROM_2K, 3186f3e57acSmx205022 EEPROM_4K, 3196f3e57acSmx205022 EEPROM_8K, 3206f3e57acSmx205022 EEPROM_16K, 3216f3e57acSmx205022 EEPROM_32K, 3226f3e57acSmx205022 EEPROM_64K 3236f3e57acSmx205022 }; 3246f3e57acSmx205022 3256f3e57acSmx205022 enum nge_eeprom_access_wid { 3266f3e57acSmx205022 ACCESS_8BIT = 0, 3276f3e57acSmx205022 ACCESS_16BIT 3286f3e57acSmx205022 }; 3296f3e57acSmx205022 3306f3e57acSmx205022 /* 3316f3e57acSmx205022 * MDIO operation 3326f3e57acSmx205022 */ 3336f3e57acSmx205022 enum nge_mdio_operation { 3346f3e57acSmx205022 NGE_MDIO_READ = 0, 3356f3e57acSmx205022 NGE_MDIO_WRITE 3366f3e57acSmx205022 }; 3376f3e57acSmx205022 3386f3e57acSmx205022 /* 3396f3e57acSmx205022 * Speed selection 3406f3e57acSmx205022 */ 3416f3e57acSmx205022 enum nge_speed { 3426f3e57acSmx205022 UNKOWN_SPEED = 0, 3436f3e57acSmx205022 NGE_10M, 3446f3e57acSmx205022 NGE_100M, 3456f3e57acSmx205022 NGE_1000M 3466f3e57acSmx205022 }; 3476f3e57acSmx205022 3486f3e57acSmx205022 /* 3496f3e57acSmx205022 * Duplex selection 3506f3e57acSmx205022 */ 3516f3e57acSmx205022 enum nge_duplex { 3526f3e57acSmx205022 UNKOWN_DUPLEX = 0, 3536f3e57acSmx205022 NGE_HD, 3546f3e57acSmx205022 NGE_FD 3556f3e57acSmx205022 }; 3566f3e57acSmx205022 3576f3e57acSmx205022 typedef struct { 3586f3e57acSmx205022 ether_addr_t addr; /* in canonical form */ 3596f3e57acSmx205022 uint8_t spare; 3606f3e57acSmx205022 uint8_t set; /* nonzero => valid */ 3616f3e57acSmx205022 } nge_mac_addr_t; 3626f3e57acSmx205022 3636f3e57acSmx205022 struct nge; 3646f3e57acSmx205022 3656f3e57acSmx205022 3666f3e57acSmx205022 #define CHIP_FLAG_COPPER 0x40 3676f3e57acSmx205022 3686f3e57acSmx205022 /* 3696f3e57acSmx205022 * Collection of physical-layer functions to: 3706f3e57acSmx205022 * (re)initialise the physical layer 3716f3e57acSmx205022 * update it to match software settings 3726f3e57acSmx205022 * check for link status change 3736f3e57acSmx205022 */ 3746f3e57acSmx205022 typedef struct { 375c322ff79Smx205022 boolean_t (*phys_restart)(struct nge *); 3766f3e57acSmx205022 void (*phys_update)(struct nge *); 3776f3e57acSmx205022 boolean_t (*phys_check)(struct nge *); 3786f3e57acSmx205022 } phys_ops_t; 3796f3e57acSmx205022 3806f3e57acSmx205022 struct nge_see_rw { 3816f3e57acSmx205022 uint32_t see_addr; /* Byte offset within SEEPROM */ 3826f3e57acSmx205022 uint32_t see_data; /* Data read/data to write */ 3836f3e57acSmx205022 }; 3846f3e57acSmx205022 3856f3e57acSmx205022 typedef struct { 3866f3e57acSmx205022 uint64_t pp_acc_size; /* in bytes: 1,2,4,8 */ 3876f3e57acSmx205022 uint64_t pp_acc_space; /* See #defines below */ 3886f3e57acSmx205022 uint64_t pp_acc_offset; 3896f3e57acSmx205022 uint64_t pp_acc_data; /* output for peek */ 3906f3e57acSmx205022 /* input for poke */ 3916f3e57acSmx205022 } nge_peekpoke_t; 3926f3e57acSmx205022 3936f3e57acSmx205022 typedef uintptr_t nge_regno_t; /* register # (offset) */ 3946f3e57acSmx205022 3956f3e57acSmx205022 typedef struct _mul_list { 3966f3e57acSmx205022 struct _mul_list *next; 3976f3e57acSmx205022 uint32_t ref_cnt; 3986f3e57acSmx205022 ether_addr_t mul_addr; 3996f3e57acSmx205022 }mul_item, *pmul_item; 4006f3e57acSmx205022 4016f3e57acSmx205022 /* 4026f3e57acSmx205022 * Describes one chunk of allocated DMA-able memory 4036f3e57acSmx205022 * 4046f3e57acSmx205022 * In some cases, this is a single chunk as allocated from the system; 4056f3e57acSmx205022 * but we also use this structure to represent slices carved off such 4066f3e57acSmx205022 * a chunk. Even when we don't really need all the information, we 4076f3e57acSmx205022 * use this structure as a convenient way of correlating the various 4086f3e57acSmx205022 * ways of looking at a piece of memory (kernel VA, IO space DVMA, 4096f3e57acSmx205022 * handle+offset, etc). 4106f3e57acSmx205022 */ 4116f3e57acSmx205022 typedef struct dma_area 4126f3e57acSmx205022 { 4136f3e57acSmx205022 4146f3e57acSmx205022 caddr_t private; /* pointer to nge */ 4156f3e57acSmx205022 frtn_t rx_recycle; /* recycle function */ 4166f3e57acSmx205022 mblk_t *mp; 4176f3e57acSmx205022 ddi_acc_handle_t acc_hdl; /* handle for memory */ 4186f3e57acSmx205022 void *mem_va; /* CPU VA of memory */ 4196f3e57acSmx205022 uint32_t nslots; /* number of slots */ 4206f3e57acSmx205022 uint32_t size; /* size per slot */ 4216f3e57acSmx205022 size_t alength; /* allocated size */ 4226f3e57acSmx205022 /* >= product of above */ 4236f3e57acSmx205022 ddi_dma_handle_t dma_hdl; /* DMA handle */ 4246f3e57acSmx205022 offset_t offset; /* relative to handle */ 4256f3e57acSmx205022 ddi_dma_cookie_t cookie; /* associated cookie */ 4266f3e57acSmx205022 uint32_t ncookies; 4276f3e57acSmx205022 uint32_t signature; /* buffer signature */ 4286f3e57acSmx205022 /* for deciding to free */ 4296f3e57acSmx205022 /* or to reuse buffers */ 4306f3e57acSmx205022 boolean_t rx_delivered; /* hold by upper layer */ 4316f3e57acSmx205022 struct dma_area *next; 4326f3e57acSmx205022 } dma_area_t; 4336f3e57acSmx205022 4346f3e57acSmx205022 #define HOST_OWN 0x00000000 4356f3e57acSmx205022 #define CONTROLER_OWN 0x00000001 4366f3e57acSmx205022 #define NGE_END_PACKET 0x00000002 4376f3e57acSmx205022 4386f3e57acSmx205022 4396f3e57acSmx205022 typedef struct nge_dmah_node 4406f3e57acSmx205022 { 4416f3e57acSmx205022 struct nge_dmah_node *next; 4426f3e57acSmx205022 ddi_dma_handle_t hndl; 4436f3e57acSmx205022 } nge_dmah_node_t; 4446f3e57acSmx205022 4456f3e57acSmx205022 typedef struct nge_dmah_list 4466f3e57acSmx205022 { 4476f3e57acSmx205022 nge_dmah_node_t *head; 4486f3e57acSmx205022 nge_dmah_node_t *tail; 4496f3e57acSmx205022 } nge_dmah_list_t; 4506f3e57acSmx205022 4516f3e57acSmx205022 /* 4526f3e57acSmx205022 * Software version of the Recv Descriptor 4536f3e57acSmx205022 * There's one of these for each recv buffer (up to 512 per ring) 4546f3e57acSmx205022 */ 4556f3e57acSmx205022 typedef struct sw_rx_sbd { 4566f3e57acSmx205022 4576f3e57acSmx205022 dma_area_t desc; /* (const) related h/w */ 4586f3e57acSmx205022 /* descriptor area */ 4596f3e57acSmx205022 dma_area_t *bufp; /* (const) related */ 4606f3e57acSmx205022 /* buffer area */ 4616f3e57acSmx205022 uint8_t flags; 4626f3e57acSmx205022 } sw_rx_sbd_t; 4636f3e57acSmx205022 4646f3e57acSmx205022 /* 4656f3e57acSmx205022 * Software version of the send Buffer Descriptor 4666f3e57acSmx205022 * There's one of these for each send buffer (up to 512 per ring) 4676f3e57acSmx205022 */ 4686f3e57acSmx205022 typedef struct sw_tx_sbd { 4696f3e57acSmx205022 4706f3e57acSmx205022 dma_area_t desc; /* (const) related h/w */ 4716f3e57acSmx205022 /* descriptor area */ 4726f3e57acSmx205022 dma_area_t pbuf; /* (const) related */ 4736f3e57acSmx205022 /* buffer area */ 4746f3e57acSmx205022 void (*tx_recycle)(struct sw_tx_sbd *); 4756f3e57acSmx205022 uint32_t flags; 4766f3e57acSmx205022 mblk_t *mp; /* related mblk, if any */ 4776f3e57acSmx205022 nge_dmah_list_t mp_hndl; 4786f3e57acSmx205022 uint32_t frags; 4796f3e57acSmx205022 uint32_t ncookies; /* dma cookie number */ 4806f3e57acSmx205022 4816f3e57acSmx205022 } sw_tx_sbd_t; 4826f3e57acSmx205022 4836f3e57acSmx205022 /* 4846f3e57acSmx205022 * Software Receive Buffer (Producer) Ring Control Block 4856f3e57acSmx205022 * There's one of these for each receiver producer ring (up to 3), 4866f3e57acSmx205022 * but each holds buffers of a different size. 4876f3e57acSmx205022 */ 4886f3e57acSmx205022 typedef struct buff_ring { 4896f3e57acSmx205022 4906f3e57acSmx205022 uint64_t nslots; /* descriptor area */ 4916f3e57acSmx205022 struct nge *ngep; /* (const) containing */ 4926f3e57acSmx205022 /* driver soft state */ 4936f3e57acSmx205022 /* initialise same */ 4946f3e57acSmx205022 uint64_t rx_hold; 4956f3e57acSmx205022 sw_rx_sbd_t *sw_rbds; /* software descriptors */ 4966f3e57acSmx205022 sw_rx_sbd_t *free_rbds; /* free ring */ 4976f3e57acSmx205022 dma_area_t *free_list; /* available buffer queue */ 4986f3e57acSmx205022 dma_area_t *recycle_list; /* recycling buffer queue */ 4996f3e57acSmx205022 kmutex_t recycle_lock[1]; 50075675fb7Svb160487 uint32_t buf_sign; /* buffer ring signature */ 50175675fb7Svb160487 /* for deciding to free */ 50275675fb7Svb160487 /* or to reuse buffers */ 5036f3e57acSmx205022 boolean_t rx_bcopy; 5046f3e57acSmx205022 } buff_ring_t; 5056f3e57acSmx205022 5066f3e57acSmx205022 /* 5076f3e57acSmx205022 * Software Receive (Return) Ring Control Block 5086f3e57acSmx205022 * There's one of these for each receiver return ring (up to 16). 5096f3e57acSmx205022 */ 5106f3e57acSmx205022 typedef struct recv_ring { 5116f3e57acSmx205022 /* 5126f3e57acSmx205022 * The elements flagged (const) in the comments below are 5136f3e57acSmx205022 * set up once during initialiation and thereafter unchanged. 5146f3e57acSmx205022 */ 5156f3e57acSmx205022 dma_area_t desc; /* (const) related h/w */ 5166f3e57acSmx205022 /* descriptor area */ 5176f3e57acSmx205022 struct nge *ngep; /* (const) containing */ 5186f3e57acSmx205022 /* driver soft state */ 5196f3e57acSmx205022 uint16_t prod_index; /* (const) ptr to h/w */ 5206f3e57acSmx205022 /* "producer index" */ 5216f3e57acSmx205022 mac_resource_handle_t handle; 5226f3e57acSmx205022 } recv_ring_t; 5236f3e57acSmx205022 5246f3e57acSmx205022 5256f3e57acSmx205022 5266f3e57acSmx205022 /* 5276f3e57acSmx205022 * Software Send Ring Control Block 5286f3e57acSmx205022 * There's one of these for each of (up to) 1 send rings 5296f3e57acSmx205022 */ 5306f3e57acSmx205022 typedef struct send_ring { 5316f3e57acSmx205022 /* 5326f3e57acSmx205022 * The elements flagged (const) in the comments below are 5336f3e57acSmx205022 * set up once during initialiation and thereafter unchanged. 5346f3e57acSmx205022 */ 5356f3e57acSmx205022 dma_area_t desc; /* (const) related h/w */ 5366f3e57acSmx205022 /* descriptor area */ 5376f3e57acSmx205022 dma_area_t buf[NGE_SEND_SLOTS_BUF]; 5386f3e57acSmx205022 /* buffer area(s) */ 5396f3e57acSmx205022 struct nge *ngep; /* (const) containing */ 5406f3e57acSmx205022 /* driver soft state */ 5416f3e57acSmx205022 542a55f7119SMiles Xu, Sun Microsystems uint32_t tx_hwmark; 543a55f7119SMiles Xu, Sun Microsystems uint32_t tx_lwmark; 5446f3e57acSmx205022 5456f3e57acSmx205022 /* 5466f3e57acSmx205022 * The tx_lock must be held when updating 5476f3e57acSmx205022 * the s/w producer index 5486f3e57acSmx205022 * (tx_next) 5496f3e57acSmx205022 */ 5506f3e57acSmx205022 kmutex_t tx_lock[1]; /* serialize h/w update */ 551a55f7119SMiles Xu, Sun Microsystems uint32_t tx_next; /* next slot to use */ 552a55f7119SMiles Xu, Sun Microsystems uint32_t tx_flow; 5536f3e57acSmx205022 5546f3e57acSmx205022 /* 5556f3e57acSmx205022 * These counters/indexes are manipulated in the transmit 5566f3e57acSmx205022 * path using atomics rather than mutexes for speed 5576f3e57acSmx205022 */ 558a55f7119SMiles Xu, Sun Microsystems uint32_t tx_free; /* # of slots available */ 5596f3e57acSmx205022 5606f3e57acSmx205022 /* 5616f3e57acSmx205022 * index (tc_next). 5626f3e57acSmx205022 */ 5636f3e57acSmx205022 kmutex_t tc_lock[1]; 564a55f7119SMiles Xu, Sun Microsystems uint32_t tc_next; /* next slot to recycle */ 5656f3e57acSmx205022 /* ("consumer index") */ 5666f3e57acSmx205022 5676f3e57acSmx205022 sw_tx_sbd_t *sw_sbds; /* software descriptors */ 5686f3e57acSmx205022 5696f3e57acSmx205022 kmutex_t dmah_lock; 5706f3e57acSmx205022 nge_dmah_list_t dmah_free; 5716f3e57acSmx205022 nge_dmah_node_t dmahndl[NGE_MAX_DMA_HDR]; 5726f3e57acSmx205022 5736f3e57acSmx205022 } send_ring_t; 5746f3e57acSmx205022 5756f3e57acSmx205022 5766f3e57acSmx205022 typedef struct { 5776f3e57acSmx205022 uint32_t businfo; /* from private reg */ 5786f3e57acSmx205022 uint16_t command; /* saved during attach */ 5796f3e57acSmx205022 5806f3e57acSmx205022 uint16_t vendor; /* vendor-id */ 5816f3e57acSmx205022 uint16_t device; /* device-id */ 5826f3e57acSmx205022 uint16_t subven; /* subsystem-vendor-id */ 5836f3e57acSmx205022 uint16_t subdev; /* subsystem-id */ 5846f3e57acSmx205022 uint8_t class_code; 5856f3e57acSmx205022 uint8_t revision; /* revision-id */ 5866f3e57acSmx205022 uint8_t clsize; /* cache-line-size */ 5876f3e57acSmx205022 uint8_t latency; /* latency-timer */ 5886f3e57acSmx205022 uint8_t flags; 5896f3e57acSmx205022 5906f3e57acSmx205022 uint16_t phy_type; /* Fiber module type */ 5916f3e57acSmx205022 uint64_t hw_mac_addr; /* from chip register */ 5926f3e57acSmx205022 nge_mac_addr_t vendor_addr; /* transform of same */ 5936f3e57acSmx205022 } chip_info_t; 5946f3e57acSmx205022 5956f3e57acSmx205022 5966f3e57acSmx205022 typedef struct { 5976f3e57acSmx205022 offset_t index; 5986f3e57acSmx205022 char *name; 5996f3e57acSmx205022 } nge_ksindex_t; 6006f3e57acSmx205022 6016f3e57acSmx205022 typedef struct { 6026f3e57acSmx205022 uint64_t tso_err_mss; 6036f3e57acSmx205022 uint64_t tso_dis; 6046f3e57acSmx205022 uint64_t tso_err_nosum; 6056f3e57acSmx205022 uint64_t tso_err_hov; 6066f3e57acSmx205022 uint64_t tso_err_huf; 6076f3e57acSmx205022 uint64_t tso_err_l2; 6086f3e57acSmx205022 uint64_t tso_err_ip; 6096f3e57acSmx205022 uint64_t tso_err_l4; 6106f3e57acSmx205022 uint64_t tso_err_tcp; 6116f3e57acSmx205022 uint64_t hsum_err_ip; 6126f3e57acSmx205022 uint64_t hsum_err_l4; 6136f3e57acSmx205022 }fe_statistics_t; 6146f3e57acSmx205022 6156f3e57acSmx205022 /* 6166f3e57acSmx205022 * statistics parameters to tune the driver 6176f3e57acSmx205022 */ 6186f3e57acSmx205022 typedef struct { 6196f3e57acSmx205022 uint64_t intr_count; 6206f3e57acSmx205022 uint64_t intr_lval; 6216f3e57acSmx205022 uint64_t recv_realloc; 6226f3e57acSmx205022 uint64_t poll_time; 6236f3e57acSmx205022 uint64_t recy_free; 6246f3e57acSmx205022 uint64_t recv_count; 6256f3e57acSmx205022 uint64_t xmit_count; 6266f3e57acSmx205022 uint64_t obytes; 6276f3e57acSmx205022 uint64_t rbytes; 6286f3e57acSmx205022 uint64_t mp_alloc_err; 6296f3e57acSmx205022 uint64_t dma_alloc_err; 6306f3e57acSmx205022 uint64_t kmem_alloc_err; 6316f3e57acSmx205022 uint64_t load_context; 6326f3e57acSmx205022 uint64_t ip_hwsum_err; 6336f3e57acSmx205022 uint64_t tcp_hwsum_err; 6346f3e57acSmx205022 uint64_t rx_nobuffer; 6356f3e57acSmx205022 uint64_t rx_err; 6366f3e57acSmx205022 uint64_t tx_stop_err; 6376f3e57acSmx205022 uint64_t tx_stall; 6386f3e57acSmx205022 uint64_t tx_rsrv_fail; 6396f3e57acSmx205022 uint64_t tx_resched; 6406f3e57acSmx205022 fe_statistics_t fe_err; 6416f3e57acSmx205022 }nge_sw_statistics_t; 6426f3e57acSmx205022 6436f3e57acSmx205022 typedef struct { 6446f3e57acSmx205022 nge_hw_statistics_t hw_statistics; 6456f3e57acSmx205022 nge_sw_statistics_t sw_statistics; 6466f3e57acSmx205022 }nge_statistics_t; 6476f3e57acSmx205022 6486f3e57acSmx205022 struct nge_desc_attr { 6496f3e57acSmx205022 6506f3e57acSmx205022 size_t rxd_size; 6516f3e57acSmx205022 size_t txd_size; 6526f3e57acSmx205022 6536f3e57acSmx205022 ddi_dma_attr_t *dma_attr; 6546f3e57acSmx205022 ddi_dma_attr_t *tx_dma_attr; 6556f3e57acSmx205022 6566f3e57acSmx205022 void (*rxd_fill)(void *, const ddi_dma_cookie_t *, size_t); 6576f3e57acSmx205022 uint32_t (*rxd_check)(const void *, size_t *); 6586f3e57acSmx205022 6596f3e57acSmx205022 void (*txd_fill)(void *, const ddi_dma_cookie_t *, size_t, 660*51fc88a8SWinson Wang - Sun Microsystems - Beijing China uint32_t, boolean_t, boolean_t); 6616f3e57acSmx205022 6629fa05d92SWinson Wang - Sun Microsystems - Beijing China uint32_t (*txd_check)(const void *); 6636f3e57acSmx205022 }; 6646f3e57acSmx205022 6656f3e57acSmx205022 typedef struct nge_desc_attr nge_desc_attr_t; 6666f3e57acSmx205022 6676f3e57acSmx205022 /* 6686f3e57acSmx205022 * Structure used to hold the device-specific config parameters. 6696f3e57acSmx205022 * The setting of such parameters may not consistent with the 6706f3e57acSmx205022 * hardware feature of the device. It's used for software purpose. 6716f3e57acSmx205022 */ 6726f3e57acSmx205022 typedef struct nge_dev_spec_param { 6736f3e57acSmx205022 boolean_t msi; /* specifies msi support */ 6746f3e57acSmx205022 boolean_t msi_x; /* specifies msi_x support */ 6756f3e57acSmx205022 boolean_t vlan; /* specifies vlan support */ 6769ae6bcf1Sjj146644 boolean_t advanced_pm; /* advanced power management support */ 677d27d4a13SMiles Xu, Sun Microsystems boolean_t mac_addr_order; /* mac address order */ 6786f3e57acSmx205022 boolean_t tx_pause_frame; /* specifies tx pause frame support */ 6796f3e57acSmx205022 boolean_t rx_pause_frame; /* specifies rx pause frame support */ 6806f3e57acSmx205022 boolean_t jumbo; /* jumbo frame support */ 6816f3e57acSmx205022 boolean_t tx_rx_64byte; /* set the max tx/rx prd fetch size */ 6826f3e57acSmx205022 boolean_t rx_hw_checksum; /* specifies tx hw checksum feature */ 6836f3e57acSmx205022 uint32_t tx_hw_checksum; /* specifies rx hw checksum feature */ 6846f3e57acSmx205022 uint32_t desc_type; /* specifies descriptor type */ 6856f3e57acSmx205022 uint32_t rx_desc_num; /* specifies rx descriptor number */ 6866f3e57acSmx205022 uint32_t tx_desc_num; /* specifies tx descriptor number */ 6876f3e57acSmx205022 uint32_t nge_split; /* specifies the split number */ 6886f3e57acSmx205022 } nge_dev_spec_param_t; 6896f3e57acSmx205022 6906f3e57acSmx205022 typedef struct nge { 6916f3e57acSmx205022 /* 6926f3e57acSmx205022 * These fields are set by attach() and unchanged thereafter ... 6936f3e57acSmx205022 */ 6946f3e57acSmx205022 dev_info_t *devinfo; /* device instance */ 6956f3e57acSmx205022 mac_handle_t mh; /* mac module handle */ 6966f3e57acSmx205022 chip_info_t chipinfo; 6976f3e57acSmx205022 ddi_acc_handle_t cfg_handle; /* DDI I/O handle */ 6986f3e57acSmx205022 ddi_acc_handle_t io_handle; /* DDI I/O handle */ 6996f3e57acSmx205022 void *io_regs; /* mapped registers */ 7006f3e57acSmx205022 7016f3e57acSmx205022 ddi_periodic_t periodic_id; /* periodical callback */ 7026f3e57acSmx205022 uint32_t factotum_flag; 7036f3e57acSmx205022 ddi_softint_handle_t factotum_hdl; /* factotum callback */ 7046f3e57acSmx205022 ddi_softint_handle_t resched_hdl; /* reschedule callback */ 7056f3e57acSmx205022 uint_t soft_pri; 7066f3e57acSmx205022 7076f3e57acSmx205022 ddi_intr_handle_t *htable; /* for array of interrupts */ 7086f3e57acSmx205022 int intr_type; /* type of interrupt */ 7096f3e57acSmx205022 int intr_actual_cnt; /* alloc intrs count */ 7106f3e57acSmx205022 int intr_req_cnt; /* request intrs count */ 7116f3e57acSmx205022 uint_t intr_pri; /* interrupt priority */ 7126f3e57acSmx205022 int intr_cap; /* interrupt capabilities */ 7136f3e57acSmx205022 7146f3e57acSmx205022 uint32_t progress; /* attach tracking */ 7156f3e57acSmx205022 uint32_t debug; /* flag to debug function */ 7166f3e57acSmx205022 7176f3e57acSmx205022 char ifname[8]; /* "nge0" ... "nge999" */ 7186f3e57acSmx205022 7196f3e57acSmx205022 7206f3e57acSmx205022 enum nge_mac_state nge_mac_state; /* definitions above */ 7216f3e57acSmx205022 enum nge_chip_state nge_chip_state; /* definitions above */ 7226f3e57acSmx205022 boolean_t promisc; 7236de4f663Smx205022 boolean_t record_promisc; 7246f3e57acSmx205022 boolean_t suspended; 7256f3e57acSmx205022 7266f3e57acSmx205022 int resched_needed; 7276f3e57acSmx205022 uint32_t default_mtu; 7286f3e57acSmx205022 uint32_t max_sdu; 7296f3e57acSmx205022 uint32_t buf_size; 7306f3e57acSmx205022 uint32_t rx_desc; 7316f3e57acSmx205022 uint32_t tx_desc; 7326f3e57acSmx205022 uint32_t rx_buf; 7336f3e57acSmx205022 uint32_t nge_split; 7346f3e57acSmx205022 uint32_t watchdog; 7356f3e57acSmx205022 uint32_t lowmem_mode; 7366f3e57acSmx205022 7376f3e57acSmx205022 7386f3e57acSmx205022 /* 7396f3e57acSmx205022 * Runtime read-write data starts here ... 7406f3e57acSmx205022 * 1 Receive Rings 7416f3e57acSmx205022 * 1 Send Rings 7426f3e57acSmx205022 * 7436f3e57acSmx205022 * Note: they're not necessarily all used. 7446f3e57acSmx205022 */ 7456f3e57acSmx205022 struct buff_ring buff[1]; 7466f3e57acSmx205022 struct recv_ring recv[1]; 7476f3e57acSmx205022 struct send_ring send[1]; 7486f3e57acSmx205022 7496f3e57acSmx205022 7506f3e57acSmx205022 kmutex_t genlock[1]; 7516f3e57acSmx205022 krwlock_t rwlock[1]; 7526f3e57acSmx205022 kmutex_t softlock[1]; 7536f3e57acSmx205022 uint32_t intr_masks; 7546f3e57acSmx205022 boolean_t poll; 7556f3e57acSmx205022 boolean_t ch_intr_mode; 75602d51d0dSjj146644 boolean_t intr_moderation; 7576f3e57acSmx205022 uint32_t recv_count; 75802d51d0dSjj146644 uint32_t quiet_time; 75902d51d0dSjj146644 uint32_t busy_time; 760*51fc88a8SWinson Wang - Sun Microsystems - Beijing China uint64_t tpkts_last; 761*51fc88a8SWinson Wang - Sun Microsystems - Beijing China uint32_t tfint_threshold; 7626f3e57acSmx205022 uint32_t sw_intr_intv; 7636f3e57acSmx205022 nge_mac_addr_t cur_uni_addr; 7646f3e57acSmx205022 uint32_t rx_datahwm; 7656f3e57acSmx205022 uint32_t rx_prdlwm; 7666f3e57acSmx205022 uint32_t rx_prdhwm; 7676f3e57acSmx205022 uint32_t rx_def; 7686f3e57acSmx205022 uint32_t desc_mode; 7696f3e57acSmx205022 7706f3e57acSmx205022 mul_item *pcur_mulist; 7716f3e57acSmx205022 nge_mac_addr_t cur_mul_addr; 7726f3e57acSmx205022 nge_mac_addr_t cur_mul_mask; 7736f3e57acSmx205022 7746f3e57acSmx205022 nge_desc_attr_t desc_attr; 7756f3e57acSmx205022 7766f3e57acSmx205022 /* 7776f3e57acSmx205022 * Link state data (protected by genlock) 7786f3e57acSmx205022 */ 7796f3e57acSmx205022 int32_t link_state; /* See GLD #defines */ 7806f3e57acSmx205022 uint32_t stall_cknum; /* Stall check number */ 7816f3e57acSmx205022 7826f3e57acSmx205022 uint32_t phy_xmii_addr; 7836f3e57acSmx205022 uint32_t phy_id; 7846f3e57acSmx205022 uint32_t phy_mode; 7856f3e57acSmx205022 const phys_ops_t *physops; 7866f3e57acSmx205022 uint16_t phy_gen_status; 7876f3e57acSmx205022 7886f3e57acSmx205022 uint32_t param_loop_mode; 7896f3e57acSmx205022 7906f3e57acSmx205022 kstat_t *nge_kstats[NGE_KSTAT_COUNT]; 7916f3e57acSmx205022 nge_statistics_t statistics; 7926f3e57acSmx205022 7936f3e57acSmx205022 nge_dev_spec_param_t dev_spec_param; 7946f3e57acSmx205022 7955a3d0718Smx205022 uint32_t param_en_pause:1, 7965a3d0718Smx205022 param_en_asym_pause:1, 7975a3d0718Smx205022 param_en_1000hdx:1, 7985a3d0718Smx205022 param_en_1000fdx:1, 7995a3d0718Smx205022 param_en_100fdx:1, 8005a3d0718Smx205022 param_en_100hdx:1, 8015a3d0718Smx205022 param_en_10fdx:1, 8025a3d0718Smx205022 param_en_10hdx:1, 8034045d941Ssowmini param_adv_autoneg:1, 8044045d941Ssowmini param_adv_pause:1, 8054045d941Ssowmini param_adv_asym_pause:1, 8064045d941Ssowmini param_adv_1000fdx:1, 8074045d941Ssowmini param_adv_1000hdx:1, 8084045d941Ssowmini param_adv_100fdx:1, 8094045d941Ssowmini param_adv_100hdx:1, 8104045d941Ssowmini param_adv_10fdx:1, 8114045d941Ssowmini param_adv_10hdx:1, 8124045d941Ssowmini param_lp_autoneg:1, 8134045d941Ssowmini param_lp_pause:1, 8144045d941Ssowmini param_lp_asym_pause:1, 8154045d941Ssowmini param_lp_1000fdx:1, 8164045d941Ssowmini param_lp_1000hdx:1, 8174045d941Ssowmini param_lp_100fdx:1, 8184045d941Ssowmini param_lp_100hdx:1, 8194045d941Ssowmini param_lp_10fdx:1, 8204045d941Ssowmini param_lp_10hdx:1, 8214045d941Ssowmini param_link_up:1, 8224045d941Ssowmini param_link_autoneg:1, 8234045d941Ssowmini param_link_rx_pause:1, 8244045d941Ssowmini param_link_tx_pause:1, 8254045d941Ssowmini param_pad_to_32:2; 8264045d941Ssowmini uint64_t param_link_speed; 8274045d941Ssowmini link_duplex_t param_link_duplex; 8284045d941Ssowmini int param_txbcopy_threshold; 8294045d941Ssowmini int param_rxbcopy_threshold; 8304045d941Ssowmini int param_recv_max_packet; 8314045d941Ssowmini int param_poll_quiet_time; 8324045d941Ssowmini int param_poll_busy_time; 8334045d941Ssowmini int param_rx_intr_hwater; 8344045d941Ssowmini int param_rx_intr_lwater; 8356f3e57acSmx205022 } nge_t; 8366f3e57acSmx205022 8376f3e57acSmx205022 extern const nge_ksindex_t nge_statistics[]; 8386f3e57acSmx205022 8396f3e57acSmx205022 /* 8406f3e57acSmx205022 * Sync a DMA area described by a dma_area_t 8416f3e57acSmx205022 */ 8426f3e57acSmx205022 #define DMA_SYNC(area, flag) ((void) ddi_dma_sync((area).dma_hdl, \ 8436f3e57acSmx205022 (area).offset, (area).alength, (flag))) 8446f3e57acSmx205022 8456f3e57acSmx205022 /* 8466f3e57acSmx205022 * Find the (kernel virtual) address of block of memory 8476f3e57acSmx205022 * described by a dma_area_t 8486f3e57acSmx205022 */ 8496f3e57acSmx205022 #define DMA_VPTR(area) ((area).mem_va) 8506f3e57acSmx205022 8516f3e57acSmx205022 /* 8526f3e57acSmx205022 * Zero a block of memory described by a dma_area_t 8536f3e57acSmx205022 */ 8546f3e57acSmx205022 #define DMA_ZERO(area) bzero(DMA_VPTR(area), (area).alength) 8556f3e57acSmx205022 8566f3e57acSmx205022 /* 8576f3e57acSmx205022 * Next/Prev value of a cyclic index 8586f3e57acSmx205022 */ 8596f3e57acSmx205022 #define NEXT(index, limit) ((index) + 1 < (limit) ? (index) + 1 : 0) 8606f3e57acSmx205022 #define PREV(index, limit) (0 == (index) ? (limit - 1) : (index) - 1) 8616f3e57acSmx205022 8626f3e57acSmx205022 #define NEXT_INDEX(ndx, num, lim)\ 8636f3e57acSmx205022 (((ndx) + (num) < (lim)) ? ((ndx) + (num)) : ((ndx) + (num) - (lim))) 8646f3e57acSmx205022 8656f3e57acSmx205022 8666f3e57acSmx205022 /* 8676f3e57acSmx205022 * Property lookups 8686f3e57acSmx205022 */ 8696f3e57acSmx205022 #define NGE_PROP_EXISTS(d, n) ddi_prop_exists(DDI_DEV_T_ANY, (d), \ 8706f3e57acSmx205022 DDI_PROP_DONTPASS, (n)) 8716f3e57acSmx205022 #define NGE_PROP_GET_INT(d, n) ddi_prop_get_int(DDI_DEV_T_ANY, (d), \ 8726f3e57acSmx205022 DDI_PROP_DONTPASS, (n), -1) 8736f3e57acSmx205022 8746f3e57acSmx205022 8756f3e57acSmx205022 /* 8766f3e57acSmx205022 * Debugging ... 8776f3e57acSmx205022 */ 8786f3e57acSmx205022 #ifdef DEBUG 8796f3e57acSmx205022 #define NGE_DEBUGGING 1 8806f3e57acSmx205022 #else 8816f3e57acSmx205022 #define NGE_DEBUGGING 0 8826f3e57acSmx205022 #endif /* DEBUG */ 8836f3e57acSmx205022 8846f3e57acSmx205022 /* 8856f3e57acSmx205022 * Bit flags in the 'debug' word ... 8866f3e57acSmx205022 */ 8876f3e57acSmx205022 #define NGE_DBG_STOP 0x00000001 /* early debug_enter() */ 8886f3e57acSmx205022 #define NGE_DBG_TRACE 0x00000002 /* general flow tracing */ 8896f3e57acSmx205022 8906f3e57acSmx205022 #define NGE_DBG_MII 0x00000010 /* low-level MII access */ 8916f3e57acSmx205022 #define NGE_DBG_CHIP 0x00000020 /* low(ish)-level code */ 8926f3e57acSmx205022 8936f3e57acSmx205022 #define NGE_DBG_RECV 0x00000100 /* receive-side code */ 8946f3e57acSmx205022 #define NGE_DBG_SEND 0x00000200 /* packet-send code */ 8956f3e57acSmx205022 8966f3e57acSmx205022 #define NGE_DBG_INIT 0x00100000 /* initialisation */ 8976f3e57acSmx205022 #define NGE_DBG_NEMO 0x00200000 /* MAC layer entry points */ 8986f3e57acSmx205022 #define NGE_DBG_STATS 0x00400000 /* statistics */ 8996f3e57acSmx205022 9006f3e57acSmx205022 #define NGE_DBG_BADIOC 0x01000000 /* unknown ioctls */ 9016f3e57acSmx205022 9026f3e57acSmx205022 #define NGE_DBG_NDD 0x10000000 /* NDD operations */ 9036f3e57acSmx205022 9046f3e57acSmx205022 9056f3e57acSmx205022 9066f3e57acSmx205022 /* 9076f3e57acSmx205022 * 'Do-if-debugging' macro. The parameter <command> should be one or more 9086f3e57acSmx205022 * C statements (but without the *final* semicolon), which will either be 9096f3e57acSmx205022 * compiled inline or completely ignored, depending on the NGE_DEBUGGING 9106f3e57acSmx205022 * compile-time flag. 9116f3e57acSmx205022 * 9126f3e57acSmx205022 * You should get a compile-time error (at least on a DEBUG build) if 9136f3e57acSmx205022 * your statement isn't actually a statement, rather than unexpected 9146f3e57acSmx205022 * run-time behaviour caused by unintended matching of if-then-elses etc. 9156f3e57acSmx205022 * 9166f3e57acSmx205022 * Note that the NGE_DDB() macro itself can only be used as a statement, 9176f3e57acSmx205022 * not an expression, and should always be followed by a semicolon. 9186f3e57acSmx205022 */ 9196f3e57acSmx205022 #if NGE_DEBUGGING 9206f3e57acSmx205022 #define NGE_DDB(command) do { \ 9216f3e57acSmx205022 { command; } \ 9226f3e57acSmx205022 _NOTE(CONSTANTCONDITION) \ 9236f3e57acSmx205022 } while (0) 9246f3e57acSmx205022 #else /* NGE_DEBUGGING */ 9256f3e57acSmx205022 #define NGE_DDB(command) 9266f3e57acSmx205022 /* 9276f3e57acSmx205022 * Old way of debugging. This is a poor way, as it leeaves empty 9286f3e57acSmx205022 * statements that cause lint to croak. 9296f3e57acSmx205022 * #define NGE_DDB(command) do { \ 9306f3e57acSmx205022 * { _NOTE(EMPTY); } \ 9316f3e57acSmx205022 * _NOTE(CONSTANTCONDITION) \ 9326f3e57acSmx205022 * } while (0) 9336f3e57acSmx205022 */ 9346f3e57acSmx205022 #endif /* NGE_DEBUGGING */ 9356f3e57acSmx205022 9366f3e57acSmx205022 /* 9376f3e57acSmx205022 * 'Internal' macros used to construct the TRACE/DEBUG macros below. 9386f3e57acSmx205022 * These provide the primitive conditional-call capability required. 9396f3e57acSmx205022 * Note: the parameter <args> is a parenthesised list of the actual 9406f3e57acSmx205022 * printf-style arguments to be passed to the debug function ... 9416f3e57acSmx205022 */ 9426f3e57acSmx205022 #define NGE_XDB(b, w, f, args) NGE_DDB(if ((b) & (w)) f args) 9436f3e57acSmx205022 #define NGE_GDB(b, args) NGE_XDB(b, nge_debug, (*nge_gdb()), args) 9446f3e57acSmx205022 #define NGE_LDB(b, args) NGE_XDB(b, ngep->debug, \ 9456f3e57acSmx205022 (*nge_db(ngep)), args) 9466f3e57acSmx205022 #define NGE_CDB(f, args) NGE_XDB(NGE_DBG, ngep->debug, f, args) 9476f3e57acSmx205022 9486f3e57acSmx205022 /* 9496f3e57acSmx205022 * Conditional-print macros. 9506f3e57acSmx205022 * 9516f3e57acSmx205022 * Define NGE_DBG to be the relevant member of the set of NGE_DBG_* values 9526f3e57acSmx205022 * above before using the NGE_GDEBUG() or NGE_DEBUG() macros. The 'G' 9536f3e57acSmx205022 * versions look at the Global debug flag word (nge_debug); the non-G 9546f3e57acSmx205022 * versions look in the per-instance data (ngep->debug) and so require a 9556f3e57acSmx205022 * variable called 'ngep' to be in scope (and initialised!) before use. 9566f3e57acSmx205022 * 9576f3e57acSmx205022 * You could redefine NGE_TRC too if you really need two different 9586f3e57acSmx205022 * flavours of debugging output in the same area of code, but I don't 9596f3e57acSmx205022 * really recommend it. 9606f3e57acSmx205022 * 9616f3e57acSmx205022 * Note: the parameter <args> is a parenthesised list of the actual 9626f3e57acSmx205022 * arguments to be passed to the debug function, usually a printf-style 9636f3e57acSmx205022 * format string and corresponding values to be formatted. 9646f3e57acSmx205022 */ 9656f3e57acSmx205022 9666f3e57acSmx205022 #define NGE_TRC NGE_DBG_TRACE 9676f3e57acSmx205022 9686f3e57acSmx205022 #define NGE_GTRACE(args) NGE_GDB(NGE_TRC, args) 9696f3e57acSmx205022 #define NGE_GDEBUG(args) NGE_GDB(NGE_DBG, args) 9706f3e57acSmx205022 #define NGE_TRACE(args) NGE_LDB(NGE_TRC, args) 9716f3e57acSmx205022 #define NGE_DEBUG(args) NGE_LDB(NGE_DBG, args) 9726f3e57acSmx205022 9736f3e57acSmx205022 /* 9746f3e57acSmx205022 * Debug-only action macros 9756f3e57acSmx205022 */ 9766f3e57acSmx205022 9776f3e57acSmx205022 9786f3e57acSmx205022 #define NGE_REPORT(args) NGE_DDB(nge_log args) 9796f3e57acSmx205022 9806f3e57acSmx205022 boolean_t nge_atomic_decrease(uint64_t *count_p, uint64_t n); 9816f3e57acSmx205022 void nge_atomic_increase(uint64_t *count_p, uint64_t n); 9826f3e57acSmx205022 9836f3e57acSmx205022 int nge_alloc_dma_mem(nge_t *ngep, size_t memsize, 9846f3e57acSmx205022 ddi_device_acc_attr_t *attr_p, uint_t dma_flags, dma_area_t *dma_p); 9856f3e57acSmx205022 void nge_free_dma_mem(dma_area_t *dma_p); 9866f3e57acSmx205022 int nge_restart(nge_t *ngep); 9876f3e57acSmx205022 void nge_wake_factotum(nge_t *ngep); 9886f3e57acSmx205022 9896f3e57acSmx205022 uint8_t nge_reg_get8(nge_t *ngep, nge_regno_t regno); 9906f3e57acSmx205022 void nge_reg_put8(nge_t *ngep, nge_regno_t regno, uint8_t data); 9916f3e57acSmx205022 uint16_t nge_reg_get16(nge_t *ngep, nge_regno_t regno); 9926f3e57acSmx205022 void nge_reg_put16(nge_t *ngep, nge_regno_t regno, uint16_t data); 9936f3e57acSmx205022 uint32_t nge_reg_get32(nge_t *ngep, nge_regno_t regno); 9946f3e57acSmx205022 void nge_reg_put32(nge_t *ngep, nge_regno_t regno, uint32_t data); 9956f3e57acSmx205022 uint_t nge_chip_factotum(caddr_t args1, caddr_t args2); 9966f3e57acSmx205022 void nge_chip_cfg_init(nge_t *ngep, chip_info_t *infop, boolean_t reset); 9976f3e57acSmx205022 void nge_init_dev_spec_param(nge_t *ngep); 9986f3e57acSmx205022 int nge_chip_stop(nge_t *ngep, boolean_t fault); 9996f3e57acSmx205022 void nge_restore_mac_addr(nge_t *ngep); 10006f3e57acSmx205022 int nge_chip_reset(nge_t *ngep); 10016f3e57acSmx205022 int nge_chip_start(nge_t *ngep); 10026f3e57acSmx205022 void nge_chip_sync(nge_t *ngep); 10036f3e57acSmx205022 10046f3e57acSmx205022 uint_t nge_chip_intr(caddr_t arg1, caddr_t arg2); 10056f3e57acSmx205022 enum ioc_reply nge_chip_ioctl(nge_t *ngep, mblk_t *mp, struct iocblk *iocp); 10066f3e57acSmx205022 10076f3e57acSmx205022 void nge_phys_init(nge_t *ngep); 10086f3e57acSmx205022 boolean_t nge_phy_reset(nge_t *ngep); 10096f3e57acSmx205022 uint16_t nge_mii_get16(nge_t *ngep, nge_regno_t regno); 10106f3e57acSmx205022 void nge_mii_put16(nge_t *ngep, nge_regno_t regno, uint16_t data); 10116f3e57acSmx205022 10126f3e57acSmx205022 void nge_recv_recycle(caddr_t arg); 10136f3e57acSmx205022 void nge_receive(nge_t *ngep); 10146f3e57acSmx205022 10156f3e57acSmx205022 uint_t nge_reschedule(caddr_t args1, caddr_t args2); 10166f3e57acSmx205022 mblk_t *nge_m_tx(void *arg, mblk_t *mp); 10176f3e57acSmx205022 10186f3e57acSmx205022 void nge_tx_recycle(nge_t *ngep, boolean_t is_intr); 10196f3e57acSmx205022 void nge_tx_recycle_all(nge_t *ngep); 10206f3e57acSmx205022 10216f3e57acSmx205022 int nge_nd_init(nge_t *ngep); 10226f3e57acSmx205022 void nge_nd_cleanup(nge_t *ngep); 10236f3e57acSmx205022 10246f3e57acSmx205022 10256f3e57acSmx205022 void nge_init_kstats(nge_t *ngep, int instance); 10266f3e57acSmx205022 void nge_fini_kstats(nge_t *ngep); 10276f3e57acSmx205022 int nge_m_stat(void *arg, uint_t stat, uint64_t *val); 10286f3e57acSmx205022 10296f3e57acSmx205022 uint32_t nge_atomic_shl32(uint32_t *sp, uint_t count); 10306f3e57acSmx205022 10316f3e57acSmx205022 void nge_log(nge_t *ngep, const char *fmt, ...); 10326f3e57acSmx205022 void nge_problem(nge_t *ngep, const char *fmt, ...); 10336f3e57acSmx205022 void nge_error(nge_t *ngep, const char *fmt, ...); 10346f3e57acSmx205022 void 10356f3e57acSmx205022 nge_report(nge_t *ngep, uint8_t error_id); 10366f3e57acSmx205022 10376f3e57acSmx205022 void (*nge_db(nge_t *ngep))(const char *fmt, ...); 10386f3e57acSmx205022 void (*nge_gdb(void))(const char *fmt, ...); 10396f3e57acSmx205022 extern uint32_t nge_debug; 10406f3e57acSmx205022 10416f3e57acSmx205022 /* 10426f3e57acSmx205022 * DESC MODE 2 10436f3e57acSmx205022 */ 10446f3e57acSmx205022 10456f3e57acSmx205022 extern void nge_sum_rxd_fill(void *, const ddi_dma_cookie_t *, size_t); 10466f3e57acSmx205022 extern uint32_t nge_sum_rxd_check(const void *, size_t *); 10476f3e57acSmx205022 10486f3e57acSmx205022 extern void nge_sum_txd_fill(void *, const ddi_dma_cookie_t *, 1049*51fc88a8SWinson Wang - Sun Microsystems - Beijing China size_t, uint32_t, boolean_t, boolean_t); 10509fa05d92SWinson Wang - Sun Microsystems - Beijing China extern uint32_t nge_sum_txd_check(const void *); 10516f3e57acSmx205022 10526f3e57acSmx205022 /* 10536f3e57acSmx205022 * DESC MODE 3 10546f3e57acSmx205022 */ 10556f3e57acSmx205022 10566f3e57acSmx205022 extern void nge_hot_rxd_fill(void *, const ddi_dma_cookie_t *, size_t); 10576f3e57acSmx205022 extern uint32_t nge_hot_rxd_check(const void *, size_t *); 10586f3e57acSmx205022 10596f3e57acSmx205022 extern void nge_hot_txd_fill(void *, const ddi_dma_cookie_t *, 1060*51fc88a8SWinson Wang - Sun Microsystems - Beijing China size_t, uint32_t, boolean_t, boolean_t); 10619fa05d92SWinson Wang - Sun Microsystems - Beijing China extern uint32_t nge_hot_txd_check(const void *); 10626f3e57acSmx205022 10636f3e57acSmx205022 #ifdef __cplusplus 10646f3e57acSmx205022 } 10656f3e57acSmx205022 #endif 10666f3e57acSmx205022 10676f3e57acSmx205022 #endif /* _SYS_NGE_H */ 1068