aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/i40e
diff options
context:
space:
mode:
authorMitch A Williams <mitch.a.williams@intel.com>2015-03-04 23:14:40 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-03-09 13:53:37 -0400
commitb29e13bb9198d2a79ab3370eb1d3ed69a05de61f (patch)
treefc6963d725221d9b44ee21803536dee997981441 /drivers/net/ethernet/intel/i40e
parentec7a06fd6d6822db287e59d67362b2207cf42ca9 (diff)
i40e: add ethtool RSS support
Add support for setting the RSS hash table and hash key through ethtool. This patch incorporates suggestions from Ben Hutchings <ben.hutchings@codethink.co.uk>. Reported-by: Ben Hutchings <ben.hutchings@codethink.co.uk> Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/i40e')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c108
2 files changed, 110 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index cc3f23685430..1c8bd7c152c2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -177,6 +177,8 @@ struct i40e_lump_tracking {
177#define I40E_FDIR_BUFFER_HEAD_ROOM 32 177#define I40E_FDIR_BUFFER_HEAD_ROOM 32
178#define I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR (I40E_FDIR_BUFFER_HEAD_ROOM * 4) 178#define I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR (I40E_FDIR_BUFFER_HEAD_ROOM * 4)
179 179
180#define I40E_HKEY_ARRAY_SIZE ((I40E_PFQF_HKEY_MAX_INDEX + 1) * 4)
181
180enum i40e_fd_stat_idx { 182enum i40e_fd_stat_idx {
181 I40E_FD_STAT_ATR, 183 I40E_FD_STAT_ATR,
182 I40E_FD_STAT_SB, 184 I40E_FD_STAT_SB,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 9ff3dc15db25..b7d0aaac5480 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -2375,6 +2375,110 @@ static int i40e_set_channels(struct net_device *dev,
2375 return -EINVAL; 2375 return -EINVAL;
2376} 2376}
2377 2377
2378#define I40E_HLUT_ARRAY_SIZE ((I40E_PFQF_HLUT_MAX_INDEX + 1) * 4)
2379/**
2380 * i40e_get_rxfh_key_size - get the RSS hash key size
2381 * @netdev: network interface device structure
2382 *
2383 * Returns the table size.
2384 **/
2385static u32 i40e_get_rxfh_key_size(struct net_device *netdev)
2386{
2387 return I40E_HKEY_ARRAY_SIZE;
2388}
2389
2390/**
2391 * i40e_get_rxfh_indir_size - get the rx flow hash indirection table size
2392 * @netdev: network interface device structure
2393 *
2394 * Returns the table size.
2395 **/
2396static u32 i40e_get_rxfh_indir_size(struct net_device *netdev)
2397{
2398 return I40E_HLUT_ARRAY_SIZE;
2399}
2400
2401static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
2402 u8 *hfunc)
2403{
2404 struct i40e_netdev_priv *np = netdev_priv(netdev);
2405 struct i40e_vsi *vsi = np->vsi;
2406 struct i40e_pf *pf = vsi->back;
2407 struct i40e_hw *hw = &pf->hw;
2408 u32 reg_val;
2409 int i, j;
2410
2411 if (hfunc)
2412 *hfunc = ETH_RSS_HASH_TOP;
2413
2414 if (!indir)
2415 return 0;
2416
2417 for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
2418 reg_val = rd32(hw, I40E_PFQF_HLUT(i));
2419 indir[j++] = reg_val & 0xff;
2420 indir[j++] = (reg_val >> 8) & 0xff;
2421 indir[j++] = (reg_val >> 16) & 0xff;
2422 indir[j++] = (reg_val >> 24) & 0xff;
2423 }
2424
2425 if (key) {
2426 for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
2427 reg_val = rd32(hw, I40E_PFQF_HKEY(i));
2428 key[j++] = (u8)(reg_val & 0xff);
2429 key[j++] = (u8)((reg_val >> 8) & 0xff);
2430 key[j++] = (u8)((reg_val >> 16) & 0xff);
2431 key[j++] = (u8)((reg_val >> 24) & 0xff);
2432 }
2433 }
2434 return 0;
2435}
2436
2437/**
2438 * i40e_set_rxfh - set the rx flow hash indirection table
2439 * @netdev: network interface device structure
2440 * @indir: indirection table
2441 * @key: hash key
2442 *
2443 * Returns -EINVAL if the table specifies an inavlid queue id, otherwise
2444 * returns 0 after programming the table.
2445 **/
2446static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
2447 const u8 *key, const u8 hfunc)
2448{
2449 struct i40e_netdev_priv *np = netdev_priv(netdev);
2450 struct i40e_vsi *vsi = np->vsi;
2451 struct i40e_pf *pf = vsi->back;
2452 struct i40e_hw *hw = &pf->hw;
2453 u32 reg_val;
2454 int i, j;
2455
2456 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
2457 return -EOPNOTSUPP;
2458
2459 if (!indir)
2460 return 0;
2461
2462 for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
2463 reg_val = indir[j++];
2464 reg_val |= indir[j++] << 8;
2465 reg_val |= indir[j++] << 16;
2466 reg_val |= indir[j++] << 24;
2467 wr32(hw, I40E_PFQF_HLUT(i), reg_val);
2468 }
2469
2470 if (key) {
2471 for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
2472 reg_val = key[j++];
2473 reg_val |= key[j++] << 8;
2474 reg_val |= key[j++] << 16;
2475 reg_val |= key[j++] << 24;
2476 wr32(hw, I40E_PFQF_HKEY(i), reg_val);
2477 }
2478 }
2479 return 0;
2480}
2481
2378/** 2482/**
2379 * i40e_get_priv_flags - report device private flags 2483 * i40e_get_priv_flags - report device private flags
2380 * @dev: network interface device structure 2484 * @dev: network interface device structure
@@ -2426,6 +2530,10 @@ static const struct ethtool_ops i40e_ethtool_ops = {
2426 .get_ethtool_stats = i40e_get_ethtool_stats, 2530 .get_ethtool_stats = i40e_get_ethtool_stats,
2427 .get_coalesce = i40e_get_coalesce, 2531 .get_coalesce = i40e_get_coalesce,
2428 .set_coalesce = i40e_set_coalesce, 2532 .set_coalesce = i40e_set_coalesce,
2533 .get_rxfh_key_size = i40e_get_rxfh_key_size,
2534 .get_rxfh_indir_size = i40e_get_rxfh_indir_size,
2535 .get_rxfh = i40e_get_rxfh,
2536 .set_rxfh = i40e_set_rxfh,
2429 .get_channels = i40e_get_channels, 2537 .get_channels = i40e_get_channels,
2430 .set_channels = i40e_set_channels, 2538 .set_channels = i40e_set_channels,
2431 .get_ts_info = i40e_get_ts_info, 2539 .get_ts_info = i40e_get_ts_info,