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