* [PATCH net-next] liquidio: Added support for trusted VF
@ 2018-03-16 22:40 Felix Manlunas
2018-03-16 22:47 ` Eric Dumazet
0 siblings, 1 reply; 2+ messages in thread
From: Felix Manlunas @ 2018-03-16 22:40 UTC (permalink / raw)
To: davem
Cc: netdev, raghu.vatsavayi, derek.chickles, satananda.burla,
intiyaz.basha, felix.manlunas
From: Intiyaz Basha <intiyaz.basha@cavium.com>
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>
Acked-by: Satanand Burla <satananda.burla@cavium.com>
Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
---
drivers/net/ethernet/cavium/liquidio/lio_main.c | 125 +++++++++++++++++++++
.../net/ethernet/cavium/liquidio/liquidio_common.h | 7 ++
.../net/ethernet/cavium/liquidio/octeon_device.h | 2 +
3 files changed, 134 insertions(+)
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 140085b..c14b87a 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -91,6 +91,12 @@ static int octeon_console_debug_enabled(u32 console)
*/
#define LIO_SYNC_OCTEON_TIME_INTERVAL_MS 60000
+struct lio_trusted_vf_ctx {
+ wait_queue_head_t wc;
+ int cond;
+ int status;
+};
+
struct liquidio_rx_ctl_context {
int octeon_id;
@@ -3265,10 +3271,128 @@ 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;
+ WRITE_ONCE(ctx->cond, 1);
+
+ /* This barrier is required to be sure that the response has
+ * been written fully before waking up the handler
+ */
+ wmb();
+
+ wake_up_interruptible(&ctx->wc);
+}
+
+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;
+ WRITE_ONCE(ctx->cond, 0);
+ init_waitqueue_head(&ctx->wc);
+
+ 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 {
+ /* Sleep on a wait queue till the cond flag indicates that the
+ * response arrived or timed-out.
+ */
+ if (sleep_cond(&ctx->wc, &ctx->cond) == -EINTR)
+ return -1;
+
+ retval = ctx->status;
+ }
+
+ 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 +3523,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,
};
diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
index ecc1682..82a783d 100644
--- a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
+++ b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
@@ -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 */
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
index 63b0c75..91937cc 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
@@ -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];
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH net-next] liquidio: Added support for trusted VF
2018-03-16 22:40 [PATCH net-next] liquidio: Added support for trusted VF Felix Manlunas
@ 2018-03-16 22:47 ` Eric Dumazet
0 siblings, 0 replies; 2+ messages in thread
From: Eric Dumazet @ 2018-03-16 22:47 UTC (permalink / raw)
To: Felix Manlunas, davem
Cc: netdev, raghu.vatsavayi, derek.chickles, satananda.burla, intiyaz.basha
On 03/16/2018 03:40 PM, Felix Manlunas wrote:
> From: Intiyaz Basha <intiyaz.basha@cavium.com>
>
> 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>
> Acked-by: Satanand Burla <satananda.burla@cavium.com>
> Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
> ---
> drivers/net/ethernet/cavium/liquidio/lio_main.c | 125 +++++++++++++++++++++
> .../net/ethernet/cavium/liquidio/liquidio_common.h | 7 ++
> .../net/ethernet/cavium/liquidio/octeon_device.h | 2 +
> 3 files changed, 134 insertions(+)
>
> diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
> index 140085b..c14b87a 100644
> --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
> +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
> @@ -91,6 +91,12 @@ static int octeon_console_debug_enabled(u32 console)
> */
> #define LIO_SYNC_OCTEON_TIME_INTERVAL_MS 60000
>
> +struct lio_trusted_vf_ctx {
> + wait_queue_head_t wc;
> + int cond;
> + int status;
> +};
> +
> struct liquidio_rx_ctl_context {
> int octeon_id;
>
> @@ -3265,10 +3271,128 @@ 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;
> + WRITE_ONCE(ctx->cond, 1);
> +
> + /* This barrier is required to be sure that the response has
> + * been written fully before waking up the handler
> + */
> + wmb();
> +
> + wake_up_interruptible(&ctx->wc);
> +}
Hmmm... it looks like you tried to reimplement completions, possibly dealing with barriers...
Check complete(), init_completion(), wait_for_completion()
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-03-16 22:47 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-16 22:40 [PATCH net-next] liquidio: Added support for trusted VF Felix Manlunas
2018-03-16 22:47 ` Eric Dumazet
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.