aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ksz884x.c
diff options
context:
space:
mode:
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>2011-04-09 23:13:21 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-10 21:55:20 -0400
commite6a46416d4233c99a041ca35c1f692ecae9f942d (patch)
tree7d96127a6e9d7ef19702dcde3da3a68304858f74 /drivers/net/ksz884x.c
parent5e982f3bfdd5d063f8806a26c87843496a35d26b (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.c73
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 */
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 * 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 */
6614static int netdev_set_rx_csum(struct net_device *dev, u32 data) 6591static 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,