]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
liquidio: Added support for trusted VF
authorIntiyaz Basha <intiyaz.basha@cavium.com>
Thu, 22 Mar 2018 06:30:54 +0000 (23:30 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 22 Mar 2018 19:04:10 +0000 (15:04 -0400)
When a VF is trusted, all promiscuous traffic will only be sent to that VF.
In normal operation promiscuous traffic is sent to the PF. There can be
only one trusted VF per PF

Signed-off-by: Intiyaz Basha <intiyaz.basha@cavium.com>
Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/cavium/liquidio/lio_main.c
drivers/net/ethernet/cavium/liquidio/liquidio_common.h
drivers/net/ethernet/cavium/liquidio/octeon_device.h

index 140085ba48cd4cdc0374756831fc07b31de40108..21280cb66550337159f2b536ad5fad8c82bc1d11 100644 (file)
@@ -91,6 +91,11 @@ static int octeon_console_debug_enabled(u32 console)
  */
 #define LIO_SYNC_OCTEON_TIME_INTERVAL_MS 60000
 
+struct lio_trusted_vf_ctx {
+       struct completion complete;
+       int status;
+};
+
 struct liquidio_rx_ctl_context {
        int octeon_id;
 
@@ -3265,10 +3270,120 @@ static int liquidio_get_vf_config(struct net_device *netdev, int vfidx,
        ether_addr_copy(&ivi->mac[0], macaddr);
        ivi->vlan = oct->sriov_info.vf_vlantci[vfidx] & VLAN_VID_MASK;
        ivi->qos = oct->sriov_info.vf_vlantci[vfidx] >> VLAN_PRIO_SHIFT;
+       if (oct->sriov_info.trusted_vf.active &&
+           oct->sriov_info.trusted_vf.id == vfidx)
+               ivi->trusted = true;
+       else
+               ivi->trusted = false;
        ivi->linkstate = oct->sriov_info.vf_linkstate[vfidx];
        return 0;
 }
 
+static void trusted_vf_callback(struct octeon_device *oct_dev,
+                               u32 status, void *ptr)
+{
+       struct octeon_soft_command *sc = (struct octeon_soft_command *)ptr;
+       struct lio_trusted_vf_ctx *ctx;
+
+       ctx = (struct lio_trusted_vf_ctx *)sc->ctxptr;
+       ctx->status = status;
+
+       complete(&ctx->complete);
+}
+
+static int liquidio_send_vf_trust_cmd(struct lio *lio, int vfidx, bool trusted)
+{
+       struct octeon_device *oct = lio->oct_dev;
+       struct lio_trusted_vf_ctx *ctx;
+       struct octeon_soft_command *sc;
+       int ctx_size, retval;
+
+       ctx_size = sizeof(struct lio_trusted_vf_ctx);
+       sc = octeon_alloc_soft_command(oct, 0, 0, ctx_size);
+
+       ctx  = (struct lio_trusted_vf_ctx *)sc->ctxptr;
+       init_completion(&ctx->complete);
+
+       sc->iq_no = lio->linfo.txpciq[0].s.q_no;
+
+       /* vfidx is 0 based, but vf_num (param1) is 1 based */
+       octeon_prepare_soft_command(oct, sc, OPCODE_NIC,
+                                   OPCODE_NIC_SET_TRUSTED_VF, 0, vfidx + 1,
+                                   trusted);
+
+       sc->callback = trusted_vf_callback;
+       sc->callback_arg = sc;
+       sc->wait_time = 1000;
+
+       retval = octeon_send_soft_command(oct, sc);
+       if (retval == IQ_SEND_FAILED) {
+               retval = -1;
+       } else {
+               /* Wait for response or timeout */
+               if (wait_for_completion_timeout(&ctx->complete,
+                                               msecs_to_jiffies(2000)))
+                       retval = ctx->status;
+               else
+                       retval = -1;
+       }
+
+       octeon_free_soft_command(oct, sc);
+
+       return retval;
+}
+
+static int liquidio_set_vf_trust(struct net_device *netdev, int vfidx,
+                                bool setting)
+{
+       struct lio *lio = GET_LIO(netdev);
+       struct octeon_device *oct = lio->oct_dev;
+
+       if (strcmp(oct->fw_info.liquidio_firmware_version, "1.7.1") < 0) {
+               /* trusted vf is not supported by firmware older than 1.7.1 */
+               return -EOPNOTSUPP;
+       }
+
+       if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced) {
+               netif_info(lio, drv, lio->netdev, "Invalid vfidx %d\n", vfidx);
+               return -EINVAL;
+       }
+
+       if (setting) {
+               /* Set */
+
+               if (oct->sriov_info.trusted_vf.active &&
+                   oct->sriov_info.trusted_vf.id == vfidx)
+                       return 0;
+
+               if (oct->sriov_info.trusted_vf.active) {
+                       netif_info(lio, drv, lio->netdev, "More than one trusted VF is not allowed\n");
+                       return -EPERM;
+               }
+       } else {
+               /* Clear */
+
+               if (!oct->sriov_info.trusted_vf.active)
+                       return 0;
+       }
+
+       if (!liquidio_send_vf_trust_cmd(lio, vfidx, setting)) {
+               if (setting) {
+                       oct->sriov_info.trusted_vf.id = vfidx;
+                       oct->sriov_info.trusted_vf.active = true;
+               } else {
+                       oct->sriov_info.trusted_vf.active = false;
+               }
+
+               netif_info(lio, drv, lio->netdev, "VF %u is %strusted\n", vfidx,
+                          setting ? "" : "not ");
+       } else {
+               netif_info(lio, drv, lio->netdev, "Failed to set VF trusted\n");
+               return -1;
+       }
+
+       return 0;
+}
+
 static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx,
                                      int linkstate)
 {
@@ -3399,6 +3514,7 @@ static const struct net_device_ops lionetdevops = {
        .ndo_set_vf_mac         = liquidio_set_vf_mac,
        .ndo_set_vf_vlan        = liquidio_set_vf_vlan,
        .ndo_get_vf_config      = liquidio_get_vf_config,
+       .ndo_set_vf_trust       = liquidio_set_vf_trust,
        .ndo_set_vf_link_state  = liquidio_set_vf_link_state,
 };
 
index ecc16824fc1b8c225d89c43154169bcb9620f706..82a783db5baf86decdc76aaa9c39d95b718f16d4 100644 (file)
@@ -84,6 +84,7 @@ enum octeon_tag_type {
 #define OPCODE_NIC_IF_CFG              0x09
 #define OPCODE_NIC_VF_DRV_NOTICE       0x0A
 #define OPCODE_NIC_INTRMOD_PARAMS      0x0B
+#define OPCODE_NIC_SET_TRUSTED_VF      0x13
 #define OPCODE_NIC_SYNC_OCTEON_TIME    0x14
 #define VF_DRV_LOADED                  1
 #define VF_DRV_REMOVED                -1
@@ -918,6 +919,12 @@ union oct_nic_if_cfg {
        } s;
 };
 
+struct lio_trusted_vf {
+       uint64_t active: 1;
+       uint64_t id : 8;
+       uint64_t reserved: 55;
+};
+
 struct lio_time {
        s64 sec;   /* seconds */
        s64 nsec;  /* nanoseconds */
index 63b0c758a0a68f6a481a5e6f3d77bb2eddff8ff3..91937cc5c1d7447021057dec9e1e7b4c709b1684 100644 (file)
@@ -370,6 +370,8 @@ struct octeon_sriov_info {
 
        u32     sriov_enabled;
 
+       struct lio_trusted_vf   trusted_vf;
+
        /*lookup table that maps DPI ring number to VF pci_dev struct pointer*/
        struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS];