]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/ti/cpsw/if_cpsw.c
MFV r348576: 9963 Seperate tunable for disabling ZIL vdev flush
[FreeBSD/FreeBSD.git] / sys / arm / ti / cpsw / if_cpsw.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org>
5  * Copyright (c) 2016 Rubicon Communications, LLC (Netgate)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 /*
31  * TI Common Platform Ethernet Switch (CPSW) Driver
32  * Found in TI8148 "DaVinci" and AM335x "Sitara" SoCs.
33  *
34  * This controller is documented in the AM335x Technical Reference
35  * Manual, in the TMS320DM814x DaVinci Digital Video Processors TRM
36  * and in the TMS320C6452 3 Port Switch Ethernet Subsystem TRM.
37  *
38  * It is basically a single Ethernet port (port 0) wired internally to
39  * a 3-port store-and-forward switch connected to two independent
40  * "sliver" controllers (port 1 and port 2).  You can operate the
41  * controller in a variety of different ways by suitably configuring
42  * the slivers and the Address Lookup Engine (ALE) that routes packets
43  * between the ports.
44  *
45  * This code was developed and tested on a BeagleBone with
46  * an AM335x SoC.
47  */
48
49 #include <sys/cdefs.h>
50 __FBSDID("$FreeBSD$");
51
52 #include "opt_cpsw.h"
53
54 #include <sys/param.h>
55 #include <sys/bus.h>
56 #include <sys/kernel.h>
57 #include <sys/lock.h>
58 #include <sys/mbuf.h>
59 #include <sys/module.h>
60 #include <sys/mutex.h>
61 #include <sys/rman.h>
62 #include <sys/socket.h>
63 #include <sys/sockio.h>
64 #include <sys/sysctl.h>
65
66 #include <machine/bus.h>
67 #include <machine/resource.h>
68 #include <machine/stdarg.h>
69
70 #include <net/ethernet.h>
71 #include <net/bpf.h>
72 #include <net/if.h>
73 #include <net/if_dl.h>
74 #include <net/if_media.h>
75 #include <net/if_types.h>
76
77 #include <arm/ti/ti_scm.h>
78 #include <arm/ti/am335x/am335x_scm.h>
79
80 #include <dev/mii/mii.h>
81 #include <dev/mii/miivar.h>
82
83 #include <dev/ofw/ofw_bus.h>
84 #include <dev/ofw/ofw_bus_subr.h>
85
86 #include <dev/fdt/fdt_common.h>
87  
88 #ifdef CPSW_ETHERSWITCH
89 #include <dev/etherswitch/etherswitch.h>
90 #include "etherswitch_if.h"
91 #endif
92
93 #include "if_cpswreg.h"
94 #include "if_cpswvar.h"
95
96 #include "miibus_if.h"
97
98 /* Device probe/attach/detach. */
99 static int cpsw_probe(device_t);
100 static int cpsw_attach(device_t);
101 static int cpsw_detach(device_t);
102 static int cpswp_probe(device_t);
103 static int cpswp_attach(device_t);
104 static int cpswp_detach(device_t);
105
106 static phandle_t cpsw_get_node(device_t, device_t);
107
108 /* Device Init/shutdown. */
109 static int cpsw_shutdown(device_t);
110 static void cpswp_init(void *);
111 static void cpswp_init_locked(void *);
112 static void cpswp_stop_locked(struct cpswp_softc *);
113
114 /* Device Suspend/Resume. */
115 static int cpsw_suspend(device_t);
116 static int cpsw_resume(device_t);
117
118 /* Ioctl. */
119 static int cpswp_ioctl(struct ifnet *, u_long command, caddr_t data);
120
121 static int cpswp_miibus_readreg(device_t, int phy, int reg);
122 static int cpswp_miibus_writereg(device_t, int phy, int reg, int value);
123 static void cpswp_miibus_statchg(device_t);
124
125 /* Send/Receive packets. */
126 static void cpsw_intr_rx(void *arg);
127 static struct mbuf *cpsw_rx_dequeue(struct cpsw_softc *);
128 static void cpsw_rx_enqueue(struct cpsw_softc *);
129 static void cpswp_start(struct ifnet *);
130 static void cpsw_intr_tx(void *);
131 static void cpswp_tx_enqueue(struct cpswp_softc *);
132 static int cpsw_tx_dequeue(struct cpsw_softc *);
133
134 /* Misc interrupts and watchdog. */
135 static void cpsw_intr_rx_thresh(void *);
136 static void cpsw_intr_misc(void *);
137 static void cpswp_tick(void *);
138 static void cpswp_ifmedia_sts(struct ifnet *, struct ifmediareq *);
139 static int cpswp_ifmedia_upd(struct ifnet *);
140 static void cpsw_tx_watchdog(void *);
141
142 /* ALE support */
143 static void cpsw_ale_read_entry(struct cpsw_softc *, uint16_t, uint32_t *);
144 static void cpsw_ale_write_entry(struct cpsw_softc *, uint16_t, uint32_t *);
145 static int cpsw_ale_mc_entry_set(struct cpsw_softc *, uint8_t, int, uint8_t *);
146 static void cpsw_ale_dump_table(struct cpsw_softc *);
147 static int cpsw_ale_update_vlan_table(struct cpsw_softc *, int, int, int, int,
148         int);
149 static int cpswp_ale_update_addresses(struct cpswp_softc *, int);
150
151 /* Statistics and sysctls. */
152 static void cpsw_add_sysctls(struct cpsw_softc *);
153 static void cpsw_stats_collect(struct cpsw_softc *);
154 static int cpsw_stats_sysctl(SYSCTL_HANDLER_ARGS);
155
156 #ifdef CPSW_ETHERSWITCH
157 static etherswitch_info_t *cpsw_getinfo(device_t);
158 static int cpsw_getport(device_t, etherswitch_port_t *);
159 static int cpsw_setport(device_t, etherswitch_port_t *);
160 static int cpsw_getconf(device_t, etherswitch_conf_t *);
161 static int cpsw_getvgroup(device_t, etherswitch_vlangroup_t *);
162 static int cpsw_setvgroup(device_t, etherswitch_vlangroup_t *);
163 static int cpsw_readreg(device_t, int);
164 static int cpsw_writereg(device_t, int, int);
165 static int cpsw_readphy(device_t, int, int);
166 static int cpsw_writephy(device_t, int, int, int);
167 #endif
168
169 /*
170  * Arbitrary limit on number of segments in an mbuf to be transmitted.
171  * Packets with more segments than this will be defragmented before
172  * they are queued.
173  */
174 #define CPSW_TXFRAGS            16
175
176 /* Shared resources. */
177 static device_method_t cpsw_methods[] = {
178         /* Device interface */
179         DEVMETHOD(device_probe,         cpsw_probe),
180         DEVMETHOD(device_attach,        cpsw_attach),
181         DEVMETHOD(device_detach,        cpsw_detach),
182         DEVMETHOD(device_shutdown,      cpsw_shutdown),
183         DEVMETHOD(device_suspend,       cpsw_suspend),
184         DEVMETHOD(device_resume,        cpsw_resume),
185         /* Bus interface */
186         DEVMETHOD(bus_add_child,        device_add_child_ordered),
187         /* OFW methods */
188         DEVMETHOD(ofw_bus_get_node,     cpsw_get_node),
189 #ifdef CPSW_ETHERSWITCH
190         /* etherswitch interface */
191         DEVMETHOD(etherswitch_getinfo,  cpsw_getinfo),
192         DEVMETHOD(etherswitch_readreg,  cpsw_readreg),
193         DEVMETHOD(etherswitch_writereg, cpsw_writereg),
194         DEVMETHOD(etherswitch_readphyreg,       cpsw_readphy),
195         DEVMETHOD(etherswitch_writephyreg,      cpsw_writephy),
196         DEVMETHOD(etherswitch_getport,  cpsw_getport),
197         DEVMETHOD(etherswitch_setport,  cpsw_setport),
198         DEVMETHOD(etherswitch_getvgroup,        cpsw_getvgroup),
199         DEVMETHOD(etherswitch_setvgroup,        cpsw_setvgroup),
200         DEVMETHOD(etherswitch_getconf,  cpsw_getconf),
201 #endif
202         DEVMETHOD_END
203 };
204
205 static driver_t cpsw_driver = {
206         "cpswss",
207         cpsw_methods,
208         sizeof(struct cpsw_softc),
209 };
210
211 static devclass_t cpsw_devclass;
212
213 DRIVER_MODULE(cpswss, simplebus, cpsw_driver, cpsw_devclass, 0, 0);
214
215 /* Port/Slave resources. */
216 static device_method_t cpswp_methods[] = {
217         /* Device interface */
218         DEVMETHOD(device_probe,         cpswp_probe),
219         DEVMETHOD(device_attach,        cpswp_attach),
220         DEVMETHOD(device_detach,        cpswp_detach),
221         /* MII interface */
222         DEVMETHOD(miibus_readreg,       cpswp_miibus_readreg),
223         DEVMETHOD(miibus_writereg,      cpswp_miibus_writereg),
224         DEVMETHOD(miibus_statchg,       cpswp_miibus_statchg),
225         DEVMETHOD_END
226 };
227
228 static driver_t cpswp_driver = {
229         "cpsw",
230         cpswp_methods,
231         sizeof(struct cpswp_softc),
232 };
233
234 static devclass_t cpswp_devclass;
235
236 #ifdef CPSW_ETHERSWITCH
237 DRIVER_MODULE(etherswitch, cpswss, etherswitch_driver, etherswitch_devclass, 0, 0);
238 MODULE_DEPEND(cpswss, etherswitch, 1, 1, 1);
239 #endif
240
241 DRIVER_MODULE(cpsw, cpswss, cpswp_driver, cpswp_devclass, 0, 0);
242 DRIVER_MODULE(miibus, cpsw, miibus_driver, miibus_devclass, 0, 0);
243 MODULE_DEPEND(cpsw, ether, 1, 1, 1);
244 MODULE_DEPEND(cpsw, miibus, 1, 1, 1);
245
246 #ifdef CPSW_ETHERSWITCH
247 static struct cpsw_vlangroups cpsw_vgroups[CPSW_VLANS];
248 #endif
249
250 static uint32_t slave_mdio_addr[] = { 0x4a100200, 0x4a100300 };
251
252 static struct resource_spec irq_res_spec[] = {
253         { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
254         { SYS_RES_IRQ, 1, RF_ACTIVE | RF_SHAREABLE },
255         { SYS_RES_IRQ, 2, RF_ACTIVE | RF_SHAREABLE },
256         { SYS_RES_IRQ, 3, RF_ACTIVE | RF_SHAREABLE },
257         { -1, 0 }
258 };
259
260 static struct {
261         void (*cb)(void *);
262 } cpsw_intr_cb[] = {
263         { cpsw_intr_rx_thresh },
264         { cpsw_intr_rx },
265         { cpsw_intr_tx },
266         { cpsw_intr_misc },
267 };
268
269 /* Number of entries here must match size of stats
270  * array in struct cpswp_softc. */
271 static struct cpsw_stat {
272         int     reg;
273         char *oid;
274 } cpsw_stat_sysctls[CPSW_SYSCTL_COUNT] = {
275         {0x00, "GoodRxFrames"},
276         {0x04, "BroadcastRxFrames"},
277         {0x08, "MulticastRxFrames"},
278         {0x0C, "PauseRxFrames"},
279         {0x10, "RxCrcErrors"},
280         {0x14, "RxAlignErrors"},
281         {0x18, "OversizeRxFrames"},
282         {0x1c, "RxJabbers"},
283         {0x20, "ShortRxFrames"},
284         {0x24, "RxFragments"},
285         {0x30, "RxOctets"},
286         {0x34, "GoodTxFrames"},
287         {0x38, "BroadcastTxFrames"},
288         {0x3c, "MulticastTxFrames"},
289         {0x40, "PauseTxFrames"},
290         {0x44, "DeferredTxFrames"},
291         {0x48, "CollisionsTxFrames"},
292         {0x4c, "SingleCollisionTxFrames"},
293         {0x50, "MultipleCollisionTxFrames"},
294         {0x54, "ExcessiveCollisions"},
295         {0x58, "LateCollisions"},
296         {0x5c, "TxUnderrun"},
297         {0x60, "CarrierSenseErrors"},
298         {0x64, "TxOctets"},
299         {0x68, "RxTx64OctetFrames"},
300         {0x6c, "RxTx65to127OctetFrames"},
301         {0x70, "RxTx128to255OctetFrames"},
302         {0x74, "RxTx256to511OctetFrames"},
303         {0x78, "RxTx512to1024OctetFrames"},
304         {0x7c, "RxTx1024upOctetFrames"},
305         {0x80, "NetOctets"},
306         {0x84, "RxStartOfFrameOverruns"},
307         {0x88, "RxMiddleOfFrameOverruns"},
308         {0x8c, "RxDmaOverruns"}
309 };
310
311 /*
312  * Basic debug support.
313  */
314
315 static void
316 cpsw_debugf_head(const char *funcname)
317 {
318         int t = (int)(time_second % (24 * 60 * 60));
319
320         printf("%02d:%02d:%02d %s ", t / (60 * 60), (t / 60) % 60, t % 60, funcname);
321 }
322
323 static void
324 cpsw_debugf(const char *fmt, ...)
325 {
326         va_list ap;
327
328         va_start(ap, fmt);
329         vprintf(fmt, ap);
330         va_end(ap);
331         printf("\n");
332
333 }
334
335 #define CPSW_DEBUGF(_sc, a) do {                                        \
336         if ((_sc)->debug) {                                             \
337                 cpsw_debugf_head(__func__);                             \
338                 cpsw_debugf a;                                          \
339         }                                                               \
340 } while (0)
341
342 /*
343  * Locking macros
344  */
345 #define CPSW_TX_LOCK(sc) do {                                           \
346                 mtx_assert(&(sc)->rx.lock, MA_NOTOWNED);                \
347                 mtx_lock(&(sc)->tx.lock);                               \
348 } while (0)
349
350 #define CPSW_TX_UNLOCK(sc)      mtx_unlock(&(sc)->tx.lock)
351 #define CPSW_TX_LOCK_ASSERT(sc) mtx_assert(&(sc)->tx.lock, MA_OWNED)
352
353 #define CPSW_RX_LOCK(sc) do {                                           \
354                 mtx_assert(&(sc)->tx.lock, MA_NOTOWNED);                \
355                 mtx_lock(&(sc)->rx.lock);                               \
356 } while (0)
357
358 #define CPSW_RX_UNLOCK(sc)              mtx_unlock(&(sc)->rx.lock)
359 #define CPSW_RX_LOCK_ASSERT(sc) mtx_assert(&(sc)->rx.lock, MA_OWNED)
360
361 #define CPSW_PORT_LOCK(_sc) do {                                        \
362                 mtx_assert(&(_sc)->lock, MA_NOTOWNED);                  \
363                 mtx_lock(&(_sc)->lock);                                 \
364 } while (0)
365
366 #define CPSW_PORT_UNLOCK(_sc)   mtx_unlock(&(_sc)->lock)
367 #define CPSW_PORT_LOCK_ASSERT(_sc)      mtx_assert(&(_sc)->lock, MA_OWNED)
368
369 /*
370  * Read/Write macros
371  */
372 #define cpsw_read_4(_sc, _reg)          bus_read_4((_sc)->mem_res, (_reg))
373 #define cpsw_write_4(_sc, _reg, _val)                                   \
374         bus_write_4((_sc)->mem_res, (_reg), (_val))
375
376 #define cpsw_cpdma_bd_offset(i) (CPSW_CPPI_RAM_OFFSET + ((i)*16))
377
378 #define cpsw_cpdma_bd_paddr(sc, slot)                                   \
379         BUS_SPACE_PHYSADDR(sc->mem_res, slot->bd_offset)
380 #define cpsw_cpdma_read_bd(sc, slot, val)                               \
381         bus_read_region_4(sc->mem_res, slot->bd_offset, (uint32_t *) val, 4)
382 #define cpsw_cpdma_write_bd(sc, slot, val)                              \
383         bus_write_region_4(sc->mem_res, slot->bd_offset, (uint32_t *) val, 4)
384 #define cpsw_cpdma_write_bd_next(sc, slot, next_slot)                   \
385         cpsw_write_4(sc, slot->bd_offset, cpsw_cpdma_bd_paddr(sc, next_slot))
386 #define cpsw_cpdma_write_bd_flags(sc, slot, val)                        \
387         bus_write_2(sc->mem_res, slot->bd_offset + 14, val)
388 #define cpsw_cpdma_read_bd_flags(sc, slot)                              \
389         bus_read_2(sc->mem_res, slot->bd_offset + 14)
390 #define cpsw_write_hdp_slot(sc, queue, slot)                            \
391         cpsw_write_4(sc, (queue)->hdp_offset, cpsw_cpdma_bd_paddr(sc, slot))
392 #define CP_OFFSET (CPSW_CPDMA_TX_CP(0) - CPSW_CPDMA_TX_HDP(0))
393 #define cpsw_read_cp(sc, queue)                                         \
394         cpsw_read_4(sc, (queue)->hdp_offset + CP_OFFSET) 
395 #define cpsw_write_cp(sc, queue, val)                                   \
396         cpsw_write_4(sc, (queue)->hdp_offset + CP_OFFSET, (val))
397 #define cpsw_write_cp_slot(sc, queue, slot)                             \
398         cpsw_write_cp(sc, queue, cpsw_cpdma_bd_paddr(sc, slot))
399
400 #if 0
401 /* XXX temporary function versions for debugging. */
402 static void
403 cpsw_write_hdp_slotX(struct cpsw_softc *sc, struct cpsw_queue *queue, struct cpsw_slot *slot)
404 {
405         uint32_t reg = queue->hdp_offset;
406         uint32_t v = cpsw_cpdma_bd_paddr(sc, slot);
407         CPSW_DEBUGF(("HDP <=== 0x%08x (was 0x%08x)", v, cpsw_read_4(sc, reg)));
408         cpsw_write_4(sc, reg, v);
409 }
410
411 static void
412 cpsw_write_cp_slotX(struct cpsw_softc *sc, struct cpsw_queue *queue, struct cpsw_slot *slot)
413 {
414         uint32_t v = cpsw_cpdma_bd_paddr(sc, slot);
415         CPSW_DEBUGF(("CP <=== 0x%08x (expecting 0x%08x)", v, cpsw_read_cp(sc, queue)));
416         cpsw_write_cp(sc, queue, v);
417 }
418 #endif
419
420 /*
421  * Expanded dump routines for verbose debugging.
422  */
423 static void
424 cpsw_dump_slot(struct cpsw_softc *sc, struct cpsw_slot *slot)
425 {
426         static const char *flags[] = {"SOP", "EOP", "Owner", "EOQ",
427             "TDownCmplt", "PassCRC", "Long", "Short", "MacCtl", "Overrun",
428             "PktErr1", "PortEn/PktErr0", "RxVlanEncap", "Port2", "Port1",
429             "Port0"};
430         struct cpsw_cpdma_bd bd;
431         const char *sep;
432         int i;
433
434         cpsw_cpdma_read_bd(sc, slot, &bd);
435         printf("BD Addr : 0x%08x   Next  : 0x%08x\n",
436             cpsw_cpdma_bd_paddr(sc, slot), bd.next);
437         printf("  BufPtr: 0x%08x   BufLen: 0x%08x\n", bd.bufptr, bd.buflen);
438         printf("  BufOff: 0x%08x   PktLen: 0x%08x\n", bd.bufoff, bd.pktlen);
439         printf("  Flags: ");
440         sep = "";
441         for (i = 0; i < 16; ++i) {
442                 if (bd.flags & (1 << (15 - i))) {
443                         printf("%s%s", sep, flags[i]);
444                         sep = ",";
445                 }
446         }
447         printf("\n");
448         if (slot->mbuf) {
449                 printf("  Ether:  %14D\n",
450                     (char *)(slot->mbuf->m_data), " ");
451                 printf("  Packet: %16D\n",
452                     (char *)(slot->mbuf->m_data) + 14, " ");
453         }
454 }
455
456 #define CPSW_DUMP_SLOT(cs, slot) do {                           \
457         IF_DEBUG(sc) {                                          \
458                 cpsw_dump_slot(sc, slot);                       \
459         }                                                       \
460 } while (0)
461
462 static void
463 cpsw_dump_queue(struct cpsw_softc *sc, struct cpsw_slots *q)
464 {
465         struct cpsw_slot *slot;
466         int i = 0;
467         int others = 0;
468
469         STAILQ_FOREACH(slot, q, next) {
470                 if (i > CPSW_TXFRAGS)
471                         ++others;
472                 else
473                         cpsw_dump_slot(sc, slot);
474                 ++i;
475         }
476         if (others)
477                 printf(" ... and %d more.\n", others);
478         printf("\n");
479 }
480
481 #define CPSW_DUMP_QUEUE(sc, q) do {                             \
482         IF_DEBUG(sc) {                                          \
483                 cpsw_dump_queue(sc, q);                         \
484         }                                                       \
485 } while (0)
486
487 static void
488 cpsw_init_slots(struct cpsw_softc *sc)
489 {
490         struct cpsw_slot *slot;
491         int i;
492
493         STAILQ_INIT(&sc->avail);
494
495         /* Put the slot descriptors onto the global avail list. */
496         for (i = 0; i < nitems(sc->_slots); i++) {
497                 slot = &sc->_slots[i];
498                 slot->bd_offset = cpsw_cpdma_bd_offset(i);
499                 STAILQ_INSERT_TAIL(&sc->avail, slot, next);
500         }
501 }
502
503 static int
504 cpsw_add_slots(struct cpsw_softc *sc, struct cpsw_queue *queue, int requested)
505 {
506         const int max_slots = nitems(sc->_slots);
507         struct cpsw_slot *slot;
508         int i;
509
510         if (requested < 0)
511                 requested = max_slots;
512
513         for (i = 0; i < requested; ++i) {
514                 slot = STAILQ_FIRST(&sc->avail);
515                 if (slot == NULL)
516                         return (0);
517                 if (bus_dmamap_create(sc->mbuf_dtag, 0, &slot->dmamap)) {
518                         device_printf(sc->dev, "failed to create dmamap\n");
519                         return (ENOMEM);
520                 }
521                 STAILQ_REMOVE_HEAD(&sc->avail, next);
522                 STAILQ_INSERT_TAIL(&queue->avail, slot, next);
523                 ++queue->avail_queue_len;
524                 ++queue->queue_slots;
525         }
526         return (0);
527 }
528
529 static void
530 cpsw_free_slot(struct cpsw_softc *sc, struct cpsw_slot *slot)
531 {
532         int error;
533
534         if (slot->dmamap) {
535                 if (slot->mbuf)
536                         bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
537                 error = bus_dmamap_destroy(sc->mbuf_dtag, slot->dmamap);
538                 KASSERT(error == 0, ("Mapping still active"));
539                 slot->dmamap = NULL;
540         }
541         if (slot->mbuf) {
542                 m_freem(slot->mbuf);
543                 slot->mbuf = NULL;
544         }
545 }
546
547 static void
548 cpsw_reset(struct cpsw_softc *sc)
549 {
550         int i;
551
552         callout_stop(&sc->watchdog.callout);
553
554         /* Reset RMII/RGMII wrapper. */
555         cpsw_write_4(sc, CPSW_WR_SOFT_RESET, 1);
556         while (cpsw_read_4(sc, CPSW_WR_SOFT_RESET) & 1)
557                 ;
558
559         /* Disable TX and RX interrupts for all cores. */
560         for (i = 0; i < 3; ++i) {
561                 cpsw_write_4(sc, CPSW_WR_C_RX_THRESH_EN(i), 0x00);
562                 cpsw_write_4(sc, CPSW_WR_C_TX_EN(i), 0x00);
563                 cpsw_write_4(sc, CPSW_WR_C_RX_EN(i), 0x00);
564                 cpsw_write_4(sc, CPSW_WR_C_MISC_EN(i), 0x00);
565         }
566
567         /* Reset CPSW subsystem. */
568         cpsw_write_4(sc, CPSW_SS_SOFT_RESET, 1);
569         while (cpsw_read_4(sc, CPSW_SS_SOFT_RESET) & 1)
570                 ;
571
572         /* Reset Sliver port 1 and 2 */
573         for (i = 0; i < 2; i++) {
574                 /* Reset */
575                 cpsw_write_4(sc, CPSW_SL_SOFT_RESET(i), 1);
576                 while (cpsw_read_4(sc, CPSW_SL_SOFT_RESET(i)) & 1)
577                         ;
578         }
579
580         /* Reset DMA controller. */
581         cpsw_write_4(sc, CPSW_CPDMA_SOFT_RESET, 1);
582         while (cpsw_read_4(sc, CPSW_CPDMA_SOFT_RESET) & 1)
583                 ;
584
585         /* Disable TX & RX DMA */
586         cpsw_write_4(sc, CPSW_CPDMA_TX_CONTROL, 0);
587         cpsw_write_4(sc, CPSW_CPDMA_RX_CONTROL, 0);
588
589         /* Clear all queues. */
590         for (i = 0; i < 8; i++) {
591                 cpsw_write_4(sc, CPSW_CPDMA_TX_HDP(i), 0);
592                 cpsw_write_4(sc, CPSW_CPDMA_RX_HDP(i), 0);
593                 cpsw_write_4(sc, CPSW_CPDMA_TX_CP(i), 0);
594                 cpsw_write_4(sc, CPSW_CPDMA_RX_CP(i), 0);
595         }
596
597         /* Clear all interrupt Masks */
598         cpsw_write_4(sc, CPSW_CPDMA_RX_INTMASK_CLEAR, 0xFFFFFFFF);
599         cpsw_write_4(sc, CPSW_CPDMA_TX_INTMASK_CLEAR, 0xFFFFFFFF);
600 }
601
602 static void
603 cpsw_init(struct cpsw_softc *sc)
604 {
605         struct cpsw_slot *slot;
606         uint32_t reg;
607
608         /* Disable the interrupt pacing. */
609         reg = cpsw_read_4(sc, CPSW_WR_INT_CONTROL);
610         reg &= ~(CPSW_WR_INT_PACE_EN | CPSW_WR_INT_PRESCALE_MASK);
611         cpsw_write_4(sc, CPSW_WR_INT_CONTROL, reg);
612
613         /* Clear ALE */
614         cpsw_write_4(sc, CPSW_ALE_CONTROL, CPSW_ALE_CTL_CLEAR_TBL);
615
616         /* Enable ALE */
617         reg = CPSW_ALE_CTL_ENABLE;
618         if (sc->dualemac)
619                 reg |= CPSW_ALE_CTL_VLAN_AWARE;
620         cpsw_write_4(sc, CPSW_ALE_CONTROL, reg);
621
622         /* Set Host Port Mapping. */
623         cpsw_write_4(sc, CPSW_PORT_P0_CPDMA_TX_PRI_MAP, 0x76543210);
624         cpsw_write_4(sc, CPSW_PORT_P0_CPDMA_RX_CH_MAP, 0);
625
626         /* Initialize ALE: set host port to forwarding(3). */
627         cpsw_write_4(sc, CPSW_ALE_PORTCTL(0),
628             ALE_PORTCTL_INGRESS | ALE_PORTCTL_FORWARD);
629
630         cpsw_write_4(sc, CPSW_SS_PTYPE, 0);
631
632         /* Enable statistics for ports 0, 1 and 2 */
633         cpsw_write_4(sc, CPSW_SS_STAT_PORT_EN, 7);
634
635         /* Turn off flow control. */
636         cpsw_write_4(sc, CPSW_SS_FLOW_CONTROL, 0);
637
638         /* Make IP hdr aligned with 4 */
639         cpsw_write_4(sc, CPSW_CPDMA_RX_BUFFER_OFFSET, 2);
640
641         /* Initialize RX Buffer Descriptors */
642         cpsw_write_4(sc, CPSW_CPDMA_RX_PENDTHRESH(0), 0);
643         cpsw_write_4(sc, CPSW_CPDMA_RX_FREEBUFFER(0), 0);
644
645         /* Enable TX & RX DMA */
646         cpsw_write_4(sc, CPSW_CPDMA_TX_CONTROL, 1);
647         cpsw_write_4(sc, CPSW_CPDMA_RX_CONTROL, 1);
648
649         /* Enable Interrupts for core 0 */
650         cpsw_write_4(sc, CPSW_WR_C_RX_THRESH_EN(0), 0xFF);
651         cpsw_write_4(sc, CPSW_WR_C_RX_EN(0), 0xFF);
652         cpsw_write_4(sc, CPSW_WR_C_TX_EN(0), 0xFF);
653         cpsw_write_4(sc, CPSW_WR_C_MISC_EN(0), 0x1F);
654
655         /* Enable host Error Interrupt */
656         cpsw_write_4(sc, CPSW_CPDMA_DMA_INTMASK_SET, 3);
657
658         /* Enable interrupts for RX and TX on Channel 0 */
659         cpsw_write_4(sc, CPSW_CPDMA_RX_INTMASK_SET,
660             CPSW_CPDMA_RX_INT(0) | CPSW_CPDMA_RX_INT_THRESH(0));
661         cpsw_write_4(sc, CPSW_CPDMA_TX_INTMASK_SET, 1);
662
663         /* Initialze MDIO - ENABLE, PREAMBLE=0, FAULTENB, CLKDIV=0xFF */
664         /* TODO Calculate MDCLK=CLK/(CLKDIV+1) */
665         cpsw_write_4(sc, MDIOCONTROL, MDIOCTL_ENABLE | MDIOCTL_FAULTENB | 0xff);
666
667         /* Select MII in GMII_SEL, Internal Delay mode */
668         //ti_scm_reg_write_4(0x650, 0);
669
670         /* Initialize active queues. */
671         slot = STAILQ_FIRST(&sc->tx.active);
672         if (slot != NULL)
673                 cpsw_write_hdp_slot(sc, &sc->tx, slot);
674         slot = STAILQ_FIRST(&sc->rx.active);
675         if (slot != NULL)
676                 cpsw_write_hdp_slot(sc, &sc->rx, slot);
677         cpsw_rx_enqueue(sc);
678         cpsw_write_4(sc, CPSW_CPDMA_RX_FREEBUFFER(0), sc->rx.active_queue_len);
679         cpsw_write_4(sc, CPSW_CPDMA_RX_PENDTHRESH(0), CPSW_TXFRAGS);
680
681         /* Activate network interface. */
682         sc->rx.running = 1;
683         sc->tx.running = 1;
684         sc->watchdog.timer = 0;
685         callout_init(&sc->watchdog.callout, 0);
686         callout_reset(&sc->watchdog.callout, hz, cpsw_tx_watchdog, sc);
687 }
688
689 /*
690  *
691  * Device Probe, Attach, Detach.
692  *
693  */
694
695 static int
696 cpsw_probe(device_t dev)
697 {
698
699         if (!ofw_bus_status_okay(dev))
700                 return (ENXIO);
701
702         if (!ofw_bus_is_compatible(dev, "ti,cpsw"))
703                 return (ENXIO);
704
705         device_set_desc(dev, "3-port Switch Ethernet Subsystem");
706         return (BUS_PROBE_DEFAULT);
707 }
708
709 static int
710 cpsw_intr_attach(struct cpsw_softc *sc)
711 {
712         int i;
713
714         for (i = 0; i < CPSW_INTR_COUNT; i++) {
715                 if (bus_setup_intr(sc->dev, sc->irq_res[i],
716                     INTR_TYPE_NET | INTR_MPSAFE, NULL,
717                     cpsw_intr_cb[i].cb, sc, &sc->ih_cookie[i]) != 0) {
718                         return (-1);
719                 }
720         }
721
722         return (0);
723 }
724
725 static void
726 cpsw_intr_detach(struct cpsw_softc *sc)
727 {
728         int i;
729
730         for (i = 0; i < CPSW_INTR_COUNT; i++) {
731                 if (sc->ih_cookie[i]) {
732                         bus_teardown_intr(sc->dev, sc->irq_res[i],
733                             sc->ih_cookie[i]);
734                 }
735         }
736 }
737
738 static int
739 cpsw_get_fdt_data(struct cpsw_softc *sc, int port)
740 {
741         char *name;
742         int len, phy, vlan;
743         pcell_t phy_id[3], vlan_id;
744         phandle_t child;
745         unsigned long mdio_child_addr;
746
747         /* Find any slave with phy-handle/phy_id */
748         phy = -1;
749         vlan = -1;
750         for (child = OF_child(sc->node); child != 0; child = OF_peer(child)) {
751                 if (OF_getprop_alloc(child, "name", (void **)&name) < 0)
752                         continue;
753                 if (sscanf(name, "slave@%lx", &mdio_child_addr) != 1) {
754                         OF_prop_free(name);
755                         continue;
756                 }
757                 OF_prop_free(name);
758                 if (mdio_child_addr != slave_mdio_addr[port])
759                         continue;
760
761                 if (fdt_get_phyaddr(child, NULL, &phy, NULL) != 0){
762                         /* Users with old DTB will have phy_id instead */
763                         phy = -1;
764                         len = OF_getproplen(child, "phy_id");
765                         if (len / sizeof(pcell_t) == 2) {
766                                 /* Get phy address from fdt */
767                                 if (OF_getencprop(child, "phy_id", phy_id, len) > 0)
768                                         phy = phy_id[1];
769                         }
770                 }
771
772                 len = OF_getproplen(child, "dual_emac_res_vlan");
773                 if (len / sizeof(pcell_t) == 1) {
774                         /* Get phy address from fdt */
775                         if (OF_getencprop(child, "dual_emac_res_vlan",
776                             &vlan_id, len) > 0) {
777                                 vlan = vlan_id;
778                         }
779                 }
780
781                 break;
782         }
783         if (phy == -1)
784                 return (ENXIO);
785         sc->port[port].phy = phy;
786         sc->port[port].vlan = vlan;
787
788         return (0);
789 }
790
791 static int
792 cpsw_attach(device_t dev)
793 {
794         int error, i;
795         struct cpsw_softc *sc;
796         uint32_t reg;
797
798         sc = device_get_softc(dev);
799         sc->dev = dev;
800         sc->node = ofw_bus_get_node(dev);
801         getbinuptime(&sc->attach_uptime);
802
803         if (OF_getencprop(sc->node, "active_slave", &sc->active_slave,
804             sizeof(sc->active_slave)) <= 0) {
805                 sc->active_slave = 0;
806         }
807         if (sc->active_slave > 1)
808                 sc->active_slave = 1;
809
810         if (OF_hasprop(sc->node, "dual_emac"))
811                 sc->dualemac = 1;
812
813         for (i = 0; i < CPSW_PORTS; i++) {
814                 if (!sc->dualemac && i != sc->active_slave)
815                         continue;
816                 if (cpsw_get_fdt_data(sc, i) != 0) {
817                         device_printf(dev,
818                             "failed to get PHY address from FDT\n");
819                         return (ENXIO);
820                 }
821         }
822
823         /* Initialize mutexes */
824         mtx_init(&sc->tx.lock, device_get_nameunit(dev),
825             "cpsw TX lock", MTX_DEF);
826         mtx_init(&sc->rx.lock, device_get_nameunit(dev),
827             "cpsw RX lock", MTX_DEF);
828
829         /* Allocate IRQ resources */
830         error = bus_alloc_resources(dev, irq_res_spec, sc->irq_res);
831         if (error) {
832                 device_printf(dev, "could not allocate IRQ resources\n");
833                 cpsw_detach(dev);
834                 return (ENXIO);
835         }
836
837         sc->mem_rid = 0;
838         sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 
839             &sc->mem_rid, RF_ACTIVE);
840         if (sc->mem_res == NULL) {
841                 device_printf(sc->dev, "failed to allocate memory resource\n");
842                 cpsw_detach(dev);
843                 return (ENXIO);
844         }
845
846         reg = cpsw_read_4(sc, CPSW_SS_IDVER);
847         device_printf(dev, "CPSW SS Version %d.%d (%d)\n", (reg >> 8 & 0x7),
848                 reg & 0xFF, (reg >> 11) & 0x1F);
849
850         cpsw_add_sysctls(sc);
851
852         /* Allocate a busdma tag and DMA safe memory for mbufs. */
853         error = bus_dma_tag_create(
854                 bus_get_dma_tag(sc->dev),       /* parent */
855                 1, 0,                           /* alignment, boundary */
856                 BUS_SPACE_MAXADDR_32BIT,        /* lowaddr */
857                 BUS_SPACE_MAXADDR,              /* highaddr */
858                 NULL, NULL,                     /* filtfunc, filtfuncarg */
859                 MCLBYTES, CPSW_TXFRAGS,         /* maxsize, nsegments */
860                 MCLBYTES, 0,                    /* maxsegsz, flags */
861                 NULL, NULL,                     /* lockfunc, lockfuncarg */
862                 &sc->mbuf_dtag);                /* dmatag */
863         if (error) {
864                 device_printf(dev, "bus_dma_tag_create failed\n");
865                 cpsw_detach(dev);
866                 return (error);
867         }
868
869         /* Allocate a NULL buffer for padding. */
870         sc->nullpad = malloc(ETHER_MIN_LEN, M_DEVBUF, M_WAITOK | M_ZERO);
871
872         cpsw_init_slots(sc);
873
874         /* Allocate slots to TX and RX queues. */
875         STAILQ_INIT(&sc->rx.avail);
876         STAILQ_INIT(&sc->rx.active);
877         STAILQ_INIT(&sc->tx.avail);
878         STAILQ_INIT(&sc->tx.active);
879         // For now:  128 slots to TX, rest to RX.
880         // XXX TODO: start with 32/64 and grow dynamically based on demand.
881         if (cpsw_add_slots(sc, &sc->tx, 128) ||
882             cpsw_add_slots(sc, &sc->rx, -1)) {
883                 device_printf(dev, "failed to allocate dmamaps\n");
884                 cpsw_detach(dev);
885                 return (ENOMEM);
886         }
887         device_printf(dev, "Initial queue size TX=%d RX=%d\n",
888             sc->tx.queue_slots, sc->rx.queue_slots);
889
890         sc->tx.hdp_offset = CPSW_CPDMA_TX_HDP(0);
891         sc->rx.hdp_offset = CPSW_CPDMA_RX_HDP(0);
892
893         if (cpsw_intr_attach(sc) == -1) {
894                 device_printf(dev, "failed to setup interrupts\n");
895                 cpsw_detach(dev);
896                 return (ENXIO);
897         }
898
899 #ifdef CPSW_ETHERSWITCH
900         for (i = 0; i < CPSW_VLANS; i++)
901                 cpsw_vgroups[i].vid = -1;
902 #endif
903
904         /* Reset the controller. */
905         cpsw_reset(sc);
906         cpsw_init(sc);
907
908         for (i = 0; i < CPSW_PORTS; i++) {
909                 if (!sc->dualemac && i != sc->active_slave)
910                         continue;
911                 sc->port[i].dev = device_add_child(dev, "cpsw", i);
912                 if (sc->port[i].dev == NULL) {
913                         cpsw_detach(dev);
914                         return (ENXIO);
915                 }
916         }
917         bus_generic_probe(dev);
918         bus_generic_attach(dev);
919
920         return (0);
921 }
922
923 static int
924 cpsw_detach(device_t dev)
925 {
926         struct cpsw_softc *sc;
927         int error, i;
928
929         bus_generic_detach(dev);
930         sc = device_get_softc(dev);
931
932         for (i = 0; i < CPSW_PORTS; i++) {
933                 if (sc->port[i].dev)
934                         device_delete_child(dev, sc->port[i].dev);
935         }
936
937         if (device_is_attached(dev)) {
938                 callout_stop(&sc->watchdog.callout);
939                 callout_drain(&sc->watchdog.callout);
940         }
941
942         /* Stop and release all interrupts */
943         cpsw_intr_detach(sc);
944
945         /* Free dmamaps and mbufs */
946         for (i = 0; i < nitems(sc->_slots); ++i)
947                 cpsw_free_slot(sc, &sc->_slots[i]);
948
949         /* Free null padding buffer. */
950         if (sc->nullpad)
951                 free(sc->nullpad, M_DEVBUF);
952
953         /* Free DMA tag */
954         if (sc->mbuf_dtag) {
955                 error = bus_dma_tag_destroy(sc->mbuf_dtag);
956                 KASSERT(error == 0, ("Unable to destroy DMA tag"));
957         }
958
959         /* Free IO memory handler */
960         if (sc->mem_res != NULL)
961                 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res);
962         bus_release_resources(dev, irq_res_spec, sc->irq_res);
963
964         /* Destroy mutexes */
965         mtx_destroy(&sc->rx.lock);
966         mtx_destroy(&sc->tx.lock);
967
968         /* Detach the switch device, if present. */
969         error = bus_generic_detach(dev);
970         if (error != 0)
971                 return (error);
972         
973         return (device_delete_children(dev));
974 }
975
976 static phandle_t
977 cpsw_get_node(device_t bus, device_t dev)
978 {
979
980         /* Share controller node with port device. */
981         return (ofw_bus_get_node(bus));
982 }
983
984 static int
985 cpswp_probe(device_t dev)
986 {
987
988         if (device_get_unit(dev) > 1) {
989                 device_printf(dev, "Only two ports are supported.\n");
990                 return (ENXIO);
991         }
992         device_set_desc(dev, "Ethernet Switch Port");
993
994         return (BUS_PROBE_DEFAULT);
995 }
996
997 static int
998 cpswp_attach(device_t dev)
999 {
1000         int error;
1001         struct ifnet *ifp;
1002         struct cpswp_softc *sc;
1003         uint32_t reg;
1004         uint8_t mac_addr[ETHER_ADDR_LEN];
1005
1006         sc = device_get_softc(dev);
1007         sc->dev = dev;
1008         sc->pdev = device_get_parent(dev);
1009         sc->swsc = device_get_softc(sc->pdev);
1010         sc->unit = device_get_unit(dev);
1011         sc->phy = sc->swsc->port[sc->unit].phy;
1012         sc->vlan = sc->swsc->port[sc->unit].vlan;
1013         if (sc->swsc->dualemac && sc->vlan == -1)
1014                 sc->vlan = sc->unit + 1;
1015
1016         if (sc->unit == 0) {
1017                 sc->physel = MDIOUSERPHYSEL0;
1018                 sc->phyaccess = MDIOUSERACCESS0;
1019         } else {
1020                 sc->physel = MDIOUSERPHYSEL1;
1021                 sc->phyaccess = MDIOUSERACCESS1;
1022         }
1023
1024         mtx_init(&sc->lock, device_get_nameunit(dev), "cpsw port lock",
1025             MTX_DEF);
1026
1027         /* Allocate network interface */
1028         ifp = sc->ifp = if_alloc(IFT_ETHER);
1029         if (ifp == NULL) {
1030                 cpswp_detach(dev);
1031                 return (ENXIO);
1032         }
1033
1034         if_initname(ifp, device_get_name(sc->dev), sc->unit);
1035         ifp->if_softc = sc;
1036         ifp->if_flags = IFF_SIMPLEX | IFF_MULTICAST | IFF_BROADCAST;
1037         ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_HWCSUM; //FIXME VLAN?
1038         ifp->if_capenable = ifp->if_capabilities;
1039
1040         ifp->if_init = cpswp_init;
1041         ifp->if_start = cpswp_start;
1042         ifp->if_ioctl = cpswp_ioctl;
1043
1044         ifp->if_snd.ifq_drv_maxlen = sc->swsc->tx.queue_slots;
1045         IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
1046         IFQ_SET_READY(&ifp->if_snd);
1047
1048         /* Get high part of MAC address from control module (mac_id[0|1]_hi) */
1049         ti_scm_reg_read_4(SCM_MAC_ID0_HI + sc->unit * 8, &reg);
1050         mac_addr[0] = reg & 0xFF;
1051         mac_addr[1] = (reg >>  8) & 0xFF;
1052         mac_addr[2] = (reg >> 16) & 0xFF;
1053         mac_addr[3] = (reg >> 24) & 0xFF;
1054
1055         /* Get low part of MAC address from control module (mac_id[0|1]_lo) */
1056         ti_scm_reg_read_4(SCM_MAC_ID0_LO + sc->unit * 8, &reg);
1057         mac_addr[4] = reg & 0xFF;
1058         mac_addr[5] = (reg >>  8) & 0xFF;
1059
1060         error = mii_attach(dev, &sc->miibus, ifp, cpswp_ifmedia_upd,
1061             cpswp_ifmedia_sts, BMSR_DEFCAPMASK, sc->phy, MII_OFFSET_ANY, 0);
1062         if (error) {
1063                 device_printf(dev, "attaching PHYs failed\n");
1064                 cpswp_detach(dev);
1065                 return (error);
1066         }
1067         sc->mii = device_get_softc(sc->miibus);
1068
1069         /* Select PHY and enable interrupts */
1070         cpsw_write_4(sc->swsc, sc->physel,
1071             MDIO_PHYSEL_LINKINTENB | (sc->phy & 0x1F));
1072
1073         ether_ifattach(sc->ifp, mac_addr);
1074         callout_init(&sc->mii_callout, 0);
1075
1076         return (0);
1077 }
1078
1079 static int
1080 cpswp_detach(device_t dev)
1081 {
1082         struct cpswp_softc *sc;
1083
1084         sc = device_get_softc(dev);
1085         CPSW_DEBUGF(sc->swsc, (""));
1086         if (device_is_attached(dev)) {
1087                 ether_ifdetach(sc->ifp);
1088                 CPSW_PORT_LOCK(sc);
1089                 cpswp_stop_locked(sc);
1090                 CPSW_PORT_UNLOCK(sc);
1091                 callout_drain(&sc->mii_callout);
1092         }
1093
1094         bus_generic_detach(dev);
1095
1096         if_free(sc->ifp);
1097         mtx_destroy(&sc->lock);
1098
1099         return (0);
1100 }
1101
1102 /*
1103  *
1104  * Init/Shutdown.
1105  *
1106  */
1107
1108 static int
1109 cpsw_ports_down(struct cpsw_softc *sc)
1110 {
1111         struct cpswp_softc *psc;
1112         struct ifnet *ifp1, *ifp2;
1113
1114         if (!sc->dualemac)
1115                 return (1);
1116         psc = device_get_softc(sc->port[0].dev);
1117         ifp1 = psc->ifp;
1118         psc = device_get_softc(sc->port[1].dev);
1119         ifp2 = psc->ifp;
1120         if ((ifp1->if_flags & IFF_UP) == 0 && (ifp2->if_flags & IFF_UP) == 0)
1121                 return (1);
1122
1123         return (0);
1124 }
1125
1126 static void
1127 cpswp_init(void *arg)
1128 {
1129         struct cpswp_softc *sc = arg;
1130
1131         CPSW_DEBUGF(sc->swsc, (""));
1132         CPSW_PORT_LOCK(sc);
1133         cpswp_init_locked(arg);
1134         CPSW_PORT_UNLOCK(sc);
1135 }
1136
1137 static void
1138 cpswp_init_locked(void *arg)
1139 {
1140 #ifdef CPSW_ETHERSWITCH
1141         int i;
1142 #endif
1143         struct cpswp_softc *sc = arg;
1144         struct ifnet *ifp;
1145         uint32_t reg;
1146
1147         CPSW_DEBUGF(sc->swsc, (""));
1148         CPSW_PORT_LOCK_ASSERT(sc);
1149         ifp = sc->ifp;
1150         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
1151                 return;
1152
1153         getbinuptime(&sc->init_uptime);
1154
1155         if (!sc->swsc->rx.running && !sc->swsc->tx.running) {
1156                 /* Reset the controller. */
1157                 cpsw_reset(sc->swsc);
1158                 cpsw_init(sc->swsc);
1159         }
1160
1161         /* Set Slave Mapping. */
1162         cpsw_write_4(sc->swsc, CPSW_SL_RX_PRI_MAP(sc->unit), 0x76543210);
1163         cpsw_write_4(sc->swsc, CPSW_PORT_P_TX_PRI_MAP(sc->unit + 1),
1164             0x33221100);
1165         cpsw_write_4(sc->swsc, CPSW_SL_RX_MAXLEN(sc->unit), 0x5f2);
1166         /* Enable MAC RX/TX modules. */
1167         /* TODO: Docs claim that IFCTL_B and IFCTL_A do the same thing? */
1168         /* Huh?  Docs call bit 0 "Loopback" some places, "FullDuplex" others. */
1169         reg = cpsw_read_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit));
1170         reg |= CPSW_SL_MACTL_GMII_ENABLE;
1171         cpsw_write_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit), reg);
1172
1173         /* Initialize ALE: set port to forwarding, initialize addrs */
1174         cpsw_write_4(sc->swsc, CPSW_ALE_PORTCTL(sc->unit + 1),
1175             ALE_PORTCTL_INGRESS | ALE_PORTCTL_FORWARD);
1176         cpswp_ale_update_addresses(sc, 1);
1177
1178         if (sc->swsc->dualemac) {
1179                 /* Set Port VID. */
1180                 cpsw_write_4(sc->swsc, CPSW_PORT_P_VLAN(sc->unit + 1),
1181                     sc->vlan & 0xfff);
1182                 cpsw_ale_update_vlan_table(sc->swsc, sc->vlan,
1183                     (1 << (sc->unit + 1)) | (1 << 0), /* Member list */
1184                     (1 << (sc->unit + 1)) | (1 << 0), /* Untagged egress */
1185                     (1 << (sc->unit + 1)) | (1 << 0), 0); /* mcast reg flood */
1186 #ifdef CPSW_ETHERSWITCH
1187                 for (i = 0; i < CPSW_VLANS; i++) {
1188                         if (cpsw_vgroups[i].vid != -1)
1189                                 continue;
1190                         cpsw_vgroups[i].vid = sc->vlan;
1191                         break;
1192                 }
1193 #endif
1194         }
1195
1196         mii_mediachg(sc->mii);
1197         callout_reset(&sc->mii_callout, hz, cpswp_tick, sc);
1198         ifp->if_drv_flags |= IFF_DRV_RUNNING;
1199         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1200 }
1201
1202 static int
1203 cpsw_shutdown(device_t dev)
1204 {
1205         struct cpsw_softc *sc;
1206         struct cpswp_softc *psc;
1207         int i;
1208
1209         sc = device_get_softc(dev);
1210         CPSW_DEBUGF(sc, (""));
1211         for (i = 0; i < CPSW_PORTS; i++) {
1212                 if (!sc->dualemac && i != sc->active_slave)
1213                         continue;
1214                 psc = device_get_softc(sc->port[i].dev);
1215                 CPSW_PORT_LOCK(psc);
1216                 cpswp_stop_locked(psc);
1217                 CPSW_PORT_UNLOCK(psc);
1218         }
1219
1220         return (0);
1221 }
1222
1223 static void
1224 cpsw_rx_teardown(struct cpsw_softc *sc)
1225 {
1226         int i = 0;
1227
1228         CPSW_RX_LOCK(sc);
1229         CPSW_DEBUGF(sc, ("starting RX teardown"));
1230         sc->rx.teardown = 1;
1231         cpsw_write_4(sc, CPSW_CPDMA_RX_TEARDOWN, 0);
1232         CPSW_RX_UNLOCK(sc);
1233         while (sc->rx.running) {
1234                 if (++i > 10) {
1235                         device_printf(sc->dev,
1236                             "Unable to cleanly shutdown receiver\n");
1237                         return;
1238                 }
1239                 DELAY(200);
1240         }
1241         if (!sc->rx.running)
1242                 CPSW_DEBUGF(sc, ("finished RX teardown (%d retries)", i));
1243 }
1244
1245 static void
1246 cpsw_tx_teardown(struct cpsw_softc *sc)
1247 {
1248         int i = 0;
1249
1250         CPSW_TX_LOCK(sc);
1251         CPSW_DEBUGF(sc, ("starting TX teardown"));
1252         /* Start the TX queue teardown if queue is not empty. */
1253         if (STAILQ_FIRST(&sc->tx.active) != NULL)
1254                 cpsw_write_4(sc, CPSW_CPDMA_TX_TEARDOWN, 0);
1255         else
1256                 sc->tx.teardown = 1;
1257         cpsw_tx_dequeue(sc);
1258         while (sc->tx.running && ++i < 10) {
1259                 DELAY(200);
1260                 cpsw_tx_dequeue(sc);
1261         }
1262         if (sc->tx.running) {
1263                 device_printf(sc->dev,
1264                     "Unable to cleanly shutdown transmitter\n");
1265         }
1266         CPSW_DEBUGF(sc,
1267             ("finished TX teardown (%d retries, %d idle buffers)", i,
1268              sc->tx.active_queue_len));
1269         CPSW_TX_UNLOCK(sc);
1270 }
1271
1272 static void
1273 cpswp_stop_locked(struct cpswp_softc *sc)
1274 {
1275         struct ifnet *ifp;
1276         uint32_t reg;
1277
1278         ifp = sc->ifp;
1279         CPSW_DEBUGF(sc->swsc, (""));
1280         CPSW_PORT_LOCK_ASSERT(sc);
1281
1282         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1283                 return;
1284
1285         /* Disable interface */
1286         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1287         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1288
1289         /* Stop ticker */
1290         callout_stop(&sc->mii_callout);
1291
1292         /* Tear down the RX/TX queues. */
1293         if (cpsw_ports_down(sc->swsc)) {
1294                 cpsw_rx_teardown(sc->swsc);
1295                 cpsw_tx_teardown(sc->swsc);
1296         }
1297
1298         /* Stop MAC RX/TX modules. */
1299         reg = cpsw_read_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit));
1300         reg &= ~CPSW_SL_MACTL_GMII_ENABLE;
1301         cpsw_write_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit), reg);
1302
1303         if (cpsw_ports_down(sc->swsc)) {
1304                 /* Capture stats before we reset controller. */
1305                 cpsw_stats_collect(sc->swsc);
1306
1307                 cpsw_reset(sc->swsc);
1308                 cpsw_init(sc->swsc);
1309         }
1310 }
1311
1312 /*
1313  *  Suspend/Resume.
1314  */
1315
1316 static int
1317 cpsw_suspend(device_t dev)
1318 {
1319         struct cpsw_softc *sc;
1320         struct cpswp_softc *psc;
1321         int i;
1322
1323         sc = device_get_softc(dev);
1324         CPSW_DEBUGF(sc, (""));
1325         for (i = 0; i < CPSW_PORTS; i++) {
1326                 if (!sc->dualemac && i != sc->active_slave)
1327                         continue;
1328                 psc = device_get_softc(sc->port[i].dev);
1329                 CPSW_PORT_LOCK(psc);
1330                 cpswp_stop_locked(psc);
1331                 CPSW_PORT_UNLOCK(psc);
1332         }
1333
1334         return (0);
1335 }
1336
1337 static int
1338 cpsw_resume(device_t dev)
1339 {
1340         struct cpsw_softc *sc;
1341
1342         sc  = device_get_softc(dev);
1343         CPSW_DEBUGF(sc, ("UNIMPLEMENTED"));
1344
1345         return (0);
1346 }
1347
1348 /*
1349  *
1350  *  IOCTL
1351  *
1352  */
1353
1354 static void
1355 cpsw_set_promisc(struct cpswp_softc *sc, int set)
1356 {
1357         uint32_t reg;
1358
1359         /*
1360          * Enabling promiscuous mode requires ALE_BYPASS to be enabled.
1361          * That disables the ALE forwarding logic and causes every
1362          * packet to be sent only to the host port.  In bypass mode,
1363          * the ALE processes host port transmit packets the same as in
1364          * normal mode.
1365          */
1366         reg = cpsw_read_4(sc->swsc, CPSW_ALE_CONTROL);
1367         reg &= ~CPSW_ALE_CTL_BYPASS;
1368         if (set)
1369                 reg |= CPSW_ALE_CTL_BYPASS;
1370         cpsw_write_4(sc->swsc, CPSW_ALE_CONTROL, reg);
1371 }
1372
1373 static void
1374 cpsw_set_allmulti(struct cpswp_softc *sc, int set)
1375 {
1376         if (set) {
1377                 printf("All-multicast mode unimplemented\n");
1378         }
1379 }
1380
1381 static int
1382 cpswp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1383 {
1384         struct cpswp_softc *sc;
1385         struct ifreq *ifr;
1386         int error;
1387         uint32_t changed;
1388
1389         error = 0;
1390         sc = ifp->if_softc;
1391         ifr = (struct ifreq *)data;
1392
1393         switch (command) {
1394         case SIOCSIFCAP:
1395                 changed = ifp->if_capenable ^ ifr->ifr_reqcap;
1396                 if (changed & IFCAP_HWCSUM) {
1397                         if ((ifr->ifr_reqcap & changed) & IFCAP_HWCSUM)
1398                                 ifp->if_capenable |= IFCAP_HWCSUM;
1399                         else
1400                                 ifp->if_capenable &= ~IFCAP_HWCSUM;
1401                 }
1402                 error = 0;
1403                 break;
1404         case SIOCSIFFLAGS:
1405                 CPSW_PORT_LOCK(sc);
1406                 if (ifp->if_flags & IFF_UP) {
1407                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1408                                 changed = ifp->if_flags ^ sc->if_flags;
1409                                 CPSW_DEBUGF(sc->swsc,
1410                                     ("SIOCSIFFLAGS: UP & RUNNING (changed=0x%x)",
1411                                     changed));
1412                                 if (changed & IFF_PROMISC)
1413                                         cpsw_set_promisc(sc,
1414                                             ifp->if_flags & IFF_PROMISC);
1415                                 if (changed & IFF_ALLMULTI)
1416                                         cpsw_set_allmulti(sc,
1417                                             ifp->if_flags & IFF_ALLMULTI);
1418                         } else {
1419                                 CPSW_DEBUGF(sc->swsc,
1420                                     ("SIOCSIFFLAGS: starting up"));
1421                                 cpswp_init_locked(sc);
1422                         }
1423                 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1424                         CPSW_DEBUGF(sc->swsc, ("SIOCSIFFLAGS: shutting down"));
1425                         cpswp_stop_locked(sc);
1426                 }
1427
1428                 sc->if_flags = ifp->if_flags;
1429                 CPSW_PORT_UNLOCK(sc);
1430                 break;
1431         case SIOCADDMULTI:
1432                 cpswp_ale_update_addresses(sc, 0);
1433                 break;
1434         case SIOCDELMULTI:
1435                 /* Ugh.  DELMULTI doesn't provide the specific address
1436                    being removed, so the best we can do is remove
1437                    everything and rebuild it all. */
1438                 cpswp_ale_update_addresses(sc, 1);
1439                 break;
1440         case SIOCGIFMEDIA:
1441         case SIOCSIFMEDIA:
1442                 error = ifmedia_ioctl(ifp, ifr, &sc->mii->mii_media, command);
1443                 break;
1444         default:
1445                 error = ether_ioctl(ifp, command, data);
1446         }
1447         return (error);
1448 }
1449
1450 /*
1451  *
1452  * MIIBUS
1453  *
1454  */
1455 static int
1456 cpswp_miibus_ready(struct cpsw_softc *sc, uint32_t reg)
1457 {
1458         uint32_t r, retries = CPSW_MIIBUS_RETRIES;
1459
1460         while (--retries) {
1461                 r = cpsw_read_4(sc, reg);
1462                 if ((r & MDIO_PHYACCESS_GO) == 0)
1463                         return (1);
1464                 DELAY(CPSW_MIIBUS_DELAY);
1465         }
1466
1467         return (0);
1468 }
1469
1470 static int
1471 cpswp_miibus_readreg(device_t dev, int phy, int reg)
1472 {
1473         struct cpswp_softc *sc;
1474         uint32_t cmd, r;
1475
1476         sc = device_get_softc(dev);
1477         if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) {
1478                 device_printf(dev, "MDIO not ready to read\n");
1479                 return (0);
1480         }
1481
1482         /* Set GO, reg, phy */
1483         cmd = MDIO_PHYACCESS_GO | (reg & 0x1F) << 21 | (phy & 0x1F) << 16;
1484         cpsw_write_4(sc->swsc, sc->phyaccess, cmd);
1485
1486         if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) {
1487                 device_printf(dev, "MDIO timed out during read\n");
1488                 return (0);
1489         }
1490
1491         r = cpsw_read_4(sc->swsc, sc->phyaccess);
1492         if ((r & MDIO_PHYACCESS_ACK) == 0) {
1493                 device_printf(dev, "Failed to read from PHY.\n");
1494                 r = 0;
1495         }
1496         return (r & 0xFFFF);
1497 }
1498
1499 static int
1500 cpswp_miibus_writereg(device_t dev, int phy, int reg, int value)
1501 {
1502         struct cpswp_softc *sc;
1503         uint32_t cmd;
1504
1505         sc = device_get_softc(dev);
1506         if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) {
1507                 device_printf(dev, "MDIO not ready to write\n");
1508                 return (0);
1509         }
1510
1511         /* Set GO, WRITE, reg, phy, and value */
1512         cmd = MDIO_PHYACCESS_GO | MDIO_PHYACCESS_WRITE |
1513             (reg & 0x1F) << 21 | (phy & 0x1F) << 16 | (value & 0xFFFF);
1514         cpsw_write_4(sc->swsc, sc->phyaccess, cmd);
1515
1516         if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) {
1517                 device_printf(dev, "MDIO timed out during write\n");
1518                 return (0);
1519         }
1520
1521         return (0);
1522 }
1523
1524 static void
1525 cpswp_miibus_statchg(device_t dev)
1526 {
1527         struct cpswp_softc *sc;
1528         uint32_t mac_control, reg;
1529
1530         sc = device_get_softc(dev);
1531         CPSW_DEBUGF(sc->swsc, (""));
1532
1533         reg = CPSW_SL_MACCONTROL(sc->unit);
1534         mac_control = cpsw_read_4(sc->swsc, reg);
1535         mac_control &= ~(CPSW_SL_MACTL_GIG | CPSW_SL_MACTL_IFCTL_A |
1536             CPSW_SL_MACTL_IFCTL_B | CPSW_SL_MACTL_FULLDUPLEX);
1537
1538         switch(IFM_SUBTYPE(sc->mii->mii_media_active)) {
1539         case IFM_1000_SX:
1540         case IFM_1000_LX:
1541         case IFM_1000_CX:
1542         case IFM_1000_T:
1543                 mac_control |= CPSW_SL_MACTL_GIG;
1544                 break;
1545
1546         case IFM_100_TX:
1547                 mac_control |= CPSW_SL_MACTL_IFCTL_A;
1548                 break;
1549         }
1550         if (sc->mii->mii_media_active & IFM_FDX)
1551                 mac_control |= CPSW_SL_MACTL_FULLDUPLEX;
1552
1553         cpsw_write_4(sc->swsc, reg, mac_control);
1554 }
1555
1556 /*
1557  *
1558  * Transmit/Receive Packets.
1559  *
1560  */
1561 static void
1562 cpsw_intr_rx(void *arg)
1563 {
1564         struct cpsw_softc *sc;
1565         struct ifnet *ifp;
1566         struct mbuf *received, *next;
1567
1568         sc = (struct cpsw_softc *)arg;
1569         CPSW_RX_LOCK(sc);
1570         if (sc->rx.teardown) {
1571                 sc->rx.running = 0;
1572                 sc->rx.teardown = 0;
1573                 cpsw_write_cp(sc, &sc->rx, 0xfffffffc);
1574         }
1575         received = cpsw_rx_dequeue(sc);
1576         cpsw_rx_enqueue(sc);
1577         cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 1);
1578         CPSW_RX_UNLOCK(sc);
1579
1580         while (received != NULL) {
1581                 next = received->m_nextpkt;
1582                 received->m_nextpkt = NULL;
1583                 ifp = received->m_pkthdr.rcvif;
1584                 (*ifp->if_input)(ifp, received);
1585                 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
1586                 received = next;
1587         }
1588 }
1589
1590 static struct mbuf *
1591 cpsw_rx_dequeue(struct cpsw_softc *sc)
1592 {
1593         int nsegs, port, removed;
1594         struct cpsw_cpdma_bd bd;
1595         struct cpsw_slot *last, *slot;
1596         struct cpswp_softc *psc;
1597         struct mbuf *m, *m0, *mb_head, *mb_tail;
1598         uint16_t m0_flags;
1599
1600         nsegs = 0;
1601         m0 = NULL;
1602         last = NULL;
1603         mb_head = NULL;
1604         mb_tail = NULL;
1605         removed = 0;
1606
1607         /* Pull completed packets off hardware RX queue. */
1608         while ((slot = STAILQ_FIRST(&sc->rx.active)) != NULL) {
1609                 cpsw_cpdma_read_bd(sc, slot, &bd);
1610
1611                 /*
1612                  * Stop on packets still in use by hardware, but do not stop
1613                  * on packets with the teardown complete flag, they will be
1614                  * discarded later.
1615                  */
1616                 if ((bd.flags & (CPDMA_BD_OWNER | CPDMA_BD_TDOWNCMPLT)) ==
1617                     CPDMA_BD_OWNER)
1618                         break;
1619
1620                 last = slot;
1621                 ++removed;
1622                 STAILQ_REMOVE_HEAD(&sc->rx.active, next);
1623                 STAILQ_INSERT_TAIL(&sc->rx.avail, slot, next);
1624
1625                 bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTREAD);
1626                 bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
1627
1628                 m = slot->mbuf;
1629                 slot->mbuf = NULL;
1630
1631                 if (bd.flags & CPDMA_BD_TDOWNCMPLT) {
1632                         CPSW_DEBUGF(sc, ("RX teardown is complete"));
1633                         m_freem(m);
1634                         sc->rx.running = 0;
1635                         sc->rx.teardown = 0;
1636                         break;
1637                 }
1638
1639                 port = (bd.flags & CPDMA_BD_PORT_MASK) - 1;
1640                 KASSERT(port >= 0 && port <= 1,
1641                     ("patcket received with invalid port: %d", port));
1642                 psc = device_get_softc(sc->port[port].dev);
1643
1644                 /* Set up mbuf */
1645                 m->m_data += bd.bufoff;
1646                 m->m_len = bd.buflen;
1647                 if (bd.flags & CPDMA_BD_SOP) {
1648                         m->m_pkthdr.len = bd.pktlen;
1649                         m->m_pkthdr.rcvif = psc->ifp;
1650                         m->m_flags |= M_PKTHDR;
1651                         m0_flags = bd.flags;
1652                         m0 = m;
1653                 }
1654                 nsegs++;
1655                 m->m_next = NULL;
1656                 m->m_nextpkt = NULL;
1657                 if (bd.flags & CPDMA_BD_EOP && m0 != NULL) {
1658                         if (m0_flags & CPDMA_BD_PASS_CRC)
1659                                 m_adj(m0, -ETHER_CRC_LEN);
1660                         m0_flags = 0;
1661                         m0 = NULL;
1662                         if (nsegs > sc->rx.longest_chain)
1663                                 sc->rx.longest_chain = nsegs;
1664                         nsegs = 0;
1665                 }
1666
1667                 if ((psc->ifp->if_capenable & IFCAP_RXCSUM) != 0) {
1668                         /* check for valid CRC by looking into pkt_err[5:4] */
1669                         if ((bd.flags &
1670                             (CPDMA_BD_SOP | CPDMA_BD_PKT_ERR_MASK)) ==
1671                             CPDMA_BD_SOP) {
1672                                 m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
1673                                 m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
1674                                 m->m_pkthdr.csum_data = 0xffff;
1675                         }
1676                 }
1677
1678                 if (STAILQ_FIRST(&sc->rx.active) != NULL &&
1679                     (bd.flags & (CPDMA_BD_EOP | CPDMA_BD_EOQ)) ==
1680                     (CPDMA_BD_EOP | CPDMA_BD_EOQ)) {
1681                         cpsw_write_hdp_slot(sc, &sc->rx,
1682                             STAILQ_FIRST(&sc->rx.active));
1683                         sc->rx.queue_restart++;
1684                 }
1685
1686                 /* Add mbuf to packet list to be returned. */
1687                 if (mb_tail != NULL && (bd.flags & CPDMA_BD_SOP)) {
1688                         mb_tail->m_nextpkt = m;
1689                 } else if (mb_tail != NULL) {
1690                         mb_tail->m_next = m;
1691                 } else if (mb_tail == NULL && (bd.flags & CPDMA_BD_SOP) == 0) {
1692                         if (bootverbose)
1693                                 printf(
1694                                     "%s: %s: discanding fragment packet w/o header\n",
1695                                     __func__, psc->ifp->if_xname);
1696                         m_freem(m);
1697                         continue;
1698                 } else {
1699                         mb_head = m;
1700                 }
1701                 mb_tail = m;
1702         }
1703
1704         if (removed != 0) {
1705                 cpsw_write_cp_slot(sc, &sc->rx, last);
1706                 sc->rx.queue_removes += removed;
1707                 sc->rx.avail_queue_len += removed;
1708                 sc->rx.active_queue_len -= removed;
1709                 if (sc->rx.avail_queue_len > sc->rx.max_avail_queue_len)
1710                         sc->rx.max_avail_queue_len = sc->rx.avail_queue_len;
1711                 CPSW_DEBUGF(sc, ("Removed %d received packet(s) from RX queue", removed));
1712         }
1713
1714         return (mb_head);
1715 }
1716
1717 static void
1718 cpsw_rx_enqueue(struct cpsw_softc *sc)
1719 {
1720         bus_dma_segment_t seg[1];
1721         struct cpsw_cpdma_bd bd;
1722         struct cpsw_slot *first_new_slot, *last_old_slot, *next, *slot;
1723         int error, nsegs, added = 0;
1724
1725         /* Register new mbufs with hardware. */
1726         first_new_slot = NULL;
1727         last_old_slot = STAILQ_LAST(&sc->rx.active, cpsw_slot, next);
1728         while ((slot = STAILQ_FIRST(&sc->rx.avail)) != NULL) {
1729                 if (first_new_slot == NULL)
1730                         first_new_slot = slot;
1731                 if (slot->mbuf == NULL) {
1732                         slot->mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1733                         if (slot->mbuf == NULL) {
1734                                 device_printf(sc->dev,
1735                                     "Unable to fill RX queue\n");
1736                                 break;
1737                         }
1738                         slot->mbuf->m_len =
1739                             slot->mbuf->m_pkthdr.len =
1740                             slot->mbuf->m_ext.ext_size;
1741                 }
1742
1743                 error = bus_dmamap_load_mbuf_sg(sc->mbuf_dtag, slot->dmamap,
1744                     slot->mbuf, seg, &nsegs, BUS_DMA_NOWAIT);
1745
1746                 KASSERT(nsegs == 1, ("More than one segment (nsegs=%d)", nsegs));
1747                 KASSERT(error == 0, ("DMA error (error=%d)", error));
1748                 if (error != 0 || nsegs != 1) {
1749                         device_printf(sc->dev,
1750                             "%s: Can't prep RX buf for DMA (nsegs=%d, error=%d)\n",
1751                             __func__, nsegs, error);
1752                         bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
1753                         m_freem(slot->mbuf);
1754                         slot->mbuf = NULL;
1755                         break;
1756                 }
1757
1758                 bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_PREREAD);
1759
1760                 /* Create and submit new rx descriptor. */
1761                 if ((next = STAILQ_NEXT(slot, next)) != NULL)
1762                         bd.next = cpsw_cpdma_bd_paddr(sc, next);
1763                 else
1764                         bd.next = 0;
1765                 bd.bufptr = seg->ds_addr;
1766                 bd.bufoff = 0;
1767                 bd.buflen = MCLBYTES - 1;
1768                 bd.pktlen = bd.buflen;
1769                 bd.flags = CPDMA_BD_OWNER;
1770                 cpsw_cpdma_write_bd(sc, slot, &bd);
1771                 ++added;
1772
1773                 STAILQ_REMOVE_HEAD(&sc->rx.avail, next);
1774                 STAILQ_INSERT_TAIL(&sc->rx.active, slot, next);
1775         }
1776
1777         if (added == 0 || first_new_slot == NULL)
1778                 return;
1779
1780         CPSW_DEBUGF(sc, ("Adding %d buffers to RX queue", added));
1781
1782         /* Link new entries to hardware RX queue. */
1783         if (last_old_slot == NULL) {
1784                 /* Start a fresh queue. */
1785                 cpsw_write_hdp_slot(sc, &sc->rx, first_new_slot);
1786         } else {
1787                 /* Add buffers to end of current queue. */
1788                 cpsw_cpdma_write_bd_next(sc, last_old_slot, first_new_slot);
1789         }
1790         sc->rx.queue_adds += added;
1791         sc->rx.avail_queue_len -= added;
1792         sc->rx.active_queue_len += added;
1793         cpsw_write_4(sc, CPSW_CPDMA_RX_FREEBUFFER(0), added);
1794         if (sc->rx.active_queue_len > sc->rx.max_active_queue_len)
1795                 sc->rx.max_active_queue_len = sc->rx.active_queue_len;
1796 }
1797
1798 static void
1799 cpswp_start(struct ifnet *ifp)
1800 {
1801         struct cpswp_softc *sc;
1802
1803         sc = ifp->if_softc;
1804         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
1805             sc->swsc->tx.running == 0) {
1806                 return;
1807         }
1808         CPSW_TX_LOCK(sc->swsc);
1809         cpswp_tx_enqueue(sc);
1810         cpsw_tx_dequeue(sc->swsc);
1811         CPSW_TX_UNLOCK(sc->swsc);
1812 }
1813
1814 static void
1815 cpsw_intr_tx(void *arg)
1816 {
1817         struct cpsw_softc *sc;
1818
1819         sc = (struct cpsw_softc *)arg;
1820         CPSW_TX_LOCK(sc);
1821         if (cpsw_read_4(sc, CPSW_CPDMA_TX_CP(0)) == 0xfffffffc)
1822                 cpsw_write_cp(sc, &sc->tx, 0xfffffffc);
1823         cpsw_tx_dequeue(sc);
1824         cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 2);
1825         CPSW_TX_UNLOCK(sc);
1826 }
1827
1828 static void
1829 cpswp_tx_enqueue(struct cpswp_softc *sc)
1830 {
1831         bus_dma_segment_t segs[CPSW_TXFRAGS];
1832         struct cpsw_cpdma_bd bd;
1833         struct cpsw_slot *first_new_slot, *last, *last_old_slot, *next, *slot;
1834         struct mbuf *m0;
1835         int error, nsegs, seg, added = 0, padlen;
1836
1837         /* Pull pending packets from IF queue and prep them for DMA. */
1838         last = NULL;
1839         first_new_slot = NULL;
1840         last_old_slot = STAILQ_LAST(&sc->swsc->tx.active, cpsw_slot, next);
1841         while ((slot = STAILQ_FIRST(&sc->swsc->tx.avail)) != NULL) {
1842                 IF_DEQUEUE(&sc->ifp->if_snd, m0);
1843                 if (m0 == NULL)
1844                         break;
1845
1846                 slot->mbuf = m0;
1847                 padlen = ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len;
1848                 if (padlen < 0)
1849                         padlen = 0;
1850                 else if (padlen > 0)
1851                         m_append(slot->mbuf, padlen, sc->swsc->nullpad);
1852
1853                 /* Create mapping in DMA memory */
1854                 error = bus_dmamap_load_mbuf_sg(sc->swsc->mbuf_dtag,
1855                     slot->dmamap, slot->mbuf, segs, &nsegs, BUS_DMA_NOWAIT);
1856                 /* If the packet is too fragmented, try to simplify. */
1857                 if (error == EFBIG ||
1858                     (error == 0 && nsegs > sc->swsc->tx.avail_queue_len)) {
1859                         bus_dmamap_unload(sc->swsc->mbuf_dtag, slot->dmamap);
1860                         m0 = m_defrag(slot->mbuf, M_NOWAIT);
1861                         if (m0 == NULL) {
1862                                 device_printf(sc->dev,
1863                                     "Can't defragment packet; dropping\n");
1864                                 m_freem(slot->mbuf);
1865                         } else {
1866                                 CPSW_DEBUGF(sc->swsc,
1867                                     ("Requeueing defragmented packet"));
1868                                 IF_PREPEND(&sc->ifp->if_snd, m0);
1869                         }
1870                         slot->mbuf = NULL;
1871                         continue;
1872                 }
1873                 if (error != 0) {
1874                         device_printf(sc->dev,
1875                             "%s: Can't setup DMA (error=%d), dropping packet\n",
1876                             __func__, error);
1877                         bus_dmamap_unload(sc->swsc->mbuf_dtag, slot->dmamap);
1878                         m_freem(slot->mbuf);
1879                         slot->mbuf = NULL;
1880                         break;
1881                 }
1882
1883                 bus_dmamap_sync(sc->swsc->mbuf_dtag, slot->dmamap,
1884                                 BUS_DMASYNC_PREWRITE);
1885
1886                 CPSW_DEBUGF(sc->swsc,
1887                     ("Queueing TX packet: %d segments + %d pad bytes",
1888                     nsegs, padlen));
1889
1890                 if (first_new_slot == NULL)
1891                         first_new_slot = slot;
1892
1893                 /* Link from the previous descriptor. */
1894                 if (last != NULL)
1895                         cpsw_cpdma_write_bd_next(sc->swsc, last, slot);
1896
1897                 slot->ifp = sc->ifp;
1898
1899                 /* If there is only one segment, the for() loop
1900                  * gets skipped and the single buffer gets set up
1901                  * as both SOP and EOP. */
1902                 if (nsegs > 1) {
1903                         next = STAILQ_NEXT(slot, next);
1904                         bd.next = cpsw_cpdma_bd_paddr(sc->swsc, next);
1905                 } else
1906                         bd.next = 0;
1907                 /* Start by setting up the first buffer. */
1908                 bd.bufptr = segs[0].ds_addr;
1909                 bd.bufoff = 0;
1910                 bd.buflen = segs[0].ds_len;
1911                 bd.pktlen = m_length(slot->mbuf, NULL);
1912                 bd.flags =  CPDMA_BD_SOP | CPDMA_BD_OWNER;
1913                 if (sc->swsc->dualemac) {
1914                         bd.flags |= CPDMA_BD_TO_PORT;
1915                         bd.flags |= ((sc->unit + 1) & CPDMA_BD_PORT_MASK);
1916                 }
1917                 for (seg = 1; seg < nsegs; ++seg) {
1918                         /* Save the previous buffer (which isn't EOP) */
1919                         cpsw_cpdma_write_bd(sc->swsc, slot, &bd);
1920                         STAILQ_REMOVE_HEAD(&sc->swsc->tx.avail, next);
1921                         STAILQ_INSERT_TAIL(&sc->swsc->tx.active, slot, next);
1922                         slot = STAILQ_FIRST(&sc->swsc->tx.avail);
1923
1924                         /* Setup next buffer (which isn't SOP) */
1925                         if (nsegs > seg + 1) {
1926                                 next = STAILQ_NEXT(slot, next);
1927                                 bd.next = cpsw_cpdma_bd_paddr(sc->swsc, next);
1928                         } else
1929                                 bd.next = 0;
1930                         bd.bufptr = segs[seg].ds_addr;
1931                         bd.bufoff = 0;
1932                         bd.buflen = segs[seg].ds_len;
1933                         bd.pktlen = 0;
1934                         bd.flags = CPDMA_BD_OWNER;
1935                 }
1936
1937                 /* Save the final buffer. */
1938                 bd.flags |= CPDMA_BD_EOP;
1939                 cpsw_cpdma_write_bd(sc->swsc, slot, &bd);
1940                 STAILQ_REMOVE_HEAD(&sc->swsc->tx.avail, next);
1941                 STAILQ_INSERT_TAIL(&sc->swsc->tx.active, slot, next);
1942
1943                 last = slot;
1944                 added += nsegs;
1945                 if (nsegs > sc->swsc->tx.longest_chain)
1946                         sc->swsc->tx.longest_chain = nsegs;
1947
1948                 BPF_MTAP(sc->ifp, m0);
1949         }
1950
1951         if (first_new_slot == NULL)
1952                 return;
1953
1954         /* Attach the list of new buffers to the hardware TX queue. */
1955         if (last_old_slot != NULL &&
1956             (cpsw_cpdma_read_bd_flags(sc->swsc, last_old_slot) &
1957              CPDMA_BD_EOQ) == 0) {
1958                 /* Add buffers to end of current queue. */
1959                 cpsw_cpdma_write_bd_next(sc->swsc, last_old_slot,
1960                     first_new_slot);
1961         } else {
1962                 /* Start a fresh queue. */
1963                 cpsw_write_hdp_slot(sc->swsc, &sc->swsc->tx, first_new_slot);
1964         }
1965         sc->swsc->tx.queue_adds += added;
1966         sc->swsc->tx.avail_queue_len -= added;
1967         sc->swsc->tx.active_queue_len += added;
1968         if (sc->swsc->tx.active_queue_len > sc->swsc->tx.max_active_queue_len) {
1969                 sc->swsc->tx.max_active_queue_len = sc->swsc->tx.active_queue_len;
1970         }
1971         CPSW_DEBUGF(sc->swsc, ("Queued %d TX packet(s)", added));
1972 }
1973
1974 static int
1975 cpsw_tx_dequeue(struct cpsw_softc *sc)
1976 {
1977         struct cpsw_slot *slot, *last_removed_slot = NULL;
1978         struct cpsw_cpdma_bd bd;
1979         uint32_t flags, removed = 0;
1980
1981         /* Pull completed buffers off the hardware TX queue. */
1982         slot = STAILQ_FIRST(&sc->tx.active);
1983         while (slot != NULL) {
1984                 flags = cpsw_cpdma_read_bd_flags(sc, slot);
1985
1986                 /* TearDown complete is only marked on the SOP for the packet. */
1987                 if ((flags & (CPDMA_BD_SOP | CPDMA_BD_TDOWNCMPLT)) ==
1988                     (CPDMA_BD_SOP | CPDMA_BD_TDOWNCMPLT)) {
1989                         sc->tx.teardown = 1;
1990                 }
1991
1992                 if ((flags & (CPDMA_BD_SOP | CPDMA_BD_OWNER)) ==
1993                     (CPDMA_BD_SOP | CPDMA_BD_OWNER) && sc->tx.teardown == 0)
1994                         break; /* Hardware is still using this packet. */
1995
1996                 bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTWRITE);
1997                 bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
1998                 m_freem(slot->mbuf);
1999                 slot->mbuf = NULL;
2000
2001                 if (slot->ifp) {
2002                         if (sc->tx.teardown == 0)
2003                                 if_inc_counter(slot->ifp, IFCOUNTER_OPACKETS, 1);
2004                         else
2005                                 if_inc_counter(slot->ifp, IFCOUNTER_OQDROPS, 1);
2006                 }
2007
2008                 /* Dequeue any additional buffers used by this packet. */
2009                 while (slot != NULL && slot->mbuf == NULL) {
2010                         STAILQ_REMOVE_HEAD(&sc->tx.active, next);
2011                         STAILQ_INSERT_TAIL(&sc->tx.avail, slot, next);
2012                         ++removed;
2013                         last_removed_slot = slot;
2014                         slot = STAILQ_FIRST(&sc->tx.active);
2015                 }
2016
2017                 cpsw_write_cp_slot(sc, &sc->tx, last_removed_slot);
2018
2019                 /* Restart the TX queue if necessary. */
2020                 cpsw_cpdma_read_bd(sc, last_removed_slot, &bd);
2021                 if (slot != NULL && bd.next != 0 && (bd.flags &
2022                     (CPDMA_BD_EOP | CPDMA_BD_OWNER | CPDMA_BD_EOQ)) ==
2023                     (CPDMA_BD_EOP | CPDMA_BD_EOQ)) {
2024                         cpsw_write_hdp_slot(sc, &sc->tx, slot);
2025                         sc->tx.queue_restart++;
2026                         break;
2027                 }
2028         }
2029
2030         if (removed != 0) {
2031                 sc->tx.queue_removes += removed;
2032                 sc->tx.active_queue_len -= removed;
2033                 sc->tx.avail_queue_len += removed;
2034                 if (sc->tx.avail_queue_len > sc->tx.max_avail_queue_len)
2035                         sc->tx.max_avail_queue_len = sc->tx.avail_queue_len;
2036                 CPSW_DEBUGF(sc, ("TX removed %d completed packet(s)", removed));
2037         }
2038
2039         if (sc->tx.teardown && STAILQ_EMPTY(&sc->tx.active)) {
2040                 CPSW_DEBUGF(sc, ("TX teardown is complete"));
2041                 sc->tx.teardown = 0;
2042                 sc->tx.running = 0;
2043         }
2044
2045         return (removed);
2046 }
2047
2048 /*
2049  *
2050  * Miscellaneous interrupts.
2051  *
2052  */
2053
2054 static void
2055 cpsw_intr_rx_thresh(void *arg)
2056 {
2057         struct cpsw_softc *sc;
2058         struct ifnet *ifp;
2059         struct mbuf *received, *next;
2060
2061         sc = (struct cpsw_softc *)arg;
2062         CPSW_RX_LOCK(sc);
2063         received = cpsw_rx_dequeue(sc);
2064         cpsw_rx_enqueue(sc);
2065         cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 0);
2066         CPSW_RX_UNLOCK(sc);
2067
2068         while (received != NULL) {
2069                 next = received->m_nextpkt;
2070                 received->m_nextpkt = NULL;
2071                 ifp = received->m_pkthdr.rcvif;
2072                 (*ifp->if_input)(ifp, received);
2073                 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
2074                 received = next;
2075         }
2076 }
2077
2078 static void
2079 cpsw_intr_misc_host_error(struct cpsw_softc *sc)
2080 {
2081         uint32_t intstat;
2082         uint32_t dmastat;
2083         int txerr, rxerr, txchan, rxchan;
2084
2085         printf("\n\n");
2086         device_printf(sc->dev,
2087             "HOST ERROR:  PROGRAMMING ERROR DETECTED BY HARDWARE\n");
2088         printf("\n\n");
2089         intstat = cpsw_read_4(sc, CPSW_CPDMA_DMA_INTSTAT_MASKED);
2090         device_printf(sc->dev, "CPSW_CPDMA_DMA_INTSTAT_MASKED=0x%x\n", intstat);
2091         dmastat = cpsw_read_4(sc, CPSW_CPDMA_DMASTATUS);
2092         device_printf(sc->dev, "CPSW_CPDMA_DMASTATUS=0x%x\n", dmastat);
2093
2094         txerr = (dmastat >> 20) & 15;
2095         txchan = (dmastat >> 16) & 7;
2096         rxerr = (dmastat >> 12) & 15;
2097         rxchan = (dmastat >> 8) & 7;
2098
2099         switch (txerr) {
2100         case 0: break;
2101         case 1: printf("SOP error on TX channel %d\n", txchan);
2102                 break;
2103         case 2: printf("Ownership bit not set on SOP buffer on TX channel %d\n", txchan);
2104                 break;
2105         case 3: printf("Zero Next Buffer but not EOP on TX channel %d\n", txchan);
2106                 break;
2107         case 4: printf("Zero Buffer Pointer on TX channel %d\n", txchan);
2108                 break;
2109         case 5: printf("Zero Buffer Length on TX channel %d\n", txchan);
2110                 break;
2111         case 6: printf("Packet length error on TX channel %d\n", txchan);
2112                 break;
2113         default: printf("Unknown error on TX channel %d\n", txchan);
2114                 break;
2115         }
2116
2117         if (txerr != 0) {
2118                 printf("CPSW_CPDMA_TX%d_HDP=0x%x\n",
2119                     txchan, cpsw_read_4(sc, CPSW_CPDMA_TX_HDP(txchan)));
2120                 printf("CPSW_CPDMA_TX%d_CP=0x%x\n",
2121                     txchan, cpsw_read_4(sc, CPSW_CPDMA_TX_CP(txchan)));
2122                 cpsw_dump_queue(sc, &sc->tx.active);
2123         }
2124
2125         switch (rxerr) {
2126         case 0: break;
2127         case 2: printf("Ownership bit not set on RX channel %d\n", rxchan);
2128                 break;
2129         case 4: printf("Zero Buffer Pointer on RX channel %d\n", rxchan);
2130                 break;
2131         case 5: printf("Zero Buffer Length on RX channel %d\n", rxchan);
2132                 break;
2133         case 6: printf("Buffer offset too big on RX channel %d\n", rxchan);
2134                 break;
2135         default: printf("Unknown RX error on RX channel %d\n", rxchan);
2136                 break;
2137         }
2138
2139         if (rxerr != 0) {
2140                 printf("CPSW_CPDMA_RX%d_HDP=0x%x\n",
2141                     rxchan, cpsw_read_4(sc,CPSW_CPDMA_RX_HDP(rxchan)));
2142                 printf("CPSW_CPDMA_RX%d_CP=0x%x\n",
2143                     rxchan, cpsw_read_4(sc, CPSW_CPDMA_RX_CP(rxchan)));
2144                 cpsw_dump_queue(sc, &sc->rx.active);
2145         }
2146
2147         printf("\nALE Table\n");
2148         cpsw_ale_dump_table(sc);
2149
2150         // XXX do something useful here??
2151         panic("CPSW HOST ERROR INTERRUPT");
2152
2153         // Suppress this interrupt in the future.
2154         cpsw_write_4(sc, CPSW_CPDMA_DMA_INTMASK_CLEAR, intstat);
2155         printf("XXX HOST ERROR INTERRUPT SUPPRESSED\n");
2156         // The watchdog will probably reset the controller
2157         // in a little while.  It will probably fail again.
2158 }
2159
2160 static void
2161 cpsw_intr_misc(void *arg)
2162 {
2163         struct cpsw_softc *sc = arg;
2164         uint32_t stat = cpsw_read_4(sc, CPSW_WR_C_MISC_STAT(0));
2165
2166         if (stat & CPSW_WR_C_MISC_EVNT_PEND)
2167                 CPSW_DEBUGF(sc, ("Time sync event interrupt unimplemented"));
2168         if (stat & CPSW_WR_C_MISC_STAT_PEND)
2169                 cpsw_stats_collect(sc);
2170         if (stat & CPSW_WR_C_MISC_HOST_PEND)
2171                 cpsw_intr_misc_host_error(sc);
2172         if (stat & CPSW_WR_C_MISC_MDIOLINK) {
2173                 cpsw_write_4(sc, MDIOLINKINTMASKED,
2174                     cpsw_read_4(sc, MDIOLINKINTMASKED));
2175         }
2176         if (stat & CPSW_WR_C_MISC_MDIOUSER) {
2177                 CPSW_DEBUGF(sc,
2178                     ("MDIO operation completed interrupt unimplemented"));
2179         }
2180         cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 3);
2181 }
2182
2183 /*
2184  *
2185  * Periodic Checks and Watchdog.
2186  *
2187  */
2188
2189 static void
2190 cpswp_tick(void *msc)
2191 {
2192         struct cpswp_softc *sc = msc;
2193
2194         /* Check for media type change */
2195         mii_tick(sc->mii);
2196         if (sc->media_status != sc->mii->mii_media.ifm_media) {
2197                 printf("%s: media type changed (ifm_media=%x)\n", __func__, 
2198                         sc->mii->mii_media.ifm_media);
2199                 cpswp_ifmedia_upd(sc->ifp);
2200         }
2201
2202         /* Schedule another timeout one second from now */
2203         callout_reset(&sc->mii_callout, hz, cpswp_tick, sc);
2204 }
2205
2206 static void
2207 cpswp_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
2208 {
2209         struct cpswp_softc *sc;
2210         struct mii_data *mii;
2211
2212         sc = ifp->if_softc;
2213         CPSW_DEBUGF(sc->swsc, (""));
2214         CPSW_PORT_LOCK(sc);
2215
2216         mii = sc->mii;
2217         mii_pollstat(mii);
2218
2219         ifmr->ifm_active = mii->mii_media_active;
2220         ifmr->ifm_status = mii->mii_media_status;
2221         CPSW_PORT_UNLOCK(sc);
2222 }
2223
2224 static int
2225 cpswp_ifmedia_upd(struct ifnet *ifp)
2226 {
2227         struct cpswp_softc *sc;
2228
2229         sc = ifp->if_softc;
2230         CPSW_DEBUGF(sc->swsc, (""));
2231         CPSW_PORT_LOCK(sc);
2232         mii_mediachg(sc->mii);
2233         sc->media_status = sc->mii->mii_media.ifm_media;
2234         CPSW_PORT_UNLOCK(sc);
2235
2236         return (0);
2237 }
2238
2239 static void
2240 cpsw_tx_watchdog_full_reset(struct cpsw_softc *sc)
2241 {
2242         struct cpswp_softc *psc;
2243         int i;
2244
2245         cpsw_debugf_head("CPSW watchdog");
2246         device_printf(sc->dev, "watchdog timeout\n");
2247         printf("CPSW_CPDMA_TX%d_HDP=0x%x\n", 0,
2248             cpsw_read_4(sc, CPSW_CPDMA_TX_HDP(0)));
2249         printf("CPSW_CPDMA_TX%d_CP=0x%x\n", 0,
2250             cpsw_read_4(sc, CPSW_CPDMA_TX_CP(0)));
2251         cpsw_dump_queue(sc, &sc->tx.active);
2252         for (i = 0; i < CPSW_PORTS; i++) {
2253                 if (!sc->dualemac && i != sc->active_slave)
2254                         continue;
2255                 psc = device_get_softc(sc->port[i].dev);
2256                 CPSW_PORT_LOCK(psc);
2257                 cpswp_stop_locked(psc);
2258                 CPSW_PORT_UNLOCK(psc);
2259         }
2260 }
2261
2262 static void
2263 cpsw_tx_watchdog(void *msc)
2264 {
2265         struct cpsw_softc *sc;
2266
2267         sc = msc;
2268         CPSW_TX_LOCK(sc);
2269         if (sc->tx.active_queue_len == 0 || !sc->tx.running) {
2270                 sc->watchdog.timer = 0; /* Nothing to do. */
2271         } else if (sc->tx.queue_removes > sc->tx.queue_removes_at_last_tick) {
2272                 sc->watchdog.timer = 0;  /* Stuff done while we weren't looking. */
2273         } else if (cpsw_tx_dequeue(sc) > 0) {
2274                 sc->watchdog.timer = 0;  /* We just did something. */
2275         } else {
2276                 /* There was something to do but it didn't get done. */
2277                 ++sc->watchdog.timer;
2278                 if (sc->watchdog.timer > 5) {
2279                         sc->watchdog.timer = 0;
2280                         ++sc->watchdog.resets;
2281                         cpsw_tx_watchdog_full_reset(sc);
2282                 }
2283         }
2284         sc->tx.queue_removes_at_last_tick = sc->tx.queue_removes;
2285         CPSW_TX_UNLOCK(sc);
2286
2287         /* Schedule another timeout one second from now */
2288         callout_reset(&sc->watchdog.callout, hz, cpsw_tx_watchdog, sc);
2289 }
2290
2291 /*
2292  *
2293  * ALE support routines.
2294  *
2295  */
2296
2297 static void
2298 cpsw_ale_read_entry(struct cpsw_softc *sc, uint16_t idx, uint32_t *ale_entry)
2299 {
2300         cpsw_write_4(sc, CPSW_ALE_TBLCTL, idx & 1023);
2301         ale_entry[0] = cpsw_read_4(sc, CPSW_ALE_TBLW0);
2302         ale_entry[1] = cpsw_read_4(sc, CPSW_ALE_TBLW1);
2303         ale_entry[2] = cpsw_read_4(sc, CPSW_ALE_TBLW2);
2304 }
2305
2306 static void
2307 cpsw_ale_write_entry(struct cpsw_softc *sc, uint16_t idx, uint32_t *ale_entry)
2308 {
2309         cpsw_write_4(sc, CPSW_ALE_TBLW0, ale_entry[0]);
2310         cpsw_write_4(sc, CPSW_ALE_TBLW1, ale_entry[1]);
2311         cpsw_write_4(sc, CPSW_ALE_TBLW2, ale_entry[2]);
2312         cpsw_write_4(sc, CPSW_ALE_TBLCTL, 1 << 31 | (idx & 1023));
2313 }
2314
2315 static void
2316 cpsw_ale_remove_all_mc_entries(struct cpsw_softc *sc)
2317 {
2318         int i;
2319         uint32_t ale_entry[3];
2320
2321         /* First four entries are link address and broadcast. */
2322         for (i = 10; i < CPSW_MAX_ALE_ENTRIES; i++) {
2323                 cpsw_ale_read_entry(sc, i, ale_entry);
2324                 if ((ALE_TYPE(ale_entry) == ALE_TYPE_ADDR ||
2325                     ALE_TYPE(ale_entry) == ALE_TYPE_VLAN_ADDR) &&
2326                     ALE_MCAST(ale_entry)  == 1) { /* MCast link addr */
2327                         ale_entry[0] = ale_entry[1] = ale_entry[2] = 0;
2328                         cpsw_ale_write_entry(sc, i, ale_entry);
2329                 }
2330         }
2331 }
2332
2333 static int
2334 cpsw_ale_mc_entry_set(struct cpsw_softc *sc, uint8_t portmap, int vlan,
2335         uint8_t *mac)
2336 {
2337         int free_index = -1, matching_index = -1, i;
2338         uint32_t ale_entry[3], ale_type;
2339
2340         /* Find a matching entry or a free entry. */
2341         for (i = 10; i < CPSW_MAX_ALE_ENTRIES; i++) {
2342                 cpsw_ale_read_entry(sc, i, ale_entry);
2343
2344                 /* Entry Type[61:60] is 0 for free entry */ 
2345                 if (free_index < 0 && ALE_TYPE(ale_entry) == 0)
2346                         free_index = i;
2347
2348                 if ((((ale_entry[1] >> 8) & 0xFF) == mac[0]) &&
2349                     (((ale_entry[1] >> 0) & 0xFF) == mac[1]) &&
2350                     (((ale_entry[0] >>24) & 0xFF) == mac[2]) &&
2351                     (((ale_entry[0] >>16) & 0xFF) == mac[3]) &&
2352                     (((ale_entry[0] >> 8) & 0xFF) == mac[4]) &&
2353                     (((ale_entry[0] >> 0) & 0xFF) == mac[5])) {
2354                         matching_index = i;
2355                         break;
2356                 }
2357         }
2358
2359         if (matching_index < 0) {
2360                 if (free_index < 0)
2361                         return (ENOMEM);
2362                 i = free_index;
2363         }
2364
2365         if (vlan != -1)
2366                 ale_type = ALE_TYPE_VLAN_ADDR << 28 | vlan << 16;
2367         else
2368                 ale_type = ALE_TYPE_ADDR << 28;
2369
2370         /* Set MAC address */
2371         ale_entry[0] = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
2372         ale_entry[1] = mac[0] << 8 | mac[1];
2373
2374         /* Entry type[61:60] and Mcast fwd state[63:62] is fw(3). */
2375         ale_entry[1] |= ALE_MCAST_FWD | ale_type;
2376
2377         /* Set portmask [68:66] */
2378         ale_entry[2] = (portmap & 7) << 2;
2379
2380         cpsw_ale_write_entry(sc, i, ale_entry);
2381
2382         return 0;
2383 }
2384
2385 static void
2386 cpsw_ale_dump_table(struct cpsw_softc *sc) {
2387         int i;
2388         uint32_t ale_entry[3];
2389         for (i = 0; i < CPSW_MAX_ALE_ENTRIES; i++) {
2390                 cpsw_ale_read_entry(sc, i, ale_entry);
2391                 switch (ALE_TYPE(ale_entry)) {
2392                 case ALE_TYPE_VLAN:
2393                         printf("ALE[%4u] %08x %08x %08x ", i, ale_entry[2],
2394                                 ale_entry[1], ale_entry[0]);
2395                         printf("type: %u ", ALE_TYPE(ale_entry));
2396                         printf("vlan: %u ", ALE_VLAN(ale_entry));
2397                         printf("untag: %u ", ALE_VLAN_UNTAG(ale_entry));
2398                         printf("reg flood: %u ", ALE_VLAN_REGFLOOD(ale_entry));
2399                         printf("unreg flood: %u ", ALE_VLAN_UNREGFLOOD(ale_entry));
2400                         printf("members: %u ", ALE_VLAN_MEMBERS(ale_entry));
2401                         printf("\n");
2402                         break;
2403                 case ALE_TYPE_ADDR:
2404                 case ALE_TYPE_VLAN_ADDR:
2405                         printf("ALE[%4u] %08x %08x %08x ", i, ale_entry[2],
2406                                 ale_entry[1], ale_entry[0]);
2407                         printf("type: %u ", ALE_TYPE(ale_entry));
2408                         printf("mac: %02x:%02x:%02x:%02x:%02x:%02x ",
2409                                 (ale_entry[1] >> 8) & 0xFF,
2410                                 (ale_entry[1] >> 0) & 0xFF,
2411                                 (ale_entry[0] >>24) & 0xFF,
2412                                 (ale_entry[0] >>16) & 0xFF,
2413                                 (ale_entry[0] >> 8) & 0xFF,
2414                                 (ale_entry[0] >> 0) & 0xFF);
2415                         printf(ALE_MCAST(ale_entry) ? "mcast " : "ucast ");
2416                         if (ALE_TYPE(ale_entry) == ALE_TYPE_VLAN_ADDR)
2417                                 printf("vlan: %u ", ALE_VLAN(ale_entry));
2418                         printf("port: %u ", ALE_PORTS(ale_entry));
2419                         printf("\n");
2420                         break;
2421                 }
2422         }
2423         printf("\n");
2424 }
2425
2426 static int
2427 cpswp_ale_update_addresses(struct cpswp_softc *sc, int purge)
2428 {
2429         uint8_t *mac;
2430         uint32_t ale_entry[3], ale_type, portmask;
2431         struct ifmultiaddr *ifma;
2432
2433         if (sc->swsc->dualemac) {
2434                 ale_type = ALE_TYPE_VLAN_ADDR << 28 | sc->vlan << 16;
2435                 portmask = 1 << (sc->unit + 1) | 1 << 0;
2436         } else {
2437                 ale_type = ALE_TYPE_ADDR << 28;
2438                 portmask = 7;
2439         }
2440
2441         /*
2442          * Route incoming packets for our MAC address to Port 0 (host).
2443          * For simplicity, keep this entry at table index 0 for port 1 and
2444          * at index 2 for port 2 in the ALE.
2445          */
2446         if_addr_rlock(sc->ifp);
2447         mac = LLADDR((struct sockaddr_dl *)sc->ifp->if_addr->ifa_addr);
2448         ale_entry[0] = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
2449         ale_entry[1] = ale_type | mac[0] << 8 | mac[1]; /* addr entry + mac */
2450         ale_entry[2] = 0; /* port = 0 */
2451         cpsw_ale_write_entry(sc->swsc, 0 + 2 * sc->unit, ale_entry);
2452
2453         /* Set outgoing MAC Address for slave port. */
2454         cpsw_write_4(sc->swsc, CPSW_PORT_P_SA_HI(sc->unit + 1),
2455             mac[3] << 24 | mac[2] << 16 | mac[1] << 8 | mac[0]);
2456         cpsw_write_4(sc->swsc, CPSW_PORT_P_SA_LO(sc->unit + 1),
2457             mac[5] << 8 | mac[4]);
2458         if_addr_runlock(sc->ifp);
2459
2460         /* Keep the broadcast address at table entry 1 (or 3). */
2461         ale_entry[0] = 0xffffffff; /* Lower 32 bits of MAC */
2462         /* ALE_MCAST_FWD, Addr type, upper 16 bits of Mac */ 
2463         ale_entry[1] = ALE_MCAST_FWD | ale_type | 0xffff;
2464         ale_entry[2] = portmask << 2;
2465         cpsw_ale_write_entry(sc->swsc, 1 + 2 * sc->unit, ale_entry);
2466
2467         /* SIOCDELMULTI doesn't specify the particular address
2468            being removed, so we have to remove all and rebuild. */
2469         if (purge)
2470                 cpsw_ale_remove_all_mc_entries(sc->swsc);
2471
2472         /* Set other multicast addrs desired. */
2473         if_maddr_rlock(sc->ifp);
2474         CK_STAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) {
2475                 if (ifma->ifma_addr->sa_family != AF_LINK)
2476                         continue;
2477                 cpsw_ale_mc_entry_set(sc->swsc, portmask, sc->vlan,
2478                     LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
2479         }
2480         if_maddr_runlock(sc->ifp);
2481
2482         return (0);
2483 }
2484
2485 static int
2486 cpsw_ale_update_vlan_table(struct cpsw_softc *sc, int vlan, int ports,
2487         int untag, int mcregflood, int mcunregflood)
2488 {
2489         int free_index, i, matching_index;
2490         uint32_t ale_entry[3];
2491
2492         free_index = matching_index = -1;
2493         /* Find a matching entry or a free entry. */
2494         for (i = 5; i < CPSW_MAX_ALE_ENTRIES; i++) {
2495                 cpsw_ale_read_entry(sc, i, ale_entry);
2496
2497                 /* Entry Type[61:60] is 0 for free entry */ 
2498                 if (free_index < 0 && ALE_TYPE(ale_entry) == 0)
2499                         free_index = i;
2500
2501                 if (ALE_VLAN(ale_entry) == vlan) {
2502                         matching_index = i;
2503                         break;
2504                 }
2505         }
2506
2507         if (matching_index < 0) {
2508                 if (free_index < 0)
2509                         return (-1);
2510                 i = free_index;
2511         }
2512
2513         ale_entry[0] = (untag & 7) << 24 | (mcregflood & 7) << 16 |
2514             (mcunregflood & 7) << 8 | (ports & 7);
2515         ale_entry[1] = ALE_TYPE_VLAN << 28 | vlan << 16;
2516         ale_entry[2] = 0;
2517         cpsw_ale_write_entry(sc, i, ale_entry);
2518
2519         return (0);
2520 }
2521
2522 /*
2523  *
2524  * Statistics and Sysctls.
2525  *
2526  */
2527
2528 #if 0
2529 static void
2530 cpsw_stats_dump(struct cpsw_softc *sc)
2531 {
2532         int i;
2533         uint32_t r;
2534
2535         for (i = 0; i < CPSW_SYSCTL_COUNT; ++i) {
2536                 r = cpsw_read_4(sc, CPSW_STATS_OFFSET +
2537                     cpsw_stat_sysctls[i].reg);
2538                 CPSW_DEBUGF(sc, ("%s: %ju + %u = %ju", cpsw_stat_sysctls[i].oid,
2539                     (intmax_t)sc->shadow_stats[i], r,
2540                     (intmax_t)sc->shadow_stats[i] + r));
2541         }
2542 }
2543 #endif
2544
2545 static void
2546 cpsw_stats_collect(struct cpsw_softc *sc)
2547 {
2548         int i;
2549         uint32_t r;
2550
2551         CPSW_DEBUGF(sc, ("Controller shadow statistics updated."));
2552
2553         for (i = 0; i < CPSW_SYSCTL_COUNT; ++i) {
2554                 r = cpsw_read_4(sc, CPSW_STATS_OFFSET +
2555                     cpsw_stat_sysctls[i].reg);
2556                 sc->shadow_stats[i] += r;
2557                 cpsw_write_4(sc, CPSW_STATS_OFFSET + cpsw_stat_sysctls[i].reg,
2558                     r);
2559         }
2560 }
2561
2562 static int
2563 cpsw_stats_sysctl(SYSCTL_HANDLER_ARGS)
2564 {
2565         struct cpsw_softc *sc;
2566         struct cpsw_stat *stat;
2567         uint64_t result;
2568
2569         sc = (struct cpsw_softc *)arg1;
2570         stat = &cpsw_stat_sysctls[oidp->oid_number];
2571         result = sc->shadow_stats[oidp->oid_number];
2572         result += cpsw_read_4(sc, CPSW_STATS_OFFSET + stat->reg);
2573         return (sysctl_handle_64(oidp, &result, 0, req));
2574 }
2575
2576 static int
2577 cpsw_stat_attached(SYSCTL_HANDLER_ARGS)
2578 {
2579         struct cpsw_softc *sc;
2580         struct bintime t;
2581         unsigned result;
2582
2583         sc = (struct cpsw_softc *)arg1;
2584         getbinuptime(&t);
2585         bintime_sub(&t, &sc->attach_uptime);
2586         result = t.sec;
2587         return (sysctl_handle_int(oidp, &result, 0, req));
2588 }
2589
2590 static int
2591 cpsw_intr_coalesce(SYSCTL_HANDLER_ARGS)
2592 {
2593         int error;
2594         struct cpsw_softc *sc;
2595         uint32_t ctrl, intr_per_ms;
2596
2597         sc = (struct cpsw_softc *)arg1;
2598         error = sysctl_handle_int(oidp, &sc->coal_us, 0, req);
2599         if (error != 0 || req->newptr == NULL)
2600                 return (error);
2601
2602         ctrl = cpsw_read_4(sc, CPSW_WR_INT_CONTROL);
2603         ctrl &= ~(CPSW_WR_INT_PACE_EN | CPSW_WR_INT_PRESCALE_MASK);
2604         if (sc->coal_us == 0) {
2605                 /* Disable the interrupt pace hardware. */
2606                 cpsw_write_4(sc, CPSW_WR_INT_CONTROL, ctrl);
2607                 cpsw_write_4(sc, CPSW_WR_C_RX_IMAX(0), 0);
2608                 cpsw_write_4(sc, CPSW_WR_C_TX_IMAX(0), 0);
2609                 return (0);
2610         }
2611
2612         if (sc->coal_us > CPSW_WR_C_IMAX_US_MAX)
2613                 sc->coal_us = CPSW_WR_C_IMAX_US_MAX;
2614         if (sc->coal_us < CPSW_WR_C_IMAX_US_MIN)
2615                 sc->coal_us = CPSW_WR_C_IMAX_US_MIN;
2616         intr_per_ms = 1000 / sc->coal_us;
2617         /* Just to make sure... */
2618         if (intr_per_ms > CPSW_WR_C_IMAX_MAX)
2619                 intr_per_ms = CPSW_WR_C_IMAX_MAX;
2620         if (intr_per_ms < CPSW_WR_C_IMAX_MIN)
2621                 intr_per_ms = CPSW_WR_C_IMAX_MIN;
2622
2623         /* Set the prescale to produce 4us pulses from the 125 Mhz clock. */
2624         ctrl |= (125 * 4) & CPSW_WR_INT_PRESCALE_MASK;
2625
2626         /* Enable the interrupt pace hardware. */
2627         cpsw_write_4(sc, CPSW_WR_C_RX_IMAX(0), intr_per_ms);
2628         cpsw_write_4(sc, CPSW_WR_C_TX_IMAX(0), intr_per_ms);
2629         ctrl |= CPSW_WR_INT_C0_RX_PULSE | CPSW_WR_INT_C0_TX_PULSE;
2630         cpsw_write_4(sc, CPSW_WR_INT_CONTROL, ctrl);
2631
2632         return (0);
2633 }
2634
2635 static int
2636 cpsw_stat_uptime(SYSCTL_HANDLER_ARGS)
2637 {
2638         struct cpsw_softc *swsc;
2639         struct cpswp_softc *sc;
2640         struct bintime t;
2641         unsigned result;
2642
2643         swsc = arg1;
2644         sc = device_get_softc(swsc->port[arg2].dev);
2645         if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) {
2646                 getbinuptime(&t);
2647                 bintime_sub(&t, &sc->init_uptime);
2648                 result = t.sec;
2649         } else
2650                 result = 0;
2651         return (sysctl_handle_int(oidp, &result, 0, req));
2652 }
2653
2654 static void
2655 cpsw_add_queue_sysctls(struct sysctl_ctx_list *ctx, struct sysctl_oid *node,
2656         struct cpsw_queue *queue)
2657 {
2658         struct sysctl_oid_list *parent;
2659
2660         parent = SYSCTL_CHILDREN(node);
2661         SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "totalBuffers",
2662             CTLFLAG_RD, &queue->queue_slots, 0,
2663             "Total buffers currently assigned to this queue");
2664         SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "activeBuffers",
2665             CTLFLAG_RD, &queue->active_queue_len, 0,
2666             "Buffers currently registered with hardware controller");
2667         SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "maxActiveBuffers",
2668             CTLFLAG_RD, &queue->max_active_queue_len, 0,
2669             "Max value of activeBuffers since last driver reset");
2670         SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "availBuffers",
2671             CTLFLAG_RD, &queue->avail_queue_len, 0,
2672             "Buffers allocated to this queue but not currently "
2673             "registered with hardware controller");
2674         SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "maxAvailBuffers",
2675             CTLFLAG_RD, &queue->max_avail_queue_len, 0,
2676             "Max value of availBuffers since last driver reset");
2677         SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "totalEnqueued",
2678             CTLFLAG_RD, &queue->queue_adds, 0,
2679             "Total buffers added to queue");
2680         SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "totalDequeued",
2681             CTLFLAG_RD, &queue->queue_removes, 0,
2682             "Total buffers removed from queue");
2683         SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "queueRestart",
2684             CTLFLAG_RD, &queue->queue_restart, 0,
2685             "Total times the queue has been restarted");
2686         SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "longestChain",
2687             CTLFLAG_RD, &queue->longest_chain, 0,
2688             "Max buffers used for a single packet");
2689 }
2690
2691 static void
2692 cpsw_add_watchdog_sysctls(struct sysctl_ctx_list *ctx, struct sysctl_oid *node,
2693         struct cpsw_softc *sc)
2694 {
2695         struct sysctl_oid_list *parent;
2696
2697         parent = SYSCTL_CHILDREN(node);
2698         SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "resets",
2699             CTLFLAG_RD, &sc->watchdog.resets, 0,
2700             "Total number of watchdog resets");
2701 }
2702
2703 static void
2704 cpsw_add_sysctls(struct cpsw_softc *sc)
2705 {
2706         struct sysctl_ctx_list *ctx;
2707         struct sysctl_oid *stats_node, *queue_node, *node;
2708         struct sysctl_oid_list *parent, *stats_parent, *queue_parent;
2709         struct sysctl_oid_list *ports_parent, *port_parent;
2710         char port[16];
2711         int i;
2712
2713         ctx = device_get_sysctl_ctx(sc->dev);
2714         parent = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
2715
2716         SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "debug",
2717             CTLFLAG_RW, &sc->debug, 0, "Enable switch debug messages");
2718
2719         SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "attachedSecs",
2720             CTLTYPE_UINT | CTLFLAG_RD, sc, 0, cpsw_stat_attached, "IU",
2721             "Time since driver attach");
2722
2723         SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "intr_coalesce_us",
2724             CTLTYPE_UINT | CTLFLAG_RW, sc, 0, cpsw_intr_coalesce, "IU",
2725             "minimum time between interrupts");
2726
2727         node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "ports",
2728             CTLFLAG_RD, NULL, "CPSW Ports Statistics");
2729         ports_parent = SYSCTL_CHILDREN(node);
2730         for (i = 0; i < CPSW_PORTS; i++) {
2731                 if (!sc->dualemac && i != sc->active_slave)
2732                         continue;
2733                 port[0] = '0' + i;
2734                 port[1] = '\0';
2735                 node = SYSCTL_ADD_NODE(ctx, ports_parent, OID_AUTO,
2736                     port, CTLFLAG_RD, NULL, "CPSW Port Statistics");
2737                 port_parent = SYSCTL_CHILDREN(node);
2738                 SYSCTL_ADD_PROC(ctx, port_parent, OID_AUTO, "uptime",
2739                     CTLTYPE_UINT | CTLFLAG_RD, sc, i,
2740                     cpsw_stat_uptime, "IU", "Seconds since driver init");
2741         }
2742
2743         stats_node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "stats",
2744                                      CTLFLAG_RD, NULL, "CPSW Statistics");
2745         stats_parent = SYSCTL_CHILDREN(stats_node);
2746         for (i = 0; i < CPSW_SYSCTL_COUNT; ++i) {
2747                 SYSCTL_ADD_PROC(ctx, stats_parent, i,
2748                                 cpsw_stat_sysctls[i].oid,
2749                                 CTLTYPE_U64 | CTLFLAG_RD, sc, 0,
2750                                 cpsw_stats_sysctl, "IU",
2751                                 cpsw_stat_sysctls[i].oid);
2752         }
2753
2754         queue_node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "queue",
2755             CTLFLAG_RD, NULL, "CPSW Queue Statistics");
2756         queue_parent = SYSCTL_CHILDREN(queue_node);
2757
2758         node = SYSCTL_ADD_NODE(ctx, queue_parent, OID_AUTO, "tx",
2759             CTLFLAG_RD, NULL, "TX Queue Statistics");
2760         cpsw_add_queue_sysctls(ctx, node, &sc->tx);
2761
2762         node = SYSCTL_ADD_NODE(ctx, queue_parent, OID_AUTO, "rx",
2763             CTLFLAG_RD, NULL, "RX Queue Statistics");
2764         cpsw_add_queue_sysctls(ctx, node, &sc->rx);
2765
2766         node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "watchdog",
2767             CTLFLAG_RD, NULL, "Watchdog Statistics");
2768         cpsw_add_watchdog_sysctls(ctx, node, sc);
2769 }
2770
2771 #ifdef CPSW_ETHERSWITCH
2772 static etherswitch_info_t etherswitch_info = {
2773         .es_nports =            CPSW_PORTS + 1,
2774         .es_nvlangroups =       CPSW_VLANS,
2775         .es_name =              "TI Common Platform Ethernet Switch (CPSW)",
2776         .es_vlan_caps =         ETHERSWITCH_VLAN_DOT1Q,
2777 };
2778
2779 static etherswitch_info_t *
2780 cpsw_getinfo(device_t dev)
2781 {
2782         return (&etherswitch_info);
2783 }
2784
2785 static int
2786 cpsw_getport(device_t dev, etherswitch_port_t *p)
2787 {
2788         int err;
2789         struct cpsw_softc *sc;
2790         struct cpswp_softc *psc;
2791         struct ifmediareq *ifmr;
2792         uint32_t reg;
2793
2794         if (p->es_port < 0 || p->es_port > CPSW_PORTS)
2795                 return (ENXIO);
2796
2797         err = 0;
2798         sc = device_get_softc(dev);
2799         if (p->es_port == CPSW_CPU_PORT) {
2800                 p->es_flags |= ETHERSWITCH_PORT_CPU;
2801                 ifmr = &p->es_ifmr;
2802                 ifmr->ifm_current = ifmr->ifm_active =
2803                     IFM_ETHER | IFM_1000_T | IFM_FDX;
2804                 ifmr->ifm_mask = 0;
2805                 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
2806                 ifmr->ifm_count = 0;
2807         } else {
2808                 psc = device_get_softc(sc->port[p->es_port - 1].dev);
2809                 err = ifmedia_ioctl(psc->ifp, &p->es_ifr,
2810                     &psc->mii->mii_media, SIOCGIFMEDIA);
2811         }
2812         reg = cpsw_read_4(sc, CPSW_PORT_P_VLAN(p->es_port));
2813         p->es_pvid = reg & ETHERSWITCH_VID_MASK;
2814
2815         reg = cpsw_read_4(sc, CPSW_ALE_PORTCTL(p->es_port));
2816         if (reg & ALE_PORTCTL_DROP_UNTAGGED)
2817                 p->es_flags |= ETHERSWITCH_PORT_DROPUNTAGGED;
2818         if (reg & ALE_PORTCTL_INGRESS)
2819                 p->es_flags |= ETHERSWITCH_PORT_INGRESS;
2820
2821         return (err);
2822 }
2823
2824 static int
2825 cpsw_setport(device_t dev, etherswitch_port_t *p)
2826 {
2827         struct cpsw_softc *sc;
2828         struct cpswp_softc *psc;
2829         struct ifmedia *ifm;
2830         uint32_t reg;
2831
2832         if (p->es_port < 0 || p->es_port > CPSW_PORTS)
2833                 return (ENXIO);
2834
2835         sc = device_get_softc(dev);
2836         if (p->es_pvid != 0) {
2837                 cpsw_write_4(sc, CPSW_PORT_P_VLAN(p->es_port),
2838                     p->es_pvid & ETHERSWITCH_VID_MASK);
2839         }
2840
2841         reg = cpsw_read_4(sc, CPSW_ALE_PORTCTL(p->es_port));
2842         if (p->es_flags & ETHERSWITCH_PORT_DROPUNTAGGED)
2843                 reg |= ALE_PORTCTL_DROP_UNTAGGED;
2844         else
2845                 reg &= ~ALE_PORTCTL_DROP_UNTAGGED;
2846         if (p->es_flags & ETHERSWITCH_PORT_INGRESS)
2847                 reg |= ALE_PORTCTL_INGRESS;
2848         else
2849                 reg &= ~ALE_PORTCTL_INGRESS;
2850         cpsw_write_4(sc, CPSW_ALE_PORTCTL(p->es_port), reg);
2851
2852         /* CPU port does not allow media settings. */
2853         if (p->es_port == CPSW_CPU_PORT)
2854                 return (0);
2855
2856         psc = device_get_softc(sc->port[p->es_port - 1].dev);
2857         ifm = &psc->mii->mii_media;
2858
2859         return (ifmedia_ioctl(psc->ifp, &p->es_ifr, ifm, SIOCSIFMEDIA));
2860 }
2861
2862 static int
2863 cpsw_getconf(device_t dev, etherswitch_conf_t *conf)
2864 {
2865
2866         /* Return the VLAN mode. */
2867         conf->cmd = ETHERSWITCH_CONF_VLAN_MODE;
2868         conf->vlan_mode = ETHERSWITCH_VLAN_DOT1Q;
2869
2870         return (0);
2871 }
2872
2873 static int
2874 cpsw_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
2875 {
2876         int i, vid;
2877         uint32_t ale_entry[3];
2878         struct cpsw_softc *sc;
2879
2880         sc = device_get_softc(dev);
2881
2882         if (vg->es_vlangroup >= CPSW_VLANS)
2883                 return (EINVAL);
2884
2885         vg->es_vid = 0;
2886         vid = cpsw_vgroups[vg->es_vlangroup].vid;
2887         if (vid == -1)
2888                 return (0);
2889
2890         for (i = 0; i < CPSW_MAX_ALE_ENTRIES; i++) {
2891                 cpsw_ale_read_entry(sc, i, ale_entry);
2892                 if (ALE_TYPE(ale_entry) != ALE_TYPE_VLAN)
2893                         continue;
2894                 if (vid != ALE_VLAN(ale_entry))
2895                         continue;
2896
2897                 vg->es_fid = 0;
2898                 vg->es_vid = ALE_VLAN(ale_entry) | ETHERSWITCH_VID_VALID;
2899                 vg->es_member_ports = ALE_VLAN_MEMBERS(ale_entry);
2900                 vg->es_untagged_ports = ALE_VLAN_UNTAG(ale_entry);
2901         }
2902
2903         return (0);
2904 }
2905
2906 static void
2907 cpsw_remove_vlan(struct cpsw_softc *sc, int vlan)
2908 {
2909         int i;
2910         uint32_t ale_entry[3];
2911
2912         for (i = 0; i < CPSW_MAX_ALE_ENTRIES; i++) {
2913                 cpsw_ale_read_entry(sc, i, ale_entry);
2914                 if (ALE_TYPE(ale_entry) != ALE_TYPE_VLAN)
2915                         continue;
2916                 if (vlan != ALE_VLAN(ale_entry))
2917                         continue;
2918                 ale_entry[0] = ale_entry[1] = ale_entry[2] = 0;
2919                 cpsw_ale_write_entry(sc, i, ale_entry);
2920                 break;
2921         }
2922 }
2923
2924 static int
2925 cpsw_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
2926 {
2927         int i;
2928         struct cpsw_softc *sc;
2929
2930         sc = device_get_softc(dev);
2931
2932         for (i = 0; i < CPSW_VLANS; i++) {
2933                 /* Is this Vlan ID in use by another vlangroup ? */
2934                 if (vg->es_vlangroup != i && cpsw_vgroups[i].vid == vg->es_vid)
2935                         return (EINVAL);
2936         }
2937
2938         if (vg->es_vid == 0) {
2939                 if (cpsw_vgroups[vg->es_vlangroup].vid == -1)
2940                         return (0);
2941                 cpsw_remove_vlan(sc, cpsw_vgroups[vg->es_vlangroup].vid);
2942                 cpsw_vgroups[vg->es_vlangroup].vid = -1;
2943                 vg->es_untagged_ports = 0;
2944                 vg->es_member_ports = 0;
2945                 vg->es_vid = 0;
2946                 return (0);
2947         }
2948
2949         vg->es_vid &= ETHERSWITCH_VID_MASK;
2950         vg->es_member_ports &= CPSW_PORTS_MASK;
2951         vg->es_untagged_ports &= CPSW_PORTS_MASK;
2952
2953         if (cpsw_vgroups[vg->es_vlangroup].vid != -1 &&
2954             cpsw_vgroups[vg->es_vlangroup].vid != vg->es_vid)
2955                 return (EINVAL);
2956
2957         cpsw_vgroups[vg->es_vlangroup].vid = vg->es_vid;
2958         cpsw_ale_update_vlan_table(sc, vg->es_vid, vg->es_member_ports,
2959             vg->es_untagged_ports, vg->es_member_ports, 0);
2960
2961         return (0);
2962 }
2963
2964 static int
2965 cpsw_readreg(device_t dev, int addr)
2966 {
2967
2968         /* Not supported. */
2969         return (0);
2970 }
2971
2972 static int
2973 cpsw_writereg(device_t dev, int addr, int value)
2974 {
2975
2976         /* Not supported. */
2977         return (0);
2978 }
2979
2980 static int
2981 cpsw_readphy(device_t dev, int phy, int reg)
2982 {
2983
2984         /* Not supported. */
2985         return (0);
2986 }
2987
2988 static int
2989 cpsw_writephy(device_t dev, int phy, int reg, int data)
2990 {
2991
2992         /* Not supported. */
2993         return (0);
2994 }
2995 #endif