diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/arm/ks8695net.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/arm/ks8695net.c')
-rw-r--r-- | drivers/net/arm/ks8695net.c | 153 |
1 files changed, 116 insertions, 37 deletions
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index 2a7b7745cc55..84f8a8f73802 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c | |||
@@ -30,16 +30,19 @@ | |||
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/irq.h> | 31 | #include <linux/irq.h> |
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/slab.h> | ||
33 | 34 | ||
34 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
35 | 36 | ||
36 | #include <mach/regs-switch.h> | 37 | #include <mach/regs-switch.h> |
37 | #include <mach/regs-misc.h> | 38 | #include <mach/regs-misc.h> |
39 | #include <asm/mach/irq.h> | ||
40 | #include <mach/regs-irq.h> | ||
38 | 41 | ||
39 | #include "ks8695net.h" | 42 | #include "ks8695net.h" |
40 | 43 | ||
41 | #define MODULENAME "ks8695_ether" | 44 | #define MODULENAME "ks8695_ether" |
42 | #define MODULEVERSION "1.01" | 45 | #define MODULEVERSION "1.02" |
43 | 46 | ||
44 | /* | 47 | /* |
45 | * Transmit and device reset timeout, default 5 seconds. | 48 | * Transmit and device reset timeout, default 5 seconds. |
@@ -95,6 +98,9 @@ struct ks8695_skbuff { | |||
95 | #define MAX_RX_DESC 16 | 98 | #define MAX_RX_DESC 16 |
96 | #define MAX_RX_DESC_MASK 0xf | 99 | #define MAX_RX_DESC_MASK 0xf |
97 | 100 | ||
101 | /*napi_weight have better more than rx DMA buffers*/ | ||
102 | #define NAPI_WEIGHT 64 | ||
103 | |||
98 | #define MAX_RXBUF_SIZE 0x700 | 104 | #define MAX_RXBUF_SIZE 0x700 |
99 | 105 | ||
100 | #define TX_RING_DMA_SIZE (sizeof(struct tx_ring_desc) * MAX_TX_DESC) | 106 | #define TX_RING_DMA_SIZE (sizeof(struct tx_ring_desc) * MAX_TX_DESC) |
@@ -120,6 +126,7 @@ enum ks8695_dtype { | |||
120 | * @dev: The platform device object for this interface | 126 | * @dev: The platform device object for this interface |
121 | * @dtype: The type of this device | 127 | * @dtype: The type of this device |
122 | * @io_regs: The ioremapped registers for this interface | 128 | * @io_regs: The ioremapped registers for this interface |
129 | * @napi : Add support NAPI for Rx | ||
123 | * @rx_irq_name: The textual name of the RX IRQ from the platform data | 130 | * @rx_irq_name: The textual name of the RX IRQ from the platform data |
124 | * @tx_irq_name: The textual name of the TX IRQ from the platform data | 131 | * @tx_irq_name: The textual name of the TX IRQ from the platform data |
125 | * @link_irq_name: The textual name of the link IRQ from the | 132 | * @link_irq_name: The textual name of the link IRQ from the |
@@ -143,6 +150,7 @@ enum ks8695_dtype { | |||
143 | * @rx_ring_dma: The DMA mapped equivalent of rx_ring | 150 | * @rx_ring_dma: The DMA mapped equivalent of rx_ring |
144 | * @rx_buffers: The sk_buff mappings for the RX ring | 151 | * @rx_buffers: The sk_buff mappings for the RX ring |
145 | * @next_rx_desc_read: The next RX descriptor to read from on IRQ | 152 | * @next_rx_desc_read: The next RX descriptor to read from on IRQ |
153 | * @rx_lock: A lock to protect Rx irq function | ||
146 | * @msg_enable: The flags for which messages to emit | 154 | * @msg_enable: The flags for which messages to emit |
147 | */ | 155 | */ |
148 | struct ks8695_priv { | 156 | struct ks8695_priv { |
@@ -152,6 +160,8 @@ struct ks8695_priv { | |||
152 | enum ks8695_dtype dtype; | 160 | enum ks8695_dtype dtype; |
153 | void __iomem *io_regs; | 161 | void __iomem *io_regs; |
154 | 162 | ||
163 | struct napi_struct napi; | ||
164 | |||
155 | const char *rx_irq_name, *tx_irq_name, *link_irq_name; | 165 | const char *rx_irq_name, *tx_irq_name, *link_irq_name; |
156 | int rx_irq, tx_irq, link_irq; | 166 | int rx_irq, tx_irq, link_irq; |
157 | 167 | ||
@@ -172,6 +182,7 @@ struct ks8695_priv { | |||
172 | dma_addr_t rx_ring_dma; | 182 | dma_addr_t rx_ring_dma; |
173 | struct ks8695_skbuff rx_buffers[MAX_RX_DESC]; | 183 | struct ks8695_skbuff rx_buffers[MAX_RX_DESC]; |
174 | int next_rx_desc_read; | 184 | int next_rx_desc_read; |
185 | spinlock_t rx_lock; | ||
175 | 186 | ||
176 | int msg_enable; | 187 | int msg_enable; |
177 | }; | 188 | }; |
@@ -317,25 +328,24 @@ ks8695_refill_rxbuffers(struct ks8695_priv *ksp) | |||
317 | */ | 328 | */ |
318 | static void | 329 | static void |
319 | ks8695_init_partial_multicast(struct ks8695_priv *ksp, | 330 | ks8695_init_partial_multicast(struct ks8695_priv *ksp, |
320 | struct dev_mc_list *addr, | 331 | struct net_device *ndev) |
321 | int nr_addr) | ||
322 | { | 332 | { |
323 | u32 low, high; | 333 | u32 low, high; |
324 | int i; | 334 | int i; |
335 | struct dev_mc_list *dmi; | ||
325 | 336 | ||
326 | for (i = 0; i < nr_addr; i++, addr = addr->next) { | 337 | i = 0; |
327 | /* Ran out of addresses? */ | 338 | netdev_for_each_mc_addr(dmi, ndev) { |
328 | if (!addr) | ||
329 | break; | ||
330 | /* Ran out of space in chip? */ | 339 | /* Ran out of space in chip? */ |
331 | BUG_ON(i == KS8695_NR_ADDRESSES); | 340 | BUG_ON(i == KS8695_NR_ADDRESSES); |
332 | 341 | ||
333 | low = (addr->dmi_addr[2] << 24) | (addr->dmi_addr[3] << 16) | | 342 | low = (dmi->dmi_addr[2] << 24) | (dmi->dmi_addr[3] << 16) | |
334 | (addr->dmi_addr[4] << 8) | (addr->dmi_addr[5]); | 343 | (dmi->dmi_addr[4] << 8) | (dmi->dmi_addr[5]); |
335 | high = (addr->dmi_addr[0] << 8) | (addr->dmi_addr[1]); | 344 | high = (dmi->dmi_addr[0] << 8) | (dmi->dmi_addr[1]); |
336 | 345 | ||
337 | ks8695_writereg(ksp, KS8695_AAL_(i), low); | 346 | ks8695_writereg(ksp, KS8695_AAL_(i), low); |
338 | ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high); | 347 | ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high); |
348 | i++; | ||
339 | } | 349 | } |
340 | 350 | ||
341 | /* Clear the remaining Additional Station Addresses */ | 351 | /* Clear the remaining Additional Station Addresses */ |
@@ -392,31 +402,75 @@ ks8695_tx_irq(int irq, void *dev_id) | |||
392 | } | 402 | } |
393 | 403 | ||
394 | /** | 404 | /** |
405 | * ks8695_get_rx_enable_bit - Get rx interrupt enable/status bit | ||
406 | * @ksp: Private data for the KS8695 Ethernet | ||
407 | * | ||
408 | * For KS8695 document: | ||
409 | * Interrupt Enable Register (offset 0xE204) | ||
410 | * Bit29 : WAN MAC Receive Interrupt Enable | ||
411 | * Bit16 : LAN MAC Receive Interrupt Enable | ||
412 | * Interrupt Status Register (Offset 0xF208) | ||
413 | * Bit29: WAN MAC Receive Status | ||
414 | * Bit16: LAN MAC Receive Status | ||
415 | * So, this Rx interrrupt enable/status bit number is equal | ||
416 | * as Rx IRQ number. | ||
417 | */ | ||
418 | static inline u32 ks8695_get_rx_enable_bit(struct ks8695_priv *ksp) | ||
419 | { | ||
420 | return ksp->rx_irq; | ||
421 | } | ||
422 | |||
423 | /** | ||
395 | * ks8695_rx_irq - Receive IRQ handler | 424 | * ks8695_rx_irq - Receive IRQ handler |
396 | * @irq: The IRQ which went off (ignored) | 425 | * @irq: The IRQ which went off (ignored) |
397 | * @dev_id: The net_device for the interrupt | 426 | * @dev_id: The net_device for the interrupt |
398 | * | 427 | * |
399 | * Process the RX ring, passing any received packets up to the | 428 | * Inform NAPI that packet reception needs to be scheduled |
400 | * host. If we received anything other than errors, we then | ||
401 | * refill the ring. | ||
402 | */ | 429 | */ |
430 | |||
403 | static irqreturn_t | 431 | static irqreturn_t |
404 | ks8695_rx_irq(int irq, void *dev_id) | 432 | ks8695_rx_irq(int irq, void *dev_id) |
405 | { | 433 | { |
406 | struct net_device *ndev = (struct net_device *)dev_id; | 434 | struct net_device *ndev = (struct net_device *)dev_id; |
407 | struct ks8695_priv *ksp = netdev_priv(ndev); | 435 | struct ks8695_priv *ksp = netdev_priv(ndev); |
436 | |||
437 | spin_lock(&ksp->rx_lock); | ||
438 | |||
439 | if (napi_schedule_prep(&ksp->napi)) { | ||
440 | unsigned long status = readl(KS8695_IRQ_VA + KS8695_INTEN); | ||
441 | unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp); | ||
442 | /*disable rx interrupt*/ | ||
443 | status &= ~mask_bit; | ||
444 | writel(status , KS8695_IRQ_VA + KS8695_INTEN); | ||
445 | __napi_schedule(&ksp->napi); | ||
446 | } | ||
447 | |||
448 | spin_unlock(&ksp->rx_lock); | ||
449 | return IRQ_HANDLED; | ||
450 | } | ||
451 | |||
452 | /** | ||
453 | * ks8695_rx - Receive packets called by NAPI poll method | ||
454 | * @ksp: Private data for the KS8695 Ethernet | ||
455 | * @budget: Number of packets allowed to process | ||
456 | */ | ||
457 | static int ks8695_rx(struct ks8695_priv *ksp, int budget) | ||
458 | { | ||
459 | struct net_device *ndev = ksp->ndev; | ||
408 | struct sk_buff *skb; | 460 | struct sk_buff *skb; |
409 | int buff_n; | 461 | int buff_n; |
410 | u32 flags; | 462 | u32 flags; |
411 | int pktlen; | 463 | int pktlen; |
412 | int last_rx_processed = -1; | 464 | int received = 0; |
413 | 465 | ||
414 | buff_n = ksp->next_rx_desc_read; | 466 | buff_n = ksp->next_rx_desc_read; |
415 | do { | 467 | while (received < budget |
416 | if (ksp->rx_buffers[buff_n].skb && | 468 | && ksp->rx_buffers[buff_n].skb |
417 | !(ksp->rx_ring[buff_n].status & cpu_to_le32(RDES_OWN))) { | 469 | && (!(ksp->rx_ring[buff_n].status & |
470 | cpu_to_le32(RDES_OWN)))) { | ||
418 | rmb(); | 471 | rmb(); |
419 | flags = le32_to_cpu(ksp->rx_ring[buff_n].status); | 472 | flags = le32_to_cpu(ksp->rx_ring[buff_n].status); |
473 | |||
420 | /* Found an SKB which we own, this means we | 474 | /* Found an SKB which we own, this means we |
421 | * received a packet | 475 | * received a packet |
422 | */ | 476 | */ |
@@ -464,7 +518,7 @@ ks8695_rx_irq(int irq, void *dev_id) | |||
464 | /* Relinquish the SKB to the network layer */ | 518 | /* Relinquish the SKB to the network layer */ |
465 | skb_put(skb, pktlen); | 519 | skb_put(skb, pktlen); |
466 | skb->protocol = eth_type_trans(skb, ndev); | 520 | skb->protocol = eth_type_trans(skb, ndev); |
467 | netif_rx(skb); | 521 | netif_receive_skb(skb); |
468 | 522 | ||
469 | /* Record stats */ | 523 | /* Record stats */ |
470 | ndev->stats.rx_packets++; | 524 | ndev->stats.rx_packets++; |
@@ -478,21 +532,12 @@ rx_failure: | |||
478 | /* Give the ring entry back to the hardware */ | 532 | /* Give the ring entry back to the hardware */ |
479 | ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN); | 533 | ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN); |
480 | rx_finished: | 534 | rx_finished: |
481 | /* And note this as processed so we can start | 535 | received++; |
482 | * from here next time | 536 | buff_n = (buff_n + 1) & MAX_RX_DESC_MASK; |
483 | */ | 537 | } |
484 | last_rx_processed = buff_n; | ||
485 | } else { | ||
486 | /* Ran out of things to process, stop now */ | ||
487 | break; | ||
488 | } | ||
489 | buff_n = (buff_n + 1) & MAX_RX_DESC_MASK; | ||
490 | } while (buff_n != ksp->next_rx_desc_read); | ||
491 | 538 | ||
492 | /* And note which RX descriptor we last did anything with */ | 539 | /* And note which RX descriptor we last did */ |
493 | if (likely(last_rx_processed != -1)) | 540 | ksp->next_rx_desc_read = buff_n; |
494 | ksp->next_rx_desc_read = | ||
495 | (last_rx_processed + 1) & MAX_RX_DESC_MASK; | ||
496 | 541 | ||
497 | /* And refill the buffers */ | 542 | /* And refill the buffers */ |
498 | ks8695_refill_rxbuffers(ksp); | 543 | ks8695_refill_rxbuffers(ksp); |
@@ -500,7 +545,37 @@ rx_finished: | |||
500 | /* Kick the RX DMA engine, in case it became suspended */ | 545 | /* Kick the RX DMA engine, in case it became suspended */ |
501 | ks8695_writereg(ksp, KS8695_DRSC, 0); | 546 | ks8695_writereg(ksp, KS8695_DRSC, 0); |
502 | 547 | ||
503 | return IRQ_HANDLED; | 548 | return received; |
549 | } | ||
550 | |||
551 | |||
552 | /** | ||
553 | * ks8695_poll - Receive packet by NAPI poll method | ||
554 | * @ksp: Private data for the KS8695 Ethernet | ||
555 | * @budget: The remaining number packets for network subsystem | ||
556 | * | ||
557 | * Invoked by the network core when it requests for new | ||
558 | * packets from the driver | ||
559 | */ | ||
560 | static int ks8695_poll(struct napi_struct *napi, int budget) | ||
561 | { | ||
562 | struct ks8695_priv *ksp = container_of(napi, struct ks8695_priv, napi); | ||
563 | unsigned long work_done; | ||
564 | |||
565 | unsigned long isr = readl(KS8695_IRQ_VA + KS8695_INTEN); | ||
566 | unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp); | ||
567 | |||
568 | work_done = ks8695_rx(ksp, budget); | ||
569 | |||
570 | if (work_done < budget) { | ||
571 | unsigned long flags; | ||
572 | spin_lock_irqsave(&ksp->rx_lock, flags); | ||
573 | __napi_complete(napi); | ||
574 | /*enable rx interrupt*/ | ||
575 | writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN); | ||
576 | spin_unlock_irqrestore(&ksp->rx_lock, flags); | ||
577 | } | ||
578 | return work_done; | ||
504 | } | 579 | } |
505 | 580 | ||
506 | /** | 581 | /** |
@@ -1126,7 +1201,7 @@ ks8695_set_multicast(struct net_device *ndev) | |||
1126 | if (ndev->flags & IFF_ALLMULTI) { | 1201 | if (ndev->flags & IFF_ALLMULTI) { |
1127 | /* enable all multicast mode */ | 1202 | /* enable all multicast mode */ |
1128 | ctrl |= DRXC_RM; | 1203 | ctrl |= DRXC_RM; |
1129 | } else if (ndev->mc_count > KS8695_NR_ADDRESSES) { | 1204 | } else if (netdev_mc_count(ndev) > KS8695_NR_ADDRESSES) { |
1130 | /* more specific multicast addresses than can be | 1205 | /* more specific multicast addresses than can be |
1131 | * handled in hardware | 1206 | * handled in hardware |
1132 | */ | 1207 | */ |
@@ -1134,8 +1209,7 @@ ks8695_set_multicast(struct net_device *ndev) | |||
1134 | } else { | 1209 | } else { |
1135 | /* enable specific multicasts */ | 1210 | /* enable specific multicasts */ |
1136 | ctrl &= ~DRXC_RM; | 1211 | ctrl &= ~DRXC_RM; |
1137 | ks8695_init_partial_multicast(ksp, ndev->mc_list, | 1212 | ks8695_init_partial_multicast(ksp, ndev); |
1138 | ndev->mc_count); | ||
1139 | } | 1213 | } |
1140 | 1214 | ||
1141 | ks8695_writereg(ksp, KS8695_DRXC, ctrl); | 1215 | ks8695_writereg(ksp, KS8695_DRXC, ctrl); |
@@ -1253,7 +1327,7 @@ ks8695_stop(struct net_device *ndev) | |||
1253 | struct ks8695_priv *ksp = netdev_priv(ndev); | 1327 | struct ks8695_priv *ksp = netdev_priv(ndev); |
1254 | 1328 | ||
1255 | netif_stop_queue(ndev); | 1329 | netif_stop_queue(ndev); |
1256 | netif_carrier_off(ndev); | 1330 | napi_disable(&ksp->napi); |
1257 | 1331 | ||
1258 | ks8695_shutdown(ksp); | 1332 | ks8695_shutdown(ksp); |
1259 | 1333 | ||
@@ -1287,6 +1361,7 @@ ks8695_open(struct net_device *ndev) | |||
1287 | return ret; | 1361 | return ret; |
1288 | } | 1362 | } |
1289 | 1363 | ||
1364 | napi_enable(&ksp->napi); | ||
1290 | netif_start_queue(ndev); | 1365 | netif_start_queue(ndev); |
1291 | 1366 | ||
1292 | return 0; | 1367 | return 0; |
@@ -1472,6 +1547,8 @@ ks8695_probe(struct platform_device *pdev) | |||
1472 | SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); | 1547 | SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); |
1473 | ndev->watchdog_timeo = msecs_to_jiffies(watchdog); | 1548 | ndev->watchdog_timeo = msecs_to_jiffies(watchdog); |
1474 | 1549 | ||
1550 | netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT); | ||
1551 | |||
1475 | /* Retrieve the default MAC addr from the chip. */ | 1552 | /* Retrieve the default MAC addr from the chip. */ |
1476 | /* The bootloader should have left it in there for us. */ | 1553 | /* The bootloader should have left it in there for us. */ |
1477 | 1554 | ||
@@ -1505,6 +1582,7 @@ ks8695_probe(struct platform_device *pdev) | |||
1505 | 1582 | ||
1506 | /* And initialise the queue's lock */ | 1583 | /* And initialise the queue's lock */ |
1507 | spin_lock_init(&ksp->txq_lock); | 1584 | spin_lock_init(&ksp->txq_lock); |
1585 | spin_lock_init(&ksp->rx_lock); | ||
1508 | 1586 | ||
1509 | /* Specify the RX DMA ring buffer */ | 1587 | /* Specify the RX DMA ring buffer */ |
1510 | ksp->rx_ring = ksp->ring_base + TX_RING_DMA_SIZE; | 1588 | ksp->rx_ring = ksp->ring_base + TX_RING_DMA_SIZE; |
@@ -1626,6 +1704,7 @@ ks8695_drv_remove(struct platform_device *pdev) | |||
1626 | struct ks8695_priv *ksp = netdev_priv(ndev); | 1704 | struct ks8695_priv *ksp = netdev_priv(ndev); |
1627 | 1705 | ||
1628 | platform_set_drvdata(pdev, NULL); | 1706 | platform_set_drvdata(pdev, NULL); |
1707 | netif_napi_del(&ksp->napi); | ||
1629 | 1708 | ||
1630 | unregister_netdev(ndev); | 1709 | unregister_netdev(ndev); |
1631 | ks8695_release_device(ksp); | 1710 | ks8695_release_device(ksp); |