2 * Copyright (c) 2002 Myson Technology Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions, and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. The name of the author may not be used to endorse or promote products
12 * derived from this software without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * Written by: yen_cw@myson.com.tw available at: http://www.myson.com.tw/
28 * $FreeBSD: src/sys/dev/my/if_my.c,v 1.2.2.4 2002/04/17 02:05:27 julian Exp $
29 * $DragonFly: src/sys/dev/netif/my/if_my.c,v 1.31 2008/08/17 04:32:34 sephe Exp $
31 * Myson fast ethernet PCI NIC driver
33 * $Id: if_my.c,v 1.40 2001/11/30 03:55:00 <yen_cw@myson.com.tw> wpaul Exp $
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/sockio.h>
39 #include <sys/malloc.h>
40 #include <sys/kernel.h>
41 #include <sys/interrupt.h>
42 #include <sys/socket.h>
43 #include <sys/queue.h>
45 #include <sys/module.h>
46 #include <sys/serialize.h>
50 #include <sys/thread2.h>
53 #include <net/ifq_var.h>
54 #include <net/if_arp.h>
55 #include <net/ethernet.h>
56 #include <net/if_media.h>
57 #include <net/if_dl.h>
60 #include <vm/vm.h> /* for vtophys */
61 #include <vm/pmap.h> /* for vtophys */
62 #include <machine/clock.h> /* for DELAY */
64 #include <bus/pci/pcireg.h>
65 #include <bus/pci/pcivar.h>
68 * #define MY_USEIOSPACE
71 static int MY_USEIOSPACE
= 1;
74 #define MY_RES SYS_RES_IOPORT
75 #define MY_RID MY_PCI_LOIO
77 #define MY_RES SYS_RES_MEMORY
78 #define MY_RID MY_PCI_LOMEM
85 * Various supported device vendors/types and their names.
87 static struct my_type my_devs
[] = {
88 {MYSONVENDORID
, MTD800ID
, "Myson MTD80X Based Fast Ethernet Card"},
89 {MYSONVENDORID
, MTD803ID
, "Myson MTD80X Based Fast Ethernet Card"},
90 {MYSONVENDORID
, MTD891ID
, "Myson MTD89X Based Giga Ethernet Card"},
95 * Various supported PHY vendors/types and their names. Note that this driver
96 * will work with pretty much any MII-compliant PHY, so failure to positively
97 * identify the chip is not a fatal error.
99 static struct my_type my_phys
[] = {
100 {MysonPHYID0
, MysonPHYID0
, "<MYSON MTD981>"},
101 {SeeqPHYID0
, SeeqPHYID0
, "<SEEQ 80225>"},
102 {AhdocPHYID0
, AhdocPHYID0
, "<AHDOC 101>"},
103 {MarvellPHYID0
, MarvellPHYID0
, "<MARVELL 88E1000>"},
104 {LevelOnePHYID0
, LevelOnePHYID0
, "<LevelOne LXT1000>"},
105 {0, 0, "<MII-compliant physical interface>"}
108 static int my_probe(device_t
);
109 static int my_attach(device_t
);
110 static int my_detach(device_t
);
111 static int my_newbuf(struct my_softc
*, struct my_chain_onefrag
*);
112 static int my_encap(struct my_softc
*, struct my_chain
*, struct mbuf
*);
113 static void my_rxeof(struct my_softc
*);
114 static void my_txeof(struct my_softc
*);
115 static void my_txeoc(struct my_softc
*);
116 static void my_intr(void *);
117 static void my_start(struct ifnet
*);
118 static int my_ioctl(struct ifnet
*, u_long
, caddr_t
, struct ucred
*);
119 static void my_init(void *);
120 static void my_stop(struct my_softc
*);
121 static void my_watchdog(struct ifnet
*);
122 static void my_shutdown(device_t
);
123 static int my_ifmedia_upd(struct ifnet
*);
124 static void my_ifmedia_sts(struct ifnet
*, struct ifmediareq
*);
125 static u_int16_t
my_phy_readreg(struct my_softc
*, int);
126 static void my_phy_writereg(struct my_softc
*, int, int);
127 static void my_autoneg_xmit(struct my_softc
*);
128 static void my_autoneg_mii(struct my_softc
*, int, int);
129 static void my_setmode_mii(struct my_softc
*, int);
130 static void my_getmode_mii(struct my_softc
*);
131 static void my_setcfg(struct my_softc
*, int);
132 static u_int8_t
my_calchash(caddr_t
);
133 static void my_setmulti(struct my_softc
*);
134 static void my_reset(struct my_softc
*);
135 static int my_list_rx_init(struct my_softc
*);
136 static int my_list_tx_init(struct my_softc
*);
137 static long my_send_cmd_to_phy(struct my_softc
*, int, int);
139 #define MY_SETBIT(sc, reg, x) CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | x)
140 #define MY_CLRBIT(sc, reg, x) CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~x)
142 static device_method_t my_methods
[] = {
143 /* Device interface */
144 DEVMETHOD(device_probe
, my_probe
),
145 DEVMETHOD(device_attach
, my_attach
),
146 DEVMETHOD(device_detach
, my_detach
),
147 DEVMETHOD(device_shutdown
, my_shutdown
),
152 static driver_t my_driver
= {
155 sizeof(struct my_softc
)
158 static devclass_t my_devclass
;
160 DECLARE_DUMMY_MODULE(if_my
);
161 DRIVER_MODULE(if_my
, pci
, my_driver
, my_devclass
, 0, 0);
164 my_send_cmd_to_phy(struct my_softc
* sc
, int opcode
, int regad
)
170 /* enable MII output */
171 miir
= CSR_READ_4(sc
, MY_MANAGEMENT
);
174 miir
|= MY_MASK_MIIR_MII_WRITE
+ MY_MASK_MIIR_MII_MDO
;
176 /* send 32 1's preamble */
177 for (i
= 0; i
< 32; i
++) {
178 /* low MDC; MDO is already high (miir) */
179 miir
&= ~MY_MASK_MIIR_MII_MDC
;
180 CSR_WRITE_4(sc
, MY_MANAGEMENT
, miir
);
183 miir
|= MY_MASK_MIIR_MII_MDC
;
184 CSR_WRITE_4(sc
, MY_MANAGEMENT
, miir
);
187 /* calculate ST+OP+PHYAD+REGAD+TA */
188 data
= opcode
| (sc
->my_phy_addr
<< 7) | (regad
<< 2);
193 /* low MDC, prepare MDO */
194 miir
&= ~(MY_MASK_MIIR_MII_MDC
+ MY_MASK_MIIR_MII_MDO
);
196 miir
|= MY_MASK_MIIR_MII_MDO
;
198 CSR_WRITE_4(sc
, MY_MANAGEMENT
, miir
);
200 miir
|= MY_MASK_MIIR_MII_MDC
;
201 CSR_WRITE_4(sc
, MY_MANAGEMENT
, miir
);
206 if (mask
== 0x2 && opcode
== MY_OP_READ
)
207 miir
&= ~MY_MASK_MIIR_MII_WRITE
;
215 my_phy_readreg(struct my_softc
* sc
, int reg
)
220 if (sc
->my_info
->my_did
== MTD803ID
)
221 data
= CSR_READ_2(sc
, MY_PHYBASE
+ reg
* 2);
223 miir
= my_send_cmd_to_phy(sc
, MY_OP_READ
, reg
);
230 miir
&= ~MY_MASK_MIIR_MII_MDC
;
231 CSR_WRITE_4(sc
, MY_MANAGEMENT
, miir
);
234 miir
= CSR_READ_4(sc
, MY_MANAGEMENT
);
235 if (miir
& MY_MASK_MIIR_MII_MDI
)
238 /* high MDC, and wait */
239 miir
|= MY_MASK_MIIR_MII_MDC
;
240 CSR_WRITE_4(sc
, MY_MANAGEMENT
, miir
);
248 miir
&= ~MY_MASK_MIIR_MII_MDC
;
249 CSR_WRITE_4(sc
, MY_MANAGEMENT
, miir
);
252 return (u_int16_t
) data
;
257 my_phy_writereg(struct my_softc
* sc
, int reg
, int data
)
262 if (sc
->my_info
->my_did
== MTD803ID
)
263 CSR_WRITE_2(sc
, MY_PHYBASE
+ reg
* 2, data
);
265 miir
= my_send_cmd_to_phy(sc
, MY_OP_WRITE
, reg
);
270 /* low MDC, prepare MDO */
271 miir
&= ~(MY_MASK_MIIR_MII_MDC
+ MY_MASK_MIIR_MII_MDO
);
273 miir
|= MY_MASK_MIIR_MII_MDO
;
274 CSR_WRITE_4(sc
, MY_MANAGEMENT
, miir
);
278 miir
|= MY_MASK_MIIR_MII_MDC
;
279 CSR_WRITE_4(sc
, MY_MANAGEMENT
, miir
);
287 miir
&= ~MY_MASK_MIIR_MII_MDC
;
288 CSR_WRITE_4(sc
, MY_MANAGEMENT
, miir
);
293 my_calchash(caddr_t addr
)
295 u_int32_t crc
, carry
;
299 /* Compute CRC for the address value. */
300 crc
= 0xFFFFFFFF; /* initial value */
302 for (i
= 0; i
< 6; i
++) {
304 for (j
= 0; j
< 8; j
++) {
305 carry
= ((crc
& 0x80000000) ? 1 : 0) ^ (c
& 0x01);
309 crc
= (crc
^ 0x04c11db6) | carry
;
314 * return the filter bit position Note: I arrived at the following
315 * nonsense through experimentation. It's not the usual way to
316 * generate the bit position but it's the only thing I could come up
319 return (~(crc
>> 26) & 0x0000003F);
324 * Program the 64-bit multicast hash filter.
327 my_setmulti(struct my_softc
* sc
)
329 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
331 u_int32_t hashes
[2] = {0, 0};
332 struct ifmultiaddr
*ifma
;
336 rxfilt
= CSR_READ_4(sc
, MY_TCRRCR
);
338 if (ifp
->if_flags
& IFF_ALLMULTI
|| ifp
->if_flags
& IFF_PROMISC
) {
340 CSR_WRITE_4(sc
, MY_TCRRCR
, rxfilt
);
341 CSR_WRITE_4(sc
, MY_MAR0
, 0xFFFFFFFF);
342 CSR_WRITE_4(sc
, MY_MAR1
, 0xFFFFFFFF);
346 /* first, zot all the existing hash bits */
347 CSR_WRITE_4(sc
, MY_MAR0
, 0);
348 CSR_WRITE_4(sc
, MY_MAR1
, 0);
350 /* now program new ones */
351 LIST_FOREACH(ifma
, &ifp
->if_multiaddrs
, ifma_link
) {
352 if (ifma
->ifma_addr
->sa_family
!= AF_LINK
)
354 h
= my_calchash(LLADDR((struct sockaddr_dl
*) ifma
->ifma_addr
));
356 hashes
[0] |= (1 << h
);
358 hashes
[1] |= (1 << (h
- 32));
366 CSR_WRITE_4(sc
, MY_MAR0
, hashes
[0]);
367 CSR_WRITE_4(sc
, MY_MAR1
, hashes
[1]);
368 CSR_WRITE_4(sc
, MY_TCRRCR
, rxfilt
);
372 * Initiate an autonegotiation session.
375 my_autoneg_xmit(struct my_softc
* sc
)
377 u_int16_t phy_sts
= 0;
379 my_phy_writereg(sc
, PHY_BMCR
, PHY_BMCR_RESET
);
381 while (my_phy_readreg(sc
, PHY_BMCR
) & PHY_BMCR_RESET
);
383 phy_sts
= my_phy_readreg(sc
, PHY_BMCR
);
384 phy_sts
|= PHY_BMCR_AUTONEGENBL
| PHY_BMCR_AUTONEGRSTR
;
385 my_phy_writereg(sc
, PHY_BMCR
, phy_sts
);
390 * Invoke autonegotiation on a PHY.
393 my_autoneg_mii(struct my_softc
* sc
, int flag
, int verbose
)
395 u_int16_t phy_sts
= 0, media
, advert
, ability
;
396 u_int16_t ability2
= 0;
397 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
398 struct ifmedia
*ifm
= &sc
->ifmedia
;
400 ifm
->ifm_media
= IFM_ETHER
| IFM_AUTO
;
402 #ifndef FORCE_AUTONEG_TFOUR
404 * First, see if autoneg is supported. If not, there's no point in
407 phy_sts
= my_phy_readreg(sc
, PHY_BMSR
);
408 if (!(phy_sts
& PHY_BMSR_CANAUTONEG
)) {
410 kprintf("my%d: autonegotiation not supported\n",
412 ifm
->ifm_media
= IFM_ETHER
| IFM_10_T
| IFM_HDX
;
417 case MY_FLAG_FORCEDELAY
:
419 * XXX Never use this option anywhere but in the probe
420 * routine: making the kernel stop dead in its tracks for
421 * three whole seconds after we've gone multi-user is really
427 case MY_FLAG_SCHEDDELAY
:
429 * Wait for the transmitter to go idle before starting an
430 * autoneg session, otherwise my_start() may clobber our
431 * timeout, and we don't want to allow transmission during an
432 * autoneg session since that can screw it up.
434 if (sc
->my_cdata
.my_tx_head
!= NULL
) {
435 sc
->my_want_auto
= 1;
441 sc
->my_want_auto
= 0;
443 case MY_FLAG_DELAYTIMEO
:
448 kprintf("my%d: invalid autoneg flag: %d\n", sc
->my_unit
, flag
);
452 if (my_phy_readreg(sc
, PHY_BMSR
) & PHY_BMSR_AUTONEGCOMP
) {
454 kprintf("my%d: autoneg complete, ", sc
->my_unit
);
455 phy_sts
= my_phy_readreg(sc
, PHY_BMSR
);
458 kprintf("my%d: autoneg not complete, ", sc
->my_unit
);
461 media
= my_phy_readreg(sc
, PHY_BMCR
);
463 /* Link is good. Report modes and set duplex mode. */
464 if (my_phy_readreg(sc
, PHY_BMSR
) & PHY_BMSR_LINKSTAT
) {
466 kprintf("my%d: link status good. ", sc
->my_unit
);
467 advert
= my_phy_readreg(sc
, PHY_ANAR
);
468 ability
= my_phy_readreg(sc
, PHY_LPAR
);
469 if ((sc
->my_pinfo
->my_vid
== MarvellPHYID0
) ||
470 (sc
->my_pinfo
->my_vid
== LevelOnePHYID0
)) {
471 ability2
= my_phy_readreg(sc
, PHY_1000SR
);
472 if (ability2
& PHY_1000SR_1000BTXFULL
) {
476 * this version did not support 1000M,
478 * IFM_ETHER | IFM_1000_T | IFM_FDX;
481 IFM_ETHER
| IFM_100_TX
| IFM_FDX
;
482 media
&= ~PHY_BMCR_SPEEDSEL
;
483 media
|= PHY_BMCR_1000
;
484 media
|= PHY_BMCR_DUPLEX
;
485 kprintf("(full-duplex, 1000Mbps)\n");
486 } else if (ability2
& PHY_1000SR_1000BTXHALF
) {
490 * this version did not support 1000M,
491 * ifm->ifm_media = IFM_ETHER | IFM_1000_T;
493 ifm
->ifm_media
= IFM_ETHER
| IFM_100_TX
;
494 media
&= ~PHY_BMCR_SPEEDSEL
;
495 media
&= ~PHY_BMCR_DUPLEX
;
496 media
|= PHY_BMCR_1000
;
497 kprintf("(half-duplex, 1000Mbps)\n");
500 if (advert
& PHY_ANAR_100BT4
&& ability
& PHY_ANAR_100BT4
) {
501 ifm
->ifm_media
= IFM_ETHER
| IFM_100_T4
;
502 media
|= PHY_BMCR_SPEEDSEL
;
503 media
&= ~PHY_BMCR_DUPLEX
;
504 kprintf("(100baseT4)\n");
505 } else if (advert
& PHY_ANAR_100BTXFULL
&&
506 ability
& PHY_ANAR_100BTXFULL
) {
507 ifm
->ifm_media
= IFM_ETHER
| IFM_100_TX
| IFM_FDX
;
508 media
|= PHY_BMCR_SPEEDSEL
;
509 media
|= PHY_BMCR_DUPLEX
;
510 kprintf("(full-duplex, 100Mbps)\n");
511 } else if (advert
& PHY_ANAR_100BTXHALF
&&
512 ability
& PHY_ANAR_100BTXHALF
) {
513 ifm
->ifm_media
= IFM_ETHER
| IFM_100_TX
| IFM_HDX
;
514 media
|= PHY_BMCR_SPEEDSEL
;
515 media
&= ~PHY_BMCR_DUPLEX
;
516 kprintf("(half-duplex, 100Mbps)\n");
517 } else if (advert
& PHY_ANAR_10BTFULL
&&
518 ability
& PHY_ANAR_10BTFULL
) {
519 ifm
->ifm_media
= IFM_ETHER
| IFM_10_T
| IFM_FDX
;
520 media
&= ~PHY_BMCR_SPEEDSEL
;
521 media
|= PHY_BMCR_DUPLEX
;
522 kprintf("(full-duplex, 10Mbps)\n");
524 ifm
->ifm_media
= IFM_ETHER
| IFM_10_T
| IFM_HDX
;
525 media
&= ~PHY_BMCR_SPEEDSEL
;
526 media
&= ~PHY_BMCR_DUPLEX
;
527 kprintf("(half-duplex, 10Mbps)\n");
529 media
&= ~PHY_BMCR_AUTONEGENBL
;
531 /* Set ASIC's duplex mode to match the PHY. */
532 my_phy_writereg(sc
, PHY_BMCR
, media
);
533 my_setcfg(sc
, media
);
536 kprintf("my%d: no carrier\n", sc
->my_unit
);
540 if (sc
->my_tx_pend
) {
548 * To get PHY ability.
551 my_getmode_mii(struct my_softc
* sc
)
553 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
556 bmsr
= my_phy_readreg(sc
, PHY_BMSR
);
558 kprintf("my%d: PHY status word: %x\n", sc
->my_unit
, bmsr
);
561 sc
->ifmedia
.ifm_media
= IFM_ETHER
| IFM_10_T
| IFM_HDX
;
563 if (bmsr
& PHY_BMSR_10BTHALF
) {
565 kprintf("my%d: 10Mbps half-duplex mode supported\n",
567 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_10_T
| IFM_HDX
,
569 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_10_T
, 0, NULL
);
571 if (bmsr
& PHY_BMSR_10BTFULL
) {
573 kprintf("my%d: 10Mbps full-duplex mode supported\n",
576 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_10_T
| IFM_FDX
,
578 sc
->ifmedia
.ifm_media
= IFM_ETHER
| IFM_10_T
| IFM_FDX
;
580 if (bmsr
& PHY_BMSR_100BTXHALF
) {
582 kprintf("my%d: 100Mbps half-duplex mode supported\n",
584 ifp
->if_baudrate
= 100000000;
585 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_100_TX
, 0, NULL
);
586 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_100_TX
| IFM_HDX
,
588 sc
->ifmedia
.ifm_media
= IFM_ETHER
| IFM_100_TX
| IFM_HDX
;
590 if (bmsr
& PHY_BMSR_100BTXFULL
) {
592 kprintf("my%d: 100Mbps full-duplex mode supported\n",
594 ifp
->if_baudrate
= 100000000;
595 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_100_TX
| IFM_FDX
,
597 sc
->ifmedia
.ifm_media
= IFM_ETHER
| IFM_100_TX
| IFM_FDX
;
599 /* Some also support 100BaseT4. */
600 if (bmsr
& PHY_BMSR_100BT4
) {
602 kprintf("my%d: 100baseT4 mode supported\n", sc
->my_unit
);
603 ifp
->if_baudrate
= 100000000;
604 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_100_T4
, 0, NULL
);
605 sc
->ifmedia
.ifm_media
= IFM_ETHER
| IFM_100_T4
;
606 #ifdef FORCE_AUTONEG_TFOUR
608 kprintf("my%d: forcing on autoneg support for BT4\n",
610 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_AUTO
, 0 NULL
):
611 sc
->ifmedia
.ifm_media
= IFM_ETHER
| IFM_AUTO
;
614 #if 0 /* this version did not support 1000M, */
615 if (sc
->my_pinfo
->my_vid
== MarvellPHYID0
) {
617 kprintf("my%d: 1000Mbps half-duplex mode supported\n",
620 ifp
->if_baudrate
= 1000000000;
621 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_1000_T
, 0, NULL
);
622 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_1000_T
| IFM_HDX
,
625 kprintf("my%d: 1000Mbps full-duplex mode supported\n",
627 ifp
->if_baudrate
= 1000000000;
628 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_1000_T
| IFM_FDX
,
630 sc
->ifmedia
.ifm_media
= IFM_ETHER
| IFM_1000_T
| IFM_FDX
;
633 if (bmsr
& PHY_BMSR_CANAUTONEG
) {
635 kprintf("my%d: autoneg supported\n", sc
->my_unit
);
636 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
| IFM_AUTO
, 0, NULL
);
637 sc
->ifmedia
.ifm_media
= IFM_ETHER
| IFM_AUTO
;
642 * Set speed and duplex mode.
645 my_setmode_mii(struct my_softc
* sc
, int media
)
647 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
651 * If an autoneg session is in progress, stop it.
653 if (sc
->my_autoneg
) {
654 kprintf("my%d: canceling autoneg session\n", sc
->my_unit
);
655 ifp
->if_timer
= sc
->my_autoneg
= sc
->my_want_auto
= 0;
656 bmcr
= my_phy_readreg(sc
, PHY_BMCR
);
657 bmcr
&= ~PHY_BMCR_AUTONEGENBL
;
658 my_phy_writereg(sc
, PHY_BMCR
, bmcr
);
660 kprintf("my%d: selecting MII, ", sc
->my_unit
);
661 bmcr
= my_phy_readreg(sc
, PHY_BMCR
);
662 bmcr
&= ~(PHY_BMCR_AUTONEGENBL
| PHY_BMCR_SPEEDSEL
| PHY_BMCR_1000
|
663 PHY_BMCR_DUPLEX
| PHY_BMCR_LOOPBK
);
665 #if 0 /* this version did not support 1000M, */
666 if (IFM_SUBTYPE(media
) == IFM_1000_T
) {
667 kprintf("1000Mbps/T4, half-duplex\n");
668 bmcr
&= ~PHY_BMCR_SPEEDSEL
;
669 bmcr
&= ~PHY_BMCR_DUPLEX
;
670 bmcr
|= PHY_BMCR_1000
;
673 if (IFM_SUBTYPE(media
) == IFM_100_T4
) {
674 kprintf("100Mbps/T4, half-duplex\n");
675 bmcr
|= PHY_BMCR_SPEEDSEL
;
676 bmcr
&= ~PHY_BMCR_DUPLEX
;
678 if (IFM_SUBTYPE(media
) == IFM_100_TX
) {
679 kprintf("100Mbps, ");
680 bmcr
|= PHY_BMCR_SPEEDSEL
;
682 if (IFM_SUBTYPE(media
) == IFM_10_T
) {
684 bmcr
&= ~PHY_BMCR_SPEEDSEL
;
686 if ((media
& IFM_GMASK
) == IFM_FDX
) {
687 kprintf("full duplex\n");
688 bmcr
|= PHY_BMCR_DUPLEX
;
690 kprintf("half duplex\n");
691 bmcr
&= ~PHY_BMCR_DUPLEX
;
693 my_phy_writereg(sc
, PHY_BMCR
, bmcr
);
698 * The Myson manual states that in order to fiddle with the 'full-duplex' and
699 * '100Mbps' bits in the netconfig register, we first have to put the
700 * transmit and/or receive logic in the idle state.
703 my_setcfg(struct my_softc
* sc
, int bmcr
)
707 if (CSR_READ_4(sc
, MY_TCRRCR
) & (MY_TE
| MY_RE
)) {
709 MY_CLRBIT(sc
, MY_TCRRCR
, (MY_TE
| MY_RE
));
710 for (i
= 0; i
< MY_TIMEOUT
; i
++) {
712 if (!(CSR_READ_4(sc
, MY_TCRRCR
) &
713 (MY_TXRUN
| MY_RXRUN
)))
717 kprintf("my%d: failed to force tx and rx to idle \n",
720 MY_CLRBIT(sc
, MY_TCRRCR
, MY_PS1000
);
721 MY_CLRBIT(sc
, MY_TCRRCR
, MY_PS10
);
722 if (bmcr
& PHY_BMCR_1000
)
723 MY_SETBIT(sc
, MY_TCRRCR
, MY_PS1000
);
724 else if (!(bmcr
& PHY_BMCR_SPEEDSEL
))
725 MY_SETBIT(sc
, MY_TCRRCR
, MY_PS10
);
726 if (bmcr
& PHY_BMCR_DUPLEX
)
727 MY_SETBIT(sc
, MY_TCRRCR
, MY_FD
);
729 MY_CLRBIT(sc
, MY_TCRRCR
, MY_FD
);
731 MY_SETBIT(sc
, MY_TCRRCR
, MY_TE
| MY_RE
);
735 my_reset(struct my_softc
* sc
)
739 MY_SETBIT(sc
, MY_BCR
, MY_SWR
);
740 for (i
= 0; i
< MY_TIMEOUT
; i
++) {
742 if (!(CSR_READ_4(sc
, MY_BCR
) & MY_SWR
))
746 kprintf("m0x%d: reset never completed!\n", sc
->my_unit
);
748 /* Wait a little while for the chip to get its brains in order. */
753 * Probe for a Myson chip. Check the PCI vendor and device IDs against our
754 * list and return a device name if we find a match.
757 my_probe(device_t dev
)
760 uint16_t vendor
, product
;
762 vendor
= pci_get_vendor(dev
);
763 product
= pci_get_device(dev
);
765 for (t
= my_devs
; t
->my_name
!= NULL
; t
++) {
766 if (vendor
== t
->my_vid
&& product
== t
->my_did
) {
767 device_set_desc(dev
, t
->my_name
);
776 * Attach the interface. Allocate softc structures, do ifmedia setup and
777 * ethernet/BPF attach.
780 my_attach(device_t dev
)
783 u_char eaddr
[ETHER_ADDR_LEN
];
784 u_int32_t command
, iobase
;
787 int media
= IFM_ETHER
| IFM_100_TX
| IFM_FDX
;
791 u_int16_t phy_vid
, phy_did
, phy_sts
= 0;
792 int rid
, unit
, error
= 0;
794 uint16_t vendor
, product
;
796 vendor
= pci_get_vendor(dev
);
797 product
= pci_get_device(dev
);
799 for (t
= my_devs
; t
->my_name
!= NULL
; t
++) {
800 if (vendor
== t
->my_vid
&& product
== t
->my_did
)
804 if (t
->my_name
== NULL
)
807 sc
= device_get_softc(dev
);
808 unit
= device_get_unit(dev
);
811 * Map control/status registers.
813 command
= pci_read_config(dev
, PCIR_COMMAND
, 4);
814 command
|= (PCIM_CMD_PORTEN
| PCIM_CMD_MEMEN
| PCIM_CMD_BUSMASTEREN
);
815 pci_write_config(dev
, PCIR_COMMAND
, command
& 0x000000ff, 4);
816 command
= pci_read_config(dev
, PCIR_COMMAND
, 4);
818 if (t
->my_did
== MTD800ID
) {
819 iobase
= pci_read_config(dev
, MY_PCI_LOIO
, 4);
824 if (!(command
& PCIM_CMD_PORTEN
)) {
825 kprintf("my%d: failed to enable I/O ports!\n", unit
);
830 if (!(command
& PCIM_CMD_MEMEN
)) {
831 kprintf("my%d: failed to enable memory mapping!\n",
839 sc
->my_res
= bus_alloc_resource_any(dev
, MY_RES
, &rid
, RF_ACTIVE
);
841 if (sc
->my_res
== NULL
) {
842 kprintf("my%d: couldn't map ports/memory\n", unit
);
846 sc
->my_btag
= rman_get_bustag(sc
->my_res
);
847 sc
->my_bhandle
= rman_get_bushandle(sc
->my_res
);
850 sc
->my_irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &rid
,
851 RF_SHAREABLE
| RF_ACTIVE
);
853 if (sc
->my_irq
== NULL
) {
854 kprintf("my%d: couldn't map interrupt\n", unit
);
861 /* Reset the adapter. */
865 * Get station address
867 for (i
= 0; i
< ETHER_ADDR_LEN
; ++i
)
868 eaddr
[i
] = CSR_READ_1(sc
, MY_PAR0
+ i
);
872 sc
->my_ldata_ptr
= kmalloc(sizeof(struct my_list_data
) + 8,
874 sc
->my_ldata
= (struct my_list_data
*) sc
->my_ldata_ptr
;
875 round
= (uintptr_t)sc
->my_ldata_ptr
& 0xF;
876 roundptr
= sc
->my_ldata_ptr
;
877 for (i
= 0; i
< 8; i
++) {
884 sc
->my_ldata
= (struct my_list_data
*) roundptr
;
885 bzero(sc
->my_ldata
, sizeof(struct my_list_data
));
887 ifp
= &sc
->arpcom
.ac_if
;
889 if_initname(ifp
, "my", unit
);
890 ifp
->if_mtu
= ETHERMTU
;
891 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
892 ifp
->if_ioctl
= my_ioctl
;
893 ifp
->if_start
= my_start
;
894 ifp
->if_watchdog
= my_watchdog
;
895 ifp
->if_init
= my_init
;
896 ifp
->if_baudrate
= 10000000;
897 ifq_set_maxlen(&ifp
->if_snd
, IFQ_MAXLEN
);
898 ifq_set_ready(&ifp
->if_snd
);
900 if (sc
->my_info
->my_did
== MTD803ID
)
901 sc
->my_pinfo
= my_phys
;
904 kprintf("my%d: probing for a PHY\n", sc
->my_unit
);
905 for (i
= MY_PHYADDR_MIN
; i
< MY_PHYADDR_MAX
+ 1; i
++) {
907 kprintf("my%d: checking address: %d\n",
910 phy_sts
= my_phy_readreg(sc
, PHY_BMSR
);
911 if ((phy_sts
!= 0) && (phy_sts
!= 0xffff))
917 phy_vid
= my_phy_readreg(sc
, PHY_VENID
);
918 phy_did
= my_phy_readreg(sc
, PHY_DEVID
);
920 kprintf("my%d: found PHY at address %d, ",
921 sc
->my_unit
, sc
->my_phy_addr
);
922 kprintf("vendor id: %x device id: %x\n",
927 if (phy_vid
== p
->my_vid
) {
933 if (sc
->my_pinfo
== NULL
)
934 sc
->my_pinfo
= &my_phys
[PHY_UNKNOWN
];
936 kprintf("my%d: PHY type: %s\n",
937 sc
->my_unit
, sc
->my_pinfo
->my_name
);
939 kprintf("my%d: MII without any phy!\n", sc
->my_unit
);
945 /* Do ifmedia setup. */
946 ifmedia_init(&sc
->ifmedia
, 0, my_ifmedia_upd
, my_ifmedia_sts
);
948 my_autoneg_mii(sc
, MY_FLAG_FORCEDELAY
, 1);
949 media
= sc
->ifmedia
.ifm_media
;
951 ifmedia_set(&sc
->ifmedia
, media
);
953 ether_ifattach(ifp
, eaddr
, NULL
);
955 error
= bus_setup_intr(dev
, sc
->my_irq
, INTR_MPSAFE
,
956 my_intr
, sc
, &sc
->my_intrhand
,
960 kprintf("my%d: couldn't set up irq\n", unit
);
964 ifp
->if_cpuid
= ithread_cpuid(rman_get_start(sc
->my_irq
));
965 KKASSERT(ifp
->if_cpuid
>= 0 && ifp
->if_cpuid
< ncpus
);
975 my_detach(device_t dev
)
977 struct my_softc
*sc
= device_get_softc(dev
);
978 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
980 if (device_is_attached(dev
)) {
981 lwkt_serialize_enter(ifp
->if_serializer
);
983 bus_teardown_intr(dev
, sc
->my_irq
, sc
->my_intrhand
);
984 lwkt_serialize_exit(ifp
->if_serializer
);
990 bus_release_resource(dev
, SYS_RES_IRQ
, 0, sc
->my_irq
);
992 bus_release_resource(dev
, MY_RES
, MY_RID
, sc
->my_res
);
999 * Initialize the transmit descriptors.
1002 my_list_tx_init(struct my_softc
* sc
)
1004 struct my_chain_data
*cd
;
1005 struct my_list_data
*ld
;
1010 for (i
= 0; i
< MY_TX_LIST_CNT
; i
++) {
1011 cd
->my_tx_chain
[i
].my_ptr
= &ld
->my_tx_list
[i
];
1012 if (i
== (MY_TX_LIST_CNT
- 1))
1013 cd
->my_tx_chain
[i
].my_nextdesc
= &cd
->my_tx_chain
[0];
1015 cd
->my_tx_chain
[i
].my_nextdesc
=
1016 &cd
->my_tx_chain
[i
+ 1];
1018 cd
->my_tx_free
= &cd
->my_tx_chain
[0];
1019 cd
->my_tx_tail
= cd
->my_tx_head
= NULL
;
1024 * Initialize the RX descriptors and allocate mbufs for them. Note that we
1025 * arrange the descriptors in a closed ring, so that the last descriptor
1026 * points back to the first.
1029 my_list_rx_init(struct my_softc
* sc
)
1031 struct my_chain_data
*cd
;
1032 struct my_list_data
*ld
;
1037 for (i
= 0; i
< MY_RX_LIST_CNT
; i
++) {
1038 cd
->my_rx_chain
[i
].my_ptr
=
1039 (struct my_desc
*) & ld
->my_rx_list
[i
];
1040 if (my_newbuf(sc
, &cd
->my_rx_chain
[i
]) == ENOBUFS
)
1042 if (i
== (MY_RX_LIST_CNT
- 1)) {
1043 cd
->my_rx_chain
[i
].my_nextdesc
= &cd
->my_rx_chain
[0];
1044 ld
->my_rx_list
[i
].my_next
= vtophys(&ld
->my_rx_list
[0]);
1046 cd
->my_rx_chain
[i
].my_nextdesc
=
1047 &cd
->my_rx_chain
[i
+ 1];
1048 ld
->my_rx_list
[i
].my_next
=
1049 vtophys(&ld
->my_rx_list
[i
+ 1]);
1052 cd
->my_rx_head
= &cd
->my_rx_chain
[0];
1057 * Initialize an RX descriptor and attach an MBUF cluster.
1060 my_newbuf(struct my_softc
* sc
, struct my_chain_onefrag
* c
)
1062 struct mbuf
*m_new
= NULL
;
1064 MGETHDR(m_new
, MB_DONTWAIT
, MT_DATA
);
1065 if (m_new
== NULL
) {
1066 kprintf("my%d: no memory for rx list -- packet dropped!\n",
1070 MCLGET(m_new
, MB_DONTWAIT
);
1071 if (!(m_new
->m_flags
& M_EXT
)) {
1072 kprintf("my%d: no memory for rx list -- packet dropped!\n",
1078 c
->my_ptr
->my_data
= vtophys(mtod(m_new
, caddr_t
));
1079 c
->my_ptr
->my_ctl
= (MCLBYTES
- 1) << MY_RBSShift
;
1080 c
->my_ptr
->my_status
= MY_OWNByNIC
;
1085 * A frame has been uploaded: pass the resulting mbuf chain up to the higher
1089 my_rxeof(struct my_softc
* sc
)
1092 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1093 struct my_chain_onefrag
*cur_rx
;
1097 while (!((rxstat
= sc
->my_cdata
.my_rx_head
->my_ptr
->my_status
)
1099 cur_rx
= sc
->my_cdata
.my_rx_head
;
1100 sc
->my_cdata
.my_rx_head
= cur_rx
->my_nextdesc
;
1102 if (rxstat
& MY_ES
) { /* error summary: give up this rx pkt */
1104 cur_rx
->my_ptr
->my_status
= MY_OWNByNIC
;
1107 /* No errors; receive the packet. */
1108 total_len
= (rxstat
& MY_FLNGMASK
) >> MY_FLNGShift
;
1109 total_len
-= ETHER_CRC_LEN
;
1111 if (total_len
< MINCLSIZE
) {
1112 m
= m_devget(mtod(cur_rx
->my_mbuf
, char *),
1113 total_len
, 0, ifp
, NULL
);
1114 cur_rx
->my_ptr
->my_status
= MY_OWNByNIC
;
1120 m
= cur_rx
->my_mbuf
;
1122 * Try to conjure up a new mbuf cluster. If that
1123 * fails, it means we have an out of memory condition
1124 * and should leave the buffer in place and continue.
1125 * This will result in a lost packet, but there's
1126 * little else we can do in this situation.
1128 if (my_newbuf(sc
, cur_rx
) == ENOBUFS
) {
1130 cur_rx
->my_ptr
->my_status
= MY_OWNByNIC
;
1133 m
->m_pkthdr
.rcvif
= ifp
;
1134 m
->m_pkthdr
.len
= m
->m_len
= total_len
;
1137 ifp
->if_input(ifp
, m
);
1143 * A frame was downloaded to the chip. It's safe for us to clean up the list
1147 my_txeof(struct my_softc
* sc
)
1149 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1150 struct my_chain
*cur_tx
;
1152 /* Clear the timeout timer. */
1154 if (sc
->my_cdata
.my_tx_head
== NULL
)
1157 * Go through our tx list and free mbufs for those frames that have
1160 while (sc
->my_cdata
.my_tx_head
->my_mbuf
!= NULL
) {
1163 cur_tx
= sc
->my_cdata
.my_tx_head
;
1164 txstat
= MY_TXSTATUS(cur_tx
);
1165 if ((txstat
& MY_OWNByNIC
) || txstat
== MY_UNSENT
)
1167 if (!(CSR_READ_4(sc
, MY_TCRRCR
) & MY_Enhanced
)) {
1168 if (txstat
& MY_TXERR
) {
1170 if (txstat
& MY_EC
) /* excessive collision */
1171 ifp
->if_collisions
++;
1172 if (txstat
& MY_LC
) /* late collision */
1173 ifp
->if_collisions
++;
1175 ifp
->if_collisions
+= (txstat
& MY_NCRMASK
) >>
1179 m_freem(cur_tx
->my_mbuf
);
1180 cur_tx
->my_mbuf
= NULL
;
1181 if (sc
->my_cdata
.my_tx_head
== sc
->my_cdata
.my_tx_tail
) {
1182 sc
->my_cdata
.my_tx_head
= NULL
;
1183 sc
->my_cdata
.my_tx_tail
= NULL
;
1186 sc
->my_cdata
.my_tx_head
= cur_tx
->my_nextdesc
;
1188 if (CSR_READ_4(sc
, MY_TCRRCR
) & MY_Enhanced
) {
1189 ifp
->if_collisions
+= (CSR_READ_4(sc
, MY_TSR
) & MY_NCRMask
);
1194 * TX 'end of channel' interrupt handler.
1197 my_txeoc(struct my_softc
* sc
)
1199 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1202 if (sc
->my_cdata
.my_tx_head
== NULL
) {
1203 ifp
->if_flags
&= ~IFF_OACTIVE
;
1204 sc
->my_cdata
.my_tx_tail
= NULL
;
1205 if (sc
->my_want_auto
)
1206 my_autoneg_mii(sc
, MY_FLAG_SCHEDDELAY
, 1);
1208 if (MY_TXOWN(sc
->my_cdata
.my_tx_head
) == MY_UNSENT
) {
1209 MY_TXOWN(sc
->my_cdata
.my_tx_head
) = MY_OWNByNIC
;
1211 CSR_WRITE_4(sc
, MY_TXPDR
, 0xFFFFFFFF);
1219 struct my_softc
*sc
= arg
;
1220 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1223 if (!(ifp
->if_flags
& IFF_UP
))
1226 /* Disable interrupts. */
1227 CSR_WRITE_4(sc
, MY_IMR
, 0x00000000);
1230 status
= CSR_READ_4(sc
, MY_ISR
);
1233 CSR_WRITE_4(sc
, MY_ISR
, status
);
1237 if (status
& MY_RI
) /* receive interrupt */
1240 if ((status
& MY_RBU
) || (status
& MY_RxErr
)) {
1241 /* rx buffer unavailable or rx error */
1249 if (status
& MY_TI
) /* tx interrupt */
1251 if (status
& MY_ETI
) /* tx early interrupt */
1253 if (status
& MY_TBU
) /* tx buffer unavailable */
1256 #if 0 /* 90/1/18 delete */
1257 if (status
& MY_FBE
) {
1265 /* Re-enable interrupts. */
1266 CSR_WRITE_4(sc
, MY_IMR
, MY_INTRS
);
1267 if (!ifq_is_empty(&ifp
->if_snd
))
1272 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
1273 * pointers to the fragment pointers.
1276 my_encap(struct my_softc
* sc
, struct my_chain
* c
, struct mbuf
* m_head
)
1278 struct my_desc
*f
= NULL
;
1280 struct mbuf
*m
, *m_new
= NULL
;
1282 /* calculate the total tx pkt length */
1284 for (m
= m_head
; m
!= NULL
; m
= m
->m_next
)
1285 total_len
+= m
->m_len
;
1287 * Start packing the mbufs in this chain into the fragment pointers.
1288 * Stop when we run out of fragments or hit the end of the mbuf
1292 MGETHDR(m_new
, MB_DONTWAIT
, MT_DATA
);
1293 if (m_new
== NULL
) {
1294 kprintf("my%d: no memory for tx list", sc
->my_unit
);
1297 if (m_head
->m_pkthdr
.len
> MHLEN
) {
1298 MCLGET(m_new
, MB_DONTWAIT
);
1299 if (!(m_new
->m_flags
& M_EXT
)) {
1301 kprintf("my%d: no memory for tx list", sc
->my_unit
);
1305 m_copydata(m_head
, 0, m_head
->m_pkthdr
.len
, mtod(m_new
, caddr_t
));
1306 m_new
->m_pkthdr
.len
= m_new
->m_len
= m_head
->m_pkthdr
.len
;
1309 f
= &c
->my_ptr
->my_frag
[0];
1311 f
->my_data
= vtophys(mtod(m_new
, caddr_t
));
1312 total_len
= m_new
->m_len
;
1313 f
->my_ctl
= MY_TXFD
| MY_TXLD
| MY_CRCEnable
| MY_PADEnable
;
1314 f
->my_ctl
|= total_len
<< MY_PKTShift
; /* pkt size */
1315 f
->my_ctl
|= total_len
; /* buffer size */
1316 /* 89/12/29 add, for mtd891 *//* [ 89? ] */
1317 if (sc
->my_info
->my_did
== MTD891ID
)
1318 f
->my_ctl
|= MY_ETIControl
| MY_RetryTxLC
;
1319 c
->my_mbuf
= m_head
;
1321 MY_TXNEXT(c
) = vtophys(&c
->my_nextdesc
->my_ptr
->my_frag
[0]);
1326 * Main transmit routine. To avoid having to do mbuf copies, we put pointers
1327 * to the mbuf data regions directly in the transmit lists. We also save a
1328 * copy of the pointers since the transmit list fragment pointers are
1329 * physical addresses.
1332 my_start(struct ifnet
* ifp
)
1334 struct my_softc
*sc
= ifp
->if_softc
;
1335 struct mbuf
*m_head
= NULL
;
1336 struct my_chain
*cur_tx
= NULL
, *start_tx
;
1340 if (sc
->my_autoneg
) {
1341 ifq_purge(&ifp
->if_snd
);
1347 * Check for an available queue slot. If there are none, punt.
1349 if (sc
->my_cdata
.my_tx_free
->my_mbuf
!= NULL
) {
1350 ifp
->if_flags
|= IFF_OACTIVE
;
1355 start_tx
= sc
->my_cdata
.my_tx_free
;
1356 while (sc
->my_cdata
.my_tx_free
->my_mbuf
== NULL
) {
1357 m_head
= ifq_dequeue(&ifp
->if_snd
, NULL
);
1361 /* Pick a descriptor off the free list. */
1362 cur_tx
= sc
->my_cdata
.my_tx_free
;
1363 sc
->my_cdata
.my_tx_free
= cur_tx
->my_nextdesc
;
1365 /* Pack the data into the descriptor. */
1366 my_encap(sc
, cur_tx
, m_head
);
1368 if (cur_tx
!= start_tx
)
1369 MY_TXOWN(cur_tx
) = MY_OWNByNIC
;
1370 BPF_MTAP(ifp
, cur_tx
->my_mbuf
);
1373 * If there are no packets queued, bail.
1375 if (cur_tx
== NULL
) {
1380 * Place the request for the upload interrupt in the last descriptor
1381 * in the chain. This way, if we're chaining several packets at once,
1382 * we'll only get an interupt once for the whole chain rather than
1383 * once for each packet.
1385 MY_TXCTL(cur_tx
) |= MY_TXIC
;
1386 cur_tx
->my_ptr
->my_frag
[0].my_ctl
|= MY_TXIC
;
1387 sc
->my_cdata
.my_tx_tail
= cur_tx
;
1388 if (sc
->my_cdata
.my_tx_head
== NULL
)
1389 sc
->my_cdata
.my_tx_head
= start_tx
;
1390 MY_TXOWN(start_tx
) = MY_OWNByNIC
;
1391 CSR_WRITE_4(sc
, MY_TXPDR
, 0xFFFFFFFF); /* tx polling demand */
1394 * Set a timeout in case the chip goes out to lunch.
1404 struct my_softc
*sc
= xsc
;
1405 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1406 u_int16_t phy_bmcr
= 0;
1409 if (sc
->my_autoneg
) {
1413 if (sc
->my_pinfo
!= NULL
)
1414 phy_bmcr
= my_phy_readreg(sc
, PHY_BMCR
);
1416 * Cancel pending I/O and free all RX/TX buffers.
1422 * Set cache alignment and burst length.
1424 #if 0 /* 89/9/1 modify, */
1425 CSR_WRITE_4(sc
, MY_BCR
, MY_RPBLE512
);
1426 CSR_WRITE_4(sc
, MY_TCRRCR
, MY_TFTSF
);
1428 CSR_WRITE_4(sc
, MY_BCR
, MY_PBL8
);
1429 CSR_WRITE_4(sc
, MY_TCRRCR
, MY_TFTSF
| MY_RBLEN
| MY_RPBLE512
);
1431 * 89/12/29 add, for mtd891,
1433 if (sc
->my_info
->my_did
== MTD891ID
) {
1434 MY_SETBIT(sc
, MY_BCR
, MY_PROG
);
1435 MY_SETBIT(sc
, MY_TCRRCR
, MY_Enhanced
);
1437 my_setcfg(sc
, phy_bmcr
);
1438 /* Init circular RX list. */
1439 if (my_list_rx_init(sc
) == ENOBUFS
) {
1440 kprintf("my%d: init failed: no memory for rx buffers\n",
1446 /* Init TX descriptors. */
1447 my_list_tx_init(sc
);
1449 /* If we want promiscuous mode, set the allframes bit. */
1450 if (ifp
->if_flags
& IFF_PROMISC
)
1451 MY_SETBIT(sc
, MY_TCRRCR
, MY_PROM
);
1453 MY_CLRBIT(sc
, MY_TCRRCR
, MY_PROM
);
1456 * Set capture broadcast bit to capture broadcast frames.
1458 if (ifp
->if_flags
& IFF_BROADCAST
)
1459 MY_SETBIT(sc
, MY_TCRRCR
, MY_AB
);
1461 MY_CLRBIT(sc
, MY_TCRRCR
, MY_AB
);
1464 * Program the multicast filter, if necessary.
1469 * Load the address of the RX list.
1471 MY_CLRBIT(sc
, MY_TCRRCR
, MY_RE
);
1472 CSR_WRITE_4(sc
, MY_RXLBA
, vtophys(&sc
->my_ldata
->my_rx_list
[0]));
1475 * Enable interrupts.
1477 CSR_WRITE_4(sc
, MY_IMR
, MY_INTRS
);
1478 CSR_WRITE_4(sc
, MY_ISR
, 0xFFFFFFFF);
1480 /* Enable receiver and transmitter. */
1481 MY_SETBIT(sc
, MY_TCRRCR
, MY_RE
);
1482 MY_CLRBIT(sc
, MY_TCRRCR
, MY_TE
);
1483 CSR_WRITE_4(sc
, MY_TXLBA
, vtophys(&sc
->my_ldata
->my_tx_list
[0]));
1484 MY_SETBIT(sc
, MY_TCRRCR
, MY_TE
);
1486 /* Restore state of BMCR */
1487 if (sc
->my_pinfo
!= NULL
)
1488 my_phy_writereg(sc
, PHY_BMCR
, phy_bmcr
);
1489 ifp
->if_flags
|= IFF_RUNNING
;
1490 ifp
->if_flags
&= ~IFF_OACTIVE
;
1495 * Set media options.
1499 my_ifmedia_upd(struct ifnet
* ifp
)
1501 struct my_softc
*sc
= ifp
->if_softc
;
1502 struct ifmedia
*ifm
= &sc
->ifmedia
;
1504 if (IFM_TYPE(ifm
->ifm_media
) != IFM_ETHER
)
1509 if (IFM_SUBTYPE(ifm
->ifm_media
) == IFM_AUTO
)
1510 my_autoneg_mii(sc
, MY_FLAG_SCHEDDELAY
, 1);
1512 my_setmode_mii(sc
, ifm
->ifm_media
);
1520 * Report current media status.
1524 my_ifmedia_sts(struct ifnet
* ifp
, struct ifmediareq
* ifmr
)
1526 struct my_softc
*sc
= ifp
->if_softc
;
1527 u_int16_t advert
= 0, ability
= 0;
1531 ifmr
->ifm_active
= IFM_ETHER
;
1532 if (!(my_phy_readreg(sc
, PHY_BMCR
) & PHY_BMCR_AUTONEGENBL
)) {
1533 #if 0 /* this version did not support 1000M, */
1534 if (my_phy_readreg(sc
, PHY_BMCR
) & PHY_BMCR_1000
)
1535 ifmr
->ifm_active
= IFM_ETHER
| IFM_1000TX
;
1537 if (my_phy_readreg(sc
, PHY_BMCR
) & PHY_BMCR_SPEEDSEL
)
1538 ifmr
->ifm_active
= IFM_ETHER
| IFM_100_TX
;
1540 ifmr
->ifm_active
= IFM_ETHER
| IFM_10_T
;
1541 if (my_phy_readreg(sc
, PHY_BMCR
) & PHY_BMCR_DUPLEX
)
1542 ifmr
->ifm_active
|= IFM_FDX
;
1544 ifmr
->ifm_active
|= IFM_HDX
;
1550 ability
= my_phy_readreg(sc
, PHY_LPAR
);
1551 advert
= my_phy_readreg(sc
, PHY_ANAR
);
1553 #if 0 /* this version did not support 1000M, */
1554 if (sc
->my_pinfo
->my_vid
= MarvellPHYID0
) {
1555 ability2
= my_phy_readreg(sc
, PHY_1000SR
);
1556 if (ability2
& PHY_1000SR_1000BTXFULL
) {
1559 ifmr
->ifm_active
= IFM_ETHER
| IFM_1000_T
| IFM_FDX
;
1560 } else if (ability
& PHY_1000SR_1000BTXHALF
) {
1563 ifmr
->ifm_active
= IFM_ETHER
| IFM_1000_T
| IFM_HDX
;
1567 if (advert
& PHY_ANAR_100BT4
&& ability
& PHY_ANAR_100BT4
)
1568 ifmr
->ifm_active
= IFM_ETHER
| IFM_100_T4
;
1569 else if (advert
& PHY_ANAR_100BTXFULL
&& ability
& PHY_ANAR_100BTXFULL
)
1570 ifmr
->ifm_active
= IFM_ETHER
| IFM_100_TX
| IFM_FDX
;
1571 else if (advert
& PHY_ANAR_100BTXHALF
&& ability
& PHY_ANAR_100BTXHALF
)
1572 ifmr
->ifm_active
= IFM_ETHER
| IFM_100_TX
| IFM_HDX
;
1573 else if (advert
& PHY_ANAR_10BTFULL
&& ability
& PHY_ANAR_10BTFULL
)
1574 ifmr
->ifm_active
= IFM_ETHER
| IFM_10_T
| IFM_FDX
;
1575 else if (advert
& PHY_ANAR_10BTHALF
&& ability
& PHY_ANAR_10BTHALF
)
1576 ifmr
->ifm_active
= IFM_ETHER
| IFM_10_T
| IFM_HDX
;
1582 my_ioctl(struct ifnet
* ifp
, u_long command
, caddr_t data
, struct ucred
*cr
)
1584 struct my_softc
*sc
= ifp
->if_softc
;
1585 struct ifreq
*ifr
= (struct ifreq
*) data
;
1591 if (ifp
->if_flags
& IFF_UP
)
1593 else if (ifp
->if_flags
& IFF_RUNNING
)
1604 error
= ifmedia_ioctl(ifp
, ifr
, &sc
->ifmedia
, command
);
1607 error
= ether_ioctl(ifp
, command
, data
);
1616 my_watchdog(struct ifnet
* ifp
)
1618 struct my_softc
*sc
= ifp
->if_softc
;
1622 if (sc
->my_autoneg
) {
1623 my_autoneg_mii(sc
, MY_FLAG_DELAYTIMEO
, 1);
1628 kprintf("my%d: watchdog timeout\n", sc
->my_unit
);
1629 if (!(my_phy_readreg(sc
, PHY_BMSR
) & PHY_BMSR_LINKSTAT
))
1630 kprintf("my%d: no carrier - transceiver cable problem?\n",
1635 if (!ifq_is_empty(&ifp
->if_snd
))
1642 * Stop the adapter and free any mbufs allocated to the RX and TX lists.
1645 my_stop(struct my_softc
* sc
)
1647 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1652 MY_CLRBIT(sc
, MY_TCRRCR
, (MY_RE
| MY_TE
));
1653 CSR_WRITE_4(sc
, MY_IMR
, 0x00000000);
1654 CSR_WRITE_4(sc
, MY_TXLBA
, 0x00000000);
1655 CSR_WRITE_4(sc
, MY_RXLBA
, 0x00000000);
1658 * Free data in the RX lists.
1660 for (i
= 0; i
< MY_RX_LIST_CNT
; i
++) {
1661 if (sc
->my_cdata
.my_rx_chain
[i
].my_mbuf
!= NULL
) {
1662 m_freem(sc
->my_cdata
.my_rx_chain
[i
].my_mbuf
);
1663 sc
->my_cdata
.my_rx_chain
[i
].my_mbuf
= NULL
;
1666 bzero((char *)&sc
->my_ldata
->my_rx_list
,
1667 sizeof(sc
->my_ldata
->my_rx_list
));
1669 * Free the TX list buffers.
1671 for (i
= 0; i
< MY_TX_LIST_CNT
; i
++) {
1672 if (sc
->my_cdata
.my_tx_chain
[i
].my_mbuf
!= NULL
) {
1673 m_freem(sc
->my_cdata
.my_tx_chain
[i
].my_mbuf
);
1674 sc
->my_cdata
.my_tx_chain
[i
].my_mbuf
= NULL
;
1677 bzero((char *)&sc
->my_ldata
->my_tx_list
,
1678 sizeof(sc
->my_ldata
->my_tx_list
));
1679 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
1683 * Stop all chip I/O so that the kernel's probe routines don't get confused
1684 * by errant DMAs when rebooting.
1687 my_shutdown(device_t dev
)
1689 struct my_softc
*sc
;
1691 sc
= device_get_softc(dev
);