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

net: pch_gbe: convert to hw_features

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: default avatarMichał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3d96c74d
...@@ -597,8 +597,6 @@ struct pch_gbe_hw_stats { ...@@ -597,8 +597,6 @@ struct pch_gbe_hw_stats {
* @rx_ring: Pointer of Rx descriptor ring structure * @rx_ring: Pointer of Rx descriptor ring structure
* @rx_buffer_len: Receive buffer length * @rx_buffer_len: Receive buffer length
* @tx_queue_len: Transmit queue 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 * @have_msi: PCI MSI mode flag
*/ */
...@@ -623,8 +621,6 @@ struct pch_gbe_adapter { ...@@ -623,8 +621,6 @@ struct pch_gbe_adapter {
struct pch_gbe_rx_ring *rx_ring; struct pch_gbe_rx_ring *rx_ring;
unsigned long rx_buffer_len; unsigned long rx_buffer_len;
unsigned long tx_queue_len; unsigned long tx_queue_len;
bool rx_csum;
bool tx_csum;
bool have_msi; bool have_msi;
}; };
......
...@@ -433,57 +433,6 @@ static int pch_gbe_set_pauseparam(struct net_device *netdev, ...@@ -433,57 +433,6 @@ static int pch_gbe_set_pauseparam(struct net_device *netdev,
return ret; return ret;
} }
/**
* 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 * pch_gbe_get_strings - Return a set of strings that describe the requested
* objects * objects
...@@ -554,9 +503,6 @@ static const struct ethtool_ops pch_gbe_ethtool_ops = { ...@@ -554,9 +503,6 @@ static const struct ethtool_ops pch_gbe_ethtool_ops = {
.set_ringparam = pch_gbe_set_ringparam, .set_ringparam = pch_gbe_set_ringparam,
.get_pauseparam = pch_gbe_get_pauseparam, .get_pauseparam = pch_gbe_get_pauseparam,
.set_pauseparam = pch_gbe_set_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_strings = pch_gbe_get_strings,
.get_ethtool_stats = pch_gbe_get_ethtool_stats, .get_ethtool_stats = pch_gbe_get_ethtool_stats,
.get_sset_count = pch_gbe_get_sset_count, .get_sset_count = pch_gbe_get_sset_count,
......
...@@ -656,6 +656,7 @@ static void pch_gbe_configure_tx(struct pch_gbe_adapter *adapter) ...@@ -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) static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev;
struct pch_gbe_hw *hw = &adapter->hw; struct pch_gbe_hw *hw = &adapter->hw;
u32 rx_mode, tcpip; u32 rx_mode, tcpip;
...@@ -666,7 +667,7 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter) ...@@ -666,7 +667,7 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)
tcpip = ioread32(&hw->reg->TCPIP_ACC); 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_OFF;
tcpip |= PCH_GBE_RX_TCPIPACC_EN; tcpip |= PCH_GBE_RX_TCPIPACC_EN;
} else { } else {
...@@ -950,7 +951,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter, ...@@ -950,7 +951,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
frame_ctrl = 0; frame_ctrl = 0;
if (unlikely(skb->len < PCH_GBE_SHORT_PKT)) if (unlikely(skb->len < PCH_GBE_SHORT_PKT))
frame_ctrl |= PCH_GBE_TXD_CTRL_APAD; 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; frame_ctrl |= PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
/* Performs checksum processing */ /* Performs checksum processing */
...@@ -958,7 +959,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter, ...@@ -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, * It is because the hardware accelerator does not support a checksum,
* when the received data size is less than 64 bytes. * 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 | frame_ctrl |= PCH_GBE_TXD_CTRL_APAD |
PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF; PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
if (skb->protocol == htons(ETH_P_IP)) { if (skb->protocol == htons(ETH_P_IP)) {
...@@ -1426,7 +1427,7 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, ...@@ -1426,7 +1427,7 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
length = (rx_desc->rx_words_eob) - 3; length = (rx_desc->rx_words_eob) - 3;
/* Decide the data conversion method */ /* Decide the data conversion method */
if (!adapter->rx_csum) { if (!(netdev->features & NETIF_F_RXCSUM)) {
/* [Header:14][payload] */ /* [Header:14][payload] */
if (NET_IP_ALIGN) { if (NET_IP_ALIGN) {
/* Because alignment differs, /* Because alignment differs,
...@@ -2029,6 +2030,29 @@ static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -2029,6 +2030,29 @@ static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu)
return 0; return 0;
} }
/**
* 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 * pch_gbe_ioctl - Controls register through a MII interface
* @netdev: Network interface device structure * @netdev: Network interface device structure
...@@ -2129,6 +2153,7 @@ static const struct net_device_ops pch_gbe_netdev_ops = { ...@@ -2129,6 +2153,7 @@ static const struct net_device_ops pch_gbe_netdev_ops = {
.ndo_set_mac_address = pch_gbe_set_mac, .ndo_set_mac_address = pch_gbe_set_mac,
.ndo_tx_timeout = pch_gbe_tx_timeout, .ndo_tx_timeout = pch_gbe_tx_timeout,
.ndo_change_mtu = pch_gbe_change_mtu, .ndo_change_mtu = pch_gbe_change_mtu,
.ndo_set_features = pch_gbe_set_features,
.ndo_do_ioctl = pch_gbe_ioctl, .ndo_do_ioctl = pch_gbe_ioctl,
.ndo_set_multicast_list = &pch_gbe_set_multi, .ndo_set_multicast_list = &pch_gbe_set_multi,
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
...@@ -2334,7 +2359,9 @@ static int pch_gbe_probe(struct pci_dev *pdev, ...@@ -2334,7 +2359,9 @@ static int pch_gbe_probe(struct pci_dev *pdev,
netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD; netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD;
netif_napi_add(netdev, &adapter->napi, netif_napi_add(netdev, &adapter->napi,
pch_gbe_napi_poll, PCH_GBE_RX_WEIGHT); 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_set_ethtool_ops(netdev);
pch_gbe_mac_load_mac_addr(&adapter->hw); pch_gbe_mac_load_mac_addr(&adapter->hw);
...@@ -2373,11 +2400,6 @@ static int pch_gbe_probe(struct pci_dev *pdev, ...@@ -2373,11 +2400,6 @@ static int pch_gbe_probe(struct pci_dev *pdev,
pch_gbe_check_options(adapter); 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 */ /* initialize the wol settings based on the eeprom settings */
adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING; adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING;
dev_info(&pdev->dev, "MAC address : %pM\n", netdev->dev_addr); dev_info(&pdev->dev, "MAC address : %pM\n", netdev->dev_addr);
......
...@@ -426,6 +426,8 @@ static void pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter) ...@@ -426,6 +426,8 @@ static void pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter)
void pch_gbe_check_options(struct pch_gbe_adapter *adapter) void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
{ {
struct pch_gbe_hw *hw = &adapter->hw; struct pch_gbe_hw *hw = &adapter->hw;
struct net_device *dev = adapter->netdev;
int val;
{ /* Transmit Descriptor Count */ { /* Transmit Descriptor Count */
static const struct pch_gbe_option opt = { static const struct pch_gbe_option opt = {
...@@ -466,9 +468,10 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter) ...@@ -466,9 +468,10 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
.err = "defaulting to Enabled", .err = "defaulting to Enabled",
.def = PCH_GBE_DEFAULT_RX_CSUM .def = PCH_GBE_DEFAULT_RX_CSUM
}; };
adapter->rx_csum = XsumRX; val = XsumRX;
pch_gbe_validate_option((int *)(&adapter->rx_csum), pch_gbe_validate_option(&val, &opt, adapter);
&opt, adapter); if (!val)
dev->features &= ~NETIF_F_RXCSUM;
} }
{ /* Checksum Offload Enable/Disable */ { /* Checksum Offload Enable/Disable */
static const struct pch_gbe_option opt = { static const struct pch_gbe_option opt = {
...@@ -477,9 +480,10 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter) ...@@ -477,9 +480,10 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
.err = "defaulting to Enabled", .err = "defaulting to Enabled",
.def = PCH_GBE_DEFAULT_TX_CSUM .def = PCH_GBE_DEFAULT_TX_CSUM
}; };
adapter->tx_csum = XsumTX; val = XsumTX;
pch_gbe_validate_option((int *)(&adapter->tx_csum), pch_gbe_validate_option(&val, &opt, adapter);
&opt, adapter); if (!val)
dev->features &= ~NETIF_F_ALL_CSUM;
} }
{ /* Flow Control */ { /* Flow Control */
static const struct pch_gbe_option opt = { static const struct pch_gbe_option opt = {
......
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