Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ixl/ixl_pf_iov.c
/****************************************************************************** | /****************************************************************************** | ||||
Copyright (c) 2013-2017, Intel Corporation | Copyright (c) 2013-2019, Intel Corporation | ||||
All rights reserved. | All rights reserved. | ||||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | ||||
modification, are permitted provided that the following conditions are met: | modification, are permitted provided that the following conditions are met: | ||||
1. Redistributions of source code must retain the above copyright notice, | 1. Redistributions of source code must retain the above copyright notice, | ||||
this list of conditions and the following disclaimer. | this list of conditions and the following disclaimer. | ||||
2. Redistributions in binary form must reproduce the above copyright | 2. Redistributions in binary form must reproduce the above copyright | ||||
notice, this list of conditions and the following disclaimer in the | notice, this list of conditions and the following disclaimer in the | ||||
▲ Show 20 Lines • Show All 178 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
ixl_vf_setup_vsi(struct ixl_pf *pf, struct ixl_vf *vf) | ixl_vf_setup_vsi(struct ixl_pf *pf, struct ixl_vf *vf) | ||||
{ | { | ||||
struct i40e_hw *hw; | struct i40e_hw *hw; | ||||
int error; | int error; | ||||
hw = &pf->hw; | hw = &pf->hw; | ||||
vf->vsi.flags |= IXL_FLAGS_IS_VF; | |||||
error = ixl_vf_alloc_vsi(pf, vf); | error = ixl_vf_alloc_vsi(pf, vf); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
vf->vsi.hw_filters_add = 0; | vf->vsi.dev = pf->dev; | ||||
vf->vsi.hw_filters_del = 0; | vf->vsi.num_hw_filters = 0; | ||||
ixl_add_filter(&vf->vsi, ixl_bcast_addr, IXL_VLAN_ANY); | |||||
ixl_reconfigure_filters(&vf->vsi); | |||||
ixl_init_filters(&vf->vsi); | |||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
ixl_vf_map_vsi_queue(struct i40e_hw *hw, struct ixl_vf *vf, int qnum, | ixl_vf_map_vsi_queue(struct i40e_hw *hw, struct ixl_vf *vf, int qnum, | ||||
uint32_t val) | uint32_t val) | ||||
{ | { | ||||
uint32_t qtable; | uint32_t qtable; | ||||
▲ Show 20 Lines • Show All 1,499 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
ixl_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *params) | ixl_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *params) | ||||
{ | { | ||||
struct ixl_pf *pf; | struct ixl_pf *pf; | ||||
struct i40e_hw *hw; | struct i40e_hw *hw; | ||||
struct ixl_vsi *pf_vsi; | struct ixl_vsi *pf_vsi; | ||||
enum i40e_status_code ret; | enum i40e_status_code ret; | ||||
int i, error; | int error; | ||||
pf = device_get_softc(dev); | pf = device_get_softc(dev); | ||||
hw = &pf->hw; | hw = &pf->hw; | ||||
pf_vsi = &pf->vsi; | pf_vsi = &pf->vsi; | ||||
IXL_PF_LOCK(pf); | IXL_PF_LOCK(pf); | ||||
pf->vfs = malloc(sizeof(struct ixl_vf) * num_vfs, M_IXL, M_NOWAIT | | pf->vfs = malloc(sizeof(struct ixl_vf) * num_vfs, M_IXL, M_NOWAIT | | ||||
M_ZERO); | M_ZERO); | ||||
if (pf->vfs == NULL) { | if (pf->vfs == NULL) { | ||||
error = ENOMEM; | error = ENOMEM; | ||||
goto fail; | goto fail; | ||||
} | } | ||||
for (i = 0; i < num_vfs; i++) | |||||
sysctl_ctx_init(&pf->vfs[i].ctx); | |||||
ret = i40e_aq_add_veb(hw, pf_vsi->uplink_seid, pf_vsi->seid, | ret = i40e_aq_add_veb(hw, pf_vsi->uplink_seid, pf_vsi->seid, | ||||
1, FALSE, &pf->veb_seid, FALSE, NULL); | 1, FALSE, &pf->veb_seid, FALSE, NULL); | ||||
if (ret != I40E_SUCCESS) { | if (ret != I40E_SUCCESS) { | ||||
error = ixl_adminq_err_to_errno(hw->aq.asq_last_status); | error = ixl_adminq_err_to_errno(hw->aq.asq_last_status); | ||||
device_printf(dev, "add_veb failed; code=%d error=%d", ret, | device_printf(dev, "add_veb failed; code=%d error=%d", ret, | ||||
error); | error); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
/* | |||||
* Adding a VEB brings back the default MAC filter(s). Remove them, | |||||
* and let the driver add the proper filters back. | |||||
*/ | |||||
ixl_del_default_hw_filters(pf_vsi); | |||||
ixl_reconfigure_filters(pf_vsi); | |||||
pf->num_vfs = num_vfs; | pf->num_vfs = num_vfs; | ||||
IXL_PF_UNLOCK(pf); | IXL_PF_UNLOCK(pf); | ||||
return (0); | return (0); | ||||
fail: | fail: | ||||
free(pf->vfs, M_IXL); | free(pf->vfs, M_IXL); | ||||
pf->vfs = NULL; | pf->vfs = NULL; | ||||
IXL_PF_UNLOCK(pf); | IXL_PF_UNLOCK(pf); | ||||
Show All 35 Lines | ixl_iov_uninit(device_t dev) | ||||
num_vfs = pf->num_vfs; | num_vfs = pf->num_vfs; | ||||
pf->vfs = NULL; | pf->vfs = NULL; | ||||
pf->num_vfs = 0; | pf->num_vfs = 0; | ||||
IXL_PF_UNLOCK(pf); | IXL_PF_UNLOCK(pf); | ||||
/* Do this after the unlock as sysctl_ctx_free might sleep. */ | /* Do this after the unlock as sysctl_ctx_free might sleep. */ | ||||
for (i = 0; i < num_vfs; i++) | for (i = 0; i < num_vfs; i++) | ||||
sysctl_ctx_free(&vfs[i].ctx); | sysctl_ctx_free(&vfs[i].vsi.sysctl_ctx); | ||||
free(vfs, M_IXL); | free(vfs, M_IXL); | ||||
} | } | ||||
static int | static int | ||||
ixl_vf_reserve_queues(struct ixl_pf *pf, struct ixl_vf *vf, int num_queues) | ixl_vf_reserve_queues(struct ixl_pf *pf, struct ixl_vf *vf, int num_queues) | ||||
{ | { | ||||
device_t dev = pf->dev; | device_t dev = pf->dev; | ||||
int error; | int error; | ||||
Show All 21 Lines | ixl_vf_reserve_queues(struct ixl_pf *pf, struct ixl_vf *vf, int num_queues) | ||||
DDPRINTF(dev, "Unallocated total: %d", ixl_pf_qmgr_get_num_free(&pf->qmgr)); | DDPRINTF(dev, "Unallocated total: %d", ixl_pf_qmgr_get_num_free(&pf->qmgr)); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
ixl_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *params) | ixl_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *params) | ||||
{ | { | ||||
char sysctl_name[QUEUE_NAME_LEN]; | char sysctl_name[IXL_QUEUE_NAME_LEN]; | ||||
struct ixl_pf *pf; | struct ixl_pf *pf; | ||||
struct ixl_vf *vf; | struct ixl_vf *vf; | ||||
const void *mac; | const void *mac; | ||||
size_t size; | size_t size; | ||||
int error; | int error; | ||||
int vf_num_queues; | int vf_num_queues; | ||||
pf = device_get_softc(dev); | pf = device_get_softc(dev); | ||||
vf = &pf->vfs[vfnum]; | vf = &pf->vfs[vfnum]; | ||||
IXL_PF_LOCK(pf); | IXL_PF_LOCK(pf); | ||||
vf->vf_num = vfnum; | vf->vf_num = vfnum; | ||||
vf->vsi.back = pf; | vf->vsi.back = pf; | ||||
vf->vf_flags = VF_FLAG_ENABLED; | vf->vf_flags = VF_FLAG_ENABLED; | ||||
SLIST_INIT(&vf->vsi.ftl); | |||||
/* Reserve queue allocation from PF */ | /* Reserve queue allocation from PF */ | ||||
vf_num_queues = nvlist_get_number(params, "num-queues"); | vf_num_queues = nvlist_get_number(params, "num-queues"); | ||||
error = ixl_vf_reserve_queues(pf, vf, vf_num_queues); | error = ixl_vf_reserve_queues(pf, vf, vf_num_queues); | ||||
if (error != 0) | if (error != 0) | ||||
goto out; | goto out; | ||||
error = ixl_vf_setup_vsi(pf, vf); | error = ixl_vf_setup_vsi(pf, vf); | ||||
Show All 21 Lines | ixl_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *params) | ||||
vf->vf_flags |= VF_FLAG_VLAN_CAP; | vf->vf_flags |= VF_FLAG_VLAN_CAP; | ||||
ixl_reset_vf(pf, vf); | ixl_reset_vf(pf, vf); | ||||
out: | out: | ||||
IXL_PF_UNLOCK(pf); | IXL_PF_UNLOCK(pf); | ||||
if (error == 0) { | if (error == 0) { | ||||
snprintf(sysctl_name, sizeof(sysctl_name), "vf%d", vfnum); | snprintf(sysctl_name, sizeof(sysctl_name), "vf%d", vfnum); | ||||
ixl_add_vsi_sysctls(pf, &vf->vsi, &vf->ctx, sysctl_name); | ixl_vsi_add_sysctls(&vf->vsi, sysctl_name, false); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||