abd4c4e901f0672c8f180e4324ed767c87585a61
[dragonfly.git] / sys / dev / netif / my / if_my.c
1 /*
2  * Copyright (c) 2002 Myson Technology Inc.
3  * 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  *    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.
13  *
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
24  * SUCH DAMAGE.
25  *
26  * Written by: yen_cw@myson.com.tw  available at: http://www.myson.com.tw/
27  *
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 $
30  *
31  * Myson fast ethernet PCI NIC driver
32  *
33  * $Id: if_my.c,v 1.40 2001/11/30 03:55:00 <yen_cw@myson.com.tw> wpaul Exp $
34  */
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/sockio.h>
38 #include <sys/mbuf.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>
44 #include <sys/bus.h>
45 #include <sys/module.h>
46 #include <sys/serialize.h>
47 #include <sys/bus.h>
48 #include <sys/rman.h>
49
50 #include <sys/thread2.h>
51
52 #include <net/if.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>
58 #include <net/bpf.h>
59
60 #include <vm/vm.h>              /* for vtophys */
61 #include <vm/pmap.h>            /* for vtophys */
62 #include <machine/clock.h>      /* for DELAY */
63
64 #include <bus/pci/pcireg.h>
65 #include <bus/pci/pcivar.h>
66
67 /*
68  * #define MY_USEIOSPACE
69  */
70
71 static int      MY_USEIOSPACE = 1;
72
73 #if (MY_USEIOSPACE)
74 #define MY_RES                  SYS_RES_IOPORT
75 #define MY_RID                  MY_PCI_LOIO
76 #else
77 #define MY_RES                  SYS_RES_MEMORY
78 #define MY_RID                  MY_PCI_LOMEM
79 #endif
80
81
82 #include "if_myreg.h"
83
84 /*
85  * Various supported device vendors/types and their names.
86  */
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"},
91         {0, 0, NULL}
92 };
93
94 /*
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.
98  */
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>"}
106 };
107
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);
138
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)
141
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),
148
149         {0, 0}
150 };
151
152 static driver_t my_driver = {
153         "my",
154         my_methods,
155         sizeof(struct my_softc)
156 };
157
158 static devclass_t my_devclass;
159
160 DECLARE_DUMMY_MODULE(if_my);
161 DRIVER_MODULE(if_my, pci, my_driver, my_devclass, 0, 0);
162
163 static long
164 my_send_cmd_to_phy(struct my_softc * sc, int opcode, int regad)
165 {
166         long            miir;
167         int             i;
168         int             mask, data;
169
170         /* enable MII output */
171         miir = CSR_READ_4(sc, MY_MANAGEMENT);
172         miir &= 0xfffffff0;
173
174         miir |= MY_MASK_MIIR_MII_WRITE + MY_MASK_MIIR_MII_MDO;
175
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);
181
182                 /* high MDC */
183                 miir |= MY_MASK_MIIR_MII_MDC;
184                 CSR_WRITE_4(sc, MY_MANAGEMENT, miir);
185         }
186
187         /* calculate ST+OP+PHYAD+REGAD+TA */
188         data = opcode | (sc->my_phy_addr << 7) | (regad << 2);
189
190         /* sent out */
191         mask = 0x8000;
192         while (mask) {
193                 /* low MDC, prepare MDO */
194                 miir &= ~(MY_MASK_MIIR_MII_MDC + MY_MASK_MIIR_MII_MDO);
195                 if (mask & data)
196                         miir |= MY_MASK_MIIR_MII_MDO;
197
198                 CSR_WRITE_4(sc, MY_MANAGEMENT, miir);
199                 /* high MDC */
200                 miir |= MY_MASK_MIIR_MII_MDC;
201                 CSR_WRITE_4(sc, MY_MANAGEMENT, miir);
202                 DELAY(30);
203
204                 /* next */
205                 mask >>= 1;
206                 if (mask == 0x2 && opcode == MY_OP_READ)
207                         miir &= ~MY_MASK_MIIR_MII_WRITE;
208         }
209
210         return miir;
211 }
212
213
214 static          u_int16_t
215 my_phy_readreg(struct my_softc * sc, int reg)
216 {
217         long            miir;
218         int             mask, data;
219
220         if (sc->my_info->my_did == MTD803ID)
221                 data = CSR_READ_2(sc, MY_PHYBASE + reg * 2);
222         else {
223                 miir = my_send_cmd_to_phy(sc, MY_OP_READ, reg);
224
225                 /* read data */
226                 mask = 0x8000;
227                 data = 0;
228                 while (mask) {
229                         /* low MDC */
230                         miir &= ~MY_MASK_MIIR_MII_MDC;
231                         CSR_WRITE_4(sc, MY_MANAGEMENT, miir);
232
233                         /* read MDI */
234                         miir = CSR_READ_4(sc, MY_MANAGEMENT);
235                         if (miir & MY_MASK_MIIR_MII_MDI)
236                                 data |= mask;
237
238                         /* high MDC, and wait */
239                         miir |= MY_MASK_MIIR_MII_MDC;
240                         CSR_WRITE_4(sc, MY_MANAGEMENT, miir);
241                         DELAY(30);
242
243                         /* next */
244                         mask >>= 1;
245                 }
246
247                 /* low MDC */
248                 miir &= ~MY_MASK_MIIR_MII_MDC;
249                 CSR_WRITE_4(sc, MY_MANAGEMENT, miir);
250         }
251
252         return (u_int16_t) data;
253 }
254
255
256 static void
257 my_phy_writereg(struct my_softc * sc, int reg, int data)
258 {
259         long            miir;
260         int             mask;
261
262         if (sc->my_info->my_did == MTD803ID)
263                 CSR_WRITE_2(sc, MY_PHYBASE + reg * 2, data);
264         else {
265                 miir = my_send_cmd_to_phy(sc, MY_OP_WRITE, reg);
266
267                 /* write data */
268                 mask = 0x8000;
269                 while (mask) {
270                         /* low MDC, prepare MDO */
271                         miir &= ~(MY_MASK_MIIR_MII_MDC + MY_MASK_MIIR_MII_MDO);
272                         if (mask & data)
273                                 miir |= MY_MASK_MIIR_MII_MDO;
274                         CSR_WRITE_4(sc, MY_MANAGEMENT, miir);
275                         DELAY(1);
276
277                         /* high MDC */
278                         miir |= MY_MASK_MIIR_MII_MDC;
279                         CSR_WRITE_4(sc, MY_MANAGEMENT, miir);
280                         DELAY(1);
281
282                         /* next */
283                         mask >>= 1;
284                 }
285
286                 /* low MDC */
287                 miir &= ~MY_MASK_MIIR_MII_MDC;
288                 CSR_WRITE_4(sc, MY_MANAGEMENT, miir);
289         }
290 }
291
292 static          u_int8_t
293 my_calchash(caddr_t addr)
294 {
295         u_int32_t       crc, carry;
296         int             i, j;
297         u_int8_t        c;
298
299         /* Compute CRC for the address value. */
300         crc = 0xFFFFFFFF;       /* initial value */
301
302         for (i = 0; i < 6; i++) {
303                 c = *(addr + i);
304                 for (j = 0; j < 8; j++) {
305                         carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01);
306                         crc <<= 1;
307                         c >>= 1;
308                         if (carry)
309                                 crc = (crc ^ 0x04c11db6) | carry;
310                 }
311         }
312
313         /*
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
317          * with that works.
318          */
319         return (~(crc >> 26) & 0x0000003F);
320 }
321
322
323 /*
324  * Program the 64-bit multicast hash filter.
325  */
326 static void
327 my_setmulti(struct my_softc * sc)
328 {
329         struct ifnet *ifp = &sc->arpcom.ac_if;
330         int             h = 0;
331         u_int32_t       hashes[2] = {0, 0};
332         struct ifmultiaddr *ifma;
333         u_int32_t       rxfilt;
334         int             mcnt = 0;
335
336         rxfilt = CSR_READ_4(sc, MY_TCRRCR);
337
338         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
339                 rxfilt |= MY_AM;
340                 CSR_WRITE_4(sc, MY_TCRRCR, rxfilt);
341                 CSR_WRITE_4(sc, MY_MAR0, 0xFFFFFFFF);
342                 CSR_WRITE_4(sc, MY_MAR1, 0xFFFFFFFF);
343
344                 return;
345         }
346         /* first, zot all the existing hash bits */
347         CSR_WRITE_4(sc, MY_MAR0, 0);
348         CSR_WRITE_4(sc, MY_MAR1, 0);
349
350         /* now program new ones */
351         TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
352                 if (ifma->ifma_addr->sa_family != AF_LINK)
353                         continue;
354                 h = my_calchash(LLADDR((struct sockaddr_dl *) ifma->ifma_addr));
355                 if (h < 32)
356                         hashes[0] |= (1 << h);
357                 else
358                         hashes[1] |= (1 << (h - 32));
359                 mcnt++;
360         }
361
362         if (mcnt)
363                 rxfilt |= MY_AM;
364         else
365                 rxfilt &= ~MY_AM;
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);
369 }
370
371 /*
372  * Initiate an autonegotiation session.
373  */
374 static void
375 my_autoneg_xmit(struct my_softc * sc)
376 {
377         u_int16_t       phy_sts = 0;
378
379         my_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);
380         DELAY(500);
381         while (my_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_RESET);
382
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);
386 }
387
388
389 /*
390  * Invoke autonegotiation on a PHY.
391  */
392 static void
393 my_autoneg_mii(struct my_softc * sc, int flag, int verbose)
394 {
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;
399
400         ifm->ifm_media = IFM_ETHER | IFM_AUTO;
401
402 #ifndef FORCE_AUTONEG_TFOUR
403         /*
404          * First, see if autoneg is supported. If not, there's no point in
405          * continuing.
406          */
407         phy_sts = my_phy_readreg(sc, PHY_BMSR);
408         if (!(phy_sts & PHY_BMSR_CANAUTONEG)) {
409                 if (verbose)
410                         kprintf("my%d: autonegotiation not supported\n",
411                             sc->my_unit);
412                 ifm->ifm_media = IFM_ETHER | IFM_10_T | IFM_HDX;
413                 return;
414         }
415 #endif
416         switch (flag) {
417         case MY_FLAG_FORCEDELAY:
418                 /*
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
422                  * bad manners.
423                  */
424                 my_autoneg_xmit(sc);
425                 DELAY(5000000);
426                 break;
427         case MY_FLAG_SCHEDDELAY:
428                 /*
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.
433                  */
434                 if (sc->my_cdata.my_tx_head != NULL) {
435                         sc->my_want_auto = 1;
436                         return;
437                 }
438                 my_autoneg_xmit(sc);
439                 ifp->if_timer = 5;
440                 sc->my_autoneg = 1;
441                 sc->my_want_auto = 0;
442                 return;
443         case MY_FLAG_DELAYTIMEO:
444                 ifp->if_timer = 0;
445                 sc->my_autoneg = 0;
446                 break;
447         default:
448                 kprintf("my%d: invalid autoneg flag: %d\n", sc->my_unit, flag);
449                 return;
450         }
451
452         if (my_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_AUTONEGCOMP) {
453                 if (verbose)
454                         kprintf("my%d: autoneg complete, ", sc->my_unit);
455                 phy_sts = my_phy_readreg(sc, PHY_BMSR);
456         } else {
457                 if (verbose)
458                         kprintf("my%d: autoneg not complete, ", sc->my_unit);
459         }
460
461         media = my_phy_readreg(sc, PHY_BMCR);
462
463         /* Link is good. Report modes and set duplex mode. */
464         if (my_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT) {
465                 if (verbose)
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) {
473                                 advert = 0;
474                                 ability = 0;
475                                 /*
476                                  * this version did not support 1000M,
477                                  * ifm->ifm_media =
478                                  * IFM_ETHER | IFM_1000_T | IFM_FDX;
479                                  */
480                                 ifm->ifm_media =
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) {
487                                 advert = 0;
488                                 ability = 0;
489                                 /*
490                                  * this version did not support 1000M,
491                                  * ifm->ifm_media = IFM_ETHER | IFM_1000_T;
492                                  */
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");
498                         }
499                 }
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");
523                 } else if (advert) {
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");
528                 }
529                 media &= ~PHY_BMCR_AUTONEGENBL;
530
531                 /* Set ASIC's duplex mode to match the PHY. */
532                 my_phy_writereg(sc, PHY_BMCR, media);
533                 my_setcfg(sc, media);
534         } else {
535                 if (verbose)
536                         kprintf("my%d: no carrier\n", sc->my_unit);
537         }
538
539         my_init(sc);
540         if (sc->my_tx_pend) {
541                 sc->my_autoneg = 0;
542                 sc->my_tx_pend = 0;
543                 if_devstart(ifp);
544         }
545 }
546
547 /*
548  * To get PHY ability.
549  */
550 static void
551 my_getmode_mii(struct my_softc * sc)
552 {
553         struct ifnet *ifp = &sc->arpcom.ac_if;
554         u_int16_t       bmsr;
555
556         bmsr = my_phy_readreg(sc, PHY_BMSR);
557         if (bootverbose)
558                 kprintf("my%d: PHY status word: %x\n", sc->my_unit, bmsr);
559
560         /* fallback */
561         sc->ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_HDX;
562
563         if (bmsr & PHY_BMSR_10BTHALF) {
564                 if (bootverbose)
565                         kprintf("my%d: 10Mbps half-duplex mode supported\n",
566                                sc->my_unit);
567                 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_HDX,
568                     0, NULL);
569                 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, NULL);
570         }
571         if (bmsr & PHY_BMSR_10BTFULL) {
572                 if (bootverbose)
573                         kprintf("my%d: 10Mbps full-duplex mode supported\n",
574                             sc->my_unit);
575
576                 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX,
577                     0, NULL);
578                 sc->ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_FDX;
579         }
580         if (bmsr & PHY_BMSR_100BTXHALF) {
581                 if (bootverbose)
582                         kprintf("my%d: 100Mbps half-duplex mode supported\n",
583                                sc->my_unit);
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,
587                             0, NULL);
588                 sc->ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_HDX;
589         }
590         if (bmsr & PHY_BMSR_100BTXFULL) {
591                 if (bootverbose)
592                         kprintf("my%d: 100Mbps full-duplex mode supported\n",
593                             sc->my_unit);
594                 ifp->if_baudrate = 100000000;
595                 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX,
596                     0, NULL);
597                 sc->ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_FDX;
598         }
599         /* Some also support 100BaseT4. */
600         if (bmsr & PHY_BMSR_100BT4) {
601                 if (bootverbose)
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
607                 if (bootverbose)
608                         kprintf("my%d: forcing on autoneg support for BT4\n",
609                             sc->my_unit);
610                 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0 NULL):
611                 sc->ifmedia.ifm_media = IFM_ETHER | IFM_AUTO;
612 #endif
613         }
614 #if 0                           /* this version did not support 1000M, */
615         if (sc->my_pinfo->my_vid == MarvellPHYID0) {
616                 if (bootverbose)
617                         kprintf("my%d: 1000Mbps half-duplex mode supported\n",
618                                sc->my_unit);
619
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,
623                     0, NULL);
624                 if (bootverbose)
625                         kprintf("my%d: 1000Mbps full-duplex mode supported\n",
626                            sc->my_unit);
627                 ifp->if_baudrate = 1000000000;
628                 ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_1000_T | IFM_FDX,
629                     0, NULL);
630                 sc->ifmedia.ifm_media = IFM_ETHER | IFM_1000_T | IFM_FDX;
631         }
632 #endif
633         if (bmsr & PHY_BMSR_CANAUTONEG) {
634                 if (bootverbose)
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;
638         }
639 }
640
641 /*
642  * Set speed and duplex mode.
643  */
644 static void
645 my_setmode_mii(struct my_softc * sc, int media)
646 {
647         struct ifnet *ifp = &sc->arpcom.ac_if;
648         u_int16_t       bmcr;
649
650         /*
651          * If an autoneg session is in progress, stop it.
652          */
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);
659         }
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);
664
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;
671         }
672 #endif
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;
677         }
678         if (IFM_SUBTYPE(media) == IFM_100_TX) {
679                 kprintf("100Mbps, ");
680                 bmcr |= PHY_BMCR_SPEEDSEL;
681         }
682         if (IFM_SUBTYPE(media) == IFM_10_T) {
683                 kprintf("10Mbps, ");
684                 bmcr &= ~PHY_BMCR_SPEEDSEL;
685         }
686         if ((media & IFM_GMASK) == IFM_FDX) {
687                 kprintf("full duplex\n");
688                 bmcr |= PHY_BMCR_DUPLEX;
689         } else {
690                 kprintf("half duplex\n");
691                 bmcr &= ~PHY_BMCR_DUPLEX;
692         }
693         my_phy_writereg(sc, PHY_BMCR, bmcr);
694         my_setcfg(sc, bmcr);
695 }
696
697 /*
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.
701  */
702 static void
703 my_setcfg(struct my_softc * sc, int bmcr)
704 {
705         int             i, restart = 0;
706
707         if (CSR_READ_4(sc, MY_TCRRCR) & (MY_TE | MY_RE)) {
708                 restart = 1;
709                 MY_CLRBIT(sc, MY_TCRRCR, (MY_TE | MY_RE));
710                 for (i = 0; i < MY_TIMEOUT; i++) {
711                         DELAY(10);
712                         if (!(CSR_READ_4(sc, MY_TCRRCR) &
713                             (MY_TXRUN | MY_RXRUN)))
714                                 break;
715                 }
716                 if (i == MY_TIMEOUT)
717                         kprintf("my%d: failed to force tx and rx to idle \n",
718                             sc->my_unit);
719         }
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);
728         else
729                 MY_CLRBIT(sc, MY_TCRRCR, MY_FD);
730         if (restart)
731                 MY_SETBIT(sc, MY_TCRRCR, MY_TE | MY_RE);
732 }
733
734 static void
735 my_reset(struct my_softc * sc)
736 {
737         int    i;
738
739         MY_SETBIT(sc, MY_BCR, MY_SWR);
740         for (i = 0; i < MY_TIMEOUT; i++) {
741                 DELAY(10);
742                 if (!(CSR_READ_4(sc, MY_BCR) & MY_SWR))
743                         break;
744         }
745         if (i == MY_TIMEOUT)
746                 kprintf("m0x%d: reset never completed!\n", sc->my_unit);
747
748         /* Wait a little while for the chip to get its brains in order. */
749         DELAY(1000);
750 }
751
752 /*
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.
755  */
756 static int
757 my_probe(device_t dev)
758 {
759         struct my_type *t;
760         uint16_t vendor, product;
761
762         vendor = pci_get_vendor(dev);
763         product = pci_get_device(dev);
764
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);
768                         return (0);
769                 }
770         }
771
772         return (ENXIO);
773 }
774
775 /*
776  * Attach the interface. Allocate softc structures, do ifmedia setup and
777  * ethernet/BPF attach.
778  */
779 static int
780 my_attach(device_t dev)
781 {
782         int             i;
783         u_char          eaddr[ETHER_ADDR_LEN];
784         u_int32_t       command, iobase;
785         struct my_softc *sc;
786         struct ifnet   *ifp;
787         int             media = IFM_ETHER | IFM_100_TX | IFM_FDX;
788         unsigned int    round;
789         caddr_t         roundptr;
790         struct my_type *p;
791         u_int16_t       phy_vid, phy_did, phy_sts = 0;
792         int             rid, unit, error = 0;
793         struct my_type *t;
794         uint16_t vendor, product;
795
796         vendor = pci_get_vendor(dev);
797         product = pci_get_device(dev);
798
799         for (t = my_devs; t->my_name != NULL; t++) {
800                 if (vendor == t->my_vid && product == t->my_did)
801                         break;
802         }
803
804         if (t->my_name == NULL)
805                 return(ENXIO);
806
807         sc = device_get_softc(dev);
808         unit = device_get_unit(dev);
809
810         /*
811          * Map control/status registers.
812          */
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);
817
818         if (t->my_did == MTD800ID) {
819                 iobase = pci_read_config(dev, MY_PCI_LOIO, 4);
820                 if (iobase & 0x300)
821                         MY_USEIOSPACE = 0;
822         }
823         if (MY_USEIOSPACE) {
824                 if (!(command & PCIM_CMD_PORTEN)) {
825                         kprintf("my%d: failed to enable I/O ports!\n", unit);
826                         error = ENXIO;
827                         return(error);
828                 }
829         } else {
830                 if (!(command & PCIM_CMD_MEMEN)) {
831                         kprintf("my%d: failed to enable memory mapping!\n",
832                             unit);
833                         error = ENXIO;
834                         return(error);
835                 }
836         }
837
838         rid = MY_RID;
839         sc->my_res = bus_alloc_resource_any(dev, MY_RES, &rid, RF_ACTIVE);
840
841         if (sc->my_res == NULL) {
842                 kprintf("my%d: couldn't map ports/memory\n", unit);
843                 error = ENXIO;
844                 goto fail;
845         }
846         sc->my_btag = rman_get_bustag(sc->my_res);
847         sc->my_bhandle = rman_get_bushandle(sc->my_res);
848
849         rid = 0;
850         sc->my_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
851             RF_SHAREABLE | RF_ACTIVE);
852
853         if (sc->my_irq == NULL) {
854                 kprintf("my%d: couldn't map interrupt\n", unit);
855                 error = ENXIO;
856                 goto fail;
857         }
858
859         sc->my_info = t;
860
861         /* Reset the adapter. */
862         my_reset(sc);
863
864         /*
865          * Get station address
866          */
867         for (i = 0; i < ETHER_ADDR_LEN; ++i)
868                 eaddr[i] = CSR_READ_1(sc, MY_PAR0 + i);
869
870         sc->my_unit = unit;
871
872         sc->my_ldata_ptr = kmalloc(sizeof(struct my_list_data) + 8,
873                                   M_DEVBUF, M_WAITOK);
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++) {
878                 if (round % 8) {
879                         round++;
880                         roundptr++;
881                 } else
882                         break;
883         }
884         sc->my_ldata = (struct my_list_data *) roundptr;
885         bzero(sc->my_ldata, sizeof(struct my_list_data));
886
887         ifp = &sc->arpcom.ac_if;
888         ifp->if_softc = sc;
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);
899
900         if (sc->my_info->my_did == MTD803ID)
901                 sc->my_pinfo = my_phys;
902         else {
903                 if (bootverbose)
904                         kprintf("my%d: probing for a PHY\n", sc->my_unit);
905                 for (i = MY_PHYADDR_MIN; i < MY_PHYADDR_MAX + 1; i++) {
906                         if (bootverbose)
907                                 kprintf("my%d: checking address: %d\n",
908                                     sc->my_unit, i);
909                         sc->my_phy_addr = i;
910                         phy_sts = my_phy_readreg(sc, PHY_BMSR);
911                         if ((phy_sts != 0) && (phy_sts != 0xffff))
912                                 break;
913                         else
914                                 phy_sts = 0;
915                 }
916                 if (phy_sts) {
917                         phy_vid = my_phy_readreg(sc, PHY_VENID);
918                         phy_did = my_phy_readreg(sc, PHY_DEVID);
919                         if (bootverbose) {
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",
923                                     phy_vid, phy_did);
924                         }
925                         p = my_phys;
926                         while (p->my_vid) {
927                                 if (phy_vid == p->my_vid) {
928                                         sc->my_pinfo = p;
929                                         break;
930                                 }
931                                 p++;
932                         }
933                         if (sc->my_pinfo == NULL)
934                                 sc->my_pinfo = &my_phys[PHY_UNKNOWN];
935                         if (bootverbose)
936                                 kprintf("my%d: PHY type: %s\n",
937                                        sc->my_unit, sc->my_pinfo->my_name);
938                 } else {
939                         kprintf("my%d: MII without any phy!\n", sc->my_unit);
940                         error = ENXIO;
941                         goto fail;
942                 }
943         }
944
945         /* Do ifmedia setup. */
946         ifmedia_init(&sc->ifmedia, 0, my_ifmedia_upd, my_ifmedia_sts);
947         my_getmode_mii(sc);
948         my_autoneg_mii(sc, MY_FLAG_FORCEDELAY, 1);
949         media = sc->ifmedia.ifm_media;
950         my_stop(sc);
951         ifmedia_set(&sc->ifmedia, media);
952
953         ether_ifattach(ifp, eaddr, NULL);
954
955         error = bus_setup_intr(dev, sc->my_irq, INTR_MPSAFE,
956                                my_intr, sc, &sc->my_intrhand, 
957                                ifp->if_serializer);
958         if (error) {
959                 ether_ifdetach(ifp);
960                 kprintf("my%d: couldn't set up irq\n", unit);
961                 goto fail;
962         }
963
964         ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->my_irq));
965         KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);
966
967         return (0);
968
969 fail:
970         my_detach(dev);
971         return (error);
972 }
973
974 static int
975 my_detach(device_t dev)
976 {
977         struct my_softc *sc = device_get_softc(dev);
978         struct ifnet *ifp = &sc->arpcom.ac_if;
979
980         if (device_is_attached(dev)) {
981                 lwkt_serialize_enter(ifp->if_serializer);
982                 my_stop(sc);
983                 bus_teardown_intr(dev, sc->my_irq, sc->my_intrhand);
984                 lwkt_serialize_exit(ifp->if_serializer);
985
986                 ether_ifdetach(ifp);
987         }
988
989         if (sc->my_irq)
990                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->my_irq);
991         if (sc->my_res)
992                 bus_release_resource(dev, MY_RES, MY_RID, sc->my_res);
993
994         return (0);
995 }
996
997
998 /*
999  * Initialize the transmit descriptors.
1000  */
1001 static int
1002 my_list_tx_init(struct my_softc * sc)
1003 {
1004         struct my_chain_data *cd;
1005         struct my_list_data *ld;
1006         int             i;
1007
1008         cd = &sc->my_cdata;
1009         ld = sc->my_ldata;
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];
1014                 else
1015                         cd->my_tx_chain[i].my_nextdesc =
1016                             &cd->my_tx_chain[i + 1];
1017         }
1018         cd->my_tx_free = &cd->my_tx_chain[0];
1019         cd->my_tx_tail = cd->my_tx_head = NULL;
1020         return (0);
1021 }
1022
1023 /*
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.
1027  */
1028 static int
1029 my_list_rx_init(struct my_softc * sc)
1030 {
1031         struct my_chain_data *cd;
1032         struct my_list_data *ld;
1033         int             i;
1034
1035         cd = &sc->my_cdata;
1036         ld = sc->my_ldata;
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)
1041                         return (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]);
1045                 } else {
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]);
1050                 }
1051         }
1052         cd->my_rx_head = &cd->my_rx_chain[0];
1053         return (0);
1054 }
1055
1056 /*
1057  * Initialize an RX descriptor and attach an MBUF cluster.
1058  */
1059 static int
1060 my_newbuf(struct my_softc * sc, struct my_chain_onefrag * c)
1061 {
1062         struct mbuf    *m_new = NULL;
1063
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",
1067                        sc->my_unit);
1068                 return (ENOBUFS);
1069         }
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",
1073                        sc->my_unit);
1074                 m_freem(m_new);
1075                 return (ENOBUFS);
1076         }
1077         c->my_mbuf = m_new;
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;
1081         return (0);
1082 }
1083
1084 /*
1085  * A frame has been uploaded: pass the resulting mbuf chain up to the higher
1086  * level protocols.
1087  */
1088 static void
1089 my_rxeof(struct my_softc * sc)
1090 {
1091         struct mbuf *m;
1092         struct ifnet *ifp = &sc->arpcom.ac_if;
1093         struct my_chain_onefrag *cur_rx;
1094         int total_len = 0;
1095         u_int32_t rxstat;
1096
1097         while (!((rxstat = sc->my_cdata.my_rx_head->my_ptr->my_status)
1098             & MY_OWNByNIC)) {
1099                 cur_rx = sc->my_cdata.my_rx_head;
1100                 sc->my_cdata.my_rx_head = cur_rx->my_nextdesc;
1101
1102                 if (rxstat & MY_ES) {   /* error summary: give up this rx pkt */
1103                         ifp->if_ierrors++;
1104                         cur_rx->my_ptr->my_status = MY_OWNByNIC;
1105                         continue;
1106                 }
1107                 /* No errors; receive the packet. */
1108                 total_len = (rxstat & MY_FLNGMASK) >> MY_FLNGShift;
1109                 total_len -= ETHER_CRC_LEN;
1110
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;
1115                         if (m == NULL) {
1116                                 ifp->if_ierrors++;
1117                                 continue;
1118                         }
1119                 } else {
1120                         m = cur_rx->my_mbuf;
1121                         /*
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.
1127                          */
1128                         if (my_newbuf(sc, cur_rx) == ENOBUFS) {
1129                                 ifp->if_ierrors++;
1130                                 cur_rx->my_ptr->my_status = MY_OWNByNIC;
1131                                 continue;
1132                         }
1133                         m->m_pkthdr.rcvif = ifp;
1134                         m->m_pkthdr.len = m->m_len = total_len;
1135                 }
1136                 ifp->if_ipackets++;
1137                 ifp->if_input(ifp, m);
1138         }
1139 }
1140
1141
1142 /*
1143  * A frame was downloaded to the chip. It's safe for us to clean up the list
1144  * buffers.
1145  */
1146 static void
1147 my_txeof(struct my_softc * sc)
1148 {
1149         struct ifnet *ifp = &sc->arpcom.ac_if;
1150         struct my_chain *cur_tx;
1151
1152         /* Clear the timeout timer. */
1153         ifp->if_timer = 0;
1154         if (sc->my_cdata.my_tx_head == NULL)
1155                 return;
1156         /*
1157          * Go through our tx list and free mbufs for those frames that have
1158          * been transmitted.
1159          */
1160         while (sc->my_cdata.my_tx_head->my_mbuf != NULL) {
1161                 u_int32_t       txstat;
1162
1163                 cur_tx = sc->my_cdata.my_tx_head;
1164                 txstat = MY_TXSTATUS(cur_tx);
1165                 if ((txstat & MY_OWNByNIC) || txstat == MY_UNSENT)
1166                         break;
1167                 if (!(CSR_READ_4(sc, MY_TCRRCR) & MY_Enhanced)) {
1168                         if (txstat & MY_TXERR) {
1169                                 ifp->if_oerrors++;
1170                                 if (txstat & MY_EC) /* excessive collision */
1171                                         ifp->if_collisions++;
1172                                 if (txstat & MY_LC)     /* late collision */
1173                                         ifp->if_collisions++;
1174                         }
1175                         ifp->if_collisions += (txstat & MY_NCRMASK) >>
1176                             MY_NCRShift;
1177                 }
1178                 ifp->if_opackets++;
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;
1184                         break;
1185                 }
1186                 sc->my_cdata.my_tx_head = cur_tx->my_nextdesc;
1187         }
1188         if (CSR_READ_4(sc, MY_TCRRCR) & MY_Enhanced) {
1189                 ifp->if_collisions += (CSR_READ_4(sc, MY_TSR) & MY_NCRMask);
1190         }
1191 }
1192
1193 /*
1194  * TX 'end of channel' interrupt handler.
1195  */
1196 static void
1197 my_txeoc(struct my_softc * sc)
1198 {
1199         struct ifnet *ifp = &sc->arpcom.ac_if;
1200
1201         ifp->if_timer = 0;
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);
1207         } else {
1208                 if (MY_TXOWN(sc->my_cdata.my_tx_head) == MY_UNSENT) {
1209                         MY_TXOWN(sc->my_cdata.my_tx_head) = MY_OWNByNIC;
1210                         ifp->if_timer = 5;
1211                         CSR_WRITE_4(sc, MY_TXPDR, 0xFFFFFFFF);
1212                 }
1213         }
1214 }
1215
1216 static void
1217 my_intr(void *arg)
1218 {
1219         struct my_softc *sc = arg;
1220         struct ifnet *ifp = &sc->arpcom.ac_if;
1221         u_int32_t status;
1222
1223         if (!(ifp->if_flags & IFF_UP))
1224                 return;
1225
1226         /* Disable interrupts. */
1227         CSR_WRITE_4(sc, MY_IMR, 0x00000000);
1228
1229         for (;;) {
1230                 status = CSR_READ_4(sc, MY_ISR);
1231                 status &= MY_INTRS;
1232                 if (status)
1233                         CSR_WRITE_4(sc, MY_ISR, status);
1234                 else
1235                         break;
1236
1237                 if (status & MY_RI)     /* receive interrupt */
1238                         my_rxeof(sc);
1239
1240                 if ((status & MY_RBU) || (status & MY_RxErr)) {
1241                         /* rx buffer unavailable or rx error */
1242                         ifp->if_ierrors++;
1243 #ifdef foo
1244                         my_stop(sc);
1245                         my_reset(sc);
1246                         my_init(sc);
1247 #endif
1248                 }
1249                 if (status & MY_TI)     /* tx interrupt */
1250                         my_txeof(sc);
1251                 if (status & MY_ETI)    /* tx early interrupt */
1252                         my_txeof(sc);
1253                 if (status & MY_TBU)    /* tx buffer unavailable */
1254                         my_txeoc(sc);
1255
1256 #if 0                           /* 90/1/18 delete */
1257                 if (status & MY_FBE) {
1258                         my_reset(sc);
1259                         my_init(sc);
1260                 }
1261 #endif
1262
1263         }
1264
1265         /* Re-enable interrupts. */
1266         CSR_WRITE_4(sc, MY_IMR, MY_INTRS);
1267         if (!ifq_is_empty(&ifp->if_snd))
1268                 if_devstart(ifp);
1269 }
1270
1271 /*
1272  * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
1273  * pointers to the fragment pointers.
1274  */
1275 static int
1276 my_encap(struct my_softc * sc, struct my_chain * c, struct mbuf * m_head)
1277 {
1278         struct my_desc *f = NULL;
1279         int             total_len;
1280         struct mbuf    *m, *m_new = NULL;
1281
1282         /* calculate the total tx pkt length */
1283         total_len = 0;
1284         for (m = m_head; m != NULL; m = m->m_next)
1285                 total_len += m->m_len;
1286         /*
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
1289          * chain.
1290          */
1291         m = m_head;
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);
1295                 return (1);
1296         }
1297         if (m_head->m_pkthdr.len > MHLEN) {
1298                 MCLGET(m_new, MB_DONTWAIT);
1299                 if (!(m_new->m_flags & M_EXT)) {
1300                         m_freem(m_new);
1301                         kprintf("my%d: no memory for tx list", sc->my_unit);
1302                         return (1);
1303                 }
1304         }
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;
1307         m_freem(m_head);
1308         m_head = m_new;
1309         f = &c->my_ptr->my_frag[0];
1310         f->my_status = 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;
1320         c->my_lastdesc = 0;
1321         MY_TXNEXT(c) = vtophys(&c->my_nextdesc->my_ptr->my_frag[0]);
1322         return (0);
1323 }
1324
1325 /*
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.
1330  */
1331 static void
1332 my_start(struct ifnet * ifp)
1333 {
1334         struct my_softc *sc = ifp->if_softc;
1335         struct mbuf    *m_head = NULL;
1336         struct my_chain *cur_tx = NULL, *start_tx;
1337
1338         crit_enter();
1339
1340         if (sc->my_autoneg) {
1341                 ifq_purge(&ifp->if_snd);
1342                 sc->my_tx_pend = 1;
1343                 crit_exit();
1344                 return;
1345         }
1346         /*
1347          * Check for an available queue slot. If there are none, punt.
1348          */
1349         if (sc->my_cdata.my_tx_free->my_mbuf != NULL) {
1350                 ifp->if_flags |= IFF_OACTIVE;
1351                 crit_exit();
1352                 return;
1353         }
1354
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);
1358                 if (m_head == NULL)
1359                         break;
1360
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;
1364
1365                 /* Pack the data into the descriptor. */
1366                 my_encap(sc, cur_tx, m_head);
1367
1368                 if (cur_tx != start_tx)
1369                         MY_TXOWN(cur_tx) = MY_OWNByNIC;
1370                 BPF_MTAP(ifp, cur_tx->my_mbuf);
1371         }
1372         /*
1373          * If there are no packets queued, bail.
1374          */
1375         if (cur_tx == NULL) {
1376                 crit_exit();
1377                 return;
1378         }
1379         /*
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.
1384          */
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 */
1392
1393         /*
1394          * Set a timeout in case the chip goes out to lunch.
1395          */
1396         ifp->if_timer = 5;
1397
1398         crit_exit();
1399 }
1400
1401 static void
1402 my_init(void *xsc)
1403 {
1404         struct my_softc *sc = xsc;
1405         struct ifnet   *ifp = &sc->arpcom.ac_if;
1406         u_int16_t       phy_bmcr = 0;
1407
1408         crit_enter();
1409         if (sc->my_autoneg) {
1410                 crit_exit();
1411                 return;
1412         }
1413         if (sc->my_pinfo != NULL)
1414                 phy_bmcr = my_phy_readreg(sc, PHY_BMCR);
1415         /*
1416          * Cancel pending I/O and free all RX/TX buffers.
1417          */
1418         my_stop(sc);
1419         my_reset(sc);
1420
1421         /*
1422          * Set cache alignment and burst length.
1423          */
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);
1427 #endif
1428         CSR_WRITE_4(sc, MY_BCR, MY_PBL8);
1429         CSR_WRITE_4(sc, MY_TCRRCR, MY_TFTSF | MY_RBLEN | MY_RPBLE512);
1430         /*
1431          * 89/12/29 add, for mtd891,
1432          */
1433         if (sc->my_info->my_did == MTD891ID) {
1434                 MY_SETBIT(sc, MY_BCR, MY_PROG);
1435                 MY_SETBIT(sc, MY_TCRRCR, MY_Enhanced);
1436         }
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",
1441                     sc->my_unit);
1442                 my_stop(sc);
1443                 crit_exit();
1444                 return;
1445         }
1446         /* Init TX descriptors. */
1447         my_list_tx_init(sc);
1448
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);
1452         else
1453                 MY_CLRBIT(sc, MY_TCRRCR, MY_PROM);
1454
1455         /*
1456          * Set capture broadcast bit to capture broadcast frames.
1457          */
1458         if (ifp->if_flags & IFF_BROADCAST)
1459                 MY_SETBIT(sc, MY_TCRRCR, MY_AB);
1460         else
1461                 MY_CLRBIT(sc, MY_TCRRCR, MY_AB);
1462
1463         /*
1464          * Program the multicast filter, if necessary.
1465          */
1466         my_setmulti(sc);
1467
1468         /*
1469          * Load the address of the RX list.
1470          */
1471         MY_CLRBIT(sc, MY_TCRRCR, MY_RE);
1472         CSR_WRITE_4(sc, MY_RXLBA, vtophys(&sc->my_ldata->my_rx_list[0]));
1473
1474         /*
1475          * Enable interrupts.
1476          */
1477         CSR_WRITE_4(sc, MY_IMR, MY_INTRS);
1478         CSR_WRITE_4(sc, MY_ISR, 0xFFFFFFFF);
1479
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);
1485
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;
1491         crit_exit();
1492 }
1493
1494 /*
1495  * Set media options.
1496  */
1497
1498 static int
1499 my_ifmedia_upd(struct ifnet * ifp)
1500 {
1501         struct my_softc *sc = ifp->if_softc;
1502         struct ifmedia *ifm = &sc->ifmedia;
1503
1504         if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
1505                 return (EINVAL);
1506
1507         crit_enter();
1508
1509         if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO)
1510                 my_autoneg_mii(sc, MY_FLAG_SCHEDDELAY, 1);
1511         else
1512                 my_setmode_mii(sc, ifm->ifm_media);
1513
1514         crit_exit();
1515
1516         return (0);
1517 }
1518
1519 /*
1520  * Report current media status.
1521  */
1522
1523 static void
1524 my_ifmedia_sts(struct ifnet * ifp, struct ifmediareq * ifmr)
1525 {
1526         struct my_softc *sc = ifp->if_softc;
1527         u_int16_t advert = 0, ability = 0;
1528
1529         crit_enter();
1530
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;
1536 #endif
1537                 if (my_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_SPEEDSEL)
1538                         ifmr->ifm_active = IFM_ETHER | IFM_100_TX;
1539                 else
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;
1543                 else
1544                         ifmr->ifm_active |= IFM_HDX;
1545
1546                 crit_exit();
1547
1548                 return;
1549         }
1550         ability = my_phy_readreg(sc, PHY_LPAR);
1551         advert = my_phy_readreg(sc, PHY_ANAR);
1552
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) {
1557                         advert = 0;
1558                         ability = 0;
1559                         ifmr->ifm_active = IFM_ETHER | IFM_1000_T | IFM_FDX;
1560                 } else if (ability & PHY_1000SR_1000BTXHALF) {
1561                         advert = 0;
1562                         ability = 0;
1563                         ifmr->ifm_active = IFM_ETHER | IFM_1000_T | IFM_HDX;
1564                 }
1565         }
1566 #endif
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;
1577
1578         crit_exit();
1579 }
1580
1581 static int
1582 my_ioctl(struct ifnet * ifp, u_long command, caddr_t data, struct ucred *cr)
1583 {
1584         struct my_softc *sc = ifp->if_softc;
1585         struct ifreq   *ifr = (struct ifreq *) data;
1586         int             error = 0;
1587
1588         crit_enter();
1589         switch (command) {
1590         case SIOCSIFFLAGS:
1591                 if (ifp->if_flags & IFF_UP)
1592                         my_init(sc);
1593                 else if (ifp->if_flags & IFF_RUNNING)
1594                         my_stop(sc);
1595                 error = 0;
1596                 break;
1597         case SIOCADDMULTI:
1598         case SIOCDELMULTI:
1599                 my_setmulti(sc);
1600                 error = 0;
1601                 break;
1602         case SIOCGIFMEDIA:
1603         case SIOCSIFMEDIA:
1604                 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
1605                 break;
1606         default:
1607                 error = ether_ioctl(ifp, command, data);
1608                 break;
1609         }
1610
1611         crit_exit();
1612         return (error);
1613 }
1614
1615 static void
1616 my_watchdog(struct ifnet * ifp)
1617 {
1618         struct my_softc *sc = ifp->if_softc;
1619
1620         crit_enter();
1621
1622         if (sc->my_autoneg) {
1623                 my_autoneg_mii(sc, MY_FLAG_DELAYTIMEO, 1);
1624                 crit_exit();
1625                 return;
1626         }
1627         ifp->if_oerrors++;
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",
1631                     sc->my_unit);
1632         my_stop(sc);
1633         my_reset(sc);
1634         my_init(sc);
1635         if (!ifq_is_empty(&ifp->if_snd))
1636                 if_devstart(ifp);
1637         crit_exit();
1638 }
1639
1640
1641 /*
1642  * Stop the adapter and free any mbufs allocated to the RX and TX lists.
1643  */
1644 static void
1645 my_stop(struct my_softc * sc)
1646 {
1647         struct ifnet *ifp = &sc->arpcom.ac_if;
1648         int    i;
1649
1650         ifp->if_timer = 0;
1651
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);
1656
1657         /*
1658          * Free data in the RX lists.
1659          */
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;
1664                 }
1665         }
1666         bzero((char *)&sc->my_ldata->my_rx_list,
1667             sizeof(sc->my_ldata->my_rx_list));
1668         /*
1669          * Free the TX list buffers.
1670          */
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;
1675                 }
1676         }
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);
1680 }
1681
1682 /*
1683  * Stop all chip I/O so that the kernel's probe routines don't get confused
1684  * by errant DMAs when rebooting.
1685  */
1686 static void
1687 my_shutdown(device_t dev)
1688 {
1689         struct my_softc *sc;
1690
1691         sc = device_get_softc(dev);
1692         my_stop(sc);
1693         return;
1694 }