Patchwork [2/2] igb: Expose RSS indirection table for ethtool

login
register
mail settings
Submitter laura.vasilescu@rosedu.org
Date July 17, 2013, 6:50 a.m.
Message ID <1374043806-17284-2-git-send-email-laura.vasilescu@rosedu.org>
Download mbox | patch
Permalink /patch/259609/
State Awaiting Upstream
Delegated to: David Miller
Headers show

Comments

laura.vasilescu@rosedu.org - July 17, 2013, 6:50 a.m.
Signed-off-by: Laura Mihaela Vasilescu <laura.vasilescu@rosedu.org>
---
 drivers/net/ethernet/intel/igb/igb_ethtool.c |   32 ++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
Jeff Kirsher - July 17, 2013, 7:12 a.m.
On Wed, 2013-07-17 at 09:50 +0300, Laura Mihaela Vasilescu wrote:
> Signed-off-by: Laura Mihaela Vasilescu <laura.vasilescu@rosedu.org>
> ---
>  drivers/net/ethernet/intel/igb/igb_ethtool.c |   32
> ++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+) 

Added this one as well to my queue, thanks!
Ben Hutchings - July 17, 2013, 4:52 p.m.
This is wrong, as there are 4 entries packed into each register.

On Wed, 2013-07-17 at 09:50 +0300, Laura Mihaela Vasilescu wrote:
> Signed-off-by: Laura Mihaela Vasilescu <laura.vasilescu@rosedu.org>
> ---
>  drivers/net/ethernet/intel/igb/igb_ethtool.c |   32 ++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
> index 85fe7b5..7e18dfa 100644
> --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
> +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
> @@ -2771,6 +2771,35 @@ static void igb_ethtool_complete(struct net_device *netdev)
>  	pm_runtime_put(&adapter->pdev->dev);
>  }
>  
> +static u32 igb_get_rss_table_size(struct net_device *netdev)
> +{
> +	return IGB_RETA_SIZE;

* 4

> +}
> +
> +static int igb_get_rss_table(struct net_device *netdev, u32 *rxfh_indir_tbl)
> +{
> +	struct igb_adapter *adapter = netdev_priv(netdev);
> +	struct e1000_hw *hw = &adapter->hw;
> +	int i;
> +
> +	for (i = 0; i < IGB_RETA_SIZE; i++)
> +		rxfh_indir_tbl[i] = rd32(E1000_RETA(i));

Unpack each register into entries i*4, i*4+1, i*4+2, i*4+3.

> +
> +	return 0;
> +}
> +
> +static int igb_set_rss_table(struct net_device *netdev, const u32 *rxfh_indir_tbl)
> +{
> +	struct igb_adapter *adapter = netdev_priv(netdev);
> +	struct e1000_hw *hw = &adapter->hw;
> +	int i;
> +
> +	for (i = 0; i < IGB_RETA_SIZE; i++)
> +		wr32(E1000_RETA(i), rxfh_indir_tbl[i]);

Pack entries i*4, i*4+1, i*4+2, i*4+3 into each register (as in
igb_setup_mrqc()).

> +
> +	return 0;
> +}

Ben.
Ben Hutchings - July 17, 2013, 5:03 p.m.
On Wed, 2013-07-17 at 17:52 +0100, Ben Hutchings wrote:
[...]
> > +static int igb_get_rss_table(struct net_device *netdev, u32 *rxfh_indir_tbl)
> > +{
> > +	struct igb_adapter *adapter = netdev_priv(netdev);
> > +	struct e1000_hw *hw = &adapter->hw;
> > +	int i;
> > +
> > +	for (i = 0; i < IGB_RETA_SIZE; i++)
> > +		rxfh_indir_tbl[i] = rd32(E1000_RETA(i));
> 
> Unpack each register into entries i*4, i*4+1, i*4+2, i*4+3.
> 
> > +
> > +	return 0;
> > +}
> > +
> > +static int igb_set_rss_table(struct net_device *netdev, const u32 *rxfh_indir_tbl)
> > +{
> > +	struct igb_adapter *adapter = netdev_priv(netdev);
> > +	struct e1000_hw *hw = &adapter->hw;
> > +	int i;
> > +
> > +	for (i = 0; i < IGB_RETA_SIZE; i++)
> > +		wr32(E1000_RETA(i), rxfh_indir_tbl[i]);
> 
> Pack entries i*4, i*4+1, i*4+2, i*4+3 into each register (as in
> igb_setup_mrqc()).
[...]

Also, the indirection table should be preserved in the driver across
hardware resets, although it may need to be reset if the number of RX
queues changes.

Commit 90415477bf13 'tg3: Make the RSS indir tbl admin configurable' is
a good example of how to do this properly.

Ben.

Patch

diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index 85fe7b5..7e18dfa 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -2771,6 +2771,35 @@  static void igb_ethtool_complete(struct net_device *netdev)
 	pm_runtime_put(&adapter->pdev->dev);
 }
 
+static u32 igb_get_rss_table_size(struct net_device *netdev)
+{
+	return IGB_RETA_SIZE;
+}
+
+static int igb_get_rss_table(struct net_device *netdev, u32 *rxfh_indir_tbl)
+{
+	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	int i;
+
+	for (i = 0; i < IGB_RETA_SIZE; i++)
+		rxfh_indir_tbl[i] = rd32(E1000_RETA(i));
+
+	return 0;
+}
+
+static int igb_set_rss_table(struct net_device *netdev, const u32 *rxfh_indir_tbl)
+{
+	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	int i;
+
+	for (i = 0; i < IGB_RETA_SIZE; i++)
+		wr32(E1000_RETA(i), rxfh_indir_tbl[i]);
+
+	return 0;
+}
+
 static const struct ethtool_ops igb_ethtool_ops = {
 	.get_settings		= igb_get_settings,
 	.set_settings		= igb_set_settings,
@@ -2804,6 +2833,9 @@  static const struct ethtool_ops igb_ethtool_ops = {
 	.set_eee		= igb_set_eee,
 	.get_module_info	= igb_get_module_info,
 	.get_module_eeprom	= igb_get_module_eeprom,
+	.get_rxfh_indir_size	= igb_get_rss_table_size,
+	.get_rxfh_indir		= igb_get_rss_table,
+	.set_rxfh_indir		= igb_set_rss_table,
 	.begin			= igb_ethtool_begin,
 	.complete		= igb_ethtool_complete,
 };