aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Regnery <tobias.regnery@gmail.com>2016-09-09 06:19:52 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-09 23:51:21 -0400
commit9ee7b683ea6313e9cd27bf9c4f70a3d360abe5df (patch)
treede44b4ae7ef25ecc3a5dc854a38254a8db58632b
parentba56947a33541fd8c2e2e6fafd0126a5f6faaf15 (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.h5
-rw-r--r--drivers/net/ethernet/atheros/alx/main.c30
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
79struct alx_priv { 82struct 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
623static 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
631static 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
623static void alx_irq_enable(struct alx_priv *alx) 639static 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
687static int alx_identify_hw(struct alx_priv *alx) 699static 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);