*
* Change by Mike Sullivan et al.:
* + added turbo card support. No need to use lanaid to configure
- * the adapter into isa compatiblity mode.
+ * the adapter into isa compatibility mode.
*
* Changes by Burt Silverman to allow the computer to behave nicely when
* a cable is pulled or not in place, or a PCMCIA card is removed hot.
#define IBMTR_DEBUG_MESSAGES 0
#include <linux/module.h>
+#include <linux/sched.h>
#ifdef PCMCIA /* required for ibmtr_cs.c to build */
#undef MODULE /* yes, really */
#define ENABLE_PAGING 1
#endif
-#define FALSE 0
-#define TRUE (!FALSE)
-
/* changes the output format of driver initialization */
#define TR_VERBOSE 0
/* version and credits */
#ifndef PCMCIA
-static char version[] __initdata =
+static char version[] __devinitdata =
"\nibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n"
" v2.1.125 10/20/98 Paul Norton <pnorton@ieee.org>\n"
" v2.2.0 12/30/98 Joel Sloan <jjs@c-me.com>\n"
#define TRC_INITV 0x02 /* verbose init trace points */
static unsigned char ibmtr_debug_trace = 0;
-static int ibmtr_probe(struct net_device *dev);
static int ibmtr_probe1(struct net_device *dev, int ioaddr);
static unsigned char get_sram_size(struct tok_info *adapt_info);
static int trdev_init(struct net_device *dev);
static void tok_open_adapter(unsigned long dev_addr);
static void open_sap(unsigned char type, struct net_device *dev);
static void tok_set_multicast_list(struct net_device *dev);
-static int tok_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t tok_send_packet(struct sk_buff *skb,
+ struct net_device *dev);
static int tok_close(struct net_device *dev);
-static irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t tok_interrupt(int irq, void *dev_id);
static void initial_tok_int(struct net_device *dev);
static void tr_tx(struct net_device *dev);
static void tr_rx(struct net_device *dev);
static void ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev);
static void tok_rerun(unsigned long dev_addr);
static void ibmtr_readlog(struct net_device *dev);
-static struct net_device_stats *tok_get_stats(struct net_device *dev);
static int ibmtr_change_mtu(struct net_device *dev, int mtu);
static void find_turbo_adapters(int *iolist);
static int __devinitdata turbo_searched = 0;
#ifndef PCMCIA
-static __u32 ibmtr_mem_base __initdata = 0xd0000;
+static __u32 ibmtr_mem_base __devinitdata = 0xd0000;
#endif
static void __devinit PrtChanID(char *pcid, short stride)
if (dev->base_addr) {
outb(0,dev->base_addr+ADAPTRESET);
- schedule_timeout(TR_RST_TIME); /* wait 50ms */
+ schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
outb(0,dev->base_addr+ADAPTRESETREL);
}
release_region(dev->base_addr, IBMTR_IO_EXTENT);
{
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
iounmap(ti->mmio);
iounmap(ti->sram_virt);
}
#endif
}
-int ibmtr_probe_card(struct net_device *dev)
-{
- int err = ibmtr_probe(dev);
- if (!err) {
- err = register_netdev(dev);
- if (err)
- ibmtr_cleanup_card(dev);
- }
- return err;
-}
-
/****************************************************************************
* ibmtr_probe(): Routine specified in the network device structure
* to probe for an IBM Token Ring Adapter. Routine outline:
* which references it.
****************************************************************************/
-static int ibmtr_probe(struct net_device *dev)
+static int __devinit ibmtr_probe(struct net_device *dev)
{
int i;
int base_addr = dev->base_addr;
return -ENODEV;
}
+int __devinit ibmtr_probe_card(struct net_device *dev)
+{
+ int err = ibmtr_probe(dev);
+ if (!err) {
+ err = register_netdev(dev);
+ if (err)
+ ibmtr_cleanup_card(dev);
+ }
+ return err;
+}
+
/*****************************************************************************/
static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
unsigned char segment, intr=0, irq=0, i, j, cardpresent=NOTOK, temp=0;
void __iomem * t_mmio = NULL;
- struct tok_info *ti = dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
void __iomem *cd_chanid;
unsigned char *tchanid, ctemp;
#ifndef PCMCIA
if (!time_after(jiffies, timeout)) continue;
DPRINTK( "Hardware timeout during initialization.\n");
iounmap(t_mmio);
- kfree(ti);
return -ENODEV;
}
ti->sram_phys =
DPRINTK("Unknown shared ram paging info %01X\n",
ti->shared_ram_paging);
iounmap(t_mmio);
- kfree(ti);
return -ENODEV;
break;
} /*end switch shared_ram_paging */
"driver limit (%05x), adapter not started.\n",
chk_base, ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE);
iounmap(t_mmio);
- kfree(ti);
return -ENODEV;
} else { /* seems cool, record what we have figured out */
ti->sram_base = new_base >> 12;
/* The PCMCIA has already got the interrupt line and the io port,
so no chance of anybody else getting it - MLP */
- if (request_irq(dev->irq = irq, &tok_interrupt, 0, "ibmtr", dev) != 0) {
+ if (request_irq(dev->irq = irq, tok_interrupt, 0, "ibmtr", dev) != 0) {
DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n",
irq);
iounmap(t_mmio);
- kfree(ti);
return -ENODEV;
}
/*?? Now, allocate some of the PIO PORTs for this driver.. */
DPRINTK("Could not grab PIO range. Halting driver.\n");
free_irq(dev->irq, dev);
iounmap(t_mmio);
- kfree(ti);
return -EBUSY;
}
channel_def[cardpresent - 1], adapter_def(ti->adapter_type));
DPRINTK("using irq %d, PIOaddr %hx, %dK shared RAM.\n",
irq, PIOaddr, ti->mapped_ram_size / 2);
- DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n",
- dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
- dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+ DPRINTK("Hardware address : %pM\n", dev->dev_addr);
if (ti->page_mask)
DPRINTK("Shared RAM paging enabled. "
"Page size: %uK Shared Ram size %dK\n",
/*****************************************************************************/
+static const struct net_device_ops trdev_netdev_ops = {
+ .ndo_open = tok_open,
+ .ndo_stop = tok_close,
+ .ndo_start_xmit = tok_send_packet,
+ .ndo_set_multicast_list = tok_set_multicast_list,
+ .ndo_change_mtu = ibmtr_change_mtu,
+};
+
static int __devinit trdev_init(struct net_device *dev)
{
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
SET_PAGE(ti->srb_page);
ti->open_failure = NO ;
- dev->open = tok_open;
- dev->stop = tok_close;
- dev->hard_start_xmit = tok_send_packet;
- dev->get_stats = tok_get_stats;
- dev->set_multicast_list = tok_set_multicast_list;
- dev->change_mtu = ibmtr_change_mtu;
+ dev->netdev_ops = &trdev_netdev_ops;
return 0;
}
unsigned long i;
PIOaddr = dev->base_addr;
- ti = (struct tok_info *) dev->priv;
+ ti = netdev_priv(dev);
/* Special processing for first interrupt after reset */
ti->do_tok_int = FIRST_INT;
/* Reset adapter */
writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
outb(0, PIOaddr + ADAPTRESET);
- current->state=TASK_UNINTERRUPTIBLE;
- schedule_timeout(TR_RST_TIME); /* wait 50ms */
+ schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
outb(0, PIOaddr + ADAPTRESETREL);
#ifdef ENABLE_PAGING
/*****************************************************************************/
static int tok_open(struct net_device *dev)
{
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
int i;
/*the case we were left in a failure state during a previous open */
DPRINTK("Adapter is up and running\n");
return 0;
}
- current->state=TASK_INTERRUPTIBLE;
- i=schedule_timeout(TR_RETRY_INTERVAL); /* wait 30 seconds */
+ i=schedule_timeout_interruptible(TR_RETRY_INTERVAL);
+ /* wait 30 seconds */
if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */
}
outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/
struct tok_info *ti;
int i;
- ti = (struct tok_info *) dev->priv;
+ ti = netdev_priv(dev);
SET_PAGE(ti->init_srb_page);
writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
for (i = 0; i < sizeof(struct dir_open_adapter); i++)
static void open_sap(unsigned char type, struct net_device *dev)
{
int i;
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
SET_PAGE(ti->srb_page);
for (i = 0; i < sizeof(struct dlc_open_sap); i++)
static void tok_set_multicast_list(struct net_device *dev)
{
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
struct dev_mc_list *mclist;
unsigned char address[4];
/*BMS ifconfig tr down or hot unplug a PCMCIA card ??hownowbrowncow*/
if (/*BMSHELPdev->start == 0 ||*/ ti->open_status != OPEN) return;
address[0] = address[1] = address[2] = address[3] = 0;
- mclist = dev->mc_list;
- for (i = 0; i < dev->mc_count; i++) {
+ netdev_for_each_mc_addr(mclist, dev) {
address[0] |= mclist->dmi_addr[2];
address[1] |= mclist->dmi_addr[3];
address[2] |= mclist->dmi_addr[4];
address[3] |= mclist->dmi_addr[5];
- mclist = mclist->next;
}
SET_PAGE(ti->srb_page);
for (i = 0; i < sizeof(struct srb_set_funct_addr); i++)
#define STATION_ID_OFST 4
-static int tok_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t tok_send_packet(struct sk_buff *skb,
+ struct net_device *dev)
{
struct tok_info *ti;
unsigned long flags;
- ti = (struct tok_info *) dev->priv;
+ ti = netdev_priv(dev);
netif_stop_queue(dev);
writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
spin_unlock_irqrestore(&(ti->lock), flags);
dev->trans_start = jiffies;
- return 0;
+ return NETDEV_TX_OK;
}
/*****************************************************************************/
static int tok_close(struct net_device *dev)
{
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
/* Important for PCMCIA hot unplug, otherwise, we'll pull the card, */
/* unloading the module from memory, and then if a timer pops, ouch */
static void dir_open_adapter (struct net_device *dev)
{
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
unsigned char ret_code;
__u16 err;
} else {
char **prphase = printphase;
char **prerror = printerror;
+ int pnr = err / 16 - 1;
+ int enr = err % 16 - 1;
DPRINTK("TR Adapter misc open failure, error code = ");
- printk("0x%x, Phase: %s, Error: %s\n",
- err, prphase[err/16 -1], prerror[err%16 -1]);
+ if (pnr < 0 || pnr >= ARRAY_SIZE(printphase) ||
+ enr < 0 ||
+ enr >= ARRAY_SIZE(printerror))
+ printk("0x%x, invalid Phase/Error.", err);
+ else
+ printk("0x%x, Phase: %s, Error: %s\n", err,
+ prphase[pnr], prerror[enr]);
printk(" retrying after %ds delay...\n",
TR_RETRY_INTERVAL/HZ);
}
/******************************************************************************/
-static irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tok_interrupt(int irq, void *dev_id)
{
unsigned char status;
/* unsigned char status_even ; */
dev = dev_id;
#if TR_VERBOSE
- DPRINTK("Int from tok_driver, dev : %p irq%d regs=%p\n", dev,irq,regs);
+ DPRINTK("Int from tok_driver, dev : %p irq%d\n", dev,irq);
#endif
- ti = (struct tok_info *) dev->priv;
+ ti = netdev_priv(dev);
if (ti->sram_phys & 1)
return IRQ_NONE; /* PCMCIA card extraction flag */
spin_lock(&(ti->lock));
"%02X\n",
(int)retcode, (int)readb(ti->ssb + 6));
else
- ti->tr_stats.tx_packets++;
+ dev->stats.tx_packets++;
break;
case XMIT_XID_CMD:
DPRINTK("xmit xid ret_code: %02X\n",
struct tok_info *ti;
unsigned char init_status; /*BMS 12/2000*/
- ti = (struct tok_info *) dev->priv;
+ ti = netdev_priv(dev);
ti->do_tok_int = NOT_FIRST;
ti->ring_speed = init_status & 0x01 ? 16 : 4;
DPRINTK("Initial interrupt : %d Mbps, shared RAM base %08x.\n",
ti->ring_speed, (unsigned int)dev->mem_start);
- ti->auto_speedsave=readb(ti->init_srb+INIT_STATUS_2_OFST)&4?TRUE:FALSE;
+ ti->auto_speedsave = (readb(ti->init_srb+INIT_STATUS_2_OFST) & 4) != 0;
if (ti->open_mode == MANUAL) wake_up(&ti->wait_for_reset);
else tok_open_adapter((unsigned long)dev);
static void tr_tx(struct net_device *dev)
{
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
struct trh_hdr *trhdr = (struct trh_hdr *) ti->current_skb->data;
unsigned int hdr_len;
__u32 dhb=0,dhb_base;
break;
}
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- ti->tr_stats.tx_bytes += ti->current_skb->len;
+ dev->stats.tx_bytes += ti->current_skb->len;
dev_kfree_skb_irq(ti->current_skb);
ti->current_skb = NULL;
netif_wake_queue(dev);
static void tr_rx(struct net_device *dev)
{
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
__u32 rbuffer;
void __iomem *rbuf, *rbufdata, *llc;
__u8 rbuffer_page = 0;
if (readb(llc + offsetof(struct trllc, llc)) != UI_CMD) {
SET_PAGE(ti->asb_page);
writeb(DATA_LOST, ti->asb + RETCODE_OFST);
- ti->tr_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
return;
}
if (!IPv4_p) {
void __iomem *trhhdr = rbuf + offsetof(struct rec_buf, data);
-
+ u8 saddr[6];
+ u8 daddr[6];
+ int i;
+ for (i = 0 ; i < 6 ; i++)
+ saddr[i] = readb(trhhdr + SADDR_OFST + i);
+ for (i = 0 ; i < 6 ; i++)
+ daddr[i] = readb(trhhdr + DADDR_OFST + i);
DPRINTK("Probably non-IP frame received.\n");
DPRINTK("ssap: %02X dsap: %02X "
- "saddr: %02X:%02X:%02X:%02X:%02X:%02X "
- "daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ "saddr: %pM daddr: %pM\n",
readb(llc + SSAP_OFST), readb(llc + DSAP_OFST),
- readb(trhhdr+SADDR_OFST), readb(trhhdr+ SADDR_OFST+1),
- readb(trhhdr+SADDR_OFST+2), readb(trhhdr+SADDR_OFST+3),
- readb(trhhdr+SADDR_OFST+4), readb(trhhdr+SADDR_OFST+5),
- readb(trhhdr+DADDR_OFST), readb(trhhdr+DADDR_OFST + 1),
- readb(trhhdr+DADDR_OFST+2), readb(trhhdr+DADDR_OFST+3),
- readb(trhhdr+DADDR_OFST+4), readb(trhhdr+DADDR_OFST+5));
+ saddr, daddr);
}
#endif
if (!(skb = dev_alloc_skb(skb_size))) {
DPRINTK("out of memory. frame dropped.\n");
- ti->tr_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
SET_PAGE(ti->asb_page);
writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
/*BMS again, if she comes in with few but leaves with many */
skb_reserve(skb, sizeof(struct trh_hdr) - lan_hdr_len);
skb_put(skb, length);
- skb->dev = dev;
data = skb->data;
rbuffer_len = ntohs(readw(rbuf + offsetof(struct rec_buf, buf_len)));
rbufdata = rbuf + offsetof(struct rec_buf, data);
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- ti->tr_stats.rx_bytes += skb->len;
- ti->tr_stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
skb->protocol = tr_type_trans(skb, dev);
if (IPv4_p) {
skb->csum = chksum;
- skb->ip_summed = 1;
+ skb->ip_summed = CHECKSUM_COMPLETE;
}
netif_rx(skb);
- dev->last_rx = jiffies;
} /*tr_rx */
/*****************************************************************************/
/*****************************************************************************/
-void tok_rerun(unsigned long dev_addr){
-
+static void tok_rerun(unsigned long dev_addr)
+{
struct net_device *dev = (struct net_device *)dev_addr;
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
if ( ti->open_action == RESTART){
ti->do_tok_int = FIRST_INT;
{
struct tok_info *ti;
- ti = (struct tok_info *) dev->priv;
+ ti = netdev_priv(dev);
ti->readlog_pending = 0;
SET_PAGE(ti->srb_page);
/*****************************************************************************/
-/* tok_get_stats(): Basically a scaffold routine which will return
- the address of the tr_statistics structure associated with
- this device -- the tr.... structure is an ethnet look-alike
- so at least for this iteration may suffice. */
-
-static struct net_device_stats *tok_get_stats(struct net_device *dev)
-{
-
- struct tok_info *toki;
- toki = (struct tok_info *) dev->priv;
- return (struct net_device_stats *) &toki->tr_stats;
-}
-
-/*****************************************************************************/
-
static int ibmtr_change_mtu(struct net_device *dev, int mtu)
{
- struct tok_info *ti = (struct tok_info *) dev->priv;
+ struct tok_info *ti = netdev_priv(dev);
if (ti->ring_speed == 16 && mtu > ti->maxmtu16)
return -EINVAL;
find_turbo_adapters(io);
- for (i = 0; io[i] && (i < IBMTR_MAX_ADAPTERS); i++) {
+ for (i = 0; i < IBMTR_MAX_ADAPTERS && io[i]; i++) {
struct net_device *dev;
irq[i] = 0;
mem[i] = 0;