master/device.c
changeset 195 674071846ee3
parent 191 ca805255a935
child 197 b9a6e2c22745
child 1618 5cff10efb927
equal deleted inserted replaced
194:c21e7c12dd50 195:674071846ee3
     1 /******************************************************************************
     1 /******************************************************************************
     2  *
     2  *
     3  *  d e v i c e . c
     3  *  d e v i c e . c
     4  *
     4  *
     5  *  Methoden für ein EtherCAT-Gerät.
     5  *  EtherCAT device methods.
     6  *
     6  *
     7  *  $Id$
     7  *  $Id$
     8  *
     8  *
     9  *****************************************************************************/
     9  *****************************************************************************/
    10 
    10 
    18 #include "master.h"
    18 #include "master.h"
    19 
    19 
    20 /*****************************************************************************/
    20 /*****************************************************************************/
    21 
    21 
    22 /**
    22 /**
    23    EtherCAT-Geräte-Konstuktor.
    23    Device constructor.
    24 
    24    \return 0 in case of success, else < 0
    25    \return 0 wenn alles ok, < 0 bei Fehler (zu wenig Speicher)
    25 */
    26 */
    26 
    27 
    27 int ec_device_init(ec_device_t *device, /**< EtherCAT device */
    28 int ec_device_init(ec_device_t *device, /**< EtherCAT-Gerät */
    28                    ec_master_t *master, /**< master owning the device */
    29                    ec_master_t *master, /**< Zugehöriger Master */
    29                    struct net_device *net_dev, /**< net_device structure */
    30                    struct net_device *net_dev, /**< Net-Device */
    30                    ec_isr_t isr, /**< pointer to device's ISR */
    31                    ec_isr_t isr, /**< Adresse der ISR */
    31                    struct module *module /**< pointer to the owning module */
    32                    struct module *module /**< Modul-Adresse */
       
    33                    )
    32                    )
    34 {
    33 {
    35     struct ethhdr *eth;
    34     struct ethhdr *eth;
    36 
    35 
    37     device->master = master;
    36     device->master = master;
    47         return -1;
    46         return -1;
    48     }
    47     }
    49 
    48 
    50     device->tx_skb->dev = net_dev;
    49     device->tx_skb->dev = net_dev;
    51 
    50 
    52     // Ethernet-II-Header hinzufuegen
    51     // add Ethernet-II-header
    53     skb_reserve(device->tx_skb, ETH_HLEN);
    52     skb_reserve(device->tx_skb, ETH_HLEN);
    54     eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN);
    53     eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN);
    55     eth->h_proto = htons(0x88A4);
    54     eth->h_proto = htons(0x88A4);
    56     memcpy(eth->h_source, net_dev->dev_addr, net_dev->addr_len);
    55     memcpy(eth->h_source, net_dev->dev_addr, net_dev->addr_len);
    57     memset(eth->h_dest, 0xFF, net_dev->addr_len);
    56     memset(eth->h_dest, 0xFF, net_dev->addr_len);
    60 }
    59 }
    61 
    60 
    62 /*****************************************************************************/
    61 /*****************************************************************************/
    63 
    62 
    64 /**
    63 /**
    65    EtherCAT-Geräte-Destuktor.
    64    EtherCAT device destuctor.
    66 
    65 */
    67    Gibt den dynamisch allozierten Speicher des
    66 
    68    EtherCAT-Gerätes (den Sende-Socket-Buffer) wieder frei.
    67 void ec_device_clear(ec_device_t *device /**< EtherCAT device */)
    69 */
       
    70 
       
    71 void ec_device_clear(ec_device_t *device /**< EtherCAT-Gerät */)
       
    72 {
    68 {
    73     if (device->open) ec_device_close(device);
    69     if (device->open) ec_device_close(device);
    74     if (device->tx_skb) dev_kfree_skb(device->tx_skb);
    70     if (device->tx_skb) dev_kfree_skb(device->tx_skb);
    75 }
    71 }
    76 
    72 
    77 /*****************************************************************************/
    73 /*****************************************************************************/
    78 
    74 
    79 /**
    75 /**
    80    Führt die open()-Funktion des Netzwerktreibers aus.
    76    Opens the EtherCAT device.
    81 
    77    \return 0 in case of success, else < 0
    82    Dies entspricht einem "ifconfig up". Vorher wird der Zeiger
    78 */
    83    auf das EtherCAT-Gerät auf Gültigkeit geprüft und der
    79 
    84    Gerätezustand zurückgesetzt.
    80 int ec_device_open(ec_device_t *device /**< EtherCAT device */)
    85 
       
    86    \return 0 bei Erfolg, < 0: Ungültiger Zeiger, oder open()
       
    87            fehlgeschlagen
       
    88 */
       
    89 
       
    90 int ec_device_open(ec_device_t *device /**< EtherCAT-Gerät */)
       
    91 {
    81 {
    92     unsigned int i;
    82     unsigned int i;
    93 
    83 
    94     if (!device->dev) {
    84     if (!device->dev) {
    95         EC_ERR("No net_device to open!\n");
    85         EC_ERR("No net_device to open!\n");
    99     if (device->open) {
    89     if (device->open) {
   100         EC_WARN("Device already opened!\n");
    90         EC_WARN("Device already opened!\n");
   101         return 0;
    91         return 0;
   102     }
    92     }
   103 
    93 
   104     // Device could have received frames before
    94     // device could have received frames before
   105     for (i = 0; i < 4; i++) ec_device_call_isr(device);
    95     for (i = 0; i < 4; i++) ec_device_call_isr(device);
   106 
    96 
   107     device->link_state = 0;
    97     device->link_state = 0;
   108 
    98 
   109     if (device->dev->open(device->dev) == 0) device->open = 1;
    99     if (device->dev->open(device->dev) == 0) device->open = 1;
   112 }
   102 }
   113 
   103 
   114 /*****************************************************************************/
   104 /*****************************************************************************/
   115 
   105 
   116 /**
   106 /**
   117    Führt die stop()-Funktion des net_devices aus.
   107    Stops the EtherCAT device.
   118 
   108    \return 0 in case of success, else < 0
   119    \return 0 bei Erfolg, < 0: Kein Gerät zum Schließen oder
   109 */
   120            Schließen fehlgeschlagen.
   110 
   121 */
   111 int ec_device_close(ec_device_t *device /**< EtherCAT device */)
   122 
       
   123 int ec_device_close(ec_device_t *device /**< EtherCAT-Gerät */)
       
   124 {
   112 {
   125     if (!device->dev) {
   113     if (!device->dev) {
   126         EC_ERR("No device to close!\n");
   114         EC_ERR("No device to close!\n");
   127         return -1;
   115         return -1;
   128     }
   116     }
   138 }
   126 }
   139 
   127 
   140 /*****************************************************************************/
   128 /*****************************************************************************/
   141 
   129 
   142 /**
   130 /**
   143    Liefert einen Zeiger auf den Sende-Speicher.
   131    Returns a pointer to the device's transmit memory.
   144 
   132    \return pointer to the TX socket buffer
   145    \return Zeiger auf den Speicher, in den die Frame-Daten sollen.
   133 */
   146 */
   134 
   147 
   135 uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT device */)
   148 uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT-Gerät */)
       
   149 {
   136 {
   150     return device->tx_skb->data + ETH_HLEN;
   137     return device->tx_skb->data + ETH_HLEN;
   151 }
   138 }
   152 
   139 
   153 /*****************************************************************************/
   140 /*****************************************************************************/
   154 
   141 
   155 /**
   142 /**
   156    Sendet den Inhalt des Socket-Buffers.
   143    Sends the content of the transmit socket buffer.
   157 
   144    Cuts the socket buffer content to the (now known) size, and calls the
   158    Schneidet den Inhalt des Socket-Buffers auf die (nun bekannte) Größe zu,
   145    start_xmit() function of the assigned net_device.
   159    fügt den Ethernet-II-Header an und ruft die start_xmit()-Funktion der
   146 */
   160    Netzwerkkarte auf.
   147 
   161 */
   148 void ec_device_send(ec_device_t *device, /**< EtherCAT device */
   162 
   149                     size_t size /**< number of bytes to send */
   163 void ec_device_send(ec_device_t *device, /**< EtherCAT-Gerät */
       
   164                     size_t size /**< Größe der zu sendenden Daten */
       
   165                     )
   150                     )
   166 {
   151 {
   167     if (unlikely(!device->link_state)) // Link down
   152     if (unlikely(!device->link_state)) // Link down
   168         return;
   153         return;
   169 
   154 
   170     // Framegröße auf (jetzt bekannte) Länge abschneiden
   155     // set the right length for the data
   171     device->tx_skb->len = ETH_HLEN + size;
   156     device->tx_skb->len = ETH_HLEN + size;
   172 
   157 
   173     if (unlikely(device->master->debug_level > 1)) {
   158     if (unlikely(device->master->debug_level > 1)) {
   174         EC_DBG("sending frame:\n");
   159         EC_DBG("sending frame:\n");
   175         ec_print_data(device->tx_skb->data + ETH_HLEN, size);
   160         ec_print_data(device->tx_skb->data + ETH_HLEN, size);
   176     }
   161     }
   177 
   162 
   178     // Senden einleiten
   163     // start sending
   179     device->dev->hard_start_xmit(device->tx_skb, device->dev);
   164     device->dev->hard_start_xmit(device->tx_skb, device->dev);
   180 }
   165 }
   181 
   166 
   182 /*****************************************************************************/
   167 /*****************************************************************************/
   183 
   168 
   184 /**
   169 /**
   185    Ruft die Interrupt-Routine der Netzwerkkarte auf.
   170    Calls the interrupt service routine of the assigned net_device.
   186 */
   171 */
   187 
   172 
   188 void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */)
   173 void ec_device_call_isr(ec_device_t *device /**< EtherCAT device */)
   189 {
   174 {
   190     if (likely(device->isr)) device->isr(0, device->dev, NULL);
   175     if (likely(device->isr)) device->isr(0, device->dev, NULL);
   191 }
   176 }
   192 
   177 
   193 /******************************************************************************
   178 /******************************************************************************
   194  *
   179  *  Device interface
   195  * Treiberschnittstelle
       
   196  *
       
   197  *****************************************************************************/
   180  *****************************************************************************/
   198 
   181 
   199 /**
   182 /**
   200    Nimmt einen Empfangenen Rahmen entgegen.
   183    Accepts a received frame.
   201 
   184    Forwards the received data to the master.
   202    Kopiert die empfangenen Daten in den Receive-Buffer.
   185 */
   203 */
   186 
   204 
   187 void ecdev_receive(ec_device_t *device, /**< EtherCAT device */
   205 void ecdev_receive(ec_device_t *device, /**< EtherCAT-Gerät */
   188                    const void *data, /**< pointer to receibed data */
   206                    const void *data, /**< Zeiger auf empfangene Daten */
   189                    size_t size /**< number of bytes received */
   207                    size_t size /**< Größe der empfangenen Daten */
       
   208                    )
   190                    )
   209 {
   191 {
   210     if (unlikely(device->master->debug_level > 1)) {
   192     if (unlikely(device->master->debug_level > 1)) {
   211         EC_DBG("Received frame:\n");
   193         EC_DBG("Received frame:\n");
   212         ec_print_data_diff(device->tx_skb->data + ETH_HLEN, data, size);
   194         ec_print_data_diff(device->tx_skb->data + ETH_HLEN, data, size);
   216 }
   198 }
   217 
   199 
   218 /*****************************************************************************/
   200 /*****************************************************************************/
   219 
   201 
   220 /**
   202 /**
   221    Setzt einen neuen Verbindungszustand.
   203    Sets a new link state.
   222 */
   204 */
   223 
   205 
   224 void ecdev_link_state(ec_device_t *device, /**< EtherCAT-Gerät */
   206 void ecdev_link_state(ec_device_t *device, /**< EtherCAT device */
   225                       uint8_t state /**< Verbindungszustand */
   207                       uint8_t state /**< new link state */
   226                       )
   208                       )
   227 {
   209 {
   228     if (unlikely(!device)) {
   210     if (unlikely(!device)) {
   229         EC_WARN("ecdev_link_state: no device!\n");
   211         EC_WARN("ecdev_link_state: no device!\n");
   230         return;
   212         return;
   240 
   222 
   241 EXPORT_SYMBOL(ecdev_receive);
   223 EXPORT_SYMBOL(ecdev_receive);
   242 EXPORT_SYMBOL(ecdev_link_state);
   224 EXPORT_SYMBOL(ecdev_link_state);
   243 
   225 
   244 /*****************************************************************************/
   226 /*****************************************************************************/
   245 
       
   246 /* Emacs-Konfiguration
       
   247 ;;; Local Variables: ***
       
   248 ;;; c-basic-offset:4 ***
       
   249 ;;; End: ***
       
   250 */