ixgbe: convert to ndo_fix_features

Private rx_csum flags are now duplicate of netdev->features &
NETIF_F_RXCSUM.  We remove those duplicates and now use the net_device_ops
ndo_set_features.  This was based on the original patch submitted by
Michal Miroslaw <mirq-linux@rere.qmqm.pl>.  I also removed the special
case not requiring a reset for X540 hardware.  It is needed just as it is
in 82599 hardware.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Cc:  Michal Miroslaw <mirq-linux@rere.qmqm.pl>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Don Skidmore 2011-07-21 05:55:00 +00:00 committed by Jeff Kirsher
parent 9417c464ba
commit 082757afcf
3 changed files with 111 additions and 217 deletions

View File

@ -587,13 +587,10 @@ extern s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
u16 soft_id); u16 soft_id);
extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
union ixgbe_atr_input *mask); union ixgbe_atr_input *mask);
extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring);
extern void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring);
extern void ixgbe_set_rx_mode(struct net_device *netdev); extern void ixgbe_set_rx_mode(struct net_device *netdev);
extern int ixgbe_setup_tc(struct net_device *dev, u8 tc); extern int ixgbe_setup_tc(struct net_device *dev, u8 tc);
extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32);
extern void ixgbe_do_reset(struct net_device *netdev);
#ifdef IXGBE_FCOE #ifdef IXGBE_FCOE
extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter);
extern int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, extern int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb,

View File

