net: pch_gbe: convert to hw_features
Michał Mirosław [Tue, 19 Apr 2011 01:56:12 +0000 (01:56 +0000)]
This also fixes bug in xmit path, where TX checksum offload state was used
instead of skb->ip_summed to decide if the offload was needed.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>

drivers/net/pch_gbe/pch_gbe.h
drivers/net/pch_gbe/pch_gbe_ethtool.c
drivers/net/pch_gbe/pch_gbe_main.c
drivers/net/pch_gbe/pch_gbe_param.c

index bf126e7..59fac77 100644 (file)
@@ -597,8 +597,6 @@ struct pch_gbe_hw_stats {
  * @rx_ring:           Pointer of Rx descriptor ring structure
  * @rx_buffer_len:     Receive buffer length
  * @tx_queue_len:      Transmit queue length
- * @rx_csum:           Receive TCP/IP checksum enable/disable
- * @tx_csum:           Transmit TCP/IP checksum enable/disable
  * @have_msi:          PCI MSI mode flag
  */
 
@@ -623,8 +621,6 @@ struct pch_gbe_adapter {
        struct pch_gbe_rx_ring *rx_ring;
        unsigned long rx_buffer_len;
        unsigned long tx_queue_len;
-       bool rx_csum;
-       bool tx_csum;
        bool have_msi;
 };
 
index d2174a4..c35d105 100644 (file)
@@ -434,57 +434,6 @@ static int pch_gbe_set_pauseparam(struct net_device *netdev,
 }
 
 /**
- * pch_gbe_get_rx_csum - Report whether receive checksums are turned on or off
- * @netdev:  Network interface device structure
- * Returns
- *     true(1):  Checksum On
- *     false(0): Checksum Off
- */
-static u32 pch_gbe_get_rx_csum(struct net_device *netdev)
-{
-       struct pch_gbe_adapter *adapter = netdev_priv(netdev);
-
-       return adapter->rx_csum;
-}
-
-/**
- * pch_gbe_set_rx_csum - Turn receive checksum on or off
- * @netdev:  Network interface device structure
- * @data:    Checksum On[true] or Off[false]
- * Returns
- *     0:                      Successful.
- *     Negative value:         Failed.
- */
-static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data)
-{
-       struct pch_gbe_adapter *adapter = netdev_priv(netdev);
-
-       adapter->rx_csum = data;
-       if ((netif_running(netdev)))
-               pch_gbe_reinit_locked(adapter);
-       else
-               pch_gbe_reset(adapter);
-
-       return 0;
-}
-
-/**
- * pch_gbe_set_tx_csum - Turn transmit checksums on or off
- * @netdev: Network interface device structure
- * @data:   Checksum on[true] or off[false]
- * Returns
- *     0:                      Successful.
- *     Negative value:         Failed.
- */
-static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data)
-{
-       struct pch_gbe_adapter *adapter = netdev_priv(netdev);
-
-       adapter->tx_csum = data;
-       return ethtool_op_set_tx_ipv6_csum(netdev, data);
-}
-
-/**
  * pch_gbe_get_strings - Return a set of strings that describe the requested
  *                      objects
  * @netdev:    Network interface device structure
@@ -554,9 +503,6 @@ static const struct ethtool_ops pch_gbe_ethtool_ops = {
        .set_ringparam = pch_gbe_set_ringparam,
        .get_pauseparam = pch_gbe_get_pauseparam,
        .set_pauseparam = pch_gbe_set_pauseparam,
-       .get_rx_csum = pch_gbe_get_rx_csum,
-       .set_rx_csum = pch_gbe_set_rx_csum,
-       .set_tx_csum = pch_gbe_set_tx_csum,
        .get_strings = pch_gbe_get_strings,
        .get_ethtool_stats = pch_gbe_get_ethtool_stats,
        .get_sset_count = pch_gbe_get_sset_count,
index 2ef2f9c..4cc9872 100644 (file)
@@ -656,6 +656,7 @@ static void pch_gbe_configure_tx(struct pch_gbe_adapter *adapter)
  */
 static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)
 {
+       struct net_device *netdev = adapter->netdev;
        struct pch_gbe_hw *hw = &adapter->hw;
        u32 rx_mode, tcpip;
 
@@ -666,7 +667,7 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)
 
        tcpip = ioread32(&hw->reg->TCPIP_ACC);
 
