aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIntiyaz Basha <intiyaz.basha@cavium.com>2018-03-22 02:30:54 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-22 15:04:10 -0400
commitf2d254fac13cc7c86871ea607c4ab1afa7f13e2e (patch)
tree9e177becf4cfebe29909b88efee308b07adbacbe
parentcf57d49c48034cb3d7eb03e813f079ceb16f1e72 (diff)
liquidio: Added support for trusted VF
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>
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_main.c116
-rw-r--r--drivers/net/ethernet/cavium/liquidio/liquidio_common.h7
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_device.h2
3 files changed, 125 insertions, 0 deletions
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 140085ba48cd..21280cb66550 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -91,6 +91,11 @@ static int octeon_console_debug_enabled(u32 console)
91 */ 91 */
92#define LIO_SYNC_OCTEON_TIME_INTERVAL_MS 60000 92#define LIO_SYNC_OCTEON_TIME_INTERVAL_MS 60000
93 93
94struct lio_trusted_vf_ctx {
95 struct completion complete;
96 int status;
97};
98
94struct liquidio_rx_ctl_context { 99struct liquidio_rx_ctl_context {
95 int octeon_id; 100 int octeon_id;
96 101
@@ -3265,10 +3270,120 @@ static int liquidio_get_vf_config(struct net_device *netdev, int vfidx,
3265 ether_addr_copy(&ivi->mac[0], macaddr); 3270 ether_addr_copy(&ivi->mac[0], macaddr);
3266 ivi->vlan = oct->sriov_info.vf_vlantci[vfidx] & VLAN_VID_MASK; 3271 ivi->vlan = oct->sriov_info.vf_vlantci[vfidx] & VLAN_VID_MASK;
3267 ivi->qos = oct->sriov_info.vf_vlantci[vfidx] >> VLAN_PRIO_SHIFT; 3272 ivi->qos = oct->sriov_info.vf_vlantci[vfidx] >> VLAN_PRIO_SHIFT;
3273 if (oct->sriov_info.trusted_vf.active &&
3274 oct->sriov_info.trusted_vf.id == vfidx)
3275 ivi->trusted = true;
3276 else
3277 ivi->trusted = false;
3268 ivi->linkstate = oct->sriov_info.vf_linkstate[vfidx]; 3278 ivi->linkstate = oct->sriov_info.vf_linkstate[vfidx];
3269 return 0; 3279 return 0;
3270} 3280}
3271 3281
3282static void trusted_vf_callback(struct octeon_device *oct_dev,
3283 u32 status, void *ptr)
3284{
3285 struct octeon_soft_command *sc = (struct octeon_soft_command *)ptr;
3286 struct lio_trusted_vf_ctx *ctx;
3287
3288 ctx = (struct lio_trusted_vf_ctx *)sc->ctxptr;
3289 ctx->status = status;
3290
3291 complete(&ctx->complete);
3292}
3293
3294static int liquidio_send_vf_trust_cmd(struct lio *lio, int vfidx, bool trusted)
3295{
3296 struct octeon_device *oct = lio->oct_dev;
3297 struct lio_trusted_vf_ctx *ctx;
3298 struct octeon_soft_command *sc;
3299 int ctx_size, retval;
3300
3301 ctx_size = sizeof(struct lio_trusted_vf_ctx);
3302 sc = octeon_alloc_soft_command(oct, 0, 0, ctx_size);
3303
3304 ctx = (struct lio_trusted_vf_ctx *)sc->ctxptr;
3305 init_completion(&ctx->complete);
3306
3307 sc->iq_no = lio->linfo.txpciq[0].s.q_no;
3308
3309 /* vfidx is 0 based, but vf_num (param1) is 1 based */
3310 octeon_prepare_soft_command(oct, sc, OPCODE_NIC,
3311 OPCODE_NIC_SET_TRUSTED_VF, 0, vfidx + 1,
3312 trusted);
3313
3314 sc->callback = trusted_vf_callback;
3315 sc->callback_arg = sc;
3316 sc->wait_time = 1000;
3317
3318 retval = octeon_send_soft_command(oct, sc);
3319 if (retval == IQ_SEND_FAILED) {
3320 retval = -1;
3321 } else {
3322 /* Wait for response or timeout */
3323 if (wait_for_completion_timeout(&ctx->complete,
3324 msecs_to_jiffies(2000)))
3325 retval = ctx->status;
3326 else
3327 retval = -1;
3328 }
3329
3330 octeon_free_soft_command(oct, sc);
3331
3332 return retval;
3333}
3334
3335static int liquidio_set_vf_trust(struct net_device *netdev, int vfidx,
3336 bool setting)
3337{
3338 struct lio *lio = GET_LIO(netdev);
3339 struct octeon_device *oct = lio->oct_dev;
3340
3341 if (strcmp(oct->fw_info.liquidio_firmware_version, "1.7.1") < 0) {
3342 /* trusted vf is not supported by firmware older than 1.7.1 */
3343 return -EOPNOTSUPP;
3344 }
3345
3346 if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced) {
3347 netif_info(lio, drv, lio->netdev, "Invalid vfidx %d\n", vfidx);
3348 return -EINVAL;
3349 }
3350
3351 if (setting) {
3352 /* Set */
3353
3354 if (oct->sriov_info.trusted_vf.active &&
3355 oct->sriov_info.trusted_vf.id == vfidx)
3356 return 0;
3357
3358 if (oct->sriov_info.trusted_vf.active) {
3359 netif_info(lio, drv, lio->netdev, "More than one trusted VF is not allowed\n");
3360 return -EPERM;
3361 }
3362 } else {
3363 /* Clear */
3364
3365 if (!oct->sriov_info.trusted_vf.active)
3366 return 0;
3367 }
3368
3369 if (!liquidio_send_vf_trust_cmd(lio, vfidx, setting)) {
3370 if (setting) {
3371 oct->sriov_info.trusted_vf.id = vfidx;
3372 oct->sriov_info.trusted_vf.active = true;
3373 } else {
3374 oct->sriov_info.trusted_vf.active = false;
3375 }
3376
3377 netif_info(lio, drv, lio->netdev, "VF %u is %strusted\n", vfidx,
3378 setting ? "" : "not ");
3379 } else {
3380 netif_info(lio, drv, lio->netdev, "Failed to set VF trusted\n");
3381 return -1;
3382 }
3383
3384 return 0;
3385}
3386
3272static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx, 3387static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx,
3273 int linkstate) 3388 int linkstate)
3274{ 3389{
@@ -3399,6 +3514,7 @@ static const struct net_device_ops lionetdevops = {
3399 .ndo_set_vf_mac = liquidio_set_vf_mac, 3514 .ndo_set_vf_mac = liquidio_set_vf_mac,
3400 .ndo_set_vf_vlan = liquidio_set_vf_vlan, 3515 .ndo_set_vf_vlan = liquidio_set_vf_vlan,
3401 .ndo_get_vf_config = liquidio_get_vf_config, 3516 .ndo_get_vf_config = liquidio_get_vf_config,
3517 .ndo_set_vf_trust = liquidio_set_vf_trust,
3402 .ndo_set_vf_link_state = liquidio_set_vf_link_state, 3518 .ndo_set_vf_link_state = liquidio_set_vf_link_state,
3403}; 3519};
3404 3520
diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h
index ecc16824fc1b..82a783db5baf 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 {
84#define OPCODE_NIC_IF_CFG 0x09 84#define OPCODE_NIC_IF_CFG 0x09
85#define OPCODE_NIC_VF_DRV_NOTICE 0x0A 85#define OPCODE_NIC_VF_DRV_NOTICE 0x0A
86#define OPCODE_NIC_INTRMOD_PARAMS 0x0B 86#define OPCODE_NIC_INTRMOD_PARAMS 0x0B
87#define OPCODE_NIC_SET_TRUSTED_VF 0x13
87#define OPCODE_NIC_SYNC_OCTEON_TIME 0x14 88#define OPCODE_NIC_SYNC_OCTEON_TIME 0x14
88#define VF_DRV_LOADED 1 89#define VF_DRV_LOADED 1
89#define VF_DRV_REMOVED -1 90#define VF_DRV_REMOVED -1
@@ -918,6 +919,12 @@ union oct_nic_if_cfg {
918 } s; 919 } s;
919}; 920};
920 921
922struct lio_trusted_vf {
923 uint64_t active: 1;
924 uint64_t id : 8;
925 uint64_t reserved: 55;
926};
927
921struct lio_time { 928struct lio_time {
922 s64 sec; /* seconds */ 929 s64 sec; /* seconds */
923 s64 nsec; /* nanoseconds */ 930 s64 nsec; /* nanoseconds */
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
index 63b0c758a0a6..91937cc5c1d7 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 {
370 370
371 u32 sriov_enabled; 371 u32 sriov_enabled;
372 372
373 struct lio_trusted_vf trusted_vf;
374
373 /*lookup table that maps DPI ring number to VF pci_dev struct pointer*/ 375 /*lookup table that maps DPI ring number to VF pci_dev struct pointer*/
374 struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS]; 376 struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS];
375 377