Hi,

I want to use the etherlabmaster for the linux kernel 3.18. Due to the fact that I found no driver I tried to create one. While creating a new driver for the e1000e is straight forward, there are two parts in the source code which changed in a way that I don't know I there are any changes needed.

file: e1000_main-3.16-ethercat.c

in procedure: e1000_clean_jumbo_rx_irq



line 4149:

        if (!adapter->ecdev) {

                buffer_info->skb = NULL;

        }



line 4271:

        if (!adapter->ecdev) {

                dev_kfree_skb(skb);     

        }


All other parts are more or less directly found in the corresponding lines.

My change as a diff:


--- e1000_main-3.18-orig.c      2016-06-29 10:16:00.000000000 +0200
+++ e1000_main-3.18-ethercat.c  2016-06-29 11:42:54.000000000 +0200
@@ -26,14 +26,14 @@


*******************************************************************************/

-#include "e1000.h"
+#include "e1000-3.18-ethercat.h"
 #include <net/ip6_checksum.h>
 #include <linux/io.h>
 #include <linux/prefetch.h>
 #include <linux/bitops.h>
 #include <linux/if_vlan.h>

-char e1000_driver_name[] = "e1000";
+char e1000_driver_name[] = "ec_e1000";
 static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
 #define DRV_VERSION "7.3.21-k8-NAPI"
 const char e1000_driver_version[] = DRV_VERSION;
@@ -88,7 +88,7 @@
        {0,}
 };

-MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
+//MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);

 int e1000_up(struct e1000_adapter *adapter);
 void e1000_down(struct e1000_adapter *adapter);
@@ -220,7 +220,7 @@
 };

 MODULE_AUTHOR("Intel Corporation, <[email protected]>");
-MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
+MODULE_DESCRIPTION("EtherCAT-capable Intel(R) PRO/1000 Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);

@@ -286,6 +286,10 @@
        int irq_flags = IRQF_SHARED;
        int err;

+       if (adapter->ecdev) {
+               return 0;
+       }
+       
        err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
                          netdev);
        if (err) {
@@ -298,6 +302,10 @@
 static void e1000_free_irq(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
+       
+       if (adapter->ecdev) {
+               return;
+       }

        free_irq(adapter->pdev->irq, netdev);
 }
@@ -310,6 +318,10 @@
 {
        struct e1000_hw *hw = &adapter->hw;

+       if (adapter->ecdev) {
+               return;
+       }
+       
        ew32(IMC, ~0);
        E1000_WRITE_FLUSH();
        synchronize_irq(adapter->pdev->irq);
@@ -323,6 +335,10 @@
 {
        struct e1000_hw *hw = &adapter->hw;

+       if (adapter->ecdev) {
+               return;
+       }
+       
        ew32(IMS, IMS_ENABLE_MASK);
        E1000_WRITE_FLUSH();
 }
@@ -406,8 +422,14 @@
         */
        for (i = 0; i < adapter->num_rx_queues; i++) {
                struct e1000_rx_ring *ring = &adapter->rx_ring[i];
-               adapter->alloc_rx_buf(adapter, ring,
+               if (adapter->ecdev) {
+                       /* fill rx ring completely! */
+                       adapter->alloc_rx_buf(adapter, ring, ring->count);
+               } else {
+                       /* this one leavees the last ring element unallocated */
+                       adapter->alloc_rx_buf(adapter, ring,
                                      E1000_DESC_UNUSED(ring));
+               }
        }
 }

@@ -420,14 +442,16 @@

        clear_bit(__E1000_DOWN, &adapter->flags);

-       napi_enable(&adapter->napi);
+       if (!adapter->ecdev) {
+               napi_enable(&adapter->napi);

-       e1000_irq_enable(adapter);
+               e1000_irq_enable(adapter);

-       netif_wake_queue(adapter->netdev);
+               netif_wake_queue(adapter->netdev);

-       /* fire a link change interrupt to start the watchdog */
-       ew32(ICS, E1000_ICS_LSC);
+               /* fire a link change interrupt to start the watchdog */
+               ew32(ICS, E1000_ICS_LSC);
+       }
        return 0;
 }

@@ -499,7 +523,9 @@
 {
        set_bit(__E1000_DOWN, &adapter->flags);

-       cancel_delayed_work_sync(&adapter->watchdog_task);
+       if (!adapter->ecdev) {
+               cancel_delayed_work_sync(&adapter->watchdog_task);
+       }

        /*
         * Since the watchdog task can reschedule other tasks, we should cancel
@@ -507,11 +533,13 @@
         * still running after the adapter has been turned down.
         */

-       cancel_delayed_work_sync(&adapter->phy_info_task);
-       cancel_delayed_work_sync(&adapter->fifo_stall_task);
+       if (!adapter->ecdev) {
+               cancel_delayed_work_sync(&adapter->phy_info_task);
+               cancel_delayed_work_sync(&adapter->fifo_stall_task);
+       }

        /* Only kill reset task if adapter is not resetting */
-       if (!test_bit(__E1000_RESETTING, &adapter->flags))
+       if (!adapter->ecdev && !test_bit(__E1000_RESETTING, &adapter->flags))
                cancel_work_sync(&adapter->reset_task);
 }

@@ -525,9 +553,11 @@
        /* disable receives in the hardware */
        rctl = er32(RCTL);
        ew32(RCTL, rctl & ~E1000_RCTL_EN);
-       /* flush and sleep below */

-       netif_tx_disable(netdev);
+       if (!adapter->ecdev) {
+               /* flush and sleep below */
+               netif_tx_disable(netdev);
+       }

        /* disable transmits in the hardware */
        tctl = er32(TCTL);
@@ -537,9 +567,11 @@
        E1000_WRITE_FLUSH();
        msleep(10);

-       napi_disable(&adapter->napi);
+       if (!adapter->ecdev) {
+               napi_disable(&adapter->napi);

-       e1000_irq_disable(adapter);
+               e1000_irq_disable(adapter);
+       }

        /* Setting DOWN must be after irq_disable to prevent
         * a screaming interrupt.  Setting DOWN also prevents
@@ -549,7 +581,10 @@

        adapter->link_speed = 0;
        adapter->link_duplex = 0;
-       netif_carrier_off(netdev);
+       
+       if (!adapter->ecdev) {
+               netif_carrier_off(netdev);
+       }

        e1000_reset(adapter);
        e1000_clean_all_tx_rings(adapter);
@@ -1211,10 +1246,20 @@
        /* reset the hardware with the new settings */
        e1000_reset(adapter);

-       strcpy(netdev->name, "eth%d");
-       err = register_netdev(netdev);
-       if (err)
-               goto err_register;
+       // offer device to EtherCAT master module
+       adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
+       if (adapter->ecdev) {
+               err = ecdev_open(adapter->ecdev);
+               if (err) {
+                       ecdev_withdraw(adapter->ecdev);
+                       goto err_register;
+               }
+       } else {
+               strcpy(netdev->name, "eth%d");
+               err = register_netdev(netdev);
+               if (err)
+                       goto err_register;
+       }

        e1000_vlan_filter_on_off(adapter, false);

@@ -1228,8 +1273,10 @@
               ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
               netdev->dev_addr);

