diff options
author | Michał Mirosław <mirq-linux@rere.qmqm.pl> | 2011-04-09 23:13:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-10 21:55:20 -0400 |
commit | e6a46416d4233c99a041ca35c1f692ecae9f942d (patch) | |
tree | 7d96127a6e9d7ef19702dcde3da3a68304858f74 /drivers/net/ksz884x.c | |
parent | 5e982f3bfdd5d063f8806a26c87843496a35d26b (diff) |
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: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ksz884x.c')
-rw-r--r-- | drivers/net/ksz884x.c | 73 |
1 files changed, 21 insertions, 52 deletions
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 7f7d5708a658..2c37a3804303 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 | ||
@@ -6583,57 +6580,33 @@ static void netdev_get_ethtool_stats(struct net_device *dev, | |||
6583 | } | 6580 | } |
6584 | 6581 | ||
6585 | /** | 6582 | /** |
6586 | * netdev_get_rx_csum - get receive checksum support | 6583 | * netdev_set_features - set receive checksum support |
6587 | * @dev: Network device. | 6584 | * @dev: Network device. |
6588 | * | 6585 | * @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 | */ | ||
6593 | static 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 | * | 6586 | * |
6610 | * This function sets receive checksum support setting. | 6587 | * This function sets receive checksum support setting. |
6611 | * | 6588 | * |
6612 | * Return 0 if successful; otherwise an error code. | 6589 | * Return 0 if successful; otherwise an error code. |
6613 | */ | 6590 | */ |
6614 | static int netdev_set_rx_csum(struct net_device *dev, u32 data) | 6591 | static int netdev_set_features(struct net_device *dev, u32 features) |
6615 | { | 6592 | { |
6616 | struct dev_priv *priv = netdev_priv(dev); | 6593 | struct dev_priv *priv = netdev_priv(dev); |
6617 | struct dev_info *hw_priv = priv->adapter; | 6594 | struct dev_info *hw_priv = priv->adapter; |
6618 | struct ksz_hw *hw = &hw_priv->hw; | 6595 | struct ksz_hw *hw = &hw_priv->hw; |
6619 | u32 new_setting = hw->rx_cfg; | ||
6620 | 6596 | ||
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); | 6597 | mutex_lock(&hw_priv->lock); |
6631 | if (new_setting != hw->rx_cfg) { | 6598 | |
6632 | hw->rx_cfg = new_setting; | 6599 | /* see note in hw_setup() */ |
6633 | if (hw->enabled) | 6600 | if (features & NETIF_F_RXCSUM) |
6634 | writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL); | 6601 | hw->rx_cfg |= DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP; |
6635 | } | 6602 | else |
6603 | hw->rx_cfg &= ~(DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP); | ||
6604 | |||
6605 | if (hw->enabled) | ||
6606 | writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL); | ||
6607 | |||
6636 | mutex_unlock(&hw_priv->lock); | 6608 | mutex_unlock(&hw_priv->lock); |
6609 | |||
6637 | return 0; | 6610 | return 0; |
6638 | } | 6611 | } |
6639 | 6612 | ||
@@ -6658,12 +6631,6 @@ static struct ethtool_ops netdev_ethtool_ops = { | |||
6658 | .get_strings = netdev_get_strings, | 6631 | .get_strings = netdev_get_strings, |
6659 | .get_sset_count = netdev_get_sset_count, | 6632 | .get_sset_count = netdev_get_sset_count, |
6660 | .get_ethtool_stats = netdev_get_ethtool_stats, | 6633 | .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 | }; | 6634 | }; |
6668 | 6635 | ||
6669 | /* | 6636 | /* |
@@ -6828,14 +6795,15 @@ static int __init netdev_init(struct net_device *dev) | |||
6828 | /* 500 ms timeout */ | 6795 | /* 500 ms timeout */ |
6829 | dev->watchdog_timeo = HZ / 2; | 6796 | dev->watchdog_timeo = HZ / 2; |
6830 | 6797 | ||
6831 | dev->features |= NETIF_F_IP_CSUM; | 6798 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM; |
6832 | 6799 | ||
6833 | /* | 6800 | /* |
6834 | * Hardware does not really support IPv6 checksum generation, but | 6801 | * Hardware does not really support IPv6 checksum generation, but |
6835 | * driver actually runs faster with this on. Refer IPV6_CSUM_GEN_HACK. | 6802 | * driver actually runs faster with this on. |
6836 | */ | 6803 | */ |
6837 | dev->features |= NETIF_F_IPV6_CSUM; | 6804 | dev->hw_features |= NETIF_F_IPV6_CSUM; |
6838 | dev->features |= NETIF_F_SG; | 6805 | |
6806 | dev->features |= dev->hw_features; | ||
6839 | 6807 | ||
6840 | sema_init(&priv->proc_sem, 1); | 6808 | sema_init(&priv->proc_sem, 1); |
6841 | 6809 | ||
@@ -6860,6 +6828,7 @@ static const struct net_device_ops netdev_ops = { | |||
6860 | .ndo_start_xmit = netdev_tx, | 6828 | .ndo_start_xmit = netdev_tx, |
6861 | .ndo_tx_timeout = netdev_tx_timeout, | 6829 | .ndo_tx_timeout = netdev_tx_timeout, |
6862 | .ndo_change_mtu = netdev_change_mtu, | 6830 | .ndo_change_mtu = netdev_change_mtu, |
6831 | .ndo_set_features = netdev_set_features, | ||
6863 | .ndo_set_mac_address = netdev_set_mac_address, | 6832 | .ndo_set_mac_address = netdev_set_mac_address, |
6864 | .ndo_validate_addr = eth_validate_addr, | 6833 | .ndo_validate_addr = eth_validate_addr, |
6865 | .ndo_do_ioctl = netdev_ioctl, | 6834 | .ndo_do_ioctl = netdev_ioctl, |