add broadcom b44 driver support
[openwrt.git] / target / linux / adm5120 / files / drivers / net / adm5120sw.c
1 /*
2 * ADM5120 built-in ethernet switch driver
3 *
4 * Copyright (C) 2007,2008 Gabor Juhos <juhosg at openwrt.org>
5 *
6 * This code was based on a driver for Linux 2.6.xx by Jeroen Vreeken.
7 * Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005
8 * NAPI extension for the Jeroen's driver
9 * Copyright Thomas Langer (Thomas.Langer@infineon.com), 2007
10 * Copyright Friedrich Beckmann (Friedrich.Beckmann@infineon.com), 2007
11 * Inspiration for the Jeroen's driver came from the ADMtek 2.4 driver.
12 * Copyright ADMtek Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License version 2 as published
16 * by the Free Software Foundation.
17 *
18 */
19
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/errno.h>
23 #include <linux/interrupt.h>
24 #include <linux/ioport.h>
25 #include <linux/spinlock.h>
26 #include <linux/platform_device.h>
27
28 #include <linux/netdevice.h>
29 #include <linux/etherdevice.h>
30 #include <linux/skbuff.h>
31
32 #include <linux/io.h>
33 #include <linux/irq.h>
34
35 #include <asm/mipsregs.h>
36
37 #include <adm5120_info.h>
38 #include <adm5120_defs.h>
39 #include <adm5120_irq.h>
40 #include <adm5120_switch.h>
41
42 #include "adm5120sw.h"
43
44 #define DRV_NAME "adm5120-switch"
45 #define DRV_DESC "ADM5120 built-in ethernet switch driver"
46 #define DRV_VERSION "0.1.0"
47
48 #define CONFIG_ADM5120_SWITCH_NAPI 1
49 #undef CONFIG_ADM5120_SWITCH_DEBUG
50
51 /* ------------------------------------------------------------------------ */
52
53 #ifdef CONFIG_ADM5120_SWITCH_DEBUG
54 #define SW_DBG(f, a...) printk(KERN_DBG "%s: " f, DRV_NAME , ## a)
55 #else
56 #define SW_DBG(f, a...) do {} while (0)
57 #endif
58 #define SW_ERR(f, a...) printk(KERN_ERR "%s: " f, DRV_NAME , ## a)
59 #define SW_INFO(f, a...) printk(KERN_INFO "%s: " f, DRV_NAME , ## a)
60
61 #define SWITCH_NUM_PORTS 6
62 #define ETH_CSUM_LEN 4
63
64 #define RX_MAX_PKTLEN 1550
65 #define RX_RING_SIZE 64
66
67 #define TX_RING_SIZE 32
68 #define TX_QUEUE_LEN 28 /* Limit ring entries actually used. */
69 #define TX_TIMEOUT HZ*400
70
71 #define RX_DESCS_SIZE (RX_RING_SIZE * sizeof(struct dma_desc *))
72 #define RX_SKBS_SIZE (RX_RING_SIZE * sizeof(struct sk_buff *))
73 #define TX_DESCS_SIZE (TX_RING_SIZE * sizeof(struct dma_desc *))
74 #define TX_SKBS_SIZE (TX_RING_SIZE * sizeof(struct sk_buff *))
75
76 #define SKB_ALLOC_LEN (RX_MAX_PKTLEN + 32)
77 #define SKB_RESERVE_LEN (NET_IP_ALIGN + NET_SKB_PAD)
78
79 #define SWITCH_INTS_HIGH (SWITCH_INT_SHD | SWITCH_INT_RHD | SWITCH_INT_HDF)
80 #define SWITCH_INTS_LOW (SWITCH_INT_SLD | SWITCH_INT_RLD | SWITCH_INT_LDF)
81 #define SWITCH_INTS_ERR (SWITCH_INT_RDE | SWITCH_INT_SDE | SWITCH_INT_CPUH)
82 #define SWITCH_INTS_Q (SWITCH_INT_P0QF | SWITCH_INT_P1QF | SWITCH_INT_P2QF | \
83 SWITCH_INT_P3QF | SWITCH_INT_P4QF | SWITCH_INT_P5QF | \
84 SWITCH_INT_CPQF | SWITCH_INT_GQF)
85
86 #define SWITCH_INTS_ALL (SWITCH_INTS_HIGH | SWITCH_INTS_LOW | \
87 SWITCH_INTS_ERR | SWITCH_INTS_Q | \
88 SWITCH_INT_MD | SWITCH_INT_PSC)
89
90 #define SWITCH_INTS_USED (SWITCH_INTS_LOW | SWITCH_INT_PSC)
91 #define SWITCH_INTS_POLL (SWITCH_INT_RLD | SWITCH_INT_LDF | SWITCH_INT_SLD)
92
93 /* ------------------------------------------------------------------------ */
94
95 struct adm5120_if_priv {
96 unsigned int vlan_no;
97 unsigned int port_mask;
98 };
99
100 struct dma_desc {
101 __u32 buf1;
102 #define DESC_OWN (1UL << 31) /* Owned by the switch */
103 #define DESC_EOR (1UL << 28) /* End of Ring */
104 #define DESC_ADDR_MASK 0x1FFFFFF
105 #define DESC_ADDR(x) ((__u32)(x) & DESC_ADDR_MASK)
106 __u32 buf2;
107 #define DESC_BUF2_EN (1UL << 31) /* Buffer 2 enable */
108 __u32 buflen;
109 __u32 misc;
110 /* definitions for tx/rx descriptors */
111 #define DESC_PKTLEN_SHIFT 16
112 #define DESC_PKTLEN_MASK 0x7FF
113 /* tx descriptor specific part */
114 #define DESC_CSUM (1UL << 31) /* Append checksum */
115 #define DESC_DSTPORT_SHIFT 8
116 #define DESC_DSTPORT_MASK 0x3F
117 #define DESC_VLAN_MASK 0x3F
118 /* rx descriptor specific part */
119 #define DESC_SRCPORT_SHIFT 12
120 #define DESC_SRCPORT_MASK 0x7
121 #define DESC_DA_MASK 0x3
122 #define DESC_DA_SHIFT 4
123 #define DESC_IPCSUM_FAIL (1UL << 3) /* IP checksum fail */
124 #define DESC_VLAN_TAG (1UL << 2) /* VLAN tag present */
125 #define DESC_TYPE_MASK 0x3 /* mask for Packet type */
126 #define DESC_TYPE_IP 0x0 /* IP packet */
127 #define DESC_TYPE_PPPoE 0x1 /* PPPoE packet */
128 } __attribute__ ((aligned(16)));
129
130 /* ------------------------------------------------------------------------ */
131
132 static int adm5120_nrdevs;
133
134 static struct net_device *adm5120_devs[SWITCH_NUM_PORTS];
135 /* Lookup table port -> device */
136 static struct net_device *adm5120_port[SWITCH_NUM_PORTS];
137
138 static struct dma_desc *txl_descs;
139 static struct dma_desc *rxl_descs;
140
141 static dma_addr_t txl_descs_dma;
142 static dma_addr_t rxl_descs_dma;
143
144 static struct sk_buff **txl_skbuff;
145 static struct sk_buff **rxl_skbuff;
146
147 static unsigned int cur_rxl, dirty_rxl; /* producer/consumer ring indices */
148 static unsigned int cur_txl, dirty_txl;
149
150 static unsigned int sw_used;
151
152 static spinlock_t tx_lock = SPIN_LOCK_UNLOCKED;
153
154 /* ------------------------------------------------------------------------ */
155
156 static inline u32 sw_read_reg(u32 reg)
157 {
158 return __raw_readl((void __iomem *)KSEG1ADDR(ADM5120_SWITCH_BASE)+reg);
159 }
160
161 static inline void sw_write_reg(u32 reg, u32 val)
162 {
163 __raw_writel(val, (void __iomem *)KSEG1ADDR(ADM5120_SWITCH_BASE)+reg);
164 }
165
166 static inline void sw_int_mask(u32 mask)
167 {
168 u32 t;
169
170 t = sw_read_reg(SWITCH_REG_INT_MASK);
171 t |= mask;
172 sw_write_reg(SWITCH_REG_INT_MASK, t);
173 }
174
175 static inline void sw_int_unmask(u32 mask)
176 {
177 u32 t;
178
179 t = sw_read_reg(SWITCH_REG_INT_MASK);
180 t &= ~mask;
181 sw_write_reg(SWITCH_REG_INT_MASK, t);
182 }
183
184 static inline void sw_int_ack(u32 mask)
185 {
186 sw_write_reg(SWITCH_REG_INT_STATUS, mask);
187 }
188
189 static inline u32 sw_int_status(void)
190 {
191 u32 t;
192
193 t = sw_read_reg(SWITCH_REG_INT_STATUS);
194 t &= ~sw_read_reg(SWITCH_REG_INT_MASK);
195 return t;
196 }
197
198 static inline u32 desc_get_srcport(struct dma_desc *desc)
199 {
200 return (desc->misc >> DESC_SRCPORT_SHIFT) & DESC_SRCPORT_MASK;
201 }
202
203 static inline u32 desc_get_pktlen(struct dma_desc *desc)
204 {
205 return (desc->misc >> DESC_PKTLEN_SHIFT) & DESC_PKTLEN_MASK;
206 }
207
208 static inline int desc_ipcsum_fail(struct dma_desc *desc)
209 {
210 return ((desc->misc & DESC_IPCSUM_FAIL) != 0);
211 }
212
213 /* ------------------------------------------------------------------------ */
214
215 static void sw_dump_desc(char *label, struct dma_desc *desc, int tx)
216 {
217 u32 t;
218
219 SW_DBG("%s %s desc/%p\n", label, tx ? "tx" : "rx", desc);
220
221 t = desc->buf1;
222 SW_DBG(" buf1 %08X addr=%08X; len=%08X %s%s\n", t,
223 t & DESC_ADDR_MASK,
224 desc->buflen,
225 (t & DESC_OWN) ? "SWITCH" : "CPU",
226 (t & DESC_EOR) ? " RE" : "");
227
228 t = desc->buf2;
229 SW_DBG(" buf2 %08X addr=%08X%s\n", desc->buf2,
230 t & DESC_ADDR_MASK,
231 (t & DESC_BUF2_EN) ? " EN" : "" );
232
233 t = desc->misc;
234 if (tx)
235 SW_DBG(" misc %08X%s pktlen=%04X ports=%02X vlan=%02X\n", t,
236 (t & DESC_CSUM) ? " CSUM" : "",
237 (t >> DESC_PKTLEN_SHIFT) & DESC_PKTLEN_MASK,
238 (t >> DESC_DSTPORT_SHIFT) & DESC_DSTPORT_MASK,
239 t & DESC_VLAN_MASK);
240 else
241 SW_DBG(" misc %08X pktlen=%04X port=%d DA=%d%s%s type=%d\n",
242 t,
243 (t >> DESC_PKTLEN_SHIFT) & DESC_PKTLEN_MASK,
244 (t >> DESC_SRCPORT_SHIFT) & DESC_SRCPORT_MASK,
245 (t >> DESC_DA_SHIFT) & DESC_DA_MASK,
246 (t & DESC_IPCSUM_FAIL) ? " IPCF" : "",
247 (t & DESC_VLAN_TAG) ? " VLAN" : "",
248 (t & DESC_TYPE_MASK));
249 }
250
251 static void sw_dump_intr_mask(char *label, u32 mask)
252 {
253 SW_DBG("%s %08X%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
254 label, mask,
255 (mask & SWITCH_INT_SHD) ? " SHD" : "",
256 (mask & SWITCH_INT_SLD) ? " SLD" : "",
257 (mask & SWITCH_INT_RHD) ? " RHD" : "",
258 (mask & SWITCH_INT_RLD) ? " RLD" : "",
259 (mask & SWITCH_INT_HDF) ? " HDF" : "",
260 (mask & SWITCH_INT_LDF) ? " LDF" : "",
261 (mask & SWITCH_INT_P0QF) ? " P0QF" : "",
262 (mask & SWITCH_INT_P1QF) ? " P1QF" : "",
263 (mask & SWITCH_INT_P2QF) ? " P2QF" : "",
264 (mask & SWITCH_INT_P3QF) ? " P3QF" : "",
265 (mask & SWITCH_INT_P4QF) ? " P4QF" : "",
266 (mask & SWITCH_INT_CPQF) ? " CPQF" : "",
267 (mask & SWITCH_INT_GQF) ? " GQF" : "",
268 (mask & SWITCH_INT_MD) ? " MD" : "",
269 (mask & SWITCH_INT_BCS) ? " BCS" : "",
270 (mask & SWITCH_INT_PSC) ? " PSC" : "",
271 (mask & SWITCH_INT_ID) ? " ID" : "",
272 (mask & SWITCH_INT_W0TE) ? " W0TE" : "",
273 (mask & SWITCH_INT_W1TE) ? " W1TE" : "",
274 (mask & SWITCH_INT_RDE) ? " RDE" : "",
275 (mask & SWITCH_INT_SDE) ? " SDE" : "",
276 (mask & SWITCH_INT_CPUH) ? " CPUH" : "");
277 }
278
279 static void sw_dump_regs(void)
280 {
281 u32 t;
282
283 t = sw_read_reg(SWITCH_REG_PHY_STATUS);
284 SW_DBG("phy_status: %08X\n", t);
285
286 t = sw_read_reg(SWITCH_REG_CPUP_CONF);
287 SW_DBG("cpup_conf: %08X%s%s%s\n", t,
288 (t & CPUP_CONF_DCPUP) ? " DCPUP" : "",
289 (t & CPUP_CONF_CRCP) ? " CRCP" : "",
290 (t & CPUP_CONF_BTM) ? " BTM" : "");
291
292 t = sw_read_reg(SWITCH_REG_PORT_CONF0);
293 SW_DBG("port_conf0: %08X\n", t);
294 t = sw_read_reg(SWITCH_REG_PORT_CONF1);
295 SW_DBG("port_conf1: %08X\n", t);
296 t = sw_read_reg(SWITCH_REG_PORT_CONF2);
297 SW_DBG("port_conf2: %08X\n", t);
298
299 t = sw_read_reg(SWITCH_REG_VLAN_G1);
300 SW_DBG("vlan g1: %08X\n", t);
301 t = sw_read_reg(SWITCH_REG_VLAN_G2);
302 SW_DBG("vlan g2: %08X\n", t);
303
304 t = sw_read_reg(SWITCH_REG_BW_CNTL0);
305 SW_DBG("bw_cntl0: %08X\n", t);
306 t = sw_read_reg(SWITCH_REG_BW_CNTL1);
307 SW_DBG("bw_cntl1: %08X\n", t);
308
309 t = sw_read_reg(SWITCH_REG_PHY_CNTL0);
310 SW_DBG("phy_cntl0: %08X\n", t);
311 t = sw_read_reg(SWITCH_REG_PHY_CNTL1);
312 SW_DBG("phy_cntl1: %08X\n", t);
313 t = sw_read_reg(SWITCH_REG_PHY_CNTL2);
314 SW_DBG("phy_cntl2: %08X\n", t);
315 t = sw_read_reg(SWITCH_REG_PHY_CNTL3);
316 SW_DBG("phy_cntl3: %08X\n", t);
317 t = sw_read_reg(SWITCH_REG_PHY_CNTL4);
318 SW_DBG("phy_cntl4: %08X\n", t);
319
320 t = sw_read_reg(SWITCH_REG_INT_STATUS);
321 sw_dump_intr_mask("int_status: ", t);
322
323 t = sw_read_reg(SWITCH_REG_INT_MASK);
324 sw_dump_intr_mask("int_mask: ", t);
325
326 t = sw_read_reg(SWITCH_REG_SHDA);
327 SW_DBG("shda: %08X\n", t);
328 t = sw_read_reg(SWITCH_REG_SLDA);
329 SW_DBG("slda: %08X\n", t);
330 t = sw_read_reg(SWITCH_REG_RHDA);
331 SW_DBG("rhda: %08X\n", t);
332 t = sw_read_reg(SWITCH_REG_RLDA);
333 SW_DBG("rlda: %08X\n", t);
334 }
335
336
337 /* ------------------------------------------------------------------------ */
338
339 static inline void adm5120_rx_dma_update(struct dma_desc *desc,
340 struct sk_buff *skb, int end)
341 {
342 desc->misc = 0;
343 desc->buf2 = 0;
344 desc->buflen = RX_MAX_PKTLEN;
345 desc->buf1 = DESC_ADDR(skb->data) |
346 DESC_OWN | (end ? DESC_EOR : 0);
347 }
348
349 static void adm5120_switch_rx_refill(void)
350 {
351 unsigned int entry;
352
353 for (; cur_rxl - dirty_rxl > 0; dirty_rxl++) {
354 struct dma_desc *desc;
355 struct sk_buff *skb;
356
357 entry = dirty_rxl % RX_RING_SIZE;
358 desc = &rxl_descs[entry];
359
360 skb = rxl_skbuff[entry];
361 if (skb == NULL) {
362 skb = alloc_skb(SKB_ALLOC_LEN, GFP_ATOMIC);
363 if (skb) {
364 skb_reserve(skb, SKB_RESERVE_LEN);
365 rxl_skbuff[entry] = skb;
366 } else {
367 SW_ERR("no memory for skb\n");
368 desc->buflen = 0;
369 desc->buf2 = 0;
370 desc->misc = 0;
371 desc->buf1 = (desc->buf1 & DESC_EOR) | DESC_OWN;
372 break;
373 }
374 }
375
376 desc->buf2 = 0;
377 desc->buflen = RX_MAX_PKTLEN;
378 desc->misc = 0;
379 desc->buf1 = (desc->buf1 & DESC_EOR) | DESC_OWN |
380 DESC_ADDR(skb->data);
381 }
382 }
383
384 static int adm5120_switch_rx(int limit)
385 {
386 unsigned int done = 0;
387
388 SW_DBG("rx start, limit=%d, cur_rxl=%u, dirty_rxl=%u\n",
389 limit, cur_rxl, dirty_rxl);
390
391 while (done < limit) {
392 int entry = cur_rxl % RX_RING_SIZE;
393 struct dma_desc *desc = &rxl_descs[entry];
394 struct net_device *rdev;
395 unsigned int port;
396
397 if (desc->buf1 & DESC_OWN)
398 break;
399
400 if (dirty_rxl + RX_RING_SIZE == cur_rxl)
401 break;
402
403 port = desc_get_srcport(desc);
404 rdev = adm5120_port[port];
405
406 SW_DBG("rx descriptor %u, desc=%p, skb=%p\n", entry, desc,
407 rxl_skbuff[entry]);
408
409 if ((rdev) && netif_running(rdev)) {
410 struct sk_buff *skb = rxl_skbuff[entry];
411 int pktlen;
412
413 pktlen = desc_get_pktlen(desc);
414 pktlen -= ETH_CSUM_LEN;
415
416 if ((pktlen == 0) || desc_ipcsum_fail(desc)) {
417 rdev->stats.rx_errors++;
418 if (pktlen == 0)
419 rdev->stats.rx_length_errors++;
420 if (desc_ipcsum_fail(desc))
421 rdev->stats.rx_crc_errors++;
422 SW_DBG("rx error, recycling skb %u\n", entry);
423 } else {
424 skb_put(skb, pktlen);
425
426 skb->dev = rdev;
427 skb->protocol = eth_type_trans(skb, rdev);
428 skb->ip_summed = CHECKSUM_UNNECESSARY;
429
430 dma_cache_wback_inv((unsigned long)skb->data,
431 skb->len);
432
433 #ifdef CONFIG_ADM5120_SWITCH_USE_NAPI
434 netif_receive_skb(skb);
435 #else
436 netif_rx(skb);
437 #endif
438
439 rdev->last_rx = jiffies;
440 rdev->stats.rx_packets++;
441 rdev->stats.rx_bytes += pktlen;
442
443 rxl_skbuff[entry] = NULL;
444 done++;
445 }
446 } else {
447 SW_DBG("no rx device, recycling skb %u\n", entry);
448 }
449
450 cur_rxl++;
451 if (cur_rxl - dirty_rxl > RX_RING_SIZE / 4)
452 adm5120_switch_rx_refill();
453 }
454
455 adm5120_switch_rx_refill();
456
457 SW_DBG("rx finished, cur_rxl=%u, dirty_rxl=%u, processed %d\n",
458 cur_rxl, dirty_rxl, done);
459
460 return done;
461 }
462
463 static void adm5120_switch_tx(void)
464 {
465 unsigned int entry;
466
467 spin_lock(&tx_lock);
468 entry = dirty_txl % TX_RING_SIZE;
469 while (dirty_txl != cur_txl) {
470 struct dma_desc *desc = &txl_descs[entry];
471 struct sk_buff *skb = txl_skbuff[entry];
472
473 if (desc->buf1 & DESC_OWN)
474 break;
475
476 if (netif_running(skb->dev)) {
477 skb->dev->stats.tx_bytes += skb->len;
478 skb->dev->stats.tx_packets++;
479 }
480
481 dev_kfree_skb_irq(skb);
482 txl_skbuff[entry] = NULL;
483 entry = (++dirty_txl) % TX_RING_SIZE;
484 }
485
486 if ((cur_txl - dirty_txl) < TX_QUEUE_LEN - 4) {
487 int i;
488 for (i = 0; i < SWITCH_NUM_PORTS; i++) {
489 if (!adm5120_devs[i])
490 continue;
491 netif_wake_queue(adm5120_devs[i]);
492 }
493 }
494 spin_unlock(&tx_lock);
495 }
496
497 #ifdef CONFIG_ADM5120_SWITCH_NAPI
498 static int adm5120_if_poll(struct net_device *dev, int *budget)
499 {
500 int limit = min(dev->quota, *budget);
501 int done;
502 u32 status;
503
504 sw_int_ack(SWITCH_INTS_POLL);
505
506 SW_DBG("%s: processing TX ring\n", dev->name);
507 adm5120_switch_tx();
508
509 SW_DBG("%s: processing RX ring\n", dev->name);
510 done = adm5120_switch_rx(limit);
511
512 *budget -= done;
513 dev->quota -= done;
514
515 status = sw_int_status() & SWITCH_INTS_POLL;
516 if ((done < limit) && (!status)) {
517 SW_DBG("disable polling mode for %s\n", dev->name);
518 netif_rx_complete(dev);
519 sw_int_unmask(SWITCH_INTS_POLL);
520 return 0;
521 }
522
523 SW_DBG("%s still in polling mode, done=%d, status=%x\n",
524 dev->name, done, status);
525 return 1;
526 }
527 #endif /* CONFIG_ADM5120_SWITCH_USE_NAPI */
528
529
530 static irqreturn_t adm5120_switch_irq(int irq, void *dev_id)
531 {
532 u32 status;
533
534 status = sw_int_status();
535 status &= SWITCH_INTS_ALL;
536 if (!status)
537 return IRQ_NONE;
538
539 #ifdef CONFIG_ADM5120_SWITCH_NAPI
540 sw_int_ack(status & ~SWITCH_INTS_POLL);
541
542 if (status & SWITCH_INTS_POLL) {
543 struct net_device *dev = dev_id;
544 sw_dump_intr_mask("poll ints", status);
545 SW_DBG("enable polling mode for %s\n", dev->name);
546 sw_int_mask(SWITCH_INTS_POLL);
547 netif_rx_schedule(dev);
548 }
549 #else
550 sw_int_ack(status);
551
552 if (status & (SWITCH_INT_RLD | SWITCH_INT_LDF)) {
553 adm5120_switch_rx(RX_RING_SIZE);
554 }
555
556 if (status & SWITCH_INT_SLD) {
557 adm5120_switch_tx();
558 }
559 #endif
560
561 return IRQ_HANDLED;
562 }
563
564 static void adm5120_set_bw(char *matrix)
565 {
566 unsigned long val;
567
568 /* Port 0 to 3 are set using the bandwidth control 0 register */
569 val = matrix[0] + (matrix[1]<<8) + (matrix[2]<<16) + (matrix[3]<<24);
570 sw_write_reg(SWITCH_REG_BW_CNTL0, val);
571
572 /* Port 4 and 5 are set using the bandwidth control 1 register */
573 val = matrix[4];
574 if (matrix[5] == 1)
575 sw_write_reg(SWITCH_REG_BW_CNTL1, val | 0x80000000);
576 else
577 sw_write_reg(SWITCH_REG_BW_CNTL1, val & ~0x8000000);
578
579 SW_DBG("D: ctl0 0x%ux, ctl1 0x%ux\n", sw_read_reg(SWITCH_REG_BW_CNTL0),
580 sw_read_reg(SWITCH_REG_BW_CNTL1));
581 }
582
583 static void adm5120_switch_tx_ring_reset(struct dma_desc *desc,
584 struct sk_buff **skbl, int num)
585 {
586 memset(desc, 0, num * sizeof(*desc));
587 desc[num-1].buf1 |= DESC_EOR;
588 memset(skbl, 0, sizeof(struct skb*)*num);
589
590 cur_txl = 0;
591 dirty_txl = 0;
592 }
593
594 static void adm5120_switch_rx_ring_reset(struct dma_desc *desc,
595 struct sk_buff **skbl, int num)
596 {
597 int i;
598
599 memset(desc, 0, num * sizeof(*desc));
600 for (i = 0; i < num; i++) {
601 skbl[i] = dev_alloc_skb(SKB_ALLOC_LEN);
602 if (!skbl[i]) {
603 i = num;
604 break;
605 }
606 skb_reserve(skbl[i], SKB_RESERVE_LEN);
607 adm5120_rx_dma_update(&desc[i], skbl[i], (num-1==i));
608 }
609
610 cur_rxl = 0;
611 dirty_rxl = 0;
612 }
613
614 static int adm5120_switch_tx_ring_alloc(void)
615 {
616 int err;
617
618 txl_descs = dma_alloc_coherent(NULL, TX_DESCS_SIZE, &txl_descs_dma,
619 GFP_ATOMIC);
620 if (!txl_descs) {
621 err = -ENOMEM;
622 goto err;
623 }
624
625 txl_skbuff = kzalloc(TX_SKBS_SIZE, GFP_KERNEL);
626 if (!txl_skbuff) {
627 err = -ENOMEM;
628 goto err;
629 }
630
631 return 0;
632
633 err:
634 return err;
635 }
636
637 static void adm5120_switch_tx_ring_free(void)
638 {
639 int i;
640
641 if (txl_skbuff) {
642 for (i = 0; i < TX_RING_SIZE; i++)
643 if (txl_skbuff[i])
644 kfree_skb(txl_skbuff[i]);
645 kfree(txl_skbuff);
646 }
647
648 if (txl_descs)
649 dma_free_coherent(NULL, TX_DESCS_SIZE, txl_descs,
650 txl_descs_dma);
651 }
652
653 static int adm5120_switch_rx_ring_alloc(void)
654 {
655 int err;
656 int i;
657
658 /* init RX ring */
659 rxl_descs = dma_alloc_coherent(NULL, RX_DESCS_SIZE, &rxl_descs_dma,
660 GFP_ATOMIC);
661 if (!rxl_descs) {
662 err = -ENOMEM;
663 goto err;
664 }
665
666 rxl_skbuff = kzalloc(RX_SKBS_SIZE, GFP_KERNEL);
667 if (!rxl_skbuff) {
668 err = -ENOMEM;
669 goto err;
670 }
671
672 for (i = 0; i < RX_RING_SIZE; i++) {
673 struct sk_buff *skb;
674 skb = alloc_skb(SKB_ALLOC_LEN, GFP_ATOMIC);
675 if (!skb) {
676 err = -ENOMEM;
677 goto err;
678 }
679 rxl_skbuff[i] = skb;
680 skb_reserve(skb, SKB_RESERVE_LEN);
681 }
682
683 return 0;
684
685 err:
686 return err;
687 }
688
689 static void adm5120_switch_rx_ring_free(void)
690 {
691 int i;
692
693 if (rxl_skbuff) {
694 for (i = 0; i < RX_RING_SIZE; i++)
695 if (rxl_skbuff[i])
696 kfree_skb(rxl_skbuff[i]);
697 kfree(rxl_skbuff);
698 }
699
700 if (rxl_descs)
701 dma_free_coherent(NULL, RX_DESCS_SIZE, rxl_descs,
702 rxl_descs_dma);
703 }
704
705 static void adm5120_write_mac(struct net_device *dev)
706 {
707 struct adm5120_if_priv *priv = netdev_priv(dev);
708 unsigned char *mac = dev->dev_addr;
709 u32 t;
710
711 t = mac[2] | (mac[3] << MAC_WT1_MAC3_SHIFT) |
712 (mac[4] << MAC_WT1_MAC4_SHIFT) | (mac[5] << MAC_WT1_MAC5_SHIFT);
713 sw_write_reg(SWITCH_REG_MAC_WT1, t);
714
715 t = (mac[0] << MAC_WT0_MAC0_SHIFT) | (mac[1] << MAC_WT0_MAC1_SHIFT) |
716 MAC_WT0_MAWC | MAC_WT0_WVE | (priv->vlan_no<<3);
717
718 sw_write_reg(SWITCH_REG_MAC_WT0, t);
719
720 while (!(sw_read_reg(SWITCH_REG_MAC_WT0) & MAC_WT0_MWD));
721 }
722
723 static void adm5120_set_vlan(char *matrix)
724 {
725 unsigned long val;
726 int vlan_port, port;
727
728 val = matrix[0] + (matrix[1]<<8) + (matrix[2]<<16) + (matrix[3]<<24);
729 sw_write_reg(SWITCH_REG_VLAN_G1, val);
730 val = matrix[4] + (matrix[5]<<8);
731 sw_write_reg(SWITCH_REG_VLAN_G2, val);
732
733 /* Now set/update the port vs. device lookup table */
734 for (port=0; port<SWITCH_NUM_PORTS; port++) {
735 for (vlan_port=0; vlan_port<SWITCH_NUM_PORTS && !(matrix[vlan_port] & (0x00000001 << port)); vlan_port++);
736 if (vlan_port <SWITCH_NUM_PORTS)
737 adm5120_port[port] = adm5120_devs[vlan_port];
738 else
739 adm5120_port[port] = NULL;
740 }
741 }
742
743 static void adm5120_switch_set_vlan_mac(unsigned int vlan, unsigned char *mac)
744 {
745 u32 t;
746
747 t = mac[2] | (mac[3] << MAC_WT1_MAC3_SHIFT)
748 | (mac[4] << MAC_WT1_MAC4_SHIFT)
749 | (mac[5] << MAC_WT1_MAC5_SHIFT);
750 sw_write_reg(SWITCH_REG_MAC_WT1, t);
751
752 t = (mac[0] << MAC_WT0_MAC0_SHIFT) | (mac[1] << MAC_WT0_MAC1_SHIFT) |
753 MAC_WT0_MAWC | MAC_WT0_WVE | (vlan << MAC_WT0_WVN_SHIFT) |
754 (MAC_WT0_WAF_STATIC << MAC_WT0_WAF_SHIFT);
755 sw_write_reg(SWITCH_REG_MAC_WT0, t);
756
757 do {
758 t = sw_read_reg(SWITCH_REG_MAC_WT0);
759 } while ((t & MAC_WT0_MWD) == 0);
760 }
761
762 static void adm5120_switch_set_vlan_ports(unsigned int vlan, u32 ports)
763 {
764 unsigned int reg;
765 u32 t;
766
767 if (vlan < 4)
768 reg = SWITCH_REG_VLAN_G1;
769 else {
770 vlan -= 4;
771 reg = SWITCH_REG_VLAN_G2;
772 }
773
774 t = sw_read_reg(reg);
775 t &= ~(0xFF << (vlan*8));
776 t |= (ports << (vlan*8));
777 sw_write_reg(reg, t);
778 }
779
780 /* ------------------------------------------------------------------------ */
781
782 static int adm5120_if_open(struct net_device *dev)
783 {
784 u32 t;
785 int err;
786 int i;
787
788 err = request_irq(dev->irq, adm5120_switch_irq,
789 (IRQF_SHARED | IRQF_DISABLED), dev->name, dev);
790 if (err) {
791 SW_ERR("unable to get irq for %s\n", dev->name);
792 goto err;
793 }
794
795 if (!sw_used++)
796 /* enable interrupts on first open */
797 sw_int_unmask(SWITCH_INTS_USED);
798
799 /* enable (additional) port */
800 t = sw_read_reg(SWITCH_REG_PORT_CONF0);
801 for (i = 0; i < SWITCH_NUM_PORTS; i++) {
802 if (dev == adm5120_devs[i])
803 t &= ~adm5120_eth_vlans[i];
804 }
805 sw_write_reg(SWITCH_REG_PORT_CONF0, t);
806
807 netif_start_queue(dev);
808
809 return 0;
810
811 err:
812 return err;
813 }
814
815 static int adm5120_if_stop(struct net_device *dev)
816 {
817 u32 t;
818 int i;
819
820 netif_stop_queue(dev);
821
822 /* disable port if not assigned to other devices */
823 t = sw_read_reg(SWITCH_REG_PORT_CONF0);
824 t |= SWITCH_PORTS_NOCPU;
825 for (i = 0; i < SWITCH_NUM_PORTS; i++) {
826 if ((dev != adm5120_devs[i]) && netif_running(adm5120_devs[i]))
827 t &= ~adm5120_eth_vlans[i];
828 }
829 sw_write_reg(SWITCH_REG_PORT_CONF0, t);
830
831 if (!--sw_used)
832 sw_int_mask(SWITCH_INTS_USED);
833
834 free_irq(dev->irq, dev);
835
836 return 0;
837 }
838
839 static int adm5120_if_hard_start_xmit(struct sk_buff *skb,
840 struct net_device *dev)
841 {
842 struct dma_desc *desc;
843 struct adm5120_if_priv *priv = netdev_priv(dev);
844 unsigned int entry;
845 unsigned long data;
846 int i;
847
848 /* lock switch irq */
849 spin_lock_irq(&tx_lock);
850
851 /* calculate the next TX descriptor entry. */
852 entry = cur_txl % TX_RING_SIZE;
853
854 desc = &txl_descs[entry];
855 if (desc->buf1 & DESC_OWN) {
856 /* We want to write a packet but the TX queue is still
857 * occupied by the DMA. We are faster than the DMA... */
858 SW_DBG("%s unable to transmit, packet dopped\n", dev->name);
859 dev_kfree_skb(skb);
860 dev->stats.tx_dropped++;
861 return 0;
862 }
863
864 txl_skbuff[entry] = skb;
865 data = (desc->buf1 & DESC_EOR);
866 data |= DESC_ADDR(skb->data);
867
868 desc->misc =
869 ((skb->len<ETH_ZLEN?ETH_ZLEN:skb->len) << DESC_PKTLEN_SHIFT) |
870 (0x1 << priv->vlan_no);
871
872 desc->buflen = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
873
874 desc->buf1 = data | DESC_OWN;
875 sw_write_reg(SWITCH_REG_SEND_TRIG, SEND_TRIG_STL);
876
877 cur_txl++;
878 if (cur_txl == dirty_txl + TX_QUEUE_LEN) {
879 for (i = 0; i < SWITCH_NUM_PORTS; i++) {
880 if (!adm5120_devs[i])
881 continue;
882 netif_stop_queue(adm5120_devs[i]);
883 }
884 }
885
886 dev->trans_start = jiffies;
887
888 spin_unlock_irq(&tx_lock);
889
890 return 0;
891 }
892
893 static void adm5120_if_tx_timeout(struct net_device *dev)
894 {
895 SW_INFO("TX timeout on %s\n",dev->name);
896 }
897
898 static void adm5120_if_set_multicast_list(struct net_device *dev)
899 {
900 struct adm5120_if_priv *priv = netdev_priv(dev);
901 u32 ports;
902 u32 t;
903
904 ports = adm5120_eth_vlans[priv->vlan_no] & SWITCH_PORTS_NOCPU;
905
906 t = sw_read_reg(SWITCH_REG_CPUP_CONF);
907 if (dev->flags & IFF_PROMISC)
908 /* enable unknown packets */
909 t &= ~(ports << CPUP_CONF_DUNP_SHIFT);
910 else
911 /* disable unknown packets */
912 t |= (ports << CPUP_CONF_DUNP_SHIFT);
913
914 if (dev->flags & IFF_PROMISC || dev->flags & IFF_ALLMULTI ||
915 dev->mc_count)
916 /* enable multicast packets */
917 t &= ~(ports << CPUP_CONF_DMCP_SHIFT);
918 else
919 /* disable multicast packets */
920 t |= (ports << CPUP_CONF_DMCP_SHIFT);
921
922 /* If there is any port configured to be in promiscuous mode, then the */
923 /* Bridge Test Mode has to be activated. This will result in */
924 /* transporting also packets learned in another VLAN to be forwarded */
925 /* to the CPU. */
926 /* The difficult scenario is when we want to build a bridge on the CPU.*/
927 /* Assume we have port0 and the CPU port in VLAN0 and port1 and the */
928 /* CPU port in VLAN1. Now we build a bridge on the CPU between */
929 /* VLAN0 and VLAN1. Both ports of the VLANs are set in promisc mode. */
930 /* Now assume a packet with ethernet source address 99 enters port 0 */
931 /* It will be forwarded to the CPU because it is unknown. Then the */
932 /* bridge in the CPU will send it to VLAN1 and it goes out at port 1. */
933 /* When now a packet with ethernet destination address 99 comes in at */
934 /* port 1 in VLAN1, then the switch has learned that this address is */
935 /* located at port 0 in VLAN0. Therefore the switch will drop */
936 /* this packet. In order to avoid this and to send the packet still */
937 /* to the CPU, the Bridge Test Mode has to be activated. */
938
939 /* Check if there is any vlan in promisc mode. */
940 if (t & (SWITCH_PORTS_NOCPU << CPUP_CONF_DUNP_SHIFT))
941 t &= ~CPUP_CONF_BTM; /* Disable Bridge Testing Mode */
942 else
943 t |= CPUP_CONF_BTM; /* Enable Bridge Testing Mode */
944
945 sw_write_reg(SWITCH_REG_CPUP_CONF, t);
946
947 }
948
949 static int adm5120_if_set_mac_address(struct net_device *dev, void *p)
950 {
951 struct sockaddr *addr = p;
952
953 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
954 adm5120_write_mac(dev);
955 return 0;
956 }
957
958 static int adm5120_if_do_ioctl(struct net_device *dev, struct ifreq *rq,
959 int cmd)
960 {
961 int err;
962 struct adm5120_sw_info info;
963 struct adm5120_if_priv *priv = netdev_priv(dev);
964
965 switch(cmd) {
966 case SIOCGADMINFO:
967 info.magic = 0x5120;
968 info.ports = adm5120_nrdevs;
969 info.vlan = priv->vlan_no;
970 err = copy_to_user(rq->ifr_data, &info, sizeof(info));
971 if (err)
972 return -EFAULT;
973 break;
974 case SIOCSMATRIX:
975 if (!capable(CAP_NET_ADMIN))
976 return -EPERM;
977 err = copy_from_user(adm5120_eth_vlans, rq->ifr_data,
978 sizeof(adm5120_eth_vlans));
979 if (err)
980 return -EFAULT;
981 adm5120_set_vlan(adm5120_eth_vlans);
982 break;
983 case SIOCGMATRIX:
984 err = copy_to_user(rq->ifr_data, adm5120_eth_vlans,
985 sizeof(adm5120_eth_vlans));
986 if (err)
987 return -EFAULT;
988 break;
989 default:
990 return -EOPNOTSUPP;
991 }
992 return 0;
993 }
994
995 static struct net_device *adm5120_if_alloc(void)
996 {
997 struct net_device *dev;
998 struct adm5120_if_priv *priv;
999
1000 dev = alloc_etherdev(sizeof(*priv));
1001 if (!dev)
1002 return NULL;
1003
1004 dev->irq = ADM5120_IRQ_SWITCH;
1005 dev->open = adm5120_if_open;
1006 dev->hard_start_xmit = adm5120_if_hard_start_xmit;
1007 dev->stop = adm5120_if_stop;
1008 dev->set_multicast_list = adm5120_if_set_multicast_list;
1009 dev->do_ioctl = adm5120_if_do_ioctl;
1010 dev->tx_timeout = adm5120_if_tx_timeout;
1011 dev->watchdog_timeo = TX_TIMEOUT;
1012 dev->set_mac_address = adm5120_if_set_mac_address;
1013 #ifdef CONFIG_ADM5120_SWITCH_NAPI
1014 dev->poll = adm5120_if_poll;
1015 dev->weight = 64;
1016 #endif
1017
1018 SET_MODULE_OWNER(dev);
1019
1020 return dev;
1021 }
1022
1023 /* ------------------------------------------------------------------------ */
1024
1025 static void adm5120_switch_cleanup(void)
1026 {
1027 int i;
1028
1029 /* disable interrupts */
1030 sw_int_mask(SWITCH_INTS_ALL);
1031
1032 for (i = 0; i < SWITCH_NUM_PORTS; i++) {
1033 struct net_device *dev = adm5120_devs[i];
1034 if (dev) {
1035 unregister_netdev(dev);
1036 free_netdev(dev);
1037 }
1038 }
1039
1040 adm5120_switch_tx_ring_free();
1041 adm5120_switch_rx_ring_free();
1042 }
1043
1044 static int __init adm5120_switch_probe(struct platform_device *pdev)
1045 {
1046 u32 t;
1047 int i, err;
1048
1049 adm5120_nrdevs = adm5120_eth_num_ports;
1050
1051 t = CPUP_CONF_DCPUP | CPUP_CONF_CRCP |
1052 SWITCH_PORTS_NOCPU << CPUP_CONF_DUNP_SHIFT |
1053 SWITCH_PORTS_NOCPU << CPUP_CONF_DMCP_SHIFT ;
1054 sw_write_reg(SWITCH_REG_CPUP_CONF, t);
1055
1056 t = (SWITCH_PORTS_NOCPU << PORT_CONF0_EMCP_SHIFT) |
1057 (SWITCH_PORTS_NOCPU << PORT_CONF0_BP_SHIFT) |
1058 (SWITCH_PORTS_NOCPU);
1059 sw_write_reg(SWITCH_REG_PORT_CONF0, t);
1060
1061 /* setup ports to Autoneg/100M/Full duplex/Auto MDIX */
1062 t = SWITCH_PORTS_PHY |
1063 (SWITCH_PORTS_PHY << PHY_CNTL2_SC_SHIFT) |
1064 (SWITCH_PORTS_PHY << PHY_CNTL2_DC_SHIFT) |
1065 (SWITCH_PORTS_PHY << PHY_CNTL2_PHYR_SHIFT) |
1066 (SWITCH_PORTS_PHY << PHY_CNTL2_AMDIX_SHIFT) |
1067 PHY_CNTL2_RMAE;
1068 sw_write_reg(SWITCH_REG_PHY_CNTL2, t);
1069
1070 t = sw_read_reg(SWITCH_REG_PHY_CNTL3);
1071 t |= PHY_CNTL3_RNT;
1072 sw_write_reg(SWITCH_REG_PHY_CNTL3, t);
1073
1074 /* Force all the packets from all ports are low priority */
1075 sw_write_reg(SWITCH_REG_PRI_CNTL, 0);
1076
1077 sw_int_mask(SWITCH_INTS_ALL);
1078 sw_int_ack(SWITCH_INTS_ALL);
1079
1080 err = adm5120_switch_rx_ring_alloc();
1081 if (err)
1082 goto err;
1083
1084 err = adm5120_switch_tx_ring_alloc();
1085 if (err)
1086 goto err;
1087
1088 adm5120_switch_tx_ring_reset(txl_descs, txl_skbuff, TX_RING_SIZE);
1089 adm5120_switch_rx_ring_reset(rxl_descs, rxl_skbuff, RX_RING_SIZE);
1090
1091 sw_write_reg(SWITCH_REG_SHDA, 0);
1092 sw_write_reg(SWITCH_REG_SLDA, KSEG1ADDR(txl_descs));
1093 sw_write_reg(SWITCH_REG_RHDA, 0);
1094 sw_write_reg(SWITCH_REG_RLDA, KSEG1ADDR(rxl_descs));
1095
1096 for (i = 0; i < SWITCH_NUM_PORTS; i++) {
1097 struct net_device *dev;
1098 struct adm5120_if_priv *priv;
1099
1100 dev = adm5120_if_alloc();
1101 if (!dev) {
1102 err = -ENOMEM;
1103 goto err;
1104 }
1105
1106 adm5120_devs[i] = dev;
1107 priv = netdev_priv(dev);
1108
1109 priv->vlan_no = i;
1110 priv->port_mask = adm5120_eth_vlans[i];
1111
1112 memcpy(dev->dev_addr, adm5120_eth_macs[i], 6);
1113 adm5120_write_mac(dev);
1114
1115 err = register_netdev(dev);
1116 if (err) {
1117 SW_INFO("%s register failed, error=%d\n",
1118 dev->name, err);
1119 goto err;
1120 }
1121 }
1122
1123 /* setup vlan/port mapping after devs are filled up */
1124 adm5120_set_vlan(adm5120_eth_vlans);
1125
1126 /* enable CPU port */
1127 t = sw_read_reg(SWITCH_REG_CPUP_CONF);
1128 t &= ~CPUP_CONF_DCPUP;
1129 sw_write_reg(SWITCH_REG_CPUP_CONF, t);
1130
1131 return 0;
1132
1133 err:
1134 adm5120_switch_cleanup();
1135
1136 SW_ERR("init failed\n");
1137 return err;
1138 }
1139
1140 static int adm5120_switch_remove(struct platform_device *dev)
1141 {
1142 adm5120_switch_cleanup();
1143 return 0;
1144 }
1145
1146 static struct platform_driver adm5120_switch_driver = {
1147 .probe = adm5120_switch_probe,
1148 .remove = adm5120_switch_remove,
1149 .driver = {
1150 .name = DRV_NAME,
1151 },
1152 };
1153
1154 /* -------------------------------------------------------------------------- */
1155
1156 static int __init adm5120_switch_mod_init(void)
1157 {
1158 int err;
1159
1160 pr_info(DRV_DESC " version " DRV_VERSION "\n");
1161 err = platform_driver_register(&adm5120_switch_driver);
1162
1163 return err;
1164 }
1165
1166 static void __exit adm5120_switch_mod_exit(void)
1167 {
1168 platform_driver_unregister(&adm5120_switch_driver);
1169 }
1170
1171 module_init(adm5120_switch_mod_init);
1172 module_exit(adm5120_switch_mod_exit);
1173
1174 MODULE_LICENSE("GPL v2");
1175 MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
1176 MODULE_DESCRIPTION(DRV_DESC);
1177 MODULE_VERSION(DRV_VERSION);
This page took 0.118137 seconds and 5 git commands to generate.