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");