summaryrefslogtreecommitdiffstats
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 7f7d5708a658..41ea5920c158 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -1221,7 +1221,6 @@ struct ksz_port_info {
#define LINK_INT_WORKING (1 << 0)
#define SMALL_PACKET_TX_BUG (1 << 1)
#define HALF_DUPLEX_SIGNAL_BUG (1 << 2)
-#define IPV6_CSUM_GEN_HACK (1 << 3)
#define RX_HUGE_FRAME (1 << 4)
#define STP_SUPPORT (1 << 8)
@@ -3748,7 +3747,6 @@ static int hw_init(struct ksz_hw *hw)
if (1 == rc)
hw->features |= HALF_DUPLEX_SIGNAL_BUG;
}
- hw->features |= IPV6_CSUM_GEN_HACK;
return rc;
}
@@ -4887,8 +4885,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
left = hw_alloc_pkt(hw, skb->len, num);
if (left) {
if (left < num ||
- ((hw->features & IPV6_CSUM_GEN_HACK) &&
- (CHECKSUM_PARTIAL == skb->ip_summed) &&
+ ((CHECKSUM_PARTIAL == skb->ip_summed) &&
(ETH_P_IPV6 == htons(skb->protocol)))) {
struct sk_buff *org_skb = skb;
@@ -6001,6 +5998,7 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
struct dev_priv *priv = netdev_priv(dev);
struct dev_info *hw_priv = priv->adapter;
struct ksz_port *port = &priv->port;
+ u32 speed = ethtool_cmd_speed(cmd);
int rc;
/*
@@ -6009,11 +6007,11 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
*/
if (cmd->autoneg && priv->advertising == cmd->advertising) {
cmd->advertising |= ADVERTISED_ALL;
- if (10 == cmd->speed)
+ if (10 == speed)
cmd->advertising &=
~(ADVERTISED_100baseT_Full |
ADVERTISED_100baseT_Half);
- else if (100 == cmd->speed)
+ else if (100 == speed)
cmd->advertising &=
~(ADVERTISED_10baseT_Full |
ADVERTISED_10baseT_Half);
@@ -6035,8 +6033,8 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
port->force_link = 0;
} else {
port->duplex = cmd->duplex + 1;
- if (cmd->speed != 1000)
- port->speed = cmd->speed;
+ if (1000 != speed)
+ port->speed = speed;
if (cmd->autoneg)
port->force_link = 0;
else
@@ -6583,57 +6581,33 @@ static void netdev_get_ethtool_stats(struct net_device *dev,
}
/**
- * netdev_get_rx_csum - get receive checksum support
+ * netdev_set_features - set receive checksum support
* @dev: Network device.
- *
- * This function gets receive checksum support setting.
- *
- * Return true if receive checksum is enabled; false otherwise.
- */
-static u32 netdev_get_rx_csum(struct net_device *dev)
-{
- struct dev_priv *priv = netdev_priv(dev);
- struct dev_info *hw_priv = priv->adapter;
- struct ksz_hw *hw = &hw_priv->hw;
-
- return hw->rx_cfg &
- (DMA_RX_CSUM_UDP |
- DMA_RX_CSUM_TCP |
- DMA_RX_CSUM_IP);
-}
-
-/**
- * netdev_set_rx_csum - set receive checksum support
- * @dev: Network device.
- * @data: Zero to disable receive checksum support.
+ * @features: New device features (offloads).
*
* This function sets receive checksum support setting.
*
* Return 0 if successful; otherwise an error code.
*/
-static int netdev_set_rx_csum(struct net_device *dev, u32 data)
+static int netdev_set_features(struct net_device *dev, u32 features)
{
struct dev_priv *priv = netdev_priv(dev);
struct dev_info *hw_priv = priv->adapter;
struct ksz_hw *hw = &hw_priv->hw;
- u32 new_setting = hw->rx_cfg;
- if (data)
- new_setting |=
- (DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP |
- DMA_RX_CSUM_IP);
- else
- new_setting &=
- ~(DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP |
- DMA_RX_CSUM_IP);
- new_setting &= ~DMA_RX_CSUM_UDP;
mutex_lock(&hw_priv->lock);
- if (new_setting != hw->rx_cfg) {
- hw->rx_cfg = new_setting;
- if (hw->enabled)
- writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
- }
+
+ /* see note in hw_setup() */
+ if (features & NETIF_F_RXCSUM)
+ hw->rx_cfg |= DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP;
+ else
+ hw->rx_cfg &= ~(DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP);
+
+ if (hw->enabled)
+ writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
+
mutex_unlock(&hw_priv->lock);
+
return 0;
}
@@ -6658,12 +6632,6 @@ static struct ethtool_ops netdev_ethtool_ops = {
.get_strings = netdev_get_strings,
.get_sset_count = netdev_get_sset_count,
.get_ethtool_stats = netdev_get_ethtool_stats,
- .get_rx_csum = netdev_get_rx_csum,
- .set_rx_csum = netdev_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
};
/*
@@ -6828,14 +6796,15 @@ static int __init netdev_init(struct net_device *dev)
/* 500 ms timeout */
dev->watchdog_timeo = HZ / 2;
- dev->features |= NETIF_F_IP_CSUM;
+ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM;
/*
* Hardware does not really support IPv6 checksum generation, but
- * driver actually runs faster with this on. Refer IPV6_CSUM_GEN_HACK.
+ * driver actually runs faster with this on.
*/
- dev->features |= NETIF_F_IPV6_CSUM;
- dev->features |= NETIF_F_SG;
+ dev->hw_features |= NETIF_F_IPV6_CSUM;
+
+ dev->features |= dev->hw_features;
sema_init(&priv->proc_sem, 1);
@@ -6860,6 +6829,7 @@ static const struct net_device_ops netdev_ops = {
.ndo_start_xmit = netdev_tx,
.ndo_tx_timeout = netdev_tx_timeout,
.ndo_change_mtu = netdev_change_mtu,
+ .ndo_set_features = netdev_set_features,
.ndo_set_mac_address = netdev_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = netdev_ioctl,