fm10k: Add support for ndo_open/stop
authorAlexander Duyck <alexander.h.duyck@intel.com>
Sat, 20 Sep 2014 23:48:29 +0000 (19:48 -0400)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Tue, 23 Sep 2014 10:59:16 +0000 (03:59 -0700)
Add support for brining the interface up/down.  This is still primitive yet
as we have not yet added support for the descriptor queues.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/fm10k/fm10k.h
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
drivers/net/ethernet/intel/fm10k/fm10k_pci.c

index 1172cba59192e2bcb95e46c6826175887b647958..bd47f28f5b05dc376506994b5e301a2ee5bddfcc 100644 (file)
@@ -130,9 +130,13 @@ extern const char fm10k_driver_version[];
 /* PCI */
 int fm10k_register_pci_driver(void);
 void fm10k_unregister_pci_driver(void);
+void fm10k_up(struct fm10k_intfc *interface);
+void fm10k_down(struct fm10k_intfc *interface);
 
 /* Netdev */
 struct net_device *fm10k_alloc_netdev(void);
 void fm10k_restore_rx_state(struct fm10k_intfc *);
 void fm10k_reset_rx_state(struct fm10k_intfc *);
+int fm10k_open(struct net_device *netdev);
+int fm10k_close(struct net_device *netdev);
 #endif /* _FM10K_H_ */
index cf7b4f32a996e26f5279d5048a78d6e158ab55c6..ca84898c208eec5ead2517e15693aa0a6db89c64 100644 (file)
 
 #include "fm10k.h"
 
+/**
+ * fm10k_request_glort_range - Request GLORTs for use in configuring rules
+ * @interface: board private structure
+ *
+ * This function allocates a range of glorts for this inteface to use.
+ **/
+static void fm10k_request_glort_range(struct fm10k_intfc *interface)
+{
+       struct fm10k_hw *hw = &interface->hw;
+       u16 mask = (~hw->mac.dglort_map) >> FM10K_DGLORTMAP_MASK_SHIFT;
+
+       /* establish GLORT base */
+       interface->glort = hw->mac.dglort_map & FM10K_DGLORTMAP_NONE;
+       interface->glort_count = 0;
+
+       /* nothing we can do until mask is allocated */
+       if (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE)
+               return;
+
+       interface->glort_count = mask + 1;
+}
+
+/**
+ * fm10k_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP).  At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ **/
+int fm10k_open(struct net_device *netdev)
+{
+       struct fm10k_intfc *interface = netdev_priv(netdev);
+
+       /* setup GLORT assignment for this port */
+       fm10k_request_glort_range(interface);
+
+       fm10k_up(interface);
+
+       return 0;
+}
+
+/**
+ * fm10k_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS.  The hardware is still under the drivers control, but
+ * needs to be disabled.  A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ **/
+int fm10k_close(struct net_device *netdev)
+{
+       struct fm10k_intfc *interface = netdev_priv(netdev);
+
+       fm10k_down(interface);
+
+       return 0;
+}
+
 static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 {
        dev_kfree_skb_any(skb);
@@ -398,6 +464,8 @@ void fm10k_reset_rx_state(struct fm10k_intfc *interface)
 }
 
 static const struct net_device_ops fm10k_netdev_ops = {
+       .ndo_open               = fm10k_open,
+       .ndo_stop               = fm10k_close,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_start_xmit         = fm10k_xmit_frame,
        .ndo_set_mac_address    = fm10k_set_mac,
index 5fcbd1d621b7e9e28974a7b251df83e43cb0c936..b6d5e722bc5e5a5621997d700b67beba9b67a5d7 100644 (file)
@@ -87,6 +87,51 @@ static int fm10k_hw_ready(struct fm10k_intfc *interface)
        return FM10K_REMOVED(hw->hw_addr) ? -ENODEV : 0;
 }
 
+void fm10k_up(struct fm10k_intfc *interface)
+{
+       struct fm10k_hw *hw = &interface->hw;
+
+       /* Enable Tx/Rx DMA */
+       hw->mac.ops.start_hw(hw);
+
+       /* configure interrupts */
+       hw->mac.ops.update_int_moderator(hw);
+
+       /* clear down bit to indicate we are ready to go */
+       clear_bit(__FM10K_DOWN, &interface->state);
+
+       /* re-establish Rx filters */
+       fm10k_restore_rx_state(interface);
+
+       /* enable transmits */
+       netif_tx_start_all_queues(interface->netdev);
+}
+
+void fm10k_down(struct fm10k_intfc *interface)
+{
+       struct net_device *netdev = interface->netdev;
+       struct fm10k_hw *hw = &interface->hw;
+
+       /* signal that we are down to the interrupt handler and service task */
+       set_bit(__FM10K_DOWN, &interface->state);
+
+       /* call carrier off first to avoid false dev_watchdog timeouts */
+       netif_carrier_off(netdev);
+
+       /* disable transmits */
+       netif_tx_stop_all_queues(netdev);
+       netif_tx_disable(netdev);
+
+       /* reset Rx filters */
+       fm10k_reset_rx_state(interface);
+
+       /* allow 10ms for device to quiesce */
+       usleep_range(10000, 20000);
+
+       /* Disable DMA engine for Tx/Rx */
+       hw->mac.ops.stop_hw(hw);
+}
+
 /**
  * fm10k_sw_init - Initialize general software structures
  * @interface: host interface private structure to initialize