Commit 4798a2b8 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont Committed by David S. Miller

Phonet: keep TX queue disabled when the device is off

Signed-off-by: default avatarRémi Denis-Courmont <remi.denis-courmont@nokia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eb9b851b
...@@ -155,12 +155,13 @@ static void gprs_data_ready(struct sock *sk, int len) ...@@ -155,12 +155,13 @@ static void gprs_data_ready(struct sock *sk, int len)
static void gprs_write_space(struct sock *sk) static void gprs_write_space(struct sock *sk)
{ {
struct gprs_dev *dev = sk->sk_user_data; struct gprs_dev *dev = sk->sk_user_data;
struct net_device *net = dev->net;
unsigned credits = pep_writeable(sk); unsigned credits = pep_writeable(sk);
spin_lock_bh(&dev->tx_lock); spin_lock_bh(&dev->tx_lock);
dev->tx_max = credits; dev->tx_max = credits;
if (credits > skb_queue_len(&dev->tx_queue)) if (credits > skb_queue_len(&dev->tx_queue) && netif_running(net))
netif_wake_queue(dev->net); netif_wake_queue(net);
spin_unlock_bh(&dev->tx_lock); spin_unlock_bh(&dev->tx_lock);
} }
...@@ -168,6 +169,23 @@ static void gprs_write_space(struct sock *sk) ...@@ -168,6 +169,23 @@ static void gprs_write_space(struct sock *sk)
* Network device callbacks * Network device callbacks
*/ */
static int gprs_open(struct net_device *dev)
{
struct gprs_dev *gp = netdev_priv(dev);
gprs_write_space(gp->sk);
return 0;
}
static int gprs_close(struct net_device *dev)
{
struct gprs_dev *gp = netdev_priv(dev);
netif_stop_queue(dev);
flush_work(&gp->tx_work);
return 0;
}
static int gprs_xmit(struct sk_buff *skb, struct net_device *net) static int gprs_xmit(struct sk_buff *skb, struct net_device *net)
{ {
struct gprs_dev *dev = netdev_priv(net); struct gprs_dev *dev = netdev_priv(net);
...@@ -254,6 +272,8 @@ static void gprs_setup(struct net_device *net) ...@@ -254,6 +272,8 @@ static void gprs_setup(struct net_device *net)
net->tx_queue_len = 10; net->tx_queue_len = 10;
net->destructor = free_netdev; net->destructor = free_netdev;
net->open = gprs_open;
net->stop = gprs_close;
net->hard_start_xmit = gprs_xmit; /* mandatory */ net->hard_start_xmit = gprs_xmit; /* mandatory */
net->change_mtu = gprs_set_mtu; net->change_mtu = gprs_set_mtu;
net->get_stats = gprs_get_stats; net->get_stats = gprs_get_stats;
...@@ -318,7 +338,6 @@ int gprs_attach(struct sock *sk) ...@@ -318,7 +338,6 @@ int gprs_attach(struct sock *sk)
dev->sk = sk; dev->sk = sk;
printk(KERN_DEBUG"%s: attached\n", net->name); printk(KERN_DEBUG"%s: attached\n", net->name);
gprs_write_space(sk); /* kick off TX */
return net->ifindex; return net->ifindex;
out_rel: out_rel:
...@@ -341,7 +360,5 @@ void gprs_detach(struct sock *sk) ...@@ -341,7 +360,5 @@ void gprs_detach(struct sock *sk)
printk(KERN_DEBUG"%s: detached\n", net->name); printk(KERN_DEBUG"%s: detached\n", net->name);
unregister_netdev(net); unregister_netdev(net);
flush_scheduled_work();
sock_put(sk); sock_put(sk);
skb_queue_purge(&dev->tx_queue);
} }
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