1 /******************************************************************************
4 Infineon Technologies AG
5 Am Campeon 1-12; 81726 Munich, Germany
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.
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.
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.
25 ****************************************************************************
26 Module : svip_virtual_eth.c
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>
39 #define SVIP_VETH_VER_STR "3.0"
40 #define SVIP_VETH_INFO_STR \
41 "@(#)SVIP virtual ethernet interface, version " SVIP_VETH_VER_STR
43 /******************************************************************************
44 * Local define/macro definitions
45 ******************************************************************************/
48 struct net_device_stats stats
;
51 /******************************************************************************
52 * Global function declarations
53 ******************************************************************************/
54 int svip_ve_rx(struct sk_buff
*skb
);
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
;
64 /******************************************************************************
65 * Global function declarations
66 ******************************************************************************/
69 * Called by MPS driver to register a transmit routine called for each outgoing
72 * \param mps_xmit pointer to transmit routine
78 void register_mps_xmit_routine(int (*mps_xmit
)(struct sk_buff
*skb
))
80 svip_ve_mps_xmit
= mps_xmit
;
82 EXPORT_SYMBOL(register_mps_xmit_routine
);
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.
89 * \param skb pointer to incoming socket buffer
91 * \return svip_ve_rx pointer to incoming messages delivering routine
95 int (*register_mps_recv_routine(void)) (struct sk_buff
*skb
)
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.
105 * \param skb pointer to skb containing outgoing data
106 * \param dev pointer to this networking device's data
108 * \return 0 on success
109 * \return non-zero on error
113 static int svip_ve_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
116 struct svip_ve_priv
*priv
= netdev_priv(dev
);
117 struct net_device_stats
*stats
= &priv
->stats
;
120 stats
->tx_bytes
+= skb
->len
;
122 if (svip_ve_mps_xmit
)
124 err
= svip_ve_mps_xmit(skb
);
127 dev
->trans_start
= jiffies
;
131 printk(KERN_ERR
"%s: MPS driver not registered, outgoing packet not delivered\n", dev
->name
);
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.
142 * \param skb pointer to skb containing the incoming message
144 * \return 0 on success
145 * \return non-zero on error
149 int svip_ve_rx(struct sk_buff
*skb
)
152 struct svip_ve_priv
*priv
= netdev_priv(svip_ve_dev
);
153 struct net_device_stats
*stats
= &priv
->stats
;
155 skb
->dev
= svip_ve_dev
;
156 skb
->protocol
= eth_type_trans(skb
, svip_ve_dev
);
159 stats
->rx_bytes
+= skb
->len
;
175 EXPORT_SYMBOL(svip_ve_rx
);
178 * Returns a pointer to the device's networking statistics data
180 * \param dev pointer to this networking device's data
182 * \return stats pointer to this network device's statistics data
186 static struct net_device_stats
*svip_ve_get_stats(struct net_device
*dev
)
188 struct svip_ve_priv
*priv
= netdev_priv(dev
);
193 static void svip_ve_tx_timeout(struct net_device
*dev
)
195 struct svip_ve_priv
*priv
= netdev_priv(dev
);
197 priv
->stats
.tx_errors
++;
198 netif_wake_queue(dev
);
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'
206 * \param dev pointer to this network device's data
208 * \return 0 on success
209 * \return non-zero on error
213 int svip_ve_open(struct net_device
*dev
)
215 netif_start_queue(dev
);
220 * Device close routine. Called e.g. upon calling
221 * 'ifconfig veth0 down'
223 * \param dev pointer to this network device's data
225 * \return 0 on success
226 * \return non-zero on error
231 int svip_ve_release(struct net_device
*dev
)
233 netif_stop_queue(dev
);
237 static int svip_ve_dev_init(struct net_device
*dev
);
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
,
250 * Device initialisation routine which registers device interface routines.
251 * It is called upon execution of 'register_netdev' routine.
253 * \param dev pointer to this network device's data
255 * \return 0 on success
256 * \return non-zero on error
260 static int svip_ve_dev_init(struct net_device
*dev
)
262 ether_setup(dev
); /* assign some of the fields */
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
;
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;
280 static int svip_ve_probe(struct platform_device
*dev
)
284 svip_ve_dev
= alloc_etherdev(sizeof(struct svip_ve_priv
));
285 svip_ve_dev
->netdev_ops
= &svip_virtual_eth_netdev_ops
;
287 strcpy(svip_ve_dev
->name
, "veth%d");
289 result
= register_netdev(svip_ve_dev
);
292 printk(KERN_INFO
"error %i registering device \"%s\"\n", result
, svip_ve_dev
->name
);
296 printk (KERN_INFO
"%s, (c) 2009, Lantiq Deutschland GmbH\n", &SVIP_VETH_INFO_STR
[4]);
302 static int svip_ve_remove(struct platform_device
*dev
)
304 unregister_netdev(svip_ve_dev
);
305 free_netdev(svip_ve_dev
);
307 printk(KERN_INFO
"%s removed\n", svip_ve_dev
->name
);
311 static struct platform_driver svip_ve_driver
= {
312 .probe
= svip_ve_probe
,
313 .remove
= svip_ve_remove
,
315 .name
= "ifxmips_svip_ve",
316 .owner
= THIS_MODULE
,
321 * Module/driver entry routine
323 static int __init
svip_ve_init_module(void)
327 ret
= platform_driver_register(&svip_ve_driver
);
329 printk(KERN_INFO
"SVIP: error(%d) registering virtual Ethernet driver!\n", ret
);
334 * Module exit routine (never called for statically linked driver)
336 static void __exit
svip_ve_cleanup_module(void)
338 platform_driver_unregister(&svip_ve_driver
);
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");
346 EXPORT_SYMBOL(register_mps_recv_routine
);