X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fnet%2Fixgbe%2Fixgbe_main.c;h=fd27513a92f6134f2bd3d04094755e165410d3c9;hb=b453368dfd74ba5a49bfaa853251212fa306e70d;hp=335119a5687abf1788ee836e80fb73b9e6fb3519;hpb=af4330631cd48987755f1a8d324dc318f60cf16b;p=karo-tx-linux.git diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 335119a5687a..fd27513a92f6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1433,27 +1433,6 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) return; } -/** - * ixgbe_irq_disable - Mask off interrupt generation on the NIC - * @adapter: board private structure - **/ -static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) -{ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(2), ~0); - } - IXGBE_WRITE_FLUSH(&adapter->hw); - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { - int i; - for (i = 0; i < adapter->num_msix_vectors; i++) - synchronize_irq(adapter->msix_entries[i].vector); - } else { - synchronize_irq(adapter->pdev->irq); - } -} - /** * ixgbe_irq_enable - Enable default interrupt generation settings * @adapter: board private structure @@ -1596,6 +1575,39 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) } } +/** + * ixgbe_irq_disable - Mask off interrupt generation on the NIC + * @adapter: board private structure + **/ +static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) +{ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(2), ~0); + } + IXGBE_WRITE_FLUSH(&adapter->hw); + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + int i; + for (i = 0; i < adapter->num_msix_vectors; i++) + synchronize_irq(adapter->msix_entries[i].vector); + } else { + synchronize_irq(adapter->pdev->irq); + } +} + +static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter) +{ + u32 mask = IXGBE_EIMS_RTX_QUEUE; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask << 16); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2), + (mask << 16 | mask)); + } + /* skip the flush */ +} + /** * ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts * @@ -2624,7 +2636,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget) if (adapter->itr_setting & 1) ixgbe_set_itr(adapter); if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable(adapter); + ixgbe_irq_enable_queues(adapter); } return work_done; } @@ -3806,17 +3818,54 @@ static void ixgbe_watchdog(unsigned long data) /* Do the watchdog outside of interrupt context due to the lovely * delays that some of the newer hardware requires */ if (!test_bit(__IXGBE_DOWN, &adapter->state)) { + u64 eics = 0; + int i; + + for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) + eics |= (1 << i); + /* Cause software interrupt to ensure rx rings are cleaned */ - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { - u32 eics = - (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1; - IXGBE_WRITE_REG(hw, IXGBE_EICS, eics); - } else { - /* For legacy and MSI interrupts don't set any bits that - * are enabled for EIAM, because this operation would - * set *both* EIMS and EICS for any bit in EIAM */ - IXGBE_WRITE_REG(hw, IXGBE_EICS, - (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + IXGBE_WRITE_REG(hw, IXGBE_EICS, (u32)eics); + } else { + /* + * for legacy and MSI interrupts don't set any + * bits that are enabled for EIAM, because this + * operation would set *both* EIMS and EICS for + * any bit in EIAM + */ + IXGBE_WRITE_REG(hw, IXGBE_EICS, + (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); + } + break; + case ixgbe_mac_82599EB: + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + /* + * EICS(0..15) first 0-15 q vectors + * EICS[1] (16..31) q vectors 16-31 + * EICS[2] (0..31) q vectors 32-63 + */ + IXGBE_WRITE_REG(hw, IXGBE_EICS, + (u32)(eics & 0xFFFF)); + IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(1), + (u32)(eics & 0xFFFF0000)); + IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(2), + (u32)(eics >> 32)); + } else { + /* + * for legacy and MSI interrupts don't set any + * bits that are enabled for EIAM, because this + * operation would set *both* EIMS and EICS for + * any bit in EIAM + */ + IXGBE_WRITE_REG(hw, IXGBE_EICS, + (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); + } + break; + default: + break; } /* Reset the timer */ mod_timer(&adapter->watchdog_timer, @@ -4272,6 +4321,16 @@ static int ixgbe_maybe_stop_tx(struct net_device *netdev, return __ixgbe_maybe_stop_tx(netdev, tx_ring, size); } +static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) + return 0; /* All traffic should default to class 0 */ + + return skb_tx_hash(dev, skb); +} + static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -4401,6 +4460,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_open = ixgbe_open, .ndo_stop = ixgbe_close, .ndo_start_xmit = ixgbe_xmit_frame, + .ndo_select_queue = ixgbe_select_queue, .ndo_get_stats = ixgbe_get_stats, .ndo_set_rx_mode = ixgbe_set_rx_mode, .ndo_set_multicast_list = ixgbe_set_rx_mode, @@ -4927,8 +4987,20 @@ static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event, return ret_val ? NOTIFY_BAD : NOTIFY_DONE; } + #endif /* CONFIG_IXGBE_DCA */ +#ifdef DEBUG +/** + * ixgbe_get_hw_dev_name - return device name string + * used by hardware layer to print debugging information + **/ +char *ixgbe_get_hw_dev_name(struct ixgbe_hw *hw) +{ + struct ixgbe_adapter *adapter = hw->back; + return adapter->netdev->name; +} +#endif module_exit(ixgbe_exit_module); /* ixgbe_main.c */