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
00030
00031
00032
00033
00039
00040
00041 #include <linux/module.h>
00042 #include <linux/skbuff.h>
00043 #include <linux/if_ether.h>
00044 #include <linux/netdevice.h>
00045 #include <linux/delay.h>
00046
00047 #include "device.h"
00048 #include "master.h"
00049
00050
00051
00057 int ec_device_init(ec_device_t *device,
00058 ec_master_t *master,
00059 struct net_device *net_dev,
00060 ec_isr_t isr,
00061 struct module *module
00062 )
00063 {
00064 struct ethhdr *eth;
00065
00066 device->master = master;
00067 device->dev = net_dev;
00068 device->isr = isr;
00069 device->module = module;
00070
00071 device->open = 0;
00072 device->link_state = 0;
00073
00074 if (ec_debug_init(&device->dbg)) {
00075 EC_ERR("Failed to init debug device!\n");
00076 goto out_return;
00077 }
00078
00079 if (!(device->tx_skb = dev_alloc_skb(ETH_FRAME_LEN))) {
00080 EC_ERR("Error allocating device socket buffer!\n");
00081 goto out_debug;
00082 }
00083
00084 device->tx_skb->dev = net_dev;
00085
00086
00087 skb_reserve(device->tx_skb, ETH_HLEN);
00088 eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN);
00089 eth->h_proto = htons(0x88A4);
00090 memcpy(eth->h_source, net_dev->dev_addr, net_dev->addr_len);
00091 memset(eth->h_dest, 0xFF, net_dev->addr_len);
00092
00093 return 0;
00094
00095 out_debug:
00096 ec_debug_clear(&device->dbg);
00097 out_return:
00098 return -1;
00099 }
00100
00101
00102
00107 void ec_device_clear(ec_device_t *device )
00108 {
00109 if (device->open) ec_device_close(device);
00110 if (device->tx_skb) dev_kfree_skb(device->tx_skb);
00111 ec_debug_clear(&device->dbg);
00112 }
00113
00114
00115
00121 int ec_device_open(ec_device_t *device )
00122 {
00123 unsigned int i;
00124
00125 if (!device->dev) {
00126 EC_ERR("No net_device to open!\n");
00127 return -1;
00128 }
00129
00130 if (device->open) {
00131 EC_WARN("Device already opened!\n");
00132 return 0;
00133 }
00134
00135
00136 for (i = 0; i < 4; i++) ec_device_call_isr(device);
00137
00138 device->link_state = 0;
00139
00140 if (device->dev->open(device->dev) == 0) device->open = 1;
00141
00142 return device->open ? 0 : -1;
00143 }
00144
00145
00146
00152 int ec_device_close(ec_device_t *device )
00153 {
00154 if (!device->dev) {
00155 EC_ERR("No device to close!\n");
00156 return -1;
00157 }
00158
00159 if (!device->open) {
00160 EC_WARN("Device already closed!\n");
00161 return 0;
00162 }
00163
00164 if (device->dev->stop(device->dev) == 0) device->open = 0;
00165
00166 return !device->open ? 0 : -1;
00167 }
00168
00169
00170
00176 uint8_t *ec_device_tx_data(ec_device_t *device )
00177 {
00178 return device->tx_skb->data + ETH_HLEN;
00179 }
00180
00181
00182
00189 void ec_device_send(ec_device_t *device,
00190 size_t size
00191 )
00192 {
00193 if (unlikely(!device->link_state))
00194 return;
00195
00196
00197 device->tx_skb->len = ETH_HLEN + size;
00198
00199 if (unlikely(device->master->debug_level > 1)) {
00200 EC_DBG("sending frame:\n");
00201 ec_print_data(device->tx_skb->data + ETH_HLEN, size);
00202 }
00203
00204 ec_debug_send(&device->dbg, device->tx_skb->data, ETH_HLEN + size);
00205
00206
00207 device->dev->hard_start_xmit(device->tx_skb, device->dev);
00208 }
00209
00210
00211
00219 void ec_device_call_isr(ec_device_t *device )
00220 {
00221 if (likely(device->isr)) device->isr(0, device->dev, NULL);
00222 }
00223
00224
00225
00226
00227
00235 void ecdev_receive(ec_device_t *device,
00236 const void *data,
00237 size_t size
00238 )
00239 {
00240 if (unlikely(device->master->debug_level > 1)) {
00241 EC_DBG("Received frame:\n");
00242 ec_print_data_diff(device->tx_skb->data + ETH_HLEN,
00243 data + ETH_HLEN, size - ETH_HLEN);
00244 }
00245
00246 ec_debug_send(&device->dbg, data, size);
00247
00248 ec_master_receive(device->master, data + ETH_HLEN, size - ETH_HLEN);
00249 }
00250
00251
00252
00260 void ecdev_link_state(ec_device_t *device,
00261 uint8_t state
00262 )
00263 {
00264 if (unlikely(!device)) {
00265 EC_WARN("ecdev_link_state: no device!\n");
00266 return;
00267 }
00268
00269 if (likely(state != device->link_state)) {
00270 device->link_state = state;
00271 EC_INFO("Link state changed to %s.\n", (state ? "UP" : "DOWN"));
00272 }
00273 }
00274
00275
00276
00279 EXPORT_SYMBOL(ecdev_receive);
00280 EXPORT_SYMBOL(ecdev_link_state);
00281
00284