diff options
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r-- | drivers/net/skge.c | 108 |
1 files changed, 38 insertions, 70 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 6d62250fba07..186eb8ebfda6 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #include "skge.h" | 44 | #include "skge.h" |
45 | 45 | ||
46 | #define DRV_NAME "skge" | 46 | #define DRV_NAME "skge" |
47 | #define DRV_VERSION "1.12" | 47 | #define DRV_VERSION "1.13" |
48 | #define PFX DRV_NAME " " | 48 | #define PFX DRV_NAME " " |
49 | 49 | ||
50 | #define DEFAULT_TX_RING_SIZE 128 | 50 | #define DEFAULT_TX_RING_SIZE 128 |
@@ -1095,16 +1095,9 @@ static void xm_link_down(struct skge_hw *hw, int port) | |||
1095 | { | 1095 | { |
1096 | struct net_device *dev = hw->dev[port]; | 1096 | struct net_device *dev = hw->dev[port]; |
1097 | struct skge_port *skge = netdev_priv(dev); | 1097 | struct skge_port *skge = netdev_priv(dev); |
1098 | u16 cmd = xm_read16(hw, port, XM_MMU_CMD); | ||
1099 | 1098 | ||
1100 | xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE); | 1099 | xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE); |
1101 | 1100 | ||
1102 | cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); | ||
1103 | xm_write16(hw, port, XM_MMU_CMD, cmd); | ||
1104 | |||
1105 | /* dummy read to ensure writing */ | ||
1106 | xm_read16(hw, port, XM_MMU_CMD); | ||
1107 | |||
1108 | if (netif_carrier_ok(dev)) | 1101 | if (netif_carrier_ok(dev)) |
1109 | skge_link_down(skge); | 1102 | skge_link_down(skge); |
1110 | } | 1103 | } |
@@ -1194,6 +1187,7 @@ static void genesis_init(struct skge_hw *hw) | |||
1194 | static void genesis_reset(struct skge_hw *hw, int port) | 1187 | static void genesis_reset(struct skge_hw *hw, int port) |
1195 | { | 1188 | { |
1196 | const u8 zero[8] = { 0 }; | 1189 | const u8 zero[8] = { 0 }; |
1190 | u32 reg; | ||
1197 | 1191 | ||
1198 | skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0); | 1192 | skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0); |
1199 | 1193 | ||
@@ -1209,6 +1203,11 @@ static void genesis_reset(struct skge_hw *hw, int port) | |||
1209 | xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); | 1203 | xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); |
1210 | 1204 | ||
1211 | xm_outhash(hw, port, XM_HSM, zero); | 1205 | xm_outhash(hw, port, XM_HSM, zero); |
1206 | |||
1207 | /* Flush TX and RX fifo */ | ||
1208 | reg = xm_read32(hw, port, XM_MODE); | ||
1209 | xm_write32(hw, port, XM_MODE, reg | XM_MD_FTF); | ||
1210 | xm_write32(hw, port, XM_MODE, reg | XM_MD_FRF); | ||
1212 | } | 1211 | } |
1213 | 1212 | ||
1214 | 1213 | ||
@@ -1634,15 +1633,14 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1634 | } | 1633 | } |
1635 | xm_write16(hw, port, XM_RX_CMD, r); | 1634 | xm_write16(hw, port, XM_RX_CMD, r); |
1636 | 1635 | ||
1637 | |||
1638 | /* We want short frames padded to 60 bytes. */ | 1636 | /* We want short frames padded to 60 bytes. */ |
1639 | xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD); | 1637 | xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD); |
1640 | 1638 | ||
1641 | /* | 1639 | /* Increase threshold for jumbo frames on dual port */ |
1642 | * Bump up the transmit threshold. This helps hold off transmit | 1640 | if (hw->ports > 1 && jumbo) |
1643 | * underruns when we're blasting traffic from both ports at once. | 1641 | xm_write16(hw, port, XM_TX_THR, 1020); |
1644 | */ | 1642 | else |
1645 | xm_write16(hw, port, XM_TX_THR, 512); | 1643 | xm_write16(hw, port, XM_TX_THR, 512); |
1646 | 1644 | ||
1647 | /* | 1645 | /* |
1648 | * Enable the reception of all error frames. This is is | 1646 | * Enable the reception of all error frames. This is is |
@@ -1713,7 +1711,13 @@ static void genesis_stop(struct skge_port *skge) | |||
1713 | { | 1711 | { |
1714 | struct skge_hw *hw = skge->hw; | 1712 | struct skge_hw *hw = skge->hw; |
1715 | int port = skge->port; | 1713 | int port = skge->port; |
1716 | u32 reg; | 1714 | unsigned retries = 1000; |
1715 | u16 cmd; | ||
1716 | |||
1717 | /* Disable Tx and Rx */ | ||
1718 | cmd = xm_read16(hw, port, XM_MMU_CMD); | ||
1719 | cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); | ||
1720 | xm_write16(hw, port, XM_MMU_CMD, cmd); | ||
1717 | 1721 | ||
1718 | genesis_reset(hw, port); | 1722 | genesis_reset(hw, port); |
1719 | 1723 | ||
@@ -1721,20 +1725,17 @@ static void genesis_stop(struct skge_port *skge) | |||
1721 | skge_write16(hw, B3_PA_CTRL, | 1725 | skge_write16(hw, B3_PA_CTRL, |
1722 | port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); | 1726 | port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); |
1723 | 1727 | ||
1724 | /* | ||
1725 | * If the transfer sticks at the MAC the STOP command will not | ||
1726 | * terminate if we don't flush the XMAC's transmit FIFO ! | ||
1727 | */ | ||
1728 | xm_write32(hw, port, XM_MODE, | ||
1729 | xm_read32(hw, port, XM_MODE)|XM_MD_FTF); | ||
1730 | |||
1731 | |||
1732 | /* Reset the MAC */ | 1728 | /* Reset the MAC */ |
1733 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); | 1729 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); |
1730 | do { | ||
1731 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); | ||
1732 | if (!(skge_read16(hw, SK_REG(port, TX_MFF_CTRL1)) & MFF_SET_MAC_RST)) | ||
1733 | break; | ||
1734 | } while (--retries > 0); | ||
1734 | 1735 | ||
1735 | /* For external PHYs there must be special handling */ | 1736 | /* For external PHYs there must be special handling */ |
1736 | if (hw->phy_type != SK_PHY_XMAC) { | 1737 | if (hw->phy_type != SK_PHY_XMAC) { |
1737 | reg = skge_read32(hw, B2_GP_IO); | 1738 | u32 reg = skge_read32(hw, B2_GP_IO); |
1738 | if (port == 0) { | 1739 | if (port == 0) { |
1739 | reg |= GP_DIR_0; | 1740 | reg |= GP_DIR_0; |
1740 | reg &= ~GP_IO_0; | 1741 | reg &= ~GP_IO_0; |
@@ -1801,11 +1802,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) | |||
1801 | xm_write32(hw, port, XM_MODE, XM_MD_FTF); | 1802 | xm_write32(hw, port, XM_MODE, XM_MD_FTF); |
1802 | ++dev->stats.tx_fifo_errors; | 1803 | ++dev->stats.tx_fifo_errors; |
1803 | } | 1804 | } |
1804 | |||
1805 | if (status & XM_IS_RXF_OV) { | ||
1806 | xm_write32(hw, port, XM_MODE, XM_MD_FRF); | ||
1807 | ++dev->stats.rx_fifo_errors; | ||
1808 | } | ||
1809 | } | 1805 | } |
1810 | 1806 | ||
1811 | static void genesis_link_up(struct skge_port *skge) | 1807 | static void genesis_link_up(struct skge_port *skge) |
@@ -1862,9 +1858,9 @@ static void genesis_link_up(struct skge_port *skge) | |||
1862 | 1858 | ||
1863 | xm_write32(hw, port, XM_MODE, mode); | 1859 | xm_write32(hw, port, XM_MODE, mode); |
1864 | 1860 | ||
1865 | /* Turn on detection of Tx underrun, Rx overrun */ | 1861 | /* Turn on detection of Tx underrun */ |
1866 | msk = xm_read16(hw, port, XM_IMSK); | 1862 | msk = xm_read16(hw, port, XM_IMSK); |
1867 | msk &= ~(XM_IS_RXF_OV | XM_IS_TXF_UR); | 1863 | msk &= ~XM_IS_TXF_UR; |
1868 | xm_write16(hw, port, XM_IMSK, msk); | 1864 | xm_write16(hw, port, XM_IMSK, msk); |
1869 | 1865 | ||
1870 | xm_read16(hw, port, XM_ISRC); | 1866 | xm_read16(hw, port, XM_ISRC); |
@@ -2194,9 +2190,12 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
2194 | TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) | | 2190 | TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) | |
2195 | TX_IPG_JAM_DATA(TX_IPG_JAM_DEF)); | 2191 | TX_IPG_JAM_DATA(TX_IPG_JAM_DEF)); |
2196 | 2192 | ||
2197 | /* serial mode register */ | 2193 | /* configure the Serial Mode Register */ |
2198 | reg = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); | 2194 | reg = DATA_BLIND_VAL(DATA_BLIND_DEF) |
2199 | if (hw->dev[port]->mtu > 1500) | 2195 | | GM_SMOD_VLAN_ENA |
2196 | | IPG_DATA_VAL(IPG_DATA_DEF); | ||
2197 | |||
2198 | if (hw->dev[port]->mtu > ETH_DATA_LEN) | ||
2200 | reg |= GM_SMOD_JUMBO_ENA; | 2199 | reg |= GM_SMOD_JUMBO_ENA; |
2201 | 2200 | ||
2202 | gma_write16(hw, port, GM_SERIAL_MODE, reg); | 2201 | gma_write16(hw, port, GM_SERIAL_MODE, reg); |
@@ -2619,8 +2618,8 @@ static int skge_up(struct net_device *dev) | |||
2619 | yukon_mac_init(hw, port); | 2618 | yukon_mac_init(hw, port); |
2620 | spin_unlock_bh(&hw->phy_lock); | 2619 | spin_unlock_bh(&hw->phy_lock); |
2621 | 2620 | ||
2622 | /* Configure RAMbuffers */ | 2621 | /* Configure RAMbuffers - equally between ports and tx/rx */ |
2623 | chunk = hw->ram_size / ((hw->ports + 1)*2); | 2622 | chunk = (hw->ram_size - hw->ram_offset) / (hw->ports * 2); |
2624 | ram_addr = hw->ram_offset + 2 * chunk * port; | 2623 | ram_addr = hw->ram_offset + 2 * chunk * port; |
2625 | 2624 | ||
2626 | skge_ramset(hw, rxqaddr[port], ram_addr, chunk); | 2625 | skge_ramset(hw, rxqaddr[port], ram_addr, chunk); |
@@ -2897,11 +2896,7 @@ static void skge_tx_timeout(struct net_device *dev) | |||
2897 | 2896 | ||
2898 | static int skge_change_mtu(struct net_device *dev, int new_mtu) | 2897 | static int skge_change_mtu(struct net_device *dev, int new_mtu) |
2899 | { | 2898 | { |
2900 | struct skge_port *skge = netdev_priv(dev); | ||
2901 | struct skge_hw *hw = skge->hw; | ||
2902 | int port = skge->port; | ||
2903 | int err; | 2899 | int err; |
2904 | u16 ctl, reg; | ||
2905 | 2900 | ||
2906 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) | 2901 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) |
2907 | return -EINVAL; | 2902 | return -EINVAL; |
@@ -2911,40 +2906,13 @@ static int skge_change_mtu(struct net_device *dev, int new_mtu) | |||
2911 | return 0; | 2906 | return 0; |
2912 | } | 2907 | } |
2913 | 2908 | ||
2914 | skge_write32(hw, B0_IMSK, 0); | 2909 | skge_down(dev); |
2915 | dev->trans_start = jiffies; /* prevent tx timeout */ | ||
2916 | netif_stop_queue(dev); | ||
2917 | napi_disable(&skge->napi); | ||
2918 | |||
2919 | ctl = gma_read16(hw, port, GM_GP_CTRL); | ||
2920 | gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); | ||
2921 | |||
2922 | skge_rx_clean(skge); | ||
2923 | skge_rx_stop(hw, port); | ||
2924 | 2910 | ||
2925 | dev->mtu = new_mtu; | 2911 | dev->mtu = new_mtu; |
2926 | 2912 | ||
2927 | reg = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); | 2913 | err = skge_up(dev); |
2928 | if (new_mtu > 1500) | ||
2929 | reg |= GM_SMOD_JUMBO_ENA; | ||
2930 | gma_write16(hw, port, GM_SERIAL_MODE, reg); | ||
2931 | |||
2932 | skge_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD); | ||
2933 | |||
2934 | err = skge_rx_fill(dev); | ||
2935 | wmb(); | ||
2936 | if (!err) | ||
2937 | skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); | ||
2938 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2939 | |||
2940 | if (err) | 2914 | if (err) |
2941 | dev_close(dev); | 2915 | dev_close(dev); |
2942 | else { | ||
2943 | gma_write16(hw, port, GM_GP_CTRL, ctl); | ||
2944 | |||
2945 | napi_enable(&skge->napi); | ||
2946 | netif_wake_queue(dev); | ||
2947 | } | ||
2948 | 2916 | ||
2949 | return err; | 2917 | return err; |
2950 | } | 2918 | } |