]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[karo-tx-linux.git] / drivers / net / ethernet / intel / ixgbevf / ixgbevf_main.c
index 6647383c4ddc85f9639eb010e0f3c5f470f4c3b9..0ee9bd4819f444b392d087403da514db125af0bd 100644 (file)
@@ -263,6 +263,8 @@ cont_loop:
        tx_ring->total_bytes += total_bytes;
        tx_ring->total_packets += total_packets;
        u64_stats_update_end(&tx_ring->syncp);
+       q_vector->tx.total_bytes += total_bytes;
+       q_vector->tx.total_packets += total_packets;
 
        return count < tx_ring->count;
 }
@@ -272,12 +274,10 @@ cont_loop:
  * @q_vector: structure containing interrupt and ring information
  * @skb: packet to send up
  * @status: hardware indication of status of receive
- * @rx_ring: rx descriptor ring (for a specific queue) to setup
  * @rx_desc: rx descriptor
  **/
 static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector,
                                struct sk_buff *skb, u8 status,
-                               struct ixgbevf_ring *ring,
                                union ixgbe_adv_rx_desc *rx_desc)
 {
        struct ixgbevf_adapter *adapter = q_vector->adapter;
@@ -433,11 +433,21 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
 
                if (!(staterr & IXGBE_RXD_STAT_EOP)) {
                        skb->next = next_buffer->skb;
-                       skb->next->prev = skb;
+                       IXGBE_CB(skb->next)->prev = skb;
                        adapter->non_eop_descs++;
                        goto next_desc;
                }
 
+               /* we should not be chaining buffers, if we did drop the skb */
+               if (IXGBE_CB(skb)->prev) {
+                       do {
+                               struct sk_buff *this = skb;
+                               skb = IXGBE_CB(skb)->prev;
+                               dev_kfree_skb(this);
+                       } while (skb);
+                       goto next_desc;
+               }
+
                /* ERR_MASK will only have valid bits if EOP set */
                if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) {
                        dev_kfree_skb_irq(skb);
@@ -461,7 +471,7 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
                }
                skb->protocol = eth_type_trans(skb, rx_ring->netdev);
 
-               ixgbevf_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc);
+               ixgbevf_receive_skb(q_vector, skb, staterr, rx_desc);
 
 next_desc:
                rx_desc->wb.upper.status_error = 0;
@@ -490,6 +500,8 @@ next_desc:
        rx_ring->total_packets += total_rx_packets;
        rx_ring->total_bytes += total_rx_bytes;
        u64_stats_update_end(&rx_ring->syncp);
+       q_vector->rx.total_packets += total_rx_packets;
+       q_vector->rx.total_bytes += total_rx_bytes;
 
        return !!budget;
 }
@@ -716,40 +728,15 @@ static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector)
        }
 }
 
-static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
+static irqreturn_t ixgbevf_msix_other(int irq, void *data)
 {
        struct ixgbevf_adapter *adapter = data;
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 msg;
-       bool got_ack = false;
-
-       if (!hw->mbx.ops.check_for_ack(hw))
-               got_ack = true;
 
-       if (!hw->mbx.ops.check_for_msg(hw)) {
-               hw->mbx.ops.read(hw, &msg, 1);
+       hw->mac.get_link_status = 1;
 
-               if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
-                       mod_timer(&adapter->watchdog_timer,
-                                 round_jiffies(jiffies + 1));
-
-               if (msg & IXGBE_VT_MSGTYPE_NACK)
-                       pr_warn("Last Request of type %2.2x to PF Nacked\n",
-                               msg & 0xFF);
-               /*
-                * Restore the PFSTS bit in case someone is polling for a
-                * return message from the PF
-                */
-               hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFSTS;
-       }
-
-       /*
-        * checking for the ack clears the PFACK bit.  Place
-        * it back in the v2p_mailbox cache so that anyone
-        * polling for an ack will not miss it
-        */
-       if (got_ack)
-               hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
+       if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
+               mod_timer(&adapter->watchdog_timer, jiffies);
 
        IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, adapter->eims_other);
 
@@ -899,10 +886,10 @@ static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter)
        }
 
        err = request_irq(adapter->msix_entries[vector].vector,
-                         &ixgbevf_msix_mbx, 0, netdev->name, adapter);
+                         &ixgbevf_msix_other, 0, netdev->name, adapter);
        if (err) {
                hw_dbg(&adapter->hw,
-                      "request_irq for msix_mbx failed: %d\n", err);
+                      "request_irq for msix_other failed: %d\n", err);
                goto free_queue_irqs;
        }
 
