diff options
author | Tobias Regnery <tobias.regnery@gmail.com> | 2016-09-09 06:19:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-09-09 23:51:21 -0400 |
commit | 9ee7b683ea6313e9cd27bf9c4f70a3d360abe5df (patch) | |
tree | de44b4ae7ef25ecc3a5dc854a38254a8db58632b | |
parent | ba56947a33541fd8c2e2e6fafd0126a5f6faaf15 (diff) |
alx: refactor msi enablement and disablement
Introduce a new flag field for the advanced interrupt capatibilities and add
new functions to enable and disable msi interrupts. These functions will be
extended later to cover msi-x interrupts.
We enable msi interrupts earlier in alx_init_intr because with msi-x and multi
queue support the number of queues must be set before we allocate resources for
the rx and tx paths.
Signed-off-by: Tobias Regnery <tobias.regnery@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/atheros/alx/alx.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/atheros/alx/main.c | 30 |
2 files changed, 26 insertions, 9 deletions
diff --git a/drivers/net/ethernet/atheros/alx/alx.h b/drivers/net/ethernet/atheros/alx/alx.h index 8fc93c5f6abc..16ca3f4fa2cc 100644 --- a/drivers/net/ethernet/atheros/alx/alx.h +++ b/drivers/net/ethernet/atheros/alx/alx.h | |||
@@ -76,6 +76,9 @@ enum alx_device_quirks { | |||
76 | ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG = BIT(0), | 76 | ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG = BIT(0), |
77 | }; | 77 | }; |
78 | 78 | ||
79 | #define ALX_FLAG_USING_MSIX BIT(0) | ||
80 | #define ALX_FLAG_USING_MSI BIT(1) | ||
81 | |||
79 | struct alx_priv { | 82 | struct alx_priv { |
80 | struct net_device *dev; | 83 | struct net_device *dev; |
81 | 84 | ||
@@ -105,7 +108,7 @@ struct alx_priv { | |||
105 | 108 | ||
106 | u16 msg_enable; | 109 | u16 msg_enable; |
107 | 110 | ||
108 | bool msi; | 111 | int flags; |
109 | 112 | ||
110 | /* protects hw.stats */ | 113 | /* protects hw.stats */ |
111 | spinlock_t stats_lock; | 114 | spinlock_t stats_lock; |
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index d29a4f3102d6..6dc1539205eb 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
@@ -620,6 +620,22 @@ static void alx_config_vector_mapping(struct alx_priv *alx) | |||
620 | alx_write_mem32(hw, ALX_MSI_ID_MAP, 0); | 620 | alx_write_mem32(hw, ALX_MSI_ID_MAP, 0); |
621 | } | 621 | } |
622 | 622 | ||
623 | static void alx_init_intr(struct alx_priv *alx, bool msix) | ||
624 | { | ||
625 | if (!(alx->flags & ALX_FLAG_USING_MSIX)) { | ||
626 | if (!pci_enable_msi(alx->hw.pdev)) | ||
627 | alx->flags |= ALX_FLAG_USING_MSI; | ||
628 | } | ||
629 | } | ||
630 | |||
631 | static void alx_disable_advanced_intr(struct alx_priv *alx) | ||
632 | { | ||
633 | if (alx->flags & ALX_FLAG_USING_MSI) { | ||
634 | pci_disable_msi(alx->hw.pdev); | ||
635 | alx->flags &= ~ALX_FLAG_USING_MSI; | ||
636 | } | ||
637 | } | ||
638 | |||
623 | static void alx_irq_enable(struct alx_priv *alx) | 639 | static void alx_irq_enable(struct alx_priv *alx) |
624 | { | 640 | { |
625 | struct alx_hw *hw = &alx->hw; | 641 | struct alx_hw *hw = &alx->hw; |
@@ -650,9 +666,7 @@ static int alx_request_irq(struct alx_priv *alx) | |||
650 | 666 | ||
651 | msi_ctrl = (hw->imt >> 1) << ALX_MSI_RETRANS_TM_SHIFT; | 667 | msi_ctrl = (hw->imt >> 1) << ALX_MSI_RETRANS_TM_SHIFT; |
652 | 668 | ||
653 | if (!pci_enable_msi(alx->hw.pdev)) { | 669 | if (alx->flags & ALX_FLAG_USING_MSI) { |
654 | alx->msi = true; | ||
655 | |||
656 | alx_write_mem32(hw, ALX_MSI_RETRANS_TIMER, | 670 | alx_write_mem32(hw, ALX_MSI_RETRANS_TIMER, |
657 | msi_ctrl | ALX_MSI_MASK_SEL_LINE); | 671 | msi_ctrl | ALX_MSI_MASK_SEL_LINE); |
658 | err = request_irq(pdev->irq, alx_intr_msi, 0, | 672 | err = request_irq(pdev->irq, alx_intr_msi, 0, |
@@ -660,6 +674,7 @@ static int alx_request_irq(struct alx_priv *alx) | |||
660 | if (!err) | 674 | if (!err) |
661 | goto out; | 675 | goto out; |
662 | /* fall back to legacy interrupt */ | 676 | /* fall back to legacy interrupt */ |
677 | alx->flags &= ~ALX_FLAG_USING_MSI; | ||
663 | pci_disable_msi(alx->hw.pdev); | 678 | pci_disable_msi(alx->hw.pdev); |
664 | } | 679 | } |
665 | 680 | ||
@@ -678,10 +693,7 @@ static void alx_free_irq(struct alx_priv *alx) | |||
678 | 693 | ||
679 | free_irq(pdev->irq, alx); | 694 | free_irq(pdev->irq, alx); |
680 | 695 | ||
681 | if (alx->msi) { | 696 | alx_disable_advanced_intr(alx); |
682 | pci_disable_msi(alx->hw.pdev); | ||
683 | alx->msi = false; | ||
684 | } | ||
685 | } | 697 | } |
686 | 698 | ||
687 | static int alx_identify_hw(struct alx_priv *alx) | 699 | static int alx_identify_hw(struct alx_priv *alx) |
@@ -847,6 +859,8 @@ static int __alx_open(struct alx_priv *alx, bool resume) | |||
847 | { | 859 | { |
848 | int err; | 860 | int err; |
849 | 861 | ||
862 | alx_init_intr(alx, false); | ||
863 | |||
850 | if (!resume) | 864 | if (!resume) |
851 | netif_carrier_off(alx->dev); | 865 | netif_carrier_off(alx->dev); |
852 | 866 | ||
@@ -1236,7 +1250,7 @@ static void alx_poll_controller(struct net_device *netdev) | |||
1236 | { | 1250 | { |
1237 | struct alx_priv *alx = netdev_priv(netdev); | 1251 | struct alx_priv *alx = netdev_priv(netdev); |
1238 | 1252 | ||
1239 | if (alx->msi) | 1253 | if (alx->flags & ALX_FLAG_USING_MSI) |
1240 | alx_intr_msi(0, alx); | 1254 | alx_intr_msi(0, alx); |
1241 | else | 1255 | else |
1242 | alx_intr_legacy(0, alx); | 1256 | alx_intr_legacy(0, alx); |