From: Eric Dumazet <eduma...@google.com>

Implement ethtool -x full support, so that rss key can be fetched
instead of assuming it matches /proc/sys/net/core/netdev_rss_key
content.

We might add "ethtool --rxfh" support later to set a different rss key.

Tested:

lpk51:~# ethtool --show-rxfh eth0 | grep -A1 'hash key'
RSS hash key:
f0:7e:81:59:c7:c9:5b:26:f7:14:7e:9e:29:01:50:99:b6:e9:8d:e1:3a:13:0c:54:71:cf:9d:72:f5:d6:c7:e0:fd:26:e2:7c:52:db:ea:e8
lpk51:~# cat /proc/sys/net/core/netdev_rss_key
f0:7e:81:59:c7:c9:5b:26:f7:14:7e:9e:29:01:50:99:b6:e9:8d:e1:3a:13:0c:54:71:cf:9d:72:f5:d6:c7:e0:fd:26:e2:7c:52:db:ea:e8:f0:89:dc:69:2f:fa:c7:71:30:a0:0c:7a

Signed-off-by: Eric Dumazet <eduma...@google.com>
Cc: Ariel Elior <ariel.el...@qlogic.com>
Cc: Yuval Mintz <yuval.mi...@cavium.com>
---
net-next is closed, merge can wait !
v3: Addressed Yuval feedback given on v2 (I hope I understood well)
v2: support CONFIG_BNX2X_SRIOV=y

 drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c |   45 ++++++----
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c      |    9 +-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h      |    4 
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c    |    2 
 4 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 
5f19427c7b278b99ee34a20b4d854e1d1293..5f31d0d52d3cdf02ded6670e032d335ac32c 
100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -3429,6 +3429,13 @@ static u32 bnx2x_get_rxfh_indir_size(struct net_device 
*dev)
        return T_ETH_INDIRECTION_TABLE_SIZE;
 }
 
+static u32 bnx2x_get_rxfh_key_size(struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       return (bp->port.pmf || !CHIP_IS_E1x(bp)) ? T_ETH_RSS_KEY * 4 : 0;
+}
+
 static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
                          u8 *hfunc)
 {
@@ -3438,23 +3445,28 @@ static int bnx2x_get_rxfh(struct net_device *dev, u32 
*indir, u8 *key,
 
        if (hfunc)
                *hfunc = ETH_RSS_HASH_TOP;
-       if (!indir)
-               return 0;
 
-       /* Get the current configuration of the RSS indirection table */
-       bnx2x_get_rss_ind_table(&bp->rss_conf_obj, ind_table);
-
-       /*
-        * We can't use a memcpy() as an internal storage of an
-        * indirection table is a u8 array while indir->ring_index
-        * points to an array of u32.
-        *
-        * Indirection table contains the FW Client IDs, so we need to
-        * align the returned table to the Client ID of the leading RSS
-        * queue.
-        */
-       for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++)
-               indir[i] = ind_table[i] - bp->fp->cl_id;
+       if (key) {
+               WARN_ON_ONCE(bnx2x_get_rxfh_key_size(dev) != T_ETH_RSS_KEY * 4);
+               bnx2x_get_rss_key(&bp->rss_conf_obj, key);
+       }
+
+       if (indir) {
+               /* Get the current configuration of the RSS indirection table */
+               bnx2x_get_rss_ind_table(&bp->rss_conf_obj, ind_table);
+
+               /*
+                * We can't use a memcpy() as an internal storage of an
+                * indirection table is a u8 array while indir->ring_index
+                * points to an array of u32.
+                *
+                * Indirection table contains the FW Client IDs, so we need to
+                * align the returned table to the Client ID of the leading RSS
+                * queue.
+                */
+               for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++)
+                       indir[i] = ind_table[i] - bp->fp->cl_id;
+       }
 
        return 0;
 }
@@ -3636,6 +3648,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
        .get_ethtool_stats      = bnx2x_get_ethtool_stats,
        .get_rxnfc              = bnx2x_get_rxnfc,
        .set_rxnfc              = bnx2x_set_rxnfc,