@@ -1057,15 +1044,46 @@ static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter, int index)
 
        srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
 
-       if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE)
-               srrctl |= IXGBEVF_RXBUFFER_2048 >>
-                       IXGBE_SRRCTL_BSIZEPKT_SHIFT;
-       else
-               srrctl |= rx_ring->rx_buf_len >>
-                       IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+       srrctl |= ALIGN(rx_ring->rx_buf_len, 1024) >>
+                 IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+
        IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(index), srrctl);
 }
 
+static void ixgbevf_set_rx_buffer_len(struct ixgbevf_adapter *adapter)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+       int i;
+       u16 rx_buf_len;
+
+       /* notify the PF of our intent to use this size of frame */
+       ixgbevf_rlpml_set_vf(hw, max_frame);
+
+       /* PF will allow an extra 4 bytes past for vlan tagged frames */
+       max_frame += VLAN_HLEN;
+
+       /*
+        * Make best use of allocation by using all but 1K of a
+        * power of 2 allocation that will be used for skb->head.
+        */
+       if ((hw->mac.type == ixgbe_mac_X540_vf) &&
+           (max_frame <= MAXIMUM_ETHERNET_VLAN_SIZE))
+               rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+       else if (max_frame <= IXGBEVF_RXBUFFER_3K)
+               rx_buf_len = IXGBEVF_RXBUFFER_3K;
+       else if (max_frame <= IXGBEVF_RXBUFFER_7K)
+               rx_buf_len = IXGBEVF_RXBUFFER_7K;
+       else if (max_frame <= IXGBEVF_RXBUFFER_15K)
+               rx_buf_len = IXGBEVF_RXBUFFER_15K;
+       else
+               rx_buf_len = IXGBEVF_MAX_RXBUFFER;
+
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               adapter->rx_ring[i].rx_buf_len = rx_buf_len;
+}
+
 /**
  * ixgbevf_configure_rx - Configure 82599 VF Receive Unit after Reset
  * @adapter: board private structure
@@ -1076,18 +1094,14 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter)
 {
        u64 rdba;
        struct ixgbe_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-       int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
        int i, j;
        u32 rdlen;
-       int rx_buf_len;
 
        /* PSRTYPE must be initialized in 82599 */
        IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, 0);
-       if (netdev->mtu <= ETH_DATA_LEN)
-               rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
-       else
-               rx_buf_len = ALIGN(max_frame, 1024);
+
+       /* set_rx_buffer_len must be called before ring initialization */
+       ixgbevf_set_rx_buffer_len(adapter);
 
        rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
        /* Setup the HW Rx Head and Tail Descriptor Pointers and
@@ -1103,7 +1117,6 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter)
                IXGBE_WRITE_REG(hw, IXGBE_VFRDT(j), 0);
                adapter->rx_ring[i].head = IXGBE_VFRDH(j);
                adapter->rx_ring[i].tail = IXGBE_VFRDT(j);
-               adapter->rx_ring[i].rx_buf_len = rx_buf_len;
 
                ixgbevf_configure_srrctl(adapter, j);
        }
@@ -1113,36 +1126,47 @@ static int ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
 {
        struct ixgbevf_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
+       int err;
+
+       if (!hw->mac.ops.set_vfta)
+               return -EOPNOTSUPP;
 
        spin_lock(&adapter->mbx_lock);
 
        /* add VID to filter table */
-       if (hw->mac.ops.set_vfta)
-               hw->mac.ops.set_vfta(hw, vid, 0, true);
+       err = hw->mac.ops.set_vfta(hw, vid, 0, true);
 
        spin_unlock(&adapter->mbx_lock);
 
+       /* translate error return types so error makes sense */
+       if (err == IXGBE_ERR_MBX)
+               return -EIO;
+
+       if (err == IXGBE_ERR_INVALID_ARGUMENT)
+               return -EACCES;
+
        set_bit(vid, adapter->active_vlans);
 
-       return 0;
+       return err;
 }
 
 static int ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 {
        struct ixgbevf_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
+       int err = -EOPNOTSUPP;
 
        spin_lock(&adapter->mbx_lock);
 
        /* remove VID from filter table */
        if (hw->mac.ops.set_vfta)
-               hw->mac.ops.set_vfta(hw, vid, 0, false);
+               err = hw->mac.ops.set_vfta(hw, vid, 0, false);
 
        spin_unlock(&adapter->mbx_lock);
 
        clear_bit(vid, adapter->active_vlans);
 
-       return 0;
+       return err;
 }
 
 static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter)
