Ticket #1945: marvell_100.diff

File marvell_100.diff, 262.0 KB (added by euan, 16 years ago)

marvell_yukon working driver for (SK) type devices.

  • src/add-ons/kernel/drivers/network/marvell_yukon_sk/Jamfile

     
     1SubDir HAIKU_TOP src add-ons kernel drivers network marvell_yukon_sk ;
     2
     3SubInclude HAIKU_TOP src add-ons kernel drivers network marvell_yukon_sk dev ;
  • src/add-ons/kernel/drivers/network/marvell_yukon_sk/dev/Jamfile

     
     1SubDir HAIKU_TOP src add-ons kernel drivers network marvell_yukon_sk dev ;
     2
     3SubInclude HAIKU_TOP src add-ons kernel drivers network marvell_yukon_sk dev mii ;
     4SubInclude HAIKU_TOP src add-ons kernel drivers network marvell_yukon_sk dev sk ;
  • src/add-ons/kernel/drivers/network/marvell_yukon_sk/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
     1289struct 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 */
     1301struct 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
     1329struct 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
     1385struct sk_jpool_entry {
     1386    int                             slot;
     1387    SLIST_ENTRY(sk_jpool_entry) jpool_entries;
     1388};
     1389
     1390struct sk_txdesc {
     1391    struct mbuf     *tx_m;
     1392    bus_dmamap_t        tx_dmamap;
     1393    STAILQ_ENTRY(sk_txdesc) tx_q;
     1394};
     1395
     1396STAILQ_HEAD(sk_txdq, sk_txdesc);
     1397
     1398struct sk_rxdesc {
     1399    struct mbuf     *rx_m;
     1400    bus_dmamap_t        rx_dmamap;
     1401};
     1402
     1403struct 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
     1432struct 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
     1457struct 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. */
     1465struct sk_if_softc;
     1466
     1467/* Softc for the GEnesis controller. */
     1468struct 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 */
     1501struct 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/marvell_yukon_sk/dev/sk/Jamfile

     
     1SubDir HAIKU_TOP src add-ons kernel drivers network marvell_yukon_sk dev sk ;
     2
     3UsePrivateHeaders kernel net ;
     4
     5UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ;
     6UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ;
     7
     8SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ;
     9
     10KernelAddon marvell_yukon_sk :
     11    if_sk.c
     12    glue.c
     13    : libfreebsd_network.a marvell_yukon_sk_mii.a
     14    ;
  • src/add-ons/kernel/drivers/network/marvell_yukon_sk/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/marvell_yukon_sk/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
     134MODULE_DEPEND(sk, pci, 1, 1, 1);
     135MODULE_DEPEND(sk, ether, 1, 1, 1);
     136MODULE_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
     142static 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
     146static 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
     190static int skc_probe(device_t);
     191static int skc_attach(device_t);
     192static int skc_detach(device_t);
     193static int skc_shutdown(device_t);
     194static int skc_suspend(device_t);
     195static int skc_resume(device_t);
     196static int sk_detach(device_t);
     197static int sk_probe(device_t);
     198static int sk_attach(device_t);
     199static void sk_tick(void *);
     200static void sk_yukon_tick(void *);
     201static void sk_intr(void *);
     202static void sk_intr_xmac(struct sk_if_softc *);
     203static void sk_intr_bcom(struct sk_if_softc *);
     204static void sk_intr_yukon(struct sk_if_softc *);
     205static __inline void sk_rxcksum(struct ifnet *, struct mbuf *, u_int32_t);
     206static __inline int sk_rxvalid(struct sk_softc *, u_int32_t, u_int32_t);
     207static void sk_rxeof(struct sk_if_softc *);
     208static void sk_jumbo_rxeof(struct sk_if_softc *);
     209static void sk_txeof(struct sk_if_softc *);
     210static void sk_txcksum(struct ifnet *, struct mbuf *, struct sk_tx_desc *);
     211static int sk_encap(struct sk_if_softc *, struct mbuf **);
     212static void sk_start(struct ifnet *);
     213static void sk_start_locked(struct ifnet *);
     214static int sk_ioctl(struct ifnet *, u_long, caddr_t);
     215static void sk_init(void *);
     216static void sk_init_locked(struct sk_if_softc *);
     217static void sk_init_xmac(struct sk_if_softc *);
     218static void sk_init_yukon(struct sk_if_softc *);
     219static void sk_stop(struct sk_if_softc *);
     220static void sk_watchdog(void *);
     221static int sk_ifmedia_upd(struct ifnet *);
     222static void sk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
     223static void sk_reset(struct sk_softc *);
     224static __inline void sk_discard_rxbuf(struct sk_if_softc *, int);
     225static __inline void sk_discard_jumbo_rxbuf(struct sk_if_softc *, int);
     226static int sk_newbuf(struct sk_if_softc *, int);
     227static int sk_jumbo_newbuf(struct sk_if_softc *, int);
     228static void sk_dmamap_cb(void *, bus_dma_segment_t *, int, int);
     229static int sk_dma_alloc(struct sk_if_softc *);
     230static void sk_dma_free(struct sk_if_softc *);
     231static void *sk_jalloc(struct sk_if_softc *);
     232static void sk_jfree(void *, void *);
     233static int sk_init_rx_ring(struct sk_if_softc *);
     234static int sk_init_jumbo_rx_ring(struct sk_if_softc *);
     235static void sk_init_tx_ring(struct sk_if_softc *);
     236static u_int32_t sk_win_read_4(struct sk_softc *, int);
     237u_int16_t sk_win_read_2(struct sk_softc *, int);
     238static u_int8_t sk_win_read_1(struct sk_softc *, int);
     239static void sk_win_write_4(struct sk_softc *, int, u_int32_t);
     240void sk_win_write_2(struct sk_softc *, int, u_int32_t);
     241static void sk_win_write_1(struct sk_softc *, int, u_int32_t);
     242
     243static int sk_miibus_readreg(device_t, int, int);
     244static int sk_miibus_writereg(device_t, int, int, int);
     245static void sk_miibus_statchg(device_t);
     246
     247static int sk_xmac_miibus_readreg(struct sk_if_softc *, int, int);
     248static int sk_xmac_miibus_writereg(struct sk_if_softc *, int, int,
     249                        int);
     250static void sk_xmac_miibus_statchg(struct sk_if_softc *);
     251
     252static int sk_marv_miibus_readreg(struct sk_if_softc *, int, int);
     253static int sk_marv_miibus_writereg(struct sk_if_softc *, int, int,
     254                        int);
     255static void sk_marv_miibus_statchg(struct sk_if_softc *);
     256
     257static uint32_t sk_xmchash(const uint8_t *);
     258static uint32_t sk_gmchash(const uint8_t *);
     259static void sk_setfilt(struct sk_if_softc *, u_int16_t *, int);
     260static void sk_setmulti(struct sk_if_softc *);
     261static void sk_setpromisc(struct sk_if_softc *);
     262
     263static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high);
     264static int sysctl_hw_sk_int_mod(SYSCTL_HANDLER_ARGS);
     265
     266#ifdef __HAIKU__
     267static 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 */
     290static 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
     306static driver_t skc_driver = {
     307    "skc",
     308    skc_methods,
     309    sizeof(struct sk_softc)
     310};
     311
     312static devclass_t skc_devclass;
     313
     314static 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
     333static driver_t sk_driver = {
     334    "sk",
     335    sk_methods,
     336    sizeof(struct sk_if_softc)
     337};
     338
     339static devclass_t sk_devclass;
     340
     341DRIVER_MODULE(skc, pci, skc_driver, skc_devclass, 0, 0);
     342DRIVER_MODULE(sk, skc, sk_driver, sk_devclass, 0, 0);
     343DRIVER_MODULE(miibus, sk, miibus_driver, miibus_devclass, 0, 0);
     344
     345static 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
     351static 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
     375static u_int32_t
     376sk_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
     388u_int16_t
     389sk_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
     401static u_int8_t
     402sk_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
     414static void
     415sk_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
     429void
     430sk_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
     444static void
     445sk_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)
     462static u_short
     463in_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
     472static int
     473sk_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
     501static int
     502sk_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
     530static void
     531sk_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
     554static int
     555sk_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
     585static int
     586sk_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
     615static void
     616sk_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
     636static int
     637sk_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
     670static int
     671sk_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
     692static void
     693sk_marv_miibus_statchg(sc_if)
     694    struct sk_if_softc  *sc_if;
     695{
     696    return;
     697}
     698
     699#define HASH_BITS       6
     700
     701static u_int32_t
     702sk_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 */
     714static u_int32_t
     715sk_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
     726static void
     727sk_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
     743static void
     744sk_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
     844static void
     845sk_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
     877static int
     878sk_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
     910static int
     911sk_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
     944static void
     945sk_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
     977static __inline void
     978sk_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
     993static __inline void
     994sk_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
     1008static int
     1009sk_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
     1053static int
     1054sk_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 */
     1120static int
     1121sk_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 */
     1137static void
     1138sk_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
     1155static int
     1156sk_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 */
     1238static int
     1239skc_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 */
     1271static void
     1272sk_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
     1329static int
     1330sk_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 */
     1361static int
     1362sk_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
     1552fail:
     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 */
     1566static int
     1567skc_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
     1830fail:
     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 */
     1844static int
     1845sk_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
     1885static int
     1886skc_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
     1916struct sk_dmamap_arg {
     1917    bus_addr_t  sk_busaddr;
     1918};
     1919
     1920static void
     1921sk_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 */
     1945static int
     1946sk_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
     2272fail:
     2273    return (error);
     2274}
     2275
     2276static void
     2277sk_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 */
     2421static void *
     2422sk_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 */
     2447static void
     2448sk_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
     2478static void
     2479sk_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
     2518sendit:
     2519    f->sk_csum_startval = 0;
     2520    f->sk_csum_start = htole32(((offset + m->m_pkthdr.csum_data) & 0xffff) |
     2521        (offset << 16));
     2522}
     2523
     2524static int
     2525sk_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
     2616static void
     2617sk_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
     2631static void
     2632sk_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
     2682static void
     2683sk_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
     2709done:
     2710    callout_reset(&sc_if->sk_watchdog_ch, hz, sk_watchdog, ifp);
     2711
     2712    return;
     2713}
     2714
     2715static int
     2716skc_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
     2737static int
     2738skc_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
     2766static int
     2767skc_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 */
     2809static __inline void
     2810sk_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
     2861static __inline int
     2862sk_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
     2883static void
     2884sk_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
     2950static void
     2951sk_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
     3018static void
     3019sk_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
     3070static void
     3071sk_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
     3115static void
     3116sk_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
     3129static void
     3130sk_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
     3183static void
     3184sk_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
     3219static void
     3220sk_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
     3238static void
     3239sk_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
     3347done_locked:
     3348    SK_UNLOCK(sc);
     3349}
     3350
     3351static void
     3352sk_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
     3516static void
     3517sk_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 */
     3652static void
     3653sk_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
     3665static void
     3666sk_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
     3865static void
     3866sk_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
     3996static int
     3997sysctl_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
     4013static int
     4014sysctl_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/marvell_yukon_sk/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
     14HAIKU_FBSD_DRIVER_GLUE(marvell_yukon_sk, skc, pci)
     15
     16extern driver_t *DRIVER_MODULE_NAME(e1000phy, miibus);
     17extern driver_t *DRIVER_MODULE_NAME(ukphy, miibus);
     18extern driver_t *DRIVER_MODULE_NAME(xmphy, miibus);
     19
     20HAIKU_DRIVER_REQUIREMENTS(0);
     21
     22driver_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
     36int
     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
     73void
     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/marvell_yukon_sk/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/marvell_yukon_sk/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/marvell_yukon_sk/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
     92static int ukphy_probe(device_t);
     93static int ukphy_attach(device_t);
     94
     95static 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
     104static devclass_t ukphy_devclass;
     105
     106static driver_t ukphy_driver = {
     107    "ukphy",
     108    ukphy_methods,
     109    sizeof(struct mii_softc)
     110};
     111
     112DRIVER_MODULE(ukphy, miibus, ukphy_driver, ukphy_devclass, 0, 0);
     113
     114static int  ukphy_service(struct mii_softc *, struct mii_data *, int);
     115
     116static int
     117ukphy_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
     127static int
     128ukphy_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
     168static int
     169ukphy_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/marvell_yukon_sk/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/marvell_yukon_sk/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
     60static int xmphy_probe(device_t);
     61static int xmphy_attach(device_t);
     62
     63static 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
     72static devclass_t xmphy_devclass;
     73
     74static driver_t xmphy_driver = {
     75    "xmphy",
     76    xmphy_methods,
     77    sizeof(struct mii_softc)
     78};
     79
     80DRIVER_MODULE(xmphy, miibus, xmphy_driver, xmphy_devclass, 0, 0);
     81
     82static int  xmphy_service(struct mii_softc *, struct mii_data *, int);
     83static void xmphy_status(struct mii_softc *);
     84static int  xmphy_mii_phy_auto(struct mii_softc *);
     85
     86static 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
     92static int
     93xmphy_probe(device_t dev)
     94{
     95
     96    return (mii_phy_dev_probe(dev, xmphys, BUS_PROBE_DEFAULT));
     97}
     98
     99static int
     100xmphy_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
     150static int
     151xmphy_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
     260static void
     261xmphy_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
     311static int
     312xmphy_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/marvell_yukon_sk/dev/mii/Jamfile

     
     1SubDir HAIKU_TOP src add-ons kernel drivers network marvell_yukon_sk dev mii ;
     2
     3UsePrivateHeaders kernel net ;
     4
     5UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ;
     6UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ;
     7
     8SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ;
     9
     10KernelStaticLibrary marvell_yukon_sk_mii.a
     11    :
     12    xmphy.c
     13    e1000phy.c
     14    ukphy.c
     15    ukphy_subr.c
     16    ;
     17
  • src/add-ons/kernel/drivers/network/marvell_yukon_sk/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
     65static int  e1000phy_probe(device_t);
     66static int  e1000phy_attach(device_t);
     67
     68struct e1000phy_softc {
     69    struct mii_softc mii_sc;
     70    int mii_model;
     71};
     72
     73static 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
     82static devclass_t e1000phy_devclass;
     83static driver_t e1000phy_driver = {
     84    "e1000phy",
     85    e1000phy_methods,
     86    sizeof(struct e1000phy_softc)
     87};
     88
     89DRIVER_MODULE(e1000phy, miibus, e1000phy_driver, e1000phy_devclass, 0, 0);
     90
     91static int  e1000phy_service(struct mii_softc *, struct mii_data *, int);
     92static void e1000phy_status(struct mii_softc *);
     93static void e1000phy_reset(struct mii_softc *);
     94static int  e1000phy_mii_phy_auto(struct e1000phy_softc *);
     95
     96static 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
     117static int
     118e1000phy_probe(device_t dev)
     119{
     120
     121    return (mii_phy_dev_probe(dev, e1000phys, BUS_PROBE_DEFAULT));
     122}
     123
     124static int
     125e1000phy_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
     208static void
     209e1000phy_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
     274static int
     275e1000phy_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);
     372done:
     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
     421static void
     422e1000phy_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
     493static int
     494e1000phy_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/marvell_yukon_sk/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/marvell_yukon_sk/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/marvell_yukon_sk/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 */
     65void
     66ukphy_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}