patch-2.3.41 linux/drivers/net/tokenring/tms380tr.c
Next file: linux/drivers/net/tokenring/tms380tr.h
Previous file: linux/drivers/net/tokenring/smctr.h
Back to the patch index
Back to the overall index
- Lines: 1464
- Date:
Wed Jan 26 13:16:05 2000
- Orig file:
v2.3.40/linux/drivers/net/tokenring/tms380tr.c
- Orig date:
Fri Jan 21 18:19:16 2000
diff -u --recursive --new-file v2.3.40/linux/drivers/net/tokenring/tms380tr.c linux/drivers/net/tokenring/tms380tr.c
@@ -1,5 +1,5 @@
/*
- * tms380tr.c: A network driver for Texas Instruments TMS380-based
+ * tms380tr.c: A network driver library for Texas Instruments TMS380-based
* Token Ring Adapters.
*
* Originally sktr.c: Written 1997 by Christoph Goos
@@ -10,14 +10,16 @@
* This software may be used and distributed according to the terms
* of the GNU Public License, incorporated herein by reference.
*
- * This device driver works with the following TMS380 adapters:
+ * The following modules are currently available for card support:
+ * - tmspci (Generic PCI card support)
+ * - abyss (Madge PCI support)
+ *
+ * The following cards are currently lacking support, even
+ * though they were supported in previous versions, because
+ * their code did not get migrated into a seperate module:
* - SysKonnect TR4/16(+) ISA (SK-4190)
- * - SysKonnect TR4/16(+) PCI (SK-4590)
- * - SysKonnect TR4/16 PCI (SK-4591)
- * - Compaq TR 4/16 PCI
- * - Thomas-Conrad TC4048 4/16 PCI
- * - 3Com 3C339 Token Link Velocity
- * - Any ISA or PCI adapter using only the TMS380 chipset
+ * They are no longer supported by this driver, at least until
+ * a module gets written for them.
*
* Sources:
* - The hardware related parts of this driver are take from
@@ -27,14 +29,16 @@
* - Also various other drivers in the linux source tree were taken
* as samples for some tasks.
* - TI TMS380 Second-Generation Token Ring User's Guide
- * - TI datasheets for respective chips
- * - David Hein at Texas Instruments
+ * - TI datasheets for respective chips
+ * - David Hein at Texas Instruments
+ * - Various Madge employees
*
* Maintainer(s):
* JS Jay Schulist jschlst@turbolinux.com
* CG Christoph Goos cgoos@syskonnect.de
* AF Adam Fritzler mid@auk.cx
- *
+ * MLP Mike Phillips phillim@amtrak.com
+ *
* Modification History:
* 29-Aug-97 CG Created
* 04-Apr-98 CG Fixed problems caused by tok_timer_check
@@ -42,22 +46,33 @@
* 27-May-98 JS Formated to Linux Kernel Format
* 31-May-98 JS Hacked in PCI support
* 16-Jun-98 JS Modulized for multiple cards with one driver
- * Sep-99 AF Renamed to tms380tr (supports more than SK's)
+ * Sep-99 AF Renamed to tms380tr (supports more than SK's)
* 23-Sep-99 AF Added Compaq and Thomas-Conrad PCI support
* Fixed a bug causing double copies on PCI
* Fixed for new multicast stuff (2.2/2.3)
* 25-Sep-99 AF Uped TPL_NUM from 3 to 9
* Removed extraneous 'No free TPL'
+ * 22-Dec-99 AF Added Madge PCI Mk2 support and generalized
+ * parts of the initilization procedure.
+ * 30-Dec-99 AF Turned tms380tr into a library ala 8390.
+ * Madge support is provided in the abyss module
+ * Generic PCI support is in the tmspci module.
*
* To do:
- * 1. Selectable 16 Mbps or 4Mbps
- * 2. Multi/Broadcast packet handling (this may have fixed itself)
- *
+ * 1. Multi/Broadcast packet handling (this may have fixed itself)
+ * 2. Write a sktrisa module that includes the old ISA support
+ * 3. Allow modules to load their own microcode
+ * 4. Speed up the BUD process -- freezing the kernel for 3+sec is
+ * quite unacceptable.
+ * 5. Still a few remaining stalls when the cable is unplugged.
*/
-static const char *version = "tms380tr.c: v1.03 29/09/1999 by Christoph Goos, Adam Fritzler\n";
+#ifdef MODULE
+static const char *version = "tms380tr.c: v1.07 21/01/2000 by Christoph Goos, Adam Fritzler\n";
+#endif
#ifdef MODULE
+#define EXPORT_SYMTAB
#include <linux/module.h>
#include <linux/version.h>
#endif
@@ -78,6 +93,7 @@
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/irq.h>
+#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/pci.h>
@@ -90,45 +106,6 @@
#include "tms380tr.h" /* Our Stuff */
#include "tms380tr_microcode.h" /* TI microcode for COMMprocessor */
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int tms380tr_portlist[] __initdata = {
- 0x0A20, 0x1A20, 0x0B20, 0x1B20, 0x0980, 0x1980, 0x0900, 0x1900,
- 0
-};
-
-/* A zero-terminated list of IRQs to be probed.
- * Used again after initial probe for tms380tr_chipset_init, called from tms380tr_open.
- */
-static unsigned short tms380tr_irqlist[] = {
- 3, 5, 9, 10, 11, 12, 15,
- 0
-};
-
-/* A zero-terminated list of DMAs to be probed. */
-static int tms380tr_dmalist[] __initdata = {
- 5, 6, 7,
- 0
-};
-
-/*
- * Table used for card detection and type determination.
- */
-struct cardinfo_table cardinfo[] = {
- { 0, 0, 0,
- "Unknown TMS380 Token Ring Adapter"},
- { TMS_ISA, 0, 0,
- "SK NET TR 4/16 ISA"},
- { TMS_PCI, PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING,
- "Compaq 4/16 TR PCI"},
- { TMS_PCI, PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR,
- "SK NET TR 4/16 PCI"},
- { TMS_PCI, PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING,
- "Thomas-Conrad TC4048 PCI 4/16"},
- { TMS_PCI, PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339,
- "3Com Token Link Velocity"},
- { 0, 0, 0, NULL}
-};
-
/* Use 0 for production, 1 for verification, 2 for debug, and
* 3 for very verbose debug.
*/
@@ -137,24 +114,24 @@
#endif
static unsigned int tms380tr_debug = TMS380TR_DEBUG;
-/* The number of low I/O ports used by the tokencard. */
-#define TMS380TR_IO_EXTENT 32
-
/* Index to functions, as function prototypes.
* Alphabetical by function name.
*/
+/* "A" */
/* "B" */
static int tms380tr_bringup_diags(struct net_device *dev);
/* "C" */
static void tms380tr_cancel_tx_queue(struct net_local* tp);
static int tms380tr_chipset_init(struct net_device *dev);
static void tms380tr_chk_irq(struct net_device *dev);
+#if 0
static unsigned char tms380tr_chk_frame(struct net_device *dev, unsigned char *Addr);
+#endif
static void tms380tr_chk_outstanding_cmds(struct net_device *dev);
static void tms380tr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr);
static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqType);
-static int tms380tr_close(struct net_device *dev);
+int tms380tr_close(struct net_device *dev);
static void tms380tr_cmd_status_irq(struct net_device *dev);
/* "D" */
static void tms380tr_disable_interrupts(struct net_device *dev);
@@ -176,20 +153,15 @@
static int tms380tr_init_card(struct net_device *dev);
static void tms380tr_init_ipb(struct net_local *tp);
static void tms380tr_init_net_local(struct net_device *dev);
-static void tms380tr_init_opb(struct net_local *tp);
-static void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static int tms380tr_isa_chk_card(struct net_device *dev, int ioaddr, struct cardinfo_table **outcard);
-static int tms380tr_isa_chk_ioaddr(int ioaddr);
+static void tms380tr_init_opb(struct net_device *dev);
+void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+/* "M" */
/* "O" */
-static int tms380tr_open(struct net_device *dev);
+int tms380tr_open(struct net_device *dev);
static void tms380tr_open_adapter(struct net_device *dev);
/* "P" */
-static int tms380tr_pci_chk_card(struct net_device *dev, struct cardinfo_table **outcard);
-int tms380tr_probe(struct net_device *dev);
-static int tms380tr_probe1(struct net_device *dev, int ioaddr);
/* "R" */
static void tms380tr_rcv_status_irq(struct net_device *dev);
-static void tms380tr_read_addr(struct net_device *dev, unsigned char *Address);
static int tms380tr_read_ptr(struct net_device *dev);
static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data,
unsigned short Address, int Length);
@@ -199,6 +171,7 @@
/* "S" */
static int tms380tr_send_packet(struct sk_buff *skb, struct net_device *dev);
static void tms380tr_set_multicast_list(struct net_device *dev);
+static int tms380tr_set_mac_address(struct net_device *dev, void *addr);
/* "T" */
static void tms380tr_timer_chk(unsigned long data);
static void tms380tr_timer_end_wait(unsigned long data);
@@ -207,269 +180,61 @@
static void tms380tr_update_rcv_stats(struct net_local *tp,
unsigned char DataPtr[], unsigned int Length);
/* "W" */
-static void tms380tr_wait(unsigned long time);
+void tms380tr_wait(unsigned long time);
static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status);
static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status);
-/*
- * Check for a network adapter of this type, and return '0' if one exists.
- * If dev->base_addr == 0, probe all likely locations.
- * If dev->base_addr == 1, always return failure.
- */
-int __init tms380tr_probe(struct net_device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- if(base_addr > 0x1ff) /* Check a single specified location. */
- return (tms380tr_probe1(dev, base_addr));
- else if(base_addr != 0) /* Don't probe at all. */
- return (-ENXIO);
-
- /*
- * Let's check for pci adapters first
- */
- if (tms380tr_probe1(dev,0) == 0) /* Success */
- return 0 ;
-
- /*
- * No pci cards found, let's check for isa
- */
+#define SIFREADB(reg) (((struct net_local *)dev->priv)->sifreadb(dev, reg))
+#define SIFWRITEB(val, reg) (((struct net_local *)dev->priv)->sifwriteb(dev, val, reg))
+#define SIFREADW(reg) (((struct net_local *)dev->priv)->sifreadw(dev, reg))
+#define SIFWRITEW(val, reg) (((struct net_local *)dev->priv)->sifwritew(dev, val, reg))
- for(i = 0; tms380tr_portlist[i]; i++)
- {
- int ioaddr = tms380tr_portlist[i];
- if(check_region(ioaddr, TMS380TR_IO_EXTENT)) /* Region already used */
- continue;
- if(!tms380tr_probe1(dev, ioaddr))
- return (0);
- }
- return (-ENODEV);
-}
-struct cardinfo_table * __init tms380tr_pci_getcardinfo(unsigned short vendor,
- unsigned short device)
+#if TMS380TR_DEBUG > 0
+static int madgemc_sifprobe(struct net_device *dev)
{
- int cur;
- for (cur = 1; cardinfo[cur].name != NULL; cur++) {
- if (cardinfo[cur].type == 2) /* PCI */
- {
- if ((cardinfo[cur].vendor_id == vendor) && (cardinfo[cur].device_id == device))
- return &cardinfo[cur];
- }
- }
+ unsigned char old, chk1, chk2;
- return NULL;
-}
+ old = SIFREADB(SIFADR); /* Get the old SIFADR value */
-/*
- * Detect and setup the PCI SysKonnect TR cards in slot order.
- */
-static int __init tms380tr_pci_chk_card(struct net_device *dev,
- struct cardinfo_table **outcard)
-{
- struct pci_dev *pci_device = NULL ;
- struct cardinfo_table *card;
- int i;
-
- if(!pci_present())
- return (-1); /* No PCI present. */
-
- while ( (pci_device=pci_find_class(PCI_CLASS_NETWORK_TOKEN_RING<<8, pci_device))) {
-
- unsigned int pci_irq_line;
- unsigned int pci_ioaddr;
-
- /* Remove I/O space marker in bit 0. */
- pci_irq_line = pci_device->irq ;
- pci_ioaddr = pci_device->resource[0].start ;
-/* pci_ioaddr &= ~3; */
-
- /* Don't return from here, just continue on the card discovery loop - MLP */
- if (!(card = tms380tr_pci_getcardinfo(pci_device->vendor, pci_device->device)))
- continue ;
-
- if(check_region(pci_ioaddr, TMS380TR_IO_EXTENT))
- continue;
-
- request_region(pci_ioaddr, TMS380TR_IO_EXTENT, card->name);
- if(request_irq(pci_device->irq, tms380tr_interrupt, SA_SHIRQ,
- card->name, dev)) {
- release_region(pci_ioaddr, TMS380TR_IO_EXTENT) ;
- return (-ENODEV); /* continue; ?? */
- }
- /* At this point we have found a valid tms380tr PCI TR card. */
-
- pci_ioaddr &= ~3 ;
- dev->base_addr = pci_ioaddr;
- dev->irq = pci_irq_line;
- dev->dma = 0;
-
- dev->addr_len = 6;
- tms380tr_read_addr(dev, (unsigned char*)dev->dev_addr);
+ chk1 = 0; /* Begin with check value 0 */
+ do {
+ madgemc_setregpage(dev, 0);
+ /* Write new SIFADR value */
+ SIFWRITEB(chk1, SIFADR);
+ chk2 = SIFREADB(SIFADR);
+ if (chk2 != chk1)
+ return -1;
- printk("%s: %s found at %#4x, IRQ %d, ring station ",
- dev->name, card->name, pci_ioaddr, dev->irq);
- printk("%2.2x", dev->dev_addr[0]);
- for (i = 1; i < 6; i++)
- printk(":%2.2x", dev->dev_addr[i]);
- printk(".\n");
-
- if (outcard)
- *outcard = card;
+ madgemc_setregpage(dev, 1);
+ /* Read, invert and write */
+ chk2 = SIFREADB(SIFADD);
+ if (chk2 != chk1)
+ return -1;
+
+ madgemc_setregpage(dev, 0);
+ chk2 ^= 0x0FE;
+ SIFWRITEB(chk2, SIFADR);
+
+ /* Read, invert and compare */
+ madgemc_setregpage(dev, 1);
+ chk2 = SIFREADB(SIFADD);
+ madgemc_setregpage(dev, 0);
+ chk2 ^= 0x0FE;
+
+ if(chk1 != chk2)
+ return (-1); /* No adapter */
+ chk1 -= 2;
+ } while(chk1 != 0); /* Repeat 128 times (all byte values) */
+
+ madgemc_setregpage(dev, 0); /* sanity */
+ /* Restore the SIFADR value */
+ SIFWRITEB(old, SIFADR);
- return 0 ;
- }
-
- return (-1);
+ return (0);
}
-
-/*
- * Detect and setup the ISA SysKonnect TR cards.
- */
-static int __init tms380tr_isa_chk_card(struct net_device *dev, int ioaddr,
- struct cardinfo_table **outcard)
-{
- int i, err;
- unsigned long flags;
- struct cardinfo_table *card = NULL;
-
- err = tms380tr_isa_chk_ioaddr(ioaddr);
- if(err < 0)
- return (-ENODEV);
-
- if(virt_to_bus((void*)((unsigned long)dev->priv+sizeof(struct net_local)))
- > ISA_MAX_ADDRESS)
- {
- printk("%s: Memory not accessible for DMA\n", dev->name);
- kfree(dev->priv);
- return (-EAGAIN);
- }
-
- /* FIXME */
- card = &cardinfo[1];
-
- /* Grab the region so that no one else tries to probe our ioports. */
- request_region(ioaddr, TMS380TR_IO_EXTENT, card->name);
- dev->base_addr = ioaddr;
-
- /* Autoselect IRQ and DMA if dev->irq == 0 */
- if(dev->irq == 0)
- {
- for(i = 0; tms380tr_irqlist[i] != 0; i++)
- {
- dev->irq = tms380tr_irqlist[i];
- err = request_irq(dev->irq, &tms380tr_interrupt, 0, card->name, dev);
- if(!err)
- break;
- }
-
- if(tms380tr_irqlist[i] == 0)
- {
- printk("%s: AutoSelect no IRQ available\n", dev->name);
- return (-EAGAIN);
- }
- }
- else
- {
- err = request_irq(dev->irq, &tms380tr_interrupt, 0, card->name, dev);
- if(err)
- {
- printk("%s: Selected IRQ not available\n", dev->name);
- return (-EAGAIN);
- }
- }
-
- /* Always allocate the DMA channel after IRQ and clean up on failure */
- if(dev->dma == 0)
- {
- for(i = 0; tms380tr_dmalist[i] != 0; i++)
- {
- dev->dma = tms380tr_dmalist[i];
- err = request_dma(dev->dma, card->name);
- if(!err)
- break;
- }
-
- if(dev->dma == 0)
- {
- printk("%s: AutoSelect no DMA available\n", dev->name);
- free_irq(dev->irq, NULL);
- return (-EAGAIN);
- }
- }
- else
- {
- err = request_dma(dev->dma, card->name);
- if(err)
- {
- printk("%s: Selected DMA not available\n", dev->name);
- free_irq(dev->irq, NULL);
- return (-EAGAIN);
- }
- }
-
- flags=claim_dma_lock();
- disable_dma(dev->dma);
- set_dma_mode(dev->dma, DMA_MODE_CASCADE);
- enable_dma(dev->dma);
- release_dma_lock(flags);
-
- printk("%s: %s found at %#4x, using IRQ %d and DMA %d.\n",
- dev->name, card->name, ioaddr, dev->irq, dev->dma);
-
- if (outcard)
- *outcard = card;
-
- return (0);
-}
-
-/*
- * Passing an ioaddr of 0 tells us to do a pci card search
- */
-
-static int __init tms380tr_probe1(struct net_device *dev, int ioaddr)
-{
- static unsigned version_printed = 0;
- struct net_local *tp;
- int err;
- struct cardinfo_table *card = NULL;
-
- if(tms380tr_debug && version_printed++ == 0)
- printk(KERN_INFO "%s", version);
-
-#ifndef MODULE
- dev = init_trdev(dev, 0);
- if(dev == NULL)
- return (-ENOMEM);
#endif
- if (ioaddr == 0) {
- err = tms380tr_pci_chk_card(dev, &card);
- } else {
- err = tms380tr_isa_chk_card(dev, ioaddr, &card);
- }
- if(err < 0)
- return (-ENODEV);
-
- /* Setup this devices private information structure */
- tp = (struct net_local *)kmalloc(sizeof(struct net_local), GFP_KERNEL | GFP_DMA);
- if(tp == NULL)
- return (-ENOMEM);
- memset(tp, 0, sizeof(struct net_local));
- init_waitqueue_head(&tp->wait_for_tok_int);
- tp->CardType = card;
-
- dev->priv = tp;
- dev->init = tms380tr_init_card;
- dev->open = tms380tr_open;
- dev->stop = tms380tr_close;
- dev->do_ioctl = NULL ;
- dev->hard_start_xmit = tms380tr_send_packet;
- dev->get_stats = tms380tr_get_stats;
- dev->set_multicast_list = &tms380tr_set_multicast_list;
- return (0);
-}
/* Dummy function */
static int __init tms380tr_init_card(struct net_device *dev)
@@ -481,42 +246,6 @@
}
/*
- * This function tests if an adapter is really installed at the
- * given I/O address. Return negative if no adapter at IO addr.
- */
-static int __init tms380tr_isa_chk_ioaddr(int ioaddr)
-{
- unsigned char old, chk1, chk2;
-
- old = inb(ioaddr + SIFADR); /* Get the old SIFADR value */
-
- chk1 = 0; /* Begin with check value 0 */
- do {
- /* Write new SIFADR value */
- outb(chk1, ioaddr + SIFADR);
-
- /* Read, invert and write */
- chk2 = inb(ioaddr + SIFADD);
- chk2 ^= 0x0FE;
- outb(chk2, ioaddr + SIFADR);
-
- /* Read, invert and compare */
- chk2 = inb(ioaddr + SIFADD);
- chk2 ^= 0x0FE;
-
- if(chk1 != chk2)
- return (-1); /* No adapter */
-
- chk1 -= 2;
- } while(chk1 != 0); /* Repeat 128 times (all byte values) */
-
- /* Restore the SIFADR value */
- outb(old, ioaddr + SIFADR);
-
- return (0);
-}
-
-/*
* Open/initialize the board. This is called sometime after
* booting when the 'ifconfig' program is run.
*
@@ -524,14 +253,14 @@
* registers that "should" only need to be set once at boot, so that
* there is non-reboot way to recover if something goes wrong.
*/
-static int tms380tr_open(struct net_device *dev)
+int tms380tr_open(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
int err;
/* Reset the hardware here. Don't forget to set the station address. */
err = tms380tr_chipset_init(dev);
- if(err)
+ if(err)
{
printk(KERN_INFO "%s: Chipset initialization error\n",
dev->name);
@@ -548,7 +277,6 @@
printk(KERN_INFO "%s: Adapter RAM size: %dK\n",
dev->name, tms380tr_read_ptr(dev));
-
tms380tr_enable_interrupts(dev);
tms380tr_open_adapter(dev);
@@ -566,8 +294,8 @@
/* If AdapterVirtOpenFlag is 1, the adapter is now open for use */
if(tp->AdapterVirtOpenFlag == 0)
{
- tms380tr_disable_interrupts(dev);
- return (-1);
+ tms380tr_disable_interrupts(dev);
+ return (-1);
}
dev->start = 1;
@@ -579,10 +307,6 @@
tp->timer.function = tms380tr_timer_chk;
tp->timer.data = (unsigned long)dev;
add_timer(&tp->timer);
-
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
return (0);
}
@@ -610,47 +334,20 @@
static int tms380tr_chipset_init(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
- unsigned char PosReg, Tmp;
- int i, err;
+ int err;
tms380tr_init_ipb(tp);
- tms380tr_init_opb(tp);
+ tms380tr_init_opb(dev);
tms380tr_init_net_local(dev);
- /* Set pos register: selects irq and dma channel.
- * Only for ISA bus adapters.
- */
- if(dev->dma > 0)
- {
- PosReg = 0;
- for(i = 0; tms380tr_irqlist[i] != 0; i++)
- {
- if(tms380tr_irqlist[i] == dev->irq)
- break;
- }
-
- /* Choose default cycle time, 500 nsec */
- PosReg |= CYCLE_TIME << 2;
- PosReg |= i << 4;
- i = dev->dma - 5;
- PosReg |= i;
-
- if(tp->DataRate == SPEED_4)
- PosReg |= LINE_SPEED_BIT;
- else
- PosReg &= ~LINE_SPEED_BIT;
-
- outb(PosReg, dev->base_addr + POSREG);
- Tmp = inb(dev->base_addr + POSREG);
- if((Tmp & ~CYCLE_TIME) != (PosReg & ~CYCLE_TIME))
- printk(KERN_INFO "%s: POSREG error\n", dev->name);
- }
err = tms380tr_reset_adapter(dev);
if(err < 0)
return (-1);
+
err = tms380tr_bringup_diags(dev);
if(err < 0)
return (-1);
+
err = tms380tr_init_adapter(dev);
if(err < 0)
return (-1);
@@ -690,7 +387,7 @@
skb_queue_head_init(&tp->SendSkbQueue);
tp->QueueSkb = MAX_TX_QUEUE;
-
+
/* Create circular chain of transmit lists */
for (i = 0; i < TPL_NUM; i++)
{
@@ -713,7 +410,7 @@
tp->Rpl[i].NextRPLAddr = htonl((unsigned long) virt_to_bus(&tp->Rpl[(i+1) % RPL_NUM]));
tp->Rpl[i].Status = (RX_VALID | RX_START_FRAME | RX_END_FRAME | RX_FRAME_IRQ);
tp->Rpl[i].FrameSize = 0;
- tp->Rpl[i].FragList[0].DataCount = SWAPB(tp->MaxPacketSize);
+ tp->Rpl[i].FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize);
/* Alloc skb and point adapter to data area */
tp->Rpl[i].Skb = dev_alloc_skb(tp->MaxPacketSize);
@@ -731,7 +428,7 @@
skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize);
/* data unreachable for DMA ? then use local buffer */
- if(tp->CardType->type == TMS_ISA && virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > ISA_MAX_ADDRESS)
+ if(tp->dmalimit && virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > tp->dmalimit)
{
tp->Rpl[i].SkbStat = SKB_DATA_COPY;
tp->Rpl[i].FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[i]));
@@ -780,28 +477,37 @@
/*
* Initializes the open parameter block.
*/
-static void tms380tr_init_opb(struct net_local *tp)
+static void tms380tr_init_opb(struct net_device *dev)
{
+ struct net_local *tp;
unsigned long Addr;
unsigned short RplSize = RPL_SIZE;
unsigned short TplSize = TPL_SIZE;
unsigned short BufferSize = BUFFER_SIZE;
+ int i;
+
+ tp = (struct net_local *)dev->priv;
tp->ocpl.OPENOptions = 0;
tp->ocpl.OPENOptions |= ENABLE_FULL_DUPLEX_SELECTION;
tp->ocpl.FullDuplex = 0;
tp->ocpl.FullDuplex |= OPEN_FULL_DUPLEX_OFF;
- /* Fixme: If mac address setable:
- * for (i=0; i<LENGTH_OF_ADDRESS; i++)
- * mac->Vam->ocpl.NodeAddr[i] = mac->CurrentAddress[i];
+ /*
+ * Set node address
+ *
+ * We go ahead and put it in the OPB even though on
+ * most of the generic adapters this isn't required.
+ * Its simpler this way. -- ASF
*/
+ for (i=0;i<6;i++)
+ tp->ocpl.NodeAddr[i] = ((unsigned char *)dev->dev_addr)[i];
tp->ocpl.GroupAddr = 0;
tp->ocpl.FunctAddr = 0;
- tp->ocpl.RxListSize = SWAPB(RplSize);
- tp->ocpl.TxListSize = SWAPB(TplSize);
- tp->ocpl.BufSize = SWAPB(BufferSize);
+ tp->ocpl.RxListSize = cpu_to_be16((unsigned short)RplSize);
+ tp->ocpl.TxListSize = cpu_to_be16((unsigned short)TplSize);
+ tp->ocpl.BufSize = cpu_to_be16((unsigned short)BufferSize);
tp->ocpl.Reserved = 0;
tp->ocpl.TXBufMin = TX_BUF_MIN;
tp->ocpl.TXBufMax = TX_BUF_MAX;
@@ -836,7 +542,7 @@
*/
static void tms380tr_disable_interrupts(struct net_device *dev)
{
- outb(0, dev->base_addr + SIFACL);
+ SIFWRITEB(0, SIFACL);
return;
}
@@ -847,7 +553,7 @@
*/
static void tms380tr_enable_interrupts(struct net_device *dev)
{
- outb(ACL_SINTEN, dev->base_addr + SIFACL);
+ SIFWRITEB(ACL_SINTEN, SIFACL);
return;
}
@@ -948,8 +654,7 @@
tp->QueueSkb++;
/* Is buffer reachable for Busmaster-DMA? */
- if(tp->CardType->type == TMS_ISA && virt_to_bus((void*)(((long) skb->data) + skb->len))
- > ISA_MAX_ADDRESS)
+ if(tp->dmalimit && virt_to_bus((void*)(((long) skb->data) + skb->len)) > tp->dmalimit)
{
/* Copy frame to local buffer */
i = tp->TplFree->TPLIndex;
@@ -975,11 +680,11 @@
/* Save the skb for delayed return of skb to system */
tpl->Skb = skb;
- tpl->FragList[0].DataCount = (unsigned short) SWAPB(length);
+ tpl->FragList[0].DataCount = cpu_to_be16((unsigned short)length);
tpl->FragList[0].DataAddr = htonl(virt_to_bus(newbuf));
/* Write the data length in the transmit list. */
- tpl->FrameSize = (unsigned short) SWAPB(length);
+ tpl->FrameSize = cpu_to_be16((unsigned short)length);
tpl->MData = newbuf;
/* Transmit the frame and set the status values. */
@@ -1057,48 +762,41 @@
/*
* The typical workload of the driver: Handle the network interface interrupts.
*/
-static void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
struct net_local *tp;
- int ioaddr;
unsigned short irq_type;
- if(dev == NULL)
- {
+ if(dev == NULL) {
printk("%s: irq %d for unknown device.\n", dev->name, irq);
return;
}
dev->interrupt = 1;
- ioaddr = dev->base_addr;
tp = (struct net_local *)dev->priv;
- irq_type = inw(ioaddr + SIFSTS);
+ irq_type = SIFREADW(SIFSTS);
- while(irq_type & STS_SYSTEM_IRQ)
- {
+ while(irq_type & STS_SYSTEM_IRQ) {
irq_type &= STS_IRQ_MASK;
- if(!tms380tr_chk_ssb(tp, irq_type))
- {
+ if(!tms380tr_chk_ssb(tp, irq_type)) {
printk(KERN_INFO "%s: DATA LATE occurred\n", dev->name);
break;
}
- switch(irq_type)
- {
- case STS_IRQ_RECEIVE_STATUS:
- tms380tr_reset_interrupt(dev);
- tms380tr_rcv_status_irq(dev);
- break;
+ switch(irq_type) {
+ case STS_IRQ_RECEIVE_STATUS:
+ tms380tr_reset_interrupt(dev);
+ tms380tr_rcv_status_irq(dev);
+ break;
- case STS_IRQ_TRANSMIT_STATUS:
- /* Check if TRANSMIT.HALT command is complete */
- if(tp->ssb.Parm[0] & COMMAND_COMPLETE)
- {
- tp->TransmitCommandActive = 0;
+ case STS_IRQ_TRANSMIT_STATUS:
+ /* Check if TRANSMIT.HALT command is complete */
+ if(tp->ssb.Parm[0] & COMMAND_COMPLETE) {
+ tp->TransmitCommandActive = 0;
tp->TransmitHaltScheduled = 0;
/* Issue a new transmit command. */
@@ -1109,40 +807,51 @@
tms380tr_tx_status_irq(dev);
break;
- case STS_IRQ_COMMAND_STATUS:
- /* The SSB contains status of last command
- * other than receive/transmit.
- */
- tms380tr_cmd_status_irq(dev);
- break;
-
- case STS_IRQ_SCB_CLEAR:
- /* The SCB is free for another command. */
- tp->ScbInUse = 0;
- tms380tr_chk_outstanding_cmds(dev);
- break;
-
- case STS_IRQ_RING_STATUS:
- tms380tr_ring_status_irq(dev);
- break;
+ case STS_IRQ_COMMAND_STATUS:
+ /* The SSB contains status of last command
+ * other than receive/transmit.
+ */
+ tms380tr_cmd_status_irq(dev);
+ break;
+
+ case STS_IRQ_SCB_CLEAR:
+ /* The SCB is free for another command. */
+ tp->ScbInUse = 0;
+ tms380tr_chk_outstanding_cmds(dev);
+ break;
+
+ case STS_IRQ_RING_STATUS:
+ tms380tr_ring_status_irq(dev);
+ break;
- case STS_IRQ_ADAPTER_CHECK:
- tms380tr_chk_irq(dev);
- break;
+ case STS_IRQ_ADAPTER_CHECK:
+ tms380tr_chk_irq(dev);
+ break;
- default:
- printk(KERN_INFO "Unknown Token Ring IRQ\n");
- break;
+ case STS_IRQ_LLC_STATUS:
+ printk(KERN_DEBUG "tms380tr: unexpected LLC status IRQ\n");
+ break;
+
+ case STS_IRQ_TIMER:
+ printk(KERN_DEBUG "tms380tr: unexpected Timer IRQ\n");
+ break;
+
+ case STS_IRQ_RECEIVE_PENDING:
+ printk(KERN_DEBUG "tms380tr: unexpected Receive Pending IRQ\n");
+ break;
+
+ default:
+ printk(KERN_INFO "Unknown Token Ring IRQ (0x%04x)\n", irq_type);
+ break;
}
/* Reset system interrupt if not already done. */
if(irq_type != STS_IRQ_TRANSMIT_STATUS
- && irq_type != STS_IRQ_RECEIVE_STATUS)
- {
+ && irq_type != STS_IRQ_RECEIVE_STATUS) {
tms380tr_reset_interrupt(dev);
}
- irq_type = inw(ioaddr + SIFSTS);
+ irq_type = SIFREADW(SIFSTS);
}
dev->interrupt = 0;
@@ -1436,7 +1145,7 @@
/*
* The inverse routine to tms380tr_open().
*/
-static int tms380tr_close(struct net_device *dev)
+int tms380tr_close(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
dev->tbusy = 1;
@@ -1469,13 +1178,9 @@
release_dma_lock(flags);
}
- outw(0xFF00, dev->base_addr + SIFCMD);
- if(dev->dma > 0)
- outb(0xff, dev->base_addr + POSREG);
-
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
+ SIFWRITEW(0xFF00, SIFCMD);
+ if(dev->dma > 0) /* what the? */
+ SIFWRITEB(0xff, POSREG);
tms380tr_cancel_tx_queue(tp);
@@ -1549,7 +1254,7 @@
/*
* Wait for some time (microseconds)
*/
-static void tms380tr_wait(unsigned long time)
+void tms380tr_wait(unsigned long time)
{
#if 0
long tmp;
@@ -1570,7 +1275,6 @@
*/
static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue)
{
- int ioaddr = dev->base_addr;
unsigned short cmd;
unsigned short SifStsValue;
unsigned long loop_counter;
@@ -1579,9 +1283,9 @@
cmd = (unsigned short)WriteValue;
loop_counter = 0,5 * 800000;
do {
- SifStsValue = inw(ioaddr + SIFSTS);
+ SifStsValue = SIFREADW(SIFSTS);
} while((SifStsValue & CMD_INTERRUPT_ADAPTER) && loop_counter--);
- outw(cmd, ioaddr + SIFCMD);
+ SIFWRITEW(cmd, SIFCMD);
return;
}
@@ -1595,22 +1299,19 @@
struct net_local *tp = (struct net_local *)dev->priv;
unsigned short *fw_ptr = (unsigned short *)&tms380tr_code;
unsigned short count, c;
- int ioaddr = dev->base_addr;
/* Hardware adapter reset */
- outw(ACL_ARESET, ioaddr + SIFACL);
+ SIFWRITEW(ACL_ARESET, SIFACL);
tms380tr_wait(40);
- c = inw(ioaddr + SIFACL);
+ c = SIFREADW(SIFACL);
tms380tr_wait(20);
if(dev->dma == 0) /* For PCI adapters */
{
- c &= ~(ACL_SPEED4 | ACL_SPEED16); /* Clear bits */
- if(tp->DataRate == SPEED_4)
- c |= ACL_SPEED4; /* Set 4Mbps */
- else
- c |= ACL_SPEED16; /* Set 16Mbps */
+ c &= ~(ACL_NSELOUT0 | ACL_NSELOUT1); /* Clear bits */
+ if(tp->setnselout)
+ c |= (*tp->setnselout)(dev);
}
/* In case a command is pending - forget it */
@@ -1618,18 +1319,20 @@
c &= ~ACL_ARESET; /* Clear adapter reset bit */
c |= ACL_CPHALT; /* Halt adapter CPU, allow download */
+ c |= ACL_BOOT;
+ c |= ACL_SINTEN;
c &= ~ACL_PSDMAEN; /* Clear pseudo dma bit */
- outw(c, ioaddr + SIFACL);
+ SIFWRITEW(c, SIFACL);
tms380tr_wait(40);
/* Download firmware via DIO interface: */
do {
/* Download first address part */
- outw(*fw_ptr, ioaddr + SIFADX);
+ SIFWRITEW(*fw_ptr, SIFADX);
fw_ptr++;
/* Download second address part */
- outw(*fw_ptr, ioaddr + SIFADD);
+ SIFWRITEW(*fw_ptr, SIFADD);
fw_ptr++;
if((count = *fw_ptr) != 0) /* Load loop counter */
@@ -1637,17 +1340,17 @@
fw_ptr++; /* Download block data */
for(; count > 0; count--)
{
- outw(*fw_ptr, ioaddr + SIFINC);
+ SIFWRITEW(*fw_ptr, SIFINC);
fw_ptr++;
}
}
else /* Stop, if last block downloaded */
{
- c = inw(ioaddr + SIFACL);
+ c = SIFREADW(SIFACL);
c &= (~ACL_CPHALT | ACL_SINTEN);
/* Clear CPHALT and start BUD */
- outw(c, ioaddr + SIFACL);
+ SIFWRITEW(c, SIFACL);
return (1);
}
} while(count == 0);
@@ -1663,7 +1366,6 @@
{
int loop_cnt, retry_cnt;
unsigned short Status;
- int ioaddr = dev->base_addr;
tms380tr_wait(HALF_SECOND);
tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET);
@@ -1679,7 +1381,7 @@
do { /* Inspect BUD results */
loop_cnt--;
tms380tr_wait(HALF_SECOND);
- Status = inw(ioaddr + SIFSTS);
+ Status = SIFREADW(SIFSTS);
Status &= STS_MASK;
if(tms380tr_debug > 3)
@@ -1701,11 +1403,16 @@
}
} while(retry_cnt > 0);
- Status = inw(ioaddr + SIFSTS);
- Status &= STS_ERROR_MASK; /* Hardware error occurred! */
-
- printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n",
- dev->name, Status);
+ Status = SIFREADW(SIFSTS);
+
+ /* Hardware error occurred! */
+ Status &= 0x001f;
+ if (Status & 0x0010)
+ printk(KERN_INFO "%s: BUD Error: Timeout\n", dev->name);
+ else if ((Status & 0x000f) > 6)
+ printk(KERN_INFO "%s: BUD Error: Illegal Failure\n", dev->name);
+ else
+ printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f);
return (-1);
}
@@ -1727,7 +1434,6 @@
unsigned char *sb_ptr = (unsigned char *) &tp->ssb;
unsigned short Status;
int i, loop_cnt, retry_cnt;
- int ioaddr = dev->base_addr;
/* Normalize: byte order low/high, word order high/low! (only IPB!) */
tp->ipb.SCB_Addr = SWAPW(virt_to_bus(&tp->scb));
@@ -1740,14 +1446,14 @@
retry_cnt--;
/* Transfer initialization block */
- outw(0x0001, ioaddr + SIFADX);
+ SIFWRITEW(0x0001, SIFADX);
/* To address 0001:0A00 of adapter RAM */
- outw(0x0A00, ioaddr + SIFADD);
+ SIFWRITEW(0x0A00, SIFADD);
/* Write 11 words to adapter RAM */
for(i = 0; i < 11; i++)
- outw(ipb_ptr[i], ioaddr + SIFINC);
+ SIFWRITEW(ipb_ptr[i], SIFINC);
/* Execute SCB adapter command */
tms380tr_exec_sifcmd(dev, CMD_EXECUTE);
@@ -1761,7 +1467,7 @@
tms380tr_wait(HALF_SECOND);
/* Mask interesting status bits */
- Status = inw(ioaddr + SIFSTS);
+ Status = SIFREADW(SIFSTS);
Status &= STS_MASK;
} while(((Status &(STS_INITIALIZE | STS_ERROR | STS_TEST)) != 0)
&& ((Status & STS_ERROR) == 0) && (loop_cnt != 0));
@@ -1792,7 +1498,7 @@
if((Status & STS_ERROR) != 0)
{
/* Initialization error occurred */
- Status = inw(ioaddr + SIFSTS);
+ Status = SIFREADW(SIFSTS);
Status &= STS_ERROR_MASK;
/* ShowInitialisationErrorCode(Status); */
return (-1); /* Unrecoverable error */
@@ -1820,7 +1526,6 @@
{
struct net_local *tp = (struct net_local *)dev->priv;
unsigned long Addr = 0;
- unsigned char i = 0;
if(tp->CMDqueue == 0)
return; /* No command execution */
@@ -1839,14 +1544,6 @@
/* Execute OPEN command */
tp->CMDqueue ^= OC_OPEN;
- /* Copy the 18 bytes of the product ID */
- while((tp->CardType->name[i] != '\0')
- && (i < PROD_ID_SIZE))
- {
- tp->ProductID[i] = tp->CardType->name[i];
- i++;
- }
-
Addr = htonl(virt_to_bus(&tp->ocpl));
tp->scb.Parm[0] = LOWORD(Addr);
tp->scb.Parm[1] = HIWORD(Addr);
@@ -2001,7 +1698,7 @@
{
struct net_local *tp = (struct net_local *)dev->priv;
- tp->CurrentRingStatus = SWAPB(tp->ssb.Parm[0]);
+ tp->CurrentRingStatus = be16_to_cpu((unsigned short)tp->ssb.Parm[0]);
/* First: fill up statistics */
if(tp->ssb.Parm[0] & SIGNAL_LOSS)
@@ -2071,19 +1768,18 @@
{
int i;
unsigned short AdapterCheckBlock[4];
- unsigned short ioaddr = dev->base_addr;
struct net_local *tp = (struct net_local *)dev->priv;
tp->AdapterOpenFlag = 0; /* Adapter closed now */
/* Page number of adapter memory */
- outw(0x0001, ioaddr + SIFADX);
+ SIFWRITEW(0x0001, SIFADX);
/* Address offset */
- outw(CHECKADDR, ioaddr + SIFADR);
+ SIFWRITEW(CHECKADDR, SIFADR);
/* Reading 8 byte adapter check block. */
for(i = 0; i < 4; i++)
- AdapterCheckBlock[i] = inw(ioaddr + SIFINC);
+ AdapterCheckBlock[i] = SIFREADW(SIFINC);
if(tms380tr_debug > 3)
{
@@ -2234,8 +1930,8 @@
tms380tr_read_ram(dev, (unsigned char *)&tp->intptrs.BurnedInAddrPtr,
ADAPTER_INT_PTRS, 16);
tms380tr_read_ram(dev, (unsigned char *)&adapterram,
- (unsigned short)SWAPB(tp->intptrs.AdapterRAMPtr), 2);
- return SWAPB(adapterram);
+ cpu_to_be16((unsigned short)tp->intptrs.AdapterRAMPtr), 2);
+ return be16_to_cpu(adapterram);
}
/*
@@ -2246,22 +1942,21 @@
{
int i;
unsigned short old_sifadx, old_sifadr, InWord;
- unsigned short ioaddr = dev->base_addr;
/* Save the current values */
- old_sifadx = inw(ioaddr + SIFADX);
- old_sifadr = inw(ioaddr + SIFADR);
+ old_sifadx = SIFREADW(SIFADX);
+ old_sifadr = SIFREADW(SIFADR);
/* Page number of adapter memory */
- outw(0x0001, ioaddr + SIFADX);
+ SIFWRITEW(0x0001, SIFADX);
/* Address offset in adapter RAM */
- outw(Address, ioaddr + SIFADR);
+ SIFWRITEW(Address, SIFADR);
/* Copy len byte from adapter memory to system data area. */
i = 0;
for(;;)
{
- InWord = inw(ioaddr + SIFINC);
+ InWord = SIFREADW(SIFINC);
*(Data + i) = HIBYTE(InWord); /* Write first byte */
if(++i == Length) /* All is done break */
@@ -2273,30 +1968,8 @@
}
/* Restore original values */
- outw(old_sifadx, ioaddr + SIFADX);
- outw(old_sifadr, ioaddr + SIFADR);
-
- return;
-}
-
-/*
- * Reads MAC address from adapter ROM.
- */
-static void tms380tr_read_addr(struct net_device *dev, unsigned char *Address)
-{
- int i, In;
- unsigned short ioaddr = dev->base_addr;
-
- /* Address: 0000:0000 */
- outw(0, ioaddr + SIFADX);
- outw(0, ioaddr + SIFADR);
-
- /* Read six byte MAC address data */
- for(i = 0; i < 6; i++)
- {
- In = inw(ioaddr + SIFINC);
- *(Address + i) = (unsigned char)(In >> 8);
- }
+ SIFWRITEW(old_sifadx, SIFADX);
+ SIFWRITEW(old_sifadr, SIFADR);
return;
}
@@ -2447,7 +2120,7 @@
/* Get the frame size (Byte swap for Intel).
* Do this early (see workaround comment below)
*/
- Length = (unsigned short)SWAPB(rpl->FrameSize);
+ Length = be16_to_cpu((unsigned short)rpl->FrameSize);
/* Check if the Frame_Start, Frame_End and
* Frame_Complete bits are set.
@@ -2463,15 +2136,16 @@
* Length2 is there because there have also been
* cases where the FrameSize was partially written
*/
- Length2 = (unsigned short)SWAPB(rpl->FrameSize);
+ Length2 = be16_to_cpu((unsigned short)rpl->FrameSize);
if(Length == 0 || Length != Length2)
{
tp->RplHead = SaveHead;
break; /* Return to tms380tr_interrupt */
}
-#if 0 /* This might happen for multicast or broadcast packets.
- The upper layers are expected to handle this, not here */
+#if 0 /* This might happen for multicast or broadcast packets.
+ The upper layers are expected to handle this, not here */
+
/* Drop frames sent by myself */
if(tms380tr_chk_frame(dev, rpl->MData))
{
@@ -2552,8 +2226,7 @@
skb_put(rpl->Skb, tp->MaxPacketSize);
/* Data unreachable for DMA ? then use local buffer */
- if(tp->CardType->type == TMS_ISA && virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize
- > ISA_MAX_ADDRESS)
+ if(tp->dmalimit && virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize > tp->dmalimit)
{
rpl->SkbStat = SKB_DATA_COPY;
rpl->FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[rpl->RPLIndex]));
@@ -2568,7 +2241,7 @@
}
}
- rpl->FragList[0].DataCount = SWAPB(tp->MaxPacketSize);
+ rpl->FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize);
rpl->FrameSize = 0;
/* Pass the last RPL back to the adapter */
@@ -2619,6 +2292,7 @@
return;
}
+#if 0
/*
* Check if it is a frame of myself. Compare source address with my current
* address in reverse direction, and mask out the TR_RII.
@@ -2639,6 +2313,20 @@
return (1); /* It is my frame. */
}
+#endif
+
+static int tms380tr_set_mac_address(struct net_device *dev, void *addr)
+{
+ struct net_local *tp = (struct net_local *)dev->priv;
+ struct sockaddr *saddr = addr;
+
+ if (tp->AdapterOpenFlag || tp->AdapterVirtOpenFlag) {
+ printk(KERN_WARNING "%s: Cannot set MAC/LAA address while card is open\n", dev->name);
+ return -EIO;
+ }
+ memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len);
+ return 0;
+}
#if TMS380TR_DEBUG > 0
/*
@@ -2651,80 +2339,73 @@
for (i = 0, j = 0; i < length / 8; i++, j += 8)
{
printk(KERN_DEBUG "%02x %02x %02x %02x %02x %02x %02x %02x\n",
- Data[j+0],Data[j+1],Data[j+2],Data[j+3],
- Data[j+4],Data[j+5],Data[j+6],Data[j+7]);
+ Data[j+0],Data[j+1],Data[j+2],Data[j+3],
+ Data[j+4],Data[j+5],Data[j+6],Data[j+7]);
}
return;
}
#endif
-#ifdef MODULE
+int tmsdev_init(struct net_device *dev)
+{
+ if (dev->priv == NULL)
+ {
+ struct net_local *tms_local;
+
+ dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL | GFP_DMA);
+ if (dev->priv == NULL)
+ return -ENOMEM;
+ memset(dev->priv, 0, sizeof(struct net_local));
+ tms_local = (struct net_local *)dev->priv;
+ init_waitqueue_head(&tms_local->wait_for_tok_int);
+ }
+
+ /* These can be overridden by the card driver if needed */
+ dev->init = tms380tr_init_card;
+ dev->open = tms380tr_open;
+ dev->stop = tms380tr_close;
+ dev->do_ioctl = NULL;
+ dev->hard_start_xmit = tms380tr_send_packet;
+ dev->get_stats = tms380tr_get_stats;
+ dev->set_multicast_list = &tms380tr_set_multicast_list;
+ dev->set_mac_address = tms380tr_set_mac_address;
-static struct net_device* dev_tms380tr[TMS380TR_MAX_ADAPTERS];
-static int io[TMS380TR_MAX_ADAPTERS] = { 0, 0 };
-static int irq[TMS380TR_MAX_ADAPTERS] = { 0, 0 };
-static int mem[TMS380TR_MAX_ADAPTERS] = { 0, 0 };
-
-MODULE_PARM(io, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i");
+ return 0;
+}
-int init_module(void)
-{
- int i;
+#ifdef MODULE
- for(i = 0; i < TMS380TR_MAX_ADAPTERS; i++)
- {
- irq[i] = 0;
- mem[i] = 0;
- dev_tms380tr[i] = NULL;
- dev_tms380tr[i] = init_trdev(dev_tms380tr[i], 0);
- if(dev_tms380tr[i] == NULL)
- return (-ENOMEM);
-
- dev_tms380tr[i]->base_addr = io[i];
- dev_tms380tr[i]->irq = irq[i];
- dev_tms380tr[i]->mem_start = mem[i];
- dev_tms380tr[i]->init = &tms380tr_probe;
-
- if(register_trdev(dev_tms380tr[i]) != 0)
- {
- kfree_s(dev_tms380tr[i], sizeof(struct net_device));
- dev_tms380tr[i] = NULL;
- if(i == 0)
- {
- printk("tms380tr: register_trdev() returned non-zero.\n");
- return (-EIO);
- }
- else
- return (0);
- }
+EXPORT_SYMBOL(tms380tr_open);
+EXPORT_SYMBOL(tms380tr_close);
+EXPORT_SYMBOL(tms380tr_interrupt);
+EXPORT_SYMBOL(tmsdev_init);
+EXPORT_SYMBOL(tms380tr_wait);
- }
+struct module *TMS380_module = NULL;
- return (0);
+int init_module(void)
+{
+ printk("%s", version);
+
+ TMS380_module = &__this_module;
+ return 0;
}
void cleanup_module(void)
{
- int i;
-
- for(i = 0; i < TMS380TR_MAX_ADAPTERS; i++)
- {
- if(dev_tms380tr[i])
- {
- unregister_trdev(dev_tms380tr[i]);
- release_region(dev_tms380tr[i]->base_addr, TMS380TR_IO_EXTENT);
- if(dev_tms380tr[i]->irq)
- free_irq(dev_tms380tr[i]->irq, dev_tms380tr[i]);
- if(dev_tms380tr[i]->dma > 0)
- free_dma(dev_tms380tr[i]->dma);
- if(dev_tms380tr[i]->priv)
- kfree_s(dev_tms380tr[i]->priv, sizeof(struct net_local));
- kfree_s(dev_tms380tr[i], sizeof(struct net_device));
- dev_tms380tr[i] = NULL;
- }
- }
+ TMS380_module = NULL;
}
-#endif /* MODULE */
+#endif
+
+
+/*
+ * Local variables:
+ * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tms380tr.c"
+ * alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tms380tr.c"
+ * c-set-style "K&R"
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)