IF's im rtl8139too-Treiber vereinfacht und kein Polling mehr.

This commit is contained in:
Florian Pose 2005-12-02 11:37:40 +00:00
parent 7dd6184f07
commit 2ce96ae16b
4 changed files with 243 additions and 284 deletions

View File

@ -109,7 +109,7 @@
*/
#define DRV_NAME "8139too_ecat"
#define DRV_NAME "8139too-ecat"
#define DRV_VERSION "0.9.27"
@ -135,7 +135,6 @@
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
#include "ec_device.h"
//#include "ec_dbg.h"
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -638,8 +637,8 @@ struct rtl8139_private {
unsigned long fifo_copy_timeout;
};
MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
MODULE_AUTHOR ("Wilhelm Hagemeister <hm@igh-essen.com>, Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver with EtherCAT functionality");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
@ -1065,15 +1064,6 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
spin_lock_init (&tp->lock);
spin_lock_init (&tp->rx_lock);
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (board_idx == ec_device_index)
{
rtl_ecat_dev.lock = &tp->lock;
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
init_waitqueue_head (&tp->thr_wait);
init_completion (&tp->thr_exited);
tp->mii.dev = dev;
@ -1430,7 +1420,6 @@ static int rtl8139_open (struct net_device *dev)
tp->rx_ring, tp->rx_ring_dma);
return -ENOMEM;
}
tp->mii.full_duplex = tp->mii.force_media;
@ -1444,23 +1433,16 @@ static int rtl8139_open (struct net_device *dev)
if (dev != rtl_ecat_dev.dev)
{
netif_start_queue (dev);
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
//FIXME muß das hier raus ??
if (netif_msg_ifup(tp))
{
printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d"
" GP Pins %2.2x %s-duplex.\n",
dev->name, pci_resource_start (tp->pci_dev, 1),
dev->irq, RTL_R8 (MediaStatus),
tp->mii.full_duplex ? "full" : "half");
}
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
{
rtl8139_start_thread(dev);
}
@ -1818,14 +1800,15 @@ static void rtl8139_tx_timeout (struct net_device *dev)
rtl_ecat_dev.state = ECAT_DS_TIMEOUT;
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* disable Tx ASAP, if not already */
tmp8 = RTL_R8 (ChipCmd);
if (tmp8 & CmdTxEnb)
RTL_W8 (ChipCmd, CmdRxEnb);
if (dev != rtl_ecat_dev.dev)
{
spin_lock(&tp->rx_lock);
/* Disable interrupts by clearing the interrupt mask. */
RTL_W16 (IntrMask, 0x0000);
@ -1836,23 +1819,20 @@ static void rtl8139_tx_timeout (struct net_device *dev)
/* ...and finally, reset everything */
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
{
if (netif_running(dev))
{
rtl8139_hw_start (dev);
netif_wake_queue (dev);
}
spin_unlock(&tp->rx_lock);
}
else
{
rtl8139_hw_start (dev);
rtl8139_tx_clear (tp);
rtl8139_hw_start(dev);
}
spin_unlock(&tp->rx_lock);
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
@ -1884,10 +1864,13 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
return 0;
}
if (dev != rtl_ecat_dev.dev) //CHANGED HM spinlock falsch
if (dev != rtl_ecat_dev.dev)
{
spin_lock_irq(&tp->lock);
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
@ -1902,6 +1885,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
netif_stop_queue (dev);
spin_unlock_irq(&tp->lock);
if (netif_msg_tx_queued(tp))
@ -1932,7 +1916,6 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
if (dev == rtl_ecat_dev.dev)
{
rtl_ecat_dev.tx_intr_cnt++;
//printk("ECAT tx interrupt\n"); // HM
rdtscl(rtl_ecat_dev.tx_time); // Get CPU cycles
}
@ -2163,7 +2146,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
while ((dev == rtl_ecat_dev.dev || netif_running(dev)) //HM
while ((dev == rtl_ecat_dev.dev || netif_running(dev))
&& received < budget
&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
u32 ring_offset = cur_rx % RX_BUF_LEN;
@ -2241,10 +2224,7 @@ no_early_rx:
/* Malloc up new buffer, compatible with net-2e. */
/* Omit the four octet CRC from the length. */
skb = dev_alloc_skb(pkt_size + 2);
}
if (dev != rtl_ecat_dev.dev)
{
if (likely(skb)) {
skb->dev = dev;
skb_reserve (skb, 2); /* 16 byte align the IP fields. */
@ -2262,7 +2242,6 @@ no_early_rx:
tp->stats.rx_packets++;
netif_receive_skb (skb);
} else {
if (net_ratelimit())
printk (KERN_WARNING
@ -2389,17 +2368,12 @@ int rtl8139_poll(struct net_device *dev, int *budget)
* Order is important since data can get interrupted
* again when we think we are done.
*/
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev) {
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
local_irq_disable();
RTL_W16_F(IntrMask, rtl8139_intr_mask); //Interrupts werden nicht enabled ?? HM
RTL_W16_F(IntrMask, rtl8139_intr_mask);
__netif_rx_complete(dev);
local_irq_enable();
}
// else
}
spin_unlock(&tp->rx_lock);
return !done;
@ -2422,22 +2396,18 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
if (dev == rtl_ecat_dev.dev)
{
rtl_ecat_dev.intr_cnt++;
status = RTL_R16 (IntrStatus);
}
else
{
spin_lock(&tp->lock);
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
status = RTL_R16 (IntrStatus);
/* shared irq? */
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
if (dev != rtl_ecat_dev.dev)
if (unlikely((status & rtl8139_intr_mask) == 0))
goto out;
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
handled = 1;
@ -2446,15 +2416,19 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
if (unlikely(status == 0xFFFF))
goto out;
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
{
/* close possible race's with dev_close */
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
if (dev != rtl_ecat_dev.dev) {
if (unlikely(!netif_running(dev))) {
RTL_W16 (IntrMask, 0);
goto out;
}
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* Acknowledge all of the current interrupt sources ASAP, but
an first get an additional status bit from CSCR. */
if (unlikely(status & RxUnderrun))
@ -2470,17 +2444,25 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
If not running start it now. */
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (status & RxAckBits){
// printk("ECAT-NIC RX-Intr Flag\n"); // HM
if (dev != rtl_ecat_dev.dev) {
if (status & RxAckBits)
{
if (dev != rtl_ecat_dev.dev)
{
/* Polling vormerken */
if (netif_rx_schedule_prep(dev)) {
RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
__netif_rx_schedule (dev);
}
}
// else
else
{
/* Beim EtherCAT-Device einfach einen Frame empfangen */
rtl8139_rx(dev, tp, 1);
}
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* Check uncommon events with one test. */
if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
@ -2542,22 +2524,11 @@ static int rtl8139_close (struct net_device *dev)
}
wait_for_completion (&tp->thr_exited);
}
}
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
{
if (netif_msg_ifdown(tp))
printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
dev->name, RTL_R16 (IntrStatus));
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
spin_lock_irqsave (&tp->lock, flags);
/* Stop the chip's Tx and Rx DMA processes. */
@ -2570,18 +2541,23 @@ static int rtl8139_close (struct net_device *dev)
tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
spin_unlock_irqrestore (&tp->lock, flags);
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
{
synchronize_irq (dev->irq); /* racy, but that's ok here */
free_irq (dev->irq, dev);
}
else
{
/* Stop the chip's Tx and Rx DMA processes. */
RTL_W8 (ChipCmd, 0);
/* Disable interrupts by clearing the interrupt mask. */
RTL_W16 (IntrMask, 0);
/* Update the error counts. */
tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -2980,6 +2956,7 @@ static int __init rtl8139_init_module (void)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
EtherCAT_device_init(&rtl_ecat_dev);
rtl_ecat_dev.isr = rtl8139_interrupt;
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/

View File

@ -18,9 +18,6 @@
#include "ec_device.h"
#include "ec_dbg.h"
extern irqreturn_t rtl8139_interrupt(int, void *, struct pt_regs *);
extern int rtl8139_poll(struct net_device *, int *);
/***************************************************************/
/**
@ -44,7 +41,7 @@ void EtherCAT_device_init(EtherCAT_device_t *ecd)
ecd->intr_cnt = 0;
ecd->state = ECAT_DS_READY;
ecd->rx_data_length = 0;
ecd->lock = NULL;
ecd->isr = NULL;
}
/***************************************************************/
@ -293,21 +290,7 @@ int EtherCAT_device_receive(EtherCAT_device_t *ecd,
void EtherCAT_device_call_isr(EtherCAT_device_t *ecd)
{
int budget;
budget = 1; /* Einen Frame empfangen */
rtl8139_interrupt(0, ecd->dev, NULL);
ecd->dev->quota = 1;
rtl8139_poll(ecd->dev, &budget);
/* HM
if (budget != 0)
{
EC_DBG(KERN_ERR "EtherCAT: Warning - Budget is %d!\n",
budget);
}
*/
if (ecd->isr) ecd->isr(0, ecd->dev, NULL);
}
/***************************************************************/
@ -336,7 +319,6 @@ void EtherCAT_device_debug(EtherCAT_device_t *ecd)
EC_DBG(KERN_DEBUG "Receive buffer: %X\n", (unsigned) ecd->rx_data);
EC_DBG(KERN_DEBUG "Receive buffer fill state: %u/%u\n",
(unsigned) ecd->rx_data_length, ECAT_FRAME_BUFFER_SIZE);
EC_DBG(KERN_DEBUG "Lock: %X\n", (unsigned) ecd->lock);
}
else
{
@ -353,3 +335,4 @@ EXPORT_SYMBOL(EtherCAT_device_close);
EXPORT_SYMBOL(EtherCAT_device_clear);
EXPORT_SYMBOL(EtherCAT_device_debug);
/***************************************************************/

View File

@ -12,6 +12,8 @@
#ifndef _EC_DEVICE_H_
#define _EC_DEVICE_H_
#include <linux/interrupt.h>
#include "ec_globals.h"
/**
@ -34,9 +36,6 @@ typedef enum
}
EtherCAT_device_state_t;
#define ECAT_BUS_TIME(ecd_ptr) ((((ecd_ptr)->rx_time - \
(ecd_ptr)->tx_time) * 1000) / cpu_khz)
/***************************************************************/
/**
@ -63,7 +62,7 @@ typedef struct
empfangene Rahmen */
volatile unsigned int rx_data_length; /**< Länge des zuletzt
empfangenen Rahmens */
spinlock_t *lock; /**< Zeiger auf das Spinlock des net_devices */
irqreturn_t (*isr)(int, void *, struct pt_regs *); /**< Adresse der ISR */
}
EtherCAT_device_t;