diff options
-rw-r--r-- | drivers/net/skge.c | 56 | ||||
-rw-r--r-- | drivers/net/skge.h | 4 |
2 files changed, 35 insertions, 25 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index f11e0e1a3d0e..290d6aa92383 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -97,10 +97,12 @@ static void genesis_mac_init(struct skge_hw *hw, int port); | |||
97 | static void genesis_reset(struct skge_hw *hw, int port); | 97 | static void genesis_reset(struct skge_hw *hw, int port); |
98 | static void genesis_link_up(struct skge_port *skge); | 98 | static void genesis_link_up(struct skge_port *skge); |
99 | 99 | ||
100 | /* Avoid conditionals by using array */ | ||
100 | static const int txqaddr[] = { Q_XA1, Q_XA2 }; | 101 | static const int txqaddr[] = { Q_XA1, Q_XA2 }; |
101 | static const int rxqaddr[] = { Q_R1, Q_R2 }; | 102 | static const int rxqaddr[] = { Q_R1, Q_R2 }; |
102 | static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; | 103 | static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; |
103 | static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; | 104 | static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; |
105 | static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 }; | ||
104 | 106 | ||
105 | /* Don't need to look at whole 16K. | 107 | /* Don't need to look at whole 16K. |
106 | * last interesting register is descriptor poll timer. | 108 | * last interesting register is descriptor poll timer. |
@@ -1382,7 +1384,9 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) | |||
1382 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 1384 | struct skge_port *skge = netdev_priv(hw->dev[port]); |
1383 | u16 status = xm_read16(hw, port, XM_ISRC); | 1385 | u16 status = xm_read16(hw, port, XM_ISRC); |
1384 | 1386 | ||
1385 | pr_debug("genesis_intr status %x\n", status); | 1387 | if (netif_msg_intr(skge)) |
1388 | printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", | ||
1389 | skge->netdev->name, status); | ||
1386 | 1390 | ||
1387 | if (status & XM_IS_TXF_UR) { | 1391 | if (status & XM_IS_TXF_UR) { |
1388 | xm_write32(hw, port, XM_MODE, XM_MD_FTF); | 1392 | xm_write32(hw, port, XM_MODE, XM_MD_FTF); |
@@ -1446,6 +1450,7 @@ static void genesis_link_up(struct skge_port *skge) | |||
1446 | */ | 1450 | */ |
1447 | if (skge->flow_control == FLOW_MODE_NONE || | 1451 | if (skge->flow_control == FLOW_MODE_NONE || |
1448 | skge->flow_control == FLOW_MODE_LOC_SEND) | 1452 | skge->flow_control == FLOW_MODE_LOC_SEND) |
1453 | /* Disable Pause Frame Reception */ | ||
1449 | cmd |= XM_MMU_IGN_PF; | 1454 | cmd |= XM_MMU_IGN_PF; |
1450 | else | 1455 | else |
1451 | /* Enable Pause Frame Reception */ | 1456 | /* Enable Pause Frame Reception */ |
@@ -1519,7 +1524,9 @@ static inline void bcom_phy_intr(struct skge_port *skge) | |||
1519 | u16 isrc; | 1524 | u16 isrc; |
1520 | 1525 | ||
1521 | isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT); | 1526 | isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT); |
1522 | pr_debug("bcom_phy_interrupt status=0x%x\n", isrc); | 1527 | if (netif_msg_intr(skge)) |
1528 | printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x\n", | ||
1529 | skge->netdev->name, isrc); | ||
1523 | 1530 | ||
1524 | if (isrc & PHY_B_IS_PSE) | 1531 | if (isrc & PHY_B_IS_PSE) |
1525 | printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n", | 1532 | printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n", |
@@ -1823,10 +1830,14 @@ static void yukon_get_stats(struct skge_port *skge, u64 *data) | |||
1823 | 1830 | ||
1824 | static void yukon_mac_intr(struct skge_hw *hw, int port) | 1831 | static void yukon_mac_intr(struct skge_hw *hw, int port) |
1825 | { | 1832 | { |
1826 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 1833 | struct net_device *dev = hw->dev[port]; |
1834 | struct skge_port *skge = netdev_priv(dev); | ||
1827 | u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC)); | 1835 | u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC)); |
1828 | 1836 | ||
1829 | pr_debug("yukon_intr status %x\n", status); | 1837 | if (netif_msg_intr(skge)) |
1838 | printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", | ||
1839 | dev->name, status); | ||
1840 | |||
1830 | if (status & GM_IS_RX_FF_OR) { | 1841 | if (status & GM_IS_RX_FF_OR) { |
1831 | ++skge->net_stats.rx_fifo_errors; | 1842 | ++skge->net_stats.rx_fifo_errors; |
1832 | gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); | 1843 | gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); |
@@ -1908,7 +1919,10 @@ static void yukon_phy_intr(struct skge_port *skge) | |||
1908 | 1919 | ||
1909 | istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); | 1920 | istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); |
1910 | phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); | 1921 | phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); |
1911 | pr_debug("yukon phy intr istat=%x phy_stat=%x\n", istatus, phystat); | 1922 | |
1923 | if (netif_msg_intr(skge)) | ||
1924 | printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x 0x%x\n", | ||
1925 | skge->netdev->name, istatus, phystat); | ||
1912 | 1926 | ||
1913 | if (istatus & PHY_M_IS_AN_COMPL) { | 1927 | if (istatus & PHY_M_IS_AN_COMPL) { |
1914 | if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP) | 1928 | if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP) |
@@ -2055,6 +2069,10 @@ static int skge_up(struct net_device *dev) | |||
2055 | 2069 | ||
2056 | skge->tx_avail = skge->tx_ring.count - 1; | 2070 | skge->tx_avail = skge->tx_ring.count - 1; |
2057 | 2071 | ||
2072 | /* Enable IRQ from port */ | ||
2073 | hw->intr_mask |= portirqmask[port]; | ||
2074 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2075 | |||
2058 | /* Initialze MAC */ | 2076 | /* Initialze MAC */ |
2059 | if (hw->chip_id == CHIP_ID_GENESIS) | 2077 | if (hw->chip_id == CHIP_ID_GENESIS) |
2060 | genesis_mac_init(hw, port); | 2078 | genesis_mac_init(hw, port); |
@@ -2449,7 +2467,8 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2449 | unsigned int to_do = min(dev->quota, *budget); | 2467 | unsigned int to_do = min(dev->quota, *budget); |
2450 | unsigned int work_done = 0; | 2468 | unsigned int work_done = 0; |
2451 | int done; | 2469 | int done; |
2452 | static const u32 irqmask[] = { IS_PORT_1, IS_PORT_2 }; | 2470 | |
2471 | pr_debug("skge_poll\n"); | ||
2453 | 2472 | ||
2454 | for (e = ring->to_clean; e != ring->to_use && work_done < to_do; | 2473 | for (e = ring->to_clean; e != ring->to_use && work_done < to_do; |
2455 | e = e->next) { | 2474 | e = e->next) { |
@@ -2512,10 +2531,9 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2512 | 2531 | ||
2513 | if (done) { | 2532 | if (done) { |
2514 | local_irq_disable(); | 2533 | local_irq_disable(); |
2515 | hw->intr_mask |= irqmask[skge->port]; | ||
2516 | /* Order is important since data can get interrupted */ | ||
2517 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2518 | __netif_rx_complete(dev); | 2534 | __netif_rx_complete(dev); |
2535 | hw->intr_mask |= portirqmask[skge->port]; | ||
2536 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2519 | local_irq_enable(); | 2537 | local_irq_enable(); |
2520 | } | 2538 | } |
2521 | 2539 | ||
@@ -2697,19 +2715,14 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2697 | return IRQ_NONE; | 2715 | return IRQ_NONE; |
2698 | 2716 | ||
2699 | status &= hw->intr_mask; | 2717 | status &= hw->intr_mask; |
2700 | 2718 | if (status & IS_R1_F) { | |
2701 | if ((status & IS_R1_F) && netif_rx_schedule_prep(hw->dev[0])) { | ||
2702 | status &= ~IS_R1_F; | ||
2703 | hw->intr_mask &= ~IS_R1_F; | 2719 | hw->intr_mask &= ~IS_R1_F; |
2704 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2720 | netif_rx_schedule(hw->dev[0]); |
2705 | __netif_rx_schedule(hw->dev[0]); | ||
2706 | } | 2721 | } |
2707 | 2722 | ||
2708 | if ((status & IS_R2_F) && netif_rx_schedule_prep(hw->dev[1])) { | 2723 | if (status & IS_R2_F) { |
2709 | status &= ~IS_R2_F; | ||
2710 | hw->intr_mask &= ~IS_R2_F; | 2724 | hw->intr_mask &= ~IS_R2_F; |
2711 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2725 | netif_rx_schedule(hw->dev[1]); |
2712 | __netif_rx_schedule(hw->dev[1]); | ||
2713 | } | 2726 | } |
2714 | 2727 | ||
2715 | if (status & IS_XA1_F) | 2728 | if (status & IS_XA1_F) |
@@ -2732,8 +2745,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2732 | tasklet_schedule(&hw->ext_tasklet); | 2745 | tasklet_schedule(&hw->ext_tasklet); |
2733 | } | 2746 | } |
2734 | 2747 | ||
2735 | if (status) | 2748 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2736 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2737 | 2749 | ||
2738 | return IRQ_HANDLED; | 2750 | return IRQ_HANDLED; |
2739 | } | 2751 | } |
@@ -2918,9 +2930,7 @@ static int skge_reset(struct skge_hw *hw) | |||
2918 | skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); | 2930 | skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); |
2919 | skge_write32(hw, B2_IRQM_CTRL, TIM_START); | 2931 | skge_write32(hw, B2_IRQM_CTRL, TIM_START); |
2920 | 2932 | ||
2921 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; | 2933 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG; |
2922 | if (hw->ports > 1) | ||
2923 | hw->intr_mask |= IS_PORT_2; | ||
2924 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2934 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2925 | 2935 | ||
2926 | if (hw->chip_id != CHIP_ID_GENESIS) | 2936 | if (hw->chip_id != CHIP_ID_GENESIS) |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 6b9a2ebbab28..ba6dfd2f01d8 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
@@ -2317,8 +2317,8 @@ enum { | |||
2317 | }; | 2317 | }; |
2318 | 2318 | ||
2319 | #define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I) | 2319 | #define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I) |
2320 | #define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ | 2320 | #define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ |
2321 | XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA) | 2321 | XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA) |
2322 | 2322 | ||
2323 | /* XM_STAT_CMD 16 bit r/w Statistics Command Register */ | 2323 | /* XM_STAT_CMD 16 bit r/w Statistics Command Register */ |
2324 | enum { | 2324 | enum { |