aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm/br2684.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/atm/br2684.c')
-rw-r--r--net/atm/br2684.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 2912665fc58c..26a646d4eb32 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -69,7 +69,7 @@ struct br2684_vcc {
69 struct net_device *device; 69 struct net_device *device;
70 /* keep old push, pop functions for chaining */ 70 /* keep old push, pop functions for chaining */
71 void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb); 71 void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb);
72 /* void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb); */ 72 void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
73 enum br2684_encaps encaps; 73 enum br2684_encaps encaps;
74 struct list_head brvccs; 74 struct list_head brvccs;
75#ifdef CONFIG_ATM_BR2684_IPFILTER 75#ifdef CONFIG_ATM_BR2684_IPFILTER
@@ -142,6 +142,22 @@ static struct net_device *br2684_find_dev(const struct br2684_if_spec *s)
142 return NULL; 142 return NULL;
143} 143}
144 144
145/* chained vcc->pop function. Check if we should wake the netif_queue */
146static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb)
147{
148 struct br2684_vcc *brvcc = BR2684_VCC(vcc);
149 struct net_device *net_dev = skb->dev;
150
151 pr_debug("br2684_pop(vcc %p ; net_dev %p )\n", vcc, net_dev);
152 brvcc->old_pop(vcc, skb);
153
154 if (!net_dev)
155 return;
156
157 if (atm_may_send(vcc, 0))
158 netif_wake_queue(net_dev);
159
160}
145/* 161/*
146 * Send a packet out a particular vcc. Not to useful right now, but paves 162 * Send a packet out a particular vcc. Not to useful right now, but paves
147 * the way for multiple vcc's per itf. Returns true if we can send, 163 * the way for multiple vcc's per itf. Returns true if we can send,
@@ -200,20 +216,19 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev,
200 216
201 ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc; 217 ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
202 pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev); 218 pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev);
203 if (!atm_may_send(atmvcc, skb->truesize)) {
204 /*
205 * We free this here for now, because we cannot know in a higher
206 * layer whether the skb pointer it supplied wasn't freed yet.
207 * Now, it always is.
208 */
209 dev_kfree_skb(skb);
210 return 0;
211 }
212 atomic_add(skb->truesize, &sk_atm(atmvcc)->sk_wmem_alloc); 219 atomic_add(skb->truesize, &sk_atm(atmvcc)->sk_wmem_alloc);
213 ATM_SKB(skb)->atm_options = atmvcc->atm_options; 220 ATM_SKB(skb)->atm_options = atmvcc->atm_options;
214 dev->stats.tx_packets++; 221 dev->stats.tx_packets++;
215 dev->stats.tx_bytes += skb->len; 222 dev->stats.tx_bytes += skb->len;
216 atmvcc->send(atmvcc, skb); 223 atmvcc->send(atmvcc, skb);
224
225 if (!atm_may_send(atmvcc, 0)) {
226 netif_stop_queue(brvcc->device);
227 /*check for race with br2684_pop*/
228 if (atm_may_send(atmvcc, 0))
229 netif_start_queue(brvcc->device);
230 }
231
217 return 1; 232 return 1;
218} 233}
219 234
@@ -223,7 +238,8 @@ static inline struct br2684_vcc *pick_outgoing_vcc(const struct sk_buff *skb,
223 return list_empty(&brdev->brvccs) ? NULL : list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */ 238 return list_empty(&brdev->brvccs) ? NULL : list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */
224} 239}
225 240
226static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev) 241static netdev_tx_t br2684_start_xmit(struct sk_buff *skb,
242 struct net_device *dev)
227{ 243{
228 struct br2684_dev *brdev = BRPRIV(dev); 244 struct br2684_dev *brdev = BRPRIV(dev);
229 struct br2684_vcc *brvcc; 245 struct br2684_vcc *brvcc;
@@ -238,7 +254,7 @@ static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
238 /* netif_stop_queue(dev); */ 254 /* netif_stop_queue(dev); */
239 dev_kfree_skb(skb); 255 dev_kfree_skb(skb);
240 read_unlock(&devs_lock); 256 read_unlock(&devs_lock);
241 return 0; 257 return NETDEV_TX_OK;
242 } 258 }
243 if (!br2684_xmit_vcc(skb, dev, brvcc)) { 259 if (!br2684_xmit_vcc(skb, dev, brvcc)) {
244 /* 260 /*
@@ -252,7 +268,7 @@ static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
252 dev->stats.tx_fifo_errors++; 268 dev->stats.tx_fifo_errors++;
253 } 269 }
254 read_unlock(&devs_lock); 270 read_unlock(&devs_lock);
255 return 0; 271 return NETDEV_TX_OK;
256} 272}
257 273
258/* 274/*
@@ -503,8 +519,10 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
503 atmvcc->user_back = brvcc; 519 atmvcc->user_back = brvcc;
504 brvcc->encaps = (enum br2684_encaps)be.encaps; 520 brvcc->encaps = (enum br2684_encaps)be.encaps;
505 brvcc->old_push = atmvcc->push; 521 brvcc->old_push = atmvcc->push;
522 brvcc->old_pop = atmvcc->pop;
506 barrier(); 523 barrier();
507 atmvcc->push = br2684_push; 524 atmvcc->push = br2684_push;
525 atmvcc->pop = br2684_pop;
508 526
509 __skb_queue_head_init(&queue); 527 __skb_queue_head_init(&queue);
510 rq = &sk_atm(atmvcc)->sk_receive_queue; 528 rq = &sk_atm(atmvcc)->sk_receive_queue;