From: Jeff Kirsher <hidden> Date: 2012-11-13 14:03:28
This series contains updates to ixgbe, ixgbevf and igb.
The following are changes since commit 9fafd65ad407d4e0c96919a325f568dd95d032af:
ipv6 ndisc: Use pre-defined in6addr_linklocal_allnodes.
and are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next master
Akeem G. Abodunrin (2):
igb: Support for modifying UDP RSS flow hashing
igb: Ethtool support to enable and disable EEE
Alexander Duyck (4):
ixgbe: Do not use DCA to prefetch the entire packet into the cache
igb: Make TSO check for CHECKSUM_PARTIAL to avoid skb_is_gso check
igb: Update igb Tx flags to improve code efficiency
igb: Improve performance and reduce size of igb_tx_map
Carolyn Wyborny (1):
igb: Clear Go Link Disconnect for 82580 and later devices
Emil Tantilov (1):
ixgbevf: fix possible use of uninitialized variable
Greg Rose (2):
ixgbevf: Add flag to indicate when rx is in net poll
ixgbevf: Reduce size of maximum rx buffer
Jakub Kicinski (1):
ixgbevf: make sure probe fails on MSI-X enable error
drivers/net/ethernet/intel/igb/e1000_82575.c | 8 +
drivers/net/ethernet/intel/igb/e1000_defines.h | 1 +
drivers/net/ethernet/intel/igb/e1000_phy.h | 1 +
drivers/net/ethernet/intel/igb/igb.h | 31 ++-
drivers/net/ethernet/intel/igb/igb_ethtool.c | 281 ++++++++++++++++++++++
drivers/net/ethernet/intel/igb/igb_main.c | 124 +++++-----
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 1 -
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 9 +-
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 54 +++--
9 files changed, 412 insertions(+), 98 deletions(-)
--
1.7.11.7
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:03:28
From: Alexander Duyck <redacted>
The way the code was previously written it was causing DCA to prefetch the
entire packet into the cache when it was enabled. That is excessive as we
only really need the headers.
We are now prefetching the headers via software so doing this from DCA would
be redundant anyway. So clear the bit that was causing us to prefetch the
packet data and instead only use DCA for the descriptor rings.
Signed-off-by: Alexander Duyck <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 1 -
1 file changed, 1 deletion(-)
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:03:29
From: Jakub Kicinski <redacted>
This driver cannot work without MSI-X interrupts
so there is no mechanism to fall back to.
Signed-off-by: Jakub Kicinski <redacted>
Acked-by: Greg Rose <redacted>
Tested-by: Sibai Li <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 26 +++++++++++------------
1 file changed, 13 insertions(+), 13 deletions(-)
@@ -1740,21 +1740,18 @@ static void ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter,while(vectors>=vector_threshold){err=pci_enable_msix(adapter->pdev,adapter->msix_entries,vectors);-if(!err)/* Success in acquiring all requested vectors. */+if(!err||err<0)/* Success or a nasty failure. */break;-elseif(err<0)-vectors=0;/* Nasty failure, quit now */else/* err == number of vectors we should try again with */vectors=err;}-if(vectors<vector_threshold){-/* Can't allocate enough MSI-X interrupts? Oh well.-*Thisjustmeanswe'llgowitheitherasingleMSI-*vectororfallbacktolegacyinterrupts.-*/-hw_dbg(&adapter->hw,-"Unable to allocate MSI-X interrupts\n");+if(vectors<vector_threshold)+err=-ENOMEM;++if(err){+dev_err(&adapter->pdev->dev,+"Unable to allocate MSI-X interrupts\n");kfree(adapter->msix_entries);adapter->msix_entries=NULL;}else{
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:03:29
From: Emil Tantilov <redacted>
This patch resolves the following warning:
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c: In function ‘ixgbevf_probe’:
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c:1742:290: warning: ‘err’ may be used uninitialized in this function [-Wuninitialized]
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c:1717:6: note: ‘err’ was declared here
Signed-off-by: Emil Tantilov <redacted>
Tested-by: Sibai Li <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:03:30
From: Greg Rose <redacted>
napi_gro_receive shouldn't be called from netpoll context. Doing
so was causing kernel panics when jumbo frames larger than 2K were set.
Add a flag to check if the Rx ring processing is occurring from interrupt
context or from netpoll context and call netif_rx() if in the polling
context.
Signed-off-by: Greg Rose <redacted>
Tested-by: Sibai Li <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 1 +
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
@@ -550,9 +553,11 @@ static int ixgbevf_poll(struct napi_struct *napi, int budget)elseper_ring_budget=budget;+adapter->flags|=IXGBE_FLAG_IN_NETPOLL;ixgbevf_for_each_ring(ring,q_vector->rx)clean_complete&=ixgbevf_clean_rx_irq(q_vector,ring,per_ring_budget);+adapter->flags&=~IXGBE_FLAG_IN_NETPOLL;/* If all work not completed, return budget and keep polling */if(!clean_complete)
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:03:31
From: Carolyn Wyborny <redacted>
Customers are requesting that the hw prevents PHY from establishing link
until the driver loads. This patch clears the Go Link Disconnect bit which
provides the requested behavior on parts 82580 and later.
Signed-off-by: Carolyn Wyborny <redacted>
Tested-by: Aaron Brown <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/igb/e1000_82575.c | 8 ++++++++
drivers/net/ethernet/intel/igb/e1000_phy.h | 1 +
2 files changed, 9 insertions(+)
@@ -1278,12 +1278,20 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw){u32ctrl;s32ret_val;+u32phpm_reg;ctrl=rd32(E1000_CTRL);ctrl|=E1000_CTRL_SLU;ctrl&=~(E1000_CTRL_FRCSPD|E1000_CTRL_FRCDPX);wr32(E1000_CTRL,ctrl);+/* Clear Go Link Disconnect bit */+if(hw->mac.type>=e1000_82580){+phpm_reg=rd32(E1000_82580_PHY_POWER_MGMT);+phpm_reg&=~E1000_82580_PM_GO_LINKD;+wr32(E1000_82580_PHY_POWER_MGMT,phpm_reg);+}+ret_val=igb_setup_serdes_link_82575(hw);if(ret_val)gotoout;
@@ -124,6 +124,7 @@ s32 igb_check_polarity_m88(struct e1000_hw *hw);#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */+#define E1000_82580_PM_GO_LINKD 0x0020 /* Go Link Disconnect *//* Enable flexible speed on link-up */#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:03:31
From: Greg Rose <redacted>
There's no need to support up to 15k buffers since the HW is limited to
9.5k in SR-IOV mode. Instead, allocate buffers that fit and align inside
of a 32K memory buffer.
Signed-off-by: Greg Rose <redacted>
Tested-by: Sibai Li <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 8 ++++----
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 18 +++++++++---------
2 files changed, 13 insertions(+), 13 deletions(-)
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:03:32
From: "Akeem G. Abodunrin" <redacted>
This patch provides ability to enable or disable UDP RSS hashing. It gives
users option of generating RSS hash based on the UDP source and destination
ports numbers. Currently, UDP flow hash is always disabled in igb-driver.
Signed-off-by: Akeem G Abodunrin <redacted>
Tested-by: Aaron Brown <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/igb/igb.h | 14 ++-
drivers/net/ethernet/intel/igb/igb_ethtool.c | 181 +++++++++++++++++++++++++++
drivers/net/ethernet/intel/igb/igb_main.c | 13 +-
3 files changed, 197 insertions(+), 11 deletions(-)
@@ -2350,6 +2350,185 @@ static int igb_get_ts_info(struct net_device *dev,}}+staticintigb_get_rss_hash_opts(structigb_adapter*adapter,+structethtool_rxnfc*cmd)+{+cmd->data=0;++/* Report default options for RSS on igb */+switch(cmd->flow_type){+caseTCP_V4_FLOW:+cmd->data|=RXH_L4_B_0_1|RXH_L4_B_2_3;+caseUDP_V4_FLOW:+if(adapter->flags&IGB_FLAG_RSS_FIELD_IPV4_UDP)+cmd->data|=RXH_L4_B_0_1|RXH_L4_B_2_3;+caseSCTP_V4_FLOW:+caseAH_ESP_V4_FLOW:+caseAH_V4_FLOW:+caseESP_V4_FLOW:+caseIPV4_FLOW:+cmd->data|=RXH_IP_SRC|RXH_IP_DST;+break;+caseTCP_V6_FLOW:+cmd->data|=RXH_L4_B_0_1|RXH_L4_B_2_3;+caseUDP_V6_FLOW:+if(adapter->flags&IGB_FLAG_RSS_FIELD_IPV6_UDP)+cmd->data|=RXH_L4_B_0_1|RXH_L4_B_2_3;+caseSCTP_V6_FLOW:+caseAH_ESP_V6_FLOW:+caseAH_V6_FLOW:+caseESP_V6_FLOW:+caseIPV6_FLOW:+cmd->data|=RXH_IP_SRC|RXH_IP_DST;+break;+default:+return-EINVAL;+}++return0;+}++staticintigb_get_rxnfc(structnet_device*dev,structethtool_rxnfc*cmd,+u32*rule_locs)+{+structigb_adapter*adapter=netdev_priv(dev);+intret=-EOPNOTSUPP;++switch(cmd->cmd){+caseETHTOOL_GRXRINGS:+cmd->data=adapter->num_rx_queues;+ret=0;+break;+caseETHTOOL_GRXFH:+ret=igb_get_rss_hash_opts(adapter,cmd);+break;+default:+break;+}++returnret;+}++#define UDP_RSS_FLAGS (IGB_FLAG_RSS_FIELD_IPV4_UDP | \+IGB_FLAG_RSS_FIELD_IPV6_UDP)+staticintigb_set_rss_hash_opt(structigb_adapter*adapter,+structethtool_rxnfc*nfc)+{+u32flags=adapter->flags;++/* RSS does not support anything other than hashing+*toqueuesonsrcanddstIPsandports+*/+if(nfc->data&~(RXH_IP_SRC|RXH_IP_DST|+RXH_L4_B_0_1|RXH_L4_B_2_3))+return-EINVAL;++switch(nfc->flow_type){+caseTCP_V4_FLOW:+caseTCP_V6_FLOW:+if(!(nfc->data&RXH_IP_SRC)||+!(nfc->data&RXH_IP_DST)||+!(nfc->data&RXH_L4_B_0_1)||+!(nfc->data&RXH_L4_B_2_3))+return-EINVAL;+break;+caseUDP_V4_FLOW:+if(!(nfc->data&RXH_IP_SRC)||+!(nfc->data&RXH_IP_DST))+return-EINVAL;+switch(nfc->data&(RXH_L4_B_0_1|RXH_L4_B_2_3)){+case0:+flags&=~IGB_FLAG_RSS_FIELD_IPV4_UDP;+break;+case(RXH_L4_B_0_1|RXH_L4_B_2_3):+flags|=IGB_FLAG_RSS_FIELD_IPV4_UDP;+break;+default:+return-EINVAL;+}+break;+caseUDP_V6_FLOW:+if(!(nfc->data&RXH_IP_SRC)||+!(nfc->data&RXH_IP_DST))+return-EINVAL;+switch(nfc->data&(RXH_L4_B_0_1|RXH_L4_B_2_3)){+case0:+flags&=~IGB_FLAG_RSS_FIELD_IPV6_UDP;+break;+case(RXH_L4_B_0_1|RXH_L4_B_2_3):+flags|=IGB_FLAG_RSS_FIELD_IPV6_UDP;+break;+default:+return-EINVAL;+}+break;+caseAH_ESP_V4_FLOW:+caseAH_V4_FLOW:+caseESP_V4_FLOW:+caseSCTP_V4_FLOW:+caseAH_ESP_V6_FLOW:+caseAH_V6_FLOW:+caseESP_V6_FLOW:+caseSCTP_V6_FLOW:+if(!(nfc->data&RXH_IP_SRC)||+!(nfc->data&RXH_IP_DST)||+(nfc->data&RXH_L4_B_0_1)||+(nfc->data&RXH_L4_B_2_3))+return-EINVAL;+break;+default:+return-EINVAL;+}++/* if we changed something we need to update flags */+if(flags!=adapter->flags){+structe1000_hw*hw=&adapter->hw;+u32mrqc=rd32(E1000_MRQC);++if((flags&UDP_RSS_FLAGS)&&+!(adapter->flags&UDP_RSS_FLAGS))+dev_err(&adapter->pdev->dev,+"enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n");++adapter->flags=flags;++/* Perform hash on these packet types */+mrqc|=E1000_MRQC_RSS_FIELD_IPV4|+E1000_MRQC_RSS_FIELD_IPV4_TCP|+E1000_MRQC_RSS_FIELD_IPV6|+E1000_MRQC_RSS_FIELD_IPV6_TCP;++mrqc&=~(E1000_MRQC_RSS_FIELD_IPV4_UDP|+E1000_MRQC_RSS_FIELD_IPV6_UDP);++if(flags&IGB_FLAG_RSS_FIELD_IPV4_UDP)+mrqc|=E1000_MRQC_RSS_FIELD_IPV4_UDP;++if(flags&IGB_FLAG_RSS_FIELD_IPV6_UDP)+mrqc|=E1000_MRQC_RSS_FIELD_IPV6_UDP;++wr32(E1000_MRQC,mrqc);+}++return0;+}++staticintigb_set_rxnfc(structnet_device*dev,structethtool_rxnfc*cmd)+{+structigb_adapter*adapter=netdev_priv(dev);+intret=-EOPNOTSUPP;++switch(cmd->cmd){+caseETHTOOL_SRXFH:+ret=igb_set_rss_hash_opt(adapter,cmd);+break;+default:+break;+}++returnret;+}+staticintigb_ethtool_begin(structnet_device*netdev){structigb_adapter*adapter=netdev_priv(netdev);
@@ -2874,18 +2874,21 @@ static void igb_setup_mrqc(struct igb_adapter *adapter)/* Don't need to set TUOFL or IPOFL, they default to 1 */wr32(E1000_RXCSUM,rxcsum);-/*-*GenerateRSShashbasedonTCPportnumbersand/or-*IPv4/v6srcanddstaddressessinceUDPcannotbe-*hashedreliablyduetoIPfragmentation-*/+/* Generate RSS hash based on packet types, TCP/UDP+*portnumbersand/orIPv4/v6srcanddstaddresses+*/mrqc=E1000_MRQC_RSS_FIELD_IPV4|E1000_MRQC_RSS_FIELD_IPV4_TCP|E1000_MRQC_RSS_FIELD_IPV6|E1000_MRQC_RSS_FIELD_IPV6_TCP|E1000_MRQC_RSS_FIELD_IPV6_TCP_EX;+if(adapter->flags&IGB_FLAG_RSS_FIELD_IPV4_UDP)+mrqc|=E1000_MRQC_RSS_FIELD_IPV4_UDP;+if(adapter->flags&IGB_FLAG_RSS_FIELD_IPV6_UDP)+mrqc|=E1000_MRQC_RSS_FIELD_IPV6_UDP;+/* If VMDq is enabled then we set the appropriate mode for that, else*wedefaulttoRSSsothatanRSShashiscalculatedperpacketeven*ifweareonlyusingonequeue*/
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:03:32
From: Alexander Duyck <redacted>
This change is meant to reduce the overhead for workloads that are not
using either TSO or checksum offloads. Most of the time the compiler
should jump ahead after failing this check to the VLAN check since in the
igb_tx_csum call we start with that check as well.
Signed-off-by: Alexander Duyck <redacted>
Tested-by: Aaron Brown <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/igb/igb_main.c | 3 +++
1 file changed, 3 insertions(+)
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:04:02
From: Alexander Duyck <redacted>
This change is meant to improve the efficiency of the Tx flags in igb by
aligning them with the values that will later be written into either the
cmd_type or olinfo. By doing this we are able to reduce most of these
functions to either just a simple shift followed by an or in the case of
cmd_type, or an and followed by an or in the case of olinfo.
In order to avoid type conversion errors I also adjusted the locations
where we were switching between CPU and little endian.
Signed-off-by: Alexander Duyck <redacted>
Tested-by: Aaron Brown <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/igb/igb.h | 17 ++++++---
drivers/net/ethernet/intel/igb/igb_main.c | 61 +++++++++++++++++--------------
2 files changed, 45 insertions(+), 33 deletions(-)
@@ -4121,24 +4121,32 @@ static void igb_tx_csum(struct igb_ring *tx_ring, struct igb_tx_buffer *first)igb_tx_ctxtdesc(tx_ring,vlan_macip_lens,type_tucmd,mss_l4len_idx);}-static__le32igb_tx_cmd_type(u32tx_flags)+#define IGB_SET_FLAG(_input, _flag, _result) \+((_flag<=_result)?\+((u32)(_input&_flag)*(_result/_flag)):\+((u32)(_input&_flag)/(_flag/_result)))++staticu32igb_tx_cmd_type(structsk_buff*skb,u32tx_flags){/* set type for advanced descriptor with frame checksum insertion */-__le32cmd_type=cpu_to_le32(E1000_ADVTXD_DTYP_DATA|-E1000_ADVTXD_DCMD_IFCS|-E1000_ADVTXD_DCMD_DEXT);+u32cmd_type=E1000_ADVTXD_DTYP_DATA|+E1000_ADVTXD_DCMD_DEXT|+E1000_ADVTXD_DCMD_IFCS;/* set HW vlan bit if vlan is present */-if(tx_flags&IGB_TX_FLAGS_VLAN)-cmd_type|=cpu_to_le32(E1000_ADVTXD_DCMD_VLE);+cmd_type|=IGB_SET_FLAG(tx_flags,IGB_TX_FLAGS_VLAN,+(E1000_ADVTXD_DCMD_VLE));++/* set segmentation bits for TSO */+cmd_type|=IGB_SET_FLAG(tx_flags,IGB_TX_FLAGS_TSO,+(E1000_ADVTXD_DCMD_TSE));/* set timestamp bit if present */-if(unlikely(tx_flags&IGB_TX_FLAGS_TSTAMP))-cmd_type|=cpu_to_le32(E1000_ADVTXD_MAC_TSTAMP);+cmd_type|=IGB_SET_FLAG(tx_flags,IGB_TX_FLAGS_TSTAMP,+(E1000_ADVTXD_MAC_TSTAMP));-/* set segmentation bits for TSO */-if(tx_flags&IGB_TX_FLAGS_TSO)-cmd_type|=cpu_to_le32(E1000_ADVTXD_DCMD_TSE);+/* insert frame checksum */+cmd_type^=IGB_SET_FLAG(skb->no_fcs,1,E1000_ADVTXD_DCMD_IFCS);returncmd_type;}
@@ -4149,19 +4157,19 @@ static void igb_tx_olinfo_status(struct igb_ring *tx_ring,{u32olinfo_status=paylen<<E1000_ADVTXD_PAYLEN_SHIFT;-/* 82575 requires a unique index per ring if any offload is enabled */-if((tx_flags&(IGB_TX_FLAGS_CSUM|IGB_TX_FLAGS_VLAN))&&-test_bit(IGB_RING_FLAG_TX_CTX_IDX,&tx_ring->flags))+/* 82575 requires a unique index per ring */+if(test_bit(IGB_RING_FLAG_TX_CTX_IDX,&tx_ring->flags))olinfo_status|=tx_ring->reg_idx<<4;/* insert L4 checksum */-if(tx_flags&IGB_TX_FLAGS_CSUM){-olinfo_status|=E1000_TXD_POPTS_TXSM<<8;+olinfo_status|=IGB_SET_FLAG(tx_flags,+IGB_TX_FLAGS_CSUM,+(E1000_TXD_POPTS_TXSM<<8));-/* insert IPv4 checksum */-if(tx_flags&IGB_TX_FLAGS_IPV4)-olinfo_status|=E1000_TXD_POPTS_IXSM<<8;-}+/* insert IPv4 checksum */+olinfo_status|=IGB_SET_FLAG(tx_flags,+IGB_TX_FLAGS_IPV4,+(E1000_TXD_POPTS_IXSM<<8));tx_desc->read.olinfo_status=cpu_to_le32(olinfo_status);}
@@ -4255,10 +4262,8 @@ static void igb_tx_map(struct igb_ring *tx_ring,netdev_tx_sent_queue(txring_txq(tx_ring),first->bytecount);/* write last descriptor with RS and EOP bits */-cmd_type|=cpu_to_le32(size)|cpu_to_le32(IGB_TXD_DCMD);-if(unlikely(skb->no_fcs))-cmd_type&=~(cpu_to_le32(E1000_ADVTXD_DCMD_IFCS));-tx_desc->read.cmd_type_len=cmd_type;+cmd_type|=size|IGB_TXD_DCMD;+tx_desc->read.cmd_type_len=cpu_to_le32(cmd_type);/* set the timestamp */first->time_stamp=jiffies;
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:04:03
From: "Akeem G. Abodunrin" <redacted>
This patch allows users to enable and disable EEE using Ethtool.
It also allows users to get EEE settings, as supported by the device.
Signed-off-by: Akeem G Abodunrin <redacted>
Tested-by: Aaron Brown <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/igb/e1000_defines.h | 1 +
drivers/net/ethernet/intel/igb/igb_ethtool.c | 100 +++++++++++++++++++++++++
2 files changed, 101 insertions(+)
@@ -2529,6 +2529,104 @@ static int igb_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)returnret;}+staticintigb_get_eee(structnet_device*netdev,structethtool_eee*edata)+{+structigb_adapter*adapter=netdev_priv(netdev);+structe1000_hw*hw=&adapter->hw;+u32ipcnfg,eeer;++if((hw->mac.type<e1000_i350)||+(hw->phy.media_type!=e1000_media_type_copper))+return-EOPNOTSUPP;++edata->supported=(SUPPORTED_1000baseT_Full|+SUPPORTED_100baseT_Full);++ipcnfg=rd32(E1000_IPCNFG);+eeer=rd32(E1000_EEER);++/* EEE status on negotiated link */+if(ipcnfg&E1000_IPCNFG_EEE_1G_AN)+edata->advertised=ADVERTISED_1000baseT_Full;++if(ipcnfg&E1000_IPCNFG_EEE_100M_AN)+edata->advertised|=ADVERTISED_100baseT_Full;++if(eeer&E1000_EEER_EEE_NEG)+edata->eee_active=true;++edata->eee_enabled=!hw->dev_spec._82575.eee_disable;++if(eeer&E1000_EEER_TX_LPI_EN)+edata->tx_lpi_enabled=true;++/* Report correct negotiated EEE status for devices that+*wronglyreportEEEathalf-duplex+*/+if(adapter->link_duplex==HALF_DUPLEX){+edata->eee_enabled=false;+edata->eee_active=false;+edata->tx_lpi_enabled=false;+edata->advertised&=~edata->advertised;+}++return0;+}++staticintigb_set_eee(structnet_device*netdev,+structethtool_eee*edata)+{+structigb_adapter*adapter=netdev_priv(netdev);+structe1000_hw*hw=&adapter->hw;+structethtool_eeeeee_curr;+s32ret_val;++if((hw->mac.type<e1000_i350)||+(hw->phy.media_type!=e1000_media_type_copper))+return-EOPNOTSUPP;++ret_val=igb_get_eee(netdev,&eee_curr);+if(ret_val)+returnret_val;++if(eee_curr.eee_enabled){+if(eee_curr.tx_lpi_enabled!=edata->tx_lpi_enabled){+dev_err(&adapter->pdev->dev,+"Setting EEE tx-lpi is not supported\n");+return-EINVAL;+}++/* Tx LPI timer is not implemented currently */+if(edata->tx_lpi_timer){+dev_err(&adapter->pdev->dev,+"Setting EEE Tx LPI timer is not supported\n");+return-EINVAL;+}++if(eee_curr.advertised!=edata->advertised){+dev_err(&adapter->pdev->dev,+"Setting EEE Advertisement is not supported\n");+return-EINVAL;+}++}elseif(!edata->eee_enabled){+dev_err(&adapter->pdev->dev,+"Setting EEE options are not supported with EEE disabled\n");+return-EINVAL;+}++if(hw->dev_spec._82575.eee_disable!=!edata->eee_enabled){+hw->dev_spec._82575.eee_disable=!edata->eee_enabled;+igb_set_eee_i350(hw);++/* reset link */+if(!netif_running(netdev))+igb_reset(adapter);+}++return0;+}+staticintigb_ethtool_begin(structnet_device*netdev){structigb_adapter*adapter=netdev_priv(netdev);
From: Jeff Kirsher <hidden> Date: 2012-11-13 14:04:03
From: Alexander Duyck <redacted>
This change is meant to both improve the performance and reduce the size of
igb_tx_map. To do this I have expanded the work done in the main loop by
pushing first into tx_buffer. This allows us to pull in the dma_mapping_error
check, the tx_buffer value assignment, and the initial DMA value assignment to
the Tx descriptor. The net result is that the function reduces in size by a
little over a 100 bytes and is about 1% or 2% faster.
Signed-off-by: Alexander Duyck <redacted>
Tested-by: Aaron Brown <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/igb/igb_main.c | 47 +++++++++++++++----------------
1 file changed, 22 insertions(+), 25 deletions(-)
@@ -4240,31 +4245,23 @@ static void igb_tx_map(struct igb_ring *tx_ring,tx_desc=IGB_TX_DESC(tx_ring,0);i=0;}+tx_desc->read.olinfo_status=0;size=skb_frag_size(frag);data_len-=size;dma=skb_frag_dma_map(tx_ring->dev,frag,0,-size,DMA_TO_DEVICE);-if(dma_mapping_error(tx_ring->dev,dma))-gotodma_error;+size,DMA_TO_DEVICE);tx_buffer=&tx_ring->tx_buffer_info[i];-dma_unmap_len_set(tx_buffer,len,size);-dma_unmap_addr_set(tx_buffer,dma,dma);--tx_desc->read.olinfo_status=0;-tx_desc->read.buffer_addr=cpu_to_le64(dma);--frag++;}-netdev_tx_sent_queue(txring_txq(tx_ring),first->bytecount);-/* write last descriptor with RS and EOP bits */cmd_type|=size|IGB_TXD_DCMD;tx_desc->read.cmd_type_len=cpu_to_le32(cmd_type);+netdev_tx_sent_queue(txring_txq(tx_ring),first->bytecount);+/* set the timestamp */first->time_stamp=jiffies;
From: Eric Dumazet <hidden> Date: 2012-11-13 14:13:34
On Tue, 2012-11-13 at 06:03 -0800, Jeff Kirsher wrote:
From: Alexander Duyck <redacted>
The way the code was previously written it was causing DCA to prefetch the
entire packet into the cache when it was enabled. That is excessive as we
only really need the headers.
We are now prefetching the headers via software so doing this from DCA would
be redundant anyway. So clear the bit that was causing us to prefetch the
packet data and instead only use DCA for the descriptor rings.
Signed-off-by: Alexander Duyck <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
Excellent !
My own ixgbe cards are moving so I cant test this, do you guys have some
numbers to share ?
Thanks
From: Alexander Duyck <hidden> Date: 2012-11-13 17:41:39
On 11/13/2012 06:13 AM, Eric Dumazet wrote:
On Tue, 2012-11-13 at 06:03 -0800, Jeff Kirsher wrote:
quoted
From: Alexander Duyck <redacted>
The way the code was previously written it was causing DCA to prefetch the
entire packet into the cache when it was enabled. That is excessive as we
only really need the headers.
We are now prefetching the headers via software so doing this from DCA would
be redundant anyway. So clear the bit that was causing us to prefetch the
packet data and instead only use DCA for the descriptor rings.
Signed-off-by: Alexander Duyck <redacted>
Tested-by: Phil Schmitt <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
Excellent !
My own ixgbe cards are moving so I cant test this, do you guys have some
numbers to share ?
Thanks
In my tests I saw no real change because of the DCA changes. I kind of
suspected that would be the case as mentioned in the patch the prefetch
and DCA were both doing the same thing so by dropping the extra DCA
prefetch I am just polluting the case less.
I have a similar set of changes for the ixgbe transmit path that are
similar to the changes I made to igb in this patch set. Those are a bit
more interesting as they actually decreased the ixgbe_xmit_frame_ring
function overhead for some of my tests by something like 15%.
Thanks,
Alex
From: David Miller <davem@davemloft.net> Date: 2012-11-13 19:19:12
From: Jeff Kirsher <redacted>
Date: Tue, 13 Nov 2012 06:03:14 -0800
This series contains updates to ixgbe, ixgbevf and igb.
The following are changes since commit 9fafd65ad407d4e0c96919a325f568dd95d032af:
ipv6 ndisc: Use pre-defined in6addr_linklocal_allnodes.
and are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next master
Pulled, but I have some long term feedback to give on one of the
patches, thanks.
From: David Miller <davem@davemloft.net> Date: 2012-11-13 19:20:07
From: Jeff Kirsher <redacted>
Date: Tue, 13 Nov 2012 06:03:18 -0800
From: Greg Rose <redacted>
napi_gro_receive shouldn't be called from netpoll context. Doing
so was causing kernel panics when jumbo frames larger than 2K were set.
Add a flag to check if the Rx ring processing is occurring from interrupt
context or from netpoll context and call netif_rx() if in the polling
context.
Signed-off-by: Greg Rose <redacted>
Tested-by: Sibai Li <redacted>
Signed-off-by: Jeff Kirsher <redacted>
This is not a scalable solution.
It is not prudent to have every single driver do a check like
this. If using GRO receive from netpoll causes problems,
then it's a generic issue rather than a driver specific one.
From: Greg Rose <hidden> Date: 2012-11-13 19:25:19
On Tue, 13 Nov 2012 14:20:05 -0500
David Miller [off-list ref] wrote:
From: Jeff Kirsher <redacted>
Date: Tue, 13 Nov 2012 06:03:18 -0800
quoted
From: Greg Rose <redacted>
napi_gro_receive shouldn't be called from netpoll context. Doing
so was causing kernel panics when jumbo frames larger than 2K were
set. Add a flag to check if the Rx ring processing is occurring
from interrupt context or from netpoll context and call netif_rx()
if in the polling context.
Signed-off-by: Greg Rose <redacted>
Tested-by: Sibai Li <redacted>
Signed-off-by: Jeff Kirsher <redacted>
This is not a scalable solution.
It is not prudent to have every single driver do a check like
this. If using GRO receive from netpoll causes problems,
then it's a generic issue rather than a driver specific one.
OK, let me look into this a bit more then.
Thanks,
- Greg