@@ -1308,6 +1332,25 @@ static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter)
        adapter->stats.base_vfmprc = adapter->stats.last_vfmprc;
 }
 
+static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+       int api[] = { ixgbe_mbox_api_10,
+                     ixgbe_mbox_api_unknown };
+       int err = 0, idx = 0;
+
+       spin_lock(&adapter->mbx_lock);
+
+       while (api[idx] != ixgbe_mbox_api_unknown) {
+               err = ixgbevf_negotiate_api_version(hw, api[idx]);
+               if (!err)
+                       break;
+               idx++;
+       }
+
+       spin_unlock(&adapter->mbx_lock);
+}
+
 static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
@@ -1315,7 +1358,6 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
        int i, j = 0;
        int num_rx_rings = adapter->num_rx_queues;
        u32 txdctl, rxdctl;
-       u32 msg[2];
 
        for (i = 0; i < adapter->num_tx_queues; i++) {
                j = adapter->tx_ring[i].reg_idx;
@@ -1356,10 +1398,6 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
                        hw->mac.ops.set_rar(hw, 0, hw->mac.perm_addr, 0);
        }
 
-       msg[0] = IXGBE_VF_SET_LPE;
-       msg[1] = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
-       hw->mbx.ops.write_posted(hw, msg, 2);
-
        spin_unlock(&adapter->mbx_lock);
 
        clear_bit(__IXGBEVF_DOWN, &adapter->state);
@@ -1371,6 +1409,7 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
        ixgbevf_save_reset_stats(adapter);
        ixgbevf_init_last_counter_stats(adapter);
 
+       hw->mac.get_link_status = 1;
        mod_timer(&adapter->watchdog_timer, jiffies);
 }
 
@@ -1378,6 +1417,8 @@ void ixgbevf_up(struct ixgbevf_adapter *adapter)
 {
        struct ixgbe_hw *hw = &adapter->hw;
 
+       ixgbevf_negotiate_api(adapter);
+
        ixgbevf_configure(adapter);
 
        ixgbevf_up_complete(adapter);
@@ -1419,7 +1460,7 @@ static void ixgbevf_clean_rx_ring(struct ixgbevf_adapter *adapter,
                        rx_buffer_info->skb = NULL;
                        do {
                                struct sk_buff *this = skb;
-                               skb = skb->prev;
+                               skb = IXGBE_CB(skb)->prev;
                                dev_kfree_skb(this);
                        } while (skb);
                }
@@ -1547,8 +1588,6 @@ void ixgbevf_down(struct ixgbevf_adapter *adapter)
 
 void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter)
 {
-       struct ixgbe_hw *hw = &adapter->hw;
-
        WARN_ON(in_interrupt());
 
        while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state))
@@ -1561,10 +1600,8 @@ void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter)
         * watchdog task will continue to schedule reset tasks until
         * the PF is up and running.
         */
-       if (!hw->mac.ops.reset_hw(hw)) {
-               ixgbevf_down(adapter);
-               ixgbevf_up(adapter);
-       }
+       ixgbevf_down(adapter);
+       ixgbevf_up(adapter);
 
        clear_bit(__IXGBEVF_RESETTING, &adapter->state);
 }
@@ -1866,6 +1903,22 @@ err_set_interrupt:
        return err;
 }
 
+/**
+ * ixgbevf_clear_interrupt_scheme - Clear the current interrupt scheme settings
+ * @adapter: board private structure to clear interrupt scheme on
+ *
+ * We go through and clear interrupt specific resources and reset the structure
+ * to pre-load conditions
+ **/
+static void ixgbevf_clear_interrupt_scheme(struct ixgbevf_adapter *adapter)
+{
+       adapter->num_tx_queues = 0;
+       adapter->num_rx_queues = 0;
+
+       ixgbevf_free_q_vectors(adapter);
+       ixgbevf_reset_interrupt_capability(adapter);
+}
+
 /**
  * ixgbevf_sw_init - Initialize general software structures
  * (struct ixgbevf_adapter)
@@ -2351,6 +2404,8 @@ static int ixgbevf_open(struct net_device *netdev)
                }
        }
 
+       ixgbevf_negotiate_api(adapter);
+
        /* allocate transmit descriptors */
        err = ixgbevf_setup_all_tx_resources(adapter);
        if (err)
