aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ksz884x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ksz884x.c')
-rw-r--r--drivers/net/ksz884x.c82
1 files changed, 26 insertions, 56 deletions
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 7f7d5708a65..41ea5920c15 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -1221,7 +1221,6 @@ struct ksz_port_info {
1221#define LINK_INT_WORKING (1 << 0) 1221#define LINK_INT_WORKING (1 << 0)
1222#define SMALL_PACKET_TX_BUG (1 << 1) 1222#define SMALL_PACKET_TX_BUG (1 << 1)
1223#define HALF_DUPLEX_SIGNAL_BUG (1 << 2) 1223#define HALF_DUPLEX_SIGNAL_BUG (1 << 2)
1224#define IPV6_CSUM_GEN_HACK (1 << 3)
1225#define RX_HUGE_FRAME (1 << 4) 1224#define RX_HUGE_FRAME (1 << 4)
1226#define STP_SUPPORT (1 << 8) 1225#define STP_SUPPORT (1 << 8)
1227 1226
@@ -3748,7 +3747,6 @@ static int hw_init(struct ksz_hw *hw)
3748 if (1 == rc) 3747 if (1 == rc)
3749 hw->features |= HALF_DUPLEX_SIGNAL_BUG; 3748 hw->features |= HALF_DUPLEX_SIGNAL_BUG;
3750 } 3749 }
3751 hw->features |= IPV6_CSUM_GEN_HACK;
3752 return rc; 3750 return rc;
3753} 3751}
3754 3752
@@ -4887,8 +4885,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
4887 left = hw_alloc_pkt(hw, skb->len, num); 4885 left = hw_alloc_pkt(hw, skb->len, num);
4888 if (left) { 4886 if (left) {
4889 if (left < num || 4887 if (left < num ||
4890 ((hw->features & IPV6_CSUM_GEN_HACK) && 4888 ((CHECKSUM_PARTIAL == skb->ip_summed) &&
4891 (CHECKSUM_PARTIAL == skb->ip_summed) &&
4892 (ETH_P_IPV6 == htons(skb->protocol)))) { 4889 (ETH_P_IPV6 == htons(skb->protocol)))) {
4893 struct sk_buff *org_skb = skb; 4890 struct sk_buff *org_skb = skb;
4894 4891
@@ -6001,6 +5998,7 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
6001 struct dev_priv *priv = netdev_priv(dev); 5998 struct dev_priv *priv = netdev_priv(dev);
6002 struct dev_info *hw_priv = priv->adapter; 5999 struct dev_info *hw_priv = priv->adapter;
6003 struct ksz_port *port = &priv->port; 6000 struct ksz_port *port = &priv->port;
6001 u32 speed = ethtool_cmd_speed(cmd);
6004 int rc; 6002 int rc;
6005 6003
6006 /* 6004 /*
@@ -6009,11 +6007,11 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
6009 */ 6007 */
6010 if (cmd->autoneg && priv->advertising == cmd->advertising) { 6008 if (cmd->autoneg && priv->advertising == cmd->advertising) {
6011 cmd->advertising |= ADVERTISED_ALL; 6009 cmd->advertising |= ADVERTISED_ALL;
6012 if (10 == cmd->speed) 6010 if (10 == speed)
6013 cmd->advertising &= 6011 cmd->advertising &=
6014 ~(ADVERTISED_100baseT_Full | 6012 ~(ADVERTISED_100baseT_Full |
6015 ADVERTISED_100baseT_Half); 6013 ADVERTISED_100baseT_Half);
6016 else if (100 == cmd->speed) 6014 else if (100 == speed)
6017 cmd->advertising &= 6015 cmd->advertising &=
6018 ~(ADVERTISED_10baseT_Full | 6016 ~(ADVERTISED_10baseT_Full |
6019 ADVERTISED_10baseT_Half); 6017 ADVERTISED_10baseT_Half);
@@ -6035,8 +6033,8 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
6035 port->force_link = 0; 6033 port->force_link = 0;
6036 } else { 6034 } else {
6037 port->duplex = cmd->duplex + 1; 6035 port->duplex = cmd->duplex + 1;
6038 if (cmd->speed != 1000) 6036 if (1000 != speed)
6039 port->speed = cmd->speed; 6037 port->speed = speed;
6040 if (cmd->autoneg) 6038 if (cmd->autoneg)
6041 port->force_link = 0; 6039 port->force_link = 0;
6042 else 6040 else
@@ -6583,57 +6581,33 @@ static void netdev_get_ethtool_stats(struct net_device *dev,
6583} 6581}
6584 6582
6585/** 6583/**
6586 * netdev_get_rx_csum - get receive checksum support 6584 * netdev_set_features - set receive checksum support
6587 * @dev: Network device. 6585 * @dev: Network device.
6588 * 6586 * @features: New device features (offloads).
6589 * This function gets receive checksum support setting.
6590 *
6591 * Return true if receive checksum is enabled; false otherwise.
6592 */
6593static u32 netdev_get_rx_csum(struct net_device *dev)
6594{
6595 struct dev_priv *priv = netdev_priv(dev);
6596 struct dev_info *hw_priv = priv->adapter;
6597 struct ksz_hw *hw = &hw_priv->hw;
6598
6599 return hw->rx_cfg &
6600 (DMA_RX_CSUM_UDP |
6601 DMA_RX_CSUM_TCP |
6602 DMA_RX_CSUM_IP);
6603}
6604
6605/**
6606 * netdev_set_rx_csum - set receive checksum support
6607 * @dev: Network device.
6608 * @data: Zero to disable receive checksum support.
6609 * 6587 *
6610 * This function sets receive checksum support setting. 6588 * This function sets receive checksum support setting.
6611 * 6589 *
6612 * Return 0 if successful; otherwise an error code. 6590 * Return 0 if successful; otherwise an error code.
6613 */ 6591 */
6614static int netdev_set_rx_csum(struct net_device *dev, u32 data) 6592static int netdev_set_features(struct net_device *dev, u32 features)
6615{ 6593{
6616 struct dev_priv *priv = netdev_priv(dev); 6594 struct dev_priv *priv = netdev_priv(dev);
6617 struct dev_info *hw_priv = priv->adapter; 6595 struct dev_info *hw_priv = priv->adapter;
6618 struct ksz_hw *hw = &hw_priv->hw; 6596 struct ksz_hw *hw = &hw_priv->hw;
6619 u32 new_setting = hw->rx_cfg;
6620 6597
6621 if (data)
6622 new_setting |=
6623 (DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP |
6624 DMA_RX_CSUM_IP);
6625 else
6626 new_setting &=
6627 ~(DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP |
6628 DMA_RX_CSUM_IP);
6629 new_setting &= ~DMA_RX_CSUM_UDP;
6630 mutex_lock(&hw_priv->lock); 6598 mutex_lock(&hw_priv->lock);
6631 if (new_setting != hw->rx_cfg) { 6599
6632 hw->rx_cfg = new_setting; 6600 /* see note in hw_setup() */
6633 if (hw->enabled) 6601 if (features & NETIF_F_RXCSUM)
6634 writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL); 6602 hw->rx_cfg |= DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP;
6635 } 6603 else
6604 hw->rx_cfg &= ~(DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP);
6605
6606 if (hw->enabled)
6607 writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
6608
6636 mutex_unlock(&hw_priv->lock); 6609 mutex_unlock(&hw_priv->lock);
6610
6637 return 0; 6611 return 0;
6638} 6612}
6639 6613
@@ -6658,12 +6632,6 @@ static struct ethtool_ops netdev_ethtool_ops = {
6658 .get_strings = netdev_get_strings, 6632 .get_strings = netdev_get_strings,
6659 .get_sset_count = netdev_get_sset_count, 6633 .get_sset_count = netdev_get_sset_count,
6660 .get_ethtool_stats = netdev_get_ethtool_stats, 6634 .get_ethtool_stats = netdev_get_ethtool_stats,
6661 .get_rx_csum = netdev_get_rx_csum,
6662 .set_rx_csum = netdev_set_rx_csum,
6663 .get_tx_csum = ethtool_op_get_tx_csum,
6664 .set_tx_csum = ethtool_op_set_tx_csum,
6665 .get_sg = ethtool_op_get_sg,
6666 .set_sg = ethtool_op_set_sg,
6667}; 6635};
6668 6636
6669/* 6637/*
@@ -6828,14 +6796,15 @@ static int __init netdev_init(struct net_device *dev)
6828 /* 500 ms timeout */ 6796 /* 500 ms timeout */
6829 dev->watchdog_timeo = HZ / 2; 6797 dev->watchdog_timeo = HZ / 2;
6830 6798
6831 dev->features |= NETIF_F_IP_CSUM; 6799 dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM;
6832 6800
6833 /* 6801 /*
6834 * Hardware does not really support IPv6 checksum generation, but 6802 * Hardware does not really support IPv6 checksum generation, but
6835 * driver actually runs faster with this on. Refer IPV6_CSUM_GEN_HACK. 6803 * driver actually runs faster with this on.
6836 */ 6804 */
6837 dev->features |= NETIF_F_IPV6_CSUM; 6805 dev->hw_features |= NETIF_F_IPV6_CSUM;
6838 dev->features |= NETIF_F_SG; 6806
6807 dev->features |= dev->hw_features;
6839 6808
6840 sema_init(&priv->proc_sem, 1); 6809 sema_init(&priv->proc_sem, 1);
6841 6810
@@ -6860,6 +6829,7 @@ static const struct net_device_ops netdev_ops = {
6860 .ndo_start_xmit = netdev_tx, 6829 .ndo_start_xmit = netdev_tx,
6861 .ndo_tx_timeout = netdev_tx_timeout, 6830 .ndo_tx_timeout = netdev_tx_timeout,
6862 .ndo_change_mtu = netdev_change_mtu, 6831 .ndo_change_mtu = netdev_change_mtu,
6832 .ndo_set_features = netdev_set_features,
6863 .ndo_set_mac_address = netdev_set_mac_address, 6833 .ndo_set_mac_address = netdev_set_mac_address,
6864 .ndo_validate_addr = eth_validate_addr, 6834 .ndo_validate_addr = eth_validate_addr,
6865 .ndo_do_ioctl = netdev_ioctl, 6835 .ndo_do_ioctl = netdev_ioctl,