00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 #ifdef __alpha__
00093 #define LOCKUP16 1
00094 #endif
00095 #ifndef LOCKUP16
00096 #define LOCKUP16 0
00097 #endif
00098
00099 #include <linux/config.h>
00100 #include <linux/module.h>
00101
00102 #include <linux/kernel.h>
00103 #include <linux/sched.h>
00104 #include <linux/types.h>
00105 #include <linux/fcntl.h>
00106 #include <linux/interrupt.h>
00107 #include <linux/ptrace.h>
00108 #include <linux/ioport.h>
00109 #include <linux/string.h>
00110 #include <linux/in.h>
00111 #include <asm/system.h>
00112 #include <asm/bitops.h>
00113 #include <asm/io.h>
00114 #include <asm/irq.h>
00115 #include <linux/delay.h>
00116 #include <linux/errno.h>
00117 #include <linux/init.h>
00118
00119 #include <linux/netdevice.h>
00120 #include <linux/etherdevice.h>
00121 #include <linux/skbuff.h>
00122 #include <linux/malloc.h>
00123
00124 #include <asm/spinlock.h>
00125
00126 #ifndef NET_DEBUG
00127 #define NET_DEBUG 4
00128 #endif
00129
00130 #include "eexpress.h"
00131
00132 #define EEXP_IO_EXTENT 16
00133
00134
00135
00136
00137
00138 struct net_local
00139 {
00140 struct net_device_stats stats;
00141 unsigned long last_tx;
00142 unsigned long init_time;
00143 unsigned short rx_first;
00144 unsigned short rx_last;
00145 unsigned short rx_ptr;
00146 unsigned short tx_head;
00147 unsigned short tx_reap;
00148 unsigned short tx_tail;
00149 unsigned short tx_link;
00150 unsigned short last_tx_restart;
00151
00152 unsigned char started;
00153 unsigned short rx_buf_start;
00154 unsigned short rx_buf_end;
00155 unsigned short num_tx_bufs;
00156 unsigned short num_rx_bufs;
00157 unsigned char width;
00158 unsigned char was_promisc;
00159 unsigned char old_mc_count;
00160 spinlock_t lock;
00161 };
00162
00163
00164
00165
00166
00167 static unsigned short start_code[] = {
00168
00169 0x0001,
00170 0x0008,0x0000,0x0000,
00171
00172 0x0000,0x0000,
00173 0x0000,0x0000,
00174
00175 0x0000,0x0000,
00176 0x0000,0x0000,
00177
00178 0x0000,0x0000,
00179 0x0000,0x0000,
00180
00181
00182 #define CONF_LINK 0x20
00183 0x0000,Cmd_Config,
00184 0x0032,
00185 0x080c,
00186 0x2e40,
00187
00188
00189
00190
00191 0x6000,
00192
00193 0xf200,
00194
00195 #define CONF_PROMISC 0x2e
00196 0x0000,
00197
00198 0x003c,
00199
00200 0x0000,Cmd_SetAddr,
00201 0x003e,
00202 #define CONF_HWADDR 0x38
00203 0x0000,0x0000,0x0000,
00204
00205 0x0000,Cmd_MCast,
00206 0x0076,
00207 #define CONF_NR_MULTICAST 0x44
00208 0x0000,
00209 #define CONF_MULTICAST 0x46
00210 0x0000, 0x0000, 0x0000,
00211 0x0000, 0x0000, 0x0000,
00212 0x0000, 0x0000, 0x0000,
00213 0x0000, 0x0000, 0x0000,
00214 0x0000, 0x0000, 0x0000,
00215 0x0000, 0x0000, 0x0000,
00216 0x0000, 0x0000, 0x0000,
00217 0x0000, 0x0000, 0x0000,
00218
00219 #define CONF_DIAG_RESULT 0x76
00220 0x0000, Cmd_Diag,
00221 0x007c,
00222
00223 0x0000,Cmd_TDR|Cmd_INT,
00224 0x0084,
00225 #define CONF_TDR_RESULT 0x82
00226 0x0000,
00227
00228 0x0000,Cmd_END|Cmd_Nop,
00229 0x0084
00230 };
00231
00232
00233 static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 };
00234
00235
00236
00237
00238
00239 extern int express_probe(struct device *dev);
00240 static int eexp_open(struct device *dev);
00241 static int eexp_close(struct device *dev);
00242 static struct net_device_stats *eexp_stats(struct device *dev);
00243 static int eexp_xmit(struct sk_buff *buf, struct device *dev);
00244
00245 static void eexp_irq(int irq, void *dev_addr, struct pt_regs *regs);
00246 static void eexp_set_multicast(struct device *dev);
00247
00248
00249
00250
00251
00252 static void eexp_hw_rx_pio(struct device *dev);
00253 static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf,
00254 unsigned short len);
00255 static int eexp_hw_probe(struct device *dev,unsigned short ioaddr);
00256 static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
00257 unsigned char location);
00258
00259 static unsigned short eexp_hw_lasttxstat(struct device *dev);
00260 static void eexp_hw_txrestart(struct device *dev);
00261
00262 static void eexp_hw_txinit (struct device *dev);
00263 static void eexp_hw_rxinit (struct device *dev);
00264
00265 static void eexp_hw_init586 (struct device *dev);
00266 static void eexp_setup_filter (struct device *dev);
00267
00268 static char *eexp_ifmap[]={"AUI", "BNC", "RJ45"};
00269 enum eexp_iftype {AUI=0, BNC=1, TPE=2};
00270
00271 #define STARTED_RU 2
00272 #define STARTED_CU 1
00273
00274
00275
00276
00277
00278 static inline unsigned short scb_status(struct device *dev)
00279 {
00280 return inw(dev->base_addr + 0xc008);
00281 }
00282
00283 static inline unsigned short scb_rdcmd(struct device *dev)
00284 {
00285 return inw(dev->base_addr + 0xc00a);
00286 }
00287
00288 static inline void scb_command(struct device *dev, unsigned short cmd)
00289 {
00290 outw(cmd, dev->base_addr + 0xc00a);
00291 }
00292
00293 static inline void scb_wrcbl(struct device *dev, unsigned short val)
00294 {
00295 outw(val, dev->base_addr + 0xc00c);
00296 }
00297
00298 static inline void scb_wrrfa(struct device *dev, unsigned short val)
00299 {
00300 outw(val, dev->base_addr + 0xc00e);
00301 }
00302
00303 static inline void set_loopback(struct device *dev)
00304 {
00305 outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config);
00306 }
00307
00308 static inline void clear_loopback(struct device *dev)
00309 {
00310 outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config);
00311 }
00312
00313 static inline unsigned short int SHADOW(short int addr)
00314 {
00315 addr &= 0x1f;
00316 if (addr > 0xf) addr += 0x3ff0;
00317 return addr + 0x4000;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 __initfunc(int express_probe(struct device *dev))
00329 {
00330 unsigned short *port;
00331 static unsigned short ports[] = { 0x300,0x310,0x270,0x320,0x340,0 };
00332 unsigned short ioaddr = dev->base_addr;
00333
00334 if (ioaddr&0xfe00)
00335 return eexp_hw_probe(dev,ioaddr);
00336 else if (ioaddr)
00337 return ENXIO;
00338
00339 for (port=&ports[0] ; *port ; port++ )
00340 {
00341 unsigned short sum = 0;
00342 int i;
00343 for ( i=0 ; i<4 ; i++ )
00344 {
00345 unsigned short t;
00346 t = inb(*port + ID_PORT);
00347 sum |= (t>>4) << ((t & 0x03)<<2);
00348 }
00349 if (sum==0xbaba && !eexp_hw_probe(dev,*port))
00350 return 0;
00351 }
00352 return -ENODEV;
00353 }
00354
00355
00356
00357
00358
00359 static int eexp_open(struct device *dev)
00360 {
00361 int irq = dev->irq;
00362 unsigned short ioaddr = dev->base_addr;
00363 struct net_local *lp = (struct net_local *)dev->priv;
00364
00365 #if NET_DEBUG > 6
00366 printk(KERN_DEBUG "%s: eexp_open()\n", dev->name);
00367 #endif
00368
00369 if (!irq || !irqrmap[irq])
00370 return -ENXIO;
00371
00372 if (request_irq(irq,&eexp_irq,0,"EtherExpress",dev))
00373 return -EAGAIN;
00374
00375 request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress");
00376 request_region(ioaddr+0x4000, 16, "EtherExpress shadow");
00377 request_region(ioaddr+0x8000, 16, "EtherExpress shadow");
00378 request_region(ioaddr+0xc000, 16, "EtherExpress shadow");
00379 dev->tbusy = 0;
00380 dev->interrupt = 0;
00381
00382 if (lp->width) {
00383 printk("%s: forcing ASIC to 8-bit mode\n", dev->name);
00384 outb(inb(dev->base_addr+Config)&~4, dev->base_addr+Config);
00385 }
00386
00387 eexp_hw_init586(dev);
00388 dev->start = 1;
00389 MOD_INC_USE_COUNT;
00390 #if NET_DEBUG > 6
00391 printk(KERN_DEBUG "%s: leaving eexp_open()\n", dev->name);
00392 #endif
00393 return 0;
00394 }
00395
00396
00397
00398
00399
00400 static int eexp_close(struct device *dev)
00401 {
00402 unsigned short ioaddr = dev->base_addr;
00403 struct net_local *lp = dev->priv;
00404
00405 int irq = dev->irq;
00406
00407 dev->tbusy = 1;
00408 dev->start = 0;
00409
00410 outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
00411 lp->started = 0;
00412 scb_command(dev, SCB_CUsuspend|SCB_RUsuspend);
00413 outb(0,ioaddr+SIGNAL_CA);
00414 free_irq(irq,dev);
00415 outb(i586_RST,ioaddr+EEPROM_Ctrl);
00416 release_region(ioaddr, EEXP_IO_EXTENT);
00417 release_region(ioaddr+0x4000, 16);
00418 release_region(ioaddr+0x8000, 16);
00419 release_region(ioaddr+0xc000, 16);
00420
00421 MOD_DEC_USE_COUNT;
00422 return 0;
00423 }
00424
00425
00426
00427
00428
00429 static struct net_device_stats *eexp_stats(struct device *dev)
00430 {
00431 struct net_local *lp = (struct net_local *)dev->priv;
00432
00433 return &lp->stats;
00434 }
00435
00436
00437
00438
00439
00440
00441 static void unstick_cu(struct device *dev)
00442 {
00443 struct net_local *lp = (struct net_local *)dev->priv;
00444 unsigned short ioaddr = dev->base_addr;
00445
00446 if (lp->started)
00447 {
00448 if ((jiffies - dev->trans_start)>50)
00449 {
00450 if (lp->tx_link==lp->last_tx_restart)
00451 {
00452 unsigned short boguscount=200,rsst;
00453 printk(KERN_WARNING "%s: Retransmit timed out, status %04x, resetting...\n",
00454 dev->name, scb_status(dev));
00455 eexp_hw_txinit(dev);
00456 lp->last_tx_restart = 0;
00457 scb_wrcbl(dev, lp->tx_link);
00458 scb_command(dev, SCB_CUstart);
00459 outb(0,ioaddr+SIGNAL_CA);
00460 while (!SCB_complete(rsst=scb_status(dev)))
00461 {
00462 if (!--boguscount)
00463 {
00464 boguscount=200;
00465 printk(KERN_WARNING "%s: Reset timed out status %04x, retrying...\n",
00466 dev->name,rsst);
00467 scb_wrcbl(dev, lp->tx_link);
00468 scb_command(dev, SCB_CUstart);
00469 outb(0,ioaddr+SIGNAL_CA);
00470 }
00471 }
00472 dev->tbusy = 0;
00473 mark_bh(NET_BH);
00474 }
00475 else
00476 {
00477 unsigned short status = scb_status(dev);
00478 if (SCB_CUdead(status))
00479 {
00480 unsigned short txstatus = eexp_hw_lasttxstat(dev);
00481 printk(KERN_WARNING "%s: Transmit timed out, CU not active status %04x %04x, restarting...\n",
00482 dev->name, status, txstatus);
00483 eexp_hw_txrestart(dev);
00484 }
00485 else
00486 {
00487 unsigned short txstatus = eexp_hw_lasttxstat(dev);
00488 if (dev->tbusy && !txstatus)
00489 {
00490 printk(KERN_WARNING "%s: CU wedged, status %04x %04x, resetting...\n",
00491 dev->name,status,txstatus);
00492 eexp_hw_init586(dev);
00493 dev->tbusy = 0;
00494 mark_bh(NET_BH);
00495 }
00496 else
00497 {
00498 printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
00499 }
00500 }
00501 }
00502 }
00503 }
00504 else
00505 {
00506 if ((jiffies-lp->init_time)>10)
00507 {
00508 unsigned short status = scb_status(dev);
00509 printk(KERN_WARNING "%s: i82586 startup timed out, status %04x, resetting...\n",
00510 dev->name, status);
00511 eexp_hw_init586(dev);
00512 dev->tbusy = 0;
00513 mark_bh(NET_BH);
00514 }
00515 }
00516 }
00517
00518
00519
00520
00521
00522 static int eexp_xmit(struct sk_buff *buf, struct device *dev)
00523 {
00524 struct net_local *lp = (struct net_local *)dev->priv;
00525 short length = buf->len;
00526 unsigned long flags;
00527
00528 #if NET_DEBUG > 6
00529 printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name);
00530 #endif
00531
00532 if(buf->len < ETH_ZLEN)
00533 {
00534 buf = skb_padto(buf, ETH_ZLEN);
00535 if(buf == NULL)
00536 return 0;
00537 length = buf->len;
00538 }
00539
00540 disable_irq(dev->irq);
00541
00542
00543
00544
00545
00546
00547 #ifdef CONFIG_SMP
00548 spin_lock_irqsave(&lp->lock, flags);
00549 #endif
00550
00551
00552
00553
00554 if (dev->tbusy) {
00555 int status = scb_status(dev);
00556 unstick_cu(dev);
00557 if ((jiffies - lp->last_tx) < HZ)
00558 {
00559 #ifdef CONFIG_SMP
00560 spin_unlock_irqrestore(&lp->lock, flags);
00561 #endif
00562
00563 return 1;
00564 }
00565 printk(KERN_INFO "%s: transmit timed out, %s?", dev->name,
00566 (SCB_complete(status)?"lost interrupt":
00567 "board on fire"));
00568 lp->stats.tx_errors++;
00569 dev->tbusy = 0;
00570 lp->last_tx = jiffies;
00571 if (!SCB_complete(status)) {
00572 scb_command(dev, SCB_CUabort);
00573 outb(0,dev->base_addr+SIGNAL_CA);
00574 }
00575 }
00576
00577 if (test_and_set_bit(0,(void *)&dev->tbusy))
00578 {
00579 lp->stats.tx_dropped++;
00580 }
00581 else
00582 {
00583 unsigned short *data = (unsigned short *)buf->data;
00584
00585 lp->stats.tx_bytes += length;
00586
00587 eexp_hw_tx_pio(dev,data,length);
00588 }
00589 dev_kfree_skb(buf);
00590 #ifdef CONFIG_SMP
00591 spin_unlock_irqrestore(&lp->lock, flags);
00592 #endif
00593 enable_irq(dev->irq);
00594 return 0;
00595 }
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 static unsigned short eexp_start_irq(struct device *dev,
00612 unsigned short status)
00613 {
00614 unsigned short ack_cmd = SCB_ack(status);
00615 struct net_local *lp = (struct net_local *)dev->priv;
00616 unsigned short ioaddr = dev->base_addr;
00617 if ((dev->flags & IFF_UP) && !(lp->started & STARTED_CU)) {
00618 short diag_status, tdr_status;
00619 while (SCB_CUstat(status)==2)
00620 status = scb_status(dev);
00621 #if NET_DEBUG > 4
00622 printk("%s: CU went non-active (status %04x)\n",
00623 dev->name, status);
00624 #endif
00625
00626 outw(CONF_DIAG_RESULT & ~31, ioaddr + SM_PTR);
00627 diag_status = inw(ioaddr + SHADOW(CONF_DIAG_RESULT));
00628 if (diag_status & 1<<11) {
00629 printk(KERN_WARNING "%s: 82586 failed self-test\n",
00630 dev->name);
00631 } else if (!(diag_status & 1<<13)) {
00632 printk(KERN_WARNING "%s: 82586 self-test failed to complete\n", dev->name);
00633 }
00634
00635 outw(CONF_TDR_RESULT & ~31, ioaddr + SM_PTR);
00636 tdr_status = inw(ioaddr + SHADOW(CONF_TDR_RESULT));
00637 if (tdr_status & (TDR_SHORT|TDR_OPEN)) {
00638 printk(KERN_WARNING "%s: TDR reports cable %s at %d tick%s\n", dev->name, (tdr_status & TDR_SHORT)?"short":"broken", tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : "");
00639 }
00640 else if (tdr_status & TDR_XCVRPROBLEM) {
00641 printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name);
00642 }
00643 else if (tdr_status & TDR_LINKOK) {
00644 #if NET_DEBUG > 4
00645 printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name);
00646 #endif
00647 } else {
00648 printk("%s: TDR is ga-ga (status %04x)\n", dev->name,
00649 tdr_status);
00650 }
00651
00652 lp->started |= STARTED_CU;
00653 scb_wrcbl(dev, lp->tx_link);
00654
00655 if (!(lp->started & STARTED_RU)) {
00656 ack_cmd |= SCB_RUstart;
00657 scb_wrrfa(dev, lp->rx_buf_start);
00658 lp->rx_ptr = lp->rx_buf_start;
00659 lp->started |= STARTED_RU;
00660 }
00661 ack_cmd |= SCB_CUstart | 0x2000;
00662 }
00663
00664 if ((dev->flags & IFF_UP) && !(lp->started & STARTED_RU) && SCB_RUstat(status)==4)
00665 lp->started|=STARTED_RU;
00666
00667 return ack_cmd;
00668 }
00669
00670 static void eexp_cmd_clear(struct device *dev)
00671 {
00672 unsigned long int oldtime = jiffies;
00673 while (scb_rdcmd(dev) && ((jiffies-oldtime)<10));
00674 if (scb_rdcmd(dev)) {
00675 printk("%s: command didn't clear\n", dev->name);
00676 }
00677 }
00678
00679 static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
00680 {
00681 struct device *dev = dev_info;
00682 struct net_local *lp;
00683 unsigned short ioaddr,status,ack_cmd;
00684 unsigned short old_read_ptr, old_write_ptr;
00685
00686 if (dev==NULL)
00687 {
00688 printk(KERN_WARNING "eexpress: irq %d for unknown device\n",
00689 irq);
00690 return;
00691 }
00692
00693 lp = (struct net_local *)dev->priv;
00694 ioaddr = dev->base_addr;
00695
00696 spin_lock(&lp->lock);
00697
00698 old_read_ptr = inw(ioaddr+READ_PTR);
00699 old_write_ptr = inw(ioaddr+WRITE_PTR);
00700
00701 outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
00702
00703
00704 dev->interrupt = 1;
00705
00706 status = scb_status(dev);
00707
00708 #if NET_DEBUG > 4
00709 printk(KERN_DEBUG "%s: interrupt (status %x)\n", dev->name, status);
00710 #endif
00711
00712 if (lp->started == (STARTED_CU | STARTED_RU)) {
00713
00714 do {
00715 eexp_cmd_clear(dev);
00716
00717 ack_cmd = SCB_ack(status);
00718 scb_command(dev, ack_cmd);
00719 outb(0,ioaddr+SIGNAL_CA);
00720
00721 eexp_cmd_clear(dev);
00722
00723 if (SCB_complete(status)) {
00724 if (!eexp_hw_lasttxstat(dev)) {
00725 printk("%s: tx interrupt but no status\n", dev->name);
00726 }
00727 }
00728
00729 if (SCB_rxdframe(status))
00730 eexp_hw_rx_pio(dev);
00731
00732 status = scb_status(dev);
00733 } while (status & 0xc000);
00734
00735 if (SCB_RUdead(status))
00736 {
00737 printk(KERN_WARNING "%s: RU stopped: status %04x\n",
00738 dev->name,status);
00739 #if 0
00740 printk(KERN_WARNING "%s: cur_rfd=%04x, cur_rbd=%04x\n", dev->name, lp->cur_rfd, lp->cur_rbd);
00741 outw(lp->cur_rfd, ioaddr+READ_PTR);
00742 printk(KERN_WARNING "%s: [%04x]\n", dev->name, inw(ioaddr+DATAPORT));
00743 outw(lp->cur_rfd+6, ioaddr+READ_PTR);
00744 printk(KERN_WARNING "%s: rbd is %04x\n", dev->name, rbd= inw(ioaddr+DATAPORT));
00745 outw(rbd, ioaddr+READ_PTR);
00746 printk(KERN_WARNING "%s: [%04x %04x] ", dev->name, inw(ioaddr+DATAPORT), inw(ioaddr+DATAPORT));
00747 outw(rbd+8, ioaddr+READ_PTR);
00748 printk("[%04x]\n", inw(ioaddr+DATAPORT));
00749 #endif
00750 lp->stats.rx_errors++;
00751 #if 1
00752 eexp_hw_rxinit(dev);
00753 #else
00754 lp->cur_rfd = lp->first_rfd;
00755 #endif
00756 scb_wrrfa(dev, lp->rx_buf_start);
00757 scb_command(dev, SCB_RUstart);
00758 outb(0,ioaddr+SIGNAL_CA);
00759 }
00760 } else {
00761 if (status & 0x8000)
00762 ack_cmd = eexp_start_irq(dev, status);
00763 else
00764 ack_cmd = SCB_ack(status);
00765 scb_command(dev, ack_cmd);
00766 outb(0,ioaddr+SIGNAL_CA);
00767 }
00768
00769 eexp_cmd_clear(dev);
00770
00771 outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ);
00772
00773 dev->interrupt = 0;
00774 #if NET_DEBUG > 6
00775 printk("%s: leaving eexp_irq()\n", dev->name);
00776 #endif
00777 outw(old_read_ptr, ioaddr+READ_PTR);
00778 outw(old_write_ptr, ioaddr+WRITE_PTR);
00779
00780 spin_unlock(&lp->lock);
00781 return;
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 static void eexp_hw_set_interface(struct device *dev)
00793 {
00794 unsigned char oldval = inb(dev->base_addr + 0x300e);
00795 oldval &= ~0x82;
00796 switch (dev->if_port) {
00797 case TPE:
00798 oldval |= 0x2;
00799 case BNC:
00800 oldval |= 0x80;
00801 break;
00802 }
00803 outb(oldval, dev->base_addr+0x300e);
00804 mdelay(20);
00805 }
00806
00807
00808
00809
00810
00811
00812
00813 static void eexp_hw_rx_pio(struct device *dev)
00814 {
00815 struct net_local *lp = (struct net_local *)dev->priv;
00816 unsigned short rx_block = lp->rx_ptr;
00817 unsigned short boguscount = lp->num_rx_bufs;
00818 unsigned short ioaddr = dev->base_addr;
00819 unsigned short status;
00820
00821 #if NET_DEBUG > 6
00822 printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name);
00823 #endif
00824
00825 do {
00826 unsigned short rfd_cmd, rx_next, pbuf, pkt_len;
00827
00828 outw(rx_block, ioaddr + READ_PTR);
00829 status = inw(ioaddr + DATAPORT);
00830
00831 if (FD_Done(status))
00832 {
00833 rfd_cmd = inw(ioaddr + DATAPORT);
00834 rx_next = inw(ioaddr + DATAPORT);
00835 pbuf = inw(ioaddr + DATAPORT);
00836
00837 outw(pbuf, ioaddr + READ_PTR);
00838 pkt_len = inw(ioaddr + DATAPORT);
00839
00840 if (rfd_cmd!=0x0000)
00841 {
00842 printk(KERN_WARNING "%s: rfd_cmd not zero:0x%04x\n",
00843 dev->name, rfd_cmd);
00844 continue;
00845 }
00846 else if (pbuf!=rx_block+0x16)
00847 {
00848 printk(KERN_WARNING "%s: rfd and rbd out of sync 0x%04x 0x%04x\n",
00849 dev->name, rx_block+0x16, pbuf);
00850 continue;
00851 }
00852 else if ((pkt_len & 0xc000)!=0xc000)
00853 {
00854 printk(KERN_WARNING "%s: EOF or F not set on received buffer (%04x)\n",
00855 dev->name, pkt_len & 0xc000);
00856 continue;
00857 }
00858 else if (!FD_OK(status))
00859 {
00860 lp->stats.rx_errors++;
00861 if (FD_CRC(status))
00862 lp->stats.rx_crc_errors++;
00863 if (FD_Align(status))
00864 lp->stats.rx_frame_errors++;
00865 if (FD_Resrc(status))
00866 lp->stats.rx_fifo_errors++;
00867 if (FD_DMA(status))
00868 lp->stats.rx_over_errors++;
00869 if (FD_Short(status))
00870 lp->stats.rx_length_errors++;
00871 }
00872 else
00873 {
00874 struct sk_buff *skb;
00875 pkt_len &= 0x3fff;
00876 skb = dev_alloc_skb(pkt_len+16);
00877 if (skb == NULL)
00878 {
00879 printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name);
00880 lp->stats.rx_dropped++;
00881 break;
00882 }
00883 skb->dev = dev;
00884 skb_reserve(skb, 2);
00885 outw(pbuf+10, ioaddr+READ_PTR);
00886 insw(ioaddr+DATAPORT, skb_put(skb,pkt_len),(pkt_len+1)>>1);
00887 skb->protocol = eth_type_trans(skb,dev);
00888 netif_rx(skb);
00889 lp->stats.rx_packets++;
00890 lp->stats.rx_bytes += pkt_len;
00891 }
00892 outw(rx_block, ioaddr+WRITE_PTR);
00893 outw(0, ioaddr+DATAPORT);
00894 outw(0, ioaddr+DATAPORT);
00895 rx_block = rx_next;
00896 }
00897 } while (FD_Done(status) && boguscount--);
00898 lp->rx_ptr = rx_block;
00899 }
00900
00901
00902
00903
00904
00905
00906
00907
00908 static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf,
00909 unsigned short len)
00910 {
00911 struct net_local *lp = (struct net_local *)dev->priv;
00912 unsigned short ioaddr = dev->base_addr;
00913
00914 if (LOCKUP16 || lp->width) {
00915
00916
00917
00918
00919
00920 scb_command(dev, SCB_CUsuspend);
00921 outw(0xFFFF, ioaddr+SIGNAL_CA);
00922 }
00923
00924 outw(lp->tx_head, ioaddr + WRITE_PTR);
00925
00926 outw(0x0000, ioaddr + DATAPORT);
00927 outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT);
00928 outw(lp->tx_head+0x08, ioaddr + DATAPORT);
00929 outw(lp->tx_head+0x0e, ioaddr + DATAPORT);
00930
00931 outw(0x0000, ioaddr + DATAPORT);
00932 outw(0x0000, ioaddr + DATAPORT);
00933 outw(lp->tx_head+0x08, ioaddr + DATAPORT);
00934
00935 outw(0x8000|len, ioaddr + DATAPORT);
00936 outw(-1, ioaddr + DATAPORT);
00937 outw(lp->tx_head+0x16, ioaddr + DATAPORT);
00938 outw(0, ioaddr + DATAPORT);
00939
00940 outsw(ioaddr + DATAPORT, buf, (len+1)>>1);
00941
00942 outw(lp->tx_tail+0xc, ioaddr + WRITE_PTR);
00943 outw(lp->tx_head, ioaddr + DATAPORT);
00944
00945 dev->trans_start = jiffies;
00946 lp->tx_tail = lp->tx_head;
00947 if (lp->tx_head==TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
00948 lp->tx_head = TX_BUF_START;
00949 else
00950 lp->tx_head += TX_BUF_SIZE;
00951 if (lp->tx_head != lp->tx_reap)
00952 dev->tbusy = 0;
00953
00954 if (LOCKUP16 || lp->width) {
00955
00956
00957 scb_command(dev, SCB_CUresume);
00958 outw(0xFFFF, ioaddr+SIGNAL_CA);
00959 }
00960
00961 lp->stats.tx_packets++;
00962 lp->last_tx = jiffies;
00963 }
00964
00965
00966
00967
00968
00969
00970
00971
00972 __initfunc(static int eexp_hw_probe(struct device *dev, unsigned short ioaddr))
00973 {
00974 unsigned short hw_addr[3];
00975 unsigned char buswidth;
00976 unsigned int memory_size;
00977 int i;
00978 unsigned short xsum = 0;
00979 struct net_local *lp;
00980
00981 printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr);
00982
00983 outb(ASIC_RST, ioaddr+EEPROM_Ctrl);
00984 outb(0, ioaddr+EEPROM_Ctrl);
00985 udelay(500);
00986 outb(i586_RST, ioaddr+EEPROM_Ctrl);
00987
00988 hw_addr[0] = eexp_hw_readeeprom(ioaddr,2);
00989 hw_addr[1] = eexp_hw_readeeprom(ioaddr,3);
00990 hw_addr[2] = eexp_hw_readeeprom(ioaddr,4);
00991
00992
00993 if (!((hw_addr[2]==0x00aa && ((hw_addr[1] & 0xff00)==0x0000)) ||
00994 (hw_addr[2]==0x0080 && ((hw_addr[1] & 0xff00)==0x5F00))))
00995 {
00996 printk(" rejected: invalid address %04x%04x%04x\n",
00997 hw_addr[2],hw_addr[1],hw_addr[0]);
00998 return -ENODEV;
00999 }
01000
01001
01002
01003
01004 for (i = 0; i < 64; i++)
01005 xsum += eexp_hw_readeeprom(ioaddr, i);
01006 if (xsum != 0xbaba)
01007 printk(" (bad EEPROM xsum 0x%02x)", xsum);
01008
01009 dev->base_addr = ioaddr;
01010 for ( i=0 ; i<6 ; i++ )
01011 dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i];
01012
01013 {
01014 static char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0};
01015 unsigned short setupval = eexp_hw_readeeprom(ioaddr,0);
01016
01017
01018 if (!dev->irq)
01019 dev->irq = irqmap[setupval>>13];
01020
01021 dev->if_port = !(setupval & 0x1000) ? AUI :
01022 eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC;
01023
01024 buswidth = !((setupval & 0x400) >> 10);
01025 }
01026
01027 dev->priv = lp = kmalloc(sizeof(struct net_local), GFP_KERNEL);
01028 if (!dev->priv)
01029 return ENOMEM;
01030
01031 memset(dev->priv, 0, sizeof(struct net_local));
01032
01033 printk("(IRQ %d, %s connector, %d-bit bus", dev->irq,
01034 eexp_ifmap[dev->if_port], buswidth?8:16);
01035
01036 eexp_hw_set_interface(dev);
01037
01038
01039 outw(0, dev->base_addr + WRITE_PTR);
01040 for (i = 0; i < 32768; i++)
01041 outw(0, dev->base_addr + DATAPORT);
01042
01043 for (memory_size = 0; memory_size < 64; memory_size++)
01044 {
01045 outw(memory_size<<10, dev->base_addr + READ_PTR);
01046 if (inw(dev->base_addr+DATAPORT))
01047 break;
01048 outw(memory_size<<10, dev->base_addr + WRITE_PTR);
01049 outw(memory_size | 0x5000, dev->base_addr+DATAPORT);
01050 outw(memory_size<<10, dev->base_addr + READ_PTR);
01051 if (inw(dev->base_addr+DATAPORT) != (memory_size | 0x5000))
01052 break;
01053 }
01054
01055
01056
01057
01058 lp->num_tx_bufs = 4;
01059 lp->rx_buf_end = 0x3ff6;
01060 switch (memory_size)
01061 {
01062 case 64:
01063 lp->rx_buf_end += 0x4000;
01064 case 48:
01065 lp->num_tx_bufs += 4;
01066 lp->rx_buf_end += 0x4000;
01067 case 32:
01068 lp->rx_buf_end += 0x4000;
01069 case 16:
01070 printk(", %dk RAM)\n", memory_size);
01071 break;
01072 default:
01073 printk(") bad memory size (%dk).\n", memory_size);
01074 kfree(dev->priv);
01075 return ENODEV;
01076 break;
01077 }
01078
01079 lp->rx_buf_start = TX_BUF_START + (lp->num_tx_bufs*TX_BUF_SIZE);
01080 lp->width = buswidth;
01081
01082 dev->open = eexp_open;
01083 dev->stop = eexp_close;
01084 dev->hard_start_xmit = eexp_xmit;
01085 dev->get_stats = eexp_stats;
01086 dev->set_multicast_list = &eexp_set_multicast;
01087 ether_setup(dev);
01088 return 0;
01089 }
01090
01091
01092
01093
01094
01095 __initfunc(static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
01096 unsigned char location))
01097 {
01098 unsigned short cmd = 0x180|(location&0x7f);
01099 unsigned short rval = 0,wval = EC_CS|i586_RST;
01100 int i;
01101
01102 outb(EC_CS|i586_RST,ioaddr+EEPROM_Ctrl);
01103 for (i=0x100 ; i ; i>>=1 )
01104 {
01105 if (cmd&i)
01106 wval |= EC_Wr;
01107 else
01108 wval &= ~EC_Wr;
01109
01110 outb(wval,ioaddr+EEPROM_Ctrl);
01111 outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
01112 eeprom_delay();
01113 outb(wval,ioaddr+EEPROM_Ctrl);
01114 eeprom_delay();
01115 }
01116 wval &= ~EC_Wr;
01117 outb(wval,ioaddr+EEPROM_Ctrl);
01118 for (i=0x8000 ; i ; i>>=1 )
01119 {
01120 outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
01121 eeprom_delay();
01122 if (inb(ioaddr+EEPROM_Ctrl)&EC_Rd)
01123 rval |= i;
01124 outb(wval,ioaddr+EEPROM_Ctrl);
01125 eeprom_delay();
01126 }
01127 wval &= ~EC_CS;
01128 outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
01129 eeprom_delay();
01130 outb(wval,ioaddr+EEPROM_Ctrl);
01131 eeprom_delay();
01132 return rval;
01133 }
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 static unsigned short eexp_hw_lasttxstat(struct device *dev)
01146 {
01147 struct net_local *lp = (struct net_local *)dev->priv;
01148 unsigned short tx_block = lp->tx_reap;
01149 unsigned short status;
01150
01151 if ((!dev->tbusy) && lp->tx_head==lp->tx_reap)
01152 return 0x0000;
01153
01154 do
01155 {
01156 outw(tx_block & ~31, dev->base_addr + SM_PTR);
01157 status = inw(dev->base_addr + SHADOW(tx_block));
01158 if (!Stat_Done(status))
01159 {
01160 lp->tx_link = tx_block;
01161 return status;
01162 }
01163 else
01164 {
01165 lp->last_tx_restart = 0;
01166 lp->stats.collisions += Stat_NoColl(status);
01167 if (!Stat_OK(status))
01168 {
01169 char *whatsup = NULL;
01170 lp->stats.tx_errors++;
01171 if (Stat_Abort(status))
01172 lp->stats.tx_aborted_errors++;
01173 if (Stat_TNoCar(status)) {
01174 whatsup = "aborted, no carrier";
01175 lp->stats.tx_carrier_errors++;
01176 }
01177 if (Stat_TNoCTS(status)) {
01178 whatsup = "aborted, lost CTS";
01179 lp->stats.tx_carrier_errors++;
01180 }
01181 if (Stat_TNoDMA(status)) {
01182 whatsup = "FIFO underran";
01183 lp->stats.tx_fifo_errors++;
01184 }
01185 if (Stat_TXColl(status)) {
01186 whatsup = "aborted, too many collisions";
01187 lp->stats.tx_aborted_errors++;
01188 }
01189 if (whatsup)
01190 printk(KERN_INFO "%s: transmit %s\n",
01191 dev->name, whatsup);
01192 }
01193 else
01194 lp->stats.tx_packets++;
01195 }
01196 if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
01197 lp->tx_reap = tx_block = TX_BUF_START;
01198 else
01199 lp->tx_reap = tx_block += TX_BUF_SIZE;
01200 dev->tbusy = 0;
01201 mark_bh(NET_BH);
01202 }
01203 while (lp->tx_reap != lp->tx_head);
01204
01205 lp->tx_link = lp->tx_tail + 0x08;
01206
01207 return status;
01208 }
01209
01210
01211
01212
01213
01214
01215
01216 static void eexp_hw_txrestart(struct device *dev)
01217 {
01218 struct net_local *lp = (struct net_local *)dev->priv;
01219 unsigned short ioaddr = dev->base_addr;
01220
01221 lp->last_tx_restart = lp->tx_link;
01222 scb_wrcbl(dev, lp->tx_link);
01223 scb_command(dev, SCB_CUstart);
01224 outb(0,ioaddr+SIGNAL_CA);
01225
01226 {
01227 unsigned short boguscount=50,failcount=5;
01228 while (!scb_status(dev))
01229 {
01230 if (!--boguscount)
01231 {
01232 if (--failcount)
01233 {
01234 printk(KERN_WARNING "%s: CU start timed out, status %04x, cmd %04x\n", dev->name, scb_status(dev), scb_rdcmd(dev));
01235 scb_wrcbl(dev, lp->tx_link);
01236 scb_command(dev, SCB_CUstart);
01237 outb(0,ioaddr+SIGNAL_CA);
01238 boguscount = 100;
01239 }
01240 else
01241 {
01242 printk(KERN_WARNING "%s: Failed to restart CU, resetting board...\n",dev->name);
01243 eexp_hw_init586(dev);
012