* [PATCH net-next v8 1/7] if_link: Add an additional parameter to ifla_vf_info for RSS querying
2015-03-25 17:42 [PATCH net-next v8 0/7]: ixgbevf: Allow querying VFs RSS indirection table and key Vlad Zolotarov
@ 2015-03-25 17:42 ` Vlad Zolotarov
2015-03-25 17:42 ` [PATCH net-next v8 2/7] ixgbe: Add a new netdev op to allow/prevent a VF from querying an RSS info Vlad Zolotarov
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Vlad Zolotarov @ 2015-03-25 17:42 UTC (permalink / raw)
To: netdev; +Cc: jeffrey.t.kirsher, avi, gleb, intel-wired-lan, Vlad Zolotarov
Add configuration setting for drivers to allow/block an RSS Redirection Table and
a Hash Key querying for discrete VFs.
On some devices VF share the mentioned above information with PF and querying it may
adduce a theoretical security risk. We want to let a system administrator to decide if he/she
wants to take this risk or not.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
---
include/linux/if_link.h | 1 +
include/linux/netdevice.h | 8 ++++++++
include/uapi/linux/if_link.h | 8 ++++++++
net/core/rtnetlink.c | 32 ++++++++++++++++++++++++++------
4 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 119130e..da49299 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -14,5 +14,6 @@ struct ifla_vf_info {
__u32 linkstate;
__u32 min_tx_rate;
__u32 max_tx_rate;
+ __u32 rss_query_en;
};
#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 08c4ab3..a858cda 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -875,6 +875,11 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
* int (*ndo_set_vf_link_state)(struct net_device *dev, int vf, int link_state);
* int (*ndo_set_vf_port)(struct net_device *dev, int vf,
* struct nlattr *port[]);
+ *
+ * Enable or disable the VF ability to query its RSS Redirection Table and
+ * Hash Key. This is needed since on some devices VF share this information
+ * with PF and querying it may adduce a theoretical security risk.
+ * int (*ndo_set_vf_rss_query_en)(struct net_device *dev, int vf, bool setting);
* int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
* int (*ndo_setup_tc)(struct net_device *dev, u8 tc)
* Called to setup 'tc' number of traffic classes in the net device. This
@@ -1094,6 +1099,9 @@ struct net_device_ops {
struct nlattr *port[]);
int (*ndo_get_vf_port)(struct net_device *dev,
int vf, struct sk_buff *skb);
+ int (*ndo_set_vf_rss_query_en)(
+ struct net_device *dev,
+ int vf, bool setting);
int (*ndo_setup_tc)(struct net_device *dev, u8 tc);
#if IS_ENABLED(CONFIG_FCOE)
int (*ndo_fcoe_enable)(struct net_device *dev);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 7ffb18d..d9cd192 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -465,6 +465,9 @@ enum {
IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */
IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */
IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */
+ IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query
+ * on/off switch
+ */
__IFLA_VF_MAX,
};
@@ -509,6 +512,11 @@ struct ifla_vf_link_state {
__u32 link_state;
};
+struct ifla_vf_rss_query_en {
+ __u32 vf;
+ __u32 setting;
+};
+
/* VF ports management section
*
* Nested layout of set/get msg is:
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index b96ac21..dcbf568 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -818,7 +818,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
nla_total_size(sizeof(struct ifla_vf_vlan)) +
nla_total_size(sizeof(struct ifla_vf_spoofchk)) +
nla_total_size(sizeof(struct ifla_vf_rate)) +
- nla_total_size(sizeof(struct ifla_vf_link_state)));
+ nla_total_size(sizeof(struct ifla_vf_link_state)) +
+ nla_total_size(sizeof(struct ifla_vf_rss_query_en)));
return size;
} else
return 0;
@@ -1132,14 +1133,16 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
struct ifla_vf_tx_rate vf_tx_rate;
struct ifla_vf_spoofchk vf_spoofchk;
struct ifla_vf_link_state vf_linkstate;
+ struct ifla_vf_rss_query_en vf_rss_query_en;
/*
* Not all SR-IOV capable drivers support the
- * spoofcheck query. Preset to -1 so the user
- * space tool can detect that the driver didn't
- * report anything.
+ * spoofcheck and "RSS query enable" query. Preset to
+ * -1 so the user space tool can detect that the driver
+ * didn't report anything.
*/
ivi.spoofchk = -1;
+ ivi.rss_query_en = -1;
memset(ivi.mac, 0, sizeof(ivi.mac));
/* The default value for VF link state is "auto"
* IFLA_VF_LINK_STATE_AUTO which equals zero
@@ -1152,7 +1155,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
vf_rate.vf =
vf_tx_rate.vf =
vf_spoofchk.vf =
- vf_linkstate.vf = ivi.vf;
+ vf_linkstate.vf =
+ vf_rss_query_en.vf = ivi.vf;
memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
vf_vlan.vlan = ivi.vlan;
@@ -1162,6 +1166,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
vf_rate.max_tx_rate = ivi.max_tx_rate;
vf_spoofchk.setting = ivi.spoofchk;
vf_linkstate.link_state = ivi.linkstate;
+ vf_rss_query_en.setting = ivi.rss_query_en;
vf = nla_nest_start(skb, IFLA_VF_INFO);
if (!vf) {
nla_nest_cancel(skb, vfinfo);
@@ -1176,7 +1181,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
&vf_spoofchk) ||
nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate),
- &vf_linkstate))
+ &vf_linkstate) ||
+ nla_put(skb, IFLA_VF_RSS_QUERY_EN,
+ sizeof(vf_rss_query_en),
+ &vf_rss_query_en))
goto nla_put_failure;
nla_nest_end(skb, vf);
}
@@ -1290,6 +1298,7 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
[IFLA_VF_SPOOFCHK] = { .len = sizeof(struct ifla_vf_spoofchk) },
[IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) },
[IFLA_VF_LINK_STATE] = { .len = sizeof(struct ifla_vf_link_state) },
+ [IFLA_VF_RSS_QUERY_EN] = { .len = sizeof(struct ifla_vf_rss_query_en) },
};
static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
@@ -1500,6 +1509,17 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
ivl->link_state);
break;
}
+ case IFLA_VF_RSS_QUERY_EN: {
+ struct ifla_vf_rss_query_en *ivrssq_en;
+
+ ivrssq_en = nla_data(vf);
+ err = -EOPNOTSUPP;
+ if (ops->ndo_set_vf_rss_query_en)
+ err = ops->ndo_set_vf_rss_query_en(dev,
+ ivrssq_en->vf,
+ ivrssq_en->setting);
+ break;
+ }
default:
err = -EINVAL;
break;
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v8 2/7] ixgbe: Add a new netdev op to allow/prevent a VF from querying an RSS info
2015-03-25 17:42 [PATCH net-next v8 0/7]: ixgbevf: Allow querying VFs RSS indirection table and key Vlad Zolotarov
2015-03-25 17:42 ` [PATCH net-next v8 1/7] if_link: Add an additional parameter to ifla_vf_info for RSS querying Vlad Zolotarov
@ 2015-03-25 17:42 ` Vlad Zolotarov
2015-03-25 17:42 ` [PATCH net-next v8 3/7] ixgbe: Add a RETA query command to VF-PF channel API Vlad Zolotarov
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Vlad Zolotarov @ 2015-03-25 17:42 UTC (permalink / raw)
To: netdev; +Cc: jeffrey.t.kirsher, avi, gleb, intel-wired-lan, Vlad Zolotarov
Implements the new netdev op to allow user to enable/disable the ability
of a specific VF to query its RSS Indirection Table and an RSS Hash Key.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 7 +++++++
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 27 ++++++++++++++++++++++++++
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h | 2 ++
4 files changed, 37 insertions(+)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 7068e9c..5e44e48 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -151,6 +151,7 @@ struct vf_data_storage {
u16 tx_rate;
u16 vlan_count;
u8 spoofchk_enabled;
+ bool rss_query_enabled;
unsigned int vf_api;
};
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 395dc6b..8853d52 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3600,6 +3600,12 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
if (hw->mac.ops.set_ethertype_anti_spoofing)
hw->mac.ops.set_ethertype_anti_spoofing(hw, true, i);
}
+
+ /* Enable/Disable RSS query feature */
+ for (i = 0; i < adapter->num_vfs; i++)
+ ixgbe_ndo_set_vf_rss_query_en(adapter->netdev, i,
+ adapter->vfinfo[i].rss_query_enabled);
+
}
static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)
@@ -8040,6 +8046,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan,
.ndo_set_vf_rate = ixgbe_ndo_set_vf_bw,
.ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk,
+ .ndo_set_vf_rss_query_en = ixgbe_ndo_set_vf_rss_query_en,
.ndo_get_vf_config = ixgbe_ndo_get_vf_config,
.ndo_get_stats64 = ixgbe_get_stats64,
#ifdef CONFIG_IXGBE_DCB
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 09a291b..4d67677 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -108,6 +108,19 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
/* enable spoof checking for all VFs */
for (i = 0; i < adapter->num_vfs; i++)
adapter->vfinfo[i].spoofchk_enabled = true;
+
+ /* by default:
+ * - Enable RSS query for x550 devices. x550 VFs don't share
+ * RSS Redirection Table and RSS Hash Key with a PF, so
+ * there isn't any possible security threat in allowing them
+ * to query this information.
+ * - disable - for all the rest since they do share it with a
+ * PF.
+ */
+ for (i = 0; i < adapter->num_vfs; i++)
+ adapter->vfinfo[i].rss_query_enabled =
+ (adapter->hw.mac.type >= ixgbe_mac_X550);
+
return 0;
}
@@ -1330,6 +1343,19 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)
return 0;
}
+int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,
+ bool setting)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ if (vf >= adapter->num_vfs)
+ return -EINVAL;
+
+ adapter->vfinfo[vf].rss_query_enabled = setting;
+
+ return 0;
+}
+
int ixgbe_ndo_get_vf_config(struct net_device *netdev,
int vf, struct ifla_vf_info *ivi)
{
@@ -1343,5 +1369,6 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,
ivi->vlan = adapter->vfinfo[vf].pf_vlan;
ivi->qos = adapter->vfinfo[vf].pf_qos;
ivi->spoofchk = adapter->vfinfo[vf].spoofchk_enabled;
+ ivi->rss_query_en = adapter->vfinfo[vf].rss_query_enabled;
return 0;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
index 32c26d5..2c197e6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
@@ -47,6 +47,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
int max_tx_rate);
int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting);
+int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,
+ bool setting);
int ixgbe_ndo_get_vf_config(struct net_device *netdev,
int vf, struct ifla_vf_info *ivi);
void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v8 3/7] ixgbe: Add a RETA query command to VF-PF channel API
2015-03-25 17:42 [PATCH net-next v8 0/7]: ixgbevf: Allow querying VFs RSS indirection table and key Vlad Zolotarov
2015-03-25 17:42 ` [PATCH net-next v8 1/7] if_link: Add an additional parameter to ifla_vf_info for RSS querying Vlad Zolotarov
2015-03-25 17:42 ` [PATCH net-next v8 2/7] ixgbe: Add a new netdev op to allow/prevent a VF from querying an RSS info Vlad Zolotarov
@ 2015-03-25 17:42 ` Vlad Zolotarov
2015-03-25 17:42 ` [PATCH net-next v8 4/7] ixgbevf: Add a RETA query code Vlad Zolotarov
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Vlad Zolotarov @ 2015-03-25 17:42 UTC (permalink / raw)
To: netdev; +Cc: jeffrey.t.kirsher, avi, gleb, intel-wired-lan, Vlad Zolotarov
82599 and x540 VFs and PF share the same RSS redirection table (RETA). Therefore we
just return it for all VFs. x550 on the other hand provides a separate redirection
table for each VF (there is a per-pool RETA table).
For 82599 and x540 RETA table is an array of 32 registers (128 bytes) and the maximum number of
registers that may be delivered in a single VF-PF channel command is 15. Therefore
we will deliver the whole table in 3 steps: 12, 12 and 8 registers in each
step correspondingly.
For x550 VFs RETA is a 64 byte array, so we may deliver it in two steps: 12 and 4 registers
correspondingly.
Thus this patch does the following:
- Adds a new API version (to specify a new commands set).
- Adds the IXGBE_VF_GET_RETA command to the VF-PF commands set.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
---
New in v5:
- Use the newly added netdev op to allow/prevent the RETA query on a per-VF basis.
New in v4:
- Deleted an empty line in ixgbe_get_vf_reta() switch-case.
New in v3:
- Pass the number of dwords and offset in RETA in the IXGBE_VF_GET_RETA request message.
This allows to reduce the added command set to a single command.
- Added a support for all devices supported by the ixgbe driver that have
SR-IOV functions support: 82599, x540 and x550. The original code supported
only 82599 and x540.
- Added the masking of the RETA entries according to the PSRTYPE[n].RQPL
value.
New in v1 (compared to RFC):
- Use "if-else" statement instead of a "switch-case" for a single option case
(in ixgbe_get_vf_reta()).
---
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h | 8 ++++
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 65 ++++++++++++++++++++++++++
2 files changed, 73 insertions(+)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
index a5cb755..f9b5eae 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
@@ -73,6 +73,7 @@ enum ixgbe_pfvf_api_rev {
ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */
ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */
ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */
+ ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */
/* This value should always be last */
ixgbe_mbox_api_unknown, /* indicates that API version is not known */
};
@@ -97,6 +98,13 @@ enum ixgbe_pfvf_api_rev {
#define IXGBE_VF_TRANS_VLAN 3 /* Indication of port vlan */
#define IXGBE_VF_DEF_QUEUE 4 /* Default queue offset */
+/* mailbox API, version 1.2 VF requests */
+#define IXGBE_VF_GET_RETA 0x0a /* VF request for RETA */
+
+/* GET_RETA request data indices within the mailbox */
+#define IXGBE_VF_RETA_SZ 1 /* Number of RETA DWs to bring */
+#define IXGBE_VF_RETA_OFFSET 2 /* Offset in RETA */
+
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
/* word in permanent address message with the current multicast type */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 4d67677..301bb1b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -437,6 +437,7 @@ static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
#endif /* CONFIG_FCOE */
switch (adapter->vfinfo[vf].vf_api) {
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
/*
* Version 1.1 supports jumbo frames on VFs if PF has
* jumbo frames enabled which means legacy VFs are
@@ -904,6 +905,7 @@ static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter,
switch (api) {
case ixgbe_mbox_api_10:
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
adapter->vfinfo[vf].vf_api = api;
return 0;
default:
@@ -927,6 +929,7 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter,
switch (adapter->vfinfo[vf].vf_api) {
case ixgbe_mbox_api_20:
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
break;
default:
return -1;
@@ -954,6 +957,65 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter,
return 0;
}
+static int ixgbe_get_vf_reta(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i, j;
+ u32 *reta = &msgbuf[1];
+ u32 mask = 0;
+ u32 psrtype;
+ u32 reta_offset_dw = msgbuf[IXGBE_VF_RETA_OFFSET];
+ u32 dwords = msgbuf[IXGBE_VF_RETA_SZ];
+
+ /* verify the PF is supporting the correct API */
+ if (!adapter->vfinfo[vf].rss_query_enabled ||
+ (adapter->vfinfo[vf].vf_api != ixgbe_mbox_api_12))
+ return -EPERM;
+
+ psrtype = IXGBE_READ_REG(hw, IXGBE_PSRTYPE(vf));
+
+ /* The redirection table is composed as follows:
+ * 82598: 128 (8 bit wide) entries containing pair of 4 bit RSS indices
+ * 82599/X540: 128 (8 bit wide) entries containing 4 bit RSS index X550:
+ * 512 (8 bit wide) entries containing 6 bit RSS index
+ *
+ * PSRTYPE[n].RQPL defines if 0, 1 or 2 bits from the redirection table
+ * value should be used.
+ */
+
+ if ((psrtype & (1 << 29)) == (1 << 29))
+ mask = 0x01010101;
+ else if ((psrtype & (2 << 29)) == (2 << 29))
+ mask = 0x03030303;
+ else
+ mask = 0;
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ /* Read the appropriate portion of RETA */
+ for (i = 0; i < dwords; i++)
+ reta[i] = IXGBE_READ_REG(hw,
+ IXGBE_RETA(i + reta_offset_dw));
+ break;
+ case ixgbe_mac_X550:
+ case ixgbe_mac_X550EM_x:
+ /* X550 has a per-VF RETA */
+ for (i = 0, j = reta_offset_dw; i < dwords; i++, j++)
+ reta[i] = IXGBE_READ_REG(hw,
+ IXGBE_PFVFRETA(j, vf));
+ break;
+ default:
+ return -1;
+ }
+
+ /* Mask the relevant bits */
+ for (i = 0; i < dwords; i++)
+ reta[i] &= mask;
+
+ return 0;
+}
+
static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
{
u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
@@ -1010,6 +1072,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
case IXGBE_VF_GET_QUEUES:
retval = ixgbe_get_vf_queues(adapter, msgbuf, vf);
break;
+ case IXGBE_VF_GET_RETA:
+ retval = ixgbe_get_vf_reta(adapter, msgbuf, vf);
+ break;
default:
e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
retval = IXGBE_ERR_MBX;
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v8 4/7] ixgbevf: Add a RETA query code
2015-03-25 17:42 [PATCH net-next v8 0/7]: ixgbevf: Allow querying VFs RSS indirection table and key Vlad Zolotarov
` (2 preceding siblings ...)
2015-03-25 17:42 ` [PATCH net-next v8 3/7] ixgbe: Add a RETA query command to VF-PF channel API Vlad Zolotarov
@ 2015-03-25 17:42 ` Vlad Zolotarov
2015-03-25 17:42 ` [PATCH net-next v8 5/7] ixgbe: Add GET_RSS_KEY command to VF-PF channel commands set Vlad Zolotarov
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Vlad Zolotarov @ 2015-03-25 17:42 UTC (permalink / raw)
To: netdev; +Cc: jeffrey.t.kirsher, avi, gleb, intel-wired-lan, Vlad Zolotarov
- Added a new API version support.
- Added the query implementation in the ixgbevf.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
---
New in v8:
- Protect mailbox with a spinlock.
New in v7:
- Add ixgbe_mbox_api_12 case in ixgbevf_set_num_queues().
- Properly expand HW RETA into the ethtool buffer.
New in v6:
- Add a proper return code when an operation is blocked by PF.
New in v3:
- Adjusted to the new interface IXGBE_VF_GET_RETA command.
- Added a proper support for x550 devices.
New in v1 (compared to RFC):
- Use "if-else" statement instead of a "switch-case" for a single option case
(in ixgbevf_get_reta()).
---
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 5 +-
drivers/net/ethernet/intel/ixgbevf/mbx.h | 8 ++
drivers/net/ethernet/intel/ixgbevf/vf.c | 124 ++++++++++++++++++++++
drivers/net/ethernet/intel/ixgbevf/vf.h | 2 +
4 files changed, 138 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 4ee15ad..a16d267 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -2030,7 +2030,8 @@ static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter)
static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- int api[] = { ixgbe_mbox_api_11,
+ int api[] = { ixgbe_mbox_api_12,
+ ixgbe_mbox_api_11,
ixgbe_mbox_api_10,
ixgbe_mbox_api_unknown };
int err = 0, idx = 0;
@@ -2332,6 +2333,7 @@ static void ixgbevf_set_num_queues(struct ixgbevf_adapter *adapter)
switch (hw->api_version) {
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
adapter->num_rx_queues = rss;
adapter->num_tx_queues = rss;
default:
@@ -3712,6 +3714,7 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
switch (adapter->hw.api_version) {
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE;
break;
default:
diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.h b/drivers/net/ethernet/intel/ixgbevf/mbx.h
index 6253e93..7342554 100644
--- a/drivers/net/ethernet/intel/ixgbevf/mbx.h
+++ b/drivers/net/ethernet/intel/ixgbevf/mbx.h
@@ -83,6 +83,7 @@ enum ixgbe_pfvf_api_rev {
ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */
ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */
ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */
+ ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */
/* This value should always be last */
ixgbe_mbox_api_unknown, /* indicates that API version is not known */
};
@@ -107,6 +108,13 @@ enum ixgbe_pfvf_api_rev {
#define IXGBE_VF_TRANS_VLAN 3 /* Indication of port VLAN */
#define IXGBE_VF_DEF_QUEUE 4 /* Default queue offset */
+/* mailbox API, version 1.2 VF requests */
+#define IXGBE_VF_GET_RETA 0x0a /* VF request for RETA */
+
+/* GET_RETA request data indices within the mailbox */
+#define IXGBE_VF_RETA_SZ 1 /* Number of RETA DWs to bring */
+#define IXGBE_VF_RETA_OFFSET 2 /* Offset in RETA */
+
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
/* word in permanent address message with the current multicast type */
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c
index 2614fd3..2e468a6 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.c
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.c
@@ -256,6 +256,129 @@ static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
return ret_val;
}
+static inline int _ixgbevf_get_reta_locked(struct ixgbe_hw *hw, u32 *msgbuf,
+ u32 *reta, u32 reta_offset_dw,
+ u32 dwords)
+{
+ int err, i;
+ u8 *hw_reta = (u8 *)&msgbuf[1];
+
+ msgbuf[0] = IXGBE_VF_GET_RETA;
+ msgbuf[IXGBE_VF_RETA_SZ] = dwords;
+ msgbuf[IXGBE_VF_RETA_OFFSET] = reta_offset_dw;
+
+ err = hw->mbx.ops.write_posted(hw, msgbuf, 3);
+
+ if (err)
+ return err;
+
+ err = hw->mbx.ops.read_posted(hw, msgbuf, 1 + dwords);
+
+ if (err)
+ return err;
+
+ msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
+
+ /* If the operation has been refused by a PF return -EPERM */
+ if (msgbuf[0] == (IXGBE_VF_GET_RETA | IXGBE_VT_MSGTYPE_NACK))
+ return -EPERM;
+
+ /* If we didn't get an ACK there must have been
+ * some sort of mailbox error so we should treat it
+ * as such.
+ */
+ if (msgbuf[0] != (IXGBE_VF_GET_RETA | IXGBE_VT_MSGTYPE_ACK))
+ return IXGBE_ERR_MBX;
+
+ /* HW RETA is an array of u8, while ethtool buffer is an array of u32.
+ * Therefore we need to "expand" the HW RETA into the ethtool buffer.
+ */
+ for (i = 0; i < dwords * 4; i++)
+ reta[reta_offset_dw * 4 + i] = hw_reta[i];
+
+ return 0;
+}
+
+/**
+ * _ixgbevf_get_reta - read a subsection of a VF's RETA table
+ *
+ * @a pointer to a port handle
+ * @msgbuf mailbox buffer to use
+ * @reta ethtool output buffer
+ * @reta_offset_dw HW RETA DWORD index to start from
+ * @dwords number of HW RETA DWORDs to fetch
+ *
+ * This function ensures the atomicy of a mailbox operation using the
+ * adapter.mbx_lock spinlock.
+ */
+static inline int _ixgbevf_get_reta(struct ixgbevf_adapter *a,
+ u32 *msgbuf, u32 *reta, u32 reta_offset_dw,
+ u32 dwords)
+{
+ int rc;
+
+ spin_lock_bh(&a->mbx_lock);
+ rc = _ixgbevf_get_reta_locked(&a->hw, msgbuf, reta, reta_offset_dw,
+ dwords);
+ spin_unlock_bh(&a->mbx_lock);
+
+ return rc;
+}
+
+/**
+ * ixgbevf_get_reta - get the RSS redirection table (RETA) contents.
+ * @adapter: pointer to the port handle
+ * @reta: buffer to fill with RETA contents.
+ *
+ * The "reta" buffer should be big enough to contain 32 registers.
+ *
+ * Returns: 0 on success.
+ * if API doesn't support this operation - (-EPERM).
+ */
+int ixgbevf_get_reta(struct ixgbevf_adapter *adapter, u32 *reta)
+{
+ int err;
+ u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
+
+ /* Return an error if API doesn't RETA querying. */
+ if (adapter->hw.api_version != ixgbe_mbox_api_12)
+ return -EPERM;
+
+ /* x550 devices have a separate RETA for each VF: 64 bytes each.
+ *
+ * We'll get it in 2 steps due to mailbox size limitation - we can bring
+ * up to 15 dwords every time. Therefore we'll bring 12 and 4 dwords.
+ *
+ * Older devices share a RETA table with the PF: 128 bytes.
+ *
+ * For them we do it in 3 steps. Therefore we'll bring it in 3 steps:
+ * 12, 12 and 8 dwords in each step correspondingly.
+ */
+
+ /* RETA[0..11] */
+ err = _ixgbevf_get_reta(adapter, msgbuf, reta, 0, 12);
+ if (err)
+ return err;
+
+ if (adapter->hw.mac.type >= ixgbe_mac_X550_vf) {
+ /* RETA[12..15] */
+ err = _ixgbevf_get_reta(adapter, msgbuf, reta, 12, 4);
+ if (err)
+ return err;
+
+ } else {
+ /* RETA[12..23] */
+ err = _ixgbevf_get_reta(adapter, msgbuf, reta, 12, 12);
+ if (err)
+ return err;
+
+ /* RETA[24..31] */
+ err = _ixgbevf_get_reta(adapter, msgbuf, reta, 24, 8);
+ }
+
+ return err;
+}
+
/**
* ixgbevf_set_rar_vf - set device MAC address
* @hw: pointer to hardware structure
@@ -545,6 +668,7 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
/* do nothing if API doesn't support ixgbevf_get_queues */
switch (hw->api_version) {
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
break;
default:
return 0;
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h
index 6688250..7944962 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.h
@@ -38,6 +38,7 @@
#include "mbx.h"
struct ixgbe_hw;
+struct ixgbevf_adapter;
/* iterator type for walking multicast address lists */
typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
@@ -210,4 +211,5 @@ void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size);
int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api);
int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
unsigned int *default_tc);
+int ixgbevf_get_reta(struct ixgbevf_adapter *adapter, u32 *reta);
#endif /* __IXGBE_VF_H__ */
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v8 5/7] ixgbe: Add GET_RSS_KEY command to VF-PF channel commands set
2015-03-25 17:42 [PATCH net-next v8 0/7]: ixgbevf: Allow querying VFs RSS indirection table and key Vlad Zolotarov
` (3 preceding siblings ...)
2015-03-25 17:42 ` [PATCH net-next v8 4/7] ixgbevf: Add a RETA query code Vlad Zolotarov
@ 2015-03-25 17:42 ` Vlad Zolotarov
2015-03-25 17:42 ` [PATCH net-next v8 6/7] ixgbevf: Add RSS Key query code Vlad Zolotarov
2015-03-25 17:42 ` [PATCH net-next v8 7/7] ixgbevf: Add the appropriate ethtool ops to query RSS indirection table and key Vlad Zolotarov
6 siblings, 0 replies; 8+ messages in thread
From: Vlad Zolotarov @ 2015-03-25 17:42 UTC (permalink / raw)
To: netdev; +Cc: jeffrey.t.kirsher, avi, gleb, intel-wired-lan, Vlad Zolotarov
For 82599 and x540 VFs and PF share the same RSS Key. Therefore we will return
the same RSS key for all VFs.
x550 on the other hand has a separate RSS Key for every pool.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
---
New in v5:
- Use a newly added netdev op to allow/prevent the RSS Hash Key querying on a per-VF
basis.
New in v3:
- Added a support for x550 devices.
New in v1 (compared to RFC):
- Use "if-else" statement instead of a "switch-case" for a single option case
(in ixgbe_get_vf_rss_key()).
---
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h | 2 ++
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 27 ++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
index f9b5eae..3f14373 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
@@ -105,6 +105,8 @@ enum ixgbe_pfvf_api_rev {
#define IXGBE_VF_RETA_SZ 1 /* Number of RETA DWs to bring */
#define IXGBE_VF_RETA_OFFSET 2 /* Offset in RETA */
+#define IXGBE_VF_GET_RSS_KEY 0x0b /* get RSS key */
+
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
/* word in permanent address message with the current multicast type */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 301bb1b..78517a1 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -1016,6 +1016,30 @@ static int ixgbe_get_vf_reta(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
return 0;
}
+static int ixgbe_get_vf_rss_key(struct ixgbe_adapter *adapter,
+ u32 *msgbuf, u32 vf)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+ u32 *rss_key = &msgbuf[1];
+
+ /* verify the PF is supporting the correct API */
+ if (!adapter->vfinfo[vf].rss_query_enabled ||
+ (adapter->vfinfo[vf].vf_api != ixgbe_mbox_api_12))
+ return -EPERM;
+
+ /* Read the RSS KEY */
+ if (hw->mac.type >= ixgbe_mac_X550) {
+ for (i = 0; i < 10; i++)
+ rss_key[i] = IXGBE_READ_REG(hw,
+ IXGBE_PFVFRSSRK(i, vf));
+ } else
+ for (i = 0; i < 10; i++)
+ rss_key[i] = IXGBE_READ_REG(hw, IXGBE_RSSRK(i));
+
+ return 0;
+}
+
static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
{
u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
@@ -1075,6 +1099,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
case IXGBE_VF_GET_RETA:
retval = ixgbe_get_vf_reta(adapter, msgbuf, vf);
break;
+ case IXGBE_VF_GET_RSS_KEY:
+ retval = ixgbe_get_vf_rss_key(adapter, msgbuf, vf);
+ break;
default:
e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
retval = IXGBE_ERR_MBX;
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v8 6/7] ixgbevf: Add RSS Key query code
2015-03-25 17:42 [PATCH net-next v8 0/7]: ixgbevf: Allow querying VFs RSS indirection table and key Vlad Zolotarov
` (4 preceding siblings ...)
2015-03-25 17:42 ` [PATCH net-next v8 5/7] ixgbe: Add GET_RSS_KEY command to VF-PF channel commands set Vlad Zolotarov
@ 2015-03-25 17:42 ` Vlad Zolotarov
2015-03-25 17:42 ` [PATCH net-next v8 7/7] ixgbevf: Add the appropriate ethtool ops to query RSS indirection table and key Vlad Zolotarov
6 siblings, 0 replies; 8+ messages in thread
From: Vlad Zolotarov @ 2015-03-25 17:42 UTC (permalink / raw)
To: netdev; +Cc: jeffrey.t.kirsher, avi, gleb, intel-wired-lan, Vlad Zolotarov
Add the ixgbevf_get_rss_key() function that queries the PF for an RSS Random Key
using a new VF-PF channel IXGBE_VF_GET_RSS_KEY command.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
---
New in v8:
- Protect a mailbox access.
New in v6:
- Return a proper return code when an operation is blocked by PF.
New in v2:
- Added a more detailed patch description.
New in v1 (compared to RFC):
- Use "if-else" statement instead of a "switch-case" for a single option case
(in ixgbevf_get_rss_key()).
---
drivers/net/ethernet/intel/ixgbevf/mbx.h | 2 ++
drivers/net/ethernet/intel/ixgbevf/vf.c | 60 ++++++++++++++++++++++++++++++++
drivers/net/ethernet/intel/ixgbevf/vf.h | 1 +
3 files changed, 63 insertions(+)
diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.h b/drivers/net/ethernet/intel/ixgbevf/mbx.h
index 7342554..923bb0f 100644
--- a/drivers/net/ethernet/intel/ixgbevf/mbx.h
+++ b/drivers/net/ethernet/intel/ixgbevf/mbx.h
@@ -115,6 +115,8 @@ enum ixgbe_pfvf_api_rev {
#define IXGBE_VF_RETA_SZ 1 /* Number of RETA DWs to bring */
#define IXGBE_VF_RETA_OFFSET 2 /* Offset in RETA */
+#define IXGBE_VF_GET_RSS_KEY 0x0b /* get RSS hash key */
+
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
/* word in permanent address message with the current multicast type */
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c
index 2e468a6..4ca0304 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.c
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.c
@@ -325,6 +325,66 @@ static inline int _ixgbevf_get_reta(struct ixgbevf_adapter *a,
return rc;
}
+static inline int ixgbevf_get_rss_key_locked(struct ixgbe_hw *hw, u8 *rss_key)
+{
+ int err;
+ u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
+
+ /* Return and error if API doesn't support RSS Random Key retrieval */
+ if (hw->api_version != ixgbe_mbox_api_12)
+ return -EPERM;
+
+ msgbuf[0] = IXGBE_VF_GET_RSS_KEY;
+ err = hw->mbx.ops.write_posted(hw, msgbuf, 1);
+
+ if (err)
+ return err;
+
+ err = hw->mbx.ops.read_posted(hw, msgbuf, 11);
+
+ if (err)
+ return err;
+
+ msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
+
+ /* If the operation has been refused by a PF return -EPERM */
+ if (msgbuf[0] == (IXGBE_VF_GET_RETA | IXGBE_VT_MSGTYPE_NACK))
+ return -EPERM;
+
+ /* If we didn't get an ACK there must have been
+ * some sort of mailbox error so we should treat it
+ * as such.
+ */
+ if (msgbuf[0] != (IXGBE_VF_GET_RSS_KEY | IXGBE_VT_MSGTYPE_ACK))
+ return IXGBE_ERR_MBX;
+
+ memcpy(rss_key, msgbuf + 1, 40);
+
+ return 0;
+}
+
+/**
+ * ixgbevf_get_rss_key - get the RSS Random Key
+ * @hw: pointer to the HW structure
+ * @reta: buffer to fill with RETA contents.
+ *
+ * The "rss_key" buffer should be big enough to contain 10 registers.
+ * Ensures the atomicy of a mailbox access using the adapter.mbx_lock spinlock.
+ *
+ * Returns: 0 on success.
+ * if API doesn't support this operation - (-EPERM).
+ */
+int ixgbevf_get_rss_key(struct ixgbevf_adapter *a, u8 *rss_key)
+{
+ int rc;
+
+ spin_lock_bh(&a->mbx_lock);
+ rc = ixgbevf_get_rss_key_locked(&a->hw, rss_key);
+ spin_unlock_bh(&a->mbx_lock);
+
+ return rc;
+}
+
/**
* ixgbevf_get_reta - get the RSS redirection table (RETA) contents.
* @adapter: pointer to the port handle
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h
index 7944962..a054716 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.h
@@ -212,4 +212,5 @@ int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api);
int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
unsigned int *default_tc);
int ixgbevf_get_reta(struct ixgbevf_adapter *adapter, u32 *reta);
+int ixgbevf_get_rss_key(struct ixgbevf_adapter *adapter, u8 *rss_key);
#endif /* __IXGBE_VF_H__ */
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next v8 7/7] ixgbevf: Add the appropriate ethtool ops to query RSS indirection table and key
2015-03-25 17:42 [PATCH net-next v8 0/7]: ixgbevf: Allow querying VFs RSS indirection table and key Vlad Zolotarov
` (5 preceding siblings ...)
2015-03-25 17:42 ` [PATCH net-next v8 6/7] ixgbevf: Add RSS Key query code Vlad Zolotarov
@ 2015-03-25 17:42 ` Vlad Zolotarov
6 siblings, 0 replies; 8+ messages in thread
From: Vlad Zolotarov @ 2015-03-25 17:42 UTC (permalink / raw)
To: netdev; +Cc: jeffrey.t.kirsher, avi, gleb, intel-wired-lan, Vlad Zolotarov
Added get_rxfh_indir_size, get_rxfh_key_size and get_rxfh ethtool_ops callbacks
implementations.
This enables the ethtool's "-x" and "--show-rxfh[-indir]" options for VF devices.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
---
New in v6:
- Added a required get_rxnfc callback to ixgbevf_ethtool_ops.
New in v4:
- Removed not needed braces in if-statement in ixgbevf_get_rxfh_indir_size().
New in v3:
- Added a proper support for x550 devices: return the correct redirection table size.
New in v2:
- Added a detailed description to the patch.
---
drivers/net/ethernet/intel/ixgbevf/ethtool.c | 58 ++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
index e83c85b..7cb4008 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
@@ -794,6 +794,60 @@ static int ixgbevf_set_coalesce(struct net_device *netdev,
return 0;
}
+static int ixgbevf_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
+ u32 *rules __always_unused)
+{
+ struct ixgbevf_adapter *adapter = netdev_priv(dev);
+
+ switch (info->cmd) {
+ case ETHTOOL_GRXRINGS:
+ info->data = adapter->num_rx_queues;
+ return 0;
+ default:
+ hw_dbg(&adapter->hw, "Command parameters not supported\n");
+ return -EOPNOTSUPP;
+ }
+}
+
+static u32 ixgbevf_get_rxfh_indir_size(struct net_device *netdev)
+{
+ struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+
+ if (adapter->hw.mac.type >= ixgbe_mac_X550_vf)
+ return 64;
+ else
+ return 128;
+}
+
+static u32 ixgbevf_get_rxfh_key_size(struct net_device *netdev)
+{
+ return 40;
+}
+
+static int ixgbevf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
+ u8 *hfunc)
+{
+ struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+ int err;
+
+ if (hfunc)
+ *hfunc = ETH_RSS_HASH_TOP;
+
+ if (indir) {
+ err = ixgbevf_get_reta(adapter, indir);
+ if (err)
+ return err;
+ }
+
+ if (key) {
+ err = ixgbevf_get_rss_key(adapter, key);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static const struct ethtool_ops ixgbevf_ethtool_ops = {
.get_settings = ixgbevf_get_settings,
.get_drvinfo = ixgbevf_get_drvinfo,
@@ -811,6 +865,10 @@ static const struct ethtool_ops ixgbevf_ethtool_ops = {
.get_ethtool_stats = ixgbevf_get_ethtool_stats,
.get_coalesce = ixgbevf_get_coalesce,
.set_coalesce = ixgbevf_set_coalesce,
+ .get_rxnfc = ixgbevf_get_rxnfc,
+ .get_rxfh_indir_size = ixgbevf_get_rxfh_indir_size,
+ .get_rxfh_key_size = ixgbevf_get_rxfh_key_size,
+ .get_rxfh = ixgbevf_get_rxfh,
};
void ixgbevf_set_ethtool_ops(struct net_device *netdev)
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread