1 /************************************************************************
4 * Infineon Technologies AG
5 * St. Martin Strasse 53; 81669 Muenchen; Germany
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
12 ************************************************************************/
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/errno.h>
17 #include <linux/types.h>
18 #include <linux/interrupt.h>
19 #include <linux/uaccess.h>
21 #include <linux/netdevice.h>
22 #include <linux/etherdevice.h>
24 #include <linux/tcp.h>
25 #include <linux/skbuff.h>
27 #include <linux/platform_device.h>
28 #include <linux/ethtool.h>
29 #include <linux/init.h>
30 #include <linux/module.h>
31 #include <linux/delay.h>
32 #include <asm/checksum.h>
34 #if 1 /** TODO: MOVE TO APPROPRIATE PLACE */
36 #define ETHERNET_PACKET_DMA_BUFFER_SIZE 0x600
37 #define REV_MII_MODE 2
41 #define DRV_NAME "ifxmips_mii0"
43 #include <lantiq_soc.h>
46 #ifdef CONFIG_DEBUG_MINI_BOOT
47 #define IKOS_MINI_BOOT
51 #undef INCAIP2_SW_DUMP
53 #define INCAIP2_SW_EMSG(fmt,args...) printk("%s: " fmt, __FUNCTION__ , ##args)
55 #define INCAIP2_SW_CHIP_NO 1
56 #define INCAIP2_SW_CHIP_ID 0
57 #define INCAIP2_SW_DEVICE_NO 1
59 #ifdef INCAIP2_SW_DEBUG_MSG
60 #define INCAIP2_SW_DMSG(fmt,args...) printk("%s: " fmt, __FUNCTION__ , ##args)
62 #define INCAIP2_SW_DMSG(fmt,args...)
65 /************************** Module Parameters *****************************/
66 static char *mode
= "bridge";
67 module_param(mode
, charp
, 0000);
68 MODULE_PARM_DESC(mode
, "<description>");
70 #ifdef HAVE_TX_TIMEOUT
71 static int timeout
= 10*HZ
;
72 module_param(timeout
, int, 0);
73 MODULE_PARM_DESC(timeout
, "Transmission watchdog timeout in seconds>");
78 extern s32
incaip2_sw_to_mbx(struct sk_buff
* skb
);
80 extern s32
svip_sw_to_mbx(struct sk_buff
* skb
);
83 struct svip_mii_priv
{
84 struct net_device_stats stats
;
85 struct dma_device_info
*dma_device
;
89 static struct net_device
*svip_mii0_dev
;
90 static unsigned char mac_addr
[MAX_ADDR_LEN
];
91 static unsigned char my_ethaddr
[MAX_ADDR_LEN
];
94 * Initialize MAC address.
95 * This function copies the ethernet address from kernel command line.
97 * \param line Pointer to parameter
101 static int __init
svip_eth_ethaddr_setup(char *line
)
106 memset(my_ethaddr
, 0, MAX_ADDR_LEN
);
107 /* there should really be routines to do this stuff */
108 for (i
= 0; i
< 6; i
++)
110 my_ethaddr
[i
] = line
? simple_strtoul(line
, &ep
, 16) : 0;
112 line
= (*ep
) ? ep
+1 : ep
;
114 INCAIP2_SW_DMSG("mac address %2x-%2x-%2x-%2x-%2x-%2x \n"
123 __setup("ethaddr=", svip_eth_ethaddr_setup
);
127 * Open RX DMA channels.
128 * This function opens all DMA rx channels.
130 * \param dma_dev pointer to DMA device information
133 static void svip_eth_open_rx_dma(struct dma_device_info
*dma_dev
)
137 for(i
=0; i
<dma_dev
->num_rx_chan
; i
++)
139 dma_dev
->rx_chan
[i
]->open(dma_dev
->rx_chan
[i
]);
145 * Open TX DMA channels.
146 * This function opens all DMA tx channels.
148 * \param dev pointer to net device structure that comprises
149 * DMA device information pointed to by it's priv field.
152 static void svip_eth_open_tx_dma(struct dma_device_info
*dma_dev
)
156 for (i
=0; i
<dma_dev
->num_tx_chan
; i
++)
158 dma_dev
->tx_chan
[i
]->open(dma_dev
->tx_chan
[i
]);
163 #ifdef CONFIG_NET_HW_FLOWCONTROL
165 * Enable receiving DMA.
166 * This function enables the receiving DMA channel.
168 * \param dev pointer to net device structure that comprises
169 * DMA device information pointed to by it's priv field.
172 void svip_eth_xon(struct net_device
*dev
)
174 struct switch_priv
*sw_dev
= (struct switch_priv
*)dev
->priv
;
175 struct dma_device_info
* dma_dev
=
176 (struct dma_device_info
*)sw_dev
->dma_device
;
179 local_irq_save(flag
);
181 INCAIP2_SW_DMSG("wakeup\n");
182 svip_eth_open_rx_dma(dma_dev
);
184 local_irq_restore(flag
);
186 #endif /* CONFIG_NET_HW_FLOWCONTROL */
190 * Open network device.
191 * This functions opens the network device and starts the interface queue.
193 * \param dev Device structure for Ethernet device
194 * \return 0 OK, device opened
195 * \return -1 Error, registering DMA device
198 int svip_mii_open(struct net_device
*dev
)
200 struct svip_mii_priv
*priv
= netdev_priv(dev
);
201 struct dma_device_info
*dma_dev
= priv
->dma_device
;
203 svip_eth_open_rx_dma(dma_dev
);
204 svip_eth_open_tx_dma(dma_dev
);
206 netif_start_queue(dev
);
212 * Close network device.
213 * This functions closes the network device, which will also stop the interface
216 * \param dev Device structure for Ethernet device
217 * \return 0 OK, device closed (cannot fail)
220 int svip_mii_release(struct net_device
*dev
)
222 struct svip_mii_priv
*priv
= netdev_priv(dev
);
223 struct dma_device_info
*dma_dev
= priv
->dma_device
;
226 for (i
= 0; i
< dma_dev
->max_rx_chan_num
; i
++)
227 dma_dev
->rx_chan
[i
]->close(dma_dev
->rx_chan
[i
]);
228 netif_stop_queue(dev
);
234 * Read data from DMA device.
235 * This function reads data from the DMA device. The function is called by
236 * the switch/DMA pseudo interrupt handler dma_intr_handler on occurence of
237 * a DMA receive interrupt.
239 * \param dev Pointer to network device structure
240 * \param dma_dev Pointer to dma device structure
241 * \return OK In case of successful data reception from dma
242 * -EIO Incorrect opt pointer provided by device
245 int svip_mii_hw_receive(struct net_device
*dev
, struct dma_device_info
*dma_dev
)
247 struct svip_mii_priv
*priv
= netdev_priv(dev
);
248 unsigned char *buf
= NULL
;
249 struct sk_buff
*skb
= NULL
;
252 len
= dma_device_read(dma_dev
, &buf
, (void **)&skb
);
254 if (len
>= ETHERNET_PACKET_DMA_BUFFER_SIZE
) {
255 printk(KERN_INFO DRV_NAME
": packet too large %d\n", len
);
256 goto mii_hw_receive_err_exit
;
260 printk(KERN_INFO DRV_NAME
": cannot restore pointer\n");
261 goto mii_hw_receive_err_exit
;
264 if (len
> (skb
->end
- skb
->tail
)) {
265 printk(KERN_INFO DRV_NAME
": BUG, len:%d end:%p tail:%p\n",
266 len
, skb
->end
, skb
->tail
);
267 goto mii_hw_receive_err_exit
;
272 skb
->protocol
= eth_type_trans(skb
, dev
);
275 priv
->stats
.rx_packets
++;
276 priv
->stats
.rx_bytes
+= len
;
279 mii_hw_receive_err_exit
:
282 dev_kfree_skb_any(skb
);
283 priv
->stats
.rx_errors
++;
284 priv
->stats
.rx_dropped
++;
293 * Write data to Ethernet switch.
294 * This function writes the data comprised in skb structure via DMA to the
295 * Ethernet Switch. It is installed as the switch driver's hard_start_xmit
298 * \param skb Pointer to socket buffer structure that contains the data
300 * \param dev Pointer to network device structure which is used for
302 * \return 1 Transmission error
303 * \return 0 OK, successful data transmission
306 static int svip_mii_hw_tx(char *buf
, int len
, struct net_device
*dev
)
309 struct svip_mii_priv
*priv
= netdev_priv(dev
);
310 struct dma_device_info
*dma_dev
= priv
->dma_device
;
311 ret
= dma_device_write(dma_dev
, buf
, len
, priv
->skb
);
315 static int svip_mii_tx(struct sk_buff
*skb
, struct net_device
*dev
)
319 struct svip_mii_priv
*priv
= netdev_priv(dev
);
320 struct dma_device_info
*dma_dev
= priv
->dma_device
;
322 len
= skb
->len
< ETH_ZLEN
? ETH_ZLEN
: skb
->len
;
325 dev
->trans_start
= jiffies
;
326 /* TODO: we got more than 1 dma channel,
327 so we should do something intelligent here to select one */
328 dma_dev
->current_tx_chan
= 0;
332 if (svip_mii_hw_tx(data
, len
, dev
) != len
) {
333 dev_kfree_skb_any(skb
);
334 priv
->stats
.tx_errors
++;
335 priv
->stats
.tx_dropped
++;
337 priv
->stats
.tx_packets
++;
338 priv
->stats
.tx_bytes
+= len
;
346 * Transmission timeout callback.
347 * This functions is called when a trasmission timeout occurs. It will wake up
348 * the interface queue again.
350 * \param dev Device structure for Ethernet device
353 void svip_mii_tx_timeout(struct net_device
*dev
)
356 struct svip_mii_priv
*priv
= netdev_priv(dev
);
358 priv
->stats
.tx_errors
++;
359 for (i
= 0; i
< priv
->dma_device
->max_tx_chan_num
; i
++)
360 priv
->dma_device
->tx_chan
[i
]->disable_irq(priv
->dma_device
->tx_chan
[i
]);
361 netif_wake_queue(dev
);
367 * Get device statistics.
368 * This functions returns the device statistics, stored in the device structure.
370 * \param dev Device structure for Ethernet device
371 * \return stats Pointer to statistics structure
374 static struct net_device_stats
*svip_get_stats(struct net_device
*dev
)
376 struct svip_mii_priv
*priv
= netdev_priv(dev
);
382 * Pseudo Interrupt handler for DMA.
383 * This function processes DMA interrupts notified to the switch device driver.
384 * The function is installed at the DMA core as interrupt handler for the
386 * It handles the following DMA interrupts:
387 * passes received data to the upper layer in case of rx interrupt,
388 * In case of a dma receive interrupt the received data is passed to the upper layer.
389 * In case of a transmit buffer full interrupt the transmit queue is stopped.
390 * In case of a transmission complete interrupt the transmit queue is restarted.
392 * \param dma_dev pointer to dma device structure
393 * \param status type of interrupt being notified (RCV_INT: dma receive
394 * interrupt, TX_BUF_FULL_INT: transmit buffer full interrupt,
395 * TRANSMIT_CPT_INT: transmission complete interrupt)
396 * \return OK In case of successful data reception from dma
399 int dma_intr_handler(struct dma_device_info
*dma_dev
, int status
)
405 svip_mii_hw_receive(svip_mii0_dev
, dma_dev
);
408 case TX_BUF_FULL_INT
:
409 printk(KERN_INFO DRV_NAME
": tx buffer full\n");
410 netif_stop_queue(svip_mii0_dev
);
411 for (i
= 0; i
< dma_dev
->max_tx_chan_num
; i
++) {
412 if ((dma_dev
->tx_chan
[i
])->control
== LTQ_DMA_CH_ON
)
413 dma_dev
->tx_chan
[i
]->enable_irq(dma_dev
->tx_chan
[i
]);
417 case TRANSMIT_CPT_INT
:
420 for (i
= 0; i
< dma_dev
->max_tx_chan_num
; i
++)
422 dma_dev
->tx_chan
[i
]->disable_irq(dma_dev
->tx_chan
[i
]);
424 dma_dev
->tx_chan
[i
]->disable_irq(dma_dev
->tx_chan
[i
], (char *)__FUNCTION__
);
426 netif_wake_queue(svip_mii0_dev
);
436 * Allocates buffer sufficient for Ethernet Frame.
437 * This function is installed as DMA callback function to be called on DMA
441 * \param *byte_offset Pointer to byte offset
442 * \param **opt pointer to skb structure
443 * \return NULL In case of buffer allocation fails
444 * buffer Pointer to allocated memory
447 unsigned char *svip_etop_dma_buffer_alloc(int len
, int *byte_offset
, void **opt
)
449 unsigned char *buffer
= NULL
;
450 struct sk_buff
*skb
= NULL
;
452 skb
= dev_alloc_skb(ETHERNET_PACKET_DMA_BUFFER_SIZE
);
456 buffer
= (unsigned char *)(skb
->data
);
458 *(int *)opt
= (int)skb
;
467 * This function frees a buffer, which can be either a data buffer or an
470 * \param *dataptr Pointer to data buffer
471 * \param *opt Pointer to skb structure
475 void svip_etop_dma_buffer_free(unsigned char *dataptr
, void *opt
)
477 struct sk_buff
*skb
= NULL
;
482 skb
= (struct sk_buff
*)opt
;
483 dev_kfree_skb_any(skb
);
487 static int svip_mii_dev_init(struct net_device
*dev
);
489 static const struct net_device_ops svip_eth_netdev_ops
= {
490 .ndo_init
= svip_mii_dev_init
,
491 .ndo_open
= svip_mii_open
,
492 .ndo_stop
= svip_mii_release
,
493 .ndo_start_xmit
= svip_mii_tx
,
494 .ndo_get_stats
= svip_get_stats
,
495 .ndo_tx_timeout
= svip_mii_tx_timeout
,
498 //#include <linux/device.h>
501 * Initialize switch driver.
502 * This functions initializes the switch driver structures and registers the
505 * \param dev Device structure for Ethernet device
507 * \return ENOMEM No memory for structures available
508 * \return -1 Error during DMA init or Ethernet address configuration.
511 static int svip_mii_dev_init(struct net_device
*dev
)
514 struct svip_mii_priv
*priv
= netdev_priv(dev
);
518 printk(KERN_INFO DRV_NAME
": %s is up\n", dev
->name
);
519 dev
->watchdog_timeo
= 10 * HZ
;
520 memset(priv
, 0, sizeof(*priv
));
521 priv
->dma_device
= dma_device_reserve("SW");
522 if (!priv
->dma_device
) {
526 priv
->dma_device
->buffer_alloc
= svip_etop_dma_buffer_alloc
;
527 priv
->dma_device
->buffer_free
= svip_etop_dma_buffer_free
;
528 priv
->dma_device
->intr_handler
= dma_intr_handler
;
530 for (i
= 0; i
< priv
->dma_device
->max_rx_chan_num
; i
++)
531 priv
->dma_device
->rx_chan
[i
]->packet_size
=
532 ETHERNET_PACKET_DMA_BUFFER_SIZE
;
534 for (i
= 0; i
< priv
->dma_device
->max_tx_chan_num
; i
++) {
535 priv
->dma_device
->tx_chan
[i
]->tx_weight
=DEFAULT_SW_CHANNEL_WEIGHT
;
536 priv
->dma_device
->tx_chan
[i
]->packet_size
=
537 ETHERNET_PACKET_DMA_BUFFER_SIZE
;
540 dma_device_register(priv
->dma_device
);
542 printk(KERN_INFO DRV_NAME
": using mac=");
544 for (i
= 0; i
< 6; i
++) {
545 dev
->dev_addr
[i
] = mac_addr
[i
];
546 printk("%02X%c", dev
->dev_addr
[i
], (i
== 5) ? ('\n') : (':'));
552 static void svip_mii_chip_init(int mode
)
556 static int svip_mii_probe(struct platform_device
*dev
)
559 unsigned char *mac
= (unsigned char *)dev
->dev
.platform_data
;
560 svip_mii0_dev
= alloc_etherdev(sizeof(struct svip_mii_priv
));
561 svip_mii0_dev
->netdev_ops
= &svip_eth_netdev_ops
;
562 memcpy(mac_addr
, mac
, 6);
563 strcpy(svip_mii0_dev
->name
, "eth%d");
564 svip_mii_chip_init(REV_MII_MODE
);
565 result
= register_netdev(svip_mii0_dev
);
567 printk(KERN_INFO DRV_NAME
568 ": error %i registering device \"%s\"\n",
569 result
, svip_mii0_dev
->name
);
572 printk(KERN_INFO DRV_NAME
": driver loaded!\n");
578 static int svip_mii_remove(struct platform_device
*dev
)
580 struct svip_mii_priv
*priv
= netdev_priv(svip_mii0_dev
);
582 printk(KERN_INFO DRV_NAME
": cleanup\n");
584 dma_device_unregister(priv
->dma_device
);
585 dma_device_release(priv
->dma_device
);
586 kfree(priv
->dma_device
);
587 unregister_netdev(svip_mii0_dev
);
588 free_netdev(svip_mii0_dev
);
593 static struct platform_driver svip_mii_driver
= {
594 .probe
= svip_mii_probe
,
595 .remove
= svip_mii_remove
,
598 .owner
= THIS_MODULE
,
604 * Initialize switch driver as module.
605 * This functions initializes the switch driver structures and registers the
606 * Ethernet device for module usage.
609 * \return ENODEV An error occured during initialization
612 int __init
svip_mii_init(void)
614 int ret
= platform_driver_register(&svip_mii_driver
);
616 printk(KERN_INFO DRV_NAME
617 ": Error registering platfom driver!\n");
623 * Remove driver module.
624 * This functions removes the driver and unregisters all devices.
628 static void __exit
svip_mii_cleanup(void)
630 platform_driver_unregister(&svip_mii_driver
);
633 module_init(svip_mii_init
);
634 module_exit(svip_mii_cleanup
);
636 MODULE_LICENSE("GPL");