diff options
author | Krzysztof Hałasa <khc@pm.waw.pl> | 2008-07-09 10:49:37 -0400 |
---|---|---|
committer | Krzysztof Hałasa <khc@pm.waw.pl> | 2008-11-21 20:49:47 -0500 |
commit | abc9d91a35a924c8db0e949cd443471672e37cdb (patch) | |
tree | 28b0186211e46b4fc731ebb34854d2b6a30d2283 | |
parent | 302243922b374b147380f61774b44612eb2040fd (diff) |
WAN: convert HD64572-based drivers to NAPI.
Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
-rw-r--r-- | drivers/net/wan/hd64572.c | 102 | ||||
-rw-r--r-- | drivers/net/wan/pc300too.c | 3 | ||||
-rw-r--r-- | drivers/net/wan/pci200syn.c | 3 |
3 files changed, 71 insertions, 37 deletions
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index aa82e8f9d333..22adec06d93a 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Hitachi (now Renesas) SCA-II HD64572 driver for Linux | 2 | * Hitachi (now Renesas) SCA-II HD64572 driver for Linux |
3 | * | 3 | * |
4 | * Copyright (C) 1998-2003 Krzysztof Halasa <khc@pm.waw.pl> | 4 | * Copyright (C) 1998-2008 Krzysztof Halasa <khc@pm.waw.pl> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of version 2 of the GNU General Public License | 7 | * under the terms of version 2 of the GNU General Public License |
@@ -45,6 +45,8 @@ | |||
45 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
46 | #include "hd64572.h" | 46 | #include "hd64572.h" |
47 | 47 | ||
48 | #define NAPI_WEIGHT 16 | ||
49 | |||
48 | #define get_msci(port) (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET) | 50 | #define get_msci(port) (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET) |
49 | #define get_dmac_rx(port) (phy_node(port) ? DMAC1RX_OFFSET : DMAC0RX_OFFSET) | 51 | #define get_dmac_rx(port) (phy_node(port) ? DMAC1RX_OFFSET : DMAC0RX_OFFSET) |
50 | #define get_dmac_tx(port) (phy_node(port) ? DMAC1TX_OFFSET : DMAC0TX_OFFSET) | 52 | #define get_dmac_tx(port) (phy_node(port) ? DMAC1TX_OFFSET : DMAC0TX_OFFSET) |
@@ -53,6 +55,7 @@ | |||
53 | #define SCA_INTR_DMAC_RX(node) (node ? 0x20 : 0x02) | 55 | #define SCA_INTR_DMAC_RX(node) (node ? 0x20 : 0x02) |
54 | #define SCA_INTR_DMAC_TX(node) (node ? 0x40 : 0x04) | 56 | #define SCA_INTR_DMAC_TX(node) (node ? 0x40 : 0x04) |
55 | 57 | ||
58 | static int sca_poll(struct napi_struct *napi, int budget); | ||
56 | 59 | ||
57 | static inline struct net_device *port_to_dev(port_t *port) | 60 | static inline struct net_device *port_to_dev(port_t *port) |
58 | { | 61 | { |
@@ -86,6 +89,20 @@ static inline port_t* dev_to_port(struct net_device *dev) | |||
86 | return dev_to_hdlc(dev)->priv; | 89 | return dev_to_hdlc(dev)->priv; |
87 | } | 90 | } |
88 | 91 | ||
92 | static inline void enable_intr(port_t *port) | ||
93 | { | ||
94 | /* DMA & MSCI IRQ enable */ | ||
95 | /* IR0_TXINT | IR0_RXINTA | IR0_DMIB* | IR0_DMIA* */ | ||
96 | sca_outl(sca_inl(IER0, port->card) | | ||
97 | (phy_node(port) ? 0x0A006600 : 0x000A0066), IER0, port->card); | ||
98 | } | ||
99 | |||
100 | static inline void disable_intr(port_t *port) | ||
101 | { | ||
102 | sca_outl(sca_inl(IER0, port->card) & | ||
103 | (phy_node(port) ? 0x00FF00FF : 0xFF00FF00), IER0, port->card); | ||
104 | } | ||
105 | |||
89 | static inline u16 next_desc(port_t *port, u16 desc, int transmit) | 106 | static inline u16 next_desc(port_t *port, u16 desc, int transmit) |
90 | { | 107 | { |
91 | return (desc + 1) % (transmit ? port_to_card(port)->tx_ring_buffers | 108 | return (desc + 1) % (transmit ? port_to_card(port)->tx_ring_buffers |
@@ -206,6 +223,7 @@ static void sca_init_port(port_t *port) | |||
206 | } | 223 | } |
207 | } | 224 | } |
208 | sca_set_carrier(port); | 225 | sca_set_carrier(port); |
226 | netif_napi_add(port_to_dev(port), &port->napi, sca_poll, NAPI_WEIGHT); | ||
209 | } | 227 | } |
210 | 228 | ||
211 | 229 | ||
@@ -256,17 +274,18 @@ static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, | |||
256 | dev->stats.rx_packets++; | 274 | dev->stats.rx_packets++; |
257 | dev->stats.rx_bytes += skb->len; | 275 | dev->stats.rx_bytes += skb->len; |
258 | skb->protocol = hdlc_type_trans(skb, dev); | 276 | skb->protocol = hdlc_type_trans(skb, dev); |
259 | netif_rx(skb); | 277 | netif_receive_skb(skb); |
260 | } | 278 | } |
261 | 279 | ||
262 | 280 | ||
263 | /* Receive DMA interrupt service */ | 281 | /* Receive DMA service */ |
264 | static inline void sca_rx_intr(port_t *port) | 282 | static inline int sca_rx_done(port_t *port, int budget) |
265 | { | 283 | { |
266 | struct net_device *dev = port_to_dev(port); | 284 | struct net_device *dev = port_to_dev(port); |
267 | u16 dmac = get_dmac_rx(port); | 285 | u16 dmac = get_dmac_rx(port); |
268 | card_t *card = port_to_card(port); | 286 | card_t *card = port_to_card(port); |
269 | u8 stat = sca_in(DSR_RX(phy_node(port)), card); /* read DMA Status */ | 287 | u8 stat = sca_in(DSR_RX(phy_node(port)), card); /* read DMA Status */ |
288 | int received = 0; | ||
270 | 289 | ||
271 | /* Reset DSR status bits */ | 290 | /* Reset DSR status bits */ |
272 | sca_out((stat & (DSR_EOT | DSR_EOM | DSR_BOF | DSR_COF)) | DSR_DWE, | 291 | sca_out((stat & (DSR_EOT | DSR_EOM | DSR_BOF | DSR_COF)) | DSR_DWE, |
@@ -276,7 +295,7 @@ static inline void sca_rx_intr(port_t *port) | |||
276 | /* Dropped one or more frames */ | 295 | /* Dropped one or more frames */ |
277 | dev->stats.rx_over_errors++; | 296 | dev->stats.rx_over_errors++; |
278 | 297 | ||
279 | while (1) { | 298 | while (received < budget) { |
280 | u32 desc_off = desc_offset(port, port->rxin, 0); | 299 | u32 desc_off = desc_offset(port, port->rxin, 0); |
281 | pkt_desc __iomem *desc; | 300 | pkt_desc __iomem *desc; |
282 | u32 cda = sca_inl(dmac + CDAL, card); | 301 | u32 cda = sca_inl(dmac + CDAL, card); |
@@ -299,8 +318,10 @@ static inline void sca_rx_intr(port_t *port) | |||
299 | dev->stats.rx_crc_errors++; | 318 | dev->stats.rx_crc_errors++; |
300 | if (stat & ST_RX_EOM) | 319 | if (stat & ST_RX_EOM) |
301 | port->rxpart = 0; /* received last fragment */ | 320 | port->rxpart = 0; /* received last fragment */ |
302 | } else | 321 | } else { |
303 | sca_rx(card, port, desc, port->rxin); | 322 | sca_rx(card, port, desc, port->rxin); |
323 | received++; | ||
324 | } | ||
304 | 325 | ||
305 | /* Set new error descriptor address */ | 326 | /* Set new error descriptor address */ |
306 | sca_outl(desc_off, dmac + EDAL, card); | 327 | sca_outl(desc_off, dmac + EDAL, card); |
@@ -309,11 +330,12 @@ static inline void sca_rx_intr(port_t *port) | |||
309 | 330 | ||
310 | /* make sure RX DMA is enabled */ | 331 | /* make sure RX DMA is enabled */ |
311 | sca_out(DSR_DE, DSR_RX(phy_node(port)), card); | 332 | sca_out(DSR_DE, DSR_RX(phy_node(port)), card); |
333 | return received; | ||
312 | } | 334 | } |
313 | 335 | ||
314 | 336 | ||
315 | /* Transmit DMA interrupt service */ | 337 | /* Transmit DMA service */ |
316 | static inline void sca_tx_intr(port_t *port) | 338 | static inline void sca_tx_done(port_t *port) |
317 | { | 339 | { |
318 | struct net_device *dev = port_to_dev(port); | 340 | struct net_device *dev = port_to_dev(port); |
319 | u16 dmac = get_dmac_tx(port); | 341 | u16 dmac = get_dmac_tx(port); |
@@ -348,27 +370,43 @@ static inline void sca_tx_intr(port_t *port) | |||
348 | } | 370 | } |
349 | 371 | ||
350 | 372 | ||
373 | static int sca_poll(struct napi_struct *napi, int budget) | ||
374 | { | ||
375 | port_t *port = container_of(napi, port_t, napi); | ||
376 | u8 stat = sca_intr_status(port->card); | ||
377 | int received = 0; | ||
378 | |||
379 | if (stat & SCA_INTR_MSCI(port->phy_node)) | ||
380 | sca_msci_intr(port); | ||
381 | |||
382 | if (stat & SCA_INTR_DMAC_TX(port->phy_node)) | ||
383 | sca_tx_done(port); | ||
384 | |||
385 | if (stat & SCA_INTR_DMAC_RX(port->phy_node)) | ||
386 | received = sca_rx_done(port, budget); | ||
387 | |||
388 | if (received < budget) { | ||
389 | netif_rx_complete(port->dev, napi); | ||
390 | enable_intr(port); | ||
391 | } | ||
392 | |||
393 | return received; | ||
394 | } | ||
395 | |||
351 | static irqreturn_t sca_intr(int irq, void* dev_id) | 396 | static irqreturn_t sca_intr(int irq, void* dev_id) |
352 | { | 397 | { |
353 | card_t *card = dev_id; | 398 | card_t *card = dev_id; |
354 | int i; | 399 | int i; |
355 | u8 stat; | 400 | u8 stat = sca_intr_status(card); |
356 | int handled = 0; | 401 | int handled = 0; |
357 | 402 | ||
358 | while((stat = sca_intr_status(card)) != 0) { | 403 | for (i = 0; i < 2; i++) { |
359 | handled = 1; | 404 | port_t *port = get_port(card, i); |
360 | for (i = 0; i < 2; i++) { | 405 | if (port && (stat & (SCA_INTR_MSCI(i) | SCA_INTR_DMAC_RX(i) | |
361 | port_t *port = get_port(card, i); | 406 | SCA_INTR_DMAC_TX(i)))) { |
362 | if (port) { | 407 | handled = 1; |
363 | if (stat & SCA_INTR_MSCI(i)) | 408 | disable_intr(port); |
364 | sca_msci_intr(port); | 409 | netif_rx_schedule(port->dev, &port->napi); |
365 | |||
366 | if (stat & SCA_INTR_DMAC_RX(i)) | ||
367 | sca_rx_intr(port); | ||
368 | |||
369 | if (stat & SCA_INTR_DMAC_TX(i)) | ||
370 | sca_tx_intr(port); | ||
371 | } | ||
372 | } | 410 | } |
373 | } | 411 | } |
374 | 412 | ||
@@ -470,18 +508,12 @@ static void sca_open(struct net_device *dev) | |||
470 | sca_out(0x3F, msci + TNR1, card); /* +1=TX DMA deactivation condition*/ | 508 | sca_out(0x3F, msci + TNR1, card); /* +1=TX DMA deactivation condition*/ |
471 | 509 | ||
472 | /* We're using the following interrupts: | 510 | /* We're using the following interrupts: |
473 | - TXINT (DMAC completed all transmisions, underrun or DCD change) | 511 | - TXINT (DMAC completed all transmissions, underrun or DCD change) |
474 | - all DMA interrupts | 512 | - all DMA interrupts |
475 | */ | 513 | */ |
476 | |||
477 | sca_set_carrier(port); | ||
478 | |||
479 | /* MSCI TXINT and RXINTA interrupt enable */ | 514 | /* MSCI TXINT and RXINTA interrupt enable */ |
480 | sca_outl(IE0_TXINT | IE0_RXINTA | IE0_UDRN | IE0_CDCD, msci + IE0, | 515 | sca_outl(IE0_TXINT | IE0_RXINTA | IE0_UDRN | IE0_CDCD, msci + IE0, |
481 | card); | 516 | card); |
482 | /* DMA & MSCI IRQ enable */ | ||
483 | sca_outl(sca_inl(IER0, card) | | ||
484 | (phy_node(port) ? 0x0A006600 : 0x000A0066), IER0, card); | ||
485 | 517 | ||
486 | sca_out(port->tmc, msci + TMCR, card); | 518 | sca_out(port->tmc, msci + TMCR, card); |
487 | sca_out(port->tmc, msci + TMCT, card); | 519 | sca_out(port->tmc, msci + TMCT, card); |
@@ -490,6 +522,9 @@ static void sca_open(struct net_device *dev) | |||
490 | sca_out(CMD_TX_ENABLE, msci + CMD, card); | 522 | sca_out(CMD_TX_ENABLE, msci + CMD, card); |
491 | sca_out(CMD_RX_ENABLE, msci + CMD, card); | 523 | sca_out(CMD_RX_ENABLE, msci + CMD, card); |
492 | 524 | ||
525 | sca_set_carrier(port); | ||
526 | enable_intr(port); | ||
527 | napi_enable(&port->napi); | ||
493 | netif_start_queue(dev); | 528 | netif_start_queue(dev); |
494 | } | 529 | } |
495 | 530 | ||
@@ -497,14 +532,11 @@ static void sca_open(struct net_device *dev) | |||
497 | static void sca_close(struct net_device *dev) | 532 | static void sca_close(struct net_device *dev) |
498 | { | 533 | { |
499 | port_t *port = dev_to_port(dev); | 534 | port_t *port = dev_to_port(dev); |
500 | card_t* card = port_to_card(port); | ||
501 | 535 | ||
502 | /* reset channel */ | 536 | /* reset channel */ |
503 | sca_out(CMD_RESET, get_msci(port) + CMD, port_to_card(port)); | 537 | sca_out(CMD_RESET, get_msci(port) + CMD, port_to_card(port)); |
504 | /* disable DMA & MSCI IRQ */ | 538 | disable_intr(port); |
505 | sca_outl(sca_inl(IER0, card) & | 539 | napi_disable(&port->napi); |
506 | (phy_node(port) ? 0x00FF00FF : 0xFF00FF00), IER0, card); | ||
507 | |||
508 | netif_stop_queue(dev); | 540 | netif_stop_queue(dev); |
509 | } | 541 | } |
510 | 542 | ||
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c index 5ab22e529fe1..289c5fe65194 100644 --- a/drivers/net/wan/pc300too.c +++ b/drivers/net/wan/pc300too.c | |||
@@ -78,6 +78,7 @@ typedef struct { | |||
78 | 78 | ||
79 | 79 | ||
80 | typedef struct port_s { | 80 | typedef struct port_s { |
81 | struct napi_struct napi; | ||
81 | struct net_device *dev; | 82 | struct net_device *dev; |
82 | struct card_s *card; | 83 | struct card_s *card; |
83 | spinlock_t lock; /* TX lock */ | 84 | spinlock_t lock; /* TX lock */ |
@@ -481,6 +482,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, | |||
481 | else | 482 | else |
482 | port->iface = IF_IFACE_V35; | 483 | port->iface = IF_IFACE_V35; |
483 | 484 | ||
485 | sca_init_port(port); | ||
484 | if (register_hdlc_device(dev)) { | 486 | if (register_hdlc_device(dev)) { |
485 | printk(KERN_ERR "pc300: unable to register hdlc " | 487 | printk(KERN_ERR "pc300: unable to register hdlc " |
486 | "device\n"); | 488 | "device\n"); |
@@ -488,7 +490,6 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, | |||
488 | pc300_pci_remove_one(pdev); | 490 | pc300_pci_remove_one(pdev); |
489 | return -ENOBUFS; | 491 | return -ENOBUFS; |
490 | } | 492 | } |
491 | sca_init_port(port); /* Set up SCA memory */ | ||
492 | 493 | ||
493 | printk(KERN_INFO "%s: PC300 node %d\n", | 494 | printk(KERN_INFO "%s: PC300 node %d\n", |
494 | dev->name, port->phy_node); | 495 | dev->name, port->phy_node); |
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index c2620beb7f75..bfcf4f67b4c0 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c | |||
@@ -65,6 +65,7 @@ typedef struct { | |||
65 | 65 | ||
66 | 66 | ||
67 | typedef struct port_s { | 67 | typedef struct port_s { |
68 | struct napi_struct napi; | ||
68 | struct net_device *dev; | 69 | struct net_device *dev; |
69 | struct card_s *card; | 70 | struct card_s *card; |
70 | spinlock_t lock; /* TX lock */ | 71 | spinlock_t lock; /* TX lock */ |
@@ -423,6 +424,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, | |||
423 | hdlc->xmit = sca_xmit; | 424 | hdlc->xmit = sca_xmit; |
424 | port->settings.clock_type = CLOCK_EXT; | 425 | port->settings.clock_type = CLOCK_EXT; |
425 | port->card = card; | 426 | port->card = card; |
427 | sca_init_port(port); | ||
426 | if (register_hdlc_device(dev)) { | 428 | if (register_hdlc_device(dev)) { |
427 | printk(KERN_ERR "pci200syn: unable to register hdlc " | 429 | printk(KERN_ERR "pci200syn: unable to register hdlc " |
428 | "device\n"); | 430 | "device\n"); |
@@ -430,7 +432,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, | |||
430 | pci200_pci_remove_one(pdev); | 432 | pci200_pci_remove_one(pdev); |
431 | return -ENOBUFS; | 433 | return -ENOBUFS; |
432 | } | 434 | } |
433 | sca_init_port(port); /* Set up SCA memory */ | ||
434 | 435 | ||
435 | printk(KERN_INFO "%s: PCI200SYN node %d\n", | 436 | printk(KERN_INFO "%s: PCI200SYN node %d\n", |
436 | dev->name, port->phy_node); | 437 | dev->name, port->phy_node); |