diff options
author | Intiyaz Basha <intiyaz.basha@cavium.com> | 2018-03-22 02:30:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-22 15:04:10 -0400 |
commit | f2d254fac13cc7c86871ea607c4ab1afa7f13e2e (patch) | |
tree | 9e177becf4cfebe29909b88efee308b07adbacbe | |
parent | cf57d49c48034cb3d7eb03e813f079ceb16f1e72 (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.c | 116 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/liquidio_common.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/octeon_device.h | 2 |
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 | ||
94 | struct lio_trusted_vf_ctx { | ||
95 | struct completion complete; | ||
96 | int status; | ||
97 | }; | ||
98 | |||
94 | struct liquidio_rx_ctl_context { | 99 | struct 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 | ||
3282 | static 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 | |||
3294 | static 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 | |||
3335 | static 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 | |||
3272 | static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx, | 3387 | static 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 | ||
922 | struct lio_trusted_vf { | ||
923 | uint64_t active: 1; | ||
924 | uint64_t id : 8; | ||
925 | uint64_t reserved: 55; | ||
926 | }; | ||
927 | |||
921 | struct lio_time { | 928 | struct 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 | ||