1*5578Smx205022 /* 2*5578Smx205022 * CDDL HEADER START 3*5578Smx205022 * 4*5578Smx205022 * The contents of this file are subject to the terms of the 5*5578Smx205022 * Common Development and Distribution License (the "License"). 6*5578Smx205022 * You may not use this file except in compliance with the License. 7*5578Smx205022 * 8*5578Smx205022 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5578Smx205022 * or http://www.opensolaris.org/os/licensing. 10*5578Smx205022 * See the License for the specific language governing permissions 11*5578Smx205022 * and limitations under the License. 12*5578Smx205022 * 13*5578Smx205022 * When distributing Covered Code, include this CDDL HEADER in each 14*5578Smx205022 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5578Smx205022 * If applicable, add the following below this CDDL HEADER, with the 16*5578Smx205022 * fields enclosed by brackets "[]" replaced with your own identifying 17*5578Smx205022 * information: Portions Copyright [yyyy] [name of copyright owner] 18*5578Smx205022 * 19*5578Smx205022 * CDDL HEADER END 20*5578Smx205022 */ 21*5578Smx205022 225574Smx205022 /* 235574Smx205022 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 245574Smx205022 * Use is subject to license terms. 255574Smx205022 */ 265574Smx205022 275574Smx205022 #ifndef _SYS_NGE_H 285574Smx205022 #define _SYS_NGE_H 295574Smx205022 305574Smx205022 #pragma ident "%Z%%M% %I% %E% SMI" 315574Smx205022 325574Smx205022 #ifdef __cplusplus 335574Smx205022 extern "C" { 345574Smx205022 #endif 355574Smx205022 365574Smx205022 375574Smx205022 #include <sys/types.h> 385574Smx205022 #include <sys/stream.h> 395574Smx205022 #include <sys/strsun.h> 405574Smx205022 #include <sys/strsubr.h> 415574Smx205022 #include <sys/stat.h> 425574Smx205022 #include <sys/pci.h> 435574Smx205022 #include <sys/note.h> 445574Smx205022 #include <sys/modctl.h> 455574Smx205022 #include <sys/kstat.h> 465574Smx205022 #include <sys/ethernet.h> 475574Smx205022 #include <sys/pattr.h> 485574Smx205022 #include <sys/errno.h> 495574Smx205022 #include <sys/dlpi.h> 505574Smx205022 #include <sys/devops.h> 515574Smx205022 #include <sys/debug.h> 525574Smx205022 #include <sys/conf.h> 535574Smx205022 #include <sys/callb.h> 545574Smx205022 555574Smx205022 #include <netinet/ip6.h> 565574Smx205022 575574Smx205022 #include <inet/common.h> 585574Smx205022 #include <inet/ip.h> 595574Smx205022 #include <netinet/udp.h> 605574Smx205022 #include <inet/mi.h> 615574Smx205022 #include <inet/nd.h> 625574Smx205022 635574Smx205022 #include <sys/ddi.h> 645574Smx205022 #include <sys/sunddi.h> 655574Smx205022 665574Smx205022 #include <sys/mac.h> 675574Smx205022 #include <sys/mac_ether.h> 685574Smx205022 695574Smx205022 /* 705574Smx205022 * Reconfiguring the network devices requires the net_config privilege 715574Smx205022 * in Solaris 10+. 725574Smx205022 */ 735574Smx205022 extern int secpolicy_net_config(const cred_t *, boolean_t); 745574Smx205022 755574Smx205022 #include <sys/netlb.h> 765574Smx205022 #include <sys/miiregs.h> 775574Smx205022 785574Smx205022 #include "nge_chip.h" 795574Smx205022 805574Smx205022 #define PIO_ADDR(ngep, offset) ((void *)((caddr_t)(ngep)->io_regs+(offset))) 815574Smx205022 /* 825574Smx205022 * Copy an ethernet address 835574Smx205022 */ 845574Smx205022 #define ethaddr_copy(src, dst) bcopy((src), (dst), ETHERADDRL) 855574Smx205022 #define ether_eq(a, b) (bcmp((caddr_t)(a), (caddr_t)(b), (ETHERADDRL)) == 0) 865574Smx205022 875574Smx205022 #define BIS(w, b) (((w) & (b)) ? B_TRUE : B_FALSE) 885574Smx205022 #define BIC(w, b) (((w) & (b)) ? B_FALSE : B_TRUE) 895574Smx205022 #define UPORDOWN(x) ((x) ? "up" : "down") 905574Smx205022 915574Smx205022 #define NGE_DRIVER_NAME "nge" 925574Smx205022 935574Smx205022 /* 945574Smx205022 * 'Progress' bit flags ... 955574Smx205022 */ 965574Smx205022 #define PROGRESS_CFG 0x0001 /* config space mapped */ 975574Smx205022 #define PROGRESS_REGS 0x0002 /* registers mapped */ 985574Smx205022 #define PROGRESS_BUFS 0x0004 /* registers mapped */ 995574Smx205022 #define PROGRESS_RESCHED 0x0008 /* resched softint registered */ 1005574Smx205022 #define PROGRESS_FACTOTUM 0x0010 /* factotum softint registered */ 1015574Smx205022 #define PROGRESS_SWINT 0x0020 /* s/w interrupt registered */ 1025574Smx205022 #define PROGRESS_INTR 0x0040 /* h/w interrupt registered */ 1035574Smx205022 /* and mutexen initialised */ 1045574Smx205022 #define PROGRESS_HWINT 0x0080 1055574Smx205022 #define PROGRESS_PHY 0x0100 /* PHY initialised */ 1065574Smx205022 #define PROGRESS_NDD 0x0200 /* NDD parameters set up */ 1075574Smx205022 #define PROGRESS_KSTATS 0x0400 /* kstats created */ 1085574Smx205022 #define PROGRESS_READY 0x0800 /* ready for work */ 1095574Smx205022 1105574Smx205022 #define NGE_HW_ERR 0x00 1115574Smx205022 #define NGE_HW_LINK 0x01 1125574Smx205022 #define NGE_HW_BM 0x02 1135574Smx205022 #define NGE_HW_RCHAN 0x03 1145574Smx205022 #define NGE_HW_TCHAN 0x04 1155574Smx205022 #define NGE_HW_ROM 0x05 1165574Smx205022 #define NGE_SW_PROBLEM_ID 0x06 1175574Smx205022 1185574Smx205022 1195574Smx205022 /* 1205574Smx205022 * NOTES: 1215574Smx205022 * 1225574Smx205022 * #defines: 1235574Smx205022 * 1245574Smx205022 * NGE_PCI_CONFIG_RNUMBER and NGE_PCI_OPREGS_RNUMBER are the 1255574Smx205022 * register-set numbers to use for the config space registers 1265574Smx205022 * and the operating registers respectively. On an OBP-based 1275574Smx205022 * machine, regset 0 refers to CONFIG space, and regset 1 will 1285574Smx205022 * be the operating registers in MEMORY space. If an expansion 1295574Smx205022 * ROM is fitted, it may appear as a further register set. 1305574Smx205022 * 1315574Smx205022 * NGE_DMA_MODE defines the mode (STREAMING/CONSISTENT) used 1325574Smx205022 * for the data buffers. The descriptors are always set up 1335574Smx205022 * in CONSISTENT mode. 1345574Smx205022 * 1355574Smx205022 * NGE_HEADROOM defines how much space we'll leave in allocated 1365574Smx205022 * mblks before the first valid data byte. This should be chosen 1375574Smx205022 * to be 2 modulo 4, so that once the ethernet header (14 bytes) 1385574Smx205022 * has been stripped off, the packet data will be 4-byte aligned. 1395574Smx205022 * The remaining space can be used by upstream modules to prepend 1405574Smx205022 * any headers required. 1415574Smx205022 */ 1425574Smx205022 1435574Smx205022 1445574Smx205022 #define NGE_PCI_OPREGS_RNUMBER 1 1455574Smx205022 #define NGE_DMA_MODE DDI_DMA_STREAMING 1465574Smx205022 #define NGE_HEADROOM 6 1475574Smx205022 #define ETHER_HEAD_LEN 14 1485574Smx205022 #ifndef VTAG_SIZE 1495574Smx205022 #define VTAG_SIZE 4 1505574Smx205022 #endif 1515574Smx205022 1525574Smx205022 #define NGE_HALFTICK 268435456LL /* 2**28 ns! */ 1535574Smx205022 #define NGE_CYCLIC_PERIOD (4*NGE_HALFTICK) /* ~0.5s */ 1545574Smx205022 1555574Smx205022 #define NGE_DEFAULT_MTU 1500 1565574Smx205022 #define NGE_DEFAULT_SDU 1518 1575574Smx205022 #define NGE_MTU_2500 2500 1585574Smx205022 #define NGE_MTU_4500 4500 1595574Smx205022 #define NGE_MAX_MTU 9000 1605574Smx205022 #define NGE_MAX_SDU 9018 1615574Smx205022 1625574Smx205022 #define NGE_DESC_MIN 0x100 1635574Smx205022 1645574Smx205022 #define NGE_STD_BUFSZ 1792 1655574Smx205022 #define NGE_JB2500_BUFSZ (3*1024) 1665574Smx205022 #define NGE_JB4500_BUFSZ (5*1024) 1675574Smx205022 #define NGE_JB9000_BUFSZ (9*1024) 1685574Smx205022 1695574Smx205022 #define NGE_SEND_SLOTS_DESC_1024 1024 1705574Smx205022 #define NGE_SEND_SLOTS_DESC_3072 3072 1715574Smx205022 #define NGE_SEND_JB2500_SLOTS_DESC 3072 1725574Smx205022 #define NGE_SEND_JB4500_SLOTS_DESC 2048 1735574Smx205022 #define NGE_SEND_JB9000_SLOTS_DESC 1024 1745574Smx205022 #define NGE_SEND_LOWMEM_SLOTS_DESC 1024 1755574Smx205022 #define NGE_SEND_SLOTS_BUF 3072 1765574Smx205022 1775574Smx205022 #define NGE_RECV_SLOTS_DESC_1024 1024 1785574Smx205022 #define NGE_RECV_SLOTS_DESC_3072 3072 1795574Smx205022 #define NGE_RECV_JB2500_SLOTS_DESC 3072 1805574Smx205022 #define NGE_RECV_JB4500_SLOTS_DESC 2048 1815574Smx205022 #define NGE_RECV_JB9000_SLOTS_DESC 1024 1825574Smx205022 #define NGE_RECV_LOWMEM_SLOTS_DESC 1024 1835574Smx205022 #define NGE_RECV_SLOTS_BUF 6144 1845574Smx205022 1855574Smx205022 #define NGE_SPLIT_32 32 1865574Smx205022 #define NGE_SPLIT_96 96 1875574Smx205022 #define NGE_SPLIT_256 256 1885574Smx205022 1895574Smx205022 #define NGE_RX_COPY_SIZE 512 1905574Smx205022 #define NGE_TX_COPY_SIZE 512 1915574Smx205022 #define NGE_MAP_FRAGS 3 1925574Smx205022 #define NGE_MAX_COOKIES 3 1935574Smx205022 #define NGE_MAX_DMA_HDR (4*1024) 1945574Smx205022 1955574Smx205022 /* Used by interrupt blank */ 1965574Smx205022 #define NGE_TICKS_CNT 128 1975574Smx205022 #define NGE_RX_PKT_CNT 8 1985574Smx205022 1995574Smx205022 /* 2005574Smx205022 * NGE-specific ioctls ... 2015574Smx205022 */ 2025574Smx205022 #define NGE_IOC ((((('N' << 8) + 'G') << 8) + 'E') << 8) 2035574Smx205022 2045574Smx205022 /* 2055574Smx205022 * PHY register read/write ioctls, used by cable test software 2065574Smx205022 */ 2075574Smx205022 #define NGE_MII_READ (NGE_IOC|1) 2085574Smx205022 #define NGE_MII_WRITE (NGE_IOC|2) 2095574Smx205022 2105574Smx205022 /* 2115574Smx205022 * SEEPROM read/write ioctls, for use by SEEPROM upgrade utility 2125574Smx205022 * 2135574Smx205022 * Note: SEEPROMs can only be accessed as 32-bit words, so <see_addr> 2145574Smx205022 * must be a multiple of 4. Not all systems have a SEEPROM fitted! 2155574Smx205022 */ 2165574Smx205022 #define NGE_SEE_READ (NGE_IOC|3) 2175574Smx205022 #define NGE_SEE_WRITE (NGE_IOC|4) 2185574Smx205022 2195574Smx205022 2205574Smx205022 /* 2215574Smx205022 * These diagnostic IOCTLS are enabled only in DEBUG drivers 2225574Smx205022 */ 2235574Smx205022 #define NGE_DIAG (NGE_IOC|5) /* currently a no-op */ 2245574Smx205022 #define NGE_PEEK (NGE_IOC|6) 2255574Smx205022 #define NGE_POKE (NGE_IOC|7) 2265574Smx205022 #define NGE_PHY_RESET (NGE_IOC|8) 2275574Smx205022 #define NGE_SOFT_RESET (NGE_IOC|9) 2285574Smx205022 #define NGE_HARD_RESET (NGE_IOC|10) 2295574Smx205022 2305574Smx205022 2315574Smx205022 enum NGE_HW_OP { 2325574Smx205022 NGE_CLEAR = 0, 2335574Smx205022 NGE_SET 2345574Smx205022 }; 2355574Smx205022 2365574Smx205022 /* 2375574Smx205022 * Required state according to GLD 2385574Smx205022 */ 2395574Smx205022 enum nge_mac_state { 2405574Smx205022 NGE_MAC_UNKNOWN, 2415574Smx205022 NGE_MAC_RESET, 2425574Smx205022 NGE_MAC_STOPPED, 2435574Smx205022 NGE_MAC_STARTED, 2445574Smx205022 NGE_MAC_UNATTACH 2455574Smx205022 }; 2465574Smx205022 enum loop_type { 2475574Smx205022 NGE_LOOP_NONE = 0, 2485574Smx205022 NGE_LOOP_EXTERNAL_100, 2495574Smx205022 NGE_LOOP_EXTERNAL_10, 2505574Smx205022 NGE_LOOP_INTERNAL_PHY, 2515574Smx205022 }; 2525574Smx205022 2535574Smx205022 /* 2545574Smx205022 * (Internal) return values from send_msg subroutines 2555574Smx205022 */ 2565574Smx205022 enum send_status { 2575574Smx205022 SEND_COPY_FAIL = -1, /* => GLD_NORESOURCES */ 2585574Smx205022 SEND_MAP_FAIL, /* => GLD_NORESOURCES */ 2595574Smx205022 SEND_COPY_SUCESS, /* OK, msg queued */ 2605574Smx205022 SEND_MAP_SUCCESS /* OK, free msg */ 2615574Smx205022 }; 2625574Smx205022 2635574Smx205022 2645574Smx205022 /* 2655574Smx205022 * NDD parameter indexes, divided into: 2665574Smx205022 * 2675574Smx205022 * read-only parameters describing the hardware's capabilities 2685574Smx205022 * read-write parameters controlling the advertised capabilities 2695574Smx205022 * read-only parameters describing the partner's capabilities 2705574Smx205022 * read-only parameters describing the link state 2715574Smx205022 */ 2725574Smx205022 enum { 2735574Smx205022 PARAM_AUTONEG_CAP, 2745574Smx205022 PARAM_PAUSE_CAP, 2755574Smx205022 PARAM_ASYM_PAUSE_CAP, 2765574Smx205022 PARAM_1000FDX_CAP, 2775574Smx205022 PARAM_1000HDX_CAP, 2785574Smx205022 PARAM_100T4_CAP, 2795574Smx205022 PARAM_100FDX_CAP, 2805574Smx205022 PARAM_100HDX_CAP, 2815574Smx205022 PARAM_10FDX_CAP, 2825574Smx205022 PARAM_10HDX_CAP, 2835574Smx205022 2845574Smx205022 PARAM_ADV_AUTONEG_CAP, 2855574Smx205022 PARAM_ADV_PAUSE_CAP, 2865574Smx205022 PARAM_ADV_ASYM_PAUSE_CAP, 2875574Smx205022 PARAM_ADV_1000FDX_CAP, 2885574Smx205022 PARAM_ADV_1000HDX_CAP, 2895574Smx205022 PARAM_ADV_100T4_CAP, 2905574Smx205022 PARAM_ADV_100FDX_CAP, 2915574Smx205022 PARAM_ADV_100HDX_CAP, 2925574Smx205022 PARAM_ADV_10FDX_CAP, 2935574Smx205022 PARAM_ADV_10HDX_CAP, 2945574Smx205022 2955574Smx205022 PARAM_LP_AUTONEG_CAP, 2965574Smx205022 PARAM_LP_PAUSE_CAP, 2975574Smx205022 PARAM_LP_ASYM_PAUSE_CAP, 2985574Smx205022 PARAM_LP_1000FDX_CAP, 2995574Smx205022 PARAM_LP_1000HDX_CAP, 3005574Smx205022 PARAM_LP_100T4_CAP, 3015574Smx205022 PARAM_LP_100FDX_CAP, 3025574Smx205022 PARAM_LP_100HDX_CAP, 3035574Smx205022 PARAM_LP_10FDX_CAP, 3045574Smx205022 PARAM_LP_10HDX_CAP, 3055574Smx205022 3065574Smx205022 PARAM_LINK_STATUS, 3075574Smx205022 PARAM_LINK_SPEED, 3085574Smx205022 PARAM_LINK_DUPLEX, 3095574Smx205022 3105574Smx205022 PARAM_LINK_AUTONEG, 3115574Smx205022 PARAM_LINK_RX_PAUSE, 3125574Smx205022 PARAM_LINK_TX_PAUSE, 3135574Smx205022 3145574Smx205022 PARAM_LOOP_MODE, 3155574Smx205022 PARAM_TXBCOPY_THRESHOLD, 3165574Smx205022 PARAM_RXBCOPY_THRESHOLD, 3175574Smx205022 PARAM_RECV_MAX_PACKET, 3185574Smx205022 3195574Smx205022 PARAM_COUNT 3205574Smx205022 }; 3215574Smx205022 3225574Smx205022 3235574Smx205022 /* 3245574Smx205022 * (Internal) return values from ioctl subroutines 3255574Smx205022 */ 3265574Smx205022 enum ioc_reply { 3275574Smx205022 IOC_INVAL = -1, /* bad, NAK with EINVAL */ 3285574Smx205022 IOC_DONE, /* OK, reply sent */ 3295574Smx205022 IOC_ACK, /* OK, just send ACK */ 3305574Smx205022 IOC_REPLY, /* OK, just send reply */ 3315574Smx205022 IOC_RESTART_ACK, /* OK, restart & ACK */ 3325574Smx205022 IOC_RESTART_REPLY /* OK, restart & reply */ 3335574Smx205022 }; 3345574Smx205022 3355574Smx205022 enum nge_pp_type { 3365574Smx205022 NGE_PP_SPACE_CFG = 0, 3375574Smx205022 NGE_PP_SPACE_REG, 3385574Smx205022 NGE_PP_SPACE_NIC, 3395574Smx205022 NGE_PP_SPACE_MII, 3405574Smx205022 NGE_PP_SPACE_NGE, 3415574Smx205022 NGE_PP_SPACE_TXDESC, 3425574Smx205022 NGE_PP_SPACE_TXBUFF, 3435574Smx205022 NGE_PP_SPACE_RXDESC, 3445574Smx205022 NGE_PP_SPACE_RXBUFF, 3455574Smx205022 NGE_PP_SPACE_STATISTICS, 3465574Smx205022 NGE_PP_SPACE_SEEPROM, 3475574Smx205022 NGE_PP_SPACE_FLASH 3485574Smx205022 }; 3495574Smx205022 3505574Smx205022 /* 3515574Smx205022 * Flag to kstat type 3525574Smx205022 */ 3535574Smx205022 enum nge_kstat_type { 3545574Smx205022 NGE_KSTAT_RAW = 0, 3555574Smx205022 NGE_KSTAT_STATS, 3565574Smx205022 NGE_KSTAT_CHIPID, 3575574Smx205022 NGE_KSTAT_DEBUG, 3585574Smx205022 NGE_KSTAT_COUNT 3595574Smx205022 }; 3605574Smx205022 3615574Smx205022 3625574Smx205022 /* 3635574Smx205022 * Actual state of the nvidia's chip 3645574Smx205022 */ 3655574Smx205022 enum nge_chip_state { 3665574Smx205022 NGE_CHIP_FAULT = -2, /* fault, need reset */ 3675574Smx205022 NGE_CHIP_ERROR, /* error, want reset */ 3685574Smx205022 NGE_CHIP_INITIAL, /* Initial state only */ 3695574Smx205022 NGE_CHIP_RESET, /* reset, need init */ 3705574Smx205022 NGE_CHIP_STOPPED, /* Tx/Rx stopped */ 3715574Smx205022 NGE_CHIP_RUNNING /* with interrupts */ 3725574Smx205022 }; 3735574Smx205022 3745574Smx205022 enum nge_eeprom_size { 3755574Smx205022 EEPROM_1K = 0, 3765574Smx205022 EEPROM_2K, 3775574Smx205022 EEPROM_4K, 3785574Smx205022 EEPROM_8K, 3795574Smx205022 EEPROM_16K, 3805574Smx205022 EEPROM_32K, 3815574Smx205022 EEPROM_64K 3825574Smx205022 }; 3835574Smx205022 3845574Smx205022 enum nge_eeprom_access_wid { 3855574Smx205022 ACCESS_8BIT = 0, 3865574Smx205022 ACCESS_16BIT 3875574Smx205022 }; 3885574Smx205022 3895574Smx205022 /* 3905574Smx205022 * MDIO operation 3915574Smx205022 */ 3925574Smx205022 enum nge_mdio_operation { 3935574Smx205022 NGE_MDIO_READ = 0, 3945574Smx205022 NGE_MDIO_WRITE 3955574Smx205022 }; 3965574Smx205022 3975574Smx205022 /* 3985574Smx205022 * Speed selection 3995574Smx205022 */ 4005574Smx205022 enum nge_speed { 4015574Smx205022 UNKOWN_SPEED = 0, 4025574Smx205022 NGE_10M, 4035574Smx205022 NGE_100M, 4045574Smx205022 NGE_1000M 4055574Smx205022 }; 4065574Smx205022 4075574Smx205022 /* 4085574Smx205022 * Duplex selection 4095574Smx205022 */ 4105574Smx205022 enum nge_duplex { 4115574Smx205022 UNKOWN_DUPLEX = 0, 4125574Smx205022 NGE_HD, 4135574Smx205022 NGE_FD 4145574Smx205022 }; 4155574Smx205022 4165574Smx205022 typedef struct { 4175574Smx205022 ether_addr_t addr; /* in canonical form */ 4185574Smx205022 uint8_t spare; 4195574Smx205022 uint8_t set; /* nonzero => valid */ 4205574Smx205022 } nge_mac_addr_t; 4215574Smx205022 4225574Smx205022 struct nge; 4235574Smx205022 4245574Smx205022 /* 4255574Smx205022 * Named Data (ND) Parameter Management Structure 4265574Smx205022 */ 4275574Smx205022 typedef struct { 4285574Smx205022 int ndp_info; 4295574Smx205022 int ndp_min; 4305574Smx205022 int ndp_max; 4315574Smx205022 int ndp_val; 4325574Smx205022 char *ndp_name; 4335574Smx205022 } nd_param_t; 4345574Smx205022 4355574Smx205022 4365574Smx205022 #define CHIP_FLAG_COPPER 0x40 4375574Smx205022 4385574Smx205022 /* 4395574Smx205022 * Collection of physical-layer functions to: 4405574Smx205022 * (re)initialise the physical layer 4415574Smx205022 * update it to match software settings 4425574Smx205022 * check for link status change 4435574Smx205022 */ 4445574Smx205022 typedef struct { 4455574Smx205022 void (*phys_restart)(struct nge *); 4465574Smx205022 void (*phys_update)(struct nge *); 4475574Smx205022 boolean_t (*phys_check)(struct nge *); 4485574Smx205022 } phys_ops_t; 4495574Smx205022 4505574Smx205022 struct nge_see_rw { 4515574Smx205022 uint32_t see_addr; /* Byte offset within SEEPROM */ 4525574Smx205022 uint32_t see_data; /* Data read/data to write */ 4535574Smx205022 }; 4545574Smx205022 4555574Smx205022 typedef struct { 4565574Smx205022 uint64_t pp_acc_size; /* in bytes: 1,2,4,8 */ 4575574Smx205022 uint64_t pp_acc_space; /* See #defines below */ 4585574Smx205022 uint64_t pp_acc_offset; 4595574Smx205022 uint64_t pp_acc_data; /* output for peek */ 4605574Smx205022 /* input for poke */ 4615574Smx205022 } nge_peekpoke_t; 4625574Smx205022 4635574Smx205022 typedef uintptr_t nge_regno_t; /* register # (offset) */ 4645574Smx205022 4655574Smx205022 typedef struct _mul_list { 4665574Smx205022 struct _mul_list *next; 4675574Smx205022 uint32_t ref_cnt; 4685574Smx205022 ether_addr_t mul_addr; 4695574Smx205022 }mul_item, *pmul_item; 4705574Smx205022 4715574Smx205022 /* 4725574Smx205022 * Describes one chunk of allocated DMA-able memory 4735574Smx205022 * 4745574Smx205022 * In some cases, this is a single chunk as allocated from the system; 4755574Smx205022 * but we also use this structure to represent slices carved off such 4765574Smx205022 * a chunk. Even when we don't really need all the information, we 4775574Smx205022 * use this structure as a convenient way of correlating the various 4785574Smx205022 * ways of looking at a piece of memory (kernel VA, IO space DVMA, 4795574Smx205022 * handle+offset, etc). 4805574Smx205022 */ 4815574Smx205022 typedef struct dma_area 4825574Smx205022 { 4835574Smx205022 4845574Smx205022 caddr_t private; /* pointer to nge */ 4855574Smx205022 frtn_t rx_recycle; /* recycle function */ 4865574Smx205022 mblk_t *mp; 4875574Smx205022 ddi_acc_handle_t acc_hdl; /* handle for memory */ 4885574Smx205022 void *mem_va; /* CPU VA of memory */ 4895574Smx205022 uint32_t nslots; /* number of slots */ 4905574Smx205022 uint32_t size; /* size per slot */ 4915574Smx205022 size_t alength; /* allocated size */ 4925574Smx205022 /* >= product of above */ 4935574Smx205022 ddi_dma_handle_t dma_hdl; /* DMA handle */ 4945574Smx205022 offset_t offset; /* relative to handle */ 4955574Smx205022 ddi_dma_cookie_t cookie; /* associated cookie */ 4965574Smx205022 uint32_t ncookies; 4975574Smx205022 uint32_t signature; /* buffer signature */ 4985574Smx205022 /* for deciding to free */ 4995574Smx205022 /* or to reuse buffers */ 5005574Smx205022 boolean_t rx_delivered; /* hold by upper layer */ 5015574Smx205022 struct dma_area *next; 5025574Smx205022 } dma_area_t; 5035574Smx205022 5045574Smx205022 #define HOST_OWN 0x00000000 5055574Smx205022 #define CONTROLER_OWN 0x00000001 5065574Smx205022 #define NGE_END_PACKET 0x00000002 5075574Smx205022 5085574Smx205022 5095574Smx205022 typedef struct nge_dmah_node 5105574Smx205022 { 5115574Smx205022 struct nge_dmah_node *next; 5125574Smx205022 ddi_dma_handle_t hndl; 5135574Smx205022 } nge_dmah_node_t; 5145574Smx205022 5155574Smx205022 typedef struct nge_dmah_list 5165574Smx205022 { 5175574Smx205022 nge_dmah_node_t *head; 5185574Smx205022 nge_dmah_node_t *tail; 5195574Smx205022 } nge_dmah_list_t; 5205574Smx205022 5215574Smx205022 /* 5225574Smx205022 * Software version of the Recv Descriptor 5235574Smx205022 * There's one of these for each recv buffer (up to 512 per ring) 5245574Smx205022 */ 5255574Smx205022 typedef struct sw_rx_sbd { 5265574Smx205022 5275574Smx205022 dma_area_t desc; /* (const) related h/w */ 5285574Smx205022 /* descriptor area */ 5295574Smx205022 dma_area_t *bufp; /* (const) related */ 5305574Smx205022 /* buffer area */ 5315574Smx205022 uint8_t flags; 5325574Smx205022 } sw_rx_sbd_t; 5335574Smx205022 5345574Smx205022 /* 5355574Smx205022 * Software version of the send Buffer Descriptor 5365574Smx205022 * There's one of these for each send buffer (up to 512 per ring) 5375574Smx205022 */ 5385574Smx205022 typedef struct sw_tx_sbd { 5395574Smx205022 5405574Smx205022 dma_area_t desc; /* (const) related h/w */ 5415574Smx205022 /* descriptor area */ 5425574Smx205022 dma_area_t pbuf; /* (const) related */ 5435574Smx205022 /* buffer area */ 5445574Smx205022 void (*tx_recycle)(struct sw_tx_sbd *); 5455574Smx205022 uint32_t flags; 5465574Smx205022 mblk_t *mp; /* related mblk, if any */ 5475574Smx205022 nge_dmah_list_t mp_hndl; 5485574Smx205022 uint32_t frags; 5495574Smx205022 uint32_t ncookies; /* dma cookie number */ 5505574Smx205022 5515574Smx205022 } sw_tx_sbd_t; 5525574Smx205022 5535574Smx205022 /* 5545574Smx205022 * Software Receive Buffer (Producer) Ring Control Block 5555574Smx205022 * There's one of these for each receiver producer ring (up to 3), 5565574Smx205022 * but each holds buffers of a different size. 5575574Smx205022 */ 5585574Smx205022 typedef struct buff_ring { 5595574Smx205022 5605574Smx205022 uint64_t nslots; /* descriptor area */ 5615574Smx205022 struct nge *ngep; /* (const) containing */ 5625574Smx205022 /* driver soft state */ 5635574Smx205022 /* initialise same */ 5645574Smx205022 uint64_t rx_hold; 5655574Smx205022 sw_rx_sbd_t *sw_rbds; /* software descriptors */ 5665574Smx205022 sw_rx_sbd_t *free_rbds; /* free ring */ 5675574Smx205022 dma_area_t *free_list; /* available buffer queue */ 5685574Smx205022 dma_area_t *recycle_list; /* recycling buffer queue */ 5695574Smx205022 kmutex_t recycle_lock[1]; 5705574Smx205022 uint32_t buf_sign; 5715574Smx205022 boolean_t rx_bcopy; 5725574Smx205022 } buff_ring_t; 5735574Smx205022 5745574Smx205022 /* 5755574Smx205022 * Software Receive (Return) Ring Control Block 5765574Smx205022 * There's one of these for each receiver return ring (up to 16). 5775574Smx205022 */ 5785574Smx205022 typedef struct recv_ring { 5795574Smx205022 /* 5805574Smx205022 * The elements flagged (const) in the comments below are 5815574Smx205022 * set up once during initialiation and thereafter unchanged. 5825574Smx205022 */ 5835574Smx205022 dma_area_t desc; /* (const) related h/w */ 5845574Smx205022 /* descriptor area */ 5855574Smx205022 struct nge *ngep; /* (const) containing */ 5865574Smx205022 /* driver soft state */ 5875574Smx205022 uint16_t prod_index; /* (const) ptr to h/w */ 5885574Smx205022 /* "producer index" */ 5895574Smx205022 mac_resource_handle_t handle; 5905574Smx205022 } recv_ring_t; 5915574Smx205022 5925574Smx205022 5935574Smx205022 5945574Smx205022 /* 5955574Smx205022 * Software Send Ring Control Block 5965574Smx205022 * There's one of these for each of (up to) 1 send rings 5975574Smx205022 */ 5985574Smx205022 typedef struct send_ring { 5995574Smx205022 /* 6005574Smx205022 * The elements flagged (const) in the comments below are 6015574Smx205022 * set up once during initialiation and thereafter unchanged. 6025574Smx205022 */ 6035574Smx205022 dma_area_t desc; /* (const) related h/w */ 6045574Smx205022 /* descriptor area */ 6055574Smx205022 dma_area_t buf[NGE_SEND_SLOTS_BUF]; 6065574Smx205022 /* buffer area(s) */ 6075574Smx205022 struct nge *ngep; /* (const) containing */ 6085574Smx205022 /* driver soft state */ 6095574Smx205022 6105574Smx205022 uint64_t tx_hwmark; 6115574Smx205022 uint64_t tx_lwmark; 6125574Smx205022 6135574Smx205022 /* 6145574Smx205022 * The tx_lock must be held when updating 6155574Smx205022 * the s/w producer index 6165574Smx205022 * (tx_next) 6175574Smx205022 */ 6185574Smx205022 kmutex_t tx_lock[1]; /* serialize h/w update */ 6195574Smx205022 uint64_t tx_next; /* next slot to use */ 6205574Smx205022 uint64_t tx_flow; 6215574Smx205022 6225574Smx205022 /* 6235574Smx205022 * These counters/indexes are manipulated in the transmit 6245574Smx205022 * path using atomics rather than mutexes for speed 6255574Smx205022 */ 6265574Smx205022 uint64_t tx_free; /* # of slots available */ 6275574Smx205022 6285574Smx205022 /* 6295574Smx205022 * index (tc_next). 6305574Smx205022 */ 6315574Smx205022 kmutex_t tc_lock[1]; 6325574Smx205022 uint64_t tc_next; /* next slot to recycle */ 6335574Smx205022 /* ("consumer index") */ 6345574Smx205022 6355574Smx205022 sw_tx_sbd_t *sw_sbds; /* software descriptors */ 6365574Smx205022 6375574Smx205022 kmutex_t dmah_lock; 6385574Smx205022 nge_dmah_list_t dmah_free; 6395574Smx205022 nge_dmah_node_t dmahndl[NGE_MAX_DMA_HDR]; 6405574Smx205022 6415574Smx205022 } send_ring_t; 6425574Smx205022 6435574Smx205022 6445574Smx205022 typedef struct { 6455574Smx205022 uint32_t businfo; /* from private reg */ 6465574Smx205022 uint16_t command; /* saved during attach */ 6475574Smx205022 6485574Smx205022 uint16_t vendor; /* vendor-id */ 6495574Smx205022 uint16_t device; /* device-id */ 6505574Smx205022 uint16_t subven; /* subsystem-vendor-id */ 6515574Smx205022 uint16_t subdev; /* subsystem-id */ 6525574Smx205022 uint8_t class_code; 6535574Smx205022 uint8_t revision; /* revision-id */ 6545574Smx205022 uint8_t clsize; /* cache-line-size */ 6555574Smx205022 uint8_t latency; /* latency-timer */ 6565574Smx205022 uint8_t flags; 6575574Smx205022 6585574Smx205022 uint16_t phy_type; /* Fiber module type */ 6595574Smx205022 uint64_t hw_mac_addr; /* from chip register */ 6605574Smx205022 nge_mac_addr_t vendor_addr; /* transform of same */ 6615574Smx205022 } chip_info_t; 6625574Smx205022 6635574Smx205022 6645574Smx205022 typedef struct { 6655574Smx205022 offset_t index; 6665574Smx205022 char *name; 6675574Smx205022 } nge_ksindex_t; 6685574Smx205022 6695574Smx205022 typedef struct { 6705574Smx205022 uint64_t tso_err_mss; 6715574Smx205022 uint64_t tso_dis; 6725574Smx205022 uint64_t tso_err_nosum; 6735574Smx205022 uint64_t tso_err_hov; 6745574Smx205022 uint64_t tso_err_huf; 6755574Smx205022 uint64_t tso_err_l2; 6765574Smx205022 uint64_t tso_err_ip; 6775574Smx205022 uint64_t tso_err_l4; 6785574Smx205022 uint64_t tso_err_tcp; 6795574Smx205022 uint64_t hsum_err_ip; 6805574Smx205022 uint64_t hsum_err_l4; 6815574Smx205022 }fe_statistics_t; 6825574Smx205022 6835574Smx205022 /* 6845574Smx205022 * statistics parameters to tune the driver 6855574Smx205022 */ 6865574Smx205022 typedef struct { 6875574Smx205022 uint64_t intr_count; 6885574Smx205022 uint64_t intr_lval; 6895574Smx205022 uint64_t recv_realloc; 6905574Smx205022 uint64_t poll_time; 6915574Smx205022 uint64_t recy_free; 6925574Smx205022 uint64_t recv_count; 6935574Smx205022 uint64_t xmit_count; 6945574Smx205022 uint64_t obytes; 6955574Smx205022 uint64_t rbytes; 6965574Smx205022 uint64_t mp_alloc_err; 6975574Smx205022 uint64_t dma_alloc_err; 6985574Smx205022 uint64_t kmem_alloc_err; 6995574Smx205022 uint64_t load_context; 7005574Smx205022 uint64_t ip_hwsum_err; 7015574Smx205022 uint64_t tcp_hwsum_err; 7025574Smx205022 uint64_t rx_nobuffer; 7035574Smx205022 uint64_t rx_err; 7045574Smx205022 uint64_t tx_stop_err; 7055574Smx205022 uint64_t tx_stall; 7065574Smx205022 uint64_t tx_rsrv_fail; 7075574Smx205022 uint64_t tx_resched; 7085574Smx205022 fe_statistics_t fe_err; 7095574Smx205022 }nge_sw_statistics_t; 7105574Smx205022 7115574Smx205022 typedef struct { 7125574Smx205022 nge_hw_statistics_t hw_statistics; 7135574Smx205022 nge_sw_statistics_t sw_statistics; 7145574Smx205022 }nge_statistics_t; 7155574Smx205022 7165574Smx205022 struct nge_desc_attr { 7175574Smx205022 7185574Smx205022 size_t rxd_size; 7195574Smx205022 size_t txd_size; 7205574Smx205022 7215574Smx205022 ddi_dma_attr_t *dma_attr; 7225574Smx205022 ddi_dma_attr_t *tx_dma_attr; 7235574Smx205022 7245574Smx205022 void (*rxd_fill)(void *, const ddi_dma_cookie_t *, size_t); 7255574Smx205022 uint32_t (*rxd_check)(const void *, size_t *); 7265574Smx205022 7275574Smx205022 void (*txd_fill)(void *, const ddi_dma_cookie_t *, size_t, 7285574Smx205022 uint32_t, boolean_t); 7295574Smx205022 7305574Smx205022 uint32_t (*txd_check)(const void *, size_t *); 7315574Smx205022 }; 7325574Smx205022 7335574Smx205022 typedef struct nge_desc_attr nge_desc_attr_t; 7345574Smx205022 7355574Smx205022 /* 7365574Smx205022 * Structure used to hold the device-specific config parameters. 7375574Smx205022 * The setting of such parameters may not consistent with the 7385574Smx205022 * hardware feature of the device. It's used for software purpose. 7395574Smx205022 */ 7405574Smx205022 typedef struct nge_dev_spec_param { 7415574Smx205022 boolean_t msi; /* specifies msi support */ 7425574Smx205022 boolean_t msi_x; /* specifies msi_x support */ 7435574Smx205022 boolean_t vlan; /* specifies vlan support */ 7445574Smx205022 boolean_t tx_pause_frame; /* specifies tx pause frame support */ 7455574Smx205022 boolean_t rx_pause_frame; /* specifies rx pause frame support */ 7465574Smx205022 boolean_t jumbo; /* jumbo frame support */ 7475574Smx205022 boolean_t tx_rx_64byte; /* set the max tx/rx prd fetch size */ 7485574Smx205022 boolean_t rx_hw_checksum; /* specifies tx hw checksum feature */ 7495574Smx205022 uint32_t tx_hw_checksum; /* specifies rx hw checksum feature */ 7505574Smx205022 uint32_t desc_type; /* specifies descriptor type */ 7515574Smx205022 uint32_t rx_desc_num; /* specifies rx descriptor number */ 7525574Smx205022 uint32_t tx_desc_num; /* specifies tx descriptor number */ 7535574Smx205022 uint32_t nge_split; /* specifies the split number */ 7545574Smx205022 } nge_dev_spec_param_t; 7555574Smx205022 7565574Smx205022 typedef struct nge { 7575574Smx205022 /* 7585574Smx205022 * These fields are set by attach() and unchanged thereafter ... 7595574Smx205022 */ 7605574Smx205022 dev_info_t *devinfo; /* device instance */ 7615574Smx205022 mac_handle_t mh; /* mac module handle */ 7625574Smx205022 chip_info_t chipinfo; 7635574Smx205022 ddi_acc_handle_t cfg_handle; /* DDI I/O handle */ 7645574Smx205022 ddi_acc_handle_t io_handle; /* DDI I/O handle */ 7655574Smx205022 void *io_regs; /* mapped registers */ 7665574Smx205022 7675574Smx205022 ddi_periodic_t periodic_id; /* periodical callback */ 7685574Smx205022 uint32_t factotum_flag; 7695574Smx205022 ddi_softint_handle_t factotum_hdl; /* factotum callback */ 7705574Smx205022 ddi_softint_handle_t resched_hdl; /* reschedule callback */ 7715574Smx205022 uint_t soft_pri; 7725574Smx205022 7735574Smx205022 ddi_intr_handle_t *htable; /* for array of interrupts */ 7745574Smx205022 int intr_type; /* type of interrupt */ 7755574Smx205022 int intr_actual_cnt; /* alloc intrs count */ 7765574Smx205022 int intr_req_cnt; /* request intrs count */ 7775574Smx205022 uint_t intr_pri; /* interrupt priority */ 7785574Smx205022 int intr_cap; /* interrupt capabilities */ 7795574Smx205022 7805574Smx205022 uint32_t progress; /* attach tracking */ 7815574Smx205022 uint32_t debug; /* flag to debug function */ 7825574Smx205022 7835574Smx205022 char ifname[8]; /* "nge0" ... "nge999" */ 7845574Smx205022 7855574Smx205022 7865574Smx205022 enum nge_mac_state nge_mac_state; /* definitions above */ 7875574Smx205022 enum nge_chip_state nge_chip_state; /* definitions above */ 7885574Smx205022 boolean_t promisc; 7895574Smx205022 boolean_t suspended; 7905574Smx205022 7915574Smx205022 int resched_needed; 7925574Smx205022 uint32_t default_mtu; 7935574Smx205022 uint32_t max_sdu; 7945574Smx205022 uint32_t buf_size; 7955574Smx205022 uint32_t rx_desc; 7965574Smx205022 uint32_t tx_desc; 7975574Smx205022 uint32_t rx_buf; 7985574Smx205022 uint32_t nge_split; 7995574Smx205022 uint32_t watchdog; 8005574Smx205022 uint32_t lowmem_mode; 8015574Smx205022 8025574Smx205022 8035574Smx205022 /* 8045574Smx205022 * Runtime read-write data starts here ... 8055574Smx205022 * 1 Receive Rings 8065574Smx205022 * 1 Send Rings 8075574Smx205022 * 8085574Smx205022 * Note: they're not necessarily all used. 8095574Smx205022 */ 8105574Smx205022 struct buff_ring buff[1]; 8115574Smx205022 struct recv_ring recv[1]; 8125574Smx205022 struct send_ring send[1]; 8135574Smx205022 8145574Smx205022 8155574Smx205022 kmutex_t genlock[1]; 8165574Smx205022 krwlock_t rwlock[1]; 8175574Smx205022 kmutex_t softlock[1]; 8185574Smx205022 uint32_t intr_masks; 8195574Smx205022 boolean_t poll; 8205574Smx205022 boolean_t ch_intr_mode; 8215574Smx205022 uint32_t recv_count; 8225574Smx205022 uint32_t poll_time; 8235574Smx205022 uint32_t sw_intr_intv; 8245574Smx205022 nge_mac_addr_t cur_uni_addr; 8255574Smx205022 uint32_t rx_datahwm; 8265574Smx205022 uint32_t rx_prdlwm; 8275574Smx205022 uint32_t rx_prdhwm; 8285574Smx205022 uint32_t rx_def; 8295574Smx205022 uint32_t desc_mode; 8305574Smx205022 8315574Smx205022 mul_item *pcur_mulist; 8325574Smx205022 nge_mac_addr_t cur_mul_addr; 8335574Smx205022 nge_mac_addr_t cur_mul_mask; 8345574Smx205022 8355574Smx205022 nge_desc_attr_t desc_attr; 8365574Smx205022 8375574Smx205022 /* 8385574Smx205022 * Link state data (protected by genlock) 8395574Smx205022 */ 8405574Smx205022 int32_t link_state; /* See GLD #defines */ 8415574Smx205022 uint32_t stall_cknum; /* Stall check number */ 8425574Smx205022 8435574Smx205022 uint32_t phy_xmii_addr; 8445574Smx205022 uint32_t phy_id; 8455574Smx205022 uint32_t phy_mode; 8465574Smx205022 const phys_ops_t *physops; 8475574Smx205022 uint16_t phy_gen_status; 8485574Smx205022 8495574Smx205022 uint32_t param_loop_mode; 8505574Smx205022 8515574Smx205022 /* 8525574Smx205022 * NDD parameters (protected by genlock) 8535574Smx205022 */ 8545574Smx205022 caddr_t nd_data_p; 8555574Smx205022 nd_param_t nd_params[PARAM_COUNT]; 8565574Smx205022 8575574Smx205022 kstat_t *nge_kstats[NGE_KSTAT_COUNT]; 8585574Smx205022 nge_statistics_t statistics; 8595574Smx205022 8605574Smx205022 nge_dev_spec_param_t dev_spec_param; 8615574Smx205022 8625574Smx205022 } nge_t; 8635574Smx205022 8645574Smx205022 extern const nge_ksindex_t nge_statistics[]; 8655574Smx205022 8665574Smx205022 /* 8675574Smx205022 * Shorthand for the NDD parameters 8685574Smx205022 */ 8695574Smx205022 #define param_adv_autoneg nd_params[PARAM_ADV_AUTONEG_CAP].ndp_val 8705574Smx205022 #define param_adv_pause nd_params[PARAM_ADV_PAUSE_CAP].ndp_val 8715574Smx205022 #define param_adv_asym_pause nd_params[PARAM_ADV_ASYM_PAUSE_CAP].ndp_val 8725574Smx205022 #define param_adv_1000fdx nd_params[PARAM_ADV_1000FDX_CAP].ndp_val 8735574Smx205022 #define param_adv_1000hdx nd_params[PARAM_ADV_1000HDX_CAP].ndp_val 8745574Smx205022 #define param_adv_100fdx nd_params[PARAM_ADV_100FDX_CAP].ndp_val 8755574Smx205022 #define param_adv_100hdx nd_params[PARAM_ADV_100HDX_CAP].ndp_val 8765574Smx205022 #define param_adv_10fdx nd_params[PARAM_ADV_10FDX_CAP].ndp_val 8775574Smx205022 #define param_adv_10hdx nd_params[PARAM_ADV_10HDX_CAP].ndp_val 8785574Smx205022 8795574Smx205022 #define param_lp_autoneg nd_params[PARAM_LP_AUTONEG_CAP].ndp_val 8805574Smx205022 #define param_lp_pause nd_params[PARAM_LP_PAUSE_CAP].ndp_val 8815574Smx205022 #define param_lp_asym_pause nd_params[PARAM_LP_ASYM_PAUSE_CAP].ndp_val 8825574Smx205022 #define param_lp_1000fdx nd_params[PARAM_LP_1000FDX_CAP].ndp_val 8835574Smx205022 #define param_lp_1000hdx nd_params[PARAM_LP_1000HDX_CAP].ndp_val 8845574Smx205022 #define param_lp_100fdx nd_params[PARAM_LP_100FDX_CAP].ndp_val 8855574Smx205022 #define param_lp_100hdx nd_params[PARAM_LP_100HDX_CAP].ndp_val 8865574Smx205022 #define param_lp_10fdx nd_params[PARAM_LP_10FDX_CAP].ndp_val 8875574Smx205022 #define param_lp_10hdx nd_params[PARAM_LP_10HDX_CAP].ndp_val 8885574Smx205022 8895574Smx205022 #define param_link_up nd_params[PARAM_LINK_STATUS].ndp_val 8905574Smx205022 #define param_link_speed nd_params[PARAM_LINK_SPEED].ndp_val 8915574Smx205022 #define param_link_duplex nd_params[PARAM_LINK_DUPLEX].ndp_val 8925574Smx205022 8935574Smx205022 #define param_link_autoneg nd_params[PARAM_LINK_AUTONEG].ndp_val 8945574Smx205022 #define param_link_rx_pause nd_params[PARAM_LINK_RX_PAUSE].ndp_val 8955574Smx205022 #define param_link_tx_pause nd_params[PARAM_LINK_TX_PAUSE].ndp_val 8965574Smx205022 8975574Smx205022 #define param_loop_mode nd_params[PARAM_LOOP_MODE].ndp_val 8985574Smx205022 8995574Smx205022 #define param_txbcopy_threshold nd_params[PARAM_TXBCOPY_THRESHOLD].ndp_val 9005574Smx205022 #define param_rxbcopy_threshold nd_params[PARAM_RXBCOPY_THRESHOLD].ndp_val 9015574Smx205022 #define param_recv_max_packet nd_params[PARAM_RECV_MAX_PACKET].ndp_val 9025574Smx205022 9035574Smx205022 /* 9045574Smx205022 * Sync a DMA area described by a dma_area_t 9055574Smx205022 */ 9065574Smx205022 #define DMA_SYNC(area, flag) ((void) ddi_dma_sync((area).dma_hdl, \ 9075574Smx205022 (area).offset, (area).alength, (flag))) 9085574Smx205022 9095574Smx205022 /* 9105574Smx205022 * Find the (kernel virtual) address of block of memory 9115574Smx205022 * described by a dma_area_t 9125574Smx205022 */ 9135574Smx205022 #define DMA_VPTR(area) ((area).mem_va) 9145574Smx205022 9155574Smx205022 /* 9165574Smx205022 * Zero a block of memory described by a dma_area_t 9175574Smx205022 */ 9185574Smx205022 #define DMA_ZERO(area) bzero(DMA_VPTR(area), (area).alength) 9195574Smx205022 9205574Smx205022 /* 9215574Smx205022 * Next/Prev value of a cyclic index 9225574Smx205022 */ 9235574Smx205022 #define NEXT(index, limit) ((index) + 1 < (limit) ? (index) + 1 : 0) 9245574Smx205022 #define PREV(index, limit) (0 == (index) ? (limit - 1) : (index) - 1) 9255574Smx205022 9265574Smx205022 #define NEXT_INDEX(ndx, num, lim)\ 9275574Smx205022 (((ndx) + (num) < (lim)) ? ((ndx) + (num)) : ((ndx) + (num) - (lim))) 9285574Smx205022 9295574Smx205022 9305574Smx205022 /* 9315574Smx205022 * Property lookups 9325574Smx205022 */ 9335574Smx205022 #define NGE_PROP_EXISTS(d, n) ddi_prop_exists(DDI_DEV_T_ANY, (d), \ 9345574Smx205022 DDI_PROP_DONTPASS, (n)) 9355574Smx205022 #define NGE_PROP_GET_INT(d, n) ddi_prop_get_int(DDI_DEV_T_ANY, (d), \ 9365574Smx205022 DDI_PROP_DONTPASS, (n), -1) 9375574Smx205022 9385574Smx205022 9395574Smx205022 /* 9405574Smx205022 * Debugging ... 9415574Smx205022 */ 9425574Smx205022 #ifdef DEBUG 9435574Smx205022 #define NGE_DEBUGGING 1 9445574Smx205022 #else 9455574Smx205022 #define NGE_DEBUGGING 0 9465574Smx205022 #endif /* DEBUG */ 9475574Smx205022 9485574Smx205022 /* 9495574Smx205022 * Bit flags in the 'debug' word ... 9505574Smx205022 */ 9515574Smx205022 #define NGE_DBG_STOP 0x00000001 /* early debug_enter() */ 9525574Smx205022 #define NGE_DBG_TRACE 0x00000002 /* general flow tracing */ 9535574Smx205022 9545574Smx205022 #define NGE_DBG_MII 0x00000010 /* low-level MII access */ 9555574Smx205022 #define NGE_DBG_CHIP 0x00000020 /* low(ish)-level code */ 9565574Smx205022 9575574Smx205022 #define NGE_DBG_RECV 0x00000100 /* receive-side code */ 9585574Smx205022 #define NGE_DBG_SEND 0x00000200 /* packet-send code */ 9595574Smx205022 9605574Smx205022 #define NGE_DBG_INIT 0x00100000 /* initialisation */ 9615574Smx205022 #define NGE_DBG_NEMO 0x00200000 /* MAC layer entry points */ 9625574Smx205022 #define NGE_DBG_STATS 0x00400000 /* statistics */ 9635574Smx205022 9645574Smx205022 #define NGE_DBG_BADIOC 0x01000000 /* unknown ioctls */ 9655574Smx205022 9665574Smx205022 #define NGE_DBG_NDD 0x10000000 /* NDD operations */ 9675574Smx205022 9685574Smx205022 9695574Smx205022 9705574Smx205022 /* 9715574Smx205022 * 'Do-if-debugging' macro. The parameter <command> should be one or more 9725574Smx205022 * C statements (but without the *final* semicolon), which will either be 9735574Smx205022 * compiled inline or completely ignored, depending on the NGE_DEBUGGING 9745574Smx205022 * compile-time flag. 9755574Smx205022 * 9765574Smx205022 * You should get a compile-time error (at least on a DEBUG build) if 9775574Smx205022 * your statement isn't actually a statement, rather than unexpected 9785574Smx205022 * run-time behaviour caused by unintended matching of if-then-elses etc. 9795574Smx205022 * 9805574Smx205022 * Note that the NGE_DDB() macro itself can only be used as a statement, 9815574Smx205022 * not an expression, and should always be followed by a semicolon. 9825574Smx205022 */ 9835574Smx205022 #if NGE_DEBUGGING 9845574Smx205022 #define NGE_DDB(command) do { \ 9855574Smx205022 { command; } \ 9865574Smx205022 _NOTE(CONSTANTCONDITION) \ 9875574Smx205022 } while (0) 9885574Smx205022 #else /* NGE_DEBUGGING */ 9895574Smx205022 #define NGE_DDB(command) 9905574Smx205022 /* 9915574Smx205022 * Old way of debugging. This is a poor way, as it leeaves empty 9925574Smx205022 * statements that cause lint to croak. 9935574Smx205022 * #define NGE_DDB(command) do { \ 9945574Smx205022 * { _NOTE(EMPTY); } \ 9955574Smx205022 * _NOTE(CONSTANTCONDITION) \ 9965574Smx205022 * } while (0) 9975574Smx205022 */ 9985574Smx205022 #endif /* NGE_DEBUGGING */ 9995574Smx205022 10005574Smx205022 /* 10015574Smx205022 * 'Internal' macros used to construct the TRACE/DEBUG macros below. 10025574Smx205022 * These provide the primitive conditional-call capability required. 10035574Smx205022 * Note: the parameter <args> is a parenthesised list of the actual 10045574Smx205022 * printf-style arguments to be passed to the debug function ... 10055574Smx205022 */ 10065574Smx205022 #define NGE_XDB(b, w, f, args) NGE_DDB(if ((b) & (w)) f args) 10075574Smx205022 #define NGE_GDB(b, args) NGE_XDB(b, nge_debug, (*nge_gdb()), args) 10085574Smx205022 #define NGE_LDB(b, args) NGE_XDB(b, ngep->debug, \ 10095574Smx205022 (*nge_db(ngep)), args) 10105574Smx205022 #define NGE_CDB(f, args) NGE_XDB(NGE_DBG, ngep->debug, f, args) 10115574Smx205022 10125574Smx205022 /* 10135574Smx205022 * Conditional-print macros. 10145574Smx205022 * 10155574Smx205022 * Define NGE_DBG to be the relevant member of the set of NGE_DBG_* values 10165574Smx205022 * above before using the NGE_GDEBUG() or NGE_DEBUG() macros. The 'G' 10175574Smx205022 * versions look at the Global debug flag word (nge_debug); the non-G 10185574Smx205022 * versions look in the per-instance data (ngep->debug) and so require a 10195574Smx205022 * variable called 'ngep' to be in scope (and initialised!) before use. 10205574Smx205022 * 10215574Smx205022 * You could redefine NGE_TRC too if you really need two different 10225574Smx205022 * flavours of debugging output in the same area of code, but I don't 10235574Smx205022 * really recommend it. 10245574Smx205022 * 10255574Smx205022 * Note: the parameter <args> is a parenthesised list of the actual 10265574Smx205022 * arguments to be passed to the debug function, usually a printf-style 10275574Smx205022 * format string and corresponding values to be formatted. 10285574Smx205022 */ 10295574Smx205022 10305574Smx205022 #define NGE_TRC NGE_DBG_TRACE 10315574Smx205022 10325574Smx205022 #define NGE_GTRACE(args) NGE_GDB(NGE_TRC, args) 10335574Smx205022 #define NGE_GDEBUG(args) NGE_GDB(NGE_DBG, args) 10345574Smx205022 #define NGE_TRACE(args) NGE_LDB(NGE_TRC, args) 10355574Smx205022 #define NGE_DEBUG(args) NGE_LDB(NGE_DBG, args) 10365574Smx205022 10375574Smx205022 /* 10385574Smx205022 * Debug-only action macros 10395574Smx205022 */ 10405574Smx205022 10415574Smx205022 10425574Smx205022 #define NGE_REPORT(args) NGE_DDB(nge_log args) 10435574Smx205022 10445574Smx205022 boolean_t nge_atomic_decrease(uint64_t *count_p, uint64_t n); 10455574Smx205022 void nge_atomic_increase(uint64_t *count_p, uint64_t n); 10465574Smx205022 10475574Smx205022 int nge_alloc_dma_mem(nge_t *ngep, size_t memsize, 10485574Smx205022 ddi_device_acc_attr_t *attr_p, uint_t dma_flags, dma_area_t *dma_p); 10495574Smx205022 void nge_free_dma_mem(dma_area_t *dma_p); 10505574Smx205022 int nge_restart(nge_t *ngep); 10515574Smx205022 void nge_wake_factotum(nge_t *ngep); 10525574Smx205022 10535574Smx205022 uint8_t nge_reg_get8(nge_t *ngep, nge_regno_t regno); 10545574Smx205022 void nge_reg_put8(nge_t *ngep, nge_regno_t regno, uint8_t data); 10555574Smx205022 uint16_t nge_reg_get16(nge_t *ngep, nge_regno_t regno); 10565574Smx205022 void nge_reg_put16(nge_t *ngep, nge_regno_t regno, uint16_t data); 10575574Smx205022 uint32_t nge_reg_get32(nge_t *ngep, nge_regno_t regno); 10585574Smx205022 void nge_reg_put32(nge_t *ngep, nge_regno_t regno, uint32_t data); 10595574Smx205022 uint_t nge_chip_factotum(caddr_t args1, caddr_t args2); 10605574Smx205022 void nge_chip_cfg_init(nge_t *ngep, chip_info_t *infop, boolean_t reset); 10615574Smx205022 void nge_init_dev_spec_param(nge_t *ngep); 10625574Smx205022 int nge_chip_stop(nge_t *ngep, boolean_t fault); 10635574Smx205022 void nge_restore_mac_addr(nge_t *ngep); 10645574Smx205022 int nge_chip_reset(nge_t *ngep); 10655574Smx205022 int nge_chip_start(nge_t *ngep); 10665574Smx205022 void nge_chip_sync(nge_t *ngep); 10675574Smx205022 10685574Smx205022 uint_t nge_chip_intr(caddr_t arg1, caddr_t arg2); 10695574Smx205022 enum ioc_reply nge_chip_ioctl(nge_t *ngep, mblk_t *mp, struct iocblk *iocp); 10705574Smx205022 10715574Smx205022 void nge_phys_init(nge_t *ngep); 10725574Smx205022 boolean_t nge_phy_reset(nge_t *ngep); 10735574Smx205022 uint16_t nge_mii_get16(nge_t *ngep, nge_regno_t regno); 10745574Smx205022 void nge_mii_put16(nge_t *ngep, nge_regno_t regno, uint16_t data); 10755574Smx205022 10765574Smx205022 void nge_recv_recycle(caddr_t arg); 10775574Smx205022 void nge_receive(nge_t *ngep); 10785574Smx205022 10795574Smx205022 uint_t nge_reschedule(caddr_t args1, caddr_t args2); 10805574Smx205022 mblk_t *nge_m_tx(void *arg, mblk_t *mp); 10815574Smx205022 10825574Smx205022 void nge_tx_recycle(nge_t *ngep, boolean_t is_intr); 10835574Smx205022 void nge_tx_recycle_all(nge_t *ngep); 10845574Smx205022 10855574Smx205022 enum ioc_reply nge_nd_ioctl(nge_t *ngep, queue_t *wq, 10865574Smx205022 mblk_t *mp, struct iocblk *iocp); 10875574Smx205022 int nge_nd_init(nge_t *ngep); 10885574Smx205022 void nge_nd_cleanup(nge_t *ngep); 10895574Smx205022 10905574Smx205022 10915574Smx205022 void nge_init_kstats(nge_t *ngep, int instance); 10925574Smx205022 void nge_fini_kstats(nge_t *ngep); 10935574Smx205022 int nge_m_stat(void *arg, uint_t stat, uint64_t *val); 10945574Smx205022 10955574Smx205022 uint32_t nge_atomic_shl32(uint32_t *sp, uint_t count); 10965574Smx205022 10975574Smx205022 void nge_log(nge_t *ngep, const char *fmt, ...); 10985574Smx205022 void nge_problem(nge_t *ngep, const char *fmt, ...); 10995574Smx205022 void nge_error(nge_t *ngep, const char *fmt, ...); 11005574Smx205022 void 11015574Smx205022 nge_report(nge_t *ngep, uint8_t error_id); 11025574Smx205022 11035574Smx205022 void (*nge_db(nge_t *ngep))(const char *fmt, ...); 11045574Smx205022 void (*nge_gdb(void))(const char *fmt, ...); 11055574Smx205022 extern uint32_t nge_debug; 11065574Smx205022 11075574Smx205022 /* 11085574Smx205022 * DESC MODE 2 11095574Smx205022 */ 11105574Smx205022 11115574Smx205022 extern void nge_sum_rxd_fill(void *, const ddi_dma_cookie_t *, size_t); 11125574Smx205022 extern uint32_t nge_sum_rxd_check(const void *, size_t *); 11135574Smx205022 11145574Smx205022 extern void nge_sum_txd_fill(void *, const ddi_dma_cookie_t *, 11155574Smx205022 size_t, uint32_t, boolean_t); 11165574Smx205022 extern uint32_t nge_sum_txd_check(const void *, size_t *); 11175574Smx205022 11185574Smx205022 /* 11195574Smx205022 * DESC MODE 3 11205574Smx205022 */ 11215574Smx205022 11225574Smx205022 extern void nge_hot_rxd_fill(void *, const ddi_dma_cookie_t *, size_t); 11235574Smx205022 extern uint32_t nge_hot_rxd_check(const void *, size_t *); 11245574Smx205022 11255574Smx205022 extern void nge_hot_txd_fill(void *, const ddi_dma_cookie_t *, 11265574Smx205022 size_t, uint32_t, boolean_t); 11275574Smx205022 extern uint32_t nge_hot_txd_check(const void *, size_t *); 11285574Smx205022 11295574Smx205022 #ifdef __cplusplus 11305574Smx205022 } 11315574Smx205022 #endif 11325574Smx205022 11335574Smx205022 #endif /* _SYS_NGE_H */ 1134