drivers/ec_device.c
changeset 39 6965c23a6826
parent 33 f4171b8aadf8
child 42 a22a202d0f42
equal deleted inserted replaced
38:3213cbbd58b7 39:6965c23a6826
     1 /****************************************************************
     1 /******************************************************************************
     2  *
     2  *
     3  *  e c _ d e v i c e . c
     3  *  e c _ d e v i c e . c
     4  *
     4  *
     5  *  Methoden für ein EtherCAT-Gerät.
     5  *  Methoden für ein EtherCAT-Gerät.
     6  *
     6  *
     7  *  $Date$
     7  *  $Id$
     8  *  $Author$
       
     9  *
     8  *
    10  ***************************************************************/
     9  *****************************************************************************/
    11 
    10 
    12 #include <linux/module.h>
    11 #include <linux/module.h>
    13 #include <linux/skbuff.h>
    12 #include <linux/skbuff.h>
    14 #include <linux/if_ether.h>
    13 #include <linux/if_ether.h>
    15 #include <linux/netdevice.h>
    14 #include <linux/netdevice.h>
    16 #include <linux/delay.h>
    15 #include <linux/delay.h>
    17 
    16 
    18 #include "ec_device.h"
    17 #include "ec_device.h"
    19 
    18 
    20 /***************************************************************/
    19 /*****************************************************************************/
    21 
    20 
    22 /**
    21 /**
    23    EtherCAT-Geräte-Konstuktor.
    22    EtherCAT-Geräte-Konstuktor.
    24 
    23 
    25    Initialisiert ein EtherCAT-Gerät, indem es die Variablen
    24    Initialisiert ein EtherCAT-Gerät, indem es die Variablen
    40   ecd->intr_cnt = 0;
    39   ecd->intr_cnt = 0;
    41   ecd->state = ECAT_DS_READY;
    40   ecd->state = ECAT_DS_READY;
    42   ecd->rx_data_length = 0;
    41   ecd->rx_data_length = 0;
    43   ecd->isr = NULL;
    42   ecd->isr = NULL;
    44   ecd->module = NULL;
    43   ecd->module = NULL;
    45 }
    44   ecd->error_reported = 0;
    46 
    45 }
    47 /***************************************************************/
    46 
       
    47 /*****************************************************************************/
    48 
    48 
    49 /**
    49 /**
    50    EtherCAT-Geräte-Destuktor.
    50    EtherCAT-Geräte-Destuktor.
    51 
    51 
    52    Gibt den dynamisch allozierten Speicher des
    52    Gibt den dynamisch allozierten Speicher des
    57 
    57 
    58 void EtherCAT_device_clear(EtherCAT_device_t *ecd)
    58 void EtherCAT_device_clear(EtherCAT_device_t *ecd)
    59 {
    59 {
    60   ecd->dev = NULL;
    60   ecd->dev = NULL;
    61 
    61 
    62   if (ecd->tx_skb)
    62   if (ecd->tx_skb) {
    63   {
       
    64     dev_kfree_skb(ecd->tx_skb);
    63     dev_kfree_skb(ecd->tx_skb);
    65     ecd->tx_skb = NULL;
    64     ecd->tx_skb = NULL;
    66   }
    65   }
    67 
    66 
    68   if (ecd->rx_skb)
    67   if (ecd->rx_skb) {
    69   {
       
    70     dev_kfree_skb(ecd->rx_skb);
    68     dev_kfree_skb(ecd->rx_skb);
    71     ecd->rx_skb = NULL;
    69     ecd->rx_skb = NULL;
    72   }
    70   }
    73 }
    71 }
    74 
    72 
    75 /***************************************************************/
    73 /*****************************************************************************/
    76 
    74 
    77 /**
    75 /**
    78    Weist einem EtherCAT-Gerät das entsprechende net_device zu.
    76    Weist einem EtherCAT-Gerät das entsprechende net_device zu.
    79 
    77 
    80    Prüft das net_device, allokiert Socket-Buffer in Sende- und
    78    Prüft das net_device, allokiert Socket-Buffer in Sende- und
    88 */
    86 */
    89 
    87 
    90 int EtherCAT_device_assign(EtherCAT_device_t *ecd,
    88 int EtherCAT_device_assign(EtherCAT_device_t *ecd,
    91                            struct net_device *dev)
    89                            struct net_device *dev)
    92 {
    90 {
    93   if (!dev)
    91   if (!dev) {
    94   {
       
    95     printk("EtherCAT: Device is NULL!\n");
    92     printk("EtherCAT: Device is NULL!\n");
    96     return -1;
    93     return -1;
    97   }
    94   }
    98 
    95 
    99   if ((ecd->tx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL)
    96   if ((ecd->tx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) {
   100   {
       
   101     printk(KERN_ERR "EtherCAT: Could not allocate device tx socket buffer!\n");
    97     printk(KERN_ERR "EtherCAT: Could not allocate device tx socket buffer!\n");
   102     return -1;
    98     return -1;
   103   }
    99   }
   104 
   100 
   105   if ((ecd->rx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL)
   101   if ((ecd->rx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) {
   106   {
       
   107     dev_kfree_skb(ecd->tx_skb);
   102     dev_kfree_skb(ecd->tx_skb);
   108     ecd->tx_skb = NULL;
   103     ecd->tx_skb = NULL;
   109 
       
   110     printk(KERN_ERR "EtherCAT: Could not allocate device rx socket buffer!\n");
   104     printk(KERN_ERR "EtherCAT: Could not allocate device rx socket buffer!\n");
   111     return -1;
   105     return -1;
   112   }
   106   }
   113 
   107 
   114   ecd->dev = dev;
   108   ecd->dev = dev;
   118   printk("EtherCAT: Assigned Device %X.\n", (unsigned) dev);
   112   printk("EtherCAT: Assigned Device %X.\n", (unsigned) dev);
   119 
   113 
   120   return 0;
   114   return 0;
   121 }
   115 }
   122 
   116 
   123 /***************************************************************/
   117 /*****************************************************************************/
   124 
   118 
   125 /**
   119 /**
   126    Führt die open()-Funktion des Netzwerktreibers aus.
   120    Führt die open()-Funktion des Netzwerktreibers aus.
   127 
   121 
   128    Dies entspricht einem "ifconfig up". Vorher wird der Zeiger
   122    Dies entspricht einem "ifconfig up". Vorher wird der Zeiger
   135    fehlgeschlagen
   129    fehlgeschlagen
   136 */
   130 */
   137 
   131 
   138 int EtherCAT_device_open(EtherCAT_device_t *ecd)
   132 int EtherCAT_device_open(EtherCAT_device_t *ecd)
   139 {
   133 {
   140   if (!ecd)
   134   if (!ecd) {
   141   {
       
   142     printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n");
   135     printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n");
   143     return -1;
   136     return -1;
   144   }
   137   }
   145 
   138 
   146   if (!ecd->dev)
   139   if (!ecd->dev) {
   147   {
       
   148     printk(KERN_ERR "EtherCAT: No net_device to open!\n");
   140     printk(KERN_ERR "EtherCAT: No net_device to open!\n");
   149     return -1;
   141     return -1;
   150   }
   142   }
   151 
   143 
   152   // Reset old device state
   144   // Reset old device state
   155   ecd->rx_intr_cnt = 0;
   147   ecd->rx_intr_cnt = 0;
   156 
   148 
   157   return ecd->dev->open(ecd->dev);
   149   return ecd->dev->open(ecd->dev);
   158 }
   150 }
   159 
   151 
   160 /***************************************************************/
   152 /*****************************************************************************/
   161 
   153 
   162 /**
   154 /**
   163    Führt die stop()-Funktion des net_devices aus.
   155    Führt die stop()-Funktion des net_devices aus.
   164 
   156 
   165    @param ecd EtherCAT-Gerät
   157    @param ecd EtherCAT-Gerät
   167    @return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen
   159    @return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen
   168 */
   160 */
   169 
   161 
   170 int EtherCAT_device_close(EtherCAT_device_t *ecd)
   162 int EtherCAT_device_close(EtherCAT_device_t *ecd)
   171 {
   163 {
   172   if (!ecd->dev)
   164   if (!ecd->dev) {
   173   {
       
   174     printk("EtherCAT: No device to close!\n");
   165     printk("EtherCAT: No device to close!\n");
   175     return -1;
   166     return -1;
   176   }
   167   }
   177 
   168 
   178   printk("EtherCAT: Stopping device (txcnt: %u, rxcnt: %u)\n",
   169   printk("EtherCAT: Stopping device (txcnt: %u, rxcnt: %u)\n",
   180          (unsigned int) ecd->rx_intr_cnt);
   171          (unsigned int) ecd->rx_intr_cnt);
   181 
   172 
   182   return ecd->dev->stop(ecd->dev);
   173   return ecd->dev->stop(ecd->dev);
   183 }
   174 }
   184 
   175 
   185 /***************************************************************/
   176 /*****************************************************************************/
   186 
   177 
   187 /**
   178 /**
   188    Sendet einen Rahmen über das EtherCAT-Gerät.
   179    Sendet einen Rahmen über das EtherCAT-Gerät.
   189 
   180 
   190    Kopiert die zu sendenden Daten in den statischen Socket-
   181    Kopiert die zu sendenden Daten in den statischen Socket-
   204                          unsigned int length)
   195                          unsigned int length)
   205 {
   196 {
   206   unsigned char *frame_data;
   197   unsigned char *frame_data;
   207   struct ethhdr *eth;
   198   struct ethhdr *eth;
   208 
   199 
   209   if (ecd->state == ECAT_DS_SENT)
   200   if (unlikely(ecd->state == ECAT_DS_SENT)) {
   210   {
   201     printk(KERN_WARNING "EtherCAT: Warning - Trying to send frame"
   211     printk(KERN_WARNING "EtherCAT: Trying to send frame while last was not received!\n");
   202            " while last was not received!\n");
   212   }
   203   }
   213 
   204 
   214   skb_trim(ecd->tx_skb, 0); // Clear transmit socket buffer
   205   // Clear transmit socket buffer and reserve
   215   skb_reserve(ecd->tx_skb, ETH_HLEN); // Reserve space for Ethernet-II header
   206   // space for Ethernet-II header
       
   207   skb_trim(ecd->tx_skb, 0);
       
   208   skb_reserve(ecd->tx_skb, ETH_HLEN);
   216 
   209 
   217   // Copy data to socket buffer
   210   // Copy data to socket buffer
   218   frame_data = skb_put(ecd->tx_skb, length);
   211   frame_data = skb_put(ecd->tx_skb, length);
   219   memcpy(frame_data, data, length);
   212   memcpy(frame_data, data, length);
   220 
   213 
   221   // Add Ethernet-II-Header
   214   // Add Ethernet-II-Header
   222   if ((eth = (struct ethhdr *) skb_push(ecd->tx_skb, ETH_HLEN)) == NULL)
   215   if (unlikely((eth = (struct ethhdr *)
   223   {
   216                 skb_push(ecd->tx_skb, ETH_HLEN)) == NULL)) {
   224     printk(KERN_ERR "EtherCAT: device_send - Could not allocate Ethernet-II header!\n");
   217     printk(KERN_ERR "EtherCAT: device_send -"
   225     return -1;
   218            " Could not allocate Ethernet-II header!\n");
   226   }
   219     return -1;
   227 
   220   }
   228   eth->h_proto = htons(0x88A4); // Protocol type
   221 
   229   memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len); // Hardware address
   222   // Protocol type
   230   memset(eth->h_dest, 0xFF, ecd->dev->addr_len); // Broadcast address
   223   eth->h_proto = htons(0x88A4);
       
   224   // Hardware address
       
   225   memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len);
       
   226   // Broadcast address
       
   227   memset(eth->h_dest, 0xFF, ecd->dev->addr_len);
   231 
   228 
   232   rdtscl(ecd->tx_time); // Get CPU cycles
   229   rdtscl(ecd->tx_time); // Get CPU cycles
   233 
   230 
   234   // Start sending of frame
   231   // Start sending of frame
   235   ecd->state = ECAT_DS_SENT;
   232   ecd->state = ECAT_DS_SENT;
   236   ecd->dev->hard_start_xmit(ecd->tx_skb, ecd->dev);
   233   ecd->dev->hard_start_xmit(ecd->tx_skb, ecd->dev);
   237 
   234 
   238   return 0;
   235   return 0;
   239 }
   236 }
   240 
   237 
   241 /***************************************************************/
   238 /*****************************************************************************/
   242 
   239 
   243 /**
   240 /**
   244    Holt einen empfangenen Rahmen von der Netzwerkkarte.
   241    Holt einen empfangenen Rahmen von der Netzwerkkarte.
   245 
   242 
   246    Zuerst wird geprüft, ob überhaupt ein Rahmen empfangen
   243    Zuerst wird geprüft, ob überhaupt ein Rahmen empfangen
   247    wurde. Wenn ja, wird diesem mit Hilfe eines Spin-Locks
   244    wurde. Wenn ja, wird dieser in den angegebenen
   248    in den angegebenen Speicherbereich kopiert.
   245    Speicherbereich kopiert.
   249 
   246 
   250    @param ecd EtherCAT-Gerät
   247    @param ecd EtherCAT-Gerät
   251    @param data Zeiger auf den Speicherbereich, in den die
   248    @param data Zeiger auf den Speicherbereich, in den die
   252                empfangenen Daten kopiert werden sollen
   249                empfangenen Daten kopiert werden sollen
   253 
   250 
   255 */
   252 */
   256 
   253 
   257 int EtherCAT_device_receive(EtherCAT_device_t *ecd,
   254 int EtherCAT_device_receive(EtherCAT_device_t *ecd,
   258                             unsigned char *data)
   255                             unsigned char *data)
   259 {
   256 {
   260   if (ecd->state != ECAT_DS_RECEIVED)
   257   if (unlikely(ecd->state != ECAT_DS_RECEIVED)) {
   261   {
   258     if (likely(ecd->error_reported)) {
   262     printk(KERN_ERR "EtherCAT: receive - Nothing received!\n");
   259       printk(KERN_ERR "EtherCAT: receive - Nothing received!\n");
   263     return -1;
   260       ecd->error_reported = 1;
   264   }
   261     }
   265 
   262     return -1;
   266   if (ecd->rx_data_length > ECAT_FRAME_BUFFER_SIZE)
   263   }
   267   {
   264 
   268     printk(KERN_ERR "EtherCAT: receive - Reveived frame too long (%i Bytes)!\n",
   265   if (unlikely(ecd->rx_data_length > ECAT_FRAME_BUFFER_SIZE)) {
   269            ecd->rx_data_length);
   266     if (likely(ecd->error_reported)) {
   270     return -1;
   267       printk(KERN_ERR "EtherCAT: receive - "
       
   268              " Reveived frame too long (%i Bytes)!\n",
       
   269              ecd->rx_data_length);
       
   270       ecd->error_reported = 1;
       
   271     }
       
   272     return -1;
       
   273   }
       
   274 
       
   275   if (unlikely(ecd->error_reported)) {
       
   276     ecd->error_reported = 0;
   271   }
   277   }
   272 
   278 
   273   memcpy(data, ecd->rx_data, ecd->rx_data_length);
   279   memcpy(data, ecd->rx_data, ecd->rx_data_length);
   274 
   280 
   275   return ecd->rx_data_length;
   281   return ecd->rx_data_length;
   276 }
   282 }
   277 
   283 
   278 /***************************************************************/
   284 /*****************************************************************************/
   279 
   285 
   280 /**
   286 /**
   281    Ruft manuell die Interrupt-Routine der Netzwerkkarte auf.
   287    Ruft manuell die Interrupt-Routine der Netzwerkkarte auf.
   282 
   288 
   283    @param ecd EtherCAT-Gerät
   289    @param ecd EtherCAT-Gerät
   285    @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0
   291    @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0
   286 */
   292 */
   287 
   293 
   288 void EtherCAT_device_call_isr(EtherCAT_device_t *ecd)
   294 void EtherCAT_device_call_isr(EtherCAT_device_t *ecd)
   289 {
   295 {
   290     if (ecd->isr) ecd->isr(0, ecd->dev, NULL);
   296   if (likely(ecd->isr)) ecd->isr(0, ecd->dev, NULL);
   291 }
   297 }
   292 
   298 
   293 /***************************************************************/
   299 /*****************************************************************************/
   294 
   300 
   295 /**
   301 /**
   296    Gibt alle Informationen über das Device-Objekt aus.
   302    Gibt alle Informationen über das Device-Objekt aus.
   297 
   303 
   298    @param ecd EtherCAT-Gerät
   304    @param ecd EtherCAT-Gerät
   302 {
   308 {
   303   printk(KERN_DEBUG "---EtherCAT device information begin---\n");
   309   printk(KERN_DEBUG "---EtherCAT device information begin---\n");
   304 
   310 
   305   if (ecd)
   311   if (ecd)
   306   {
   312   {
   307     printk(KERN_DEBUG "Assigned net_device: %X\n", (unsigned) ecd->dev);
   313     printk(KERN_DEBUG "Assigned net_device: %X\n",
   308     printk(KERN_DEBUG "Transmit socket buffer: %X\n", (unsigned) ecd->tx_skb);
   314            (unsigned) ecd->dev);
   309     printk(KERN_DEBUG "Receive socket buffer: %X\n", (unsigned) ecd->rx_skb);
   315     printk(KERN_DEBUG "Transmit socket buffer: %X\n",
   310     printk(KERN_DEBUG "Time of last transmission: %u\n", (unsigned) ecd->tx_time);
   316            (unsigned) ecd->tx_skb);
   311     printk(KERN_DEBUG "Time of last receive: %u\n", (unsigned) ecd->rx_time);
   317     printk(KERN_DEBUG "Receive socket buffer: %X\n",
   312     printk(KERN_DEBUG "Number of transmit interrupts: %u\n", (unsigned) ecd->tx_intr_cnt);
   318            (unsigned) ecd->rx_skb);
   313     printk(KERN_DEBUG "Number of receive interrupts: %u\n", (unsigned) ecd->rx_intr_cnt);
   319     printk(KERN_DEBUG "Time of last transmission: %u\n",
   314     printk(KERN_DEBUG "Total Number of interrupts: %u\n", (unsigned) ecd->intr_cnt);
   320            (unsigned) ecd->tx_time);
   315     printk(KERN_DEBUG "Actual device state: %i\n", (int) ecd->state);
   321     printk(KERN_DEBUG "Time of last receive: %u\n",
   316     printk(KERN_DEBUG "Receive buffer: %X\n", (unsigned) ecd->rx_data);
   322            (unsigned) ecd->rx_time);
       
   323     printk(KERN_DEBUG "Number of transmit interrupts: %u\n",
       
   324            (unsigned) ecd->tx_intr_cnt);
       
   325     printk(KERN_DEBUG "Number of receive interrupts: %u\n",
       
   326            (unsigned) ecd->rx_intr_cnt);
       
   327     printk(KERN_DEBUG "Total Number of interrupts: %u\n",
       
   328            (unsigned) ecd->intr_cnt);
       
   329     printk(KERN_DEBUG "Actual device state: %i\n",
       
   330            (int) ecd->state);
       
   331     printk(KERN_DEBUG "Receive buffer: %X\n",
       
   332            (unsigned) ecd->rx_data);
   317     printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n",
   333     printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n",
   318            (unsigned) ecd->rx_data_length, ECAT_FRAME_BUFFER_SIZE);
   334            (unsigned) ecd->rx_data_length, ECAT_FRAME_BUFFER_SIZE);
   319   }
   335   }
   320   else
   336   else
   321   {
   337   {
   323   }
   339   }
   324 
   340 
   325   printk(KERN_DEBUG "---EtherCAT device information end---\n");
   341   printk(KERN_DEBUG "---EtherCAT device information end---\n");
   326 }
   342 }
   327 
   343 
   328 /***************************************************************/
   344 /*****************************************************************************/
   329 
   345 
   330 EXPORT_SYMBOL(EtherCAT_device_init);
   346 EXPORT_SYMBOL(EtherCAT_device_init);
   331 EXPORT_SYMBOL(EtherCAT_device_clear);
   347 EXPORT_SYMBOL(EtherCAT_device_clear);
   332 EXPORT_SYMBOL(EtherCAT_device_assign);
   348 EXPORT_SYMBOL(EtherCAT_device_assign);
   333 EXPORT_SYMBOL(EtherCAT_device_open);
   349 EXPORT_SYMBOL(EtherCAT_device_open);
   334 EXPORT_SYMBOL(EtherCAT_device_close);
   350 EXPORT_SYMBOL(EtherCAT_device_close);
   335 
   351 
   336 /***************************************************************/
   352 /*****************************************************************************/