Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
Show First 20 Lines • Show All 1,271 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Called when we receive a data packet from the "wire" on the | * Called when we receive a data packet from the "wire" on the | ||||
* specified device | * specified device | ||||
* | * | ||||
* Note: This is no longer used as a callback | * Note: This is no longer used as a callback | ||||
*/ | */ | ||||
int | int | ||||
netvsc_recv(struct hn_rx_ring *rxr, netvsc_packet *packet, | netvsc_recv(struct hn_rx_ring *rxr, const void *data, int dlen, | ||||
const struct hn_recvinfo *info) | const struct hn_recvinfo *info) | ||||
{ | { | ||||
struct ifnet *ifp = rxr->hn_ifp; | struct ifnet *ifp = rxr->hn_ifp; | ||||
struct mbuf *m_new; | struct mbuf *m_new; | ||||
int size, do_lro = 0, do_csum = 1; | int size, do_lro = 0, do_csum = 1; | ||||
int hash_type = M_HASHTYPE_OPAQUE_HASH; | int hash_type = M_HASHTYPE_OPAQUE_HASH; | ||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) | if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) | ||||
return (0); | return (0); | ||||
/* | /* | ||||
* Bail out if packet contains more data than configured MTU. | * Bail out if packet contains more data than configured MTU. | ||||
*/ | */ | ||||
if (packet->tot_data_buf_len > (ifp->if_mtu + ETHER_HDR_LEN)) { | if (dlen > (ifp->if_mtu + ETHER_HDR_LEN)) { | ||||
return (0); | return (0); | ||||
} else if (packet->tot_data_buf_len <= MHLEN) { | } else if (dlen <= MHLEN) { | ||||
m_new = m_gethdr(M_NOWAIT, MT_DATA); | m_new = m_gethdr(M_NOWAIT, MT_DATA); | ||||
if (m_new == NULL) { | if (m_new == NULL) { | ||||
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); | if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); | ||||
return (0); | return (0); | ||||
} | } | ||||
memcpy(mtod(m_new, void *), packet->data, | memcpy(mtod(m_new, void *), data, dlen); | ||||
packet->tot_data_buf_len); | m_new->m_pkthdr.len = m_new->m_len = dlen; | ||||
m_new->m_pkthdr.len = m_new->m_len = packet->tot_data_buf_len; | |||||
rxr->hn_small_pkts++; | rxr->hn_small_pkts++; | ||||
} else { | } else { | ||||
/* | /* | ||||
* Get an mbuf with a cluster. For packets 2K or less, | * Get an mbuf with a cluster. For packets 2K or less, | ||||
* get a standard 2K cluster. For anything larger, get a | * get a standard 2K cluster. For anything larger, get a | ||||
* 4K cluster. Any buffers larger than 4K can cause problems | * 4K cluster. Any buffers larger than 4K can cause problems | ||||
* if looped around to the Hyper-V TX channel, so avoid them. | * if looped around to the Hyper-V TX channel, so avoid them. | ||||
*/ | */ | ||||
size = MCLBYTES; | size = MCLBYTES; | ||||
if (packet->tot_data_buf_len > MCLBYTES) { | if (dlen > MCLBYTES) { | ||||
/* 4096 */ | /* 4096 */ | ||||
size = MJUMPAGESIZE; | size = MJUMPAGESIZE; | ||||
} | } | ||||
m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, size); | m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, size); | ||||
if (m_new == NULL) { | if (m_new == NULL) { | ||||
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); | if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); | ||||
return (0); | return (0); | ||||
} | } | ||||
hv_m_append(m_new, packet->tot_data_buf_len, packet->data); | hv_m_append(m_new, dlen, data); | ||||
} | } | ||||
m_new->m_pkthdr.rcvif = ifp; | m_new->m_pkthdr.rcvif = ifp; | ||||
if (__predict_false((ifp->if_capenable & IFCAP_RXCSUM) == 0)) | if (__predict_false((ifp->if_capenable & IFCAP_RXCSUM) == 0)) | ||||
do_csum = 0; | do_csum = 0; | ||||
/* receive side checksum offload */ | /* receive side checksum offload */ | ||||
if (info->csum_info != NULL) { | if (info->csum_info != NULL) { | ||||
▲ Show 20 Lines • Show All 1,707 Lines • Show Last 20 Lines |