Commit d0d43048 authored by Dave Jones's avatar Dave Jones Committed by Jeff Garzik

[netdrvr rcpci45] final vendor update

parent a74f6ff1
......@@ -29,6 +29,9 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
** Pete Popov, Oct 2001: Fixed a few bugs to make the driver functional
** again. Note that this card is not supported or manufactured by
** RedCreek anymore.
**
** Rasmus Andersen, December 2000: Converted to new PCI API and general
** cleanup.
......@@ -63,7 +66,7 @@
#include <asm/uaccess.h>
static char version[] __initdata =
"RedCreek Communications PCI linux driver version 2.03\n";
"RedCreek Communications PCI linux driver version 2.20\n";
#define RC_LINUX_MODULE
#include "rclanmtl.h"
......@@ -88,6 +91,14 @@ static char version[] __initdata =
/* RedCreek's OSM default LAN receive Initiator */
#define DEFAULT_RECV_INIT_CONTEXT 0xA17
/* minimum msg buffer size needed by the card
* Note that the size of this buffer is hard code in the
* ipsec card's firmware. Thus, the size MUST be a minimum
* of 16K. Otherwise the card will end up using memory
* that does not belong to it.
*/
#define MSG_BUF_SIZE 16384
static U32 DriverControlWord;
static void rc_timer (unsigned long);
......@@ -119,38 +130,24 @@ rcpci45_remove_one (struct pci_dev *pdev)
PDPA pDpa = dev->priv;
if (!dev) {
printk (KERN_ERR
"(rcpci45 driver:) remove non-existent device\n");
printk (KERN_ERR "%s: remove non-existent device\n",
dev->name);
return;
}
dprintk ("remove_one: IOP reset: 0x%x\n", RCResetIOP (dev));
/* RAA Inspired by starfire.c and yellowfin.c we keep these
* here. */
RCResetIOP (dev);
unregister_netdev (dev);
free_irq (dev->irq, dev);
iounmap ((void *) dev->base_addr);
pci_release_regions (pdev);
kfree (pDpa->PLanApiPA);
if (pDpa->msgbuf)
kfree (pDpa->msgbuf);
if (pDpa->pPab)
kfree (pDpa->pPab);
kfree (pDpa);
kfree (dev);
pci_set_drvdata (pdev, NULL);
}
static int
RCinit (struct net_device *dev)
{
dev->open = &RCopen;
dev->hard_start_xmit = &RC_xmit_packet;
dev->stop = &RCclose;
dev->get_stats = &RCget_stats;
dev->do_ioctl = &RCioctl;
dev->set_config = &RCconfig;
return 0;
}
static int
rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
......@@ -165,17 +162,17 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
/*
* Allocate and fill new device structure.
* We need enough for struct net_device plus DPA plus the LAN API private
* area, which requires a minimum of 16KB. The top of the allocated
* area will be assigned to struct net_device; the next chunk will be
* assigned to DPA; and finally, the rest will be assigned to the
* the LAN API layer.
* We need enough for struct net_device plus DPA plus the LAN
* API private area, which requires a minimum of 16KB. The top
* of the allocated area will be assigned to struct net_device;
* the next chunk will be assigned to DPA; and finally, the rest
* will be assigned to the LAN API layer.
*/
dev = init_etherdev (NULL, sizeof (*pDpa));
if (!dev) {
printk (KERN_ERR
"(rcpci45 driver:) unable to allocate in init_etherdev\n");
"(rcpci45 driver:) init_etherdev alloc failed\n");
error = -ENOMEM;
goto err_out;
}
......@@ -183,13 +180,14 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
error = pci_enable_device (pdev);
if (error) {
printk (KERN_ERR
"(rcpci45 driver:) %d: unable to enable pci device, aborting\n",
"(rcpci45 driver:) %d: pci enable device error\n",
card_idx);
goto err_out;
}
error = -ENOMEM;
pci_start = pci_resource_start (pdev, 0);
pci_len = pci_resource_len (pdev, 0);
printk("pci_start %lx pci_len %lx\n", pci_start, pci_len);
pci_set_drvdata (pdev, dev);
......@@ -199,29 +197,30 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (!pci_start || !(pci_resource_flags (pdev, 0) & IORESOURCE_MEM)) {
printk (KERN_ERR
"(rcpci45 driver:) No PCI memory resources! Aborting.\n");
"(rcpci45 driver:) No PCI mem resources! Aborting\n");
error = -EBUSY;
goto err_out_free_dev;
}
/*
* Save the starting address of the LAN API private area. We'll
* pass that to RCInitI2OMsgLayer().
* pDpa->msgbuf is where the card will dma the I2O
* messages. Thus, we need contiguous physical pages of
* memory.
*/
/* RAA FIXME: This size should be a #define somewhere after I
* clear up some questions: What flags are neeeded in the alloc below
* and what needs to be done before the memarea is long word aligned?
* (Look in old code for an approach.) (Also note that the 16K below
* is substantially less than the 32K allocated before (even though
* some of the spacce was used for data structures.) */
pDpa->msgbuf = kmalloc (16384, GFP_KERNEL);
pDpa->msgbuf = kmalloc (MSG_BUF_SIZE, GFP_DMA|GFP_ATOMIC|GFP_KERNEL);
if (!pDpa->msgbuf) {
printk (KERN_ERR "(rcpci45 driver:) Could not allocate %d byte memory for the private msgbuf!\n", 16384); /* RAA FIXME not hardcoded! */
printk (KERN_ERR "(rcpci45 driver:) \
Could not allocate %d byte memory for the \
private msgbuf!\n", MSG_BUF_SIZE);
goto err_out_free_dev;
}
pDpa->PLanApiPA = (void *) (((long) pDpa->msgbuf + 0xff) & ~0xff);
dprintk ("pDpa->PLanApiPA = %p\n", pDpa->PLanApiPA);
/*
* Save the starting address of the LAN API private area. We'll
* pass that to RCInitI2OMsgLayer().
*
*/
pDpa->PLanApiPA = (void *) (((long) pDpa->msgbuf + 0xff) & ~0xff);
/* The adapter is accessible through memory-access read/write, not
* I/O read/write. Thus, we need to map it to some virtual address
......@@ -234,17 +233,20 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
vaddr = (ulong *) ioremap (pci_start, pci_len);
if (!vaddr) {
printk (KERN_ERR
"(rcpci45 driver:) Unable to remap address range from %lu to %lu\n",
"(rcpci45 driver:) \
Unable to remap address range from %lu to %lu\n",
pci_start, pci_start + pci_len);
goto err_out_free_region;
}
dprintk ("rcpci45_init_one: 0x%x, priv = 0x%x, vaddr = 0x%x\n",
(uint) dev, (uint) dev->priv, (uint) vaddr);
dev->base_addr = (unsigned long) vaddr;
dev->irq = pdev->irq;
dev->init = &RCinit;
dev->open = &RCopen;
dev->hard_start_xmit = &RC_xmit_packet;
dev->stop = &RCclose;
dev->get_stats = &RCget_stats;
dev->do_ioctl = &RCioctl;
dev->set_config = &RCconfig;
return 0; /* success */
......@@ -257,7 +259,7 @@ rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
kfree (dev);
err_out:
card_idx--;
return error;
return -ENODEV;
}
static struct pci_driver rcpci45_driver = {
......@@ -271,9 +273,8 @@ static int __init
rcpci_init_module (void)
{
int rc = pci_module_init (&rcpci45_driver);
if (!rc)
printk (KERN_INFO "%s", version);
printk (KERN_ERR "%s", version);
return rc;
}
......@@ -286,28 +287,46 @@ RCopen (struct net_device *dev)
int requested = 0;
int error;
dprintk ("(rcpci45 driver:) RCopen\n");
/* Request a shared interrupt line. */
error = request_irq (dev->irq, RCinterrupt, SA_SHIRQ, dev->name, dev);
if (error) {
printk (KERN_ERR "(rcpci45 driver:) %s: unable to get IRQ %d\n",
dev->name, dev->irq);
goto err_out;
}
MOD_INC_USE_COUNT;
if (pDpa->nexus) {
/* This is not the first time RCopen is called. Thus,
* the interface was previously opened and later closed
* by RCclose(). RCclose() does a Shutdown; to wake up
* the adapter, a reset is mandatory before we can post
* receive buffers. However, if the adapter initiated
* a reboot while the interface was closed -- and interrupts
* were turned off -- we need will need to reinitialize
* the adapter, rather than simply waking it up.
*/
printk (KERN_INFO "Waking up adapter...\n");
RCResetLANCard (dev, 0, 0, 0);
} else {
pDpa->nexus = 1;
/*
* RCInitI2OMsgLayer is done only once, unless the
* adapter was sent a warm reboot
*/
error = RCInitI2OMsgLayer (dev, (PFNTXCALLBACK) RCxmit_callback,
(PFNRXCALLBACK) RCrecv_callback,
(PFNCALLBACK) RCreboot_callback);
if (error) {
printk (KERN_ERR
"(rcpci45 driver:) Unable to initialize msg layer\n");
goto err_out_free_irq;
printk (KERN_ERR "%s: Unable to init msg layer (%x)\n",
dev->name, error);
goto err_out;
}
if ((error = RCGetMAC (dev, NULL))) {
printk (KERN_ERR
"(rcpci45 driver:) Unable to get adapter MAC\n");
goto err_out_free_irq;
printk (KERN_ERR "%s: Unable to get adapter MAC\n",
dev->name);
goto err_out;
}
}
/* Request a shared interrupt line. */
error = request_irq (dev->irq, RCinterrupt, SA_SHIRQ, dev->name, dev);
if (error) {
printk (KERN_ERR "%s: unable to get IRQ %d\n",
dev->name, dev->irq);
goto err_out;
}
DriverControlWord |= WARM_REBOOT_CAPABLE;
......@@ -316,26 +335,8 @@ RCopen (struct net_device *dev)
printk (KERN_INFO "%s: RedCreek Communications IPSEC VPN adapter\n",
dev->name);
/* RAA: Old RCopen starts here */
RCEnableI2OInterrupts (dev);
/* RAA Hmm, how does the comment below jibe with the newly imported
* code above? A FIXME!!*/
if (pDpa->nexus) {
/* This is not the first time RCopen is called. Thus,
* the interface was previously opened and later closed
* by RCclose(). RCclose() does a Shutdown; to wake up
* the adapter, a reset is mandatory before we can post
* receive buffers. However, if the adapter initiated
* a reboot while the interface was closed -- and interrupts
* were turned off -- we need will need to reinitialize
* the adapter, rather than simply waking it up.
*/
dprintk (KERN_INFO "Waking up adapter...\n");
RCResetLANCard (dev, 0, 0, 0);
} else
pDpa->nexus = 1;
while (post_buffers) {
if (post_buffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
requested = MAX_NMBR_POST_BUFFERS_PER_MSG;
......@@ -345,29 +346,30 @@ RCopen (struct net_device *dev)
if (count < requested) {
/*
* Check to see if we were able to post any buffers at all.
* Check to see if we were able to post
* any buffers at all.
*/
if (post_buffers == MAX_NMBR_RCV_BUFFERS) {
printk (KERN_ERR
"(rcpci45 driver:) Error RCopen: not able to allocate any buffers\r\n");
return (-ENOMEM);
printk (KERN_ERR "%s: \
unable to allocate any buffers\n",
dev->name);
goto err_out_free_irq;
}
printk (KERN_WARNING
"(rcpci45 driver:) Warning RCopen: not able to allocate all requested buffers\r\n");
printk (KERN_WARNING "%s: \
unable to allocate all requested buffers\n", dev->name);
break; /* we'll try to post more buffers later */
} else
post_buffers -= count;
}
pDpa->numOutRcvBuffers = MAX_NMBR_RCV_BUFFERS - post_buffers;
pDpa->shutdown = 0; /* just in case */
dprintk ("RCopen: posted %d buffers\n", (uint) pDpa->numOutRcvBuffers);
MOD_INC_USE_COUNT;
netif_start_queue (dev);
return 0;
err_out_free_irq:
free_irq (dev->irq, dev);
err_out:
MOD_DEC_USE_COUNT;
return error;
}
......@@ -383,15 +385,16 @@ RC_xmit_packet (struct sk_buff *skb, struct net_device *dev)
netif_stop_queue (dev);
if (pDpa->shutdown || pDpa->reboot) {
dprintk ("RC_xmit_packet: tbusy!\n");
printk ("RC_xmit_packet: tbusy!\n");
return 1;
}
/*
* The user is free to reuse the TCB after RCI2OSendPacket() returns, since
* the function copies the necessary info into its own private space. Thus,
* our TCB can be a local structure. The skb, on the other hand, will be
* freed up in our interrupt handler.
* The user is free to reuse the TCB after RCI2OSendPacket()
* returns, since the function copies the necessary info into its
* own private space. Thus, our TCB can be a local structure.
* The skb, on the other hand, will be freed up in our interrupt
* handler.
*/
ptcb->bcount = 1;
......@@ -405,11 +408,9 @@ RC_xmit_packet (struct sk_buff *skb, struct net_device *dev)
ptcb->b.size = skb->len;
ptcb->b.addr = virt_to_bus ((void *) skb->data);
dprintk ("RC xmit: skb = 0x%x, pDpa = 0x%x, id = %d, ptcb = 0x%x\n",
(uint) skb, (uint) pDpa, (uint) pDpa->id, (uint) ptcb);
if ((status = RCI2OSendPacket (dev, (U32) NULL, (PRCTCB) ptcb))
!= RC_RTN_NO_ERROR) {
dprintk ("RC send error 0x%x\n", (uint) status);
printk ("%s: send error 0x%x\n", dev->name, (uint) status);
return 1;
} else {
dev->trans_start = jiffies;
......@@ -439,23 +440,20 @@ RCxmit_callback (U32 Status,
PDPA pDpa = dev->priv;
if (!pDpa) {
printk (KERN_ERR
"(rcpci45 driver:) Fatal error: xmit callback, !pDpa\n");
printk (KERN_ERR "%s: Fatal Error in xmit callback, !pDpa\n",
dev->name);
return;
}
/* dprintk("xmit_callback: Status = 0x%x\n", (uint)Status); */
if (Status != I2O_REPLY_STATUS_SUCCESS)
dprintk ("xmit_callback: Status = 0x%x\n", (uint) Status);
printk (KERN_INFO "%s: xmit_callback: Status = 0x%x\n",
dev->name, (uint) Status);
if (pDpa->shutdown || pDpa->reboot)
dprintk ("xmit callback: shutdown||reboot\n");
dprintk ("xmit_callback: PcktCount = %d, BC = 0x%x\n",
(uint) PcktCount, (uint) BufferContext);
printk (KERN_INFO "%s: xmit callback: shutdown||reboot\n",
dev->name);
while (PcktCount--) {
skb = (struct sk_buff *) (BufferContext[0]);
dprintk ("skb = 0x%x\n", (uint) skb);
BufferContext++;
dev_kfree_skb_irq (skb);
}
......@@ -467,19 +465,18 @@ RCreset_callback (U32 Status, U32 p1, U32 p2, struct net_device *dev)
{
PDPA pDpa = dev->priv;
dprintk ("RCreset_callback Status 0x%x\n", (uint) Status);
printk ("RCreset_callback Status 0x%x\n", (uint) Status);
/*
* Check to see why we were called.
*/
if (pDpa->shutdown) {
printk (KERN_INFO
"(rcpci45 driver:) Shutting down interface\n");
printk (KERN_INFO "%s: shutting down interface\n",
dev->name);
pDpa->shutdown = 0;
pDpa->reboot = 0;
MOD_DEC_USE_COUNT;
} else if (pDpa->reboot) {
printk (KERN_INFO
"(rcpci45 driver:) reboot, shutdown adapter\n");
printk (KERN_INFO "%s: reboot, shutdown adapter\n",
dev->name);
/*
* We don't set any of the flags in RCShutdownLANCard()
* and we don't pass a callback routine to it.
......@@ -488,7 +485,7 @@ RCreset_callback (U32 Status, U32 p1, U32 p2, struct net_device *dev)
*/
RCDisableI2OInterrupts (dev);
RCShutdownLANCard (dev, 0, 0, 0);
printk (KERN_INFO "(rcpci45 driver:) scheduling timer...\n");
printk (KERN_INFO "%s: scheduling timer...\n", dev->name);
init_timer (&pDpa->timer);
pDpa->timer.expires = RUN_AT ((40 * HZ) / 10); /* 4 sec. */
pDpa->timer.data = (unsigned long) dev;
......@@ -502,12 +499,12 @@ RCreboot_callback (U32 Status, U32 p1, U32 p2, struct net_device *dev)
{
PDPA pDpa = dev->priv;
dprintk ("RCreboot: rcv buffers outstanding = %d\n",
(uint) pDpa->numOutRcvBuffers);
printk (KERN_INFO "%s: reboot: rcv buffers outstanding = %d\n",
dev->name, (uint) pDpa->numOutRcvBuffers);
if (pDpa->shutdown) {
printk (KERN_INFO
"(rcpci45 driver:) skipping reboot sequence -- shutdown already initiated\n");
printk (KERN_INFO "%s: skip reboot, shutdown initiated\n",
dev->name);
return;
}
pDpa->reboot = 1;
......@@ -559,12 +556,9 @@ RCrecv_callback (U32 Status,
ptcb->bcount = 1;
dprintk ("RCrecv_callback: 0x%x, 0x%x, 0x%x\n",
(uint) PktCount, (uint) BucketsRemain, (uint) PacketDescBlock);
if ((pDpa->shutdown || pDpa->reboot) && !Status)
dprintk ("shutdown||reboot && !Status: PktCount = %d\n",
PktCount);
printk (KERN_INFO "%s: shutdown||reboot && !Status (%d)\n",
dev->name, PktCount);
if ((Status != I2O_REPLY_STATUS_SUCCESS) || pDpa->shutdown) {
/*
......@@ -573,76 +567,38 @@ RCrecv_callback (U32 Status,
*/
if (!pDpa->shutdown && !pDpa->reboot)
printk (KERN_INFO
"(rcpci45 driver:) RCrecv error: status = 0x%x\n",
(uint) Status);
printk (KERN_INFO "%s: recv error status = 0x%x\n",
dev->name, (uint) Status);
else
dprintk ("Returning %d buffers, status = 0x%x\n",
PktCount, (uint) Status);
printk (KERN_DEBUG "%s: Returning %d buffs stat 0x%x\n",
dev->name, PktCount, (uint) Status);
/*
* TO DO: check the nature of the failure and put the adapter in
* failed mode if it's a hard failure. Send a reset to the adapter
* and free all outstanding memory.
* TO DO: check the nature of the failure and put the
* adapter in failed mode if it's a hard failure.
* Send a reset to the adapter and free all outstanding memory.
*/
if (Status == I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER)
dprintk ("RCrecv status ABORT NO DATA TRANSFER\n");
/* check for reset status: I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER */
if (PacketDescBlock) {
while (PktCount--) {
skb = (struct sk_buff *) PacketDescBlock[0];
dprintk ("free skb 0x%p\n", skb);
dev_kfree_skb (skb);
pDpa->numOutRcvBuffers--;
PacketDescBlock += BD_SIZE; /* point to next context field */
/* point to next context field */
PacketDescBlock += BD_SIZE;
}
}
return;
} else {
while (PktCount--) {
skb = (struct sk_buff *) PacketDescBlock[0];
if (pDpa->shutdown)
dprintk ("shutdown: skb=0x%x\n", (uint) skb);
dprintk ("skb = 0x%x: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
(uint) skb, (uint) skb->data[0],
(uint) skb->data[1], (uint) skb->data[2],
(uint) skb->data[3], (uint) skb->data[4],
(uint) skb->data[5]);
#ifdef PROMISCUOUS_BY_DEFAULT /* early 2.x firmware */
if ((memcmp (dev->dev_addr, skb->data, 6)) &&
(!broadcast_packet (skb->data))) {
/*
* Re-post the buffer to the adapter. Since the adapter usually
* return 1 to 2 receive buffers at a time, it's not too inefficient
* post one buffer at a time but ... may be that should be
* optimized at some point.
*/
ptcb->b.context = (U32) skb;
ptcb->b.scount = 1;
ptcb->b.size = MAX_ETHER_SIZE;
ptcb->b.addr = virt_to_bus ((void *) skb->data);
if (RCPostRecvBuffers (dev, (PRCTCB) ptcb) !=
RC_RTN_NO_ERROR) {
printk (KERN_WARNING
"(rcpci45 driver:) RCrecv_callback: post buffer failed!\n");
dev_kfree_skb (skb);
} else
pDpa->numOutRcvBuffers++;
} else
#endif /* PROMISCUOUS_BY_DEFAULT */
{
len = PacketDescBlock[2];
skb->dev = dev;
skb_put (skb, len); /* adjust length and tail */
skb->protocol = eth_type_trans (skb, dev);
netif_rx (skb); /* send the packet to the kernel */
dev->last_rx = jiffies;
}
pDpa->numOutRcvBuffers--;
PacketDescBlock += BD_SIZE; /* point to next context field */
/* point to next context field */
PacketDescBlock += BD_SIZE;
}
}
......@@ -679,11 +635,8 @@ RCinterrupt (int irq, void *dev_id, struct pt_regs *regs)
pDpa = dev->priv;
if (pDpa->shutdown)
dprintk ("shutdown: service irq\n");
dprintk ("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n",
(uint) pDpa, (uint) dev, (uint) pDpa->id);
dprintk ("dev = 0x%x\n", (uint) dev);
printk (KERN_DEBUG "%s: shutdown, service irq\n",
dev->name);
RCProcI2OMsgQ (dev);
}
......@@ -714,7 +667,11 @@ rc_timer (unsigned long data)
RCReportDriverCapability (dev, DriverControlWord);
RCEnableI2OInterrupts (dev);
if (dev->flags & IFF_UP) {
if (!(dev->flags & IFF_UP)) {
retry = 0;
return;
}
while (post_buffers) {
if (post_buffers >
MAX_NMBR_POST_BUFFERS_PER_MSG)
......@@ -731,45 +688,39 @@ rc_timer (unsigned long data)
}
pDpa->numOutRcvBuffers =
MAX_NMBR_RCV_BUFFERS - post_buffers;
dprintk ("rc: posted %d buffers \r\n",
(uint) pDpa->numOutRcvBuffers);
}
dprintk ("Initialization done.\n");
printk ("Initialization done.\n");
netif_wake_queue (dev);
retry = 0;
return;
case RC_RTN_FREE_Q_EMPTY:
retry++;
printk (KERN_WARNING
"(rcpci45 driver:) inbound free q empty\n");
printk (KERN_WARNING "%s inbound free q empty\n",
dev->name);
break;
default:
retry++;
printk (KERN_WARNING
"(rcpci45 driver:) bad status after reboot: %d\n",
init_status);
printk (KERN_WARNING "%s bad stat after reboot: %d\n",
dev->name, init_status);
break;
}
if (retry > REBOOT_REINIT_RETRY_LIMIT) {
printk (KERN_WARNING
"(rcpci45 driver:) unable to reinitialize adapter after reboot\n");
printk (KERN_WARNING
"(rcpci45 driver:) decrementing driver and closing interface\n");
printk (KERN_WARNING "%s unable to reinitialize adapter after reboot\n", dev->name);
printk (KERN_WARNING "%s decrementing driver and closing interface\n", dev->name);
RCDisableI2OInterrupts (dev);
dev->flags &= ~IFF_UP;
MOD_DEC_USE_COUNT;
} else {
printk (KERN_INFO
"(rcpci45 driver:) rescheduling timer...\n");
printk (KERN_INFO "%s: rescheduling timer...\n",
dev->name);
init_timer (&pDpa->timer);
pDpa->timer.expires = RUN_AT ((40 * HZ) / 10); /* 3 sec. */
pDpa->timer.expires = RUN_AT ((40 * HZ) / 10);
pDpa->timer.data = (unsigned long) dev;
pDpa->timer.function = &rc_timer; /* timer handler */
pDpa->timer.function = &rc_timer;
add_timer (&pDpa->timer);
}
} else
printk (KERN_WARNING "(rcpci45 driver:) timer??\n");
printk (KERN_WARNING "%s: unexpected timer irq\n", dev->name);
}
static int
......@@ -777,19 +728,16 @@ RCclose (struct net_device *dev)
{
PDPA pDpa = dev->priv;
printk("RCclose\n");
netif_stop_queue (dev);
dprintk ("RCclose\r\n");
if (pDpa->reboot) {
printk (KERN_INFO
"(rcpci45 driver:) skipping reset -- adapter already in reboot mode\n");
printk (KERN_INFO "%s skipping reset -- adapter already in reboot mode\n", dev->name);
dev->flags &= ~IFF_UP;
pDpa->shutdown = 1;
MOD_DEC_USE_COUNT;
return 0;
}
dprintk ("receive buffers outstanding: %d\n",
(uint) pDpa->numOutRcvBuffers);
pDpa->shutdown = 1;
......@@ -805,6 +753,7 @@ RCclose (struct net_device *dev)
(PFNCALLBACK) RCreset_callback);
dev->flags &= ~IFF_UP;
MOD_DEC_USE_COUNT;
return 0;
}
......@@ -816,40 +765,26 @@ RCget_stats (struct net_device *dev)
PDPA pDpa = dev->priv;
if (!pDpa) {
dprintk ("RCget_stats: !pDpa\n");
return 0;
} else if (!(dev->flags & IFF_UP)) {
dprintk ("RCget_stats: device down\n");
return 0;
}
memset (&RCstats, 0, sizeof (RCLINKSTATS));
if ((RCGetLinkStatistics (dev, &RCstats, (void *) 0)) ==
RC_RTN_NO_ERROR) {
dprintk ("TX_good 0x%x\n", (uint) RCstats.TX_good);
dprintk ("TX_maxcol 0x%x\n", (uint) RCstats.TX_maxcol);
dprintk ("TX_latecol 0x%x\n", (uint) RCstats.TX_latecol);
dprintk ("TX_urun 0x%x\n", (uint) RCstats.TX_urun);
dprintk ("TX_crs 0x%x\n", (uint) RCstats.TX_crs);
dprintk ("TX_def 0x%x\n", (uint) RCstats.TX_def);
dprintk ("TX_singlecol 0x%x\n", (uint) RCstats.TX_singlecol);
dprintk ("TX_multcol 0x%x\n", (uint) RCstats.TX_multcol);
dprintk ("TX_totcol 0x%x\n", (uint) RCstats.TX_totcol);
dprintk ("Rcv_good 0x%x\n", (uint) RCstats.Rcv_good);
dprintk ("Rcv_CRCerr 0x%x\n", (uint) RCstats.Rcv_CRCerr);
dprintk ("Rcv_alignerr 0x%x\n", (uint) RCstats.Rcv_alignerr);
dprintk ("Rcv_reserr 0x%x\n", (uint) RCstats.Rcv_reserr);
dprintk ("Rcv_orun 0x%x\n", (uint) RCstats.Rcv_orun);
dprintk ("Rcv_cdt 0x%x\n", (uint) RCstats.Rcv_cdt);
dprintk ("Rcv_runt 0x%x\n", (uint) RCstats.Rcv_runt);
pDpa->stats.rx_packets = RCstats.Rcv_good; /* total packets received */
pDpa->stats.tx_packets = RCstats.TX_good; /* total packets transmitted */
pDpa->stats.rx_errors = RCstats.Rcv_CRCerr + RCstats.Rcv_alignerr + RCstats.Rcv_reserr + RCstats.Rcv_orun + RCstats.Rcv_cdt + RCstats.Rcv_runt; /* bad packets received */
pDpa->stats.tx_errors = RCstats.TX_urun + RCstats.TX_crs + RCstats.TX_def + RCstats.TX_totcol; /* packet transmit problems */
/* total packets received */
pDpa->stats.rx_packets = RCstats.Rcv_good
/* total packets transmitted */;
pDpa->stats.tx_packets = RCstats.TX_good;
pDpa->stats.rx_errors = RCstats.Rcv_CRCerr +
RCstats.Rcv_alignerr + RCstats.Rcv_reserr +
RCstats.Rcv_orun + RCstats.Rcv_cdt + RCstats.Rcv_runt;
pDpa->stats.tx_errors = RCstats.TX_urun + RCstats.TX_crs +
RCstats.TX_def + RCstats.TX_totcol;
/*
* This needs improvement.
......@@ -861,11 +796,11 @@ RCget_stats (struct net_device *dev)
/* detailed rx_errors: */
pDpa->stats.rx_length_errors = 0;
pDpa->stats.rx_over_errors = RCstats.Rcv_orun; /* receiver ring buff overflow */
pDpa->stats.rx_crc_errors = RCstats.Rcv_CRCerr; /* recved pkt with crc error */
pDpa->stats.rx_frame_errors = 0; /* recv'd frame alignment error */
pDpa->stats.rx_fifo_errors = 0; /* recv'r fifo overrun */
pDpa->stats.rx_missed_errors = 0; /* receiver missed packet */
pDpa->stats.rx_over_errors = RCstats.Rcv_orun;
pDpa->stats.rx_crc_errors = RCstats.Rcv_CRCerr;
pDpa->stats.rx_frame_errors = 0;
pDpa->stats.rx_fifo_errors = 0;
pDpa->stats.rx_missed_errors = 0;
/* detailed tx_errors */
pDpa->stats.tx_aborted_errors = 0;
......@@ -885,8 +820,6 @@ RCioctl (struct net_device *dev, struct ifreq *rq, int cmd)
RCuser_struct RCuser;
PDPA pDpa = dev->priv;
dprintk ("RCioctl: cmd = 0x%x\n", cmd);
if (!capable (CAP_NET_ADMIN))
return -EPERM;
......@@ -910,16 +843,12 @@ RCioctl (struct net_device *dev, struct ifreq *rq, int cmd)
switch (RCuser.cmd) {
case RCUC_GETFWVER:
printk (KERN_INFO
"(rcpci45 driver:) RC GETFWVER\n");
RCUD_GETFWVER = &RCuser.RCUS_GETFWVER;
RCGetFirmwareVer (dev,
(PU8) & RCUD_GETFWVER->
FirmString, NULL);
break;
case RCUC_GETINFO:
printk (KERN_INFO
"(rcpci45 driver:) RC GETINFO\n");
RCUD_GETINFO = &RCuser.RCUS_GETINFO;
RCUD_GETINFO->mem_start = dev->base_addr;
RCUD_GETINFO->mem_end =
......@@ -928,8 +857,6 @@ RCioctl (struct net_device *dev, struct ifreq *rq, int cmd)
RCUD_GETINFO->irq = dev->irq;
break;
case RCUC_GETIPANDMASK:
printk (KERN_INFO
"(rcpci45 driver:) RC GETIPANDMASK\n");
RCUD_GETIPANDMASK = &RCuser.RCUS_GETIPANDMASK;
RCGetRavlinIPandMask (dev,
(PU32) &
......@@ -939,8 +866,6 @@ RCioctl (struct net_device *dev, struct ifreq *rq, int cmd)
NetMask, NULL);
break;
case RCUC_GETLINKSTATISTICS:
printk (KERN_INFO
"(rcpci45 driver:) RC GETLINKSTATISTICS\n");
RCUD_GETLINKSTATISTICS =
&RCuser.RCUS_GETLINKSTATISTICS;
RCGetLinkStatistics (dev,
......@@ -949,75 +874,39 @@ RCioctl (struct net_device *dev, struct ifreq *rq, int cmd)
StatsReturn, NULL);
break;
case RCUC_GETLINKSTATUS:
printk (KERN_INFO
"(rcpci45 driver:) RC GETLINKSTATUS\n");
RCUD_GETLINKSTATUS = &RCuser.RCUS_GETLINKSTATUS;
RCGetLinkStatus (dev,
(PU32) & RCUD_GETLINKSTATUS->
ReturnStatus, NULL);
break;
case RCUC_GETMAC:
printk (KERN_INFO
"(rcpci45 driver:) RC GETMAC\n");
RCUD_GETMAC = &RCuser.RCUS_GETMAC;
RCGetMAC (dev, NULL);
memcpy(RCUD_GETMAC, dev->dev_addr, 8);
break;
case RCUC_GETPROM:
printk (KERN_INFO
"(rcpci45 driver:) RC GETPROM\n");
RCUD_GETPROM = &RCuser.RCUS_GETPROM;
RCGetPromiscuousMode (dev,
(PU32) & RCUD_GETPROM->
PromMode, NULL);
break;
case RCUC_GETBROADCAST:
printk (KERN_INFO
"(rcpci45 driver:) RC GETBROADCAST\n");
RCUD_GETBROADCAST = &RCuser.RCUS_GETBROADCAST;
RCGetBroadcastMode (dev,
(PU32) & RCUD_GETBROADCAST->
BroadcastMode, NULL);
break;
case RCUC_GETSPEED:
printk (KERN_INFO
"(rcpci45 driver:) RC GETSPEED\n");
if (!(dev->flags & IFF_UP)) {
printk (KERN_ERR
"(rcpci45 driver:) RCioctl, GETSPEED error: interface down\n");
return -ENODATA;
}
RCUD_GETSPEED = &RCuser.RCUS_GETSPEED;
RCGetLinkSpeed (dev,
(PU32) & RCUD_GETSPEED->
LinkSpeedCode, NULL);
printk (KERN_INFO
"(rcpci45 driver:) RC speed = 0x%u\n",
RCUD_GETSPEED->LinkSpeedCode);
break;
case RCUC_SETIPANDMASK:
printk (KERN_INFO
"(rcpci45 driver:) RC SETIPANDMASK\n");
RCUD_SETIPANDMASK = &RCuser.RCUS_SETIPANDMASK;
printk (KERN_INFO
"(rcpci45 driver:) RC New IP Addr = %d.%d.%d.%d, ",
(U8) ((RCUD_SETIPANDMASK->
IpAddr) & 0xff),
(U8) ((RCUD_SETIPANDMASK->
IpAddr >> 8) & 0xff),
(U8) ((RCUD_SETIPANDMASK->
IpAddr >> 16) & 0xff),
(U8) ((RCUD_SETIPANDMASK->
IpAddr >> 24) & 0xff));
printk (KERN_INFO
"(rcpci45 driver:) RC New Mask = %d.%d.%d.%d\n",
(U8) ((RCUD_SETIPANDMASK->
NetMask) & 0xff),
(U8) ((RCUD_SETIPANDMASK->
NetMask >> 8) & 0xff),
(U8) ((RCUD_SETIPANDMASK->
NetMask >> 16) & 0xff),
(U8) ((RCUD_SETIPANDMASK->
NetMask >> 24) & 0xff));
RCSetRavlinIPandMask (dev,
(U32) RCUD_SETIPANDMASK->
IpAddr,
......@@ -1025,61 +914,33 @@ RCioctl (struct net_device *dev, struct ifreq *rq, int cmd)
NetMask);
break;
case RCUC_SETMAC:
printk (KERN_INFO
"(rcpci45 driver:) RC SETMAC\n");
RCUD_SETMAC = &RCuser.RCUS_SETMAC;
printk (KERN_INFO
"(rcpci45 driver:) RC New MAC addr = %02X:%02X:%02X:%02X:%02X:%02X\n",
(U8) (RCUD_SETMAC->mac[0]),
(U8) (RCUD_SETMAC->mac[1]),
(U8) (RCUD_SETMAC->mac[2]),
(U8) (RCUD_SETMAC->mac[3]),
(U8) (RCUD_SETMAC->mac[4]),
(U8) (RCUD_SETMAC->mac[5]));
RCSetMAC (dev, (PU8) & RCUD_SETMAC->mac);
break;
case RCUC_SETSPEED:
printk (KERN_INFO
"(rcpci45 driver:) RC SETSPEED\n");
RCUD_SETSPEED = &RCuser.RCUS_SETSPEED;
RCSetLinkSpeed (dev,
(U16) RCUD_SETSPEED->
LinkSpeedCode);
printk (KERN_INFO
"(rcpci45 driver:) RC New speed = 0x%x\n",
RCUD_SETSPEED->LinkSpeedCode);
break;
case RCUC_SETPROM:
printk (KERN_INFO
"(rcpci45 driver:) RC SETPROM\n");
RCUD_SETPROM = &RCuser.RCUS_SETPROM;
RCSetPromiscuousMode (dev,
(U16) RCUD_SETPROM->
PromMode);
printk (KERN_INFO
"(rcpci45 driver:) RC New prom mode = 0x%x\n",
RCUD_SETPROM->PromMode);
break;
case RCUC_SETBROADCAST:
printk (KERN_INFO
"(rcpci45 driver:) RC SETBROADCAST\n");
RCUD_SETBROADCAST = &RCuser.RCUS_SETBROADCAST;
RCSetBroadcastMode (dev,
(U16) RCUD_SETBROADCAST->
BroadcastMode);
printk (KERN_INFO
"(rcpci45 driver:) RC New broadcast mode = 0x%x\n",
RCUD_SETBROADCAST->BroadcastMode);
break;
default:
printk (KERN_INFO
"(rcpci45 driver:) RC command default\n");
RCUD_DEFAULT = &RCuser.RCUS_DEFAULT;
RCUD_DEFAULT->rc = 0x11223344;
break;
}
if (copy_to_user
(rq->ifr_data, &RCuser, sizeof (RCuser)))
if (copy_to_user (rq->ifr_data, &RCuser,
sizeof (RCuser)))
return -EFAULT;
break;
} /* RCU_COMMAND */
......@@ -1097,15 +958,14 @@ RCconfig (struct net_device *dev, struct ifmap *map)
/*
* To be completed ...
*/
dprintk ("RCconfig\n");
return 0;
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
"(rcpci45 driver:) Change I/O address not implemented\n");
printk (KERN_WARNING "%s Change I/O address not implemented\n",
dev->name);
return -EOPNOTSUPP;
}
return 0;
......@@ -1134,44 +994,36 @@ RC_allocate_and_post_buffers (struct net_device *dev, int numBuffers)
if (!numBuffers)
return 0;
else if (numBuffers > MAX_NMBR_POST_BUFFERS_PER_MSG) {
dprintk ("Too many buffers requested!\n");
dprintk ("attempting to allocate only 32 buffers\n");
printk (KERN_ERR "%s: Too many buffers requested!\n",
dev->name);
numBuffers = 32;
}
p = (PU32) kmalloc (sizeof (U32) + numBuffers * sizeof (singleB),
GFP_KERNEL);
dprintk ("TCB = 0x%x\n", (uint) p);
GFP_DMA|GFP_ATOMIC|GFP_KERNEL);
if (!p) {
printk (KERN_WARNING
"(rcpci45 driver:) RCopen: unable to allocate TCB\n");
printk (KERN_WARNING "%s unable to allocate TCB\n",
dev->name);
return 0;
}
p[0] = 0; /* Buffer Count */
pB = (psingleB) ((U32) p + sizeof (U32)); /* point to the first buffer */
dprintk ("p[0] = 0x%x, p = 0x%x, pB = 0x%x\n", (uint) p[0], (uint) p,
(uint) pB);
dprintk ("pB = 0x%x\n", (uint) pB);
pB = (psingleB) ((U32) p + sizeof (U32));/* point to the first buffer */
for (i = 0; i < numBuffers; i++) {
skb = dev_alloc_skb (MAX_ETHER_SIZE + 2);
if (!skb) {
dprintk
("Doh! RCopen: unable to allocate enough skbs!\n");
if (*p != 0) { /* did we allocate any buffers at all? */
dprintk ("will post only %d buffers \n",
(uint) (*p));
printk (KERN_WARNING
"%s: unable to allocate enough skbs!\n",
dev->name);
if (*p != 0) { /* did we allocate any buffers */
break;
} else {
kfree (p); /* Free the TCB */
return 0;
}
}
dprintk ("post 0x%x\n", (uint) skb);
skb_reserve (skb, 2); /* Align IP on 16 byte boundaries */
pB->context = (U32) skb;
pB->scount = 1; /* segment count */
......@@ -1182,18 +1034,16 @@ RC_allocate_and_post_buffers (struct net_device *dev, int numBuffers)
}
if ((status = RCPostRecvBuffers (dev, (PRCTCB) p)) != RC_RTN_NO_ERROR) {
printk (KERN_WARNING
"(rcpci45 driver:) Post buffer failed with error code 0x%x!\n",
status);
pB = (psingleB) ((U32) p + sizeof (U32)); /* point to the first buffer */
printk (KERN_WARNING "%s: Post buffer failed, error 0x%x\n",
dev->name, status);
/* point to the first buffer */
pB = (psingleB) ((U32) p + sizeof (U32));
while (p[0]) {
skb = (struct sk_buff *) pB->context;
dprintk ("freeing 0x%x\n", (uint) skb);
dev_kfree_skb (skb);
p[0]--;
pB++;
}
dprintk ("freed all buffers, p[0] = %d\n", (uint) p[0]);
}
res = p[0];
kfree (p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment