* meth.c
@ 2003-06-29 22:57 ilya
0 siblings, 0 replies; only message in thread
From: ilya @ 2003-06-29 22:57 UTC (permalink / raw)
To: ralf; +Cc: linux-mips
[-- Attachment #1.1: Type: text/plain, Size: 157 bytes --]
Here is what I currently have for my O2 ethernet driver.
It still shows some weired behaviour sometimes, but works well enough to boot
and run O2 over NFS.
[-- Attachment #1.2: meth.diff --]
[-- Type: text/plain, Size: 22287 bytes --]
Index: drivers/net/meth.c
===================================================================
RCS file: /home/cvs/linux/drivers/net/meth.c,v
retrieving revision 1.4
diff -u -r1.4 meth.c
--- drivers/net/meth.c 1 Jul 2002 20:01:25 -0000 1.4
+++ drivers/net/meth.c 29 Jun 2003 22:55:44 -0000
@@ -55,10 +55,6 @@
MODULE_AUTHOR("Ilya Volynets");
MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver");
-/* This is a load-time options */
-/*static int eth = 0;
-MODULE_PARM(eth, "i");*/
-
#define HAVE_TX_TIMEOUT
/* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */
#define TX_TIMEOUT (400*HZ/1000)
@@ -68,15 +64,13 @@
MODULE_PARM(timeout, "i");
#endif
-int meth_eth;
-
/*
* This structure is private to each device. It is used to pass
* packets in and out, so there is place for a packet
*/
typedef struct meth_private {
- struct net_device_stats stats;
+ struct net_device_stats stats;
volatile struct meth_regs *regs;
u64 mode; /* in-memory copy of MAC control register */
int phy_addr; /* address of phy, used by mdio_* functions, initialized in mdio_probe*/
@@ -92,12 +86,12 @@
dma_addr_t rx_ring_dmas[RX_RING_ENTRIES];
int rx_write;
- spinlock_t meth_lock;
+ spinlock_t meth_lock;
} meth_private;
extern struct net_device meth_devs[];
void meth_tx_timeout (struct net_device *dev);
-void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs);
+irqreturn_t meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs);
/* global, initialized in ip32-setup.c */
char o2meth_eaddr[8]={0,0,0,0,0,0,0,0};
@@ -109,14 +103,9 @@
DPRINTK("Loading MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
(int)o2meth_eaddr[0]&0xFF,(int)o2meth_eaddr[1]&0xFF,(int)o2meth_eaddr[2]&0xFF,
(int)o2meth_eaddr[3]&0xFF,(int)o2meth_eaddr[4]&0xFF,(int)o2meth_eaddr[5]&0xFF);
- //memcpy(dev->dev_addr,o2meth_eaddr+2,6);
for (i=0; i<6; i++)
dev->dev_addr[i]=o2meth_eaddr[i];
- regs->mac_addr= //dev->dev_addr[0]|(dev->dev_addr[1]<<8)|
- //dev->dev_addr[2]<<16|(dev->dev_addr[3]<<24)|
- //dev->dev_addr[4]<<32|(dev->dev_addr[5]<<40);
- (*(u64*)o2meth_eaddr)>>16;
- DPRINTK("MAC, finally is %0lx\n",regs->mac_addr);
+ regs->mac_addr=(*(u64*)o2meth_eaddr)>>16;
}
/*
@@ -124,19 +113,19 @@
*/
#define WAIT_FOR_PHY(___regs, ___rval) \
while((___rval=___regs->phy_data)&MDIO_BUSY){ \
- udelay(25); \
+ udelay(25); \
}
/*read phy register, return value read */
static int mdio_read(meth_private *priv,int phyreg)
{
volatile meth_regs* regs=priv->regs;
volatile u32 rval;
- WAIT_FOR_PHY(regs,rval)
+ WAIT_FOR_PHY(regs,rval);
regs->phy_registers=(priv->phy_addr<<5)|(phyreg&0x1f);
udelay(25);
regs->phy_trans_go=1;
udelay(25);
- WAIT_FOR_PHY(regs,rval)
+ WAIT_FOR_PHY(regs,rval);
return rval&MDIO_DATA_MASK;
}
@@ -145,14 +134,13 @@
{
volatile meth_regs* regs=priv->regs;
int rval;
-/// DPRINTK("Trying to write value %i to reguster %i\n",val, pfyreg);
- spin_lock_irq(&priv->meth_lock);
- WAIT_FOR_PHY(regs,rval)
+ spin_lock(&priv->meth_lock);
+ WAIT_FOR_PHY(regs,rval);
regs->phy_registers=(priv->phy_addr<<5)|(pfyreg&0x1f);
regs->phy_data=val;
udelay(25);
- WAIT_FOR_PHY(regs,rval)
- spin_unlock_irq(&priv->meth_lock);
+ WAIT_FOR_PHY(regs,rval);
+ spin_unlock(&priv->meth_lock);
}
/* Modify phy register using given mask and value */
@@ -165,11 +153,6 @@
mdio_write(priv,phyreg,rval);
}
-/* handle errata data on MDIO bus */
-//static void mdio_errata(meth_private *priv)
-//{
- /* Hmmm... what the hell is phyerrata? does it come from sys init parameters in IRIX */
-//}
static int mdio_probe(meth_private *priv)
{
int i, p2, p3;
@@ -177,25 +160,25 @@
/* check if phy is detected already */
if(priv->phy_addr>=0&&priv->phy_addr<32)
return 0;
- spin_lock_irq(&priv->meth_lock);
+ spin_lock(&priv->meth_lock);
for (i=0;i<32;++i){
priv->phy_addr=(char)i;
p2=mdio_read(priv,2);
#ifdef MFE_DEBUG
p3=mdio_read(priv,3);
switch ((p2<<12)|(p3>>4)){
- case PHY_QS6612X:
- DPRINTK("PHY is QS6612X\n");
- break;
- case PHY_ICS1889:
- DPRINTK("PHY is ICS1889\n");
- break;
- case PHY_ICS1890:
- DPRINTK("PHY is ICS1890\n");
- break;
- case PHY_DP83840:
- DPRINTK("PHY is DP83840\n");
- break;
+ case PHY_QS6612X:
+ DPRINTK("PHY is QS6612X\n");
+ break;
+ case PHY_ICS1889:
+ DPRINTK("PHY is ICS1889\n");
+ break;
+ case PHY_ICS1890:
+ DPRINTK("PHY is ICS1890\n");
+ break;
+ case PHY_DP83840:
+ DPRINTK("PHY is DP83840\n");
+ break;
}
#endif
if(p2!=0xffff&&p2!=0x0000){
@@ -203,7 +186,7 @@
break;
}
}
- spin_unlock_irq(&priv->meth_lock);
+ spin_unlock(&priv->meth_lock);
if(priv->phy_addr<32) {
return 0;
}
@@ -269,15 +252,9 @@
static int meth_init_rx_ring(meth_private *priv)
{
int i;
- DPRINTK("Initializing RX ring\n");
for(i=0;i<RX_RING_ENTRIES;i++){
- DPRINTK("\t1:\t%i\t",i);
- /*if(!(priv->rx_ring[i]=get_free_page(GFP_KERNEL)))
- return -ENOMEM;
- DPRINTK("\t2:\t%i\n",i);*/
priv->rx_ring[i]=(rx_packet*)pci_alloc_consistent(NULL,METH_RX_BUFF_SIZE,&(priv->rx_ring_dmas[i]));
/* I'll need to re-sync it after each RX */
- DPRINTK("\t%p\n",priv->rx_ring[i]);
priv->regs->rx_fifo=priv->rx_ring_dmas[i];
}
priv->rx_write = 0;
@@ -290,8 +267,8 @@
/* Remove any pending skb */
for (i = 0; i < TX_RING_ENTRIES; i++) {
- if (priv->tx_skbs[i])
- dev_kfree_skb(priv->tx_skbs[i]);
+ if (priv->tx_skbs[i])
+ dev_kfree_skb(priv->tx_skbs[i]);
priv->tx_skbs[i] = NULL;
}
pci_free_consistent(NULL,
@@ -318,7 +295,6 @@
priv->regs->mac_ctrl = SGI_MAC_RESET;
priv->regs->mac_ctrl = 0;
udelay(25);
- DPRINTK("MAC control after reset: %016lx\n", priv->regs->mac_ctrl);
/* Load ethernet address */
load_eaddr(dev, priv->regs);
@@ -341,7 +317,7 @@
/* Now set dma control, but don't enable DMA, yet */
priv->regs->dma_ctrl= (4 << METH_RX_OFFSET_SHIFT) |
- (RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT);
+ (RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT);
return(0);
}
@@ -356,9 +332,20 @@
{
meth_private *priv=dev->priv;
volatile meth_regs *regs=priv->regs;
+ int ret;
- MOD_INC_USE_COUNT;
+ /* Initialize the hardware */
+ if((ret=meth_reset(dev)) < 0)
+ return ret;
+
+ /* Allocate the ring buffers */
+ if((ret=meth_init_tx_ring(priv))<0||(ret=meth_init_rx_ring(priv))<0){
+ meth_free_tx_ring(priv);
+ meth_free_rx_ring(priv);
+ return ret;
+ }
+ DPRINTK("Will set dma_ctl now\n");
/* Start DMA */
regs->dma_ctrl|=
METH_DMA_TX_EN|/*METH_DMA_TX_INT_EN|*/
@@ -368,6 +355,7 @@
printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq);
return -EAGAIN;
}
+ DPRINTK("About to start queue\n");
netif_start_queue(dev);
DPRINTK("Opened... DMA control=0x%08lx\n", regs->dma_ctrl);
return 0;
@@ -375,14 +363,16 @@
int meth_release(struct net_device *dev)
{
- netif_stop_queue(dev); /* can't transmit any more */
+ meth_private *priv=dev->priv;
+ netif_stop_queue(dev); /* can't transmit any more */
/* shut down dma */
((meth_private*)(dev->priv))->regs->dma_ctrl&=
~(METH_DMA_TX_EN|METH_DMA_TX_INT_EN|
- METH_DMA_RX_EN|METH_DMA_RX_INT_EN);
+ METH_DMA_RX_EN|METH_DMA_RX_INT_EN);
free_irq(dev->irq, dev);
- MOD_DEC_USE_COUNT;
- return 0;
+ meth_free_tx_ring(priv);
+ meth_free_rx_ring(priv);
+ return 0;
}
/*
@@ -390,24 +380,24 @@
*/
int meth_config(struct net_device *dev, struct ifmap *map)
{
- if (dev->flags & IFF_UP) /* can't act on a running interface */
- return -EBUSY;
+ if (dev->flags & IFF_UP) /* can't act on a running interface */
+ return -EBUSY;
- /* Don't allow changing the I/O address */
- if (map->base_addr != dev->base_addr) {
- printk(KERN_WARNING "meth: Can't change I/O address\n");
- return -EOPNOTSUPP;
- }
-
- /* Allow changing the IRQ */
- if (map->irq != dev->irq) {
- printk(KERN_WARNING "meth: Can't change IRQ\n");
- return -EOPNOTSUPP;
- }
+ /* Don't allow changing the I/O address */
+ if (map->base_addr != dev->base_addr) {
+ printk(KERN_WARNING "meth: Can't change I/O address\n");
+ return -EOPNOTSUPP;
+ }
+
+ /* Don't allow changing the IRQ */
+ if (map->irq != dev->irq) {
+ printk(KERN_WARNING "meth: Can't change IRQ\n");
+ return -EOPNOTSUPP;
+ }
DPRINTK("Configured\n");
- /* ignore other fields */
- return 0;
+ /* ignore other fields */
+ return 0;
}
/*
@@ -415,49 +405,62 @@
*/
void meth_rx(struct net_device* dev)
{
- struct sk_buff *skb;
- struct meth_private *priv = (struct meth_private *) dev->priv;
+ struct sk_buff *skb;
+ struct meth_private *priv = (struct meth_private *) dev->priv;
rx_packet *rxb;
- DPRINTK("RX...\n");
- // TEMP while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){
- while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){
- int len=rxb->status.parsed.rx_len - 4; /* omit CRC */
- DPRINTK("(%i)\n",priv->rx_write);
+ int twptr=priv->rx_write;
+ u64 status;
+ spin_lock(&(priv->meth_lock));
+ while ((status=(rxb=priv->rx_ring[priv->rx_write])->status.raw)&0x8000000000000000)
+ {
+ int len=(status&0xFFFF) - 4; /* omit CRC */
/* length sanity check */
if(len < 60 || len > 1518) {
- printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x.\n",
- dev->name, priv->rx_write, rxb->status.raw);
- priv->stats.rx_errors++;
- priv->stats.rx_length_errors++;
+ printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2lx.\n",
+ dev->name, priv->rx_write, rxb->status.raw);
+ priv->stats.rx_errors++;
+ priv->stats.rx_length_errors++;
}
- if(!(rxb->status.raw&METH_RX_STATUS_ERRORS)){
+ if(!(status&METH_RX_STATUS_ERRORS)){
skb=alloc_skb(len+2,GFP_ATOMIC);/* Should be atomic -- we are in interrupt */
if(!skb){
/* Ouch! No memory! Drop packet on the floor */
- DPRINTK("!!!>>>Ouch! Not enough Memory for RX buffer!\n");
priv->stats.rx_dropped++;
} else {
skb_reserve(skb, 2); /* align IP on 16B boundary */
- memcpy(skb_put(skb, len), rxb->buf, len);
- /* Write metadata, and then pass to the receive level */
- skb->dev = dev;
- skb->protocol = eth_type_trans(skb, dev);
- //skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
-
- DPRINTK("passing packet\n");
- DPRINTK("len = %d rxb->status = %x\n",
- len, rxb->status.raw);
- netif_rx(skb);
+ memcpy(skb_put(skb, len), rxb->buf, len);
+ /* Write metadata, and then pass to the receive level */
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+
dev->last_rx = jiffies;
priv->stats.rx_packets++;
priv->stats.rx_bytes+=len;
- DPRINTK("There we go... Whew...\n");
+ netif_rx(skb);
}
+ } else {
+ printk(KERN_WARNING "meth: RX error: status=0x%016lx\n",status);
+ if(status&METH_RX_ST_RCV_CODE_VIOLATION)
+ printk(KERN_WARNING "Receive Code Violation\n");
+ if(status&METH_RX_ST_CRC_ERR)
+ printk(KERN_WARNING "CRC error\n");
+ if(status&METH_RX_ST_INV_PREAMBLE_CTX)
+ printk(KERN_WARNING "Invalid Preamble Context\n");
+ if(status&METH_RX_ST_LONG_EVT_SEEN)
+ printk(KERN_WARNING "Long Event Seen...\n");
+ if(status&METH_RX_ST_BAD_PACKET)
+ printk(KERN_WARNING "Bad Packet\n");
+ if(status&METH_RX_ST_CARRIER_EVT_SEEN)
+ printk(KERN_WARNING "Carrier Event Seen\n");
}
+ rxb->status.raw=0;
priv->regs->rx_fifo=priv->rx_ring_dmas[priv->rx_write];
- rxb->status.raw=0;
priv->rx_write=(priv->rx_write+1)&(RX_RING_ENTRIES-1);
+ if(priv->rx_write==twptr) {
+ DPRINTK("going rounds\n");
+ }
}
+ spin_unlock(&(priv->meth_lock));
}
static int meth_tx_full(struct net_device *dev)
@@ -505,20 +508,10 @@
/*
* The typical interrupt entry point
*/
-void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs)
+irqreturn_t meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs)
{
struct meth_private *priv;
- union {
- u32 reg; /*Whole status register */
- struct {
- u32 : 2,
- rx_seq : 5,
- tx_read : 9,
-
- rx_read : 8,
- int_mask: 8;
- } parsed;
- } status;
+ u32 status;
/*
* As usual, check the "device" pointer for shared handlers.
* Then assign "struct device *dev"
@@ -526,33 +519,44 @@
struct net_device *dev = (struct net_device *)dev_id;
/* ... and check with hw if it's really ours */
- if (!dev /*paranoid*/ ) return;
+ if (!dev /*paranoid*/ ) return IRQ_HANDLED;
- /* Lock the device */
priv = (struct meth_private *) dev->priv;
- status.reg = priv->regs->int_flags;
+ status = priv->regs->int_flags;
- DPRINTK("Interrupt, status %08x...\n",status.reg);
- if (status.parsed.int_mask & METH_INT_RX_THRESHOLD) {
+ if (status & METH_INT_RX_THRESHOLD) {
/* send it to meth_rx for handling */
meth_rx(dev);
}
- if (status.parsed.int_mask & (METH_INT_TX_EMPTY|METH_INT_TX_PKT)) {
+ if (status & (METH_INT_TX_EMPTY|METH_INT_TX_PKT)) {
/* a transmission is over: free the skb */
- meth_tx_cleanup(dev, status.parsed.tx_read);
+ meth_tx_cleanup(dev, (priv->regs->tx_info&TX_INFO_RPTR)>>16);
}
/* check for errors too... */
- if (status.parsed.int_mask & (METH_INT_TX_LINK_FAIL))
+ if (status & (METH_INT_TX_LINK_FAIL))
printk(KERN_WARNING "meth: link failure\n");
- if (status.parsed.int_mask & (METH_INT_MEM_ERROR))
+ if (status & (METH_INT_MEM_ERROR))
printk(KERN_WARNING "meth: memory error\n");
- if (status.parsed.int_mask & (METH_INT_TX_ABORT))
+ if (status & (METH_INT_TX_ABORT))
printk(KERN_WARNING "meth: aborted\n");
- DPRINTK("Interrupt handling done...\n");
-
- priv->regs->int_flags=status.reg&0xff; /* clear interrupts */
+ if (status & (METH_INT_RX_OVERFLOW))
+ printk(KERN_WARNING "meth: RX overflow\n");
+ if (status & (METH_INT_RX_UNDERFLOW))
+ printk(KERN_WARNING "meth: RX underflow\n");
+
+#define METH_INT_ERROR (METH_INT_TX_LINK_FAIL| \
+ METH_INT_MEM_ERROR| \
+ METH_INT_TX_ABORT| \
+ METH_INT_RX_OVERFLOW| \
+ METH_INT_RX_UNDERFLOW)
+ if( status & METH_INT_ERROR) {
+ printk(KERN_WARNING "meth: error status: 0x%08x\n",status);
+ netif_wake_queue(dev);
+ }
+ priv->regs->int_flags=status&0xff; /* clear interrupts */
+ return IRQ_HANDLED;
}
/*
@@ -563,13 +567,11 @@
tx_packet *desc=&priv->tx_ring[priv->tx_write];
int len = (skb->len<ETH_ZLEN)?ETH_ZLEN:skb->len;
- DPRINTK("preparing short packet\n");
/* maybe I should set whole thing to 0 first... */
memcpy(desc->data.dt+(120-len),skb->data,skb->len);
if(skb->len < len)
memset(desc->data.dt+120-len+skb->len,0,len-skb->len);
desc->header.raw=METH_TX_CMD_INT_EN|(len-1)|((128-len)<<16);
- DPRINTK("desc=%016lx\n",desc->header.raw);
}
#define TX_CATBUF1 BIT(25)
static void meth_tx_1page_prepare(meth_private* priv, struct sk_buff* skb)
@@ -580,13 +582,6 @@
int buffer_len = skb->len - unaligned_len;
dma_addr_t catbuf;
- DPRINTK("preparing 1 page...\n");
- DPRINTK("length=%d data=%p\n", skb->len, skb->data);
- DPRINTK("unaligned_len=%d\n", unaligned_len);
- DPRINTK("buffer_data=%p buffer_len=%d\n",
- buffer_data,
- buffer_len);
-
desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|(skb->len-1);
/* unaligned part */
@@ -601,11 +596,8 @@
buffer_data,
buffer_len,
PCI_DMA_TODEVICE);
- DPRINTK("catbuf=%x\n", catbuf);
desc->data.cat_buf[0].form.start_addr = catbuf >> 3;
desc->data.cat_buf[0].form.len = buffer_len-1;
- DPRINTK("desc=%016lx\n",desc->header.raw);
- DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw);
}
#define TX_CATBUF2 BIT(26)
static void meth_tx_2page_prepare(meth_private* priv, struct sk_buff* skb)
@@ -618,16 +610,6 @@
int buffer2_len = skb->len - buffer1_len - unaligned_len;
dma_addr_t catbuf1, catbuf2;
- DPRINTK("preparing 2 pages... \n");
- DPRINTK("length=%d data=%p\n", skb->len, skb->data);
- DPRINTK("unaligned_len=%d\n", unaligned_len);
- DPRINTK("buffer1_data=%p buffer1_len=%d\n",
- buffer1_data,
- buffer1_len);
- DPRINTK("buffer2_data=%p buffer2_len=%d\n",
- buffer2_data,
- buffer2_len);
-
desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|TX_CATBUF2|(skb->len-1);
/* unaligned part */
if(unaligned_len){
@@ -641,7 +623,6 @@
buffer1_data,
buffer1_len,
PCI_DMA_TODEVICE);
- DPRINTK("catbuf1=%x\n", catbuf1);
desc->data.cat_buf[0].form.start_addr = catbuf1 >> 3;
desc->data.cat_buf[0].form.len = buffer1_len-1;
/* second page */
@@ -649,18 +630,12 @@
buffer2_data,
buffer2_len,
PCI_DMA_TODEVICE);
- DPRINTK("catbuf2=%x\n", catbuf2);
desc->data.cat_buf[1].form.start_addr = catbuf2 >> 3;
desc->data.cat_buf[1].form.len = buffer2_len-1;
- DPRINTK("desc=%016lx\n",desc->header.raw);
- DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw);
- DPRINTK("cat_buf[1].raw=%016lx\n",desc->data.cat_buf[1].raw);
}
-
void meth_add_to_tx_ring(meth_private *priv, struct sk_buff* skb)
{
- DPRINTK("Transmitting data...\n");
if(skb->len <= 120) {
/* Whole packet fits into descriptor */
meth_tx_short_prepare(priv,skb);
@@ -676,7 +651,7 @@
/* Remember the skb, so we can free it at interrupt time */
priv->tx_skbs[priv->tx_write] = skb;
priv->tx_write = (priv->tx_write+1) & (TX_RING_ENTRIES-1);
- priv->regs->tx_info.wptr = priv->tx_write;
+ priv->regs->tx_info = priv->tx_write;
priv->tx_count ++;
/* Enable DMA transfer */
priv->regs->dma_ctrl |= METH_DMA_TX_INT_EN;
@@ -689,18 +664,18 @@
{
struct meth_private *priv = (struct meth_private *) dev->priv;
- spin_lock_irq(&priv->meth_lock);
+ spin_lock(&priv->meth_lock);
meth_add_to_tx_ring(priv, skb);
dev->trans_start = jiffies; /* save the timestamp */
/* If TX ring is full, tell the upper layer to stop sending packets */
if (meth_tx_full(dev)) {
- DPRINTK("TX full: stopping\n");
+ printk("TX full: stopping\n");
netif_stop_queue(dev);
}
- spin_unlock_irq(&priv->meth_lock);
+ spin_unlock(&priv->meth_lock);
return 0;
}
@@ -716,9 +691,9 @@
printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
/* Protect against concurrent rx interrupts */
- spin_lock_irq(&priv->meth_lock);
+ spin_lock(&priv->meth_lock);
- /* Try to reset the adaptor. */
+ /* Try to reset the interface. */
meth_reset(dev);
priv->stats.tx_errors++;
@@ -733,7 +708,7 @@
priv->regs->dma_ctrl|=METH_DMA_TX_EN|METH_DMA_RX_EN|METH_DMA_RX_INT_EN;
/* Enable interrupt */
- spin_unlock_irq(&priv->meth_lock);
+ spin_unlock(&priv->meth_lock);
dev->trans_start = jiffies;
netif_wake_queue(dev);
@@ -747,8 +722,8 @@
int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- DPRINTK("ioctl\n");
- return 0;
+ DPRINTK("ioctl\n");
+ return 0;
}
/*
@@ -756,8 +731,8 @@
*/
struct net_device_stats *meth_stats(struct net_device *dev)
{
- struct meth_private *priv = (struct meth_private *) dev->priv;
- return &priv->stats;
+ struct meth_private *priv = (struct meth_private *) dev->priv;
+ return &priv->stats;
}
/*
@@ -767,7 +742,6 @@
int meth_init(struct net_device *dev)
{
meth_private *priv;
- int ret;
/*
* Then, assign other fields in dev, using ether_setup() and some
* hand assignments
@@ -806,20 +780,9 @@
dev->base_addr=SGI_MFE;
priv->phy_addr = -1; /* No phy is known yet... */
- /* Initialize the hardware */
- if((ret=meth_reset(dev)) < 0)
- return ret;
-
- /* Allocate the ring buffers */
- if((ret=meth_init_tx_ring(priv))<0||(ret=meth_init_rx_ring(priv))<0){
- meth_free_tx_ring(priv);
- meth_free_rx_ring(priv);
- return ret;
- }
-
printk("SGI O2 Fast Ethernet rev. %ld\n", priv->regs->mac_ctrl >> 29);
- return 0;
+ return 0;
}
/*
@@ -827,7 +790,7 @@
*/
struct net_device meth_devs[1] = {
- { init: meth_init, } /* init, nothing more */
+ { init: meth_init, } /* init, nothing more */
};
/*
@@ -844,18 +807,15 @@
printk("meth: error %i registering device \"%s\"\n",
result, meth_devs->name);
else device_present++;
-#ifndef METH_DEBUG
- EXPORT_NO_SYMBOLS;
-#endif
return device_present ? 0 : -ENODEV;
}
void meth_cleanup(void)
{
- kfree(meth_devs->priv);
- unregister_netdev(meth_devs);
- return;
+ kfree(meth_devs->priv);
+ unregister_netdev(meth_devs);
+ return;
}
module_init(meth_init_module);
Index: drivers/net/meth.h
===================================================================
RCS file: /home/cvs/linux/drivers/net/meth.h,v
retrieving revision 1.2
diff -u -r1.2 meth.h
--- drivers/net/meth.h 1 Jul 2002 20:01:25 -0000 1.2
+++ drivers/net/meth.h 29 Jun 2003 22:55:45 -0000
@@ -85,7 +85,7 @@
} tx_packet;
typedef union rx_status_vector {
- struct {
+ volatile struct {
u64 pad1:1;/*fill it with ones*/
u64 pad2:15;/*fill with 0*/
u64 ip_chk_sum:16;
@@ -103,7 +103,7 @@
u64 rx_code_violation:1;
u64 rx_len:16;
} parsed;
- u64 raw;
+ volatile u64 raw;
} rx_status_vector;
typedef struct rx_packet {
@@ -113,6 +113,8 @@
char buf[METH_RX_BUFF_SIZE-sizeof(rx_status_vector)-3*sizeof(u64)-sizeof(u16)];/* data */
} rx_packet;
+#define TX_INFO_RPTR 0x00FF0000
+#define TX_INFO_WPTR 0x000000FF
typedef struct meth_regs {
u64 mac_ctrl; /*0x00,rw,31:0*/
u64 int_flags; /*0x08,rw,30:0*/
@@ -120,10 +122,7 @@
u64 timer; /*0x18,rw,5:0*/
u64 int_tx; /*0x20,wo,0:0*/
u64 int_rx; /*0x28,wo,9:4*/
- struct {
- u32 tx_info_pad;
- u32 rptr:16,wptr:16;
- } tx_info; /*0x30,rw,31:0*/
+ u64 tx_info; /*0x30,rw,31:0*/
u64 tx_info_al; /*0x38,rw,31:0*/
struct {
u32 rx_buff_pad1;
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2003-06-29 22:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-06-29 22:57 meth.c ilya
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox