Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ixl/if_ixl.c
Show First 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | |||||
static void ixl_if_multi_set(if_ctx_t ctx); | static void ixl_if_multi_set(if_ctx_t ctx); | ||||
static int ixl_if_mtu_set(if_ctx_t ctx, uint32_t mtu); | static int ixl_if_mtu_set(if_ctx_t ctx, uint32_t mtu); | ||||
static void ixl_if_media_status(if_ctx_t ctx, struct ifmediareq *ifmr); | static void ixl_if_media_status(if_ctx_t ctx, struct ifmediareq *ifmr); | ||||
static int ixl_if_media_change(if_ctx_t ctx); | static int ixl_if_media_change(if_ctx_t ctx); | ||||
static int ixl_if_promisc_set(if_ctx_t ctx, int flags); | static int ixl_if_promisc_set(if_ctx_t ctx, int flags); | ||||
static void ixl_if_timer(if_ctx_t ctx, uint16_t qid); | static void ixl_if_timer(if_ctx_t ctx, uint16_t qid); | ||||
static void ixl_if_vlan_register(if_ctx_t ctx, u16 vtag); | static void ixl_if_vlan_register(if_ctx_t ctx, u16 vtag); | ||||
static void ixl_if_vlan_unregister(if_ctx_t ctx, u16 vtag); | static void ixl_if_vlan_unregister(if_ctx_t ctx, u16 vtag); | ||||
static void ixl_if_vxlan_register(if_ctx_t ctx, u16 port); | |||||
static void ixl_if_vxlan_unregister(if_ctx_t ctx, u16 port); | |||||
static uint64_t ixl_if_get_counter(if_ctx_t ctx, ift_counter cnt); | static uint64_t ixl_if_get_counter(if_ctx_t ctx, ift_counter cnt); | ||||
static int ixl_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req); | static int ixl_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req); | ||||
static int ixl_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data); | static int ixl_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data); | ||||
static bool ixl_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event); | static bool ixl_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event); | ||||
#ifdef PCI_IOV | #ifdef PCI_IOV | ||||
static void ixl_if_vflr_handle(if_ctx_t ctx); | static void ixl_if_vflr_handle(if_ctx_t ctx); | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | static device_method_t ixl_if_methods[] = { | ||||
DEVMETHOD(ifdi_multi_set, ixl_if_multi_set), | DEVMETHOD(ifdi_multi_set, ixl_if_multi_set), | ||||
DEVMETHOD(ifdi_mtu_set, ixl_if_mtu_set), | DEVMETHOD(ifdi_mtu_set, ixl_if_mtu_set), | ||||
DEVMETHOD(ifdi_media_status, ixl_if_media_status), | DEVMETHOD(ifdi_media_status, ixl_if_media_status), | ||||
DEVMETHOD(ifdi_media_change, ixl_if_media_change), | DEVMETHOD(ifdi_media_change, ixl_if_media_change), | ||||
DEVMETHOD(ifdi_promisc_set, ixl_if_promisc_set), | DEVMETHOD(ifdi_promisc_set, ixl_if_promisc_set), | ||||
DEVMETHOD(ifdi_timer, ixl_if_timer), | DEVMETHOD(ifdi_timer, ixl_if_timer), | ||||
DEVMETHOD(ifdi_vlan_register, ixl_if_vlan_register), | DEVMETHOD(ifdi_vlan_register, ixl_if_vlan_register), | ||||
DEVMETHOD(ifdi_vlan_unregister, ixl_if_vlan_unregister), | DEVMETHOD(ifdi_vlan_unregister, ixl_if_vlan_unregister), | ||||
DEVMETHOD(ifdi_vxlan_register, ixl_if_vxlan_register), | |||||
DEVMETHOD(ifdi_vxlan_unregister, ixl_if_vxlan_unregister), | |||||
DEVMETHOD(ifdi_get_counter, ixl_if_get_counter), | DEVMETHOD(ifdi_get_counter, ixl_if_get_counter), | ||||
DEVMETHOD(ifdi_i2c_req, ixl_if_i2c_req), | DEVMETHOD(ifdi_i2c_req, ixl_if_i2c_req), | ||||
DEVMETHOD(ifdi_priv_ioctl, ixl_if_priv_ioctl), | DEVMETHOD(ifdi_priv_ioctl, ixl_if_priv_ioctl), | ||||
DEVMETHOD(ifdi_needs_restart, ixl_if_needs_restart), | DEVMETHOD(ifdi_needs_restart, ixl_if_needs_restart), | ||||
#ifdef PCI_IOV | #ifdef PCI_IOV | ||||
DEVMETHOD(ifdi_iov_init, ixl_if_iov_init), | DEVMETHOD(ifdi_iov_init, ixl_if_iov_init), | ||||
DEVMETHOD(ifdi_iov_uninit, ixl_if_iov_uninit), | DEVMETHOD(ifdi_iov_uninit, ixl_if_iov_uninit), | ||||
DEVMETHOD(ifdi_iov_vf_add, ixl_if_iov_vf_add), | DEVMETHOD(ifdi_iov_vf_add, ixl_if_iov_vf_add), | ||||
▲ Show 20 Lines • Show All 520 Lines • ▼ Show 20 Lines | if (error) { | ||||
device_printf(dev, "Initial ixl_switch_config() failed: %d\n", | device_printf(dev, "Initial ixl_switch_config() failed: %d\n", | ||||
error); | error); | ||||
goto err; | goto err; | ||||
} | } | ||||
/* Add protocol filters to list */ | /* Add protocol filters to list */ | ||||
ixl_init_filters(vsi); | ixl_init_filters(vsi); | ||||
/* Initialize udp_ports bitmap for VXLAN offloads */ | |||||
memset(&pf->udp_ports, 0, sizeof(pf->udp_ports)); | |||||
/* Init queue allocation manager */ | /* Init queue allocation manager */ | ||||
error = ixl_pf_qmgr_init(&pf->qmgr, hw->func_caps.num_tx_qp); | error = ixl_pf_qmgr_init(&pf->qmgr, hw->func_caps.num_tx_qp); | ||||
if (error) { | if (error) { | ||||
device_printf(dev, "Failed to init queue manager for PF queues, error %d\n", | device_printf(dev, "Failed to init queue manager for PF queues, error %d\n", | ||||
error); | error); | ||||
goto err; | goto err; | ||||
} | } | ||||
/* reserve a contiguous allocation for the PF's VSI */ | /* reserve a contiguous allocation for the PF's VSI */ | ||||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Lines | ixl_if_init(if_ctx_t ctx) | ||||
ixl_enable_rings(vsi); | ixl_enable_rings(vsi); | ||||
i40e_aq_set_default_vsi(hw, vsi->seid, NULL); | i40e_aq_set_default_vsi(hw, vsi->seid, NULL); | ||||
/* Re-add configure filters to HW */ | /* Re-add configure filters to HW */ | ||||
ixl_reconfigure_filters(vsi); | ixl_reconfigure_filters(vsi); | ||||
/* Sync all UDP filters */ | |||||
ixl_sync_udp_filters(pf, true); | |||||
/* Configure promiscuous mode */ | /* Configure promiscuous mode */ | ||||
ixl_if_promisc_set(ctx, if_getflags(ifp)); | ixl_if_promisc_set(ctx, if_getflags(ifp)); | ||||
#ifdef IXL_IW | #ifdef IXL_IW | ||||
if (ixl_enable_iwarp && pf->iw_enabled) { | if (ixl_enable_iwarp && pf->iw_enabled) { | ||||
ret = ixl_iw_pf_init(pf); | ret = ixl_iw_pf_init(pf); | ||||
if (ret) | if (ret) | ||||
device_printf(dev, | device_printf(dev, | ||||
▲ Show 20 Lines • Show All 412 Lines • ▼ Show 20 Lines | if (!i40e_check_asq_alive(&pf->hw)) | ||||
return; | return; | ||||
if (pf->state & IXL_PF_STATE_MDD_PENDING) | if (pf->state & IXL_PF_STATE_MDD_PENDING) | ||||
ixl_handle_mdd_event(pf); | ixl_handle_mdd_event(pf); | ||||
ixl_process_adminq(pf, &pending); | ixl_process_adminq(pf, &pending); | ||||
ixl_update_link_status(pf); | ixl_update_link_status(pf); | ||||
if (IXL_PF_HAS_PENDING_UDP_FILTER_SYNC(pf)) | |||||
ixl_sync_udp_filters(pf, false); | |||||
/* | /* | ||||
* If there are still messages to process, reschedule ourselves. | * If there are still messages to process, reschedule ourselves. | ||||
* Otherwise, re-enable our interrupt and go to sleep. | * Otherwise, re-enable our interrupt and go to sleep. | ||||
*/ | */ | ||||
if (pending > 0) | if (pending > 0) | ||||
iflib_admin_intr_deferred(ctx); | iflib_admin_intr_deferred(ctx); | ||||
else | else | ||||
ixl_enable_intr0(hw); | ixl_enable_intr0(hw); | ||||
▲ Show 20 Lines • Show All 289 Lines • ▼ Show 20 Lines | ixl_if_vlan_unregister(if_ctx_t ctx, u16 vtag) | ||||
if (vsi->num_vlans < IXL_MAX_VLAN_FILTERS) | if (vsi->num_vlans < IXL_MAX_VLAN_FILTERS) | ||||
ixl_del_filter(vsi, hw->mac.addr, vtag); | ixl_del_filter(vsi, hw->mac.addr, vtag); | ||||
else if (vsi->num_vlans == IXL_MAX_VLAN_FILTERS) { | else if (vsi->num_vlans == IXL_MAX_VLAN_FILTERS) { | ||||
ixl_del_filter(vsi, hw->mac.addr, IXL_VLAN_ANY); | ixl_del_filter(vsi, hw->mac.addr, IXL_VLAN_ANY); | ||||
ixl_add_vlan_filters(vsi, hw->mac.addr); | ixl_add_vlan_filters(vsi, hw->mac.addr); | ||||
} | } | ||||
} | } | ||||
static void | |||||
ixl_if_vxlan_register(if_ctx_t ctx, u16 port) | |||||
{ | |||||
struct ixl_pf *pf = iflib_get_softc(ctx); | |||||
int idx; | |||||
/* Check if port already exists */ | |||||
idx = ixl_get_udp_port_idx(pf, port); | |||||
if (idx != -1) { | |||||
device_printf(pf->dev, "port %d already offloaded\n", port); | |||||
return; | |||||
} | |||||
/* Now check if there is space to add the new port */ | |||||
idx = ixl_get_udp_port_idx(pf, 0); | |||||
if (idx == -1) { | |||||
device_printf(pf->dev, | |||||
"maximum number of offloaded UDP ports reached, not adding port %d\n", | |||||
port); | |||||
return; | |||||
} | |||||
pf->udp_ports[idx].port = port; | |||||
pf->udp_ports[idx].filter_index = IXL_UDP_PORT_INDEX_UNUSED; | |||||
pf->udp_ports[idx].is_marked_for_deletion = FALSE; | |||||
pf->pending_udp_bitmap |= BIT_ULL(idx); | |||||
atomic_set_32(&pf->state, IXL_PF_STATE_UDP_FILTER_SYNC_PENDING); | |||||
if (if_getdrvflags(iflib_get_ifp(ctx)) & IFF_DRV_RUNNING) | |||||
iflib_admin_intr_deferred(ctx); | |||||
} | |||||
static void | |||||
ixl_if_vxlan_unregister(if_ctx_t ctx, u16 port) | |||||
{ | |||||
struct ixl_pf *pf = iflib_get_softc(ctx); | |||||
int idx; | |||||
/* Check if port already exists */ | |||||
idx = ixl_get_udp_port_idx(pf, port); | |||||
if (idx == -1) { | |||||
device_printf(pf->dev, | |||||
"UDP port %d was not found, not deleting\n", port); | |||||
return; | |||||
} | |||||
/* If port exists, set the value to 0. When ixl_if_vxlan_register looks for | |||||
* an empty entry for a new tunnel, it looks for entries with port set to 0. | |||||
* Also, mark current entry for deletion and make the deletion pending. | |||||
*/ | |||||
pf->udp_ports[idx].port = 0; | |||||
pf->udp_ports[idx].is_marked_for_deletion = TRUE; | |||||
/* Toggle pending bit instead of setting it. This way if we are | |||||
* deleting a port that has yet to be added we just clear the pending | |||||
* bit and don't have to worry about it. | |||||
*/ | |||||
pf->pending_udp_bitmap ^= BIT_ULL(idx); | |||||
atomic_set_32(&pf->state, IXL_PF_STATE_UDP_FILTER_SYNC_PENDING); | |||||
if (if_getdrvflags(iflib_get_ifp(ctx)) & IFF_DRV_RUNNING) | |||||
iflib_admin_intr_deferred(ctx); | |||||
} | |||||
static uint64_t | static uint64_t | ||||
ixl_if_get_counter(if_ctx_t ctx, ift_counter cnt) | ixl_if_get_counter(if_ctx_t ctx, ift_counter cnt) | ||||
{ | { | ||||
struct ixl_pf *pf = iflib_get_softc(ctx); | struct ixl_pf *pf = iflib_get_softc(ctx); | ||||
struct ixl_vsi *vsi = &pf->vsi; | struct ixl_vsi *vsi = &pf->vsi; | ||||
if_t ifp = iflib_get_ifp(ctx); | if_t ifp = iflib_get_ifp(ctx); | ||||
switch (cnt) { | switch (cnt) { | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* @returns true if iflib needs to reinit the interface, false otherwise | * @returns true if iflib needs to reinit the interface, false otherwise | ||||
*/ | */ | ||||
static bool | static bool | ||||
ixl_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) | ixl_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) | ||||
{ | { | ||||
switch (event) { | switch (event) { | ||||
case IFLIB_RESTART_VLAN_CONFIG: | case IFLIB_RESTART_VLAN_CONFIG: | ||||
case IFLIB_RESTART_VXLAN_CONFIG: | |||||
default: | default: | ||||
return (false); | return (false); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Sanity check and save off tunable values. | * Sanity check and save off tunable values. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 66 Lines • Show Last 20 Lines |