Skip to content

Commit e60a9de

Browse files
committed
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== Intel Wired LAN Driver Updates 2015-04-11 This series contains updates to iflink, ixgbe and ixgbevf. The entire set of changes come from Vlad Zolotarov to ultimately add the ethtool ops to VF driver to allow querying the RSS indirection table and RSS random key. Currently we support only 82599 and x540 devices. On those devices, VFs share the RSS redirection table and hash key with a PF. Letting the VF query this information may introduce some security risks, therefore this feature will be disabled by default. The new netdev op allows a system administrator to change the default behaviour with "ip link set" command. The relevant iproute2 patch has already been sent and awaits for this series upstream. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 1ceb0b8 + b641173 commit e60a9de

File tree

16 files changed

+505
-53
lines changed

16 files changed

+505
-53
lines changed

drivers/net/ethernet/intel/ixgbe/ixgbe.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ struct vf_data_storage {
151151
u16 tx_rate;
152152
u16 vlan_count;
153153
u8 spoofchk_enabled;
154+
bool rss_query_enabled;
154155
unsigned int vf_api;
155156
};
156157

@@ -766,6 +767,15 @@ struct ixgbe_adapter {
766767

767768
u8 default_up;
768769
unsigned long fwd_bitmask; /* Bitmask indicating in use pools */
770+
771+
/* maximum number of RETA entries among all devices supported by ixgbe
772+
* driver: currently it's x550 device in non-SRIOV mode
773+
*/
774+
#define IXGBE_MAX_RETA_ENTRIES 512
775+
u8 rss_indir_tbl[IXGBE_MAX_RETA_ENTRIES];
776+
777+
#define IXGBE_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */
778+
u32 rss_key[IXGBE_RSS_KEY_SIZE / sizeof(u32)];
769779
};
770780

771781
static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
@@ -955,4 +965,5 @@ void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter);
955965
netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
956966
struct ixgbe_adapter *adapter,
957967
struct ixgbe_ring *tx_ring);
968+
u32 ixgbe_rss_indir_tbl_entries(struct ixgbe_adapter *adapter);
958969
#endif /* _IXGBE_H_ */

drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,6 +2853,45 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
28532853
return ret;
28542854
}
28552855

2856+
static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev)
2857+
{
2858+
struct ixgbe_adapter *adapter = netdev_priv(netdev);
2859+
2860+
return sizeof(adapter->rss_key);
2861+
}
2862+
2863+
static u32 ixgbe_rss_indir_size(struct net_device *netdev)
2864+
{
2865+
struct ixgbe_adapter *adapter = netdev_priv(netdev);
2866+
2867+
return ixgbe_rss_indir_tbl_entries(adapter);
2868+
}
2869+
2870+
static void ixgbe_get_reta(struct ixgbe_adapter *adapter, u32 *indir)
2871+
{
2872+
int i, reta_size = ixgbe_rss_indir_tbl_entries(adapter);
2873+
2874+
for (i = 0; i < reta_size; i++)
2875+
indir[i] = adapter->rss_indir_tbl[i];
2876+
}
2877+
2878+
static int ixgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
2879+
u8 *hfunc)
2880+
{
2881+
struct ixgbe_adapter *adapter = netdev_priv(netdev);
2882+
2883+
if (hfunc)
2884+
*hfunc = ETH_RSS_HASH_TOP;
2885+
2886+
if (indir)
2887+
ixgbe_get_reta(adapter, indir);
2888+
2889+
if (key)
2890+
memcpy(key, adapter->rss_key, ixgbe_get_rxfh_key_size(netdev));
2891+
2892+
return 0;
2893+
}
2894+
28562895
static int ixgbe_get_ts_info(struct net_device *dev,
28572896
struct ethtool_ts_info *info)
28582897
{
@@ -3110,6 +3149,9 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
31103149
.set_coalesce = ixgbe_set_coalesce,
31113150
.get_rxnfc = ixgbe_get_rxnfc,
31123151
.set_rxnfc = ixgbe_set_rxnfc,
3152+
.get_rxfh_indir_size = ixgbe_rss_indir_size,
3153+
.get_rxfh_key_size = ixgbe_get_rxfh_key_size,
3154+
.get_rxfh = ixgbe_get_rxfh,
31133155
.get_channels = ixgbe_get_channels,
31143156
.set_channels = ixgbe_set_channels,
31153157
.get_ts_info = ixgbe_get_ts_info,

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 108 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3228,89 +3228,148 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
32283228
IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl);
32293229
}
32303230

