aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm
diff options
context:
space:
mode:
Diffstat (limited to 'net/atm')
-rw-r--r--net/atm/br2684.c58
-rw-r--r--net/atm/clip.c39
-rw-r--r--net/atm/lec.c66
-rw-r--r--net/atm/lec.h1
-rw-r--r--net/atm/mpc.c32
-rw-r--r--net/atm/mpc.h5
6 files changed, 91 insertions, 110 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index ea9438fc6855..334fcd4a4ea4 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -83,7 +83,6 @@ struct br2684_dev {
83 struct list_head br2684_devs; 83 struct list_head br2684_devs;
84 int number; 84 int number;
85 struct list_head brvccs; /* one device <=> one vcc (before xmas) */ 85 struct list_head brvccs; /* one device <=> one vcc (before xmas) */
86 struct net_device_stats stats;
87 int mac_was_set; 86 int mac_was_set;
88 enum br2684_payload payload; 87 enum br2684_payload payload;
89}; 88};
@@ -148,9 +147,10 @@ static struct net_device *br2684_find_dev(const struct br2684_if_spec *s)
148 * the way for multiple vcc's per itf. Returns true if we can send, 147 * the way for multiple vcc's per itf. Returns true if we can send,
149 * otherwise false 148 * otherwise false
150 */ 149 */
151static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev, 150static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev,
152 struct br2684_vcc *brvcc) 151 struct br2684_vcc *brvcc)
153{ 152{
153 struct br2684_dev *brdev = BRPRIV(dev);
154 struct atm_vcc *atmvcc; 154 struct atm_vcc *atmvcc;
155 int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2; 155 int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2;
156 156
@@ -211,8 +211,8 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
211 } 211 }
212 atomic_add(skb->truesize, &sk_atm(atmvcc)->sk_wmem_alloc); 212 atomic_add(skb->truesize, &sk_atm(atmvcc)->sk_wmem_alloc);
213 ATM_SKB(skb)->atm_options = atmvcc->atm_options; 213 ATM_SKB(skb)->atm_options = atmvcc->atm_options;
214 brdev->stats.tx_packets++; 214 dev->stats.tx_packets++;
215 brdev->stats.tx_bytes += skb->len; 215 dev->stats.tx_bytes += skb->len;
216 atmvcc->send(atmvcc, skb); 216 atmvcc->send(atmvcc, skb);
217 return 1; 217 return 1;
218} 218}
@@ -233,14 +233,14 @@ static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
233 brvcc = pick_outgoing_vcc(skb, brdev); 233 brvcc = pick_outgoing_vcc(skb, brdev);
234 if (brvcc == NULL) { 234 if (brvcc == NULL) {
235 pr_debug("no vcc attached to dev %s\n", dev->name); 235 pr_debug("no vcc attached to dev %s\n", dev->name);
236 brdev->stats.tx_errors++; 236 dev->stats.tx_errors++;
237 brdev->stats.tx_carrier_errors++; 237 dev->stats.tx_carrier_errors++;
238 /* netif_stop_queue(dev); */ 238 /* netif_stop_queue(dev); */
239 dev_kfree_skb(skb); 239 dev_kfree_skb(skb);
240 read_unlock(&devs_lock); 240 read_unlock(&devs_lock);
241 return 0; 241 return 0;
242 } 242 }
243 if (!br2684_xmit_vcc(skb, brdev, brvcc)) { 243 if (!br2684_xmit_vcc(skb, dev, brvcc)) {
244 /* 244 /*
245 * We should probably use netif_*_queue() here, but that 245 * We should probably use netif_*_queue() here, but that
246 * involves added complication. We need to walk before 246 * involves added complication. We need to walk before
@@ -248,27 +248,20 @@ static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
248 * 248 *
249 * Don't free here! this pointer might be no longer valid! 249 * Don't free here! this pointer might be no longer valid!
250 */ 250 */
251 brdev->stats.tx_errors++; 251 dev->stats.tx_errors++;
252 brdev->stats.tx_fifo_errors++; 252 dev->stats.tx_fifo_errors++;
253 } 253 }
254 read_unlock(&devs_lock); 254 read_unlock(&devs_lock);
255 return 0; 255 return 0;
256} 256}
257 257
258static struct net_device_stats *br2684_get_stats(struct net_device *dev)
259{
260 pr_debug("br2684_get_stats\n");
261 return &BRPRIV(dev)->stats;
262}
263
264/* 258/*
265 * We remember when the MAC gets set, so we don't override it later with 259 * We remember when the MAC gets set, so we don't override it later with
266 * the ESI of the ATM card of the first VC 260 * the ESI of the ATM card of the first VC
267 */ 261 */
268static int (*my_eth_mac_addr) (struct net_device *, void *);
269static int br2684_mac_addr(struct net_device *dev, void *p) 262static int br2684_mac_addr(struct net_device *dev, void *p)
270{ 263{
271 int err = my_eth_mac_addr(dev, p); 264 int err = eth_mac_addr(dev, p);
272 if (!err) 265 if (!err)
273 BRPRIV(dev)->mac_was_set = 1; 266 BRPRIV(dev)->mac_was_set = 1;
274 return err; 267 return err;
@@ -430,17 +423,17 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
430 /* sigh, interface is down? */ 423 /* sigh, interface is down? */
431 if (unlikely(!(net_dev->flags & IFF_UP))) 424 if (unlikely(!(net_dev->flags & IFF_UP)))
432 goto dropped; 425 goto dropped;
433 brdev->stats.rx_packets++; 426 net_dev->stats.rx_packets++;
434 brdev->stats.rx_bytes += skb->len; 427 net_dev->stats.rx_bytes += skb->len;
435 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); 428 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
436 netif_rx(skb); 429 netif_rx(skb);
437 return; 430 return;
438 431
439dropped: 432dropped:
440 brdev->stats.rx_dropped++; 433 net_dev->stats.rx_dropped++;
441 goto free_skb; 434 goto free_skb;
442error: 435error:
443 brdev->stats.rx_errors++; 436 net_dev->stats.rx_errors++;
444free_skb: 437free_skb:
445 dev_kfree_skb(skb); 438 dev_kfree_skb(skb);
446 return; 439 return;
@@ -531,8 +524,8 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
531 524
532 skb->next = skb->prev = NULL; 525 skb->next = skb->prev = NULL;
533 br2684_push(atmvcc, skb); 526 br2684_push(atmvcc, skb);
534 BRPRIV(skb->dev)->stats.rx_bytes -= skb->len; 527 skb->dev->stats.rx_bytes -= skb->len;
535 BRPRIV(skb->dev)->stats.rx_packets--; 528 skb->dev->stats.rx_packets--;
536 529
537 skb = next; 530 skb = next;
538 } 531 }
@@ -544,17 +537,20 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
544 return err; 537 return err;
545} 538}
546 539
540static const struct net_device_ops br2684_netdev_ops = {
541 .ndo_start_xmit = br2684_start_xmit,
542 .ndo_set_mac_address = br2684_mac_addr,
543 .ndo_change_mtu = eth_change_mtu,
544 .ndo_validate_addr = eth_validate_addr,
545};
546
547static void br2684_setup(struct net_device *netdev) 547static void br2684_setup(struct net_device *netdev)
548{ 548{
549 struct br2684_dev *brdev = BRPRIV(netdev); 549 struct br2684_dev *brdev = BRPRIV(netdev);
550 550
551 ether_setup(netdev); 551 ether_setup(netdev);
552 brdev->net_dev = netdev;
553 552
554 my_eth_mac_addr = netdev->set_mac_address; 553 netdev->netdev_ops = &br2684_netdev_ops;
555 netdev->set_mac_address = br2684_mac_addr;
556 netdev->hard_start_xmit = br2684_start_xmit;
557 netdev->get_stats = br2684_get_stats;
558 554
559 INIT_LIST_HEAD(&brdev->brvccs); 555 INIT_LIST_HEAD(&brdev->brvccs);
560} 556}
@@ -565,10 +561,8 @@ static void br2684_setup_routed(struct net_device *netdev)
565 brdev->net_dev = netdev; 561 brdev->net_dev = netdev;
566 562
567 netdev->hard_header_len = 0; 563 netdev->hard_header_len = 0;
568 my_eth_mac_addr = netdev->set_mac_address; 564
569 netdev->set_mac_address = br2684_mac_addr; 565 netdev->netdev_ops = &br2684_netdev_ops;
570 netdev->hard_start_xmit = br2684_start_xmit;
571 netdev->get_stats = br2684_get_stats;
572 netdev->addr_len = 0; 566 netdev->addr_len = 0;
573 netdev->mtu = 1500; 567 netdev->mtu = 1500;
574 netdev->type = ARPHRD_PPP; 568 netdev->type = ARPHRD_PPP;
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 2d33a83be799..3dc0a3a42a57 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -214,15 +214,15 @@ static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb)
214 skb->protocol = ((__be16 *) skb->data)[3]; 214 skb->protocol = ((__be16 *) skb->data)[3];
215 skb_pull(skb, RFC1483LLC_LEN); 215 skb_pull(skb, RFC1483LLC_LEN);
216 if (skb->protocol == htons(ETH_P_ARP)) { 216 if (skb->protocol == htons(ETH_P_ARP)) {
217 PRIV(skb->dev)->stats.rx_packets++; 217 skb->dev->stats.rx_packets++;
218 PRIV(skb->dev)->stats.rx_bytes += skb->len; 218 skb->dev->stats.rx_bytes += skb->len;
219 clip_arp_rcv(skb); 219 clip_arp_rcv(skb);
220 return; 220 return;
221 } 221 }
222 } 222 }
223 clip_vcc->last_use = jiffies; 223 clip_vcc->last_use = jiffies;
224 PRIV(skb->dev)->stats.rx_packets++; 224 skb->dev->stats.rx_packets++;
225 PRIV(skb->dev)->stats.rx_bytes += skb->len; 225 skb->dev->stats.rx_bytes += skb->len;
226 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); 226 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
227 netif_rx(skb); 227 netif_rx(skb);
228} 228}
@@ -372,7 +372,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
372 if (!skb->dst) { 372 if (!skb->dst) {
373 printk(KERN_ERR "clip_start_xmit: skb->dst == NULL\n"); 373 printk(KERN_ERR "clip_start_xmit: skb->dst == NULL\n");
374 dev_kfree_skb(skb); 374 dev_kfree_skb(skb);
375 clip_priv->stats.tx_dropped++; 375 dev->stats.tx_dropped++;
376 return 0; 376 return 0;
377 } 377 }
378 if (!skb->dst->neighbour) { 378 if (!skb->dst->neighbour) {
@@ -380,13 +380,13 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
380 skb->dst->neighbour = clip_find_neighbour(skb->dst, 1); 380 skb->dst->neighbour = clip_find_neighbour(skb->dst, 1);
381 if (!skb->dst->neighbour) { 381 if (!skb->dst->neighbour) {
382 dev_kfree_skb(skb); /* lost that one */ 382 dev_kfree_skb(skb); /* lost that one */
383 clip_priv->stats.tx_dropped++; 383 dev->stats.tx_dropped++;
384 return 0; 384 return 0;
385 } 385 }
386#endif 386#endif
387 printk(KERN_ERR "clip_start_xmit: NO NEIGHBOUR !\n"); 387 printk(KERN_ERR "clip_start_xmit: NO NEIGHBOUR !\n");
388 dev_kfree_skb(skb); 388 dev_kfree_skb(skb);
389 clip_priv->stats.tx_dropped++; 389 dev->stats.tx_dropped++;
390 return 0; 390 return 0;
391 } 391 }
392 entry = NEIGH2ENTRY(skb->dst->neighbour); 392 entry = NEIGH2ENTRY(skb->dst->neighbour);
@@ -400,7 +400,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
400 skb_queue_tail(&entry->neigh->arp_queue, skb); 400 skb_queue_tail(&entry->neigh->arp_queue, skb);
401 else { 401 else {
402 dev_kfree_skb(skb); 402 dev_kfree_skb(skb);
403 clip_priv->stats.tx_dropped++; 403 dev->stats.tx_dropped++;
404 } 404 }
405 return 0; 405 return 0;
406 } 406 }
@@ -423,8 +423,8 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
423 printk(KERN_WARNING "clip_start_xmit: XOFF->XOFF transition\n"); 423 printk(KERN_WARNING "clip_start_xmit: XOFF->XOFF transition\n");
424 return 0; 424 return 0;
425 } 425 }
426 clip_priv->stats.tx_packets++; 426 dev->stats.tx_packets++;
427 clip_priv->stats.tx_bytes += skb->len; 427 dev->stats.tx_bytes += skb->len;
428 vcc->send(vcc, skb); 428 vcc->send(vcc, skb);
429 if (atm_may_send(vcc, 0)) { 429 if (atm_may_send(vcc, 0)) {
430 entry->vccs->xoff = 0; 430 entry->vccs->xoff = 0;
@@ -443,11 +443,6 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
443 return 0; 443 return 0;
444} 444}
445 445
446static struct net_device_stats *clip_get_stats(struct net_device *dev)
447{
448 return &PRIV(dev)->stats;
449}
450
451static int clip_mkip(struct atm_vcc *vcc, int timeout) 446static int clip_mkip(struct atm_vcc *vcc, int timeout)
452{ 447{
453 struct clip_vcc *clip_vcc; 448 struct clip_vcc *clip_vcc;
@@ -501,8 +496,8 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout)
501 496
502 skb_get(skb); 497 skb_get(skb);
503 clip_push(vcc, skb); 498 clip_push(vcc, skb);
504 PRIV(skb->dev)->stats.rx_packets--; 499 skb->dev->stats.rx_packets--;
505 PRIV(skb->dev)->stats.rx_bytes -= len; 500 skb->dev->stats.rx_bytes -= len;
506 kfree_skb(skb); 501 kfree_skb(skb);
507 } 502 }
508 503
@@ -557,11 +552,13 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
557 return error; 552 return error;
558} 553}
559 554
555static const struct net_device_ops clip_netdev_ops = {
556 .ndo_start_xmit = clip_start_xmit,
557};
558
560static void clip_setup(struct net_device *dev) 559static void clip_setup(struct net_device *dev)
561{ 560{
562 dev->hard_start_xmit = clip_start_xmit; 561 dev->netdev_ops = &clip_netdev_ops;
563 /* sg_xmit ... */
564 dev->get_stats = clip_get_stats;
565 dev->type = ARPHRD_ATM; 562 dev->type = ARPHRD_ATM;
566 dev->hard_header_len = RFC1483LLC_LEN; 563 dev->hard_header_len = RFC1483LLC_LEN;
567 dev->mtu = RFC1626_MTU; 564 dev->mtu = RFC1626_MTU;
@@ -621,7 +618,7 @@ static int clip_device_event(struct notifier_block *this, unsigned long event,
621 } 618 }
622 619
623 /* ignore non-CLIP devices */ 620 /* ignore non-CLIP devices */
624 if (dev->type != ARPHRD_ATM || dev->hard_start_xmit != clip_start_xmit) 621 if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops)
625 return NOTIFY_DONE; 622 return NOTIFY_DONE;
626 623
627 switch (event) { 624 switch (event) {
diff --git a/net/atm/lec.c b/net/atm/lec.c
index e5e301550e8a..199b6bb79f42 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -62,7 +62,6 @@ static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 };
62static int lec_open(struct net_device *dev); 62static int lec_open(struct net_device *dev);
63static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev); 63static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev);
64static int lec_close(struct net_device *dev); 64static int lec_close(struct net_device *dev);
65static struct net_device_stats *lec_get_stats(struct net_device *dev);
66static void lec_init(struct net_device *dev); 65static void lec_init(struct net_device *dev);
67static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, 66static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
68 const unsigned char *mac_addr); 67 const unsigned char *mac_addr);
@@ -218,28 +217,28 @@ static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
218 217
219static int lec_open(struct net_device *dev) 218static int lec_open(struct net_device *dev)
220{ 219{
221 struct lec_priv *priv = netdev_priv(dev);
222
223 netif_start_queue(dev); 220 netif_start_queue(dev);
224 memset(&priv->stats, 0, sizeof(struct net_device_stats)); 221 memset(&dev->stats, 0, sizeof(struct net_device_stats));
225 222
226 return 0; 223 return 0;
227} 224}
228 225
229static __inline__ void 226static void
230lec_send(struct atm_vcc *vcc, struct sk_buff *skb, struct lec_priv *priv) 227lec_send(struct atm_vcc *vcc, struct sk_buff *skb)
231{ 228{
229 struct net_device *dev = skb->dev;
230
232 ATM_SKB(skb)->vcc = vcc; 231 ATM_SKB(skb)->vcc = vcc;
233 ATM_SKB(skb)->atm_options = vcc->atm_options; 232 ATM_SKB(skb)->atm_options = vcc->atm_options;
234 233
235 atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc); 234 atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
236 if (vcc->send(vcc, skb) < 0) { 235 if (vcc->send(vcc, skb) < 0) {
237 priv->stats.tx_dropped++; 236 dev->stats.tx_dropped++;
238 return; 237 return;
239 } 238 }
240 239
241 priv->stats.tx_packets++; 240 dev->stats.tx_packets++;
242 priv->stats.tx_bytes += skb->len; 241 dev->stats.tx_bytes += skb->len;
243} 242}
244 243
245static void lec_tx_timeout(struct net_device *dev) 244static void lec_tx_timeout(struct net_device *dev)
@@ -270,7 +269,7 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
270 pr_debug("lec_start_xmit called\n"); 269 pr_debug("lec_start_xmit called\n");
271 if (!priv->lecd) { 270 if (!priv->lecd) {
272 printk("%s:No lecd attached\n", dev->name); 271 printk("%s:No lecd attached\n", dev->name);
273 priv->stats.tx_errors++; 272 dev->stats.tx_errors++;
274 netif_stop_queue(dev); 273 netif_stop_queue(dev);
275 return -EUNATCH; 274 return -EUNATCH;
276 } 275 }
@@ -345,7 +344,7 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
345 GFP_ATOMIC); 344 GFP_ATOMIC);
346 dev_kfree_skb(skb); 345 dev_kfree_skb(skb);
347 if (skb2 == NULL) { 346 if (skb2 == NULL) {
348 priv->stats.tx_dropped++; 347 dev->stats.tx_dropped++;
349 return 0; 348 return 0;
350 } 349 }
351 skb = skb2; 350 skb = skb2;
@@ -380,7 +379,7 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
380 ("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ", 379 ("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ",
381 dev->name); 380 dev->name);
382 pr_debug("MAC address %pM\n", lec_h->h_dest); 381 pr_debug("MAC address %pM\n", lec_h->h_dest);
383 priv->stats.tx_dropped++; 382 dev->stats.tx_dropped++;
384 dev_kfree_skb(skb); 383 dev_kfree_skb(skb);
385 } 384 }
386 goto out; 385 goto out;
@@ -392,10 +391,10 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
392 while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) { 391 while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
393 pr_debug("lec.c: emptying tx queue, "); 392 pr_debug("lec.c: emptying tx queue, ");
394 pr_debug("MAC address %pM\n", lec_h->h_dest); 393 pr_debug("MAC address %pM\n", lec_h->h_dest);
395 lec_send(vcc, skb2, priv); 394 lec_send(vcc, skb2);
396 } 395 }
397 396
398 lec_send(vcc, skb, priv); 397 lec_send(vcc, skb);
399 398
400 if (!atm_may_send(vcc, 0)) { 399 if (!atm_may_send(vcc, 0)) {
401 struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); 400 struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
@@ -427,15 +426,6 @@ static int lec_close(struct net_device *dev)
427 return 0; 426 return 0;
428} 427}
429 428
430/*
431 * Get the current statistics.
432 * This may be called with the card open or closed.
433 */
434static struct net_device_stats *lec_get_stats(struct net_device *dev)
435{
436 return &((struct lec_priv *)netdev_priv(dev))->stats;
437}
438
439static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb) 429static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
440{ 430{
441 unsigned long flags; 431 unsigned long flags;
@@ -512,7 +502,7 @@ static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
512 priv->lane2_ops = NULL; 502 priv->lane2_ops = NULL;
513 if (priv->lane_version > 1) 503 if (priv->lane_version > 1)
514 priv->lane2_ops = &lane2_ops; 504 priv->lane2_ops = &lane2_ops;
515 if (dev->change_mtu(dev, mesg->content.config.mtu)) 505 if (dev_set_mtu(dev, mesg->content.config.mtu))
516 printk("%s: change_mtu to %d failed\n", dev->name, 506 printk("%s: change_mtu to %d failed\n", dev->name,
517 mesg->content.config.mtu); 507 mesg->content.config.mtu);
518 priv->is_proxy = mesg->content.config.is_proxy; 508 priv->is_proxy = mesg->content.config.is_proxy;
@@ -677,17 +667,19 @@ static void lec_set_multicast_list(struct net_device *dev)
677 return; 667 return;
678} 668}
679 669
670static const struct net_device_ops lec_netdev_ops = {
671 .ndo_open = lec_open,
672 .ndo_stop = lec_close,
673 .ndo_start_xmit = lec_start_xmit,
674 .ndo_change_mtu = lec_change_mtu,
675 .ndo_tx_timeout = lec_tx_timeout,
676 .ndo_set_multicast_list = lec_set_multicast_list,
677};
678
679
680static void lec_init(struct net_device *dev) 680static void lec_init(struct net_device *dev)
681{ 681{
682 dev->change_mtu = lec_change_mtu; 682 dev->netdev_ops = &lec_netdev_ops;
683 dev->open = lec_open;
684 dev->stop = lec_close;
685 dev->hard_start_xmit = lec_start_xmit;
686 dev->tx_timeout = lec_tx_timeout;
687
688 dev->get_stats = lec_get_stats;
689 dev->set_multicast_list = lec_set_multicast_list;
690 dev->do_ioctl = NULL;
691 printk("%s: Initialized!\n", dev->name); 683 printk("%s: Initialized!\n", dev->name);
692} 684}
693 685
@@ -810,8 +802,8 @@ static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
810 else 802 else
811#endif 803#endif
812 skb->protocol = eth_type_trans(skb, dev); 804 skb->protocol = eth_type_trans(skb, dev);
813 priv->stats.rx_packets++; 805 dev->stats.rx_packets++;
814 priv->stats.rx_bytes += skb->len; 806 dev->stats.rx_bytes += skb->len;
815 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); 807 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
816 netif_rx(skb); 808 netif_rx(skb);
817 } 809 }
@@ -1887,7 +1879,7 @@ restart:
1887 lec_arp_hold(entry); 1879 lec_arp_hold(entry);
1888 spin_unlock_irqrestore(&priv->lec_arp_lock, flags); 1880 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1889 while ((skb = skb_dequeue(&entry->tx_wait)) != NULL) 1881 while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
1890 lec_send(vcc, skb, entry->priv); 1882 lec_send(vcc, skb);
1891 entry->last_used = jiffies; 1883 entry->last_used = jiffies;
1892 entry->status = ESI_FORWARD_DIRECT; 1884 entry->status = ESI_FORWARD_DIRECT;
1893 lec_arp_put(entry); 1885 lec_arp_put(entry);
@@ -2305,7 +2297,7 @@ restart:
2305 lec_arp_hold(entry); 2297 lec_arp_hold(entry);
2306 spin_unlock_irqrestore(&priv->lec_arp_lock, flags); 2298 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2307 while ((skb = skb_dequeue(&entry->tx_wait)) != NULL) 2299 while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
2308 lec_send(vcc, skb, entry->priv); 2300 lec_send(vcc, skb);
2309 entry->last_used = jiffies; 2301 entry->last_used = jiffies;
2310 entry->status = ESI_FORWARD_DIRECT; 2302 entry->status = ESI_FORWARD_DIRECT;
2311 lec_arp_put(entry); 2303 lec_arp_put(entry);
diff --git a/net/atm/lec.h b/net/atm/lec.h
index 0d376682c1a3..9d14d196cc1d 100644
--- a/net/atm/lec.h
+++ b/net/atm/lec.h
@@ -69,7 +69,6 @@ struct lane2_ops {
69#define LEC_ARP_TABLE_SIZE 16 69#define LEC_ARP_TABLE_SIZE 16
70 70
71struct lec_priv { 71struct lec_priv {
72 struct net_device_stats stats;
73 unsigned short lecid; /* Lecid of this client */ 72 unsigned short lecid; /* Lecid of this client */
74 struct hlist_head lec_arp_empty_ones; 73 struct hlist_head lec_arp_empty_ones;
75 /* Used for storing VCC's that don't have a MAC address attached yet */ 74 /* Used for storing VCC's that don't have a MAC address attached yet */
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index 039d5cc72c3d..e5bf11453a18 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -286,33 +286,32 @@ static void start_mpc(struct mpoa_client *mpc, struct net_device *dev)
286{ 286{
287 287
288 dprintk("mpoa: (%s) start_mpc:\n", mpc->dev->name); 288 dprintk("mpoa: (%s) start_mpc:\n", mpc->dev->name);
289 if (dev->hard_start_xmit == NULL) { 289 if (!dev->netdev_ops)
290 printk("mpoa: (%s) start_mpc: dev->hard_start_xmit == NULL, not starting\n", 290 printk("mpoa: (%s) start_mpc not starting\n", dev->name);
291 dev->name); 291 else {
292 return; 292 mpc->old_ops = dev->netdev_ops;
293 mpc->new_ops = *mpc->old_ops;
294 mpc->new_ops.ndo_start_xmit = mpc_send_packet;
295 dev->netdev_ops = &mpc->new_ops;
293 } 296 }
294 mpc->old_hard_start_xmit = dev->hard_start_xmit;
295 dev->hard_start_xmit = mpc_send_packet;
296
297 return;
298} 297}
299 298
300static void stop_mpc(struct mpoa_client *mpc) 299static void stop_mpc(struct mpoa_client *mpc)
301{ 300{
302 301 struct net_device *dev = mpc->dev;
303 dprintk("mpoa: (%s) stop_mpc:", mpc->dev->name); 302 dprintk("mpoa: (%s) stop_mpc:", mpc->dev->name);
304 303
305 /* Lets not nullify lec device's dev->hard_start_xmit */ 304 /* Lets not nullify lec device's dev->hard_start_xmit */
306 if (mpc->dev->hard_start_xmit != mpc_send_packet) { 305 if (dev->netdev_ops != &mpc->new_ops) {
307 dprintk(" mpc already stopped, not fatal\n"); 306 dprintk(" mpc already stopped, not fatal\n");
308 return; 307 return;
309 } 308 }
310 dprintk("\n"); 309 dprintk("\n");
311 mpc->dev->hard_start_xmit = mpc->old_hard_start_xmit;
312 mpc->old_hard_start_xmit = NULL;
313 /* close_shortcuts(mpc); ??? FIXME */
314 310
315 return; 311 dev->netdev_ops = mpc->old_ops;
312 mpc->old_ops = NULL;
313
314 /* close_shortcuts(mpc); ??? FIXME */
316} 315}
317 316
318static const char *mpoa_device_type_string(char type) __attribute__ ((unused)); 317static const char *mpoa_device_type_string(char type) __attribute__ ((unused));
@@ -531,7 +530,6 @@ static int send_via_shortcut(struct sk_buff *skb, struct mpoa_client *mpc)
531 */ 530 */
532static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev) 531static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev)
533{ 532{
534 int retval;
535 struct mpoa_client *mpc; 533 struct mpoa_client *mpc;
536 struct ethhdr *eth; 534 struct ethhdr *eth;
537 int i = 0; 535 int i = 0;
@@ -561,9 +559,7 @@ static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev)
561 } 559 }
562 560
563 non_ip: 561 non_ip:
564 retval = mpc->old_hard_start_xmit(skb,dev); 562 return mpc->old_ops->ndo_start_xmit(skb,dev);
565
566 return retval;
567} 563}
568 564
569static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg) 565static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
diff --git a/net/atm/mpc.h b/net/atm/mpc.h
index 24c386c35f57..0919a88bbc70 100644
--- a/net/atm/mpc.h
+++ b/net/atm/mpc.h
@@ -15,7 +15,7 @@ struct mpoa_client {
15 struct mpoa_client *next; 15 struct mpoa_client *next;
16 struct net_device *dev; /* lec in question */ 16 struct net_device *dev; /* lec in question */
17 int dev_num; /* e.g. 2 for lec2 */ 17 int dev_num; /* e.g. 2 for lec2 */
18 int (*old_hard_start_xmit)(struct sk_buff *skb, struct net_device *dev); 18
19 struct atm_vcc *mpoad_vcc; /* control channel to mpoad */ 19 struct atm_vcc *mpoad_vcc; /* control channel to mpoad */
20 uint8_t mps_ctrl_addr[ATM_ESA_LEN]; /* MPS control ATM address */ 20 uint8_t mps_ctrl_addr[ATM_ESA_LEN]; /* MPS control ATM address */
21 uint8_t our_ctrl_addr[ATM_ESA_LEN]; /* MPC's control ATM address */ 21 uint8_t our_ctrl_addr[ATM_ESA_LEN]; /* MPC's control ATM address */
@@ -31,6 +31,9 @@ struct mpoa_client {
31 uint8_t *mps_macs; /* array of MPS MAC addresses, >=1 */ 31 uint8_t *mps_macs; /* array of MPS MAC addresses, >=1 */
32 int number_of_mps_macs; /* number of the above MAC addresses */ 32 int number_of_mps_macs; /* number of the above MAC addresses */
33 struct mpc_parameters parameters; /* parameters for this client */ 33 struct mpc_parameters parameters; /* parameters for this client */
34
35 const struct net_device_ops *old_ops;
36 struct net_device_ops new_ops;
34}; 37};
35 38
36 39