Ticket #1945: syskonnect.diff
File syskonnect.diff, 261.6 KB (added by , 16 years ago) |
---|
-
src/add-ons/kernel/drivers/network/syskonnect/Jamfile
1 SubDir HAIKU_TOP src add-ons kernel drivers network syskonnect ; 2 3 SubInclude HAIKU_TOP src add-ons kernel drivers network syskonnect dev ; -
src/add-ons/kernel/drivers/network/syskonnect/dev/Jamfile
1 SubDir HAIKU_TOP src add-ons kernel drivers network syskonnect dev ; 2 3 SubInclude HAIKU_TOP src add-ons kernel drivers network syskonnect dev mii ; 4 SubInclude HAIKU_TOP src add-ons kernel drivers network syskonnect dev sk ; -
src/add-ons/kernel/drivers/network/syskonnect/dev/sk/if_skreg.h
1 /* $OpenBSD: if_skreg.h,v 1.10 2003/08/12 05:23:06 nate Exp $ */ 2 3 /*-f 4 * Copyright (c) 1997, 1998, 1999, 2000 5 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Bill Paul. 18 * 4. Neither the name of the author nor the names of any co-contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 * THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 * $FreeBSD: src/sys/dev/sk/if_skreg.h,v 1.41 2007/04/02 04:43:41 yongari Exp $ 35 */ 36 37 /*- 38 * Copyright (c) 2003 Nathan L. Binkert <binkertn@umich.edu> 39 * 40 * Permission to use, copy, modify, and distribute this software for any 41 * purpose with or without fee is hereby granted, provided that the above 42 * copyright notice and this permission notice appear in all copies. 43 * 44 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 45 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 46 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 47 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 48 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 49 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 50 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 51 */ 52 53 /* Values to keep the different chip revisions apart (SK_CHIPVER). */ 54 #define SK_GENESIS 0x0A 55 #define SK_YUKON 0xB0 56 #define SK_YUKON_LITE 0xB1 57 #define SK_YUKON_LP 0xB2 58 #define SK_YUKON_FAMILY(x) ((x) & 0xB0) 59 60 /* Known revisions in SK_CONFIG. */ 61 #define SK_YUKON_LITE_REV_A0 0x0 /* invented, see test in skc_attach. */ 62 #define SK_YUKON_LITE_REV_A1 0x3 63 #define SK_YUKON_LITE_REV_A3 0x7 64 65 /* 66 * SysKonnect PCI vendor ID 67 */ 68 #define VENDORID_SK 0x1148 69 70 /* 71 * Marvell PCI vendor ID 72 */ 73 #define VENDORID_MARVELL 0x11AB 74 75 /* 76 * SK-NET gigabit ethernet device IDs 77 */ 78 #define DEVICEID_SK_V1 0x4300 79 #define DEVICEID_SK_V2 0x4320 80 81 /* 82 * Belkin F5D5005 83 */ 84 #define DEVICEID_BELKIN_5005 0x5005 85 86 /* 87 * 3Com PCI vendor ID 88 */ 89 #define VENDORID_3COM 0x10b7 90 91 /* 92 * 3Com gigabit ethernet device ID 93 */ 94 #define DEVICEID_3COM_3C940 0x1700 95 96 /* 97 * Linksys PCI vendor ID 98 */ 99 #define VENDORID_LINKSYS 0x1737 100 101 /* 102 * Linksys gigabit ethernet device ID 103 */ 104 #define DEVICEID_LINKSYS_EG1032 0x1032 105 106 /* 107 * Linksys gigabit ethernet rev 2 sub-device ID 108 */ 109 #define SUBDEVICEID_LINKSYS_EG1032_REV2 0x0015 110 111 /* 112 * D-Link PCI vendor ID 113 */ 114 #define VENDORID_DLINK 0x1186 115 116 /* 117 * D-Link gigabit ethernet device ID 118 */ 119 #define DEVICEID_DLINK_DGE530T_A1 0x4c00 120 #define DEVICEID_DLINK_DGE530T_B1 0x4b01 121 122 /* 123 * GEnesis registers. The GEnesis chip has a 256-byte I/O window 124 * but internally it has a 16K register space. This 16K space is 125 * divided into 128-byte blocks. The first 128 bytes of the I/O 126 * window represent the first block, which is permanently mapped 127 * at the start of the window. The other 127 blocks can be mapped 128 * to the second 128 bytes of the I/O window by setting the desired 129 * block value in the RAP register in block 0. Not all of the 127 130 * blocks are actually used. Most registers are 32 bits wide, but 131 * there are a few 16-bit and 8-bit ones as well. 132 */ 133 134 135 /* Start of remappable register window. */ 136 #define SK_WIN_BASE 0x0080 137 138 /* Size of a window */ 139 #define SK_WIN_LEN 0x80 140 141 #define SK_WIN_MASK 0x3F80 142 #define SK_REG_MASK 0x7F 143 144 /* Compute the window of a given register (for the RAP register) */ 145 #define SK_WIN(reg) (((reg) & SK_WIN_MASK) / SK_WIN_LEN) 146 147 /* Compute the relative offset of a register within the window */ 148 #define SK_REG(reg) ((reg) & SK_REG_MASK) 149 150 #define SK_PORT_A 0 151 #define SK_PORT_B 1 152 153 /* 154 * Compute offset of port-specific register. Since there are two 155 * ports, there are two of some GEnesis modules (e.g. two sets of 156 * DMA queues, two sets of FIFO control registers, etc...). Normally, 157 * the block for port 0 is at offset 0x0 and the block for port 1 is 158 * at offset 0x80 (i.e. the next page over). However for the transmit 159 * BMUs and RAMbuffers, there are two blocks for each port: one for 160 * the sync transmit queue and one for the async queue (which we don't 161 * use). However instead of ordering them like this: 162 * TX sync 1 / TX sync 2 / TX async 1 / TX async 2 163 * SysKonnect has instead ordered them like this: 164 * TX sync 1 / TX async 1 / TX sync 2 / TX async 2 165 * This means that when referencing the TX BMU and RAMbuffer registers, 166 * we have to double the block offset (0x80 * 2) in order to reach the 167 * second queue. This prevents us from using the same formula 168 * (sk_port * 0x80) to compute the offsets for all of the port-specific 169 * blocks: we need an extra offset for the BMU and RAMbuffer registers. 170 * The simplest thing is to provide an extra argument to these macros: 171 * the 'skip' parameter. The 'skip' value is the number of extra pages 172 * for skip when computing the port0/port1 offsets. For most registers, 173 * the skip value is 0; for the BMU and RAMbuffer registers, it's 1. 174 */ 175 #define SK_IF_READ_4(sc_if, skip, reg) \ 176 sk_win_read_4(sc_if->sk_softc, reg + \ 177 ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN)) 178 #define SK_IF_READ_2(sc_if, skip, reg) \ 179 sk_win_read_2(sc_if->sk_softc, reg + \ 180 ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN)) 181 #define SK_IF_READ_1(sc_if, skip, reg) \ 182 sk_win_read_1(sc_if->sk_softc, reg + \ 183 ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN)) 184 185 #define SK_IF_WRITE_4(sc_if, skip, reg, val) \ 186 sk_win_write_4(sc_if->sk_softc, \ 187 reg + ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN), val) 188 #define SK_IF_WRITE_2(sc_if, skip, reg, val) \ 189 sk_win_write_2(sc_if->sk_softc, \ 190 reg + ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN), val) 191 #define SK_IF_WRITE_1(sc_if, skip, reg, val) \ 192 sk_win_write_1(sc_if->sk_softc, \ 193 reg + ((sc_if->sk_port * (skip + 1)) * SK_WIN_LEN), val) 194 195 /* Block 0 registers, permanently mapped at iobase. */ 196 #define SK_RAP 0x0000 197 #define SK_CSR 0x0004 198 #define SK_LED 0x0006 199 #define SK_ISR 0x0008 /* interrupt source */ 200 #define SK_IMR 0x000C /* interrupt mask */ 201 #define SK_IESR 0x0010 /* interrupt hardware error source */ 202 #define SK_IEMR 0x0014 /* interrupt hardware error mask */ 203 #define SK_ISSR 0x0018 /* special interrupt source */ 204 #define SK_XM_IMR0 0x0020 205 #define SK_XM_ISR0 0x0028 206 #define SK_XM_PHYADDR0 0x0030 207 #define SK_XM_PHYDATA0 0x0034 208 #define SK_XM_IMR1 0x0040 209 #define SK_XM_ISR1 0x0048 210 #define SK_XM_PHYADDR1 0x0050 211 #define SK_XM_PHYDATA1 0x0054 212 #define SK_BMU_RX_CSR0 0x0060 213 #define SK_BMU_RX_CSR1 0x0064 214 #define SK_BMU_TXS_CSR0 0x0068 215 #define SK_BMU_TXA_CSR0 0x006C 216 #define SK_BMU_TXS_CSR1 0x0070 217 #define SK_BMU_TXA_CSR1 0x0074 218 219 /* SK_CSR register */ 220 #define SK_CSR_SW_RESET 0x0001 221 #define SK_CSR_SW_UNRESET 0x0002 222 #define SK_CSR_MASTER_RESET 0x0004 223 #define SK_CSR_MASTER_UNRESET 0x0008 224 #define SK_CSR_MASTER_STOP 0x0010 225 #define SK_CSR_MASTER_DONE 0x0020 226 #define SK_CSR_SW_IRQ_CLEAR 0x0040 227 #define SK_CSR_SW_IRQ_SET 0x0080 228 #define SK_CSR_SLOTSIZE 0x0100 /* 1 == 64 bits, 0 == 32 */ 229 #define SK_CSR_BUSCLOCK 0x0200 /* 1 == 33/66 Mhz, = 33 */ 230 231 /* SK_LED register */ 232 #define SK_LED_GREEN_OFF 0x01 233 #define SK_LED_GREEN_ON 0x02 234 235 /* SK_ISR register */ 236 #define SK_ISR_TX2_AS_CHECK 0x00000001 237 #define SK_ISR_TX2_AS_EOF 0x00000002 238 #define SK_ISR_TX2_AS_EOB 0x00000004 239 #define SK_ISR_TX2_S_CHECK 0x00000008 240 #define SK_ISR_TX2_S_EOF 0x00000010 241 #define SK_ISR_TX2_S_EOB 0x00000020 242 #define SK_ISR_TX1_AS_CHECK 0x00000040 243 #define SK_ISR_TX1_AS_EOF 0x00000080 244 #define SK_ISR_TX1_AS_EOB 0x00000100 245 #define SK_ISR_TX1_S_CHECK 0x00000200 246 #define SK_ISR_TX1_S_EOF 0x00000400 247 #define SK_ISR_TX1_S_EOB 0x00000800 248 #define SK_ISR_RX2_CHECK 0x00001000 249 #define SK_ISR_RX2_EOF 0x00002000 250 #define SK_ISR_RX2_EOB 0x00004000 251 #define SK_ISR_RX1_CHECK 0x00008000 252 #define SK_ISR_RX1_EOF 0x00010000 253 #define SK_ISR_RX1_EOB 0x00020000 254 #define SK_ISR_LINK2_OFLOW 0x00040000 255 #define SK_ISR_MAC2 0x00080000 256 #define SK_ISR_LINK1_OFLOW 0x00100000 257 #define SK_ISR_MAC1 0x00200000 258 #define SK_ISR_TIMER 0x00400000 259 #define SK_ISR_EXTERNAL_REG 0x00800000 260 #define SK_ISR_SW 0x01000000 261 #define SK_ISR_I2C_RDY 0x02000000 262 #define SK_ISR_TX2_TIMEO 0x04000000 263 #define SK_ISR_TX1_TIMEO 0x08000000 264 #define SK_ISR_RX2_TIMEO 0x10000000 265 #define SK_ISR_RX1_TIMEO 0x20000000 266 #define SK_ISR_RSVD 0x40000000 267 #define SK_ISR_HWERR 0x80000000 268 269 /* SK_IMR register */ 270 #define SK_IMR_TX2_AS_CHECK 0x00000001 271 #define SK_IMR_TX2_AS_EOF 0x00000002 272 #define SK_IMR_TX2_AS_EOB 0x00000004 273 #define SK_IMR_TX2_S_CHECK 0x00000008 274 #define SK_IMR_TX2_S_EOF 0x00000010 275 #define SK_IMR_TX2_S_EOB 0x00000020 276 #define SK_IMR_TX1_AS_CHECK 0x00000040 277 #define SK_IMR_TX1_AS_EOF 0x00000080 278 #define SK_IMR_TX1_AS_EOB 0x00000100 279 #define SK_IMR_TX1_S_CHECK 0x00000200 280 #define SK_IMR_TX1_S_EOF 0x00000400 281 #define SK_IMR_TX1_S_EOB 0x00000800 282 #define SK_IMR_RX2_CHECK 0x00001000 283 #define SK_IMR_RX2_EOF 0x00002000 284 #define SK_IMR_RX2_EOB 0x00004000 285 #define SK_IMR_RX1_CHECK 0x00008000 286 #define SK_IMR_RX1_EOF 0x00010000 287 #define SK_IMR_RX1_EOB 0x00020000 288 #define SK_IMR_LINK2_OFLOW 0x00040000 289 #define SK_IMR_MAC2 0x00080000 290 #define SK_IMR_LINK1_OFLOW 0x00100000 291 #define SK_IMR_MAC1 0x00200000 292 #define SK_IMR_TIMER 0x00400000 293 #define SK_IMR_EXTERNAL_REG 0x00800000 294 #define SK_IMR_SW 0x01000000 295 #define SK_IMR_I2C_RDY 0x02000000 296 #define SK_IMR_TX2_TIMEO 0x04000000 297 #define SK_IMR_TX1_TIMEO 0x08000000 298 #define SK_IMR_RX2_TIMEO 0x10000000 299 #define SK_IMR_RX1_TIMEO 0x20000000 300 #define SK_IMR_RSVD 0x40000000 301 #define SK_IMR_HWERR 0x80000000 302 303 #define SK_INTRS1 \ 304 (SK_IMR_RX1_EOF|SK_IMR_TX1_S_EOF|SK_IMR_MAC1) 305 306 #define SK_INTRS2 \ 307 (SK_IMR_RX2_EOF|SK_IMR_TX2_S_EOF|SK_IMR_MAC2) 308 309 /* SK_IESR register */ 310 #define SK_IESR_PAR_RX2 0x00000001 311 #define SK_IESR_PAR_RX1 0x00000002 312 #define SK_IESR_PAR_MAC2 0x00000004 313 #define SK_IESR_PAR_MAC1 0x00000008 314 #define SK_IESR_PAR_WR_RAM 0x00000010 315 #define SK_IESR_PAR_RD_RAM 0x00000020 316 #define SK_IESR_NO_TSTAMP_MAC2 0x00000040 317 #define SK_IESR_NO_TSTAMO_MAC1 0x00000080 318 #define SK_IESR_NO_STS_MAC2 0x00000100 319 #define SK_IESR_NO_STS_MAC1 0x00000200 320 #define SK_IESR_IRQ_STS 0x00000400 321 #define SK_IESR_MASTERERR 0x00000800 322 323 /* SK_IEMR register */ 324 #define SK_IEMR_PAR_RX2 0x00000001 325 #define SK_IEMR_PAR_RX1 0x00000002 326 #define SK_IEMR_PAR_MAC2 0x00000004 327 #define SK_IEMR_PAR_MAC1 0x00000008 328 #define SK_IEMR_PAR_WR_RAM 0x00000010 329 #define SK_IEMR_PAR_RD_RAM 0x00000020 330 #define SK_IEMR_NO_TSTAMP_MAC2 0x00000040 331 #define SK_IEMR_NO_TSTAMO_MAC1 0x00000080 332 #define SK_IEMR_NO_STS_MAC2 0x00000100 333 #define SK_IEMR_NO_STS_MAC1 0x00000200 334 #define SK_IEMR_IRQ_STS 0x00000400 335 #define SK_IEMR_MASTERERR 0x00000800 336 337 /* Block 2 */ 338 #define SK_MAC0_0 0x0100 339 #define SK_MAC0_1 0x0104 340 #define SK_MAC1_0 0x0108 341 #define SK_MAC1_1 0x010C 342 #define SK_MAC2_0 0x0110 343 #define SK_MAC2_1 0x0114 344 #define SK_CONNTYPE 0x0118 345 #define SK_PMDTYPE 0x0119 346 #define SK_CONFIG 0x011A 347 #define SK_CHIPVER 0x011B 348 #define SK_EPROM0 0x011C 349 #define SK_EPROM1 0x011D /* yukon/genesis */ 350 #define SK_EPROM2 0x011E /* yukon/genesis */ 351 #define SK_EPROM3 0x011F 352 #define SK_EP_ADDR 0x0120 353 #define SK_EP_DATA 0x0124 354 #define SK_EP_LOADCTL 0x0128 355 #define SK_EP_LOADTST 0x0129 356 #define SK_TIMERINIT 0x0130 357 #define SK_TIMER 0x0134 358 #define SK_TIMERCTL 0x0138 359 #define SK_TIMERTST 0x0139 360 #define SK_IMTIMERINIT 0x0140 361 #define SK_IMTIMER 0x0144 362 #define SK_IMTIMERCTL 0x0148 363 #define SK_IMTIMERTST 0x0149 364 #define SK_IMMR 0x014C 365 #define SK_IHWEMR 0x0150 366 #define SK_TESTCTL1 0x0158 367 #define SK_TESTCTL2 0x0159 368 #define SK_GPIO 0x015C 369 #define SK_I2CHWCTL 0x0160 370 #define SK_I2CHWDATA 0x0164 371 #define SK_I2CHWIRQ 0x0168 372 #define SK_I2CSW 0x016C 373 #define SK_BLNKINIT 0x0170 374 #define SK_BLNKCOUNT 0x0174 375 #define SK_BLNKCTL 0x0178 376 #define SK_BLNKSTS 0x0179 377 #define SK_BLNKTST 0x017A 378 379 #define SK_IMCTL_STOP 0x02 380 #define SK_IMCTL_START 0x04 381 382 #define SK_IMTIMER_TICKS_GENESIS 177 /* FBSD ticks are 1/100, Haiku 3? secs 53 */ 383 #define SK_IMTIMER_TICKS_YUKON 260 /* FBSD ticks are 1/100, Haiku 3? secs 78 */ 384 #define SK_IM_USECS(x, t) ((x) * (t)) 385 386 #define SK_IM_MIN 10 387 #define SK_IM_DEFAULT 100 388 #define SK_IM_MAX 10000 389 390 /* 391 * The SK_EPROM0 register contains a byte that describes the 392 * amount of SRAM mounted on the NIC. The value also tells if 393 * the chips are 64K or 128K. This affects the RAMbuffer address 394 * offset that we need to use. 395 */ 396 #define SK_RAMSIZE_512K_64 0x1 397 #define SK_RAMSIZE_1024K_128 0x2 398 #define SK_RAMSIZE_1024K_64 0x3 399 #define SK_RAMSIZE_2048K_128 0x4 400 401 #define SK_RBOFF_0 0x0 402 #define SK_RBOFF_80000 0x80000 403 404 /* 405 * SK_EEPROM1 contains the PHY type, which may be XMAC for 406 * fiber-based cards or BCOM for 1000baseT cards with a Broadcom 407 * PHY. 408 */ 409 #define SK_PHYTYPE_XMAC 0 /* integeated XMAC II PHY */ 410 #define SK_PHYTYPE_BCOM 1 /* Broadcom BCM5400 */ 411 #define SK_PHYTYPE_LONE 2 /* Level One LXT1000 */ 412 #define SK_PHYTYPE_NAT 3 /* National DP83891 */ 413 #define SK_PHYTYPE_MARV_COPPER 4 /* Marvell 88E1011S */ 414 #define SK_PHYTYPE_MARV_FIBER 5 /* Marvell 88E1011S (fiber) */ 415 416 /* 417 * PHY addresses. 418 */ 419 #define SK_PHYADDR_XMAC 0x0 420 #define SK_PHYADDR_BCOM 0x1 421 #define SK_PHYADDR_LONE 0x3 422 #define SK_PHYADDR_NAT 0x0 423 #define SK_PHYADDR_MARV 0x0 424 425 #define SK_CONFIG_SINGLEMAC 0x01 426 #define SK_CONFIG_DIS_DSL_CLK 0x02 427 428 #define SK_PMD_1000BASELX 0x4C 429 #define SK_PMD_1000BASESX 0x53 430 #define SK_PMD_1000BASECX 0x43 431 #define SK_PMD_1000BASETX 0x54 432 433 /* GPIO bits */ 434 #define SK_GPIO_DAT0 0x00000001 435 #define SK_GPIO_DAT1 0x00000002 436 #define SK_GPIO_DAT2 0x00000004 437 #define SK_GPIO_DAT3 0x00000008 438 #define SK_GPIO_DAT4 0x00000010 439 #define SK_GPIO_DAT5 0x00000020 440 #define SK_GPIO_DAT6 0x00000040 441 #define SK_GPIO_DAT7 0x00000080 442 #define SK_GPIO_DAT8 0x00000100 443 #define SK_GPIO_DAT9 0x00000200 444 #define SK_GPIO_DIR0 0x00010000 445 #define SK_GPIO_DIR1 0x00020000 446 #define SK_GPIO_DIR2 0x00040000 447 #define SK_GPIO_DIR3 0x00080000 448 #define SK_GPIO_DIR4 0x00100000 449 #define SK_GPIO_DIR5 0x00200000 450 #define SK_GPIO_DIR6 0x00400000 451 #define SK_GPIO_DIR7 0x00800000 452 #define SK_GPIO_DIR8 0x01000000 453 #define SK_GPIO_DIR9 0x02000000 454 455 /* Block 3 Ram interface and MAC arbiter registers */ 456 #define SK_RAMADDR 0x0180 457 #define SK_RAMDATA0 0x0184 458 #define SK_RAMDATA1 0x0188 459 #define SK_TO0 0x0190 460 #define SK_TO1 0x0191 461 #define SK_TO2 0x0192 462 #define SK_TO3 0x0193 463 #define SK_TO4 0x0194 464 #define SK_TO5 0x0195 465 #define SK_TO6 0x0196 466 #define SK_TO7 0x0197 467 #define SK_TO8 0x0198 468 #define SK_TO9 0x0199 469 #define SK_TO10 0x019A 470 #define SK_TO11 0x019B 471 #define SK_RITIMEO_TMR 0x019C 472 #define SK_RAMCTL 0x01A0 473 #define SK_RITIMER_TST 0x01A2 474 475 #define SK_RAMCTL_RESET 0x0001 476 #define SK_RAMCTL_UNRESET 0x0002 477 #define SK_RAMCTL_CLR_IRQ_WPAR 0x0100 478 #define SK_RAMCTL_CLR_IRQ_RPAR 0x0200 479 480 /* Mac arbiter registers */ 481 #define SK_MINIT_RX1 0x01B0 482 #define SK_MINIT_RX2 0x01B1 483 #define SK_MINIT_TX1 0x01B2 484 #define SK_MINIT_TX2 0x01B3 485 #define SK_MTIMEO_RX1 0x01B4 486 #define SK_MTIMEO_RX2 0x01B5 487 #define SK_MTIMEO_TX1 0x01B6 488 #define SK_MTIEMO_TX2 0x01B7 489 #define SK_MACARB_CTL 0x01B8 490 #define SK_MTIMER_TST 0x01BA 491 #define SK_RCINIT_RX1 0x01C0 492 #define SK_RCINIT_RX2 0x01C1 493 #define SK_RCINIT_TX1 0x01C2 494 #define SK_RCINIT_TX2 0x01C3 495 #define SK_RCTIMEO_RX1 0x01C4 496 #define SK_RCTIMEO_RX2 0x01C5 497 #define SK_RCTIMEO_TX1 0x01C6 498 #define SK_RCTIMEO_TX2 0x01C7 499 #define SK_RECOVERY_CTL 0x01C8 500 #define SK_RCTIMER_TST 0x01CA 501 502 /* Packet arbiter registers */ 503 #define SK_RXPA1_TINIT 0x01D0 504 #define SK_RXPA2_TINIT 0x01D4 505 #define SK_TXPA1_TINIT 0x01D8 506 #define SK_TXPA2_TINIT 0x01DC 507 #define SK_RXPA1_TIMEO 0x01E0 508 #define SK_RXPA2_TIMEO 0x01E4 509 #define SK_TXPA1_TIMEO 0x01E8 510 #define SK_TXPA2_TIMEO 0x01EC 511 #define SK_PKTARB_CTL 0x01F0 512 #define SK_PKTATB_TST 0x01F2 513 514 #define SK_PKTARB_TIMEOUT 0x2000 515 516 #define SK_PKTARBCTL_RESET 0x0001 517 #define SK_PKTARBCTL_UNRESET 0x0002 518 #define SK_PKTARBCTL_RXTO1_OFF 0x0004 519 #define SK_PKTARBCTL_RXTO1_ON 0x0008 520 #define SK_PKTARBCTL_RXTO2_OFF 0x0010 521 #define SK_PKTARBCTL_RXTO2_ON 0x0020 522 #define SK_PKTARBCTL_TXTO1_OFF 0x0040 523 #define SK_PKTARBCTL_TXTO1_ON 0x0080 524 #define SK_PKTARBCTL_TXTO2_OFF 0x0100 525 #define SK_PKTARBCTL_TXTO2_ON 0x0200 526 #define SK_PKTARBCTL_CLR_IRQ_RXTO1 0x0400 527 #define SK_PKTARBCTL_CLR_IRQ_RXTO2 0x0800 528 #define SK_PKTARBCTL_CLR_IRQ_TXTO1 0x1000 529 #define SK_PKTARBCTL_CLR_IRQ_TXTO2 0x2000 530 531 #define SK_MINIT_XMAC_B2 54 532 #define SK_MINIT_XMAC_C1 63 533 534 #define SK_MACARBCTL_RESET 0x0001 535 #define SK_MACARBCTL_UNRESET 0x0002 536 #define SK_MACARBCTL_FASTOE_OFF 0x0004 537 #define SK_MACARBCRL_FASTOE_ON 0x0008 538 539 #define SK_RCINIT_XMAC_B2 54 540 #define SK_RCINIT_XMAC_C1 0 541 542 #define SK_RECOVERYCTL_RX1_OFF 0x0001 543 #define SK_RECOVERYCTL_RX1_ON 0x0002 544 #define SK_RECOVERYCTL_RX2_OFF 0x0004 545 #define SK_RECOVERYCTL_RX2_ON 0x0008 546 #define SK_RECOVERYCTL_TX1_OFF 0x0010 547 #define SK_RECOVERYCTL_TX1_ON 0x0020 548 #define SK_RECOVERYCTL_TX2_OFF 0x0040 549 #define SK_RECOVERYCTL_TX2_ON 0x0080 550 551 #define SK_RECOVERY_XMAC_B2 \ 552 (SK_RECOVERYCTL_RX1_ON|SK_RECOVERYCTL_RX2_ON| \ 553 SK_RECOVERYCTL_TX1_ON|SK_RECOVERYCTL_TX2_ON) 554 555 #define SK_RECOVERY_XMAC_C1 \ 556 (SK_RECOVERYCTL_RX1_OFF|SK_RECOVERYCTL_RX2_OFF| \ 557 SK_RECOVERYCTL_TX1_OFF|SK_RECOVERYCTL_TX2_OFF) 558 559 /* Block 4 -- TX Arbiter MAC 1 */ 560 #define SK_TXAR1_TIMERINIT 0x0200 561 #define SK_TXAR1_TIMERVAL 0x0204 562 #define SK_TXAR1_LIMITINIT 0x0208 563 #define SK_TXAR1_LIMITCNT 0x020C 564 #define SK_TXAR1_COUNTERCTL 0x0210 565 #define SK_TXAR1_COUNTERTST 0x0212 566 #define SK_TXAR1_COUNTERSTS 0x0212 567 568 /* Block 5 -- TX Arbiter MAC 2 */ 569 #define SK_TXAR2_TIMERINIT 0x0280 570 #define SK_TXAR2_TIMERVAL 0x0284 571 #define SK_TXAR2_LIMITINIT 0x0288 572 #define SK_TXAR2_LIMITCNT 0x028C 573 #define SK_TXAR2_COUNTERCTL 0x0290 574 #define SK_TXAR2_COUNTERTST 0x0291 575 #define SK_TXAR2_COUNTERSTS 0x0292 576 577 #define SK_TXARCTL_OFF 0x01 578 #define SK_TXARCTL_ON 0x02 579 #define SK_TXARCTL_RATECTL_OFF 0x04 580 #define SK_TXARCTL_RATECTL_ON 0x08 581 #define SK_TXARCTL_ALLOC_OFF 0x10 582 #define SK_TXARCTL_ALLOC_ON 0x20 583 #define SK_TXARCTL_FSYNC_OFF 0x40 584 #define SK_TXARCTL_FSYNC_ON 0x80 585 586 /* Block 6 -- External registers */ 587 #define SK_EXTREG_BASE 0x300 588 #define SK_EXTREG_END 0x37C 589 590 /* Block 7 -- PCI config registers */ 591 #define SK_PCI_BASE 0x0380 592 #define SK_PCI_END 0x03FC 593 594 /* Compute offset of mirrored PCI register */ 595 #define SK_PCI_REG(reg) ((reg) + SK_PCI_BASE) 596 597 /* Block 8 -- RX queue 1 */ 598 #define SK_RXQ1_BUFCNT 0x0400 599 #define SK_RXQ1_BUFCTL 0x0402 600 #define SK_RXQ1_NEXTDESC 0x0404 601 #define SK_RXQ1_RXBUF_LO 0x0408 602 #define SK_RXQ1_RXBUF_HI 0x040C 603 #define SK_RXQ1_RXSTAT 0x0410 604 #define SK_RXQ1_TIMESTAMP 0x0414 605 #define SK_RXQ1_CSUM1 0x0418 606 #define SK_RXQ1_CSUM2 0x041A 607 #define SK_RXQ1_CSUM1_START 0x041C 608 #define SK_RXQ1_CSUM2_START 0x041E 609 #define SK_RXQ1_CURADDR_LO 0x0420 610 #define SK_RXQ1_CURADDR_HI 0x0424 611 #define SK_RXQ1_CURCNT_LO 0x0428 612 #define SK_RXQ1_CURCNT_HI 0x042C 613 #define SK_RXQ1_CURBYTES 0x0430 614 #define SK_RXQ1_BMU_CSR 0x0434 615 #define SK_RXQ1_WATERMARK 0x0438 616 #define SK_RXQ1_FLAG 0x043A 617 #define SK_RXQ1_TEST1 0x043C 618 #define SK_RXQ1_TEST2 0x0440 619 #define SK_RXQ1_TEST3 0x0444 620 621 /* Block 9 -- RX queue 2 */ 622 #define SK_RXQ2_BUFCNT 0x0480 623 #define SK_RXQ2_BUFCTL 0x0482 624 #define SK_RXQ2_NEXTDESC 0x0484 625 #define SK_RXQ2_RXBUF_LO 0x0488 626 #define SK_RXQ2_RXBUF_HI 0x048C 627 #define SK_RXQ2_RXSTAT 0x0490 628 #define SK_RXQ2_TIMESTAMP 0x0494 629 #define SK_RXQ2_CSUM1 0x0498 630 #define SK_RXQ2_CSUM2 0x049A 631 #define SK_RXQ2_CSUM1_START 0x049C 632 #define SK_RXQ2_CSUM2_START 0x049E 633 #define SK_RXQ2_CURADDR_LO 0x04A0 634 #define SK_RXQ2_CURADDR_HI 0x04A4 635 #define SK_RXQ2_CURCNT_LO 0x04A8 636 #define SK_RXQ2_CURCNT_HI 0x04AC 637 #define SK_RXQ2_CURBYTES 0x04B0 638 #define SK_RXQ2_BMU_CSR 0x04B4 639 #define SK_RXQ2_WATERMARK 0x04B8 640 #define SK_RXQ2_FLAG 0x04BA 641 #define SK_RXQ2_TEST1 0x04BC 642 #define SK_RXQ2_TEST2 0x04C0 643 #define SK_RXQ2_TEST3 0x04C4 644 645 #define SK_RXBMU_CLR_IRQ_ERR 0x00000001 646 #define SK_RXBMU_CLR_IRQ_EOF 0x00000002 647 #define SK_RXBMU_CLR_IRQ_EOB 0x00000004 648 #define SK_RXBMU_CLR_IRQ_PAR 0x00000008 649 #define SK_RXBMU_RX_START 0x00000010 650 #define SK_RXBMU_RX_STOP 0x00000020 651 #define SK_RXBMU_POLL_OFF 0x00000040 652 #define SK_RXBMU_POLL_ON 0x00000080 653 #define SK_RXBMU_TRANSFER_SM_RESET 0x00000100 654 #define SK_RXBMU_TRANSFER_SM_UNRESET 0x00000200 655 #define SK_RXBMU_DESCWR_SM_RESET 0x00000400 656 #define SK_RXBMU_DESCWR_SM_UNRESET 0x00000800 657 #define SK_RXBMU_DESCRD_SM_RESET 0x00001000 658 #define SK_RXBMU_DESCRD_SM_UNRESET 0x00002000 659 #define SK_RXBMU_SUPERVISOR_SM_RESET 0x00004000 660 #define SK_RXBMU_SUPERVISOR_SM_UNRESET 0x00008000 661 #define SK_RXBMU_PFI_SM_RESET 0x00010000 662 #define SK_RXBMU_PFI_SM_UNRESET 0x00020000 663 #define SK_RXBMU_FIFO_RESET 0x00040000 664 #define SK_RXBMU_FIFO_UNRESET 0x00080000 665 #define SK_RXBMU_DESC_RESET 0x00100000 666 #define SK_RXBMU_DESC_UNRESET 0x00200000 667 #define SK_RXBMU_SUPERVISOR_IDLE 0x01000000 668 669 #define SK_RXBMU_ONLINE \ 670 (SK_RXBMU_TRANSFER_SM_UNRESET|SK_RXBMU_DESCWR_SM_UNRESET| \ 671 SK_RXBMU_DESCRD_SM_UNRESET|SK_RXBMU_SUPERVISOR_SM_UNRESET| \ 672 SK_RXBMU_PFI_SM_UNRESET|SK_RXBMU_FIFO_UNRESET| \ 673 SK_RXBMU_DESC_UNRESET) 674 675 #define SK_RXBMU_OFFLINE \ 676 (SK_RXBMU_TRANSFER_SM_RESET|SK_RXBMU_DESCWR_SM_RESET| \ 677 SK_RXBMU_DESCRD_SM_RESET|SK_RXBMU_SUPERVISOR_SM_RESET| \ 678 SK_RXBMU_PFI_SM_RESET|SK_RXBMU_FIFO_RESET| \ 679 SK_RXBMU_DESC_RESET) 680 681 /* Block 12 -- TX sync queue 1 */ 682 #define SK_TXQS1_BUFCNT 0x0600 683 #define SK_TXQS1_BUFCTL 0x0602 684 #define SK_TXQS1_NEXTDESC 0x0604 685 #define SK_TXQS1_RXBUF_LO 0x0608 686 #define SK_TXQS1_RXBUF_HI 0x060C 687 #define SK_TXQS1_RXSTAT 0x0610 688 #define SK_TXQS1_CSUM_STARTVAL 0x0614 689 #define SK_TXQS1_CSUM_STARTPOS 0x0618 690 #define SK_TXQS1_CSUM_WRITEPOS 0x061A 691 #define SK_TXQS1_CURADDR_LO 0x0620 692 #define SK_TXQS1_CURADDR_HI 0x0624 693 #define SK_TXQS1_CURCNT_LO 0x0628 694 #define SK_TXQS1_CURCNT_HI 0x062C 695 #define SK_TXQS1_CURBYTES 0x0630 696 #define SK_TXQS1_BMU_CSR 0x0634 697 #define SK_TXQS1_WATERMARK 0x0638 698 #define SK_TXQS1_FLAG 0x063A 699 #define SK_TXQS1_TEST1 0x063C 700 #define SK_TXQS1_TEST2 0x0640 701 #define SK_TXQS1_TEST3 0x0644 702 703 /* Block 13 -- TX async queue 1 */ 704 #define SK_TXQA1_BUFCNT 0x0680 705 #define SK_TXQA1_BUFCTL 0x0682 706 #define SK_TXQA1_NEXTDESC 0x0684 707 #define SK_TXQA1_RXBUF_LO 0x0688 708 #define SK_TXQA1_RXBUF_HI 0x068C 709 #define SK_TXQA1_RXSTAT 0x0690 710 #define SK_TXQA1_CSUM_STARTVAL 0x0694 711 #define SK_TXQA1_CSUM_STARTPOS 0x0698 712 #define SK_TXQA1_CSUM_WRITEPOS 0x069A 713 #define SK_TXQA1_CURADDR_LO 0x06A0 714 #define SK_TXQA1_CURADDR_HI 0x06A4 715 #define SK_TXQA1_CURCNT_LO 0x06A8 716 #define SK_TXQA1_CURCNT_HI 0x06AC 717 #define SK_TXQA1_CURBYTES 0x06B0 718 #define SK_TXQA1_BMU_CSR 0x06B4 719 #define SK_TXQA1_WATERMARK 0x06B8 720 #define SK_TXQA1_FLAG 0x06BA 721 #define SK_TXQA1_TEST1 0x06BC 722 #define SK_TXQA1_TEST2 0x06C0 723 #define SK_TXQA1_TEST3 0x06C4 724 725 /* Block 14 -- TX sync queue 2 */ 726 #define SK_TXQS2_BUFCNT 0x0700 727 #define SK_TXQS2_BUFCTL 0x0702 728 #define SK_TXQS2_NEXTDESC 0x0704 729 #define SK_TXQS2_RXBUF_LO 0x0708 730 #define SK_TXQS2_RXBUF_HI 0x070C 731 #define SK_TXQS2_RXSTAT 0x0710 732 #define SK_TXQS2_CSUM_STARTVAL 0x0714 733 #define SK_TXQS2_CSUM_STARTPOS 0x0718 734 #define SK_TXQS2_CSUM_WRITEPOS 0x071A 735 #define SK_TXQS2_CURADDR_LO 0x0720 736 #define SK_TXQS2_CURADDR_HI 0x0724 737 #define SK_TXQS2_CURCNT_LO 0x0728 738 #define SK_TXQS2_CURCNT_HI 0x072C 739 #define SK_TXQS2_CURBYTES 0x0730 740 #define SK_TXQS2_BMU_CSR 0x0734 741 #define SK_TXQS2_WATERMARK 0x0738 742 #define SK_TXQS2_FLAG 0x073A 743 #define SK_TXQS2_TEST1 0x073C 744 #define SK_TXQS2_TEST2 0x0740 745 #define SK_TXQS2_TEST3 0x0744 746 747 /* Block 15 -- TX async queue 2 */ 748 #define SK_TXQA2_BUFCNT 0x0780 749 #define SK_TXQA2_BUFCTL 0x0782 750 #define SK_TXQA2_NEXTDESC 0x0784 751 #define SK_TXQA2_RXBUF_LO 0x0788 752 #define SK_TXQA2_RXBUF_HI 0x078C 753 #define SK_TXQA2_RXSTAT 0x0790 754 #define SK_TXQA2_CSUM_STARTVAL 0x0794 755 #define SK_TXQA2_CSUM_STARTPOS 0x0798 756 #define SK_TXQA2_CSUM_WRITEPOS 0x079A 757 #define SK_TXQA2_CURADDR_LO 0x07A0 758 #define SK_TXQA2_CURADDR_HI 0x07A4 759 #define SK_TXQA2_CURCNT_LO 0x07A8 760 #define SK_TXQA2_CURCNT_HI 0x07AC 761 #define SK_TXQA2_CURBYTES 0x07B0 762 #define SK_TXQA2_BMU_CSR 0x07B4 763 #define SK_TXQA2_WATERMARK 0x07B8 764 #define SK_TXQA2_FLAG 0x07BA 765 #define SK_TXQA2_TEST1 0x07BC 766 #define SK_TXQA2_TEST2 0x07C0 767 #define SK_TXQA2_TEST3 0x07C4 768 769 #define SK_TXBMU_CLR_IRQ_ERR 0x00000001 770 #define SK_TXBMU_CLR_IRQ_EOF 0x00000002 771 #define SK_TXBMU_CLR_IRQ_EOB 0x00000004 772 #define SK_TXBMU_TX_START 0x00000010 773 #define SK_TXBMU_TX_STOP 0x00000020 774 #define SK_TXBMU_POLL_OFF 0x00000040 775 #define SK_TXBMU_POLL_ON 0x00000080 776 #define SK_TXBMU_TRANSFER_SM_RESET 0x00000100 777 #define SK_TXBMU_TRANSFER_SM_UNRESET 0x00000200 778 #define SK_TXBMU_DESCWR_SM_RESET 0x00000400 779 #define SK_TXBMU_DESCWR_SM_UNRESET 0x00000800 780 #define SK_TXBMU_DESCRD_SM_RESET 0x00001000 781 #define SK_TXBMU_DESCRD_SM_UNRESET 0x00002000 782 #define SK_TXBMU_SUPERVISOR_SM_RESET 0x00004000 783 #define SK_TXBMU_SUPERVISOR_SM_UNRESET 0x00008000 784 #define SK_TXBMU_PFI_SM_RESET 0x00010000 785 #define SK_TXBMU_PFI_SM_UNRESET 0x00020000 786 #define SK_TXBMU_FIFO_RESET 0x00040000 787 #define SK_TXBMU_FIFO_UNRESET 0x00080000 788 #define SK_TXBMU_DESC_RESET 0x00100000 789 #define SK_TXBMU_DESC_UNRESET 0x00200000 790 #define SK_TXBMU_SUPERVISOR_IDLE 0x01000000 791 792 #define SK_TXBMU_ONLINE \ 793 (SK_TXBMU_TRANSFER_SM_UNRESET|SK_TXBMU_DESCWR_SM_UNRESET| \ 794 SK_TXBMU_DESCRD_SM_UNRESET|SK_TXBMU_SUPERVISOR_SM_UNRESET| \ 795 SK_TXBMU_PFI_SM_UNRESET|SK_TXBMU_FIFO_UNRESET| \ 796 SK_TXBMU_DESC_UNRESET|SK_TXBMU_POLL_ON) 797 798 #define SK_TXBMU_OFFLINE \ 799 (SK_TXBMU_TRANSFER_SM_RESET|SK_TXBMU_DESCWR_SM_RESET| \ 800 SK_TXBMU_DESCRD_SM_RESET|SK_TXBMU_SUPERVISOR_SM_RESET| \ 801 SK_TXBMU_PFI_SM_RESET|SK_TXBMU_FIFO_RESET| \ 802 SK_TXBMU_DESC_RESET|SK_TXBMU_POLL_OFF) 803 804 /* Block 16 -- Receive RAMbuffer 1 */ 805 #define SK_RXRB1_START 0x0800 806 #define SK_RXRB1_END 0x0804 807 #define SK_RXRB1_WR_PTR 0x0808 808 #define SK_RXRB1_RD_PTR 0x080C 809 #define SK_RXRB1_UTHR_PAUSE 0x0810 810 #define SK_RXRB1_LTHR_PAUSE 0x0814 811 #define SK_RXRB1_UTHR_HIPRIO 0x0818 812 #define SK_RXRB1_UTHR_LOPRIO 0x081C 813 #define SK_RXRB1_PKTCNT 0x0820 814 #define SK_RXRB1_LVL 0x0824 815 #define SK_RXRB1_CTLTST 0x0828 816 817 /* Block 17 -- Receive RAMbuffer 2 */ 818 #define SK_RXRB2_START 0x0880 819 #define SK_RXRB2_END 0x0884 820 #define SK_RXRB2_WR_PTR 0x0888 821 #define SK_RXRB2_RD_PTR 0x088C 822 #define SK_RXRB2_UTHR_PAUSE 0x0890 823 #define SK_RXRB2_LTHR_PAUSE 0x0894 824 #define SK_RXRB2_UTHR_HIPRIO 0x0898 825 #define SK_RXRB2_UTHR_LOPRIO 0x089C 826 #define SK_RXRB2_PKTCNT 0x08A0 827 #define SK_RXRB2_LVL 0x08A4 828 #define SK_RXRB2_CTLTST 0x08A8 829 830 /* Block 20 -- Sync. Transmit RAMbuffer 1 */ 831 #define SK_TXRBS1_START 0x0A00 832 #define SK_TXRBS1_END 0x0A04 833 #define SK_TXRBS1_WR_PTR 0x0A08 834 #define SK_TXRBS1_RD_PTR 0x0A0C 835 #define SK_TXRBS1_PKTCNT 0x0A20 836 #define SK_TXRBS1_LVL 0x0A24 837 #define SK_TXRBS1_CTLTST 0x0A28 838 839 /* Block 21 -- Async. Transmit RAMbuffer 1 */ 840 #define SK_TXRBA1_START 0x0A80 841 #define SK_TXRBA1_END 0x0A84 842 #define SK_TXRBA1_WR_PTR 0x0A88 843 #define SK_TXRBA1_RD_PTR 0x0A8C 844 #define SK_TXRBA1_PKTCNT 0x0AA0 845 #define SK_TXRBA1_LVL 0x0AA4 846 #define SK_TXRBA1_CTLTST 0x0AA8 847 848 /* Block 22 -- Sync. Transmit RAMbuffer 2 */ 849 #define SK_TXRBS2_START 0x0B00 850 #define SK_TXRBS2_END 0x0B04 851 #define SK_TXRBS2_WR_PTR 0x0B08 852 #define SK_TXRBS2_RD_PTR 0x0B0C 853 #define SK_TXRBS2_PKTCNT 0x0B20 854 #define SK_TXRBS2_LVL 0x0B24 855 #define SK_TXRBS2_CTLTST 0x0B28 856 857 /* Block 23 -- Async. Transmit RAMbuffer 2 */ 858 #define SK_TXRBA2_START 0x0B80 859 #define SK_TXRBA2_END 0x0B84 860 #define SK_TXRBA2_WR_PTR 0x0B88 861 #define SK_TXRBA2_RD_PTR 0x0B8C 862 #define SK_TXRBA2_PKTCNT 0x0BA0 863 #define SK_TXRBA2_LVL 0x0BA4 864 #define SK_TXRBA2_CTLTST 0x0BA8 865 866 #define SK_RBCTL_RESET 0x00000001 867 #define SK_RBCTL_UNRESET 0x00000002 868 #define SK_RBCTL_OFF 0x00000004 869 #define SK_RBCTL_ON 0x00000008 870 #define SK_RBCTL_STORENFWD_OFF 0x00000010 871 #define SK_RBCTL_STORENFWD_ON 0x00000020 872 873 /* Block 24 -- RX MAC FIFO 1 regisrers and LINK_SYNC counter */ 874 #define SK_RXF1_END 0x0C00 875 #define SK_RXF1_WPTR 0x0C04 876 #define SK_RXF1_RPTR 0x0C0C 877 #define SK_RXF1_PKTCNT 0x0C10 878 #define SK_RXF1_LVL 0x0C14 879 #define SK_RXF1_MACCTL 0x0C18 880 #define SK_RXF1_CTL 0x0C1C 881 #define SK_RXLED1_CNTINIT 0x0C20 882 #define SK_RXLED1_COUNTER 0x0C24 883 #define SK_RXLED1_CTL 0x0C28 884 #define SK_RXLED1_TST 0x0C29 885 #define SK_LINK_SYNC1_CINIT 0x0C30 886 #define SK_LINK_SYNC1_COUNTER 0x0C34 887 #define SK_LINK_SYNC1_CTL 0x0C38 888 #define SK_LINK_SYNC1_TST 0x0C39 889 #define SK_LINKLED1_CTL 0x0C3C 890 891 #define SK_FIFO_END 0x3F 892 893 /* Receive MAC FIFO 1 (Yukon Only) */ 894 #define SK_RXMF1_END 0x0C40 895 #define SK_RXMF1_THRESHOLD 0x0C44 896 #define SK_RXMF1_CTRL_TEST 0x0C48 897 #define SK_RXMF1_FLUSH_MASK 0x0C4C 898 #define SK_RXMF1_FLUSH_THRESHOLD 0x0C50 899 #define SK_RXMF1_WRITE_PTR 0x0C60 900 #define SK_RXMF1_WRITE_LEVEL 0x0C68 901 #define SK_RXMF1_READ_PTR 0x0C70 902 #define SK_RXMF1_READ_LEVEL 0x0C78 903 904 /* Receive MAC FIFO 1 Control/Test */ 905 #define SK_RFCTL_WR_PTR_TST_ON 0x00004000 /* Write pointer test on*/ 906 #define SK_RFCTL_WR_PTR_TST_OFF 0x00002000 /* Write pointer test off */ 907 #define SK_RFCTL_WR_PTR_STEP 0x00001000 /* Write pointer increment */ 908 #define SK_RFCTL_RD_PTR_TST_ON 0x00000400 /* Read pointer test on */ 909 #define SK_RFCTL_RD_PTR_TST_OFF 0x00000200 /* Read pointer test off */ 910 #define SK_RFCTL_RD_PTR_STEP 0x00000100 /* Read pointer increment */ 911 #define SK_RFCTL_FIFO_FLUSH_OFF 0x00000080 /* RX FIFO Flsuh mode off */ 912 #define SK_RFCTL_FIFO_FLUSH_ON 0x00000040 /* RX FIFO Flush mode on */ 913 #define SK_RFCTL_RX_FIFO_OVER 0x00000020 /* Clear IRQ RX FIFO Overrun */ 914 #define SK_RFCTL_FRAME_RX_DONE 0x00000010 /* Clear IRQ Frame RX Done */ 915 #define SK_RFCTL_OPERATION_ON 0x00000008 /* Operational mode on */ 916 #define SK_RFCTL_OPERATION_OFF 0x00000004 /* Operational mode off */ 917 #define SK_RFCTL_RESET_CLEAR 0x00000002 /* MAC FIFO Reset Clear */ 918 #define SK_RFCTL_RESET_SET 0x00000001 /* MAC FIFO Reset Set */ 919 920 #define SK_RFCTL_FIFO_THRESHOLD 0x0a /* flush threshold (default) */ 921 922 /* Block 25 -- RX MAC FIFO 2 regisrers and LINK_SYNC counter */ 923 #define SK_RXF2_END 0x0C80 924 #define SK_RXF2_WPTR 0x0C84 925 #define SK_RXF2_RPTR 0x0C8C 926 #define SK_RXF2_PKTCNT 0x0C90 927 #define SK_RXF2_LVL 0x0C94 928 #define SK_RXF2_MACCTL 0x0C98 929 #define SK_RXF2_CTL 0x0C9C 930 #define SK_RXLED2_CNTINIT 0x0CA0 931 #define SK_RXLED2_COUNTER 0x0CA4 932 #define SK_RXLED2_CTL 0x0CA8 933 #define SK_RXLED2_TST 0x0CA9 934 #define SK_LINK_SYNC2_CINIT 0x0CB0 935 #define SK_LINK_SYNC2_COUNTER 0x0CB4 936 #define SK_LINK_SYNC2_CTL 0x0CB8 937 #define SK_LINK_SYNC2_TST 0x0CB9 938 #define SK_LINKLED2_CTL 0x0CBC 939 940 #define SK_RXMACCTL_CLR_IRQ_NOSTS 0x00000001 941 #define SK_RXMACCTL_CLR_IRQ_NOTSTAMP 0x00000002 942 #define SK_RXMACCTL_TSTAMP_OFF 0x00000004 943 #define SK_RXMACCTL_RSTAMP_ON 0x00000008 944 #define SK_RXMACCTL_FLUSH_OFF 0x00000010 945 #define SK_RXMACCTL_FLUSH_ON 0x00000020 946 #define SK_RXMACCTL_PAUSE_OFF 0x00000040 947 #define SK_RXMACCTL_PAUSE_ON 0x00000080 948 #define SK_RXMACCTL_AFULL_OFF 0x00000100 949 #define SK_RXMACCTL_AFULL_ON 0x00000200 950 #define SK_RXMACCTL_VALIDTIME_PATCH_OFF 0x00000400 951 #define SK_RXMACCTL_VALIDTIME_PATCH_ON 0x00000800 952 #define SK_RXMACCTL_RXRDY_PATCH_OFF 0x00001000 953 #define SK_RXMACCTL_RXRDY_PATCH_ON 0x00002000 954 #define SK_RXMACCTL_STS_TIMEO 0x00FF0000 955 #define SK_RXMACCTL_TSTAMP_TIMEO 0xFF000000 956 957 #define SK_RXLEDCTL_ENABLE 0x0001 958 #define SK_RXLEDCTL_COUNTER_STOP 0x0002 959 #define SK_RXLEDCTL_COUNTER_START 0x0004 960 961 #define SK_LINKLED_OFF 0x0001 962 #define SK_LINKLED_ON 0x0002 963 #define SK_LINKLED_LINKSYNC_OFF 0x0004 964 #define SK_LINKLED_LINKSYNC_ON 0x0008 965 #define SK_LINKLED_BLINK_OFF 0x0010 966 #define SK_LINKLED_BLINK_ON 0x0020 967 968 /* Block 26 -- TX MAC FIFO 1 regisrers */ 969 #define SK_TXF1_END 0x0D00 970 #define SK_TXF1_WPTR 0x0D04 971 #define SK_TXF1_RPTR 0x0D0C 972 #define SK_TXF1_PKTCNT 0x0D10 973 #define SK_TXF1_LVL 0x0D14 974 #define SK_TXF1_MACCTL 0x0D18 975 #define SK_TXF1_CTL 0x0D1C 976 #define SK_TXLED1_CNTINIT 0x0D20 977 #define SK_TXLED1_COUNTER 0x0D24 978 #define SK_TXLED1_CTL 0x0D28 979 #define SK_TXLED1_TST 0x0D29 980 981 /* Transmit MAC FIFO 1 (Yukon Only) */ 982 #define SK_TXMF1_END 0x0D40 983 #define SK_TXMF1_THRESHOLD 0x0D44 984 #define SK_TXMF1_CTRL_TEST 0x0D48 985 #define SK_TXMF1_WRITE_PTR 0x0D60 986 #define SK_TXMF1_WRITE_SHADOW 0x0D64 987 #define SK_TXMF1_WRITE_LEVEL 0x0D68 988 #define SK_TXMF1_READ_PTR 0x0D70 989 #define SK_TXMF1_RESTART_PTR 0x0D74 990 #define SK_TXMF1_READ_LEVEL 0x0D78 991 992 /* Transmit MAC FIFO Control/Test */ 993 #define SK_TFCTL_WR_PTR_TST_ON 0x00004000 /* Write pointer test on*/ 994 #define SK_TFCTL_WR_PTR_TST_OFF 0x00002000 /* Write pointer test off */ 995 #define SK_TFCTL_WR_PTR_STEP 0x00001000 /* Write pointer increment */ 996 #define SK_TFCTL_RD_PTR_TST_ON 0x00000400 /* Read pointer test on */ 997 #define SK_TFCTL_RD_PTR_TST_OFF 0x00000200 /* Read pointer test off */ 998 #define SK_TFCTL_RD_PTR_STEP 0x00000100 /* Read pointer increment */ 999 #define SK_TFCTL_TX_FIFO_UNDER 0x00000040 /* Clear IRQ TX FIFO Under */ 1000 #define SK_TFCTL_FRAME_TX_DONE 0x00000020 /* Clear IRQ Frame TX Done */ 1001 #define SK_TFCTL_IRQ_PARITY_ER 0x00000010 /* Clear IRQ Parity Error */ 1002 #define SK_TFCTL_OPERATION_ON 0x00000008 /* Operational mode on */ 1003 #define SK_TFCTL_OPERATION_OFF 0x00000004 /* Operational mode off */ 1004 #define SK_TFCTL_RESET_CLEAR 0x00000002 /* MAC FIFO Reset Clear */ 1005 #define SK_TFCTL_RESET_SET 0x00000001 /* MAC FIFO Reset Set */ 1006 1007 /* Block 27 -- TX MAC FIFO 2 regisrers */ 1008 #define SK_TXF2_END 0x0D80 1009 #define SK_TXF2_WPTR 0x0D84 1010 #define SK_TXF2_RPTR 0x0D8C 1011 #define SK_TXF2_PKTCNT 0x0D90 1012 #define SK_TXF2_LVL 0x0D94 1013 #define SK_TXF2_MACCTL 0x0D98 1014 #define SK_TXF2_CTL 0x0D9C 1015 #define SK_TXLED2_CNTINIT 0x0DA0 1016 #define SK_TXLED2_COUNTER 0x0DA4 1017 #define SK_TXLED2_CTL 0x0DA8 1018 #define SK_TXLED2_TST 0x0DA9 1019 1020 #define SK_TXMACCTL_XMAC_RESET 0x00000001 1021 #define SK_TXMACCTL_XMAC_UNRESET 0x00000002 1022 #define SK_TXMACCTL_LOOP_OFF 0x00000004 1023 #define SK_TXMACCTL_LOOP_ON 0x00000008 1024 #define SK_TXMACCTL_FLUSH_OFF 0x00000010 1025 #define SK_TXMACCTL_FLUSH_ON 0x00000020 1026 #define SK_TXMACCTL_WAITEMPTY_OFF 0x00000040 1027 #define SK_TXMACCTL_WAITEMPTY_ON 0x00000080 1028 #define SK_TXMACCTL_AFULL_OFF 0x00000100 1029 #define SK_TXMACCTL_AFULL_ON 0x00000200 1030 #define SK_TXMACCTL_TXRDY_PATCH_OFF 0x00000400 1031 #define SK_TXMACCTL_RXRDY_PATCH_ON 0x00000800 1032 #define SK_TXMACCTL_PKT_RECOVERY_OFF 0x00001000 1033 #define SK_TXMACCTL_PKT_RECOVERY_ON 0x00002000 1034 #define SK_TXMACCTL_CLR_IRQ_PERR 0x00008000 1035 #define SK_TXMACCTL_WAITAFTERFLUSH 0x00010000 1036 1037 #define SK_TXLEDCTL_ENABLE 0x0001 1038 #define SK_TXLEDCTL_COUNTER_STOP 0x0002 1039 #define SK_TXLEDCTL_COUNTER_START 0x0004 1040 1041 #define SK_FIFO_RESET 0x00000001 1042 #define SK_FIFO_UNRESET 0x00000002 1043 #define SK_FIFO_OFF 0x00000004 1044 #define SK_FIFO_ON 0x00000008 1045 1046 /* Block 28 -- Descriptor Poll Timer */ 1047 #define SK_DPT_INIT 0x0e00 /* Initial value 24 bits */ 1048 #define SK_DPT_TIMER 0x0e04 /* Mul of 78.12MHz clk (24b) */ 1049 1050 #define SK_DPT_TIMER_MAX 0x00ffffffff /* 214.75ms at 78.125MHz */ 1051 1052 #define SK_DPT_TIMER_CTRL 0x0e08 /* Timer Control 16 bits */ 1053 #define SK_DPT_TCTL_STOP 0x0001 /* Stop Timer */ 1054 #define SK_DPT_TCTL_START 0x0002 /* Start Timer */ 1055 1056 #define SK_DPT_TIMER_TEST 0x0e0a /* Timer Test 16 bits */ 1057 #define SK_DPT_TTEST_STEP 0x0001 /* Timer Decrement */ 1058 #define SK_DPT_TTEST_OFF 0x0002 /* Test Mode Off */ 1059 #define SK_DPT_TTEST_ON 0x0004 /* Test Mode On */ 1060 1061 /* Block 29 -- reserved */ 1062 1063 /* Block 30 -- GMAC/GPHY Control Registers (Yukon Only)*/ 1064 #define SK_GMAC_CTRL 0x0f00 /* GMAC Control Register */ 1065 #define SK_GPHY_CTRL 0x0f04 /* GPHY Control Register */ 1066 #define SK_GMAC_ISR 0x0f08 /* GMAC Interrupt Source Register */ 1067 #define SK_GMAC_IMR 0x0f0c /* GMAC Interrupt Mask Register */ 1068 #define SK_LINK_CTRL 0x0f10 /* Link Control Register (LCR) */ 1069 #define SK_WOL_CTRL 0x0f20 /* Wake on LAN Control Register */ 1070 #define SK_MAC_ADDR_LOW 0x0f24 /* Mack Address Registers LOW */ 1071 #define SK_MAC_ADDR_HIGH 0x0f28 /* Mack Address Registers HIGH */ 1072 #define SK_PAT_READ_PTR 0x0f2c /* Pattern Read Pointer Register */ 1073 #define SK_PAT_LEN_REG0 0x0f30 /* Pattern Length Register 0 */ 1074 #define SK_PAT_LEN0 0x0f30 /* Pattern Length 0 */ 1075 #define SK_PAT_LEN1 0x0f31 /* Pattern Length 1 */ 1076 #define SK_PAT_LEN2 0x0f32 /* Pattern Length 2 */ 1077 #define SK_PAT_LEN3 0x0f33 /* Pattern Length 3 */ 1078 #define SK_PAT_LEN_REG1 0x0f34 /* Pattern Length Register 1 */ 1079 #define SK_PAT_LEN4 0x0f34 /* Pattern Length 4 */ 1080 #define SK_PAT_LEN5 0x0f35 /* Pattern Length 5 */ 1081 #define SK_PAT_LEN6 0x0f36 /* Pattern Length 6 */ 1082 #define SK_PAT_LEN7 0x0f37 /* Pattern Length 7 */ 1083 #define SK_PAT_CTR_REG0 0x0f38 /* Pattern Counter Register 0 */ 1084 #define SK_PAT_CTR0 0x0f38 /* Pattern Counter 0 */ 1085 #define SK_PAT_CTR1 0x0f39 /* Pattern Counter 1 */ 1086 #define SK_PAT_CTR2 0x0f3a /* Pattern Counter 2 */ 1087 #define SK_PAT_CTR3 0x0f3b /* Pattern Counter 3 */ 1088 #define SK_PAT_CTR_REG1 0x0f3c /* Pattern Counter Register 1 */ 1089 #define SK_PAT_CTR4 0x0f3c /* Pattern Counter 4 */ 1090 #define SK_PAT_CTR5 0x0f3d /* Pattern Counter 5 */ 1091 #define SK_PAT_CTR6 0x0f3e /* Pattern Counter 6 */ 1092 #define SK_PAT_CTR7 0x0f3f /* Pattern Counter 7 */ 1093 1094 #define SK_GMAC_LOOP_ON 0x00000020 /* Loopback mode for testing */ 1095 #define SK_GMAC_LOOP_OFF 0x00000010 /* purposes */ 1096 #define SK_GMAC_PAUSE_ON 0x00000008 /* enable forward of pause */ 1097 #define SK_GMAC_PAUSE_OFF 0x00000004 /* signal to GMAC */ 1098 #define SK_GMAC_RESET_CLEAR 0x00000002 /* Clear GMAC Reset */ 1099 #define SK_GMAC_RESET_SET 0x00000001 /* Set GMAC Reset */ 1100 1101 #define SK_GPHY_SEL_BDT 0x10000000 /* Select Bidirectional xfer */ 1102 #define SK_GPHY_INT_POL_HI 0x08000000 /* IRQ Polarity Active */ 1103 #define SK_GPHY_75_OHM 0x04000000 /* Use 75 Ohm Termination */ 1104 #define SK_GPHY_DIS_FC 0x02000000 /* Disable Auto Fiber/Copper */ 1105 #define SK_GPHY_DIS_SLEEP 0x01000000 /* Disable Energy Detect */ 1106 #define SK_GPHY_HWCFG_M_3 0x00800000 /* HWCFG_MODE[3] */ 1107 #define SK_GPHY_HWCFG_M_2 0x00400000 /* HWCFG_MODE[2] */ 1108 #define SK_GPHY_HWCFG_M_1 0x00200000 /* HWCFG_MODE[1] */ 1109 #define SK_GPHY_HWCFG_M_0 0x00100000 /* HWCFG_MODE[0] */ 1110 #define SK_GPHY_ANEG_0 0x00080000 /* ANEG[0] */ 1111 #define SK_GPHY_ENA_XC 0x00040000 /* Enable MDI Crossover */ 1112 #define SK_GPHY_DIS_125 0x00020000 /* Disable 125MHz Clock */ 1113 #define SK_GPHY_ANEG_3 0x00010000 /* ANEG[3] */ 1114 #define SK_GPHY_ANEG_2 0x00008000 /* ANEG[2] */ 1115 #define SK_GPHY_ANEG_1 0x00004000 /* ANEG[1] */ 1116 #define SK_GPHY_ENA_PAUSE 0x00002000 /* Enable Pause */ 1117 #define SK_GPHY_PHYADDR_4 0x00001000 /* Bit 4 of Phy Addr */ 1118 #define SK_GPHY_PHYADDR_3 0x00000800 /* Bit 3 of Phy Addr */ 1119 #define SK_GPHY_PHYADDR_2 0x00000400 /* Bit 2 of Phy Addr */ 1120 #define SK_GPHY_PHYADDR_1 0x00000200 /* Bit 1 of Phy Addr */ 1121 #define SK_GPHY_PHYADDR_0 0x00000100 /* Bit 0 of Phy Addr */ 1122 #define SK_GPHY_RESET_CLEAR 0x00000002 /* Clear GPHY Reset */ 1123 #define SK_GPHY_RESET_SET 0x00000001 /* Set GPHY Reset */ 1124 1125 #define SK_GPHY_COPPER (SK_GPHY_HWCFG_M_0 | SK_GPHY_HWCFG_M_1 | \ 1126 SK_GPHY_HWCFG_M_2 | SK_GPHY_HWCFG_M_3 ) 1127 #define SK_GPHY_FIBER (SK_GPHY_HWCFG_M_0 | SK_GPHY_HWCFG_M_1 | \ 1128 SK_GPHY_HWCFG_M_2 ) 1129 #define SK_GPHY_ANEG_ALL (SK_GPHY_ANEG_0 | SK_GPHY_ANEG_1 | \ 1130 SK_GPHY_ANEG_2 | SK_GPHY_ANEG_3 ) 1131 1132 #define SK_GMAC_INT_TX_OFLOW 0x20 /* Transmit Counter Overflow */ 1133 #define SK_GMAC_INT_RX_OFLOW 0x10 /* Receiver Overflow */ 1134 #define SK_GMAC_INT_TX_UNDER 0x08 /* Transmit FIFO Underrun */ 1135 #define SK_GMAC_INT_TX_DONE 0x04 /* Transmit Complete */ 1136 #define SK_GMAC_INT_RX_OVER 0x02 /* Receive FIFO Overrun */ 1137 #define SK_GMAC_INT_RX_DONE 0x01 /* Receive Complete */ 1138 1139 #define SK_LINK_RESET_CLEAR 0x0002 /* Link Reset Clear */ 1140 #define SK_LINK_RESET_SET 0x0001 /* Link Reset Set */ 1141 1142 /* Block 31 -- reserved */ 1143 1144 /* Block 32-33 -- Pattern Ram */ 1145 #define SK_WOL_PRAM 0x1000 1146 1147 /* Block 0x22 - 0x3f -- reserved */ 1148 1149 /* Block 0x40 to 0x4F -- XMAC 1 registers */ 1150 #define SK_XMAC1_BASE 0x2000 1151 1152 /* Block 0x50 to 0x5F -- MARV 1 registers */ 1153 #define SK_MARV1_BASE 0x2800 1154 1155 /* Block 0x60 to 0x6F -- XMAC 2 registers */ 1156 #define SK_XMAC2_BASE 0x3000 1157 1158 /* Block 0x70 to 0x7F -- MARV 2 registers */ 1159 #define SK_MARV2_BASE 0x3800 1160 1161 /* Compute relative offset of an XMAC register in the XMAC window(s). */ 1162 #define SK_XMAC_REG(sc, reg) (((reg) * 2) + SK_XMAC1_BASE + \ 1163 (((sc)->sk_port) * (SK_XMAC2_BASE - SK_XMAC1_BASE))) 1164 1165 #if 0 1166 #define SK_XM_READ_4(sc, reg) \ 1167 ((sk_win_read_2(sc->sk_softc, \ 1168 SK_XMAC_REG(sc, reg)) & 0xFFFF) | \ 1169 ((sk_win_read_2(sc->sk_softc, \ 1170 SK_XMAC_REG(sc, reg + 2)) & 0xFFFF) << 16)) 1171 1172 #define SK_XM_WRITE_4(sc, reg, val) \ 1173 sk_win_write_2(sc->sk_softc, SK_XMAC_REG(sc, reg), \ 1174 ((val) & 0xFFFF)); \ 1175 sk_win_write_2(sc->sk_softc, SK_XMAC_REG(sc, reg + 2), \ 1176 ((val) >> 16) & 0xFFFF) 1177 #else 1178 #define SK_XM_READ_4(sc, reg) \ 1179 sk_win_read_4(sc->sk_softc, SK_XMAC_REG(sc, reg)) 1180 1181 #define SK_XM_WRITE_4(sc, reg, val) \ 1182 sk_win_write_4(sc->sk_softc, SK_XMAC_REG(sc, reg), (val)) 1183 #endif 1184 1185 #define SK_XM_READ_2(sc, reg) \ 1186 sk_win_read_2(sc->sk_softc, SK_XMAC_REG(sc, reg)) 1187 1188 #define SK_XM_WRITE_2(sc, reg, val) \ 1189 sk_win_write_2(sc->sk_softc, SK_XMAC_REG(sc, reg), val) 1190 1191 #define SK_XM_SETBIT_4(sc, reg, x) \ 1192 SK_XM_WRITE_4(sc, reg, (SK_XM_READ_4(sc, reg)) | (x)) 1193 1194 #define SK_XM_CLRBIT_4(sc, reg, x) \ 1195 SK_XM_WRITE_4(sc, reg, (SK_XM_READ_4(sc, reg)) & ~(x)) 1196 1197 #define SK_XM_SETBIT_2(sc, reg, x) \ 1198 SK_XM_WRITE_2(sc, reg, (SK_XM_READ_2(sc, reg)) | (x)) 1199 1200 #define SK_XM_CLRBIT_2(sc, reg, x) \ 1201 SK_XM_WRITE_2(sc, reg, (SK_XM_READ_2(sc, reg)) & ~(x)) 1202 1203 /* Compute relative offset of an MARV register in the MARV window(s). */ 1204 #define SK_YU_REG(sc, reg) \ 1205 ((reg) + SK_MARV1_BASE + \ 1206 (((sc)->sk_port) * (SK_MARV2_BASE - SK_MARV1_BASE))) 1207 1208 #define SK_YU_READ_4(sc, reg) \ 1209 sk_win_read_4((sc)->sk_softc, SK_YU_REG((sc), (reg))) 1210 1211 #define SK_YU_READ_2(sc, reg) \ 1212 sk_win_read_2((sc)->sk_softc, SK_YU_REG((sc), (reg))) 1213 1214 #define SK_YU_WRITE_4(sc, reg, val) \ 1215 sk_win_write_4((sc)->sk_softc, SK_YU_REG((sc), (reg)), (val)) 1216 1217 #define SK_YU_WRITE_2(sc, reg, val) \ 1218 sk_win_write_2((sc)->sk_softc, SK_YU_REG((sc), (reg)), (val)) 1219 1220 #define SK_YU_SETBIT_4(sc, reg, x) \ 1221 SK_YU_WRITE_4(sc, reg, (SK_YU_READ_4(sc, reg)) | (x)) 1222 1223 #define SK_YU_CLRBIT_4(sc, reg, x) \ 1224 SK_YU_WRITE_4(sc, reg, (SK_YU_READ_4(sc, reg)) & ~(x)) 1225 1226 #define SK_YU_SETBIT_2(sc, reg, x) \ 1227 SK_YU_WRITE_2(sc, reg, (SK_YU_READ_2(sc, reg)) | (x)) 1228 1229 #define SK_YU_CLRBIT_2(sc, reg, x) \ 1230 SK_YU_WRITE_2(sc, reg, (SK_YU_READ_2(sc, reg)) & ~(x)) 1231 1232 /* 1233 * The default FIFO threshold on the XMAC II is 4 bytes. On 1234 * dual port NICs, this often leads to transmit underruns, so we 1235 * bump the threshold a little. 1236 */ 1237 #define SK_XM_TX_FIFOTHRESH 512 1238 1239 #define SK_PCI_VENDOR_ID 0x0000 1240 #define SK_PCI_DEVICE_ID 0x0002 1241 #define SK_PCI_COMMAND 0x0004 1242 #define SK_PCI_STATUS 0x0006 1243 #define SK_PCI_REVID 0x0008 1244 #define SK_PCI_CLASSCODE 0x0009 1245 #define SK_PCI_CACHELEN 0x000C 1246 #define SK_PCI_LATENCY_TIMER 0x000D 1247 #define SK_PCI_HEADER_TYPE 0x000E 1248 #define SK_PCI_LOMEM 0x0010 1249 #define SK_PCI_LOIO 0x0014 1250 #define SK_PCI_SUBVEN_ID 0x002C 1251 #define SK_PCI_SYBSYS_ID 0x002E 1252 #define SK_PCI_BIOSROM 0x0030 1253 #define SK_PCI_INTLINE 0x003C 1254 #define SK_PCI_INTPIN 0x003D 1255 #define SK_PCI_MINGNT 0x003E 1256 #define SK_PCI_MINLAT 0x003F 1257 1258 /* device specific PCI registers */ 1259 #define SK_PCI_OURREG1 0x0040 1260 #define SK_PCI_OURREG2 0x0044 1261 #define SK_PCI_CAPID 0x0048 /* 8 bits */ 1262 #define SK_PCI_NEXTPTR 0x0049 /* 8 bits */ 1263 #define SK_PCI_PWRMGMTCAP 0x004A /* 16 bits */ 1264 #define SK_PCI_PWRMGMTCTRL 0x004C /* 16 bits */ 1265 #define SK_PCI_PME_EVENT 0x004F 1266 1267 #define SK_PSTATE_MASK 0x0003 1268 #define SK_PSTATE_D0 0x0000 1269 #define SK_PSTATE_D1 0x0001 1270 #define SK_PSTATE_D2 0x0002 1271 #define SK_PSTATE_D3 0x0003 1272 #define SK_PME_EN 0x0010 1273 #define SK_PME_STATUS 0x8000 1274 1275 #define CSR_WRITE_4(sc, reg, val) \ 1276 bus_write_4((sc)->sk_res[0], (reg), (val)) 1277 #define CSR_WRITE_2(sc, reg, val) \ 1278 bus_write_2((sc)->sk_res[0], (reg), (val)) 1279 #define CSR_WRITE_1(sc, reg, val) \ 1280 bus_write_1((sc)->sk_res[0], (reg), (val)) 1281 1282 #define CSR_READ_4(sc, reg) \ 1283 bus_read_4((sc)->sk_res[0], (reg)) 1284 #define CSR_READ_2(sc, reg) \ 1285 bus_read_2((sc)->sk_res[0], (reg)) 1286 #define CSR_READ_1(sc, reg) \ 1287 bus_read_1((sc)->sk_res[0], (reg)) 1288 1289 struct sk_type { 1290 u_int16_t sk_vid; 1291 u_int16_t sk_did; 1292 char *sk_name; 1293 }; 1294 1295 #define SK_ADDR_LO(x) ((u_int64_t) (x) & 0xffffffff) 1296 #define SK_ADDR_HI(x) ((u_int64_t) (x) >> 32) 1297 1298 #define SK_RING_ALIGN 64 1299 1300 /* RX queue descriptor data structure */ 1301 struct sk_rx_desc { 1302 u_int32_t sk_ctl; 1303 u_int32_t sk_next; 1304 u_int32_t sk_data_lo; 1305 u_int32_t sk_data_hi; 1306 u_int32_t sk_xmac_rxstat; 1307 u_int32_t sk_timestamp; 1308 u_int32_t sk_csum; 1309 u_int32_t sk_csum_start; 1310 }; 1311 1312 #define SK_OPCODE_DEFAULT 0x00550000 1313 #define SK_OPCODE_CSUM 0x00560000 1314 1315 #define SK_RXCTL_LEN 0x0000FFFF 1316 #define SK_RXCTL_OPCODE 0x00FF0000 1317 #define SK_RXCTL_TSTAMP_VALID 0x01000000 1318 #define SK_RXCTL_STATUS_VALID 0x02000000 1319 #define SK_RXCTL_DEV0 0x04000000 1320 #define SK_RXCTL_EOF_INTR 0x08000000 1321 #define SK_RXCTL_EOB_INTR 0x10000000 1322 #define SK_RXCTL_LASTFRAG 0x20000000 1323 #define SK_RXCTL_FIRSTFRAG 0x40000000 1324 #define SK_RXCTL_OWN 0x80000000 1325 1326 #define SK_RXSTAT \ 1327 (SK_RXCTL_EOF_INTR|SK_RXCTL_LASTFRAG|SK_RXCTL_FIRSTFRAG|SK_RXCTL_OWN) 1328 1329 struct sk_tx_desc { 1330 u_int32_t sk_ctl; 1331 u_int32_t sk_next; 1332 u_int32_t sk_data_lo; 1333 u_int32_t sk_data_hi; 1334 u_int32_t sk_xmac_txstat; 1335 u_int32_t sk_csum_startval; 1336 u_int32_t sk_csum_start; 1337 u_int32_t sk_rsvd1; 1338 }; 1339 1340 #define SK_TXCTL_LEN 0x0000FFFF 1341 #define SK_TXCTL_OPCODE 0x00FF0000 1342 #define SK_TXCTL_SW 0x01000000 1343 #define SK_TXCTL_NOCRC 0x02000000 1344 #define SK_TXCTL_STORENFWD 0x04000000 1345 #define SK_TXCTL_EOF_INTR 0x08000000 1346 #define SK_TXCTL_EOB_INTR 0x10000000 1347 #define SK_TXCTL_LASTFRAG 0x20000000 1348 #define SK_TXCTL_FIRSTFRAG 0x40000000 1349 #define SK_TXCTL_OWN 0x80000000 1350 1351 #define SK_TXSTAT \ 1352 (SK_OPCODE_DEFAULT|SK_TXCTL_EOF_INTR|SK_TXCTL_LASTFRAG|SK_TXCTL_OWN) 1353 1354 #define SK_RXBYTES(x) ((x) & 0x0000FFFF) 1355 #define SK_TXBYTES SK_RXBYTES 1356 1357 #define SK_TX_RING_CNT 512 1358 #define SK_RX_RING_CNT 256 1359 #define SK_JUMBO_RX_RING_CNT 256 1360 #define SK_MAXTXSEGS 32 1361 #define SK_MAXRXSEGS 32 1362 1363 /* 1364 * Jumbo buffer stuff. Note that we must allocate more jumbo 1365 * buffers than there are descriptors in the receive ring. This 1366 * is because we don't know how long it will take for a packet 1367 * to be released after we hand it off to the upper protocol 1368 * layers. To be safe, we allocate 1.5 times the number of 1369 * receive descriptors. 1370 */ 1371 #define SK_JUMBO_FRAMELEN 9018 1372 #define SK_JUMBO_MTU (SK_JUMBO_FRAMELEN-ETHER_HDR_LEN-ETHER_CRC_LEN) 1373 #define SK_MAX_FRAMELEN \ 1374 (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN - ETHER_CRC_LEN) 1375 #define SK_MIN_FRAMELEN (ETHER_MIN_LEN - ETHER_CRC_LEN) 1376 #define SK_JSLOTS ((SK_RX_RING_CNT * 3) / 2) 1377 1378 #define SK_JRAWLEN (SK_JUMBO_FRAMELEN + ETHER_ALIGN) 1379 #define SK_JLEN (SK_JRAWLEN + (sizeof(u_int64_t) - \ 1380 (SK_JRAWLEN % sizeof(u_int64_t)))) 1381 #define SK_JPAGESZ PAGE_SIZE 1382 #define SK_RESID (SK_JPAGESZ - (SK_JLEN * SK_JSLOTS) % SK_JPAGESZ) 1383 #define SK_JMEM ((SK_JLEN * SK_JSLOTS) + SK_RESID) 1384 1385 struct sk_jpool_entry { 1386 int slot; 1387 SLIST_ENTRY(sk_jpool_entry) jpool_entries; 1388 }; 1389 1390 struct sk_txdesc { 1391 struct mbuf *tx_m; 1392 bus_dmamap_t tx_dmamap; 1393 STAILQ_ENTRY(sk_txdesc) tx_q; 1394 }; 1395 1396 STAILQ_HEAD(sk_txdq, sk_txdesc); 1397 1398 struct sk_rxdesc { 1399 struct mbuf *rx_m; 1400 bus_dmamap_t rx_dmamap; 1401 }; 1402 1403 struct sk_chain_data { 1404 bus_dma_tag_t sk_parent_tag; 1405 bus_dma_tag_t sk_tx_tag; 1406 struct sk_txdesc sk_txdesc[SK_TX_RING_CNT]; 1407 struct sk_txdq sk_txfreeq; 1408 struct sk_txdq sk_txbusyq; 1409 bus_dma_tag_t sk_rx_tag; 1410 struct sk_rxdesc sk_rxdesc[SK_RX_RING_CNT]; 1411 bus_dma_tag_t sk_tx_ring_tag; 1412 bus_dma_tag_t sk_rx_ring_tag; 1413 bus_dmamap_t sk_tx_ring_map; 1414 bus_dmamap_t sk_rx_ring_map; 1415 bus_dmamap_t sk_rx_sparemap; 1416 bus_dma_tag_t sk_jumbo_rx_tag; 1417 bus_dma_tag_t sk_jumbo_tag; 1418 bus_dmamap_t sk_jumbo_map; 1419 bus_dma_tag_t sk_jumbo_mtag; 1420 caddr_t sk_jslots[SK_JSLOTS]; 1421 struct sk_rxdesc sk_jumbo_rxdesc[SK_JUMBO_RX_RING_CNT]; 1422 bus_dma_tag_t sk_jumbo_rx_ring_tag; 1423 bus_dmamap_t sk_jumbo_rx_ring_map; 1424 bus_dmamap_t sk_jumbo_rx_sparemap; 1425 int sk_tx_prod; 1426 int sk_tx_cons; 1427 int sk_tx_cnt; 1428 int sk_rx_cons; 1429 int sk_jumbo_rx_cons; 1430 }; 1431 1432 struct sk_ring_data { 1433 struct sk_tx_desc *sk_tx_ring; 1434 bus_addr_t sk_tx_ring_paddr; 1435 struct sk_rx_desc *sk_rx_ring; 1436 bus_addr_t sk_rx_ring_paddr; 1437 struct sk_rx_desc *sk_jumbo_rx_ring; 1438 bus_addr_t sk_jumbo_rx_ring_paddr; 1439 void *sk_jumbo_buf; 1440 bus_addr_t sk_jumbo_buf_paddr; 1441 }; 1442 1443 #define SK_TX_RING_ADDR(sc, i) \ 1444 ((sc)->sk_rdata.sk_tx_ring_paddr + sizeof(struct sk_tx_desc) * (i)) 1445 #define SK_RX_RING_ADDR(sc, i) \ 1446 ((sc)->sk_rdata.sk_rx_ring_paddr + sizeof(struct sk_rx_desc) * (i)) 1447 #define SK_JUMBO_RX_RING_ADDR(sc, i) \ 1448 ((sc)->sk_rdata.sk_jumbo_rx_ring_paddr + sizeof(struct sk_rx_desc) * (i)) 1449 1450 #define SK_TX_RING_SZ \ 1451 (sizeof(struct sk_tx_desc) * SK_TX_RING_CNT) 1452 #define SK_RX_RING_SZ \ 1453 (sizeof(struct sk_rx_desc) * SK_RX_RING_CNT) 1454 #define SK_JUMBO_RX_RING_SZ \ 1455 (sizeof(struct sk_rx_desc) * SK_JUMBO_RX_RING_CNT) 1456 1457 struct sk_bcom_hack { 1458 int reg; 1459 int val; 1460 }; 1461 1462 #define SK_INC(x, y) (x) = (x + 1) % y 1463 1464 /* Forward decl. */ 1465 struct sk_if_softc; 1466 1467 /* Softc for the GEnesis controller. */ 1468 struct sk_softc { 1469 struct resource *sk_res[2]; /* I/O and IRQ resources */ 1470 struct resource_spec *sk_res_spec; 1471 void *sk_intrhand; /* irq handler handle */ 1472 device_t sk_dev; 1473 u_int8_t sk_type; 1474 u_int8_t sk_rev; 1475 u_int8_t spare; 1476 u_int32_t sk_rboff; /* RAMbuffer offset */ 1477 u_int32_t sk_ramsize; /* amount of RAM on NIC */ 1478 u_int32_t sk_pmd; /* physical media type */ 1479 u_int32_t sk_coppertype; 1480 u_int32_t sk_intrmask; 1481 u_int32_t sk_intstatus; 1482 int sk_int_mod; 1483 int sk_int_ticks; 1484 int sk_suspended; 1485 struct sk_if_softc *sk_if[2]; 1486 device_t sk_devs[2]; 1487 struct mtx sk_mii_mtx; 1488 struct mtx sk_mtx; 1489 }; 1490 1491 #define SK_LOCK(_sc) mtx_lock(&(_sc)->sk_mtx) 1492 #define SK_UNLOCK(_sc) mtx_unlock(&(_sc)->sk_mtx) 1493 #define SK_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sk_mtx, MA_OWNED) 1494 #define SK_IF_LOCK(_sc) SK_LOCK((_sc)->sk_softc) 1495 #define SK_IF_UNLOCK(_sc) SK_UNLOCK((_sc)->sk_softc) 1496 #define SK_IF_LOCK_ASSERT(_sc) SK_LOCK_ASSERT((_sc)->sk_softc) 1497 #define SK_IF_MII_LOCK(_sc) mtx_lock(&(_sc)->sk_softc->sk_mii_mtx) 1498 #define SK_IF_MII_UNLOCK(_sc) mtx_unlock(&(_sc)->sk_softc->sk_mii_mtx) 1499 1500 /* Softc for each logical interface */ 1501 struct sk_if_softc { 1502 struct ifnet *sk_ifp; /* interface info */ 1503 device_t sk_miibus; 1504 device_t sk_if_dev; 1505 u_int8_t sk_port; /* port # on controller */ 1506 u_int8_t sk_xmac_rev; /* XMAC chip rev (B2 or C1) */ 1507 u_int32_t sk_rx_ramstart; 1508 u_int32_t sk_rx_ramend; 1509 u_int32_t sk_tx_ramstart; 1510 u_int32_t sk_tx_ramend; 1511 int sk_phytype; 1512 int sk_phyaddr; 1513 int sk_link; 1514 struct callout sk_tick_ch; 1515 struct callout sk_watchdog_ch; 1516 int sk_watchdog_timer; 1517 struct sk_chain_data sk_cdata; 1518 struct sk_ring_data sk_rdata; 1519 struct sk_softc *sk_softc; /* parent controller */ 1520 int sk_tx_bmu; /* TX BMU register */ 1521 int sk_if_flags; 1522 SLIST_HEAD(__sk_jfreehead, sk_jpool_entry) sk_jfree_listhead; 1523 SLIST_HEAD(__sk_jinusehead, sk_jpool_entry) sk_jinuse_listhead; 1524 struct mtx sk_jlist_mtx; 1525 }; 1526 1527 #define SK_JLIST_LOCK(_sc) mtx_lock(&(_sc)->sk_jlist_mtx) 1528 #define SK_JLIST_UNLOCK(_sc) mtx_unlock(&(_sc)->sk_jlist_mtx) 1529 1530 #define SK_TIMEOUT 1000 -
src/add-ons/kernel/drivers/network/syskonnect/dev/sk/Jamfile
1 SubDir HAIKU_TOP src add-ons kernel drivers network syskonnect dev sk ; 2 3 UsePrivateHeaders kernel net ; 4 5 UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ; 6 UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ; 7 8 SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ; 9 10 KernelAddon syskonnect : 11 if_sk.c 12 glue.c 13 : libfreebsd_network.a syskonnect_mii.a 14 ; -
src/add-ons/kernel/drivers/network/syskonnect/dev/sk/yukonreg.h
1 /* $OpenBSD: yukonreg.h,v 1.2 2003/08/12 05:23:06 nate Exp $ */ 2 /*- 3 * Copyright (c) 2003 Nathan L. Binkert <binkertn@umich.edu> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * 17 * $FreeBSD: src/sys/dev/sk/yukonreg.h,v 1.3 2006/04/27 05:59:09 yongari Exp $ 18 */ 19 20 /* General Purpose Status Register (GPSR) */ 21 #define YUKON_GPSR 0x0000 22 23 #define YU_GPSR_SPEED 0x8000 /* speed 0 - 10Mbps, 1 - 100Mbps */ 24 #define YU_GPSR_DUPLEX 0x4000 /* 0 - half duplex, 1 - full duplex */ 25 #define YU_GPSR_FCTL_TX 0x2000 /* Tx flow control, 1 - disabled */ 26 #define YU_GPSR_LINK 0x1000 /* link status (down/up) */ 27 #define YU_GPSR_PAUSE 0x0800 /* flow control enable/disable */ 28 #define YU_GPSR_TX_IN_PROG 0x0400 /* transmit in progress */ 29 #define YU_GPSR_EXCESS_COL 0x0200 /* excessive collisions occurred */ 30 #define YU_GPSR_LATE_COL 0x0100 /* late collision occurred */ 31 #define YU_GPSR_MII_PHY_STC 0x0020 /* MII PHY status change */ 32 #define YU_GPSR_GIG_SPEED 0x0010 /* Gigabit Speed (0 - use speed bit) */ 33 #define YU_GPSR_PARTITION 0x0008 /* partition mode */ 34 #define YU_GPSR_FCTL_RX 0x0004 /* Rx flow control, 1 - disabled */ 35 #define YU_GPSR_PROMS_EN 0x0002 /* promiscuous mode, 1 - enabled */ 36 37 /* General Purpose Control Register (GPCR) */ 38 #define YUKON_GPCR 0x0004 39 40 #define YU_GPCR_FCTL_TX_DIS 0x2000 /* Disable Tx flow control 802.3x */ 41 #define YU_GPCR_TXEN 0x1000 /* Transmit Enable */ 42 #define YU_GPCR_RXEN 0x0800 /* Receive Enable */ 43 #define YU_GPCR_BURSTEN 0x0400 /* Burst Mode Enable */ 44 #define YU_GPCR_LPBK 0x0200 /* MAC Loopback Enable */ 45 #define YU_GPCR_PAR 0x0100 /* Partition Enable */ 46 #define YU_GPCR_GIG 0x0080 /* Gigabit Speed 1000Mbps */ 47 #define YU_GPCR_FLP 0x0040 /* Force Link Pass */ 48 #define YU_GPCR_DUPLEX 0x0020 /* Duplex Enable */ 49 #define YU_GPCR_FCTL_RX_DIS 0x0010 /* Disable Rx flow control 802.3x */ 50 #define YU_GPCR_SPEED 0x0008 /* Port Speed 100Mbps */ 51 #define YU_GPCR_DPLX_DIS 0x0004 /* Disable Auto-Update for duplex */ 52 #define YU_GPCR_FCTL_DIS 0x0002 /* Disable Auto-Update for 802.3x */ 53 #define YU_GPCR_SPEED_DIS 0x0001 /* Disable Auto-Update for speed */ 54 55 /* Transmit Control Register (TCR) */ 56 #define YUKON_TCR 0x0008 57 58 #define YU_TCR_FJ 0x8000 /* force jam / flow control */ 59 #define YU_TCR_CRCD 0x4000 /* insert CRC (0 - enable) */ 60 #define YU_TCR_PADD 0x2000 /* pad packets to 64b (0 - enable) */ 61 #define YU_TCR_COLTH 0x1c00 /* collision threshold */ 62 63 /* Receive Control Register (RCR) */ 64 #define YUKON_RCR 0x000c 65 66 #define YU_RCR_UFLEN 0x8000 /* unicast filter enable */ 67 #define YU_RCR_MUFLEN 0x4000 /* multicast filter enable */ 68 #define YU_RCR_CRCR 0x2000 /* remove CRC */ 69 #define YU_RCR_PASSFC 0x1000 /* pass flow control packets */ 70 71 /* Transmit Flow Control Register (TFCR) */ 72 #define YUKON_TFCR 0x0010 /* Pause Time */ 73 74 /* Transmit Parameter Register (TPR) */ 75 #define YUKON_TPR 0x0014 76 77 #define YU_TPR_JAM_LEN(x) (((x) & 0x3) << 14) 78 #define YU_TPR_JAM_IPG(x) (((x) & 0x1f) << 9) 79 #define YU_TPR_JAM2DATA_IPG(x) (((x) & 0x1f) << 4) 80 81 /* Serial Mode Register (SMR) */ 82 #define YUKON_SMR 0x0018 83 84 #define YU_SMR_DATA_BLIND(x) (((x) & 0x1f) << 11) 85 #define YU_SMR_LIMIT4 0x0400 /* reset after 16 / 4 collisions */ 86 #define YU_SMR_MFL_JUMBO 0x0100 /* max frame length for jumbo frames */ 87 #define YU_SMR_MFL_VLAN 0x0200 /* max frame length + vlan tag */ 88 #define YU_SMR_IPG_DATA(x) ((x) & 0x1f) 89 90 /* Source Address Low #1 (SAL1) */ 91 #define YUKON_SAL1 0x001c /* SA1[15:0] */ 92 93 /* Source Address Middle #1 (SAM1) */ 94 #define YUKON_SAM1 0x0020 /* SA1[31:16] */ 95 96 /* Source Address High #1 (SAH1) */ 97 #define YUKON_SAH1 0x0024 /* SA1[47:32] */ 98 99 /* Source Address Low #2 (SAL2) */ 100 #define YUKON_SAL2 0x0028 /* SA2[15:0] */ 101 102 /* Source Address Middle #2 (SAM2) */ 103 #define YUKON_SAM2 0x002c /* SA2[31:16] */ 104 105 /* Source Address High #2 (SAH2) */ 106 #define YUKON_SAH2 0x0030 /* SA2[47:32] */ 107 108 /* Multicatst Address Hash Register 1 (MCAH1) */ 109 #define YUKON_MCAH1 0x0034 110 111 /* Multicatst Address Hash Register 2 (MCAH2) */ 112 #define YUKON_MCAH2 0x0038 113 114 /* Multicatst Address Hash Register 3 (MCAH3) */ 115 #define YUKON_MCAH3 0x003c 116 117 /* Multicatst Address Hash Register 4 (MCAH4) */ 118 #define YUKON_MCAH4 0x0040 119 120 /* Transmit Interrupt Register (TIR) */ 121 #define YUKON_TIR 0x0044 122 123 #define YU_TIR_OUT_UNICAST 0x0001 /* Num Unicast Packets Transmitted */ 124 #define YU_TIR_OUT_BROADCAST 0x0002 /* Num Broadcast Packets Transmitted */ 125 #define YU_TIR_OUT_PAUSE 0x0004 /* Num Pause Packets Transmitted */ 126 #define YU_TIR_OUT_MULTICAST 0x0008 /* Num Multicast Packets Transmitted */ 127 #define YU_TIR_OUT_OCTETS 0x0030 /* Num Bytes Transmitted */ 128 #define YU_TIR_OUT_64_OCTETS 0x0000 /* Num Packets Transmitted */ 129 #define YU_TIR_OUT_127_OCTETS 0x0000 /* Num Packets Transmitted */ 130 #define YU_TIR_OUT_255_OCTETS 0x0000 /* Num Packets Transmitted */ 131 #define YU_TIR_OUT_511_OCTETS 0x0000 /* Num Packets Transmitted */ 132 #define YU_TIR_OUT_1023_OCTETS 0x0000 /* Num Packets Transmitted */ 133 #define YU_TIR_OUT_1518_OCTETS 0x0000 /* Num Packets Transmitted */ 134 #define YU_TIR_OUT_MAX_OCTETS 0x0000 /* Num Packets Transmitted */ 135 #define YU_TIR_OUT_SPARE 0x0000 /* Num Packets Transmitted */ 136 #define YU_TIR_OUT_COLLISIONS 0x0000 /* Num Packets Transmitted */ 137 #define YU_TIR_OUT_LATE 0x0000 /* Num Packets Transmitted */ 138 139 /* Receive Interrupt Register (RIR) */ 140 #define YUKON_RIR 0x0048 141 142 /* Transmit and Receive Interrupt Register (TRIR) */ 143 #define YUKON_TRIR 0x004c 144 145 /* Transmit Interrupt Mask Register (TIMR) */ 146 #define YUKON_TIMR 0x0050 147 148 /* Receive Interrupt Mask Register (RIMR) */ 149 #define YUKON_RIMR 0x0054 150 151 /* Transmit and Receive Interrupt Mask Register (TRIMR) */ 152 #define YUKON_TRIMR 0x0058 153 154 /* SMI Control Register (SMICR) */ 155 #define YUKON_SMICR 0x0080 156 157 #define YU_SMICR_PHYAD(x) (((x) & 0x1f) << 11) 158 #define YU_SMICR_REGAD(x) (((x) & 0x1f) << 6) 159 #define YU_SMICR_OPCODE 0x0020 /* opcode (0 - write, 1 - read) */ 160 #define YU_SMICR_OP_READ 0x0020 /* opcode read */ 161 #define YU_SMICR_OP_WRITE 0x0000 /* opcode write */ 162 #define YU_SMICR_READ_VALID 0x0010 /* read valid */ 163 #define YU_SMICR_BUSY 0x0008 /* busy (writing) */ 164 165 /* SMI Data Register (SMIDR) */ 166 #define YUKON_SMIDR 0x0084 167 168 /* PHY Addres Register (PAR) */ 169 #define YUKON_PAR 0x0088 170 171 #define YU_PAR_MIB_CLR 0x0020 /* MIB Counters Clear Mode */ 172 #define YU_PAR_LOAD_TSTCNT 0x0010 /* Load count 0xfffffff0 into cntr */ 173 174 /* Receive status */ 175 #define YU_RXSTAT_FOFL 0x00000001 /* Rx FIFO overflow */ 176 #define YU_RXSTAT_CRCERR 0x00000002 /* CRC error */ 177 #define YU_RXSTAT_FRAGMENT 0x00000008 /* fragment */ 178 #define YU_RXSTAT_LONGERR 0x00000010 /* too long packet */ 179 #define YU_RXSTAT_MIIERR 0x00000020 /* MII error */ 180 #define YU_RXSTAT_BADFC 0x00000040 /* bad flow-control packet */ 181 #define YU_RXSTAT_GOODFC 0x00000080 /* good flow-control packet */ 182 #define YU_RXSTAT_RXOK 0x00000100 /* receice OK (Good packet) */ 183 #define YU_RXSTAT_BROADCAST 0x00000200 /* broadcast packet */ 184 #define YU_RXSTAT_MULTICAST 0x00000400 /* multicast packet */ 185 #define YU_RXSTAT_RUNT 0x00000800 /* undersize packet */ 186 #define YU_RXSTAT_JABBER 0x00001000 /* jabber packet */ 187 #define YU_RXSTAT_VLAN 0x00002000 /* VLAN packet */ 188 #define YU_RXSTAT_LENSHIFT 16 189 190 #define YU_RXSTAT_BYTES(x) ((x) >> YU_RXSTAT_LENSHIFT) -
src/add-ons/kernel/drivers/network/syskonnect/dev/sk/if_sk.c
1 /* $OpenBSD: if_sk.c,v 2.33 2003/08/12 05:23:06 nate Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998, 1999, 2000 5 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Bill Paul. 18 * 4. Neither the name of the author nor the names of any co-contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 * THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 /*- 35 * Copyright (c) 2003 Nathan L. Binkert <binkertn@umich.edu> 36 * 37 * Permission to use, copy, modify, and distribute this software for any 38 * purpose with or without fee is hereby granted, provided that the above 39 * copyright notice and this permission notice appear in all copies. 40 * 41 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 42 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 43 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 44 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 45 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 46 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 47 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 48 */ 49 50 #include <sys/cdefs.h> 51 __FBSDID("$FreeBSD: src/sys/dev/sk/if_sk.c,v 1.138 2007/11/22 02:44:59 yongari Exp $"); 52 53 /* 54 * SysKonnect SK-NET gigabit ethernet driver for FreeBSD. Supports 55 * the SK-984x series adapters, both single port and dual port. 56 * References: 57 * The XaQti XMAC II datasheet, 58 * http://www.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf 59 * The SysKonnect GEnesis manual, http://www.syskonnect.com 60 * 61 * Note: XaQti has been acquired by Vitesse, and Vitesse does not have the 62 * XMAC II datasheet online. I have put my copy at people.freebsd.org as a 63 * convenience to others until Vitesse corrects this problem: 64 * 65 * http://people.freebsd.org/~wpaul/SysKonnect/xmacii_datasheet_rev_c_9-29.pdf 66 * 67 * Written by Bill Paul <wpaul@ee.columbia.edu> 68 * Department of Electrical Engineering 69 * Columbia University, New York City 70 */ 71 /* 72 * The SysKonnect gigabit ethernet adapters consist of two main 73 * components: the SysKonnect GEnesis controller chip and the XaQti Corp. 74 * XMAC II gigabit ethernet MAC. The XMAC provides all of the MAC 75 * components and a PHY while the GEnesis controller provides a PCI 76 * interface with DMA support. Each card may have between 512K and 77 * 2MB of SRAM on board depending on the configuration. 78 * 79 * The SysKonnect GEnesis controller can have either one or two XMAC 80 * chips connected to it, allowing single or dual port NIC configurations. 81 * SysKonnect has the distinction of being the only vendor on the market 82 * with a dual port gigabit ethernet NIC. The GEnesis provides dual FIFOs, 83 * dual DMA queues, packet/MAC/transmit arbiters and direct access to the 84 * XMAC registers. This driver takes advantage of these features to allow 85 * both XMACs to operate as independent interfaces. 86 */ 87 88 #include <sys/param.h> 89 #include <sys/systm.h> 90 #include <sys/bus.h> 91 #include <sys/endian.h> 92 #include <sys/mbuf.h> 93 #include <sys/malloc.h> 94 #include <sys/kernel.h> 95 #include <sys/module.h> 96 #include <sys/socket.h> 97 #include <sys/sockio.h> 98 #include <sys/queue.h> 99 #include <sys/sysctl.h> 100 101 #include <net/bpf.h> 102 #include <net/ethernet.h> 103 #include <net/if.h> 104 #include <net/if_arp.h> 105 #include <net/if_dl.h> 106 #include <net/if_media.h> 107 #include <net/if_types.h> 108 #include <net/if_vlan_var.h> 109 110 #include <netinet/in.h> 111 #include <netinet/in_systm.h> 112 #include <netinet/ip.h> 113 114 #include <machine/bus.h> 115 #include <machine/in_cksum.h> 116 #include <machine/resource.h> 117 #include <sys/rman.h> 118 119 #include <dev/mii/mii.h> 120 #include <dev/mii/miivar.h> 121 #include <dev/mii/brgphyreg.h> 122 123 #include <dev/pci/pcireg.h> 124 #include <dev/pci/pcivar.h> 125 126 #if 0 127 #define SK_USEIOSPACE 128 #endif 129 130 #include <dev/sk/if_skreg.h> 131 #include <dev/sk/xmaciireg.h> 132 #include <dev/sk/yukonreg.h> 133 134 MODULE_DEPEND(sk, pci, 1, 1, 1); 135 MODULE_DEPEND(sk, ether, 1, 1, 1); 136 MODULE_DEPEND(sk, miibus, 1, 1, 1); 137 138 /* "device miibus" required. See GENERIC if you get errors here. */ 139 #include "miibus_if.h" 140 141 #ifndef lint 142 static const char rcsid[] = 143 "$FreeBSD: src/sys/dev/sk/if_sk.c,v 1.138 2007/11/22 02:44:59 yongari Exp $"; 144 #endif 145 146 static struct sk_type sk_devs[] = { 147 { 148 VENDORID_SK, 149 DEVICEID_SK_V1, 150 "SysKonnect Gigabit Ethernet (V1.0)" 151 }, 152 { 153 VENDORID_SK, 154 DEVICEID_SK_V2, 155 "SysKonnect Gigabit Ethernet (V2.0)" 156 }, 157 { 158 VENDORID_MARVELL, 159 DEVICEID_SK_V2, 160 "Marvell Gigabit Ethernet" 161 }, 162 { 163 VENDORID_MARVELL, 164 DEVICEID_BELKIN_5005, 165 "Belkin F5D5005 Gigabit Ethernet" 166 }, 167 { 168 VENDORID_3COM, 169 DEVICEID_3COM_3C940, 170 "3Com 3C940 Gigabit Ethernet" 171 }, 172 { 173 VENDORID_LINKSYS, 174 DEVICEID_LINKSYS_EG1032, 175 "Linksys EG1032 Gigabit Ethernet" 176 }, 177 { 178 VENDORID_DLINK, 179 DEVICEID_DLINK_DGE530T_A1, 180 "D-Link DGE-530T Gigabit Ethernet" 181 }, 182 { 183 VENDORID_DLINK, 184 DEVICEID_DLINK_DGE530T_B1, 185 "D-Link DGE-530T Gigabit Ethernet" 186 }, 187 { 0, 0, NULL } 188 }; 189 190 static int skc_probe(device_t); 191 static int skc_attach(device_t); 192 static int skc_detach(device_t); 193 static int skc_shutdown(device_t); 194 static int skc_suspend(device_t); 195 static int skc_resume(device_t); 196 static int sk_detach(device_t); 197 static int sk_probe(device_t); 198 static int sk_attach(device_t); 199 static void sk_tick(void *); 200 static void sk_yukon_tick(void *); 201 static void sk_intr(void *); 202 static void sk_intr_xmac(struct sk_if_softc *); 203 static void sk_intr_bcom(struct sk_if_softc *); 204 static void sk_intr_yukon(struct sk_if_softc *); 205 static __inline void sk_rxcksum(struct ifnet *, struct mbuf *, u_int32_t); 206 static __inline int sk_rxvalid(struct sk_softc *, u_int32_t, u_int32_t); 207 static void sk_rxeof(struct sk_if_softc *); 208 static void sk_jumbo_rxeof(struct sk_if_softc *); 209 static void sk_txeof(struct sk_if_softc *); 210 static void sk_txcksum(struct ifnet *, struct mbuf *, struct sk_tx_desc *); 211 static int sk_encap(struct sk_if_softc *, struct mbuf **); 212 static void sk_start(struct ifnet *); 213 static void sk_start_locked(struct ifnet *); 214 static int sk_ioctl(struct ifnet *, u_long, caddr_t); 215 static void sk_init(void *); 216 static void sk_init_locked(struct sk_if_softc *); 217 static void sk_init_xmac(struct sk_if_softc *); 218 static void sk_init_yukon(struct sk_if_softc *); 219 static void sk_stop(struct sk_if_softc *); 220 static void sk_watchdog(void *); 221 static int sk_ifmedia_upd(struct ifnet *); 222 static void sk_ifmedia_sts(struct ifnet *, struct ifmediareq *); 223 static void sk_reset(struct sk_softc *); 224 static __inline void sk_discard_rxbuf(struct sk_if_softc *, int); 225 static __inline void sk_discard_jumbo_rxbuf(struct sk_if_softc *, int); 226 static int sk_newbuf(struct sk_if_softc *, int); 227 static int sk_jumbo_newbuf(struct sk_if_softc *, int); 228 static void sk_dmamap_cb(void *, bus_dma_segment_t *, int, int); 229 static int sk_dma_alloc(struct sk_if_softc *); 230 static void sk_dma_free(struct sk_if_softc *); 231 static void *sk_jalloc(struct sk_if_softc *); 232 static void sk_jfree(void *, void *); 233 static int sk_init_rx_ring(struct sk_if_softc *); 234 static int sk_init_jumbo_rx_ring(struct sk_if_softc *); 235 static void sk_init_tx_ring(struct sk_if_softc *); 236 static u_int32_t sk_win_read_4(struct sk_softc *, int); 237 u_int16_t sk_win_read_2(struct sk_softc *, int); 238 static u_int8_t sk_win_read_1(struct sk_softc *, int); 239 static void sk_win_write_4(struct sk_softc *, int, u_int32_t); 240 void sk_win_write_2(struct sk_softc *, int, u_int32_t); 241 static void sk_win_write_1(struct sk_softc *, int, u_int32_t); 242 243 static int sk_miibus_readreg(device_t, int, int); 244 static int sk_miibus_writereg(device_t, int, int, int); 245 static void sk_miibus_statchg(device_t); 246 247 static int sk_xmac_miibus_readreg(struct sk_if_softc *, int, int); 248 static int sk_xmac_miibus_writereg(struct sk_if_softc *, int, int, 249 int); 250 static void sk_xmac_miibus_statchg(struct sk_if_softc *); 251 252 static int sk_marv_miibus_readreg(struct sk_if_softc *, int, int); 253 static int sk_marv_miibus_writereg(struct sk_if_softc *, int, int, 254 int); 255 static void sk_marv_miibus_statchg(struct sk_if_softc *); 256 257 static uint32_t sk_xmchash(const uint8_t *); 258 static uint32_t sk_gmchash(const uint8_t *); 259 static void sk_setfilt(struct sk_if_softc *, u_int16_t *, int); 260 static void sk_setmulti(struct sk_if_softc *); 261 static void sk_setpromisc(struct sk_if_softc *); 262 263 static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high); 264 static int sysctl_hw_sk_int_mod(SYSCTL_HANDLER_ARGS); 265 266 #ifdef __HAIKU__ 267 static u_short in_addword(u_short a, u_short b); 268 #endif 269 270 /* 271 * It seems that SK-NET GENESIS supports very simple checksum offload 272 * capability for Tx and I believe it can generate 0 checksum value for 273 * UDP packets in Tx as the hardware can't differenciate UDP packets from 274 * TCP packets. 0 chcecksum value for UDP packet is an invalid one as it 275 * means sender didn't perforam checksum computation. For the safety I 276 * disabled UDP checksum offload capability at the moment. Alternatively 277 * we can intrduce a LINK0/LINK1 flag as hme(4) did in its Tx checksum 278 * offload routine. 279 */ 280 #define SK_CSUM_FEATURES (CSUM_TCP) 281 282 /* 283 * Note that we have newbus methods for both the GEnesis controller 284 * itself and the XMAC(s). The XMACs are children of the GEnesis, and 285 * the miibus code is a child of the XMACs. We need to do it this way 286 * so that the miibus drivers can access the PHY registers on the 287 * right PHY. It's not quite what I had in mind, but it's the only 288 * design that achieves the desired effect. 289 */ 290 static device_method_t skc_methods[] = { 291 /* Device interface */ 292 DEVMETHOD(device_probe, skc_probe), 293 DEVMETHOD(device_attach, skc_attach), 294 DEVMETHOD(device_detach, skc_detach), 295 DEVMETHOD(device_suspend, skc_suspend), 296 DEVMETHOD(device_resume, skc_resume), 297 DEVMETHOD(device_shutdown, skc_shutdown), 298 299 /* bus interface */ 300 DEVMETHOD(bus_print_child, bus_generic_print_child), 301 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 302 303 { 0, 0 } 304 }; 305 306 static driver_t skc_driver = { 307 "skc", 308 skc_methods, 309 sizeof(struct sk_softc) 310 }; 311 312 static devclass_t skc_devclass; 313 314 static device_method_t sk_methods[] = { 315 /* Device interface */ 316 DEVMETHOD(device_probe, sk_probe), 317 DEVMETHOD(device_attach, sk_attach), 318 DEVMETHOD(device_detach, sk_detach), 319 DEVMETHOD(device_shutdown, bus_generic_shutdown), 320 321 /* bus interface */ 322 DEVMETHOD(bus_print_child, bus_generic_print_child), 323 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 324 325 /* MII interface */ 326 DEVMETHOD(miibus_readreg, sk_miibus_readreg), 327 DEVMETHOD(miibus_writereg, sk_miibus_writereg), 328 DEVMETHOD(miibus_statchg, sk_miibus_statchg), 329 330 { 0, 0 } 331 }; 332 333 static driver_t sk_driver = { 334 "sk", 335 sk_methods, 336 sizeof(struct sk_if_softc) 337 }; 338 339 static devclass_t sk_devclass; 340 341 DRIVER_MODULE(skc, pci, skc_driver, skc_devclass, 0, 0); 342 DRIVER_MODULE(sk, skc, sk_driver, sk_devclass, 0, 0); 343 DRIVER_MODULE(miibus, sk, miibus_driver, miibus_devclass, 0, 0); 344 345 static struct resource_spec sk_res_spec_io[] = { 346 { SYS_RES_IOPORT, PCIR_BAR(1), RF_ACTIVE }, 347 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 348 { -1, 0, 0 } 349 }; 350 351 static struct resource_spec sk_res_spec_mem[] = { 352 { SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE }, 353 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 354 { -1, 0, 0 } 355 }; 356 357 #define SK_SETBIT(sc, reg, x) \ 358 CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | x) 359 360 #define SK_CLRBIT(sc, reg, x) \ 361 CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~x) 362 363 #define SK_WIN_SETBIT_4(sc, reg, x) \ 364 sk_win_write_4(sc, reg, sk_win_read_4(sc, reg) | x) 365 366 #define SK_WIN_CLRBIT_4(sc, reg, x) \ 367 sk_win_write_4(sc, reg, sk_win_read_4(sc, reg) & ~x) 368 369 #define SK_WIN_SETBIT_2(sc, reg, x) \ 370 sk_win_write_2(sc, reg, sk_win_read_2(sc, reg) | x) 371 372 #define SK_WIN_CLRBIT_2(sc, reg, x) \ 373 sk_win_write_2(sc, reg, sk_win_read_2(sc, reg) & ~x) 374 375 static u_int32_t 376 sk_win_read_4(sc, reg) 377 struct sk_softc *sc; 378 int reg; 379 { 380 #ifdef SK_USEIOSPACE 381 CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); 382 return(CSR_READ_4(sc, SK_WIN_BASE + SK_REG(reg))); 383 #else 384 return(CSR_READ_4(sc, reg)); 385 #endif 386 } 387 388 u_int16_t 389 sk_win_read_2(sc, reg) 390 struct sk_softc *sc; 391 int reg; 392 { 393 #ifdef SK_USEIOSPACE 394 CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); 395 return(CSR_READ_2(sc, SK_WIN_BASE + SK_REG(reg))); 396 #else 397 return(CSR_READ_2(sc, reg)); 398 #endif 399 } 400 401 static u_int8_t 402 sk_win_read_1(sc, reg) 403 struct sk_softc *sc; 404 int reg; 405 { 406 #ifdef SK_USEIOSPACE 407 CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); 408 return(CSR_READ_1(sc, SK_WIN_BASE + SK_REG(reg))); 409 #else 410 return(CSR_READ_1(sc, reg)); 411 #endif 412 } 413 414 static void 415 sk_win_write_4(sc, reg, val) 416 struct sk_softc *sc; 417 int reg; 418 u_int32_t val; 419 { 420 #ifdef SK_USEIOSPACE 421 CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); 422 CSR_WRITE_4(sc, SK_WIN_BASE + SK_REG(reg), val); 423 #else 424 CSR_WRITE_4(sc, reg, val); 425 #endif 426 return; 427 } 428 429 void 430 sk_win_write_2(sc, reg, val) 431 struct sk_softc *sc; 432 int reg; 433 u_int32_t val; 434 { 435 #ifdef SK_USEIOSPACE 436 CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); 437 CSR_WRITE_2(sc, SK_WIN_BASE + SK_REG(reg), val); 438 #else 439 CSR_WRITE_2(sc, reg, val); 440 #endif 441 return; 442 } 443 444 static void 445 sk_win_write_1(sc, reg, val) 446 struct sk_softc *sc; 447 int reg; 448 u_int32_t val; 449 { 450 #ifdef SK_USEIOSPACE 451 CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); 452 CSR_WRITE_1(sc, SK_WIN_BASE + SK_REG(reg), val); 453 #else 454 CSR_WRITE_1(sc, reg, val); 455 #endif 456 return; 457 } 458 459 #ifdef __HAIKU__ 460 /* stole these from in_cksum.c */ 461 #define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) 462 static u_short 463 in_addword(u_short a, u_short b) 464 { 465 u_int64_t sum = a + b; 466 467 ADDCARRY(sum); 468 return (sum); 469 } 470 #endif 471 472 static int 473 sk_miibus_readreg(dev, phy, reg) 474 device_t dev; 475 int phy, reg; 476 { 477 struct sk_if_softc *sc_if; 478 int v; 479 480 sc_if = device_get_softc(dev); 481 482 SK_IF_MII_LOCK(sc_if); 483 switch(sc_if->sk_softc->sk_type) { 484 case SK_GENESIS: 485 v = sk_xmac_miibus_readreg(sc_if, phy, reg); 486 break; 487 case SK_YUKON: 488 case SK_YUKON_LITE: 489 case SK_YUKON_LP: 490 v = sk_marv_miibus_readreg(sc_if, phy, reg); 491 break; 492 default: 493 v = 0; 494 break; 495 } 496 SK_IF_MII_UNLOCK(sc_if); 497 498 return (v); 499 } 500 501 static int 502 sk_miibus_writereg(dev, phy, reg, val) 503 device_t dev; 504 int phy, reg, val; 505 { 506 struct sk_if_softc *sc_if; 507 int v; 508 509 sc_if = device_get_softc(dev); 510 511 SK_IF_MII_LOCK(sc_if); 512 switch(sc_if->sk_softc->sk_type) { 513 case SK_GENESIS: 514 v = sk_xmac_miibus_writereg(sc_if, phy, reg, val); 515 break; 516 case SK_YUKON: 517 case SK_YUKON_LITE: 518 case SK_YUKON_LP: 519 v = sk_marv_miibus_writereg(sc_if, phy, reg, val); 520 break; 521 default: 522 v = 0; 523 break; 524 } 525 SK_IF_MII_UNLOCK(sc_if); 526 527 return (v); 528 } 529 530 static void 531 sk_miibus_statchg(dev) 532 device_t dev; 533 { 534 struct sk_if_softc *sc_if; 535 536 sc_if = device_get_softc(dev); 537 538 SK_IF_MII_LOCK(sc_if); 539 switch(sc_if->sk_softc->sk_type) { 540 case SK_GENESIS: 541 sk_xmac_miibus_statchg(sc_if); 542 break; 543 case SK_YUKON: 544 case SK_YUKON_LITE: 545 case SK_YUKON_LP: 546 sk_marv_miibus_statchg(sc_if); 547 break; 548 } 549 SK_IF_MII_UNLOCK(sc_if); 550 551 return; 552 } 553 554 static int 555 sk_xmac_miibus_readreg(sc_if, phy, reg) 556 struct sk_if_softc *sc_if; 557 int phy, reg; 558 { 559 int i; 560 561 if (sc_if->sk_phytype == SK_PHYTYPE_XMAC && phy != 0) 562 return(0); 563 564 SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8)); 565 SK_XM_READ_2(sc_if, XM_PHY_DATA); 566 if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) { 567 for (i = 0; i < SK_TIMEOUT; i++) { 568 DELAY(1); 569 if (SK_XM_READ_2(sc_if, XM_MMUCMD) & 570 XM_MMUCMD_PHYDATARDY) 571 break; 572 } 573 574 if (i == SK_TIMEOUT) { 575 if_printf(sc_if->sk_ifp, "phy failed to come ready\n"); 576 return(0); 577 } 578 } 579 DELAY(1); 580 i = SK_XM_READ_2(sc_if, XM_PHY_DATA); 581 582 return(i); 583 } 584 585 static int 586 sk_xmac_miibus_writereg(sc_if, phy, reg, val) 587 struct sk_if_softc *sc_if; 588 int phy, reg, val; 589 { 590 int i; 591 592 SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8)); 593 for (i = 0; i < SK_TIMEOUT; i++) { 594 if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY)) 595 break; 596 } 597 598 if (i == SK_TIMEOUT) { 599 if_printf(sc_if->sk_ifp, "phy failed to come ready\n"); 600 return (ETIMEDOUT); 601 } 602 603 SK_XM_WRITE_2(sc_if, XM_PHY_DATA, val); 604 for (i = 0; i < SK_TIMEOUT; i++) { 605 DELAY(1); 606 if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY)) 607 break; 608 } 609 if (i == SK_TIMEOUT) 610 if_printf(sc_if->sk_ifp, "phy write timed out\n"); 611 612 return(0); 613 } 614 615 static void 616 sk_xmac_miibus_statchg(sc_if) 617 struct sk_if_softc *sc_if; 618 { 619 struct mii_data *mii; 620 621 mii = device_get_softc(sc_if->sk_miibus); 622 623 /* 624 * If this is a GMII PHY, manually set the XMAC's 625 * duplex mode accordingly. 626 */ 627 if (sc_if->sk_phytype != SK_PHYTYPE_XMAC) { 628 if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) { 629 SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX); 630 } else { 631 SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_GMIIFDX); 632 } 633 } 634 } 635 636 static int 637 sk_marv_miibus_readreg(sc_if, phy, reg) 638 struct sk_if_softc *sc_if; 639 int phy, reg; 640 { 641 u_int16_t val; 642 int i; 643 644 if (phy != 0 || 645 (sc_if->sk_phytype != SK_PHYTYPE_MARV_COPPER && 646 sc_if->sk_phytype != SK_PHYTYPE_MARV_FIBER)) { 647 return(0); 648 } 649 650 SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) | 651 YU_SMICR_REGAD(reg) | YU_SMICR_OP_READ); 652 653 for (i = 0; i < SK_TIMEOUT; i++) { 654 DELAY(1); 655 val = SK_YU_READ_2(sc_if, YUKON_SMICR); 656 if (val & YU_SMICR_READ_VALID) 657 break; 658 } 659 660 if (i == SK_TIMEOUT) { 661 if_printf(sc_if->sk_ifp, "phy failed to come ready\n"); 662 return(0); 663 } 664 665 val = SK_YU_READ_2(sc_if, YUKON_SMIDR); 666 667 return(val); 668 } 669 670 static int 671 sk_marv_miibus_writereg(sc_if, phy, reg, val) 672 struct sk_if_softc *sc_if; 673 int phy, reg, val; 674 { 675 int i; 676 677 SK_YU_WRITE_2(sc_if, YUKON_SMIDR, val); 678 SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) | 679 YU_SMICR_REGAD(reg) | YU_SMICR_OP_WRITE); 680 681 for (i = 0; i < SK_TIMEOUT; i++) { 682 DELAY(1); 683 if ((SK_YU_READ_2(sc_if, YUKON_SMICR) & YU_SMICR_BUSY) == 0) 684 break; 685 } 686 if (i == SK_TIMEOUT) 687 if_printf(sc_if->sk_ifp, "phy write timeout\n"); 688 689 return(0); 690 } 691 692 static void 693 sk_marv_miibus_statchg(sc_if) 694 struct sk_if_softc *sc_if; 695 { 696 return; 697 } 698 699 #define HASH_BITS 6 700 701 static u_int32_t 702 sk_xmchash(addr) 703 const uint8_t *addr; 704 { 705 uint32_t crc; 706 707 /* Compute CRC for the address value. */ 708 crc = ether_crc32_le(addr, ETHER_ADDR_LEN); 709 710 return (~crc & ((1 << HASH_BITS) - 1)); 711 } 712 713 /* gmchash is just a big endian crc */ 714 static u_int32_t 715 sk_gmchash(addr) 716 const uint8_t *addr; 717 { 718 uint32_t crc; 719 720 /* Compute CRC for the address value. */ 721 crc = ether_crc32_be(addr, ETHER_ADDR_LEN); 722 723 return (crc & ((1 << HASH_BITS) - 1)); 724 } 725 726 static void 727 sk_setfilt(sc_if, addr, slot) 728 struct sk_if_softc *sc_if; 729 u_int16_t *addr; 730 int slot; 731 { 732 int base; 733 734 base = XM_RXFILT_ENTRY(slot); 735 736 SK_XM_WRITE_2(sc_if, base, addr[0]); 737 SK_XM_WRITE_2(sc_if, base + 2, addr[1]); 738 SK_XM_WRITE_2(sc_if, base + 4, addr[2]); 739 740 return; 741 } 742 743 static void 744 sk_setmulti(sc_if) 745 struct sk_if_softc *sc_if; 746 { 747 struct sk_softc *sc = sc_if->sk_softc; 748 struct ifnet *ifp = sc_if->sk_ifp; 749 u_int32_t hashes[2] = { 0, 0 }; 750 int h = 0, i; 751 struct ifmultiaddr *ifma; 752 u_int16_t dummy[] = { 0, 0, 0 }; 753 u_int16_t maddr[(ETHER_ADDR_LEN+1)/2]; 754 755 SK_IF_LOCK_ASSERT(sc_if); 756 757 /* First, zot all the existing filters. */ 758 switch(sc->sk_type) { 759 case SK_GENESIS: 760 for (i = 1; i < XM_RXFILT_MAX; i++) 761 sk_setfilt(sc_if, dummy, i); 762 763 SK_XM_WRITE_4(sc_if, XM_MAR0, 0); 764 SK_XM_WRITE_4(sc_if, XM_MAR2, 0); 765 break; 766 case SK_YUKON: 767 case SK_YUKON_LITE: 768 case SK_YUKON_LP: 769 SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0); 770 SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0); 771 SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0); 772 SK_YU_WRITE_2(sc_if, YUKON_MCAH4, 0); 773 break; 774 } 775 776 /* Now program new ones. */ 777 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 778 hashes[0] = 0xFFFFFFFF; 779 hashes[1] = 0xFFFFFFFF; 780 } else { 781 i = 1; 782 IF_ADDR_LOCK(ifp); 783 TAILQ_FOREACH_REVERSE(ifma, &ifp->if_multiaddrs, ifmultihead, ifma_link) { 784 if (ifma->ifma_addr->sa_family != AF_LINK) 785 continue; 786 /* 787 * Program the first XM_RXFILT_MAX multicast groups 788 * into the perfect filter. For all others, 789 * use the hash table. 790 */ 791 if (sc->sk_type == SK_GENESIS && i < XM_RXFILT_MAX) { 792 bcopy(LLADDR( 793 (struct sockaddr_dl *)ifma->ifma_addr), 794 maddr, ETHER_ADDR_LEN); 795 sk_setfilt(sc_if, maddr, i); 796 i++; 797 continue; 798 } 799 800 switch(sc->sk_type) { 801 case SK_GENESIS: 802 bcopy(LLADDR( 803 (struct sockaddr_dl *)ifma->ifma_addr), 804 maddr, ETHER_ADDR_LEN); 805 h = sk_xmchash((const uint8_t *)maddr); 806 break; 807 case SK_YUKON: 808 case SK_YUKON_LITE: 809 case SK_YUKON_LP: 810 bcopy(LLADDR( 811 (struct sockaddr_dl *)ifma->ifma_addr), 812 maddr, ETHER_ADDR_LEN); 813 h = sk_gmchash((const uint8_t *)maddr); 814 break; 815 } 816 if (h < 32) 817 hashes[0] |= (1 << h); 818 else 819 hashes[1] |= (1 << (h - 32)); 820 } 821 IF_ADDR_UNLOCK(ifp); 822 } 823 824 switch(sc->sk_type) { 825 case SK_GENESIS: 826 SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_HASH| 827 XM_MODE_RX_USE_PERFECT); 828 SK_XM_WRITE_4(sc_if, XM_MAR0, hashes[0]); 829 SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]); 830 break; 831 case SK_YUKON: 832 case SK_YUKON_LITE: 833 case SK_YUKON_LP: 834 SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff); 835 SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff); 836 SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff); 837 SK_YU_WRITE_2(sc_if, YUKON_MCAH4, (hashes[1] >> 16) & 0xffff); 838 break; 839 } 840 841 return; 842 } 843 844 static void 845 sk_setpromisc(sc_if) 846 struct sk_if_softc *sc_if; 847 { 848 struct sk_softc *sc = sc_if->sk_softc; 849 struct ifnet *ifp = sc_if->sk_ifp; 850 851 SK_IF_LOCK_ASSERT(sc_if); 852 853 switch(sc->sk_type) { 854 case SK_GENESIS: 855 if (ifp->if_flags & IFF_PROMISC) { 856 SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC); 857 } else { 858 SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC); 859 } 860 break; 861 case SK_YUKON: 862 case SK_YUKON_LITE: 863 case SK_YUKON_LP: 864 if (ifp->if_flags & IFF_PROMISC) { 865 SK_YU_CLRBIT_2(sc_if, YUKON_RCR, 866 YU_RCR_UFLEN | YU_RCR_MUFLEN); 867 } else { 868 SK_YU_SETBIT_2(sc_if, YUKON_RCR, 869 YU_RCR_UFLEN | YU_RCR_MUFLEN); 870 } 871 break; 872 } 873 874 return; 875 } 876 877 static int 878 sk_init_rx_ring(sc_if) 879 struct sk_if_softc *sc_if; 880 { 881 struct sk_ring_data *rd; 882 bus_addr_t addr; 883 u_int32_t csum_start; 884 int i; 885 886 sc_if->sk_cdata.sk_rx_cons = 0; 887 888 csum_start = (ETHER_HDR_LEN + sizeof(struct ip)) << 16 | 889 ETHER_HDR_LEN; 890 rd = &sc_if->sk_rdata; 891 bzero(rd->sk_rx_ring, sizeof(struct sk_rx_desc) * SK_RX_RING_CNT); 892 for (i = 0; i < SK_RX_RING_CNT; i++) { 893 if (sk_newbuf(sc_if, i) != 0) 894 return (ENOBUFS); 895 if (i == (SK_RX_RING_CNT - 1)) 896 addr = SK_RX_RING_ADDR(sc_if, 0); 897 else 898 addr = SK_RX_RING_ADDR(sc_if, i + 1); 899 rd->sk_rx_ring[i].sk_next = htole32(SK_ADDR_LO(addr)); 900 rd->sk_rx_ring[i].sk_csum_start = htole32(csum_start); 901 } 902 903 bus_dmamap_sync(sc_if->sk_cdata.sk_rx_ring_tag, 904 sc_if->sk_cdata.sk_rx_ring_map, 905 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 906 907 return(0); 908 } 909 910 static int 911 sk_init_jumbo_rx_ring(sc_if) 912 struct sk_if_softc *sc_if; 913 { 914 struct sk_ring_data *rd; 915 bus_addr_t addr; 916 u_int32_t csum_start; 917 int i; 918 919 sc_if->sk_cdata.sk_jumbo_rx_cons = 0; 920 921 csum_start = ((ETHER_HDR_LEN + sizeof(struct ip)) << 16) | 922 ETHER_HDR_LEN; 923 rd = &sc_if->sk_rdata; 924 bzero(rd->sk_jumbo_rx_ring, 925 sizeof(struct sk_rx_desc) * SK_JUMBO_RX_RING_CNT); 926 for (i = 0; i < SK_JUMBO_RX_RING_CNT; i++) { 927 if (sk_jumbo_newbuf(sc_if, i) != 0) 928 return (ENOBUFS); 929 if (i == (SK_JUMBO_RX_RING_CNT - 1)) 930 addr = SK_JUMBO_RX_RING_ADDR(sc_if, 0); 931 else 932 addr = SK_JUMBO_RX_RING_ADDR(sc_if, i + 1); 933 rd->sk_jumbo_rx_ring[i].sk_next = htole32(SK_ADDR_LO(addr)); 934 rd->sk_jumbo_rx_ring[i].sk_csum_start = htole32(csum_start); 935 } 936 937 bus_dmamap_sync(sc_if->sk_cdata.sk_jumbo_rx_ring_tag, 938 sc_if->sk_cdata.sk_jumbo_rx_ring_map, 939 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 940 941 return (0); 942 } 943 944 static void 945 sk_init_tx_ring(sc_if) 946 struct sk_if_softc *sc_if; 947 { 948 struct sk_ring_data *rd; 949 struct sk_txdesc *txd; 950 bus_addr_t addr; 951 int i; 952 953 STAILQ_INIT(&sc_if->sk_cdata.sk_txfreeq); 954 STAILQ_INIT(&sc_if->sk_cdata.sk_txbusyq); 955 956 sc_if->sk_cdata.sk_tx_prod = 0; 957 sc_if->sk_cdata.sk_tx_cons = 0; 958 sc_if->sk_cdata.sk_tx_cnt = 0; 959 960 rd = &sc_if->sk_rdata; 961 bzero(rd->sk_tx_ring, sizeof(struct sk_tx_desc) * SK_TX_RING_CNT); 962 for (i = 0; i < SK_TX_RING_CNT; i++) { 963 if (i == (SK_TX_RING_CNT - 1)) 964 addr = SK_TX_RING_ADDR(sc_if, 0); 965 else 966 addr = SK_TX_RING_ADDR(sc_if, i + 1); 967 rd->sk_tx_ring[i].sk_next = htole32(SK_ADDR_LO(addr)); 968 txd = &sc_if->sk_cdata.sk_txdesc[i]; 969 STAILQ_INSERT_TAIL(&sc_if->sk_cdata.sk_txfreeq, txd, tx_q); 970 } 971 972 bus_dmamap_sync(sc_if->sk_cdata.sk_tx_ring_tag, 973 sc_if->sk_cdata.sk_tx_ring_map, 974 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 975 } 976 977 static __inline void 978 sk_discard_rxbuf(sc_if, idx) 979 struct sk_if_softc *sc_if; 980 int idx; 981 { 982 struct sk_rx_desc *r; 983 struct sk_rxdesc *rxd; 984 struct mbuf *m; 985 986 987 r = &sc_if->sk_rdata.sk_rx_ring[idx]; 988 rxd = &sc_if->sk_cdata.sk_rxdesc[idx]; 989 m = rxd->rx_m; 990 r->sk_ctl = htole32(m->m_len | SK_RXSTAT | SK_OPCODE_CSUM); 991 } 992 993 static __inline void 994 sk_discard_jumbo_rxbuf(sc_if, idx) 995 struct sk_if_softc *sc_if; 996 int idx; 997 { 998 struct sk_rx_desc *r; 999 struct sk_rxdesc *rxd; 1000 struct mbuf *m; 1001 1002 r = &sc_if->sk_rdata.sk_jumbo_rx_ring[idx]; 1003 rxd = &sc_if->sk_cdata.sk_jumbo_rxdesc[idx]; 1004 m = rxd->rx_m; 1005 r->sk_ctl = htole32(m->m_len | SK_RXSTAT | SK_OPCODE_CSUM); 1006 } 1007 1008 static int 1009 sk_newbuf(sc_if, idx) 1010 struct sk_if_softc *sc_if; 1011 int idx; 1012 { 1013 struct sk_rx_desc *r; 1014 struct sk_rxdesc *rxd; 1015 struct mbuf *m; 1016 bus_dma_segment_t segs[1]; 1017 bus_dmamap_t map; 1018 int nsegs; 1019 1020 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 1021 if (m == NULL) 1022 return (ENOBUFS); 1023 m->m_len = m->m_pkthdr.len = MCLBYTES; 1024 m_adj(m, ETHER_ALIGN); 1025 1026 if (bus_dmamap_load_mbuf_sg(sc_if->sk_cdata.sk_rx_tag, 1027 sc_if->sk_cdata.sk_rx_sparemap, m, segs, &nsegs, 0) != 0) { 1028 m_freem(m); 1029 return (ENOBUFS); 1030 } 1031 KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs)); 1032 1033 rxd = &sc_if->sk_cdata.sk_rxdesc[idx]; 1034 if (rxd->rx_m != NULL) { 1035 bus_dmamap_sync(sc_if->sk_cdata.sk_rx_tag, rxd->rx_dmamap, 1036 BUS_DMASYNC_POSTREAD); 1037 bus_dmamap_unload(sc_if->sk_cdata.sk_rx_tag, rxd->rx_dmamap); 1038 } 1039 map = rxd->rx_dmamap; 1040 rxd->rx_dmamap = sc_if->sk_cdata.sk_rx_sparemap; 1041 sc_if->sk_cdata.sk_rx_sparemap = map; 1042 bus_dmamap_sync(sc_if->sk_cdata.sk_rx_tag, rxd->rx_dmamap, 1043 BUS_DMASYNC_PREREAD); 1044 rxd->rx_m = m; 1045 r = &sc_if->sk_rdata.sk_rx_ring[idx]; 1046 r->sk_data_lo = htole32(SK_ADDR_LO(segs[0].ds_addr)); 1047 r->sk_data_hi = htole32(SK_ADDR_HI(segs[0].ds_addr)); 1048 r->sk_ctl = htole32(segs[0].ds_len | SK_RXSTAT | SK_OPCODE_CSUM); 1049 1050 return (0); 1051 } 1052 1053 static int 1054 sk_jumbo_newbuf(sc_if, idx) 1055 struct sk_if_softc *sc_if; 1056 int idx; 1057 { 1058 struct sk_rx_desc *r; 1059 struct sk_rxdesc *rxd; 1060 struct mbuf *m; 1061 bus_dma_segment_t segs[1]; 1062 bus_dmamap_t map; 1063 int nsegs; 1064 void *buf; 1065 1066 MGETHDR(m, M_DONTWAIT, MT_DATA); 1067 if (m == NULL) 1068 return (ENOBUFS); 1069 buf = sk_jalloc(sc_if); 1070 if (buf == NULL) { 1071 m_freem(m); 1072 return (ENOBUFS); 1073 } 1074 /* Attach the buffer to the mbuf */ 1075 MEXTADD(m, buf, SK_JLEN, sk_jfree, (struct sk_if_softc *)sc_if, 0, 1076 EXT_NET_DRV); 1077 if ((m->m_flags & M_EXT) == 0) { 1078 m_freem(m); 1079 return (ENOBUFS); 1080 } 1081 m->m_pkthdr.len = m->m_len = SK_JLEN; 1082 /* 1083 * Adjust alignment so packet payload begins on a 1084 * longword boundary. Mandatory for Alpha, useful on 1085 * x86 too. 1086 */ 1087 m_adj(m, ETHER_ALIGN); 1088 1089 if (bus_dmamap_load_mbuf_sg(sc_if->sk_cdata.sk_jumbo_rx_tag, 1090 sc_if->sk_cdata.sk_jumbo_rx_sparemap, m, segs, &nsegs, 0) != 0) { 1091 m_freem(m); 1092 return (ENOBUFS); 1093 } 1094 KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs)); 1095 1096 rxd = &sc_if->sk_cdata.sk_jumbo_rxdesc[idx]; 1097 if (rxd->rx_m != NULL) { 1098 bus_dmamap_sync(sc_if->sk_cdata.sk_jumbo_rx_tag, rxd->rx_dmamap, 1099 BUS_DMASYNC_POSTREAD); 1100 bus_dmamap_unload(sc_if->sk_cdata.sk_jumbo_rx_tag, 1101 rxd->rx_dmamap); 1102 } 1103 map = rxd->rx_dmamap; 1104 rxd->rx_dmamap = sc_if->sk_cdata.sk_jumbo_rx_sparemap; 1105 sc_if->sk_cdata.sk_jumbo_rx_sparemap = map; 1106 bus_dmamap_sync(sc_if->sk_cdata.sk_jumbo_rx_tag, rxd->rx_dmamap, 1107 BUS_DMASYNC_PREREAD); 1108 rxd->rx_m = m; 1109 r = &sc_if->sk_rdata.sk_jumbo_rx_ring[idx]; 1110 r->sk_data_lo = htole32(SK_ADDR_LO(segs[0].ds_addr)); 1111 r->sk_data_hi = htole32(SK_ADDR_HI(segs[0].ds_addr)); 1112 r->sk_ctl = htole32(segs[0].ds_len | SK_RXSTAT | SK_OPCODE_CSUM); 1113 1114 return (0); 1115 } 1116 1117 /* 1118 * Set media options. 1119 */ 1120 static int 1121 sk_ifmedia_upd(ifp) 1122 struct ifnet *ifp; 1123 { 1124 struct sk_if_softc *sc_if = ifp->if_softc; 1125 struct mii_data *mii; 1126 1127 mii = device_get_softc(sc_if->sk_miibus); 1128 sk_init(sc_if); 1129 mii_mediachg(mii); 1130 1131 return(0); 1132 } 1133 1134 /* 1135 * Report current media status. 1136 */ 1137 static void 1138 sk_ifmedia_sts(ifp, ifmr) 1139 struct ifnet *ifp; 1140 struct ifmediareq *ifmr; 1141 { 1142 struct sk_if_softc *sc_if; 1143 struct mii_data *mii; 1144 1145 sc_if = ifp->if_softc; 1146 mii = device_get_softc(sc_if->sk_miibus); 1147 1148 mii_pollstat(mii); 1149 ifmr->ifm_active = mii->mii_media_active; 1150 ifmr->ifm_status = mii->mii_media_status; 1151 1152 return; 1153 } 1154 1155 static int 1156 sk_ioctl(ifp, command, data) 1157 struct ifnet *ifp; 1158 u_long command; 1159 caddr_t data; 1160 { 1161 struct sk_if_softc *sc_if = ifp->if_softc; 1162 struct ifreq *ifr = (struct ifreq *) data; 1163 int error, mask; 1164 struct mii_data *mii; 1165 1166 error = 0; 1167 switch(command) { 1168 case SIOCSIFMTU: 1169 SK_IF_LOCK(sc_if); 1170 if (ifr->ifr_mtu > SK_JUMBO_MTU) 1171 error = EINVAL; 1172 else { 1173 ifp->if_mtu = ifr->ifr_mtu; 1174 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1175 sk_init_locked(sc_if); 1176 } 1177 SK_IF_UNLOCK(sc_if); 1178 break; 1179 case SIOCSIFFLAGS: 1180 SK_IF_LOCK(sc_if); 1181 if (ifp->if_flags & IFF_UP) { 1182 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 1183 if ((ifp->if_flags ^ sc_if->sk_if_flags) 1184 & IFF_PROMISC) { 1185 sk_setpromisc(sc_if); 1186 sk_setmulti(sc_if); 1187 } 1188 } else 1189 sk_init_locked(sc_if); 1190 } else { 1191 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1192 sk_stop(sc_if); 1193 } 1194 sc_if->sk_if_flags = ifp->if_flags; 1195 SK_IF_UNLOCK(sc_if); 1196 break; 1197 case SIOCADDMULTI: 1198 case SIOCDELMULTI: 1199 SK_IF_LOCK(sc_if); 1200 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1201 sk_setmulti(sc_if); 1202 SK_IF_UNLOCK(sc_if); 1203 break; 1204 case SIOCGIFMEDIA: 1205 case SIOCSIFMEDIA: 1206 mii = device_get_softc(sc_if->sk_miibus); 1207 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 1208 break; 1209 case SIOCSIFCAP: 1210 SK_IF_LOCK(sc_if); 1211 if (sc_if->sk_softc->sk_type == SK_GENESIS) { 1212 SK_IF_UNLOCK(sc_if); 1213 break; 1214 } 1215 mask = ifr->ifr_reqcap ^ ifp->if_capenable; 1216 if (mask & IFCAP_HWCSUM) { 1217 ifp->if_capenable ^= IFCAP_HWCSUM; 1218 if (IFCAP_HWCSUM & ifp->if_capenable && 1219 IFCAP_HWCSUM & ifp->if_capabilities) 1220 ifp->if_hwassist = SK_CSUM_FEATURES; 1221 else 1222 ifp->if_hwassist = 0; 1223 } 1224 SK_IF_UNLOCK(sc_if); 1225 break; 1226 default: 1227 error = ether_ioctl(ifp, command, data); 1228 break; 1229 } 1230 1231 return (error); 1232 } 1233 1234 /* 1235 * Probe for a SysKonnect GEnesis chip. Check the PCI vendor and device 1236 * IDs against our list and return a device name if we find a match. 1237 */ 1238 static int 1239 skc_probe(dev) 1240 device_t dev; 1241 { 1242 struct sk_type *t = sk_devs; 1243 1244 1245 while(t->sk_name != NULL) { 1246 if ((pci_get_vendor(dev) == t->sk_vid) && 1247 (pci_get_device(dev) == t->sk_did)) { 1248 /* 1249 * Only attach to rev. 2 of the Linksys EG1032 adapter. 1250 * Rev. 3 is supported by re(4). 1251 */ 1252 if ((t->sk_vid == VENDORID_LINKSYS) && 1253 (t->sk_did == DEVICEID_LINKSYS_EG1032) && 1254 (pci_get_subdevice(dev) != 1255 SUBDEVICEID_LINKSYS_EG1032_REV2)) { 1256 t++; 1257 continue; 1258 } 1259 device_set_desc(dev, t->sk_name); 1260 return (BUS_PROBE_DEFAULT); 1261 } 1262 t++; 1263 } 1264 1265 return(ENXIO); 1266 } 1267 1268 /* 1269 * Force the GEnesis into reset, then bring it out of reset. 1270 */ 1271 static void 1272 sk_reset(sc) 1273 struct sk_softc *sc; 1274 { 1275 1276 CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_RESET); 1277 CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_RESET); 1278 if (SK_YUKON_FAMILY(sc->sk_type)) 1279 CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET); 1280 1281 DELAY(1000); 1282 CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_UNRESET); 1283 DELAY(2); 1284 CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_UNRESET); 1285 if (SK_YUKON_FAMILY(sc->sk_type)) 1286 CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR); 1287 1288 if (sc->sk_type == SK_GENESIS) { 1289 /* Configure packet arbiter */ 1290 sk_win_write_2(sc, SK_PKTARB_CTL, SK_PKTARBCTL_UNRESET); 1291 sk_win_write_2(sc, SK_RXPA1_TINIT, SK_PKTARB_TIMEOUT); 1292 sk_win_write_2(sc, SK_TXPA1_TINIT, SK_PKTARB_TIMEOUT); 1293 sk_win_write_2(sc, SK_RXPA2_TINIT, SK_PKTARB_TIMEOUT); 1294 sk_win_write_2(sc, SK_TXPA2_TINIT, SK_PKTARB_TIMEOUT); 1295 } 1296 1297 /* Enable RAM interface */ 1298 sk_win_write_4(sc, SK_RAMCTL, SK_RAMCTL_UNRESET); 1299 1300 /* 1301 * Configure interrupt moderation. The moderation timer 1302 * defers interrupts specified in the interrupt moderation 1303 * timer mask based on the timeout specified in the interrupt 1304 * moderation timer init register. Each bit in the timer 1305 * register represents one tick, so to specify a timeout in 1306 * microseconds, we have to multiply by the correct number of 1307 * ticks-per-microsecond. 1308 */ 1309 switch (sc->sk_type) { 1310 case SK_GENESIS: 1311 sc->sk_int_ticks = SK_IMTIMER_TICKS_GENESIS; 1312 break; 1313 default: 1314 sc->sk_int_ticks = SK_IMTIMER_TICKS_YUKON; 1315 break; 1316 } 1317 if (bootverbose) 1318 device_printf(sc->sk_dev, "interrupt moderation is %d us\n", 1319 sc->sk_int_mod); 1320 sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(sc->sk_int_mod, 1321 sc->sk_int_ticks)); 1322 sk_win_write_4(sc, SK_IMMR, SK_ISR_TX1_S_EOF|SK_ISR_TX2_S_EOF| 1323 SK_ISR_RX1_EOF|SK_ISR_RX2_EOF); 1324 sk_win_write_1(sc, SK_IMTIMERCTL, SK_IMCTL_START); 1325 1326 return; 1327 } 1328 1329 static int 1330 sk_probe(dev) 1331 device_t dev; 1332 { 1333 struct sk_softc *sc; 1334 1335 sc = device_get_softc(device_get_parent(dev)); 1336 1337 /* 1338 * Not much to do here. We always know there will be 1339 * at least one XMAC present, and if there are two, 1340 * skc_attach() will create a second device instance 1341 * for us. 1342 */ 1343 switch (sc->sk_type) { 1344 case SK_GENESIS: 1345 device_set_desc(dev, "XaQti Corp. XMAC II"); 1346 break; 1347 case SK_YUKON: 1348 case SK_YUKON_LITE: 1349 case SK_YUKON_LP: 1350 device_set_desc(dev, "Marvell Semiconductor, Inc. Yukon"); 1351 break; 1352 } 1353 1354 return (BUS_PROBE_DEFAULT); 1355 } 1356 1357 /* 1358 * Each XMAC chip is attached as a separate logical IP interface. 1359 * Single port cards will have only one logical interface of course. 1360 */ 1361 static int 1362 sk_attach(dev) 1363 device_t dev; 1364 { 1365 struct sk_softc *sc; 1366 struct sk_if_softc *sc_if; 1367 struct ifnet *ifp; 1368 int i, port, error; 1369 u_char eaddr[6]; 1370 1371 if (dev == NULL) 1372 return(EINVAL); 1373 1374 error = 0; 1375 sc_if = device_get_softc(dev); 1376 sc = device_get_softc(device_get_parent(dev)); 1377 port = *(int *)device_get_ivars(dev); 1378 1379 sc_if->sk_if_dev = dev; 1380 sc_if->sk_port = port; 1381 sc_if->sk_softc = sc; 1382 sc->sk_if[port] = sc_if; 1383 if (port == SK_PORT_A) 1384 sc_if->sk_tx_bmu = SK_BMU_TXS_CSR0; 1385 if (port == SK_PORT_B) 1386 sc_if->sk_tx_bmu = SK_BMU_TXS_CSR1; 1387 1388 callout_init_mtx(&sc_if->sk_tick_ch, &sc_if->sk_softc->sk_mtx, 0); 1389 callout_init_mtx(&sc_if->sk_watchdog_ch, &sc_if->sk_softc->sk_mtx, 0); 1390 1391 if (sk_dma_alloc(sc_if) != 0) { 1392 error = ENOMEM; 1393 goto fail; 1394 } 1395 1396 ifp = sc_if->sk_ifp = if_alloc(IFT_ETHER); 1397 if (ifp == NULL) { 1398 device_printf(sc_if->sk_if_dev, "can not if_alloc()\n"); 1399 error = ENOSPC; 1400 goto fail; 1401 } 1402 ifp->if_softc = sc_if; 1403 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 1404 ifp->if_mtu = ETHERMTU; 1405 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1406 /* 1407 * SK_GENESIS has a bug in checksum offload - From linux. 1408 */ 1409 if (sc_if->sk_softc->sk_type != SK_GENESIS) { 1410 ifp->if_capabilities = IFCAP_HWCSUM; 1411 ifp->if_hwassist = SK_CSUM_FEATURES; 1412 } else { 1413 ifp->if_capabilities = 0; 1414 ifp->if_hwassist = 0; 1415 } 1416 ifp->if_capenable = ifp->if_capabilities; 1417 ifp->if_ioctl = sk_ioctl; 1418 ifp->if_start = sk_start; 1419 ifp->if_timer = 0; 1420 ifp->if_watchdog = NULL; 1421 ifp->if_init = sk_init; 1422 IFQ_SET_MAXLEN(&ifp->if_snd, SK_TX_RING_CNT - 1); 1423 ifp->if_snd.ifq_drv_maxlen = SK_TX_RING_CNT - 1; 1424 IFQ_SET_READY(&ifp->if_snd); 1425 1426 /* 1427 * Get station address for this interface. Note that 1428 * dual port cards actually come with three station 1429 * addresses: one for each port, plus an extra. The 1430 * extra one is used by the SysKonnect driver software 1431 * as a 'virtual' station address for when both ports 1432 * are operating in failover mode. Currently we don't 1433 * use this extra address. 1434 */ 1435 SK_IF_LOCK(sc_if); 1436 for (i = 0; i < ETHER_ADDR_LEN; i++) 1437 eaddr[i] = 1438 sk_win_read_1(sc, SK_MAC0_0 + (port * 8) + i); 1439 1440 /* 1441 * Set up RAM buffer addresses. The NIC will have a certain 1442 * amount of SRAM on it, somewhere between 512K and 2MB. We 1443 * need to divide this up a) between the transmitter and 1444 * receiver and b) between the two XMACs, if this is a 1445 * dual port NIC. Our algotithm is to divide up the memory 1446 * evenly so that everyone gets a fair share. 1447 * 1448 * Just to be contrary, Yukon2 appears to have separate memory 1449 * for each MAC. 1450 */ 1451 if (sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC) { 1452 u_int32_t chunk, val; 1453 1454 chunk = sc->sk_ramsize / 2; 1455 val = sc->sk_rboff / sizeof(u_int64_t); 1456 sc_if->sk_rx_ramstart = val; 1457 val += (chunk / sizeof(u_int64_t)); 1458 sc_if->sk_rx_ramend = val - 1; 1459 sc_if->sk_tx_ramstart = val; 1460 val += (chunk / sizeof(u_int64_t)); 1461 sc_if->sk_tx_ramend = val - 1; 1462 } else { 1463 u_int32_t chunk, val; 1464 1465 chunk = sc->sk_ramsize / 4; 1466 val = (sc->sk_rboff + (chunk * 2 * sc_if->sk_port)) / 1467 sizeof(u_int64_t); 1468 sc_if->sk_rx_ramstart = val; 1469 val += (chunk / sizeof(u_int64_t)); 1470 sc_if->sk_rx_ramend = val - 1; 1471 sc_if->sk_tx_ramstart = val; 1472 val += (chunk / sizeof(u_int64_t)); 1473 sc_if->sk_tx_ramend = val - 1; 1474 } 1475 1476 /* Read and save PHY type and set PHY address */ 1477 sc_if->sk_phytype = sk_win_read_1(sc, SK_EPROM1) & 0xF; 1478 if (!SK_YUKON_FAMILY(sc->sk_type)) { 1479 switch(sc_if->sk_phytype) { 1480 case SK_PHYTYPE_XMAC: 1481 sc_if->sk_phyaddr = SK_PHYADDR_XMAC; 1482 break; 1483 case SK_PHYTYPE_BCOM: 1484 sc_if->sk_phyaddr = SK_PHYADDR_BCOM; 1485 break; 1486 default: 1487 device_printf(sc->sk_dev, "unsupported PHY type: %d\n", 1488 sc_if->sk_phytype); 1489 error = ENODEV; 1490 SK_IF_UNLOCK(sc_if); 1491 goto fail; 1492 } 1493 } else { 1494 if (sc_if->sk_phytype < SK_PHYTYPE_MARV_COPPER && 1495 sc->sk_pmd != 'S') { 1496 /* not initialized, punt */ 1497 sc_if->sk_phytype = SK_PHYTYPE_MARV_COPPER; 1498 sc->sk_coppertype = 1; 1499 } 1500 1501 sc_if->sk_phyaddr = SK_PHYADDR_MARV; 1502 1503 if (!(sc->sk_coppertype)) 1504 sc_if->sk_phytype = SK_PHYTYPE_MARV_FIBER; 1505 } 1506 1507 /* 1508 * Call MI attach routine. Can't hold locks when calling into ether_*. 1509 */ 1510 SK_IF_UNLOCK(sc_if); 1511 ether_ifattach(ifp, eaddr); 1512 SK_IF_LOCK(sc_if); 1513 1514 /* 1515 * The hardware should be ready for VLAN_MTU by default: 1516 * XMAC II has 0x8100 in VLAN Tag Level 1 register initially; 1517 * YU_SMR_MFL_VLAN is set by this driver in Yukon. 1518 * 1519 */ 1520 ifp->if_capabilities |= IFCAP_VLAN_MTU; 1521 ifp->if_capenable |= IFCAP_VLAN_MTU; 1522 /* 1523 * Tell the upper layer(s) we support long frames. 1524 * Must appear after the call to ether_ifattach() because 1525 * ether_ifattach() sets ifi_hdrlen to the default value. 1526 */ 1527 ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); 1528 1529 /* 1530 * Do miibus setup. 1531 */ 1532 switch (sc->sk_type) { 1533 case SK_GENESIS: 1534 sk_init_xmac(sc_if); 1535 break; 1536 case SK_YUKON: 1537 case SK_YUKON_LITE: 1538 case SK_YUKON_LP: 1539 sk_init_yukon(sc_if); 1540 break; 1541 } 1542 1543 SK_IF_UNLOCK(sc_if); 1544 if (mii_phy_probe(dev, &sc_if->sk_miibus, 1545 sk_ifmedia_upd, sk_ifmedia_sts)) { 1546 device_printf(sc_if->sk_if_dev, "no PHY found!\n"); 1547 ether_ifdetach(ifp); 1548 error = ENXIO; 1549 goto fail; 1550 } 1551 1552 fail: 1553 if (error) { 1554 /* Access should be ok even though lock has been dropped */ 1555 sc->sk_if[port] = NULL; 1556 sk_detach(dev); 1557 } 1558 1559 return(error); 1560 } 1561 1562 /* 1563 * Attach the interface. Allocate softc structures, do ifmedia 1564 * setup and ethernet/BPF attach. 1565 */ 1566 static int 1567 skc_attach(dev) 1568 device_t dev; 1569 { 1570 struct sk_softc *sc; 1571 int error = 0, *port; 1572 uint8_t skrs; 1573 const char *pname = NULL; 1574 char *revstr; 1575 1576 sc = device_get_softc(dev); 1577 sc->sk_dev = dev; 1578 1579 mtx_init(&sc->sk_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 1580 MTX_DEF); 1581 mtx_init(&sc->sk_mii_mtx, "sk_mii_mutex", NULL, MTX_DEF); 1582 /* 1583 * Map control/status registers. 1584 */ 1585 pci_enable_busmaster(dev); 1586 1587 /* Allocate resources */ 1588 #ifdef SK_USEIOSPACE 1589 sc->sk_res_spec = sk_res_spec_io; 1590 #else 1591 sc->sk_res_spec = sk_res_spec_mem; 1592 #endif 1593 error = bus_alloc_resources(dev, sc->sk_res_spec, sc->sk_res); 1594 if (error) { 1595 if (sc->sk_res_spec == sk_res_spec_mem) 1596 sc->sk_res_spec = sk_res_spec_io; 1597 else 1598 sc->sk_res_spec = sk_res_spec_mem; 1599 error = bus_alloc_resources(dev, sc->sk_res_spec, sc->sk_res); 1600 if (error) { 1601 device_printf(dev, "couldn't allocate %s resources\n", 1602 sc->sk_res_spec == sk_res_spec_mem ? "memory" : 1603 "I/O"); 1604 goto fail; 1605 } 1606 } 1607 1608 sc->sk_type = sk_win_read_1(sc, SK_CHIPVER); 1609 sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4) & 0xf; 1610 1611 /* Bail out if chip is not recognized. */ 1612 if (sc->sk_type != SK_GENESIS && !SK_YUKON_FAMILY(sc->sk_type)) { 1613 device_printf(dev, "unknown device: chipver=%02x, rev=%x\n", 1614 sc->sk_type, sc->sk_rev); 1615 error = ENXIO; 1616 goto fail; 1617 } 1618 1619 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1620 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 1621 OID_AUTO, "int_mod", CTLTYPE_INT|CTLFLAG_RW, 1622 &sc->sk_int_mod, 0, sysctl_hw_sk_int_mod, "I", 1623 "SK interrupt moderation"); 1624 1625 /* Pull in device tunables. */ 1626 sc->sk_int_mod = SK_IM_DEFAULT; 1627 error = resource_int_value(device_get_name(dev), device_get_unit(dev), 1628 "int_mod", &sc->sk_int_mod); 1629 if (error == 0) { 1630 if (sc->sk_int_mod < SK_IM_MIN || 1631 sc->sk_int_mod > SK_IM_MAX) { 1632 device_printf(dev, "int_mod value out of range; " 1633 "using default: %d\n", SK_IM_DEFAULT); 1634 sc->sk_int_mod = SK_IM_DEFAULT; 1635 } 1636 } 1637 1638 /* Reset the adapter. */ 1639 sk_reset(sc); 1640 1641 skrs = sk_win_read_1(sc, SK_EPROM0); 1642 if (sc->sk_type == SK_GENESIS) { 1643 /* Read and save RAM size and RAMbuffer offset */ 1644 switch(skrs) { 1645 case SK_RAMSIZE_512K_64: 1646 sc->sk_ramsize = 0x80000; 1647 sc->sk_rboff = SK_RBOFF_0; 1648 break; 1649 case SK_RAMSIZE_1024K_64: 1650 sc->sk_ramsize = 0x100000; 1651 sc->sk_rboff = SK_RBOFF_80000; 1652 break; 1653 case SK_RAMSIZE_1024K_128: 1654 sc->sk_ramsize = 0x100000; 1655 sc->sk_rboff = SK_RBOFF_0; 1656 break; 1657 case SK_RAMSIZE_2048K_128: 1658 sc->sk_ramsize = 0x200000; 1659 sc->sk_rboff = SK_RBOFF_0; 1660 break; 1661 default: 1662 device_printf(dev, "unknown ram size: %d\n", skrs); 1663 error = ENXIO; 1664 goto fail; 1665 } 1666 } else { /* SK_YUKON_FAMILY */ 1667 if (skrs == 0x00) 1668 sc->sk_ramsize = 0x20000; 1669 else 1670 sc->sk_ramsize = skrs * (1<<12); 1671 sc->sk_rboff = SK_RBOFF_0; 1672 } 1673 1674 /* Read and save physical media type */ 1675 sc->sk_pmd = sk_win_read_1(sc, SK_PMDTYPE); 1676 1677 if (sc->sk_pmd == 'T' || sc->sk_pmd == '1') 1678 sc->sk_coppertype = 1; 1679 else 1680 sc->sk_coppertype = 0; 1681 1682 /* Determine whether to name it with VPD PN or just make it up. 1683 * Marvell Yukon VPD PN seems to freqently be bogus. */ 1684 switch (pci_get_device(dev)) { 1685 case DEVICEID_SK_V1: 1686 case DEVICEID_BELKIN_5005: 1687 case DEVICEID_3COM_3C940: 1688 case DEVICEID_LINKSYS_EG1032: 1689 case DEVICEID_DLINK_DGE530T_A1: 1690 case DEVICEID_DLINK_DGE530T_B1: 1691 /* Stay with VPD PN. */ 1692 (void) pci_get_vpd_ident(dev, &pname); 1693 break; 1694 case DEVICEID_SK_V2: 1695 /* YUKON VPD PN might bear no resemblance to reality. */ 1696 switch (sc->sk_type) { 1697 case SK_GENESIS: 1698 /* Stay with VPD PN. */ 1699 (void) pci_get_vpd_ident(dev, &pname); 1700 break; 1701 case SK_YUKON: 1702 pname = "Marvell Yukon Gigabit Ethernet"; 1703 break; 1704 case SK_YUKON_LITE: 1705 pname = "Marvell Yukon Lite Gigabit Ethernet"; 1706 break; 1707 case SK_YUKON_LP: 1708 pname = "Marvell Yukon LP Gigabit Ethernet"; 1709 break; 1710 default: 1711 pname = "Marvell Yukon (Unknown) Gigabit Ethernet"; 1712 break; 1713 } 1714 1715 /* Yukon Lite Rev. A0 needs special test. */ 1716 if (sc->sk_type == SK_YUKON || sc->sk_type == SK_YUKON_LP) { 1717 u_int32_t far; 1718 u_int8_t testbyte; 1719 1720 /* Save flash address register before testing. */ 1721 far = sk_win_read_4(sc, SK_EP_ADDR); 1722 1723 sk_win_write_1(sc, SK_EP_ADDR+0x03, 0xff); 1724 testbyte = sk_win_read_1(sc, SK_EP_ADDR+0x03); 1725 1726 if (testbyte != 0x00) { 1727 /* Yukon Lite Rev. A0 detected. */ 1728 sc->sk_type = SK_YUKON_LITE; 1729 sc->sk_rev = SK_YUKON_LITE_REV_A0; 1730 /* Restore flash address register. */ 1731 sk_win_write_4(sc, SK_EP_ADDR, far); 1732 } 1733 } 1734 break; 1735 default: 1736 device_printf(dev, "unknown device: vendor=%04x, device=%04x, " 1737 "chipver=%02x, rev=%x\n", 1738 pci_get_vendor(dev), pci_get_device(dev), 1739 sc->sk_type, sc->sk_rev); 1740 error = ENXIO; 1741 goto fail; 1742 } 1743 1744 if (sc->sk_type == SK_YUKON_LITE) { 1745 switch (sc->sk_rev) { 1746 case SK_YUKON_LITE_REV_A0: 1747 revstr = "A0"; 1748 break; 1749 case SK_YUKON_LITE_REV_A1: 1750 revstr = "A1"; 1751 break; 1752 case SK_YUKON_LITE_REV_A3: 1753 revstr = "A3"; 1754 break; 1755 default: 1756 revstr = ""; 1757 break; 1758 } 1759 } else { 1760 revstr = ""; 1761 } 1762 1763 /* Announce the product name and more VPD data if there. */ 1764 if (pname != NULL) 1765 device_printf(dev, "%s rev. %s(0x%x)\n", 1766 pname, revstr, sc->sk_rev); 1767 1768 if (bootverbose) { 1769 device_printf(dev, "chip ver = 0x%02x\n", sc->sk_type); 1770 device_printf(dev, "chip rev = 0x%02x\n", sc->sk_rev); 1771 device_printf(dev, "SK_EPROM0 = 0x%02x\n", skrs); 1772 device_printf(dev, "SRAM size = 0x%06x\n", sc->sk_ramsize); 1773 } 1774 1775 sc->sk_devs[SK_PORT_A] = device_add_child(dev, "sk", -1); 1776 if (sc->sk_devs[SK_PORT_A] == NULL) { 1777 device_printf(dev, "failed to add child for PORT_A\n"); 1778 error = ENXIO; 1779 goto fail; 1780 } 1781 port = malloc(sizeof(int), M_DEVBUF, M_NOWAIT); 1782 if (port == NULL) { 1783 device_printf(dev, "failed to allocate memory for " 1784 "ivars of PORT_A\n"); 1785 error = ENXIO; 1786 goto fail; 1787 } 1788 *port = SK_PORT_A; 1789 device_set_ivars(sc->sk_devs[SK_PORT_A], port); 1790 1791 if (!(sk_win_read_1(sc, SK_CONFIG) & SK_CONFIG_SINGLEMAC)) { 1792 sc->sk_devs[SK_PORT_B] = device_add_child(dev, "sk", -1); 1793 if (sc->sk_devs[SK_PORT_B] == NULL) { 1794 device_printf(dev, "failed to add child for PORT_B\n"); 1795 error = ENXIO; 1796 goto fail; 1797 } 1798 port = malloc(sizeof(int), M_DEVBUF, M_NOWAIT); 1799 if (port == NULL) { 1800 device_printf(dev, "failed to allocate memory for " 1801 "ivars of PORT_B\n"); 1802 error = ENXIO; 1803 goto fail; 1804 } 1805 *port = SK_PORT_B; 1806 device_set_ivars(sc->sk_devs[SK_PORT_B], port); 1807 } 1808 1809 /* Turn on the 'driver is loaded' LED. */ 1810 CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON); 1811 1812 error = bus_generic_attach(dev); 1813 if (error) { 1814 device_printf(dev, "failed to attach port(s)\n"); 1815 goto fail; 1816 } 1817 1818 /* Hook interrupt last to avoid having to lock softc */ 1819 #ifdef __HAIKU__ 1820 atomic_and((int32 *)&sc->sk_intstatus, 0); 1821 #endif 1822 error = bus_setup_intr(dev, sc->sk_res[1], INTR_TYPE_NET|INTR_MPSAFE/*|INTR_FAST*/, 1823 NULL, sk_intr, sc, &sc->sk_intrhand); 1824 1825 if (error) { 1826 device_printf(dev, "couldn't set up irq\n"); 1827 goto fail; 1828 } 1829 1830 fail: 1831 if (error) 1832 skc_detach(dev); 1833 1834 return(error); 1835 } 1836 1837 /* 1838 * Shutdown hardware and free up resources. This can be called any 1839 * time after the mutex has been initialized. It is called in both 1840 * the error case in attach and the normal detach case so it needs 1841 * to be careful about only freeing resources that have actually been 1842 * allocated. 1843 */ 1844 static int 1845 sk_detach(dev) 1846 device_t dev; 1847 { 1848 struct sk_if_softc *sc_if; 1849 struct ifnet *ifp; 1850 1851 sc_if = device_get_softc(dev); 1852 KASSERT(mtx_initialized(&sc_if->sk_softc->sk_mtx), 1853 ("sk mutex not initialized in sk_detach")); 1854 SK_IF_LOCK(sc_if); 1855 1856 ifp = sc_if->sk_ifp; 1857 /* These should only be active if attach_xmac succeeded */ 1858 if (device_is_attached(dev)) { 1859 sk_stop(sc_if); 1860 /* Can't hold locks while calling detach */ 1861 SK_IF_UNLOCK(sc_if); 1862 callout_drain(&sc_if->sk_tick_ch); 1863 callout_drain(&sc_if->sk_watchdog_ch); 1864 ether_ifdetach(ifp); 1865 SK_IF_LOCK(sc_if); 1866 } 1867 if (ifp) 1868 if_free(ifp); 1869 /* 1870 * We're generally called from skc_detach() which is using 1871 * device_delete_child() to get to here. It's already trashed 1872 * miibus for us, so don't do it here or we'll panic. 1873 */ 1874 /* 1875 if (sc_if->sk_miibus != NULL) 1876 device_delete_child(dev, sc_if->sk_miibus); 1877 */ 1878 bus_generic_detach(dev); 1879 sk_dma_free(sc_if); 1880 SK_IF_UNLOCK(sc_if); 1881 1882 return(0); 1883 } 1884 1885 static int 1886 skc_detach(dev) 1887 device_t dev; 1888 { 1889 struct sk_softc *sc; 1890 1891 sc = device_get_softc(dev); 1892 KASSERT(mtx_initialized(&sc->sk_mtx), ("sk mutex not initialized")); 1893 1894 if (device_is_alive(dev)) { 1895 if (sc->sk_devs[SK_PORT_A] != NULL) { 1896 free(device_get_ivars(sc->sk_devs[SK_PORT_A]), M_DEVBUF); 1897 device_delete_child(dev, sc->sk_devs[SK_PORT_A]); 1898 } 1899 if (sc->sk_devs[SK_PORT_B] != NULL) { 1900 free(device_get_ivars(sc->sk_devs[SK_PORT_B]), M_DEVBUF); 1901 device_delete_child(dev, sc->sk_devs[SK_PORT_B]); 1902 } 1903 bus_generic_detach(dev); 1904 } 1905 1906 if (sc->sk_intrhand) 1907 bus_teardown_intr(dev, sc->sk_res[1], sc->sk_intrhand); 1908 bus_release_resources(dev, sc->sk_res_spec, sc->sk_res); 1909 1910 mtx_destroy(&sc->sk_mii_mtx); 1911 mtx_destroy(&sc->sk_mtx); 1912 1913 return(0); 1914 } 1915 1916 struct sk_dmamap_arg { 1917 bus_addr_t sk_busaddr; 1918 }; 1919 1920 static void 1921 sk_dmamap_cb(arg, segs, nseg, error) 1922 void *arg; 1923 bus_dma_segment_t *segs; 1924 int nseg; 1925 int error; 1926 { 1927 struct sk_dmamap_arg *ctx; 1928 1929 if (error != 0) 1930 return; 1931 1932 ctx = arg; 1933 ctx->sk_busaddr = segs[0].ds_addr; 1934 } 1935 1936 /* 1937 * Allocate jumbo buffer storage. The SysKonnect adapters support 1938 * "jumbograms" (9K frames), although SysKonnect doesn't currently 1939 * use them in their drivers. In order for us to use them, we need 1940 * large 9K receive buffers, however standard mbuf clusters are only 1941 * 2048 bytes in size. Consequently, we need to allocate and manage 1942 * our own jumbo buffer pool. Fortunately, this does not require an 1943 * excessive amount of additional code. 1944 */ 1945 static int 1946 sk_dma_alloc(sc_if) 1947 struct sk_if_softc *sc_if; 1948 { 1949 struct sk_dmamap_arg ctx; 1950 struct sk_txdesc *txd; 1951 struct sk_rxdesc *rxd; 1952 struct sk_rxdesc *jrxd; 1953 u_int8_t *ptr; 1954 struct sk_jpool_entry *entry; 1955 int error, i; 1956 1957 mtx_init(&sc_if->sk_jlist_mtx, "sk_jlist_mtx", NULL, MTX_DEF); 1958 SLIST_INIT(&sc_if->sk_jfree_listhead); 1959 SLIST_INIT(&sc_if->sk_jinuse_listhead); 1960 1961 /* create parent tag */ 1962 /* 1963 * XXX 1964 * This driver should use BUS_SPACE_MAXADDR for lowaddr argument 1965 * in bus_dma_tag_create(9) as the NIC would support DAC mode. 1966 * However bz@ reported that it does not work on amd64 with > 4GB 1967 * RAM. Until we have more clues of the breakage, disable DAC mode 1968 * by limiting DMA address to be in 32bit address space. 1969 */ 1970 error = bus_dma_tag_create( 1971 bus_get_dma_tag(sc_if->sk_if_dev),/* parent */ 1972 1, 0, /* algnmnt, boundary */ 1973 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 1974 BUS_SPACE_MAXADDR, /* highaddr */ 1975 NULL, NULL, /* filter, filterarg */ 1976 BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ 1977 0, /* nsegments */ 1978 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 1979 0, /* flags */ 1980 NULL, NULL, /* lockfunc, lockarg */ 1981 &sc_if->sk_cdata.sk_parent_tag); 1982 if (error != 0) { 1983 device_printf(sc_if->sk_if_dev, 1984 "failed to create parent DMA tag\n"); 1985 goto fail; 1986 } 1987 /* create tag for Tx ring */ 1988 error = bus_dma_tag_create(sc_if->sk_cdata.sk_parent_tag,/* parent */ 1989 SK_RING_ALIGN, 0, /* algnmnt, boundary */ 1990 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 1991 BUS_SPACE_MAXADDR, /* highaddr */ 1992 NULL, NULL, /* filter, filterarg */ 1993 SK_TX_RING_SZ, /* maxsize */ 1994 1, /* nsegments */ 1995 SK_TX_RING_SZ, /* maxsegsize */ 1996 0, /* flags */ 1997 NULL, NULL, /* lockfunc, lockarg */ 1998 &sc_if->sk_cdata.sk_tx_ring_tag); 1999 if (error != 0) { 2000 device_printf(sc_if->sk_if_dev, 2001 "failed to allocate Tx ring DMA tag\n"); 2002 goto fail; 2003 } 2004 2005 /* create tag for Rx ring */ 2006 error = bus_dma_tag_create(sc_if->sk_cdata.sk_parent_tag,/* parent */ 2007 SK_RING_ALIGN, 0, /* algnmnt, boundary */ 2008 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 2009 BUS_SPACE_MAXADDR, /* highaddr */ 2010 NULL, NULL, /* filter, filterarg */ 2011 SK_RX_RING_SZ, /* maxsize */ 2012 1, /* nsegments */ 2013 SK_RX_RING_SZ, /* maxsegsize */ 2014 0, /* flags */ 2015 NULL, NULL, /* lockfunc, lockarg */ 2016 &sc_if->sk_cdata.sk_rx_ring_tag); 2017 if (error != 0) { 2018 device_printf(sc_if->sk_if_dev, 2019 "failed to allocate Rx ring DMA tag\n"); 2020 goto fail; 2021 } 2022 2023 /* create tag for jumbo Rx ring */ 2024 error = bus_dma_tag_create(sc_if->sk_cdata.sk_parent_tag,/* parent */ 2025 SK_RING_ALIGN, 0, /* algnmnt, boundary */ 2026 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 2027 BUS_SPACE_MAXADDR, /* highaddr */ 2028 NULL, NULL, /* filter, filterarg */ 2029 SK_JUMBO_RX_RING_SZ, /* maxsize */ 2030 1, /* nsegments */ 2031 SK_JUMBO_RX_RING_SZ, /* maxsegsize */ 2032 0, /* flags */ 2033 NULL, NULL, /* lockfunc, lockarg */ 2034 &sc_if->sk_cdata.sk_jumbo_rx_ring_tag); 2035 if (error != 0) { 2036 device_printf(sc_if->sk_if_dev, 2037 "failed to allocate jumbo Rx ring DMA tag\n"); 2038 goto fail; 2039 } 2040 2041 /* create tag for jumbo buffer blocks */ 2042 error = bus_dma_tag_create(sc_if->sk_cdata.sk_parent_tag,/* parent */ 2043 PAGE_SIZE, 0, /* algnmnt, boundary */ 2044 BUS_SPACE_MAXADDR, /* lowaddr */ 2045 BUS_SPACE_MAXADDR, /* highaddr */ 2046 NULL, NULL, /* filter, filterarg */ 2047 SK_JMEM, /* maxsize */ 2048 1, /* nsegments */ 2049 SK_JMEM, /* maxsegsize */ 2050 0, /* flags */ 2051 NULL, NULL, /* lockfunc, lockarg */ 2052 &sc_if->sk_cdata.sk_jumbo_tag); 2053 if (error != 0) { 2054 device_printf(sc_if->sk_if_dev, 2055 "failed to allocate jumbo Rx buffer block DMA tag\n"); 2056 goto fail; 2057 } 2058 2059 /* create tag for Tx buffers */ 2060 error = bus_dma_tag_create(sc_if->sk_cdata.sk_parent_tag,/* parent */ 2061 1, 0, /* algnmnt, boundary */ 2062 BUS_SPACE_MAXADDR, /* lowaddr */ 2063 BUS_SPACE_MAXADDR, /* highaddr */ 2064 NULL, NULL, /* filter, filterarg */ 2065 MCLBYTES * SK_MAXTXSEGS, /* maxsize */ 2066 SK_MAXTXSEGS, /* nsegments */ 2067 MCLBYTES, /* maxsegsize */ 2068 0, /* flags */ 2069 NULL, NULL, /* lockfunc, lockarg */ 2070 &sc_if->sk_cdata.sk_tx_tag); 2071 if (error != 0) { 2072 device_printf(sc_if->sk_if_dev, 2073 "failed to allocate Tx DMA tag\n"); 2074 goto fail; 2075 } 2076 2077 /* create tag for Rx buffers */ 2078 error = bus_dma_tag_create(sc_if->sk_cdata.sk_parent_tag,/* parent */ 2079 1, 0, /* algnmnt, boundary */ 2080 BUS_SPACE_MAXADDR, /* lowaddr */ 2081 BUS_SPACE_MAXADDR, /* highaddr */ 2082 NULL, NULL, /* filter, filterarg */ 2083 MCLBYTES, /* maxsize */ 2084 1, /* nsegments */ 2085 MCLBYTES, /* maxsegsize */ 2086 0, /* flags */ 2087 NULL, NULL, /* lockfunc, lockarg */ 2088 &sc_if->sk_cdata.sk_rx_tag); 2089 if (error != 0) { 2090 device_printf(sc_if->sk_if_dev, 2091 "failed to allocate Rx DMA tag\n"); 2092 goto fail; 2093 } 2094 2095 /* create tag for jumbo Rx buffers */ 2096 error = bus_dma_tag_create(sc_if->sk_cdata.sk_parent_tag,/* parent */ 2097 PAGE_SIZE, 0, /* algnmnt, boundary */ 2098 BUS_SPACE_MAXADDR, /* lowaddr */ 2099 BUS_SPACE_MAXADDR, /* highaddr */ 2100 NULL, NULL, /* filter, filterarg */ 2101 MCLBYTES * SK_MAXRXSEGS, /* maxsize */ 2102 SK_MAXRXSEGS, /* nsegments */ 2103 SK_JLEN, /* maxsegsize */ 2104 0, /* flags */ 2105 NULL, NULL, /* lockfunc, lockarg */ 2106 &sc_if->sk_cdata.sk_jumbo_rx_tag); 2107 if (error != 0) { 2108 device_printf(sc_if->sk_if_dev, 2109 "failed to allocate jumbo Rx DMA tag\n"); 2110 goto fail; 2111 } 2112 2113 /* allocate DMA'able memory and load the DMA map for Tx ring */ 2114 error = bus_dmamem_alloc(sc_if->sk_cdata.sk_tx_ring_tag, 2115 (void **)&sc_if->sk_rdata.sk_tx_ring, BUS_DMA_NOWAIT | BUS_DMA_ZERO, 2116 &sc_if->sk_cdata.sk_tx_ring_map); 2117 if (error != 0) { 2118 device_printf(sc_if->sk_if_dev, 2119 "failed to allocate DMA'able memory for Tx ring\n"); 2120 goto fail; 2121 } 2122 2123 ctx.sk_busaddr = 0; 2124 error = bus_dmamap_load(sc_if->sk_cdata.sk_tx_ring_tag, 2125 sc_if->sk_cdata.sk_tx_ring_map, sc_if->sk_rdata.sk_tx_ring, 2126 SK_TX_RING_SZ, sk_dmamap_cb, &ctx, BUS_DMA_NOWAIT); 2127 if (error != 0) { 2128 device_printf(sc_if->sk_if_dev, 2129 "failed to load DMA'able memory for Tx ring\n"); 2130 goto fail; 2131 } 2132 sc_if->sk_rdata.sk_tx_ring_paddr = ctx.sk_busaddr; 2133 2134 /* allocate DMA'able memory and load the DMA map for Rx ring */ 2135 error = bus_dmamem_alloc(sc_if->sk_cdata.sk_rx_ring_tag, 2136 (void **)&sc_if->sk_rdata.sk_rx_ring, BUS_DMA_NOWAIT | BUS_DMA_ZERO, 2137 &sc_if->sk_cdata.sk_rx_ring_map); 2138 if (error != 0) { 2139 device_printf(sc_if->sk_if_dev, 2140 "failed to allocate DMA'able memory for Rx ring\n"); 2141 goto fail; 2142 } 2143 2144 ctx.sk_busaddr = 0; 2145 error = bus_dmamap_load(sc_if->sk_cdata.sk_rx_ring_tag, 2146 sc_if->sk_cdata.sk_rx_ring_map, sc_if->sk_rdata.sk_rx_ring, 2147 SK_RX_RING_SZ, sk_dmamap_cb, &ctx, BUS_DMA_NOWAIT); 2148 if (error != 0) { 2149 device_printf(sc_if->sk_if_dev, 2150 "failed to load DMA'able memory for Rx ring\n"); 2151 goto fail; 2152 } 2153 sc_if->sk_rdata.sk_rx_ring_paddr = ctx.sk_busaddr; 2154 2155 /* allocate DMA'able memory and load the DMA map for jumbo Rx ring */ 2156 error = bus_dmamem_alloc(sc_if->sk_cdata.sk_jumbo_rx_ring_tag, 2157 (void **)&sc_if->sk_rdata.sk_jumbo_rx_ring, 2158 BUS_DMA_NOWAIT|BUS_DMA_ZERO, &sc_if->sk_cdata.sk_jumbo_rx_ring_map); 2159 if (error != 0) { 2160 device_printf(sc_if->sk_if_dev, 2161 "failed to allocate DMA'able memory for jumbo Rx ring\n"); 2162 goto fail; 2163 } 2164 2165 ctx.sk_busaddr = 0; 2166 error = bus_dmamap_load(sc_if->sk_cdata.sk_jumbo_rx_ring_tag, 2167 sc_if->sk_cdata.sk_jumbo_rx_ring_map, 2168 sc_if->sk_rdata.sk_jumbo_rx_ring, SK_JUMBO_RX_RING_SZ, sk_dmamap_cb, 2169 &ctx, BUS_DMA_NOWAIT); 2170 if (error != 0) { 2171 device_printf(sc_if->sk_if_dev, 2172 "failed to load DMA'able memory for jumbo Rx ring\n"); 2173 goto fail; 2174 } 2175 sc_if->sk_rdata.sk_jumbo_rx_ring_paddr = ctx.sk_busaddr; 2176 2177 /* create DMA maps for Tx buffers */ 2178 for (i = 0; i < SK_TX_RING_CNT; i++) { 2179 txd = &sc_if->sk_cdata.sk_txdesc[i]; 2180 txd->tx_m = NULL; 2181 txd->tx_dmamap = 0; 2182 error = bus_dmamap_create(sc_if->sk_cdata.sk_tx_tag, 0, 2183 &txd->tx_dmamap); 2184 if (error != 0) { 2185 device_printf(sc_if->sk_if_dev, 2186 "failed to create Tx dmamap\n"); 2187 goto fail; 2188 } 2189 } 2190 /* create DMA maps for Rx buffers */ 2191 if ((error = bus_dmamap_create(sc_if->sk_cdata.sk_rx_tag, 0, 2192 &sc_if->sk_cdata.sk_rx_sparemap)) != 0) { 2193 device_printf(sc_if->sk_if_dev, 2194 "failed to create spare Rx dmamap\n"); 2195 goto fail; 2196 } 2197 for (i = 0; i < SK_RX_RING_CNT; i++) { 2198 rxd = &sc_if->sk_cdata.sk_rxdesc[i]; 2199 rxd->rx_m = NULL; 2200 rxd->rx_dmamap = 0; 2201 error = bus_dmamap_create(sc_if->sk_cdata.sk_rx_tag, 0, 2202 &rxd->rx_dmamap); 2203 if (error != 0) { 2204 device_printf(sc_if->sk_if_dev, 2205 "failed to create Rx dmamap\n"); 2206 goto fail; 2207 } 2208 } 2209 /* create DMA maps for jumbo Rx buffers */ 2210 if ((error = bus_dmamap_create(sc_if->sk_cdata.sk_jumbo_rx_tag, 0, 2211 &sc_if->sk_cdata.sk_jumbo_rx_sparemap)) != 0) { 2212 device_printf(sc_if->sk_if_dev, 2213 "failed to create spare jumbo Rx dmamap\n"); 2214 goto fail; 2215 } 2216 for (i = 0; i < SK_JUMBO_RX_RING_CNT; i++) { 2217 jrxd = &sc_if->sk_cdata.sk_jumbo_rxdesc[i]; 2218 jrxd->rx_m = NULL; 2219 jrxd->rx_dmamap = 0; 2220 error = bus_dmamap_create(sc_if->sk_cdata.sk_jumbo_rx_tag, 0, 2221 &jrxd->rx_dmamap); 2222 if (error != 0) { 2223 device_printf(sc_if->sk_if_dev, 2224 "failed to create jumbo Rx dmamap\n"); 2225 goto fail; 2226 } 2227 } 2228 2229 /* allocate DMA'able memory and load the DMA map for jumbo buf */ 2230 error = bus_dmamem_alloc(sc_if->sk_cdata.sk_jumbo_tag, 2231 (void **)&sc_if->sk_rdata.sk_jumbo_buf, 2232 BUS_DMA_NOWAIT|BUS_DMA_ZERO, &sc_if->sk_cdata.sk_jumbo_map); 2233 if (error != 0) { 2234 device_printf(sc_if->sk_if_dev, 2235 "failed to allocate DMA'able memory for jumbo buf\n"); 2236 goto fail; 2237 } 2238 2239 ctx.sk_busaddr = 0; 2240 error = bus_dmamap_load(sc_if->sk_cdata.sk_jumbo_tag, 2241 sc_if->sk_cdata.sk_jumbo_map, 2242 sc_if->sk_rdata.sk_jumbo_buf, SK_JMEM, sk_dmamap_cb, 2243 &ctx, BUS_DMA_NOWAIT); 2244 if (error != 0) { 2245 device_printf(sc_if->sk_if_dev, 2246 "failed to load DMA'able memory for jumbobuf\n"); 2247 goto fail; 2248 } 2249 sc_if->sk_rdata.sk_jumbo_buf_paddr = ctx.sk_busaddr; 2250 2251 /* 2252 * Now divide it up into 9K pieces and save the addresses 2253 * in an array. 2254 */ 2255 ptr = sc_if->sk_rdata.sk_jumbo_buf; 2256 for (i = 0; i < SK_JSLOTS; i++) { 2257 sc_if->sk_cdata.sk_jslots[i] = ptr; 2258 ptr += SK_JLEN; 2259 entry = malloc(sizeof(struct sk_jpool_entry), 2260 M_DEVBUF, M_NOWAIT); 2261 if (entry == NULL) { 2262 device_printf(sc_if->sk_if_dev, 2263 "no memory for jumbo buffers!\n"); 2264 error = ENOMEM; 2265 goto fail; 2266 } 2267 entry->slot = i; 2268 SLIST_INSERT_HEAD(&sc_if->sk_jfree_listhead, entry, 2269 jpool_entries); 2270 } 2271 2272 fail: 2273 return (error); 2274 } 2275 2276 static void 2277 sk_dma_free(sc_if) 2278 struct sk_if_softc *sc_if; 2279 { 2280 struct sk_txdesc *txd; 2281 struct sk_rxdesc *rxd; 2282 struct sk_rxdesc *jrxd; 2283 struct sk_jpool_entry *entry; 2284 int i; 2285 2286 SK_JLIST_LOCK(sc_if); 2287 while ((entry = SLIST_FIRST(&sc_if->sk_jinuse_listhead))) { 2288 device_printf(sc_if->sk_if_dev, 2289 "asked to free buffer that is in use!\n"); 2290 SLIST_REMOVE_HEAD(&sc_if->sk_jinuse_listhead, jpool_entries); 2291 SLIST_INSERT_HEAD(&sc_if->sk_jfree_listhead, entry, 2292 jpool_entries); 2293 } 2294 2295 while (!SLIST_EMPTY(&sc_if->sk_jfree_listhead)) { 2296 entry = SLIST_FIRST(&sc_if->sk_jfree_listhead); 2297 SLIST_REMOVE_HEAD(&sc_if->sk_jfree_listhead, jpool_entries); 2298 free(entry, M_DEVBUF); 2299 } 2300 SK_JLIST_UNLOCK(sc_if); 2301 2302 /* destroy jumbo buffer block */ 2303 if (sc_if->sk_cdata.sk_jumbo_map) 2304 bus_dmamap_unload(sc_if->sk_cdata.sk_jumbo_tag, 2305 sc_if->sk_cdata.sk_jumbo_map); 2306 2307 if (sc_if->sk_rdata.sk_jumbo_buf) { 2308 bus_dmamem_free(sc_if->sk_cdata.sk_jumbo_tag, 2309 sc_if->sk_rdata.sk_jumbo_buf, 2310 sc_if->sk_cdata.sk_jumbo_map); 2311 sc_if->sk_rdata.sk_jumbo_buf = NULL; 2312 sc_if->sk_cdata.sk_jumbo_map = 0; 2313 } 2314 2315 /* Tx ring */ 2316 if (sc_if->sk_cdata.sk_tx_ring_tag) { 2317 if (sc_if->sk_cdata.sk_tx_ring_map) 2318 bus_dmamap_unload(sc_if->sk_cdata.sk_tx_ring_tag, 2319 sc_if->sk_cdata.sk_tx_ring_map); 2320 if (sc_if->sk_cdata.sk_tx_ring_map && 2321 sc_if->sk_rdata.sk_tx_ring) 2322 bus_dmamem_free(sc_if->sk_cdata.sk_tx_ring_tag, 2323 sc_if->sk_rdata.sk_tx_ring, 2324 sc_if->sk_cdata.sk_tx_ring_map); 2325 sc_if->sk_rdata.sk_tx_ring = NULL; 2326 sc_if->sk_cdata.sk_tx_ring_map = 0; 2327 bus_dma_tag_destroy(sc_if->sk_cdata.sk_tx_ring_tag); 2328 sc_if->sk_cdata.sk_tx_ring_tag = NULL; 2329 } 2330 /* Rx ring */ 2331 if (sc_if->sk_cdata.sk_rx_ring_tag) { 2332 if (sc_if->sk_cdata.sk_rx_ring_map) 2333 bus_dmamap_unload(sc_if->sk_cdata.sk_rx_ring_tag, 2334 sc_if->sk_cdata.sk_rx_ring_map); 2335 if (sc_if->sk_cdata.sk_rx_ring_map && 2336 sc_if->sk_rdata.sk_rx_ring) 2337 bus_dmamem_free(sc_if->sk_cdata.sk_rx_ring_tag, 2338 sc_if->sk_rdata.sk_rx_ring, 2339 sc_if->sk_cdata.sk_rx_ring_map); 2340 sc_if->sk_rdata.sk_rx_ring = NULL; 2341 sc_if->sk_cdata.sk_rx_ring_map = 0; 2342 bus_dma_tag_destroy(sc_if->sk_cdata.sk_rx_ring_tag); 2343 sc_if->sk_cdata.sk_rx_ring_tag = NULL; 2344 } 2345 /* jumbo Rx ring */ 2346 if (sc_if->sk_cdata.sk_jumbo_rx_ring_tag) { 2347 if (sc_if->sk_cdata.sk_jumbo_rx_ring_map) 2348 bus_dmamap_unload(sc_if->sk_cdata.sk_jumbo_rx_ring_tag, 2349 sc_if->sk_cdata.sk_jumbo_rx_ring_map); 2350 if (sc_if->sk_cdata.sk_jumbo_rx_ring_map && 2351 sc_if->sk_rdata.sk_jumbo_rx_ring) 2352 bus_dmamem_free(sc_if->sk_cdata.sk_jumbo_rx_ring_tag, 2353 sc_if->sk_rdata.sk_jumbo_rx_ring, 2354 sc_if->sk_cdata.sk_jumbo_rx_ring_map); 2355 sc_if->sk_rdata.sk_jumbo_rx_ring = NULL; 2356 sc_if->sk_cdata.sk_jumbo_rx_ring_map = 0; 2357 bus_dma_tag_destroy(sc_if->sk_cdata.sk_jumbo_rx_ring_tag); 2358 sc_if->sk_cdata.sk_jumbo_rx_ring_tag = NULL; 2359 } 2360 /* Tx buffers */ 2361 if (sc_if->sk_cdata.sk_tx_tag) { 2362 for (i = 0; i < SK_TX_RING_CNT; i++) { 2363 txd = &sc_if->sk_cdata.sk_txdesc[i]; 2364 if (txd->tx_dmamap) { 2365 bus_dmamap_destroy(sc_if->sk_cdata.sk_tx_tag, 2366 txd->tx_dmamap); 2367 txd->tx_dmamap = 0; 2368 } 2369 } 2370 bus_dma_tag_destroy(sc_if->sk_cdata.sk_tx_tag); 2371 sc_if->sk_cdata.sk_tx_tag = NULL; 2372 } 2373 /* Rx buffers */ 2374 if (sc_if->sk_cdata.sk_rx_tag) { 2375 for (i = 0; i < SK_RX_RING_CNT; i++) { 2376 rxd = &sc_if->sk_cdata.sk_rxdesc[i]; 2377 if (rxd->rx_dmamap) { 2378 bus_dmamap_destroy(sc_if->sk_cdata.sk_rx_tag, 2379 rxd->rx_dmamap); 2380 rxd->rx_dmamap = 0; 2381 } 2382 } 2383 if (sc_if->sk_cdata.sk_rx_sparemap) { 2384 bus_dmamap_destroy(sc_if->sk_cdata.sk_rx_tag, 2385 sc_if->sk_cdata.sk_rx_sparemap); 2386 sc_if->sk_cdata.sk_rx_sparemap = 0; 2387 } 2388 bus_dma_tag_destroy(sc_if->sk_cdata.sk_rx_tag); 2389 sc_if->sk_cdata.sk_rx_tag = NULL; 2390 } 2391 /* jumbo Rx buffers */ 2392 if (sc_if->sk_cdata.sk_jumbo_rx_tag) { 2393 for (i = 0; i < SK_JUMBO_RX_RING_CNT; i++) { 2394 jrxd = &sc_if->sk_cdata.sk_jumbo_rxdesc[i]; 2395 if (jrxd->rx_dmamap) { 2396 bus_dmamap_destroy( 2397 sc_if->sk_cdata.sk_jumbo_rx_tag, 2398 jrxd->rx_dmamap); 2399 jrxd->rx_dmamap = 0; 2400 } 2401 } 2402 if (sc_if->sk_cdata.sk_jumbo_rx_sparemap) { 2403 bus_dmamap_destroy(sc_if->sk_cdata.sk_jumbo_rx_tag, 2404 sc_if->sk_cdata.sk_jumbo_rx_sparemap); 2405 sc_if->sk_cdata.sk_jumbo_rx_sparemap = 0; 2406 } 2407 bus_dma_tag_destroy(sc_if->sk_cdata.sk_jumbo_rx_tag); 2408 sc_if->sk_cdata.sk_jumbo_rx_tag = NULL; 2409 } 2410 2411 if (sc_if->sk_cdata.sk_parent_tag) { 2412 bus_dma_tag_destroy(sc_if->sk_cdata.sk_parent_tag); 2413 sc_if->sk_cdata.sk_parent_tag = NULL; 2414 } 2415 mtx_destroy(&sc_if->sk_jlist_mtx); 2416 } 2417 2418 /* 2419 * Allocate a jumbo buffer. 2420 */ 2421 static void * 2422 sk_jalloc(sc_if) 2423 struct sk_if_softc *sc_if; 2424 { 2425 struct sk_jpool_entry *entry; 2426 2427 SK_JLIST_LOCK(sc_if); 2428 2429 entry = SLIST_FIRST(&sc_if->sk_jfree_listhead); 2430 2431 if (entry == NULL) { 2432 SK_JLIST_UNLOCK(sc_if); 2433 return (NULL); 2434 } 2435 2436 SLIST_REMOVE_HEAD(&sc_if->sk_jfree_listhead, jpool_entries); 2437 SLIST_INSERT_HEAD(&sc_if->sk_jinuse_listhead, entry, jpool_entries); 2438 2439 SK_JLIST_UNLOCK(sc_if); 2440 2441 return (sc_if->sk_cdata.sk_jslots[entry->slot]); 2442 } 2443 2444 /* 2445 * Release a jumbo buffer. 2446 */ 2447 static void 2448 sk_jfree(buf, args) 2449 void *buf; 2450 void *args; 2451 { 2452 struct sk_if_softc *sc_if; 2453 struct sk_jpool_entry *entry; 2454 int i; 2455 2456 /* Extract the softc struct pointer. */ 2457 sc_if = (struct sk_if_softc *)args; 2458 KASSERT(sc_if != NULL, ("%s: can't find softc pointer!", __func__)); 2459 2460 SK_JLIST_LOCK(sc_if); 2461 /* calculate the slot this buffer belongs to */ 2462 i = ((vm_offset_t)buf 2463 - (vm_offset_t)sc_if->sk_rdata.sk_jumbo_buf) / SK_JLEN; 2464 KASSERT(i >= 0 && i < SK_JSLOTS, 2465 ("%s: asked to free buffer that we don't manage!", __func__)); 2466 2467 entry = SLIST_FIRST(&sc_if->sk_jinuse_listhead); 2468 KASSERT(entry != NULL, ("%s: buffer not in use!", __func__)); 2469 entry->slot = i; 2470 SLIST_REMOVE_HEAD(&sc_if->sk_jinuse_listhead, jpool_entries); 2471 SLIST_INSERT_HEAD(&sc_if->sk_jfree_listhead, entry, jpool_entries); 2472 if (SLIST_EMPTY(&sc_if->sk_jinuse_listhead)) 2473 wakeup(sc_if); 2474 2475 SK_JLIST_UNLOCK(sc_if); 2476 } 2477 2478 static void 2479 sk_txcksum(ifp, m, f) 2480 struct ifnet *ifp; 2481 struct mbuf *m; 2482 struct sk_tx_desc *f; 2483 { 2484 struct ip *ip; 2485 u_int16_t offset; 2486 u_int8_t *p; 2487 2488 offset = sizeof(struct ip) + ETHER_HDR_LEN; 2489 for(; m && m->m_len == 0; m = m->m_next) 2490 ; 2491 if (m == NULL || m->m_len < ETHER_HDR_LEN) { 2492 if_printf(ifp, "%s: m_len < ETHER_HDR_LEN\n", __func__); 2493 /* checksum may be corrupted */ 2494 goto sendit; 2495 } 2496 if (m->m_len < ETHER_HDR_LEN + sizeof(u_int32_t)) { 2497 if (m->m_len != ETHER_HDR_LEN) { 2498 if_printf(ifp, "%s: m_len != ETHER_HDR_LEN\n", 2499 __func__); 2500 /* checksum may be corrupted */ 2501 goto sendit; 2502 } 2503 for(m = m->m_next; m && m->m_len == 0; m = m->m_next) 2504 ; 2505 if (m == NULL) { 2506 offset = sizeof(struct ip) + ETHER_HDR_LEN; 2507 /* checksum may be corrupted */ 2508 goto sendit; 2509 } 2510 ip = mtod(m, struct ip *); 2511 } else { 2512 p = mtod(m, u_int8_t *); 2513 p += ETHER_HDR_LEN; 2514 ip = (struct ip *)p; 2515 } 2516 offset = (ip->ip_hl << 2) + ETHER_HDR_LEN; 2517 2518 sendit: 2519 f->sk_csum_startval = 0; 2520 f->sk_csum_start = htole32(((offset + m->m_pkthdr.csum_data) & 0xffff) | 2521 (offset << 16)); 2522 } 2523 2524 static int 2525 sk_encap(sc_if, m_head) 2526 struct sk_if_softc *sc_if; 2527 struct mbuf **m_head; 2528 { 2529 struct sk_txdesc *txd; 2530 struct sk_tx_desc *f = NULL; 2531 struct mbuf *m; 2532 bus_dma_segment_t txsegs[SK_MAXTXSEGS]; 2533 u_int32_t cflags, frag, si, sk_ctl; 2534 int error, i, nseg; 2535 2536 SK_IF_LOCK_ASSERT(sc_if); 2537 2538 if ((txd = STAILQ_FIRST(&sc_if->sk_cdata.sk_txfreeq)) == NULL) 2539 return (ENOBUFS); 2540 2541 error = bus_dmamap_load_mbuf_sg(sc_if->sk_cdata.sk_tx_tag, 2542 txd->tx_dmamap, *m_head, txsegs, &nseg, 0); 2543 if (error == EFBIG) { 2544 m = m_defrag(*m_head, M_DONTWAIT); 2545 if (m == NULL) { 2546 m_freem(*m_head); 2547 *m_head = NULL; 2548 return (ENOMEM); 2549 } 2550 *m_head = m; 2551 error = bus_dmamap_load_mbuf_sg(sc_if->sk_cdata.sk_tx_tag, 2552 txd->tx_dmamap, *m_head, txsegs, &nseg, 0); 2553 if (error != 0) { 2554 m_freem(*m_head); 2555 *m_head = NULL; 2556 return (error); 2557 } 2558 } else if (error != 0) 2559 return (error); 2560 if (nseg == 0) { 2561 m_freem(*m_head); 2562 *m_head = NULL; 2563 return (EIO); 2564 } 2565 if (sc_if->sk_cdata.sk_tx_cnt + nseg >= SK_TX_RING_CNT) { 2566 bus_dmamap_unload(sc_if->sk_cdata.sk_tx_tag, txd->tx_dmamap); 2567 return (ENOBUFS); 2568 } 2569 2570 m = *m_head; 2571 if ((m->m_pkthdr.csum_flags & sc_if->sk_ifp->if_hwassist) != 0) 2572 cflags = SK_OPCODE_CSUM; 2573 else 2574 cflags = SK_OPCODE_DEFAULT; 2575 si = frag = sc_if->sk_cdata.sk_tx_prod; 2576 for (i = 0; i < nseg; i++) { 2577 f = &sc_if->sk_rdata.sk_tx_ring[frag]; 2578 f->sk_data_lo = htole32(SK_ADDR_LO(txsegs[i].ds_addr)); 2579 f->sk_data_hi = htole32(SK_ADDR_HI(txsegs[i].ds_addr)); 2580 sk_ctl = txsegs[i].ds_len | cflags; 2581 if (i == 0) { 2582 if (cflags == SK_OPCODE_CSUM) 2583 sk_txcksum(sc_if->sk_ifp, m, f); 2584 sk_ctl |= SK_TXCTL_FIRSTFRAG; 2585 } else 2586 sk_ctl |= SK_TXCTL_OWN; 2587 f->sk_ctl = htole32(sk_ctl); 2588 sc_if->sk_cdata.sk_tx_cnt++; 2589 SK_INC(frag, SK_TX_RING_CNT); 2590 } 2591 sc_if->sk_cdata.sk_tx_prod = frag; 2592 2593 /* set EOF on the last desciptor */ 2594 frag = (frag + SK_TX_RING_CNT - 1) % SK_TX_RING_CNT; 2595 f = &sc_if->sk_rdata.sk_tx_ring[frag]; 2596 f->sk_ctl |= htole32(SK_TXCTL_LASTFRAG | SK_TXCTL_EOF_INTR); 2597 2598 /* turn the first descriptor ownership to NIC */ 2599 f = &sc_if->sk_rdata.sk_tx_ring[si]; 2600 f->sk_ctl |= htole32(SK_TXCTL_OWN); 2601 2602 STAILQ_REMOVE_HEAD(&sc_if->sk_cdata.sk_txfreeq, tx_q); 2603 STAILQ_INSERT_TAIL(&sc_if->sk_cdata.sk_txbusyq, txd, tx_q); 2604 txd->tx_m = m; 2605 2606 /* sync descriptors */ 2607 bus_dmamap_sync(sc_if->sk_cdata.sk_tx_tag, txd->tx_dmamap, 2608 BUS_DMASYNC_PREWRITE); 2609 bus_dmamap_sync(sc_if->sk_cdata.sk_tx_ring_tag, 2610 sc_if->sk_cdata.sk_tx_ring_map, 2611 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2612 2613 return (0); 2614 } 2615 2616 static void 2617 sk_start(ifp) 2618 struct ifnet *ifp; 2619 { 2620 struct sk_if_softc *sc_if; 2621 2622 sc_if = ifp->if_softc; 2623 2624 SK_IF_LOCK(sc_if); 2625 sk_start_locked(ifp); 2626 SK_IF_UNLOCK(sc_if); 2627 2628 return; 2629 } 2630 2631 static void 2632 sk_start_locked(ifp) 2633 struct ifnet *ifp; 2634 { 2635 struct sk_softc *sc; 2636 struct sk_if_softc *sc_if; 2637 struct mbuf *m_head; 2638 int enq; 2639 2640 sc_if = ifp->if_softc; 2641 sc = sc_if->sk_softc; 2642 2643 SK_IF_LOCK_ASSERT(sc_if); 2644 2645 for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && 2646 sc_if->sk_cdata.sk_tx_cnt < SK_TX_RING_CNT - 1; ) { 2647 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); 2648 if (m_head == NULL) 2649 break; 2650 2651 /* 2652 * Pack the data into the transmit ring. If we 2653 * don't have room, set the OACTIVE flag and wait 2654 * for the NIC to drain the ring. 2655 */ 2656 if (sk_encap(sc_if, &m_head)) { 2657 if (m_head == NULL) 2658 break; 2659 IFQ_DRV_PREPEND(&ifp->if_snd, m_head); 2660 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 2661 break; 2662 } 2663 2664 enq++; 2665 /* 2666 * If there's a BPF listener, bounce a copy of this frame 2667 * to him. 2668 */ 2669 BPF_MTAP(ifp, m_head); 2670 } 2671 2672 if (enq > 0) { 2673 /* Transmit */ 2674 CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START); 2675 2676 /* Set a timeout in case the chip goes out to lunch. */ 2677 sc_if->sk_watchdog_timer = 5; 2678 } 2679 } 2680 2681 2682 static void 2683 sk_watchdog(arg) 2684 void *arg; 2685 { 2686 struct sk_if_softc *sc_if; 2687 struct ifnet *ifp; 2688 2689 ifp = arg; 2690 sc_if = ifp->if_softc; 2691 2692 SK_IF_LOCK_ASSERT(sc_if); 2693 2694 if (sc_if->sk_watchdog_timer == 0 || --sc_if->sk_watchdog_timer) 2695 goto done; 2696 2697 /* 2698 * Reclaim first as there is a possibility of losing Tx completion 2699 * interrupts. 2700 */ 2701 sk_txeof(sc_if); 2702 if (sc_if->sk_cdata.sk_tx_cnt != 0) { 2703 if_printf(sc_if->sk_ifp, "watchdog timeout\n"); 2704 ifp->if_oerrors++; 2705 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 2706 sk_init_locked(sc_if); 2707 } 2708 2709 done: 2710 callout_reset(&sc_if->sk_watchdog_ch, hz, sk_watchdog, ifp); 2711 2712 return; 2713 } 2714 2715 static int 2716 skc_shutdown(dev) 2717 device_t dev; 2718 { 2719 struct sk_softc *sc; 2720 2721 sc = device_get_softc(dev); 2722 SK_LOCK(sc); 2723 2724 /* Turn off the 'driver is loaded' LED. */ 2725 CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_OFF); 2726 2727 /* 2728 * Reset the GEnesis controller. Doing this should also 2729 * assert the resets on the attached XMAC(s). 2730 */ 2731 sk_reset(sc); 2732 SK_UNLOCK(sc); 2733 2734 return (0); 2735 } 2736 2737 static int 2738 skc_suspend(dev) 2739 device_t dev; 2740 { 2741 struct sk_softc *sc; 2742 struct sk_if_softc *sc_if0, *sc_if1; 2743 struct ifnet *ifp0 = NULL, *ifp1 = NULL; 2744 2745 sc = device_get_softc(dev); 2746 2747 SK_LOCK(sc); 2748 2749 sc_if0 = sc->sk_if[SK_PORT_A]; 2750 sc_if1 = sc->sk_if[SK_PORT_B]; 2751 if (sc_if0 != NULL) 2752 ifp0 = sc_if0->sk_ifp; 2753 if (sc_if1 != NULL) 2754 ifp1 = sc_if1->sk_ifp; 2755 if (ifp0 != NULL) 2756 sk_stop(sc_if0); 2757 if (ifp1 != NULL) 2758 sk_stop(sc_if1); 2759 sc->sk_suspended = 1; 2760 2761 SK_UNLOCK(sc); 2762 2763 return (0); 2764 } 2765 2766 static int 2767 skc_resume(dev) 2768 device_t dev; 2769 { 2770 struct sk_softc *sc; 2771 struct sk_if_softc *sc_if0, *sc_if1; 2772 struct ifnet *ifp0 = NULL, *ifp1 = NULL; 2773 2774 sc = device_get_softc(dev); 2775 2776 SK_LOCK(sc); 2777 2778 sc_if0 = sc->sk_if[SK_PORT_A]; 2779 sc_if1 = sc->sk_if[SK_PORT_B]; 2780 if (sc_if0 != NULL) 2781 ifp0 = sc_if0->sk_ifp; 2782 if (sc_if1 != NULL) 2783 ifp1 = sc_if1->sk_ifp; 2784 if (ifp0 != NULL && ifp0->if_flags & IFF_UP) 2785 sk_init_locked(sc_if0); 2786 if (ifp1 != NULL && ifp1->if_flags & IFF_UP) 2787 sk_init_locked(sc_if1); 2788 sc->sk_suspended = 0; 2789 2790 SK_UNLOCK(sc); 2791 2792 return (0); 2793 } 2794 2795 /* 2796 * According to the data sheet from SK-NET GENESIS the hardware can compute 2797 * two Rx checksums at the same time(Each checksum start position is 2798 * programmed in Rx descriptors). However it seems that TCP/UDP checksum 2799 * does not work at least on my Yukon hardware. I tried every possible ways 2800 * to get correct checksum value but couldn't get correct one. So TCP/UDP 2801 * checksum offload was disabled at the moment and only IP checksum offload 2802 * was enabled. 2803 * As nomral IP header size is 20 bytes I can't expect it would give an 2804 * increase in throughput. However it seems it doesn't hurt performance in 2805 * my testing. If there is a more detailed information for checksum secret 2806 * of the hardware in question please contact yongari@FreeBSD.org to add 2807 * TCP/UDP checksum offload support. 2808 */ 2809 static __inline void 2810 sk_rxcksum(ifp, m, csum) 2811 struct ifnet *ifp; 2812 struct mbuf *m; 2813 u_int32_t csum; 2814 { 2815 struct ether_header *eh; 2816 struct ip *ip; 2817 int32_t hlen, len, pktlen; 2818 u_int16_t csum1, csum2, ipcsum; 2819 2820 pktlen = m->m_pkthdr.len; 2821 if (pktlen < sizeof(struct ether_header) + sizeof(struct ip)) 2822 return; 2823 eh = mtod(m, struct ether_header *); 2824 if (eh->ether_type != htons(ETHERTYPE_IP)) 2825 return; 2826 ip = (struct ip *)(eh + 1); 2827 if (ip->ip_v != IPVERSION) 2828 return; 2829 hlen = ip->ip_hl << 2; 2830 pktlen -= sizeof(struct ether_header); 2831 if (hlen < sizeof(struct ip)) 2832 return; 2833 if (ntohs(ip->ip_len) < hlen) 2834 return; 2835 if (ntohs(ip->ip_len) != pktlen) 2836 return; 2837 2838 csum1 = htons(csum & 0xffff); 2839 csum2 = htons((csum >> 16) & 0xffff); 2840 ipcsum = in_addword(csum1, ~csum2 & 0xffff); 2841 /* checksum fixup for IP options */ 2842 len = hlen - sizeof(struct ip); 2843 if (len > 0) { 2844 /* 2845 * If the second checksum value is correct we can compute IP 2846 * checksum with simple math. Unfortunately the second checksum 2847 * value is wrong so we can't verify the checksum from the 2848 * value(It seems there is some magic here to get correct 2849 * value). If the second checksum value is correct it also 2850 * means we can get TCP/UDP checksum) here. However, it still 2851 * needs pseudo header checksum calculation due to hardware 2852 * limitations. 2853 */ 2854 return; 2855 } 2856 m->m_pkthdr.csum_flags = CSUM_IP_CHECKED; 2857 if (ipcsum == 0xffff) 2858 m->m_pkthdr.csum_flags |= CSUM_IP_VALID; 2859 } 2860 2861 static __inline int 2862 sk_rxvalid(sc, stat, len) 2863 struct sk_softc *sc; 2864 u_int32_t stat, len; 2865 { 2866 2867 if (sc->sk_type == SK_GENESIS) { 2868 if ((stat & XM_RXSTAT_ERRFRAME) == XM_RXSTAT_ERRFRAME || 2869 XM_RXSTAT_BYTES(stat) != len) 2870 return (0); 2871 } else { 2872 if ((stat & (YU_RXSTAT_CRCERR | YU_RXSTAT_LONGERR | 2873 YU_RXSTAT_MIIERR | YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC | 2874 YU_RXSTAT_JABBER)) != 0 || 2875 (stat & YU_RXSTAT_RXOK) != YU_RXSTAT_RXOK || 2876 YU_RXSTAT_BYTES(stat) != len) 2877 return (0); 2878 } 2879 2880 return (1); 2881 } 2882 2883 static void 2884 sk_rxeof(sc_if) 2885 struct sk_if_softc *sc_if; 2886 { 2887 struct sk_softc *sc; 2888 struct mbuf *m; 2889 struct ifnet *ifp; 2890 struct sk_rx_desc *cur_rx; 2891 struct sk_rxdesc *rxd; 2892 int cons, prog; 2893 u_int32_t csum, rxstat, sk_ctl; 2894 2895 sc = sc_if->sk_softc; 2896 ifp = sc_if->sk_ifp; 2897 2898 SK_IF_LOCK_ASSERT(sc_if); 2899 2900 bus_dmamap_sync(sc_if->sk_cdata.sk_rx_ring_tag, 2901 sc_if->sk_cdata.sk_rx_ring_map, BUS_DMASYNC_POSTREAD); 2902 2903 prog = 0; 2904 for (cons = sc_if->sk_cdata.sk_rx_cons; prog < SK_RX_RING_CNT; 2905 prog++, SK_INC(cons, SK_RX_RING_CNT)) { 2906 cur_rx = &sc_if->sk_rdata.sk_rx_ring[cons]; 2907 sk_ctl = le32toh(cur_rx->sk_ctl); 2908 if ((sk_ctl & SK_RXCTL_OWN) != 0) 2909 break; 2910 rxd = &sc_if->sk_cdata.sk_rxdesc[cons]; 2911 rxstat = le32toh(cur_rx->sk_xmac_rxstat); 2912 2913 if ((sk_ctl & (SK_RXCTL_STATUS_VALID | SK_RXCTL_FIRSTFRAG | 2914 SK_RXCTL_LASTFRAG)) != (SK_RXCTL_STATUS_VALID | 2915 SK_RXCTL_FIRSTFRAG | SK_RXCTL_LASTFRAG) || 2916 SK_RXBYTES(sk_ctl) < SK_MIN_FRAMELEN || 2917 SK_RXBYTES(sk_ctl) > SK_MAX_FRAMELEN || 2918 sk_rxvalid(sc, rxstat, SK_RXBYTES(sk_ctl)) == 0) { 2919 ifp->if_ierrors++; 2920 sk_discard_rxbuf(sc_if, cons); 2921 continue; 2922 } 2923 2924 m = rxd->rx_m; 2925 csum = le32toh(cur_rx->sk_csum); 2926 if (sk_newbuf(sc_if, cons) != 0) { 2927 ifp->if_iqdrops++; 2928 /* reuse old buffer */ 2929 sk_discard_rxbuf(sc_if, cons); 2930 continue; 2931 } 2932 m->m_pkthdr.rcvif = ifp; 2933 m->m_pkthdr.len = m->m_len = SK_RXBYTES(sk_ctl); 2934 ifp->if_ipackets++; 2935 if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) 2936 sk_rxcksum(ifp, m, csum); 2937 SK_IF_UNLOCK(sc_if); 2938 (*ifp->if_input)(ifp, m); 2939 SK_IF_LOCK(sc_if); 2940 } 2941 2942 if (prog > 0) { 2943 sc_if->sk_cdata.sk_rx_cons = cons; 2944 bus_dmamap_sync(sc_if->sk_cdata.sk_rx_ring_tag, 2945 sc_if->sk_cdata.sk_rx_ring_map, 2946 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2947 } 2948 } 2949 2950 static void 2951 sk_jumbo_rxeof(sc_if) 2952 struct sk_if_softc *sc_if; 2953 { 2954 struct sk_softc *sc; 2955 struct mbuf *m; 2956 struct ifnet *ifp; 2957 struct sk_rx_desc *cur_rx; 2958 struct sk_rxdesc *jrxd; 2959 int cons, prog; 2960 u_int32_t csum, rxstat, sk_ctl; 2961 2962 sc = sc_if->sk_softc; 2963 ifp = sc_if->sk_ifp; 2964 2965 SK_IF_LOCK_ASSERT(sc_if); 2966 2967 bus_dmamap_sync(sc_if->sk_cdata.sk_jumbo_rx_ring_tag, 2968 sc_if->sk_cdata.sk_jumbo_rx_ring_map, BUS_DMASYNC_POSTREAD); 2969 2970 prog = 0; 2971 for (cons = sc_if->sk_cdata.sk_jumbo_rx_cons; 2972 prog < SK_JUMBO_RX_RING_CNT; 2973 prog++, SK_INC(cons, SK_JUMBO_RX_RING_CNT)) { 2974 cur_rx = &sc_if->sk_rdata.sk_jumbo_rx_ring[cons]; 2975 sk_ctl = le32toh(cur_rx->sk_ctl); 2976 if ((sk_ctl & SK_RXCTL_OWN) != 0) 2977 break; 2978 jrxd = &sc_if->sk_cdata.sk_jumbo_rxdesc[cons]; 2979 rxstat = le32toh(cur_rx->sk_xmac_rxstat); 2980 2981 if ((sk_ctl & (SK_RXCTL_STATUS_VALID | SK_RXCTL_FIRSTFRAG | 2982 SK_RXCTL_LASTFRAG)) != (SK_RXCTL_STATUS_VALID | 2983 SK_RXCTL_FIRSTFRAG | SK_RXCTL_LASTFRAG) || 2984 SK_RXBYTES(sk_ctl) < SK_MIN_FRAMELEN || 2985 SK_RXBYTES(sk_ctl) > SK_JUMBO_FRAMELEN || 2986 sk_rxvalid(sc, rxstat, SK_RXBYTES(sk_ctl)) == 0) { 2987 ifp->if_ierrors++; 2988 sk_discard_jumbo_rxbuf(sc_if, cons); 2989 continue; 2990 } 2991 2992 m = jrxd->rx_m; 2993 csum = le32toh(cur_rx->sk_csum); 2994 if (sk_jumbo_newbuf(sc_if, cons) != 0) { 2995 ifp->if_iqdrops++; 2996 /* reuse old buffer */ 2997 sk_discard_jumbo_rxbuf(sc_if, cons); 2998 continue; 2999 } 3000 m->m_pkthdr.rcvif = ifp; 3001 m->m_pkthdr.len = m->m_len = SK_RXBYTES(sk_ctl); 3002 ifp->if_ipackets++; 3003 if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) 3004 sk_rxcksum(ifp, m, csum); 3005 SK_IF_UNLOCK(sc_if); 3006 (*ifp->if_input)(ifp, m); 3007 SK_IF_LOCK(sc_if); 3008 } 3009 3010 if (prog > 0) { 3011 sc_if->sk_cdata.sk_jumbo_rx_cons = cons; 3012 bus_dmamap_sync(sc_if->sk_cdata.sk_jumbo_rx_ring_tag, 3013 sc_if->sk_cdata.sk_jumbo_rx_ring_map, 3014 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 3015 } 3016 } 3017 3018 static void 3019 sk_txeof(sc_if) 3020 struct sk_if_softc *sc_if; 3021 { 3022 struct sk_softc *sc; 3023 struct sk_txdesc *txd; 3024 struct sk_tx_desc *cur_tx; 3025 struct ifnet *ifp; 3026 u_int32_t idx, sk_ctl; 3027 3028 sc = sc_if->sk_softc; 3029 ifp = sc_if->sk_ifp; 3030 3031 txd = STAILQ_FIRST(&sc_if->sk_cdata.sk_txbusyq); 3032 if (txd == NULL) 3033 return; 3034 bus_dmamap_sync(sc_if->sk_cdata.sk_tx_ring_tag, 3035 sc_if->sk_cdata.sk_tx_ring_map, BUS_DMASYNC_POSTREAD); 3036 /* 3037 * Go through our tx ring and free mbufs for those 3038 * frames that have been sent. 3039 */ 3040 for (idx = sc_if->sk_cdata.sk_tx_cons;; SK_INC(idx, SK_TX_RING_CNT)) { 3041 if (sc_if->sk_cdata.sk_tx_cnt <= 0) 3042 break; 3043 cur_tx = &sc_if->sk_rdata.sk_tx_ring[idx]; 3044 sk_ctl = le32toh(cur_tx->sk_ctl); 3045 if (sk_ctl & SK_TXCTL_OWN) 3046 break; 3047 sc_if->sk_cdata.sk_tx_cnt--; 3048 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 3049 if ((sk_ctl & SK_TXCTL_LASTFRAG) == 0) 3050 continue; 3051 bus_dmamap_sync(sc_if->sk_cdata.sk_tx_tag, txd->tx_dmamap, 3052 BUS_DMASYNC_POSTWRITE); 3053 bus_dmamap_unload(sc_if->sk_cdata.sk_tx_tag, txd->tx_dmamap); 3054 3055 ifp->if_opackets++; 3056 m_freem(txd->tx_m); 3057 txd->tx_m = NULL; 3058 STAILQ_REMOVE_HEAD(&sc_if->sk_cdata.sk_txbusyq, tx_q); 3059 STAILQ_INSERT_TAIL(&sc_if->sk_cdata.sk_txfreeq, txd, tx_q); 3060 txd = STAILQ_FIRST(&sc_if->sk_cdata.sk_txbusyq); 3061 } 3062 sc_if->sk_cdata.sk_tx_cons = idx; 3063 sc_if->sk_watchdog_timer = sc_if->sk_cdata.sk_tx_cnt > 0 ? 5 : 0; 3064 3065 bus_dmamap_sync(sc_if->sk_cdata.sk_tx_ring_tag, 3066 sc_if->sk_cdata.sk_tx_ring_map, 3067 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 3068 } 3069 3070 static void 3071 sk_tick(xsc_if) 3072 void *xsc_if; 3073 { 3074 struct sk_if_softc *sc_if; 3075 struct mii_data *mii; 3076 struct ifnet *ifp; 3077 int i; 3078 3079 sc_if = xsc_if; 3080 ifp = sc_if->sk_ifp; 3081 mii = device_get_softc(sc_if->sk_miibus); 3082 3083 if (!(ifp->if_flags & IFF_UP)) 3084 return; 3085 3086 if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) { 3087 sk_intr_bcom(sc_if); 3088 return; 3089 } 3090 3091 /* 3092 * According to SysKonnect, the correct way to verify that 3093 * the link has come back up is to poll bit 0 of the GPIO 3094 * register three times. This pin has the signal from the 3095 * link_sync pin connected to it; if we read the same link 3096 * state 3 times in a row, we know the link is up. 3097 */ 3098 for (i = 0; i < 3; i++) { 3099 if (SK_XM_READ_2(sc_if, XM_GPIO) & XM_GPIO_GP0_SET) 3100 break; 3101 } 3102 3103 if (i != 3) { 3104 callout_reset(&sc_if->sk_tick_ch, hz, sk_tick, sc_if); 3105 return; 3106 } 3107 3108 /* Turn the GP0 interrupt back on. */ 3109 SK_XM_CLRBIT_2(sc_if, XM_IMR, XM_IMR_GP0_SET); 3110 SK_XM_READ_2(sc_if, XM_ISR); 3111 mii_tick(mii); 3112 callout_stop(&sc_if->sk_tick_ch); 3113 } 3114 3115 static void 3116 sk_yukon_tick(xsc_if) 3117 void *xsc_if; 3118 { 3119 struct sk_if_softc *sc_if; 3120 struct mii_data *mii; 3121 3122 sc_if = xsc_if; 3123 mii = device_get_softc(sc_if->sk_miibus); 3124 3125 mii_tick(mii); 3126 callout_reset(&sc_if->sk_tick_ch, hz, sk_yukon_tick, sc_if); 3127 } 3128 3129 static void 3130 sk_intr_bcom(sc_if) 3131 struct sk_if_softc *sc_if; 3132 { 3133 struct mii_data *mii; 3134 struct ifnet *ifp; 3135 int status; 3136 mii = device_get_softc(sc_if->sk_miibus); 3137 ifp = sc_if->sk_ifp; 3138 3139 SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB); 3140 3141 /* 3142 * Read the PHY interrupt register to make sure 3143 * we clear any pending interrupts. 3144 */ 3145 status = sk_xmac_miibus_readreg(sc_if, SK_PHYADDR_BCOM, BRGPHY_MII_ISR); 3146 3147 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 3148 sk_init_xmac(sc_if); 3149 return; 3150 } 3151 3152 if (status & (BRGPHY_ISR_LNK_CHG|BRGPHY_ISR_AN_PR)) { 3153 int lstat; 3154 lstat = sk_xmac_miibus_readreg(sc_if, SK_PHYADDR_BCOM, 3155 BRGPHY_MII_AUXSTS); 3156 3157 if (!(lstat & BRGPHY_AUXSTS_LINK) && sc_if->sk_link) { 3158 mii_mediachg(mii); 3159 /* Turn off the link LED. */ 3160 SK_IF_WRITE_1(sc_if, 0, 3161 SK_LINKLED1_CTL, SK_LINKLED_OFF); 3162 sc_if->sk_link = 0; 3163 } else if (status & BRGPHY_ISR_LNK_CHG) { 3164 sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM, 3165 BRGPHY_MII_IMR, 0xFF00); 3166 mii_tick(mii); 3167 sc_if->sk_link = 1; 3168 /* Turn on the link LED. */ 3169 SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, 3170 SK_LINKLED_ON|SK_LINKLED_LINKSYNC_OFF| 3171 SK_LINKLED_BLINK_OFF); 3172 } else { 3173 mii_tick(mii); 3174 callout_reset(&sc_if->sk_tick_ch, hz, sk_tick, sc_if); 3175 } 3176 } 3177 3178 SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB); 3179 3180 return; 3181 } 3182 3183 static void 3184 sk_intr_xmac(sc_if) 3185 struct sk_if_softc *sc_if; 3186 { 3187 struct sk_softc *sc; 3188 u_int16_t status; 3189 3190 sc = sc_if->sk_softc; 3191 status = SK_XM_READ_2(sc_if, XM_ISR); 3192 3193 /* 3194 * Link has gone down. Start MII tick timeout to 3195 * watch for link resync. 3196 */ 3197 if (sc_if->sk_phytype == SK_PHYTYPE_XMAC) { 3198 if (status & XM_ISR_GP0_SET) { 3199 SK_XM_SETBIT_2(sc_if, XM_IMR, XM_IMR_GP0_SET); 3200 callout_reset(&sc_if->sk_tick_ch, hz, sk_tick, sc_if); 3201 } 3202 3203 if (status & XM_ISR_AUTONEG_DONE) { 3204 callout_reset(&sc_if->sk_tick_ch, hz, sk_tick, sc_if); 3205 } 3206 } 3207 3208 if (status & XM_IMR_TX_UNDERRUN) 3209 SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_FLUSH_TXFIFO); 3210 3211 if (status & XM_IMR_RX_OVERRUN) 3212 SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_FLUSH_RXFIFO); 3213 3214 status = SK_XM_READ_2(sc_if, XM_ISR); 3215 3216 return; 3217 } 3218 3219 static void 3220 sk_intr_yukon(sc_if) 3221 struct sk_if_softc *sc_if; 3222 { 3223 u_int8_t status; 3224 3225 status = SK_IF_READ_1(sc_if, 0, SK_GMAC_ISR); 3226 /* RX overrun */ 3227 if ((status & SK_GMAC_INT_RX_OVER) != 0) { 3228 SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, 3229 SK_RFCTL_RX_FIFO_OVER); 3230 } 3231 /* TX underrun */ 3232 if ((status & SK_GMAC_INT_TX_UNDER) != 0) { 3233 SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, 3234 SK_TFCTL_TX_FIFO_UNDER); 3235 } 3236 } 3237 3238 static void 3239 sk_intr(xsc) 3240 void *xsc; 3241 { 3242 struct sk_softc *sc = xsc; 3243 struct sk_if_softc *sc_if0, *sc_if1; 3244 struct ifnet *ifp0 = NULL, *ifp1 = NULL; 3245 u_int32_t status; 3246 3247 SK_LOCK(sc); 3248 3249 #ifndef __HAIKU__ 3250 status = CSR_READ_4(sc, SK_ISSR); 3251 if (status == 0 || status == 0xffffffff || sc->sk_suspended) 3252 { 3253 goto done_locked; 3254 } 3255 #endif 3256 3257 sc_if0 = sc->sk_if[SK_PORT_A]; 3258 sc_if1 = sc->sk_if[SK_PORT_B]; 3259 3260 if (sc_if0 != NULL) 3261 ifp0 = sc_if0->sk_ifp; 3262 if (sc_if1 != NULL) 3263 ifp1 = sc_if1->sk_ifp; 3264 3265 #ifndef __HAIKU__ 3266 for (; (status &= sc->sk_intrmask) != 0;) { 3267 #else 3268 status = atomic_and((int32 *)&sc->sk_intstatus, 0); 3269 status &= sc->sk_intrmask; 3270 while (true) { 3271 3272 if (status == 0 || status == 0xffffffff || sc->sk_suspended) 3273 { 3274 goto done_locked; 3275 } 3276 #endif 3277 3278 /* Handle receive interrupts first. */ 3279 if (status & SK_ISR_RX1_EOF) { 3280 if (ifp0->if_mtu > SK_MAX_FRAMELEN) 3281 sk_jumbo_rxeof(sc_if0); 3282 else 3283 sk_rxeof(sc_if0); 3284 CSR_WRITE_4(sc, SK_BMU_RX_CSR0, 3285 SK_RXBMU_CLR_IRQ_EOF|SK_RXBMU_RX_START); 3286 } 3287 if (status & SK_ISR_RX2_EOF) { 3288 if (ifp1->if_mtu > SK_MAX_FRAMELEN) 3289 sk_jumbo_rxeof(sc_if1); 3290 else 3291 sk_rxeof(sc_if1); 3292 CSR_WRITE_4(sc, SK_BMU_RX_CSR1, 3293 SK_RXBMU_CLR_IRQ_EOF|SK_RXBMU_RX_START); 3294 } 3295 3296 /* Then transmit interrupts. */ 3297 if (status & SK_ISR_TX1_S_EOF) { 3298 sk_txeof(sc_if0); 3299 CSR_WRITE_4(sc, SK_BMU_TXS_CSR0, SK_TXBMU_CLR_IRQ_EOF); 3300 } 3301 if (status & SK_ISR_TX2_S_EOF) { 3302 sk_txeof(sc_if1); 3303 CSR_WRITE_4(sc, SK_BMU_TXS_CSR1, SK_TXBMU_CLR_IRQ_EOF); 3304 } 3305 3306 /* Then MAC interrupts. */ 3307 if (status & SK_ISR_MAC1 && 3308 ifp0->if_drv_flags & IFF_DRV_RUNNING) { 3309 if (sc->sk_type == SK_GENESIS) 3310 sk_intr_xmac(sc_if0); 3311 else 3312 sk_intr_yukon(sc_if0); 3313 } 3314 3315 if (status & SK_ISR_MAC2 && 3316 ifp1->if_drv_flags & IFF_DRV_RUNNING) { 3317 if (sc->sk_type == SK_GENESIS) 3318 sk_intr_xmac(sc_if1); 3319 else 3320 sk_intr_yukon(sc_if1); 3321 } 3322 3323 if (status & SK_ISR_EXTERNAL_REG) { 3324 if (ifp0 != NULL && 3325 sc_if0->sk_phytype == SK_PHYTYPE_BCOM) 3326 sk_intr_bcom(sc_if0); 3327 if (ifp1 != NULL && 3328 sc_if1->sk_phytype == SK_PHYTYPE_BCOM) 3329 sk_intr_bcom(sc_if1); 3330 } 3331 #ifdef __HAIKU__ 3332 status = CSR_READ_4(sc, SK_ISSR); 3333 if (((status & sc->sk_intrmask) == 0) || status == 0xffffffff || 3334 sc->sk_suspended) { 3335 break; 3336 } 3337 #endif 3338 } 3339 3340 CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); 3341 3342 if (ifp0 != NULL && !IFQ_DRV_IS_EMPTY(&ifp0->if_snd)) 3343 sk_start_locked(ifp0); 3344 if (ifp1 != NULL && !IFQ_DRV_IS_EMPTY(&ifp1->if_snd)) 3345 sk_start_locked(ifp1); 3346 3347 done_locked: 3348 SK_UNLOCK(sc); 3349 } 3350 3351 static void 3352 sk_init_xmac(sc_if) 3353 struct sk_if_softc *sc_if; 3354 { 3355 struct sk_softc *sc; 3356 struct ifnet *ifp; 3357 u_int16_t eaddr[(ETHER_ADDR_LEN+1)/2]; 3358 struct sk_bcom_hack bhack[] = { 3359 { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 }, 3360 { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 }, 3361 { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 }, 3362 { 0, 0 } }; 3363 3364 SK_IF_LOCK_ASSERT(sc_if); 3365 3366 sc = sc_if->sk_softc; 3367 ifp = sc_if->sk_ifp; 3368 3369 /* Unreset the XMAC. */ 3370 SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, SK_TXMACCTL_XMAC_UNRESET); 3371 DELAY(1000); 3372 3373 /* Reset the XMAC's internal state. */ 3374 SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC); 3375 3376 /* Save the XMAC II revision */ 3377 sc_if->sk_xmac_rev = XM_XMAC_REV(SK_XM_READ_4(sc_if, XM_DEVID)); 3378 3379 /* 3380 * Perform additional initialization for external PHYs, 3381 * namely for the 1000baseTX cards that use the XMAC's 3382 * GMII mode. 3383 */ 3384 if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) { 3385 int i = 0; 3386 u_int32_t val; 3387 3388 /* Take PHY out of reset. */ 3389 val = sk_win_read_4(sc, SK_GPIO); 3390 if (sc_if->sk_port == SK_PORT_A) 3391 val |= SK_GPIO_DIR0|SK_GPIO_DAT0; 3392 else 3393 val |= SK_GPIO_DIR2|SK_GPIO_DAT2; 3394 sk_win_write_4(sc, SK_GPIO, val); 3395 3396 /* Enable GMII mode on the XMAC. */ 3397 SK_XM_SETBIT_2(sc_if, XM_HWCFG, XM_HWCFG_GMIIMODE); 3398 3399 sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM, 3400 BRGPHY_MII_BMCR, BRGPHY_BMCR_RESET); 3401 DELAY(10000); 3402 sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM, 3403 BRGPHY_MII_IMR, 0xFFF0); 3404 3405 /* 3406 * Early versions of the BCM5400 apparently have 3407 * a bug that requires them to have their reserved 3408 * registers initialized to some magic values. I don't 3409 * know what the numbers do, I'm just the messenger. 3410 */ 3411 if (sk_xmac_miibus_readreg(sc_if, SK_PHYADDR_BCOM, 0x03) 3412 == 0x6041) { 3413 while(bhack[i].reg) { 3414 sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM, 3415 bhack[i].reg, bhack[i].val); 3416 i++; 3417 } 3418 } 3419 } 3420 3421 /* Set station address */ 3422 bcopy(IF_LLADDR(sc_if->sk_ifp), eaddr, ETHER_ADDR_LEN); 3423 SK_XM_WRITE_2(sc_if, XM_PAR0, eaddr[0]); 3424 SK_XM_WRITE_2(sc_if, XM_PAR1, eaddr[1]); 3425 SK_XM_WRITE_2(sc_if, XM_PAR2, eaddr[2]); 3426 SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_STATION); 3427 3428 if (ifp->if_flags & IFF_BROADCAST) { 3429 SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD); 3430 } else { 3431 SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD); 3432 } 3433 3434 /* We don't need the FCS appended to the packet. */ 3435 SK_XM_SETBIT_2(sc_if, XM_RXCMD, XM_RXCMD_STRIPFCS); 3436 3437 /* We want short frames padded to 60 bytes. */ 3438 SK_XM_SETBIT_2(sc_if, XM_TXCMD, XM_TXCMD_AUTOPAD); 3439 3440 /* 3441 * Enable the reception of all error frames. This is is 3442 * a necessary evil due to the design of the XMAC. The 3443 * XMAC's receive FIFO is only 8K in size, however jumbo 3444 * frames can be up to 9000 bytes in length. When bad 3445 * frame filtering is enabled, the XMAC's RX FIFO operates 3446 * in 'store and forward' mode. For this to work, the 3447 * entire frame has to fit into the FIFO, but that means 3448 * that jumbo frames larger than 8192 bytes will be 3449 * truncated. Disabling all bad frame filtering causes 3450 * the RX FIFO to operate in streaming mode, in which 3451 * case the XMAC will start transfering frames out of the 3452 * RX FIFO as soon as the FIFO threshold is reached. 3453 */ 3454 if (ifp->if_mtu > SK_MAX_FRAMELEN) { 3455 SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_BADFRAMES| 3456 XM_MODE_RX_GIANTS|XM_MODE_RX_RUNTS|XM_MODE_RX_CRCERRS| 3457 XM_MODE_RX_INRANGELEN); 3458 SK_XM_SETBIT_2(sc_if, XM_RXCMD, XM_RXCMD_BIGPKTOK); 3459 } else 3460 SK_XM_CLRBIT_2(sc_if, XM_RXCMD, XM_RXCMD_BIGPKTOK); 3461 3462 /* 3463 * Bump up the transmit threshold. This helps hold off transmit 3464 * underruns when we're blasting traffic from both ports at once. 3465 */ 3466 SK_XM_WRITE_2(sc_if, XM_TX_REQTHRESH, SK_XM_TX_FIFOTHRESH); 3467 3468 /* Set promiscuous mode */ 3469 sk_setpromisc(sc_if); 3470 3471 /* Set multicast filter */ 3472 sk_setmulti(sc_if); 3473 3474 /* Clear and enable interrupts */ 3475 SK_XM_READ_2(sc_if, XM_ISR); 3476 if (sc_if->sk_phytype == SK_PHYTYPE_XMAC) 3477 SK_XM_WRITE_2(sc_if, XM_IMR, XM_INTRS); 3478 else 3479 SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF); 3480 3481 /* Configure MAC arbiter */ 3482 switch(sc_if->sk_xmac_rev) { 3483 case XM_XMAC_REV_B2: 3484 sk_win_write_1(sc, SK_RCINIT_RX1, SK_RCINIT_XMAC_B2); 3485 sk_win_write_1(sc, SK_RCINIT_TX1, SK_RCINIT_XMAC_B2); 3486 sk_win_write_1(sc, SK_RCINIT_RX2, SK_RCINIT_XMAC_B2); 3487 sk_win_write_1(sc, SK_RCINIT_TX2, SK_RCINIT_XMAC_B2); 3488 sk_win_write_1(sc, SK_MINIT_RX1, SK_MINIT_XMAC_B2); 3489 sk_win_write_1(sc, SK_MINIT_TX1, SK_MINIT_XMAC_B2); 3490 sk_win_write_1(sc, SK_MINIT_RX2, SK_MINIT_XMAC_B2); 3491 sk_win_write_1(sc, SK_MINIT_TX2, SK_MINIT_XMAC_B2); 3492 sk_win_write_1(sc, SK_RECOVERY_CTL, SK_RECOVERY_XMAC_B2); 3493 break; 3494 case XM_XMAC_REV_C1: 3495 sk_win_write_1(sc, SK_RCINIT_RX1, SK_RCINIT_XMAC_C1); 3496 sk_win_write_1(sc, SK_RCINIT_TX1, SK_RCINIT_XMAC_C1); 3497 sk_win_write_1(sc, SK_RCINIT_RX2, SK_RCINIT_XMAC_C1); 3498 sk_win_write_1(sc, SK_RCINIT_TX2, SK_RCINIT_XMAC_C1); 3499 sk_win_write_1(sc, SK_MINIT_RX1, SK_MINIT_XMAC_C1); 3500 sk_win_write_1(sc, SK_MINIT_TX1, SK_MINIT_XMAC_C1); 3501 sk_win_write_1(sc, SK_MINIT_RX2, SK_MINIT_XMAC_C1); 3502 sk_win_write_1(sc, SK_MINIT_TX2, SK_MINIT_XMAC_C1); 3503 sk_win_write_1(sc, SK_RECOVERY_CTL, SK_RECOVERY_XMAC_B2); 3504 break; 3505 default: 3506 break; 3507 } 3508 sk_win_write_2(sc, SK_MACARB_CTL, 3509 SK_MACARBCTL_UNRESET|SK_MACARBCTL_FASTOE_OFF); 3510 3511 sc_if->sk_link = 1; 3512 3513 return; 3514 } 3515 3516 static void 3517 sk_init_yukon(sc_if) 3518 struct sk_if_softc *sc_if; 3519 { 3520 u_int32_t phy, v; 3521 u_int16_t reg; 3522 struct sk_softc *sc; 3523 struct ifnet *ifp; 3524 int i; 3525 3526 SK_IF_LOCK_ASSERT(sc_if); 3527 3528 sc = sc_if->sk_softc; 3529 ifp = sc_if->sk_ifp; 3530 3531 if (sc->sk_type == SK_YUKON_LITE && 3532 sc->sk_rev >= SK_YUKON_LITE_REV_A3) { 3533 /* 3534 * Workaround code for COMA mode, set PHY reset. 3535 * Otherwise it will not correctly take chip out of 3536 * powerdown (coma) 3537 */ 3538 v = sk_win_read_4(sc, SK_GPIO); 3539 v |= SK_GPIO_DIR9 | SK_GPIO_DAT9; 3540 sk_win_write_4(sc, SK_GPIO, v); 3541 } 3542 3543 /* GMAC and GPHY Reset */ 3544 SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET); 3545 SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET); 3546 DELAY(1000); 3547 3548 if (sc->sk_type == SK_YUKON_LITE && 3549 sc->sk_rev >= SK_YUKON_LITE_REV_A3) { 3550 /* 3551 * Workaround code for COMA mode, clear PHY reset 3552 */ 3553 v = sk_win_read_4(sc, SK_GPIO); 3554 v |= SK_GPIO_DIR9; 3555 v &= ~SK_GPIO_DAT9; 3556 sk_win_write_4(sc, SK_GPIO, v); 3557 } 3558 3559 phy = SK_GPHY_INT_POL_HI | SK_GPHY_DIS_FC | SK_GPHY_DIS_SLEEP | 3560 SK_GPHY_ENA_XC | SK_GPHY_ANEG_ALL | SK_GPHY_ENA_PAUSE; 3561 3562 if (sc->sk_coppertype) 3563 phy |= SK_GPHY_COPPER; 3564 else 3565 phy |= SK_GPHY_FIBER; 3566 3567 SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, phy | SK_GPHY_RESET_SET); 3568 DELAY(1000); 3569 SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, phy | SK_GPHY_RESET_CLEAR); 3570 SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF | 3571 SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR); 3572 3573 /* unused read of the interrupt source register */ 3574 SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR); 3575 3576 reg = SK_YU_READ_2(sc_if, YUKON_PAR); 3577 3578 /* MIB Counter Clear Mode set */ 3579 reg |= YU_PAR_MIB_CLR; 3580 SK_YU_WRITE_2(sc_if, YUKON_PAR, reg); 3581 3582 /* MIB Counter Clear Mode clear */ 3583 reg &= ~YU_PAR_MIB_CLR; 3584 SK_YU_WRITE_2(sc_if, YUKON_PAR, reg); 3585 3586 /* receive control reg */ 3587 SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR); 3588 3589 /* transmit parameter register */ 3590 SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) | 3591 YU_TPR_JAM_IPG(0xb) | YU_TPR_JAM2DATA_IPG(0x1a) ); 3592 3593 /* serial mode register */ 3594 reg = YU_SMR_DATA_BLIND(0x1c) | YU_SMR_MFL_VLAN | YU_SMR_IPG_DATA(0x1e); 3595 if (ifp->if_mtu > SK_MAX_FRAMELEN) 3596 reg |= YU_SMR_MFL_JUMBO; 3597 SK_YU_WRITE_2(sc_if, YUKON_SMR, reg); 3598 3599 /* Setup Yukon's address */ 3600 for (i = 0; i < 3; i++) { 3601 /* Write Source Address 1 (unicast filter) */ 3602 SK_YU_WRITE_2(sc_if, YUKON_SAL1 + i * 4, 3603 IF_LLADDR(sc_if->sk_ifp)[i * 2] | 3604 IF_LLADDR(sc_if->sk_ifp)[i * 2 + 1] << 8); 3605 } 3606 3607 for (i = 0; i < 3; i++) { 3608 reg = sk_win_read_2(sc_if->sk_softc, 3609 SK_MAC1_0 + i * 2 + sc_if->sk_port * 8); 3610 SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg); 3611 } 3612 3613 /* Set promiscuous mode */ 3614 sk_setpromisc(sc_if); 3615 3616 /* Set multicast filter */ 3617 sk_setmulti(sc_if); 3618 3619 /* enable interrupt mask for counter overflows */ 3620 SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0); 3621 SK_YU_WRITE_2(sc_if, YUKON_RIMR, 0); 3622 SK_YU_WRITE_2(sc_if, YUKON_TRIMR, 0); 3623 3624 /* Configure RX MAC FIFO Flush Mask */ 3625 v = YU_RXSTAT_FOFL | YU_RXSTAT_CRCERR | YU_RXSTAT_MIIERR | 3626 YU_RXSTAT_BADFC | YU_RXSTAT_GOODFC | YU_RXSTAT_RUNT | 3627 YU_RXSTAT_JABBER; 3628 SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_MASK, v); 3629 3630 /* Disable RX MAC FIFO Flush for YUKON-Lite Rev. A0 only */ 3631 if (sc->sk_type == SK_YUKON_LITE && sc->sk_rev == SK_YUKON_LITE_REV_A0) 3632 v = SK_TFCTL_OPERATION_ON; 3633 else 3634 v = SK_TFCTL_OPERATION_ON | SK_RFCTL_FIFO_FLUSH_ON; 3635 /* Configure RX MAC FIFO */ 3636 SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_CLEAR); 3637 SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_CTRL_TEST, v); 3638 3639 /* Increase flush threshould to 64 bytes */ 3640 SK_IF_WRITE_2(sc_if, 0, SK_RXMF1_FLUSH_THRESHOLD, 3641 SK_RFCTL_FIFO_THRESHOLD + 1); 3642 3643 /* Configure TX MAC FIFO */ 3644 SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_CLEAR); 3645 SK_IF_WRITE_2(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_OPERATION_ON); 3646 } 3647 3648 /* 3649 * Note that to properly initialize any part of the GEnesis chip, 3650 * you first have to take it out of reset mode. 3651 */ 3652 static void 3653 sk_init(xsc) 3654 void *xsc; 3655 { 3656 struct sk_if_softc *sc_if = xsc; 3657 3658 SK_IF_LOCK(sc_if); 3659 sk_init_locked(sc_if); 3660 SK_IF_UNLOCK(sc_if); 3661 3662 return; 3663 } 3664 3665 static void 3666 sk_init_locked(sc_if) 3667 struct sk_if_softc *sc_if; 3668 { 3669 struct sk_softc *sc; 3670 struct ifnet *ifp; 3671 struct mii_data *mii; 3672 u_int16_t reg; 3673 u_int32_t imr; 3674 int error; 3675 3676 SK_IF_LOCK_ASSERT(sc_if); 3677 3678 ifp = sc_if->sk_ifp; 3679 sc = sc_if->sk_softc; 3680 mii = device_get_softc(sc_if->sk_miibus); 3681 3682 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 3683 return; 3684 3685 /* Cancel pending I/O and free all RX/TX buffers. */ 3686 sk_stop(sc_if); 3687 3688 if (sc->sk_type == SK_GENESIS) { 3689 /* Configure LINK_SYNC LED */ 3690 SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_ON); 3691 SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, 3692 SK_LINKLED_LINKSYNC_ON); 3693 3694 /* Configure RX LED */ 3695 SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, 3696 SK_RXLEDCTL_COUNTER_START); 3697 3698 /* Configure TX LED */ 3699 SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, 3700 SK_TXLEDCTL_COUNTER_START); 3701 } 3702 3703 /* 3704 * Configure descriptor poll timer 3705 * 3706 * SK-NET GENESIS data sheet says that possibility of losing Start 3707 * transmit command due to CPU/cache related interim storage problems 3708 * under certain conditions. The document recommends a polling 3709 * mechanism to send a Start transmit command to initiate transfer 3710 * of ready descriptors regulary. To cope with this issue sk(4) now 3711 * enables descriptor poll timer to initiate descriptor processing 3712 * periodically as defined by SK_DPT_TIMER_MAX. However sk(4) still 3713 * issue SK_TXBMU_TX_START to Tx BMU to get fast execution of Tx 3714 * command instead of waiting for next descriptor polling time. 3715 * The same rule may apply to Rx side too but it seems that is not 3716 * needed at the moment. 3717 * Since sk(4) uses descriptor polling as a last resort there is no 3718 * need to set smaller polling time than maximum allowable one. 3719 */ 3720 SK_IF_WRITE_4(sc_if, 0, SK_DPT_INIT, SK_DPT_TIMER_MAX); 3721 3722 /* Configure I2C registers */ 3723 3724 /* Configure XMAC(s) */ 3725 switch (sc->sk_type) { 3726 case SK_GENESIS: 3727 sk_init_xmac(sc_if); 3728 break; 3729 case SK_YUKON: 3730 case SK_YUKON_LITE: 3731 case SK_YUKON_LP: 3732 sk_init_yukon(sc_if); 3733 break; 3734 } 3735 mii_mediachg(mii); 3736 3737 if (sc->sk_type == SK_GENESIS) { 3738 /* Configure MAC FIFOs */ 3739 SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_UNRESET); 3740 SK_IF_WRITE_4(sc_if, 0, SK_RXF1_END, SK_FIFO_END); 3741 SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_ON); 3742 3743 SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_UNRESET); 3744 SK_IF_WRITE_4(sc_if, 0, SK_TXF1_END, SK_FIFO_END); 3745 SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_ON); 3746 } 3747 3748 /* Configure transmit arbiter(s) */ 3749 SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, 3750 SK_TXARCTL_ON|SK_TXARCTL_FSYNC_ON); 3751 3752 /* Configure RAMbuffers */ 3753 SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_UNRESET); 3754 SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_START, sc_if->sk_rx_ramstart); 3755 SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_WR_PTR, sc_if->sk_rx_ramstart); 3756 SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_RD_PTR, sc_if->sk_rx_ramstart); 3757 SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_END, sc_if->sk_rx_ramend); 3758 SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_ON); 3759 3760 SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_UNRESET); 3761 SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_STORENFWD_ON); 3762 SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_START, sc_if->sk_tx_ramstart); 3763 SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_WR_PTR, sc_if->sk_tx_ramstart); 3764 SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_RD_PTR, sc_if->sk_tx_ramstart); 3765 SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_END, sc_if->sk_tx_ramend); 3766 SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_ON); 3767 3768 /* Configure BMUs */ 3769 SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_ONLINE); 3770 if (ifp->if_mtu > SK_MAX_FRAMELEN) { 3771 SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_LO, 3772 SK_ADDR_LO(SK_JUMBO_RX_RING_ADDR(sc_if, 0))); 3773 SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_HI, 3774 SK_ADDR_HI(SK_JUMBO_RX_RING_ADDR(sc_if, 0))); 3775 } else { 3776 SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_LO, 3777 SK_ADDR_LO(SK_RX_RING_ADDR(sc_if, 0))); 3778 SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_CURADDR_HI, 3779 SK_ADDR_HI(SK_RX_RING_ADDR(sc_if, 0))); 3780 } 3781 3782 SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_ONLINE); 3783 SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_CURADDR_LO, 3784 SK_ADDR_LO(SK_TX_RING_ADDR(sc_if, 0))); 3785 SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_CURADDR_HI, 3786 SK_ADDR_HI(SK_TX_RING_ADDR(sc_if, 0))); 3787 3788 /* Init descriptors */ 3789 if (ifp->if_mtu > SK_MAX_FRAMELEN) 3790 error = sk_init_jumbo_rx_ring(sc_if); 3791 else 3792 error = sk_init_rx_ring(sc_if); 3793 if (error != 0) { 3794 device_printf(sc_if->sk_if_dev, 3795 "initialization failed: no memory for rx buffers\n"); 3796 sk_stop(sc_if); 3797 return; 3798 } 3799 sk_init_tx_ring(sc_if); 3800 3801 /* Set interrupt moderation if changed via sysctl. */ 3802 imr = sk_win_read_4(sc, SK_IMTIMERINIT); 3803 if (imr != SK_IM_USECS(sc->sk_int_mod, sc->sk_int_ticks)) { 3804 sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(sc->sk_int_mod, 3805 sc->sk_int_ticks)); 3806 if (bootverbose) 3807 device_printf(sc_if->sk_if_dev, 3808 "interrupt moderation is %d us.\n", 3809 sc->sk_int_mod); 3810 } 3811 3812 /* Configure interrupt handling */ 3813 CSR_READ_4(sc, SK_ISSR); 3814 if (sc_if->sk_port == SK_PORT_A) 3815 sc->sk_intrmask |= SK_INTRS1; 3816 else 3817 sc->sk_intrmask |= SK_INTRS2; 3818 3819 sc->sk_intrmask |= SK_ISR_EXTERNAL_REG; 3820 3821 CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); 3822 3823 /* Start BMUs. */ 3824 SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_START); 3825 3826 switch(sc->sk_type) { 3827 case SK_GENESIS: 3828 /* Enable XMACs TX and RX state machines */ 3829 SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_IGNPAUSE); 3830 SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB); 3831 break; 3832 case SK_YUKON: 3833 case SK_YUKON_LITE: 3834 case SK_YUKON_LP: 3835 reg = SK_YU_READ_2(sc_if, YUKON_GPCR); 3836 reg |= YU_GPCR_TXEN | YU_GPCR_RXEN; 3837 #if 0 3838 /* XXX disable 100Mbps and full duplex mode? */ 3839 reg &= ~(YU_GPCR_SPEED | YU_GPCR_DPLX_DIS); 3840 #endif 3841 SK_YU_WRITE_2(sc_if, YUKON_GPCR, reg); 3842 } 3843 3844 /* Activate descriptor polling timer */ 3845 SK_IF_WRITE_4(sc_if, 0, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_START); 3846 /* start transfer of Tx descriptors */ 3847 CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START); 3848 3849 ifp->if_drv_flags |= IFF_DRV_RUNNING; 3850 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 3851 3852 switch (sc->sk_type) { 3853 case SK_YUKON: 3854 case SK_YUKON_LITE: 3855 case SK_YUKON_LP: 3856 callout_reset(&sc_if->sk_tick_ch, hz, sk_yukon_tick, sc_if); 3857 break; 3858 } 3859 3860 callout_reset(&sc_if->sk_watchdog_ch, hz, sk_watchdog, ifp); 3861 3862 return; 3863 } 3864 3865 static void 3866 sk_stop(sc_if) 3867 struct sk_if_softc *sc_if; 3868 { 3869 int i; 3870 struct sk_softc *sc; 3871 struct sk_txdesc *txd; 3872 struct sk_rxdesc *rxd; 3873 struct sk_rxdesc *jrxd; 3874 struct ifnet *ifp; 3875 u_int32_t val; 3876 3877 SK_IF_LOCK_ASSERT(sc_if); 3878 sc = sc_if->sk_softc; 3879 ifp = sc_if->sk_ifp; 3880 3881 callout_stop(&sc_if->sk_tick_ch); 3882 callout_stop(&sc_if->sk_watchdog_ch); 3883 3884 /* stop Tx descriptor polling timer */ 3885 SK_IF_WRITE_4(sc_if, 0, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_STOP); 3886 /* stop transfer of Tx descriptors */ 3887 CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_STOP); 3888 for (i = 0; i < SK_TIMEOUT; i++) { 3889 val = CSR_READ_4(sc, sc_if->sk_tx_bmu); 3890 if ((val & SK_TXBMU_TX_STOP) == 0) 3891 break; 3892 DELAY(1); 3893 } 3894 if (i == SK_TIMEOUT) 3895 device_printf(sc_if->sk_if_dev, 3896 "can not stop transfer of Tx descriptor\n"); 3897 /* stop transfer of Rx descriptors */ 3898 SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_STOP); 3899 for (i = 0; i < SK_TIMEOUT; i++) { 3900 val = SK_IF_READ_4(sc_if, 0, SK_RXQ1_BMU_CSR); 3901 if ((val & SK_RXBMU_RX_STOP) == 0) 3902 break; 3903 DELAY(1); 3904 } 3905 if (i == SK_TIMEOUT) 3906 device_printf(sc_if->sk_if_dev, 3907 "can not stop transfer of Rx descriptor\n"); 3908 3909 if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) { 3910 /* Put PHY back into reset. */ 3911 val = sk_win_read_4(sc, SK_GPIO); 3912 if (sc_if->sk_port == SK_PORT_A) { 3913 val |= SK_GPIO_DIR0; 3914 val &= ~SK_GPIO_DAT0; 3915 } else { 3916 val |= SK_GPIO_DIR2; 3917 val &= ~SK_GPIO_DAT2; 3918 } 3919 sk_win_write_4(sc, SK_GPIO, val); 3920 } 3921 3922 /* Turn off various components of this interface. */ 3923 SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC); 3924 switch (sc->sk_type) { 3925 case SK_GENESIS: 3926 SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, SK_TXMACCTL_XMAC_RESET); 3927 SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET); 3928 break; 3929 case SK_YUKON: 3930 case SK_YUKON_LITE: 3931 case SK_YUKON_LP: 3932 SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET); 3933 SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET); 3934 break; 3935 } 3936 SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE); 3937 SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); 3938 SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_OFFLINE); 3939 SK_IF_WRITE_4(sc_if, 1, SK_TXRBS1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); 3940 SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF); 3941 SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP); 3942 SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP); 3943 SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF); 3944 SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF); 3945 3946 /* Disable interrupts */ 3947 if (sc_if->sk_port == SK_PORT_A) 3948 sc->sk_intrmask &= ~SK_INTRS1; 3949 else 3950 sc->sk_intrmask &= ~SK_INTRS2; 3951 CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); 3952 3953 SK_XM_READ_2(sc_if, XM_ISR); 3954 SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF); 3955 3956 /* Free RX and TX mbufs still in the queues. */ 3957 for (i = 0; i < SK_RX_RING_CNT; i++) { 3958 rxd = &sc_if->sk_cdata.sk_rxdesc[i]; 3959 if (rxd->rx_m != NULL) { 3960 bus_dmamap_sync(sc_if->sk_cdata.sk_rx_tag, 3961 rxd->rx_dmamap, BUS_DMASYNC_POSTREAD); 3962 bus_dmamap_unload(sc_if->sk_cdata.sk_rx_tag, 3963 rxd->rx_dmamap); 3964 m_freem(rxd->rx_m); 3965 rxd->rx_m = NULL; 3966 } 3967 } 3968 for (i = 0; i < SK_JUMBO_RX_RING_CNT; i++) { 3969 jrxd = &sc_if->sk_cdata.sk_jumbo_rxdesc[i]; 3970 if (jrxd->rx_m != NULL) { 3971 bus_dmamap_sync(sc_if->sk_cdata.sk_jumbo_rx_tag, 3972 jrxd->rx_dmamap, BUS_DMASYNC_POSTREAD); 3973 bus_dmamap_unload(sc_if->sk_cdata.sk_jumbo_rx_tag, 3974 jrxd->rx_dmamap); 3975 m_freem(jrxd->rx_m); 3976 jrxd->rx_m = NULL; 3977 } 3978 } 3979 for (i = 0; i < SK_TX_RING_CNT; i++) { 3980 txd = &sc_if->sk_cdata.sk_txdesc[i]; 3981 if (txd->tx_m != NULL) { 3982 bus_dmamap_sync(sc_if->sk_cdata.sk_tx_tag, 3983 txd->tx_dmamap, BUS_DMASYNC_POSTWRITE); 3984 bus_dmamap_unload(sc_if->sk_cdata.sk_tx_tag, 3985 txd->tx_dmamap); 3986 m_freem(txd->tx_m); 3987 txd->tx_m = NULL; 3988 } 3989 } 3990 3991 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING|IFF_DRV_OACTIVE); 3992 3993 return; 3994 } 3995 3996 static int 3997 sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high) 3998 { 3999 int error, value; 4000 4001 if (!arg1) 4002 return (EINVAL); 4003 value = *(int *)arg1; 4004 error = sysctl_handle_int(oidp, &value, 0, req); 4005 if (error || !req->newptr) 4006 return (error); 4007 if (value < low || value > high) 4008 return (EINVAL); 4009 *(int *)arg1 = value; 4010 return (0); 4011 } 4012 4013 static int 4014 sysctl_hw_sk_int_mod(SYSCTL_HANDLER_ARGS) 4015 { 4016 return (sysctl_int_range(oidp, arg1, arg2, req, SK_IM_MIN, SK_IM_MAX)); 4017 } -
src/add-ons/kernel/drivers/network/syskonnect/dev/sk/glue.c
1 /* 2 * Copyright 2007, Hugo Santos. All Rights Reserved. 3 * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8 #include <sys/bus.h> 9 #include <sys/rman.h> 10 #include "if_skreg.h" 11 12 #include "xmaciireg.h" 13 14 HAIKU_FBSD_DRIVER_GLUE(syskonnect, skc, pci) 15 16 extern driver_t *DRIVER_MODULE_NAME(e1000phy, miibus); 17 extern driver_t *DRIVER_MODULE_NAME(ukphy, miibus); 18 extern driver_t *DRIVER_MODULE_NAME(xmphy, miibus); 19 20 HAIKU_DRIVER_REQUIREMENTS(0); 21 22 driver_t * 23 __haiku_select_miibus_driver(device_t dev) 24 { 25 driver_t *drivers[] = { 26 DRIVER_MODULE_NAME(xmphy, miibus), 27 DRIVER_MODULE_NAME(e1000phy, miibus), 28 DRIVER_MODULE_NAME(ukphy, miibus), 29 NULL 30 }; 31 32 return __haiku_probe_miibus(dev, drivers); 33 } 34 35 36 int 37 __haiku_disable_interrupts(device_t dev) 38 { 39 struct sk_softc* sc = device_get_softc(dev); 40 u_int32_t status; 41 u_int32_t mask; 42 HAIKU_INTR_REGISTER_STATE; 43 44 mask = sc->sk_intrmask; 45 HAIKU_INTR_REGISTER_ENTER(); 46 47 status = CSR_READ_4(sc, SK_ISSR); 48 if (status == 0 || status == 0xffffffff || sc->sk_suspended) 49 { 50 HAIKU_INTR_REGISTER_LEAVE(); 51 return 0; 52 } 53 54 if (sc->sk_if[SK_PORT_A] != NULL) 55 { 56 mask &= ~SK_INTRS1; 57 } 58 59 if (sc->sk_if[SK_PORT_B] != NULL) 60 { 61 mask &= ~SK_INTRS2; 62 } 63 64 mask &= ~SK_ISR_EXTERNAL_REG; 65 CSR_WRITE_4(sc, SK_IMR, mask); 66 67 HAIKU_INTR_REGISTER_LEAVE(); 68 69 atomic_or((int32 *)&sc->sk_intstatus, status); 70 return status & sc->sk_intrmask; 71 } 72 73 void 74 __haiku_reenable_interrupts(device_t dev) 75 { 76 struct sk_softc *sc = device_get_softc(dev); 77 78 CSR_READ_4(sc, SK_ISSR); 79 CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask); 80 } 81 82 -
src/add-ons/kernel/drivers/network/syskonnect/dev/sk/xmaciireg.h
1 /*- 2 * Copyright (c) 1997, 1998, 1999, 2000 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bill Paul. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 * $FreeBSD: src/sys/dev/sk/xmaciireg.h,v 1.5 2006/04/27 05:59:09 yongari Exp $ 33 */ 34 35 /* 36 * Registers and data structures for the XaQti Corporation XMAC II 37 * Gigabit Ethernet MAC. Datasheet is available from http://www.xaqti.com. 38 * The XMAC can be programmed for 16-bit or 32-bit register access modes. 39 * The SysKonnect gigabit ethernet adapters use 16-bit mode, so that's 40 * how the registers are laid out here. 41 */ 42 43 #define XM_DEVICEID 0x00E0AE20 44 #define XM_XAQTI_OUI 0x00E0AE 45 46 #define XM_XMAC_REV(x) (((x) & 0x000000E0) >> 5) 47 48 #define XM_XMAC_REV_B2 0x0 49 #define XM_XMAC_REV_C1 0x1 50 51 #define XM_MMUCMD 0x0000 52 #define XM_POFF 0x0008 53 #define XM_BURST 0x000C 54 #define XM_VLAN_TAGLEV1 0x0010 55 #define XM_VLAN_TAGLEV2 0x0014 56 #define XM_TXCMD 0x0020 57 #define XM_TX_RETRYLIMIT 0x0024 58 #define XM_TX_SLOTTIME 0x0028 59 #define XM_TX_IPG 0x003C 60 #define XM_RXCMD 0x0030 61 #define XM_PHY_ADDR 0x0034 62 #define XM_PHY_DATA 0x0038 63 #define XM_GPIO 0x0040 64 #define XM_IMR 0x0044 65 #define XM_ISR 0x0048 66 #define XM_HWCFG 0x004C 67 #define XM_TX_LOWAT 0x0060 68 #define XM_TX_HIWAT 0x0062 69 #define XM_TX_REQTHRESH_LO 0x0064 70 #define XM_TX_REQTHRESH_HI 0x0066 71 #define XM_TX_REQTHRESH XM_TX_REQTHRESH_LO 72 #define XM_PAUSEDST0 0x0068 73 #define XM_PAUSEDST1 0x006A 74 #define XM_PAUSEDST2 0x006C 75 #define XM_CTLPARM_LO 0x0070 76 #define XM_CTLPARM_HI 0x0072 77 #define XM_CTLPARM XM_CTLPARM_LO 78 #define XM_OPCODE_PAUSE_TIMER 0x0074 79 #define XM_TXSTAT_LIFO 0x0078 80 81 /* 82 * Perfect filter registers. The XMAC has a table of 16 perfect 83 * filter entries, spaced 8 bytes apart. This is in addition to 84 * the station address registers, which appear below. 85 */ 86 #define XM_RXFILT_BASE 0x0080 87 #define XM_RXFILT_END 0x0107 88 #define XM_RXFILT_MAX 16 89 #define XM_RXFILT_ENTRY(ent) (XM_RXFILT_BASE + ((ent * 8))) 90 91 /* Primary station address. */ 92 #define XM_PAR0 0x0108 93 #define XM_PAR1 0x010A 94 #define XM_PAR2 0x010C 95 96 /* 64-bit multicast hash table registers */ 97 #define XM_MAR0 0x0110 98 #define XM_MAR1 0x0112 99 #define XM_MAR2 0x0114 100 #define XM_MAR3 0x0116 101 #define XM_RX_LOWAT 0x0118 102 #define XM_RX_HIWAT 0x011A 103 #define XM_RX_REQTHRESH_LO 0x011C 104 #define XM_RX_REQTHRESH_HI 0x011E 105 #define XM_RX_REQTHRESH XM_RX_REQTHRESH_LO 106 #define XM_DEVID_LO 0x0120 107 #define XM_DEVID_HI 0x0122 108 #define XM_DEVID XM_DEVID_LO 109 #define XM_MODE_LO 0x0124 110 #define XM_MODE_HI 0x0126 111 #define XM_MODE XM_MODE_LO 112 #define XM_LASTSRC0 0x0128 113 #define XM_LASTSRC1 0x012A 114 #define XM_LASTSRC2 0x012C 115 #define XM_TSTAMP_READ 0x0130 116 #define XM_TSTAMP_LOAD 0x0134 117 #define XM_STATS_CMD 0x0200 118 #define XM_RXCNT_EVENT_LO 0x0204 119 #define XM_RXCNT_EVENT_HI 0x0206 120 #define XM_RXCNT_EVENT XM_RXCNT_EVENT_LO 121 #define XM_TXCNT_EVENT_LO 0x0208 122 #define XM_TXCNT_EVENT_HI 0x020A 123 #define XM_TXCNT_EVENT XM_TXCNT_EVENT_LO 124 #define XM_RXCNT_EVMASK_LO 0x020C 125 #define XM_RXCNT_EVMASK_HI 0x020E 126 #define XM_RXCNT_EVMASK XM_RXCNT_EVMASK_LO 127 #define XM_TXCNT_EVMASK_LO 0x0210 128 #define XM_TXCNT_EVMASK_HI 0x0212 129 #define XM_TXCNT_EVMASK XM_TXCNT_EVMASK_LO 130 131 /* Statistics command register */ 132 #define XM_STATCMD_CLR_TX 0x0001 133 #define XM_STATCMD_CLR_RX 0x0002 134 #define XM_STATCMD_COPY_TX 0x0004 135 #define XM_STATCMD_COPY_RX 0x0008 136 #define XM_STATCMD_SNAP_TX 0x0010 137 #define XM_STATCMD_SNAP_RX 0x0020 138 139 /* TX statistics registers */ 140 #define XM_TXSTATS_PKTSOK 0x280 141 #define XM_TXSTATS_BYTESOK_HI 0x284 142 #define XM_TXSTATS_BYTESOK_LO 0x288 143 #define XM_TXSTATS_BCASTSOK 0x28C 144 #define XM_TXSTATS_MCASTSOK 0x290 145 #define XM_TXSTATS_UCASTSOK 0x294 146 #define XM_TXSTATS_GIANTS 0x298 147 #define XM_TXSTATS_BURSTCNT 0x29C 148 #define XM_TXSTATS_PAUSEPKTS 0x2A0 149 #define XM_TXSTATS_MACCTLPKTS 0x2A4 150 #define XM_TXSTATS_SINGLECOLS 0x2A8 151 #define XM_TXSTATS_MULTICOLS 0x2AC 152 #define XM_TXSTATS_EXCESSCOLS 0x2B0 153 #define XM_TXSTATS_LATECOLS 0x2B4 154 #define XM_TXSTATS_DEFER 0x2B8 155 #define XM_TXSTATS_EXCESSDEFER 0x2BC 156 #define XM_TXSTATS_UNDERRUN 0x2C0 157 #define XM_TXSTATS_CARRIERSENSE 0x2C4 158 #define XM_TXSTATS_UTILIZATION 0x2C8 159 #define XM_TXSTATS_64 0x2D0 160 #define XM_TXSTATS_65_127 0x2D4 161 #define XM_TXSTATS_128_255 0x2D8 162 #define XM_TXSTATS_256_511 0x2DC 163 #define XM_TXSTATS_512_1023 0x2E0 164 #define XM_TXSTATS_1024_MAX 0x2E4 165 166 /* RX statistics registers */ 167 #define XM_RXSTATS_PKTSOK 0x300 168 #define XM_RXSTATS_BYTESOK_HI 0x304 169 #define XM_RXSTATS_BYTESOK_LO 0x308 170 #define XM_RXSTATS_BCASTSOK 0x30C 171 #define XM_RXSTATS_MCASTSOK 0x310 172 #define XM_RXSTATS_UCASTSOK 0x314 173 #define XM_RXSTATS_PAUSEPKTS 0x318 174 #define XM_RXSTATS_MACCTLPKTS 0x31C 175 #define XM_RXSTATS_BADPAUSEPKTS 0x320 176 #define XM_RXSTATS_BADMACCTLPKTS 0x324 177 #define XM_RXSTATS_BURSTCNT 0x328 178 #define XM_RXSTATS_MISSEDPKTS 0x32C 179 #define XM_RXSTATS_FRAMEERRS 0x330 180 #define XM_RXSTATS_OVERRUN 0x334 181 #define XM_RXSTATS_JABBER 0x338 182 #define XM_RXSTATS_CARRLOSS 0x33C 183 #define XM_RXSTATS_INRNGLENERR 0x340 184 #define XM_RXSTATS_SYMERR 0x344 185 #define XM_RXSTATS_SHORTEVENT 0x348 186 #define XM_RXSTATS_RUNTS 0x34C 187 #define XM_RXSTATS_GIANTS 0x350 188 #define XM_RXSTATS_CRCERRS 0x354 189 #define XM_RXSTATS_CEXTERRS 0x35C 190 #define XM_RXSTATS_UTILIZATION 0x360 191 #define XM_RXSTATS_64 0x368 192 #define XM_RXSTATS_65_127 0x36C 193 #define XM_RXSTATS_128_255 0x370 194 #define XM_RXSTATS_256_511 0x374 195 #define XM_RXSTATS_512_1023 0x378 196 #define XM_RXSTATS_1024_MAX 0x37C 197 198 #define XM_MMUCMD_TX_ENB 0x0001 199 #define XM_MMUCMD_RX_ENB 0x0002 200 #define XM_MMUCMD_GMIILOOP 0x0004 201 #define XM_MMUCMD_RATECTL 0x0008 202 #define XM_MMUCMD_GMIIFDX 0x0010 203 #define XM_MMUCMD_NO_MGMT_PRMB 0x0020 204 #define XM_MMUCMD_SIMCOL 0x0040 205 #define XM_MMUCMD_FORCETX 0x0080 206 #define XM_MMUCMD_LOOPENB 0x0200 207 #define XM_MMUCMD_IGNPAUSE 0x0400 208 #define XM_MMUCMD_PHYBUSY 0x0800 209 #define XM_MMUCMD_PHYDATARDY 0x1000 210 211 #define XM_TXCMD_AUTOPAD 0x0001 212 #define XM_TXCMD_NOCRC 0x0002 213 #define XM_TXCMD_NOPREAMBLE 0x0004 214 #define XM_TXCMD_NOGIGAMODE 0x0008 215 #define XM_TXCMD_SAMPLELINE 0x0010 216 #define XM_TXCMD_ENCBYPASS 0x0020 217 #define XM_TXCMD_XMITBK2BK 0x0040 218 #define XM_TXCMD_FAIRSHARE 0x0080 219 220 #define XM_RXCMD_DISABLE_CEXT 0x0001 221 #define XM_RXCMD_STRIPPAD 0x0002 222 #define XM_RXCMD_SAMPLELINE 0x0004 223 #define XM_RXCMD_SELFRX 0x0008 224 #define XM_RXCMD_STRIPFCS 0x0010 225 #define XM_RXCMD_TRANSPARENT 0x0020 226 #define XM_RXCMD_IPGCAPTURE 0x0040 227 #define XM_RXCMD_BIGPKTOK 0x0080 228 #define XM_RXCMD_LENERROK 0x0100 229 230 #define XM_GPIO_GP0_SET 0x0001 231 #define XM_GPIO_RESETSTATS 0x0004 232 #define XM_GPIO_RESETMAC 0x0008 233 #define XM_GPIO_FORCEINT 0x0020 234 #define XM_GPIO_ANEGINPROG 0x0040 235 236 #define XM_IMR_RX_EOF 0x0001 237 #define XM_IMR_TX_EOF 0x0002 238 #define XM_IMR_TX_UNDERRUN 0x0004 239 #define XM_IMR_RX_OVERRUN 0x0008 240 #define XM_IMR_TX_STATS_OFLOW 0x0010 241 #define XM_IMR_RX_STATS_OFLOW 0x0020 242 #define XM_IMR_TSTAMP_OFLOW 0x0040 243 #define XM_IMR_AUTONEG_DONE 0x0080 244 #define XM_IMR_NEXTPAGE_RDY 0x0100 245 #define XM_IMR_PAGE_RECEIVED 0x0200 246 #define XM_IMR_LP_REQCFG 0x0400 247 #define XM_IMR_GP0_SET 0x0800 248 #define XM_IMR_FORCEINTR 0x1000 249 #define XM_IMR_TX_ABORT 0x2000 250 #define XM_IMR_LINKEVENT 0x4000 251 252 #define XM_INTRS \ 253 (~(XM_IMR_GP0_SET|XM_IMR_AUTONEG_DONE|XM_IMR_TX_UNDERRUN)) 254 255 #define XM_ISR_RX_EOF 0x0001 256 #define XM_ISR_TX_EOF 0x0002 257 #define XM_ISR_TX_UNDERRUN 0x0004 258 #define XM_ISR_RX_OVERRUN 0x0008 259 #define XM_ISR_TX_STATS_OFLOW 0x0010 260 #define XM_ISR_RX_STATS_OFLOW 0x0020 261 #define XM_ISR_TSTAMP_OFLOW 0x0040 262 #define XM_ISR_AUTONEG_DONE 0x0080 263 #define XM_ISR_NEXTPAGE_RDY 0x0100 264 #define XM_ISR_PAGE_RECEIVED 0x0200 265 #define XM_ISR_LP_REQCFG 0x0400 266 #define XM_ISR_GP0_SET 0x0800 267 #define XM_ISR_FORCEINTR 0x1000 268 #define XM_ISR_TX_ABORT 0x2000 269 #define XM_ISR_LINKEVENT 0x4000 270 271 #define XM_HWCFG_GENEOP 0x0008 272 #define XM_HWCFG_SIGSTATCKH 0x0004 273 #define XM_HWCFG_GMIIMODE 0x0001 274 275 #define XM_MODE_FLUSH_RXFIFO 0x00000001 276 #define XM_MODE_FLUSH_TXFIFO 0x00000002 277 #define XM_MODE_BIGENDIAN 0x00000004 278 #define XM_MODE_RX_PROMISC 0x00000008 279 #define XM_MODE_RX_NOBROAD 0x00000010 280 #define XM_MODE_RX_NOMULTI 0x00000020 281 #define XM_MODE_RX_NOUNI 0x00000040 282 #define XM_MODE_RX_BADFRAMES 0x00000080 283 #define XM_MODE_RX_CRCERRS 0x00000100 284 #define XM_MODE_RX_GIANTS 0x00000200 285 #define XM_MODE_RX_INRANGELEN 0x00000400 286 #define XM_MODE_RX_RUNTS 0x00000800 287 #define XM_MODE_RX_MACCTL 0x00001000 288 #define XM_MODE_RX_USE_PERFECT 0x00002000 289 #define XM_MODE_RX_USE_STATION 0x00004000 290 #define XM_MODE_RX_USE_HASH 0x00008000 291 #define XM_MODE_RX_ADDRPAIR 0x00010000 292 #define XM_MODE_PAUSEONHI 0x00020000 293 #define XM_MODE_PAUSEONLO 0x00040000 294 #define XM_MODE_TIMESTAMP 0x00080000 295 #define XM_MODE_SENDPAUSE 0x00100000 296 #define XM_MODE_SENDCONTINUOUS 0x00200000 297 #define XM_MODE_LE_STATUSWORD 0x00400000 298 #define XM_MODE_AUTOFIFOPAUSE 0x00800000 299 #define XM_MODE_EXPAUSEGEN 0x02000000 300 #define XM_MODE_RX_INVERSE 0x04000000 301 302 #define XM_RXSTAT_MACCTL 0x00000001 303 #define XM_RXSTAT_ERRFRAME 0x00000002 304 #define XM_RXSTAT_CRCERR 0x00000004 305 #define XM_RXSTAT_GIANT 0x00000008 306 #define XM_RXSTAT_RUNT 0x00000010 307 #define XM_RXSTAT_FRAMEERR 0x00000020 308 #define XM_RXSTAT_INRANGEERR 0x00000040 309 #define XM_RXSTAT_CARRIERERR 0x00000080 310 #define XM_RXSTAT_COLLERR 0x00000100 311 #define XM_RXSTAT_802_3 0x00000200 312 #define XM_RXSTAT_CARREXTERR 0x00000400 313 #define XM_RXSTAT_BURSTMODE 0x00000800 314 #define XM_RXSTAT_UNICAST 0x00002000 315 #define XM_RXSTAT_MULTICAST 0x00004000 316 #define XM_RXSTAT_BROADCAST 0x00008000 317 #define XM_RXSTAT_VLAN_LEV1 0x00010000 318 #define XM_RXSTAT_VLAN_LEV2 0x00020000 319 #define XM_RXSTAT_LEN 0xFFFC0000 320 #define XM_RXSTAT_LENSHIFT 18 321 322 #define XM_RXSTAT_BYTES(x) ((x) >> XM_RXSTAT_LENSHIFT) 323 324 /* 325 * XMAC PHY registers, indirectly accessed through 326 * XM_PHY_ADDR and XM_PHY_REG. 327 */ 328 329 #define XM_PHY_BMCR 0x0000 /* control */ 330 #define XM_PHY_BMSR 0x0001 /* status */ 331 #define XM_PHY_VENID 0x0002 /* vendor id */ 332 #define XM_PHY_DEVID 0x0003 /* device id */ 333 #define XM_PHY_ANAR 0x0004 /* autoneg advertisenemt */ 334 #define XM_PHY_LPAR 0x0005 /* link partner ability */ 335 #define XM_PHY_ANEXP 0x0006 /* autoneg expansion */ 336 #define XM_PHY_NEXTP 0x0007 /* nextpage */ 337 #define XM_PHY_LPNEXTP 0x0008 /* link partner's nextpage */ 338 #define XM_PHY_EXTSTS 0x000F /* extented status */ 339 #define XM_PHY_RESAB 0x0010 /* resolved ability */ 340 341 #define XM_BMCR_DUPLEX 0x0100 342 #define XM_BMCR_RENEGOTIATE 0x0200 343 #define XM_BMCR_AUTONEGENBL 0x1000 344 #define XM_BMCR_LOOPBACK 0x4000 345 #define XM_BMCR_RESET 0x8000 346 347 #define XM_BMSR_EXTCAP 0x0001 348 #define XM_BMSR_LINKSTAT 0x0004 349 #define XM_BMSR_AUTONEGABLE 0x0008 350 #define XM_BMSR_REMFAULT 0x0010 351 #define XM_BMSR_AUTONEGDONE 0x0020 352 #define XM_BMSR_EXTSTAT 0x0100 353 354 #define XM_VENID_XAQTI 0xD14C 355 #define XM_DEVID_XMAC 0x0002 356 357 #define XM_ANAR_FULLDUPLEX 0x0020 358 #define XM_ANAR_HALFDUPLEX 0x0040 359 #define XM_ANAR_PAUSEBITS 0x0180 360 #define XM_ANAR_REMFAULTBITS 0x1800 361 #define XM_ANAR_ACK 0x4000 362 #define XM_ANAR_NEXTPAGE 0x8000 363 364 #define XM_LPAR_FULLDUPLEX 0x0020 365 #define XM_LPAR_HALFDUPLEX 0x0040 366 #define XM_LPAR_PAUSEBITS 0x0180 367 #define XM_LPAR_REMFAULTBITS 0x1800 368 #define XM_LPAR_ACK 0x4000 369 #define XM_LPAR_NEXTPAGE 0x8000 370 371 #define XM_PAUSE_NOPAUSE 0x0000 372 #define XM_PAUSE_SYMPAUSE 0x0080 373 #define XM_PAUSE_ASYMPAUSE 0x0100 374 #define XM_PAUSE_BOTH 0x0180 375 376 #define XM_REMFAULT_LINKOK 0x0000 377 #define XM_REMFAULT_LINKFAIL 0x0800 378 #define XM_REMFAULT_OFFLINE 0x1000 379 #define XM_REMFAULT_ANEGERR 0x1800 380 381 #define XM_ANEXP_GOTPAGE 0x0002 382 #define XM_ANEXP_NEXTPAGE_SELF 0x0004 383 #define XM_ANEXP_NEXTPAGE_LP 0x0008 384 385 #define XM_NEXTP_MESSAGE 0x07FF 386 #define XM_NEXTP_TOGGLE 0x0800 387 #define XM_NEXTP_ACK2 0x1000 388 #define XM_NEXTP_MPAGE 0x2000 389 #define XM_NEXTP_ACK1 0x4000 390 #define XM_NEXTP_NPAGE 0x8000 391 392 #define XM_LPNEXTP_MESSAGE 0x07FF 393 #define XM_LPNEXTP_TOGGLE 0x0800 394 #define XM_LPNEXTP_ACK2 0x1000 395 #define XM_LPNEXTP_MPAGE 0x2000 396 #define XM_LPNEXTP_ACK1 0x4000 397 #define XM_LPNEXTP_NPAGE 0x8000 398 399 #define XM_EXTSTS_HALFDUPLEX 0x4000 400 #define XM_EXTSTS_FULLDUPLEX 0x8000 401 402 #define XM_RESAB_PAUSEMISMATCH 0x0008 403 #define XM_RESAB_ABLMISMATCH 0x0010 404 #define XM_RESAB_FDMODESEL 0x0020 405 #define XM_RESAB_HDMODESEL 0x0040 406 #define XM_RESAB_PAUSEBITS 0x0180 -
src/add-ons/kernel/drivers/network/syskonnect/dev/mii/brgphyreg.h
1 /*- 2 * Copyright (c) 2000 3 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bill Paul. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 * $FreeBSD: src/sys/dev/mii/brgphyreg.h,v 1.6.2.2 2007/06/14 21:07:19 davidch Exp $ 33 */ 34 35 #ifndef _DEV_MII_BRGPHYREG_H_ 36 #define _DEV_MII_BRGPHYREG_H_ 37 38 /* 39 * Broadcom BCM5400 registers 40 */ 41 42 #define BRGPHY_MII_BMCR 0x00 43 #define BRGPHY_BMCR_RESET 0x8000 44 #define BRGPHY_BMCR_LOOP 0x4000 45 #define BRGPHY_BMCR_SPD0 0x2000 /* Speed select, lower bit */ 46 #define BRGPHY_BMCR_AUTOEN 0x1000 /* Autoneg enabled */ 47 #define BRGPHY_BMCR_PDOWN 0x0800 /* Power down */ 48 #define BRGPHY_BMCR_ISO 0x0400 /* Isolate */ 49 #define BRGPHY_BMCR_STARTNEG 0x0200 /* Restart autoneg */ 50 #define BRGPHY_BMCR_FDX 0x0100 /* Duplex mode */ 51 #define BRGPHY_BMCR_CTEST 0x0080 /* Collision test enable */ 52 #define BRGPHY_BMCR_SPD1 0x0040 /* Speed select, upper bit */ 53 54 #define BRGPHY_S1000 BRGPHY_BMCR_SPD1 /* 1000mbps */ 55 #define BRGPHY_S100 BRGPHY_BMCR_SPD0 /* 100mpbs */ 56 #define BRGPHY_S10 0 /* 10mbps */ 57 58 #define BRGPHY_MII_BMSR 0x01 59 #define BRGPHY_BMSR_EXTSTS 0x0100 /* Extended status present */ 60 #define BRGPHY_BMSR_PRESUB 0x0040 /* Preamble surpression */ 61 #define BRGPHY_BMSR_ACOMP 0x0020 /* Autoneg complete */ 62 #define BRGPHY_BMSR_RFAULT 0x0010 /* Remote fault condition occured */ 63 #define BRGPHY_BMSR_ANEG 0x0008 /* Autoneg capable */ 64 #define BRGPHY_BMSR_LINK 0x0004 /* Link status */ 65 #define BRGPHY_BMSR_JABBER 0x0002 /* Jabber detected */ 66 #define BRGPHY_BMSR_EXT 0x0001 /* Extended capability */ 67 68 #define BRGPHY_MII_ANAR 0x04 69 #define BRGPHY_ANAR_NP 0x8000 /* Next page */ 70 #define BRGPHY_ANAR_RF 0x2000 /* Remote fault */ 71 #define BRGPHY_ANAR_ASP 0x0800 /* Asymmetric Pause */ 72 #define BRGPHY_ANAR_PC 0x0400 /* Pause capable */ 73 #define BRGPHY_ANAR_SEL 0x001F /* Selector field, 00001=Ethernet */ 74 75 #define BRGPHY_MII_ANLPAR 0x05 76 #define BRGPHY_ANLPAR_NP 0x8000 /* Next page */ 77 #define BRGPHY_ANLPAR_RF 0x2000 /* Remote fault */ 78 #define BRGPHY_ANLPAR_ASP 0x0800 /* Asymmetric Pause */ 79 #define BRGPHY_ANLPAR_PC 0x0400 /* Pause capable */ 80 #define BRGPHY_ANLPAR_SEL 0x001F /* Selector field, 00001=Ethernet */ 81 82 #define BRGPHY_SEL_TYPE 0x0001 /* Ethernet */ 83 84 #define BRGPHY_MII_ANER 0x06 85 #define BRGPHY_ANER_PDF 0x0010 /* Parallel detection fault */ 86 #define BRGPHY_ANER_LPNP 0x0008 /* Link partner can next page */ 87 #define BRGPHY_ANER_NP 0x0004 /* Local PHY can next page */ 88 #define BRGPHY_ANER_RX 0x0002 /* Next page received */ 89 #define BRGPHY_ANER_LPAN 0x0001 /* Link partner autoneg capable */ 90 91 #define BRGPHY_MII_NEXTP 0x07 /* Next page */ 92 93 #define BRGPHY_MII_NEXTP_LP 0x08 /* Next page of link partner */ 94 95 #define BRGPHY_MII_1000CTL 0x09 /* 1000baseT control */ 96 #define BRGPHY_1000CTL_TST 0xE000 /* Test modes */ 97 #define BRGPHY_1000CTL_MSE 0x1000 /* Master/Slave enable */ 98 #define BRGPHY_1000CTL_MSC 0x0800 /* Master/Slave configuration */ 99 #define BRGPHY_1000CTL_RD 0x0400 /* Repeater/DTE */ 100 #define BRGPHY_1000CTL_AFD 0x0200 /* Advertise full duplex */ 101 #define BRGPHY_1000CTL_AHD 0x0100 /* Advertise half duplex */ 102 103 #define BRGPHY_MII_1000STS 0x0A /* 1000baseT status */ 104 #define BRGPHY_1000STS_MSF 0x8000 /* Master/slave fault */ 105 #define BRGPHY_1000STS_MSR 0x4000 /* Master/slave result */ 106 #define BRGPHY_1000STS_LRS 0x2000 /* Local receiver status */ 107 #define BRGPHY_1000STS_RRS 0x1000 /* Remote receiver status */ 108 #define BRGPHY_1000STS_LPFD 0x0800 /* Link partner can FD */ 109 #define BRGPHY_1000STS_LPHD 0x0400 /* Link partner can HD */ 110 #define BRGPHY_1000STS_IEC 0x00FF /* Idle error count */ 111 112 #define BRGPHY_MII_EXTSTS 0x0F /* Extended status */ 113 #define BRGPHY_EXTSTS_X_FD_CAP 0x8000 /* 1000base-X FD capable */ 114 #define BRGPHY_EXTSTS_X_HD_CAP 0x4000 /* 1000base-X HD capable */ 115 #define BRGPHY_EXTSTS_T_FD_CAP 0x2000 /* 1000base-T FD capable */ 116 #define BRGPHY_EXTSTS_T_HD_CAP 0x1000 /* 1000base-T HD capable */ 117 118 #define BRGPHY_MII_PHY_EXTCTL 0x10 /* PHY extended control */ 119 #define BRGPHY_PHY_EXTCTL_MAC_PHY 0x8000 /* 10BIT/GMI-interface */ 120 #define BRGPHY_PHY_EXTCTL_DIS_CROSS 0x4000 /* Disable MDI crossover */ 121 #define BRGPHY_PHY_EXTCTL_TX_DIS 0x2000 /* TX output disabled */ 122 #define BRGPHY_PHY_EXTCTL_INT_DIS 0x1000 /* Interrupts disabled */ 123 #define BRGPHY_PHY_EXTCTL_F_INT 0x0800 /* Force interrupt */ 124 #define BRGPHY_PHY_EXTCTL_BY_45 0x0400 /* Bypass 4B5B-Decoder */ 125 #define BRGPHY_PHY_EXTCTL_BY_SCR 0x0200 /* Bypass scrambler */ 126 #define BRGPHY_PHY_EXTCTL_BY_MLT3 0x0100 /* Bypass MLT3 encoder */ 127 #define BRGPHY_PHY_EXTCTL_BY_RXA 0x0080 /* Bypass RX alignment */ 128 #define BRGPHY_PHY_EXTCTL_RES_SCR 0x0040 /* Reset scrambler */ 129 #define BRGPHY_PHY_EXTCTL_EN_LTR 0x0020 /* Enable LED traffic mode */ 130 #define BRGPHY_PHY_EXTCTL_LED_ON 0x0010 /* Force LEDs on */ 131 #define BRGPHY_PHY_EXTCTL_LED_OFF 0x0008 /* Force LEDs off */ 132 #define BRGPHY_PHY_EXTCTL_EX_IPG 0x0004 /* Extended TX IPG mode */ 133 #define BRGPHY_PHY_EXTCTL_3_LED 0x0002 /* Three link LED mode */ 134 #define BRGPHY_PHY_EXTCTL_HIGH_LA 0x0001 /* GMII Fifo Elasticy (?) */ 135 136 #define BRGPHY_MII_PHY_EXTSTS 0x11 /* PHY extended status */ 137 #define BRGPHY_PHY_EXTSTS_CROSS_STAT 0x2000 /* MDI crossover status */ 138 #define BRGPHY_PHY_EXTSTS_INT_STAT 0x1000 /* Interrupt status */ 139 #define BRGPHY_PHY_EXTSTS_RRS 0x0800 /* Remote receiver status */ 140 #define BRGPHY_PHY_EXTSTS_LRS 0x0400 /* Local receiver status */ 141 #define BRGPHY_PHY_EXTSTS_LOCKED 0x0200 /* Locked */ 142 #define BRGPHY_PHY_EXTSTS_LS 0x0100 /* Link status */ 143 #define BRGPHY_PHY_EXTSTS_RF 0x0080 /* Remove fault */ 144 #define BRGPHY_PHY_EXTSTS_CE_ER 0x0040 /* Carrier ext error */ 145 #define BRGPHY_PHY_EXTSTS_BAD_SSD 0x0020 /* Bad SSD */ 146 #define BRGPHY_PHY_EXTSTS_BAD_ESD 0x0010 /* Bad ESS */ 147 #define BRGPHY_PHY_EXTSTS_RX_ER 0x0008 /* RX error */ 148 #define BRGPHY_PHY_EXTSTS_TX_ER 0x0004 /* TX error */ 149 #define BRGPHY_PHY_EXTSTS_LOCK_ER 0x0002 /* Lock error */ 150 #define BRGPHY_PHY_EXTSTS_MLT3_ER 0x0001 /* MLT3 code error */ 151 152 #define BRGPHY_MII_RXERRCNT 0x12 /* RX error counter */ 153 154 #define BRGPHY_MII_FCERRCNT 0x13 /* False carrier sense counter */ 155 #define BGRPHY_FCERRCNT 0x00FF /* False carrier counter */ 156 157 #define BRGPHY_MII_RXNOCNT 0x14 /* RX not OK counter */ 158 #define BRGPHY_RXNOCNT_LOCAL 0xFF00 /* Local RX not OK counter */ 159 #define BRGPHY_RXNOCNT_REMOTE 0x00FF /* Local RX not OK counter */ 160 161 #define BRGPHY_MII_DSP_RW_PORT 0x15 /* DSP coefficient r/w port */ 162 163 #define BRGPHY_MII_DSP_ADDR_REG 0x17 /* DSP coefficient addr register */ 164 165 #define BRGPHY_DSP_TAP_NUMBER_MASK 0x00 166 #define BRGPHY_DSP_AGC_A 0x00 167 #define BRGPHY_DSP_AGC_B 0x01 168 #define BRGPHY_DSP_MSE_PAIR_STATUS 0x02 169 #define BRGPHY_DSP_SOFT_DECISION 0x03 170 #define BRGPHY_DSP_PHASE_REG 0x04 171 #define BRGPHY_DSP_SKEW 0x05 172 #define BRGPHY_DSP_POWER_SAVER_UPPER_BOUND 0x06 173 #define BRGPHY_DSP_POWER_SAVER_LOWER_BOUND 0x07 174 #define BRGPHY_DSP_LAST_ECHO 0x08 175 #define BRGPHY_DSP_FREQUENCY 0x09 176 #define BRGPHY_DSP_PLL_BANDWIDTH 0x0A 177 #define BRGPHY_DSP_PLL_PHASE_OFFSET 0x0B 178 179 #define BRGPHYDSP_FILTER_DCOFFSET 0x0C00 180 #define BRGPHY_DSP_FILTER_FEXT3 0x0B00 181 #define BRGPHY_DSP_FILTER_FEXT2 0x0A00 182 #define BRGPHY_DSP_FILTER_FEXT1 0x0900 183 #define BRGPHY_DSP_FILTER_FEXT0 0x0800 184 #define BRGPHY_DSP_FILTER_NEXT3 0x0700 185 #define BRGPHY_DSP_FILTER_NEXT2 0x0600 186 #define BRGPHY_DSP_FILTER_NEXT1 0x0500 187 #define BRGPHY_DSP_FILTER_NEXT0 0x0400 188 #define BRGPHY_DSP_FILTER_ECHO 0x0300 189 #define BRGPHY_DSP_FILTER_DFE 0x0200 190 #define BRGPHY_DSP_FILTER_FFE 0x0100 191 192 #define BRGPHY_DSP_CONTROL_ALL_FILTERS 0x1000 193 194 #define BRGPHY_DSP_SEL_CH_0 0x0000 195 #define BRGPHY_DSP_SEL_CH_1 0x2000 196 #define BRGPHY_DSP_SEL_CH_2 0x4000 197 #define BRGPHY_DSP_SEL_CH_3 0x6000 198 199 #define BRGPHY_MII_AUXCTL 0x18 /* AUX control */ 200 #define BRGPHY_AUXCTL_LOW_SQ 0x8000 /* Low squelch */ 201 #define BRGPHY_AUXCTL_LONG_PKT 0x4000 /* RX long packets */ 202 #define BRGPHY_AUXCTL_ER_CTL 0x3000 /* Edgerate control */ 203 #define BRGPHY_AUXCTL_TX_TST 0x0400 /* TX test, always 1 */ 204 #define BRGPHY_AUXCTL_DIS_PRF 0x0080 /* dis part resp filter */ 205 #define BRGPHY_AUXCTL_DIAG_MODE 0x0004 /* Diagnostic mode */ 206 207 #define BRGPHY_MII_AUXSTS 0x19 /* AUX status */ 208 #define BRGPHY_AUXSTS_ACOMP 0x8000 /* Autoneg complete */ 209 #define BRGPHY_AUXSTS_AN_ACK 0x4000 /* Autoneg complete ack */ 210 #define BRGPHY_AUXSTS_AN_ACK_D 0x2000 /* Autoneg complete ack detect */ 211 #define BRGPHY_AUXSTS_AN_NPW 0x1000 /* Autoneg next page wait */ 212 #define BRGPHY_AUXSTS_AN_RES 0x0700 /* Autoneg HCD */ 213 #define BRGPHY_AUXSTS_PDF 0x0080 /* Parallel detect. fault */ 214 #define BRGPHY_AUXSTS_RF 0x0040 /* Remote fault */ 215 #define BRGPHY_AUXSTS_ANP_R 0x0020 /* Autoneg page received */ 216 #define BRGPHY_AUXSTS_LP_ANAB 0x0010 /* Link partner autoneg ability */ 217 #define BRGPHY_AUXSTS_LP_NPAB 0x0008 /* Link partner next page ability */ 218 #define BRGPHY_AUXSTS_LINK 0x0004 /* Link status */ 219 #define BRGPHY_AUXSTS_PRR 0x0002 /* Pause resolution-RX */ 220 #define BRGPHY_AUXSTS_PRT 0x0001 /* Pause resolution-TX */ 221 222 #define BRGPHY_RES_1000FD 0x0700 /* 1000baseT full duplex */ 223 #define BRGPHY_RES_1000HD 0x0600 /* 1000baseT half duplex */ 224 #define BRGPHY_RES_100FD 0x0500 /* 100baseT full duplex */ 225 #define BRGPHY_RES_100T4 0x0400 /* 100baseT4 */ 226 #define BRGPHY_RES_100HD 0x0300 /* 100baseT half duplex */ 227 #define BRGPHY_RES_10FD 0x0200 /* 10baseT full duplex */ 228 #define BRGPHY_RES_10HD 0x0100 /* 10baseT half duplex */ 229 230 #define BRGPHY_MII_ISR 0x1A /* Interrupt status */ 231 #define BRGPHY_ISR_PSERR 0x4000 /* Pair swap error */ 232 #define BRGPHY_ISR_MDXI_SC 0x2000 /* MDIX Status Change */ 233 #define BRGPHY_ISR_HCT 0x1000 /* Counter above 32K */ 234 #define BRGPHY_ISR_LCT 0x0800 /* All counter below 128 */ 235 #define BRGPHY_ISR_AN_PR 0x0400 /* Autoneg page received */ 236 #define BRGPHY_ISR_NO_HDCL 0x0200 /* No HCD Link */ 237 #define BRGPHY_ISR_NO_HDC 0x0100 /* No HCD */ 238 #define BRGPHY_ISR_USHDC 0x0080 /* Negotiated Unsupported HCD */ 239 #define BRGPHY_ISR_SCR_S_ERR 0x0040 /* Scrambler sync error */ 240 #define BRGPHY_ISR_RRS_CHG 0x0020 /* Remote RX status change */ 241 #define BRGPHY_ISR_LRS_CHG 0x0010 /* Local RX status change */ 242 #define BRGPHY_ISR_DUP_CHG 0x0008 /* Duplex mode change */ 243 #define BRGPHY_ISR_LSP_CHG 0x0004 /* Link speed changed */ 244 #define BRGPHY_ISR_LNK_CHG 0x0002 /* Link status change */ 245 #define BRGPHY_ISR_CRCERR 0x0001 /* CRC error */ 246 247 #define BRGPHY_MII_IMR 0x1B /* Interrupt mask */ 248 #define BRGPHY_IMR_PSERR 0x4000 /* Pair swap error */ 249 #define BRGPHY_IMR_MDXI_SC 0x2000 /* MDIX Status Change */ 250 #define BRGPHY_IMR_HCT 0x1000 /* Counter above 32K */ 251 #define BRGPHY_IMR_LCT 0x0800 /* All counter below 128 */ 252 #define BRGPHY_IMR_AN_PR 0x0400 /* Autoneg page received */ 253 #define BRGPHY_IMR_NO_HDCL 0x0200 /* No HCD Link */ 254 #define BRGPHY_IMR_NO_HDC 0x0100 /* No HCD */ 255 #define BRGPHY_IMR_USHDC 0x0080 /* Negotiated Unsupported HCD */ 256 #define BRGPHY_IMR_SCR_S_ERR 0x0040 /* Scrambler sync error */ 257 #define BRGPHY_IMR_RRS_CHG 0x0020 /* Remote RX status change */ 258 #define BRGPHY_IMR_LRS_CHG 0x0010 /* Local RX status change */ 259 #define BRGPHY_IMR_DUP_CHG 0x0008 /* Duplex mode change */ 260 #define BRGPHY_IMR_LSP_CHG 0x0004 /* Link speed changed */ 261 #define BRGPHY_IMR_LNK_CHG 0x0002 /* Link status change */ 262 #define BRGPHY_IMR_CRCERR 0x0001 /* CRC error */ 263 264 /*******************************************************/ 265 /* Begin: Shared SerDes PHY register definitions */ 266 /*******************************************************/ 267 268 /* SerDes autoneg is different from copper */ 269 #define BRGPHY_SERDES_ANAR 0x04 270 #define BRGPHY_SERDES_ANAR_FDX 0x0020 271 #define BRGPHY_SERDES_ANAR_HDX 0x0040 272 #define BRGPHY_SERDES_ANAR_NO_PAUSE (0x0 << 7) 273 #define BRGPHY_SERDES_ANAR_SYM_PAUSE (0x1 << 7) 274 #define BRGPHY_SERDES_ANAR_ASYM_PAUSE (0x2 << 7) 275 #define BRGPHY_SERDES_ANAR_BOTH_PAUSE (0x3 << 7) 276 277 #define BRGPHY_SERDES_ANLPAR 0x05 278 #define BRGPHY_SERDES_ANLPAR_FDX 0x0020 279 #define BRGPHY_SERDES_ANLPAR_HDX 0x0040 280 #define BRGPHY_SERDES_ANLPAR_NO_PAUSE (0x0 << 7) 281 #define BRGPHY_SERDES_ANLPAR_SYM_PAUSE (0x1 << 7) 282 #define BRGPHY_SERDES_ANLPAR_ASYM_PAUSE (0x2 << 7) 283 #define BRGPHY_SERDES_ANLPAR_BOTH_PAUSE (0x3 << 7) 284 285 /*******************************************************/ 286 /* End: Shared SerDes PHY register definitions */ 287 /*******************************************************/ 288 289 /*******************************************************/ 290 /* Begin: PHY register values for the 5706 PHY */ 291 /*******************************************************/ 292 293 /* 294 * Shadow register 0x1C, bit 15 is write enable, 295 * bits 14-10 select function (0x00 to 0x1F). 296 */ 297 #define BRGPHY_MII_SHADOW_1C 0x1C 298 #define BRGPHY_SHADOW_1C_WRITE_EN 0x8000 299 #define BRGPHY_SHADOW_1C_SELECT_MASK 0x7C00 300 301 /* Shadow 0x1C Mode Control Register (select value 0x1F) */ 302 #define BRGPHY_SHADOW_1C_MODE_CTRL (0x1F << 10) 303 /* When set, Regs 0-0x0F are 1000X, else 1000T */ 304 #define BRGPHY_SHADOW_1C_ENA_1000X 0x0001 305 306 #define BRGPHY_MII_TEST1 0x1E 307 #define BRGPHY_TEST1_TRIM_EN 0x0010 308 #define BRGPHY_TEST1_CRC_EN 0x8000 309 310 #define BRGPHY_MII_TEST2 0x1F 311 312 /*******************************************************/ 313 /* End: PHY register values for the 5706 PHY */ 314 /*******************************************************/ 315 316 /*******************************************************/ 317 /* Begin: PHY register values for the 5708S SerDes PHY */ 318 /*******************************************************/ 319 320 /* Autoneg Next Page Transmit 1 Regiser */ 321 #define BRGPHY_5708S_ANEG_NXT_PG_XMIT1 0x0B 322 #define BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G 0x0001 323 324 /* Use the BLOCK_ADDR register to select the page for registers 0x10 to 0x1E */ 325 #define BRGPHY_5708S_BLOCK_ADDR 0x1f 326 #define BRGPHY_5708S_DIG_PG0 0x0000 327 #define BRGPHY_5708S_DIG3_PG2 0x0002 328 #define BRGPHY_5708S_TX_MISC_PG5 0x0005 329 330 /* 5708S SerDes "Digital" Registers (page 0) */ 331 #define BRGPHY_5708S_PG0_1000X_CTL1 0x10 332 #define BRGPHY_5708S_PG0_1000X_CTL1_AUTODET_EN 0x0010 333 #define BRGPHY_5708S_PG0_1000X_CTL1_FIBER_MODE 0x0001 334 335 #define BRGPHY_5708S_PG0_1000X_STAT1 0x14 336 #define BRGPHY_5708S_PG0_1000X_STAT1_LINK 0x0002 337 #define BRGPHY_5708S_PG0_1000X_STAT1_FDX 0x0004 338 #define BRGPHY_5708S_PG0_1000X_STAT1_SPEED_MASK 0x0018 339 #define BRGPHY_5708S_PG0_1000X_STAT1_SPEED_10 (0x0 << 3) 340 #define BRGPHY_5708S_PG0_1000X_STAT1_SPEED_100 (0x1 << 3) 341 #define BRGPHY_5708S_PG0_1000X_STAT1_SPEED_1G (0x2 << 3) 342 #define BRGPHY_5708S_PG0_1000X_STAT1_SPEED_25G (0x3 << 3) 343 344 345 #define BRGPHY_5708S_PG0_1000X_CTL2 0x11 346 #define BRGPHY_5708S_PG0_1000X_CTL2_PAR_DET_EN 0x0001 347 348 /* 5708S SerDes "Digital 3" Registers (page 2) */ 349 #define BRGPHY_5708S_PG2_DIGCTL_3_0 0x10 350 #define BRGPHY_5708S_PG2_DIGCTL_3_0_USE_IEEE 0x0001 351 352 /* 5708S SerDes "TX Misc" Registers (page 5) */ 353 #define BRGPHY_5708S_PG5_2500STATUS1 0x10 354 #define BRGPHY_5708S_PG5_TXACTL1 0x15 355 #define BRGPHY_5708S_PG5_TXACTL3 0x17 356 357 /*******************************************************/ 358 /* End: PHY register values for the 5708S SerDes PHY */ 359 /*******************************************************/ 360 361 #define BRGPHY_INTRS \ 362 ~(BRGPHY_IMR_LNK_CHG|BRGPHY_IMR_LSP_CHG|BRGPHY_IMR_DUP_CHG) 363 364 #endif /* _DEV_BRGPHY_MIIREG_H_ */ -
src/add-ons/kernel/drivers/network/syskonnect/dev/mii/ukphy.c
1 /* $NetBSD: ukphy.c,v 1.2 1999/04/23 04:24:32 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center, and by Frank van der Linden. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /*- 41 * Copyright (c) 1997 Manuel Bouyer. All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed by Manuel Bouyer. 54 * 4. The name of the author may not be used to endorse or promote products 55 * derived from this software without specific prior written permission. 56 * 57 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 58 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 59 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 60 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 61 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 62 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 63 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 64 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 65 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 66 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 67 */ 68 69 #include <sys/cdefs.h> 70 __FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20 2007/01/20 00:52:29 marius Exp $"); 71 72 /* 73 * driver for generic unknown PHYs 74 */ 75 76 #include <sys/param.h> 77 #include <sys/systm.h> 78 #include <sys/kernel.h> 79 #include <sys/socket.h> 80 #include <sys/errno.h> 81 #include <sys/module.h> 82 #include <sys/bus.h> 83 84 #include <net/if.h> 85 #include <net/if_media.h> 86 87 #include <dev/mii/mii.h> 88 #include <dev/mii/miivar.h> 89 90 #include "miibus_if.h" 91 92 static int ukphy_probe(device_t); 93 static int ukphy_attach(device_t); 94 95 static device_method_t ukphy_methods[] = { 96 /* device interface */ 97 DEVMETHOD(device_probe, ukphy_probe), 98 DEVMETHOD(device_attach, ukphy_attach), 99 DEVMETHOD(device_detach, mii_phy_detach), 100 DEVMETHOD(device_shutdown, bus_generic_shutdown), 101 { 0, 0 } 102 }; 103 104 static devclass_t ukphy_devclass; 105 106 static driver_t ukphy_driver = { 107 "ukphy", 108 ukphy_methods, 109 sizeof(struct mii_softc) 110 }; 111 112 DRIVER_MODULE(ukphy, miibus, ukphy_driver, ukphy_devclass, 0, 0); 113 114 static int ukphy_service(struct mii_softc *, struct mii_data *, int); 115 116 static int 117 ukphy_probe(device_t dev) 118 { 119 120 /* 121 * We know something is here, so always match at a low priority. 122 */ 123 device_set_desc(dev, "Generic IEEE 802.3u media interface"); 124 return (BUS_PROBE_GENERIC); 125 } 126 127 static int 128 ukphy_attach(device_t dev) 129 { 130 struct mii_softc *sc; 131 struct mii_attach_args *ma; 132 struct mii_data *mii; 133 134 sc = device_get_softc(dev); 135 ma = device_get_ivars(dev); 136 sc->mii_dev = device_get_parent(dev); 137 mii = device_get_softc(sc->mii_dev); 138 LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); 139 140 if (bootverbose) 141 device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", 142 MII_OUI(ma->mii_id1, ma->mii_id2), 143 MII_MODEL(ma->mii_id2), MII_REV(ma->mii_id2)); 144 145 sc->mii_inst = mii->mii_instance; 146 sc->mii_phy = ma->mii_phyno; 147 sc->mii_service = ukphy_service; 148 sc->mii_pdata = mii; 149 150 mii->mii_instance++; 151 152 mii_phy_reset(sc); 153 154 sc->mii_capabilities = 155 PHY_READ(sc, MII_BMSR) & ma->mii_capmask; 156 if (sc->mii_capabilities & BMSR_EXTSTAT) 157 sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); 158 device_printf(dev, " "); 159 mii_phy_add_media(sc); 160 printf("\n"); 161 162 MIIBUS_MEDIAINIT(sc->mii_dev); 163 mii_phy_setmedia(sc); 164 165 return (0); 166 } 167 168 static int 169 ukphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 170 { 171 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 172 int reg; 173 174 switch (cmd) { 175 case MII_POLLSTAT: 176 /* 177 * If we're not polling our PHY instance, just return. 178 */ 179 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 180 return (0); 181 break; 182 183 case MII_MEDIACHG: 184 /* 185 * If the media indicates a different PHY instance, 186 * isolate ourselves. 187 */ 188 if (IFM_INST(ife->ifm_media) != sc->mii_inst) { 189 reg = PHY_READ(sc, MII_BMCR); 190 PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); 191 return (0); 192 } 193 194 /* 195 * If the interface is not up, don't do anything. 196 */ 197 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 198 break; 199 200 mii_phy_setmedia(sc); 201 break; 202 203 case MII_TICK: 204 /* 205 * If we're not currently selected, just return. 206 */ 207 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 208 return (0); 209 if (mii_phy_tick(sc) == EJUSTRETURN) 210 return (0); 211 break; 212 } 213 214 /* Update the media status. */ 215 ukphy_status(sc); 216 217 /* Callback if something changed. */ 218 mii_phy_update(sc, cmd); 219 return (0); 220 } -
src/add-ons/kernel/drivers/network/syskonnect/dev/mii/miidevs.h
1 #define MII_OUI_MARVELL 0x005043 2 #define MII_OUI_xxMARVELL 0x000ac2 3 4 #define MII_MODEL_MARVELL_E1000 0x0000 5 #define MII_MODEL_MARVELL_E1011 0x0002 6 #define MII_MODEL_MARVELL_E1000_3 0x0003 7 #define MII_MODEL_MARVELL_E1000S 0x0004 8 #define MII_MODEL_MARVELL_E1000_5 0x0005 9 #define MII_MODEL_MARVELL_E1000_6 0x0006 10 #define MII_MODEL_MARVELL_E3082 0x0008 11 #define MII_MODEL_MARVELL_E1112 0x0009 12 #define MII_MODEL_MARVELL_E1149 0x000b 13 #define MII_MODEL_MARVELL_E1111 0x000c 14 #define MII_MODEL_MARVELL_E1116 0x0021 15 #define MII_MODEL_MARVELL_E1118 0x0022 16 17 #define MII_MODEL_xxMARVELL_E1000 0x0005 18 #define MII_MODEL_xxMARVELL_E1011 0x0002 19 #define MII_MODEL_xxMARVELL_E1000_3 0x0003 20 #define MII_MODEL_xxMARVELL_E1000_5 0x0005 21 #define MII_MODEL_xxMARVELL_E1111 0x000c 22 23 #define MII_STR_MARVELL_E1000 "Marvell 88E1000 Gigabit PHY" 24 #define MII_STR_MARVELL_E1011 "Marvell 88E1011 Gigabit PHY" 25 #define MII_STR_MARVELL_E1000_3 "Marvell 88E1000 Gigabit PHY" 26 #define MII_STR_MARVELL_E1000S "Marvell 88E1000S Gigabit PHY" 27 #define MII_STR_MARVELL_E1000_5 "Marvell 88E1000 Gigabit PHY" 28 #define MII_STR_MARVELL_E1000_6 "Marvell 88E1000 Gigabit PHY" 29 #define MII_STR_MARVELL_E3082 "Marvell 88E3082 10/100 Fast Ethernet PHY" 30 #define MII_STR_MARVELL_E1112 "Marvell 88E1112 Gigabit PHY" 31 #define MII_STR_MARVELL_E1149 "Marvell 88E1149 Gigabit PHY" 32 #define MII_STR_MARVELL_E1111 "Marvell 88E1111 Gigabit PHY" 33 #define MII_STR_MARVELL_E1116 "Marvell 88E1116 Gigabit PHY" 34 #define MII_STR_MARVELL_E1118 "Marvell 88E1118 Gigabit PHY" 35 36 #define MII_STR_xxMARVELL_E1000 "Marvell 88E1000 Gigabit PHY" 37 #define MII_STR_xxMARVELL_E1011 "Marvell 88E1011 Gigabit PHY" 38 #define MII_STR_xxMARVELL_E1000_3 "Marvell 88E1000 Gigabit PHY" 39 #define MII_STR_xxMARVELL_E1000_5 "Marvell 88E1000 Gigabit PHY" 40 #define MII_STR_xxMARVELL_E1111 "Marvell 88E1111 Gigabit PHY" 41 42 #define MII_OUI_JATO 0x00e083 /*Jato Technologies*/ 43 #define MII_OUI_XAQTI 0x00e0ae /*XaQti Corp.*/ 44 45 #define MII_OUI_xxXAQTI 0x350700 /*XaQti Corp.*/ 46 47 /* Jato Technologies PHYs */ 48 #define MII_MODEL_JATO_BASEX 0x0000 49 #define MII_STR_JATO_BASEX "Jato 1000baseX media interface" 50 51 /* XaQti Corp. PHYs. */ 52 #define MII_MODEL_XAQTI_XMACII 0x0000 53 #define MII_STR_XAQTI_XMACII "XaQti Corp. XMAC II gigabit interface" 54 55 -
src/add-ons/kernel/drivers/network/syskonnect/dev/mii/xmphy.c
1 /*- 2 * Copyright (c) 2000 3 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bill Paul. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD: src/sys/dev/mii/xmphy.c,v 1.21 2006/12/02 19:36:25 marius Exp $"); 35 36 /* 37 * driver for the XaQti XMAC II's internal PHY. This is sort of 38 * like a 10/100 PHY, except the only thing we're really autoselecting 39 * here is full/half duplex. Speed is always 1000mbps. 40 */ 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/module.h> 46 #include <sys/socket.h> 47 #include <sys/bus.h> 48 49 #include <net/if.h> 50 #include <net/if_media.h> 51 52 #include <dev/mii/mii.h> 53 #include <dev/mii/miivar.h> 54 #include "miidevs.h" 55 56 #include <dev/mii/xmphyreg.h> 57 58 #include "miibus_if.h" 59 60 static int xmphy_probe(device_t); 61 static int xmphy_attach(device_t); 62 63 static device_method_t xmphy_methods[] = { 64 /* device interface */ 65 DEVMETHOD(device_probe, xmphy_probe), 66 DEVMETHOD(device_attach, xmphy_attach), 67 DEVMETHOD(device_detach, mii_phy_detach), 68 DEVMETHOD(device_shutdown, bus_generic_shutdown), 69 { 0, 0 } 70 }; 71 72 static devclass_t xmphy_devclass; 73 74 static driver_t xmphy_driver = { 75 "xmphy", 76 xmphy_methods, 77 sizeof(struct mii_softc) 78 }; 79 80 DRIVER_MODULE(xmphy, miibus, xmphy_driver, xmphy_devclass, 0, 0); 81 82 static int xmphy_service(struct mii_softc *, struct mii_data *, int); 83 static void xmphy_status(struct mii_softc *); 84 static int xmphy_mii_phy_auto(struct mii_softc *); 85 86 static const struct mii_phydesc xmphys[] = { 87 { MII_OUI_xxXAQTI, MII_MODEL_XAQTI_XMACII, MII_STR_XAQTI_XMACII }, 88 MII_PHY_DESC(JATO, BASEX), 89 MII_PHY_END 90 }; 91 92 static int 93 xmphy_probe(device_t dev) 94 { 95 96 return (mii_phy_dev_probe(dev, xmphys, BUS_PROBE_DEFAULT)); 97 } 98 99 static int 100 xmphy_attach(device_t dev) 101 { 102 struct mii_softc *sc; 103 struct mii_attach_args *ma; 104 struct mii_data *mii; 105 const char *sep = ""; 106 107 sc = device_get_softc(dev); 108 ma = device_get_ivars(dev); 109 sc->mii_dev = device_get_parent(dev); 110 mii = device_get_softc(sc->mii_dev); 111 LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); 112 113 sc->mii_inst = mii->mii_instance; 114 sc->mii_phy = ma->mii_phyno; 115 sc->mii_service = xmphy_service; 116 sc->mii_pdata = mii; 117 118 sc->mii_flags |= MIIF_NOISOLATE; 119 mii->mii_instance++; 120 121 #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) 122 #define PRINT(s) printf("%s%s", sep, s); sep = ", " 123 124 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), 125 BMCR_ISO); 126 #if 0 127 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), 128 BMCR_LOOP|BMCR_S100); 129 #endif 130 131 mii_phy_reset(sc); 132 133 device_printf(dev, " "); 134 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, 0, sc->mii_inst), 135 XMPHY_BMCR_FDX); 136 PRINT("1000baseSX"); 137 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), 0); 138 PRINT("1000baseSX-FDX"); 139 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); 140 PRINT("auto"); 141 142 printf("\n"); 143 #undef ADD 144 #undef PRINT 145 146 MIIBUS_MEDIAINIT(sc->mii_dev); 147 return (0); 148 } 149 150 static int 151 xmphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 152 { 153 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 154 int reg; 155 156 switch (cmd) { 157 case MII_POLLSTAT: 158 /* 159 * If we're not polling our PHY instance, just return. 160 */ 161 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 162 return (0); 163 break; 164 165 case MII_MEDIACHG: 166 /* 167 * If the media indicates a different PHY instance, 168 * isolate ourselves. 169 */ 170 if (IFM_INST(ife->ifm_media) != sc->mii_inst) { 171 reg = PHY_READ(sc, MII_BMCR); 172 PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); 173 return (0); 174 } 175 176 /* 177 * If the interface is not up, don't do anything. 178 */ 179 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 180 break; 181 182 switch (IFM_SUBTYPE(ife->ifm_media)) { 183 case IFM_AUTO: 184 #ifdef foo 185 /* 186 * If we're already in auto mode, just return. 187 */ 188 if (PHY_READ(sc, XMPHY_MII_BMCR) & XMPHY_BMCR_AUTOEN) 189 return (0); 190 #endif 191 (void) xmphy_mii_phy_auto(sc); 192 break; 193 case IFM_1000_SX: 194 mii_phy_reset(sc); 195 if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) { 196 PHY_WRITE(sc, XMPHY_MII_ANAR, XMPHY_ANAR_FDX); 197 PHY_WRITE(sc, XMPHY_MII_BMCR, XMPHY_BMCR_FDX); 198 } else { 199 PHY_WRITE(sc, XMPHY_MII_ANAR, XMPHY_ANAR_HDX); 200 PHY_WRITE(sc, XMPHY_MII_BMCR, 0); 201 } 202 break; 203 case IFM_100_T4: 204 case IFM_100_TX: 205 case IFM_10_T: 206 default: 207 return (EINVAL); 208 } 209 break; 210 211 case MII_TICK: 212 /* 213 * If we're not currently selected, just return. 214 */ 215 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 216 return (0); 217 218 /* 219 * Is the interface even up? 220 */ 221 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 222 return (0); 223 224 /* 225 * Only used for autonegotiation. 226 */ 227 if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) 228 break; 229 230 /* 231 * Check to see if we have link. If we do, we don't 232 * need to restart the autonegotiation process. Read 233 * the BMSR twice in case it's latched. 234 */ 235 reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); 236 if (reg & BMSR_LINK) 237 break; 238 239 /* 240 * Only retry autonegotiation every 5 seconds. 241 */ 242 if (++sc->mii_ticks <= MII_ANEGTICKS) 243 break; 244 245 sc->mii_ticks = 0; 246 247 mii_phy_reset(sc); 248 xmphy_mii_phy_auto(sc); 249 return (0); 250 } 251 252 /* Update the media status. */ 253 xmphy_status(sc); 254 255 /* Callback if something changed. */ 256 mii_phy_update(sc, cmd); 257 return (0); 258 } 259 260 static void 261 xmphy_status(struct mii_softc *sc) 262 { 263 struct mii_data *mii = sc->mii_pdata; 264 int bmsr, bmcr, anlpar; 265 266 mii->mii_media_status = IFM_AVALID; 267 mii->mii_media_active = IFM_ETHER; 268 269 bmsr = PHY_READ(sc, XMPHY_MII_BMSR) | 270 PHY_READ(sc, XMPHY_MII_BMSR); 271 if (bmsr & XMPHY_BMSR_LINK) 272 mii->mii_media_status |= IFM_ACTIVE; 273 274 /* Do dummy read of extended status register. */ 275 bmcr = PHY_READ(sc, XMPHY_MII_EXTSTS); 276 277 bmcr = PHY_READ(sc, XMPHY_MII_BMCR); 278 279 if (bmcr & XMPHY_BMCR_LOOP) 280 mii->mii_media_active |= IFM_LOOP; 281 282 283 if (bmcr & XMPHY_BMCR_AUTOEN) { 284 if ((bmsr & XMPHY_BMSR_ACOMP) == 0) { 285 if (bmsr & XMPHY_BMSR_LINK) { 286 mii->mii_media_active |= IFM_1000_SX|IFM_HDX; 287 return; 288 } 289 /* Erg, still trying, I guess... */ 290 mii->mii_media_active |= IFM_NONE; 291 return; 292 } 293 294 mii->mii_media_active |= IFM_1000_SX; 295 anlpar = PHY_READ(sc, XMPHY_MII_ANAR) & 296 PHY_READ(sc, XMPHY_MII_ANLPAR); 297 if (anlpar & XMPHY_ANLPAR_FDX) 298 mii->mii_media_active |= IFM_FDX; 299 else 300 mii->mii_media_active |= IFM_HDX; 301 return; 302 } 303 304 mii->mii_media_active |= IFM_1000_SX; 305 if (bmcr & XMPHY_BMCR_FDX) 306 mii->mii_media_active |= IFM_FDX; 307 else 308 mii->mii_media_active |= IFM_HDX; 309 } 310 311 static int 312 xmphy_mii_phy_auto(struct mii_softc *mii) 313 { 314 int anar = 0; 315 316 anar = PHY_READ(mii, XMPHY_MII_ANAR); 317 anar |= XMPHY_ANAR_FDX|XMPHY_ANAR_HDX; 318 PHY_WRITE(mii, XMPHY_MII_ANAR, anar); 319 DELAY(1000); 320 PHY_WRITE(mii, XMPHY_MII_BMCR, 321 XMPHY_BMCR_AUTOEN | XMPHY_BMCR_STARTNEG); 322 323 return (EJUSTRETURN); 324 } -
src/add-ons/kernel/drivers/network/syskonnect/dev/mii/Jamfile
1 SubDir HAIKU_TOP src add-ons kernel drivers network syskonnect dev mii ; 2 3 UsePrivateHeaders kernel net ; 4 5 UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ; 6 UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ; 7 8 SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ; 9 10 KernelStaticLibrary syskonnect_mii.a 11 : 12 xmphy.c 13 e1000phy.c 14 ukphy.c 15 ukphy_subr.c 16 ; 17 -
src/add-ons/kernel/drivers/network/syskonnect/dev/mii/e1000phy.c
1 /*- 2 * Principal Author: Parag Patel 3 * Copyright (c) 2001 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice unmodified, this list of conditions, and the following 11 * disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * Additonal Copyright (c) 2001 by Traakan Software under same licence. 29 * Secondary Author: Matthew Jacob 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD: src/sys/dev/mii/e1000phy.c,v 1.18 2006/12/11 11:09:48 yongari Exp $"); 34 35 /* 36 * driver for the Marvell 88E1000 series external 1000/100/10-BT PHY. 37 */ 38 39 /* 40 * Support added for the Marvell 88E1011 (Alaska) 1000/100/10baseTX and 41 * 1000baseSX PHY. 42 * Nathan Binkert <nate@openbsd.org> 43 * Jung-uk Kim <jkim@niksun.com> 44 */ 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/kernel.h> 49 #include <sys/module.h> 50 #include <sys/socket.h> 51 #include <sys/bus.h> 52 53 54 #include <net/if.h> 55 #include <net/if_media.h> 56 57 #include <dev/mii/mii.h> 58 #include <dev/mii/miivar.h> 59 #include "miidevs.h" 60 61 #include <dev/mii/e1000phyreg.h> 62 63 #include "miibus_if.h" 64 65 static int e1000phy_probe(device_t); 66 static int e1000phy_attach(device_t); 67 68 struct e1000phy_softc { 69 struct mii_softc mii_sc; 70 int mii_model; 71 }; 72 73 static device_method_t e1000phy_methods[] = { 74 /* device interface */ 75 DEVMETHOD(device_probe, e1000phy_probe), 76 DEVMETHOD(device_attach, e1000phy_attach), 77 DEVMETHOD(device_detach, mii_phy_detach), 78 DEVMETHOD(device_shutdown, bus_generic_shutdown), 79 { 0, 0 } 80 }; 81 82 static devclass_t e1000phy_devclass; 83 static driver_t e1000phy_driver = { 84 "e1000phy", 85 e1000phy_methods, 86 sizeof(struct e1000phy_softc) 87 }; 88 89 DRIVER_MODULE(e1000phy, miibus, e1000phy_driver, e1000phy_devclass, 0, 0); 90 91 static int e1000phy_service(struct mii_softc *, struct mii_data *, int); 92 static void e1000phy_status(struct mii_softc *); 93 static void e1000phy_reset(struct mii_softc *); 94 static int e1000phy_mii_phy_auto(struct e1000phy_softc *); 95 96 static const struct mii_phydesc e1000phys[] = { 97 MII_PHY_DESC(MARVELL, E1000), 98 MII_PHY_DESC(MARVELL, E1011), 99 MII_PHY_DESC(MARVELL, E1000_3), 100 MII_PHY_DESC(MARVELL, E1000S), 101 MII_PHY_DESC(MARVELL, E1000_5), 102 MII_PHY_DESC(MARVELL, E1000_6), 103 MII_PHY_DESC(MARVELL, E3082), 104 MII_PHY_DESC(MARVELL, E1112), 105 MII_PHY_DESC(MARVELL, E1149), 106 MII_PHY_DESC(MARVELL, E1111), 107 MII_PHY_DESC(MARVELL, E1116), 108 MII_PHY_DESC(MARVELL, E1118), 109 MII_PHY_DESC(xxMARVELL, E1000), 110 MII_PHY_DESC(xxMARVELL, E1011), 111 MII_PHY_DESC(xxMARVELL, E1000_3), 112 MII_PHY_DESC(xxMARVELL, E1000_5), 113 MII_PHY_DESC(xxMARVELL, E1111), 114 MII_PHY_END 115 }; 116 117 static int 118 e1000phy_probe(device_t dev) 119 { 120 121 return (mii_phy_dev_probe(dev, e1000phys, BUS_PROBE_DEFAULT)); 122 } 123 124 static int 125 e1000phy_attach(device_t dev) 126 { 127 struct e1000phy_softc *esc; 128 struct mii_softc *sc; 129 struct mii_attach_args *ma; 130 struct mii_data *mii; 131 int fast_ether; 132 133 esc = device_get_softc(dev); 134 sc = &esc->mii_sc; 135 ma = device_get_ivars(dev); 136 sc->mii_dev = device_get_parent(dev); 137 mii = device_get_softc(sc->mii_dev); 138 LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); 139 140 sc->mii_inst = mii->mii_instance; 141 sc->mii_phy = ma->mii_phyno; 142 sc->mii_service = e1000phy_service; 143 sc->mii_pdata = mii; 144 sc->mii_anegticks = MII_ANEGTICKS_GIGE; 145 mii->mii_instance++; 146 147 fast_ether = 0; 148 esc->mii_model = MII_MODEL(ma->mii_id2); 149 switch (esc->mii_model) { 150 case MII_MODEL_MARVELL_E1011: 151 case MII_MODEL_MARVELL_E1112: 152 if (PHY_READ(sc, E1000_ESSR) & E1000_ESSR_FIBER_LINK) 153 sc->mii_flags |= MIIF_HAVEFIBER; 154 break; 155 case MII_MODEL_MARVELL_E3082: 156 /* 88E3082 10/100 Fast Ethernet PHY. */ 157 sc->mii_anegticks = MII_ANEGTICKS; 158 fast_ether = 1; 159 break; 160 } 161 162 e1000phy_reset(sc); 163 164 device_printf(dev, " "); 165 166 #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) 167 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), 168 E1000_CR_ISOLATE); 169 if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { 170 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), 171 E1000_CR_SPEED_10); 172 printf("10baseT, "); 173 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), 174 E1000_CR_SPEED_10 | E1000_CR_FULL_DUPLEX); 175 printf("10baseT-FDX, "); 176 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), 177 E1000_CR_SPEED_100); 178 printf("100baseTX, "); 179 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), 180 E1000_CR_SPEED_100 | E1000_CR_FULL_DUPLEX); 181 printf("100baseTX-FDX, "); 182 if (fast_ether == 0) { 183 /* 184 * 1000BT-simplex not supported; driver must ignore 185 * this entry, but it must be present in order to 186 * manually set full-duplex. 187 */ 188 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, 189 sc->mii_inst), E1000_CR_SPEED_1000); 190 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, 191 sc->mii_inst), 192 E1000_CR_SPEED_1000 | E1000_CR_FULL_DUPLEX); 193 printf("1000baseTX-FDX, "); 194 } 195 } else { 196 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), 197 E1000_CR_SPEED_1000 | E1000_CR_FULL_DUPLEX); 198 printf("1000baseSX-FDX, "); 199 } 200 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); 201 printf("auto\n"); 202 #undef ADD 203 204 MIIBUS_MEDIAINIT(sc->mii_dev); 205 return (0); 206 } 207 208 static void 209 e1000phy_reset(struct mii_softc *sc) 210 { 211 struct e1000phy_softc *esc; 212 uint16_t reg; 213 214 esc = (struct e1000phy_softc *)sc; 215 reg = PHY_READ(sc, E1000_SCR); 216 if ((sc->mii_flags & MIIF_HAVEFIBER) != 0) { 217 reg &= ~E1000_SCR_AUTO_X_MODE; 218 PHY_WRITE(sc, E1000_SCR, reg); 219 if (esc->mii_model == MII_MODEL_MARVELL_E1112) { 220 /* Select 1000BASE-X only mode. */ 221 PHY_WRITE(sc, E1000_EADR, 2); 222 reg = PHY_READ(sc, E1000_SCR); 223 reg &= ~E1000_SCR_MODE_MASK; 224 reg |= E1000_SCR_MODE_1000BX; 225 PHY_WRITE(sc, E1000_SCR, reg); 226 PHY_WRITE(sc, E1000_EADR, 1); 227 } 228 } else { 229 switch (esc->mii_model) { 230 case MII_MODEL_MARVELL_E1111: 231 case MII_MODEL_MARVELL_E1112: 232 case MII_MODEL_MARVELL_E1116: 233 case MII_MODEL_MARVELL_E1118: 234 case MII_MODEL_MARVELL_E1149: 235 /* Disable energy detect mode. */ 236 reg &= ~E1000_SCR_EN_DETECT_MASK; 237 reg |= E1000_SCR_AUTO_X_MODE; 238 break; 239 case MII_MODEL_MARVELL_E3082: 240 reg |= (E1000_SCR_AUTO_X_MODE >> 1); 241 break; 242 default: 243 reg &= ~E1000_SCR_AUTO_X_MODE; 244 break; 245 } 246 /* Enable CRS on TX. */ 247 reg |= E1000_SCR_ASSERT_CRS_ON_TX; 248 /* Auto correction for reversed cable polarity. */ 249 reg &= ~E1000_SCR_POLARITY_REVERSAL; 250 PHY_WRITE(sc, E1000_SCR, reg); 251 } 252 253 switch (MII_MODEL(esc->mii_model)) { 254 case MII_MODEL_MARVELL_E3082: 255 case MII_MODEL_MARVELL_E1112: 256 case MII_MODEL_MARVELL_E1116: 257 case MII_MODEL_MARVELL_E1118: 258 case MII_MODEL_MARVELL_E1149: 259 break; 260 default: 261 /* Force TX_CLK to 25MHz clock. */ 262 reg = PHY_READ(sc, E1000_ESCR); 263 reg |= E1000_ESCR_TX_CLK_25; 264 PHY_WRITE(sc, E1000_ESCR, reg); 265 break; 266 } 267 268 /* Reset the PHY so all changes take effect. */ 269 reg = PHY_READ(sc, E1000_CR); 270 reg |= E1000_CR_RESET; 271 PHY_WRITE(sc, E1000_CR, reg); 272 } 273 274 static int 275 e1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 276 { 277 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 278 struct e1000phy_softc *esc = (struct e1000phy_softc *)sc; 279 uint16_t speed, gig; 280 int reg; 281 282 switch (cmd) { 283 case MII_POLLSTAT: 284 /* 285 * If we're not polling our PHY instance, just return. 286 */ 287 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 288 return (0); 289 break; 290 291 case MII_MEDIACHG: 292 /* 293 * If the media indicates a different PHY instance, 294 * isolate ourselves. 295 */ 296 if (IFM_INST(ife->ifm_media) != sc->mii_inst) { 297 reg = PHY_READ(sc, E1000_CR); 298 PHY_WRITE(sc, E1000_CR, reg | E1000_CR_ISOLATE); 299 return (0); 300 } 301 302 /* 303 * If the interface is not up, don't do anything. 304 */ 305 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 306 break; 307 308 if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { 309 e1000phy_mii_phy_auto(esc); 310 break; 311 } 312 313 speed = 0; 314 switch (IFM_SUBTYPE(ife->ifm_media)) { 315 case IFM_1000_T: 316 if (esc->mii_model == MII_MODEL_MARVELL_E3082) 317 return (EINVAL); 318 speed = E1000_CR_SPEED_1000; 319 break; 320 case IFM_1000_SX: 321 if (esc->mii_model == MII_MODEL_MARVELL_E3082) 322 return (EINVAL); 323 speed = E1000_CR_SPEED_1000; 324 break; 325 case IFM_100_TX: 326 speed = E1000_CR_SPEED_100; 327 break; 328 case IFM_10_T: 329 speed = E1000_CR_SPEED_10; 330 break; 331 case IFM_NONE: 332 reg = PHY_READ(sc, E1000_CR); 333 PHY_WRITE(sc, E1000_CR, 334 reg | E1000_CR_ISOLATE | E1000_CR_POWER_DOWN); 335 goto done; 336 default: 337 return (EINVAL); 338 } 339 340 if (((ife->ifm_media & IFM_GMASK) & IFM_FDX) != 0) { 341 speed |= E1000_CR_FULL_DUPLEX; 342 gig = E1000_1GCR_1000T_FD; 343 } else 344 gig = E1000_1GCR_1000T; 345 346 reg = PHY_READ(sc, E1000_CR); 347 reg &= ~E1000_CR_AUTO_NEG_ENABLE; 348 PHY_WRITE(sc, E1000_CR, reg | E1000_CR_RESET); 349 350 /* 351 * When setting the link manually, one side must 352 * be the master and the other the slave. However 353 * ifmedia doesn't give us a good way to specify 354 * this, so we fake it by using one of the LINK 355 * flags. If LINK0 is set, we program the PHY to 356 * be a master, otherwise it's a slave. 357 */ 358 if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T || 359 (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_SX)) { 360 if ((mii->mii_ifp->if_flags & IFF_LINK0)) 361 PHY_WRITE(sc, E1000_1GCR, gig | 362 E1000_1GCR_MS_ENABLE | E1000_1GCR_MS_VALUE); 363 else 364 PHY_WRITE(sc, E1000_1GCR, gig | 365 E1000_1GCR_MS_ENABLE); 366 } else { 367 if (esc->mii_model != MII_MODEL_MARVELL_E3082) 368 PHY_WRITE(sc, E1000_1GCR, 0); 369 } 370 PHY_WRITE(sc, E1000_AR, E1000_AR_SELECTOR_FIELD); 371 PHY_WRITE(sc, E1000_CR, speed | E1000_CR_RESET); 372 done: 373 break; 374 case MII_TICK: 375 /* 376 * If we're not currently selected, just return. 377 */ 378 if (IFM_INST(ife->ifm_media) != sc->mii_inst) 379 return (0); 380 381 /* 382 * Is the interface even up? 383 */ 384 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 385 return (0); 386 387 /* 388 * Only used for autonegotiation. 389 */ 390 if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) 391 break; 392 393 /* 394 * check for link. 395 * Read the status register twice; BMSR_LINK is latch-low. 396 */ 397 reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); 398 if (reg & BMSR_LINK) { 399 sc->mii_ticks = 0; 400 break; 401 } 402 403 /* Announce link loss right after it happens. */ 404 if (sc->mii_ticks <= sc->mii_anegticks) 405 return (0); 406 407 sc->mii_ticks = 0; 408 e1000phy_reset(sc); 409 e1000phy_mii_phy_auto(esc); 410 break; 411 } 412 413 /* Update the media status. */ 414 e1000phy_status(sc); 415 416 /* Callback if something changed. */ 417 mii_phy_update(sc, cmd); 418 return (0); 419 } 420 421 static void 422 e1000phy_status(struct mii_softc *sc) 423 { 424 struct mii_data *mii = sc->mii_pdata; 425 int bmsr, bmcr, esr, gsr, ssr, isr, ar, lpar; 426 427 mii->mii_media_status = IFM_AVALID; 428 mii->mii_media_active = IFM_ETHER; 429 430 bmsr = PHY_READ(sc, E1000_SR) | PHY_READ(sc, E1000_SR); 431 esr = PHY_READ(sc, E1000_ESR); 432 bmcr = PHY_READ(sc, E1000_CR); 433 ssr = PHY_READ(sc, E1000_SSR); 434 isr = PHY_READ(sc, E1000_ISR); 435 ar = PHY_READ(sc, E1000_AR); 436 lpar = PHY_READ(sc, E1000_LPAR); 437 438 if (bmsr & E1000_SR_LINK_STATUS) 439 mii->mii_media_status |= IFM_ACTIVE; 440 441 if (bmcr & E1000_CR_LOOPBACK) 442 mii->mii_media_active |= IFM_LOOP; 443 444 if ((((bmcr & E1000_CR_AUTO_NEG_ENABLE) != 0) && 445 ((bmsr & E1000_SR_AUTO_NEG_COMPLETE) == 0)) || 446 ((ssr & E1000_SSR_LINK) == 0) || 447 ((ssr & E1000_SSR_SPD_DPLX_RESOLVED) == 0)) { 448 /* Erg, still trying, I guess... */ 449 mii->mii_media_active |= IFM_NONE; 450 return; 451 } 452 453 if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { 454 if (ssr & E1000_SSR_1000MBS) 455 mii->mii_media_active |= IFM_1000_T; 456 else if (ssr & E1000_SSR_100MBS) 457 mii->mii_media_active |= IFM_100_TX; 458 else 459 mii->mii_media_active |= IFM_10_T; 460 } else { 461 if (ssr & E1000_SSR_1000MBS) 462 mii->mii_media_active |= IFM_1000_SX; 463 } 464 465 if (ssr & E1000_SSR_DUPLEX) 466 mii->mii_media_active |= IFM_FDX; 467 else 468 mii->mii_media_active |= IFM_HDX; 469 470 if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { 471 /* FLAG0==rx-flow-control FLAG1==tx-flow-control */ 472 if ((ar & E1000_AR_PAUSE) && (lpar & E1000_LPAR_PAUSE)) { 473 mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1; 474 } else if (!(ar & E1000_AR_PAUSE) && (ar & E1000_AR_ASM_DIR) && 475 (lpar & E1000_LPAR_PAUSE) && (lpar & E1000_LPAR_ASM_DIR)) { 476 mii->mii_media_active |= IFM_FLAG1; 477 } else if ((ar & E1000_AR_PAUSE) && (ar & E1000_AR_ASM_DIR) && 478 !(lpar & E1000_LPAR_PAUSE) && (lpar & E1000_LPAR_ASM_DIR)) { 479 mii->mii_media_active |= IFM_FLAG0; 480 } 481 } 482 483 /* FLAG2 : local PHY resolved to MASTER */ 484 if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) || 485 (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX)) { 486 PHY_READ(sc, E1000_1GSR); 487 gsr = PHY_READ(sc, E1000_1GSR); 488 if ((gsr & E1000_1GSR_MS_CONFIG_RES) != 0) 489 mii->mii_media_active |= IFM_FLAG2; 490 } 491 } 492 493 static int 494 e1000phy_mii_phy_auto(struct e1000phy_softc *esc) 495 { 496 struct mii_softc *sc; 497 498 sc = &esc->mii_sc; 499 if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) 500 PHY_WRITE(sc, E1000_AR, E1000_AR_10T | E1000_AR_10T_FD | 501 E1000_AR_100TX | E1000_AR_100TX_FD | 502 E1000_AR_PAUSE | E1000_AR_ASM_DIR); 503 else 504 PHY_WRITE(sc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | 505 E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE); 506 if (esc->mii_model != MII_MODEL_MARVELL_E3082) 507 PHY_WRITE(sc, E1000_1GCR, 508 E1000_1GCR_1000T_FD | E1000_1GCR_1000T); 509 PHY_WRITE(sc, E1000_CR, 510 E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG); 511 512 return (EJUSTRETURN); 513 } -
src/add-ons/kernel/drivers/network/syskonnect/dev/mii/xmphyreg.h
1 /*- 2 * Copyright (c) 2000 3 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bill Paul. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 * $FreeBSD: src/sys/dev/mii/xmphyreg.h,v 1.4 2005/01/06 01:42:56 imp Exp $ 33 */ 34 35 #ifndef _DEV_MII_XMPHYREG_H_ 36 #define _DEV_MII_XMPHYREG_H_ 37 38 /* 39 * XaQti XMAC II PHY registers 40 */ 41 42 #define XMPHY_MII_BMCR 0x00 43 #define XMPHY_BMCR_RESET 0x8000 44 #define XMPHY_BMCR_LOOP 0x4000 45 #define XMPHY_BMCR_AUTOEN 0x1000 /* Autoneg enabled */ 46 #define XMPHY_BMCR_PDOWN 0x0800 /* Power down */ 47 #define XMPHY_BMCR_ISO 0x0400 /* Isolate */ 48 #define XMPHY_BMCR_STARTNEG 0x0200 /* Restart autoneg */ 49 #define XMPHY_BMCR_FDX 0x0100 /* Duplex mode */ 50 51 #define XMPHY_MII_BMSR 0x01 52 #define XMPHY_BMSR_EXTSTS 0x0100 /* Extended status present */ 53 #define XMPHY_BMSR_ACOMP 0x0020 /* Autoneg complete */ 54 #define XMPHY_BMSR_RFAULT 0x0010 /* Remote fault condition occured */ 55 #define XMPHY_BMSR_ANEG 0x0008 /* Autoneg capable */ 56 #define XMPHY_BMSR_LINK 0x0004 /* Link status */ 57 #define XMPHY_BMSR_EXT 0x0001 /* Extended capability */ 58 59 #define XMPHY_MII_ANAR 0x04 60 #define XMPHY_ANAR_NP 0x8000 /* Next page */ 61 #define XMPHY_ANAR_ACK 0x4000 /* Next page or base received */ 62 #define XMPHY_ANAR_RFBITS 0x3000 /* Remote fault bits */ 63 #define XMPHY_ANAR_PAUSEBITS 0x0180 /* Pause bits */ 64 #define XMPHY_ANAR_HDX 0x0040 /* Select half duplex */ 65 #define XMPHY_ANAR_FDX 0x0020 /* Select full duplex */ 66 67 #define XMPHY_MII_ANLPAR 0x05 68 #define XMPHY_ANLPAR_NP 0x8000 /* Next page */ 69 #define XMPHY_ANLPAR_ACK 0x4000 /* Next page or base received */ 70 #define XMPHY_ANLPAR_RFBITS 0x3000 /* Remote fault bits */ 71 #define XMPHY_ANLPAR_PAUSEBITS 0x0180 /* Pause bits */ 72 #define XMPHY_ANLPAR_HDX 0x0040 /* Select half duplex */ 73 #define XMPHY_ANLPAR_FDX 0x0020 /* Select full duplex */ 74 75 #define XMPHY_RF_OK 0x0000 /* No error -- link is good */ 76 #define XMPHY_RF_LINKFAIL 0x1000 /* Link failure */ 77 #define XMPHY_RF_OFFLINE 0x2000 /* Offline */ 78 #define XMPHY_RF_ANEGFAIL 0x3000 /* Autonegotiation error */ 79 80 #define XMPHY_PAUSE_NOPAUSE 0x0000 /* No pause possible */ 81 #define XMPHY_PAUSE_ASYMETRIC 0x0080 /* Asymetric pause toward LP */ 82 #define XMPHY_PAUSE_SYMETRIC 0x0100 /* Symetric pause */ 83 #define XMPHY_PAUSE_BOTH 0x0180 /* Both sym and asym pause */ 84 85 #define XMPHY_MII_ANER 0x06 86 #define XMPHY_ANER_LPNP 0x0008 /* Link partner can next page */ 87 #define XMPHY_ANER_NP 0x0004 /* Local PHY can next page */ 88 #define XMPHY_ANER_RX 0x0002 /* Next page received */ 89 90 #define XMPHY_MII_NEXTP 0x07 /* Next page */ 91 #define XMPHY_NEXTP_MORE 0x8000 /* More next pages to follow */ 92 #define XMPHY_NEXTP_ACK1 0x4000 /* Ack bit received OK */ 93 #define XMPHY_NEXTP_MP 0x2000 /* Page is message page */ 94 #define XMPHY_NEXTP_ACK2 0x1000 /* can comply with message (r/o) */ 95 #define XMPHY_NEXTP_TOGGLE 0x0800 /* sync with LP */ 96 #define XMPHY_NEXTP_MESSAGE 0x07FF /* message */ 97 98 #define XMPHY_MII_NEXTPLP 0x08 /* Next page of link partner */ 99 #define XMPHY_NEXTPLP_MORE 0x8000 /* More next pages to follow */ 100 #define XMPHY_NEXTPLP_ACK1 0x4000 /* Ack bit received OK */ 101 #define XMPHY_NEXTPLP_MP 0x2000 /* Page is message page */ 102 #define XMPHY_NEXTPLP_ACK2 0x1000 /* can comply with message (r/o) */ 103 #define XMPHY_NEXTPLP_TOGGLE 0x0800 /* sync with LP */ 104 #define XMPHY_NEXTPLP_MESSAGE 0x07FF /* message */ 105 106 #define XMPHY_MII_EXTSTS 0x0F /* Extended status */ 107 #define XMPHY_EXTSTS_FDX 0x8000 /* 1000base-X FD capable */ 108 #define XMPHY_EXTSTS_HDX 0x4000 /* 1000base-X HD capable */ 109 110 #define XMPHY_MII_RESAB 0x10 /* Resolved ability */ 111 #define XMPHY_RESAB_PAUSEBITS 0x0180 /* Pause bits */ 112 #define XMPHY_RESAB_HDX 0x0040 /* Half duplex selected */ 113 #define XMPHY_RESAB_FDX 0x0020 /* Full duplex selected */ 114 #define XMPHY_RESAB_ABLMIS 0x0010 /* Ability mismatch */ 115 #define XMPHY_RESAB_PAUSEMIS 0x0008 /* Pause mismatch */ 116 117 #endif /* _DEV_MII_XMPHYREG_H_ */ -
src/add-ons/kernel/drivers/network/syskonnect/dev/mii/e1000phyreg.h
1 /* $FreeBSD: src/sys/dev/mii/e1000phyreg.h,v 1.4 2006/12/11 10:43:32 yongari Exp $ */ 2 /*- 3 * Principal Author: Parag Patel 4 * Copyright (c) 2001 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice unmodified, this list of conditions, and the following 12 * disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * Additonal Copyright (c) 2001 by Traakan Software under same licence. 30 * Secondary Author: Matthew Jacob 31 */ 32 33 /*- 34 * Derived by information released by Intel under the following license: 35 * 36 * Copyright (c) 1999 - 2001, Intel Corporation 37 * 38 * All rights reserved. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions are met: 42 * 43 * 1. Redistributions of source code must retain the above copyright notice, 44 * this list of conditions and the following disclaimer. 45 * 46 * 2. Redistributions in binary form must reproduce the above copyright notice, 47 * this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 50 * 3. Neither the name of Intel Corporation nor the names of its contributors 51 * may be used to endorse or promote products derived from this software 52 * without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 55 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 58 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 59 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 60 * LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 61 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 63 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 64 * 65 */ 66 67 /* 68 * Marvell E1000 PHY registers 69 */ 70 71 #define E1000_MAX_REG_ADDRESS 0x1F 72 73 #define E1000_CR 0x00 /* control register */ 74 #define E1000_CR_SPEED_SELECT_MSB 0x0040 75 #define E1000_CR_COLL_TEST_ENABLE 0x0080 76 #define E1000_CR_FULL_DUPLEX 0x0100 77 #define E1000_CR_RESTART_AUTO_NEG 0x0200 78 #define E1000_CR_ISOLATE 0x0400 79 #define E1000_CR_POWER_DOWN 0x0800 80 #define E1000_CR_AUTO_NEG_ENABLE 0x1000 81 #define E1000_CR_SPEED_SELECT_LSB 0x2000 82 #define E1000_CR_LOOPBACK 0x4000 83 #define E1000_CR_RESET 0x8000 84 85 #define E1000_CR_SPEED_1000 0x0040 86 #define E1000_CR_SPEED_100 0x2000 87 #define E1000_CR_SPEED_10 0x0000 88 89 #define E1000_SR 0x01 /* status register */ 90 #define E1000_SR_EXTENDED 0x0001 91 #define E1000_SR_JABBER_DETECT 0x0002 92 #define E1000_SR_LINK_STATUS 0x0004 93 #define E1000_SR_AUTO_NEG 0x0008 94 #define E1000_SR_REMOTE_FAULT 0x0010 95 #define E1000_SR_AUTO_NEG_COMPLETE 0x0020 96 #define E1000_SR_PREAMBLE_SUPPRESS 0x0040 97 #define E1000_SR_EXTENDED_STATUS 0x0100 98 #define E1000_SR_100T2 0x0200 99 #define E1000_SR_100T2_FD 0x0400 100 #define E1000_SR_10T 0x0800 101 #define E1000_SR_10T_FD 0x1000 102 #define E1000_SR_100TX 0x2000 103 #define E1000_SR_100TX_FD 0x4000 104 #define E1000_SR_100T4 0x8000 105 106 #define E1000_ID1 0x02 /* ID register 1 */ 107 #define E1000_ID2 0x03 /* ID register 2 */ 108 #define E1000_ID_88E1000 0x01410C50 109 #define E1000_ID_88E1000S 0x01410C40 110 #define E1000_ID_88E1011 0x01410C20 111 #define E1000_ID_MASK 0xFFFFFFF0 112 113 #define E1000_AR 0x04 /* autonegotiation advertise reg */ 114 #define E1000_AR_SELECTOR_FIELD 0x0001 115 #define E1000_AR_10T 0x0020 116 #define E1000_AR_10T_FD 0x0040 117 #define E1000_AR_100TX 0x0080 118 #define E1000_AR_100TX_FD 0x0100 119 #define E1000_AR_100T4 0x0200 120 #define E1000_AR_PAUSE 0x0400 121 #define E1000_AR_ASM_DIR 0x0800 122 #define E1000_AR_REMOTE_FAULT 0x2000 123 #define E1000_AR_NEXT_PAGE 0x8000 124 #define E1000_AR_SPEED_MASK 0x01E0 125 126 /* Autonegotiation register bits for fiber cards (Alaska Only!) */ 127 #define E1000_FA_1000X_FD 0x0020 128 #define E1000_FA_1000X 0x0040 129 #define E1000_FA_SYM_PAUSE 0x0080 130 #define E1000_FA_ASYM_PAUSE 0x0100 131 #define E1000_FA_FAULT1 0x1000 132 #define E1000_FA_FAULT2 0x2000 133 #define E1000_FA_NEXT_PAGE 0x8000 134 135 #define E1000_LPAR 0x05 /* autoneg link partner abilities reg */ 136 #define E1000_LPAR_SELECTOR_FIELD 0x0001 137 #define E1000_LPAR_10T 0x0020 138 #define E1000_LPAR_10T_FD 0x0040 139 #define E1000_LPAR_100TX 0x0080 140 #define E1000_LPAR_100TX_FD 0x0100 141 #define E1000_LPAR_100T4 0x0200 142 #define E1000_LPAR_PAUSE 0x0400 143 #define E1000_LPAR_ASM_DIR 0x0800 144 #define E1000_LPAR_REMOTE_FAULT 0x2000 145 #define E1000_LPAR_ACKNOWLEDGE 0x4000 146 #define E1000_LPAR_NEXT_PAGE 0x8000 147 148 /* autoneg link partner ability register bits for fiber cards (Alaska Only!) */ 149 #define E1000_FPAR_1000X_FD 0x0020 150 #define E1000_FPAR_1000X 0x0040 151 #define E1000_FPAR_SYM_PAUSE 0x0080 152 #define E1000_FPAR_ASYM_PAUSE 0x0100 153 #define E1000_FPAR_FAULT1 0x1000 154 #define E1000_FPAR_FAULT2 0x2000 155 #define E1000_FPAR_ACK 0x4000 156 #define E1000_FPAR_NEXT_PAGE 0x8000 157 158 #define E1000_ER 0x06 /* autoneg expansion reg */ 159 #define E1000_ER_LP_NWAY 0x0001 160 #define E1000_ER_PAGE_RXD 0x0002 161 #define E1000_ER_NEXT_PAGE 0x0004 162 #define E1000_ER_LP_NEXT_PAGE 0x0008 163 #define E1000_ER_PAR_DETECT_FAULT 0x0100 164 165 #define E1000_NPTX 0x07 /* autoneg next page TX */ 166 #define E1000_NPTX_MSG_CODE_FIELD 0x0001 167 #define E1000_NPTX_TOGGLE 0x0800 168 #define E1000_NPTX_ACKNOWLDGE2 0x1000 169 #define E1000_NPTX_MSG_PAGE 0x2000 170 #define E1000_NPTX_NEXT_PAGE 0x8000 171 172 #define E1000_RNPR 0x08 /* autoneg link-partner (?) next page */ 173 #define E1000_RNPR_MSG_CODE_FIELD 0x0001 174 #define E1000_RNPR_TOGGLE 0x0800 175 #define E1000_RNPR_ACKNOWLDGE2 0x1000 176 #define E1000_RNPR_MSG_PAGE 0x2000 177 #define E1000_RNPR_ACKNOWLDGE 0x4000 178 #define E1000_RNPR_NEXT_PAGE 0x8000 179 180 #define E1000_1GCR 0x09 /* 1000T (1G) control reg */ 181 #define E1000_1GCR_ASYM_PAUSE 0x0080 182 #define E1000_1GCR_1000T 0x0100 183 #define E1000_1GCR_1000T_FD 0x0200 184 #define E1000_1GCR_REPEATER_DTE 0x0400 185 #define E1000_1GCR_MS_VALUE 0x0800 186 #define E1000_1GCR_MS_ENABLE 0x1000 187 #define E1000_1GCR_TEST_MODE_NORMAL 0x0000 188 #define E1000_1GCR_TEST_MODE_1 0x2000 189 #define E1000_1GCR_TEST_MODE_2 0x4000 190 #define E1000_1GCR_TEST_MODE_3 0x6000 191 #define E1000_1GCR_TEST_MODE_4 0x8000 192 #define E1000_1GCR_SPEED_MASK 0x0300 193 194 #define E1000_1GSR 0x0A /* 1000T (1G) status reg */ 195 #define E1000_1GSR_IDLE_ERROR_CNT 0x0000 196 #define E1000_1GSR_ASYM_PAUSE_DIR 0x0100 197 #define E1000_1GSR_LP 0x0400 198 #define E1000_1GSR_LP_FD 0x0800 199 #define E1000_1GSR_REMOTE_RX_STATUS 0x1000 200 #define E1000_1GSR_LOCAL_RX_STATUS 0x2000 201 #define E1000_1GSR_MS_CONFIG_RES 0x4000 202 #define E1000_1GSR_MS_CONFIG_FAULT 0x8000 203 204 #define E1000_ESR 0x0F /* IEEE extended status reg */ 205 #define E1000_ESR_1000T 0x1000 206 #define E1000_ESR_1000T_FD 0x2000 207 #define E1000_ESR_1000X 0x4000 208 #define E1000_ESR_1000X_FD 0x8000 209 210 #define E1000_TX_POLARITY_MASK 0x0100 211 #define E1000_TX_NORMAL_POLARITY 0 212 213 #define E1000_AUTO_POLARITY_DISABLE 0x0010 214 215 #define E1000_SCR 0x10 /* special control register */ 216 #define E1000_SCR_JABBER_DISABLE 0x0001 217 #define E1000_SCR_POLARITY_REVERSAL 0x0002 218 #define E1000_SCR_SQE_TEST 0x0004 219 #define E1000_SCR_INT_FIFO_DISABLE 0x0008 220 #define E1000_SCR_CLK125_DISABLE 0x0010 221 #define E1000_SCR_MDI_MANUAL_MODE 0x0000 222 #define E1000_SCR_MDIX_MANUAL_MODE 0x0020 223 #define E1000_SCR_AUTO_X_1000T 0x0040 224 #define E1000_SCR_AUTO_X_MODE 0x0060 225 #define E1000_SCR_10BT_EXT_ENABLE 0x0080 226 #define E1000_SCR_MII_5BIT_ENABLE 0x0100 227 #define E1000_SCR_SCRAMBLER_DISABLE 0x0200 228 #define E1000_SCR_FORCE_LINK_GOOD 0x0400 229 #define E1000_SCR_ASSERT_CRS_ON_TX 0x0800 230 #define E1000_SCR_RX_FIFO_DEPTH_6 0x0000 231 #define E1000_SCR_RX_FIFO_DEPTH_8 0x1000 232 #define E1000_SCR_RX_FIFO_DEPTH_10 0x2000 233 #define E1000_SCR_RX_FIFO_DEPTH_12 0x3000 234 #define E1000_SCR_TX_FIFO_DEPTH_6 0x0000 235 #define E1000_SCR_TX_FIFO_DEPTH_8 0x4000 236 #define E1000_SCR_TX_FIFO_DEPTH_10 0x8000 237 #define E1000_SCR_TX_FIFO_DEPTH_12 0xC000 238 239 #define E1000_SCR_EN_DETECT_MASK 0x0300 240 241 /* 88E1112 page 2 */ 242 #define E1000_SCR_MODE_MASK 0x0380 243 #define E1000_SCR_MODE_AUTO 0x0180 244 #define E1000_SCR_MODE_COPPER 0x0280 245 #define E1000_SCR_MODE_1000BX 0x0380 246 247 #define E1000_SSR 0x11 /* special status register */ 248 #define E1000_SSR_JABBER 0x0001 249 #define E1000_SSR_REV_POLARITY 0x0002 250 #define E1000_SSR_MDIX 0x0020 251 #define E1000_SSR_LINK 0x0400 252 #define E1000_SSR_SPD_DPLX_RESOLVED 0x0800 253 #define E1000_SSR_PAGE_RCVD 0x1000 254 #define E1000_SSR_DUPLEX 0x2000 255 #define E1000_SSR_SPEED 0xC000 256 #define E1000_SSR_10MBS 0x0000 257 #define E1000_SSR_100MBS 0x4000 258 #define E1000_SSR_1000MBS 0x8000 259 260 #define E1000_IER 0x12 /* interrupt enable reg */ 261 #define E1000_IER_JABBER 0x0001 262 #define E1000_IER_POLARITY_CHANGE 0x0002 263 #define E1000_IER_MDIX_CHANGE 0x0040 264 #define E1000_IER_FIFO_OVER_UNDERUN 0x0080 265 #define E1000_IER_FALSE_CARRIER 0x0100 266 #define E1000_IER_SYMBOL_ERROR 0x0200 267 #define E1000_IER_LINK_STAT_CHANGE 0x0400 268 #define E1000_IER_AUTO_NEG_COMPLETE 0x0800 269 #define E1000_IER_PAGE_RECEIVED 0x1000 270 #define E1000_IER_DUPLEX_CHANGED 0x2000 271 #define E1000_IER_SPEED_CHANGED 0x4000 272 #define E1000_IER_AUTO_NEG_ERR 0x8000 273 274 #define E1000_ISR 0x13 /* interrupt status reg */ 275 #define E1000_ISR_JABBER 0x0001 276 #define E1000_ISR_POLARITY_CHANGE 0x0002 277 #define E1000_ISR_MDIX_CHANGE 0x0040 278 #define E1000_ISR_FIFO_OVER_UNDERUN 0x0080 279 #define E1000_ISR_FALSE_CARRIER 0x0100 280 #define E1000_ISR_SYMBOL_ERROR 0x0200 281 #define E1000_ISR_LINK_STAT_CHANGE 0x0400 282 #define E1000_ISR_AUTO_NEG_COMPLETE 0x0800 283 #define E1000_ISR_PAGE_RECEIVED 0x1000 284 #define E1000_ISR_DUPLEX_CHANGED 0x2000 285 #define E1000_ISR_SPEED_CHANGED 0x4000 286 #define E1000_ISR_AUTO_NEG_ERR 0x8000 287 288 #define E1000_ESCR 0x14 /* extended special control reg */ 289 #define E1000_ESCR_FIBER_LOOPBACK 0x4000 290 #define E1000_ESCR_DOWN_NO_IDLE 0x8000 291 #define E1000_ESCR_TX_CLK_2_5 0x0060 292 #define E1000_ESCR_TX_CLK_25 0x0070 293 #define E1000_ESCR_TX_CLK_0 0x0000 294 295 #define E1000_RECR 0x15 /* RX error counter reg */ 296 297 #define E1000_EADR 0x16 /* extended address reg */ 298 299 #define E1000_LCR 0x18 /* LED control reg */ 300 #define E1000_LCR_LED_TX 0x0001 301 #define E1000_LCR_LED_RX 0x0002 302 #define E1000_LCR_LED_DUPLEX 0x0004 303 #define E1000_LCR_LINK 0x0008 304 #define E1000_LCR_BLINK_42MS 0x0000 305 #define E1000_LCR_BLINK_84MS 0x0100 306 #define E1000_LCR_BLINK_170MS 0x0200 307 #define E1000_LCR_BLINK_340MS 0x0300 308 #define E1000_LCR_BLINK_670MS 0x0400 309 #define E1000_LCR_PULSE_OFF 0x0000 310 #define E1000_LCR_PULSE_21_42MS 0x1000 311 #define E1000_LCR_PULSE_42_84MS 0x2000 312 #define E1000_LCR_PULSE_84_170MS 0x3000 313 #define E1000_LCR_PULSE_170_340MS 0x4000 314 #define E1000_LCR_PULSE_340_670MS 0x5000 315 #define E1000_LCR_PULSE_670_13S 0x6000 316 #define E1000_LCR_PULSE_13_26S 0x7000 317 318 /* The following register is found only on the 88E1011 Alaska PHY */ 319 #define E1000_ESSR 0x1B /* Extended PHY specific sts */ 320 #define E1000_ESSR_FIBER_LINK 0x2000 321 #define E1000_ESSR_GMII_COPPER 0x000f 322 #define E1000_ESSR_GMII_FIBER 0x0007 323 #define E1000_ESSR_TBI_COPPER 0x000d 324 #define E1000_ESSR_TBI_FIBER 0x0005 -
src/add-ons/kernel/drivers/network/syskonnect/dev/mii/ukphy_subr.c
1 /* $NetBSD: ukphy_subr.c,v 1.2 1998/11/05 04:08:02 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center, and by Frank van der Linden. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 #include <sys/cdefs.h> 41 __FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.8.8.1 2006/07/19 04:40:26 yongari Exp $"); 42 43 /* 44 * Subroutines shared by the ukphy driver and other PHY drivers. 45 */ 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/socket.h> 50 #include <sys/module.h> 51 #include <sys/bus.h> 52 53 #include <net/if.h> 54 #include <net/if_media.h> 55 56 #include <dev/mii/mii.h> 57 #include <dev/mii/miivar.h> 58 59 #include "miibus_if.h" 60 61 /* 62 * Media status subroutine. If a PHY driver does media detection simply 63 * by decoding the NWay autonegotiation, use this routine. 64 */ 65 void 66 ukphy_status(struct mii_softc *phy) 67 { 68 struct mii_data *mii = phy->mii_pdata; 69 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 70 int bmsr, bmcr, anlpar, gtcr, gtsr; 71 72 mii->mii_media_status = IFM_AVALID; 73 mii->mii_media_active = IFM_ETHER; 74 75 bmsr = PHY_READ(phy, MII_BMSR) | PHY_READ(phy, MII_BMSR); 76 if (bmsr & BMSR_LINK) 77 mii->mii_media_status |= IFM_ACTIVE; 78 79 bmcr = PHY_READ(phy, MII_BMCR); 80 if (bmcr & BMCR_ISO) { 81 mii->mii_media_active |= IFM_NONE; 82 mii->mii_media_status = 0; 83 return; 84 } 85 86 if (bmcr & BMCR_LOOP) 87 mii->mii_media_active |= IFM_LOOP; 88 89 if (bmcr & BMCR_AUTOEN) { 90 /* 91 * NWay autonegotiation takes the highest-order common 92 * bit of the ANAR and ANLPAR (i.e. best media advertised 93 * both by us and our link partner). 94 */ 95 if ((bmsr & BMSR_ACOMP) == 0) { 96 /* Erg, still trying, I guess... */ 97 mii->mii_media_active |= IFM_NONE; 98 return; 99 } 100 101 anlpar = PHY_READ(phy, MII_ANAR) & PHY_READ(phy, MII_ANLPAR); 102 if ((phy->mii_flags & MIIF_HAVE_GTCR) != 0 && 103 (phy->mii_extcapabilities & 104 (EXTSR_1000THDX | EXTSR_1000TFDX)) != 0) { 105 gtcr = PHY_READ(phy, MII_100T2CR); 106 gtsr = PHY_READ(phy, MII_100T2SR); 107 } else 108 gtcr = gtsr = 0; 109 110 if ((gtcr & GTCR_ADV_1000TFDX) && (gtsr & GTSR_LP_1000TFDX)) 111 mii->mii_media_active |= IFM_1000_T|IFM_FDX; 112 else if ((gtcr & GTCR_ADV_1000THDX) && 113 (gtsr & GTSR_LP_1000THDX)) 114 mii->mii_media_active |= IFM_1000_T; 115 else if (anlpar & ANLPAR_T4) 116 mii->mii_media_active |= IFM_100_T4; 117 else if (anlpar & ANLPAR_TX_FD) 118 mii->mii_media_active |= IFM_100_TX|IFM_FDX; 119 else if (anlpar & ANLPAR_TX) 120 mii->mii_media_active |= IFM_100_TX; 121 else if (anlpar & ANLPAR_10_FD) 122 mii->mii_media_active |= IFM_10_T|IFM_FDX; 123 else if (anlpar & ANLPAR_10) 124 mii->mii_media_active |= IFM_10_T; 125 else 126 mii->mii_media_active |= IFM_NONE; 127 } else 128 mii->mii_media_active = ife->ifm_media; 129 }