master/ethernet.c
changeset 210 1cc6bcb1e6ae
parent 208 b7797f8a813d
child 212 82980deb8b00
equal deleted inserted replaced
209:fe044345aaec 210:1cc6bcb1e6ae
    25    \file
    25    \file
    26    Ethernet-over-EtherCAT (EoE).
    26    Ethernet-over-EtherCAT (EoE).
    27 */
    27 */
    28 
    28 
    29 /*****************************************************************************/
    29 /*****************************************************************************/
       
    30 
       
    31 #include <linux/etherdevice.h>
    30 
    32 
    31 #include "../include/ecrt.h"
    33 #include "../include/ecrt.h"
    32 #include "globals.h"
    34 #include "globals.h"
    33 #include "master.h"
    35 #include "master.h"
    34 #include "slave.h"
    36 #include "slave.h"
    53 void ec_eoedev_init(struct net_device *);
    55 void ec_eoedev_init(struct net_device *);
    54 int ec_eoedev_open(struct net_device *);
    56 int ec_eoedev_open(struct net_device *);
    55 int ec_eoedev_stop(struct net_device *);
    57 int ec_eoedev_stop(struct net_device *);
    56 int ec_eoedev_tx(struct sk_buff *, struct net_device *);
    58 int ec_eoedev_tx(struct sk_buff *, struct net_device *);
    57 struct net_device_stats *ec_eoedev_stats(struct net_device *);
    59 struct net_device_stats *ec_eoedev_stats(struct net_device *);
       
    60 void ec_eoedev_rx(struct net_device *, const uint8_t *, size_t);
    58 
    61 
    59 /*****************************************************************************/
    62 /*****************************************************************************/
    60 
    63 
    61 /**
    64 /**
    62    EoE constructor.
    65    EoE constructor.
    67     ec_eoedev_priv_t *priv;
    70     ec_eoedev_priv_t *priv;
    68     int result;
    71     int result;
    69 
    72 
    70     eoe->slave = slave;
    73     eoe->slave = slave;
    71     eoe->rx_state = EC_EOE_IDLE;
    74     eoe->rx_state = EC_EOE_IDLE;
       
    75     eoe->opened = 0;
    72 
    76 
    73     if (!(eoe->dev =
    77     if (!(eoe->dev =
    74           alloc_netdev(sizeof(ec_eoedev_priv_t), "eoe%d", ec_eoedev_init))) {
    78           alloc_netdev(sizeof(ec_eoedev_priv_t), "eoe%d", ec_eoedev_init))) {
    75         EC_ERR("Unable to allocate net_device for EoE object!\n");
    79         EC_ERR("Unable to allocate net_device for EoE object!\n");
    76         goto out_return;
    80         goto out_return;
   118 void ec_eoe_run(ec_eoe_t *eoe)
   122 void ec_eoe_run(ec_eoe_t *eoe)
   119 {
   123 {
   120     uint8_t *data;
   124     uint8_t *data;
   121     ec_master_t *master;
   125     ec_master_t *master;
   122     size_t rec_size;
   126     size_t rec_size;
   123     unsigned int i;
   127     uint8_t fragment_number, frame_number, last_fragment, time_appended;
   124     uint8_t fragment_number;
   128     uint8_t fragment_offset, frame_type;
   125     uint8_t complete_size;
   129 
   126     uint8_t frame_number;
   130     if (!eoe->opened) return;
   127     uint8_t last_fragment;
       
   128 
   131 
   129     master = eoe->slave->master;
   132     master = eoe->slave->master;
   130 
   133 
   131     if (eoe->rx_state == EC_EOE_IDLE) {
   134     if (eoe->rx_state == EC_EOE_IDLE) {
   132         ec_slave_mbox_prepare_check(eoe->slave);
   135         ec_slave_mbox_prepare_check(eoe->slave);
   161             master->stats.eoe_errors++;
   164             master->stats.eoe_errors++;
   162             eoe->rx_state = EC_EOE_IDLE;
   165             eoe->rx_state = EC_EOE_IDLE;
   163             return;
   166             return;
   164         }
   167         }
   165 
   168 
   166         fragment_number = EC_READ_U16(data + 2) & 0x003F;
   169         frame_type = EC_READ_U16(data) & 0x000F;
   167         complete_size = (EC_READ_U16(data + 2) >> 6) & 0x003F;
   170 
   168         frame_number = (EC_READ_U16(data + 2) >> 12) & 0x0003;
   171         if (frame_type == 0x00) { // EoE Fragment Request
   169         last_fragment = (EC_READ_U16(data + 2) >> 15) & 0x0001;
   172             last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
   170 
   173             time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
   171         EC_DBG("EOE %s received, fragment: %i, complete size: %i (0x%02X),"
   174             fragment_number = EC_READ_U16(data + 2) & 0x003F;
   172                " frame %i%s\n",
   175             fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
   173                fragment_number ? "fragment" : "initiate", fragment_number,
   176             frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
   174                (complete_size - 31) / 32, complete_size, frame_number,
   177 
   175                last_fragment ? ", last fragment" : "");
   178 #if 0
   176         EC_DBG("");
   179             EC_DBG("EOE fragment req received, fragment: %i, offset: %i,"
   177         for (i = 0; i < rec_size - 2; i++) {
   180                    " frame %i%s%s, %i bytes\n", fragment_number,
   178             printk("%02X ", data[i + 2]);
   181                    fragment_offset, frame_number,
   179             if ((i + 1) % 16 == 0) {
   182                    last_fragment ? ", last fragment" : "",
   180                 printk("\n");
   183                    time_appended ? ", + timestamp" : "",
   181                 EC_DBG("");
   184                    time_appended ? rec_size - 8 : rec_size - 4);
       
   185 
       
   186 #if 0
       
   187             EC_DBG("");
       
   188             for (i = 0; i < rec_size - 4; i++) {
       
   189                 printk("%02X ", data[i + 4]);
       
   190                 if ((i + 1) % 16 == 0) {
       
   191                     printk("\n");
       
   192                     EC_DBG("");
       
   193                 }
   182             }
   194             }
   183         }
   195             printk("\n");
   184         printk("\n");
   196 #endif
       
   197 #endif
       
   198 
       
   199             ec_eoedev_rx(eoe->dev, data + 4,
       
   200                          time_appended ? rec_size - 8 : rec_size - 4);
       
   201         }
       
   202         else {
       
   203 #if 1
       
   204             EC_DBG("other frame received.\n");
       
   205 #endif
       
   206         }
   185 
   207 
   186         eoe->rx_state = EC_EOE_IDLE;
   208         eoe->rx_state = EC_EOE_IDLE;
   187         return;
   209         return;
   188     }
   210     }
   189 }
   211 }
   196 
   218 
   197 void ec_eoe_print(const ec_eoe_t *eoe)
   219 void ec_eoe_print(const ec_eoe_t *eoe)
   198 {
   220 {
   199     EC_INFO("  EoE slave %i\n", eoe->slave->ring_position);
   221     EC_INFO("  EoE slave %i\n", eoe->slave->ring_position);
   200     EC_INFO("    RX State %i\n", eoe->rx_state);
   222     EC_INFO("    RX State %i\n", eoe->rx_state);
       
   223     EC_INFO("    Assigned device: %s (%s)\n", eoe->dev->name,
       
   224             eoe->opened ? "opened" : "closed");
   201 }
   225 }
   202 
   226 
   203 /*****************************************************************************/
   227 /*****************************************************************************/
   204 
   228 
   205 /**
   229 /**
   207 */
   231 */
   208 
   232 
   209 void ec_eoedev_init(struct net_device *dev /**< pointer to the net_device */)
   233 void ec_eoedev_init(struct net_device *dev /**< pointer to the net_device */)
   210 {
   234 {
   211     ec_eoedev_priv_t *priv;
   235     ec_eoedev_priv_t *priv;
       
   236     unsigned int i;
   212 
   237 
   213     // initialize net_device
   238     // initialize net_device
   214     ether_setup(dev);
   239     ether_setup(dev);
   215     dev->open = ec_eoedev_open;
   240     dev->open = ec_eoedev_open;
   216     dev->stop = ec_eoedev_stop;
   241     dev->stop = ec_eoedev_stop;
   217     dev->hard_start_xmit = ec_eoedev_tx;
   242     dev->hard_start_xmit = ec_eoedev_tx;
   218     dev->get_stats = ec_eoedev_stats;
   243     dev->get_stats = ec_eoedev_stats;
   219 
   244 
       
   245     for (i = 0; i < 6; i++) dev->dev_addr[i] = (i + 1) | (i + 1) << 4;
       
   246 
   220     // initialize private data
   247     // initialize private data
   221     priv = netdev_priv(dev);
   248     priv = netdev_priv(dev);
   222     memset(priv, 0, sizeof(ec_eoedev_priv_t));
   249     memset(priv, 0, sizeof(ec_eoedev_priv_t));
   223 }
   250 }
   224 
   251 
   229 */
   256 */
   230 
   257 
   231 int ec_eoedev_open(struct net_device *dev /**< EoE net_device */)
   258 int ec_eoedev_open(struct net_device *dev /**< EoE net_device */)
   232 {
   259 {
   233     ec_eoedev_priv_t *priv = netdev_priv(dev);
   260     ec_eoedev_priv_t *priv = netdev_priv(dev);
       
   261     priv->eoe->opened = 1;
   234     netif_start_queue(dev);
   262     netif_start_queue(dev);
   235     EC_INFO("%s (slave %i) opened.\n", dev->name,
   263     EC_INFO("%s (slave %i) opened.\n", dev->name,
   236             priv->eoe->slave->ring_position);
   264             priv->eoe->slave->ring_position);
   237     return 0;
   265     return 0;
   238 }
   266 }
   245 
   273 
   246 int ec_eoedev_stop(struct net_device *dev /**< EoE net_device */)
   274 int ec_eoedev_stop(struct net_device *dev /**< EoE net_device */)
   247 {
   275 {
   248     ec_eoedev_priv_t *priv = netdev_priv(dev);
   276     ec_eoedev_priv_t *priv = netdev_priv(dev);
   249     netif_stop_queue(dev);
   277     netif_stop_queue(dev);
       
   278     priv->eoe->opened = 0;
   250     EC_INFO("%s (slave %i) stopped.\n", dev->name,
   279     EC_INFO("%s (slave %i) stopped.\n", dev->name,
   251             priv->eoe->slave->ring_position);
   280             priv->eoe->slave->ring_position);
   252     return 0;
   281     return 0;
   253 }
   282 }
   254 
   283 
   270 }
   299 }
   271 
   300 
   272 /*****************************************************************************/
   301 /*****************************************************************************/
   273 
   302 
   274 /**
   303 /**
       
   304    Receives data from the bus and passes it to the network stack.
       
   305 */
       
   306 
       
   307 void ec_eoedev_rx(struct net_device *dev, /**< EoE net_device */
       
   308                  const uint8_t *data, /**< pointer to the data */
       
   309                  size_t size /**< size of the received data */
       
   310                  )
       
   311 {
       
   312     ec_eoedev_priv_t *priv = netdev_priv(dev);
       
   313     struct sk_buff *skb;
       
   314 
       
   315     // allocate socket buffer
       
   316     if (!(skb = dev_alloc_skb(size + 2))) {
       
   317         if (printk_ratelimit())
       
   318             EC_WARN("EoE RX: low on mem. frame dropped.\n");
       
   319         priv->stats.rx_dropped++;
       
   320         return;
       
   321     }
       
   322 
       
   323     // copy received data to socket buffer
       
   324     memcpy(skb_put(skb, size), data, size);
       
   325 
       
   326     // set socket buffer fields
       
   327     skb->dev = dev;
       
   328     skb->protocol = eth_type_trans(skb, dev);
       
   329     skb->ip_summed = CHECKSUM_UNNECESSARY;
       
   330 
       
   331     // update statistics
       
   332     priv->stats.rx_packets++;
       
   333     priv->stats.rx_bytes += size;
       
   334 
       
   335     // pass socket buffer to network stack
       
   336     netif_rx(skb);
       
   337 }
       
   338 
       
   339 /*****************************************************************************/
       
   340 
       
   341 /**
   275    Gets statistics about the virtual network device.
   342    Gets statistics about the virtual network device.
   276 */
   343 */
   277 
   344 
   278 struct net_device_stats *ec_eoedev_stats(struct net_device *dev
   345 struct net_device_stats *ec_eoedev_stats(struct net_device *dev
   279                                          /**< EoE net_device */)
   346                                          /**< EoE net_device */)