3231-
static void ixgbe_setup_reta(struct ixgbe_adapter *adapter, const u32 *seed)
3231+
/**
3232+
* Return a number of entries in the RSS indirection table
3233+
*
3234+
* @adapter: device handle
3235+
*
3236+
* - 82598/82599/X540: 128
3237+
* - X550(non-SRIOV mode): 512
3238+
* - X550(SRIOV mode): 64
3239+
*/
3240+
u32 ixgbe_rss_indir_tbl_entries(struct ixgbe_adapter *adapter)
3241+
{
3242+
if (adapter->hw.mac.type < ixgbe_mac_X550)
3243+
return 128;
3244+
else if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
3245+
return 64;
3246+
else
3247+
return 512;
3248+
}
3249+
3250+
/**
3251+
* Write the RETA table to HW
3252+
*
3253+
* @adapter: device handle
3254+
*
3255+
* Write the RSS redirection table stored in adapter.rss_indir_tbl[] to HW.
3256+
*/
3257+
static void ixgbe_store_reta(struct ixgbe_adapter *adapter)
32323258
{
3259+
u32 i, reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
32333260
struct ixgbe_hw *hw = &adapter->hw;
32343261
u32 reta = 0;
3235-
int i, j;
3236-
int reta_entries = 128;
3237-
u16 rss_i = adapter->ring_feature[RING_F_RSS].indices;
3238-
int indices_multi;
3239-
3240-
/*
3241-
* Program table for at least 2 queues w/ SR-IOV so that VFs can
3242-
* make full use of any rings they may have. We will use the
3243-
* PSRTYPE register to control how many rings we use within the PF.
3244-
*/
3245-
if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && (rss_i < 2))
3246-
rss_i = 2;
3247-
3248-
/* Fill out hash function seeds */
3249-
for (i = 0; i < 10; i++)
3250-
IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
3262+
u32 indices_multi;
3263+
u8 *indir_tbl = adapter->rss_indir_tbl;
32513264

32523265
/* Fill out the redirection table as follows:
3253-
* 82598: 128 (8 bit wide) entries containing pair of 4 bit RSS indices
3254-
* 82599/X540: 128 (8 bit wide) entries containing 4 bit RSS index
3255-
* X550: 512 (8 bit wide) entries containing 6 bit RSS index
3266+
* - 82598: 8 bit wide entries containing pair of 4 bit RSS
3267+
* indices.
3268+
* - 82599/X540: 8 bit wide entries containing 4 bit RSS index
3269+
* - X550: 8 bit wide entries containing 6 bit RSS index
32563270
*/
32573271
if (adapter->hw.mac.type == ixgbe_mac_82598EB)
32583272
indices_multi = 0x11;
32593273
else
32603274
indices_multi = 0x1;
32613275

3262-
switch (adapter->hw.mac.type) {
3263-
case ixgbe_mac_X550:
3264-
case ixgbe_mac_X550EM_x:
3265-
if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
3266-
reta_entries = 512;
3267-
default:
3268-
break;
3269-
}
3270-
3271-
/* Fill out redirection table */
3272-
for (i = 0, j = 0; i < reta_entries; i++, j++) {
3273-
if (j == rss_i)
3274-
j = 0;
3275-
reta = (reta << 8) | (j * indices_multi);
3276+
/* Write redirection table to HW */
3277+
for (i = 0; i < reta_entries; i++) {
3278+
reta |= indices_multi * indir_tbl[i] << (i & 0x3) * 8;
32763279
if ((i & 3) == 3) {
32773280
if (i < 128)
32783281
IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
32793282
else
32803283
IXGBE_WRITE_REG(hw, IXGBE_ERETA((i >> 2) - 32),
32813284
reta);
3285+
reta = 0;
32823286
}
32833287
}
32843288
}
32853289

