|
1 /****************************************************************************** |
|
2 * |
|
3 * $Id$ |
|
4 * |
|
5 * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH |
|
6 * |
|
7 * This file is part of the IgH EtherCAT Master. |
|
8 * |
|
9 * The IgH EtherCAT Master is free software; you can redistribute it |
|
10 * and/or modify it under the terms of the GNU General Public License |
|
11 * as published by the Free Software Foundation; either version 2 of the |
|
12 * License, or (at your option) any later version. |
|
13 * |
|
14 * The IgH EtherCAT Master is distributed in the hope that it will be |
|
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17 * GNU General Public License for more details. |
|
18 * |
|
19 * You should have received a copy of the GNU General Public License |
|
20 * along with the IgH EtherCAT Master; if not, write to the Free Software |
|
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
22 * |
|
23 * The right to use EtherCAT Technology is granted and comes free of |
|
24 * charge under condition of compatibility of product made by |
|
25 * Licensee. People intending to distribute/sell products based on the |
|
26 * code, have to sign an agreement to guarantee that products using |
|
27 * software based on IgH EtherCAT master stay compatible with the actual |
|
28 * EtherCAT specification (which are released themselves as an open |
|
29 * standard) as the (only) precondition to have the right to use EtherCAT |
|
30 * Technology, IP and trade marks. |
|
31 * |
|
32 *****************************************************************************/ |
|
33 |
|
34 /** |
|
35 \file |
|
36 Ethernet interface for debugging purposes. |
|
37 */ |
|
38 |
|
39 /*****************************************************************************/ |
|
40 |
|
41 #include <linux/etherdevice.h> |
|
42 |
|
43 #include "globals.h" |
|
44 #include "debug.h" |
|
45 |
|
46 /*****************************************************************************/ |
|
47 |
|
48 // net_device functions |
|
49 int ec_dbgdev_open(struct net_device *); |
|
50 int ec_dbgdev_stop(struct net_device *); |
|
51 struct net_device_stats *ec_dbgdev_stats(struct net_device *); |
|
52 |
|
53 /*****************************************************************************/ |
|
54 |
|
55 /** |
|
56 Debug constructor. |
|
57 Initializes the debug object, creates a net_device and registeres it. |
|
58 */ |
|
59 |
|
60 int ec_debug_init(ec_debug_t *dbg /**< debug object */) |
|
61 { |
|
62 int result; |
|
63 |
|
64 dbg->opened = 0; |
|
65 memset(&dbg->stats, 0, sizeof(struct net_device_stats)); |
|
66 |
|
67 if (!(dbg->dev = |
|
68 alloc_netdev(sizeof(ec_debug_t *), "ec%d", ether_setup))) { |
|
69 EC_ERR("Unable to allocate net_device for debug object!\n"); |
|
70 goto out_return; |
|
71 } |
|
72 |
|
73 // initialize net_device |
|
74 dbg->dev->open = ec_dbgdev_open; |
|
75 dbg->dev->stop = ec_dbgdev_stop; |
|
76 dbg->dev->get_stats = ec_dbgdev_stats; |
|
77 |
|
78 // initialize private data |
|
79 *((ec_debug_t **) netdev_priv(dbg->dev)) = dbg; |
|
80 |
|
81 // connect the net_device to the kernel |
|
82 if ((result = register_netdev(dbg->dev))) { |
|
83 EC_ERR("Unable to register net_device: error %i\n", result); |
|
84 goto out_free; |
|
85 } |
|
86 |
|
87 return 0; |
|
88 |
|
89 out_free: |
|
90 free_netdev(dbg->dev); |
|
91 dbg->dev = NULL; |
|
92 out_return: |
|
93 return -1; |
|
94 } |
|
95 |
|
96 /*****************************************************************************/ |
|
97 |
|
98 /** |
|
99 Debug destructor. |
|
100 Unregisteres the net_device and frees allocated memory. |
|
101 */ |
|
102 |
|
103 void ec_debug_clear(ec_debug_t *dbg /**< debug object */) |
|
104 { |
|
105 if (dbg->dev) { |
|
106 unregister_netdev(dbg->dev); |
|
107 free_netdev(dbg->dev); |
|
108 } |
|
109 } |
|
110 |
|
111 /*****************************************************************************/ |
|
112 |
|
113 /** |
|
114 Sends frame data to the interface. |
|
115 */ |
|
116 |
|
117 void ec_debug_send(ec_debug_t *dbg, /**< debug object */ |
|
118 const uint8_t *data, /**< frame data */ |
|
119 size_t size /**< size of the frame data */ |
|
120 ) |
|
121 { |
|
122 struct sk_buff *skb; |
|
123 |
|
124 if (!dbg->opened) return; |
|
125 |
|
126 // allocate socket buffer |
|
127 if (!(skb = dev_alloc_skb(size))) { |
|
128 dbg->stats.rx_dropped++; |
|
129 return; |
|
130 } |
|
131 |
|
132 // copy frame contents into socket buffer |
|
133 memcpy(skb_put(skb, size), data, size); |
|
134 |
|
135 // update device statistics |
|
136 dbg->stats.rx_packets++; |
|
137 dbg->stats.rx_bytes += size; |
|
138 |
|
139 // pass socket buffer to network stack |
|
140 skb->dev = dbg->dev; |
|
141 skb->protocol = eth_type_trans(skb, dbg->dev); |
|
142 skb->ip_summed = CHECKSUM_UNNECESSARY; |
|
143 netif_rx(skb); |
|
144 } |
|
145 |
|
146 /****************************************************************************** |
|
147 * NET_DEVICE functions |
|
148 *****************************************************************************/ |
|
149 |
|
150 /** |
|
151 Opens the virtual network device. |
|
152 */ |
|
153 |
|
154 int ec_dbgdev_open(struct net_device *dev /**< debug net_device */) |
|
155 { |
|
156 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev)); |
|
157 dbg->opened = 1; |
|
158 EC_INFO("debug interface %s opened.\n", dev->name); |
|
159 return 0; |
|
160 } |
|
161 |
|
162 /*****************************************************************************/ |
|
163 |
|
164 /** |
|
165 Stops the virtual network device. |
|
166 */ |
|
167 |
|
168 int ec_dbgdev_stop(struct net_device *dev /**< debug net_device */) |
|
169 { |
|
170 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev)); |
|
171 dbg->opened = 0; |
|
172 EC_INFO("debug interface %s stopped.\n", dev->name); |
|
173 return 0; |
|
174 } |
|
175 |
|
176 /*****************************************************************************/ |
|
177 |
|
178 /** |
|
179 Gets statistics about the virtual network device. |
|
180 */ |
|
181 |
|
182 struct net_device_stats *ec_dbgdev_stats(struct net_device *dev |
|
183 /**< debug net_device */) |
|
184 { |
|
185 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev)); |
|
186 return &dbg->stats; |
|
187 } |
|
188 |
|
189 /*****************************************************************************/ |