master/device.c
changeset 693 e341f1788608
parent 692 fe7cf37c33f1
child 725 8bacb27f3aa2
equal deleted inserted replaced
692:fe7cf37c33f1 693:e341f1788608
    67 
    67 
    68 int ec_device_init(ec_device_t *device, /**< EtherCAT device */
    68 int ec_device_init(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;
       
    73     struct ethhdr *eth;
    72 #ifdef EC_DEBUG_IF
    74 #ifdef EC_DEBUG_IF
    73     char ifname[10];
    75     char ifname[10];
    74     char mb = 'x';
    76     char mb = 'x';
    75 #endif
    77 #endif
    76 #ifdef EC_DEBUG_RING
    78 #ifdef EC_DEBUG_RING
    77     device->debug_frame_index = 0;
    79     device->debug_frame_index = 0;
    78     device->debug_frame_count = 0;
    80     device->debug_frame_count = 0;
    79 #endif
    81 #endif
    80 
    82 
    81     device->master = master;
    83     device->master = master;
       
    84     device->tx_ring_index = 0;
    82 
    85 
    83 #ifdef EC_DEBUG_IF
    86 #ifdef EC_DEBUG_IF
    84     if (device == &master->main_device)
    87     if (device == &master->main_device)
    85         mb = 'm';
    88         mb = 'm';
    86     else if (device == &master->backup_device)
    89     else if (device == &master->backup_device)
    92         EC_ERR("Failed to init debug device!\n");
    95         EC_ERR("Failed to init debug device!\n");
    93         goto out_return;
    96         goto out_return;
    94     }
    97     }
    95 #endif
    98 #endif
    96 
    99 
    97     if (!(device->tx_skb = dev_alloc_skb(ETH_FRAME_LEN))) {
   100     for (i = 0; i < EC_TX_RING_SIZE; i++)
    98         EC_ERR("Error allocating device socket buffer!\n");
   101         device->tx_skb[i] = NULL;
    99 #ifdef EC_DEBUG_IF
   102 
   100         goto out_debug;
   103     for (i = 0; i < EC_TX_RING_SIZE; i++) {
   101 #else
   104         if (!(device->tx_skb[i] = dev_alloc_skb(ETH_FRAME_LEN))) {
   102         goto out_return;
   105             EC_ERR("Error allocating device socket buffer!\n");
   103 #endif
   106             goto out_tx_ring;
   104     }
   107         }
   105 
   108 
   106     // add Ethernet-II-header
   109         // add Ethernet-II-header
   107     skb_reserve(device->tx_skb, ETH_HLEN);
   110         skb_reserve(device->tx_skb[i], ETH_HLEN);
   108     device->eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN);
   111         eth = (struct ethhdr *) skb_push(device->tx_skb[i], ETH_HLEN);
   109     device->eth->h_proto = htons(0x88A4);
   112         eth->h_proto = htons(0x88A4);
   110     memset(device->eth->h_dest, 0xFF, ETH_ALEN);
   113         memset(eth->h_dest, 0xFF, ETH_ALEN);
       
   114     }
   111 
   115 
   112     ec_device_detach(device); // resets remaining fields
   116     ec_device_detach(device); // resets remaining fields
   113     return 0;
   117     return 0;
   114 
   118 
   115 #ifdef EC_DEBUG_IF
   119 out_tx_ring:
   116  out_debug:
   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
   117     ec_debug_clear(&device->dbg);
   124     ec_debug_clear(&device->dbg);
   118 #endif
   125 out_return:
   119  out_return:
   126 #endif
   120     return -1;
   127     return -1;
   121 }
   128 }
   122 
   129 
   123 /*****************************************************************************/
   130 /*****************************************************************************/
   124 
   131 
   126    EtherCAT device destuctor.
   133    EtherCAT device destuctor.
   127 */
   134 */
   128 
   135 
   129 void ec_device_clear(ec_device_t *device /**< EtherCAT device */)
   136 void ec_device_clear(ec_device_t *device /**< EtherCAT device */)
   130 {
   137 {
       
   138     unsigned int i;
       
   139 
   131     if (device->open) ec_device_close(device);
   140     if (device->open) ec_device_close(device);
   132     dev_kfree_skb(device->tx_skb);
   141     for (i = 0; i < EC_TX_RING_SIZE; i++)
       
   142         dev_kfree_skb(device->tx_skb[i]);
   133 #ifdef EC_DEBUG_IF
   143 #ifdef EC_DEBUG_IF
   134     ec_debug_clear(&device->dbg);
   144     ec_debug_clear(&device->dbg);
   135 #endif
   145 #endif
   136 }
   146 }
   137 
   147 
   145         struct net_device *net_dev, /**< net_device structure */
   155         struct net_device *net_dev, /**< net_device structure */
   146         ec_pollfunc_t poll, /**< pointer to device's poll function */
   156         ec_pollfunc_t poll, /**< pointer to device's poll function */
   147         struct module *module /**< the device's module */
   157         struct module *module /**< the device's module */
   148         )
   158         )
   149 {
   159 {
       
   160     unsigned int i;
       
   161     struct ethhdr *eth;
       
   162 
   150     ec_device_detach(device); // resets fields
   163     ec_device_detach(device); // resets fields
   151 
   164 
   152     device->dev = net_dev;
   165     device->dev = net_dev;
   153     device->poll = poll;
   166     device->poll = poll;
   154     device->module = module;
   167     device->module = module;
   155 
   168 
   156     device->tx_skb->dev = net_dev;
   169     for (i = 0; i < EC_TX_RING_SIZE; i++) {
   157     memcpy(device->eth->h_source, net_dev->dev_addr, ETH_ALEN);
   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     }
   158 }
   174 }
   159 
   175 
   160 /*****************************************************************************/
   176 /*****************************************************************************/
   161 
   177 
   162 /**
   178 /**
   163    Disconnect from net_device.
   179    Disconnect from net_device.
   164 */
   180 */
   165 
   181 
   166 void ec_device_detach(ec_device_t *device /**< EtherCAT device */)
   182 void ec_device_detach(ec_device_t *device /**< EtherCAT device */)
   167 {
   183 {
       
   184     unsigned int i;
       
   185 
   168     device->dev = NULL;
   186     device->dev = NULL;
   169     device->poll = NULL;
   187     device->poll = NULL;
   170     device->module = NULL;
   188     device->module = NULL;
   171     device->open = 0;
   189     device->open = 0;
   172     device->link_state = 0; // down
   190     device->link_state = 0; // down
   173     device->tx_count = 0;
   191     device->tx_count = 0;
   174     device->rx_count = 0;
   192     device->rx_count = 0;
   175     device->tx_skb->dev = NULL;
   193     for (i = 0; i < EC_TX_RING_SIZE; i++)
       
   194         device->tx_skb[i]->dev = NULL;
   176 }
   195 }
   177 
   196 
   178 /*****************************************************************************/
   197 /*****************************************************************************/
   179 
   198 
   180 /**
   199 /**
   234    \return pointer to the TX socket buffer
   253    \return pointer to the TX socket buffer
   235 */
   254 */
   236 
   255 
   237 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 */)
   238 {
   257 {
   239     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;
   240 }
   264 }
   241 
   265 
   242 /*****************************************************************************/
   266 /*****************************************************************************/
   243 
   267 
   244 /**
   268 /**
   249 
   273 
   250 void ec_device_send(ec_device_t *device, /**< EtherCAT device */
   274 void ec_device_send(ec_device_t *device, /**< EtherCAT device */
   251                     size_t size /**< number of bytes to send */
   275                     size_t size /**< number of bytes to send */
   252                     )
   276                     )
   253 {
   277 {
       
   278     struct sk_buff *skb = device->tx_skb[device->tx_ring_index];
       
   279 
   254     if (unlikely(!device->link_state)) // Link down
   280     if (unlikely(!device->link_state)) // Link down
   255         return;
   281         return;
   256 
   282 
   257     // set the right length for the data
   283     // set the right length for the data
   258     device->tx_skb->len = ETH_HLEN + size;
   284     skb->len = ETH_HLEN + size;
   259 
   285 
   260     if (unlikely(device->master->debug_level > 1)) {
   286     if (unlikely(device->master->debug_level > 1)) {
   261         EC_DBG("sending frame:\n");
   287         EC_DBG("sending frame:\n");
   262         ec_print_data(device->tx_skb->data + ETH_HLEN, size);
   288         ec_print_data(skb->data + ETH_HLEN, size);
   263     }
   289     }
   264 
   290 
   265 #ifdef EC_DEBUG_IF
   291 #ifdef EC_DEBUG_IF
   266     ec_debug_send(&device->dbg, device->tx_skb->data, ETH_HLEN + size);
   292     ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size);
   267 #endif
   293 #endif
   268 #ifdef EC_DEBUG_RING
   294 #ifdef EC_DEBUG_RING
   269     ec_device_debug_ring_append(
   295     ec_device_debug_ring_append(
   270             device, TX, device->tx_skb->data + ETH_HLEN, size);
   296             device, TX, skb->data + ETH_HLEN, size);
   271 #endif
   297 #endif
   272 
   298 
   273     // start sending
   299     // start sending
   274     device->dev->hard_start_xmit(device->tx_skb, device->dev);
   300     device->dev->hard_start_xmit(skb, device->dev);
   275     device->tx_count++;
   301     device->tx_count++;
   276 }
   302 }
   277 
   303 
   278 /*****************************************************************************/
   304 /*****************************************************************************/
   279 
   305 
   387     size_t ec_size = size - ETH_HLEN;
   413     size_t ec_size = size - ETH_HLEN;
   388     device->rx_count++;
   414     device->rx_count++;
   389 
   415 
   390     if (unlikely(device->master->debug_level > 1)) {
   416     if (unlikely(device->master->debug_level > 1)) {
   391         EC_DBG("Received frame:\n");
   417         EC_DBG("Received frame:\n");
   392         ec_print_data_diff(device->tx_skb->data + ETH_HLEN, ec_data, ec_size);
   418         ec_print_data(ec_data, ec_size);
   393     }
   419     }
   394 
   420 
   395 #ifdef EC_DEBUG_IF
   421 #ifdef EC_DEBUG_IF
   396     ec_debug_send(&device->dbg, data, size);
   422     ec_debug_send(&device->dbg, data, size);
   397 #endif
   423 #endif