if_mec.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395
  1. /* $OpenBSD: if_mec.c,v 1.30 2015/06/24 09:40:53 mpi Exp $ */
  2. /* $NetBSD: if_mec_mace.c,v 1.5 2004/08/01 06:36:36 tsutsui Exp $ */
  3. /*
  4. * Copyright (c) 2004 Izumi Tsutsui.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. The name of the author may not be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  19. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  20. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. /*
  30. * Copyright (c) 2003 Christopher SEKIYA
  31. * All rights reserved.
  32. *
  33. * Redistribution and use in source and binary forms, with or without
  34. * modification, are permitted provided that the following conditions
  35. * are met:
  36. * 1. Redistributions of source code must retain the above copyright
  37. * notice, this list of conditions and the following disclaimer.
  38. * 2. Redistributions in binary form must reproduce the above copyright
  39. * notice, this list of conditions and the following disclaimer in the
  40. * documentation and/or other materials provided with the distribution.
  41. * 3. All advertising materials mentioning features or use of this software
  42. * must display the following acknowledgement:
  43. * This product includes software developed for the
  44. * NetBSD Project. See http://www.NetBSD.org/ for
  45. * information about NetBSD.
  46. * 4. The name of the author may not be used to endorse or promote products
  47. * derived from this software without specific prior written permission.
  48. *
  49. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  50. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  51. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  52. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  53. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  54. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  55. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  56. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  57. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  58. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59. */
  60. /*
  61. * MACE MAC-110 Ethernet driver.
  62. */
  63. #include "bpfilter.h"
  64. #include <sys/param.h>
  65. #include <sys/systm.h>
  66. #include <sys/device.h>
  67. #include <sys/timeout.h>
  68. #include <sys/mbuf.h>
  69. #include <sys/malloc.h>
  70. #include <sys/kernel.h>
  71. #include <sys/socket.h>
  72. #include <sys/ioctl.h>
  73. #include <sys/errno.h>
  74. #include <net/if.h>
  75. #include <net/if_dl.h>
  76. #include <net/if_media.h>
  77. #include <net/if_types.h>
  78. #if NBPFILTER > 0
  79. #include <net/bpf.h>
  80. #endif
  81. #include <netinet/in.h>
  82. #include <netinet/if_ether.h>
  83. #include <machine/bus.h>
  84. #include <machine/intr.h>
  85. #include <machine/autoconf.h>
  86. #include <dev/mii/mii.h>
  87. #include <dev/mii/miivar.h>
  88. #include <mips64/arcbios.h>
  89. #include <sgi/dev/if_mecreg.h>
  90. #include <sgi/localbus/macebusvar.h>
  91. #ifdef MEC_DEBUG
  92. #define MEC_DEBUG_RESET 0x01
  93. #define MEC_DEBUG_START 0x02
  94. #define MEC_DEBUG_STOP 0x04
  95. #define MEC_DEBUG_INTR 0x08
  96. #define MEC_DEBUG_RXINTR 0x10
  97. #define MEC_DEBUG_TXINTR 0x20
  98. uint32_t mec_debug = 0xff;
  99. #define DPRINTF(x, y) if (mec_debug & (x)) printf y
  100. #else
  101. #define DPRINTF(x, y) /* nothing */
  102. #endif
  103. /*
  104. * Transmit descriptor list size.
  105. */
  106. #define MEC_NTXDESC 64
  107. #define MEC_NTXDESC_MASK (MEC_NTXDESC - 1)
  108. #define MEC_NEXTTX(x) (((x) + 1) & MEC_NTXDESC_MASK)
  109. /*
  110. * Software state for TX.
  111. */
  112. struct mec_txsoft {
  113. struct mbuf *txs_mbuf; /* Head of our mbuf chain. */
  114. bus_dmamap_t txs_dmamap; /* Our DMA map. */
  115. uint32_t txs_flags;
  116. #define MEC_TXS_BUFLEN_MASK 0x0000007f /* Data len in txd_buf. */
  117. #define MEC_TXS_TXDBUF 0x00000080 /* txd_buf is used. */
  118. #define MEC_TXS_TXDPTR1 0x00000100 /* txd_ptr[0] is used. */
  119. };
  120. /*
  121. * Transmit buffer descriptor.
  122. */
  123. #define MEC_TXDESCSIZE 128
  124. #define MEC_NTXPTR 3
  125. #define MEC_TXD_BUFOFFSET \
  126. (sizeof(uint64_t) + MEC_NTXPTR * sizeof(uint64_t))
  127. #define MEC_TXD_BUFSIZE (MEC_TXDESCSIZE - MEC_TXD_BUFOFFSET)
  128. #define MEC_TXD_BUFSTART(len) (MEC_TXD_BUFSIZE - (len))
  129. #define MEC_TXD_ALIGN 8
  130. #define MEC_TXD_ROUNDUP(addr) \
  131. (((addr) + (MEC_TXD_ALIGN - 1)) & ~((uint64_t)MEC_TXD_ALIGN - 1))
  132. struct mec_txdesc {
  133. volatile uint64_t txd_cmd;
  134. #define MEC_TXCMD_DATALEN 0x000000000000ffff /* Data length. */
  135. #define MEC_TXCMD_BUFSTART 0x00000000007f0000 /* Start byte offset. */
  136. #define TXCMD_BUFSTART(x) ((x) << 16)
  137. #define MEC_TXCMD_TERMDMA 0x0000000000800000 /* Stop DMA on abort. */
  138. #define MEC_TXCMD_TXINT 0x0000000001000000 /* INT after TX done. */
  139. #define MEC_TXCMD_PTR1 0x0000000002000000 /* Valid 1st txd_ptr. */
  140. #define MEC_TXCMD_PTR2 0x0000000004000000 /* Valid 2nd txd_ptr. */
  141. #define MEC_TXCMD_PTR3 0x0000000008000000 /* Valid 3rd txd_ptr. */
  142. #define MEC_TXCMD_UNUSED 0xfffffffff0000000ULL /* Should be zero. */
  143. #define txd_stat txd_cmd
  144. #define MEC_TXSTAT_LEN 0x000000000000ffff /* TX length. */
  145. #define MEC_TXSTAT_COLCNT 0x00000000000f0000 /* Collision count. */
  146. #define MEC_TXSTAT_COLCNT_SHIFT 16
  147. #define MEC_TXSTAT_LATE_COL 0x0000000000100000 /* Late collision. */
  148. #define MEC_TXSTAT_CRCERROR 0x0000000000200000 /* */
  149. #define MEC_TXSTAT_DEFERRED 0x0000000000400000 /* */
  150. #define MEC_TXSTAT_SUCCESS 0x0000000000800000 /* TX complete. */
  151. #define MEC_TXSTAT_TOOBIG 0x0000000001000000 /* */
  152. #define MEC_TXSTAT_UNDERRUN 0x0000000002000000 /* */
  153. #define MEC_TXSTAT_COLLISIONS 0x0000000004000000 /* */
  154. #define MEC_TXSTAT_EXDEFERRAL 0x0000000008000000 /* */
  155. #define MEC_TXSTAT_COLLIDED 0x0000000010000000 /* */
  156. #define MEC_TXSTAT_UNUSED 0x7fffffffe0000000ULL /* Should be zero. */
  157. #define MEC_TXSTAT_SENT 0x8000000000000000ULL /* Packet sent. */
  158. uint64_t txd_ptr[MEC_NTXPTR];
  159. #define MEC_TXPTR_UNUSED2 0x0000000000000007 /* Should be zero. */
  160. #define MEC_TXPTR_DMAADDR 0x00000000fffffff8 /* TX DMA address. */
  161. #define MEC_TXPTR_LEN 0x0000ffff00000000ULL /* Buffer length. */
  162. #define TXPTR_LEN(x) ((uint64_t)(x) << 32)
  163. #define MEC_TXPTR_UNUSED1 0xffff000000000000ULL /* Should be zero. */
  164. uint8_t txd_buf[MEC_TXD_BUFSIZE];
  165. };
  166. /*
  167. * Receive buffer size.
  168. */
  169. #define MEC_NRXDESC 16
  170. #define MEC_NRXDESC_MASK (MEC_NRXDESC - 1)
  171. #define MEC_NEXTRX(x) (((x) + 1) & MEC_NRXDESC_MASK)
  172. /*
  173. * Receive buffer description.
  174. */
  175. #define MEC_RXDESCSIZE 4096 /* Umm, should be 4kbyte aligned. */
  176. #define MEC_RXD_NRXPAD 3
  177. #define MEC_RXD_DMAOFFSET (1 + MEC_RXD_NRXPAD)
  178. #define MEC_RXD_BUFOFFSET (MEC_RXD_DMAOFFSET * sizeof(uint64_t))
  179. #define MEC_RXD_BUFSIZE (MEC_RXDESCSIZE - MEC_RXD_BUFOFFSET)
  180. struct mec_rxdesc {
  181. volatile uint64_t rxd_stat;
  182. #define MEC_RXSTAT_LEN 0x000000000000ffff /* Data length. */
  183. #define MEC_RXSTAT_VIOLATION 0x0000000000010000 /* Code violation (?). */
  184. #define MEC_RXSTAT_UNUSED2 0x0000000000020000 /* Unknown (?). */
  185. #define MEC_RXSTAT_CRCERROR 0x0000000000040000 /* CRC error. */
  186. #define MEC_RXSTAT_MULTICAST 0x0000000000080000 /* Multicast packet. */
  187. #define MEC_RXSTAT_BROADCAST 0x0000000000100000 /* Broadcast packet. */
  188. #define MEC_RXSTAT_INVALID 0x0000000000200000 /* Invalid preamble. */
  189. #define MEC_RXSTAT_LONGEVENT 0x0000000000400000 /* Long packet. */
  190. #define MEC_RXSTAT_BADPACKET 0x0000000000800000 /* Bad packet. */
  191. #define MEC_RXSTAT_CAREVENT 0x0000000001000000 /* Carrier event. */
  192. #define MEC_RXSTAT_MATCHMCAST 0x0000000002000000 /* Match multicast. */
  193. #define MEC_RXSTAT_MATCHMAC 0x0000000004000000 /* Match MAC. */
  194. #define MEC_RXSTAT_SEQNUM 0x00000000f8000000 /* Sequence number. */
  195. #define MEC_RXSTAT_CKSUM 0x0000ffff00000000ULL /* IP checksum. */
  196. #define MEC_RXSTAT_UNUSED1 0x7fff000000000000ULL /* Should be zero. */
  197. #define MEC_RXSTAT_RECEIVED 0x8000000000000000ULL /* Set to 1 on RX. */
  198. uint64_t rxd_pad1[MEC_RXD_NRXPAD];
  199. uint8_t rxd_buf[MEC_RXD_BUFSIZE];
  200. };
  201. /*
  202. * Control structures for DMA ops.
  203. */
  204. struct mec_control_data {
  205. /*
  206. * TX descriptors and buffers.
  207. */
  208. struct mec_txdesc mcd_txdesc[MEC_NTXDESC];
  209. /*
  210. * RX descriptors and buffers.
  211. */
  212. struct mec_rxdesc mcd_rxdesc[MEC_NRXDESC];
  213. };
  214. /*
  215. * It _seems_ there are some restrictions on descriptor address:
  216. *
  217. * - Base address of txdescs should be 8kbyte aligned
  218. * - Each txdesc should be 128byte aligned
  219. * - Each rxdesc should be 4kbyte aligned
  220. *
  221. * So we should specify 64k align to allocalte txdescs.
  222. * In this case, sizeof(struct mec_txdesc) * MEC_NTXDESC is 8192
  223. * so rxdescs are also allocated at 4kbyte aligned.
  224. */
  225. #define MEC_CONTROL_DATA_ALIGN (8 * 1024)
  226. #define MEC_CDOFF(x) offsetof(struct mec_control_data, x)
  227. #define MEC_CDTXOFF(x) MEC_CDOFF(mcd_txdesc[(x)])
  228. #define MEC_CDRXOFF(x) MEC_CDOFF(mcd_rxdesc[(x)])
  229. /*
  230. * Software state per device.
  231. */
  232. struct mec_softc {
  233. struct device sc_dev; /* Generic device structures. */
  234. struct arpcom sc_ac; /* Ethernet common part. */
  235. bus_space_tag_t sc_st; /* bus_space tag. */
  236. bus_space_handle_t sc_sh; /* bus_space handle. */
  237. bus_dma_tag_t sc_dmat; /* bus_dma tag. */
  238. struct mii_data sc_mii; /* MII/media information. */
  239. int sc_phyaddr; /* MII address. */
  240. struct timeout sc_tick_ch; /* Tick timeout. */
  241. bus_dmamap_t sc_cddmamap; /* bus_dma map for control data. */
  242. #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
  243. /* Pointer to allocated control data. */
  244. struct mec_control_data *sc_control_data;
  245. #define sc_txdesc sc_control_data->mcd_txdesc
  246. #define sc_rxdesc sc_control_data->mcd_rxdesc
  247. /* Software state for TX descs. */
  248. struct mec_txsoft sc_txsoft[MEC_NTXDESC];
  249. int sc_txpending; /* Number of TX requests pending. */
  250. int sc_txdirty; /* First dirty TX descriptor. */
  251. int sc_txlast; /* Last used TX descriptor. */
  252. int sc_rxptr; /* Next ready RX buffer. */
  253. };
  254. #define MEC_CDTXADDR(sc, x) ((sc)->sc_cddma + MEC_CDTXOFF(x))
  255. #define MEC_CDRXADDR(sc, x) ((sc)->sc_cddma + MEC_CDRXOFF(x))
  256. #define MEC_TXDESCSYNC(sc, x, ops) \
  257. bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
  258. MEC_CDTXOFF(x), MEC_TXDESCSIZE, (ops))
  259. #define MEC_TXCMDSYNC(sc, x, ops) \
  260. bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
  261. MEC_CDTXOFF(x), sizeof(uint64_t), (ops))
  262. #define MEC_RXSTATSYNC(sc, x, ops) \
  263. bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
  264. MEC_CDRXOFF(x), sizeof(uint64_t), (ops))
  265. #define MEC_RXBUFSYNC(sc, x, len, ops) \
  266. bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
  267. MEC_CDRXOFF(x) + MEC_RXD_BUFOFFSET, \
  268. ETHER_ALIGN + (len), (ops))
  269. /* XXX these values should be moved to <net/if_ether.h> ? */
  270. #define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
  271. struct cfdriver mec_cd = {
  272. NULL, "mec", DV_IFNET
  273. };
  274. int mec_match(struct device *, void *, void *);
  275. void mec_attach(struct device *, struct device *, void *);
  276. struct cfattach mec_ca = {
  277. sizeof(struct mec_softc), mec_match, mec_attach
  278. };
  279. int mec_mii_readreg(struct device *, int, int);
  280. void mec_mii_writereg(struct device *, int, int, int);
  281. int mec_mii_wait(struct mec_softc *);
  282. void mec_statchg(struct device *);
  283. void mec_mediastatus(struct ifnet *, struct ifmediareq *);
  284. int mec_mediachange(struct ifnet *);
  285. int mec_init(struct ifnet * ifp);
  286. void mec_start(struct ifnet *);
  287. void mec_watchdog(struct ifnet *);
  288. void mec_tick(void *);
  289. int mec_ioctl(struct ifnet *, u_long, caddr_t);
  290. void mec_reset(struct mec_softc *);
  291. void mec_iff(struct mec_softc *);
  292. int mec_intr(void *arg);
  293. void mec_stop(struct ifnet *);
  294. void mec_rxintr(struct mec_softc *, uint32_t);
  295. void mec_txintr(struct mec_softc *, uint32_t);
  296. int
  297. mec_match(struct device *parent, void *match, void *aux)
  298. {
  299. return (1);
  300. }
  301. void
  302. mec_attach(struct device *parent, struct device *self, void *aux)
  303. {
  304. struct mec_softc *sc = (void *)self;
  305. struct macebus_attach_args *maa = aux;
  306. struct ifnet *ifp = &sc->sc_ac.ac_if;
  307. uint32_t command;
  308. struct mii_softc *child;
  309. bus_dma_segment_t seg;
  310. int i, err, rseg;
  311. sc->sc_st = maa->maa_iot;
  312. if (bus_space_map(sc->sc_st, maa->maa_baseaddr, MEC_NREGS, 0,
  313. &sc->sc_sh) != 0) {
  314. printf(": can't map i/o space\n");
  315. return;
  316. }
  317. /* Set up DMA structures. */
  318. sc->sc_dmat = maa->maa_dmat;
  319. /*
  320. * Allocate the control data structures, and create and load the
  321. * DMA map for it.
  322. */
  323. if ((err = bus_dmamem_alloc(sc->sc_dmat,
  324. sizeof(struct mec_control_data), MEC_CONTROL_DATA_ALIGN, 0,
  325. &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
  326. printf(": unable to allocate control data, error = %d\n", err);
  327. goto fail_0;
  328. }
  329. /*
  330. * XXX needs re-think...
  331. * control data structures contain whole RX data buffer, so
  332. * BUS_DMA_COHERENT (which disables cache) may cause some performance
  333. * issue on copying data from the RX buffer to mbuf on normal memory,
  334. * though we have to make sure all bus_dmamap_sync(9) ops are called
  335. * properly in that case.
  336. */
  337. if ((err = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
  338. sizeof(struct mec_control_data),
  339. (caddr_t *)&sc->sc_control_data, /*BUS_DMA_COHERENT*/ 0)) != 0) {
  340. printf(": unable to map control data, error = %d\n", err);
  341. goto fail_1;
  342. }
  343. memset(sc->sc_control_data, 0, sizeof(struct mec_control_data));
  344. if ((err = bus_dmamap_create(sc->sc_dmat,
  345. sizeof(struct mec_control_data), 1,
  346. sizeof(struct mec_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
  347. printf(": unable to create control data DMA map, error = %d\n",
  348. err);
  349. goto fail_2;
  350. }
  351. if ((err = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
  352. sc->sc_control_data, sizeof(struct mec_control_data), NULL,
  353. BUS_DMA_NOWAIT)) != 0) {
  354. printf(": unable to load control data DMA map, error = %d\n",
  355. err);
  356. goto fail_3;
  357. }
  358. /* Create TX buffer DMA maps. */
  359. for (i = 0; i < MEC_NTXDESC; i++) {
  360. if ((err = bus_dmamap_create(sc->sc_dmat,
  361. MCLBYTES, 1, MCLBYTES, 0, 0,
  362. &sc->sc_txsoft[i].txs_dmamap)) != 0) {
  363. printf(": unable to create tx DMA map %d, error = %d\n",
  364. i, err);
  365. goto fail_4;
  366. }
  367. }
  368. timeout_set(&sc->sc_tick_ch, mec_tick, sc);
  369. /* Use the Ethernet address from the ARCBIOS. */
  370. enaddr_aton(bios_enaddr, sc->sc_ac.ac_enaddr);
  371. /* Reset device. */
  372. mec_reset(sc);
  373. command = bus_space_read_8(sc->sc_st, sc->sc_sh, MEC_MAC_CONTROL);
  374. printf(": MAC-110 rev %d, address %s\n",
  375. (command & MEC_MAC_REVISION) >> MEC_MAC_REVISION_SHIFT,
  376. ether_sprintf(sc->sc_ac.ac_enaddr));
  377. /* Done, now attach everything. */
  378. sc->sc_mii.mii_ifp = ifp;
  379. sc->sc_mii.mii_readreg = mec_mii_readreg;
  380. sc->sc_mii.mii_writereg = mec_mii_writereg;
  381. sc->sc_mii.mii_statchg = mec_statchg;
  382. /* Set up PHY properties. */
  383. ifmedia_init(&sc->sc_mii.mii_media, 0, mec_mediachange,
  384. mec_mediastatus);
  385. mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
  386. MII_OFFSET_ANY, 0);
  387. child = LIST_FIRST(&sc->sc_mii.mii_phys);
  388. if (child == NULL) {
  389. /* No PHY attached. */
  390. ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL,
  391. 0, NULL);
  392. ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL);
  393. } else {
  394. ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);
  395. sc->sc_phyaddr = child->mii_phy;
  396. }
  397. bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
  398. ifp->if_softc = sc;
  399. ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  400. ifp->if_ioctl = mec_ioctl;
  401. ifp->if_start = mec_start;
  402. ifp->if_watchdog = mec_watchdog;
  403. IFQ_SET_READY(&ifp->if_snd);
  404. if_attach(ifp);
  405. IFQ_SET_MAXLEN(&ifp->if_snd, MEC_NTXDESC - 1);
  406. ether_ifattach(ifp);
  407. /* Establish interrupt handler. */
  408. macebus_intr_establish(maa->maa_intr, maa->maa_mace_intr,
  409. IST_EDGE, IPL_NET, mec_intr, sc, sc->sc_dev.dv_xname);
  410. return;
  411. /*
  412. * Free any resources we've allocated during the failed attach
  413. * attempt. Do this in reverse order and fall though.
  414. */
  415. fail_4:
  416. for (i = 0; i < MEC_NTXDESC; i++) {
  417. if (sc->sc_txsoft[i].txs_dmamap != NULL)
  418. bus_dmamap_destroy(sc->sc_dmat,
  419. sc->sc_txsoft[i].txs_dmamap);
  420. }
  421. bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
  422. fail_3:
  423. bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
  424. fail_2:
  425. bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
  426. sizeof(struct mec_control_data));
  427. fail_1:
  428. bus_dmamem_free(sc->sc_dmat, &seg, rseg);
  429. fail_0:
  430. return;
  431. }
  432. int
  433. mec_mii_readreg(struct device *self, int phy, int reg)
  434. {
  435. struct mec_softc *sc = (void *)self;
  436. bus_space_tag_t st = sc->sc_st;
  437. bus_space_handle_t sh = sc->sc_sh;
  438. uint32_t val;
  439. int i;
  440. if (mec_mii_wait(sc) != 0)
  441. return 0;
  442. bus_space_write_4(st, sh, MEC_PHY_ADDRESS,
  443. (phy << MEC_PHY_ADDR_DEVSHIFT) | (reg & MEC_PHY_ADDR_REGISTER));
  444. bus_space_write_8(st, sh, MEC_PHY_READ_INITIATE, 1);
  445. delay(25);
  446. for (i = 0; i < 20; i++) {
  447. delay(30);
  448. val = bus_space_read_4(st, sh, MEC_PHY_DATA);
  449. if ((val & MEC_PHY_DATA_BUSY) == 0)
  450. return val & MEC_PHY_DATA_VALUE;
  451. }
  452. return 0;
  453. }
  454. void
  455. mec_mii_writereg(struct device *self, int phy, int reg, int val)
  456. {
  457. struct mec_softc *sc = (void *)self;
  458. bus_space_tag_t st = sc->sc_st;
  459. bus_space_handle_t sh = sc->sc_sh;
  460. if (mec_mii_wait(sc) != 0) {
  461. printf("timed out writing %x: %x\n", reg, val);
  462. return;
  463. }
  464. bus_space_write_4(st, sh, MEC_PHY_ADDRESS,
  465. (phy << MEC_PHY_ADDR_DEVSHIFT) | (reg & MEC_PHY_ADDR_REGISTER));
  466. delay(60);
  467. bus_space_write_4(st, sh, MEC_PHY_DATA, val & MEC_PHY_DATA_VALUE);
  468. delay(60);
  469. mec_mii_wait(sc);
  470. }
  471. int
  472. mec_mii_wait(struct mec_softc *sc)
  473. {
  474. uint32_t busy;
  475. int i, s;
  476. for (i = 0; i < 100; i++) {
  477. delay(30);
  478. s = splhigh();
  479. busy = bus_space_read_4(sc->sc_st, sc->sc_sh, MEC_PHY_DATA);
  480. splx(s);
  481. if ((busy & MEC_PHY_DATA_BUSY) == 0)
  482. return 0;
  483. if (busy == 0xffff) /* XXX ? */
  484. return 0;
  485. }
  486. printf("%s: MII timed out\n", sc->sc_dev.dv_xname);
  487. return 1;
  488. }
  489. void
  490. mec_statchg(struct device *self)
  491. {
  492. struct mec_softc *sc = (void *)self;
  493. bus_space_tag_t st = sc->sc_st;
  494. bus_space_handle_t sh = sc->sc_sh;
  495. uint32_t control;
  496. control = bus_space_read_8(st, sh, MEC_MAC_CONTROL);
  497. control &= ~(MEC_MAC_IPGT | MEC_MAC_IPGR1 | MEC_MAC_IPGR2 |
  498. MEC_MAC_FULL_DUPLEX | MEC_MAC_SPEED_SELECT);
  499. /* Must also set IPG here for duplex stuff... */
  500. if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0) {
  501. control |= MEC_MAC_FULL_DUPLEX;
  502. } else {
  503. /* Set IPG. */
  504. control |= MEC_MAC_IPG_DEFAULT;
  505. }
  506. bus_space_write_8(st, sh, MEC_MAC_CONTROL, control);
  507. }
  508. void
  509. mec_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
  510. {
  511. struct mec_softc *sc = ifp->if_softc;
  512. if ((ifp->if_flags & IFF_UP) == 0)
  513. return;
  514. mii_pollstat(&sc->sc_mii);
  515. ifmr->ifm_status = sc->sc_mii.mii_media_status;
  516. ifmr->ifm_active = sc->sc_mii.mii_media_active;
  517. }
  518. int
  519. mec_mediachange(struct ifnet *ifp)
  520. {
  521. struct mec_softc *sc = ifp->if_softc;
  522. if ((ifp->if_flags & IFF_UP) == 0)
  523. return 0;
  524. return mii_mediachg(&sc->sc_mii);
  525. }
  526. int
  527. mec_init(struct ifnet *ifp)
  528. {
  529. struct mec_softc *sc = ifp->if_softc;
  530. bus_space_tag_t st = sc->sc_st;
  531. bus_space_handle_t sh = sc->sc_sh;
  532. struct mec_rxdesc *rxd;
  533. int i;
  534. /* Cancel any pending I/O. */
  535. mec_stop(ifp);
  536. /* Reset device. */
  537. mec_reset(sc);
  538. /* Setup filter for multicast or promisc mode. */
  539. mec_iff(sc);
  540. /* Set the TX ring pointer to the base address. */
  541. bus_space_write_8(st, sh, MEC_TX_RING_BASE, MEC_CDTXADDR(sc, 0));
  542. sc->sc_txpending = 0;
  543. sc->sc_txdirty = 0;
  544. sc->sc_txlast = MEC_NTXDESC - 1;
  545. /* Put RX buffers into FIFO. */
  546. for (i = 0; i < MEC_NRXDESC; i++) {
  547. rxd = &sc->sc_rxdesc[i];
  548. rxd->rxd_stat = 0;
  549. MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_PREREAD);
  550. MEC_RXBUFSYNC(sc, i, ETHER_MAX_LEN, BUS_DMASYNC_PREREAD);
  551. bus_space_write_8(st, sh, MEC_MCL_RX_FIFO, MEC_CDRXADDR(sc, i));
  552. }
  553. sc->sc_rxptr = 0;
  554. #if 0 /* XXX no info */
  555. bus_space_write_8(st, sh, MEC_TIMER, 0);
  556. #endif
  557. /*
  558. * MEC_DMA_TX_INT_ENABLE will be set later otherwise it causes
  559. * spurious interrupts when TX buffers are empty.
  560. */
  561. bus_space_write_8(st, sh, MEC_DMA_CONTROL,
  562. (MEC_RXD_DMAOFFSET << MEC_DMA_RX_DMA_OFFSET_SHIFT) |
  563. (MEC_NRXDESC << MEC_DMA_RX_INT_THRESH_SHIFT) |
  564. MEC_DMA_TX_DMA_ENABLE | /* MEC_DMA_TX_INT_ENABLE | */
  565. MEC_DMA_RX_DMA_ENABLE | MEC_DMA_RX_INT_ENABLE);
  566. timeout_add_sec(&sc->sc_tick_ch, 1);
  567. ifp->if_flags |= IFF_RUNNING;
  568. ifp->if_flags &= ~IFF_OACTIVE;
  569. mec_start(ifp);
  570. mii_mediachg(&sc->sc_mii);
  571. return 0;
  572. }
  573. void
  574. mec_reset(struct mec_softc *sc)
  575. {
  576. bus_space_tag_t st = sc->sc_st;
  577. bus_space_handle_t sh = sc->sc_sh;
  578. uint64_t address;
  579. int i;
  580. /* Reset chip. */
  581. bus_space_write_8(st, sh, MEC_MAC_CONTROL, MEC_MAC_CORE_RESET);
  582. delay(1000);
  583. bus_space_write_8(st, sh, MEC_MAC_CONTROL, 0);
  584. delay(1000);
  585. /* Set Ethernet address. */
  586. address = 0;
  587. for (i = 0; i < ETHER_ADDR_LEN; i++) {
  588. address = address << 8;
  589. address += sc->sc_ac.ac_enaddr[i];
  590. }
  591. bus_space_write_8(st, sh, MEC_STATION, address);
  592. /* Default to 100/half and let auto-negotiation work its magic. */
  593. bus_space_write_8(st, sh, MEC_MAC_CONTROL,
  594. MEC_MAC_SPEED_SELECT | MEC_MAC_IPG_DEFAULT);
  595. bus_space_write_8(st, sh, MEC_DMA_CONTROL, 0);
  596. DPRINTF(MEC_DEBUG_RESET, ("mec: control now %llx\n",
  597. bus_space_read_8(st, sh, MEC_MAC_CONTROL)));
  598. }
  599. void
  600. mec_start(struct ifnet *ifp)
  601. {
  602. struct mec_softc *sc = ifp->if_softc;
  603. struct mbuf *m0;
  604. struct mec_txdesc *txd;
  605. struct mec_txsoft *txs;
  606. bus_dmamap_t dmamap;
  607. bus_space_tag_t st = sc->sc_st;
  608. bus_space_handle_t sh = sc->sc_sh;
  609. uint64_t txdaddr;
  610. int error, firsttx, nexttx, opending;
  611. int len, bufoff, buflen, unaligned, txdlen;
  612. if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
  613. return;
  614. /*
  615. * Remember the previous txpending and the first transmit descriptor.
  616. */
  617. opending = sc->sc_txpending;
  618. firsttx = MEC_NEXTTX(sc->sc_txlast);
  619. DPRINTF(MEC_DEBUG_START,
  620. ("mec_start: opending = %d, firsttx = %d\n", opending, firsttx));
  621. for (;;) {
  622. /* Grab a packet off the queue. */
  623. IFQ_POLL(&ifp->if_snd, m0);
  624. if (m0 == NULL)
  625. break;
  626. if (sc->sc_txpending == MEC_NTXDESC) {
  627. break;
  628. }
  629. /*
  630. * Get the next available transmit descriptor.
  631. */
  632. nexttx = MEC_NEXTTX(sc->sc_txlast);
  633. txd = &sc->sc_txdesc[nexttx];
  634. txs = &sc->sc_txsoft[nexttx];
  635. buflen = 0;
  636. bufoff = 0;
  637. txdaddr = 0; /* XXX gcc */
  638. txdlen = 0; /* XXX gcc */
  639. len = m0->m_pkthdr.len;
  640. DPRINTF(MEC_DEBUG_START,
  641. ("mec_start: len = %d, nexttx = %d\n", len, nexttx));
  642. IFQ_DEQUEUE(&ifp->if_snd, m0);
  643. if (len < ETHER_PAD_LEN) {
  644. /*
  645. * I don't know if MEC chip does auto padding,
  646. * so if the packet is small enough,
  647. * just copy it to the buffer in txdesc.
  648. * Maybe this is the simple way.
  649. */
  650. DPRINTF(MEC_DEBUG_START, ("mec_start: short packet\n"));
  651. bufoff = MEC_TXD_BUFSTART(ETHER_PAD_LEN);
  652. m_copydata(m0, 0, m0->m_pkthdr.len,
  653. txd->txd_buf + bufoff);
  654. memset(txd->txd_buf + bufoff + len, 0,
  655. ETHER_PAD_LEN - len);
  656. len = buflen = ETHER_PAD_LEN;
  657. txs->txs_flags = MEC_TXS_TXDBUF | buflen;
  658. } else {
  659. /*
  660. * If the packet won't fit the buffer in txdesc,
  661. * we have to use concatenate pointer to handle it.
  662. * While MEC can handle up to three segments to
  663. * concatenate, MEC requires that both the second and
  664. * third segments have to be 8 byte aligned.
  665. * Since it's unlikely for mbuf clusters, we use
  666. * only the first concatenate pointer. If the packet
  667. * doesn't fit in one DMA segment, allocate new mbuf
  668. * and copy the packet to it.
  669. *
  670. * Besides, if the start address of the first segments
  671. * is not 8 byte aligned, such part have to be copied
  672. * to the txdesc buffer. (XXX see below comments)
  673. */
  674. DPRINTF(MEC_DEBUG_START, ("mec_start: long packet\n"));
  675. dmamap = txs->txs_dmamap;
  676. if (bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
  677. BUS_DMA_WRITE | BUS_DMA_NOWAIT) != 0) {
  678. struct mbuf *m;
  679. DPRINTF(MEC_DEBUG_START,
  680. ("mec_start: re-allocating mbuf\n"));
  681. MGETHDR(m, M_DONTWAIT, MT_DATA);
  682. if (m == NULL) {
  683. printf("%s: unable to allocate "
  684. "TX mbuf\n", sc->sc_dev.dv_xname);
  685. break;
  686. }
  687. if (len > (MHLEN - ETHER_ALIGN)) {
  688. MCLGET(m, M_DONTWAIT);
  689. if ((m->m_flags & M_EXT) == 0) {
  690. printf("%s: unable to allocate "
  691. "TX cluster\n",
  692. sc->sc_dev.dv_xname);
  693. m_freem(m);
  694. break;
  695. }
  696. }
  697. /*
  698. * Each packet has the Ethernet header, so
  699. * in many cases the header isn't 4-byte aligned
  700. * and data after the header is 4-byte aligned.
  701. * Thus adding 2-byte offset before copying to
  702. * new mbuf avoids unaligned copy and this may
  703. * improve performance.
  704. * As noted above, unaligned part has to be
  705. * copied to txdesc buffer so this may cause
  706. * extra copy ops, but for now MEC always
  707. * requires some data in txdesc buffer,
  708. * so we always have to copy some data anyway.
  709. */
  710. m->m_data += ETHER_ALIGN;
  711. m_copydata(m0, 0, len, mtod(m, caddr_t));
  712. m->m_pkthdr.len = m->m_len = len;
  713. m_freem(m0);
  714. m0 = m;
  715. error = bus_dmamap_load_mbuf(sc->sc_dmat,
  716. dmamap, m, BUS_DMA_WRITE | BUS_DMA_NOWAIT);
  717. if (error) {
  718. printf("%s: unable to load TX buffer, "
  719. "error = %d\n",
  720. sc->sc_dev.dv_xname, error);
  721. m_freem(m);
  722. break;
  723. }
  724. }
  725. /* Handle unaligned part. */
  726. txdaddr = MEC_TXD_ROUNDUP(dmamap->dm_segs[0].ds_addr);
  727. txs->txs_flags = MEC_TXS_TXDPTR1;
  728. unaligned =
  729. dmamap->dm_segs[0].ds_addr & (MEC_TXD_ALIGN - 1);
  730. DPRINTF(MEC_DEBUG_START,
  731. ("mec_start: ds_addr = 0x%x, unaligned = %d\n",
  732. (u_int)dmamap->dm_segs[0].ds_addr, unaligned));
  733. if (unaligned != 0) {
  734. buflen = MEC_TXD_ALIGN - unaligned;
  735. bufoff = MEC_TXD_BUFSTART(buflen);
  736. DPRINTF(MEC_DEBUG_START,
  737. ("mec_start: unaligned, "
  738. "buflen = %d, bufoff = %d\n",
  739. buflen, bufoff));
  740. memcpy(txd->txd_buf + bufoff,
  741. mtod(m0, caddr_t), buflen);
  742. txs->txs_flags |= MEC_TXS_TXDBUF | buflen;
  743. }
  744. #if 1
  745. else {
  746. /*
  747. * XXX needs hardware info XXX
  748. * It seems MEC always requires some data
  749. * in txd_buf[] even if buffer is
  750. * 8-byte aligned otherwise DMA abort error
  751. * occurs later...
  752. */
  753. buflen = MEC_TXD_ALIGN;
  754. bufoff = MEC_TXD_BUFSTART(buflen);
  755. memcpy(txd->txd_buf + bufoff,
  756. mtod(m0, caddr_t), buflen);
  757. DPRINTF(MEC_DEBUG_START,
  758. ("mec_start: aligned, "
  759. "buflen = %d, bufoff = %d\n",
  760. buflen, bufoff));
  761. txs->txs_flags |= MEC_TXS_TXDBUF | buflen;
  762. txdaddr += MEC_TXD_ALIGN;
  763. }
  764. #endif
  765. txdlen = len - buflen;
  766. DPRINTF(MEC_DEBUG_START,
  767. ("mec_start: txdaddr = 0x%llx, txdlen = %d\n",
  768. txdaddr, txdlen));
  769. /*
  770. * Sync the DMA map for TX mbuf.
  771. *
  772. * XXX unaligned part doesn't have to be sync'ed,
  773. * but it's harmless...
  774. */
  775. bus_dmamap_sync(sc->sc_dmat, dmamap, 0,
  776. dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
  777. }
  778. #if NBPFILTER > 0
  779. /*
  780. * Pass packet to bpf if there is a listener.
  781. */
  782. if (ifp->if_bpf)
  783. bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
  784. #endif
  785. /*
  786. * Setup the transmit descriptor.
  787. */
  788. /* TXINT bit will be set later on the last packet. */
  789. txd->txd_cmd = (len - 1);
  790. /* But also set TXINT bit on a half of TXDESC. */
  791. if (sc->sc_txpending == (MEC_NTXDESC / 2))
  792. txd->txd_cmd |= MEC_TXCMD_TXINT;
  793. if (txs->txs_flags & MEC_TXS_TXDBUF)
  794. txd->txd_cmd |= TXCMD_BUFSTART(MEC_TXDESCSIZE - buflen);
  795. if (txs->txs_flags & MEC_TXS_TXDPTR1) {
  796. txd->txd_cmd |= MEC_TXCMD_PTR1;
  797. txd->txd_ptr[0] = TXPTR_LEN(txdlen - 1) | txdaddr;
  798. /*
  799. * Store a pointer to the packet so we can
  800. * free it later.
  801. */
  802. txs->txs_mbuf = m0;
  803. } else {
  804. txd->txd_ptr[0] = 0;
  805. /*
  806. * In this case all data are copied to buffer in txdesc,
  807. * we can free TX mbuf here.
  808. */
  809. m_freem(m0);
  810. }
  811. DPRINTF(MEC_DEBUG_START,
  812. ("mec_start: txd_cmd = 0x%llx, txd_ptr = 0x%llx\n",
  813. txd->txd_cmd, txd->txd_ptr[0]));
  814. DPRINTF(MEC_DEBUG_START,
  815. ("mec_start: len = %d (0x%04x), buflen = %d (0x%02x)\n",
  816. len, len, buflen, buflen));
  817. /* Sync TX descriptor. */
  818. MEC_TXDESCSYNC(sc, nexttx,
  819. BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  820. /* Advance the TX pointer. */
  821. sc->sc_txpending++;
  822. sc->sc_txlast = nexttx;
  823. }
  824. if (sc->sc_txpending == MEC_NTXDESC) {
  825. /* No more slots; notify upper layer. */
  826. ifp->if_flags |= IFF_OACTIVE;
  827. }
  828. if (sc->sc_txpending != opending) {
  829. /*
  830. * Cause a TX interrupt to happen on the last packet
  831. * we enqueued.
  832. */
  833. sc->sc_txdesc[sc->sc_txlast].txd_cmd |= MEC_TXCMD_TXINT;
  834. MEC_TXCMDSYNC(sc, sc->sc_txlast,
  835. BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  836. /* Start TX. */
  837. bus_space_write_8(st, sh, MEC_TX_RING_PTR,
  838. MEC_NEXTTX(sc->sc_txlast));
  839. /*
  840. * If the transmitter was idle,
  841. * reset the txdirty pointer and re-enable TX interrupt.
  842. */
  843. if (opending == 0) {
  844. sc->sc_txdirty = firsttx;
  845. bus_space_write_8(st, sh, MEC_TX_ALIAS,
  846. MEC_TX_ALIAS_INT_ENABLE);
  847. }
  848. /* Set a watchdog timer in case the chip flakes out. */
  849. ifp->if_timer = 5;
  850. }
  851. }
  852. void
  853. mec_stop(struct ifnet *ifp)
  854. {
  855. struct mec_softc *sc = ifp->if_softc;
  856. struct mec_txsoft *txs;
  857. int i;
  858. DPRINTF(MEC_DEBUG_STOP, ("mec_stop\n"));
  859. ifp->if_timer = 0;
  860. ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
  861. timeout_del(&sc->sc_tick_ch);
  862. mii_down(&sc->sc_mii);
  863. /* Disable DMA. */
  864. bus_space_write_8(sc->sc_st, sc->sc_sh, MEC_DMA_CONTROL, 0);
  865. /* Release any TX buffers. */
  866. for (i = 0; i < MEC_NTXDESC; i++) {
  867. txs = &sc->sc_txsoft[i];
  868. if ((txs->txs_flags & MEC_TXS_TXDPTR1) != 0) {
  869. bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
  870. m_freem(txs->txs_mbuf);
  871. txs->txs_mbuf = NULL;
  872. }
  873. }
  874. }
  875. int
  876. mec_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  877. {
  878. struct mec_softc *sc = ifp->if_softc;
  879. struct ifreq *ifr = (struct ifreq *)data;
  880. struct ifaddr *ifa = (struct ifaddr *)data;
  881. int s, error = 0;
  882. s = splnet();
  883. switch (cmd) {
  884. case SIOCSIFADDR:
  885. ifp->if_flags |= IFF_UP;
  886. if (!(ifp->if_flags & IFF_RUNNING))
  887. mec_init(ifp);
  888. if (ifa->ifa_addr->sa_family == AF_INET)
  889. arp_ifinit(&sc->sc_ac, ifa);
  890. break;
  891. case SIOCSIFFLAGS:
  892. if (ifp->if_flags & IFF_UP) {
  893. if (ifp->if_flags & IFF_RUNNING)
  894. error = ENETRESET;
  895. else
  896. mec_init(ifp);
  897. } else {
  898. if (ifp->if_flags & IFF_RUNNING)
  899. mec_stop(ifp);
  900. }
  901. break;
  902. case SIOCSIFMEDIA:
  903. case SIOCGIFMEDIA:
  904. error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
  905. break;
  906. default:
  907. error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
  908. }
  909. if (error == ENETRESET) {
  910. if (ifp->if_flags & IFF_RUNNING)
  911. mec_iff(sc);
  912. error = 0;
  913. }
  914. splx(s);
  915. return error;
  916. }
  917. void
  918. mec_watchdog(struct ifnet *ifp)
  919. {
  920. struct mec_softc *sc = ifp->if_softc;
  921. printf("%s: device timeout\n", sc->sc_dev.dv_xname);
  922. ifp->if_oerrors++;
  923. mec_init(ifp);
  924. }
  925. void
  926. mec_tick(void *arg)
  927. {
  928. struct mec_softc *sc = arg;
  929. int s;
  930. s = splnet();
  931. mii_tick(&sc->sc_mii);
  932. splx(s);
  933. timeout_add_sec(&sc->sc_tick_ch, 1);
  934. }
  935. void
  936. mec_iff(struct mec_softc *sc)
  937. {
  938. struct arpcom *ac = &sc->sc_ac;
  939. struct ifnet *ifp = &sc->sc_ac.ac_if;
  940. struct ether_multi *enm;
  941. struct ether_multistep step;
  942. bus_space_tag_t st = sc->sc_st;
  943. bus_space_handle_t sh = sc->sc_sh;
  944. uint64_t mchash = 0;
  945. uint32_t control, hash;
  946. control = bus_space_read_8(st, sh, MEC_MAC_CONTROL);
  947. control &= ~MEC_MAC_FILTER_MASK;
  948. ifp->if_flags &= ~IFF_ALLMULTI;
  949. if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
  950. ifp->if_flags |= IFF_ALLMULTI;
  951. if (ifp->if_flags & IFF_PROMISC)
  952. control |= MEC_MAC_FILTER_PROMISC;
  953. else
  954. control |= MEC_MAC_FILTER_ALLMULTI;
  955. mchash = 0xffffffffffffffffULL;
  956. } else {
  957. ETHER_FIRST_MULTI(step, ac, enm);
  958. while (enm != NULL) {
  959. hash = ether_crc32_be(enm->enm_addrlo,
  960. ETHER_ADDR_LEN) >> 26;
  961. mchash |= 1 << hash;
  962. ETHER_NEXT_MULTI(step, enm);
  963. }
  964. if (ac->ac_multicnt > 0)
  965. control |= MEC_MAC_FILTER_MATCHMULTI;
  966. }
  967. bus_space_write_8(st, sh, MEC_MULTICAST, mchash);
  968. bus_space_write_8(st, sh, MEC_MAC_CONTROL, control);
  969. }
  970. int
  971. mec_intr(void *arg)
  972. {
  973. struct mec_softc *sc = arg;
  974. bus_space_tag_t st = sc->sc_st;
  975. bus_space_handle_t sh = sc->sc_sh;
  976. struct ifnet *ifp = &sc->sc_ac.ac_if;
  977. uint32_t statreg, statack, dmac;
  978. int handled, sent;
  979. DPRINTF(MEC_DEBUG_INTR, ("mec_intr: called\n"));
  980. handled = sent = 0;
  981. for (;;) {
  982. statreg = bus_space_read_8(st, sh, MEC_INT_STATUS);
  983. DPRINTF(MEC_DEBUG_INTR,
  984. ("mec_intr: INT_STAT = 0x%x\n", statreg));
  985. statack = statreg & MEC_INT_STATUS_MASK;
  986. if (statack == 0)
  987. break;
  988. bus_space_write_8(st, sh, MEC_INT_STATUS, statack);
  989. handled = 1;
  990. if (statack &
  991. (MEC_INT_RX_THRESHOLD |
  992. MEC_INT_RX_FIFO_UNDERFLOW)) {
  993. mec_rxintr(sc, statreg);
  994. }
  995. dmac = bus_space_read_8(st, sh, MEC_DMA_CONTROL);
  996. DPRINTF(MEC_DEBUG_INTR,
  997. ("mec_intr: DMA_CONT = 0x%x\n", dmac));
  998. if (statack &
  999. (MEC_INT_TX_EMPTY |
  1000. MEC_INT_TX_PACKET_SENT |
  1001. MEC_INT_TX_ABORT)) {
  1002. mec_txintr(sc, statreg);
  1003. sent = 1;
  1004. }
  1005. if (statack &
  1006. (MEC_INT_TX_LINK_FAIL |
  1007. MEC_INT_TX_MEM_ERROR |
  1008. MEC_INT_TX_ABORT |
  1009. MEC_INT_RX_DMA_UNDERFLOW)) {
  1010. printf("%s: mec_intr: interrupt status = 0x%x\n",
  1011. sc->sc_dev.dv_xname, statreg);
  1012. }
  1013. }
  1014. if (sent) {
  1015. /* Try to get more packets going. */
  1016. mec_start(ifp);
  1017. }
  1018. return handled;
  1019. }
  1020. void
  1021. mec_rxintr(struct mec_softc *sc, uint32_t stat)
  1022. {
  1023. bus_space_tag_t st = sc->sc_st;
  1024. bus_space_handle_t sh = sc->sc_sh;
  1025. struct ifnet *ifp = &sc->sc_ac.ac_if;
  1026. struct mbuf_list ml = MBUF_LIST_INITIALIZER();
  1027. struct mbuf *m;
  1028. struct mec_rxdesc *rxd;
  1029. uint64_t rxstat;
  1030. u_int len;
  1031. int i, last;
  1032. DPRINTF(MEC_DEBUG_RXINTR, ("mec_rxintr: called\n"));
  1033. bus_space_write_8(st, sh, MEC_RX_ALIAS, 0);
  1034. last = (stat & MEC_INT_RX_MCL_FIFO_ALIAS) >> 8;
  1035. /* XXX does alias count mod 32 even if 16 descs are set up? */
  1036. last &= MEC_NRXDESC_MASK;
  1037. if (stat & MEC_INT_RX_FIFO_UNDERFLOW)
  1038. last = (last - 1) & MEC_NRXDESC_MASK;
  1039. DPRINTF(MEC_DEBUG_RXINTR, ("mec_rxintr: rxptr %d last %d\n",
  1040. sc->sc_rxptr, last));
  1041. for (i = sc->sc_rxptr; i != last; i = MEC_NEXTRX(i)) {
  1042. MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_POSTREAD);
  1043. rxd = &sc->sc_rxdesc[i];
  1044. rxstat = rxd->rxd_stat;
  1045. DPRINTF(MEC_DEBUG_RXINTR,
  1046. ("mec_rxintr: rxstat = 0x%llx, rxptr = %d\n",
  1047. rxstat, i));
  1048. DPRINTF(MEC_DEBUG_RXINTR, ("mec_rxintr: rxfifo = 0x%x\n",
  1049. (u_int)bus_space_read_8(st, sh, MEC_RX_FIFO)));
  1050. if ((rxstat & MEC_RXSTAT_RECEIVED) == 0) {
  1051. /* Status not received but FIFO counted? Drop it! */
  1052. goto dropit;
  1053. }
  1054. len = rxstat & MEC_RXSTAT_LEN;
  1055. if (len < ETHER_MIN_LEN ||
  1056. len > ETHER_MAX_LEN) {
  1057. /* Invalid length packet; drop it. */
  1058. DPRINTF(MEC_DEBUG_RXINTR,
  1059. ("mec_rxintr: wrong packet\n"));
  1060. dropit:
  1061. ifp->if_ierrors++;
  1062. rxd->rxd_stat = 0;
  1063. MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_PREREAD);
  1064. bus_space_write_8(st, sh, MEC_MCL_RX_FIFO,
  1065. MEC_CDRXADDR(sc, i));
  1066. continue;
  1067. }
  1068. if (rxstat &
  1069. (MEC_RXSTAT_BADPACKET |
  1070. MEC_RXSTAT_LONGEVENT |
  1071. MEC_RXSTAT_INVALID |
  1072. MEC_RXSTAT_CRCERROR |
  1073. MEC_RXSTAT_VIOLATION)) {
  1074. printf("%s: mec_rxintr: status = 0x%llx\n",
  1075. sc->sc_dev.dv_xname, rxstat);
  1076. goto dropit;
  1077. }
  1078. /*
  1079. * Now allocate an mbuf (and possibly a cluster) to hold
  1080. * the received packet.
  1081. */
  1082. MGETHDR(m, M_DONTWAIT, MT_DATA);
  1083. if (m == NULL) {
  1084. printf("%s: unable to allocate RX mbuf\n",
  1085. sc->sc_dev.dv_xname);
  1086. goto dropit;
  1087. }
  1088. if (len > (MHLEN - ETHER_ALIGN)) {
  1089. MCLGET(m, M_DONTWAIT);
  1090. if ((m->m_flags & M_EXT) == 0) {
  1091. printf("%s: unable to allocate RX cluster\n",
  1092. sc->sc_dev.dv_xname);
  1093. m_freem(m);
  1094. m = NULL;
  1095. goto dropit;
  1096. }
  1097. }
  1098. /*
  1099. * Note MEC chip seems to insert 2 byte padding at the start of
  1100. * RX buffer, but we copy whole buffer to avoid unaligned copy.
  1101. */
  1102. MEC_RXBUFSYNC(sc, i, len + ETHER_ALIGN, BUS_DMASYNC_POSTREAD);
  1103. memcpy(mtod(m, caddr_t), rxd->rxd_buf,
  1104. ETHER_ALIGN + len - ETHER_CRC_LEN);
  1105. MEC_RXBUFSYNC(sc, i, ETHER_MAX_LEN, BUS_DMASYNC_PREREAD);
  1106. m->m_data += ETHER_ALIGN;
  1107. /* Put RX buffer into FIFO again. */
  1108. rxd->rxd_stat = 0;
  1109. MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_PREREAD);
  1110. bus_space_write_8(st, sh, MEC_MCL_RX_FIFO, MEC_CDRXADDR(sc, i));
  1111. m->m_pkthdr.len = m->m_len = len - ETHER_CRC_LEN;
  1112. ml_enqueue(&ml, m);
  1113. }
  1114. /* Update RX pointer. */
  1115. sc->sc_rxptr = i;
  1116. bus_space_write_8(st, sh, MEC_RX_ALIAS,
  1117. (MEC_NRXDESC << MEC_DMA_RX_INT_THRESH_SHIFT) |
  1118. MEC_DMA_RX_INT_ENABLE);
  1119. if_input(ifp, &ml);
  1120. }
  1121. void
  1122. mec_txintr(struct mec_softc *sc, uint32_t stat)
  1123. {
  1124. struct ifnet *ifp = &sc->sc_ac.ac_if;
  1125. struct mec_txdesc *txd;
  1126. struct mec_txsoft *txs;
  1127. bus_dmamap_t dmamap;
  1128. uint64_t txstat;
  1129. int i, last;
  1130. u_int col;
  1131. ifp->if_flags &= ~IFF_OACTIVE;
  1132. DPRINTF(MEC_DEBUG_TXINTR, ("mec_txintr: called\n"));
  1133. bus_space_write_8(sc->sc_st, sc->sc_sh, MEC_TX_ALIAS, 0);
  1134. last = (stat & MEC_INT_TX_RING_BUFFER_ALIAS) >> 16;
  1135. DPRINTF(MEC_DEBUG_TXINTR, ("mec_txintr: dirty %d last %d\n",
  1136. sc->sc_txdirty, last));
  1137. for (i = sc->sc_txdirty; i != last && sc->sc_txpending != 0;
  1138. i = MEC_NEXTTX(i), sc->sc_txpending--) {
  1139. txd = &sc->sc_txdesc[i];
  1140. MEC_TXDESCSYNC(sc, i,
  1141. BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  1142. txstat = txd->txd_stat;
  1143. DPRINTF(MEC_DEBUG_TXINTR,
  1144. ("mec_txintr: dirty = %d, txstat = 0x%llx\n",
  1145. i, txstat));
  1146. if ((txstat & MEC_TXSTAT_SENT) == 0) {
  1147. MEC_TXCMDSYNC(sc, i, BUS_DMASYNC_PREREAD);
  1148. break;
  1149. }
  1150. txs = &sc->sc_txsoft[i];
  1151. if ((txs->txs_flags & MEC_TXS_TXDPTR1) != 0) {
  1152. dmamap = txs->txs_dmamap;
  1153. bus_dmamap_sync(sc->sc_dmat, dmamap, 0,
  1154. dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
  1155. bus_dmamap_unload(sc->sc_dmat, dmamap);
  1156. m_freem(txs->txs_mbuf);
  1157. txs->txs_mbuf = NULL;
  1158. }
  1159. if ((txstat & MEC_TXSTAT_SUCCESS) == 0) {
  1160. printf("%s: TX error: txstat = 0x%llx\n",
  1161. sc->sc_dev.dv_xname, txstat);
  1162. ifp->if_oerrors++;
  1163. } else {
  1164. col = (txstat & MEC_TXSTAT_COLCNT) >>
  1165. MEC_TXSTAT_COLCNT_SHIFT;
  1166. ifp->if_collisions += col;
  1167. ifp->if_opackets++;
  1168. }
  1169. }
  1170. /* Update the dirty TX buffer pointer. */
  1171. sc->sc_txdirty = i;
  1172. DPRINTF(MEC_DEBUG_INTR,
  1173. ("mec_txintr: sc_txdirty = %2d, sc_txpending = %2d\n",
  1174. sc->sc_txdirty, sc->sc_txpending));
  1175. /* Cancel the watchdog timer if there are no pending TX packets. */
  1176. if (sc->sc_txpending == 0)
  1177. ifp->if_timer = 0;
  1178. else if (!(stat & MEC_INT_TX_EMPTY))
  1179. bus_space_write_8(sc->sc_st, sc->sc_sh, MEC_TX_ALIAS,
  1180. MEC_TX_ALIAS_INT_ENABLE);
  1181. }