3286-
static void ixgbe_setup_vfreta(struct ixgbe_adapter *adapter, const u32 *seed)
3290+
/**
3291+
* Write the RETA table to HW (for x550 devices in SRIOV mode)
3292+
*
3293+
* @adapter: device handle
3294+
*
3295+
* Write the RSS redirection table stored in adapter.rss_indir_tbl[] to HW.
3296+
*/
3297+
static void ixgbe_store_vfreta(struct ixgbe_adapter *adapter)
32873298
{
3299+
u32 i, reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
32883300
struct ixgbe_hw *hw = &adapter->hw;
32893301
u32 vfreta = 0;
3302+
unsigned int pf_pool = adapter->num_vfs;
3303+
3304+
/* Write redirection table to HW */
3305+
for (i = 0; i < reta_entries; i++) {
3306+
vfreta |= (u32)adapter->rss_indir_tbl[i] << (i & 0x3) * 8;
3307+
if ((i & 3) == 3) {
3308+
IXGBE_WRITE_REG(hw, IXGBE_PFVFRETA(i >> 2, pf_pool),
3309+
vfreta);
3310+
vfreta = 0;
3311+
}
3312+
}
3313+
}
3314+
3315+
static void ixgbe_setup_reta(struct ixgbe_adapter *adapter)
3316+
{
3317+
struct ixgbe_hw *hw = &adapter->hw;
3318+
u32 i, j;
3319+
u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
3320+
u16 rss_i = adapter->ring_feature[RING_F_RSS].indices;
3321+
3322+
/* Program table for at least 2 queues w/ SR-IOV so that VFs can
3323+
* make full use of any rings they may have. We will use the
3324+
* PSRTYPE register to control how many rings we use within the PF.
3325+
*/
3326+
if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && (rss_i < 2))
3327+
rss_i = 2;
3328+
3329+
/* Fill out hash function seeds */
3330+
for (i = 0; i < 10; i++)
3331+
IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), adapter->rss_key[i]);
3332+
3333+
/* Fill out redirection table */
3334+
memset(adapter->rss_indir_tbl, 0, sizeof(adapter->rss_indir_tbl));
3335+
3336+
for (i = 0, j = 0; i < reta_entries; i++, j++) {
3337+
if (j == rss_i)
3338+
j = 0;
3339+
3340+
adapter->rss_indir_tbl[i] = j;
3341+
}
3342+
3343+
ixgbe_store_reta(adapter);
3344+
}
3345+
3346+
static void ixgbe_setup_vfreta(struct ixgbe_adapter *adapter)
3347+
{
3348+
struct ixgbe_hw *hw = &adapter->hw;
32903349
u16 rss_i = adapter->ring_feature[RING_F_RSS].indices;
32913350
unsigned int pf_pool = adapter->num_vfs;
32923351
int i, j;
32933352

32943353
/* Fill out hash function seeds */
32953354
for (i = 0; i < 10; i++)
3296-
IXGBE_WRITE_REG(hw, IXGBE_PFVFRSSRK(i, pf_pool), seed[i]);
3355+
IXGBE_WRITE_REG(hw, IXGBE_PFVFRSSRK(i, pf_pool),
3356+
adapter->rss_key[i]);
32973357

32983358
/* Fill out the redirection table */
32993359
for (i = 0, j = 0; i < 64; i++, j++) {
33003360
if (j == rss_i)
33013361
j = 0;
3302-
vfreta = (vfreta << 8) | j;
3303-
if ((i & 3) == 3)
3304-
IXGBE_WRITE_REG(hw, IXGBE_PFVFRETA(i >> 2, pf_pool),
3305-
vfreta);
3362+
3363+
adapter->rss_indir_tbl[i] = j;
33063364
}
3365+
3366+
ixgbe_store_vfreta(adapter);
33073367
}
33083368

