00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00035
00036
00037 #include <linux/version.h>
00038 #include <linux/netdevice.h>
00039 #include <linux/etherdevice.h>
00040
00041 #include "globals.h"
00042 #include "master.h"
00043 #include "debug.h"
00044
00045
00046
00047
00048 int ec_dbgdev_open(struct net_device *);
00049 int ec_dbgdev_stop(struct net_device *);
00050 int ec_dbgdev_tx(struct sk_buff *, struct net_device *);
00051 struct net_device_stats *ec_dbgdev_stats(struct net_device *);
00052
00053 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
00054
00056 static const struct net_device_ops ec_dbg_netdev_ops =
00057 {
00058 .ndo_open = ec_dbgdev_open,
00059 .ndo_stop = ec_dbgdev_stop,
00060 .ndo_start_xmit = ec_dbgdev_tx,
00061 .ndo_get_stats = ec_dbgdev_stats,
00062 };
00063 #endif
00064
00065
00066
00074 int ec_debug_init(
00075 ec_debug_t *dbg,
00076 ec_device_t *device,
00077 const char *name
00078 )
00079 {
00080 dbg->device = device;
00081 dbg->registered = 0;
00082 dbg->opened = 0;
00083
00084 memset(&dbg->stats, 0, sizeof(struct net_device_stats));
00085
00086 if (!(dbg->dev =
00087 alloc_netdev(sizeof(ec_debug_t *), name, ether_setup))) {
00088 EC_MASTER_ERR(device->master, "Unable to allocate net_device"
00089 " for debug object!\n");
00090 return -ENODEV;
00091 }
00092
00093
00094 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
00095 dbg->dev->netdev_ops = &ec_dbg_netdev_ops;
00096 #else
00097 dbg->dev->open = ec_dbgdev_open;
00098 dbg->dev->stop = ec_dbgdev_stop;
00099 dbg->dev->hard_start_xmit = ec_dbgdev_tx;
00100 dbg->dev->get_stats = ec_dbgdev_stats;
00101 #endif
00102
00103
00104 *((ec_debug_t **) netdev_priv(dbg->dev)) = dbg;
00105
00106 return 0;
00107 }
00108
00109
00110
00115 void ec_debug_clear(
00116 ec_debug_t *dbg
00117 )
00118 {
00119 ec_debug_unregister(dbg);
00120 free_netdev(dbg->dev);
00121 }
00122
00123
00124
00127 void ec_debug_register(
00128 ec_debug_t *dbg,
00129 const struct net_device *net_dev
00130 )
00131 {
00132 int result;
00133
00134 ec_debug_unregister(dbg);
00135
00136
00137 memcpy(dbg->dev->dev_addr, net_dev->dev_addr, ETH_ALEN);
00138
00139
00140 if ((result = register_netdev(dbg->dev))) {
00141 EC_MASTER_WARN(dbg->device->master, "Unable to register net_device:"
00142 " error %i\n", result);
00143 } else {
00144 dbg->registered = 1;
00145 }
00146 }
00147
00148
00149
00152 void ec_debug_unregister(
00153 ec_debug_t *dbg
00154 )
00155 {
00156 if (dbg->registered) {
00157 dbg->opened = 0;
00158 dbg->registered = 0;
00159 unregister_netdev(dbg->dev);
00160 }
00161 }
00162
00163
00164
00167 void ec_debug_send(
00168 ec_debug_t *dbg,
00169 const uint8_t *data,
00170 size_t size
00171 )
00172 {
00173 struct sk_buff *skb;
00174
00175 if (!dbg->opened)
00176 return;
00177
00178
00179 if (!(skb = dev_alloc_skb(size))) {
00180 dbg->stats.rx_dropped++;
00181 return;
00182 }
00183
00184
00185 memcpy(skb_put(skb, size), data, size);
00186
00187
00188 dbg->stats.rx_packets++;
00189 dbg->stats.rx_bytes += size;
00190
00191
00192 skb->dev = dbg->dev;
00193 skb->protocol = eth_type_trans(skb, dbg->dev);
00194 skb->ip_summed = CHECKSUM_UNNECESSARY;
00195 netif_rx(skb);
00196 }
00197
00198
00199
00200
00201
00206 int ec_dbgdev_open(
00207 struct net_device *dev
00208 )
00209 {
00210 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
00211 dbg->opened = 1;
00212 EC_MASTER_INFO(dbg->device->master, "Debug interface %s opened.\n",
00213 dev->name);
00214 return 0;
00215 }
00216
00217
00218
00223 int ec_dbgdev_stop(
00224 struct net_device *dev
00225 )
00226 {
00227 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
00228 dbg->opened = 0;
00229 EC_MASTER_INFO(dbg->device->master, "Debug interface %s stopped.\n",
00230 dev->name);
00231 return 0;
00232 }
00233
00234
00235
00240 int ec_dbgdev_tx(
00241 struct sk_buff *skb,
00242 struct net_device *dev
00243 )
00244 {
00245 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
00246
00247 dev_kfree_skb(skb);
00248 dbg->stats.tx_dropped++;
00249 return 0;
00250 }
00251
00252
00253
00258 struct net_device_stats *ec_dbgdev_stats(
00259 struct net_device *dev
00260 )
00261 {
00262 ec_debug_t *dbg = *((ec_debug_t **) netdev_priv(dev));
00263 return &dbg->stats;
00264 }
00265
00266