Commit e6a46416 authored by Michał Mirosław's avatar Michał Mirosław Committed by David S. Miller

net: ksz884x: convert to hw_features

This also fixes possible race when changing receive checksum state
and removes IPV6_CSUM_GEN_HACK as it's always set.

BTW, The claim about fake IPV6 checksum looks dubious. If that were true,
then there's a problem in networking core and should be fixed there and not
in random drivers.

BTW#2, there's no MAINTAINERS entry for this driver. I assume this driver
is supported by Micrel?
Signed-off-by: default avatarMichał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5e982f3b
...@@ -1221,7 +1221,6 @@ struct ksz_port_info { ...@@ -1221,7 +1221,6 @@ struct ksz_port_info {
#define LINK_INT_WORKING (1 << 0) #define LINK_INT_WORKING (1 << 0)
#define SMALL_PACKET_TX_BUG (1 << 1) #define SMALL_PACKET_TX_BUG (1 << 1)
#define HALF_DUPLEX_SIGNAL_BUG (1 << 2) #define HALF_DUPLEX_SIGNAL_BUG (1 << 2)
#define IPV6_CSUM_GEN_HACK (1 << 3)
#define RX_HUGE_FRAME (1 << 4) #define RX_HUGE_FRAME (1 << 4)
#define STP_SUPPORT (1 << 8) #define STP_SUPPORT (1 << 8)
...@@ -3748,7 +3747,6 @@ static int hw_init(struct ksz_hw *hw) ...@@ -3748,7 +3747,6 @@ static int hw_init(struct ksz_hw *hw)
if (1 == rc) if (1 == rc)
hw->features |= HALF_DUPLEX_SIGNAL_BUG; hw->features |= HALF_DUPLEX_SIGNAL_BUG;
} }
hw->features |= IPV6_CSUM_GEN_HACK;
return rc; return rc;
} }
...@@ -4887,8 +4885,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -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); left = hw_alloc_pkt(hw, skb->len, num);
if (left) { if (left) {
if (left < num || 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)))) { (ETH_P_IPV6 == htons(skb->protocol)))) {
struct sk_buff *org_skb = skb; struct sk_buff *org_skb = skb;
...@@ -6583,57 +6580,33 @@ static void netdev_get_ethtool_stats(struct net_device *dev, ...@@ -6583,57 +6580,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. * @dev: Network device.
* * @features: New device features (offloads).
* 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.
* *
* This function sets receive checksum support setting. * This function sets receive checksum support setting.
* *
* Return 0 if successful; otherwise an error code. * 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_priv *priv = netdev_priv(dev);
struct dev_info *hw_priv = priv->adapter; struct dev_info *hw_priv = priv->adapter;
struct ksz_hw *hw = &hw_priv->hw; 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); mutex_lock(&hw_priv->lock);
if (new_setting != hw->rx_cfg) {
hw->rx_cfg = new_setting; /* 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) if (hw->enabled)
writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL); writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
}
mutex_unlock(&hw_priv->lock); mutex_unlock(&hw_priv->lock);
return 0; return 0;
} }
...@@ -6658,12 +6631,6 @@ static struct ethtool_ops netdev_ethtool_ops = { ...@@ -6658,12 +6631,6 @@ static struct ethtool_ops netdev_ethtool_ops = {
.get_strings = netdev_get_strings, .get_strings = netdev_get_strings,
.get_sset_count = netdev_get_sset_count, .get_sset_count = netdev_get_sset_count,
.get_ethtool_stats = netdev_get_ethtool_stats, .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 +6795,15 @@ static int __init netdev_init(struct net_device *dev) ...@@ -6828,14 +6795,15 @@ static int __init netdev_init(struct net_device *dev)
/* 500 ms timeout */ /* 500 ms timeout */
dev->watchdog_timeo = HZ / 2; 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 * 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->hw_features |= NETIF_F_IPV6_CSUM;
dev->features |= NETIF_F_SG;
dev->features |= dev->hw_features;
sema_init(&priv->proc_sem, 1); sema_init(&priv->proc_sem, 1);
...@@ -6860,6 +6828,7 @@ static const struct net_device_ops netdev_ops = { ...@@ -6860,6 +6828,7 @@ static const struct net_device_ops netdev_ops = {
.ndo_start_xmit = netdev_tx, .ndo_start_xmit = netdev_tx,
.ndo_tx_timeout = netdev_tx_timeout, .ndo_tx_timeout = netdev_tx_timeout,
.ndo_change_mtu = netdev_change_mtu, .ndo_change_mtu = netdev_change_mtu,
.ndo_set_features = netdev_set_features,
.ndo_set_mac_address = netdev_set_mac_address, .ndo_set_mac_address = netdev_set_mac_address,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = netdev_ioctl, .ndo_do_ioctl = netdev_ioctl,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment