1 /*        $NetBSD: dm9000.c,v 1.38 2024/12/01 20:24:23 andvar Exp $   */
2 
3 /*
4  * Copyright (c) 2009 Paul Fleischer
5  * All rights reserved.
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  * 3. The name of the company nor the name of the author may be used to
13  *    endorse or promote products derived from this software without specific
14  *    prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 /* based on sys/dev/ic/cs89x0.c */
30 /*
31  * Copyright (c) 2004 Christopher Gilbert
32  * All rights reserved.
33  *
34  * 1. Redistributions of source code must retain the above copyright
35  *    notice, this list of conditions and the following disclaimer.
36  * 2. Redistributions in binary form must reproduce the above copyright
37  *    notice, this list of conditions and the following disclaimer in the
38  *    documentation and/or other materials provided with the distribution.
39  * 3. The name of the company nor the name of the author may be used to
40  *    endorse or promote products derived from this software without specific
41  *    prior written permission.
42  *
43  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
44  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
45  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
46  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
47  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
49  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53  * SUCH DAMAGE.
54  */
55 
56 /*
57  * Copyright 1997
58  * Digital Equipment Corporation. All rights reserved.
59  *
60  * This software is furnished under license and may be used and
61  * copied only in accordance with the following terms and conditions.
62  * Subject to these conditions, you may download, copy, install,
63  * use, modify and distribute this software in source and/or binary
64  * form. No title or ownership is transferred hereby.
65  *
66  * 1) Any source code used, modified or distributed must reproduce
67  *    and retain this copyright notice and list of conditions as
68  *    they appear in the source file.
69  *
70  * 2) No right is granted to use any trade name, trademark, or logo of
71  *    Digital Equipment Corporation. Neither the "Digital Equipment
72  *    Corporation" name nor any trademark or logo of Digital Equipment
73  *    Corporation may be used to endorse or promote products derived
74  *    from this software without the prior written permission of
75  *    Digital Equipment Corporation.
76  *
77  * 3) This software is provided "AS-IS" and any express or implied
78  *    warranties, including but not limited to, any implied warranties
79  *    of merchantability, fitness for a particular purpose, or
80  *    non-infringement are disclaimed. In no event shall DIGITAL be
81  *    liable for any damages whatsoever, and in particular, DIGITAL
82  *    shall not be liable for special, indirect, consequential, or
83  *    incidental damages or damages for lost profits, loss of
84  *    revenue or loss of use, whether such damages arise in contract,
85  *    negligence, tort, under statute, in equity, at law or otherwise,
86  *    even if advised of the possibility of such damage.
87  */
88 
89 #include <sys/cdefs.h>
90 
91 #include <sys/param.h>
92 #include <sys/bus.h>
93 #include <sys/intr.h>
94 #include <sys/device.h>
95 #include <sys/mbuf.h>
96 #include <sys/sockio.h>
97 #include <sys/errno.h>
98 #include <sys/cprng.h>
99 #include <sys/rndsource.h>
100 #include <sys/kernel.h>
101 #include <sys/systm.h>
102 
103 #include <net/if.h>
104 #include <net/if_dl.h>
105 #include <net/if_ether.h>
106 #include <net/if_media.h>
107 #include <dev/mii/mii.h>
108 #include <dev/mii/miivar.h>
109 #include <net/bpf.h>
110 
111 #include <dev/ic/dm9000var.h>
112 #include <dev/ic/dm9000reg.h>
113 
114 #if 1
115 #undef DM9000_DEBUG
116 #undef DM9000_TX_DEBUG
117 #undef DM9000_TX_DATA_DEBUG
118 #undef DM9000_RX_DEBUG
119 #undef  DM9000_RX_DATA_DEBUG
120 #else
121 #define DM9000_DEBUG
122 #define  DM9000_TX_DEBUG
123 #define DM9000_TX_DATA_DEBUG
124 #define DM9000_RX_DEBUG
125 #define  DM9000_RX_DATA_DEBUG
126 #endif
127 
128 #ifdef DM9000_DEBUG
129 #define DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
130 #else
131 #define DPRINTF(s) do {} while (/*CONSTCOND*/0)
132 #endif
133 
134 #ifdef DM9000_TX_DEBUG
135 #define TX_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
136 #else
137 #define TX_DPRINTF(s) do {} while (/*CONSTCOND*/0)
138 #endif
139 
140 #ifdef DM9000_RX_DEBUG
141 #define RX_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
142 #else
143 #define RX_DPRINTF(s) do {} while (/*CONSTCOND*/0)
144 #endif
145 
146 #ifdef DM9000_RX_DATA_DEBUG
147 #define RX_DATA_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
148 #else
149 #define RX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0)
150 #endif
151 
152 #ifdef DM9000_TX_DATA_DEBUG
153 #define TX_DATA_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0)
154 #else
155 #define TX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0)
156 #endif
157 
158 static void dme_reset(struct dme_softc *);
159 static int dme_init(struct ifnet *);
160 static void dme_stop(struct ifnet *, int);
161 static void dme_start(struct ifnet *);
162 static int dme_ioctl(struct ifnet *, u_long, void *);
163 
164 static void dme_set_rcvfilt(struct dme_softc *);
165 static void mii_statchg(struct ifnet *);
166 static void lnkchg(struct dme_softc *);
167 static void phy_tick(void *);
168 static int mii_readreg(device_t, int, int, uint16_t *);
169 static int mii_writereg(device_t, int, int, uint16_t);
170 
171 static void dme_prepare(struct ifnet *);
172 static void dme_transmit(struct ifnet *);
173 static void dme_receive(struct ifnet *);
174 
175 static int pkt_read_2(struct dme_softc *, struct mbuf **);
176 static int pkt_write_2(struct dme_softc *, struct mbuf *);
177 static int pkt_read_1(struct dme_softc *, struct mbuf **);
178 static int pkt_write_1(struct dme_softc *, struct mbuf *);
179 #define PKT_READ(ii,m) (*(ii)->sc_pkt_read)((ii),(m))
180 #define PKT_WRITE(ii,m) (*(ii)->sc_pkt_write)((ii),(m))
181 
182 #define ETHER_IS_ONE(x) \
183              (((x)[0] & (x)[1] & (x)[2] & (x)[3] & (x)[4] & (x)[5]) == 255)
184 #define ETHER_IS_ZERO(x) \
185              (((x)[0] | (x)[1] | (x)[2] | (x)[3] | (x)[4] | (x)[5]) == 0)
186 
187 int
dme_attach(struct dme_softc * sc,const uint8_t * notusedanymore)188 dme_attach(struct dme_softc *sc, const uint8_t *notusedanymore)
189 {
190           struct ifnet *ifp = &sc->sc_ethercom.ec_if;
191           struct mii_data *mii = &sc->sc_mii;
192           struct ifmedia *ifm = &mii->mii_media;
193           uint8_t b[2];
194           uint16_t io_mode;
195           uint8_t enaddr[ETHER_ADDR_LEN];
196           prop_dictionary_t dict;
197           prop_data_t ea;
198 
199           dme_read_c(sc, DM9000_VID0, b, 2);
200           sc->sc_vendor_id = le16toh((uint16_t)b[1] << 8 | b[0]);
201           dme_read_c(sc, DM9000_PID0, b, 2);
202           sc->sc_product_id = le16toh((uint16_t)b[1] << 8 | b[0]);
203 
204           /* TODO: Check the vendor ID as well */
205           if (sc->sc_product_id != 0x9000) {
206                     panic("dme_attach: product id mismatch (0x%hx != 0x9000)",
207                         sc->sc_product_id);
208           }
209 #if 1 || DM9000_DEBUG
210           {
211                     dme_read_c(sc, DM9000_PAB0, enaddr, 6);
212                     aprint_normal_dev(sc->sc_dev,
213                         "DM9000 was configured with MAC address: %s\n",
214                         ether_sprintf(enaddr));
215           }
216 #endif
217           dict = device_properties(sc->sc_dev);
218           ea = (dict) ? prop_dictionary_get(dict, "mac-address") : NULL;
219           if (ea != NULL) {
220                  /*
221                      * If the MAC address is overridden by a device property,
222                      * use that.
223                      */
224                     KASSERT(prop_object_type(ea) == PROP_TYPE_DATA);
225                     KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN);
226                     memcpy(enaddr, prop_data_value(ea), ETHER_ADDR_LEN);
227                     aprint_debug_dev(sc->sc_dev, "got MAC address!\n");
228           } else {
229                     /*
230                      * If we did not get an externally configure address,
231                      * try to read one from the current setup, before
232                      * resetting the chip.
233                      */
234                     dme_read_c(sc, DM9000_PAB0, enaddr, 6);
235                     if (ETHER_IS_ONE(enaddr) || ETHER_IS_ZERO(enaddr)) {
236                               /* make a random MAC address */
237                               uint32_t maclo = 0x00f2 | (cprng_strong32() << 16);
238                               uint32_t machi = cprng_strong32();
239                               enaddr[0] = maclo;
240                               enaddr[1] = maclo >> 8;
241                               enaddr[2] = maclo >> 16;
242                               enaddr[3] = maclo >> 26;
243                               enaddr[4] = machi;
244                               enaddr[5] = machi >> 8;
245                     }
246           }
247           /* TODO: perform explicit EEPROM read op if it's available */
248 
249           dme_reset(sc);
250 
251           mii->mii_ifp = ifp;
252           mii->mii_readreg = mii_readreg;
253           mii->mii_writereg = mii_writereg;
254           mii->mii_statchg = mii_statchg;
255 
256           /* assume davicom PHY at 1. ext PHY could be hooked but only at 0-3 */
257           sc->sc_ethercom.ec_mii = mii;
258           ifmedia_init(ifm, 0, ether_mediachange, ether_mediastatus);
259           mii_attach(sc->sc_dev, mii, 0xffffffff, 1 /* PHY 1 */,
260                     MII_OFFSET_ANY, 0);
261           if (LIST_FIRST(&mii->mii_phys) == NULL) {
262                     ifmedia_add(ifm, IFM_ETHER | IFM_NONE, 0, NULL);
263                     ifmedia_set(ifm, IFM_ETHER | IFM_NONE);
264           } else
265                     ifmedia_set(ifm, IFM_ETHER | IFM_AUTO);
266           ifm->ifm_media = ifm->ifm_cur->ifm_media;
267 
268           strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
269           ifp->if_softc = sc;
270           ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
271           ifp->if_init = dme_init;
272           ifp->if_start = dme_start;
273           ifp->if_stop = dme_stop;
274           ifp->if_ioctl = dme_ioctl;
275           ifp->if_watchdog = NULL; /* no watchdog used */
276           IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
277           IFQ_SET_READY(&ifp->if_snd);
278 
279           if_attach(ifp);
280           ether_ifattach(ifp, enaddr);
281           if_deferred_start_init(ifp, NULL);
282 
283           rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
284             RND_TYPE_NET, RND_FLAG_DEFAULT);
285 
286           /* might be unnecessary as link change interrupt works well */
287           callout_init(&sc->sc_link_callout, 0);
288           callout_setfunc(&sc->sc_link_callout, phy_tick, sc);
289 
290           io_mode = (dme_read(sc, DM9000_ISR) &
291               DM9000_IOMODE_MASK) >> DM9000_IOMODE_SHIFT;
292 
293           /* frame body read/write ops in 2 byte quantity or byte-wise. */
294           DPRINTF(("DM9000 Operation Mode: "));
295           switch (io_mode) {
296           case DM9000_MODE_8BIT:
297                     DPRINTF(("8-bit mode"));
298                     sc->sc_data_width = 1;
299                     sc->sc_pkt_write = pkt_write_1;
300                     sc->sc_pkt_read = pkt_read_1;
301                     break;
302           case DM9000_MODE_16BIT:
303                     DPRINTF(("16-bit mode"));
304                     sc->sc_data_width = 2;
305                     sc->sc_pkt_write = pkt_write_2;
306                     sc->sc_pkt_read = pkt_read_2;
307                     break;
308           case DM9000_MODE_32BIT:
309                     DPRINTF(("32-bit mode"));
310                     sc->sc_data_width = 4;
311                     panic("32bit mode is unsupported\n");
312                     break;
313           default:
314                     DPRINTF(("Invalid mode"));
315                     break;
316           }
317           DPRINTF(("\n"));
318 
319           return 0;
320 }
321 
322 int
dme_detach(struct dme_softc * sc)323 dme_detach(struct dme_softc *sc)
324 {
325           return 0;
326 }
327 
328 /* Software Initialize/Reset of the DM9000 */
329 static void
dme_reset(struct dme_softc * sc)330 dme_reset(struct dme_softc *sc)
331 {
332           uint8_t misc;
333 
334           /* We only re-initialized the PHY in this function the first time it is
335            * called. */
336           if (!sc->sc_phy_initialized) {
337                     /* PHY Reset */
338                     mii_writereg(sc->sc_dev, 1, MII_BMCR, BMCR_RESET);
339 
340                     /* PHY Power Down */
341                     misc = dme_read(sc, DM9000_GPR);
342                     dme_write(sc, DM9000_GPR, misc | DM9000_GPR_PHY_PWROFF);
343           }
344 
345           /* Reset the DM9000 twice, as described in section 2 of the Programming
346            * Guide.
347            * The PHY is initialized and enabled between those two resets.
348            */
349 
350           /* Software Reset */
351           dme_write(sc, DM9000_NCR,
352               DM9000_NCR_RST | DM9000_NCR_LBK_MAC_INTERNAL);
353           delay(20);
354           dme_write(sc, DM9000_NCR, 0x0);
355 
356           if (!sc->sc_phy_initialized) {
357                     /* PHY Enable */
358                     misc = dme_read(sc, DM9000_GPR);
359                     dme_write(sc, DM9000_GPR, misc & ~DM9000_GPR_PHY_PWROFF);
360                     misc = dme_read(sc, DM9000_GPCR);
361                     dme_write(sc, DM9000_GPCR, misc | DM9000_GPCR_GPIO0_OUT);
362 
363                     dme_write(sc, DM9000_NCR,
364                         DM9000_NCR_RST | DM9000_NCR_LBK_MAC_INTERNAL);
365                     delay(20);
366                     dme_write(sc, DM9000_NCR, 0x0);
367           }
368 
369           /* Select internal PHY, no wakeup event, no collosion mode,
370            * normal loopback mode.
371            */
372           dme_write(sc, DM9000_NCR, DM9000_NCR_LBK_NORMAL);
373 
374           /* Will clear TX1END, TX2END, and WAKEST fields by reading DM9000_NSR*/
375           dme_read(sc, DM9000_NSR);
376 
377           /* Enable wraparound of read/write pointer, frame received latch,
378            * and frame transmitted latch.
379            */
380           dme_write(sc, DM9000_IMR,
381               DM9000_IMR_PAR | DM9000_IMR_PRM | DM9000_IMR_PTM);
382 
383           dme_write(sc, DM9000_RCR,
384               DM9000_RCR_DIS_CRC | DM9000_RCR_DIS_LONG | DM9000_RCR_WTDIS);
385 
386           sc->sc_phy_initialized = 1;
387 }
388 
389 static int
dme_init(struct ifnet * ifp)390 dme_init(struct ifnet *ifp)
391 {
392           struct dme_softc *sc = ifp->if_softc;
393 
394           dme_stop(ifp, 0);
395           dme_reset(sc);
396           dme_write_c(sc, DM9000_PAB0, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
397           dme_set_rcvfilt(sc);
398           (void)ether_mediachange(ifp);
399 
400           sc->txbusy = sc->txready = 0;
401 
402           ifp->if_flags |= IFF_RUNNING;
403           callout_schedule(&sc->sc_link_callout, hz);
404 
405           return 0;
406 }
407 
408 /* Configure multicast filter */
409 static void
dme_set_rcvfilt(struct dme_softc * sc)410 dme_set_rcvfilt(struct dme_softc *sc)
411 {
412           struct ethercom     *ec = &sc->sc_ethercom;
413           struct ifnet *ifp = &ec->ec_if;
414           struct ether_multi *enm;
415           struct ether_multistep step;
416           uint8_t mchash[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; /* 64bit mchash */
417           uint32_t h = 0;
418           int rcr;
419 
420           rcr = dme_read(sc, DM9000_RCR);
421           rcr &= ~(DM9000_RCR_PRMSC | DM9000_RCR_ALL);
422           dme_write(sc, DM9000_RCR, rcr &~ DM9000_RCR_RXEN);
423 
424           ETHER_LOCK(ec);
425           if (ifp->if_flags & IFF_PROMISC) {
426                     ec->ec_flags |= ETHER_F_ALLMULTI;
427                     ETHER_UNLOCK(ec);
428                     /* run promisc. mode */
429                     rcr |= DM9000_RCR_PRMSC;
430                     goto update;
431           }
432           ec->ec_flags &= ~ETHER_F_ALLMULTI;
433           ETHER_FIRST_MULTI(step, ec, enm);
434           while (enm != NULL) {
435                     if (memcpy(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
436                               /*
437                                * We must listen to a range of multicast addresses.
438                                * For now, just accept all multicasts, rather than
439                                * trying to set only those filter bits needed to match
440                                * the range.  (At this time, the only use of address
441                                * ranges is for IP multicast routing, for which the
442                                * range is big enough to require all bits set.)
443                                */
444                               ec->ec_flags |= ETHER_F_ALLMULTI;
445                               ETHER_UNLOCK(ec);
446                               memset(mchash, 0xff, sizeof(mchash)); /* necessary? */
447                               /* accept all mulicast frame */
448                               rcr |= DM9000_RCR_ALL;
449                               goto update;
450                     }
451                     h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) & 0x3f;
452                     /* 3(5:3) and 3(2:0) sampling to have uint8_t[8] */
453                     mchash[h / 8] |= 1 << (h % 8);
454                     ETHER_NEXT_MULTI(step, enm);
455           }
456           ETHER_UNLOCK(ec);
457           /* DM9000 receive filter is always on */
458           mchash[7] |= 0x80; /* to catch bcast frame */
459  update:
460           dme_write_c(sc, DM9000_MAB0, mchash, sizeof(mchash));
461           dme_write(sc, DM9000_RCR, rcr | DM9000_RCR_RXEN);
462           return;
463 }
464 
465 void
lnkchg(struct dme_softc * sc)466 lnkchg(struct dme_softc *sc)
467 {
468           struct ifnet *ifp = &sc->sc_ethercom.ec_if;
469           struct ifmediareq ifmr;
470 
471           ether_mediastatus(ifp, &ifmr);
472 }
473 
474 static void
mii_statchg(struct ifnet * ifp)475 mii_statchg(struct ifnet *ifp)
476 {
477           struct dme_softc *sc = ifp->if_softc;
478           struct mii_data *mii = &sc->sc_mii;
479           uint8_t fcr, ncr;
480 
481 #if 0
482           const uint8_t Mbps[2] = { 10, 100 };
483           uint8_t nsr = dme_read(sc, DM9000_NSR);
484           int spd = Mbps[!!(nsr & DM9000_NSR_SPEED)];
485           /* speed/duplexity available also in reg 0x11 of internal PHY */
486           if (nsr & DM9000_NSR_LINKST)
487                     printf("link up,spd%d", spd);
488           else
489                     printf("link down");
490 
491           /* show resolved mii(4) parameters */
492           printf("MII spd%d",
493               (int)(sc->sc_ethercom.ec_if.if_baudrate / IF_Mbps(1)));
494           if (mii->mii_media_active & IFM_FDX)
495                     printf(",full-duplex");
496           printf("\n");
497 #endif
498 
499           /* Adjust duplexity and PAUSE flow control. */
500           fcr = dme_read(sc, DM9000_FCR) &~ DM9000_FCR_FLCE;
501           ncr = dme_read(sc, DM9000_NCR) &~ DM9000_NCR_FDX;
502           if ((mii->mii_media_active & IFM_FDX)
503               && (mii->mii_media_active & IFM_FLOW)) {
504                     fcr |= DM9000_FCR_FLCE;
505                     ncr |= DM9000_NCR_FDX;
506           }
507           dme_write(sc, DM9000_FCR, fcr);
508           dme_write(sc, DM9000_NCR, ncr);
509 }
510 
511 static void
phy_tick(void * arg)512 phy_tick(void *arg)
513 {
514           struct dme_softc *sc = arg;
515           struct mii_data *mii = &sc->sc_mii;
516           int s;
517 
518           s = splnet();
519           mii_tick(mii);
520           splx(s);
521 
522           callout_schedule(&sc->sc_link_callout, hz);
523 }
524 
525 static int
mii_readreg(device_t self,int phy,int reg,uint16_t * val)526 mii_readreg(device_t self, int phy, int reg, uint16_t *val)
527 {
528           struct dme_softc *sc = device_private(self);
529 
530           if (phy != 1)
531                     return EINVAL;
532 
533           /* Select Register to read*/
534           dme_write(sc, DM9000_EPAR, DM9000_EPAR_INT_PHY +
535               (reg & DM9000_EPAR_EROA_MASK));
536           /* Select read operation (DM9000_EPCR_ERPRR) from the PHY */
537           dme_write(sc, DM9000_EPCR, DM9000_EPCR_ERPRR + DM9000_EPCR_EPOS_PHY);
538 
539           /* Wait until access to PHY has completed */
540           while (dme_read(sc, DM9000_EPCR) & DM9000_EPCR_ERRE)
541                     ;
542 
543           /* Reset ERPRR-bit */
544           dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY);
545 
546           *val = dme_read(sc, DM9000_EPDRL) | (dme_read(sc, DM9000_EPDRH) << 8);
547           return 0;
548 }
549 
550 static int
mii_writereg(device_t self,int phy,int reg,uint16_t val)551 mii_writereg(device_t self, int phy, int reg, uint16_t val)
552 {
553           struct dme_softc *sc = device_private(self);
554 
555           if (phy != 1)
556                     return EINVAL;
557 
558           /* Select Register to write */
559           dme_write(sc, DM9000_EPAR, DM9000_EPAR_INT_PHY +
560               (reg & DM9000_EPAR_EROA_MASK));
561 
562           /* Write data to the two data registers */
563           dme_write(sc, DM9000_EPDRL, val & 0xFF);
564           dme_write(sc, DM9000_EPDRH, (val >> 8) & 0xFF);
565 
566           /* Select write operation (DM9000_EPCR_ERPRW) from the PHY */
567           dme_write(sc, DM9000_EPCR, DM9000_EPCR_ERPRW + DM9000_EPCR_EPOS_PHY);
568 
569           /* Wait until access to PHY has completed */
570           while (dme_read(sc, DM9000_EPCR) & DM9000_EPCR_ERRE)
571                     ;
572 
573           /* Reset ERPRR-bit */
574           dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY);
575 
576           return 0;
577 }
578 
579 void
dme_stop(struct ifnet * ifp,int disable)580 dme_stop(struct ifnet *ifp, int disable)
581 {
582           struct dme_softc *sc = ifp->if_softc;
583 
584           /* Not quite sure what to do when called with disable == 0 */
585           if (disable) {
586                     /* Disable RX */
587                     dme_write(sc, DM9000_RCR, 0x0);
588           }
589           mii_down(&sc->sc_mii);
590           callout_stop(&sc->sc_link_callout);
591 
592           ifp->if_flags &= ~IFF_RUNNING;
593           ifp->if_timer = 0;
594 }
595 
596 static void
dme_start(struct ifnet * ifp)597 dme_start(struct ifnet *ifp)
598 {
599           struct dme_softc *sc = ifp->if_softc;
600 
601           if ((ifp->if_flags & IFF_RUNNING) == 0) {
602                     return;
603           }
604           if (!sc->txready) {
605                     dme_prepare(ifp);
606           }
607           if (sc->txbusy) {
608                     /*
609                      * We need to wait until the current frame has
610                      * been transmitted.
611                      */
612                     return;
613           }
614           if (sc->txready) {
615                     /* We are ready to transmit right away */
616                     dme_transmit(ifp);
617           }
618           dme_prepare(ifp); /* Prepare next one */
619 }
620 
621 /* Prepare data to be transmitted (i.e. dequeue and load it into the DM9000) */
622 static void
dme_prepare(struct ifnet * ifp)623 dme_prepare(struct ifnet *ifp)
624 {
625           struct dme_softc *sc = ifp->if_softc;
626           uint16_t length;
627           struct mbuf *m;
628 
629           KASSERT(!sc->txready);
630 
631           IFQ_DEQUEUE(&ifp->if_snd, m);
632           if (m == NULL) {
633                     TX_DPRINTF(("dme_prepare: Nothing to transmit\n"));
634                     return; /* Nothing to transmit */
635           }
636 
637           /* Element has now been removed from the queue, so we better send it */
638 
639           bpf_mtap(ifp, m, BPF_D_OUT);
640 
641           /* Setup the DM9000 to accept the writes, and then write each buf in
642              the chain. */
643 
644           TX_DATA_DPRINTF(("dme_prepare: Writing data: "));
645           bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->dme_io, DM9000_MWCMD);
646           length = PKT_WRITE(sc, m);
647           bpf_mtap(ifp, m, BPF_D_OUT);
648           TX_DATA_DPRINTF(("\n"));
649 
650           if (length % sc->sc_data_width != 0)
651                     panic("dme_prepare: length is not compatible with IO_MODE");
652 
653           sc->txready_length = length;
654           sc->txready = 1;
655           m_freem(m);
656 }
657 
658 /* Transmit prepared data */
659 static void
dme_transmit(struct ifnet * ifp)660 dme_transmit(struct ifnet *ifp)
661 {
662           struct dme_softc *sc = ifp->if_softc;
663 
664           TX_DPRINTF(("dme_transmit: PRE: txready: %d, txbusy: %d\n",
665                     sc->txready, sc->txbusy));
666 
667           /* prime frame length first */
668           dme_write(sc, DM9000_TXPLL, sc->txready_length & 0xff);
669           dme_write(sc, DM9000_TXPLH, (sc->txready_length >> 8) & 0xff);
670           /* read isr next */
671           dme_read(sc, DM9000_ISR);
672           /* finally issue a request to send */
673           dme_write(sc, DM9000_TCR, DM9000_TCR_TXREQ);
674           sc->txready = 0;
675           sc->txbusy = 1;
676           sc->txready_length = 0;
677 }
678 
679 /* Receive data */
680 static void
dme_receive(struct ifnet * ifp)681 dme_receive(struct ifnet *ifp)
682 {
683           struct dme_softc *sc = ifp->if_softc;
684           struct mbuf *m;
685           uint8_t avail, rsr;
686 
687           DPRINTF(("inside dme_receive\n"));
688 
689           /* frame has just arrived, retrieve it */
690           /* called right after Rx frame available interrupt */
691           do {
692                     /* "no increment" read to get the avail byte without
693                        moving past it. */
694                     bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->dme_io,
695                               DM9000_MRCMDX);
696                     /* Read twice */
697                     avail = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data);
698                     avail = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data);
699                     avail &= 03;        /* 1:0 we only want these bits */
700                     if (avail == 01) {
701                               /* Read with address increment. */
702                               bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->dme_io,
703                                         DM9000_MRCMD);
704                               rsr = PKT_READ(sc, &m);
705                               if (m == NULL) {
706                                         /* failed to allocate a receive buffer */
707                                         RX_DPRINTF(("dme_receive: "
708                                                   "Error allocating buffer\n"));
709                                         if_statinc(ifp, if_ierrors);
710                                         continue;
711                               }
712                               if (rsr & (DM9000_RSR_CE | DM9000_RSR_PLE)) {
713                                         /* Error while receiving the frame,
714                                          * discard it and keep track of counters
715                                          */
716                                         RX_DPRINTF(("dme_receive: "
717                                                   "Error reciving frame\n"));
718                                         if_statinc(ifp, if_ierrors);
719                                         continue;
720                               }
721                               if (rsr & DM9000_RSR_LCS) {
722                                         if_statinc(ifp, if_collisions);
723                                         continue;
724                               }
725                               /* pick and forward this frame to ifq */
726                               if_percpuq_enqueue(ifp->if_percpuq, m);
727                     } else if (avail != 00) {
728                               /* Should this be logged somehow? */
729                               printf("%s: Resetting chip\n",
730                                      device_xname(sc->sc_dev));
731                               dme_reset(sc);
732                               break;
733                     }
734           } while (avail == 01);
735           /* frame received successfully */
736 }
737 
738 int
dme_intr(void * arg)739 dme_intr(void *arg)
740 {
741           struct dme_softc *sc = arg;
742           struct ifnet *ifp = &sc->sc_ethercom.ec_if;
743           uint8_t isr, nsr, tsr;
744 
745           DPRINTF(("dme_intr: Begin\n"));
746 
747           /* Disable interrupts */
748           dme_write(sc, DM9000_IMR, DM9000_IMR_PAR);
749 
750           isr = dme_read(sc, DM9000_ISR);
751           dme_write(sc, DM9000_ISR, isr); /* write to clear */
752 
753           if (isr & DM9000_ISR_PRS) {
754                     KASSERT(ifp->if_flags & IFF_RUNNING);
755                     dme_receive(ifp);
756           }
757           if (isr & DM9000_ISR_LNKCHNG)
758                     lnkchg(sc);
759           if (isr & DM9000_ISR_PTS) {
760                     tsr = 0x01; /* Initialize to an error value */
761 
762                     /* A frame has been transmitted */
763                     sc->txbusy = 0;
764 
765                     nsr = dme_read(sc, DM9000_NSR);
766                     if (nsr & DM9000_NSR_TX1END) {
767                               tsr = dme_read(sc, DM9000_TSR1);
768                               TX_DPRINTF(("dme_intr: Sent using channel 0\n"));
769                     } else if (nsr & DM9000_NSR_TX2END) {
770                               tsr = dme_read(sc, DM9000_TSR2);
771                               TX_DPRINTF(("dme_intr: Sent using channel 1\n"));
772                     }
773 
774                     if (tsr == 0x0) {
775                               /* Frame successfully sent */
776                               if_statinc(ifp, if_opackets);
777                     } else {
778                               if_statinc(ifp, if_oerrors);
779                     }
780 
781                     /* If we have nothing ready to transmit, prepare something */
782                     if (!sc->txready)
783                               dme_prepare(ifp);
784 
785                     if (sc->txready)
786                               dme_transmit(ifp);
787 
788                     /* Prepare the next frame */
789                     dme_prepare(ifp);
790 
791                     if_schedule_deferred_start(ifp);
792           }
793 
794           /* Enable interrupts again */
795           dme_write(sc, DM9000_IMR,
796               DM9000_IMR_PAR | DM9000_IMR_PRM | DM9000_IMR_PTM);
797 
798           DPRINTF(("dme_intr: End\n"));
799 
800           return (isr != 0);
801 }
802 
803 static int
dme_ioctl(struct ifnet * ifp,u_long cmd,void * data)804 dme_ioctl(struct ifnet *ifp, u_long cmd, void *data)
805 {
806           struct dme_softc *sc = ifp->if_softc;
807           struct ifreq *ifr = (struct ifreq *)data;
808           struct ifmedia *ifm = &sc->sc_mii.mii_media;
809           int s, error;
810 
811           s = splnet();
812           switch (cmd) {
813           case SIOCSIFMEDIA:
814                     /* Flow control requires full-duplex mode. */
815                     if (IFM_SUBTYPE(ifr->ifr_media) == IFM_AUTO ||
816                         (ifr->ifr_media & IFM_FDX) == 0)
817                               ifr->ifr_media &= ~IFM_ETH_FMASK;
818                     if (IFM_SUBTYPE(ifr->ifr_media) != IFM_AUTO) {
819                               if ((ifr->ifr_media & IFM_ETH_FMASK) == IFM_FLOW) {
820                                         ifr->ifr_media |=
821                                                   IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE;
822                               }
823                     }
824                     error = ifmedia_ioctl(ifp, ifr, ifm, cmd);
825                     break;
826           default:
827                     if ((error = ether_ioctl(ifp, cmd, data)) != ENETRESET)
828                               break;
829                     error = 0;
830                     if (cmd == SIOCSIFCAP)
831                               error = if_init(ifp);
832                     else if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
833                               ;
834                     else if (ifp->if_flags && IFF_RUNNING) {
835                               /* Address list has changed, reconfigure filter */
836                               dme_set_rcvfilt(sc);
837                     }
838                     break;
839           }
840           splx(s);
841           return error;
842 }
843 
844 static struct mbuf *
dme_alloc_receive_buffer(struct ifnet * ifp,unsigned int frame_length)845 dme_alloc_receive_buffer(struct ifnet *ifp, unsigned int frame_length)
846 {
847           struct dme_softc *sc = ifp->if_softc;
848           struct mbuf *m;
849           int pad, quantum;
850 
851           quantum = sc->sc_data_width;
852           MGETHDR(m, M_DONTWAIT, MT_DATA);
853           if (m == NULL)
854                     return NULL;
855 
856           m_set_rcvif(m, ifp);
857           /* Ensure that we always allocate an even number of
858            * bytes in order to avoid writing beyond the buffer
859            */
860           m->m_pkthdr.len = frame_length + (frame_length % quantum);
861           pad = ALIGN(sizeof(struct ether_header)) -
862                     sizeof(struct ether_header);
863           /* All our frames have the CRC attached */
864           m->m_flags |= M_HASFCS;
865           if (m->m_pkthdr.len + pad > MHLEN) {
866                     MCLGET(m, M_DONTWAIT);
867                     if ((m->m_flags & M_EXT) == 0) {
868                               m_freem(m);
869                               return NULL;
870                     }
871           }
872 
873           m->m_data += pad;
874           m->m_len = frame_length + (frame_length % quantum);
875 
876           return m;
877 }
878 
879 static int
pkt_write_2(struct dme_softc * sc,struct mbuf * bufChain)880 pkt_write_2(struct dme_softc *sc, struct mbuf *bufChain)
881 {
882           int left_over_count = 0; /* Number of bytes from previous mbuf, which
883                                             need to be written with the next.*/
884           uint16_t left_over_buf = 0;
885           int length = 0;
886           struct mbuf *buf;
887           uint8_t *write_ptr;
888 
889           /* We expect that the DM9000 has been setup to accept writes before
890              this function is called. */
891 
892           for (buf = bufChain; buf != NULL; buf = buf->m_next) {
893                     int to_write = buf->m_len;
894 
895                     length += to_write;
896 
897                     write_ptr = buf->m_data;
898                     while (to_write > 0 ||
899                         (buf->m_next == NULL && left_over_count > 0)) {
900                               if (left_over_count > 0) {
901                                         uint8_t b = 0;
902                                         DPRINTF(("pkt_write_16: "
903                                                    "Writing left over byte\n"));
904 
905                                         if (to_write > 0) {
906                                                   b = *write_ptr;
907                                                   to_write--;
908                                                   write_ptr++;
909 
910                                                   DPRINTF(("Took single byte\n"));
911                                         } else {
912                                                   DPRINTF(("Leftover in last run\n"));
913                                                   length++;
914                                         }
915 
916                                         /* Does shift direction depend on endianness? */
917                                         left_over_buf = left_over_buf | (b << 8);
918 
919                                         bus_space_write_2(sc->sc_iot, sc->sc_ioh,
920                                                               sc->dme_data, left_over_buf);
921                                         TX_DATA_DPRINTF(("%02X ", left_over_buf));
922                                         left_over_count = 0;
923                               } else if ((long)write_ptr % 2 != 0) {
924                                         /* Misaligned data */
925                                         DPRINTF(("pkt_write_16: "
926                                                    "Detected misaligned data\n"));
927                                         left_over_buf = *write_ptr;
928                                         left_over_count = 1;
929                                         write_ptr++;
930                                         to_write--;
931                               } else {
932                                         int i;
933                                         uint16_t *dptr = (uint16_t *)write_ptr;
934 
935                                         /* A block of aligned data. */
936                                         for (i = 0; i < to_write / 2; i++) {
937                                                   /* buf will be half-word aligned
938                                                    * all the time
939                                                    */
940                                                   bus_space_write_2(sc->sc_iot,
941                                                       sc->sc_ioh, sc->dme_data, *dptr);
942                                                   TX_DATA_DPRINTF(("%02X %02X ",
943                                                       *dptr & 0xFF, (*dptr >> 8) & 0xFF));
944                                                   dptr++;
945                                         }
946 
947                                         write_ptr += i * 2;
948                                         if (to_write % 2 != 0) {
949                                                   DPRINTF(("pkt_write_16: "
950                                                              "to_write %% 2: %d\n",
951                                                              to_write % 2));
952                                                   left_over_count = 1;
953                                                   /* XXX: Does this depend on
954                                                    * the endianness?
955                                                    */
956                                                   left_over_buf = *write_ptr;
957 
958                                                   write_ptr++;
959                                                   to_write--;
960                                                   DPRINTF(("pkt_write_16: "
961                                                              "to_write (after): %d\n",
962                                                              to_write));
963                                                   DPRINTF(("pkt_write_16: i * 2: %d\n",
964                                                              i*2));
965                                         }
966                                         to_write -= i * 2;
967                               }
968                     } /* while (...) */
969           } /* for (...) */
970 
971           return length;
972 }
973 
974 static int
pkt_read_2(struct dme_softc * sc,struct mbuf ** outBuf)975 pkt_read_2(struct dme_softc *sc, struct mbuf **outBuf)
976 {
977           struct ifnet *ifp = &sc->sc_ethercom.ec_if;
978           uint8_t rx_status;
979           struct mbuf *m;
980           uint16_t data;
981           uint16_t frame_length;
982           uint16_t i;
983           uint16_t *buf;
984 
985           data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, sc->dme_data);
986           rx_status = data & 0xFF;
987 
988           frame_length = bus_space_read_2(sc->sc_iot,
989                                                   sc->sc_ioh, sc->dme_data);
990           if (frame_length > ETHER_MAX_LEN) {
991                     printf("Got frame of length: %d\n", frame_length);
992                     printf("ETHER_MAX_LEN is: %d\n", ETHER_MAX_LEN);
993                     panic("Something is rotten");
994           }
995           RX_DPRINTF(("dme_receive: rx_statux: 0x%x, frame_length: %d\n",
996                     rx_status, frame_length));
997 
998           m = dme_alloc_receive_buffer(ifp, frame_length);
999           if (m == NULL) {
1000                     /*
1001                      * didn't get a receive buffer, so we read the rest of the
1002                      * frame, throw it away and return an error
1003                      */
1004                     for (i = 0; i < frame_length; i += 2) {
1005                               data = bus_space_read_2(sc->sc_iot,
1006                                                   sc->sc_ioh, sc->dme_data);
1007                     }
1008                     *outBuf = NULL;
1009                     return 0;
1010           }
1011 
1012           buf = mtod(m, uint16_t*);
1013 
1014           RX_DPRINTF(("dme_receive: "));
1015 
1016           for (i = 0; i < frame_length; i += 2) {
1017                     data = bus_space_read_2(sc->sc_iot,
1018                                                   sc->sc_ioh, sc->dme_data);
1019                     if ( (frame_length % 2 != 0) &&
1020                          (i == frame_length - 1) ) {
1021                               data = data & 0xff;
1022                               RX_DPRINTF((" L "));
1023                     }
1024                     *buf = data;
1025                     buf++;
1026                     RX_DATA_DPRINTF(("%02X %02X ", data & 0xff,
1027                                          (data >> 8) & 0xff));
1028           }
1029 
1030           RX_DATA_DPRINTF(("\n"));
1031           RX_DPRINTF(("Read %d bytes\n", i));
1032 
1033           *outBuf = m;
1034           return rx_status;
1035 }
1036 
1037 static int
pkt_write_1(struct dme_softc * sc,struct mbuf * bufChain)1038 pkt_write_1(struct dme_softc *sc, struct mbuf *bufChain)
1039 {
1040           int length = 0, i;
1041           struct mbuf *buf;
1042           uint8_t *write_ptr;
1043 
1044           /*
1045            * We expect that the DM9000 has been setup to accept writes before
1046            * this function is called.
1047            */
1048 
1049           for (buf = bufChain; buf != NULL; buf = buf->m_next) {
1050                     int to_write = buf->m_len;
1051 
1052                     length += to_write;
1053 
1054                     write_ptr = buf->m_data;
1055                     for (i = 0; i < to_write; i++) {
1056                               bus_space_write_1(sc->sc_iot, sc->sc_ioh,
1057                                   sc->dme_data, *write_ptr);
1058                               write_ptr++;
1059                     }
1060           } /* for (...) */
1061 
1062           return length;
1063 }
1064 
1065 static int
pkt_read_1(struct dme_softc * sc,struct mbuf ** outBuf)1066 pkt_read_1(struct dme_softc *sc, struct mbuf **outBuf)
1067 {
1068           struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1069           uint8_t rx_status;
1070           struct mbuf *m;
1071           uint8_t *buf;
1072           uint16_t frame_length;
1073           uint16_t i, reg;
1074           uint8_t data;
1075 
1076           reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data);
1077           reg |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data) << 8;
1078           rx_status = reg & 0xFF;
1079 
1080           reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data);
1081           reg |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data) << 8;
1082           frame_length = reg;
1083 
1084           if (frame_length > ETHER_MAX_LEN) {
1085                     printf("Got frame of length: %d\n", frame_length);
1086                     printf("ETHER_MAX_LEN is: %d\n", ETHER_MAX_LEN);
1087                     panic("Something is rotten");
1088           }
1089           RX_DPRINTF(("dme_receive: "
1090                         "rx_statux: 0x%x, frame_length: %d\n",
1091                         rx_status, frame_length));
1092 
1093           m = dme_alloc_receive_buffer(ifp, frame_length);
1094           if (m == NULL) {
1095                     /*
1096                      * didn't get a receive buffer, so we read the rest of the
1097                      * frame, throw it away and return an error
1098                      */
1099                     for (i = 0; i < frame_length; i++ ) {
1100                               data = bus_space_read_2(sc->sc_iot,
1101                                                   sc->sc_ioh, sc->dme_data);
1102                     }
1103                     *outBuf = NULL;
1104                     return 0;
1105           }
1106 
1107           buf = mtod(m, uint8_t *);
1108 
1109           RX_DPRINTF(("dme_receive: "));
1110           for (i = 0; i< frame_length; i += 1) {
1111                     data = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data);
1112                     *buf = data;
1113                     buf++;
1114                     RX_DATA_DPRINTF(("%02X ", data));
1115           }
1116 
1117           RX_DATA_DPRINTF(("\n"));
1118           RX_DPRINTF(("Read %d bytes\n", i));
1119 
1120           *outBuf = m;
1121           return rx_status;
1122 }
1123