Index: sys/net/iflib.h =================================================================== --- sys/net/iflib.h +++ sys/net/iflib.h @@ -246,7 +246,7 @@ /* fields necessary for probe */ pci_vendor_info_t *isc_vendor_info; char *isc_driver_version; -/* optional function to transform the read values to match the table*/ + /* optional function to transform the read values to match the table*/ void (*isc_parse_devinfo) (uint16_t *device_id, uint16_t *subvendor_id, uint16_t *subdevice_id, uint16_t *rev_id); int isc_nrxd_min[8]; @@ -375,6 +375,8 @@ if_shared_ctx_t iflib_get_sctx(if_ctx_t ctx); void iflib_set_mac(if_ctx_t ctx, uint8_t mac[ETHER_ADDR_LEN]); +void iflib_request_reset(if_ctx_t ctx); +uint8_t iflib_in_detach(if_ctx_t ctx); /* * If the driver can plug cleanly in to newbus use these Index: sys/net/iflib.c =================================================================== --- sys/net/iflib.c +++ sys/net/iflib.c @@ -101,6 +101,10 @@ #include #endif +#ifdef PCI_IOV +#include +#endif + #include /* * enable accounting of every mbuf as it comes in to and goes out of @@ -157,9 +161,9 @@ struct iflib_ctx { KOBJ_FIELDS; - /* - * Pointer to hardware driver's softc - */ + /* + * Pointer to hardware driver's softc + */ void *ifc_softc; device_t ifc_dev; if_t ifc_ifp; @@ -178,7 +182,7 @@ uint32_t ifc_if_flags; uint32_t ifc_flags; uint32_t ifc_max_fl_buf_size; - int ifc_in_detach; + uint32_t ifc_in_detach; int ifc_link_state; int ifc_link_irq; @@ -256,7 +260,13 @@ void iflib_set_detach(if_ctx_t ctx) { - ctx->ifc_in_detach = 1; + atomic_store_rel_32(&ctx->ifc_in_detach, 1); +} + +uint8_t +iflib_in_detach(if_ctx_t ctx) +{ + return (atomic_load_acq_32(&ctx->ifc_in_detach) != 0); } void @@ -3857,8 +3867,9 @@ ctx->ifc_flags &= ~(IFC_DO_RESET|IFC_DO_WATCHDOG); STATE_UNLOCK(ctx); - if ((!running & !oactive) && - !(ctx->ifc_sctx->isc_flags & IFLIB_ADMIN_ALWAYS_RUN)) + if ((!running & !oactive) && !(ctx->ifc_sctx->isc_flags & IFLIB_ADMIN_ALWAYS_RUN)) + return; + if (iflib_in_detach(ctx)) return; CTX_LOCK(ctx); @@ -3897,7 +3908,8 @@ { if_ctx_t ctx = context; - if (!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING)) + if (!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING) && + !(ctx->ifc_sctx->isc_flags & IFLIB_ADMIN_ALWAYS_RUN)) return; CTX_LOCK(ctx); @@ -4909,9 +4921,16 @@ device_printf(dev,"Vlan in use, detach first\n"); return (EBUSY); } +#ifdef PCI_IOV + if (pci_iov_detach(dev)) { + device_printf(dev, "SR-IOV in use; detach first.\n"); + return (EBUSY); + } +#endif + + iflib_set_detach(ctx); CTX_LOCK(ctx); - ctx->ifc_in_detach = 1; iflib_stop(ctx); CTX_UNLOCK(ctx); @@ -5324,7 +5343,7 @@ fl[j].ifl_ifdi = &rxq->ifr_ifdi[j + rxq->ifr_fl_offset]; fl[j].ifl_rxd_size = scctx->isc_rxd_size[j]; } - /* Allocate receive buffers for the ring*/ + /* Allocate receive buffers for the ring */ if (iflib_rxsd_alloc(rxq)) { device_printf(dev, "Critical Failure setting up receive buffers\n"); @@ -6388,6 +6407,15 @@ } +void +iflib_request_reset(if_ctx_t ctx) +{ + + STATE_LOCK(ctx); + ctx->ifc_flags |= IFC_DO_RESET; + STATE_UNLOCK(ctx); +} + #ifndef __NO_STRICT_ALIGNMENT static struct mbuf * iflib_fixup_rx(struct mbuf *m)