@@ -2860,10 +2915,8 @@ static int ixgbevf_set_mac(struct net_device *netdev, void *p)
 static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
 {
        struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-       struct ixgbe_hw *hw = &adapter->hw;
        int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
        int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE;
-       u32 msg[2];
 
        if (adapter->hw.mac.type == ixgbe_mac_X540_vf)
                max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE;
@@ -2877,35 +2930,91 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
        /* must set new MTU before calling down or up */
        netdev->mtu = new_mtu;
 
-       if (!netif_running(netdev)) {
-               msg[0] = IXGBE_VF_SET_LPE;
-               msg[1] = max_frame;
-               hw->mbx.ops.write_posted(hw, msg, 2);
-       }
-
        if (netif_running(netdev))
                ixgbevf_reinit_locked(adapter);
 
        return 0;
 }
 
-static void ixgbevf_shutdown(struct pci_dev *pdev)
+static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_PM
+       int retval = 0;
+#endif
 
        netif_device_detach(netdev);
 
        if (netif_running(netdev)) {
+               rtnl_lock();
                ixgbevf_down(adapter);
                ixgbevf_free_irq(adapter);
                ixgbevf_free_all_tx_resources(adapter);
                ixgbevf_free_all_rx_resources(adapter);
+               rtnl_unlock();
        }
 
-       pci_save_state(pdev);
+       ixgbevf_clear_interrupt_scheme(adapter);
 
+#ifdef CONFIG_PM
+       retval = pci_save_state(pdev);
+       if (retval)
+               return retval;
+
+#endif
        pci_disable_device(pdev);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int ixgbevf_resume(struct pci_dev *pdev)
+{
+       struct ixgbevf_adapter *adapter = pci_get_drvdata(pdev);
+       struct net_device *netdev = adapter->netdev;
+       u32 err;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       /*
+        * pci_restore_state clears dev->state_saved so call
+        * pci_save_state to restore it.
+        */
+       pci_save_state(pdev);
+
+       err = pci_enable_device_mem(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n");
+               return err;
+       }
+       pci_set_master(pdev);
+
+       rtnl_lock();
+       err = ixgbevf_init_interrupt_scheme(adapter);
+       rtnl_unlock();
+       if (err) {
+               dev_err(&pdev->dev, "Cannot initialize interrupts\n");
+               return err;
+       }
+
+       ixgbevf_reset(adapter);
+
+       if (netif_running(netdev)) {
+               err = ixgbevf_open(netdev);
+               if (err)
+                       return err;
+       }
+
+       netif_device_attach(netdev);
+
+       return err;
+}
+
+#endif /* CONFIG_PM */
+static void ixgbevf_shutdown(struct pci_dev *pdev)
+{
+       ixgbevf_suspend(pdev, PMSG_SUSPEND);
 }
 
 static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev,
@@ -2946,7 +3055,7 @@ static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev,
        return stats;
 }
 
-static const struct net_device_ops ixgbe_netdev_ops = {
+static const struct net_device_ops ixgbevf_netdev_ops = {
        .ndo_open               = ixgbevf_open,
        .ndo_stop               = ixgbevf_close,
        .ndo_start_xmit         = ixgbevf_xmit_frame,
@@ -2962,7 +3071,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
 
 static void ixgbevf_assign_netdev_ops(struct net_device *dev)
 {
-       dev->netdev_ops = &ixgbe_netdev_ops;
+       dev->netdev_ops = &ixgbevf_netdev_ops;
        ixgbevf_set_ethtool_ops(dev);
        dev->watchdog_timeo = 5 * HZ;
 }
@@ -3131,6 +3240,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
        return 0;
 
 err_register:
+       ixgbevf_clear_interrupt_scheme(adapter);
 err_sw_init:
        ixgbevf_reset_interrupt_capability(adapter);
        iounmap(hw->hw_addr);
@@ -3168,6 +3278,7 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev)
        if (netdev->reg_state == NETREG_REGISTERED)
                unregister_netdev(netdev);
 
+       ixgbevf_clear_interrupt_scheme(adapter);
        ixgbevf_reset_interrupt_capability(adapter);
 
        iounmap(adapter->hw.hw_addr);
@@ -3267,6 +3378,11 @@ static struct pci_driver ixgbevf_driver = {
        .id_table = ixgbevf_pci_tbl,
        .probe    = ixgbevf_probe,
        .remove   = __devexit_p(ixgbevf_remove),
+#ifdef CONFIG_PM
+       /* Power Management Hooks */
+       .suspend  = ixgbevf_suspend,
+       .resume   = ixgbevf_resume,
+#endif
        .shutdown = ixgbevf_shutdown,
        .err_handler = &ixgbevf_err_handler
 };