1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_DMFE_IMPL_H 27 #define _SYS_DMFE_IMPL_H 28 29 #include <sys/types.h> 30 #include <sys/stream.h> 31 #include <sys/strsun.h> 32 #include <sys/stat.h> 33 #include <sys/pci.h> 34 #include <sys/note.h> 35 #include <sys/modctl.h> 36 #include <sys/kstat.h> 37 #include <sys/ethernet.h> 38 #include <sys/devops.h> 39 #include <sys/debug.h> 40 #include <sys/conf.h> 41 42 #include <sys/vlan.h> 43 44 #include <sys/dditypes.h> 45 #include <sys/ddi.h> 46 #include <sys/sunddi.h> 47 48 #include <sys/mii.h> 49 #include <sys/mac_provider.h> 50 #include <sys/mac_ether.h> 51 #include "dmfe.h" 52 53 #define DMFE_MAX_PKT_SIZE (VLAN_TAGSZ + ETHERMAX + ETHERFCSL) 54 55 56 #define DRIVER_NAME "dmfe" 57 58 /* 59 * Describes the identity of a specific chip 60 */ 61 typedef struct { 62 uint16_t vendor; 63 uint16_t device; 64 uint8_t revision; 65 uint8_t spare; 66 } chip_id_t; 67 68 /* 69 * Describes the state of a descriptor ring 70 * 71 * NOTE: n_free and next_busy are only used for the Tx descriptors 72 * and are not valid on the receive side. 73 */ 74 typedef struct { 75 uint32_t n_desc; /* # of descriptors */ 76 uint32_t n_free; /* # of free descriptors */ 77 uint32_t next_free; /* next index to use/check */ 78 uint32_t next_busy; /* next index to reclaim */ 79 } desc_state_t; 80 81 /* 82 * Describes one chunk of allocated DMA-able memory 83 */ 84 typedef struct { 85 ddi_dma_handle_t dma_hdl; 86 ddi_acc_handle_t acc_hdl; 87 size_t alength; /* allocated size */ 88 caddr_t mem_va; /* CPU VA of memory */ 89 uint32_t spare1; 90 uint32_t mem_dvma; /* DVMA addr of memory */ 91 caddr_t setup_va; 92 uint32_t spare2; 93 uint32_t setup_dvma; 94 int spare3; 95 int ncookies; 96 } dma_area_t; 97 98 /* 99 * Indexes into the driver-specific kstats, divided into: 100 * 101 * cyclic activity 102 * reasons for waking the factotum 103 * the factotum's activities 104 */ 105 enum { 106 KS_CYCLIC_RUN, 107 108 KS_INTERRUPT, 109 KS_TX_STALL, 110 KS_CHIP_ERROR, 111 112 KS_FACTOTUM_RUN, 113 KS_RECOVERY, 114 115 KS_DRV_COUNT 116 }; 117 118 /* 119 * Actual state of the DM9102A chip 120 */ 121 enum chip_state { 122 CHIP_ERROR = -1, /* error, need reset */ 123 CHIP_UNKNOWN, /* Initial state only */ 124 CHIP_RESET, /* reset, need init */ 125 CHIP_STOPPED, /* Tx/Rx stopped */ 126 CHIP_TX_ONLY, /* Tx (re)started */ 127 CHIP_TX_RX, /* Tx & Rx (re)started */ 128 CHIP_RUNNING /* with interrupts */ 129 }; 130 131 /* 132 * Required state according to MAC 133 */ 134 enum mac_state { 135 DMFE_MAC_UNKNOWN, 136 DMFE_MAC_RESET, 137 DMFE_MAC_STOPPED, 138 DMFE_MAC_STARTED 139 }; 140 141 /* 142 * (Internal) return values from ioctl subroutines 143 */ 144 enum ioc_reply { 145 IOC_INVAL = -1, /* bad, NAK with EINVAL */ 146 IOC_DONE, /* OK, reply sent */ 147 IOC_REPLY, /* OK, just send reply */ 148 IOC_ACK, /* OK, just send ACK */ 149 IOC_RESTART, /* OK, restart & reply */ 150 IOC_RESTART_ACK /* OK, restart & ACK */ 151 }; 152 153 /* 154 * Per-instance soft-state structure 155 */ 156 typedef struct dmfe { 157 /* 158 * These fields are set by attach() and unchanged thereafter ... 159 */ 160 dev_info_t *devinfo; /* device instance */ 161 mac_handle_t mh; /* MAC instance data */ 162 mii_handle_t mii; /* MII handle */ 163 ddi_acc_handle_t io_handle; /* DDI I/O handle */ 164 caddr_t io_reg; /* mapped registers */ 165 boolean_t suspended; 166 167 uint32_t debug; /* per-instance debug */ 168 uint32_t progress; /* attach tracking */ 169 chip_id_t chipid; 170 uint8_t vendor_addr[ETHERADDRL]; 171 char ifname[12]; /* "dmfeXXXX" */ 172 173 dma_area_t tx_desc; /* transmit descriptors */ 174 dma_area_t tx_buff; /* transmit buffers */ 175 dma_area_t rx_desc; /* receive descriptors */ 176 dma_area_t rx_buff; /* receive buffers */ 177 178 ddi_periodic_t cycid; /* periodical callback */ 179 ddi_softintr_t factotum_id; /* identity of factotum */ 180 ddi_iblock_cookie_t iblk; 181 182 /* 183 * Locks: 184 * 185 * <milock> is used only by the MII (PHY) level code, to ensure 186 * exclusive access during the bit-twiddling needed to send 187 * signals along the MII serial bus. These operations are 188 * --S--L--O--W-- so we keep this lock separate, so that 189 * faster operations (e.g. interrupts) aren't delayed by 190 * waiting for it. 191 * 192 * <oplock> is a general "outer" lock, protecting most r/w data 193 * and chip state. It is also acquired by the interrupt 194 * handler. 195 * 196 * <rxlock> is used to protect the Rx-side buffers, descriptors, 197 * and statistics during a single call to dmfe_getp(). 198 * This is called from inside the interrupt handler, but 199 * <oplock> is not held across this call. 200 * 201 * <txlock> is an "inner" lock, and protects only the Tx-side 202 * data below and in the ring buffers/descriptors. The 203 * Tx-side code uses only this lock, avoiding contention 204 * with the receive-side code. 205 * 206 * Any of the locks can be acquired singly, but where multiple 207 * locks are acquired, they *must* be in the order: 208 * 209 * milock >>> oplock >>> rxlock >>> txlock. 210 * 211 * *None* of these locks may be held across calls out to the 212 * MAC routines mac_rx() or mac_tx_notify(); MAC locks must 213 * be regarded as *outermost* locks in all cases, as they will 214 * already be held before calling the ioctl() or get_stats() 215 * entry points - which then have to acquire multiple locks, in 216 * the order described here. 217 */ 218 kmutex_t milock[1]; 219 kmutex_t oplock[1]; 220 kmutex_t rxlock[1]; 221 kmutex_t txlock[1]; 222 223 /* 224 * DMFE Extended kstats, protected by <oplock> 225 */ 226 kstat_t *ksp_drv; 227 kstat_named_t *knp_drv; 228 229 /* 230 * GLD statistics; the prefix tells which lock each is protected by. 231 */ 232 233 uint64_t rx_stats_ipackets; 234 uint64_t rx_stats_multi; 235 uint64_t rx_stats_bcast; 236 uint64_t rx_stats_ierrors; 237 uint64_t rx_stats_norcvbuf; 238 uint64_t rx_stats_rbytes; 239 uint64_t rx_stats_missed; 240 uint64_t rx_stats_align; 241 uint64_t rx_stats_fcs; 242 uint64_t rx_stats_toolong; 243 uint64_t rx_stats_macrcv_errors; 244 uint64_t rx_stats_overflow; 245 uint64_t rx_stats_short; 246 247 uint64_t tx_stats_oerrors; 248 uint64_t tx_stats_opackets; 249 uint64_t tx_stats_multi; 250 uint64_t tx_stats_bcast; 251 uint64_t tx_stats_obytes; 252 uint64_t tx_stats_collisions; 253 uint64_t tx_stats_nocarrier; 254 uint64_t tx_stats_xmtlatecoll; 255 uint64_t tx_stats_excoll; 256 uint64_t tx_stats_macxmt_errors; 257 uint64_t tx_stats_jabber; 258 uint64_t tx_stats_defer; 259 uint64_t tx_stats_first_coll; 260 uint64_t tx_stats_multi_coll; 261 uint64_t tx_stats_underflow; 262 263 /* 264 * These two sets of desciptors are manipulated during 265 * packet receive/transmit respectively. 266 */ 267 desc_state_t rx; /* describes Rx ring */ 268 desc_state_t tx; /* describes Tx ring */ 269 270 /* 271 * Miscellaneous Tx-side variables (protected by txlock) 272 */ 273 uint32_t tx_pending_tix; /* tix since reclaim */ 274 uint8_t *tx_mcast; /* bitmask: pkt is mcast */ 275 uint8_t *tx_bcast; /* bitmask: pkt is bcast */ 276 277 /* 278 * Miscellaneous operating variables (protected by oplock) 279 */ 280 uint16_t factotum_flag; /* callback pending */ 281 uint16_t need_setup; /* send-setup pending */ 282 uint32_t opmode; /* operating mode shadow */ 283 uint32_t imask; /* interrupt mask shadow */ 284 enum mac_state mac_state; /* RESET/STOPPED/STARTED */ 285 enum chip_state chip_state; /* see above */ 286 287 /* 288 * Current Ethernet address & multicast map ... 289 */ 290 uint8_t curr_addr[ETHERADDRL]; 291 uint8_t mcast_refs[MCASTBUF_SIZE]; 292 boolean_t addr_set; 293 294 /* 295 * Guard element used to check data integrity 296 */ 297 uint64_t dmfe_guard; 298 } dmfe_t; 299 300 /* 301 * 'Progress' bit flags ... 302 */ 303 #define PROGRESS_CONFIG 0x0001 /* config space initialised */ 304 #define PROGRESS_MUTEX 0x0002 /* mutexes initialized */ 305 #define PROGRESS_REGS 0x0004 /* registers mapped */ 306 #define PROGRESS_BUFS 0x0008 /* buffers allocated */ 307 #define PROGRESS_SOFTINT 0x0010 /* softint registered */ 308 #define PROGRESS_HWINT 0x0020 /* h/w interrupt registered */ 309 310 /* 311 * Sync a DMA area described by a dma_area_t 312 */ 313 #define DMA_SYNC(descp, flag) ((void) ddi_dma_sync((descp)->dma_hdl, \ 314 0, (descp)->alength, flag)) 315 316 /* 317 * Next value of a cyclic index 318 */ 319 #define NEXT(index, limit) ((index)+1 < (limit) ? (index)+1 : 0); 320 321 /* 322 * Copy an ethernet address 323 */ 324 #define ethaddr_copy(src, dst) bcopy((src), (dst), ETHERADDRL) 325 326 /* 327 * Get/set/increment a (64-bit) driver-private kstat 328 */ 329 #define DRV_KS_GET(dmfep, id) \ 330 (((dmfep)->knp_drv) ? ((dmfep)->knp_drv)[id].value.ui64 : 0) 331 332 #define DRV_KS_SET(dmfep, id, val) \ 333 do { \ 334 if ((dmfep)->knp_drv) \ 335 ((dmfep)->knp_drv)[id].value.ui64 = (val); \ 336 _NOTE(CONSTANTCONDITION) \ 337 } while (0) 338 339 #define DRV_KS_INC(dmfep, id) \ 340 do { \ 341 if ((dmfep)->knp_drv) \ 342 ((dmfep)->knp_drv)[id].value.ui64 += 1; \ 343 _NOTE(CONSTANTCONDITION) \ 344 } while (0) 345 346 347 #define DMFE_GUARD 0x1919603003090218 348 349 /* 350 * Inter-source-file linkage ... 351 */ 352 353 /* dmfe_log.c */ 354 void dmfe_warning(dmfe_t *dmfep, const char *fmt, ...); 355 void dmfe_error(dmfe_t *dmfep, const char *fmt, ...); 356 void dmfe_notice(dmfe_t *dmfep, const char *fmt, ...); 357 void dmfe_log(dmfe_t *dmfep, const char *fmt, ...); 358 void dmfe_log_init(void); 359 void dmfe_log_fini(void); 360 361 /* dmfe_main.c */ 362 uint32_t dmfe_chip_get32(dmfe_t *dmfep, off_t offset); 363 void dmfe_chip_put32(dmfe_t *dmfep, off_t offset, uint32_t value); 364 365 /* dmfe_mii.c */ 366 void dmfe_read_eeprom(dmfe_t *dmfep, uint16_t addr, uint8_t *ptr, int cnt); 367 boolean_t dmfe_init_phy(dmfe_t *dmfep); 368 369 #endif /* _SYS_DMFE_IMPL_H */ 370