-       /* carrier off reporting is important to ethtool even BEFORE open */
-       netif_carrier_off(netdev);
+       if (!adapter->ecdev) {
+               /* carrier off reporting is important to ethtool even BEFORE 
open */
+               netif_carrier_off(netdev);
+       }

        e_info(probe, "Intel(R) PRO/1000 Network Connection\n");

@@ -1276,7 +1323,12 @@
        e1000_down_and_stop(adapter);
        e1000_release_manageability(adapter);

-       unregister_netdev(netdev);
+       if (adapter->ecdev) {
+               ecdev_close(adapter->ecdev);
+               ecdev_withdraw(adapter->ecdev);      
+       } else {
+               unregister_netdev(netdev);
+       }

        e1000_phy_hw_reset(hw);

@@ -1404,11 +1456,13 @@
        /* From here on the code is the same as e1000_up() */
        clear_bit(__E1000_DOWN, &adapter->flags);

-       napi_enable(&adapter->napi);
+       if (!adapter->ecdev) {
+               napi_enable(&adapter->napi);

-       e1000_irq_enable(adapter);
+               e1000_irq_enable(adapter);

-       netif_start_queue(netdev);
+               netif_start_queue(netdev);
+       }

        /* fire a link status change interrupt to start the watchdog */
        ew32(ICS, E1000_ICS_LSC);
@@ -2170,7 +2224,7 @@
        E1000_WRITE_FLUSH();
        mdelay(5);

-       if (netif_running(netdev))
+       if (!adapter->ecdev && netif_running(netdev))
                e1000_clean_all_rx_rings(adapter);
 }

@@ -2189,11 +2243,17 @@
        if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
                e1000_pci_set_mwi(hw);

