patch-2.2.6 linux/drivers/net/rcpci45.c
Next file: linux/drivers/net/syncppp.c
Previous file: linux/drivers/net/rclanmtl.h
Back to the patch index
Back to the overall index
- Lines: 541
- Date:
Mon Apr 12 16:18:27 1999
- Orig file:
v2.2.5/linux/drivers/net/rcpci45.c
- Orig date:
Tue Jan 19 11:32:51 1999
diff -u --recursive --new-file v2.2.5/linux/drivers/net/rcpci45.c linux/drivers/net/rcpci45.c
@@ -1,4 +1,5 @@
/*
+**
** RCpci45.c
**
**
@@ -36,16 +37,18 @@
**
**
** Pete Popov, January 11,99: Fixed a couple of 2.1.x problems
-** (virt_to_bus() not called), tested it under 2.2pre5, and added a
-** #define to enable the use of the same file for both, the 2.0.x kernels
-** as well as the 2.1.x.
+** (virt_to_bus() not called), tested it under 2.2pre5 (as a module), and
+** added a #define(s) to enable the use of the same file for both, the 2.0.x
+** kernels as well as the 2.1.x.
**
** Ported to 2.1.x by Alan Cox 1998/12/9.
**
+** Sometime in mid 1998, written by Pete Popov and Brian Moyle.
+**
***************************************************************************/
static char *version =
-"RedCreek Communications PCI linux driver version 2.00\n";
+"RedCreek Communications PCI linux driver version 2.02\n";
#include <linux/module.h>
@@ -155,11 +158,10 @@
};
-static int RCscan(void);
-static struct device
-*RCfound_device(struct device *, int, int, int, int, int, int);
+static int RCinit(struct device *dev);
+static int RCscan(struct device *dev);
+static int RCfound_device(struct device *, int, int, int, int, int, int);
-static int RCprobe1(struct device *);
static int RCopen(struct device *);
static int RC_xmit_packet(struct sk_buff *, struct device *);
static void RCinterrupt(int, void *, struct pt_regs *);
@@ -180,134 +182,143 @@
#ifdef MODULE
int init_module(void)
#else
-int rcpci_probe(struct netdevice *dev)
+int rcpci_probe(struct device *dev)
#endif
{
int cards_found;
- printk(version);
-
- root_RCdev = NULL;
- cards_found = RCscan();
#ifdef MODULE
- return cards_found ? 0 : -ENODEV;
+ cards_found = RCscan(NULL);
#else
- return -1;
+ cards_found = RCscan(dev);
#endif
+ if (cards_found)
+ printk(version);
+ return cards_found ? 0 : -ENODEV;
}
-static int RCscan()
+static int RCscan(struct device *dev)
{
int cards_found = 0;
- struct device *dev = 0;
+ static int pci_index = 0;
+
+ if (!pcibios_present())
+ return cards_found;
- if (pcibios_present())
+ for (;pci_index < 0x8; pci_index++)
{
- static int pci_index = 0;
unsigned char pci_bus, pci_device_fn;
int scan_status;
int board_index = 0;
+ unsigned char pci_irq_line;
+ unsigned short pci_command, vendor, device, class;
+ unsigned int pci_ioaddr;
- for (;pci_index < 0xff; pci_index++)
- {
- unsigned char pci_irq_line;
- unsigned short pci_command, vendor, device, class;
- unsigned int pci_ioaddr;
-
-
- scan_status =
- (pcibios_find_device (RC_PCI45_VENDOR_ID,
- RC_PCI45_DEVICE_ID,
- pci_index,
- &pci_bus,
- &pci_device_fn));
-#ifdef RCDEBUG
- printk("rc scan_status = 0x%X\n", scan_status);
-#endif
- if (scan_status != PCIBIOS_SUCCESSFUL)
- break;
- pcibios_read_config_word(pci_bus,
- pci_device_fn,
- PCI_VENDOR_ID, &vendor);
- pcibios_read_config_word(pci_bus,
- pci_device_fn,
- PCI_DEVICE_ID, &device);
- pcibios_read_config_byte(pci_bus,
- pci_device_fn,
- PCI_INTERRUPT_LINE, &pci_irq_line);
- pcibios_read_config_dword(pci_bus,
- pci_device_fn,
- PCI_BASE_ADDRESS_0, &pci_ioaddr);
- pcibios_read_config_word(pci_bus,
- pci_device_fn,
- PCI_CLASS_DEVICE, &class);
-
- pci_ioaddr &= ~0xf;
+ scan_status =
+ (pcibios_find_device (RC_PCI45_VENDOR_ID,
+ RC_PCI45_DEVICE_ID,
+ pci_index,
+ &pci_bus,
+ &pci_device_fn));
#ifdef RCDEBUG
- printk("rc: Found RedCreek PCI adapter\n");
- printk("rc: pci class = 0x%x 0x%x \n", class, class>>8);
- printk("rc: pci_bus = %d, pci_device_fn = %d\n", pci_bus, pci_device_fn);
- printk("rc: pci_irq_line = 0x%x \n", pci_irq_line);
- printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr);
+ printk("rc scan_status = 0x%X\n", scan_status);
+#endif
+ if (scan_status != PCIBIOS_SUCCESSFUL)
+ break;
+ pcibios_read_config_word(pci_bus,
+ pci_device_fn,
+ PCI_VENDOR_ID, &vendor);
+ pcibios_read_config_word(pci_bus,
+ pci_device_fn,
+ PCI_DEVICE_ID, &device);
+ pcibios_read_config_byte(pci_bus,
+ pci_device_fn,
+ PCI_INTERRUPT_LINE, &pci_irq_line);
+ pcibios_read_config_dword(pci_bus,
+ pci_device_fn,
+ PCI_BASE_ADDRESS_0, &pci_ioaddr);
+ pcibios_read_config_word(pci_bus,
+ pci_device_fn,
+ PCI_CLASS_DEVICE, &class);
+
+ pci_ioaddr &= ~0xf;
+
+#ifdef RCDEBUG
+ printk("rc: Found RedCreek PCI adapter\n");
+ printk("rc: pci class = 0x%x 0x%x \n", class, class>>8);
+ printk("rc: pci_bus = %d, pci_device_fn = %d\n", pci_bus, pci_device_fn);
+ printk("rc: pci_irq_line = 0x%x \n", pci_irq_line);
+ printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr);
#endif
-#if 1
- if (check_region(pci_ioaddr, 2*32768))
- {
- printk("rc: check_region failed\n");
- continue;
- }
- else
- {
- printk("rc: check_region passed\n");
- }
+ if (check_region(pci_ioaddr, 2*32768))
+ {
+ printk("rc: check_region failed\n");
+ continue;
+ }
+#ifdef RCDEBUG
+ else
+ {
+ printk("rc: check_region passed\n");
+ }
#endif
-
+
+ /*
+ * Get and check the bus-master and latency values.
+ * Some PCI BIOSes fail to set the master-enable bit.
+ */
+
+ pcibios_read_config_word(pci_bus,
+ pci_device_fn,
+ PCI_COMMAND,
+ &pci_command);
+ if ( ! (pci_command & PCI_COMMAND_MASTER)) {
+ printk("rc: PCI Master Bit has not been set!\n");
+
+ pci_command |= PCI_COMMAND_MASTER;
+ pcibios_write_config_word(pci_bus,
+ pci_device_fn,
+ PCI_COMMAND,
+ pci_command);
+ }
+ if ( ! (pci_command & PCI_COMMAND_MEMORY)) {
/*
- * Get and check the bus-master and latency values.
- * Some PCI BIOSes fail to set the master-enable bit.
+ * If the BIOS did not set the memory enable bit, what else
+ * did it not initialize? Skip this adapter.
*/
-
- pcibios_read_config_word(pci_bus,
- pci_device_fn,
- PCI_COMMAND,
- &pci_command);
- if ( ! (pci_command & PCI_COMMAND_MASTER)) {
- printk("rc: PCI Master Bit has not been set!\n");
-
- pci_command |= PCI_COMMAND_MASTER;
- pcibios_write_config_word(pci_bus,
- pci_device_fn,
- PCI_COMMAND,
- pci_command);
- }
- if ( ! (pci_command & PCI_COMMAND_MEMORY)) {
- /*
- * If the BIOS did not set the memory enable bit, what else
- * did it not initialize? Skip this adapter.
- */
- printk("rc: Adapter %d, PCI Memory Bit has not been set!\n",
- cards_found);
- printk("rc: Bios problem? \n");
- continue;
- }
-
- dev = RCfound_device(dev, pci_ioaddr, pci_irq_line,
- pci_bus, pci_device_fn,
- board_index++, cards_found);
-
- if (dev) {
- dev = 0;
- cards_found++;
- }
+ printk("rc: Adapter %d, PCI Memory Bit has not been set!\n",
+ cards_found);
+ printk("rc: Bios problem? \n");
+ continue;
+ }
+
+ if (!RCfound_device(dev, pci_ioaddr, pci_irq_line,
+ pci_bus, pci_device_fn,
+ board_index++, cards_found))
+ {
+ dev = 0;
+ cards_found++;
}
}
+#ifdef RCDEBUG
printk("rc: found %d cards \n", cards_found);
+#endif
return cards_found;
}
-static struct device *
+static int RCinit(struct 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
RCfound_device(struct device *dev, int memaddr, int irq,
int bus, int function, int product_index, int card_idx)
{
@@ -324,18 +335,37 @@
* assigned to DPA; and finally, the rest will be assigned to the
* the LAN API layer.
*/
+
+#ifdef MODULE
dev = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC);
+ if (!dev)
+ {
+ printk("rc: unable to kmalloc dev\n");
+ return 1;
+ }
memset(dev, 0, dev_size);
-#ifdef RCDEBUG
- printk("rc: dev = 0x%08X\n", (uint)dev);
-#endif
-
/*
* dev->priv will point to the start of DPA.
*/
dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15);
+#else
+ dev->priv = 0;
+ dev->priv = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC);
+ if (!dev->priv)
+ {
+ printk("rc: unable to kmalloc private area\n");
+ return 1;
+ }
+ memset(dev->priv, 0, dev_size);
+#endif
+
+#ifdef RCDEBUG
+ printk("rc: dev = 0x%x, dev->priv = 0x%x\n", (uint)dev, (uint)dev->priv);
+#endif
+
pDpa = dev->priv;
- dev->name = pDpa->devname;
+ if (!dev->name)
+ dev->name = pDpa->devname;
pDpa->dev = dev; /* this is just for easy reference */
pDpa->function = function;
@@ -378,24 +408,21 @@
printk( "RC PCI 45: %s: unable to get IRQ %d\n", (PU8)dev->name, (uint)dev->irq );
iounmap(vaddr);
kfree(dev);
- return 0;
+ return 1;
}
init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr,
- pDpa->PLanApiPA, (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
- (PFNTXCALLBACK)RCxmit_callback,
- (PFNRXCALLBACK)RCrecv_callback,
- (PFNCALLBACK)RCreboot_callback);
-#ifdef RCDEBUG
- printk("rc: I2O msg initted: status = 0x%x\n", init_status);
-#endif
+ pDpa->PLanApiPA, (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
+ (PFNTXCALLBACK)RCxmit_callback,
+ (PFNRXCALLBACK)RCrecv_callback,
+ (PFNCALLBACK)RCreboot_callback);
if (init_status)
{
printk("rc: Unable to initialize msg layer\n");
free_irq(dev->irq, dev);
iounmap(vaddr);
kfree(dev);
- return 0;
+ return 1;
}
if (RCGetMAC(pDpa->id, dev->dev_addr, NULL))
{
@@ -403,38 +430,34 @@
free_irq(dev->irq, dev);
iounmap(vaddr);
kfree(dev);
- return 0;
+ return 1;
}
DriverControlWord |= WARM_REBOOT_CAPABLE;
RCReportDriverCapability(pDpa->id, DriverControlWord);
- dev->init = RCprobe1;
+ dev->init = &RCinit;
ether_setup(dev); /* linux kernel interface */
pDpa->next = root_RCdev;
root_RCdev = dev;
+#ifdef MODULE
if (register_netdev(dev) != 0) /* linux kernel interface */
{
printk("rc: unable to register device \n");
free_irq(dev->irq, dev);
iounmap(vaddr);
kfree(dev);
- return 0;
+ return 1;
}
- return dev;
-}
+#else
+ RCinit(dev);
+#endif
+ printk("%s: RedCreek Communications IPSEC VPN adapter\n",
+ dev->name);
-static int RCprobe1(struct 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;
+ return 0; /* success */
}
static int
@@ -516,6 +539,7 @@
#ifdef RCDEBUG
printk("rc: RC_xmit_packet: tbusy!\n");
#endif
+ dev->tbusy = 1;
return 1;
}
@@ -658,7 +682,7 @@
RCShutdownLANCard(pDpa->id,0,0,0);
printk("rc: scheduling timer...\n");
init_timer(&pDpa->timer);
- pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */
+ pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 4 sec. */
pDpa->timer.data = (unsigned long)dev;
pDpa->timer.function = &rc_timer; /* timer handler */
add_timer(&pDpa->timer);
@@ -757,9 +781,11 @@
if (!pDpa->shutdown && !pDpa->reboot)
printk("rc: RCrecv error: status = 0x%x\n", (uint)Status);
+#ifdef RCDEBUG
else
printk("rc: Returning %d buffers, status = 0x%x\n",
PktCount, (uint)Status);
+#endif
/*
* 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
@@ -808,6 +834,8 @@
(uint)skb->data[0], (uint)skb->data[1], (uint)skb->data[2],
(uint)skb->data[3], (uint)skb->data[4], (uint)skb->data[5]);
#endif
+
+#ifdef PROMISCUOUS_BY_DEFAULT /* early 2.x firmware */
if ( (memcmp(dev->dev_addr, skb->data, 6)) &&
(!broadcast_packet(skb->data)))
{
@@ -838,6 +866,7 @@
}
}
else
+#endif /* PROMISCUOUS_BY_DEFAULT */
{
len = PacketDescBlock[2];
skb->dev = dev;
@@ -883,10 +912,10 @@
pDpa = (PDPA) (dev->priv);
+#ifdef RCDEBUG
if (pDpa->shutdown)
printk("rc: shutdown: service irq\n");
-#ifdef RCDEBUG
printk("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n",
(uint)pDpa, (uint)dev, (uint)pDpa->id);
printk("dev = 0x%x\n", (uint)dev);
@@ -901,7 +930,8 @@
return;
}
-#define REBOOT_REINIT_RETRY_LIMIT 10
+
+#define REBOOT_REINIT_RETRY_LIMIT 4
static void rc_timer(unsigned long data)
{
struct device *dev = (struct device *)data;
@@ -914,12 +944,12 @@
if (pDpa->reboot)
{
-
init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr,
- pDpa->PLanApiPA, pDpa->PLanApiPA,
- (PFNTXCALLBACK)RCxmit_callback,
- (PFNRXCALLBACK)RCrecv_callback,
- (PFNCALLBACK)RCreboot_callback);
+ pDpa->PLanApiPA,
+ (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
+ (PFNTXCALLBACK)RCxmit_callback,
+ (PFNRXCALLBACK)RCrecv_callback,
+ (PFNCALLBACK)RCreboot_callback);
switch(init_status)
{
@@ -949,14 +979,16 @@
(uint)pDpa->numOutRcvBuffers);
}
printk("rc: Initialization done.\n");
+ dev->tbusy=0;
+ retry=0;
return;
case RC_RTN_FREE_Q_EMPTY:
retry++;
- printk("rc: inbound free q emtpy\n");
+ printk("rc: inbound free q empty\n");
break;
default:
retry++;
- printk("rc: unexpected bad status after reboot\n");
+ printk("rc: bad status after reboot: %d\n", init_status);
break;
}
@@ -972,7 +1004,7 @@
{
printk("rc: rescheduling timer...\n");
init_timer(&pDpa->timer);
- pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */
+ pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 3 sec. */
pDpa->timer.data = (unsigned long)dev;
pDpa->timer.function = &rc_timer; /* timer handler */
add_timer(&pDpa->timer);
@@ -1286,6 +1318,8 @@
return 0;
}
+
+#ifdef MODULE
void
cleanup_module(void)
{
@@ -1315,6 +1349,8 @@
root_RCdev = next;
}
}
+#endif
+
static int
RC_allocate_and_post_buffers(struct device *dev, int numBuffers)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)