1 /****************************************************************************** |
1 /****************************************************************************** |
2 * |
2 * |
3 * 8 1 3 9 t o o . c |
3 * 8 1 3 9 t o o . c |
4 * |
4 * |
5 * EtherCAT-Treiber für RTL8139-kompatible Netzwerkkarten. |
5 * EtherCAT driver for RTL8139-compatible NICs. |
6 * |
6 * |
7 * Autoren: Wilhelm Hagemeister, Florian Pose |
7 * Authors: Florian Pose <fp@igh-essen.com> |
|
8 * Wilhelm Hagemeister <hm@igh-essen.com> |
8 * |
9 * |
9 * $Date$ |
10 * $Date$ |
10 * $Author$ |
11 * $Author$ |
11 * |
12 * |
12 * (C) Copyright IgH 2005 |
13 * (C) Copyright IgH 2006 |
13 * Ingenieurgemeinschaft IgH |
14 * Ingenieurgemeinschaft IgH |
14 * Heinz-Bäcker Str. 34 |
15 * Heinz-Bäcker Str. 34 |
15 * D-45356 Essen |
16 * D-45356 Essen |
16 * Tel.: +49 201/61 99 31 |
17 * Tel.: +49 201/61 99 31 |
17 * Fax.: +49 201/61 98 36 |
18 * Fax.: +49 201/61 98 36 |
642 unsigned long fifo_copy_timeout; |
642 unsigned long fifo_copy_timeout; |
643 }; |
643 }; |
644 |
644 |
645 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
645 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
646 |
646 |
647 MODULE_AUTHOR ("Wilhelm Hagemeister <hm@igh-essen.com>, Florian Pose <fp@igh-essen.com>"); |
647 MODULE_AUTHOR("Wilhelm Hagemeister <hm@igh-essen.com>," |
648 MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver with EtherCAT functionality"); |
648 " Florian Pose <fp@igh-essen.com>"); |
|
649 MODULE_DESCRIPTION("RealTek RTL-8139 Fast Ethernet" |
|
650 " driver with EtherCAT functionality"); |
649 MODULE_LICENSE("GPL"); |
651 MODULE_LICENSE("GPL"); |
650 MODULE_VERSION(COMPILE_INFO); |
652 MODULE_VERSION(COMPILE_INFO); |
651 |
653 |
652 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
654 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
653 |
655 |
662 |
664 |
663 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
665 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
664 |
666 |
665 module_param(ec_device_index, int, -1); |
667 module_param(ec_device_index, int, -1); |
666 module_param(ec_device_master_index, int, 0); |
668 module_param(ec_device_master_index, int, 0); |
667 MODULE_PARM_DESC(ec_device_index, "Index of the device reserved for EtherCAT."); |
669 MODULE_PARM_DESC(ec_device_index, |
668 MODULE_PARM_DESC(ec_device_master_index, "Index of the EtherCAT master to register the device."); |
670 "Index of the device reserved for EtherCAT."); |
|
671 MODULE_PARM_DESC(ec_device_master_index, |
|
672 "Index of the EtherCAT master to register the device."); |
669 |
673 |
670 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
674 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
671 |
675 |
672 static int read_eeprom (void __iomem *ioaddr, int location, int addr_len); |
676 static int read_eeprom (void __iomem *ioaddr, int location, int addr_len); |
673 static int rtl8139_open (struct net_device *dev); |
677 static int rtl8139_open (struct net_device *dev); |
1080 |
1084 |
1081 /* dev is fully set up and ready to use now */ |
1085 /* dev is fully set up and ready to use now */ |
1082 |
1086 |
1083 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
1087 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
1084 |
1088 |
1085 /* EtherCAT-Karten nicht beim Stack anmelden. */ |
1089 if (dev != rtl_ec_net_dev) { |
1086 if (dev != rtl_ec_net_dev) |
1090 DPRINTK("About to register device named %s (%p)...\n", |
1087 { |
1091 dev->name, dev); |
1088 DPRINTK("About to register device named %s (%p)...\n", dev->name, dev); |
1092 i = register_netdev (dev); |
1089 i = register_netdev (dev); |
1093 if (i) goto err_out; |
1090 if (i) goto err_out; |
|
1091 } |
1094 } |
1092 |
1095 |
1093 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
1096 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
1094 |
1097 |
1095 pci_set_drvdata (pdev, dev); |
1098 pci_set_drvdata (pdev, dev); |
1392 |
1394 |
1393 #ifdef EC_DEBUG |
1395 #ifdef EC_DEBUG |
1394 printk(KERN_DEBUG "%s: open\n", dev->name); |
1396 printk(KERN_DEBUG "%s: open\n", dev->name); |
1395 #endif |
1397 #endif |
1396 |
1398 |
1397 if (dev != rtl_ec_net_dev) |
1399 if (dev != rtl_ec_net_dev) { |
1398 { |
1400 retval = request_irq(dev->irq, rtl8139_interrupt, |
1399 retval = request_irq(dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); |
1401 SA_SHIRQ, dev->name, dev); |
1400 if (retval) |
1402 if (retval) |
1401 return retval; |
1403 return retval; |
1402 } |
1404 } |
1403 |
1405 |
1404 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
1406 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
1405 |
1407 |
1406 tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN, |
1408 tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN, |
1434 rtl8139_init_ring (dev); |
1435 rtl8139_init_ring (dev); |
1435 rtl8139_hw_start (dev); |
1436 rtl8139_hw_start (dev); |
1436 |
1437 |
1437 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
1438 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
1438 |
1439 |
1439 if (dev != rtl_ec_net_dev) |
1440 if (dev != rtl_ec_net_dev) { |
1440 { |
1441 netif_start_queue (dev); |
1441 netif_start_queue (dev); |
1442 |
1442 |
1443 if (netif_msg_ifup(tp)) { |
1443 if (netif_msg_ifup(tp)) |
1444 printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d" |
1444 { |
1445 " GP Pins %2.2x %s-duplex.\n", |
1445 printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d" |
1446 dev->name, pci_resource_start (tp->pci_dev, 1), |
1446 " GP Pins %2.2x %s-duplex.\n", |
1447 dev->irq, RTL_R8 (MediaStatus), |
1447 dev->name, pci_resource_start (tp->pci_dev, 1), |
1448 tp->mii.full_duplex ? "full" : "half"); |
1448 dev->irq, RTL_R8 (MediaStatus), |
1449 } |
1449 tp->mii.full_duplex ? "full" : "half"); |
1450 |
1450 } |
1451 rtl8139_start_thread(dev); |
1451 |
|
1452 rtl8139_start_thread(dev); |
|
1453 } |
1452 } |
1454 |
1453 |
1455 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
1454 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
1456 |
1455 |
1457 return 0; |
1456 return 0; |
1534 if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb))) |
1533 if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb))) |
1535 RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb); |
1534 RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb); |
1536 |
1535 |
1537 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
1536 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
1538 |
1537 |
1539 if (dev != rtl_ec_net_dev) |
1538 if (dev != rtl_ec_net_dev) { |
1540 { |
1539 /* Enable all known interrupts by setting the interrupt mask. */ |
1541 /* Enable all known interrupts by setting the interrupt mask. */ |
1540 RTL_W16 (IntrMask, rtl8139_intr_mask); |
1542 RTL_W16 (IntrMask, rtl8139_intr_mask); |
|
1543 } |
1541 } |
1544 |
1542 |
1545 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
1543 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
1546 } |
1544 } |
1547 |
1545 |
1803 RTL_W8 (ChipCmd, CmdRxEnb); |
1801 RTL_W8 (ChipCmd, CmdRxEnb); |
1804 |
1802 |
1805 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
1803 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
1806 |
1804 |
1807 |
1805 |
1808 if (dev != rtl_ec_net_dev) |
1806 if (dev != rtl_ec_net_dev) { |
1809 { |
1807 spin_lock(&tp->rx_lock); |
1810 spin_lock(&tp->rx_lock); |
1808 |
1811 |
1809 /* Disable interrupts by clearing the interrupt mask. */ |
1812 /* Disable interrupts by clearing the interrupt mask. */ |
1810 RTL_W16 (IntrMask, 0x0000); |
1813 RTL_W16 (IntrMask, 0x0000); |
1811 |
1814 |
1812 /* Stop a shared interrupt from scavenging while we are. */ |
1815 /* Stop a shared interrupt from scavenging while we are. */ |
1813 spin_lock_irqsave (&tp->lock, flags); |
1816 spin_lock_irqsave (&tp->lock, flags); |
1814 rtl8139_tx_clear (tp); |
1817 rtl8139_tx_clear (tp); |
1815 spin_unlock_irqrestore (&tp->lock, flags); |
1818 spin_unlock_irqrestore (&tp->lock, flags); |
1816 |
1819 |
1817 /* ...and finally, reset everything */ |
1820 /* ...and finally, reset everything */ |
1818 |
1821 |
1819 if (netif_running(dev)) { |
1822 if (netif_running(dev)) |
1820 rtl8139_hw_start (dev); |
1823 { |
1821 netif_wake_queue (dev); |
1824 rtl8139_hw_start (dev); |
1822 } |
1825 netif_wake_queue (dev); |
1823 |
1826 } |
1824 spin_unlock(&tp->rx_lock); |
1827 |
|
1828 spin_unlock(&tp->rx_lock); |
|
1829 } |
1825 } |
1830 else |
1826 else { |
1831 { |
1827 rtl8139_tx_clear (tp); |
1832 rtl8139_tx_clear (tp); |
1828 rtl8139_hw_start(dev); |
1833 rtl8139_hw_start(dev); |
|
1834 } |
1829 } |
1835 |
1830 |
1836 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
1831 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
1837 } |
1832 } |
1838 |
1833 |
2182 goto out; |
2174 goto out; |
2183 } |
2175 } |
2184 |
2176 |
2185 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2177 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2186 |
2178 |
2187 if (dev != rtl_ec_net_dev) |
2179 if (dev != rtl_ec_net_dev) { |
2188 { |
2180 /* Malloc up new buffer, compatible with net-2e. */ |
2189 /* Malloc up new buffer, compatible with net-2e. */ |
2181 /* Omit the four octet CRC from the length. */ |
2190 /* Omit the four octet CRC from the length. */ |
2182 skb = dev_alloc_skb(pkt_size + 2); |
2191 skb = dev_alloc_skb(pkt_size + 2); |
2183 |
2192 |
2184 if (likely(skb)) { |
2193 if (likely(skb)) { |
2185 skb->dev = dev; |
2194 skb->dev = dev; |
2186 skb_reserve (skb, 2); /* 16 byte align the IP fields. */ |
2195 skb_reserve (skb, 2); /* 16 byte align the IP fields. */ |
|
2196 #if RX_BUF_IDX == 3 |
2187 #if RX_BUF_IDX == 3 |
2197 wrap_copy(skb, rx_ring, ring_offset+4, pkt_size); |
2188 wrap_copy(skb, rx_ring, ring_offset+4, pkt_size); |
2198 #else |
2189 #else |
2199 eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0); |
2190 eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0); |
2200 #endif |
2191 #endif |
2201 skb_put (skb, pkt_size); |
2192 skb_put (skb, pkt_size); |
2202 |
2193 |
2203 skb->protocol = eth_type_trans (skb, dev); |
2194 skb->protocol = eth_type_trans (skb, dev); |
2204 |
2195 |
2205 dev->last_rx = jiffies; |
2196 dev->last_rx = jiffies; |
2206 tp->stats.rx_bytes += pkt_size; |
2197 tp->stats.rx_bytes += pkt_size; |
2207 tp->stats.rx_packets++; |
2198 tp->stats.rx_packets++; |
2208 |
2199 |
2209 netif_receive_skb (skb); |
2200 netif_receive_skb (skb); |
2210 } else { |
2201 } else { |
2211 if (net_ratelimit()) |
2202 if (net_ratelimit()) |
2212 printk (KERN_WARNING |
2203 printk (KERN_WARNING |
2213 "%s: Memory squeeze, dropping packet.\n", |
2204 "%s: Memory squeeze, dropping packet.\n", |
2214 dev->name); |
2205 dev->name); |
2215 tp->stats.rx_dropped++; |
2206 tp->stats.rx_dropped++; |
2216 } |
2207 } |
2217 } |
2208 } |
2218 else |
2209 else |
2219 { |
2210 { |
2220 ecdev_receive(rtl_ec_dev, |
2211 ecdev_receive(rtl_ec_dev, |
2221 &rx_ring[ring_offset + 4] + ETH_HLEN, |
2212 &rx_ring[ring_offset + 4] + ETH_HLEN, |
2222 pkt_size - ETH_HLEN); |
2213 pkt_size - ETH_HLEN); |
2223 dev->last_rx = jiffies; |
2214 dev->last_rx = jiffies; |
2224 tp->stats.rx_bytes += pkt_size; |
2215 tp->stats.rx_bytes += pkt_size; |
2225 tp->stats.rx_packets++; |
2216 tp->stats.rx_packets++; |
2226 } |
2217 } |
2227 |
2218 |
2345 int link_changed = 0; /* avoid bogus "uninit" warning */ |
2336 int link_changed = 0; /* avoid bogus "uninit" warning */ |
2346 int handled = 0; |
2337 int handled = 0; |
2347 |
2338 |
2348 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2339 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2349 |
2340 |
2350 if (dev == rtl_ec_net_dev) |
2341 if (dev == rtl_ec_net_dev) { |
2351 { |
2342 status = RTL_R16 (IntrStatus); |
2352 status = RTL_R16 (IntrStatus); |
2343 } |
2353 } |
2344 else { |
2354 else |
2345 spin_lock(&tp->lock); |
2355 { |
2346 |
2356 spin_lock(&tp->lock); |
2347 status = RTL_R16 (IntrStatus); |
2357 |
2348 |
2358 status = RTL_R16 (IntrStatus); |
2349 if (unlikely((status & rtl8139_intr_mask) == 0)) |
2359 |
2350 goto out; |
2360 if (unlikely((status & rtl8139_intr_mask) == 0)) |
|
2361 goto out; |
|
2362 } |
2351 } |
2363 |
2352 |
2364 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2353 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2365 |
2354 |
2366 handled = 1; |
2355 handled = 1; |
2369 if (unlikely(status == 0xFFFF)) |
2358 if (unlikely(status == 0xFFFF)) |
2370 goto out; |
2359 goto out; |
2371 |
2360 |
2372 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2361 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2373 |
2362 |
2374 if (dev != rtl_ec_net_dev) |
2363 if (dev != rtl_ec_net_dev) { |
2375 { |
2364 /* close possible race's with dev_close */ |
2376 /* close possible race's with dev_close */ |
2365 if (unlikely(!netif_running(dev))) { |
2377 if (unlikely(!netif_running(dev))) { |
2366 RTL_W16 (IntrMask, 0); |
2378 RTL_W16 (IntrMask, 0); |
2367 goto out; |
2379 goto out; |
2368 } |
2380 } |
|
2381 } |
2369 } |
2382 |
2370 |
2383 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2371 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2384 |
2372 |
2385 /* Acknowledge all of the current interrupt sources ASAP, but |
2373 /* Acknowledge all of the current interrupt sources ASAP, but |
2397 |
2385 |
2398 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2386 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2399 |
2387 |
2400 if (status & RxAckBits) |
2388 if (status & RxAckBits) |
2401 { |
2389 { |
2402 if (dev != rtl_ec_net_dev) |
2390 if (dev != rtl_ec_net_dev) { |
2403 { |
2391 /* Mark for polling */ |
2404 /* Polling vormerken */ |
2392 if (netif_rx_schedule_prep(dev)) { |
2405 if (netif_rx_schedule_prep(dev)) { |
2393 RTL_W16_F (IntrMask, rtl8139_norx_intr_mask); |
2406 RTL_W16_F (IntrMask, rtl8139_norx_intr_mask); |
2394 __netif_rx_schedule (dev); |
2407 __netif_rx_schedule (dev); |
2395 } |
2408 } |
2396 } |
2409 } |
2397 else { |
2410 else |
2398 /* EtherCAT device: Just receive all frames */ |
2411 { |
2399 rtl8139_rx(dev, tp, 100); // FIXME |
2412 /* Beim EtherCAT-Device einfach alle Frames empfangen */ |
2400 } |
2413 rtl8139_rx(dev, tp, 100); // FIXME |
|
2414 } |
|
2415 } |
2401 } |
2416 |
2402 |
2417 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2403 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2418 |
2404 |
2419 /* Check uncommon events with one test. */ |
2405 /* Check uncommon events with one test. */ |
2461 int ret = 0; |
2446 int ret = 0; |
2462 unsigned long flags; |
2447 unsigned long flags; |
2463 |
2448 |
2464 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2449 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2465 |
2450 |
2466 if (dev != rtl_ec_net_dev) |
2451 if (dev != rtl_ec_net_dev) { |
2467 { |
2452 netif_stop_queue(dev); |
2468 netif_stop_queue(dev); |
2453 if (tp->thr_pid >= 0) { |
2469 if (tp->thr_pid >= 0) { |
2454 tp->time_to_die = 1; |
2470 tp->time_to_die = 1; |
2455 wmb(); |
2471 wmb(); |
2456 ret = kill_proc (tp->thr_pid, SIGTERM, 1); |
2472 ret = kill_proc (tp->thr_pid, SIGTERM, 1); |
2457 if (ret) { |
2473 if (ret) { |
2458 printk (KERN_ERR "%s: unable to signal thread\n", dev->name); |
2474 printk (KERN_ERR "%s: unable to signal thread\n", dev->name); |
2459 return ret; |
2475 return ret; |
|
2476 } |
|
2477 wait_for_completion (&tp->thr_exited); |
|
2478 } |
2460 } |
2479 |
2461 wait_for_completion (&tp->thr_exited); |
2480 if (netif_msg_ifdown(tp)) |
2462 } |
2481 printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n", |
2463 |
2482 dev->name, RTL_R16 (IntrStatus)); |
2464 if (netif_msg_ifdown(tp)) |
2483 |
2465 printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n", |
2484 spin_lock_irqsave (&tp->lock, flags); |
2466 dev->name, RTL_R16 (IntrStatus)); |
2485 |
2467 |
2486 /* Stop the chip's Tx and Rx DMA processes. */ |
2468 spin_lock_irqsave (&tp->lock, flags); |
2487 RTL_W8 (ChipCmd, 0); |
2469 |
2488 |
2470 /* Stop the chip's Tx and Rx DMA processes. */ |
2489 /* Disable interrupts by clearing the interrupt mask. */ |
2471 RTL_W8 (ChipCmd, 0); |
2490 RTL_W16 (IntrMask, 0); |
2472 |
2491 |
2473 /* Disable interrupts by clearing the interrupt mask. */ |
2492 /* Update the error counts. */ |
2474 RTL_W16 (IntrMask, 0); |
2493 tp->stats.rx_missed_errors += RTL_R32 (RxMissed); |
2475 |
2494 RTL_W32 (RxMissed, 0); |
2476 /* Update the error counts. */ |
2495 |
2477 tp->stats.rx_missed_errors += RTL_R32 (RxMissed); |
2496 spin_unlock_irqrestore (&tp->lock, flags); |
2478 RTL_W32 (RxMissed, 0); |
2497 |
2479 |
2498 synchronize_irq (dev->irq); /* racy, but that's ok here */ |
2480 spin_unlock_irqrestore (&tp->lock, flags); |
2499 free_irq (dev->irq, dev); |
2481 |
|
2482 synchronize_irq (dev->irq); /* racy, but that's ok here */ |
|
2483 free_irq (dev->irq, dev); |
2500 } |
2484 } |
2501 else |
2485 else { |
2502 { |
2486 /* Stop the chip's Tx and Rx DMA processes. */ |
2503 /* Stop the chip's Tx and Rx DMA processes. */ |
2487 RTL_W8 (ChipCmd, 0); |
2504 RTL_W8 (ChipCmd, 0); |
2488 |
2505 |
2489 /* Disable interrupts by clearing the interrupt mask. */ |
2506 /* Disable interrupts by clearing the interrupt mask. */ |
2490 RTL_W16 (IntrMask, 0); |
2507 RTL_W16 (IntrMask, 0); |
2491 |
2508 |
2492 /* Update the error counts. */ |
2509 /* Update the error counts. */ |
2493 tp->stats.rx_missed_errors += RTL_R32 (RxMissed); |
2510 tp->stats.rx_missed_errors += RTL_R32 (RxMissed); |
2494 RTL_W32 (RxMissed, 0); |
2511 RTL_W32 (RxMissed, 0); |
|
2512 } |
2495 } |
2513 |
2496 |
2514 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2497 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2515 |
2498 |
2516 rtl8139_tx_clear (tp); |
2499 rtl8139_tx_clear (tp); |
2747 void __iomem *ioaddr = tp->mmio_addr; |
2730 void __iomem *ioaddr = tp->mmio_addr; |
2748 unsigned long flags; |
2731 unsigned long flags; |
2749 |
2732 |
2750 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2733 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2751 |
2734 |
2752 if (dev == rtl_ec_net_dev || netif_running(dev)) |
2735 if (dev == rtl_ec_net_dev || netif_running(dev)) { |
2753 { |
2736 spin_lock_irqsave (&tp->lock, flags); |
2754 spin_lock_irqsave (&tp->lock, flags); |
2737 tp->stats.rx_missed_errors += RTL_R32 (RxMissed); |
2755 tp->stats.rx_missed_errors += RTL_R32 (RxMissed); |
2738 RTL_W32 (RxMissed, 0); |
2756 RTL_W32 (RxMissed, 0); |
2739 spin_unlock_irqrestore (&tp->lock, flags); |
2757 spin_unlock_irqrestore (&tp->lock, flags); |
|
2758 } |
2740 } |
2759 |
2741 |
2760 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2742 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2761 |
2743 |
2762 return &tp->stats; |
2744 return &tp->stats; |
2940 } |
2922 } |
2941 |
2923 |
2942 |
2924 |
2943 static void __exit rtl8139_cleanup_module (void) |
2925 static void __exit rtl8139_cleanup_module (void) |
2944 { |
2926 { |
2945 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2927 /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ |
2946 |
2928 |
2947 printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n"); |
2929 printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n"); |
2948 |
2930 |
2949 if (rtl_ec_net_dev) { |
2931 if (rtl_ec_net_dev) { |
2950 printk(KERN_INFO "Stopping device...\n"); |
2932 printk(KERN_INFO "Stopping device...\n"); |
2951 ecdev_stop(ec_device_master_index); |
2933 ecdev_stop(ec_device_master_index); |
2952 printk(KERN_INFO "Unregistering device...\n"); |
2934 printk(KERN_INFO "Unregistering device...\n"); |
2953 ecdev_unregister(ec_device_master_index, rtl_ec_dev); |
2935 ecdev_unregister(ec_device_master_index, rtl_ec_dev); |
2954 rtl_ec_dev = NULL; |
2936 rtl_ec_dev = NULL; |
2955 } |
2937 } |
2956 |
2938 |
2957 pci_unregister_driver(&rtl8139_pci_driver); |
2939 pci_unregister_driver(&rtl8139_pci_driver); |
2958 |
2940 |
2959 printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n"); |
2941 printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n"); |
2960 |
2942 |
2961 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2943 /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ |
2962 } |
2944 } |
2963 |
2945 |
2964 |
2946 |
2965 module_init(rtl8139_init_module); |
2947 module_init(rtl8139_init_module); |
2966 module_exit(rtl8139_cleanup_module); |
2948 module_exit(rtl8139_cleanup_module); |