-       if (adapter->rx_csum) {
+       if (netdev->features & NETIF_F_RXCSUM) {
                tcpip &= ~PCH_GBE_RX_TCPIPACC_OFF;
                tcpip |= PCH_GBE_RX_TCPIPACC_EN;
        } else {
@@ -950,7 +951,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
        frame_ctrl = 0;
        if (unlikely(skb->len < PCH_GBE_SHORT_PKT))
                frame_ctrl |= PCH_GBE_TXD_CTRL_APAD;
-       if (unlikely(!adapter->tx_csum))
+       if (skb->ip_summed == CHECKSUM_NONE)
                frame_ctrl |= PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
 
        /* Performs checksum processing */
@@ -958,7 +959,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
         * It is because the hardware accelerator does not support a checksum,
         * when the received data size is less than 64 bytes.
         */
-       if ((skb->len < PCH_GBE_SHORT_PKT) && (adapter->tx_csum)) {
+       if (skb->len < PCH_GBE_SHORT_PKT && skb->ip_summed != CHECKSUM_NONE) {
                frame_ctrl |= PCH_GBE_TXD_CTRL_APAD |
                              PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
                if (skb->protocol == htons(ETH_P_IP)) {
@@ -1426,7 +1427,7 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
                        length = (rx_desc->rx_words_eob) - 3;
 
                        /* Decide the data conversion method */
-                       if (!adapter->rx_csum) {
+                       if (!(netdev->features & NETIF_F_RXCSUM)) {
                                /* [Header:14][payload] */
                                if (NET_IP_ALIGN) {
                                        /* Because alignment differs,
@@ -2030,6 +2031,29 @@ static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu)
 }
 
 /**
+ * pch_gbe_set_features - Reset device after features changed
+ * @netdev:   Network interface device structure
+ * @features:  New features
+ * Returns
+ *     0:              HW state updated successfully
+ */
+static int pch_gbe_set_features(struct net_device *netdev, u32 features)
+{
+       struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+       u32 changed = features ^ netdev->features;
+
+       if (!(changed & NETIF_F_RXCSUM))
+               return 0;
+
+       if (netif_running(netdev))
+               pch_gbe_reinit_locked(adapter);
+       else
+               pch_gbe_reset(adapter);
+
+       return 0;
+}
+
+/**
  * pch_gbe_ioctl - Controls register through a MII interface
  * @netdev:   Network interface device structure
  * @ifr:      Pointer to ifr structure
@@ -2129,6 +2153,7 @@ static const struct net_device_ops pch_gbe_netdev_ops = {
        .ndo_set_mac_address = pch_gbe_set_mac,
        .ndo_tx_timeout = pch_gbe_tx_timeout,
        .ndo_change_mtu = pch_gbe_change_mtu,
+       .ndo_set_features = pch_gbe_set_features,
        .ndo_do_ioctl = pch_gbe_ioctl,
        .ndo_set_multicast_list = &pch_gbe_set_multi,
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2334,7 +2359,9 @@ static int pch_gbe_probe(struct pci_dev *pdev,
        netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD;
        netif_napi_add(netdev, &adapter->napi,
                       pch_gbe_napi_poll, PCH_GBE_RX_WEIGHT);
-       netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO;
+       netdev->hw_features = NETIF_F_RXCSUM |
+               NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+       netdev->features = netdev->hw_features;
        pch_gbe_set_ethtool_ops(netdev);
 
        pch_gbe_mac_load_mac_addr(&adapter->hw);
@@ -2373,11 +2400,6 @@ static int pch_gbe_probe(struct pci_dev *pdev,
 
        pch_gbe_check_options(adapter);
 
-       if (adapter->tx_csum)
-               netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-       else
-               netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-
        /* initialize the wol settings based on the eeprom settings */
        adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING;
        dev_info(&pdev->dev, "MAC address : %pM\n", netdev->dev_addr);
index ef0996a..5b5d90a 100644 (file)
@@ -426,6 +426,8 @@ full_duplex_only:
 void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
 {
        struct pch_gbe_hw *hw = &adapter->hw;
+       struct net_device *dev = adapter->netdev;
+       int val;
 
        { /* Transmit Descriptor Count */
                static const struct pch_gbe_option opt = {
@@ -466,9 +468,10 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
                        .err  = "defaulting to Enabled",
                        .def  = PCH_GBE_DEFAULT_RX_CSUM
                };
-               adapter->rx_csum = XsumRX;
-               pch_gbe_validate_option((int *)(&adapter->rx_csum),
-                                       &opt, adapter);
+               val = XsumRX;
+               pch_gbe_validate_option(&val, &opt, adapter);
+               if (!val)
+                       dev->features &= ~NETIF_F_RXCSUM;
        }
        { /* Checksum Offload Enable/Disable */
                static const struct pch_gbe_option opt = {
@@ -477,9 +480,10 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
                        .err  = "defaulting to Enabled",
                        .def  = PCH_GBE_DEFAULT_TX_CSUM
                };
-               adapter->tx_csum = XsumTX;
-               pch_gbe_validate_option((int *)(&adapter->tx_csum),
-                                               &opt, adapter);
+               val = XsumTX;
+               pch_gbe_validate_option(&val, &opt, adapter);
+               if (!val)
+                       dev->features &= ~NETIF_F_ALL_CSUM;
        }
        { /* Flow Control */
                static const struct pch_gbe_option opt = {