+       .get_rxfh_key_size      = bnx2x_get_rxfh_key_size,
        .get_rxfh_indir_size    = bnx2x_get_rxfh_indir_size,
        .get_rxfh               = bnx2x_get_rxfh,
        .set_rxfh               = bnx2x_set_rxfh,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index 
cea6bdcde33f0be220815378142ea9e8dfc7..08ba33ccef87ba1f0d29ae4bdd48261fb901 
100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -4538,9 +4538,11 @@ static int bnx2x_setup_rss(struct bnx2x *bp,
        /* RSS keys */
        if (test_bit(BNX2X_RSS_SET_SRCH, &p->rss_flags)) {
                u8 *dst = (u8 *)(data->rss_key) + sizeof(data->rss_key);
-               const u8 *src = (const u8 *)p->rss_key;
+               const u8 *src = (const u8 *)o->rss_key;
                int i;
 
+               /* Remember the last configuration */
+               memcpy(o->rss_key, p->rss_key, T_ETH_RSS_KEY * 4);
                /* Apparently, bnx2x reads this array in reverse order
                 * We need to byte swap rss_key to comply with Toeplitz specs.
                 */
@@ -4596,6 +4598,11 @@ void bnx2x_get_rss_ind_table(struct bnx2x_rss_config_obj 
*rss_obj,
        memcpy(ind_table, rss_obj->ind_table, sizeof(rss_obj->ind_table));
 }
 
+void bnx2x_get_rss_key(const struct bnx2x_rss_config_obj *rss_obj, u8 *key)
+{
+       memcpy(key, rss_obj->rss_key, T_ETH_RSS_KEY * 4);
+}
+
 int bnx2x_config_rss(struct bnx2x *bp,
                     struct bnx2x_config_rss_params *p)
 {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
index 
0bf2fd470819e64d2d7788b57caee6569b9b..2244107e1da103559c899b1774b815bcc0f9 
100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
@@ -760,6 +760,8 @@ struct bnx2x_rss_config_obj {
        /* Last configured indirection table */
        u8                      ind_table[T_ETH_INDIRECTION_TABLE_SIZE];
 
+       u32                     rss_key[T_ETH_RSS_KEY];
+
        /* flags for enabling 4-tupple hash on UDP */
        u8                      udp_rss_v4;
        u8                      udp_rss_v6;
@@ -1530,6 +1532,8 @@ int bnx2x_config_rss(struct bnx2x *bp,
 void bnx2x_get_rss_ind_table(struct bnx2x_rss_config_obj *rss_obj,
                             u8 *ind_table);
 
+void bnx2x_get_rss_key(const struct bnx2x_rss_config_obj *rss_obj, u8 *key);
+
 #define PF_MAC_CREDIT_E2(bp, func_num)                                 \
        ((MAX_MAC_CREDIT_E2 - GET_NUM_VFS_PER_PATH(bp) * VF_MAC_CREDIT_CNT) / \
         func_num + GET_NUM_VFS_PER_PF(bp) * VF_MAC_CREDIT_CNT)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
index 
bfae300cf25ff881292dc36ad56e51e37132..79e4e1890e94e244a72d50d76d41963a4b23 
100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
@@ -1985,7 +1985,7 @@ static void bnx2x_vf_mbx_update_rss(struct bnx2x *bp, 
struct bnx2x_virtf *vf,
        /* set vfop params according to rss tlv */
        memcpy(rss.ind_table, rss_tlv->ind_table,
               T_ETH_INDIRECTION_TABLE_SIZE);
-       memcpy(rss.rss_key, rss_tlv->rss_key, sizeof(rss_tlv->rss_key));
+       memcpy(&vf->rss_conf_obj.rss_key, rss_tlv->rss_key, 
sizeof(rss_tlv->rss_key));
        rss.rss_obj = &vf->rss_conf_obj;
        rss.rss_result_mask = rss_tlv->rss_result_mask;
 


Reply via email to