-       if (netif_running(netdev)) {
+       if (!adapter->netdev && netif_running(netdev)) {
                /* No need to loop, because 82542 supports only 1 queue */
                struct e1000_rx_ring *ring = &adapter->rx_ring[0];
                e1000_configure_rx(adapter);
-               adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
+               if (adapter->ecdev) {
+                       /* fill rx ring completely */
+                       adapter->alloc_rx_buf(adapter, ring, ring->count);
+               } else {
+                       /* this one leaves the last ring element unallocated! */
+                       adapter->alloc_rx_buf(adapter, ring, 
E1000_DESC_UNUSED(ring));
+               }
        }
 }

@@ -2442,13 +2502,14 @@
        u32 link, tctl;

        link = e1000_has_link(adapter);
-       if ((netif_carrier_ok(netdev)) && link)
+       if (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)
                goto link_up;

        if (link) {
-               if (!netif_carrier_ok(netdev)) {
+               if ((adatper->ecdev && !ecdev_get_link(adapter->ecdev))
+                       || (!adapter->ecdev && !netif_carrier_ok(netdev))) {
                        u32 ctrl;
-                       bool txb2b = true;
+                       bool txb2b __attribute__ ((unused)) = true;
                        /* update snapshot of PHY registers on LSC */
                        e1000_get_speed_and_duplex(hw,
                                                   &adapter->link_speed,
@@ -2483,24 +2544,34 @@
                        tctl = er32(TCTL);
                        tctl |= E1000_TCTL_EN;
                        ew32(TCTL, tctl);
-
-                       netif_carrier_on(netdev);
-                       if (!test_bit(__E1000_DOWN, &adapter->flags))
-                               schedule_delayed_work(&adapter->phy_info_task,
+                       
+                       if (adapter->ecdev) {
+                               ecdev_set_link(adapter->ecdev, 1);
+                       } else {
+                               netif_carrier_on(netdev);
+                               if (!test_bit(__E1000_DOWN, &adapter->flags))
+                                       
schedule_delayed_work(&adapter->phy_info_task,
                                                      2 * HZ);
+                       }
                        adapter->smartspeed = 0;
                }
        } else {
-               if (netif_carrier_ok(netdev)) {
+               if ((adapter->ecdev && ecdev_get_link(adapter->ecdev))
+                       || (!adapter->ecdev && netif_carrier_ok(netdev))) {
                        adapter->link_speed = 0;
                        adapter->link_duplex = 0;
                        pr_info("%s NIC Link is Down\n",
                                netdev->name);
-                       netif_carrier_off(netdev);
+                               
+                       if (adapter->ecdev) {
+                               ecdev_set_link(dapter->ecdev, 0);
+                       } else {
+                               netif_carrier_off(netdev);

-                       if (!test_bit(__E1000_DOWN, &adapter->flags))
-                               schedule_delayed_work(&adapter->phy_info_task,
+                               if (!test_bit(__E1000_DOWN, &adapter->flags))
+                                       
schedule_delayed_work(&adapter->phy_info_task,
                                                      2 * HZ);
+                       }
                }

                e1000_smartspeed(adapter);
@@ -2521,7 +2592,7 @@

        e1000_update_adaptive(hw);

-       if (!netif_carrier_ok(netdev)) {
+       if (!adapter->ecdev && !netif_carrier_ok(netdev)) {
                if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
                        /* We've lost link, so the controller stops DMA,
                         * but we've got queued Tx work that's never going
@@ -2557,7 +2628,7 @@
        adapter->detect_tx_hung = true;

        /* Reschedule the task */
-       if (!test_bit(__E1000_DOWN, &adapter->flags))
+       if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags))
                schedule_delayed_work(&adapter->watchdog_task, 2 * HZ);
 }

@@ -3085,6 +3156,10 @@
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_tx_ring *tx_ring = adapter->tx_ring;

+       if (adapter->ecdev) {
+               return -EBUSY;
+       }
+       
        netif_stop_queue(netdev);
        /* Herbert's original patch had:
         *  smp_mb__after_netif_stop_queue();
@@ -3181,7 +3256,9 @@
                                if (!__pskb_pull_tail(skb, pull_size)) {
                                        e_err(drv, "__pskb_pull_tail "
                                              "failed.\n");
-                                       dev_kfree_skb_any(skb);
+                                       if (!adapter->ecdev) {
+                                               dev_kfree_skb_any(skb);
+                                       }
                                        return NETDEV_TX_OK;
                                }
                                len = skb_headlen(skb);
@@ -3229,9 +3306,11 @@

        if (unlikely((hw->mac_type == e1000_82547) &&
                     (e1000_82547_fifo_workaround(adapter, skb)))) {
-               netif_stop_queue(netdev);
-               if (!test_bit(__E1000_DOWN, &adapter->flags))
-                       schedule_delayed_work(&adapter->fifo_stall_task, 1);
+               if (!adapter->ecdev) {
+                       netif_stop_queue(netdev);
+                       if (!test_bit(__E1000_DOWN, &adapter->flags))
+                               
schedule_delayed_work(&adapter->fifo_stall_task, 1);
+               }
                return NETDEV_TX_BUSY;
        }

@@ -3244,7 +3323,9 @@

        tso = e1000_tso(adapter, tx_ring, skb, protocol);
        if (tso < 0) {
-               dev_kfree_skb_any(skb);
+               if (!adapter->ecdev) {
+                       dev_kfree_skb_any(skb);
+               }
                return NETDEV_TX_OK;
        }

@@ -3269,11 +3350,15 @@
                skb_tx_timestamp(skb);

                e1000_tx_queue(adapter, tx_ring, tx_flags, count);
-               /* Make sure there is space in the ring for the next send. */
-               e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
+               if (!adapter->ecdev) {
+                       /* Make sure there is space in the ring for the next 
send. */
+                       e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
+               }

        } else {
-               dev_kfree_skb_any(skb);
+               if (!adapter->ecdev) {
+                       dev_kfree_skb_any(skb);
+               }
                tx_ring->buffer_info[first].time_stamp = 0;
                tx_ring->next_to_use = first;
        }
@@ -3533,6 +3618,10 @@
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
        int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
+       
+       if (adapter->ecdev) {
+               return -EBUSY;
+       }

        if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
            (max_frame > MAX_JUMBO_FRAME_SIZE)) {
@@ -3609,7 +3698,7 @@
        struct net_device *netdev = adapter->netdev;
        struct e1000_hw *hw = &adapter->hw;
        struct pci_dev *pdev = adapter->pdev;
-       unsigned long flags;
+       unsigned long flags = 0;
        u16 phy_tmp;

 #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
@@ -3622,7 +3711,9 @@
        if (pci_channel_offline(pdev))
                return;

-       spin_lock_irqsave(&adapter->stats_lock, flags);
+       if (!adapter->ecdev) {
+               spin_lock_irqsave(&adapter->stats_lock, flags);
+       }

        /* these counters are modified from e1000_tbi_adjust_stats,
         * called from the interrupt context, so they must only
@@ -3751,7 +3842,20 @@
                adapter->stats.mgpdc += er32(MGTPDC);
        }

-       spin_unlock_irqrestore(&adapter->stats_lock, flags);
+       if (!adapter->ecdev) {
+               spin_unlock_irqrestore(&adapter->stats_lock, flags);
+       }
+}
+
+void ec_poll(struct net_device *netdev)
+{
+       struct e1000_adapter *adapter = netdev_priv(netdev);
+       if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
+               e1000_watchdog(&adapter->watchdog_task.work);
+               adapter->ec_watchdog_jiffies = jiffies;
+       }
+
+       e1000_intr(0, netdev);
 }

 /**
@@ -3779,26 +3883,37 @@
        if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
                hw->get_link_status = 1;
                /* guard against interrupt when we're going down */
-               if (!test_bit(__E1000_DOWN, &adapter->flags))
+               if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags))
                        schedule_delayed_work(&adapter->watchdog_task, 1);
        }

-       /* disable interrupts, without the synchronize_irq bit */
-       ew32(IMC, ~0);
-       E1000_WRITE_FLUSH();
-
-       if (likely(napi_schedule_prep(&adapter->napi))) {
-               adapter->total_tx_bytes = 0;
-               adapter->total_tx_packets = 0;
-               adapter->total_rx_bytes = 0;
-               adapter->total_rx_packets = 0;
-               __napi_schedule(&adapter->napi);
+       if (adapter->ecdev) {
+               int i, ec_work_done = 0;
+               for (i = 0; i < E1000_MAX_INTR; i++) {
+                       if (unlikely(!adapter->clean_rx(adapter, 
adapter->rx_ring,
+                                                       &ec_work_done, 100) &&
+                                               !e1000_clean_tx_irq(adapter, 
adapter->tx_ring))) {
+                               break;
+                       }
+               }               
        } else {
-               /* this really should not happen! if it does it is basically a
-                * bug, but not a hard error, so enable ints and continue
-                */
-               if (!test_bit(__E1000_DOWN, &adapter->flags))
-                       e1000_irq_enable(adapter);
+               /* disable interrupts, without the synchronize_irq bit */
+               ew32(IMC, ~0);
+               E1000_WRITE_FLUSH();
+
+               if (likely(napi_schedule_prep(&adapter->napi))) {
+                       adapter->total_tx_bytes = 0;
+                       adapter->total_tx_packets = 0;
+                       adapter->total_rx_bytes = 0;
+                       adapter->total_rx_packets = 0;
+                       __napi_schedule(&adapter->napi);
+               } else {
+                       /* this really should not happen! if it does it is 
basically a
+                       * bug, but not a hard error, so enable ints and continue
+                       */
+                       if (!test_bit(__E1000_DOWN, &adapter->flags))
+                               e1000_irq_enable(adapter);
+               }
        }

        return IRQ_HANDLED;
@@ -3807,6 +3922,7 @@
 /**
  * e1000_clean - NAPI Rx polling callback
  * @adapter: board private structure
+ * EtherCAT: never called
  **/
 static int e1000_clean(struct napi_struct *napi, int budget)
 {
@@ -3883,10 +3999,12 @@

        tx_ring->next_to_clean = i;

-       netdev_completed_queue(netdev, pkts_compl, bytes_compl);
+       if (!adapter->ecdev) {
+               netdev_completed_queue(netdev, pkts_compl, bytes_compl);
+       }

 #define TX_WAKE_THRESHOLD 32
-       if (unlikely(count && netif_carrier_ok(netdev) &&
+       if (!adapter->ecdev && unlikely(count && netif_carrier_ok(netdev) &&
                     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
                /* Make sure that anybody stopping the queue after this
                 * sees the new next_to_clean.
@@ -3900,7 +4018,7 @@
                }
        }

-       if (adapter->detect_tx_hung) {
+       if (!adapter->ecdev && adapter->detect_tx_hung) {
                /* Detect a transmit hang in hardware, this serializes the
                 * check with the clearing of time_stamp and movement of i
                 */
@@ -4173,7 +4291,8 @@
                length = le16_to_cpu(rx_desc->length);

                /* errors is only valid for DD + EOP descriptors */
-               if (unlikely((status & E1000_RXD_STAT_EOP) &&
+               if (!adapter->ecdev &&
+                       unlikely((status & E1000_RXD_STAT_EOP) &&
                    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
                        u8 *mapped = page_address(buffer_info->rxbuf.page);

@@ -4187,7 +4306,7 @@
                                /* an error means any chain goes out the window
                                 * too
                                 */
-                               if (rx_ring->rx_skb_top)
+                               if (!adapter->ecdev && rx_ring->rx_skb_top)
                                        dev_kfree_skb(rx_ring->rx_skb_top);
                                rx_ring->rx_skb_top = NULL;
                                goto next_desc;
@@ -4255,8 +4374,16 @@
                                        total_rx_bytes += skb->len;
                                        total_rx_packets++;

-                                       e1000_receive_skb(adapter, status,
+                                       if (adapter->ecdev) {
+                                               ecdev_receive(adapter->ecdev, 
skb->data, length);
+                                               
+                                               // No need to detect link 
status as
+                                               // long as frames are received: 
Reset watchdog.
+                                               adapter->ec_watchdog_jiffies = 
jiffies;
+                                       } else {
+                                               e1000_receive_skb(adapter, 
status,
                                                          rx_desc->special, 
skb);
+                                       }
                                        goto next_desc;
                                } else {
                                        skb = napi_get_frags(&adapter->napi);
@@ -4327,7 +4454,7 @@
 {
        struct sk_buff *skb;

-       if (length > copybreak)
+       if (adapter->ecdev || length > copybreak)
                return NULL;

        skb = e1000_alloc_rx_skb(adapter, length);
@@ -5065,6 +5192,10 @@
        int retval = 0;
 #endif

+       if (adapter->ecdev) {
+               return -EBUSY;
+       }
+
        netif_device_detach(netdev);

        if (netif_running(netdev)) {
@@ -5169,6 +5300,10 @@
        struct e1000_hw *hw = &adapter->hw;
        u32 err;

+       if (adapter->ecdev) {
+               return -EBUSY;
+       }
+       
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
        pci_save_state(pdev);
@@ -5201,7 +5336,9 @@
        if (netif_running(netdev))
                e1000_up(adapter);

-       netif_device_attach(netdev);
+       if (!adapter->ecdev) {
+               netif_device_attach(netdev);
+       }

        return 0;
 }
------------------

My question is, are there new procedures which are replacing the two lines above or are the changes in a way that there are no changes naccessary in the new kernel module for version 3.18?

Thanks for any hints and help.

regards

  W. Holzke






_______________________________________________
etherlab-users mailing list
[email protected]
http://lists.etherlab.org/mailman/listinfo/etherlab-users

Reply via email to