master/device.c
branchstable-1.3
changeset 1744 7bc131b92039
parent 1739 5fcbd29151d2
child 1746 72e7507b3f1b
equal deleted inserted replaced
1743:1a7067207637 1744:7bc131b92039
    40 
    40 
    41 #include <linux/module.h>
    41 #include <linux/module.h>
    42 #include <linux/skbuff.h>
    42 #include <linux/skbuff.h>
    43 #include <linux/if_ether.h>
    43 #include <linux/if_ether.h>
    44 #include <linux/netdevice.h>
    44 #include <linux/netdevice.h>
    45 #include <linux/delay.h>
       
    46 
    45 
    47 #include "device.h"
    46 #include "device.h"
    48 #include "master.h"
    47 #include "master.h"
    49 
    48 
       
    49 #ifdef EC_DEBUG_RING
       
    50 #define timersub(a, b, result) \
       
    51     do { \
       
    52         (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
       
    53         (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
       
    54         if ((result)->tv_usec < 0) { \
       
    55             --(result)->tv_sec; \
       
    56             (result)->tv_usec += 1000000; \
       
    57         } \
       
    58     } while (0)
       
    59 #endif
       
    60 
    50 /*****************************************************************************/
    61 /*****************************************************************************/
    51 
    62 
    52 /**
    63 /**
    53    Device constructor.
    64    Device constructor.
    54    \return 0 in case of success, else < 0
    65    \return 0 in case of success, else < 0
    55 */
    66 */
    56 
    67 
    57 int ec_device_init(ec_device_t *device, /**< EtherCAT device */
    68 int ec_device_init(ec_device_t *device, /**< EtherCAT device */
    58                    ec_master_t *master, /**< master owning the device */
    69         ec_master_t *master /**< master owning the device */
    59                    struct net_device *net_dev, /**< net_device structure */
    70         )
    60                    ec_pollfunc_t poll, /**< pointer to device's poll function */
    71 {
    61                    struct module *module /**< the device's module */
    72     unsigned int i;
    62                    )
       
    63 {
       
    64     struct ethhdr *eth;
    73     struct ethhdr *eth;
       
    74 #ifdef EC_DEBUG_IF
       
    75     char ifname[10];
       
    76     char mb = 'x';
       
    77 #endif
       
    78 #ifdef EC_DEBUG_RING
       
    79     device->debug_frame_index = 0;
       
    80     device->debug_frame_count = 0;
       
    81 #endif
    65 
    82 
    66     device->master = master;
    83     device->master = master;
       
    84     device->tx_ring_index = 0;
       
    85 
       
    86 #ifdef EC_DEBUG_IF
       
    87     if (device == &master->main_device)
       
    88         mb = 'm';
       
    89     else if (device == &master->backup_device)
       
    90         mb = 'b';
       
    91 
       
    92     sprintf(ifname, "ecdbg%c%u", mb, master->index);
       
    93 
       
    94     if (ec_debug_init(&device->dbg, ifname)) {
       
    95         EC_ERR("Failed to init debug device!\n");
       
    96         goto out_return;
       
    97     }
       
    98 #endif
       
    99 
       
   100     for (i = 0; i < EC_TX_RING_SIZE; i++)
       
   101         device->tx_skb[i] = NULL;
       
   102 
       
   103     for (i = 0; i < EC_TX_RING_SIZE; i++) {
       
   104         if (!(device->tx_skb[i] = dev_alloc_skb(ETH_FRAME_LEN))) {
       
   105             EC_ERR("Error allocating device socket buffer!\n");
       
   106             goto out_tx_ring;
       
   107         }
       
   108 
       
   109         // add Ethernet-II-header
       
   110         skb_reserve(device->tx_skb[i], ETH_HLEN);
       
   111         eth = (struct ethhdr *) skb_push(device->tx_skb[i], ETH_HLEN);
       
   112         eth->h_proto = htons(0x88A4);
       
   113         memset(eth->h_dest, 0xFF, ETH_ALEN);
       
   114     }
       
   115 
       
   116     ec_device_detach(device); // resets remaining fields
       
   117     return 0;
       
   118 
       
   119 out_tx_ring:
       
   120     for (i = 0; i < EC_TX_RING_SIZE; i++)
       
   121         if (device->tx_skb[i])
       
   122             dev_kfree_skb(device->tx_skb[i]);
       
   123 #ifdef EC_DEBUG_IF
       
   124     ec_debug_clear(&device->dbg);
       
   125 out_return:
       
   126 #endif
       
   127     return -1;
       
   128 }
       
   129 
       
   130 /*****************************************************************************/
       
   131 
       
   132 /**
       
   133    EtherCAT device destuctor.
       
   134 */
       
   135 
       
   136 void ec_device_clear(ec_device_t *device /**< EtherCAT device */)
       
   137 {
       
   138     unsigned int i;
       
   139 
       
   140     if (device->open) ec_device_close(device);
       
   141     for (i = 0; i < EC_TX_RING_SIZE; i++)
       
   142         dev_kfree_skb(device->tx_skb[i]);
       
   143 #ifdef EC_DEBUG_IF
       
   144     ec_debug_clear(&device->dbg);
       
   145 #endif
       
   146 }
       
   147 
       
   148 /*****************************************************************************/
       
   149 
       
   150 /**
       
   151    Associate with net_device.
       
   152 */
       
   153 
       
   154 void ec_device_attach(ec_device_t *device, /**< EtherCAT device */
       
   155         struct net_device *net_dev, /**< net_device structure */
       
   156         ec_pollfunc_t poll, /**< pointer to device's poll function */
       
   157         struct module *module /**< the device's module */
       
   158         )
       
   159 {
       
   160     unsigned int i;
       
   161     struct ethhdr *eth;
       
   162 
       
   163     ec_device_detach(device); // resets fields
       
   164 
    67     device->dev = net_dev;
   165     device->dev = net_dev;
    68     device->poll = poll;
   166     device->poll = poll;
    69     device->module = module;
   167     device->module = module;
    70 
   168 
       
   169     for (i = 0; i < EC_TX_RING_SIZE; i++) {
       
   170         device->tx_skb[i]->dev = net_dev;
       
   171         eth = (struct ethhdr *) (device->tx_skb[i]->data + ETH_HLEN);
       
   172         memcpy(eth->h_source, net_dev->dev_addr, ETH_ALEN);
       
   173     }
       
   174 }
       
   175 
       
   176 /*****************************************************************************/
       
   177 
       
   178 /**
       
   179    Disconnect from net_device.
       
   180 */
       
   181 
       
   182 void ec_device_detach(ec_device_t *device /**< EtherCAT device */)
       
   183 {
       
   184     unsigned int i;
       
   185 
       
   186     device->dev = NULL;
       
   187     device->poll = NULL;
       
   188     device->module = NULL;
    71     device->open = 0;
   189     device->open = 0;
    72     device->link_state = 0; // down
   190     device->link_state = 0; // down
    73 
       
    74     device->tx_count = 0;
   191     device->tx_count = 0;
    75     device->rx_count = 0;
   192     device->rx_count = 0;
    76 
   193     for (i = 0; i < EC_TX_RING_SIZE; i++)
    77 #ifdef EC_DBG_IF
   194         device->tx_skb[i]->dev = NULL;
    78     if (ec_debug_init(&device->dbg)) {
       
    79         EC_ERR("Failed to init debug device!\n");
       
    80         goto out_return;
       
    81     }
       
    82 #endif
       
    83 
       
    84     if (!(device->tx_skb = dev_alloc_skb(ETH_FRAME_LEN))) {
       
    85         EC_ERR("Error allocating device socket buffer!\n");
       
    86 #ifdef EC_DBG_IF
       
    87         goto out_debug;
       
    88 #else
       
    89         goto out_return;
       
    90 #endif
       
    91     }
       
    92 
       
    93     device->tx_skb->dev = net_dev;
       
    94 
       
    95     // add Ethernet-II-header
       
    96     skb_reserve(device->tx_skb, ETH_HLEN);
       
    97     eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN);
       
    98     eth->h_proto = htons(0x88A4);
       
    99     memcpy(eth->h_source, net_dev->dev_addr, net_dev->addr_len);
       
   100     memset(eth->h_dest, 0xFF, net_dev->addr_len);
       
   101 
       
   102     return 0;
       
   103 
       
   104 #ifdef EC_DBG_IF
       
   105  out_debug:
       
   106     ec_debug_clear(&device->dbg);
       
   107 #endif
       
   108  out_return:
       
   109     return -1;
       
   110 }
       
   111 
       
   112 /*****************************************************************************/
       
   113 
       
   114 /**
       
   115    EtherCAT device destuctor.
       
   116 */
       
   117 
       
   118 void ec_device_clear(ec_device_t *device /**< EtherCAT device */)
       
   119 {
       
   120     if (device->open) ec_device_close(device);
       
   121     if (device->tx_skb) dev_kfree_skb(device->tx_skb);
       
   122 #ifdef EC_DBG_IF
       
   123     ec_debug_clear(&device->dbg);
       
   124 #endif
       
   125 }
   195 }
   126 
   196 
   127 /*****************************************************************************/
   197 /*****************************************************************************/
   128 
   198 
   129 /**
   199 /**
   131    \return 0 in case of success, else < 0
   201    \return 0 in case of success, else < 0
   132 */
   202 */
   133 
   203 
   134 int ec_device_open(ec_device_t *device /**< EtherCAT device */)
   204 int ec_device_open(ec_device_t *device /**< EtherCAT device */)
   135 {
   205 {
   136     unsigned int i;
       
   137 
       
   138     if (!device->dev) {
   206     if (!device->dev) {
   139         EC_ERR("No net_device to open!\n");
   207         EC_ERR("No net_device to open!\n");
   140         return -1;
   208         return -1;
   141     }
   209     }
   142 
   210 
   143     if (device->open) {
   211     if (device->open) {
   144         EC_WARN("Device already opened!\n");
   212         EC_WARN("Device already opened!\n");
   145         return 0;
   213         return 0;
   146     }
   214     }
   147 
   215 
   148     // device could have received frames before
       
   149     for (i = 0; i < 4; i++) ec_device_poll(device);
       
   150 
       
   151     device->link_state = 0;
   216     device->link_state = 0;
   152     device->tx_count = 0;
   217     device->tx_count = 0;
   153     device->rx_count = 0;
   218     device->rx_count = 0;
   154 
   219 
   155     if (device->dev->open(device->dev) == 0) device->open = 1;
   220     if (device->dev->open(device->dev) == 0) device->open = 1;
   188    \return pointer to the TX socket buffer
   253    \return pointer to the TX socket buffer
   189 */
   254 */
   190 
   255 
   191 uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT device */)
   256 uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT device */)
   192 {
   257 {
   193     return device->tx_skb->data + ETH_HLEN;
   258     /* cycle through socket buffers, because otherwise there is a race
       
   259      * condition, if multiple frames are sent and the DMA is not scheduled in
       
   260      * between. */
       
   261     device->tx_ring_index++;
       
   262     device->tx_ring_index %= EC_TX_RING_SIZE;
       
   263     return device->tx_skb[device->tx_ring_index]->data + ETH_HLEN;
   194 }
   264 }
   195 
   265 
   196 /*****************************************************************************/
   266 /*****************************************************************************/
   197 
   267 
   198 /**
   268 /**
   203 
   273 
   204 void ec_device_send(ec_device_t *device, /**< EtherCAT device */
   274 void ec_device_send(ec_device_t *device, /**< EtherCAT device */
   205                     size_t size /**< number of bytes to send */
   275                     size_t size /**< number of bytes to send */
   206                     )
   276                     )
   207 {
   277 {
       
   278     struct sk_buff *skb = device->tx_skb[device->tx_ring_index];
       
   279 
   208     if (unlikely(!device->link_state)) // Link down
   280     if (unlikely(!device->link_state)) // Link down
   209         return;
   281         return;
   210 
   282 
   211     // set the right length for the data
   283     // set the right length for the data
   212     device->tx_skb->len = ETH_HLEN + size;
   284     skb->len = ETH_HLEN + size;
   213 
   285 
   214     if (unlikely(device->master->debug_level > 1)) {
   286     if (unlikely(device->master->debug_level > 1)) {
   215         EC_DBG("sending frame:\n");
   287         EC_DBG("sending frame:\n");
   216         ec_print_data(device->tx_skb->data + ETH_HLEN, size);
   288         ec_print_data(skb->data + ETH_HLEN, size);
   217     }
   289     }
   218 
   290 
   219 #ifdef EC_DBG_IF
   291 #ifdef EC_DEBUG_IF
   220     ec_debug_send(&device->dbg, device->tx_skb->data, ETH_HLEN + size);
   292     ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size);
       
   293 #endif
       
   294 #ifdef EC_DEBUG_RING
       
   295     ec_device_debug_ring_append(
       
   296             device, TX, skb->data + ETH_HLEN, size);
   221 #endif
   297 #endif
   222 
   298 
   223     // start sending
   299     // start sending
   224     device->dev->hard_start_xmit(device->tx_skb, device->dev);
   300     device->dev->hard_start_xmit(skb, device->dev);
   225     device->tx_count++;
   301     device->tx_count++;
   226 }
   302 }
       
   303 
       
   304 /*****************************************************************************/
       
   305 
       
   306 #ifdef EC_DEBUG_RING
       
   307 /**
       
   308  * Appends frame data to the debug ring.
       
   309  */
       
   310 
       
   311 void ec_device_debug_ring_append(
       
   312         ec_device_t *device, /**< EtherCAT device */
       
   313         ec_debug_frame_dir_t dir, /**< direction */
       
   314         const void *data, /**< frame data */
       
   315         size_t size /**< data size */
       
   316         )
       
   317 {
       
   318     ec_debug_frame_t *df = &device->debug_frames[device->debug_frame_index];
       
   319 
       
   320     df->dir = dir;
       
   321     if (dir == TX)
       
   322         do_gettimeofday(&df->t);
       
   323     else
       
   324         df->t = device->timeval_poll;
       
   325     memcpy(df->data, data, size);
       
   326     df->data_size = size;
       
   327 
       
   328     device->debug_frame_index++;
       
   329     device->debug_frame_index %= EC_DEBUG_RING_SIZE;
       
   330     if (unlikely(device->debug_frame_count < EC_DEBUG_RING_SIZE))
       
   331         device->debug_frame_count++;
       
   332 }
       
   333 
       
   334 /*****************************************************************************/
       
   335 
       
   336 /**
       
   337  * Outputs the debug ring.
       
   338  */
       
   339 
       
   340 void ec_device_debug_ring_print(
       
   341         const ec_device_t *device /**< EtherCAT device */
       
   342         )
       
   343 {
       
   344     int i;
       
   345     unsigned int ring_index;
       
   346     const ec_debug_frame_t *df;
       
   347     struct timeval t0, diff;
       
   348 
       
   349     // calculate index of the newest frame in the ring to get its time
       
   350     ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE - 1)
       
   351         % EC_DEBUG_RING_SIZE;
       
   352     t0 = device->debug_frames[ring_index].t;
       
   353 
       
   354     EC_DBG("Debug ring %i:\n", ring_index);
       
   355 
       
   356     // calculate index of the oldest frame in the ring
       
   357     ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE
       
   358             - device->debug_frame_count) % EC_DEBUG_RING_SIZE;
       
   359 
       
   360     for (i = 0; i < device->debug_frame_count; i++) {
       
   361         df = &device->debug_frames[ring_index];
       
   362         timersub(&t0, &df->t, &diff);
       
   363 
       
   364         EC_DBG("Frame %i, dt=%u.%06u s, %s:\n",
       
   365                 i + 1 - device->debug_frame_count,
       
   366                 (unsigned int) diff.tv_sec,
       
   367                 (unsigned int) diff.tv_usec,
       
   368                 (df->dir == TX) ? "TX" : "RX");
       
   369         ec_print_data(df->data, df->data_size);
       
   370 
       
   371         ring_index++;
       
   372         ring_index %= EC_DEBUG_RING_SIZE;
       
   373     }
       
   374 }
       
   375 #endif
   227 
   376 
   228 /*****************************************************************************/
   377 /*****************************************************************************/
   229 
   378 
   230 /**
   379 /**
   231    Calls the poll function of the assigned net_device.
   380    Calls the poll function of the assigned net_device.
   236 
   385 
   237 void ec_device_poll(ec_device_t *device /**< EtherCAT device */)
   386 void ec_device_poll(ec_device_t *device /**< EtherCAT device */)
   238 {
   387 {
   239     device->cycles_poll = get_cycles();
   388     device->cycles_poll = get_cycles();
   240     device->jiffies_poll = jiffies;
   389     device->jiffies_poll = jiffies;
       
   390 #ifdef EC_DEBUG_RING
       
   391     do_gettimeofday(&device->timeval_poll);
       
   392 #endif
   241     device->poll(device->dev);
   393     device->poll(device->dev);
   242 }
   394 }
   243 
   395 
   244 /******************************************************************************
   396 /******************************************************************************
   245  *  Device interface
   397  *  Device interface
   255 void ecdev_receive(ec_device_t *device, /**< EtherCAT device */
   407 void ecdev_receive(ec_device_t *device, /**< EtherCAT device */
   256                    const void *data, /**< pointer to received data */
   408                    const void *data, /**< pointer to received data */
   257                    size_t size /**< number of bytes received */
   409                    size_t size /**< number of bytes received */
   258                    )
   410                    )
   259 {
   411 {
       
   412     const void *ec_data = data + ETH_HLEN;
       
   413     size_t ec_size = size - ETH_HLEN;
   260     device->rx_count++;
   414     device->rx_count++;
   261 
   415 
   262     if (unlikely(device->master->debug_level > 1)) {
   416     if (unlikely(device->master->debug_level > 1)) {
   263         EC_DBG("Received frame:\n");
   417         EC_DBG("Received frame:\n");
   264         ec_print_data_diff(device->tx_skb->data + ETH_HLEN,
   418         ec_print_data(ec_data, ec_size);
   265                            data + ETH_HLEN, size - ETH_HLEN);
   419     }
   266     }
   420 
   267 
   421 #ifdef EC_DEBUG_IF
   268 #ifdef EC_DBG_IF
       
   269     ec_debug_send(&device->dbg, data, size);
   422     ec_debug_send(&device->dbg, data, size);
   270 #endif
   423 #endif
   271 
   424 #ifdef EC_DEBUG_RING
   272     ec_master_receive_datagrams(device->master,
   425     ec_device_debug_ring_append(device, RX, ec_data, ec_size);
   273                                 data + ETH_HLEN,
   426 #endif
   274                                 size - ETH_HLEN);
   427 
       
   428     ec_master_receive_datagrams(device->master, ec_data, ec_size);
   275 }
   429 }
   276 
   430 
   277 /*****************************************************************************/
   431 /*****************************************************************************/
   278 
   432 
   279 /**
   433 /**
   281    If the device notifies the master about the link being down, the master
   435    If the device notifies the master about the link being down, the master
   282    will not try to send frames using this device.
   436    will not try to send frames using this device.
   283    \ingroup DeviceInterface
   437    \ingroup DeviceInterface
   284 */
   438 */
   285 
   439 
   286 void ecdev_link_state(ec_device_t *device, /**< EtherCAT device */
   440 void ecdev_set_link(ec_device_t *device, /**< EtherCAT device */
   287                       uint8_t state /**< new link state */
   441         uint8_t state /**< new link state */
   288                       )
   442         )
   289 {
   443 {
   290     if (unlikely(!device)) {
   444     if (unlikely(!device)) {
   291         EC_WARN("ecdev_link_state: no device!\n");
   445         EC_WARN("ecdev_link_state: no device!\n");
   292         return;
   446         return;
   293     }
   447     }
   298     }
   452     }
   299 }
   453 }
   300 
   454 
   301 /*****************************************************************************/
   455 /*****************************************************************************/
   302 
   456 
       
   457 /**
       
   458    Reads the link state.
       
   459    \ingroup DeviceInterface
       
   460 */
       
   461 
       
   462 uint8_t ecdev_get_link(ec_device_t *device /**< EtherCAT device */)
       
   463 {
       
   464     if (unlikely(!device)) {
       
   465         EC_WARN("ecdev_link_state: no device!\n");
       
   466         return 0;
       
   467     }
       
   468 
       
   469     return device->link_state;
       
   470 }
       
   471 
       
   472 /*****************************************************************************/
       
   473 
   303 /** \cond */
   474 /** \cond */
   304 
   475 
   305 EXPORT_SYMBOL(ecdev_receive);
   476 EXPORT_SYMBOL(ecdev_receive);
   306 EXPORT_SYMBOL(ecdev_link_state);
   477 EXPORT_SYMBOL(ecdev_get_link);
       
   478 EXPORT_SYMBOL(ecdev_set_link);
   307 
   479 
   308 /** \endcond */
   480 /** \endcond */
   309 
   481 
   310 /*****************************************************************************/
   482 /*****************************************************************************/