0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #define DRV_NAME "3c515"
0026
0027 #define CORKSCREW 1
0028
0029
0030
0031
0032 static int rx_copybreak = 200;
0033
0034
0035 static const int mtu = 1500;
0036
0037
0038 static int max_interrupt_work = 20;
0039
0040
0041 #define AUTOMEDIA 1
0042
0043
0044
0045
0046
0047 #define VORTEX_BUS_MASTER
0048
0049
0050
0051 #define TX_RING_SIZE 16
0052 #define RX_RING_SIZE 16
0053 #define PKT_BUF_SZ 1536
0054
0055 #include <linux/module.h>
0056 #include <linux/isapnp.h>
0057 #include <linux/kernel.h>
0058 #include <linux/netdevice.h>
0059 #include <linux/string.h>
0060 #include <linux/errno.h>
0061 #include <linux/in.h>
0062 #include <linux/ioport.h>
0063 #include <linux/skbuff.h>
0064 #include <linux/etherdevice.h>
0065 #include <linux/interrupt.h>
0066 #include <linux/timer.h>
0067 #include <linux/ethtool.h>
0068 #include <linux/bitops.h>
0069
0070 #include <linux/uaccess.h>
0071 #include <asm/io.h>
0072 #include <asm/dma.h>
0073
0074 #define NEW_MULTICAST
0075 #include <linux/delay.h>
0076
0077 #define MAX_UNITS 8
0078
0079 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
0080 MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver");
0081 MODULE_LICENSE("GPL");
0082
0083
0084
0085 #define DRIVER_DEBUG 1
0086
0087
0088 static int rx_nocopy, rx_copy, queued_packet;
0089
0090
0091
0092 #define WAIT_TX_AVAIL 200
0093
0094
0095 #define TX_TIMEOUT ((4*HZ)/10)
0096
0097
0098
0099
0100 #define CORKSCREW_TOTAL_SIZE 0x20
0101
0102 #ifdef DRIVER_DEBUG
0103 static int corkscrew_debug = DRIVER_DEBUG;
0104 #else
0105 static int corkscrew_debug = 1;
0106 #endif
0107
0108 #define CORKSCREW_ID 10
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169 #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
0170 #define EL3_CMD 0x0e
0171 #define EL3_STATUS 0x0e
0172
0173
0174
0175
0176
0177
0178
0179 enum corkscrew_cmd {
0180 TotalReset = 0 << 11, SelectWindow = 1 << 11, StartCoax = 2 << 11,
0181 RxDisable = 3 << 11, RxEnable = 4 << 11, RxReset = 5 << 11,
0182 UpStall = 6 << 11, UpUnstall = (6 << 11) + 1, DownStall = (6 << 11) + 2,
0183 DownUnstall = (6 << 11) + 3, RxDiscard = 8 << 11, TxEnable = 9 << 11,
0184 TxDisable = 10 << 11, TxReset = 11 << 11, FakeIntr = 12 << 11,
0185 AckIntr = 13 << 11, SetIntrEnb = 14 << 11, SetStatusEnb = 15 << 11,
0186 SetRxFilter = 16 << 11, SetRxThreshold = 17 << 11,
0187 SetTxThreshold = 18 << 11, SetTxStart = 19 << 11, StartDMAUp = 20 << 11,
0188 StartDMADown = (20 << 11) + 1, StatsEnable = 21 << 11,
0189 StatsDisable = 22 << 11, StopCoax = 23 << 11,
0190 };
0191
0192
0193 enum RxFilter {
0194 RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8
0195 };
0196
0197
0198 enum corkscrew_status {
0199 IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
0200 TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
0201 IntReq = 0x0040, StatsFull = 0x0080,
0202 DMADone = 1 << 8, DownComplete = 1 << 9, UpComplete = 1 << 10,
0203 DMAInProgress = 1 << 11,
0204 CmdInProgress = 1 << 12,
0205 };
0206
0207
0208
0209 enum Window1 {
0210 TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14,
0211 RxStatus = 0x18, Timer = 0x1A, TxStatus = 0x1B,
0212 TxFree = 0x1C,
0213 };
0214 enum Window0 {
0215 Wn0IRQ = 0x08,
0216 #if defined(CORKSCREW)
0217 Wn0EepromCmd = 0x200A,
0218 Wn0EepromData = 0x200C,
0219 #else
0220 Wn0EepromCmd = 10,
0221 Wn0EepromData = 12,
0222 #endif
0223 };
0224 enum Win0_EEPROM_bits {
0225 EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0,
0226 EEPROM_EWENB = 0x30,
0227 EEPROM_EWDIS = 0x00,
0228 };
0229
0230
0231 enum eeprom_offset {
0232 PhysAddr01 = 0, PhysAddr23 = 1, PhysAddr45 = 2, ModelID = 3,
0233 EtherLink3ID = 7,
0234 };
0235
0236 enum Window3 {
0237 Wn3_Config = 0, Wn3_MAC_Ctrl = 6, Wn3_Options = 8,
0238 };
0239 enum wn3_config {
0240 Ram_size = 7,
0241 Ram_width = 8,
0242 Ram_speed = 0x30,
0243 Rom_size = 0xc0,
0244 Ram_split_shift = 16,
0245 Ram_split = 3 << Ram_split_shift,
0246 Xcvr_shift = 20,
0247 Xcvr = 7 << Xcvr_shift,
0248 Autoselect = 0x1000000,
0249 };
0250
0251 enum Window4 {
0252 Wn4_NetDiag = 6, Wn4_Media = 10,
0253 };
0254 enum Win4_Media_bits {
0255 Media_SQE = 0x0008,
0256 Media_10TP = 0x00C0,
0257 Media_Lnk = 0x0080,
0258 Media_LnkBeat = 0x0800,
0259 };
0260 enum Window7 {
0261 Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12,
0262 };
0263
0264
0265 enum MasterCtrl {
0266 PktStatus = 0x400, DownListPtr = 0x404, FragAddr = 0x408, FragLen =
0267 0x40c,
0268 TxFreeThreshold = 0x40f, UpPktStatus = 0x410, UpListPtr = 0x418,
0269 };
0270
0271
0272
0273
0274 struct boom_rx_desc {
0275 u32 next;
0276 s32 status;
0277 u32 addr;
0278 s32 length;
0279 };
0280
0281
0282 enum rx_desc_status {
0283 RxDComplete = 0x00008000, RxDError = 0x4000,
0284
0285 };
0286
0287 struct boom_tx_desc {
0288 u32 next;
0289 s32 status;
0290 u32 addr;
0291 s32 length;
0292 };
0293
0294 struct corkscrew_private {
0295 const char *product_name;
0296 struct list_head list;
0297 struct net_device *our_dev;
0298
0299 struct boom_rx_desc rx_ring[RX_RING_SIZE];
0300 struct boom_tx_desc tx_ring[TX_RING_SIZE];
0301
0302 struct sk_buff *rx_skbuff[RX_RING_SIZE];
0303 struct sk_buff *tx_skbuff[TX_RING_SIZE];
0304 unsigned int cur_rx, cur_tx;
0305 unsigned int dirty_rx, dirty_tx;
0306 struct sk_buff *tx_skb;
0307 struct timer_list timer;
0308 int capabilities ;
0309 int options;
0310 int last_rx_packets;
0311 unsigned int available_media:8,
0312 media_override:3,
0313 default_media:3,
0314 full_duplex:1, autoselect:1, bus_master:1,
0315 full_bus_master_tx:1, full_bus_master_rx:1,
0316 tx_full:1;
0317 spinlock_t lock;
0318 struct device *dev;
0319 };
0320
0321
0322
0323
0324 enum xcvr_types {
0325 XCVR_10baseT = 0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx,
0326 XCVR_100baseFx, XCVR_MII = 6, XCVR_Default = 8,
0327 };
0328
0329 static struct media_table {
0330 char *name;
0331 unsigned int media_bits:16,
0332 mask:8,
0333 next:8;
0334 short wait;
0335 } media_tbl[] = {
0336 { "10baseT", Media_10TP, 0x08, XCVR_10base2, (14 * HZ) / 10 },
0337 { "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1 * HZ) / 10},
0338 { "undefined", 0, 0x80, XCVR_10baseT, 10000},
0339 { "10base2", 0, 0x10, XCVR_AUI, (1 * HZ) / 10},
0340 { "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14 * HZ) / 10},
0341 { "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14 * HZ) / 10},
0342 { "MII", 0, 0x40, XCVR_10baseT, 3 * HZ},
0343 { "undefined", 0, 0x01, XCVR_10baseT, 10000},
0344 { "Default", 0, 0xFF, XCVR_10baseT, 10000},
0345 };
0346
0347 #ifdef __ISAPNP__
0348 static struct isapnp_device_id corkscrew_isapnp_adapters[] = {
0349 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
0350 ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5051),
0351 (long) "3Com Fast EtherLink ISA" },
0352 { }
0353 };
0354
0355 MODULE_DEVICE_TABLE(isapnp, corkscrew_isapnp_adapters);
0356
0357 static int nopnp;
0358 #endif
0359
0360 static struct net_device *corkscrew_scan(int unit);
0361 static int corkscrew_setup(struct net_device *dev, int ioaddr,
0362 struct pnp_dev *idev, int card_number);
0363 static int corkscrew_open(struct net_device *dev);
0364 static void corkscrew_timer(struct timer_list *t);
0365 static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
0366 struct net_device *dev);
0367 static int corkscrew_rx(struct net_device *dev);
0368 static void corkscrew_timeout(struct net_device *dev, unsigned int txqueue);
0369 static int boomerang_rx(struct net_device *dev);
0370 static irqreturn_t corkscrew_interrupt(int irq, void *dev_id);
0371 static int corkscrew_close(struct net_device *dev);
0372 static void update_stats(int addr, struct net_device *dev);
0373 static struct net_device_stats *corkscrew_get_stats(struct net_device *dev);
0374 static void set_rx_mode(struct net_device *dev);
0375 static const struct ethtool_ops netdev_ethtool_ops;
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392 static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1, };
0393
0394 #ifdef MODULE
0395 static int debug = -1;
0396
0397 module_param(debug, int, 0);
0398 module_param_array(options, int, NULL, 0);
0399 module_param(rx_copybreak, int, 0);
0400 module_param(max_interrupt_work, int, 0);
0401 MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
0402 MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering");
0403 MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames");
0404 MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt");
0405
0406
0407
0408 static LIST_HEAD(root_corkscrew_dev);
0409
0410 static int corkscrew_init_module(void)
0411 {
0412 int found = 0;
0413 if (debug >= 0)
0414 corkscrew_debug = debug;
0415 while (corkscrew_scan(-1))
0416 found++;
0417 return found ? 0 : -ENODEV;
0418 }
0419 module_init(corkscrew_init_module);
0420
0421 #else
0422 struct net_device *tc515_probe(int unit)
0423 {
0424 struct net_device *dev = corkscrew_scan(unit);
0425
0426 if (!dev)
0427 return ERR_PTR(-ENODEV);
0428
0429 return dev;
0430 }
0431 #endif
0432
0433 static int check_device(unsigned ioaddr)
0434 {
0435 int timer;
0436
0437 if (!request_region(ioaddr, CORKSCREW_TOTAL_SIZE, "3c515"))
0438 return 0;
0439
0440 if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0)) {
0441 release_region(ioaddr, CORKSCREW_TOTAL_SIZE);
0442 return 0;
0443 }
0444
0445 outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
0446
0447 for (timer = 4; timer >= 0; timer--) {
0448 udelay(162);
0449 if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
0450 break;
0451 }
0452 if (inw(ioaddr + Wn0EepromData) != 0x6d50) {
0453 release_region(ioaddr, CORKSCREW_TOTAL_SIZE);
0454 return 0;
0455 }
0456 return 1;
0457 }
0458
0459 static void cleanup_card(struct net_device *dev)
0460 {
0461 struct corkscrew_private *vp = netdev_priv(dev);
0462 list_del_init(&vp->list);
0463 if (dev->dma)
0464 free_dma(dev->dma);
0465 outw(TotalReset, dev->base_addr + EL3_CMD);
0466 release_region(dev->base_addr, CORKSCREW_TOTAL_SIZE);
0467 if (vp->dev)
0468 pnp_device_detach(to_pnp_dev(vp->dev));
0469 }
0470
0471 static struct net_device *corkscrew_scan(int unit)
0472 {
0473 struct net_device *dev;
0474 static int cards_found = 0;
0475 static int ioaddr;
0476 int err;
0477 #ifdef __ISAPNP__
0478 short i;
0479 static int pnp_cards;
0480 #endif
0481
0482 dev = alloc_etherdev(sizeof(struct corkscrew_private));
0483 if (!dev)
0484 return ERR_PTR(-ENOMEM);
0485
0486 if (unit >= 0) {
0487 sprintf(dev->name, "eth%d", unit);
0488 netdev_boot_setup_check(dev);
0489 }
0490
0491 #ifdef __ISAPNP__
0492 if(nopnp == 1)
0493 goto no_pnp;
0494 for(i=0; corkscrew_isapnp_adapters[i].vendor != 0; i++) {
0495 struct pnp_dev *idev = NULL;
0496 int irq;
0497 while((idev = pnp_find_dev(NULL,
0498 corkscrew_isapnp_adapters[i].vendor,
0499 corkscrew_isapnp_adapters[i].function,
0500 idev))) {
0501
0502 if (pnp_device_attach(idev) < 0)
0503 continue;
0504 if (pnp_activate_dev(idev) < 0) {
0505 pr_warn("pnp activate failed (out of resources?)\n");
0506 pnp_device_detach(idev);
0507 continue;
0508 }
0509 if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) {
0510 pnp_device_detach(idev);
0511 continue;
0512 }
0513 ioaddr = pnp_port_start(idev, 0);
0514 irq = pnp_irq(idev, 0);
0515 if (!check_device(ioaddr)) {
0516 pnp_device_detach(idev);
0517 continue;
0518 }
0519 if(corkscrew_debug)
0520 pr_debug("ISAPNP reports %s at i/o 0x%x, irq %d\n",
0521 (char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
0522 pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
0523 inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
0524
0525 SET_NETDEV_DEV(dev, &idev->dev);
0526 pnp_cards++;
0527 err = corkscrew_setup(dev, ioaddr, idev, cards_found++);
0528 if (!err)
0529 return dev;
0530 cleanup_card(dev);
0531 }
0532 }
0533 no_pnp:
0534 #endif
0535
0536
0537 for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) {
0538 if (!check_device(ioaddr))
0539 continue;
0540
0541 pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
0542 inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
0543 err = corkscrew_setup(dev, ioaddr, NULL, cards_found++);
0544 if (!err)
0545 return dev;
0546 cleanup_card(dev);
0547 }
0548 free_netdev(dev);
0549 return NULL;
0550 }
0551
0552
0553 static const struct net_device_ops netdev_ops = {
0554 .ndo_open = corkscrew_open,
0555 .ndo_stop = corkscrew_close,
0556 .ndo_start_xmit = corkscrew_start_xmit,
0557 .ndo_tx_timeout = corkscrew_timeout,
0558 .ndo_get_stats = corkscrew_get_stats,
0559 .ndo_set_rx_mode = set_rx_mode,
0560 .ndo_set_mac_address = eth_mac_addr,
0561 .ndo_validate_addr = eth_validate_addr,
0562 };
0563
0564
0565 static int corkscrew_setup(struct net_device *dev, int ioaddr,
0566 struct pnp_dev *idev, int card_number)
0567 {
0568 struct corkscrew_private *vp = netdev_priv(dev);
0569 unsigned int eeprom[0x40], checksum = 0;
0570 __be16 addr[ETH_ALEN / 2];
0571 int i;
0572 int irq;
0573
0574 #ifdef __ISAPNP__
0575 if (idev) {
0576 irq = pnp_irq(idev, 0);
0577 vp->dev = &idev->dev;
0578 } else {
0579 irq = inw(ioaddr + 0x2002) & 15;
0580 }
0581 #else
0582 irq = inw(ioaddr + 0x2002) & 15;
0583 #endif
0584
0585 dev->base_addr = ioaddr;
0586 dev->irq = irq;
0587 dev->dma = inw(ioaddr + 0x2000) & 7;
0588 vp->product_name = "3c515";
0589 vp->options = dev->mem_start;
0590 vp->our_dev = dev;
0591
0592 if (!vp->options) {
0593 if (card_number >= MAX_UNITS)
0594 vp->options = -1;
0595 else
0596 vp->options = options[card_number];
0597 }
0598
0599 if (vp->options >= 0) {
0600 vp->media_override = vp->options & 7;
0601 if (vp->media_override == 2)
0602 vp->media_override = 0;
0603 vp->full_duplex = (vp->options & 8) ? 1 : 0;
0604 vp->bus_master = (vp->options & 16) ? 1 : 0;
0605 } else {
0606 vp->media_override = 7;
0607 vp->full_duplex = 0;
0608 vp->bus_master = 0;
0609 }
0610 #ifdef MODULE
0611 list_add(&vp->list, &root_corkscrew_dev);
0612 #endif
0613
0614 pr_info("%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
0615
0616 spin_lock_init(&vp->lock);
0617
0618 timer_setup(&vp->timer, corkscrew_timer, 0);
0619
0620
0621 EL3WINDOW(0);
0622 for (i = 0; i < 0x18; i++) {
0623 int timer;
0624 outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
0625
0626 for (timer = 4; timer >= 0; timer--) {
0627 udelay(162);
0628 if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
0629 break;
0630 }
0631 eeprom[i] = inw(ioaddr + Wn0EepromData);
0632 checksum ^= eeprom[i];
0633 if (i < 3)
0634 addr[i] = htons(eeprom[i]);
0635 }
0636 eth_hw_addr_set(dev, (u8 *)addr);
0637 checksum = (checksum ^ (checksum >> 8)) & 0xff;
0638 if (checksum != 0x00)
0639 pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
0640 pr_cont(" %pM", dev->dev_addr);
0641 if (eeprom[16] == 0x11c7) {
0642 if (request_dma(dev->dma, "3c515")) {
0643 pr_cont(", DMA %d allocation failed", dev->dma);
0644 dev->dma = 0;
0645 } else
0646 pr_cont(", DMA %d", dev->dma);
0647 }
0648 pr_cont(", IRQ %d\n", dev->irq);
0649
0650 if (corkscrew_debug && (dev->irq <= 0 || dev->irq > 15))
0651 pr_warn(" *** Warning: this IRQ is unlikely to work! ***\n");
0652
0653 {
0654 static const char * const ram_split[] = {
0655 "5:3", "3:1", "1:1", "3:5"
0656 };
0657 __u32 config;
0658 EL3WINDOW(3);
0659 vp->available_media = inw(ioaddr + Wn3_Options);
0660 config = inl(ioaddr + Wn3_Config);
0661 if (corkscrew_debug > 1)
0662 pr_info(" Internal config register is %4.4x, transceivers %#x.\n",
0663 config, inw(ioaddr + Wn3_Options));
0664 pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
0665 8 << config & Ram_size,
0666 config & Ram_width ? "word" : "byte",
0667 ram_split[(config & Ram_split) >> Ram_split_shift],
0668 config & Autoselect ? "autoselect/" : "",
0669 media_tbl[(config & Xcvr) >> Xcvr_shift].name);
0670 vp->default_media = (config & Xcvr) >> Xcvr_shift;
0671 vp->autoselect = config & Autoselect ? 1 : 0;
0672 dev->if_port = vp->default_media;
0673 }
0674 if (vp->media_override != 7) {
0675 pr_info(" Media override to transceiver type %d (%s).\n",
0676 vp->media_override,
0677 media_tbl[vp->media_override].name);
0678 dev->if_port = vp->media_override;
0679 }
0680
0681 vp->capabilities = eeprom[16];
0682 vp->full_bus_master_tx = (vp->capabilities & 0x20) ? 1 : 0;
0683
0684
0685 vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
0686
0687
0688 dev->netdev_ops = &netdev_ops;
0689 dev->watchdog_timeo = (400 * HZ) / 1000;
0690 dev->ethtool_ops = &netdev_ethtool_ops;
0691
0692 return register_netdev(dev);
0693 }
0694
0695
0696 static int corkscrew_open(struct net_device *dev)
0697 {
0698 int ioaddr = dev->base_addr;
0699 struct corkscrew_private *vp = netdev_priv(dev);
0700 bool armtimer = false;
0701 __u32 config;
0702 int i;
0703
0704
0705 EL3WINDOW(3);
0706 if (vp->full_duplex)
0707 outb(0x20, ioaddr + Wn3_MAC_Ctrl);
0708 config = inl(ioaddr + Wn3_Config);
0709
0710 if (vp->media_override != 7) {
0711 if (corkscrew_debug > 1)
0712 pr_info("%s: Media override to transceiver %d (%s).\n",
0713 dev->name, vp->media_override,
0714 media_tbl[vp->media_override].name);
0715 dev->if_port = vp->media_override;
0716 } else if (vp->autoselect) {
0717
0718 dev->if_port = 4;
0719 while (!(vp->available_media & media_tbl[dev->if_port].mask))
0720 dev->if_port = media_tbl[dev->if_port].next;
0721
0722 if (corkscrew_debug > 1)
0723 pr_debug("%s: Initial media type %s.\n",
0724 dev->name, media_tbl[dev->if_port].name);
0725 armtimer = true;
0726 } else
0727 dev->if_port = vp->default_media;
0728
0729 config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift);
0730 outl(config, ioaddr + Wn3_Config);
0731
0732 if (corkscrew_debug > 1) {
0733 pr_debug("%s: corkscrew_open() InternalConfig %8.8x.\n",
0734 dev->name, config);
0735 }
0736
0737 outw(TxReset, ioaddr + EL3_CMD);
0738 for (i = 20; i >= 0; i--)
0739 if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
0740 break;
0741
0742 outw(RxReset, ioaddr + EL3_CMD);
0743
0744 for (i = 20; i >= 0; i--)
0745 if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
0746 break;
0747
0748 outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
0749
0750
0751 if (vp->capabilities == 0x11c7) {
0752
0753 if (dev->irq == 0 ||
0754 dev->dma == 0 ||
0755 request_irq(dev->irq, corkscrew_interrupt, 0,
0756 vp->product_name, dev))
0757 return -EAGAIN;
0758 enable_dma(dev->dma);
0759 set_dma_mode(dev->dma, DMA_MODE_CASCADE);
0760 } else if (request_irq(dev->irq, corkscrew_interrupt, IRQF_SHARED,
0761 vp->product_name, dev)) {
0762 return -EAGAIN;
0763 }
0764
0765 if (armtimer)
0766 mod_timer(&vp->timer, jiffies + media_tbl[dev->if_port].wait);
0767
0768 if (corkscrew_debug > 1) {
0769 EL3WINDOW(4);
0770 pr_debug("%s: corkscrew_open() irq %d media status %4.4x.\n",
0771 dev->name, dev->irq, inw(ioaddr + Wn4_Media));
0772 }
0773
0774
0775 EL3WINDOW(2);
0776 for (i = 0; i < 6; i++)
0777 outb(dev->dev_addr[i], ioaddr + i);
0778 for (; i < 12; i += 2)
0779 outw(0, ioaddr + i);
0780
0781 if (dev->if_port == 3)
0782
0783 outw(StartCoax, ioaddr + EL3_CMD);
0784 EL3WINDOW(4);
0785 outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP | Media_SQE)) |
0786 media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
0787
0788
0789 outw(StatsDisable, ioaddr + EL3_CMD);
0790 EL3WINDOW(6);
0791 for (i = 0; i < 10; i++)
0792 inb(ioaddr + i);
0793 inw(ioaddr + 10);
0794 inw(ioaddr + 12);
0795
0796 EL3WINDOW(4);
0797 inb(ioaddr + 12);
0798
0799 outw(0x0040, ioaddr + Wn4_NetDiag);
0800
0801
0802 EL3WINDOW(7);
0803
0804 if (vp->full_bus_master_rx) {
0805 vp->cur_rx = vp->dirty_rx = 0;
0806 if (corkscrew_debug > 2)
0807 pr_debug("%s: Filling in the Rx ring.\n", dev->name);
0808 for (i = 0; i < RX_RING_SIZE; i++) {
0809 struct sk_buff *skb;
0810 if (i < (RX_RING_SIZE - 1))
0811 vp->rx_ring[i].next =
0812 isa_virt_to_bus(&vp->rx_ring[i + 1]);
0813 else
0814 vp->rx_ring[i].next = 0;
0815 vp->rx_ring[i].status = 0;
0816 vp->rx_ring[i].length = PKT_BUF_SZ | 0x80000000;
0817 skb = netdev_alloc_skb(dev, PKT_BUF_SZ);
0818 vp->rx_skbuff[i] = skb;
0819 if (skb == NULL)
0820 break;
0821 skb_reserve(skb, 2);
0822 vp->rx_ring[i].addr = isa_virt_to_bus(skb->data);
0823 }
0824 if (i != 0)
0825 vp->rx_ring[i - 1].next =
0826 isa_virt_to_bus(&vp->rx_ring[0]);
0827 outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
0828 }
0829 if (vp->full_bus_master_tx) {
0830 vp->cur_tx = vp->dirty_tx = 0;
0831 outb(PKT_BUF_SZ >> 8, ioaddr + TxFreeThreshold);
0832
0833 for (i = 0; i < TX_RING_SIZE; i++)
0834 vp->tx_skbuff[i] = NULL;
0835 outl(0, ioaddr + DownListPtr);
0836 }
0837
0838 set_rx_mode(dev);
0839 outw(StatsEnable, ioaddr + EL3_CMD);
0840
0841 netif_start_queue(dev);
0842
0843 outw(RxEnable, ioaddr + EL3_CMD);
0844 outw(TxEnable, ioaddr + EL3_CMD);
0845
0846 outw(SetStatusEnb | AdapterFailure | IntReq | StatsFull |
0847 (vp->full_bus_master_tx ? DownComplete : TxAvailable) |
0848 (vp->full_bus_master_rx ? UpComplete : RxComplete) |
0849 (vp->bus_master ? DMADone : 0), ioaddr + EL3_CMD);
0850
0851 outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
0852 ioaddr + EL3_CMD);
0853 outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull
0854 | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete,
0855 ioaddr + EL3_CMD);
0856
0857 return 0;
0858 }
0859
0860 static void corkscrew_timer(struct timer_list *t)
0861 {
0862 #ifdef AUTOMEDIA
0863 struct corkscrew_private *vp = from_timer(vp, t, timer);
0864 struct net_device *dev = vp->our_dev;
0865 int ioaddr = dev->base_addr;
0866 unsigned long flags;
0867 int ok = 0;
0868
0869 if (corkscrew_debug > 1)
0870 pr_debug("%s: Media selection timer tick happened, %s.\n",
0871 dev->name, media_tbl[dev->if_port].name);
0872
0873 spin_lock_irqsave(&vp->lock, flags);
0874
0875 {
0876 int old_window = inw(ioaddr + EL3_CMD) >> 13;
0877 int media_status;
0878 EL3WINDOW(4);
0879 media_status = inw(ioaddr + Wn4_Media);
0880 switch (dev->if_port) {
0881 case 0:
0882 case 4:
0883 case 5:
0884 if (media_status & Media_LnkBeat) {
0885 ok = 1;
0886 if (corkscrew_debug > 1)
0887 pr_debug("%s: Media %s has link beat, %x.\n",
0888 dev->name,
0889 media_tbl[dev->if_port].name,
0890 media_status);
0891 } else if (corkscrew_debug > 1)
0892 pr_debug("%s: Media %s is has no link beat, %x.\n",
0893 dev->name,
0894 media_tbl[dev->if_port].name,
0895 media_status);
0896
0897 break;
0898 default:
0899 if (corkscrew_debug > 1)
0900 pr_debug("%s: Media %s is has no indication, %x.\n",
0901 dev->name,
0902 media_tbl[dev->if_port].name,
0903 media_status);
0904 ok = 1;
0905 }
0906 if (!ok) {
0907 __u32 config;
0908
0909 do {
0910 dev->if_port =
0911 media_tbl[dev->if_port].next;
0912 }
0913 while (!(vp->available_media & media_tbl[dev->if_port].mask));
0914
0915 if (dev->if_port == 8) {
0916 dev->if_port = vp->default_media;
0917 if (corkscrew_debug > 1)
0918 pr_debug("%s: Media selection failing, using default %s port.\n",
0919 dev->name,
0920 media_tbl[dev->if_port].name);
0921 } else {
0922 if (corkscrew_debug > 1)
0923 pr_debug("%s: Media selection failed, now trying %s port.\n",
0924 dev->name,
0925 media_tbl[dev->if_port].name);
0926 vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
0927 add_timer(&vp->timer);
0928 }
0929 outw((media_status & ~(Media_10TP | Media_SQE)) |
0930 media_tbl[dev->if_port].media_bits,
0931 ioaddr + Wn4_Media);
0932
0933 EL3WINDOW(3);
0934 config = inl(ioaddr + Wn3_Config);
0935 config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift);
0936 outl(config, ioaddr + Wn3_Config);
0937
0938 outw(dev->if_port == 3 ? StartCoax : StopCoax,
0939 ioaddr + EL3_CMD);
0940 }
0941 EL3WINDOW(old_window);
0942 }
0943
0944 spin_unlock_irqrestore(&vp->lock, flags);
0945 if (corkscrew_debug > 1)
0946 pr_debug("%s: Media selection timer finished, %s.\n",
0947 dev->name, media_tbl[dev->if_port].name);
0948
0949 #endif
0950 }
0951
0952 static void corkscrew_timeout(struct net_device *dev, unsigned int txqueue)
0953 {
0954 int i;
0955 struct corkscrew_private *vp = netdev_priv(dev);
0956 int ioaddr = dev->base_addr;
0957
0958 pr_warn("%s: transmit timed out, tx_status %2.2x status %4.4x\n",
0959 dev->name, inb(ioaddr + TxStatus),
0960 inw(ioaddr + EL3_STATUS));
0961
0962 if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
0963 pr_warn("%s: Transmitter encountered 16 collisions -- network cable problem?\n",
0964 dev->name);
0965 #ifndef final_version
0966 pr_debug(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
0967 vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx,
0968 vp->cur_tx);
0969 pr_debug(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
0970 &vp->tx_ring[0]);
0971 for (i = 0; i < TX_RING_SIZE; i++) {
0972 pr_debug(" %d: %p length %8.8x status %8.8x\n", i,
0973 &vp->tx_ring[i],
0974 vp->tx_ring[i].length, vp->tx_ring[i].status);
0975 }
0976 #endif
0977
0978 outw(TxReset, ioaddr + EL3_CMD);
0979 for (i = 20; i >= 0; i--)
0980 if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
0981 break;
0982 outw(TxEnable, ioaddr + EL3_CMD);
0983 netif_trans_update(dev);
0984 dev->stats.tx_errors++;
0985 dev->stats.tx_dropped++;
0986 netif_wake_queue(dev);
0987 }
0988
0989 static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
0990 struct net_device *dev)
0991 {
0992 struct corkscrew_private *vp = netdev_priv(dev);
0993 int ioaddr = dev->base_addr;
0994
0995
0996
0997 netif_stop_queue(dev);
0998
0999 if (vp->full_bus_master_tx) {
1000
1001 int entry = vp->cur_tx % TX_RING_SIZE;
1002 struct boom_tx_desc *prev_entry;
1003 unsigned long flags;
1004 int i;
1005
1006 if (vp->tx_full)
1007 return NETDEV_TX_BUSY;
1008 if (vp->cur_tx != 0)
1009 prev_entry = &vp->tx_ring[(vp->cur_tx - 1) % TX_RING_SIZE];
1010 else
1011 prev_entry = NULL;
1012 if (corkscrew_debug > 3)
1013 pr_debug("%s: Trying to send a packet, Tx index %d.\n",
1014 dev->name, vp->cur_tx);
1015
1016 vp->tx_skbuff[entry] = skb;
1017 vp->tx_ring[entry].next = 0;
1018 vp->tx_ring[entry].addr = isa_virt_to_bus(skb->data);
1019 vp->tx_ring[entry].length = skb->len | 0x80000000;
1020 vp->tx_ring[entry].status = skb->len | 0x80000000;
1021
1022 spin_lock_irqsave(&vp->lock, flags);
1023 outw(DownStall, ioaddr + EL3_CMD);
1024
1025 for (i = 20; i >= 0; i--)
1026 if ((inw(ioaddr + EL3_STATUS) & CmdInProgress) == 0)
1027 break;
1028 if (prev_entry)
1029 prev_entry->next = isa_virt_to_bus(&vp->tx_ring[entry]);
1030 if (inl(ioaddr + DownListPtr) == 0) {
1031 outl(isa_virt_to_bus(&vp->tx_ring[entry]),
1032 ioaddr + DownListPtr);
1033 queued_packet++;
1034 }
1035 outw(DownUnstall, ioaddr + EL3_CMD);
1036 spin_unlock_irqrestore(&vp->lock, flags);
1037
1038 vp->cur_tx++;
1039 if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1)
1040 vp->tx_full = 1;
1041 else {
1042 if (prev_entry)
1043 prev_entry->status &= ~0x80000000;
1044 netif_wake_queue(dev);
1045 }
1046 return NETDEV_TX_OK;
1047 }
1048
1049 outl(skb->len, ioaddr + TX_FIFO);
1050 dev->stats.tx_bytes += skb->len;
1051 #ifdef VORTEX_BUS_MASTER
1052 if (vp->bus_master) {
1053
1054 outl(isa_virt_to_bus(skb->data), ioaddr + Wn7_MasterAddr);
1055 outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
1056 vp->tx_skb = skb;
1057 outw(StartDMADown, ioaddr + EL3_CMD);
1058
1059 } else {
1060
1061 outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
1062 dev_kfree_skb(skb);
1063 if (inw(ioaddr + TxFree) > 1536) {
1064 netif_wake_queue(dev);
1065 } else
1066
1067 outw(SetTxThreshold + (1536 >> 2),
1068 ioaddr + EL3_CMD);
1069 }
1070 #else
1071
1072 outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
1073 dev_kfree_skb(skb);
1074 if (inw(ioaddr + TxFree) > 1536) {
1075 netif_wake_queue(dev);
1076 } else
1077
1078 outw(SetTxThreshold + (1536 >> 2), ioaddr + EL3_CMD);
1079 #endif
1080
1081
1082
1083 {
1084 short tx_status;
1085 int i = 4;
1086
1087 while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
1088 if (tx_status & 0x3C) {
1089 if (corkscrew_debug > 2)
1090 pr_debug("%s: Tx error, status %2.2x.\n",
1091 dev->name, tx_status);
1092 if (tx_status & 0x04)
1093 dev->stats.tx_fifo_errors++;
1094 if (tx_status & 0x38)
1095 dev->stats.tx_aborted_errors++;
1096 if (tx_status & 0x30) {
1097 int j;
1098 outw(TxReset, ioaddr + EL3_CMD);
1099 for (j = 20; j >= 0; j--)
1100 if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
1101 break;
1102 }
1103 outw(TxEnable, ioaddr + EL3_CMD);
1104 }
1105 outb(0x00, ioaddr + TxStatus);
1106 }
1107 }
1108 return NETDEV_TX_OK;
1109 }
1110
1111
1112
1113
1114 static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
1115 {
1116
1117 struct net_device *dev = dev_id;
1118 struct corkscrew_private *lp = netdev_priv(dev);
1119 int ioaddr, status;
1120 int latency;
1121 int i = max_interrupt_work;
1122
1123 ioaddr = dev->base_addr;
1124 latency = inb(ioaddr + Timer);
1125
1126 spin_lock(&lp->lock);
1127
1128 status = inw(ioaddr + EL3_STATUS);
1129
1130 if (corkscrew_debug > 4)
1131 pr_debug("%s: interrupt, status %4.4x, timer %d.\n",
1132 dev->name, status, latency);
1133 if ((status & 0xE000) != 0xE000) {
1134 static int donedidthis;
1135
1136
1137
1138 if (donedidthis++ > 100) {
1139 pr_err("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
1140 dev->name, status, netif_running(dev));
1141 free_irq(dev->irq, dev);
1142 dev->irq = -1;
1143 }
1144 }
1145
1146 do {
1147 if (corkscrew_debug > 5)
1148 pr_debug("%s: In interrupt loop, status %4.4x.\n",
1149 dev->name, status);
1150 if (status & RxComplete)
1151 corkscrew_rx(dev);
1152
1153 if (status & TxAvailable) {
1154 if (corkscrew_debug > 5)
1155 pr_debug(" TX room bit was handled.\n");
1156
1157 outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
1158 netif_wake_queue(dev);
1159 }
1160 if (status & DownComplete) {
1161 unsigned int dirty_tx = lp->dirty_tx;
1162
1163 while (lp->cur_tx - dirty_tx > 0) {
1164 int entry = dirty_tx % TX_RING_SIZE;
1165 if (inl(ioaddr + DownListPtr) == isa_virt_to_bus(&lp->tx_ring[entry]))
1166 break;
1167 if (lp->tx_skbuff[entry]) {
1168 dev_consume_skb_irq(lp->tx_skbuff[entry]);
1169 lp->tx_skbuff[entry] = NULL;
1170 }
1171 dirty_tx++;
1172 }
1173 lp->dirty_tx = dirty_tx;
1174 outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
1175 if (lp->tx_full && (lp->cur_tx - dirty_tx <= TX_RING_SIZE - 1)) {
1176 lp->tx_full = 0;
1177 netif_wake_queue(dev);
1178 }
1179 }
1180 #ifdef VORTEX_BUS_MASTER
1181 if (status & DMADone) {
1182 outw(0x1000, ioaddr + Wn7_MasterStatus);
1183 dev_consume_skb_irq(lp->tx_skb);
1184 netif_wake_queue(dev);
1185 }
1186 #endif
1187 if (status & UpComplete) {
1188 boomerang_rx(dev);
1189 outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
1190 }
1191 if (status & (AdapterFailure | RxEarly | StatsFull)) {
1192
1193 if (status & RxEarly) {
1194 corkscrew_rx(dev);
1195 outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
1196 }
1197 if (status & StatsFull) {
1198 static int DoneDidThat;
1199 if (corkscrew_debug > 4)
1200 pr_debug("%s: Updating stats.\n", dev->name);
1201 update_stats(ioaddr, dev);
1202
1203
1204 if (DoneDidThat == 0 && inw(ioaddr + EL3_STATUS) & StatsFull) {
1205 int win, reg;
1206 pr_notice("%s: Updating stats failed, disabling stats as an interrupt source.\n",
1207 dev->name);
1208 for (win = 0; win < 8; win++) {
1209 EL3WINDOW(win);
1210 pr_notice("Vortex window %d:", win);
1211 for (reg = 0; reg < 16; reg++)
1212 pr_cont(" %2.2x", inb(ioaddr + reg));
1213 pr_cont("\n");
1214 }
1215 EL3WINDOW(7);
1216 outw(SetIntrEnb | TxAvailable |
1217 RxComplete | AdapterFailure |
1218 UpComplete | DownComplete |
1219 TxComplete, ioaddr + EL3_CMD);
1220 DoneDidThat++;
1221 }
1222 }
1223 if (status & AdapterFailure) {
1224
1225 outw(RxReset, ioaddr + EL3_CMD);
1226
1227 set_rx_mode(dev);
1228 outw(RxEnable, ioaddr + EL3_CMD);
1229 outw(AckIntr | AdapterFailure,
1230 ioaddr + EL3_CMD);
1231 }
1232 }
1233
1234 if (--i < 0) {
1235 pr_err("%s: Too much work in interrupt, status %4.4x. Disabling functions (%4.4x).\n",
1236 dev->name, status, SetStatusEnb | ((~status) & 0x7FE));
1237
1238 outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
1239 outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
1240 break;
1241 }
1242
1243 outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
1244
1245 } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
1246
1247 spin_unlock(&lp->lock);
1248
1249 if (corkscrew_debug > 4)
1250 pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
1251 return IRQ_HANDLED;
1252 }
1253
1254 static int corkscrew_rx(struct net_device *dev)
1255 {
1256 int ioaddr = dev->base_addr;
1257 int i;
1258 short rx_status;
1259
1260 if (corkscrew_debug > 5)
1261 pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
1262 inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
1263 while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
1264 if (rx_status & 0x4000) {
1265 unsigned char rx_error = inb(ioaddr + RxErrors);
1266 if (corkscrew_debug > 2)
1267 pr_debug(" Rx error: status %2.2x.\n",
1268 rx_error);
1269 dev->stats.rx_errors++;
1270 if (rx_error & 0x01)
1271 dev->stats.rx_over_errors++;
1272 if (rx_error & 0x02)
1273 dev->stats.rx_length_errors++;
1274 if (rx_error & 0x04)
1275 dev->stats.rx_frame_errors++;
1276 if (rx_error & 0x08)
1277 dev->stats.rx_crc_errors++;
1278 if (rx_error & 0x10)
1279 dev->stats.rx_length_errors++;
1280 } else {
1281
1282 short pkt_len = rx_status & 0x1fff;
1283 struct sk_buff *skb;
1284
1285 skb = netdev_alloc_skb(dev, pkt_len + 5 + 2);
1286 if (corkscrew_debug > 4)
1287 pr_debug("Receiving packet size %d status %4.4x.\n",
1288 pkt_len, rx_status);
1289 if (skb != NULL) {
1290 skb_reserve(skb, 2);
1291
1292 insl(ioaddr + RX_FIFO,
1293 skb_put(skb, pkt_len),
1294 (pkt_len + 3) >> 2);
1295 outw(RxDiscard, ioaddr + EL3_CMD);
1296 skb->protocol = eth_type_trans(skb, dev);
1297 netif_rx(skb);
1298 dev->stats.rx_packets++;
1299 dev->stats.rx_bytes += pkt_len;
1300
1301 for (i = 200; i >= 0; i--)
1302 if (! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
1303 break;
1304 continue;
1305 } else if (corkscrew_debug)
1306 pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
1307 }
1308 outw(RxDiscard, ioaddr + EL3_CMD);
1309 dev->stats.rx_dropped++;
1310
1311 for (i = 200; i >= 0; i--)
1312 if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
1313 break;
1314 }
1315 return 0;
1316 }
1317
1318 static int boomerang_rx(struct net_device *dev)
1319 {
1320 struct corkscrew_private *vp = netdev_priv(dev);
1321 int entry = vp->cur_rx % RX_RING_SIZE;
1322 int ioaddr = dev->base_addr;
1323 int rx_status;
1324
1325 if (corkscrew_debug > 5)
1326 pr_debug(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
1327 inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
1328 while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
1329 if (rx_status & RxDError) {
1330 unsigned char rx_error = rx_status >> 16;
1331 if (corkscrew_debug > 2)
1332 pr_debug(" Rx error: status %2.2x.\n",
1333 rx_error);
1334 dev->stats.rx_errors++;
1335 if (rx_error & 0x01)
1336 dev->stats.rx_over_errors++;
1337 if (rx_error & 0x02)
1338 dev->stats.rx_length_errors++;
1339 if (rx_error & 0x04)
1340 dev->stats.rx_frame_errors++;
1341 if (rx_error & 0x08)
1342 dev->stats.rx_crc_errors++;
1343 if (rx_error & 0x10)
1344 dev->stats.rx_length_errors++;
1345 } else {
1346
1347 short pkt_len = rx_status & 0x1fff;
1348 struct sk_buff *skb;
1349
1350 dev->stats.rx_bytes += pkt_len;
1351 if (corkscrew_debug > 4)
1352 pr_debug("Receiving packet size %d status %4.4x.\n",
1353 pkt_len, rx_status);
1354
1355
1356
1357 if (pkt_len < rx_copybreak &&
1358 (skb = netdev_alloc_skb(dev, pkt_len + 4)) != NULL) {
1359 skb_reserve(skb, 2);
1360
1361 skb_put_data(skb,
1362 isa_bus_to_virt(vp->rx_ring[entry].addr),
1363 pkt_len);
1364 rx_copy++;
1365 } else {
1366 void *temp;
1367
1368 skb = vp->rx_skbuff[entry];
1369 vp->rx_skbuff[entry] = NULL;
1370 temp = skb_put(skb, pkt_len);
1371
1372 if (isa_bus_to_virt(vp->rx_ring[entry].addr) != temp)
1373 pr_warn("%s: Warning -- the skbuff addresses do not match in boomerang_rx: %p vs. %p / %p\n",
1374 dev->name,
1375 isa_bus_to_virt(vp->rx_ring[entry].addr),
1376 skb->head, temp);
1377 rx_nocopy++;
1378 }
1379 skb->protocol = eth_type_trans(skb, dev);
1380 netif_rx(skb);
1381 dev->stats.rx_packets++;
1382 }
1383 entry = (++vp->cur_rx) % RX_RING_SIZE;
1384 }
1385
1386 for (; vp->cur_rx - vp->dirty_rx > 0; vp->dirty_rx++) {
1387 struct sk_buff *skb;
1388 entry = vp->dirty_rx % RX_RING_SIZE;
1389 if (vp->rx_skbuff[entry] == NULL) {
1390 skb = netdev_alloc_skb(dev, PKT_BUF_SZ);
1391 if (skb == NULL)
1392 break;
1393 skb_reserve(skb, 2);
1394 vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data);
1395 vp->rx_skbuff[entry] = skb;
1396 }
1397 vp->rx_ring[entry].status = 0;
1398 }
1399 return 0;
1400 }
1401
1402 static int corkscrew_close(struct net_device *dev)
1403 {
1404 struct corkscrew_private *vp = netdev_priv(dev);
1405 int ioaddr = dev->base_addr;
1406 int i;
1407
1408 netif_stop_queue(dev);
1409
1410 if (corkscrew_debug > 1) {
1411 pr_debug("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
1412 dev->name, inw(ioaddr + EL3_STATUS),
1413 inb(ioaddr + TxStatus));
1414 pr_debug("%s: corkscrew close stats: rx_nocopy %d rx_copy %d tx_queued %d.\n",
1415 dev->name, rx_nocopy, rx_copy, queued_packet);
1416 }
1417
1418 del_timer_sync(&vp->timer);
1419
1420
1421 outw(StatsDisable, ioaddr + EL3_CMD);
1422
1423
1424 outw(RxDisable, ioaddr + EL3_CMD);
1425 outw(TxDisable, ioaddr + EL3_CMD);
1426
1427 if (dev->if_port == XCVR_10base2)
1428
1429 outw(StopCoax, ioaddr + EL3_CMD);
1430
1431 free_irq(dev->irq, dev);
1432
1433 outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
1434
1435 update_stats(ioaddr, dev);
1436 if (vp->full_bus_master_rx) {
1437 outl(0, ioaddr + UpListPtr);
1438 for (i = 0; i < RX_RING_SIZE; i++)
1439 if (vp->rx_skbuff[i]) {
1440 dev_kfree_skb(vp->rx_skbuff[i]);
1441 vp->rx_skbuff[i] = NULL;
1442 }
1443 }
1444 if (vp->full_bus_master_tx) {
1445 outl(0, ioaddr + DownListPtr);
1446 for (i = 0; i < TX_RING_SIZE; i++)
1447 if (vp->tx_skbuff[i]) {
1448 dev_kfree_skb(vp->tx_skbuff[i]);
1449 vp->tx_skbuff[i] = NULL;
1450 }
1451 }
1452
1453 return 0;
1454 }
1455
1456 static struct net_device_stats *corkscrew_get_stats(struct net_device *dev)
1457 {
1458 struct corkscrew_private *vp = netdev_priv(dev);
1459 unsigned long flags;
1460
1461 if (netif_running(dev)) {
1462 spin_lock_irqsave(&vp->lock, flags);
1463 update_stats(dev->base_addr, dev);
1464 spin_unlock_irqrestore(&vp->lock, flags);
1465 }
1466 return &dev->stats;
1467 }
1468
1469
1470
1471
1472
1473
1474
1475
1476 static void update_stats(int ioaddr, struct net_device *dev)
1477 {
1478
1479
1480 EL3WINDOW(6);
1481 dev->stats.tx_carrier_errors += inb(ioaddr + 0);
1482 dev->stats.tx_heartbeat_errors += inb(ioaddr + 1);
1483 inb(ioaddr + 2);
1484 dev->stats.collisions += inb(ioaddr + 3);
1485 dev->stats.tx_window_errors += inb(ioaddr + 4);
1486 dev->stats.rx_fifo_errors += inb(ioaddr + 5);
1487 dev->stats.tx_packets += inb(ioaddr + 6);
1488 dev->stats.tx_packets += (inb(ioaddr + 9) & 0x30) << 4;
1489 inb(ioaddr + 7);
1490
1491 inb(ioaddr + 8);
1492
1493
1494
1495 inw(ioaddr + 10);
1496 inw(ioaddr + 12);
1497
1498 EL3WINDOW(4);
1499 inb(ioaddr + 12);
1500
1501
1502 EL3WINDOW(7);
1503 }
1504
1505
1506
1507
1508
1509 static void set_rx_mode(struct net_device *dev)
1510 {
1511 int ioaddr = dev->base_addr;
1512 unsigned short new_mode;
1513
1514 if (dev->flags & IFF_PROMISC) {
1515 if (corkscrew_debug > 3)
1516 pr_debug("%s: Setting promiscuous mode.\n",
1517 dev->name);
1518 new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
1519 } else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
1520 new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast;
1521 } else
1522 new_mode = SetRxFilter | RxStation | RxBroadcast;
1523
1524 outw(new_mode, ioaddr + EL3_CMD);
1525 }
1526
1527 static void netdev_get_drvinfo(struct net_device *dev,
1528 struct ethtool_drvinfo *info)
1529 {
1530 strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
1531 snprintf(info->bus_info, sizeof(info->bus_info), "ISA 0x%lx",
1532 dev->base_addr);
1533 }
1534
1535 static u32 netdev_get_msglevel(struct net_device *dev)
1536 {
1537 return corkscrew_debug;
1538 }
1539
1540 static void netdev_set_msglevel(struct net_device *dev, u32 level)
1541 {
1542 corkscrew_debug = level;
1543 }
1544
1545 static const struct ethtool_ops netdev_ethtool_ops = {
1546 .get_drvinfo = netdev_get_drvinfo,
1547 .get_msglevel = netdev_get_msglevel,
1548 .set_msglevel = netdev_set_msglevel,
1549 };
1550
1551
1552 #ifdef MODULE
1553 void cleanup_module(void)
1554 {
1555 while (!list_empty(&root_corkscrew_dev)) {
1556 struct net_device *dev;
1557 struct corkscrew_private *vp;
1558
1559 vp = list_entry(root_corkscrew_dev.next,
1560 struct corkscrew_private, list);
1561 dev = vp->our_dev;
1562 unregister_netdev(dev);
1563 cleanup_card(dev);
1564 free_netdev(dev);
1565 }
1566 }
1567 #endif