diff options
author | Govindarajulu Varadarajan <_govind@gmx.com> | 2014-12-10 03:10:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-12-10 14:41:48 -0500 |
commit | 4f675eb2a736dfb65d68a00ff38e9342252eeabc (patch) | |
tree | d4cc906539c74be231e0d4c26174e52bb99e1900 | |
parent | 7dbea3e8662eb491e9da109cf8ffc372e160fe9a (diff) |
enic: add support for set/get rss hash key
This patch adds support for setting/getting rss hash key using ethtool.
v2:
respin patch to support RSS hash function changes.
Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic_ethtool.c | 38 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic_main.c | 13 |
3 files changed, 49 insertions, 4 deletions
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h index 5ba5ad071bb6..25c4d88853d8 100644 --- a/drivers/net/ethernet/cisco/enic/enic.h +++ b/drivers/net/ethernet/cisco/enic/enic.h | |||
@@ -187,6 +187,7 @@ struct enic { | |||
187 | unsigned int cq_count; | 187 | unsigned int cq_count; |
188 | struct enic_rfs_flw_tbl rfs_h; | 188 | struct enic_rfs_flw_tbl rfs_h; |
189 | u32 rx_copybreak; | 189 | u32 rx_copybreak; |
190 | u8 rss_key[ENIC_RSS_LEN]; | ||
190 | }; | 191 | }; |
191 | 192 | ||
192 | static inline struct device *enic_get_dev(struct enic *enic) | 193 | static inline struct device *enic_get_dev(struct enic *enic) |
@@ -246,5 +247,6 @@ int enic_sriov_enabled(struct enic *enic); | |||
246 | int enic_is_valid_vf(struct enic *enic, int vf); | 247 | int enic_is_valid_vf(struct enic *enic, int vf); |
247 | int enic_is_dynamic(struct enic *enic); | 248 | int enic_is_dynamic(struct enic *enic); |
248 | void enic_set_ethtool_ops(struct net_device *netdev); | 249 | void enic_set_ethtool_ops(struct net_device *netdev); |
250 | int __enic_set_rsskey(struct enic *enic); | ||
249 | 251 | ||
250 | #endif /* _ENIC_H_ */ | 252 | #endif /* _ENIC_H_ */ |
diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c index 85173d620758..eba1eb846d34 100644 --- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c +++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "enic.h" | 23 | #include "enic.h" |
24 | #include "enic_dev.h" | 24 | #include "enic_dev.h" |
25 | #include "enic_clsf.h" | 25 | #include "enic_clsf.h" |
26 | #include "vnic_rss.h" | ||
26 | 27 | ||
27 | struct enic_stat { | 28 | struct enic_stat { |
28 | char name[ETH_GSTRING_LEN]; | 29 | char name[ETH_GSTRING_LEN]; |
@@ -416,6 +417,40 @@ static int enic_set_tunable(struct net_device *dev, | |||
416 | return ret; | 417 | return ret; |
417 | } | 418 | } |
418 | 419 | ||
420 | static u32 enic_get_rxfh_key_size(struct net_device *netdev) | ||
421 | { | ||
422 | return ENIC_RSS_LEN; | ||
423 | } | ||
424 | |||
425 | static int enic_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey, | ||
426 | u8 *hfunc) | ||
427 | { | ||
428 | struct enic *enic = netdev_priv(netdev); | ||
429 | |||
430 | if (hkey) | ||
431 | memcpy(hkey, enic->rss_key, ENIC_RSS_LEN); | ||
432 | |||
433 | if (hfunc) | ||
434 | *hfunc = ETH_RSS_HASH_TOP; | ||
435 | |||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | static int enic_set_rxfh(struct net_device *netdev, const u32 *indir, | ||
440 | const u8 *hkey, const u8 hfunc) | ||
441 | { | ||
442 | struct enic *enic = netdev_priv(netdev); | ||
443 | |||
444 | if ((hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) || | ||
445 | indir) | ||
446 | return -EINVAL; | ||
447 | |||
448 | if (hkey) | ||
449 | memcpy(enic->rss_key, hkey, ENIC_RSS_LEN); | ||
450 | |||
451 | return __enic_set_rsskey(enic); | ||
452 | } | ||
453 | |||
419 | static const struct ethtool_ops enic_ethtool_ops = { | 454 | static const struct ethtool_ops enic_ethtool_ops = { |
420 | .get_settings = enic_get_settings, | 455 | .get_settings = enic_get_settings, |
421 | .get_drvinfo = enic_get_drvinfo, | 456 | .get_drvinfo = enic_get_drvinfo, |
@@ -430,6 +465,9 @@ static const struct ethtool_ops enic_ethtool_ops = { | |||
430 | .get_rxnfc = enic_get_rxnfc, | 465 | .get_rxnfc = enic_get_rxnfc, |
431 | .get_tunable = enic_get_tunable, | 466 | .get_tunable = enic_get_tunable, |
432 | .set_tunable = enic_set_tunable, | 467 | .set_tunable = enic_set_tunable, |
468 | .get_rxfh_key_size = enic_get_rxfh_key_size, | ||
469 | .get_rxfh = enic_get_rxfh, | ||
470 | .set_rxfh = enic_set_rxfh, | ||
433 | }; | 471 | }; |
434 | 472 | ||
435 | void enic_set_ethtool_ops(struct net_device *netdev) | 473 | void enic_set_ethtool_ops(struct net_device *netdev) |
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 86ee350e57f0..868d0f605d60 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c | |||
@@ -1888,11 +1888,10 @@ static int enic_dev_hang_reset(struct enic *enic) | |||
1888 | return err; | 1888 | return err; |
1889 | } | 1889 | } |
1890 | 1890 | ||
1891 | static int enic_set_rsskey(struct enic *enic) | 1891 | int __enic_set_rsskey(struct enic *enic) |
1892 | { | 1892 | { |
1893 | union vnic_rss_key *rss_key_buf_va; | 1893 | union vnic_rss_key *rss_key_buf_va; |
1894 | dma_addr_t rss_key_buf_pa; | 1894 | dma_addr_t rss_key_buf_pa; |
1895 | u8 rss_key[ENIC_RSS_LEN]; | ||
1896 | int i, kidx, bidx, err; | 1895 | int i, kidx, bidx, err; |
1897 | 1896 | ||
1898 | rss_key_buf_va = pci_zalloc_consistent(enic->pdev, | 1897 | rss_key_buf_va = pci_zalloc_consistent(enic->pdev, |
@@ -1901,11 +1900,10 @@ static int enic_set_rsskey(struct enic *enic) | |||
1901 | if (!rss_key_buf_va) | 1900 | if (!rss_key_buf_va) |
1902 | return -ENOMEM; | 1901 | return -ENOMEM; |
1903 | 1902 | ||
1904 | netdev_rss_key_fill(rss_key, ENIC_RSS_LEN); | ||
1905 | for (i = 0; i < ENIC_RSS_LEN; i++) { | 1903 | for (i = 0; i < ENIC_RSS_LEN; i++) { |
1906 | kidx = i / ENIC_RSS_BYTES_PER_KEY; | 1904 | kidx = i / ENIC_RSS_BYTES_PER_KEY; |
1907 | bidx = i % ENIC_RSS_BYTES_PER_KEY; | 1905 | bidx = i % ENIC_RSS_BYTES_PER_KEY; |
1908 | rss_key_buf_va->key[kidx].b[bidx] = rss_key[i]; | 1906 | rss_key_buf_va->key[kidx].b[bidx] = enic->rss_key[i]; |
1909 | } | 1907 | } |
1910 | spin_lock_bh(&enic->devcmd_lock); | 1908 | spin_lock_bh(&enic->devcmd_lock); |
1911 | err = enic_set_rss_key(enic, | 1909 | err = enic_set_rss_key(enic, |
@@ -1919,6 +1917,13 @@ static int enic_set_rsskey(struct enic *enic) | |||
1919 | return err; | 1917 | return err; |
1920 | } | 1918 | } |
1921 | 1919 | ||
1920 | static int enic_set_rsskey(struct enic *enic) | ||
1921 | { | ||
1922 | netdev_rss_key_fill(enic->rss_key, ENIC_RSS_LEN); | ||
1923 | |||
1924 | return __enic_set_rsskey(enic); | ||
1925 | } | ||
1926 | |||
1922 | static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits) | 1927 | static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits) |
1923 | { | 1928 | { |
1924 | dma_addr_t rss_cpu_buf_pa; | 1929 | dma_addr_t rss_cpu_buf_pa; |