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