33093369
static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
33103370
{
33113371
struct ixgbe_hw *hw = &adapter->hw;
33123372
u32 mrqc = 0, rss_field = 0, vfmrqc = 0;
3313-
u32 rss_key[10];
33143373
u32 rxcsum;
33153374

33163375
/* Disable indicating checksum in descriptor, enables RSS hash */
@@ -3354,7 +3413,7 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
33543413
if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP)
33553414
rss_field |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
33563415

3357-
netdev_rss_key_fill(rss_key, sizeof(rss_key));
3416+
netdev_rss_key_fill(adapter->rss_key, sizeof(adapter->rss_key));
33583417
if ((hw->mac.type >= ixgbe_mac_X550) &&
33593418
(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) {
33603419
unsigned int pf_pool = adapter->num_vfs;
@@ -3364,12 +3423,12 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
33643423
IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
33653424

33663425
/* Setup RSS through the VF registers */
3367-
ixgbe_setup_vfreta(adapter, rss_key);
3426+
ixgbe_setup_vfreta(adapter);
33683427
vfmrqc = IXGBE_MRQC_RSSEN;
33693428
vfmrqc |= rss_field;
33703429
IXGBE_WRITE_REG(hw, IXGBE_PFVFMRQC(pf_pool), vfmrqc);
33713430
} else {
3372-
ixgbe_setup_reta(adapter, rss_key);
3431+
ixgbe_setup_reta(adapter);
33733432
mrqc |= rss_field;
33743433
IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
33753434
}
@@ -3599,6 +3658,10 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
35993658
/* enable ethertype anti spoofing if hw supports it */
36003659
if (hw->mac.ops.set_ethertype_anti_spoofing)
36013660
hw->mac.ops.set_ethertype_anti_spoofing(hw, true, i);
3661+
3662+
/* Enable/Disable RSS query feature */
3663+
ixgbe_ndo_set_vf_rss_query_en(adapter->netdev, i,
3664+
adapter->vfinfo[i].rss_query_enabled);
36023665
}
36033666
}
36043667

@@ -8101,6 +8164,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
81018164
.ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan,
81028165
.ndo_set_vf_rate = ixgbe_ndo_set_vf_bw,
81038166
.ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk,
8167+
.ndo_set_vf_rss_query_en = ixgbe_ndo_set_vf_rss_query_en,
81048168
.ndo_get_vf_config = ixgbe_ndo_get_vf_config,
81058169
.ndo_get_stats64 = ixgbe_get_stats64,
81068170
#ifdef CONFIG_IXGBE_DCB

drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ enum ixgbe_pfvf_api_rev {
7373
ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */
7474
ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */
7575
ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */
76+
ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */
7677
/* This value should always be last */
7778
ixgbe_mbox_api_unknown, /* indicates that API version is not known */
7879
};
@@ -97,6 +98,10 @@ enum ixgbe_pfvf_api_rev {
9798
#define IXGBE_VF_TRANS_VLAN 3 /* Indication of port vlan */
9899
#define IXGBE_VF_DEF_QUEUE 4 /* Default queue offset */
99100

101+
/* mailbox API, version 1.2 VF requests */
102+
#define IXGBE_VF_GET_RETA 0x0a /* VF request for RETA */
103+
#define IXGBE_VF_GET_RSS_KEY 0x0b /* get RSS key */
104+
100105
/* length of permanent address message returned from PF */
101106
#define IXGBE_VF_PERMADDR_MSG_LEN 4
102107
/* word in permanent address message with the current multicast type */

0 commit comments

Comments
 (0)