diff options
Diffstat (limited to 'drivers/net/pch_gbe')
-rw-r--r-- | drivers/net/pch_gbe/pch_gbe.h | 4 | ||||
-rw-r--r-- | drivers/net/pch_gbe/pch_gbe_ethtool.c | 65 | ||||
-rw-r--r-- | drivers/net/pch_gbe/pch_gbe_main.c | 48 | ||||
-rw-r--r-- | drivers/net/pch_gbe/pch_gbe_param.c | 16 | ||||
-rw-r--r-- | drivers/net/pch_gbe/pch_gbe_phy.c | 4 |
5 files changed, 54 insertions, 83 deletions
diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h index bf126e76fab..59fac77d0db 100644 --- a/drivers/net/pch_gbe/pch_gbe.h +++ b/drivers/net/pch_gbe/pch_gbe.h @@ -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; }; diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c index d2174a40d70..ea2d8e41887 100644 --- a/drivers/net/pch_gbe/pch_gbe_ethtool.c +++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c @@ -92,7 +92,7 @@ static int pch_gbe_get_settings(struct net_device *netdev, ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half); if (!netif_carrier_ok(adapter->netdev)) - ecmd->speed = -1; + ethtool_cmd_speed_set(ecmd, -1); return ret; } @@ -109,12 +109,15 @@ static int pch_gbe_set_settings(struct net_device *netdev, { struct pch_gbe_adapter *adapter = netdev_priv(netdev); struct pch_gbe_hw *hw = &adapter->hw; + u32 speed = ethtool_cmd_speed(ecmd); int ret; pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET); - if (ecmd->speed == USHRT_MAX) { - ecmd->speed = SPEED_1000; + /* when set_settings() is called with a ethtool_cmd previously + * filled by get_settings() on a down link, speed is -1: */ + if (speed == UINT_MAX) { + speed = SPEED_1000; ecmd->duplex = DUPLEX_FULL; } ret = mii_ethtool_sset(&adapter->mii, ecmd); @@ -122,7 +125,7 @@ static int pch_gbe_set_settings(struct net_device *netdev, pr_err("Error: mii_ethtool_sset\n"); return ret; } - hw->mac.link_speed = ecmd->speed; + hw->mac.link_speed = speed; hw->mac.link_duplex = ecmd->duplex; hw->phy.autoneg_advertised = ecmd->advertising; hw->mac.autoneg = ecmd->autoneg; @@ -434,57 +437,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 +506,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, diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 56d049a472d..c2476fd9657 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -659,6 +659,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; @@ -669,7 +670,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 { @@ -890,12 +891,12 @@ static void pch_gbe_watchdog(unsigned long data) struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data; struct net_device *netdev = adapter->netdev; struct pch_gbe_hw *hw = &adapter->hw; - struct ethtool_cmd cmd; pr_debug("right now = %ld\n", jiffies); pch_gbe_update_stats(adapter); if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) { + struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; netdev->tx_queue_len = adapter->tx_queue_len; /* mii library handles link maintenance tasks */ if (mii_ethtool_gset(&adapter->mii, &cmd)) { @@ -905,7 +906,7 @@ static void pch_gbe_watchdog(unsigned long data) PCH_GBE_WATCHDOG_PERIOD)); return; } - hw->mac.link_speed = cmd.speed; + hw->mac.link_speed = ethtool_cmd_speed(&cmd); hw->mac.link_duplex = cmd.duplex; /* Set the RGMII control. */ pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed, @@ -915,7 +916,7 @@ static void pch_gbe_watchdog(unsigned long data) hw->mac.link_duplex); netdev_dbg(netdev, "Link is Up %d Mbps %s-Duplex\n", - cmd.speed, + hw->mac.link_speed, cmd.duplex == DUPLEX_FULL ? "Full" : "Half"); netif_carrier_on(netdev); netif_wake_queue(netdev); @@ -953,7 +954,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 */ @@ -961,7 +962,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)) { @@ -1429,7 +1430,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, @@ -2032,6 +2033,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 @@ -2131,6 +2155,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 @@ -2336,7 +2361,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); @@ -2375,11 +2402,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); diff --git a/drivers/net/pch_gbe/pch_gbe_param.c b/drivers/net/pch_gbe/pch_gbe_param.c index ef0996a0eaa..5b5d90a47e2 100644 --- a/drivers/net/pch_gbe/pch_gbe_param.c +++ b/drivers/net/pch_gbe/pch_gbe_param.c @@ -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 = { diff --git a/drivers/net/pch_gbe/pch_gbe_phy.c b/drivers/net/pch_gbe/pch_gbe_phy.c index 923a687acd3..28bb9603d73 100644 --- a/drivers/net/pch_gbe/pch_gbe_phy.c +++ b/drivers/net/pch_gbe/pch_gbe_phy.c @@ -247,7 +247,7 @@ inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw) void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw) { struct pch_gbe_adapter *adapter; - struct ethtool_cmd cmd; + struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; int ret; u16 mii_reg; @@ -256,7 +256,7 @@ void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw) if (ret) pr_err("Error: mii_ethtool_gset\n"); - cmd.speed = hw->mac.link_speed; + ethtool_cmd_speed_set(&cmd, hw->mac.link_speed); cmd.duplex = hw->mac.link_duplex; cmd.advertising = hw->phy.autoneg_advertised; cmd.autoneg = hw->mac.autoneg; |