Commit 578bdec4 authored by Andrey Shvetsov's avatar Andrey Shvetsov Committed by Greg Kroah-Hartman

staging: most: allocate private net_dev_context with the alloc_netdev

This moves the allocation of the net_dev to the aim_probe_channel() and
uses the parameter sizeof_priv of the function alloc_netdev to reserve
the space for the struct net_dev_context.

As a side effect, the nd->dev always points to the existing net_dev.
Signed-off-by: default avatarAndrey Shvetsov <andrey.shvetsov@k2l.de>
Signed-off-by: default avatarChristian Gromm <christian.gromm@microchip.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d5451608
...@@ -154,14 +154,12 @@ static int skb_to_mep(const struct sk_buff *skb, struct mbo *mbo) ...@@ -154,14 +154,12 @@ static int skb_to_mep(const struct sk_buff *skb, struct mbo *mbo)
static int most_nd_set_mac_address(struct net_device *dev, void *p) static int most_nd_set_mac_address(struct net_device *dev, void *p)
{ {
struct net_dev_context *nd = dev->ml_priv; struct net_dev_context *nd = netdev_priv(dev);
int err = eth_mac_addr(dev, p); int err = eth_mac_addr(dev, p);
if (err) if (err)
return err; return err;
BUG_ON(nd->dev != dev);
nd->is_mamac = nd->is_mamac =
(dev->dev_addr[0] == 0 && dev->dev_addr[1] == 0 && (dev->dev_addr[0] == 0 && dev->dev_addr[1] == 0 &&
dev->dev_addr[2] == 0 && dev->dev_addr[3] == 0); dev->dev_addr[2] == 0 && dev->dev_addr[3] == 0);
...@@ -180,12 +178,10 @@ static void on_netinfo(struct most_interface *iface, ...@@ -180,12 +178,10 @@ static void on_netinfo(struct most_interface *iface,
static int most_nd_open(struct net_device *dev) static int most_nd_open(struct net_device *dev)
{ {
struct net_dev_context *nd = dev->ml_priv; struct net_dev_context *nd = netdev_priv(dev);
netdev_info(dev, "open net device\n"); netdev_info(dev, "open net device\n");
BUG_ON(nd->dev != dev);
BUG_ON(!nd->tx.linked || !nd->rx.linked); BUG_ON(!nd->tx.linked || !nd->rx.linked);
if (most_start_channel(nd->iface, nd->rx.ch_id, &aim)) { if (most_start_channel(nd->iface, nd->rx.ch_id, &aim)) {
...@@ -212,11 +208,10 @@ static int most_nd_open(struct net_device *dev) ...@@ -212,11 +208,10 @@ static int most_nd_open(struct net_device *dev)
static int most_nd_stop(struct net_device *dev) static int most_nd_stop(struct net_device *dev)
{ {
struct net_dev_context *nd = dev->ml_priv; struct net_dev_context *nd = netdev_priv(dev);
netdev_info(dev, "stop net device\n"); netdev_info(dev, "stop net device\n");
BUG_ON(nd->dev != dev);
netif_stop_queue(dev); netif_stop_queue(dev);
if (nd->iface->request_netinfo) if (nd->iface->request_netinfo)
nd->iface->request_netinfo(nd->iface, nd->tx.ch_id, NULL); nd->iface->request_netinfo(nd->iface, nd->tx.ch_id, NULL);
...@@ -229,12 +224,10 @@ static int most_nd_stop(struct net_device *dev) ...@@ -229,12 +224,10 @@ static int most_nd_stop(struct net_device *dev)
static netdev_tx_t most_nd_start_xmit(struct sk_buff *skb, static netdev_tx_t most_nd_start_xmit(struct sk_buff *skb,
struct net_device *dev) struct net_device *dev)
{ {
struct net_dev_context *nd = dev->ml_priv; struct net_dev_context *nd = netdev_priv(dev);
struct mbo *mbo; struct mbo *mbo;
int ret; int ret;
BUG_ON(nd->dev != dev);
mbo = most_get_mbo(nd->iface, nd->tx.ch_id, &aim); mbo = most_get_mbo(nd->iface, nd->tx.ch_id, &aim);
if (!mbo) { if (!mbo) {
...@@ -275,18 +268,6 @@ static void most_nd_setup(struct net_device *dev) ...@@ -275,18 +268,6 @@ static void most_nd_setup(struct net_device *dev)
dev->netdev_ops = &most_nd_ops; dev->netdev_ops = &most_nd_ops;
} }
static void most_net_rm_netdev_safe(struct net_dev_context *nd)
{
if (!nd->dev)
return;
pr_info("remove net device %p\n", nd->dev);
unregister_netdev(nd->dev);
free_netdev(nd->dev);
nd->dev = NULL;
}
static struct net_dev_context *get_net_dev_context( static struct net_dev_context *get_net_dev_context(
struct most_interface *iface) struct most_interface *iface)
{ {
...@@ -321,11 +302,16 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx, ...@@ -321,11 +302,16 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx,
nd = get_net_dev_context(iface); nd = get_net_dev_context(iface);
if (!nd) { if (!nd) {
nd = kzalloc(sizeof(*nd), GFP_KERNEL); struct net_device *dev;
if (!nd)
dev = alloc_netdev(sizeof(struct net_dev_context), "meth%d",
NET_NAME_UNKNOWN, most_nd_setup);
if (!dev)
return -ENOMEM; return -ENOMEM;
nd = netdev_priv(dev);
nd->iface = iface; nd->iface = iface;
nd->dev = dev;
spin_lock_irqsave(&list_lock, flags); spin_lock_irqsave(&list_lock, flags);
list_add(&nd->list, &net_devices); list_add(&nd->list, &net_devices);
...@@ -338,31 +324,13 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx, ...@@ -338,31 +324,13 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx,
return -EINVAL; return -EINVAL;
} }
if (nd->tx.linked || nd->rx.linked) {
struct net_device *dev =
alloc_netdev(0, "meth%d", NET_NAME_UNKNOWN,
most_nd_setup);
if (!dev) {
pr_err("no memory for net_device\n");
return -ENOMEM;
}
nd->dev = dev;
ch->ch_id = channel_idx;
ch->linked = true;
dev->ml_priv = nd;
if (register_netdev(dev)) {
pr_err("registering net device failed\n");
ch->linked = false;
free_netdev(dev);
return -EINVAL;
}
}
ch->ch_id = channel_idx; ch->ch_id = channel_idx;
ch->linked = true; ch->linked = true;
if (nd->tx.linked && nd->rx.linked && register_netdev(nd->dev)) {
pr_err("register_netdev() failed\n");
ch->linked = false;
return -EINVAL;
}
return 0; return 0;
} }
...@@ -385,19 +353,19 @@ static int aim_disconnect_channel(struct most_interface *iface, ...@@ -385,19 +353,19 @@ static int aim_disconnect_channel(struct most_interface *iface,
else else
return -EINVAL; return -EINVAL;
ch->linked = false;
/* /*
* do not call most_stop_channel() here, because channels are * do not call most_stop_channel() here, because channels are
* going to be closed in ndo_stop() after unregister_netdev() * going to be closed in ndo_stop() after unregister_netdev()
*/ */
most_net_rm_netdev_safe(nd); if (nd->rx.linked && nd->tx.linked)
unregister_netdev(nd->dev);
ch->linked = false;
if (!nd->rx.linked && !nd->tx.linked) { if (!nd->rx.linked && !nd->tx.linked) {
spin_lock_irqsave(&list_lock, flags); spin_lock_irqsave(&list_lock, flags);
list_del(&nd->list); list_del(&nd->list);
spin_unlock_irqrestore(&list_lock, flags); spin_unlock_irqrestore(&list_lock, flags);
kfree(nd); free_netdev(nd->dev);
} }
return 0; return 0;
...@@ -412,9 +380,6 @@ static int aim_resume_tx_channel(struct most_interface *iface, ...@@ -412,9 +380,6 @@ static int aim_resume_tx_channel(struct most_interface *iface,
if (!nd || nd->tx.ch_id != channel_idx) if (!nd || nd->tx.ch_id != channel_idx)
return 0; return 0;
if (!nd->dev)
return 0;
netif_wake_queue(nd->dev); netif_wake_queue(nd->dev);
return 0; return 0;
} }
...@@ -434,10 +399,6 @@ static int aim_rx_data(struct mbo *mbo) ...@@ -434,10 +399,6 @@ static int aim_rx_data(struct mbo *mbo)
return -EIO; return -EIO;
dev = nd->dev; dev = nd->dev;
if (!dev) {
pr_err_once("drop packet: missing net_device\n");
return -EIO;
}
if (nd->is_mamac) { if (nd->is_mamac) {
if (!PMS_IS_MAMAC(buf, len)) if (!PMS_IS_MAMAC(buf, len))
...@@ -531,8 +492,6 @@ static void on_netinfo(struct most_interface *iface, ...@@ -531,8 +492,6 @@ static void on_netinfo(struct most_interface *iface,
return; return;
dev = nd->dev; dev = nd->dev;
if (!dev)
return;
if (link_stat) if (link_stat)
netif_carrier_on(dev); netif_carrier_on(dev);
......
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