[lantiq] move files/ -> files-3.3/
[openwrt.git] / target / linux / lantiq / files-3.3 / drivers / net / ethernet / svip_virtual_eth.c
1 /******************************************************************************
2
3                                Copyright (c) 2007
4                             Infineon Technologies AG
5                      Am Campeon 1-12; 81726 Munich, Germany
6
7   THE DELIVERY OF THIS SOFTWARE AS WELL AS THE HEREBY GRANTED NON-EXCLUSIVE,
8   WORLDWIDE LICENSE TO USE, COPY, MODIFY, DISTRIBUTE AND SUBLICENSE THIS
9   SOFTWARE IS FREE OF CHARGE.
10
11   THE LICENSED SOFTWARE IS PROVIDED "AS IS" AND INFINEON EXPRESSLY DISCLAIMS
12   ALL REPRESENTATIONS AND WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING
13   WITHOUT LIMITATION, WARRANTIES OR REPRESENTATIONS OF WORKMANSHIP,
14   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, THAT THE
15   OPERATING OF THE LICENSED SOFTWARE WILL BE ERROR FREE OR FREE OF ANY THIRD
16   PARTY CLAIMS, INCLUDING WITHOUT LIMITATION CLAIMS OF THIRD PARTY INTELLECTUAL
17   PROPERTY INFRINGEMENT.
18
19   EXCEPT FOR ANY LIABILITY DUE TO WILFUL ACTS OR GROSS NEGLIGENCE AND EXCEPT
20   FOR ANY PERSONAL INJURY INFINEON SHALL IN NO EVENT BE LIABLE FOR ANY CLAIM
21   OR DAMAGES OF ANY KIND, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23   DEALINGS IN THE SOFTWARE.
24
25  ****************************************************************************
26 Module      : svip_virtual_eth.c
27
28 Description : This file contains network driver implementation for a
29 Virtual Ethernet interface. The Virtual Ethernet interface
30 is part of Infineon's VINETIC-SVIP Linux BSP.
31  *******************************************************************************/
32 #include <linux/module.h>
33 #include <linux/kernel.h>
34 #include <linux/netdevice.h>
35 #include <linux/platform_device.h>
36 #include <linux/etherdevice.h>
37 #include <linux/init.h>
38
39 #define SVIP_VETH_VER_STR      "3.0"
40 #define SVIP_VETH_INFO_STR \
41         "@(#)SVIP virtual ethernet interface, version " SVIP_VETH_VER_STR
42
43 /******************************************************************************
44  * Local define/macro definitions
45  ******************************************************************************/
46 struct svip_ve_priv
47 {
48         struct net_device_stats stats;
49 };
50
51 /******************************************************************************
52  * Global function declarations
53  ******************************************************************************/
54 int svip_ve_rx(struct sk_buff *skb);
55
56 /******************************************************************************
57  * Local variable declarations
58  ******************************************************************************/
59 static struct net_device *svip_ve_dev;
60 static int watchdog_timeout = 10*HZ;
61 static int (*svip_ve_mps_xmit)(struct sk_buff *skb) = NULL;
62
63
64 /******************************************************************************
65  * Global function declarations
66  ******************************************************************************/
67
68 /**
69  * Called by MPS driver to register a transmit routine called for each outgoing
70  * VoFW0 message.
71  *
72  * \param   mps_xmit    pointer to transmit routine
73  *
74  * \return  none
75  *
76  * \ingroup Internal
77  */
78 void register_mps_xmit_routine(int (*mps_xmit)(struct sk_buff *skb))
79 {
80         svip_ve_mps_xmit = mps_xmit;
81 }
82 EXPORT_SYMBOL(register_mps_xmit_routine);
83
84 /**
85  * Returns a pointer to the routine used to deliver an incoming packet/message
86  * from the MPS mailbox to the networking layer. This routine is called by MPS
87  * driver during initialisation time.
88  *
89  * \param   skb         pointer to incoming socket buffer
90  *
91  * \return  svip_ve_rx  pointer to incoming messages delivering routine
92  *
93  * \ingroup Internal
94  */
95 int (*register_mps_recv_routine(void)) (struct sk_buff *skb)
96 {
97         return svip_ve_rx;
98 }
99
100 /**
101  * Used to deliver outgoing packets to VoFW0 module through the MPS driver.
102  * Upon loading/initialisation the MPS driver is registering a transmitting
103  * routine, which is called here to deliver the packet to the VoFW0 module.
104  *
105  * \param   skb            pointer to skb containing outgoing data
106  * \param   dev            pointer to this networking device's data
107  *
108  * \return  0 on success
109  * \return  non-zero on error
110  *
111  * \ingroup Internal
112  */
113 static int svip_ve_xmit(struct sk_buff *skb, struct net_device *dev)
114 {
115         int err;
116         struct svip_ve_priv *priv = netdev_priv(dev);
117         struct net_device_stats *stats = &priv->stats;
118
119         stats->tx_packets++;
120         stats->tx_bytes += skb->len;
121
122         if (svip_ve_mps_xmit)
123         {
124                 err = svip_ve_mps_xmit(skb);
125                 if (err)
126                         stats->tx_errors++;
127                 dev->trans_start = jiffies;
128                 return err;
129         }
130         else
131                 printk(KERN_ERR "%s: MPS driver not registered, outgoing packet not delivered\n", dev->name);
132
133         dev_kfree_skb(skb);
134
135         return -1;
136 }
137
138 /**
139  * Called by MPS driver upon receipt of a new message from VoFW0 module in
140  * the data inbox. The packet is pushed up the IP module for further processing.
141  *
142  * \param   skb            pointer to skb containing the incoming message
143  *
144  * \return  0 on success
145  * \return  non-zero on error
146  *
147  * \ingroup Internal
148  */
149 int svip_ve_rx(struct sk_buff *skb)
150 {
151         int err;
152         struct svip_ve_priv *priv = netdev_priv(svip_ve_dev);
153         struct net_device_stats *stats = &priv->stats;
154
155         skb->dev = svip_ve_dev;
156         skb->protocol = eth_type_trans(skb, svip_ve_dev);
157
158         stats->rx_packets++;
159         stats->rx_bytes += skb->len;
160
161         err = netif_rx(skb);
162         switch (err)
163         {
164         case NET_RX_SUCCESS:
165                 return 0;
166                 break;
167         case NET_RX_DROP:
168         default:
169                 stats->rx_dropped++;
170                 break;
171         }
172
173         return 1;
174 }
175 EXPORT_SYMBOL(svip_ve_rx);
176
177 /**
178  * Returns a pointer to the device's networking statistics data
179  *
180  * \param   dev            pointer to this networking device's data
181  *
182  * \return  stats          pointer to this network device's statistics data
183  *
184  * \ingroup Internal
185  */
186 static struct net_device_stats *svip_ve_get_stats(struct net_device *dev)
187 {
188         struct svip_ve_priv *priv = netdev_priv(dev);
189
190         return &priv->stats;
191 }
192
193 static void svip_ve_tx_timeout(struct net_device *dev)
194 {
195         struct svip_ve_priv *priv = netdev_priv(dev);
196
197         priv->stats.tx_errors++;
198         netif_wake_queue(dev);
199 }
200
201 /**
202  * Device open routine. Called e.g. upon setting of an IP address using,
203  * 'ifconfig veth0 YYY.YYY.YYY.YYY netmask ZZZ.ZZZ.ZZZ.ZZZ' or
204  * 'ifconfig veth0 up'
205  *
206  * \param   dev            pointer to this network device's data
207  *
208  * \return  0 on success
209  * \return  non-zero on error
210  *
211  * \ingroup Internal
212  */
213 int svip_ve_open(struct net_device *dev)
214 {
215         netif_start_queue(dev);
216         return 0;
217 }
218
219 /**
220  * Device close routine. Called e.g. upon calling
221  * 'ifconfig veth0 down'
222  *
223  * \param   dev            pointer to this network device's data
224  *
225  * \return  0 on success
226  * \return  non-zero on error
227  *
228  * \ingroup Internal
229  */
230
231 int svip_ve_release(struct net_device *dev)
232 {
233         netif_stop_queue(dev);
234         return 0;
235 }
236
237 static int svip_ve_dev_init(struct net_device *dev);
238
239 static const struct net_device_ops svip_virtual_eth_netdev_ops = {
240         .ndo_init = svip_ve_dev_init,
241         .ndo_open = svip_ve_open,
242         .ndo_stop = svip_ve_release,
243         .ndo_start_xmit = svip_ve_xmit,
244         .ndo_get_stats = svip_ve_get_stats,
245         .ndo_tx_timeout = svip_ve_tx_timeout,
246 };
247
248
249 /**
250  * Device initialisation routine which registers device interface routines.
251  * It is called upon execution of 'register_netdev' routine.
252  *
253  * \param   dev            pointer to this network device's data
254  *
255  * \return  0 on success
256  * \return  non-zero on error
257  *
258  * \ingroup Internal
259  */
260 static int svip_ve_dev_init(struct net_device *dev)
261 {
262         ether_setup(dev); /* assign some of the fields */
263
264         dev->watchdog_timeo  = watchdog_timeout;
265         memset(netdev_priv(dev), 0, sizeof(struct svip_ve_priv));
266         dev->flags |= IFF_NOARP|IFF_PROMISC;
267         dev->flags &= ~IFF_MULTICAST;
268
269         /* dedicated MAC address to veth0, 00:03:19:00:15:80 */
270         dev->dev_addr[0] = 0x00;
271         dev->dev_addr[1] = 0x03;
272         dev->dev_addr[2] = 0x19;
273         dev->dev_addr[3] = 0x00;
274         dev->dev_addr[4] = 0x15;
275         dev->dev_addr[5] = 0x80;
276
277         return 0;
278 }
279
280 static int svip_ve_probe(struct platform_device *dev)
281 {
282         int result = 0;
283
284         svip_ve_dev = alloc_etherdev(sizeof(struct svip_ve_priv));
285         svip_ve_dev->netdev_ops = &svip_virtual_eth_netdev_ops;
286
287         strcpy(svip_ve_dev->name, "veth%d");
288
289         result = register_netdev(svip_ve_dev);
290         if (result)
291         {
292                 printk(KERN_INFO "error %i registering device \"%s\"\n", result, svip_ve_dev->name);
293                 goto out;
294         }
295
296         printk (KERN_INFO "%s, (c) 2009, Lantiq Deutschland GmbH\n", &SVIP_VETH_INFO_STR[4]);
297
298 out:
299         return result;
300 }
301
302 static int svip_ve_remove(struct platform_device *dev)
303 {
304         unregister_netdev(svip_ve_dev);
305         free_netdev(svip_ve_dev);
306
307         printk(KERN_INFO "%s removed\n", svip_ve_dev->name);
308         return 0;
309 }
310
311 static struct platform_driver svip_ve_driver = {
312         .probe = svip_ve_probe,
313         .remove = svip_ve_remove,
314         .driver = {
315                 .name = "ifxmips_svip_ve",
316                 .owner = THIS_MODULE,
317         },
318 };
319
320 /**
321  * Module/driver entry routine
322  */
323 static int __init svip_ve_init_module(void)
324 {
325         int ret;
326
327         ret = platform_driver_register(&svip_ve_driver);
328         if (ret)
329                 printk(KERN_INFO "SVIP: error(%d) registering virtual Ethernet driver!\n", ret);
330         return ret;
331 }
332
333 /**
334  * Module exit routine (never called for statically linked driver)
335  */
336 static void __exit svip_ve_cleanup_module(void)
337 {
338         platform_driver_unregister(&svip_ve_driver);
339 }
340
341 module_init(svip_ve_init_module);
342 module_exit(svip_ve_cleanup_module);
343 MODULE_LICENSE("GPL");
344 MODULE_DESCRIPTION("virtual ethernet driver for LANTIQ SVIP system");
345
346 EXPORT_SYMBOL(register_mps_recv_routine);