summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv/netvsc/hv_net_vsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/hyperv/netvsc/hv_net_vsc.c')
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.c148
1 files changed, 59 insertions, 89 deletions
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c
index a62f450..a3fe0e2 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -57,31 +57,30 @@ MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
* Forward declarations
*/
static void hv_nv_on_channel_callback(void *xchan);
-static int hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device);
-static int hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device);
+static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc);
+static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *);
static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
-static int hv_nv_connect_to_vsp(struct hv_device *device);
+static int hv_nv_connect_to_vsp(struct hn_softc *sc);
static void hv_nv_on_send_completion(netvsc_dev *net_dev,
- struct hv_device *device, struct hv_vmbus_channel *, hv_vm_packet_descriptor *pkt);
+ struct hv_vmbus_channel *, hv_vm_packet_descriptor *pkt);
static void hv_nv_on_receive_completion(struct hv_vmbus_channel *chan,
uint64_t tid, uint32_t status);
static void hv_nv_on_receive(netvsc_dev *net_dev,
- struct hv_device *device, struct hv_vmbus_channel *chan,
+ struct hn_softc *sc, struct hv_vmbus_channel *chan,
hv_vm_packet_descriptor *pkt);
/*
*
*/
static inline netvsc_dev *
-hv_nv_alloc_net_device(struct hv_device *device)
+hv_nv_alloc_net_device(struct hn_softc *sc)
{
netvsc_dev *net_dev;
- hn_softc_t *sc = device_get_softc(device->device);
net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO);
- net_dev->dev = device;
+ net_dev->sc = sc;
net_dev->destroy = FALSE;
sc->net_dev = net_dev;
@@ -89,43 +88,21 @@ hv_nv_alloc_net_device(struct hv_device *device)
}
/*
- *
+ * XXX unnecessary; nuke it.
*/
static inline netvsc_dev *
-hv_nv_get_outbound_net_device(struct hv_device *device)
+hv_nv_get_outbound_net_device(struct hn_softc *sc)
{
- hn_softc_t *sc = device_get_softc(device->device);
- netvsc_dev *net_dev = sc->net_dev;;
-
- if ((net_dev != NULL) && net_dev->destroy) {
- return (NULL);
- }
-
- return (net_dev);
+ return sc->net_dev;
}
/*
- *
+ * XXX unnecessary; nuke it.
*/
static inline netvsc_dev *
-hv_nv_get_inbound_net_device(struct hv_device *device)
+hv_nv_get_inbound_net_device(struct hn_softc *sc)
{
- hn_softc_t *sc = device_get_softc(device->device);
- netvsc_dev *net_dev = sc->net_dev;;
-
- if (net_dev == NULL) {
- return (net_dev);
- }
- /*
- * When the device is being destroyed; we only
- * permit incoming packets if and only if there
- * are outstanding sends.
- */
- if (net_dev->destroy) {
- return (NULL);
- }
-
- return (net_dev);
+ return sc->net_dev;
}
int
@@ -163,13 +140,13 @@ hv_nv_get_next_send_section(netvsc_dev *net_dev)
* Hyper-V extensible switch and the synthetic data path.
*/
static int
-hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device)
+hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
{
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
int ret = 0;
- net_dev = hv_nv_get_outbound_net_device(device);
+ net_dev = hv_nv_get_outbound_net_device(sc);
if (!net_dev) {
return (ENODEV);
}
@@ -184,7 +161,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device)
* GPADL: Guest physical address descriptor list.
*/
ret = hv_vmbus_channel_establish_gpadl(
- device->channel, net_dev->rx_buf,
+ sc->hn_prichan, net_dev->rx_buf,
net_dev->rx_buf_size, &net_dev->rx_buf_gpadl_handle);
if (ret != 0) {
goto cleanup;
@@ -205,7 +182,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device)
/* Send the gpadl notification request */
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -255,13 +232,13 @@ exit:
* Net VSC initialize send buffer with net VSP
*/
static int
-hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device)
+hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
{
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
int ret = 0;
- net_dev = hv_nv_get_outbound_net_device(device);
+ net_dev = hv_nv_get_outbound_net_device(sc);
if (!net_dev) {
return (ENODEV);
}
@@ -278,7 +255,7 @@ hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device)
* Note: This call uses the vmbus connection rather than the
* channel to establish the gpadl handle.
*/
- ret = hv_vmbus_channel_establish_gpadl(device->channel,
+ ret = hv_vmbus_channel_establish_gpadl(sc->hn_prichan,
net_dev->send_buf, net_dev->send_buf_size,
&net_dev->send_buf_gpadl_handle);
if (ret != 0) {
@@ -299,7 +276,7 @@ hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device)
/* Send the gpadl notification request */
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -359,7 +336,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id =
NETVSC_RECEIVE_BUFFER_ID;
- ret = hv_vmbus_channel_send_packet(net_dev->dev->channel,
+ ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan,
revoke_pkt, sizeof(nvsp_msg),
(uint64_t)(uintptr_t)revoke_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
@@ -375,7 +352,7 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
/* Tear down the gpadl on the vsp end */
if (net_dev->rx_buf_gpadl_handle) {
- ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel,
+ ret = hv_vmbus_channel_teardown_gpdal(net_dev->sc->hn_prichan,
net_dev->rx_buf_gpadl_handle);
/*
* If we failed here, we might as well return and have a leak
@@ -427,7 +404,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id =
NETVSC_SEND_BUFFER_ID;
- ret = hv_vmbus_channel_send_packet(net_dev->dev->channel,
+ ret = hv_vmbus_channel_send_packet(net_dev->sc->hn_prichan,
revoke_pkt, sizeof(nvsp_msg),
(uint64_t)(uintptr_t)revoke_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
@@ -442,7 +419,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
/* Tear down the gpadl on the vsp end */
if (net_dev->send_buf_gpadl_handle) {
- ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel,
+ ret = hv_vmbus_channel_teardown_gpdal(net_dev->sc->hn_prichan,
net_dev->send_buf_gpadl_handle);
/*
@@ -477,7 +454,7 @@ hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
* to the negotiated version, so we cannot rely on that.
*/
static int
-hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
+hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
uint32_t nvsp_ver)
{
nvsp_msg *init_pkt;
@@ -494,7 +471,7 @@ hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;
/* Send the init request */
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -515,13 +492,13 @@ hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
* Not valid for NDIS version 1.
*/
static int
-hv_nv_send_ndis_config(struct hv_device *device, uint32_t mtu)
+hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu)
{
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
int ret;
- net_dev = hv_nv_get_outbound_net_device(device);
+ net_dev = hv_nv_get_outbound_net_device(sc);
if (!net_dev)
return (-ENODEV);
@@ -538,7 +515,7 @@ hv_nv_send_ndis_config(struct hv_device *device, uint32_t mtu)
= 1;
/* Send the configuration packet */
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
if (ret != 0)
@@ -551,7 +528,7 @@ hv_nv_send_ndis_config(struct hv_device *device, uint32_t mtu)
* Net VSC connect to VSP
*/
static int
-hv_nv_connect_to_vsp(struct hv_device *device)
+hv_nv_connect_to_vsp(struct hn_softc *sc)
{
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
@@ -563,20 +540,16 @@ hv_nv_connect_to_vsp(struct hv_device *device)
int i;
int protocol_number = nitems(protocol_list);
int ret = 0;
- device_t dev = device->device;
- hn_softc_t *sc = device_get_softc(dev);
+ device_t dev = sc->hn_dev;
struct ifnet *ifp = sc->arpcom.ac_ifp;
- net_dev = hv_nv_get_outbound_net_device(device);
- if (!net_dev) {
- return (ENODEV);
- }
+ net_dev = hv_nv_get_outbound_net_device(sc);
/*
* Negotiate the NVSP version. Try the latest NVSP first.
*/
for (i = protocol_number - 1; i >= 0; i--) {
- if (hv_nv_negotiate_nvsp_protocol(device, net_dev,
+ if (hv_nv_negotiate_nvsp_protocol(sc, net_dev,
protocol_list[i]) == 0) {
net_dev->nvsp_version = protocol_list[i];
if (bootverbose)
@@ -598,7 +571,7 @@ hv_nv_connect_to_vsp(struct hv_device *device)
* This needs to be right after the NVSP init message per Haiyang
*/
if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
- ret = hv_nv_send_ndis_config(device, ifp->if_mtu);
+ ret = hv_nv_send_ndis_config(sc, ifp->if_mtu);
/*
* Send the NDIS version
@@ -621,7 +594,7 @@ hv_nv_connect_to_vsp(struct hv_device *device)
/* Send the init request */
- ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
+ ret = hv_vmbus_channel_send_packet(sc->hn_prichan, init_pkt,
sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
if (ret != 0) {
@@ -642,9 +615,9 @@ hv_nv_connect_to_vsp(struct hv_device *device)
net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
- ret = hv_nv_init_rx_buffer_with_net_vsp(device);
+ ret = hv_nv_init_rx_buffer_with_net_vsp(sc);
if (ret == 0)
- ret = hv_nv_init_send_buffer_with_net_vsp(device);
+ ret = hv_nv_init_send_buffer_with_net_vsp(sc);
cleanup:
return (ret);
@@ -676,13 +649,13 @@ hv_nv_subchan_attach(struct hv_vmbus_channel *chan)
* Callback when the device belonging to this driver is added
*/
netvsc_dev *
-hv_nv_on_device_add(struct hv_device *device, void *additional_info)
+hv_nv_on_device_add(struct hn_softc *sc, void *additional_info)
{
- struct hv_vmbus_channel *chan = device->channel;
+ struct hv_vmbus_channel *chan = sc->hn_prichan;
netvsc_dev *net_dev;
int ret = 0;
- net_dev = hv_nv_alloc_net_device(device);
+ net_dev = hv_nv_alloc_net_device(sc);
if (net_dev == NULL)
return NULL;
@@ -706,7 +679,7 @@ hv_nv_on_device_add(struct hv_device *device, void *additional_info)
/*
* Connect with the NetVsp
*/
- ret = hv_nv_connect_to_vsp(device);
+ ret = hv_nv_connect_to_vsp(sc);
if (ret != 0)
goto close;
@@ -732,9 +705,8 @@ cleanup:
* Net VSC on device remove
*/
int
-hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
+hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
{
- hn_softc_t *sc = device_get_softc(device->device);
netvsc_dev *net_dev = sc->net_dev;;
/* Stop outbound traffic ie sends and receives completions */
@@ -747,12 +719,12 @@ hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
/* Now, we can close the channel safely */
if (!destroy_channel) {
- device->channel->state =
+ sc->hn_prichan->state =
HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE;
}
- free(device->channel->hv_chan_rdbuf, M_NETVSC);
- hv_vmbus_channel_close(device->channel);
+ free(sc->hn_prichan->hv_chan_rdbuf, M_NETVSC);
+ hv_vmbus_channel_close(sc->hn_prichan);
sema_destroy(&net_dev->channel_init_sema);
free(net_dev, M_NETVSC);
@@ -764,8 +736,7 @@ hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
* Net VSC on send completion
*/
static void
-hv_nv_on_send_completion(netvsc_dev *net_dev,
- struct hv_device *device, struct hv_vmbus_channel *chan,
+hv_nv_on_send_completion(netvsc_dev *net_dev, struct hv_vmbus_channel *chan,
hv_vm_packet_descriptor *pkt)
{
nvsp_msg *nvsp_msg_pkt;
@@ -870,14 +841,14 @@ hv_nv_on_send(struct hv_vmbus_channel *chan, netvsc_packet *pkt)
* with virtual addresses.
*/
static void
-hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device,
+hv_nv_on_receive(netvsc_dev *net_dev, struct hn_softc *sc,
struct hv_vmbus_channel *chan, hv_vm_packet_descriptor *pkt)
{
hv_vm_transfer_page_packet_header *vm_xfer_page_pkt;
nvsp_msg *nvsp_msg_pkt;
netvsc_packet vsc_pkt;
netvsc_packet *net_vsc_pkt = &vsc_pkt;
- device_t dev = device->device;
+ device_t dev = sc->hn_dev;
int count = 0;
int i = 0;
int status = nvsp_status_success;
@@ -911,7 +882,6 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device,
}
count = vm_xfer_page_pkt->range_count;
- net_vsc_pkt->device = device;
/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
for (i = 0; i < count; i++) {
@@ -921,7 +891,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device,
net_vsc_pkt->tot_data_buf_len =
vm_xfer_page_pkt->ranges[i].byte_count;
- hv_rf_on_receive(net_dev, device, chan, net_vsc_pkt);
+ hv_rf_on_receive(net_dev, chan, net_vsc_pkt);
if (net_vsc_pkt->status != nvsp_status_success) {
status = nvsp_status_failure;
}
@@ -977,14 +947,14 @@ retry_send_cmplt:
* Net VSC receiving vRSS send table from VSP
*/
static void
-hv_nv_send_table(struct hv_device *device, hv_vm_packet_descriptor *pkt)
+hv_nv_send_table(struct hn_softc *sc, hv_vm_packet_descriptor *pkt)
{
netvsc_dev *net_dev;
nvsp_msg *nvsp_msg_pkt;
int i;
uint32_t count, *table;
- net_dev = hv_nv_get_inbound_net_device(device);
+ net_dev = hv_nv_get_inbound_net_device(sc);
if (!net_dev)
return;
@@ -1020,9 +990,9 @@ static void
hv_nv_on_channel_callback(void *xchan)
{
struct hv_vmbus_channel *chan = xchan;
- struct hv_device *device = chan->device;
+ device_t dev = chan->ch_dev;
+ struct hn_softc *sc = device_get_softc(dev);
netvsc_dev *net_dev;
- device_t dev = device->device;
uint32_t bytes_rxed;
uint64_t request_id;
hv_vm_packet_descriptor *desc;
@@ -1030,7 +1000,7 @@ hv_nv_on_channel_callback(void *xchan)
int bufferlen = NETVSC_PACKET_SIZE;
int ret = 0;
- net_dev = hv_nv_get_inbound_net_device(device);
+ net_dev = hv_nv_get_inbound_net_device(sc);
if (net_dev == NULL)
return;
@@ -1044,14 +1014,14 @@ hv_nv_on_channel_callback(void *xchan)
desc = (hv_vm_packet_descriptor *)buffer;
switch (desc->type) {
case HV_VMBUS_PACKET_TYPE_COMPLETION:
- hv_nv_on_send_completion(net_dev, device,
- chan, desc);
+ hv_nv_on_send_completion(net_dev, chan,
+ desc);
break;
case HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES:
- hv_nv_on_receive(net_dev, device, chan, desc);
+ hv_nv_on_receive(net_dev, sc, chan, desc);
break;
case HV_VMBUS_PACKET_TYPE_DATA_IN_BAND:
- hv_nv_send_table(device, desc);
+ hv_nv_send_table(sc, desc);
break;
default:
device_printf(dev,
OpenPOWER on IntegriCloud