diff options
author | Mitch A Williams <mitch.a.williams@intel.com> | 2015-03-04 23:14:40 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2015-03-09 13:53:37 -0400 |
commit | b29e13bb9198d2a79ab3370eb1d3ed69a05de61f (patch) | |
tree | fc6963d725221d9b44ee21803536dee997981441 /drivers/net/ethernet/intel/i40e | |
parent | ec7a06fd6d6822db287e59d67362b2207cf42ca9 (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.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 108 |
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 | |||
180 | enum i40e_fd_stat_idx { | 182 | enum 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 | **/ | ||
2385 | static 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 | **/ | ||
2396 | static u32 i40e_get_rxfh_indir_size(struct net_device *netdev) | ||
2397 | { | ||
2398 | return I40E_HLUT_ARRAY_SIZE; | ||
2399 | } | ||
2400 | |||
2401 | static 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 | **/ | ||
2446 | static 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, |