Commit 584a270d authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Tim Gardner

hv_netvsc: get rid of struct net_device pointer in struct netvsc_device

BugLink: http://bugs.launchpad.net/bugs/1616677

Simplify netvsvc pointer graph by getting rid of the redundant ndev
pointer. We can always get a pointer to struct net_device from somewhere
else.
Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
(cherry picked from commit 0a1275ca)
Signed-off-by: default avatarTim Gardner <tim.gardner@canonical.com>
Acked-by: default avatarBrad Figg <brad.figg@canonical.com>
Acked-by: default avatarKamal Mostafa <kamal@canonical.com>
parent 449ca62c
...@@ -173,7 +173,6 @@ struct rndis_device { ...@@ -173,7 +173,6 @@ struct rndis_device {
/* Interface */ /* Interface */
struct rndis_message; struct rndis_message;
struct netvsc_device;
int netvsc_device_add(struct hv_device *device, void *additional_info); int netvsc_device_add(struct hv_device *device, void *additional_info);
int netvsc_device_remove(struct hv_device *device); int netvsc_device_remove(struct hv_device *device);
int netvsc_send(struct hv_device *device, int netvsc_send(struct hv_device *device,
...@@ -203,7 +202,7 @@ int rndis_filter_receive(struct hv_device *dev, ...@@ -203,7 +202,7 @@ int rndis_filter_receive(struct hv_device *dev,
int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter); int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac); int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac);
void netvsc_switch_datapath(struct netvsc_device *nv_dev, bool vf); void netvsc_switch_datapath(struct net_device *nv_dev, bool vf);
#define NVSP_INVALID_PROTOCOL_VERSION ((u32)0xFFFFFFFF) #define NVSP_INVALID_PROTOCOL_VERSION ((u32)0xFFFFFFFF)
...@@ -711,8 +710,6 @@ struct netvsc_device { ...@@ -711,8 +710,6 @@ struct netvsc_device {
struct nvsp_message revoke_packet; struct nvsp_message revoke_packet;
/* unsigned char HwMacAddr[HW_MACADDR_LEN]; */ /* unsigned char HwMacAddr[HW_MACADDR_LEN]; */
struct net_device *ndev;
struct vmbus_channel *chn_table[VRSS_CHANNEL_MAX]; struct vmbus_channel *chn_table[VRSS_CHANNEL_MAX];
u32 send_table[VRSS_SEND_TAB_SIZE]; u32 send_table[VRSS_SEND_TAB_SIZE];
u32 max_chn; u32 max_chn;
......
...@@ -37,12 +37,12 @@ ...@@ -37,12 +37,12 @@
* Switch the data path from the synthetic interface to the VF * Switch the data path from the synthetic interface to the VF
* interface. * interface.
*/ */
void netvsc_switch_datapath(struct netvsc_device *nv_dev, bool vf) void netvsc_switch_datapath(struct net_device *ndev, bool vf)
{ {
struct nvsp_message *init_pkt = &nv_dev->channel_init_pkt;
struct net_device *ndev = nv_dev->ndev;
struct net_device_context *net_device_ctx = netdev_priv(ndev); struct net_device_context *net_device_ctx = netdev_priv(ndev);
struct hv_device *dev = net_device_ctx->device_ctx; struct hv_device *dev = net_device_ctx->device_ctx;
struct netvsc_device *nv_dev = net_device_ctx->nvdev;
struct nvsp_message *init_pkt = &nv_dev->channel_init_pkt;
memset(init_pkt, 0, sizeof(struct nvsp_message)); memset(init_pkt, 0, sizeof(struct nvsp_message));
init_pkt->hdr.msg_type = NVSP_MSG4_TYPE_SWITCH_DATA_PATH; init_pkt->hdr.msg_type = NVSP_MSG4_TYPE_SWITCH_DATA_PATH;
...@@ -80,7 +80,6 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) ...@@ -80,7 +80,6 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device)
net_device->destroy = false; net_device->destroy = false;
atomic_set(&net_device->open_cnt, 0); atomic_set(&net_device->open_cnt, 0);
atomic_set(&net_device->vf_use_cnt, 0); atomic_set(&net_device->vf_use_cnt, 0);
net_device->ndev = ndev;
net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT; net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT; net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
...@@ -263,7 +262,7 @@ static int netvsc_init_buf(struct hv_device *device) ...@@ -263,7 +262,7 @@ static int netvsc_init_buf(struct hv_device *device)
net_device = get_outbound_net_device(device); net_device = get_outbound_net_device(device);
if (!net_device) if (!net_device)
return -ENODEV; return -ENODEV;
ndev = net_device->ndev; ndev = hv_get_drvdata(device);
node = cpu_to_node(device->channel->target_cpu); node = cpu_to_node(device->channel->target_cpu);
net_device->recv_buf = vzalloc_node(net_device->recv_buf_size, node); net_device->recv_buf = vzalloc_node(net_device->recv_buf_size, node);
...@@ -453,6 +452,7 @@ static int negotiate_nvsp_ver(struct hv_device *device, ...@@ -453,6 +452,7 @@ static int negotiate_nvsp_ver(struct hv_device *device,
struct nvsp_message *init_packet, struct nvsp_message *init_packet,
u32 nvsp_ver) u32 nvsp_ver)
{ {
struct net_device *ndev = hv_get_drvdata(device);
int ret; int ret;
unsigned long t; unsigned long t;
...@@ -486,8 +486,7 @@ static int negotiate_nvsp_ver(struct hv_device *device, ...@@ -486,8 +486,7 @@ static int negotiate_nvsp_ver(struct hv_device *device,
/* NVSPv2 or later: Send NDIS config */ /* NVSPv2 or later: Send NDIS config */
memset(init_packet, 0, sizeof(struct nvsp_message)); memset(init_packet, 0, sizeof(struct nvsp_message));
init_packet->hdr.msg_type = NVSP_MSG2_TYPE_SEND_NDIS_CONFIG; init_packet->hdr.msg_type = NVSP_MSG2_TYPE_SEND_NDIS_CONFIG;
init_packet->msg.v2_msg.send_ndis_config.mtu = net_device->ndev->mtu + init_packet->msg.v2_msg.send_ndis_config.mtu = ndev->mtu + ETH_HLEN;
ETH_HLEN;
init_packet->msg.v2_msg.send_ndis_config.capability.ieee8021q = 1; init_packet->msg.v2_msg.send_ndis_config.capability.ieee8021q = 1;
if (nvsp_ver >= NVSP_PROTOCOL_VERSION_5) if (nvsp_ver >= NVSP_PROTOCOL_VERSION_5)
...@@ -507,7 +506,6 @@ static int netvsc_connect_vsp(struct hv_device *device) ...@@ -507,7 +506,6 @@ static int netvsc_connect_vsp(struct hv_device *device)
struct netvsc_device *net_device; struct netvsc_device *net_device;
struct nvsp_message *init_packet; struct nvsp_message *init_packet;
int ndis_version; int ndis_version;
struct net_device *ndev;
u32 ver_list[] = { NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2, u32 ver_list[] = { NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2,
NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5 }; NVSP_PROTOCOL_VERSION_4, NVSP_PROTOCOL_VERSION_5 };
int i, num_ver = 4; /* number of different NVSP versions */ int i, num_ver = 4; /* number of different NVSP versions */
...@@ -515,7 +513,6 @@ static int netvsc_connect_vsp(struct hv_device *device) ...@@ -515,7 +513,6 @@ static int netvsc_connect_vsp(struct hv_device *device)
net_device = get_outbound_net_device(device); net_device = get_outbound_net_device(device);
if (!net_device) if (!net_device)
return -ENODEV; return -ENODEV;
ndev = net_device->ndev;
init_packet = &net_device->channel_init_pkt; init_packet = &net_device->channel_init_pkt;
...@@ -768,6 +765,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device *net_device, ...@@ -768,6 +765,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device *net_device,
} }
static inline int netvsc_send_pkt( static inline int netvsc_send_pkt(
struct hv_device *device,
struct hv_netvsc_packet *packet, struct hv_netvsc_packet *packet,
struct netvsc_device *net_device, struct netvsc_device *net_device,
struct hv_page_buffer **pb, struct hv_page_buffer **pb,
...@@ -776,7 +774,7 @@ static inline int netvsc_send_pkt( ...@@ -776,7 +774,7 @@ static inline int netvsc_send_pkt(
struct nvsp_message nvmsg; struct nvsp_message nvmsg;
u16 q_idx = packet->q_idx; u16 q_idx = packet->q_idx;
struct vmbus_channel *out_channel = net_device->chn_table[q_idx]; struct vmbus_channel *out_channel = net_device->chn_table[q_idx];
struct net_device *ndev = net_device->ndev; struct net_device *ndev = hv_get_drvdata(device);
u64 req_id; u64 req_id;
int ret; int ret;
struct hv_page_buffer *pgbuf; struct hv_page_buffer *pgbuf;
...@@ -971,7 +969,8 @@ int netvsc_send(struct hv_device *device, ...@@ -971,7 +969,8 @@ int netvsc_send(struct hv_device *device,
} }
if (msd_send) { if (msd_send) {
m_ret = netvsc_send_pkt(msd_send, net_device, NULL, msd_skb); m_ret = netvsc_send_pkt(device, msd_send, net_device,
NULL, msd_skb);
if (m_ret != 0) { if (m_ret != 0) {
netvsc_free_send_slot(net_device, netvsc_free_send_slot(net_device,
...@@ -982,7 +981,7 @@ int netvsc_send(struct hv_device *device, ...@@ -982,7 +981,7 @@ int netvsc_send(struct hv_device *device,
send_now: send_now:
if (cur_send) if (cur_send)
ret = netvsc_send_pkt(cur_send, net_device, pb, skb); ret = netvsc_send_pkt(device, cur_send, net_device, pb, skb);
if (ret != 0 && section_index != NETVSC_INVALID_INDEX) if (ret != 0 && section_index != NETVSC_INVALID_INDEX)
netvsc_free_send_slot(net_device, section_index); netvsc_free_send_slot(net_device, section_index);
...@@ -998,9 +997,7 @@ static void netvsc_send_recv_completion(struct hv_device *device, ...@@ -998,9 +997,7 @@ static void netvsc_send_recv_completion(struct hv_device *device,
struct nvsp_message recvcompMessage; struct nvsp_message recvcompMessage;
int retries = 0; int retries = 0;
int ret; int ret;
struct net_device *ndev; struct net_device *ndev = hv_get_drvdata(device);
ndev = net_device->ndev;
recvcompMessage.hdr.msg_type = recvcompMessage.hdr.msg_type =
NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE; NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE;
...@@ -1047,11 +1044,9 @@ static void netvsc_receive(struct netvsc_device *net_device, ...@@ -1047,11 +1044,9 @@ static void netvsc_receive(struct netvsc_device *net_device,
u32 status = NVSP_STAT_SUCCESS; u32 status = NVSP_STAT_SUCCESS;
int i; int i;
int count = 0; int count = 0;
struct net_device *ndev; struct net_device *ndev = hv_get_drvdata(device);
void *data; void *data;
ndev = net_device->ndev;
/* /*
* All inbound packets other than send completion should be xfer page * All inbound packets other than send completion should be xfer page
* packet * packet
...@@ -1107,14 +1102,13 @@ static void netvsc_send_table(struct hv_device *hdev, ...@@ -1107,14 +1102,13 @@ static void netvsc_send_table(struct hv_device *hdev,
struct nvsp_message *nvmsg) struct nvsp_message *nvmsg)
{ {
struct netvsc_device *nvscdev; struct netvsc_device *nvscdev;
struct net_device *ndev; struct net_device *ndev = hv_get_drvdata(hdev);
int i; int i;
u32 count, *tab; u32 count, *tab;
nvscdev = get_outbound_net_device(hdev); nvscdev = get_outbound_net_device(hdev);
if (!nvscdev) if (!nvscdev)
return; return;
ndev = nvscdev->ndev;
count = nvmsg->msg.v5_msg.send_table.count; count = nvmsg->msg.v5_msg.send_table.count;
if (count != VRSS_SEND_TAB_SIZE) { if (count != VRSS_SEND_TAB_SIZE) {
...@@ -1173,7 +1167,7 @@ void netvsc_channel_cb(void *context) ...@@ -1173,7 +1167,7 @@ void netvsc_channel_cb(void *context)
net_device = get_inbound_net_device(device); net_device = get_inbound_net_device(device);
if (!net_device) if (!net_device)
return; return;
ndev = net_device->ndev; ndev = hv_get_drvdata(device);
buffer = get_per_channel_state(channel); buffer = get_per_channel_state(channel);
do { do {
......
...@@ -67,18 +67,19 @@ static void do_set_multicast(struct work_struct *w) ...@@ -67,18 +67,19 @@ static void do_set_multicast(struct work_struct *w)
{ {
struct net_device_context *ndevctx = struct net_device_context *ndevctx =
container_of(w, struct net_device_context, work); container_of(w, struct net_device_context, work);
struct netvsc_device *nvdev; struct hv_device *device_obj = ndevctx->device_ctx;
struct net_device *ndev = hv_get_drvdata(device_obj);
struct netvsc_device *nvdev = ndevctx->nvdev;
struct rndis_device *rdev; struct rndis_device *rdev;
nvdev = ndevctx->nvdev; if (!nvdev)
if (nvdev == NULL || nvdev->ndev == NULL)
return; return;
rdev = nvdev->extension; rdev = nvdev->extension;
if (rdev == NULL) if (rdev == NULL)
return; return;
if (nvdev->ndev->flags & IFF_PROMISC) if (ndev->flags & IFF_PROMISC)
rndis_filter_set_packet_filter(rdev, rndis_filter_set_packet_filter(rdev,
NDIS_PACKET_TYPE_PROMISCUOUS); NDIS_PACKET_TYPE_PROMISCUOUS);
else else
...@@ -1050,23 +1051,22 @@ static const struct net_device_ops device_ops = { ...@@ -1050,23 +1051,22 @@ static const struct net_device_ops device_ops = {
*/ */
static void netvsc_link_change(struct work_struct *w) static void netvsc_link_change(struct work_struct *w)
{ {
struct net_device_context *ndev_ctx; struct net_device_context *ndev_ctx =
struct net_device *net; container_of(w, struct net_device_context, dwork.work);
struct hv_device *device_obj = ndev_ctx->device_ctx;
struct net_device *net = hv_get_drvdata(device_obj);
struct netvsc_device *net_device; struct netvsc_device *net_device;
struct rndis_device *rdev; struct rndis_device *rdev;
struct netvsc_reconfig *event = NULL; struct netvsc_reconfig *event = NULL;
bool notify = false, reschedule = false; bool notify = false, reschedule = false;
unsigned long flags, next_reconfig, delay; unsigned long flags, next_reconfig, delay;
ndev_ctx = container_of(w, struct net_device_context, dwork.work);
rtnl_lock(); rtnl_lock();
if (ndev_ctx->start_remove) if (ndev_ctx->start_remove)
goto out_unlock; goto out_unlock;
net_device = ndev_ctx->nvdev; net_device = ndev_ctx->nvdev;
rdev = net_device->extension; rdev = net_device->extension;
net = net_device->ndev;
next_reconfig = ndev_ctx->last_reconfig + LINKCHANGE_INT; next_reconfig = ndev_ctx->last_reconfig + LINKCHANGE_INT;
if (time_is_after_jiffies(next_reconfig)) { if (time_is_after_jiffies(next_reconfig)) {
...@@ -1167,10 +1167,9 @@ static void netvsc_notify_peers(struct work_struct *wrk) ...@@ -1167,10 +1167,9 @@ static void netvsc_notify_peers(struct work_struct *wrk)
atomic_dec(&gwrk->netvsc_dev->vf_use_cnt); atomic_dec(&gwrk->netvsc_dev->vf_use_cnt);
} }
static struct netvsc_device *get_netvsc_device(char *mac) static struct net_device *get_netvsc_net_device(char *mac)
{ {
struct net_device *dev; struct net_device *dev, *found = NULL;
struct net_device_context *netvsc_ctx = NULL;
int rtnl_locked; int rtnl_locked;
rtnl_locked = rtnl_trylock(); rtnl_locked = rtnl_trylock();
...@@ -1179,21 +1178,20 @@ static struct netvsc_device *get_netvsc_device(char *mac) ...@@ -1179,21 +1178,20 @@ static struct netvsc_device *get_netvsc_device(char *mac)
if (memcmp(dev->dev_addr, mac, ETH_ALEN) == 0) { if (memcmp(dev->dev_addr, mac, ETH_ALEN) == 0) {
if (dev->netdev_ops != &device_ops) if (dev->netdev_ops != &device_ops)
continue; continue;
netvsc_ctx = netdev_priv(dev); found = dev;
break; break;
} }
} }
if (rtnl_locked) if (rtnl_locked)
rtnl_unlock(); rtnl_unlock();
if (netvsc_ctx == NULL) return found;
return NULL;
return netvsc_ctx->nvdev;
} }
static int netvsc_register_vf(struct net_device *vf_netdev) static int netvsc_register_vf(struct net_device *vf_netdev)
{ {
struct net_device *ndev;
struct net_device_context *net_device_ctx;
struct netvsc_device *netvsc_dev; struct netvsc_device *netvsc_dev;
const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops; const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops;
...@@ -1205,11 +1203,16 @@ static int netvsc_register_vf(struct net_device *vf_netdev) ...@@ -1205,11 +1203,16 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
* associate with the VF interface. If we don't find a matching * associate with the VF interface. If we don't find a matching
* synthetic interface, move on. * synthetic interface, move on.
*/ */
netvsc_dev = get_netvsc_device(vf_netdev->dev_addr); ndev = get_netvsc_net_device(vf_netdev->dev_addr);
if (!ndev)
return NOTIFY_DONE;
net_device_ctx = netdev_priv(ndev);
netvsc_dev = net_device_ctx->nvdev;
if (netvsc_dev == NULL) if (netvsc_dev == NULL)
return NOTIFY_DONE; return NOTIFY_DONE;
netdev_info(netvsc_dev->ndev, "VF registering: %s\n", vf_netdev->name); netdev_info(ndev, "VF registering: %s\n", vf_netdev->name);
/* /*
* Take a reference on the module. * Take a reference on the module.
*/ */
...@@ -1221,6 +1224,7 @@ static int netvsc_register_vf(struct net_device *vf_netdev) ...@@ -1221,6 +1224,7 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
static int netvsc_vf_up(struct net_device *vf_netdev) static int netvsc_vf_up(struct net_device *vf_netdev)
{ {
struct net_device *ndev;
struct netvsc_device *netvsc_dev; struct netvsc_device *netvsc_dev;
const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops; const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops;
struct net_device_context *net_device_ctx; struct net_device_context *net_device_ctx;
...@@ -1228,13 +1232,17 @@ static int netvsc_vf_up(struct net_device *vf_netdev) ...@@ -1228,13 +1232,17 @@ static int netvsc_vf_up(struct net_device *vf_netdev)
if (eth_ops == &ethtool_ops) if (eth_ops == &ethtool_ops)
return NOTIFY_DONE; return NOTIFY_DONE;
netvsc_dev = get_netvsc_device(vf_netdev->dev_addr); ndev = get_netvsc_net_device(vf_netdev->dev_addr);
if (!ndev)
return NOTIFY_DONE;
net_device_ctx = netdev_priv(ndev);
netvsc_dev = net_device_ctx->nvdev;
if ((netvsc_dev == NULL) || (netvsc_dev->vf_netdev == NULL)) if ((netvsc_dev == NULL) || (netvsc_dev->vf_netdev == NULL))
return NOTIFY_DONE; return NOTIFY_DONE;
netdev_info(netvsc_dev->ndev, "VF up: %s\n", vf_netdev->name); netdev_info(ndev, "VF up: %s\n", vf_netdev->name);
net_device_ctx = netdev_priv(netvsc_dev->ndev);
netvsc_dev->vf_inject = true; netvsc_dev->vf_inject = true;
/* /*
...@@ -1245,11 +1253,10 @@ static int netvsc_vf_up(struct net_device *vf_netdev) ...@@ -1245,11 +1253,10 @@ static int netvsc_vf_up(struct net_device *vf_netdev)
/* /*
* notify the host to switch the data path. * notify the host to switch the data path.
*/ */
netvsc_switch_datapath(netvsc_dev, true); netvsc_switch_datapath(ndev, true);
netdev_info(netvsc_dev->ndev, "Data path switched to VF: %s\n", netdev_info(ndev, "Data path switched to VF: %s\n", vf_netdev->name);
vf_netdev->name);
netif_carrier_off(netvsc_dev->ndev); netif_carrier_off(ndev);
/* /*
* Now notify peers. We are scheduling work to * Now notify peers. We are scheduling work to
...@@ -1267,6 +1274,7 @@ static int netvsc_vf_up(struct net_device *vf_netdev) ...@@ -1267,6 +1274,7 @@ static int netvsc_vf_up(struct net_device *vf_netdev)
static int netvsc_vf_down(struct net_device *vf_netdev) static int netvsc_vf_down(struct net_device *vf_netdev)
{ {
struct net_device *ndev;
struct netvsc_device *netvsc_dev; struct netvsc_device *netvsc_dev;
struct net_device_context *net_device_ctx; struct net_device_context *net_device_ctx;
const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops; const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops;
...@@ -1274,13 +1282,17 @@ static int netvsc_vf_down(struct net_device *vf_netdev) ...@@ -1274,13 +1282,17 @@ static int netvsc_vf_down(struct net_device *vf_netdev)
if (eth_ops == &ethtool_ops) if (eth_ops == &ethtool_ops)
return NOTIFY_DONE; return NOTIFY_DONE;
netvsc_dev = get_netvsc_device(vf_netdev->dev_addr); ndev = get_netvsc_net_device(vf_netdev->dev_addr);
if (!ndev)
return NOTIFY_DONE;
net_device_ctx = netdev_priv(ndev);
netvsc_dev = net_device_ctx->nvdev;
if ((netvsc_dev == NULL) || (netvsc_dev->vf_netdev == NULL)) if ((netvsc_dev == NULL) || (netvsc_dev->vf_netdev == NULL))
return NOTIFY_DONE; return NOTIFY_DONE;
netdev_info(netvsc_dev->ndev, "VF down: %s\n", vf_netdev->name); netdev_info(ndev, "VF down: %s\n", vf_netdev->name);
net_device_ctx = netdev_priv(netvsc_dev->ndev);
netvsc_dev->vf_inject = false; netvsc_dev->vf_inject = false;
/* /*
* Wait for currently active users to * Wait for currently active users to
...@@ -1289,16 +1301,15 @@ static int netvsc_vf_down(struct net_device *vf_netdev) ...@@ -1289,16 +1301,15 @@ static int netvsc_vf_down(struct net_device *vf_netdev)
while (atomic_read(&netvsc_dev->vf_use_cnt) != 0) while (atomic_read(&netvsc_dev->vf_use_cnt) != 0)
udelay(50); udelay(50);
netvsc_switch_datapath(netvsc_dev, false); netvsc_switch_datapath(ndev, false);
netdev_info(netvsc_dev->ndev, "Data path switched from VF: %s\n", netdev_info(ndev, "Data path switched from VF: %s\n", vf_netdev->name);
vf_netdev->name);
rndis_filter_close(net_device_ctx->device_ctx); rndis_filter_close(net_device_ctx->device_ctx);
netif_carrier_on(netvsc_dev->ndev); netif_carrier_on(ndev);
/* /*
* Notify peers. * Notify peers.
*/ */
atomic_inc(&netvsc_dev->vf_use_cnt); atomic_inc(&netvsc_dev->vf_use_cnt);
net_device_ctx->gwrk.netdev = netvsc_dev->ndev; net_device_ctx->gwrk.netdev = ndev;
net_device_ctx->gwrk.netvsc_dev = netvsc_dev; net_device_ctx->gwrk.netvsc_dev = netvsc_dev;
schedule_work(&net_device_ctx->gwrk.dwrk); schedule_work(&net_device_ctx->gwrk.dwrk);
...@@ -1308,17 +1319,23 @@ static int netvsc_vf_down(struct net_device *vf_netdev) ...@@ -1308,17 +1319,23 @@ static int netvsc_vf_down(struct net_device *vf_netdev)
static int netvsc_unregister_vf(struct net_device *vf_netdev) static int netvsc_unregister_vf(struct net_device *vf_netdev)
{ {
struct net_device *ndev;
struct netvsc_device *netvsc_dev; struct netvsc_device *netvsc_dev;
const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops; const struct ethtool_ops *eth_ops = vf_netdev->ethtool_ops;
struct net_device_context *net_device_ctx;
if (eth_ops == &ethtool_ops) if (eth_ops == &ethtool_ops)
return NOTIFY_DONE; return NOTIFY_DONE;
netvsc_dev = get_netvsc_device(vf_netdev->dev_addr); ndev = get_netvsc_net_device(vf_netdev->dev_addr);
if (!ndev)
return NOTIFY_DONE;
net_device_ctx = netdev_priv(ndev);
netvsc_dev = net_device_ctx->nvdev;
if (netvsc_dev == NULL) if (netvsc_dev == NULL)
return NOTIFY_DONE; return NOTIFY_DONE;
netdev_info(netvsc_dev->ndev, "VF unregistering: %s\n", netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name);
vf_netdev->name);
netvsc_dev->vf_netdev = NULL; netvsc_dev->vf_netdev = NULL;
module_put(THIS_MODULE); module_put(THIS_MODULE);
......
...@@ -1061,8 +1061,8 @@ int rndis_filter_device_add(struct hv_device *dev, ...@@ -1061,8 +1061,8 @@ int rndis_filter_device_add(struct hv_device *dev,
ret = rndis_filter_query_device(rndis_device, ret = rndis_filter_query_device(rndis_device,
RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
&mtu, &size); &mtu, &size);
if (ret == 0 && size == sizeof(u32) && mtu < net_device->ndev->mtu) if (ret == 0 && size == sizeof(u32) && mtu < net->mtu)
net_device->ndev->mtu = mtu; net->mtu = mtu;
/* Get the mac address */ /* Get the mac address */
ret = rndis_filter_query_device_mac(rndis_device); ret = rndis_filter_query_device_mac(rndis_device);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment