diff options
| -rw-r--r-- | drivers/net/sky2.c | 85 | ||||
| -rw-r--r-- | drivers/net/sky2.h | 8 |
2 files changed, 68 insertions, 25 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 910c600a6caf..4d1ec78c437a 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -743,12 +743,17 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
| 743 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { | 743 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { |
| 744 | sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); | 744 | sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); |
| 745 | sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); | 745 | sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); |
| 746 | if (hw->dev[port]->mtu > ETH_DATA_LEN) { | 746 | |
| 747 | /* set Tx GMAC FIFO Almost Empty Threshold */ | 747 | /* set Tx GMAC FIFO Almost Empty Threshold */ |
| 748 | sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), 0x180); | 748 | sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), |
| 749 | /* Disable Store & Forward mode for TX */ | 749 | (ECU_JUMBO_WM << 16) | ECU_AE_THR); |
| 750 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS); | 750 | |
| 751 | } | 751 | if (hw->dev[port]->mtu > ETH_DATA_LEN) |
| 752 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
| 753 | TX_JUMBO_ENA | TX_STFW_DIS); | ||
| 754 | else | ||
| 755 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
| 756 | TX_JUMBO_DIS | TX_STFW_ENA); | ||
| 752 | } | 757 | } |
| 753 | 758 | ||
| 754 | } | 759 | } |
| @@ -1281,7 +1286,7 @@ static int sky2_up(struct net_device *dev) | |||
| 1281 | /* Set almost empty threshold */ | 1286 | /* Set almost empty threshold */ |
| 1282 | if (hw->chip_id == CHIP_ID_YUKON_EC_U | 1287 | if (hw->chip_id == CHIP_ID_YUKON_EC_U |
| 1283 | && hw->chip_rev == CHIP_REV_YU_EC_U_A0) | 1288 | && hw->chip_rev == CHIP_REV_YU_EC_U_A0) |
| 1284 | sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0); | 1289 | sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV); |
| 1285 | 1290 | ||
| 1286 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | 1291 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
| 1287 | TX_RING_SIZE - 1); | 1292 | TX_RING_SIZE - 1); |
| @@ -1587,13 +1592,6 @@ static int sky2_down(struct net_device *dev) | |||
| 1587 | sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), | 1592 | sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), |
| 1588 | RB_RST_SET | RB_DIS_OP_MD); | 1593 | RB_RST_SET | RB_DIS_OP_MD); |
| 1589 | 1594 | ||
| 1590 | /* WA for dev. #4.209 */ | ||
| 1591 | if (hw->chip_id == CHIP_ID_YUKON_EC_U | ||
| 1592 | && (hw->chip_rev == CHIP_REV_YU_EC_U_A1 || hw->chip_rev == CHIP_REV_YU_EC_U_B0)) | ||
| 1593 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
| 1594 | sky2->speed != SPEED_1000 ? | ||
| 1595 | TX_STFW_ENA : TX_STFW_DIS); | ||
| 1596 | |||
| 1597 | ctrl = gma_read16(hw, port, GM_GP_CTRL); | 1595 | ctrl = gma_read16(hw, port, GM_GP_CTRL); |
| 1598 | ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA); | 1596 | ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA); |
| 1599 | gma_write16(hw, port, GM_GP_CTRL, ctrl); | 1597 | gma_write16(hw, port, GM_GP_CTRL, ctrl); |
| @@ -1893,6 +1891,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1893 | { | 1891 | { |
| 1894 | struct sky2_port *sky2 = netdev_priv(dev); | 1892 | struct sky2_port *sky2 = netdev_priv(dev); |
| 1895 | struct sky2_hw *hw = sky2->hw; | 1893 | struct sky2_hw *hw = sky2->hw; |
| 1894 | unsigned port = sky2->port; | ||
| 1896 | int err; | 1895 | int err; |
| 1897 | u16 ctl, mode; | 1896 | u16 ctl, mode; |
| 1898 | u32 imask; | 1897 | u32 imask; |
| @@ -1900,10 +1899,6 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1900 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) | 1899 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) |
| 1901 | return -EINVAL; | 1900 | return -EINVAL; |
| 1902 | 1901 | ||
| 1903 | /* TSO on Yukon Ultra and MTU > 1500 not supported */ | ||
| 1904 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && new_mtu > ETH_DATA_LEN) | ||
| 1905 | dev->features &= ~NETIF_F_TSO; | ||
| 1906 | |||
| 1907 | if (!netif_running(dev)) { | 1902 | if (!netif_running(dev)) { |
| 1908 | dev->mtu = new_mtu; | 1903 | dev->mtu = new_mtu; |
| 1909 | return 0; | 1904 | return 0; |
| @@ -1918,8 +1913,18 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1918 | 1913 | ||
| 1919 | synchronize_irq(hw->pdev->irq); | 1914 | synchronize_irq(hw->pdev->irq); |
| 1920 | 1915 | ||
| 1921 | ctl = gma_read16(hw, sky2->port, GM_GP_CTRL); | 1916 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { |
| 1922 | gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); | 1917 | if (new_mtu > ETH_DATA_LEN) { |
| 1918 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
| 1919 | TX_JUMBO_ENA | TX_STFW_DIS); | ||
| 1920 | dev->features &= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM; | ||
| 1921 | } else | ||
| 1922 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
| 1923 | TX_JUMBO_DIS | TX_STFW_ENA); | ||
| 1924 | } | ||
| 1925 | |||
| 1926 | ctl = gma_read16(hw, port, GM_GP_CTRL); | ||
| 1927 | gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); | ||
| 1923 | sky2_rx_stop(sky2); | 1928 | sky2_rx_stop(sky2); |
| 1924 | sky2_rx_clean(sky2); | 1929 | sky2_rx_clean(sky2); |
| 1925 | 1930 | ||
| @@ -1931,9 +1936,9 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1931 | if (dev->mtu > ETH_DATA_LEN) | 1936 | if (dev->mtu > ETH_DATA_LEN) |
| 1932 | mode |= GM_SMOD_JUMBO_ENA; | 1937 | mode |= GM_SMOD_JUMBO_ENA; |
| 1933 | 1938 | ||
| 1934 | gma_write16(hw, sky2->port, GM_SERIAL_MODE, mode); | 1939 | gma_write16(hw, port, GM_SERIAL_MODE, mode); |
| 1935 | 1940 | ||
| 1936 | sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD); | 1941 | sky2_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD); |
| 1937 | 1942 | ||
| 1938 | err = sky2_rx_start(sky2); | 1943 | err = sky2_rx_start(sky2); |
| 1939 | sky2_write32(hw, B0_IMSK, imask); | 1944 | sky2_write32(hw, B0_IMSK, imask); |
| @@ -1941,7 +1946,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1941 | if (err) | 1946 | if (err) |
| 1942 | dev_close(dev); | 1947 | dev_close(dev); |
| 1943 | else { | 1948 | else { |
| 1944 | gma_write16(hw, sky2->port, GM_GP_CTRL, ctl); | 1949 | gma_write16(hw, port, GM_GP_CTRL, ctl); |
| 1945 | 1950 | ||
| 1946 | netif_poll_enable(hw->dev[0]); | 1951 | netif_poll_enable(hw->dev[0]); |
| 1947 | netif_wake_queue(dev); | 1952 | netif_wake_queue(dev); |
| @@ -3334,6 +3339,36 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
| 3334 | regs->len - B3_RI_WTO_R1); | 3339 | regs->len - B3_RI_WTO_R1); |
| 3335 | } | 3340 | } |
| 3336 | 3341 | ||
| 3342 | /* In order to do Jumbo packets on these chips, need to turn off the | ||
| 3343 | * transmit store/forward. Therefore checksum offload won't work. | ||
| 3344 | */ | ||
| 3345 | static int no_tx_offload(struct net_device *dev) | ||
| 3346 | { | ||
| 3347 | const struct sky2_port *sky2 = netdev_priv(dev); | ||
| 3348 | const struct sky2_hw *hw = sky2->hw; | ||
| 3349 | |||
| 3350 | return dev->mtu > ETH_DATA_LEN && | ||
| 3351 | (hw->chip_id == CHIP_ID_YUKON_EX | ||
| 3352 | || hw->chip_id == CHIP_ID_YUKON_EC_U); | ||
| 3353 | } | ||
| 3354 | |||
| 3355 | static int sky2_set_tx_csum(struct net_device *dev, u32 data) | ||
| 3356 | { | ||
| 3357 | if (data && no_tx_offload(dev)) | ||
| 3358 | return -EINVAL; | ||
| 3359 | |||
| 3360 | return ethtool_op_set_tx_csum(dev, data); | ||
| 3361 | } | ||
| 3362 | |||
| 3363 | |||
| 3364 | static int sky2_set_tso(struct net_device *dev, u32 data) | ||
| 3365 | { | ||
| 3366 | if (data && no_tx_offload(dev)) | ||
| 3367 | return -EINVAL; | ||
| 3368 | |||
| 3369 | return ethtool_op_set_tso(dev, data); | ||
| 3370 | } | ||
| 3371 | |||
| 3337 | static const struct ethtool_ops sky2_ethtool_ops = { | 3372 | static const struct ethtool_ops sky2_ethtool_ops = { |
| 3338 | .get_settings = sky2_get_settings, | 3373 | .get_settings = sky2_get_settings, |
| 3339 | .set_settings = sky2_set_settings, | 3374 | .set_settings = sky2_set_settings, |
| @@ -3349,9 +3384,9 @@ static const struct ethtool_ops sky2_ethtool_ops = { | |||
| 3349 | .get_sg = ethtool_op_get_sg, | 3384 | .get_sg = ethtool_op_get_sg, |
| 3350 | .set_sg = ethtool_op_set_sg, | 3385 | .set_sg = ethtool_op_set_sg, |
| 3351 | .get_tx_csum = ethtool_op_get_tx_csum, | 3386 | .get_tx_csum = ethtool_op_get_tx_csum, |
| 3352 | .set_tx_csum = ethtool_op_set_tx_csum, | 3387 | .set_tx_csum = sky2_set_tx_csum, |
| 3353 | .get_tso = ethtool_op_get_tso, | 3388 | .get_tso = ethtool_op_get_tso, |
| 3354 | .set_tso = ethtool_op_set_tso, | 3389 | .set_tso = sky2_set_tso, |
| 3355 | .get_rx_csum = sky2_get_rx_csum, | 3390 | .get_rx_csum = sky2_get_rx_csum, |
| 3356 | .set_rx_csum = sky2_set_rx_csum, | 3391 | .set_rx_csum = sky2_set_rx_csum, |
| 3357 | .get_strings = sky2_get_strings, | 3392 | .get_strings = sky2_get_strings, |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 9ca4a2c061c6..5efb5afc45ba 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
| @@ -741,6 +741,11 @@ enum { | |||
| 741 | TX_GMF_RP = 0x0d70,/* 32 bit Tx GMAC FIFO Read Pointer */ | 741 | TX_GMF_RP = 0x0d70,/* 32 bit Tx GMAC FIFO Read Pointer */ |
| 742 | TX_GMF_RSTP = 0x0d74,/* 32 bit Tx GMAC FIFO Restart Pointer */ | 742 | TX_GMF_RSTP = 0x0d74,/* 32 bit Tx GMAC FIFO Restart Pointer */ |
| 743 | TX_GMF_RLEV = 0x0d78,/* 32 bit Tx GMAC FIFO Read Level */ | 743 | TX_GMF_RLEV = 0x0d78,/* 32 bit Tx GMAC FIFO Read Level */ |
| 744 | |||
| 745 | /* Threshold values for Yukon-EC Ultra and Extreme */ | ||
| 746 | ECU_AE_THR = 0x0070, /* Almost Empty Threshold */ | ||
| 747 | ECU_TXFF_LEV = 0x01a0, /* Tx BMU FIFO Level */ | ||
| 748 | ECU_JUMBO_WM = 0x0080, /* Jumbo Mode Watermark */ | ||
| 744 | }; | 749 | }; |
| 745 | 750 | ||
| 746 | /* Descriptor Poll Timer Registers */ | 751 | /* Descriptor Poll Timer Registers */ |
| @@ -1634,6 +1639,9 @@ enum { | |||
| 1634 | TX_VLAN_TAG_ON = 1<<25,/* enable VLAN tagging */ | 1639 | TX_VLAN_TAG_ON = 1<<25,/* enable VLAN tagging */ |
| 1635 | TX_VLAN_TAG_OFF = 1<<24,/* disable VLAN tagging */ | 1640 | TX_VLAN_TAG_OFF = 1<<24,/* disable VLAN tagging */ |
| 1636 | 1641 | ||
| 1642 | TX_JUMBO_ENA = 1<<23,/* PCI Jumbo Mode enable (Yukon-EC Ultra) */ | ||
| 1643 | TX_JUMBO_DIS = 1<<22,/* PCI Jumbo Mode enable (Yukon-EC Ultra) */ | ||
| 1644 | |||
| 1637 | GMF_WSP_TST_ON = 1<<18,/* Write Shadow Pointer Test On */ | 1645 | GMF_WSP_TST_ON = 1<<18,/* Write Shadow Pointer Test On */ |
| 1638 | GMF_WSP_TST_OFF = 1<<17,/* Write Shadow Pointer Test Off */ | 1646 | GMF_WSP_TST_OFF = 1<<17,/* Write Shadow Pointer Test Off */ |
| 1639 | GMF_WSP_STEP = 1<<16,/* Write Shadow Pointer Step/Increment */ | 1647 | GMF_WSP_STEP = 1<<16,/* Write Shadow Pointer Step/Increment */ |
