Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Intiyaz Basha and committed by
David S. Miller
f2d254fa cf57d49c

+125
+116
drivers/net/ethernet/cavium/liquidio/lio_main.c
··· 91 91 */ 92 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 99 struct liquidio_rx_ctl_context { 95 100 int octeon_id; 96 101 ··· 3270 3265 ether_addr_copy(&ivi->mac[0], macaddr); 3271 3266 ivi->vlan = oct->sriov_info.vf_vlantci[vfidx] & VLAN_VID_MASK; 3272 3267 ivi->qos = oct->sriov_info.vf_vlantci[vfidx] >> VLAN_PRIO_SHIFT; 3268 + if (oct->sriov_info.trusted_vf.active && 3269 + oct->sriov_info.trusted_vf.id == vfidx) 3270 + ivi->trusted = true; 3271 + else 3272 + ivi->trusted = false; 3273 3273 ivi->linkstate = oct->sriov_info.vf_linkstate[vfidx]; 3274 + return 0; 3275 + } 3276 + 3277 + static void trusted_vf_callback(struct octeon_device *oct_dev, 3278 + u32 status, void *ptr) 3279 + { 3280 + struct octeon_soft_command *sc = (struct octeon_soft_command *)ptr; 3281 + struct lio_trusted_vf_ctx *ctx; 3282 + 3283 + ctx = (struct lio_trusted_vf_ctx *)sc->ctxptr; 3284 + ctx->status = status; 3285 + 3286 + complete(&ctx->complete); 3287 + } 3288 + 3289 + static int liquidio_send_vf_trust_cmd(struct lio *lio, int vfidx, bool trusted) 3290 + { 3291 + struct octeon_device *oct = lio->oct_dev; 3292 + struct lio_trusted_vf_ctx *ctx; 3293 + struct octeon_soft_command *sc; 3294 + int ctx_size, retval; 3295 + 3296 + ctx_size = sizeof(struct lio_trusted_vf_ctx); 3297 + sc = octeon_alloc_soft_command(oct, 0, 0, ctx_size); 3298 + 3299 + ctx = (struct lio_trusted_vf_ctx *)sc->ctxptr; 3300 + init_completion(&ctx->complete); 3301 + 3302 + sc->iq_no = lio->linfo.txpciq[0].s.q_no; 3303 + 3304 + /* vfidx is 0 based, but vf_num (param1) is 1 based */ 3305 + octeon_prepare_soft_command(oct, sc, OPCODE_NIC, 3306 + OPCODE_NIC_SET_TRUSTED_VF, 0, vfidx + 1, 3307 + trusted); 3308 + 3309 + sc->callback = trusted_vf_callback; 3310 + sc->callback_arg = sc; 3311 + sc->wait_time = 1000; 3312 + 3313 + retval = octeon_send_soft_command(oct, sc); 3314 + if (retval == IQ_SEND_FAILED) { 3315 + retval = -1; 3316 + } else { 3317 + /* Wait for response or timeout */ 3318 + if (wait_for_completion_timeout(&ctx->complete, 3319 + msecs_to_jiffies(2000))) 3320 + retval = ctx->status; 3321 + else 3322 + retval = -1; 3323 + } 3324 + 3325 + octeon_free_soft_command(oct, sc); 3326 + 3327 + return retval; 3328 + } 3329 + 3330 + static int liquidio_set_vf_trust(struct net_device *netdev, int vfidx, 3331 + bool setting) 3332 + { 3333 + struct lio *lio = GET_LIO(netdev); 3334 + struct octeon_device *oct = lio->oct_dev; 3335 + 3336 + if (strcmp(oct->fw_info.liquidio_firmware_version, "1.7.1") < 0) { 3337 + /* trusted vf is not supported by firmware older than 1.7.1 */ 3338 + return -EOPNOTSUPP; 3339 + } 3340 + 3341 + if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced) { 3342 + netif_info(lio, drv, lio->netdev, "Invalid vfidx %d\n", vfidx); 3343 + return -EINVAL; 3344 + } 3345 + 3346 + if (setting) { 3347 + /* Set */ 3348 + 3349 + if (oct->sriov_info.trusted_vf.active && 3350 + oct->sriov_info.trusted_vf.id == vfidx) 3351 + return 0; 3352 + 3353 + if (oct->sriov_info.trusted_vf.active) { 3354 + netif_info(lio, drv, lio->netdev, "More than one trusted VF is not allowed\n"); 3355 + return -EPERM; 3356 + } 3357 + } else { 3358 + /* Clear */ 3359 + 3360 + if (!oct->sriov_info.trusted_vf.active) 3361 + return 0; 3362 + } 3363 + 3364 + if (!liquidio_send_vf_trust_cmd(lio, vfidx, setting)) { 3365 + if (setting) { 3366 + oct->sriov_info.trusted_vf.id = vfidx; 3367 + oct->sriov_info.trusted_vf.active = true; 3368 + } else { 3369 + oct->sriov_info.trusted_vf.active = false; 3370 + } 3371 + 3372 + netif_info(lio, drv, lio->netdev, "VF %u is %strusted\n", vfidx, 3373 + setting ? "" : "not "); 3374 + } else { 3375 + netif_info(lio, drv, lio->netdev, "Failed to set VF trusted\n"); 3376 + return -1; 3377 + } 3378 + 3274 3379 return 0; 3275 3380 } 3276 3381 ··· 3514 3399 .ndo_set_vf_mac = liquidio_set_vf_mac, 3515 3400 .ndo_set_vf_vlan = liquidio_set_vf_vlan, 3516 3401 .ndo_get_vf_config = liquidio_get_vf_config, 3402 + .ndo_set_vf_trust = liquidio_set_vf_trust, 3517 3403 .ndo_set_vf_link_state = liquidio_set_vf_link_state, 3518 3404 }; 3519 3405
+7
drivers/net/ethernet/cavium/liquidio/liquidio_common.h
··· 84 84 #define OPCODE_NIC_IF_CFG 0x09 85 85 #define OPCODE_NIC_VF_DRV_NOTICE 0x0A 86 86 #define OPCODE_NIC_INTRMOD_PARAMS 0x0B 87 + #define OPCODE_NIC_SET_TRUSTED_VF 0x13 87 88 #define OPCODE_NIC_SYNC_OCTEON_TIME 0x14 88 89 #define VF_DRV_LOADED 1 89 90 #define VF_DRV_REMOVED -1 ··· 917 916 u64 base_queue:16; 918 917 #endif 919 918 } s; 919 + }; 920 + 921 + struct lio_trusted_vf { 922 + uint64_t active: 1; 923 + uint64_t id : 8; 924 + uint64_t reserved: 55; 920 925 }; 921 926 922 927 struct lio_time {
+2
drivers/net/ethernet/cavium/liquidio/octeon_device.h
··· 370 370 371 371 u32 sriov_enabled; 372 372 373 + struct lio_trusted_vf trusted_vf; 374 + 373 375 /*lookup table that maps DPI ring number to VF pci_dev struct pointer*/ 374 376 struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS]; 375 377