master/device.c
changeset 78 3d74183d6c6b
parent 73 9f4ea66d89a3
child 84 b4ae98855cea
equal deleted inserted replaced
77:677967864795 78:3d74183d6c6b
    13 #include <linux/if_ether.h>
    13 #include <linux/if_ether.h>
    14 #include <linux/netdevice.h>
    14 #include <linux/netdevice.h>
    15 #include <linux/delay.h>
    15 #include <linux/delay.h>
    16 
    16 
    17 #include "device.h"
    17 #include "device.h"
       
    18 #include "master.h"
    18 
    19 
    19 /*****************************************************************************/
    20 /*****************************************************************************/
    20 
    21 
    21 /**
    22 /**
    22    EtherCAT-Geräte-Konstuktor.
    23    EtherCAT-Geräte-Konstuktor.
    23 
    24 */
    24    Initialisiert ein EtherCAT-Gerät, indem es die Variablen
    25 
    25    in der Struktur auf die Default-Werte setzt.
    26 int ec_device_init(ec_device_t *device, /**< EtherCAT-Gerät */
    26 
    27                    ec_master_t *master /**< Zugehöriger Master */
    27    @param ecd Zu initialisierendes EtherCAT-Gerät
    28                    )
    28 */
    29 {
    29 
    30     device->master = master;
    30 int ec_device_init(ec_device_t *ecd)
    31     device->dev = NULL;
    31 {
    32     device->open = 0;
    32     ecd->dev = NULL;
    33     device->tx_time = 0;
    33     ecd->open = 0;
    34     device->rx_time = 0;
    34     ecd->tx_time = 0;
    35     device->state = EC_DEVICE_STATE_READY;
    35     ecd->rx_time = 0;
    36     device->rx_data_size = 0;
    36     ecd->state = EC_DEVICE_STATE_READY;
    37     device->isr = NULL;
    37     ecd->rx_data_length = 0;
    38     device->module = NULL;
    38     ecd->isr = NULL;
    39     device->error_reported = 0;
    39     ecd->module = NULL;
    40 
    40     ecd->error_reported = 0;
    41     if ((device->tx_skb = dev_alloc_skb(ETH_HLEN + EC_MAX_FRAME_SIZE)) == NULL) {
    41 
       
    42     if ((ecd->tx_skb = dev_alloc_skb(ETH_HLEN + EC_MAX_FRAME_SIZE)) == NULL) {
       
    43         printk(KERN_ERR "EtherCAT: Error allocating device socket buffer!\n");
    42         printk(KERN_ERR "EtherCAT: Error allocating device socket buffer!\n");
    44         return -1;
    43         return -1;
    45     }
    44     }
    46 
    45 
    47     return 0;
    46     return 0;
    52 /**
    51 /**
    53    EtherCAT-Geräte-Destuktor.
    52    EtherCAT-Geräte-Destuktor.
    54 
    53 
    55    Gibt den dynamisch allozierten Speicher des
    54    Gibt den dynamisch allozierten Speicher des
    56    EtherCAT-Gerätes (die beiden Socket-Buffer) wieder frei.
    55    EtherCAT-Gerätes (die beiden Socket-Buffer) wieder frei.
    57 
    56 */
    58    @param ecd EtherCAT-Gerät
    57 
    59 */
    58 void ec_device_clear(ec_device_t *device /**< EtherCAT-Gerät */)
    60 
    59 {
    61 void ec_device_clear(ec_device_t *ecd)
    60     if (device->open) ec_device_close(device);
    62 {
    61 
    63     if (ecd->open) ec_device_close(ecd);
    62     device->dev = NULL;
    64 
    63 
    65     ecd->dev = NULL;
    64     if (device->tx_skb) {
    66 
    65         dev_kfree_skb(device->tx_skb);
    67     if (ecd->tx_skb) {
    66         device->tx_skb = NULL;
    68         dev_kfree_skb(ecd->tx_skb);
       
    69         ecd->tx_skb = NULL;
       
    70     }
    67     }
    71 }
    68 }
    72 
    69 
    73 /*****************************************************************************/
    70 /*****************************************************************************/
    74 
    71 
    77 
    74 
    78    Dies entspricht einem "ifconfig up". Vorher wird der Zeiger
    75    Dies entspricht einem "ifconfig up". Vorher wird der Zeiger
    79    auf das EtherCAT-Gerät auf Gültigkeit geprüft und der
    76    auf das EtherCAT-Gerät auf Gültigkeit geprüft und der
    80    Gerätezustand zurückgesetzt.
    77    Gerätezustand zurückgesetzt.
    81 
    78 
    82    @param ecd EtherCAT-Gerät
    79    \return 0 bei Erfolg, < 0: Ungültiger Zeiger, oder open()
    83 
    80            fehlgeschlagen
    84    @return 0 bei Erfolg, < 0: Ungültiger Zeiger, oder open()
    81 */
    85    fehlgeschlagen
    82 
    86 */
    83 int ec_device_open(ec_device_t *device /**< EtherCAT-Gerät */)
    87 
       
    88 int ec_device_open(ec_device_t *ecd)
       
    89 {
    84 {
    90     unsigned int i;
    85     unsigned int i;
    91 
    86 
    92     if (!ecd) {
    87     if (!device) {
    93         printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n");
    88         printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n");
    94         return -1;
    89         return -1;
    95     }
    90     }
    96 
    91 
    97     if (!ecd->dev) {
    92     if (!device->dev) {
    98         printk(KERN_ERR "EtherCAT: No net_device to open!\n");
    93         printk(KERN_ERR "EtherCAT: No net_device to open!\n");
    99         return -1;
    94         return -1;
   100     }
    95     }
   101 
    96 
   102     if (ecd->open) {
    97     if (device->open) {
   103         printk(KERN_WARNING "EtherCAT: Device already opened!\n");
    98         printk(KERN_WARNING "EtherCAT: Device already opened!\n");
   104     }
    99     }
   105     else {
   100     else {
   106         // Device could have received frames before
   101         // Device could have received frames before
   107         for (i = 0; i < 4; i++) ec_device_call_isr(ecd);
   102         for (i = 0; i < 4; i++) ec_device_call_isr(device);
   108 
   103 
   109         // Reset old device state
   104         // Reset old device state
   110         ecd->state = EC_DEVICE_STATE_READY;
   105         device->state = EC_DEVICE_STATE_READY;
   111 
   106 
   112         if (ecd->dev->open(ecd->dev) == 0) ecd->open = 1;
   107         if (device->dev->open(device->dev) == 0) device->open = 1;
   113     }
   108     }
   114 
   109 
   115     return ecd->open ? 0 : -1;
   110     return device->open ? 0 : -1;
   116 }
   111 }
   117 
   112 
   118 /*****************************************************************************/
   113 /*****************************************************************************/
   119 
   114 
   120 /**
   115 /**
   121    Führt die stop()-Funktion des net_devices aus.
   116    Führt die stop()-Funktion des net_devices aus.
   122 
   117 
   123    @param ecd EtherCAT-Gerät
   118    \return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen oder
   124 
       
   125    @return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen oder
       
   126    Schliessen fehlgeschlagen.
   119    Schliessen fehlgeschlagen.
   127 */
   120 */
   128 
   121 
   129 int ec_device_close(ec_device_t *ecd)
   122 int ec_device_close(ec_device_t *device /**< EtherCAT-Gerät */)
   130 {
   123 {
   131     if (!ecd->dev) {
   124     if (!device->dev) {
   132         printk(KERN_ERR "EtherCAT: No device to close!\n");
   125         printk(KERN_ERR "EtherCAT: No device to close!\n");
   133         return -1;
   126         return -1;
   134     }
   127     }
   135 
   128 
   136     if (!ecd->open) {
   129     if (!device->open) {
   137         printk(KERN_WARNING "EtherCAT: Device already closed!\n");
   130         printk(KERN_WARNING "EtherCAT: Device already closed!\n");
   138     }
   131     }
   139     else {
   132     else {
   140         if (ecd->dev->stop(ecd->dev) == 0) ecd->open = 0;
   133         if (device->dev->stop(device->dev) == 0) device->open = 0;
   141     }
   134     }
   142 
   135 
   143     return !ecd->open ? 0 : -1;
   136     return !device->open ? 0 : -1;
   144 }
   137 }
   145 
   138 
   146 /*****************************************************************************/
   139 /*****************************************************************************/
   147 
   140 
   148 /**
   141 /**
   149    Bereitet den geräteinternen Socket-Buffer auf den Versand vor.
   142    Bereitet den geräteinternen Socket-Buffer auf den Versand vor.
   150 
   143 
   151    \return Zeiger auf den Speicher, in den die Frame-Daten sollen.
   144    \return Zeiger auf den Speicher, in den die Frame-Daten sollen.
   152 */
   145 */
   153 
   146 
   154 uint8_t *ec_device_prepare(ec_device_t *ecd /**< EtherCAT-Gerät */)
   147 uint8_t *ec_device_prepare(ec_device_t *device /**< EtherCAT-Gerät */)
   155 {
   148 {
   156     // Clear transmit socket buffer and reserve space for Ethernet-II header
   149     // Clear transmit socket buffer and reserve space for Ethernet-II header
   157     skb_trim(ecd->tx_skb, 0);
   150     skb_trim(device->tx_skb, 0);
   158     skb_reserve(ecd->tx_skb, ETH_HLEN);
   151     skb_reserve(device->tx_skb, ETH_HLEN);
   159 
   152 
   160     // Erstmal Speicher für maximal langen Frame reservieren
   153     // Erstmal Speicher für maximal langen Frame reservieren
   161     return skb_put(ecd->tx_skb, EC_MAX_FRAME_SIZE);
   154     return skb_put(device->tx_skb, EC_MAX_FRAME_SIZE);
   162 }
   155 }
   163 
   156 
   164 /*****************************************************************************/
   157 /*****************************************************************************/
   165 
   158 
   166 /**
   159 /**
   172 
   165 
   173    \return 0 bei Erfolg, < 0: Vorheriger Rahmen noch
   166    \return 0 bei Erfolg, < 0: Vorheriger Rahmen noch
   174    nicht empfangen, oder kein Speicher mehr vorhanden
   167    nicht empfangen, oder kein Speicher mehr vorhanden
   175 */
   168 */
   176 
   169 
   177 void ec_device_send(ec_device_t *ecd, /**< EtherCAT-Gerät */
   170 void ec_device_send(ec_device_t *device, /**< EtherCAT-Gerät */
   178                     unsigned int length /**< Länge der zu sendenden Daten */
   171                     unsigned int length /**< Länge der zu sendenden Daten */
   179                     )
   172                     )
   180 {
   173 {
   181     struct ethhdr *eth;
   174     struct ethhdr *eth;
   182 
   175 
   183     // Framegroesse auf (jetzt bekannte) Laenge abschneiden
   176     // Framegroesse auf (jetzt bekannte) Laenge abschneiden
   184     skb_trim(ecd->tx_skb, length);
   177     skb_trim(device->tx_skb, length);
   185 
   178 
   186     // Ethernet-II-Header hinzufuegen
   179     // Ethernet-II-Header hinzufuegen
   187     eth = (struct ethhdr *) skb_push(ecd->tx_skb, ETH_HLEN);
   180     eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN);
   188     eth->h_proto = htons(0x88A4);
   181     eth->h_proto = htons(0x88A4);
   189     memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len);
   182     memcpy(eth->h_source, device->dev->dev_addr, device->dev->addr_len);
   190     memset(eth->h_dest, 0xFF, ecd->dev->addr_len);
   183     memset(eth->h_dest, 0xFF, device->dev->addr_len);
   191 
   184 
   192     ecd->state = EC_DEVICE_STATE_SENT;
   185     device->state = EC_DEVICE_STATE_SENT;
   193     ecd->rx_data_length = 0;
   186     device->rx_data_size = 0;
       
   187 
       
   188     if (unlikely(device->master->debug_level > 1)) {
       
   189         printk(KERN_DEBUG "EtherCAT: Sending frame:\n");
       
   190         ec_data_print(device->tx_skb->data + ETH_HLEN, device->tx_skb->len);
       
   191     }
   194 
   192 
   195     // Senden einleiten
   193     // Senden einleiten
   196     rdtscl(ecd->tx_time); // Get CPU cycles
   194     rdtscl(device->tx_time); // Get CPU cycles
   197     ecd->dev->hard_start_xmit(ecd->tx_skb, ecd->dev);
   195     device->dev->hard_start_xmit(device->tx_skb, device->dev);
   198 }
   196 }
   199 
   197 
   200 /*****************************************************************************/
   198 /*****************************************************************************/
   201 
   199 
   202 /**
   200 /**
   203    Gibt die Anzahl der empfangenen Bytes zurück.
   201    Gibt die Anzahl der empfangenen Bytes zurück.
   204 
   202 
   205    \return Empfangene Bytes, oder 0, wenn kein Frame empfangen wurde.
   203    \return Empfangene Bytes, oder 0, wenn kein Frame empfangen wurde.
   206 */
   204 */
   207 
   205 
   208 unsigned int ec_device_received(const ec_device_t *ecd)
   206 unsigned int ec_device_received(const ec_device_t *device)
   209 {
   207 {
   210     return ecd->rx_data_length;
   208     return device->rx_data_size;
   211 }
   209 }
   212 
   210 
   213 /*****************************************************************************/
   211 /*****************************************************************************/
   214 
   212 
   215 /**
   213 /**
   216    Gibt die empfangenen Daten zurück.
   214    Gibt die empfangenen Daten zurück.
   217 
   215 
   218    \return Adresse auf empfangene Daten.
   216    \return Adresse auf empfangene Daten.
   219 */
   217 */
   220 
   218 
   221 uint8_t *ec_device_data(ec_device_t *ecd)
   219 uint8_t *ec_device_data(ec_device_t *device)
   222 {
   220 {
   223     return ecd->rx_data;
   221     return device->rx_data;
   224 }
   222 }
   225 
   223 
   226 /*****************************************************************************/
   224 /*****************************************************************************/
   227 
   225 
   228 /**
   226 /**
   229    Ruft die Interrupt-Routine der Netzwerkkarte auf.
   227    Ruft die Interrupt-Routine der Netzwerkkarte auf.
   230 
   228 */
   231    @param ecd EtherCAT-Gerät
   229 
   232 
   230 void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */)
   233    @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0
   231 {
   234 */
   232     if (likely(device->isr)) device->isr(0, device->dev, NULL);
   235 
       
   236 void ec_device_call_isr(ec_device_t *ecd)
       
   237 {
       
   238     if (likely(ecd->isr)) ecd->isr(0, ecd->dev, NULL);
       
   239 }
   233 }
   240 
   234 
   241 /*****************************************************************************/
   235 /*****************************************************************************/
   242 
   236 
   243 /**
   237 /**
   244    Gibt alle Informationen über das Device-Objekt aus.
   238    Gibt alle Informationen über das Device-Objekt aus.
   245 
   239 */
   246    @param ecd EtherCAT-Gerät
   240 
   247 */
   241 void ec_device_print(ec_device_t *device /**< EtherCAT-Gerät */)
   248 
       
   249 void ec_device_print(ec_device_t *ecd)
       
   250 {
   242 {
   251     printk(KERN_DEBUG "---EtherCAT device information begin---\n");
   243     printk(KERN_DEBUG "---EtherCAT device information begin---\n");
   252 
   244 
   253     if (ecd)
   245     if (device)
   254     {
   246     {
   255         printk(KERN_DEBUG "Assigned net_device: %X\n",
   247         printk(KERN_DEBUG "Assigned net_device: %X\n",
   256                (unsigned) ecd->dev);
   248                (unsigned) device->dev);
   257         printk(KERN_DEBUG "Transmit socket buffer: %X\n",
   249         printk(KERN_DEBUG "Transmit socket buffer: %X\n",
   258                (unsigned) ecd->tx_skb);
   250                (unsigned) device->tx_skb);
   259         printk(KERN_DEBUG "Time of last transmission: %u\n",
   251         printk(KERN_DEBUG "Time of last transmission: %u\n",
   260                (unsigned) ecd->tx_time);
   252                (unsigned) device->tx_time);
   261         printk(KERN_DEBUG "Time of last receive: %u\n",
   253         printk(KERN_DEBUG "Time of last receive: %u\n",
   262                (unsigned) ecd->rx_time);
   254                (unsigned) device->rx_time);
   263         printk(KERN_DEBUG "Actual device state: %i\n",
   255         printk(KERN_DEBUG "Actual device state: %i\n",
   264                (int) ecd->state);
   256                (int) device->state);
   265         printk(KERN_DEBUG "Receive buffer: %X\n",
   257         printk(KERN_DEBUG "Receive buffer: %X\n",
   266                (unsigned) ecd->rx_data);
   258                (unsigned) device->rx_data);
   267         printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n",
   259         printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n",
   268                (unsigned) ecd->rx_data_length, EC_MAX_FRAME_SIZE);
   260                (unsigned) device->rx_data_size, EC_MAX_FRAME_SIZE);
   269     }
   261     }
   270     else
   262     else
   271     {
   263     {
   272         printk(KERN_DEBUG "Device is NULL!\n");
   264         printk(KERN_DEBUG "Device is NULL!\n");
   273     }
   265     }
   274 
   266 
   275     printk(KERN_DEBUG "---EtherCAT device information end---\n");
   267     printk(KERN_DEBUG "---EtherCAT device information end---\n");
   276 }
   268 }
   277 
   269 
       
   270 /*****************************************************************************/
       
   271 
       
   272 /**
       
   273    Gibt das letzte Rahmenpaar aus.
       
   274 */
       
   275 
       
   276 void ec_device_debug(const ec_device_t *device /**< EtherCAT-Gerät */)
       
   277 {
       
   278     printk(KERN_DEBUG "EtherCAT: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
       
   279     ec_data_print(device->tx_skb->data + ETH_HLEN, device->tx_skb->len);
       
   280     printk(KERN_DEBUG "------------------------------------------------\n");
       
   281     ec_data_print_diff(device->tx_skb->data + ETH_HLEN, device->rx_data,
       
   282                        device->rx_data_size);
       
   283     printk(KERN_DEBUG "EtherCAT: <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
       
   284 }
       
   285 
       
   286 /*****************************************************************************/
       
   287 
       
   288 /**
       
   289    Gibt Frame-Inhalte zwecks Debugging aus.
       
   290 */
       
   291 
       
   292 void ec_data_print(const uint8_t *data /**< Daten */,
       
   293                    size_t size /**< Anzahl Bytes */
       
   294                    )
       
   295 {
       
   296     size_t i;
       
   297 
       
   298     printk(KERN_DEBUG);
       
   299     for (i = 0; i < size; i++) {
       
   300         printk("%02X ", data[i]);
       
   301         if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG);
       
   302     }
       
   303     printk("\n");
       
   304 }
       
   305 
       
   306 /*****************************************************************************/
       
   307 
       
   308 /**
       
   309    Gibt Frame-Inhalte zwecks Debugging aus, differentiell.
       
   310 */
       
   311 
       
   312 void ec_data_print_diff(const uint8_t *d1, /**< Daten 1 */
       
   313                         const uint8_t *d2, /**< Daten 2 */
       
   314                         size_t size /** Anzahl Bytes */
       
   315                         )
       
   316 {
       
   317     size_t i;
       
   318 
       
   319     printk(KERN_DEBUG);
       
   320     for (i = 0; i < size; i++) {
       
   321         if (d1[i] == d2[i]) printk(".. ");
       
   322         else printk("%02X ", d2[i]);
       
   323         if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG);
       
   324     }
       
   325     printk("\n");
       
   326 }
       
   327 
   278 /******************************************************************************
   328 /******************************************************************************
   279  *
   329  *
   280  * Treiberschnittstelle
   330  * Treiberschnittstelle
   281  *
   331  *
   282  *****************************************************************************/
   332  *****************************************************************************/
   283 
   333 
   284 void EtherCAT_dev_state(ec_device_t *ecd, ec_device_state_t state)
   334 /**
   285 {
   335    Setzt den Zustand des EtherCAT-Gerätes.
   286     ecd->state = state;
   336 */
   287 }
   337 
   288 
   338 void EtherCAT_dev_state(ec_device_t *device,  /**< EtherCAT-Gerät */
   289 /*****************************************************************************/
   339                         ec_device_state_t state /**< Neuer Zustand */
   290 
   340                         )
   291 int EtherCAT_dev_is_ec(ec_device_t *ecd, struct net_device *dev)
   341 {
   292 {
   342     device->state = state;
   293     return ecd && ecd->dev == dev;
   343 }
   294 }
   344 
   295 
   345 /*****************************************************************************/
   296 /*****************************************************************************/
   346 
   297 
   347 /**
   298 void EtherCAT_dev_receive(ec_device_t *ecd, void *data, unsigned int size)
   348    Prüft, ob das Net-Device \a dev zum registrierten EtherCAT-Gerät gehört.
       
   349 */
       
   350 
       
   351 int EtherCAT_dev_is_ec(const ec_device_t *device,  /**< EtherCAT-Gerät */
       
   352                        const struct net_device *dev /**< Net-Device */
       
   353                        )
       
   354 {
       
   355     return device && device->dev == dev;
       
   356 }
       
   357 
       
   358 /*****************************************************************************/
       
   359 
       
   360 void EtherCAT_dev_receive(ec_device_t *device, const void *data, size_t size)
   299 {
   361 {
   300     // Copy received data to ethercat-device buffer
   362     // Copy received data to ethercat-device buffer
   301     memcpy(ecd->rx_data, data, size);
   363     memcpy(device->rx_data, data, size);
   302     ecd->rx_data_length = size;
   364     device->rx_data_size = size;
   303     ecd->state = EC_DEVICE_STATE_RECEIVED;
   365     device->state = EC_DEVICE_STATE_RECEIVED;
       
   366 
       
   367     if (unlikely(device->master->debug_level > 1)) {
       
   368         printk(KERN_DEBUG "EtherCAT: Received frame:\n");
       
   369         ec_data_print_diff(device->tx_skb->data + ETH_HLEN, device->rx_data,
       
   370                            device->rx_data_size);
       
   371     }
   304 }
   372 }
   305 
   373 
   306 /*****************************************************************************/
   374 /*****************************************************************************/
   307 
   375 
   308 EXPORT_SYMBOL(EtherCAT_dev_is_ec);
   376 EXPORT_SYMBOL(EtherCAT_dev_is_ec);