1c7fd2ed0Sgs150176 /* 2c7fd2ed0Sgs150176 * CDDL HEADER START 3c7fd2ed0Sgs150176 * 4c7fd2ed0Sgs150176 * The contents of this file are subject to the terms of the 5ba2e4443Sseb * Common Development and Distribution License (the "License"). 6ba2e4443Sseb * You may not use this file except in compliance with the License. 7c7fd2ed0Sgs150176 * 8c7fd2ed0Sgs150176 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9c7fd2ed0Sgs150176 * or http://www.opensolaris.org/os/licensing. 10c7fd2ed0Sgs150176 * See the License for the specific language governing permissions 11c7fd2ed0Sgs150176 * and limitations under the License. 12c7fd2ed0Sgs150176 * 13c7fd2ed0Sgs150176 * When distributing Covered Code, include this CDDL HEADER in each 14c7fd2ed0Sgs150176 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15c7fd2ed0Sgs150176 * If applicable, add the following below this CDDL HEADER, with the 16c7fd2ed0Sgs150176 * fields enclosed by brackets "[]" replaced with your own identifying 17c7fd2ed0Sgs150176 * information: Portions Copyright [yyyy] [name of copyright owner] 18c7fd2ed0Sgs150176 * 19c7fd2ed0Sgs150176 * CDDL HEADER END 20c7fd2ed0Sgs150176 */ 21c7fd2ed0Sgs150176 /* 227b114c4bSWinson Wang - Sun Microsystems - Beijing China * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23c7fd2ed0Sgs150176 * Use is subject to license terms. 24c7fd2ed0Sgs150176 */ 25c7fd2ed0Sgs150176 26c7fd2ed0Sgs150176 #ifndef _RGE_H 27c7fd2ed0Sgs150176 #define _RGE_H 28c7fd2ed0Sgs150176 29c7fd2ed0Sgs150176 #ifdef __cplusplus 30c7fd2ed0Sgs150176 extern "C" { 31c7fd2ed0Sgs150176 #endif 32c7fd2ed0Sgs150176 33c7fd2ed0Sgs150176 #include <sys/types.h> 34c7fd2ed0Sgs150176 #include <sys/stream.h> 35c7fd2ed0Sgs150176 #include <sys/strsun.h> 36c7fd2ed0Sgs150176 #include <sys/strsubr.h> 37c7fd2ed0Sgs150176 #include <sys/stat.h> 38c7fd2ed0Sgs150176 #include <sys/pci.h> 393a84c50fSWinson Wang - Sun Microsystems - Beijing China #include <sys/pci_cap.h> 40c7fd2ed0Sgs150176 #include <sys/note.h> 41c7fd2ed0Sgs150176 #include <sys/modctl.h> 42c7fd2ed0Sgs150176 #include <sys/kstat.h> 43c7fd2ed0Sgs150176 #include <sys/ethernet.h> 44c7fd2ed0Sgs150176 #include <sys/vlan.h> 45c7fd2ed0Sgs150176 #include <sys/errno.h> 46c7fd2ed0Sgs150176 #include <sys/dlpi.h> 47c7fd2ed0Sgs150176 #include <sys/devops.h> 48c7fd2ed0Sgs150176 #include <sys/debug.h> 49c7fd2ed0Sgs150176 #include <sys/conf.h> 50c7fd2ed0Sgs150176 51c7fd2ed0Sgs150176 #include <netinet/ip6.h> 52c7fd2ed0Sgs150176 #include <inet/common.h> 53c7fd2ed0Sgs150176 #include <inet/ip.h> 54c7fd2ed0Sgs150176 #include <inet/mi.h> 55c7fd2ed0Sgs150176 #include <inet/nd.h> 56c7fd2ed0Sgs150176 #include <sys/pattr.h> 57c7fd2ed0Sgs150176 58c7fd2ed0Sgs150176 #include <sys/ddi.h> 59c7fd2ed0Sgs150176 #include <sys/sunddi.h> 60c7fd2ed0Sgs150176 61da14cebeSEric Cheng #include <sys/mac_provider.h> 62ba2e4443Sseb #include <sys/mac_ether.h> 63c7fd2ed0Sgs150176 64c7fd2ed0Sgs150176 /* 65c7fd2ed0Sgs150176 * Reconfiguring the network devices requires the net_config privilege 66aa817493Sgs150176 * in Solaris 10+. 67c7fd2ed0Sgs150176 */ 68c7fd2ed0Sgs150176 extern int secpolicy_net_config(const cred_t *, boolean_t); 69c7fd2ed0Sgs150176 70c7fd2ed0Sgs150176 #include <sys/netlb.h> /* originally from cassini */ 71c7fd2ed0Sgs150176 #include <sys/miiregs.h> /* by fjlite out of intel */ 72c7fd2ed0Sgs150176 73c7fd2ed0Sgs150176 #include "rge_hw.h" 74aa817493Sgs150176 75c7fd2ed0Sgs150176 /* 76c7fd2ed0Sgs150176 * Name of the driver 77c7fd2ed0Sgs150176 */ 78c7fd2ed0Sgs150176 #define RGE_DRIVER_NAME "rge" 79c7fd2ed0Sgs150176 80c7fd2ed0Sgs150176 /* 81c7fd2ed0Sgs150176 * The driver supports the NDD ioctls ND_GET/ND_SET, and the loopback 82c7fd2ed0Sgs150176 * ioctls LB_GET_INFO_SIZE/LB_GET_INFO/LB_GET_MODE/LB_SET_MODE 83c7fd2ed0Sgs150176 * 84c7fd2ed0Sgs150176 * These are the values to use with LD_SET_MODE. 85c7fd2ed0Sgs150176 */ 86c7fd2ed0Sgs150176 #define RGE_LOOP_NONE 0 87c7fd2ed0Sgs150176 #define RGE_LOOP_INTERNAL_PHY 1 88c7fd2ed0Sgs150176 #define RGE_LOOP_INTERNAL_MAC 2 89c7fd2ed0Sgs150176 90c7fd2ed0Sgs150176 /* 91c7fd2ed0Sgs150176 * RGE-specific ioctls ... 92c7fd2ed0Sgs150176 */ 93c7fd2ed0Sgs150176 #define RGE_IOC ((((('R' << 8) + 'G') << 8) + 'E') << 8) 94c7fd2ed0Sgs150176 95c7fd2ed0Sgs150176 /* 96c7fd2ed0Sgs150176 * PHY register read/write ioctls, used by cable test software 97c7fd2ed0Sgs150176 */ 98c7fd2ed0Sgs150176 #define RGE_MII_READ (RGE_IOC|1) 99c7fd2ed0Sgs150176 #define RGE_MII_WRITE (RGE_IOC|2) 100c7fd2ed0Sgs150176 101c7fd2ed0Sgs150176 struct rge_mii_rw { 102c7fd2ed0Sgs150176 uint32_t mii_reg; /* PHY register number [0..31] */ 103c7fd2ed0Sgs150176 uint32_t mii_data; /* data to write/data read */ 104c7fd2ed0Sgs150176 }; 105c7fd2ed0Sgs150176 106c7fd2ed0Sgs150176 /* 107c7fd2ed0Sgs150176 * These diagnostic IOCTLS are enabled only in DEBUG drivers 108c7fd2ed0Sgs150176 */ 109c7fd2ed0Sgs150176 #define RGE_DIAG (RGE_IOC|10) /* currently a no-op */ 110c7fd2ed0Sgs150176 #define RGE_PEEK (RGE_IOC|11) 111c7fd2ed0Sgs150176 #define RGE_POKE (RGE_IOC|12) 112c7fd2ed0Sgs150176 #define RGE_PHY_RESET (RGE_IOC|13) 113c7fd2ed0Sgs150176 #define RGE_SOFT_RESET (RGE_IOC|14) 114c7fd2ed0Sgs150176 #define RGE_HARD_RESET (RGE_IOC|15) 115c7fd2ed0Sgs150176 116c7fd2ed0Sgs150176 typedef struct { 117c7fd2ed0Sgs150176 uint64_t pp_acc_size; /* in bytes: 1,2,4,8 */ 118c7fd2ed0Sgs150176 uint64_t pp_acc_space; /* See #defines below */ 119c7fd2ed0Sgs150176 uint64_t pp_acc_offset; 120c7fd2ed0Sgs150176 uint64_t pp_acc_data; /* output for peek */ 121c7fd2ed0Sgs150176 /* input for poke */ 122c7fd2ed0Sgs150176 } rge_peekpoke_t; 123c7fd2ed0Sgs150176 124c7fd2ed0Sgs150176 #define RGE_PP_SPACE_CFG 0 /* PCI config space */ 125c7fd2ed0Sgs150176 #define RGE_PP_SPACE_REG 1 /* PCI memory space */ 126c7fd2ed0Sgs150176 #define RGE_PP_SPACE_MII 2 /* PHY's MII registers */ 127c7fd2ed0Sgs150176 #define RGE_PP_SPACE_RGE 3 /* driver's soft state */ 128c7fd2ed0Sgs150176 #define RGE_PP_SPACE_TXDESC 4 /* TX descriptors */ 129c7fd2ed0Sgs150176 #define RGE_PP_SPACE_TXBUFF 5 /* TX buffers */ 130c7fd2ed0Sgs150176 #define RGE_PP_SPACE_RXDESC 6 /* RX descriptors */ 131c7fd2ed0Sgs150176 #define RGE_PP_SPACE_RXBUFF 7 /* RX buffers */ 132c7fd2ed0Sgs150176 #define RGE_PP_SPACE_STATISTICS 8 /* statistics block */ 133c7fd2ed0Sgs150176 134c7fd2ed0Sgs150176 /* 135c7fd2ed0Sgs150176 * RTL8169 CRC poly 136c7fd2ed0Sgs150176 */ 137c7fd2ed0Sgs150176 #define RGE_HASH_POLY 0x04C11DB7 /* 0x04C11DB6 */ 138c7fd2ed0Sgs150176 #define RGE_HASH_CRC 0xFFFFFFFFU 139c7fd2ed0Sgs150176 #define RGE_MCAST_BUF_SIZE 64 /* multicast hash table size in bits */ 140c7fd2ed0Sgs150176 141c7fd2ed0Sgs150176 /* 142c7fd2ed0Sgs150176 * Rx/Tx buffer parameters 143c7fd2ed0Sgs150176 */ 144c7fd2ed0Sgs150176 #define RGE_BUF_SLOTS 2048 145c7fd2ed0Sgs150176 #define RGE_RECV_COPY_SIZE 256 146c7fd2ed0Sgs150176 #define RGE_HEADROOM 6 147c7fd2ed0Sgs150176 148c7fd2ed0Sgs150176 /* 149c7fd2ed0Sgs150176 * Driver chip operation parameters 150c7fd2ed0Sgs150176 */ 151c7fd2ed0Sgs150176 #define RGE_CYCLIC_PERIOD (1000000000) /* ~1s */ 152c7fd2ed0Sgs150176 #define CHIP_RESET_LOOP 1000 15352643194Sgs150176 #define PHY_RESET_LOOP 10 154c7fd2ed0Sgs150176 #define STATS_DUMP_LOOP 1000 155c7fd2ed0Sgs150176 #define RXBUFF_FREE_LOOP 1000 156c7fd2ed0Sgs150176 #define RGE_RX_INT_TIME 128 157c7fd2ed0Sgs150176 #define RGE_RX_INT_PKTS 8 158c7fd2ed0Sgs150176 159c7fd2ed0Sgs150176 /* 160c7fd2ed0Sgs150176 * Named Data (ND) Parameter Management Structure 161c7fd2ed0Sgs150176 */ 162c7fd2ed0Sgs150176 typedef struct { 163c7fd2ed0Sgs150176 int ndp_info; 164c7fd2ed0Sgs150176 int ndp_min; 165c7fd2ed0Sgs150176 int ndp_max; 166c7fd2ed0Sgs150176 int ndp_val; 167c7fd2ed0Sgs150176 char *ndp_name; 168c7fd2ed0Sgs150176 } nd_param_t; /* 0x18 (24) bytes */ 169c7fd2ed0Sgs150176 170c7fd2ed0Sgs150176 /* 171c7fd2ed0Sgs150176 * NDD parameter indexes, divided into: 172c7fd2ed0Sgs150176 * 173c7fd2ed0Sgs150176 * read-only parameters describing the hardware's capabilities 174c7fd2ed0Sgs150176 * read-write parameters controlling the advertised capabilities 175c7fd2ed0Sgs150176 * read-only parameters describing the partner's capabilities 176c7fd2ed0Sgs150176 * read-only parameters describing the link state 177c7fd2ed0Sgs150176 */ 178c7fd2ed0Sgs150176 enum { 179c7fd2ed0Sgs150176 PARAM_AUTONEG_CAP = 0, 180c7fd2ed0Sgs150176 PARAM_PAUSE_CAP, 181c7fd2ed0Sgs150176 PARAM_ASYM_PAUSE_CAP, 182c7fd2ed0Sgs150176 PARAM_1000FDX_CAP, 183c7fd2ed0Sgs150176 PARAM_1000HDX_CAP, 184c7fd2ed0Sgs150176 PARAM_100T4_CAP, 185c7fd2ed0Sgs150176 PARAM_100FDX_CAP, 186c7fd2ed0Sgs150176 PARAM_100HDX_CAP, 187c7fd2ed0Sgs150176 PARAM_10FDX_CAP, 188c7fd2ed0Sgs150176 PARAM_10HDX_CAP, 189c7fd2ed0Sgs150176 190c7fd2ed0Sgs150176 PARAM_ADV_AUTONEG_CAP, 191c7fd2ed0Sgs150176 PARAM_ADV_PAUSE_CAP, 192c7fd2ed0Sgs150176 PARAM_ADV_ASYM_PAUSE_CAP, 193c7fd2ed0Sgs150176 PARAM_ADV_1000FDX_CAP, 194c7fd2ed0Sgs150176 PARAM_ADV_1000HDX_CAP, 195c7fd2ed0Sgs150176 PARAM_ADV_100T4_CAP, 196c7fd2ed0Sgs150176 PARAM_ADV_100FDX_CAP, 197c7fd2ed0Sgs150176 PARAM_ADV_100HDX_CAP, 198c7fd2ed0Sgs150176 PARAM_ADV_10FDX_CAP, 199c7fd2ed0Sgs150176 PARAM_ADV_10HDX_CAP, 200c7fd2ed0Sgs150176 201c7fd2ed0Sgs150176 PARAM_LINK_STATUS, 202c7fd2ed0Sgs150176 PARAM_LINK_SPEED, 203c7fd2ed0Sgs150176 PARAM_LINK_DUPLEX, 204c7fd2ed0Sgs150176 205c7fd2ed0Sgs150176 PARAM_LOOP_MODE, 206c7fd2ed0Sgs150176 207c7fd2ed0Sgs150176 PARAM_COUNT 208c7fd2ed0Sgs150176 }; 209c7fd2ed0Sgs150176 210c7fd2ed0Sgs150176 enum rge_chip_state { 211c7fd2ed0Sgs150176 RGE_CHIP_FAULT = -2, /* fault, need reset */ 212c7fd2ed0Sgs150176 RGE_CHIP_ERROR, /* error, want reset */ 213c7fd2ed0Sgs150176 RGE_CHIP_INITIAL, /* Initial state only */ 214c7fd2ed0Sgs150176 RGE_CHIP_RESET, /* reset, need init */ 215c7fd2ed0Sgs150176 RGE_CHIP_STOPPED, /* Tx/Rx stopped */ 216c7fd2ed0Sgs150176 RGE_CHIP_RUNNING /* with interrupts */ 217c7fd2ed0Sgs150176 }; 218c7fd2ed0Sgs150176 219c7fd2ed0Sgs150176 enum rge_mac_state { 220aa817493Sgs150176 RGE_MAC_ATTACH = 0, 221aa817493Sgs150176 RGE_MAC_STOPPED, 222c7fd2ed0Sgs150176 RGE_MAC_STARTED, 223c7fd2ed0Sgs150176 RGE_MAC_UNATTACH 224c7fd2ed0Sgs150176 }; 225c7fd2ed0Sgs150176 226c7fd2ed0Sgs150176 enum rge_sync_op { 227c7fd2ed0Sgs150176 RGE_OP_NULL, 228c7fd2ed0Sgs150176 RGE_GET_MAC, /* get mac address operation */ 229c7fd2ed0Sgs150176 RGE_SET_MAC, /* set mac address operation */ 230c7fd2ed0Sgs150176 RGE_SET_MUL, /* set multicast address op */ 231c7fd2ed0Sgs150176 RGE_SET_PROMISC /* set promisc mode */ 232c7fd2ed0Sgs150176 }; 233c7fd2ed0Sgs150176 234c7fd2ed0Sgs150176 /* 235c7fd2ed0Sgs150176 * (Internal) return values from ioctl subroutines 236c7fd2ed0Sgs150176 */ 237c7fd2ed0Sgs150176 enum ioc_reply { 238c7fd2ed0Sgs150176 IOC_INVAL = -1, /* bad, NAK with EINVAL */ 239c7fd2ed0Sgs150176 IOC_DONE, /* OK, reply sent */ 240c7fd2ed0Sgs150176 IOC_ACK, /* OK, just send ACK */ 241c7fd2ed0Sgs150176 IOC_REPLY, /* OK, just send reply */ 242c7fd2ed0Sgs150176 IOC_RESTART_ACK, /* OK, restart & ACK */ 243c7fd2ed0Sgs150176 IOC_RESTART_REPLY /* OK, restart & reply */ 244c7fd2ed0Sgs150176 }; 245c7fd2ed0Sgs150176 246c7fd2ed0Sgs150176 /* 247c7fd2ed0Sgs150176 * (Internal) enumeration of this driver's kstats 248c7fd2ed0Sgs150176 */ 249c7fd2ed0Sgs150176 enum { 2500d2a8e5eSgd78059 RGE_KSTAT_DRIVER = 0, 251c7fd2ed0Sgs150176 RGE_KSTAT_COUNT 252c7fd2ed0Sgs150176 }; 253c7fd2ed0Sgs150176 254c7fd2ed0Sgs150176 /* 255c7fd2ed0Sgs150176 * Basic data types, for clarity in distinguishing 'numbers' 256c7fd2ed0Sgs150176 * used for different purposes ... 257c7fd2ed0Sgs150176 * 258c7fd2ed0Sgs150176 * A <rge_regno_t> is a register 'address' (offset) in any one of 259c7fd2ed0Sgs150176 * various address spaces (PCI config space, PCI memory-mapped I/O 260c7fd2ed0Sgs150176 * register space, MII registers, etc). None of these exceeds 64K, 261c7fd2ed0Sgs150176 * so we could use a 16-bit representation but pointer-sized objects 262c7fd2ed0Sgs150176 * are more "natural" in most architectures; they seem to be handled 263c7fd2ed0Sgs150176 * more efficiently on SPARC and no worse on x86. 264c7fd2ed0Sgs150176 * 265c7fd2ed0Sgs150176 * RGE_REGNO_NONE represents the non-existent value in this space. 266c7fd2ed0Sgs150176 */ 267c7fd2ed0Sgs150176 typedef uintptr_t rge_regno_t; /* register # (offset) */ 268c7fd2ed0Sgs150176 #define RGE_REGNO_NONE (~(uintptr_t)0u) 269c7fd2ed0Sgs150176 270c7fd2ed0Sgs150176 /* 271c7fd2ed0Sgs150176 * Describes one chunk of allocated DMA-able memory 272c7fd2ed0Sgs150176 * 273c7fd2ed0Sgs150176 * In some cases, this is a single chunk as allocated from the system; 274c7fd2ed0Sgs150176 * but we also use this structure to represent slices carved off such 275c7fd2ed0Sgs150176 * a chunk. Even when we don't really need all the information, we 276c7fd2ed0Sgs150176 * use this structure as a convenient way of correlating the various 277c7fd2ed0Sgs150176 * ways of looking at a piece of memory (kernel VA, IO space DVMA, 278c7fd2ed0Sgs150176 * handle+offset, etc). 279c7fd2ed0Sgs150176 */ 280c7fd2ed0Sgs150176 typedef struct { 281c7fd2ed0Sgs150176 ddi_acc_handle_t acc_hdl; /* handle for memory */ 282c7fd2ed0Sgs150176 void *mem_va; /* CPU VA of memory */ 283c7fd2ed0Sgs150176 uint32_t nslots; /* number of slots */ 284c7fd2ed0Sgs150176 uint32_t size; /* size per slot */ 285c7fd2ed0Sgs150176 size_t alength; /* allocated size */ 286c7fd2ed0Sgs150176 ddi_dma_handle_t dma_hdl; /* DMA handle */ 287c7fd2ed0Sgs150176 offset_t offset; /* relative to handle */ 288c7fd2ed0Sgs150176 ddi_dma_cookie_t cookie; /* associated cookie */ 289c7fd2ed0Sgs150176 uint32_t ncookies; /* must be 1 */ 290c7fd2ed0Sgs150176 uint32_t token; /* arbitrary identifier */ 291c7fd2ed0Sgs150176 } dma_area_t; 292c7fd2ed0Sgs150176 293c7fd2ed0Sgs150176 /* 294c7fd2ed0Sgs150176 * Software version of the Receive Buffer Descriptor 295c7fd2ed0Sgs150176 */ 296c7fd2ed0Sgs150176 typedef struct { 297c7fd2ed0Sgs150176 caddr_t private; /* pointer to rge */ 298c7fd2ed0Sgs150176 dma_area_t pbuf; /* (const) related */ 299c7fd2ed0Sgs150176 /* buffer area */ 300c7fd2ed0Sgs150176 frtn_t rx_recycle; /* recycle function */ 301c7fd2ed0Sgs150176 mblk_t *mp; 302c7fd2ed0Sgs150176 } dma_buf_t; 303c7fd2ed0Sgs150176 304c7fd2ed0Sgs150176 typedef struct sw_rbd { 305c7fd2ed0Sgs150176 dma_buf_t *rx_buf; 306c7fd2ed0Sgs150176 uint8_t flags; 307c7fd2ed0Sgs150176 } sw_rbd_t; 308c7fd2ed0Sgs150176 309c7fd2ed0Sgs150176 /* 310c7fd2ed0Sgs150176 * Software version of the Send Buffer Descriptor 311c7fd2ed0Sgs150176 */ 312c7fd2ed0Sgs150176 typedef struct sw_sbd { 313c7fd2ed0Sgs150176 dma_area_t desc; /* (const) related h/w */ 314c7fd2ed0Sgs150176 /* descriptor area */ 315c7fd2ed0Sgs150176 dma_area_t pbuf; /* (const) related */ 316c7fd2ed0Sgs150176 /* buffer area */ 317c7fd2ed0Sgs150176 } sw_sbd_t; 318c7fd2ed0Sgs150176 319c7fd2ed0Sgs150176 3203a84c50fSWinson Wang - Sun Microsystems - Beijing China #define HW_RBD_INIT(rbd, slot) { \ 3213a84c50fSWinson Wang - Sun Microsystems - Beijing China (rbd)->vlan_tag = 0; \ 3223a84c50fSWinson Wang - Sun Microsystems - Beijing China if ((slot) == (RGE_RECV_SLOTS -1)) { \ 3233a84c50fSWinson Wang - Sun Microsystems - Beijing China (rbd)->flags_len |= \ 3243a84c50fSWinson Wang - Sun Microsystems - Beijing China RGE_BSWAP_32(BD_FLAG_EOR | BD_FLAG_HW_OWN); \ 3253a84c50fSWinson Wang - Sun Microsystems - Beijing China } else { \ 3263a84c50fSWinson Wang - Sun Microsystems - Beijing China (rbd)->flags_len |= RGE_BSWAP_32(BD_FLAG_HW_OWN); \ 3273a84c50fSWinson Wang - Sun Microsystems - Beijing China } \ 3283a84c50fSWinson Wang - Sun Microsystems - Beijing China } 3293a84c50fSWinson Wang - Sun Microsystems - Beijing China #define HW_SBD_SET(sbd, slot) { \ 3303a84c50fSWinson Wang - Sun Microsystems - Beijing China if ((slot) == (RGE_SEND_SLOTS -1)) { \ 3313a84c50fSWinson Wang - Sun Microsystems - Beijing China (sbd)->flags_len |= \ 3323a84c50fSWinson Wang - Sun Microsystems - Beijing China RGE_BSWAP_32(BD_FLAG_EOR | SBD_FLAG_TX_PKT); \ 3333a84c50fSWinson Wang - Sun Microsystems - Beijing China } else { \ 3343a84c50fSWinson Wang - Sun Microsystems - Beijing China (sbd)->flags_len |= RGE_BSWAP_32(SBD_FLAG_TX_PKT); \ 3353a84c50fSWinson Wang - Sun Microsystems - Beijing China } \ 3363a84c50fSWinson Wang - Sun Microsystems - Beijing China } 337c7fd2ed0Sgs150176 338c7fd2ed0Sgs150176 /* 339c7fd2ed0Sgs150176 * Describes the characteristics of a specific chip 340c7fd2ed0Sgs150176 */ 341c7fd2ed0Sgs150176 typedef struct { 342c7fd2ed0Sgs150176 uint16_t command; /* saved during attach */ 343c7fd2ed0Sgs150176 uint16_t vendor; /* vendor-id */ 344c7fd2ed0Sgs150176 uint16_t device; /* device-id */ 345c7fd2ed0Sgs150176 uint16_t subven; /* subsystem-vendor-id */ 346c7fd2ed0Sgs150176 uint16_t subdev; /* subsystem-id */ 347c7fd2ed0Sgs150176 uint8_t revision; /* revision-id */ 348c7fd2ed0Sgs150176 uint8_t clsize; /* cache-line-size */ 349c7fd2ed0Sgs150176 uint8_t latency; /* latency-timer */ 350aa817493Sgs150176 boolean_t is_pcie; 351*0b758ccbSAlexander Eremin boolean_t enable_mac_first; 352c7fd2ed0Sgs150176 uint32_t mac_ver; 353c7fd2ed0Sgs150176 uint32_t phy_ver; 354c7fd2ed0Sgs150176 uint32_t rxconfig; 355c7fd2ed0Sgs150176 uint32_t txconfig; 356c7fd2ed0Sgs150176 } chip_id_t; 357c7fd2ed0Sgs150176 358c7fd2ed0Sgs150176 typedef struct rge_stats { 35922dc2133Smx205022 uint64_t rpackets; 360c7fd2ed0Sgs150176 uint64_t rbytes; 36122dc2133Smx205022 uint64_t opackets; 362c7fd2ed0Sgs150176 uint64_t obytes; 363c7fd2ed0Sgs150176 uint32_t overflow; 364c7fd2ed0Sgs150176 uint32_t defer; /* dot3StatsDeferredTransmissions */ 365c7fd2ed0Sgs150176 uint32_t crc_err; /* dot3StatsFCSErrors */ 366c7fd2ed0Sgs150176 uint32_t in_short; 367c7fd2ed0Sgs150176 uint32_t no_rcvbuf; /* ifInDiscards */ 368c7fd2ed0Sgs150176 uint32_t intr; /* interrupt count */ 369c7fd2ed0Sgs150176 uint16_t chip_reset; 370c7fd2ed0Sgs150176 uint16_t phy_reset; 37122dc2133Smx205022 boolean_t tx_pre_ismax; 37222dc2133Smx205022 boolean_t tx_cur_ismax; 373c7fd2ed0Sgs150176 } rge_stats_t; 374c7fd2ed0Sgs150176 375c7fd2ed0Sgs150176 /* 376c7fd2ed0Sgs150176 * Per-instance soft-state structure 377c7fd2ed0Sgs150176 */ 378c7fd2ed0Sgs150176 typedef struct rge { 379c7fd2ed0Sgs150176 dev_info_t *devinfo; /* device instance */ 380ba2e4443Sseb mac_handle_t mh; /* mac module handle */ 381c7fd2ed0Sgs150176 ddi_acc_handle_t cfg_handle; /* DDI I/O handle */ 382c7fd2ed0Sgs150176 ddi_acc_handle_t io_handle; /* DDI I/O handle */ 383c7fd2ed0Sgs150176 caddr_t io_regs; /* mapped registers */ 384dd4eeefdSeota ddi_periodic_t periodic_id; /* periodical callback */ 385aa817493Sgs150176 ddi_softint_handle_t resched_hdl; /* reschedule callback */ 386aa817493Sgs150176 ddi_softint_handle_t factotum_hdl; /* factotum callback */ 387aa817493Sgs150176 uint_t soft_pri; 388aa817493Sgs150176 ddi_intr_handle_t *htable; /* For array of interrupts */ 389aa817493Sgs150176 int intr_type; /* What type of interrupt */ 390aa817493Sgs150176 int intr_rqst; /* # of request intrs count */ 391aa817493Sgs150176 int intr_cnt; /* # of intrs count returned */ 392aa817493Sgs150176 uint_t intr_pri; /* Interrupt priority */ 393aa817493Sgs150176 int intr_cap; /* Interrupt capabilities */ 394aa817493Sgs150176 boolean_t msi_enable; 395aa817493Sgs150176 396c7fd2ed0Sgs150176 uint32_t ethmax_size; 397aa817493Sgs150176 uint32_t default_mtu; 398c7fd2ed0Sgs150176 uint32_t rxbuf_size; 399c7fd2ed0Sgs150176 uint32_t txbuf_size; 400aa817493Sgs150176 uint32_t chip_flags; 401aa817493Sgs150176 uint32_t head_room; 402c7fd2ed0Sgs150176 char ifname[8]; /* "rge0" ... "rge999" */ 403c7fd2ed0Sgs150176 int32_t instance; 404c7fd2ed0Sgs150176 uint32_t progress; /* attach tracking */ 405c7fd2ed0Sgs150176 uint32_t debug; /* per-instance debug */ 406c7fd2ed0Sgs150176 chip_id_t chipid; 407c7fd2ed0Sgs150176 408c7fd2ed0Sgs150176 /* 409c7fd2ed0Sgs150176 * These structures describe the blocks of memory allocated during 410c7fd2ed0Sgs150176 * attach(). They remain unchanged thereafter, although the memory 411c7fd2ed0Sgs150176 * they describe is carved up into various separate regions and may 412c7fd2ed0Sgs150176 * therefore be described by other structures as well. 413c7fd2ed0Sgs150176 */ 414c7fd2ed0Sgs150176 dma_area_t dma_area_rxdesc; 415c7fd2ed0Sgs150176 dma_area_t dma_area_txdesc; 416c7fd2ed0Sgs150176 dma_area_t dma_area_stats; 417c7fd2ed0Sgs150176 /* describes hardware statistics area */ 418c7fd2ed0Sgs150176 419c7fd2ed0Sgs150176 uint8_t netaddr[ETHERADDRL]; /* mac address */ 420c7fd2ed0Sgs150176 uint16_t int_mask; /* interrupt mask */ 421c7fd2ed0Sgs150176 422c7fd2ed0Sgs150176 /* used for multicast/promisc mode set */ 423c7fd2ed0Sgs150176 char mcast_refs[RGE_MCAST_BUF_SIZE]; 424aa817493Sgs150176 uint8_t mcast_hash[RGE_MCAST_NUM]; 425c7fd2ed0Sgs150176 boolean_t promisc; /* promisc state flag */ 426c7fd2ed0Sgs150176 427c7fd2ed0Sgs150176 /* used for recv */ 428c7fd2ed0Sgs150176 rge_bd_t *rx_ring; 429c7fd2ed0Sgs150176 dma_area_t rx_desc; 430c7fd2ed0Sgs150176 boolean_t rx_bcopy; 431c7fd2ed0Sgs150176 uint32_t rx_next; /* current rx bd index */ 432c7fd2ed0Sgs150176 sw_rbd_t *sw_rbds; 433aa817493Sgs150176 sw_rbd_t *free_srbds; 434c7fd2ed0Sgs150176 uint32_t rf_next; /* current free buf index */ 435c7fd2ed0Sgs150176 uint32_t rc_next; /* current recycle buf index */ 436c7fd2ed0Sgs150176 uint32_t rx_free; /* number of rx free buf */ 437c7fd2ed0Sgs150176 438c7fd2ed0Sgs150176 /* used for send */ 439c7fd2ed0Sgs150176 rge_bd_t *tx_ring; 440c7fd2ed0Sgs150176 dma_area_t tx_desc; 441c7fd2ed0Sgs150176 uint32_t tx_free; /* number of free tx bd */ 442c7fd2ed0Sgs150176 uint32_t tx_next; /* current tx bd index */ 443c7fd2ed0Sgs150176 uint32_t tc_next; /* current tx recycle index */ 444c7fd2ed0Sgs150176 uint32_t tx_flow; 445c7fd2ed0Sgs150176 uint32_t tc_tail; 446c7fd2ed0Sgs150176 sw_sbd_t *sw_sbds; 447c7fd2ed0Sgs150176 448c7fd2ed0Sgs150176 /* mutex */ 449c7fd2ed0Sgs150176 kmutex_t genlock[1]; /* i/o reg access */ 450c7fd2ed0Sgs150176 krwlock_t errlock[1]; /* rge restart */ 451c7fd2ed0Sgs150176 kmutex_t tx_lock[1]; /* send access */ 452c7fd2ed0Sgs150176 kmutex_t tc_lock[1]; /* send recycle access */ 453c7fd2ed0Sgs150176 kmutex_t rx_lock[1]; /* receive access */ 454c7fd2ed0Sgs150176 kmutex_t rc_lock[1]; /* receive recycle access */ 455c7fd2ed0Sgs150176 456c7fd2ed0Sgs150176 /* 457c7fd2ed0Sgs150176 * Miscellaneous operating variables (not synchronised) 458c7fd2ed0Sgs150176 */ 459c7fd2ed0Sgs150176 uint32_t watchdog; /* watches for Tx stall */ 460c7fd2ed0Sgs150176 boolean_t resched_needed; 461c7fd2ed0Sgs150176 uint32_t factotum_flag; /* softint pending */ 462c7fd2ed0Sgs150176 463c7fd2ed0Sgs150176 /* 464c7fd2ed0Sgs150176 * Physical layer 465c7fd2ed0Sgs150176 */ 466c7fd2ed0Sgs150176 rge_regno_t phy_mii_addr; /* should be (const) 1! */ 467c7fd2ed0Sgs150176 uint16_t link_down_count; 468c7fd2ed0Sgs150176 469c7fd2ed0Sgs150176 /* 470c7fd2ed0Sgs150176 * NDD parameters (protected by genlock) 471c7fd2ed0Sgs150176 */ 472c7fd2ed0Sgs150176 caddr_t nd_data_p; 473c7fd2ed0Sgs150176 nd_param_t nd_params[PARAM_COUNT]; 474c7fd2ed0Sgs150176 475c7fd2ed0Sgs150176 /* 476c7fd2ed0Sgs150176 * Driver kstats, protected by <genlock> where necessary 477c7fd2ed0Sgs150176 */ 478c7fd2ed0Sgs150176 kstat_t *rge_kstats[RGE_KSTAT_COUNT]; 479c7fd2ed0Sgs150176 480c7fd2ed0Sgs150176 /* H/W statistics */ 481c7fd2ed0Sgs150176 rge_hw_stats_t *hw_stats; 482c7fd2ed0Sgs150176 rge_stats_t stats; 483c7fd2ed0Sgs150176 enum rge_mac_state rge_mac_state; /* definitions above */ 484c7fd2ed0Sgs150176 enum rge_chip_state rge_chip_state; /* definitions above */ 485343c2616Smx205022 486343c2616Smx205022 boolean_t suspended; 4873a84c50fSWinson Wang - Sun Microsystems - Beijing China 4883a84c50fSWinson Wang - Sun Microsystems - Beijing China /* 4893a84c50fSWinson Wang - Sun Microsystems - Beijing China * Polling 4903a84c50fSWinson Wang - Sun Microsystems - Beijing China */ 4913a84c50fSWinson Wang - Sun Microsystems - Beijing China #define TX_COALESC max(RGE_BUF_SLOTS/32LL, 8) 4923a84c50fSWinson Wang - Sun Microsystems - Beijing China #define RX_COALESC 8LL 4933a84c50fSWinson Wang - Sun Microsystems - Beijing China #define CLK_TICK 100 4943a84c50fSWinson Wang - Sun Microsystems - Beijing China clock_t curr_tick; 4953a84c50fSWinson Wang - Sun Microsystems - Beijing China clock_t tick_delta; 4963a84c50fSWinson Wang - Sun Microsystems - Beijing China uint64_t last_opackets; 4973a84c50fSWinson Wang - Sun Microsystems - Beijing China uint64_t last_rpackets; 4987b114c4bSWinson Wang - Sun Microsystems - Beijing China uint32_t rx_fifo_ovf; 499c7fd2ed0Sgs150176 } rge_t; 500c7fd2ed0Sgs150176 501c7fd2ed0Sgs150176 /* 502c7fd2ed0Sgs150176 * 'Progress' bit flags ... 503c7fd2ed0Sgs150176 */ 504c7fd2ed0Sgs150176 #define PROGRESS_CFG 0x0001 /* config space mapped */ 505c7fd2ed0Sgs150176 #define PROGRESS_REGS 0x0002 /* registers mapped */ 506c7fd2ed0Sgs150176 #define PROGRESS_RESCHED 0x0010 /* resched softint registered */ 507c7fd2ed0Sgs150176 #define PROGRESS_FACTOTUM 0x0020 /* factotum softint registered */ 508c7fd2ed0Sgs150176 #define PROGRESS_INTR 0X0040 /* h/w interrupt registered */ 509c7fd2ed0Sgs150176 /* and mutexen initialised */ 510aa817493Sgs150176 #define PROGRESS_INIT 0x0080 /* rx/buf/tx ring initialised */ 511c7fd2ed0Sgs150176 #define PROGRESS_PHY 0x0100 /* PHY initialised */ 512c7fd2ed0Sgs150176 #define PROGRESS_NDD 0x1000 /* NDD parameters set up */ 513c7fd2ed0Sgs150176 #define PROGRESS_KSTATS 0x2000 /* kstats created */ 514c7fd2ed0Sgs150176 #define PROGRESS_READY 0x8000 /* ready for work */ 515c7fd2ed0Sgs150176 516c7fd2ed0Sgs150176 /* 517aa817493Sgs150176 * Special chip flags 518aa817493Sgs150176 */ 519aa817493Sgs150176 #define CHIP_FLAG_FORCE_BCOPY 0x10000000 520aa817493Sgs150176 521aa817493Sgs150176 /* 522c7fd2ed0Sgs150176 * Shorthand for the NDD parameters 523c7fd2ed0Sgs150176 */ 524c7fd2ed0Sgs150176 #define param_adv_autoneg nd_params[PARAM_ADV_AUTONEG_CAP].ndp_val 525c7fd2ed0Sgs150176 #define param_adv_pause nd_params[PARAM_ADV_PAUSE_CAP].ndp_val 526c7fd2ed0Sgs150176 #define param_adv_asym_pause nd_params[PARAM_ADV_ASYM_PAUSE_CAP].ndp_val 527c7fd2ed0Sgs150176 #define param_adv_1000fdx nd_params[PARAM_ADV_1000FDX_CAP].ndp_val 528c7fd2ed0Sgs150176 #define param_adv_1000hdx nd_params[PARAM_ADV_1000HDX_CAP].ndp_val 529c7fd2ed0Sgs150176 #define param_adv_100fdx nd_params[PARAM_ADV_100FDX_CAP].ndp_val 530c7fd2ed0Sgs150176 #define param_adv_100hdx nd_params[PARAM_ADV_100HDX_CAP].ndp_val 531c7fd2ed0Sgs150176 #define param_adv_10fdx nd_params[PARAM_ADV_10FDX_CAP].ndp_val 532c7fd2ed0Sgs150176 #define param_adv_10hdx nd_params[PARAM_ADV_10HDX_CAP].ndp_val 533c7fd2ed0Sgs150176 534c7fd2ed0Sgs150176 #define param_link_up nd_params[PARAM_LINK_STATUS].ndp_val 535c7fd2ed0Sgs150176 #define param_link_speed nd_params[PARAM_LINK_SPEED].ndp_val 536c7fd2ed0Sgs150176 #define param_link_duplex nd_params[PARAM_LINK_DUPLEX].ndp_val 537c7fd2ed0Sgs150176 538c7fd2ed0Sgs150176 #define param_loop_mode nd_params[PARAM_LOOP_MODE].ndp_val 539c7fd2ed0Sgs150176 540c7fd2ed0Sgs150176 /* 541c7fd2ed0Sgs150176 * Sync a DMA area described by a dma_area_t 542c7fd2ed0Sgs150176 */ 543c7fd2ed0Sgs150176 #define DMA_SYNC(area, flag) ((void) ddi_dma_sync((area).dma_hdl, \ 544c7fd2ed0Sgs150176 (area).offset, (area).alength, (flag))) 545c7fd2ed0Sgs150176 546c7fd2ed0Sgs150176 /* 547c7fd2ed0Sgs150176 * Find the (kernel virtual) address of block of memory 548c7fd2ed0Sgs150176 * described by a dma_area_t 549c7fd2ed0Sgs150176 */ 550c7fd2ed0Sgs150176 #define DMA_VPTR(area) ((area).mem_va) 551c7fd2ed0Sgs150176 552c7fd2ed0Sgs150176 /* 553c7fd2ed0Sgs150176 * Zero a block of memory described by a dma_area_t 554c7fd2ed0Sgs150176 */ 555c7fd2ed0Sgs150176 #define DMA_ZERO(area) bzero(DMA_VPTR(area), (area).alength) 556c7fd2ed0Sgs150176 557c7fd2ed0Sgs150176 /* 558c7fd2ed0Sgs150176 * Next/Last value of a cyclic index 559c7fd2ed0Sgs150176 */ 560c7fd2ed0Sgs150176 #define NEXT(index, limit) ((index)+1 < (limit) ? (index)+1 : 0); 561c7fd2ed0Sgs150176 #define LAST(index, limit) ((index) ? (index)-1 : (limit - 1)); 562c7fd2ed0Sgs150176 /* 563c7fd2ed0Sgs150176 * Property lookups 564c7fd2ed0Sgs150176 */ 565c7fd2ed0Sgs150176 #define RGE_PROP_EXISTS(d, n) ddi_prop_exists(DDI_DEV_T_ANY, (d), \ 566c7fd2ed0Sgs150176 DDI_PROP_DONTPASS, (n)) 567c7fd2ed0Sgs150176 #define RGE_PROP_GET_INT(d, n) ddi_prop_get_int(DDI_DEV_T_ANY, (d), \ 568c7fd2ed0Sgs150176 DDI_PROP_DONTPASS, (n), -1) 569c7fd2ed0Sgs150176 570c7fd2ed0Sgs150176 /* 571c7fd2ed0Sgs150176 * Endian swap 572c7fd2ed0Sgs150176 */ 573c7fd2ed0Sgs150176 #ifdef _BIG_ENDIAN 574c7fd2ed0Sgs150176 #define RGE_BSWAP_16(x) ((((x) & 0xff00) >> 8) | \ 575c7fd2ed0Sgs150176 (((x) & 0x00ff) << 8)) 576c7fd2ed0Sgs150176 #define RGE_BSWAP_32(x) ((((x) & 0xff000000) >> 24) | \ 577c7fd2ed0Sgs150176 (((x) & 0x00ff0000) >> 8) | \ 578c7fd2ed0Sgs150176 (((x) & 0x0000ff00) << 8) | \ 579c7fd2ed0Sgs150176 (((x) & 0x000000ff) << 24)) 580c7fd2ed0Sgs150176 #define RGE_BSWAP_64(x) (RGE_BSWAP_32((x) >> 32) | \ 581c7fd2ed0Sgs150176 (RGE_BSWAP_32(x) << 32)) 582c7fd2ed0Sgs150176 #else 583c7fd2ed0Sgs150176 #define RGE_BSWAP_16(x) (x) 584c7fd2ed0Sgs150176 #define RGE_BSWAP_32(x) (x) 585c7fd2ed0Sgs150176 #define RGE_BSWAP_64(x) (x) 586c7fd2ed0Sgs150176 #endif 587c7fd2ed0Sgs150176 588c7fd2ed0Sgs150176 /* 589c7fd2ed0Sgs150176 * Bit test macros, returning boolean_t values 590c7fd2ed0Sgs150176 */ 591c7fd2ed0Sgs150176 #define BIS(w, b) (((w) & (b)) ? B_TRUE : B_FALSE) 592c7fd2ed0Sgs150176 #define BIC(w, b) (((w) & (b)) ? B_FALSE : B_TRUE) 593c7fd2ed0Sgs150176 #define UPORDOWN(x) ((x) ? "up" : "down") 594c7fd2ed0Sgs150176 595c7fd2ed0Sgs150176 /* 596c7fd2ed0Sgs150176 * Bit flags in the 'debug' word ... 597c7fd2ed0Sgs150176 */ 598c7fd2ed0Sgs150176 #define RGE_DBG_STOP 0x00000001 /* early debug_enter() */ 599c7fd2ed0Sgs150176 #define RGE_DBG_TRACE 0x00000002 /* general flow tracing */ 600c7fd2ed0Sgs150176 601c7fd2ed0Sgs150176 #define RGE_DBG_REGS 0x00000010 /* low-level accesses */ 602c7fd2ed0Sgs150176 #define RGE_DBG_MII 0x00000020 /* low-level MII access */ 603c7fd2ed0Sgs150176 #define RGE_DBG_SEEPROM 0x00000040 /* low-level SEEPROM IO */ 604c7fd2ed0Sgs150176 #define RGE_DBG_CHIP 0x00000080 /* low(ish)-level code */ 605c7fd2ed0Sgs150176 606c7fd2ed0Sgs150176 #define RGE_DBG_RECV 0x00000100 /* receive-side code */ 607c7fd2ed0Sgs150176 #define RGE_DBG_SEND 0x00000200 /* packet-send code */ 608c7fd2ed0Sgs150176 609c7fd2ed0Sgs150176 #define RGE_DBG_INT 0x00001000 /* interrupt handler */ 610c7fd2ed0Sgs150176 #define RGE_DBG_FACT 0x00002000 /* factotum (softint) */ 611c7fd2ed0Sgs150176 612c7fd2ed0Sgs150176 #define RGE_DBG_PHY 0x00010000 /* Copper PHY code */ 613c7fd2ed0Sgs150176 #define RGE_DBG_SERDES 0x00020000 /* SerDes code */ 614c7fd2ed0Sgs150176 #define RGE_DBG_PHYS 0x00040000 /* Physical layer code */ 615c7fd2ed0Sgs150176 #define RGE_DBG_LINK 0x00080000 /* Link status check */ 616c7fd2ed0Sgs150176 617c7fd2ed0Sgs150176 #define RGE_DBG_INIT 0x00100000 /* initialisation */ 618c7fd2ed0Sgs150176 #define RGE_DBG_NEMO 0x00200000 /* nemo interaction */ 619c7fd2ed0Sgs150176 #define RGE_DBG_ADDR 0x00400000 /* address-setting code */ 620c7fd2ed0Sgs150176 #define RGE_DBG_STATS 0x00800000 /* statistics */ 621c7fd2ed0Sgs150176 622c7fd2ed0Sgs150176 #define RGE_DBG_IOCTL 0x01000000 /* ioctl handling */ 623c7fd2ed0Sgs150176 #define RGE_DBG_LOOP 0x02000000 /* loopback ioctl code */ 624c7fd2ed0Sgs150176 #define RGE_DBG_PPIO 0x04000000 /* Peek/poke ioctls */ 625c7fd2ed0Sgs150176 #define RGE_DBG_BADIOC 0x08000000 /* unknown ioctls */ 626c7fd2ed0Sgs150176 627c7fd2ed0Sgs150176 #define RGE_DBG_MCTL 0x10000000 /* mctl (csum) code */ 628c7fd2ed0Sgs150176 #define RGE_DBG_NDD 0x20000000 /* NDD operations */ 629c7fd2ed0Sgs150176 630c7fd2ed0Sgs150176 /* 631c7fd2ed0Sgs150176 * Debugging ... 632c7fd2ed0Sgs150176 */ 633c7fd2ed0Sgs150176 #ifdef DEBUG 634c7fd2ed0Sgs150176 #define RGE_DEBUGGING 1 635c7fd2ed0Sgs150176 #else 636c7fd2ed0Sgs150176 #define RGE_DEBUGGING 0 637c7fd2ed0Sgs150176 #endif /* DEBUG */ 638c7fd2ed0Sgs150176 639c7fd2ed0Sgs150176 640c7fd2ed0Sgs150176 /* 641c7fd2ed0Sgs150176 * 'Do-if-debugging' macro. The parameter <command> should be one or more 642c7fd2ed0Sgs150176 * C statements (but without the *final* semicolon), which will either be 643c7fd2ed0Sgs150176 * compiled inline or completely ignored, depending on the RGE_DEBUGGING 644c7fd2ed0Sgs150176 * compile-time flag. 645c7fd2ed0Sgs150176 * 646c7fd2ed0Sgs150176 * You should get a compile-time error (at least on a DEBUG build) if 647c7fd2ed0Sgs150176 * your statement isn't actually a statement, rather than unexpected 648c7fd2ed0Sgs150176 * run-time behaviour caused by unintended matching of if-then-elses etc. 649c7fd2ed0Sgs150176 * 650c7fd2ed0Sgs150176 * Note that the RGE_DDB() macro itself can only be used as a statement, 651c7fd2ed0Sgs150176 * not an expression, and should always be followed by a semicolon. 652c7fd2ed0Sgs150176 */ 653c7fd2ed0Sgs150176 #if RGE_DEBUGGING 654c7fd2ed0Sgs150176 #define RGE_DDB(command) do { \ 655c7fd2ed0Sgs150176 { command; } \ 656c7fd2ed0Sgs150176 _NOTE(CONSTANTCONDITION) \ 657c7fd2ed0Sgs150176 } while (0) 658c7fd2ed0Sgs150176 #else /* RGE_DEBUGGING */ 659c7fd2ed0Sgs150176 #define RGE_DDB(command) do { \ 660c7fd2ed0Sgs150176 { _NOTE(EMPTY); } \ 661c7fd2ed0Sgs150176 _NOTE(CONSTANTCONDITION) \ 662c7fd2ed0Sgs150176 } while (0) 663c7fd2ed0Sgs150176 #endif /* RGE_DEBUGGING */ 664c7fd2ed0Sgs150176 665c7fd2ed0Sgs150176 /* 666c7fd2ed0Sgs150176 * 'Internal' macros used to construct the TRACE/DEBUG macros below. 667c7fd2ed0Sgs150176 * These provide the primitive conditional-call capability required. 668c7fd2ed0Sgs150176 * Note: the parameter <args> is a parenthesised list of the actual 669c7fd2ed0Sgs150176 * printf-style arguments to be passed to the debug function ... 670c7fd2ed0Sgs150176 */ 671c7fd2ed0Sgs150176 #define RGE_XDB(b, w, f, args) RGE_DDB(if ((b) & (w)) f args) 672c7fd2ed0Sgs150176 #define RGE_GDB(b, args) RGE_XDB(b, rge_debug, (*rge_gdb()), args) 673c7fd2ed0Sgs150176 #define RGE_LDB(b, args) RGE_XDB(b, rgep->debug, (*rge_db(rgep)), args) 674c7fd2ed0Sgs150176 #define RGE_CDB(f, args) RGE_XDB(RGE_DBG, rgep->debug, f, args) 675c7fd2ed0Sgs150176 676c7fd2ed0Sgs150176 /* 677c7fd2ed0Sgs150176 * Conditional-print macros. 678c7fd2ed0Sgs150176 * 679c7fd2ed0Sgs150176 * Define RGE_DBG to be the relevant member of the set of RGE_DBG_* values 680c7fd2ed0Sgs150176 * above before using the RGE_GDEBUG() or RGE_DEBUG() macros. The 'G' 681c7fd2ed0Sgs150176 * versions look at the Global debug flag word (rge_debug); the non-G 682c7fd2ed0Sgs150176 * versions look in the per-instance data (rgep->debug) and so require a 683c7fd2ed0Sgs150176 * variable called 'rgep' to be in scope (and initialised!) before use. 684c7fd2ed0Sgs150176 * 685c7fd2ed0Sgs150176 * You could redefine RGE_TRC too if you really need two different 686c7fd2ed0Sgs150176 * flavours of debugging output in the same area of code, but I don't 687c7fd2ed0Sgs150176 * really recommend it. 688c7fd2ed0Sgs150176 * 689c7fd2ed0Sgs150176 * Note: the parameter <args> is a parenthesised list of the actual 690c7fd2ed0Sgs150176 * arguments to be passed to the debug function, usually a printf-style 691c7fd2ed0Sgs150176 * format string and corresponding values to be formatted. 692c7fd2ed0Sgs150176 */ 693c7fd2ed0Sgs150176 694c7fd2ed0Sgs150176 #define RGE_TRC RGE_DBG_TRACE /* default 'trace' bit */ 695c7fd2ed0Sgs150176 #define RGE_GTRACE(args) RGE_GDB(RGE_TRC, args) 696c7fd2ed0Sgs150176 #define RGE_GDEBUG(args) RGE_GDB(RGE_DBG, args) 697c7fd2ed0Sgs150176 #define RGE_TRACE(args) RGE_LDB(RGE_TRC, args) 698c7fd2ed0Sgs150176 #define RGE_DEBUG(args) RGE_LDB(RGE_DBG, args) 699c7fd2ed0Sgs150176 700c7fd2ed0Sgs150176 /* 701c7fd2ed0Sgs150176 * Debug-only action macros 702c7fd2ed0Sgs150176 */ 703c7fd2ed0Sgs150176 #define RGE_BRKPT(rgep, s) RGE_DDB(rge_dbg_enter(rgep, s)) 704c7fd2ed0Sgs150176 #define RGE_MARK(rgep) RGE_DDB(rge_led_mark(rgep)) 705c7fd2ed0Sgs150176 #define RGE_PCICHK(rgep) RGE_DDB(rge_pci_check(rgep)) 706c7fd2ed0Sgs150176 #define RGE_PKTDUMP(args) RGE_DDB(rge_pkt_dump args) 707c7fd2ed0Sgs150176 #define RGE_REPORT(args) RGE_DDB(rge_log args) 708c7fd2ed0Sgs150176 709c7fd2ed0Sgs150176 /* 710c7fd2ed0Sgs150176 * Inter-source-file linkage ... 711c7fd2ed0Sgs150176 */ 712c7fd2ed0Sgs150176 713c7fd2ed0Sgs150176 /* rge_chip.c */ 714c7fd2ed0Sgs150176 uint16_t rge_mii_get16(rge_t *rgep, uintptr_t mii); 715c7fd2ed0Sgs150176 void rge_mii_put16(rge_t *rgep, uintptr_t mii, uint16_t data); 716c7fd2ed0Sgs150176 void rge_chip_cfg_init(rge_t *rgep, chip_id_t *cidp); 717c7fd2ed0Sgs150176 void rge_chip_ident(rge_t *rgep); 718c7fd2ed0Sgs150176 int rge_chip_reset(rge_t *rgep); 719c7fd2ed0Sgs150176 void rge_chip_init(rge_t *rgep); 720c7fd2ed0Sgs150176 void rge_chip_start(rge_t *rgep); 721c7fd2ed0Sgs150176 void rge_chip_stop(rge_t *rgep, boolean_t fault); 722c7fd2ed0Sgs150176 void rge_chip_sync(rge_t *rgep, enum rge_sync_op todo); 723da14cebeSEric Cheng void rge_chip_blank(void *arg, time_t ticks, uint_t count, int flag); 724c7fd2ed0Sgs150176 void rge_tx_trigger(rge_t *rgep); 725c7fd2ed0Sgs150176 void rge_hw_stats_dump(rge_t *rgep); 726aa817493Sgs150176 uint_t rge_intr(caddr_t arg1, caddr_t arg2); 727aa817493Sgs150176 uint_t rge_chip_factotum(caddr_t arg1, caddr_t arg2); 728c7fd2ed0Sgs150176 void rge_chip_cyclic(void *arg); 729c7fd2ed0Sgs150176 enum ioc_reply rge_chip_ioctl(rge_t *rgep, queue_t *wq, mblk_t *mp, 730c7fd2ed0Sgs150176 struct iocblk *iocp); 731c7fd2ed0Sgs150176 boolean_t rge_phy_reset(rge_t *rgep); 732c7fd2ed0Sgs150176 void rge_phy_init(rge_t *rgep); 733c7fd2ed0Sgs150176 void rge_phy_update(rge_t *rgep); 734c7fd2ed0Sgs150176 735c7fd2ed0Sgs150176 /* rge_kstats.c */ 736c7fd2ed0Sgs150176 void rge_init_kstats(rge_t *rgep, int instance); 737c7fd2ed0Sgs150176 void rge_fini_kstats(rge_t *rgep); 738ba2e4443Sseb int rge_m_stat(void *arg, uint_t stat, uint64_t *val); 739c7fd2ed0Sgs150176 740c7fd2ed0Sgs150176 /* rge_log.c */ 741c7fd2ed0Sgs150176 #if RGE_DEBUGGING 742c7fd2ed0Sgs150176 void (*rge_db(rge_t *rgep))(const char *fmt, ...); 743c7fd2ed0Sgs150176 void (*rge_gdb(void))(const char *fmt, ...); 744c7fd2ed0Sgs150176 void rge_pkt_dump(rge_t *rgep, rge_bd_t *hbp, sw_rbd_t *sdp, const char *msg); 745c7fd2ed0Sgs150176 void rge_dbg_enter(rge_t *rgep, const char *msg); 746c7fd2ed0Sgs150176 #endif /* RGE_DEBUGGING */ 747c7fd2ed0Sgs150176 void rge_problem(rge_t *rgep, const char *fmt, ...); 748c7fd2ed0Sgs150176 void rge_notice(rge_t *rgep, const char *fmt, ...); 749c7fd2ed0Sgs150176 void rge_log(rge_t *rgep, const char *fmt, ...); 750c7fd2ed0Sgs150176 void rge_error(rge_t *rgep, const char *fmt, ...); 751c7fd2ed0Sgs150176 extern kmutex_t rge_log_mutex[1]; 752c7fd2ed0Sgs150176 extern uint32_t rge_debug; 753c7fd2ed0Sgs150176 754c7fd2ed0Sgs150176 /* rge_main.c */ 755c7fd2ed0Sgs150176 void rge_restart(rge_t *rgep); 756c7fd2ed0Sgs150176 757c7fd2ed0Sgs150176 /* rge_ndd.c */ 758c7fd2ed0Sgs150176 int rge_nd_init(rge_t *rgep); 759c7fd2ed0Sgs150176 enum ioc_reply rge_nd_ioctl(rge_t *rgep, queue_t *wq, mblk_t *mp, 760c7fd2ed0Sgs150176 struct iocblk *iocp); 761c7fd2ed0Sgs150176 void rge_nd_cleanup(rge_t *rgep); 762c7fd2ed0Sgs150176 763c7fd2ed0Sgs150176 /* rge_rxtx.c */ 764c7fd2ed0Sgs150176 void rge_rx_recycle(caddr_t arg); 765c7fd2ed0Sgs150176 void rge_receive(rge_t *rgep); 7669e1a9180SLi-Zhen You void rge_send_recycle(rge_t *rgep); 767c7fd2ed0Sgs150176 mblk_t *rge_m_tx(void *arg, mblk_t *mp); 768aa817493Sgs150176 uint_t rge_reschedule(caddr_t arg1, caddr_t arg2); 769c7fd2ed0Sgs150176 770c7fd2ed0Sgs150176 #ifdef __cplusplus 771c7fd2ed0Sgs150176 } 772c7fd2ed0Sgs150176 #endif 773c7fd2ed0Sgs150176 774c7fd2ed0Sgs150176 #endif /* _RGE_H */ 775