Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
* Forward declarations | * Forward declarations | ||||
*/ | */ | ||||
static int hv_rf_send_request(rndis_device *device, rndis_request *request, | static int hv_rf_send_request(rndis_device *device, rndis_request *request, | ||||
uint32_t message_type); | uint32_t message_type); | ||||
static void hv_rf_receive_response(rndis_device *device, | static void hv_rf_receive_response(rndis_device *device, | ||||
const rndis_msg *response); | const rndis_msg *response); | ||||
static void hv_rf_receive_indicate_status(rndis_device *device, | static void hv_rf_receive_indicate_status(rndis_device *device, | ||||
const rndis_msg *response); | const rndis_msg *response); | ||||
static void hv_rf_receive_data(struct hn_rx_ring *rxr, const rndis_msg *message, | static void hv_rf_receive_data(struct hn_rx_ring *rxr, | ||||
netvsc_packet *pkt); | const void *data, int dlen); | ||||
static int hv_rf_query_device(rndis_device *device, uint32_t oid, | static int hv_rf_query_device(rndis_device *device, uint32_t oid, | ||||
void *result, uint32_t *result_size); | void *result, uint32_t *result_size); | ||||
static inline int hv_rf_query_device_mac(rndis_device *device); | static inline int hv_rf_query_device_mac(rndis_device *device); | ||||
static inline int hv_rf_query_device_link_status(rndis_device *device); | static inline int hv_rf_query_device_link_status(rndis_device *device); | ||||
static int hv_rf_set_packet_filter(rndis_device *device, uint32_t new_filter); | static int hv_rf_set_packet_filter(rndis_device *device, uint32_t new_filter); | ||||
static int hv_rf_init_device(rndis_device *device); | static int hv_rf_init_device(rndis_device *device); | ||||
static int hv_rf_open_device(rndis_device *device); | static int hv_rf_open_device(rndis_device *device); | ||||
static int hv_rf_close_device(rndis_device *device); | static int hv_rf_close_device(rndis_device *device); | ||||
▲ Show 20 Lines • Show All 430 Lines • ▼ Show 20 Lines | skip: | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
/* | /* | ||||
* RNDIS filter receive data | * RNDIS filter receive data | ||||
*/ | */ | ||||
static void | static void | ||||
hv_rf_receive_data(struct hn_rx_ring *rxr, const rndis_msg *message, | hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen) | ||||
netvsc_packet *pkt) | |||||
{ | { | ||||
const rndis_msg *message = data; | |||||
const rndis_packet *rndis_pkt; | const rndis_packet *rndis_pkt; | ||||
uint32_t data_offset; | uint32_t data_offset; | ||||
struct hn_recvinfo info; | struct hn_recvinfo info; | ||||
rndis_pkt = &message->msg.packet; | rndis_pkt = &message->msg.packet; | ||||
/* | /* | ||||
* Fixme: Handle multiple rndis pkt msgs that may be enclosed in this | * Fixme: Handle multiple rndis pkt msgs that may be enclosed in this | ||||
* netvsc packet (ie tot_data_buf_len != message_length) | * netvsc packet (ie tot_data_buf_len != message_length) | ||||
*/ | */ | ||||
/* Remove rndis header, then pass data packet up the stack */ | /* Remove rndis header, then pass data packet up the stack */ | ||||
data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset; | data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset; | ||||
pkt->tot_data_buf_len -= data_offset; | dlen -= data_offset; | ||||
if (pkt->tot_data_buf_len < rndis_pkt->data_length) { | if (dlen < rndis_pkt->data_length) { | ||||
pkt->status = HN_NVS_STATUS_FAILED; | |||||
if_printf(rxr->hn_ifp, | if_printf(rxr->hn_ifp, | ||||
"total length %u is less than data length %u\n", | "total length %u is less than data length %u\n", | ||||
pkt->tot_data_buf_len, rndis_pkt->data_length); | dlen, rndis_pkt->data_length); | ||||
return; | return; | ||||
} | } | ||||
pkt->tot_data_buf_len = rndis_pkt->data_length; | dlen = rndis_pkt->data_length; | ||||
pkt->data = (void *)((unsigned long)pkt->data + data_offset); | data = (const uint8_t *)data + data_offset; | ||||
if (hv_rf_find_recvinfo(rndis_pkt, &info)) { | if (hv_rf_find_recvinfo(rndis_pkt, &info)) { | ||||
pkt->status = HN_NVS_STATUS_FAILED; | |||||
if_printf(rxr->hn_ifp, "recvinfo parsing failed\n"); | if_printf(rxr->hn_ifp, "recvinfo parsing failed\n"); | ||||
return; | return; | ||||
} | } | ||||
netvsc_recv(rxr, pkt, &info); | netvsc_recv(rxr, data, dlen, &info); | ||||
} | } | ||||
/* | /* | ||||
* RNDIS filter on receive | * RNDIS filter on receive | ||||
*/ | */ | ||||
int | int | ||||
hv_rf_on_receive(netvsc_dev *net_dev, | hv_rf_on_receive(netvsc_dev *net_dev, | ||||
struct hn_rx_ring *rxr, netvsc_packet *pkt) | struct hn_rx_ring *rxr, const void *data, int dlen) | ||||
{ | { | ||||
rndis_device *rndis_dev; | rndis_device *rndis_dev; | ||||
const rndis_msg *rndis_hdr; | const rndis_msg *rndis_hdr; | ||||
/* Make sure the rndis device state is initialized */ | /* Make sure the rndis device state is initialized */ | ||||
if (net_dev->extension == NULL) { | if (net_dev->extension == NULL) | ||||
pkt->status = HN_NVS_STATUS_FAILED; | |||||
return (ENODEV); | return (ENODEV); | ||||
} | |||||
rndis_dev = (rndis_device *)net_dev->extension; | rndis_dev = (rndis_device *)net_dev->extension; | ||||
if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) { | if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) | ||||
pkt->status = HN_NVS_STATUS_FAILED; | |||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
rndis_hdr = pkt->data; | rndis_hdr = data; | ||||
switch (rndis_hdr->ndis_msg_type) { | switch (rndis_hdr->ndis_msg_type) { | ||||
/* data message */ | /* data message */ | ||||
case REMOTE_NDIS_PACKET_MSG: | case REMOTE_NDIS_PACKET_MSG: | ||||
hv_rf_receive_data(rxr, rndis_hdr, pkt); | hv_rf_receive_data(rxr, data, dlen); | ||||
break; | break; | ||||
/* completion messages */ | /* completion messages */ | ||||
case REMOTE_NDIS_INITIALIZE_CMPLT: | case REMOTE_NDIS_INITIALIZE_CMPLT: | ||||
case REMOTE_NDIS_QUERY_CMPLT: | case REMOTE_NDIS_QUERY_CMPLT: | ||||
case REMOTE_NDIS_SET_CMPLT: | case REMOTE_NDIS_SET_CMPLT: | ||||
case REMOTE_NDIS_RESET_CMPLT: | case REMOTE_NDIS_RESET_CMPLT: | ||||
case REMOTE_NDIS_KEEPALIVE_CMPLT: | case REMOTE_NDIS_KEEPALIVE_CMPLT: | ||||
hv_rf_receive_response(rndis_dev, rndis_hdr); | hv_rf_receive_response(rndis_dev, rndis_hdr); | ||||
▲ Show 20 Lines • Show All 698 Lines • Show Last 20 Lines |