mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-04 12:52:15 +00:00
hyperv/hn: Regroup ifnet setup code.
While I'm here, add comment along the attach DEVMETHOD. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7874
This commit is contained in:
parent
a5ec35dfee
commit
174e02e003
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305923
@ -456,6 +456,9 @@ netvsc_attach(device_t dev)
|
|||||||
sc->hn_prichan = vmbus_get_channel(dev);
|
sc->hn_prichan = vmbus_get_channel(dev);
|
||||||
HN_LOCK_INIT(sc);
|
HN_LOCK_INIT(sc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup taskqueue for transmission.
|
||||||
|
*/
|
||||||
if (hn_tx_taskq == NULL) {
|
if (hn_tx_taskq == NULL) {
|
||||||
sc->hn_tx_taskq = taskqueue_create("hn_tx", M_WAITOK,
|
sc->hn_tx_taskq = taskqueue_create("hn_tx", M_WAITOK,
|
||||||
taskqueue_thread_enqueue, &sc->hn_tx_taskq);
|
taskqueue_thread_enqueue, &sc->hn_tx_taskq);
|
||||||
@ -477,10 +480,21 @@ netvsc_attach(device_t dev)
|
|||||||
sc->hn_tx_taskq = hn_tx_taskq;
|
sc->hn_tx_taskq = hn_tx_taskq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate ifnet and setup its name earlier, so that if_printf
|
||||||
|
* can be used by functions, which will be called after
|
||||||
|
* ether_ifattach().
|
||||||
|
*/
|
||||||
ifp = sc->hn_ifp = if_alloc(IFT_ETHER);
|
ifp = sc->hn_ifp = if_alloc(IFT_ETHER);
|
||||||
ifp->if_softc = sc;
|
ifp->if_softc = sc;
|
||||||
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
|
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize ifmedia earlier so that it can be unconditionally
|
||||||
|
* destroyed, if error happened later on.
|
||||||
|
*/
|
||||||
|
ifmedia_init(&sc->hn_media, 0, hn_ifmedia_upd, hn_ifmedia_sts);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Figure out the # of RX rings (ring_cnt) and the # of TX rings
|
* Figure out the # of RX rings (ring_cnt) and the # of TX rings
|
||||||
* to use (tx_ring_cnt).
|
* to use (tx_ring_cnt).
|
||||||
@ -511,6 +525,10 @@ netvsc_attach(device_t dev)
|
|||||||
*/
|
*/
|
||||||
sc->hn_cpu = atomic_fetchadd_int(&hn_cpu_index, ring_cnt) % mp_ncpus;
|
sc->hn_cpu = atomic_fetchadd_int(&hn_cpu_index, ring_cnt) % mp_ncpus;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create enough TX/RX rings, even if only limited number of
|
||||||
|
* channels can be allocated.
|
||||||
|
*/
|
||||||
error = hn_create_tx_data(sc, tx_ring_cnt);
|
error = hn_create_tx_data(sc, tx_ring_cnt);
|
||||||
if (error)
|
if (error)
|
||||||
goto failed;
|
goto failed;
|
||||||
@ -533,6 +551,51 @@ netvsc_attach(device_t dev)
|
|||||||
if (error)
|
if (error)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
error = hn_rndis_get_linkstatus(sc, &link_status);
|
||||||
|
if (error)
|
||||||
|
goto failed;
|
||||||
|
if (link_status == NDIS_MEDIA_STATE_CONNECTED)
|
||||||
|
sc->hn_carrier = 1;
|
||||||
|
|
||||||
|
error = hn_rndis_get_eaddr(sc, eaddr);
|
||||||
|
if (error)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
#if __FreeBSD_version >= 1100099
|
||||||
|
if (sc->hn_rx_ring_inuse > 1) {
|
||||||
|
/*
|
||||||
|
* Reduce TCP segment aggregation limit for multiple
|
||||||
|
* RX rings to increase ACK timeliness.
|
||||||
|
*/
|
||||||
|
hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MULTIRX_DEF);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hn_set_chim_size(sc, sc->hn_chim_szmax);
|
||||||
|
if (hn_tx_chimney_size > 0 &&
|
||||||
|
hn_tx_chimney_size < sc->hn_chim_szmax)
|
||||||
|
hn_set_chim_size(sc, hn_tx_chimney_size);
|
||||||
|
|
||||||
|
ctx = device_get_sysctl_ctx(dev);
|
||||||
|
child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
|
||||||
|
SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "nvs_version", CTLFLAG_RD,
|
||||||
|
&sc->hn_nvs_ver, 0, "NVS version");
|
||||||
|
SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version",
|
||||||
|
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
|
||||||
|
hn_ndis_version_sysctl, "A", "NDIS version");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the ifmedia, which has been initialized earlier.
|
||||||
|
*/
|
||||||
|
ifmedia_add(&sc->hn_media, IFM_ETHER | IFM_AUTO, 0, NULL);
|
||||||
|
ifmedia_set(&sc->hn_media, IFM_ETHER | IFM_AUTO);
|
||||||
|
/* XXX ifmedia_set really should do this for us */
|
||||||
|
sc->hn_media.ifm_media = sc->hn_media.ifm_cur->ifm_media;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the ifnet for this interface.
|
||||||
|
*/
|
||||||
|
|
||||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||||
ifp->if_ioctl = hn_ioctl;
|
ifp->if_ioctl = hn_ioctl;
|
||||||
ifp->if_init = hn_init;
|
ifp->if_init = hn_init;
|
||||||
@ -548,15 +611,6 @@ netvsc_attach(device_t dev)
|
|||||||
ifp->if_qflush = hn_xmit_qflush;
|
ifp->if_qflush = hn_xmit_qflush;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifmedia_init(&sc->hn_media, 0, hn_ifmedia_upd, hn_ifmedia_sts);
|
|
||||||
ifmedia_add(&sc->hn_media, IFM_ETHER | IFM_AUTO, 0, NULL);
|
|
||||||
ifmedia_set(&sc->hn_media, IFM_ETHER | IFM_AUTO);
|
|
||||||
/* XXX ifmedia_set really should do this for us */
|
|
||||||
sc->hn_media.ifm_media = sc->hn_media.ifm_cur->ifm_media;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tell upper layers that we support full VLAN capability.
|
|
||||||
*/
|
|
||||||
ifp->if_capabilities |=
|
ifp->if_capabilities |=
|
||||||
IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_TSO |
|
IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_TSO |
|
||||||
IFCAP_LRO;
|
IFCAP_LRO;
|
||||||
@ -565,34 +619,14 @@ netvsc_attach(device_t dev)
|
|||||||
IFCAP_LRO;
|
IFCAP_LRO;
|
||||||
ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO;
|
ifp->if_hwassist = sc->hn_tx_ring[0].hn_csum_assist | CSUM_TSO;
|
||||||
|
|
||||||
#if __FreeBSD_version >= 1100099
|
|
||||||
if (sc->hn_rx_ring_inuse > 1) {
|
|
||||||
/*
|
|
||||||
* Reduce TCP segment aggregation limit for multiple
|
|
||||||
* RX rings to increase ACK timeliness.
|
|
||||||
*/
|
|
||||||
hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MULTIRX_DEF);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
error = hn_rndis_get_linkstatus(sc, &link_status);
|
|
||||||
if (error)
|
|
||||||
goto failed;
|
|
||||||
if (link_status == NDIS_MEDIA_STATE_CONNECTED)
|
|
||||||
sc->hn_carrier = 1;
|
|
||||||
|
|
||||||
tso_maxlen = hn_tso_maxlen;
|
tso_maxlen = hn_tso_maxlen;
|
||||||
if (tso_maxlen <= 0 || tso_maxlen > IP_MAXPACKET)
|
if (tso_maxlen <= 0 || tso_maxlen > IP_MAXPACKET)
|
||||||
tso_maxlen = IP_MAXPACKET;
|
tso_maxlen = IP_MAXPACKET;
|
||||||
|
|
||||||
ifp->if_hw_tsomaxsegcount = HN_TX_DATA_SEGCNT_MAX;
|
ifp->if_hw_tsomaxsegcount = HN_TX_DATA_SEGCNT_MAX;
|
||||||
ifp->if_hw_tsomaxsegsize = PAGE_SIZE;
|
ifp->if_hw_tsomaxsegsize = PAGE_SIZE;
|
||||||
ifp->if_hw_tsomax = tso_maxlen -
|
ifp->if_hw_tsomax = tso_maxlen -
|
||||||
(ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
|
(ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
|
||||||
|
|
||||||
error = hn_rndis_get_eaddr(sc, eaddr);
|
|
||||||
if (error)
|
|
||||||
goto failed;
|
|
||||||
ether_ifattach(ifp, eaddr);
|
ether_ifattach(ifp, eaddr);
|
||||||
|
|
||||||
if_printf(ifp, "TSO: %u/%u/%u\n", ifp->if_hw_tsomax,
|
if_printf(ifp, "TSO: %u/%u/%u\n", ifp->if_hw_tsomax,
|
||||||
@ -601,21 +635,9 @@ netvsc_attach(device_t dev)
|
|||||||
/* Inform the upper layer about the long frame support. */
|
/* Inform the upper layer about the long frame support. */
|
||||||
ifp->if_hdrlen = sizeof(struct ether_vlan_header);
|
ifp->if_hdrlen = sizeof(struct ether_vlan_header);
|
||||||
|
|
||||||
hn_set_chim_size(sc, sc->hn_chim_szmax);
|
|
||||||
if (hn_tx_chimney_size > 0 &&
|
|
||||||
hn_tx_chimney_size < sc->hn_chim_szmax)
|
|
||||||
hn_set_chim_size(sc, hn_tx_chimney_size);
|
|
||||||
|
|
||||||
ctx = device_get_sysctl_ctx(dev);
|
|
||||||
child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
|
|
||||||
SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "nvs_version", CTLFLAG_RD,
|
|
||||||
&sc->hn_nvs_ver, 0, "NVS version");
|
|
||||||
SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version",
|
|
||||||
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
|
|
||||||
hn_ndis_version_sysctl, "A", "NDIS version");
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
failed:
|
failed:
|
||||||
|
/* TODO: reuse netvsc_detach() */
|
||||||
hn_destroy_tx_data(sc);
|
hn_destroy_tx_data(sc);
|
||||||
if (ifp != NULL)
|
if (ifp != NULL)
|
||||||
if_free(ifp);
|
if_free(ifp);
|
||||||
|
Loading…
Reference in New Issue
Block a user