aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c')
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c95
1 files changed, 91 insertions, 4 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 7f37fe7269a7..1d17b5872dd1 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -36,6 +36,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/ipv6.h>
+#include <linux/if_bridge.h>
#ifdef NETIF_F_HW_VLAN_CTAG_TX
#include <linux/if_vlan.h>
#endif
@@ -79,7 +80,7 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
/* Initialize default switching mode VEB */
IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
- adapter->flags2 |= IXGBE_FLAG2_BRIDGE_MODE_VEB;
+ adapter->bridge_mode = BRIDGE_MODE_VEB;
/* If call to enable VFs succeeded then allocate memory
* for per VF control structures.
@@ -105,9 +106,18 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
adapter->flags2 &= ~(IXGBE_FLAG2_RSC_CAPABLE |
IXGBE_FLAG2_RSC_ENABLED);
- /* enable spoof checking for all VFs */
- for (i = 0; i < adapter->num_vfs; i++)
+ for (i = 0; i < adapter->num_vfs; i++) {
+ /* enable spoof checking for all VFs */
adapter->vfinfo[i].spoofchk_enabled = true;
+
+ /* We support VF RSS querying only for 82599 and x540
+ * devices at the moment. These devices share RSS
+ * indirection table and RSS hash key with PF therefore
+ * we want to disable the querying by default.
+ */
+ adapter->vfinfo[i].rss_query_enabled = 0;
+ }
+
return 0;
}
@@ -141,7 +151,7 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
* The 82599 supports up to 64 VFs per physical function
* but this implementation limits allocation to 63 so that
* basic networking resources are still available to the
- * physical function. If the user requests greater thn
+ * physical function. If the user requests greater than
* 63 VFs then it is an error - reset to default of zero.
*/
adapter->num_vfs = min_t(unsigned int, adapter->num_vfs, IXGBE_MAX_VFS_DRV_LIMIT);
@@ -424,6 +434,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
@@ -891,6 +902,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:
@@ -914,6 +926,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;
@@ -941,6 +954,53 @@ 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)
+{
+ u32 i, j;
+ u32 *out_buf = &msgbuf[1];
+ const u8 *reta = adapter->rss_indir_tbl;
+ u32 reta_size = ixgbe_rss_indir_tbl_entries(adapter);
+
+ /* Check if operation is permitted */
+ if (!adapter->vfinfo[vf].rss_query_enabled)
+ return -EPERM;
+
+ /* verify the PF is supporting the correct API */
+ if (adapter->vfinfo[vf].vf_api != ixgbe_mbox_api_12)
+ return -EOPNOTSUPP;
+
+ /* This mailbox command is supported (required) only for 82599 and x540
+ * VFs which support up to 4 RSS queues. Therefore we will compress the
+ * RETA by saving only 2 bits from each entry. This way we will be able
+ * to transfer the whole RETA in a single mailbox operation.
+ */
+ for (i = 0; i < reta_size / 16; i++) {
+ out_buf[i] = 0;
+ for (j = 0; j < 16; j++)
+ out_buf[i] |= (u32)(reta[16 * i + j] & 0x3) << (2 * j);
+ }
+
+ return 0;
+}
+
+static int ixgbe_get_vf_rss_key(struct ixgbe_adapter *adapter,
+ u32 *msgbuf, u32 vf)
+{
+ u32 *rss_key = &msgbuf[1];
+
+ /* Check if the operation is permitted */
+ if (!adapter->vfinfo[vf].rss_query_enabled)
+ return -EPERM;
+
+ /* verify the PF is supporting the correct API */
+ if (adapter->vfinfo[vf].vf_api != ixgbe_mbox_api_12)
+ return -EOPNOTSUPP;
+
+ memcpy(rss_key, adapter->rss_key, sizeof(adapter->rss_key));
+
+ return 0;
+}
+
static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
{
u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
@@ -997,6 +1057,12 @@ 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;
+ 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;
@@ -1330,6 +1396,26 @@ 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);
+
+ /* This operation is currently supported only for 82599 and x540
+ * devices.
+ */
+ if (adapter->hw.mac.type < ixgbe_mac_82599EB ||
+ adapter->hw.mac.type >= ixgbe_mac_X550)
+ return -EOPNOTSUPP;
+
+ 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 +1429,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;
}