@ -442,109 +442,6 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
return 0; return 0;
} }
static void ixgbe_do_reset(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
if (netif_running(netdev))
ixgbe_reinit_locked(adapter);
else
ixgbe_reset(adapter);
}
static u32 ixgbe_get_rx_csum(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED;
}
static void ixgbe_set_rsc(struct ixgbe_adapter *adapter)
{
int i;
for (i = 0; i < adapter->num_rx_queues; i++) {
struct ixgbe_ring *ring = adapter->rx_ring[i];
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
set_ring_rsc_enabled(ring);
ixgbe_configure_rscctl(adapter, ring);
} else {
ixgbe_clear_rscctl(adapter, ring);
}
}
}
static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
bool need_reset = false;
if (data) {
adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
} else {
adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) {
adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
netdev->features &= ~NETIF_F_LRO;
}
switch (adapter->hw.mac.type) {
case ixgbe_mac_X540:
ixgbe_set_rsc(adapter);
break;
case ixgbe_mac_82599EB:
need_reset = true;
break;
default:
break;
}
}
if (need_reset)
ixgbe_do_reset(netdev);
return 0;
}
static u32 ixgbe_get_tx_csum(struct net_device *netdev)
{
return (netdev->features & NETIF_F_IP_CSUM) != 0;
}
static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
u32 feature_list;
feature_list = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
feature_list |= NETIF_F_SCTP_CSUM;
break;
default:
break;
}
if (data)
netdev->features |= feature_list;
else
netdev->features &= ~feature_list;
return 0;
}
static int ixgbe_set_tso(struct net_device *netdev, u32 data)
{
if (data) {
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
} else {
netdev->features &= ~NETIF_F_TSO;
netdev->features &= ~NETIF_F_TSO6;
}
return 0;
}
static u32 ixgbe_get_msglevel(struct net_device *netdev) static u32 ixgbe_get_msglevel(struct net_device *netdev)
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
@ -2289,81 +2186,6 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
return 0; return 0;
} }
static int ixgbe_set_flags(struct net_device *netdev, u32 data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
bool need_reset = false;
int rc;
#ifdef CONFIG_IXGBE_DCB
if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
!(data & ETH_FLAG_RXVLAN))
return -EINVAL;
#endif
need_reset = (data & ETH_FLAG_RXVLAN) !=
(netdev->features & NETIF_F_HW_VLAN_RX);
if ((data & ETH_FLAG_RXHASH) &&
!(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
return -EOPNOTSUPP;
rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE |
ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
ETH_FLAG_RXHASH);
if (rc)
return rc;
/* if state changes we need to update adapter->flags and reset */
if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) &&
(!!(data & ETH_FLAG_LRO) !=
!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) {
if ((data & ETH_FLAG_LRO) &&
(!adapter->rx_itr_setting ||
(adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE))) {
e_info(probe, "rx-usecs set too low, "
"not enabling RSC.\n");
} else {
adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED;
switch (adapter->hw.mac.type) {
case ixgbe_mac_X540:
ixgbe_set_rsc(adapter);
break;
case ixgbe_mac_82599EB:
need_reset = true;
break;
default:
break;
}
}
}
/*
* Check if Flow Director n-tuple support was enabled or disabled. If
* the state changed, we need to reset.
*/
if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) {
/* turn off ATR, enable perfect filters and reset */
if (data & ETH_FLAG_NTUPLE) {
adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
need_reset = true;
}
} else if (!(data & ETH_FLAG_NTUPLE)) {
/* turn off Flow Director, set ATR and reset */
adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
if ((adapter->flags & IXGBE_FLAG_RSS_ENABLED) &&
!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
need_reset = true;
}
if (need_reset)
ixgbe_do_reset(netdev);
return 0;
}
static int ixgbe_get_ethtool_fdir_entry(struct ixgbe_adapter *adapter, static int ixgbe_get_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
struct ethtool_rxnfc *cmd) struct ethtool_rxnfc *cmd)
{ {
@ -2746,16 +2568,8 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.set_ringparam = ixgbe_set_ringparam, .set_ringparam = ixgbe_set_ringparam,
.get_pauseparam = ixgbe_get_pauseparam, .get_pauseparam = ixgbe_get_pauseparam,
.set_pauseparam = ixgbe_set_pauseparam, .set_pauseparam = ixgbe_set_pauseparam,
.get_rx_csum = ixgbe_get_rx_csum,
.set_rx_csum = ixgbe_set_rx_csum,
.get_tx_csum = ixgbe_get_tx_csum,
.set_tx_csum = ixgbe_set_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_msglevel = ixgbe_get_msglevel, .get_msglevel = ixgbe_get_msglevel,
.set_msglevel = ixgbe_set_msglevel, .set_msglevel = ixgbe_set_msglevel,
.get_tso = ethtool_op_get_tso,
.set_tso = ixgbe_set_tso,
.self_test = ixgbe_diag_test, .self_test = ixgbe_diag_test,
.get_strings = ixgbe_get_strings, .get_strings = ixgbe_get_strings,
.set_phys_id = ixgbe_set_phys_id, .set_phys_id = ixgbe_set_phys_id,
@ -2763,8 +2577,6 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_ethtool_stats = ixgbe_get_ethtool_stats, .get_ethtool_stats = ixgbe_get_ethtool_stats,
.get_coalesce = ixgbe_get_coalesce, .get_coalesce = ixgbe_get_coalesce,
.set_coalesce = ixgbe_set_coalesce, .set_coalesce = ixgbe_set_coalesce,
.get_flags = ethtool_op_get_flags,
.set_flags = ixgbe_set_flags,
.get_rxnfc = ixgbe_get_rxnfc, .get_rxnfc = ixgbe_get_rxnfc,
.set_rxnfc = ixgbe_set_rxnfc, .set_rxnfc = ixgbe_set_rxnfc,
}; };

View File

@ -2861,29 +2861,12 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
} }
/**
* ixgbe_clear_rscctl - disable RSC for the indicated ring
* @adapter: address of board private structure
* @ring: structure containing ring specific data
**/
void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 rscctrl;
u8 reg_idx = ring->reg_idx;
rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx));
rscctrl &= ~IXGBE_RSCCTL_RSCEN;
IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl);
}
/** /**
* ixgbe_configure_rscctl - enable RSC for the indicated ring * ixgbe_configure_rscctl - enable RSC for the indicated ring
* @adapter: address of board private structure * @adapter: address of board private structure
* @index: index of ring to set * @index: index of ring to set
**/ **/
void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring) struct ixgbe_ring *ring)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
@ -7122,6 +7105,98 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
return 0; return 0;
} }
void ixgbe_do_reset(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
if (netif_running(netdev))
ixgbe_reinit_locked(adapter);
else
ixgbe_reset(adapter);
}
static u32 ixgbe_fix_features(struct net_device *netdev, u32 data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
#ifdef CONFIG_DCB
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
data &= ~NETIF_F_HW_VLAN_RX;
#endif
/* return error if RXHASH is being enabled when RSS is not supported */
if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
data &= ~NETIF_F_RXHASH;
/* If Rx checksum is disabled, then RSC/LRO should also be disabled */
if (!(data & NETIF_F_RXCSUM))
data &= ~NETIF_F_LRO;
/* Turn off LRO if not RSC capable or invalid ITR settings */
if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) {
data &= ~NETIF_F_LRO;
} else if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) &&
(adapter->rx_itr_setting != 1 &&
adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE)) {
data &= ~NETIF_F_LRO;
e_info(probe, "rx-usecs set too low, not enabling RSC\n");
}
return data;
}
static int ixgbe_set_features(struct net_device *netdev, u32 data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
bool need_reset = false;
/* If Rx checksum is disabled, then RSC/LRO should also be disabled */
if (!(data & NETIF_F_RXCSUM))
adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
else
adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
/* Make sure RSC matches LRO, reset if change */
if (!!(data & NETIF_F_LRO) !=
!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) {
adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED;
switch (adapter->hw.mac.type) {
case ixgbe_mac_X540:
case ixgbe_mac_82599EB:
need_reset = true;
break;
default:
break;
}
}
/*
* Check if Flow Director n-tuple support was enabled or disabled. If
* the state changed, we need to reset.
*/
if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) {
/* turn off ATR, enable perfect filters and reset */
if (data & NETIF_F_NTUPLE) {
adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
need_reset = true;
}
} else if (!(data & NETIF_F_NTUPLE)) {
/* turn off Flow Director, set ATR and reset */
adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
if ((adapter->flags & IXGBE_FLAG_RSS_ENABLED) &&
!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
need_reset = true;
}
if (need_reset)
ixgbe_do_reset(netdev);
return 0;
}
static const struct net_device_ops ixgbe_netdev_ops = { static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = ixgbe_open, .ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close, .ndo_stop = ixgbe_close,
@ -7153,6 +7228,8 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_fcoe_disable = ixgbe_fcoe_disable, .ndo_fcoe_disable = ixgbe_fcoe_disable,
.ndo_fcoe_get_wwn = ixgbe_fcoe_get_wwn, .ndo_fcoe_get_wwn = ixgbe_fcoe_get_wwn,
#endif /* IXGBE_FCOE */ #endif /* IXGBE_FCOE */
.ndo_set_features = ixgbe_set_features,
.ndo_fix_features = ixgbe_fix_features,
}; };
static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter, static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
@ -7420,20 +7497,24 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->features = NETIF_F_SG | netdev->features = NETIF_F_SG |
NETIF_F_IP_CSUM | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER; NETIF_F_HW_VLAN_FILTER |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_GRO |
NETIF_F_RXHASH |
NETIF_F_RXCSUM;
netdev->features |= NETIF_F_IPV6_CSUM; netdev->hw_features = netdev->features;
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
netdev->features |= NETIF_F_GRO;
netdev->features |= NETIF_F_RXHASH;
switch (adapter->hw.mac.type) { switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB: case ixgbe_mac_82599EB:
case ixgbe_mac_X540: case ixgbe_mac_X540:
netdev->features |= NETIF_F_SCTP_CSUM; netdev->features |= NETIF_F_SCTP_CSUM;
netdev->hw_features |= NETIF_F_SCTP_CSUM |
NETIF_F_NTUPLE;
break; break;
default: default:
break; break;
@ -7472,6 +7553,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->vlan_features |= NETIF_F_HIGHDMA; netdev->vlan_features |= NETIF_F_HIGHDMA;
} }
if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)
netdev->hw_features |= NETIF_F_LRO;
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
netdev->features |= NETIF_F_LRO; netdev->features |= NETIF_F_LRO;
@ -7508,8 +7591,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err) if (err)
goto err_sw_init; goto err_sw_init;
if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) {
netdev->hw_features &= ~NETIF_F_RXHASH;
netdev->features &= ~NETIF_F_RXHASH; netdev->features &= ~NETIF_F_RXHASH;
}
switch (pdev->device) { switch (pdev->device) {
case IXGBE_DEV_ID_82599_SFP: case IXGBE_DEV_ID_82599_SFP: