aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2005-12-09 14:34:56 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-12-12 15:27:20 -0500
commitfb17358fe31e01baf902a9fd1fce0e29e3493517 (patch)
treeeaeb557cd4835bf608a20563915b1985931db55c /drivers/net/sky2.c
parentbdb5c58ebe4301f9c3470cc35adeff1ef7ee99eb (diff)
[PATCH] sky2: ethtool get/set interrupt coalescing
Add support for get/set the interrupt coalescing settings. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c115
1 files changed, 103 insertions, 12 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index f2f8f60a0911..0ab376845e39 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -24,9 +24,6 @@
24 */ 24 */
25 25
26/* 26/*
27 * TODO
28 * - coalescing setting?
29 *
30 * TOTEST 27 * TOTEST
31 * - speed setting 28 * - speed setting
32 * - suspend/resume 29 * - suspend/resume
@@ -2019,29 +2016,30 @@ static void sky2_netpoll(struct net_device *dev)
2019#endif 2016#endif
2020 2017
2021/* Chip internal frequency for clock calculations */ 2018/* Chip internal frequency for clock calculations */
2022static inline u32 sky2_khz(const struct sky2_hw *hw) 2019static inline u32 sky2_mhz(const struct sky2_hw *hw)
2023{ 2020{
2024 switch (hw->chip_id) { 2021 switch (hw->chip_id) {
2025 case CHIP_ID_YUKON_EC: 2022 case CHIP_ID_YUKON_EC:
2026 case CHIP_ID_YUKON_EC_U: 2023 case CHIP_ID_YUKON_EC_U:
2027 return 125000; /* 125 Mhz */ 2024 return 125; /* 125 Mhz */
2028 case CHIP_ID_YUKON_FE: 2025 case CHIP_ID_YUKON_FE:
2029 return 100000; /* 100 Mhz */ 2026 return 100; /* 100 Mhz */
2030 default: /* YUKON_XL */ 2027 default: /* YUKON_XL */
2031 return 156000; /* 156 Mhz */ 2028 return 156; /* 156 Mhz */
2032 } 2029 }
2033} 2030}
2034 2031
2035static inline u32 sky2_ms2clk(const struct sky2_hw *hw, u32 ms) 2032static inline u32 sky2_us2clk(const struct sky2_hw *hw, u32 us)
2036{ 2033{
2037 return sky2_khz(hw) * ms; 2034 return sky2_mhz(hw) * us;
2038} 2035}
2039 2036
2040static inline u32 sky2_us2clk(const struct sky2_hw *hw, u32 us) 2037static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
2041{ 2038{
2042 return (sky2_khz(hw) * us) / 1000; 2039 return clk / sky2_mhz(hw);
2043} 2040}
2044 2041
2042
2045static int sky2_reset(struct sky2_hw *hw) 2043static int sky2_reset(struct sky2_hw *hw)
2046{ 2044{
2047 u32 ctst; 2045 u32 ctst;
@@ -2169,7 +2167,7 @@ static int sky2_reset(struct sky2_hw *hw)
2169 /* Set the list last index */ 2167 /* Set the list last index */
2170 sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); 2168 sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1);
2171 2169
2172 sky2_write32(hw, STAT_TX_TIMER_INI, sky2_ms2clk(hw, 10)); 2170 sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
2173 2171
2174 /* These status setup values are copied from SysKonnect's driver */ 2172 /* These status setup values are copied from SysKonnect's driver */
2175 if (is_ec_a1(hw)) { 2173 if (is_ec_a1(hw)) {
@@ -2680,6 +2678,97 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
2680} 2678}
2681#endif 2679#endif
2682 2680
2681static int sky2_get_coalesce(struct net_device *dev,
2682 struct ethtool_coalesce *ecmd)
2683{
2684 struct sky2_port *sky2 = netdev_priv(dev);
2685 struct sky2_hw *hw = sky2->hw;
2686
2687 if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_STOP)
2688 ecmd->tx_coalesce_usecs = 0;
2689 else {
2690 u32 clks = sky2_read32(hw, STAT_TX_TIMER_INI);
2691 ecmd->tx_coalesce_usecs = sky2_clk2us(hw, clks);
2692 }
2693 ecmd->tx_max_coalesced_frames = sky2_read16(hw, STAT_TX_IDX_TH);
2694
2695 if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_STOP)
2696 ecmd->rx_coalesce_usecs = 0;
2697 else {
2698 u32 clks = sky2_read32(hw, STAT_LEV_TIMER_INI);
2699 ecmd->rx_coalesce_usecs = sky2_clk2us(hw, clks);
2700 }
2701 ecmd->rx_max_coalesced_frames = sky2_read8(hw, STAT_FIFO_WM);
2702
2703 if (sky2_read8(hw, STAT_ISR_TIMER_CTRL) == TIM_STOP)
2704 ecmd->rx_coalesce_usecs_irq = 0;
2705 else {
2706 u32 clks = sky2_read32(hw, STAT_ISR_TIMER_INI);
2707 ecmd->rx_coalesce_usecs_irq = sky2_clk2us(hw, clks);
2708 }
2709
2710 ecmd->rx_max_coalesced_frames_irq = sky2_read8(hw, STAT_FIFO_ISR_WM);
2711
2712 return 0;
2713}
2714
2715/* Note: this affect both ports */
2716static int sky2_set_coalesce(struct net_device *dev,
2717 struct ethtool_coalesce *ecmd)
2718{
2719 struct sky2_port *sky2 = netdev_priv(dev);
2720 struct sky2_hw *hw = sky2->hw;
2721 const u32 tmin = sky2_clk2us(hw, 1);
2722 const u32 tmax = 5000;
2723
2724 if (ecmd->tx_coalesce_usecs != 0 &&
2725 (ecmd->tx_coalesce_usecs < tmin || ecmd->tx_coalesce_usecs > tmax))
2726 return -EINVAL;
2727
2728 if (ecmd->rx_coalesce_usecs != 0 &&
2729 (ecmd->rx_coalesce_usecs < tmin || ecmd->rx_coalesce_usecs > tmax))
2730 return -EINVAL;
2731
2732 if (ecmd->rx_coalesce_usecs_irq != 0 &&
2733 (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax))
2734 return -EINVAL;
2735
2736 if (ecmd->tx_max_coalesced_frames > 0xffff)
2737 return -EINVAL;
2738 if (ecmd->rx_max_coalesced_frames > 0xff)
2739 return -EINVAL;
2740 if (ecmd->rx_max_coalesced_frames_irq > 0xff)
2741 return -EINVAL;
2742
2743 if (ecmd->tx_coalesce_usecs == 0)
2744 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
2745 else {
2746 sky2_write32(hw, STAT_TX_TIMER_INI,
2747 sky2_us2clk(hw, ecmd->tx_coalesce_usecs));
2748 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
2749 }
2750 sky2_write16(hw, STAT_TX_IDX_TH, ecmd->tx_max_coalesced_frames);
2751
2752 if (ecmd->rx_coalesce_usecs == 0)
2753 sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
2754 else {
2755 sky2_write32(hw, STAT_LEV_TIMER_INI,
2756 sky2_us2clk(hw, ecmd->rx_coalesce_usecs));
2757 sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
2758 }
2759 sky2_write8(hw, STAT_FIFO_WM, ecmd->rx_max_coalesced_frames);
2760
2761 if (ecmd->rx_coalesce_usecs_irq == 0)
2762 sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP);
2763 else {
2764 sky2_write32(hw, STAT_TX_TIMER_INI,
2765 sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq));
2766 sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
2767 }
2768 sky2_write8(hw, STAT_FIFO_ISR_WM, ecmd->rx_max_coalesced_frames_irq);
2769 return 0;
2770}
2771
2683static void sky2_get_ringparam(struct net_device *dev, 2772static void sky2_get_ringparam(struct net_device *dev,
2684 struct ethtool_ringparam *ering) 2773 struct ethtool_ringparam *ering)
2685{ 2774{
@@ -2765,6 +2854,8 @@ static struct ethtool_ops sky2_ethtool_ops = {
2765 .get_rx_csum = sky2_get_rx_csum, 2854 .get_rx_csum = sky2_get_rx_csum,
2766 .set_rx_csum = sky2_set_rx_csum, 2855 .set_rx_csum = sky2_set_rx_csum,
2767 .get_strings = sky2_get_strings, 2856 .get_strings = sky2_get_strings,
2857 .get_coalesce = sky2_get_coalesce,
2858 .set_coalesce = sky2_set_coalesce,
2768 .get_ringparam = sky2_get_ringparam, 2859 .get_ringparam = sky2_get_ringparam,
2769 .set_ringparam = sky2_set_ringparam, 2860 .set_ringparam = sky2_set_ringparam,
2770 .get_pauseparam = sky2_get_pauseparam, 2861 .get_pauseparam = sky2_get_pauseparam,