master/device.c
changeset 1011 a0759d0dded4
parent 986 a486591ba86b
child 1029 61ffe5f22306
equal deleted inserted replaced
1010:6672b86e7b10 1011:a0759d0dded4
    58     } while (0)
    58     } while (0)
    59 #endif
    59 #endif
    60 
    60 
    61 /*****************************************************************************/
    61 /*****************************************************************************/
    62 
    62 
    63 /**
    63 /** Constructor.
    64    Device constructor.
    64  * 
    65    \return 0 in case of success, else < 0
    65  * \return 0 in case of success, else < 0
    66 */
    66  */
    67 
    67 int ec_device_init(
    68 int ec_device_init(ec_device_t *device, /**< EtherCAT device */
    68         ec_device_t *device, /**< EtherCAT device */
    69         ec_master_t *master /**< master owning the device */
    69         ec_master_t *master /**< master owning the device */
    70         )
    70         )
    71 {
    71 {
    72     unsigned int i;
    72     unsigned int i;
    73     struct ethhdr *eth;
    73     struct ethhdr *eth;
   127     return -1;
   127     return -1;
   128 }
   128 }
   129 
   129 
   130 /*****************************************************************************/
   130 /*****************************************************************************/
   131 
   131 
   132 /**
   132 /** Destuctor.
   133    EtherCAT device destuctor.
   133  */
   134 */
   134 void ec_device_clear(
   135 
   135         ec_device_t *device /**< EtherCAT device */
   136 void ec_device_clear(ec_device_t *device /**< EtherCAT device */)
   136         )
   137 {
   137 {
   138     unsigned int i;
   138     unsigned int i;
   139 
   139 
   140     if (device->open) ec_device_close(device);
   140     if (device->open) ec_device_close(device);
   141     for (i = 0; i < EC_TX_RING_SIZE; i++)
   141     for (i = 0; i < EC_TX_RING_SIZE; i++)
   145 #endif
   145 #endif
   146 }
   146 }
   147 
   147 
   148 /*****************************************************************************/
   148 /*****************************************************************************/
   149 
   149 
   150 /**
   150 /** Associate with net_device.
   151    Associate with net_device.
   151  */
   152 */
   152 void ec_device_attach(
   153 
   153         ec_device_t *device, /**< EtherCAT device */
   154 void ec_device_attach(ec_device_t *device, /**< EtherCAT device */
       
   155         struct net_device *net_dev, /**< net_device structure */
   154         struct net_device *net_dev, /**< net_device structure */
   156         ec_pollfunc_t poll, /**< pointer to device's poll function */
   155         ec_pollfunc_t poll, /**< pointer to device's poll function */
   157         struct module *module /**< the device's module */
   156         struct module *module /**< the device's module */
   158         )
   157         )
   159 {
   158 {
   173     }
   172     }
   174 }
   173 }
   175 
   174 
   176 /*****************************************************************************/
   175 /*****************************************************************************/
   177 
   176 
   178 /**
   177 /** Disconnect from net_device.
   179    Disconnect from net_device.
   178  */
   180 */
   179 void ec_device_detach(
   181 
   180         ec_device_t *device /**< EtherCAT device */
   182 void ec_device_detach(ec_device_t *device /**< EtherCAT device */)
   181         )
   183 {
   182 {
   184     unsigned int i;
   183     unsigned int i;
   185 
   184 
   186     device->dev = NULL;
   185     device->dev = NULL;
   187     device->poll = NULL;
   186     device->poll = NULL;
   194         device->tx_skb[i]->dev = NULL;
   193         device->tx_skb[i]->dev = NULL;
   195 }
   194 }
   196 
   195 
   197 /*****************************************************************************/
   196 /*****************************************************************************/
   198 
   197 
   199 /**
   198 /** Opens the EtherCAT device.
   200    Opens the EtherCAT device.
   199  *
   201    \return 0 in case of success, else < 0
   200  * \return 0 in case of success, else < 0
   202 */
   201  */
   203 
   202 int ec_device_open(
   204 int ec_device_open(ec_device_t *device /**< EtherCAT device */)
   203         ec_device_t *device /**< EtherCAT device */
       
   204         )
   205 {
   205 {
   206     if (!device->dev) {
   206     if (!device->dev) {
   207         EC_ERR("No net_device to open!\n");
   207         EC_ERR("No net_device to open!\n");
   208         return -1;
   208         return -1;
   209     }
   209     }
   222     return device->open ? 0 : -1;
   222     return device->open ? 0 : -1;
   223 }
   223 }
   224 
   224 
   225 /*****************************************************************************/
   225 /*****************************************************************************/
   226 
   226 
   227 /**
   227 /** Stops the EtherCAT device.
   228    Stops the EtherCAT device.
   228  *
   229    \return 0 in case of success, else < 0
   229  * \return 0 in case of success, else < 0
   230 */
   230  */
   231 
   231 int ec_device_close(
   232 int ec_device_close(ec_device_t *device /**< EtherCAT device */)
   232         ec_device_t *device /**< EtherCAT device */
       
   233         )
   233 {
   234 {
   234     if (!device->dev) {
   235     if (!device->dev) {
   235         EC_ERR("No device to close!\n");
   236         EC_ERR("No device to close!\n");
   236         return -1;
   237         return -1;
   237     }
   238     }
   246     return !device->open ? 0 : -1;
   247     return !device->open ? 0 : -1;
   247 }
   248 }
   248 
   249 
   249 /*****************************************************************************/
   250 /*****************************************************************************/
   250 
   251 
   251 /**
   252 /** Returns a pointer to the device's transmit memory.
   252    Returns a pointer to the device's transmit memory.
   253  *
   253    \return pointer to the TX socket buffer
   254  * \return pointer to the TX socket buffer
   254 */
   255  */
   255 
   256 uint8_t *ec_device_tx_data(
   256 uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT device */)
   257         ec_device_t *device /**< EtherCAT device */
       
   258         )
   257 {
   259 {
   258     /* cycle through socket buffers, because otherwise there is a race
   260     /* cycle through socket buffers, because otherwise there is a race
   259      * condition, if multiple frames are sent and the DMA is not scheduled in
   261      * condition, if multiple frames are sent and the DMA is not scheduled in
   260      * between. */
   262      * between. */
   261     device->tx_ring_index++;
   263     device->tx_ring_index++;
   263     return device->tx_skb[device->tx_ring_index]->data + ETH_HLEN;
   265     return device->tx_skb[device->tx_ring_index]->data + ETH_HLEN;
   264 }
   266 }
   265 
   267 
   266 /*****************************************************************************/
   268 /*****************************************************************************/
   267 
   269 
   268 /**
   270 /** Sends the content of the transmit socket buffer.
   269    Sends the content of the transmit socket buffer.
   271  *
   270    Cuts the socket buffer content to the (now known) size, and calls the
   272  * Cuts the socket buffer content to the (now known) size, and calls the
   271    start_xmit() function of the assigned net_device.
   273  * start_xmit() function of the assigned net_device.
   272 */
   274  */
   273 
   275 void ec_device_send(
   274 void ec_device_send(ec_device_t *device, /**< EtherCAT device */
   276         ec_device_t *device, /**< EtherCAT device */
   275                     size_t size /**< number of bytes to send */
   277         size_t size /**< number of bytes to send */
   276                     )
   278         )
   277 {
   279 {
   278     struct sk_buff *skb = device->tx_skb[device->tx_ring_index];
   280     struct sk_buff *skb = device->tx_skb[device->tx_ring_index];
   279 
   281 
   280     if (unlikely(!device->link_state)) // Link down
   282     if (unlikely(!device->link_state)) // Link down
   281         return;
   283         return;
   302 }
   304 }
   303 
   305 
   304 /*****************************************************************************/
   306 /*****************************************************************************/
   305 
   307 
   306 #ifdef EC_DEBUG_RING
   308 #ifdef EC_DEBUG_RING
   307 /**
   309 /** Appends frame data to the debug ring.
   308  * Appends frame data to the debug ring.
   310  */
   309  */
       
   310 
       
   311 void ec_device_debug_ring_append(
   311 void ec_device_debug_ring_append(
   312         ec_device_t *device, /**< EtherCAT device */
   312         ec_device_t *device, /**< EtherCAT device */
   313         ec_debug_frame_dir_t dir, /**< direction */
   313         ec_debug_frame_dir_t dir, /**< direction */
   314         const void *data, /**< frame data */
   314         const void *data, /**< frame data */
   315         size_t size /**< data size */
   315         size_t size /**< data size */
   331         device->debug_frame_count++;
   331         device->debug_frame_count++;
   332 }
   332 }
   333 
   333 
   334 /*****************************************************************************/
   334 /*****************************************************************************/
   335 
   335 
   336 /**
   336 /** Outputs the debug ring.
   337  * Outputs the debug ring.
   337  */
   338  */
       
   339 
       
   340 void ec_device_debug_ring_print(
   338 void ec_device_debug_ring_print(
   341         const ec_device_t *device /**< EtherCAT device */
   339         const ec_device_t *device /**< EtherCAT device */
   342         )
   340         )
   343 {
   341 {
   344     int i;
   342     int i;
   374 }
   372 }
   375 #endif
   373 #endif
   376 
   374 
   377 /*****************************************************************************/
   375 /*****************************************************************************/
   378 
   376 
   379 /**
   377 /** Calls the poll function of the assigned net_device.
   380    Calls the poll function of the assigned net_device.
   378  *
   381    The master itself works without using interrupts. Therefore the processing
   379  * The master itself works without using interrupts. Therefore the processing
   382    of received data and status changes of the network device has to be
   380  * of received data and status changes of the network device has to be
   383    done by the master calling the ISR "manually".
   381  * done by the master calling the ISR "manually".
   384 */
   382  */
   385 
   383 void ec_device_poll(
   386 void ec_device_poll(ec_device_t *device /**< EtherCAT device */)
   384         ec_device_t *device /**< EtherCAT device */
       
   385         )
   387 {
   386 {
   388     device->cycles_poll = get_cycles();
   387     device->cycles_poll = get_cycles();
   389     device->jiffies_poll = jiffies;
   388     device->jiffies_poll = jiffies;
   390 #ifdef EC_DEBUG_RING
   389 #ifdef EC_DEBUG_RING
   391     do_gettimeofday(&device->timeval_poll);
   390     do_gettimeofday(&device->timeval_poll);
   395 
   394 
   396 /******************************************************************************
   395 /******************************************************************************
   397  *  Device interface
   396  *  Device interface
   398  *****************************************************************************/
   397  *****************************************************************************/
   399 
   398 
   400 /**
   399 /** Withdraws an EtherCAT device from the master.
   401    Accepts a received frame.
   400  *
   402    Forwards the received data to the master. The master will analyze the frame
   401  * The device is disconnected from the master and all device ressources
   403    and dispatch the received commands to the sending instances.
   402  * are freed.
   404    \ingroup DeviceInterface
   403  *
   405 */
   404  * \attention Before calling this function, the ecdev_stop() function has
   406 
   405  *            to be called, to be sure that the master does not use the device
   407 void ecdev_receive(ec_device_t *device, /**< EtherCAT device */
   406  *            any more.
   408                    const void *data, /**< pointer to received data */
   407  * \ingroup DeviceInterface
   409                    size_t size /**< number of bytes received */
   408  */
   410                    )
   409 void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */)
       
   410 {
       
   411     ec_master_t *master = device->master;
       
   412     char str[20];
       
   413 
       
   414     ec_mac_print(device->dev->dev_addr, str);
       
   415     EC_INFO("Master %u releasing main device %s.\n", master->index, str);
       
   416     
       
   417     down(&master->device_sem);
       
   418     ec_device_detach(device);
       
   419     up(&master->device_sem);
       
   420 }
       
   421 
       
   422 /*****************************************************************************/
       
   423 
       
   424 /** Opens the network device and makes the master enter IDLE mode.
       
   425  *
       
   426  * \return 0 on success, else < 0
       
   427  * \ingroup DeviceInterface
       
   428  */
       
   429 int ecdev_open(ec_device_t *device /**< EtherCAT device */)
       
   430 {
       
   431     if (ec_device_open(device)) {
       
   432         EC_ERR("Failed to open device!\n");
       
   433         return -1;
       
   434     }
       
   435 
       
   436     if (ec_master_enter_idle_mode(device->master)) {
       
   437         EC_ERR("Failed to enter idle mode!\n");
       
   438         return -1;
       
   439     }
       
   440 
       
   441     return 0;
       
   442 }
       
   443 
       
   444 /*****************************************************************************/
       
   445 
       
   446 /** Makes the master leave IDLE mode and closes the network device.
       
   447  *
       
   448  * \return 0 on success, else < 0
       
   449  * \ingroup DeviceInterface
       
   450  */
       
   451 void ecdev_close(ec_device_t *device /**< EtherCAT device */)
       
   452 {
       
   453     ec_master_leave_idle_mode(device->master);
       
   454 
       
   455     if (ec_device_close(device))
       
   456         EC_WARN("Failed to close device!\n");
       
   457 }
       
   458 
       
   459 /*****************************************************************************/
       
   460 
       
   461 /** Accepts a received frame.
       
   462  *
       
   463  * Forwards the received data to the master. The master will analyze the frame
       
   464  * and dispatch the received commands to the sending instances.
       
   465  * 
       
   466  * \ingroup DeviceInterface
       
   467  */
       
   468 void ecdev_receive(
       
   469         ec_device_t *device, /**< EtherCAT device */
       
   470         const void *data, /**< pointer to received data */
       
   471         size_t size /**< number of bytes received */
       
   472         )
   411 {
   473 {
   412     const void *ec_data = data + ETH_HLEN;
   474     const void *ec_data = data + ETH_HLEN;
   413     size_t ec_size = size - ETH_HLEN;
   475     size_t ec_size = size - ETH_HLEN;
   414     device->rx_count++;
   476     device->rx_count++;
   415 
   477 
   428     ec_master_receive_datagrams(device->master, ec_data, ec_size);
   490     ec_master_receive_datagrams(device->master, ec_data, ec_size);
   429 }
   491 }
   430 
   492 
   431 /*****************************************************************************/
   493 /*****************************************************************************/
   432 
   494 
   433 /**
   495 /** Sets a new link state.
   434    Sets a new link state.
   496  *
   435    If the device notifies the master about the link being down, the master
   497  * If the device notifies the master about the link being down, the master
   436    will not try to send frames using this device.
   498  * will not try to send frames using this device.
   437    \ingroup DeviceInterface
   499  * 
   438 */
   500  * \ingroup DeviceInterface
   439 
   501  */
   440 void ecdev_set_link(ec_device_t *device, /**< EtherCAT device */
   502 void ecdev_set_link(
       
   503         ec_device_t *device, /**< EtherCAT device */
   441         uint8_t state /**< new link state */
   504         uint8_t state /**< new link state */
   442         )
   505         )
   443 {
   506 {
   444     if (unlikely(!device)) {
   507     if (unlikely(!device)) {
   445         EC_WARN("ecdev_link_state: no device!\n");
   508         EC_WARN("ecdev_set_link(): No device!\n");
   446         return;
   509         return;
   447     }
   510     }
   448 
   511 
   449     if (likely(state != device->link_state)) {
   512     if (likely(state != device->link_state)) {
   450         device->link_state = state;
   513         device->link_state = state;
   452     }
   515     }
   453 }
   516 }
   454 
   517 
   455 /*****************************************************************************/
   518 /*****************************************************************************/
   456 
   519 
   457 /**
   520 /** Reads the link state.
   458    Reads the link state.
   521  *
   459    \ingroup DeviceInterface
   522  * \ingroup DeviceInterface
   460 */
   523  */
   461 
   524 uint8_t ecdev_get_link(
   462 uint8_t ecdev_get_link(ec_device_t *device /**< EtherCAT device */)
   525         const ec_device_t *device /**< EtherCAT device */
       
   526         )
   463 {
   527 {
   464     if (unlikely(!device)) {
   528     if (unlikely(!device)) {
   465         EC_WARN("ecdev_link_state: no device!\n");
   529         EC_WARN("ecdev_get_link(): No device!\n");
   466         return 0;
   530         return 0;
   467     }
   531     }
   468 
   532 
   469     return device->link_state;
   533     return device->link_state;
   470 }
   534 }
   471 
   535 
   472 /*****************************************************************************/
   536 /*****************************************************************************/
   473 
   537 
   474 /** \cond */
   538 /** \cond */
   475 
   539 
       
   540 EXPORT_SYMBOL(ecdev_withdraw);
       
   541 EXPORT_SYMBOL(ecdev_open);
       
   542 EXPORT_SYMBOL(ecdev_close);
   476 EXPORT_SYMBOL(ecdev_receive);
   543 EXPORT_SYMBOL(ecdev_receive);
   477 EXPORT_SYMBOL(ecdev_get_link);
   544 EXPORT_SYMBOL(ecdev_get_link);
   478 EXPORT_SYMBOL(ecdev_set_link);
   545 EXPORT_SYMBOL(ecdev_set_link);
   479 
   546 
   480 /** \endcond */
   547 /** \endcond */