Newer
Older
/*
* Copyright (c) 1997-2000 LAN Media Corporation (LMC)
* All rights reserved. www.lanmedia.com
* Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
*
* This code is written by:
* Andrew Stanley-Jones (asj@cban.com)
* Rob Braun (bbraun@vix.com),
* Michael Graff (explorer@vix.com) and
* Matt Thomas (matt@3am-software.com).
*
* With Help By:
* David Boggs
* Ron Crane
* Alan Cox
*
* This software may be used and distributed according to the terms
* of the GNU General Public License version 2, incorporated herein by reference.
*
* Driver for the LanMedia LMC5200, LMC5245, LMC1000, LMC1200 cards.
*
* To control link specific options lmcctl is required.
* It can be obtained from ftp.lanmedia.com.
*
* Linux driver notes:
* Linux uses the device struct lmc_private to pass private information
* arround.
*
* The initialization portion of this driver (the lmc_reset() and the
* lmc_dec_reset() functions, as well as the led controls and the
* lmc_initcsrs() functions.
*
* The watchdog function runs every second and checks to see if
* we still have link, and that the timing source is what we expected
* it to be. If link is lost, the interface is marked down, and
* we no longer can transmit.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/delay.h>
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <linux/init.h>
#include <linux/in.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/inet.h>
#include <linux/bitops.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>
//#include <asm/spinlock.h>
#define DRIVER_MAJOR_VERSION 1
#define DRIVER_MINOR_VERSION 34
#define DRIVER_SUB_VERSION 0
#define DRIVER_VERSION ((DRIVER_MAJOR_VERSION << 8) + DRIVER_MINOR_VERSION)
#include "lmc.h"
#include "lmc_var.h"
#include "lmc_ioctl.h"
#include "lmc_debug.h"
#include "lmc_proto.h"
static int LMC_PKT_BUF_SZ = 1542;
static struct pci_device_id lmc_pci_tbl[] = {
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
PCI_VENDOR_ID_LMC, PCI_ANY_ID },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
PCI_ANY_ID, PCI_VENDOR_ID_LMC },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, lmc_pci_tbl);
static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
static int lmc_rx (struct net_device *dev);
static int lmc_open(struct net_device *dev);
static int lmc_close(struct net_device *dev);
static struct net_device_stats *lmc_get_stats(struct net_device *dev);
static irqreturn_t lmc_interrupt(int irq, void *dev_instance);
static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base, size_t csr_size);
static void lmc_softreset(lmc_softc_t * const);
static void lmc_running_reset(struct net_device *dev);
static int lmc_ifdown(struct net_device * const);
static void lmc_watchdog(unsigned long data);
static void lmc_reset(lmc_softc_t * const sc);
static void lmc_dec_reset(lmc_softc_t * const sc);
static void lmc_driver_timeout(struct net_device *dev);
/*
* linux reserves 16 device specific IOCTLs. We call them
* LMCIOC* to control various bits of our world.
*/
int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
lmc_softc_t *sc = dev_to_sc(dev);
int ret = -EOPNOTSUPP;
u16 regVal;
unsigned long flags;
lmc_trace(dev, "lmc_ioctl in");
/*
* Most functions mess with the structure
* Disable interrupts while we do the polling
*/
switch (cmd) {
/*
* Return current driver state. Since we keep this up
* To date internally, just copy this out to the user.
*/
case LMCIOCGINFO: /*fold01*/
if (copy_to_user(ifr->ifr_data, &sc->ictl, sizeof(lmc_ctl_t)))
ret = -EFAULT;
else
ret = 0;
break;
case LMCIOCSINFO: /*fold01*/
if (!capable(CAP_NET_ADMIN)) {
ret = -EPERM;
break;
}
if(dev->flags & IFF_UP){
ret = -EBUSY;
break;
}
if (copy_from_user(&ctl, ifr->ifr_data, sizeof(lmc_ctl_t))) {
ret = -EFAULT;
break;
}
sc->lmc_media->set_status (sc, &ctl);
if(ctl.crc_length != sc->ictl.crc_length) {
sc->lmc_media->set_crc_length(sc, ctl.crc_length);
if (sc->ictl.crc_length == LMC_CTL_CRC_LENGTH_16)
sc->TxDescriptControlInit |= LMC_TDES_ADD_CRC_DISABLE;
else
sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE;
}
spin_unlock_irqrestore(&sc->lmc_lock, flags);
ret = 0;
break;
case LMCIOCIFTYPE: /*fold01*/
{
u16 old_type = sc->if_type;
u16 new_type;
if (!capable(CAP_NET_ADMIN)) {
ret = -EPERM;
break;
}
if (copy_from_user(&new_type, ifr->ifr_data, sizeof(u16))) {
ret = -EFAULT;
break;
}
if (new_type == old_type)
{
ret = 0 ;
break; /* no change */
}
lmc_proto_close(sc);
sc->if_type = new_type;
lmc_proto_attach(sc);
spin_unlock_irqrestore(&sc->lmc_lock, flags);
sc->lmc_xinfo.Magic0 = 0xBEEFCAFE;
sc->lmc_xinfo.PciCardType = sc->lmc_cardtype;
sc->lmc_xinfo.PciSlotNumber = 0;
sc->lmc_xinfo.DriverMajorVersion = DRIVER_MAJOR_VERSION;
sc->lmc_xinfo.DriverMinorVersion = DRIVER_MINOR_VERSION;
sc->lmc_xinfo.DriverSubVersion = DRIVER_SUB_VERSION;
sc->lmc_xinfo.XilinxRevisionNumber =
lmc_mii_readreg (sc, 0, 3) & 0xf;
sc->lmc_xinfo.MaxFrameSize = LMC_PKT_BUF_SZ;
sc->lmc_xinfo.link_status = sc->lmc_media->get_link_status (sc);
sc->lmc_xinfo.mii_reg16 = lmc_mii_readreg (sc, 0, 16);
spin_unlock_irqrestore(&sc->lmc_lock, flags);
sc->lmc_xinfo.Magic1 = 0xDEADBEEF;
if (copy_to_user(ifr->ifr_data, &sc->lmc_xinfo,
ret = -EFAULT;
else
ret = 0;
if (sc->lmc_cardtype == LMC_CARDTYPE_T1) {
lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_LSB);
sc->extra_stats.framingBitErrorCount +=
lmc_mii_readreg(sc, 0, 18) & 0xff;
lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_MSB);
sc->extra_stats.framingBitErrorCount +=
(lmc_mii_readreg(sc, 0, 18) & 0xff) << 8;
lmc_mii_writereg(sc, 0, 17, T1FRAMER_LCV_LSB);
sc->extra_stats.lineCodeViolationCount +=
lmc_mii_readreg(sc, 0, 18) & 0xff;
lmc_mii_writereg(sc, 0, 17, T1FRAMER_LCV_MSB);
sc->extra_stats.lineCodeViolationCount +=
(lmc_mii_readreg(sc, 0, 18) & 0xff) << 8;
lmc_mii_writereg(sc, 0, 17, T1FRAMER_AERR);
regVal = lmc_mii_readreg(sc, 0, 18) & 0xff;
sc->extra_stats.lossOfFrameCount +=
(regVal & T1FRAMER_LOF_MASK) >> 4;
sc->extra_stats.changeOfFrameAlignmentCount +=
(regVal & T1FRAMER_COFA_MASK) >> 2;
sc->extra_stats.severelyErroredFrameCount +=
regVal & T1FRAMER_SEF_MASK;
}
spin_unlock_irqrestore(&sc->lmc_lock, flags);
if (copy_to_user(ifr->ifr_data, &sc->lmc_device->stats,
sizeof(sc->lmc_device->stats)) ||
copy_to_user(ifr->ifr_data + sizeof(sc->lmc_device->stats),
&sc->extra_stats, sizeof(sc->extra_stats)))
ret = -EFAULT;
else
ret = 0;
break;
case LMCIOCCLEARLMCSTATS:
if (!capable(CAP_NET_ADMIN)) {
ret = -EPERM;
break;
}
memset(&sc->lmc_device->stats, 0, sizeof(sc->lmc_device->stats));
memset(&sc->extra_stats, 0, sizeof(sc->extra_stats));
sc->extra_stats.check = STATCHECK;
sc->extra_stats.version_size = (DRIVER_VERSION << 16) +
sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats);
sc->extra_stats.lmc_cardtype = sc->lmc_cardtype;
spin_unlock_irqrestore(&sc->lmc_lock, flags);
case LMCIOCSETCIRCUIT: /*fold01*/
if (!capable(CAP_NET_ADMIN)){
ret = -EPERM;
break;
}
if(dev->flags & IFF_UP){
ret = -EBUSY;
break;
}
if (copy_from_user(&ctl, ifr->ifr_data, sizeof(lmc_ctl_t))) {
ret = -EFAULT;
break;
}
sc->lmc_media->set_circuit_type(sc, ctl.circuit_type);
sc->ictl.circuit_type = ctl.circuit_type;
spin_unlock_irqrestore(&sc->lmc_lock, flags);
ret = 0;
break;
case LMCIOCRESET: /*fold01*/
if (!capable(CAP_NET_ADMIN)){
ret = -EPERM;
break;
}
/* Reset driver and bring back to current state */
printk (" REG16 before reset +%04x\n", lmc_mii_readreg (sc, 0, 16));
lmc_running_reset (dev);
printk (" REG16 after reset +%04x\n", lmc_mii_readreg (sc, 0, 16));
LMC_EVENT_LOG(LMC_EVENT_FORCEDRESET, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16));
spin_unlock_irqrestore(&sc->lmc_lock, flags);
ret = 0;
break;
#ifdef DEBUG
case LMCIOCDUMPEVENTLOG:
if (copy_to_user(ifr->ifr_data, &lmcEventLogIndex, sizeof(u32))) {
ret = -EFAULT;
break;
}
if (copy_to_user(ifr->ifr_data + sizeof(u32), lmcEventLogBuf,
sizeof(lmcEventLogBuf)))
ret = -EFAULT;
else
ret = 0;
break;
#endif /* end ifdef _DBG_EVENTLOG */
case LMCIOCT1CONTROL: /*fold01*/
if (sc->lmc_cardtype != LMC_CARDTYPE_T1){
ret = -EOPNOTSUPP;
break;
}
break;
case LMCIOCXILINX: /*fold01*/
{
struct lmc_xilinx_control xc; /*fold02*/
if (!capable(CAP_NET_ADMIN)){
ret = -EPERM;
break;
}
/*
* Stop the xwitter whlie we restart the hardware
*/
netif_stop_queue(dev);
if (copy_from_user(&xc, ifr->ifr_data, sizeof(struct lmc_xilinx_control))) {
switch(xc.command){
case lmc_xilinx_reset: /*fold02*/
{
u16 mii;
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
mii = lmc_mii_readreg (sc, 0, 16);
/*
* Make all of them 0 and make input
*/
lmc_gpio_mkinput(sc, 0xff);
/*
* make the reset output
*/
lmc_gpio_mkoutput(sc, LMC_GEP_RESET);
/*
* RESET low to force configuration. This also forces
* the transmitter clock to be internal, but we expect to reset
* that later anyway.
*/
sc->lmc_gpio &= ~LMC_GEP_RESET;
LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
/*
* hold for more than 10 microseconds
*/
udelay(50);
sc->lmc_gpio |= LMC_GEP_RESET;
LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
/*
* stop driving Xilinx-related signals
*/
lmc_gpio_mkinput(sc, 0xff);
/* Reset the frammer hardware */
sc->lmc_media->set_link_status (sc, 1);
sc->lmc_media->set_status (sc, NULL);
// lmc_softreset(sc);
{
int i;
for(i = 0; i < 5; i++){
lmc_led_on(sc, LMC_DS3_LED0);
mdelay(100);
lmc_led_off(sc, LMC_DS3_LED0);
lmc_led_on(sc, LMC_DS3_LED1);
mdelay(100);
lmc_led_off(sc, LMC_DS3_LED1);
lmc_led_on(sc, LMC_DS3_LED3);
mdelay(100);
lmc_led_off(sc, LMC_DS3_LED3);
lmc_led_on(sc, LMC_DS3_LED2);
mdelay(100);
lmc_led_off(sc, LMC_DS3_LED2);
}
}
spin_unlock_irqrestore(&sc->lmc_lock, flags);
ret = 0x0;
}
break;
case lmc_xilinx_load_prom: /*fold02*/
{
u16 mii;
int timeout = 500000;
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
mii = lmc_mii_readreg (sc, 0, 16);
/*
* Make all of them 0 and make input
*/
lmc_gpio_mkinput(sc, 0xff);
/*
* make the reset output
*/
lmc_gpio_mkoutput(sc, LMC_GEP_DP | LMC_GEP_RESET);
/*
* RESET low to force configuration. This also forces
* the transmitter clock to be internal, but we expect to reset
* that later anyway.
*/
sc->lmc_gpio &= ~(LMC_GEP_RESET | LMC_GEP_DP);
LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
/*
* hold for more than 10 microseconds
*/
udelay(50);
sc->lmc_gpio |= LMC_GEP_DP | LMC_GEP_RESET;
LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
/*
* busy wait for the chip to reset
*/
while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 &&
(timeout-- > 0))
/*
* stop driving Xilinx-related signals
*/
lmc_gpio_mkinput(sc, 0xff);
spin_unlock_irqrestore(&sc->lmc_lock, flags);
ret = 0x0;
break;
}
case lmc_xilinx_load: /*fold02*/
{
char *data;
int pos;
int timeout = 500000;
ret = -EINVAL;
break;
}
data = kmalloc(xc.len, GFP_KERNEL);
printk(KERN_WARNING "%s: Failed to allocate memory for copy\n", dev->name);
ret = -ENOMEM;
break;
}
if(copy_from_user(data, xc.data, xc.len))
{
kfree(data);
ret = -ENOMEM;
break;
}
printk("%s: Starting load of data Len: %d at 0x%p == 0x%p\n", dev->name, xc.len, xc.data, data);
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
lmc_gpio_mkinput(sc, 0xff);
/*
* Clear the Xilinx and start prgramming from the DEC
*/
/*
* Set ouput as:
* Reset: 0 (active)
* DP: 0 (active)
* Mode: 1
*
*/
sc->lmc_gpio = 0x00;
sc->lmc_gpio &= ~LMC_GEP_DP;
sc->lmc_gpio &= ~LMC_GEP_RESET;
sc->lmc_gpio |= LMC_GEP_MODE;
LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
lmc_gpio_mkoutput(sc, LMC_GEP_MODE | LMC_GEP_DP | LMC_GEP_RESET);
/*
* Wait at least 10 us 20 to be safe
*/
udelay(50);
/*
* Clear reset and activate programming lines
* Reset: Input
* DP: Input
* Clock: Output
* Data: Output
* Mode: Output
*/
lmc_gpio_mkinput(sc, LMC_GEP_DP | LMC_GEP_RESET);
/*
* Set LOAD, DATA, Clock to 1
*/
sc->lmc_gpio = 0x00;
sc->lmc_gpio |= LMC_GEP_MODE;
sc->lmc_gpio |= LMC_GEP_DATA;
sc->lmc_gpio |= LMC_GEP_CLK;
LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
lmc_gpio_mkoutput(sc, LMC_GEP_DATA | LMC_GEP_CLK | LMC_GEP_MODE );
/*
* busy wait for the chip to reset
*/
while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 &&
(timeout-- > 0))
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
printk(KERN_DEBUG "%s: Waited %d for the Xilinx to clear it's memory\n", dev->name, 500000-timeout);
for(pos = 0; pos < xc.len; pos++){
switch(data[pos]){
case 0:
sc->lmc_gpio &= ~LMC_GEP_DATA; /* Data is 0 */
break;
case 1:
sc->lmc_gpio |= LMC_GEP_DATA; /* Data is 1 */
break;
default:
printk(KERN_WARNING "%s Bad data in xilinx programming data at %d, got %d wanted 0 or 1\n", dev->name, pos, data[pos]);
sc->lmc_gpio |= LMC_GEP_DATA; /* Assume it's 1 */
}
sc->lmc_gpio &= ~LMC_GEP_CLK; /* Clock to zero */
sc->lmc_gpio |= LMC_GEP_MODE;
LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
udelay(1);
sc->lmc_gpio |= LMC_GEP_CLK; /* Put the clack back to one */
sc->lmc_gpio |= LMC_GEP_MODE;
LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
udelay(1);
}
if((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0){
printk(KERN_WARNING "%s: Reprogramming FAILED. Needs to be reprogrammed. (corrupted data)\n", dev->name);
}
else if((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_DP) == 0){
printk(KERN_WARNING "%s: Reprogramming FAILED. Needs to be reprogrammed. (done)\n", dev->name);
}
else {
printk(KERN_DEBUG "%s: Done reprogramming Xilinx, %d bits, good luck!\n", dev->name, pos);
}
lmc_gpio_mkinput(sc, 0xff);
sc->lmc_miireg16 |= LMC_MII16_FIFO_RESET;
lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET;
lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
spin_unlock_irqrestore(&sc->lmc_lock, flags);
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
kfree(data);
ret = 0;
break;
}
default: /*fold02*/
ret = -EBADE;
break;
}
netif_wake_queue(dev);
sc->lmc_txfull = 0;
}
break;
default: /*fold01*/
/* If we don't know what to do, give the protocol a shot. */
ret = lmc_proto_ioctl (sc, ifr, cmd);
break;
}
lmc_trace(dev, "lmc_ioctl out");
return ret;
}
/* the watchdog process that cruises around */
static void lmc_watchdog (unsigned long data) /*fold00*/
{
struct net_device *dev = (struct net_device *)data;
lmc_softc_t *sc = dev_to_sc(dev);
unsigned long flags;
lmc_trace(dev, "lmc_watchdog in");
spin_lock_irqsave(&sc->lmc_lock, flags);
if(sc->check != 0xBEAFCAFE){
printk("LMC: Corrupt net_device struct, breaking out\n");
spin_unlock_irqrestore(&sc->lmc_lock, flags);
return;
}
/* Make sure the tx jabber and rx watchdog are off,
* and the transmit and receive processes are running.
*/
LMC_CSR_WRITE (sc, csr_15, 0x00000011);
sc->lmc_cmdmode |= TULIP_CMD_TXRUN | TULIP_CMD_RXRUN;
LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);
if (sc->lmc_ok == 0)
goto kick_timer;
LMC_EVENT_LOG(LMC_EVENT_WATCHDOG, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16));
/* --- begin time out check -----------------------------------
* check for a transmit interrupt timeout
* Has the packet xmt vs xmt serviced threshold been exceeded */
if (sc->lmc_taint_tx == sc->lastlmc_taint_tx &&
sc->lmc_device->stats.tx_packets > sc->lasttx_packets &&
sc->tx_TimeoutInd == 0)
{
/* wait for the watchdog to come around again */
sc->tx_TimeoutInd = 1;
}
else if (sc->lmc_taint_tx == sc->lastlmc_taint_tx &&
sc->lmc_device->stats.tx_packets > sc->lasttx_packets &&
sc->tx_TimeoutInd)
{
LMC_EVENT_LOG(LMC_EVENT_XMTINTTMO, LMC_CSR_READ (sc, csr_status), 0);
sc->tx_TimeoutDisplay = 1;
sc->extra_stats.tx_TimeoutCnt++;
/* DEC chip is stuck, hit it with a RESET!!!! */
lmc_running_reset (dev);
/* look at receive & transmit process state to make sure they are running */
LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ (sc, csr_status), 0);
/* look at: DSR - 02 for Reg 16
* CTS - 08
* DCD - 10
* RI - 20
* for Reg 17
*/
LMC_EVENT_LOG(LMC_EVENT_RESET2, lmc_mii_readreg (sc, 0, 16), lmc_mii_readreg (sc, 0, 17));
/* reset the transmit timeout detection flag */
sc->tx_TimeoutInd = 0;
sc->lastlmc_taint_tx = sc->lmc_taint_tx;
sc->lasttx_packets = sc->lmc_device->stats.tx_packets;
} else {
sc->tx_TimeoutInd = 0;
sc->lastlmc_taint_tx = sc->lmc_taint_tx;
sc->lasttx_packets = sc->lmc_device->stats.tx_packets;
}
/* --- end time out check ----------------------------------- */
link_status = sc->lmc_media->get_link_status (sc);
/*
* hardware level link lost, but the interface is marked as up.
* Mark it as down.
*/
if ((link_status == 0) && (sc->last_link_status != 0)) {
printk(KERN_WARNING "%s: hardware/physical link down\n", dev->name);
sc->last_link_status = 0;
/* lmc_reset (sc); Why reset??? The link can go down ok */
/* Inform the world that link has been lost */
netif_carrier_off(dev);
}
/*
* hardware link is up, but the interface is marked as down.
* Bring it back up again.
*/
if (link_status != 0 && sc->last_link_status == 0) {
printk(KERN_WARNING "%s: hardware/physical link up\n", dev->name);
sc->last_link_status = 1;
/* lmc_reset (sc); Again why reset??? */
netif_carrier_on(dev);
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
}
/* Call media specific watchdog functions */
sc->lmc_media->watchdog(sc);
/*
* Poke the transmitter to make sure it
* never stops, even if we run out of mem
*/
LMC_CSR_WRITE(sc, csr_rxpoll, 0);
/*
* Check for code that failed
* and try and fix it as appropriate
*/
if(sc->failed_ring == 1){
/*
* Failed to setup the recv/xmit rin
* Try again
*/
sc->failed_ring = 0;
lmc_softreset(sc);
}
if(sc->failed_recv_alloc == 1){
/*
* We failed to alloc mem in the
* interrupt handler, go through the rings
* and rebuild them
*/
sc->failed_recv_alloc = 0;
lmc_softreset(sc);
}
/*
* remember the timer value
*/
kick_timer:
ticks = LMC_CSR_READ (sc, csr_gp_timer);
LMC_CSR_WRITE (sc, csr_gp_timer, 0xffffffffUL);
sc->ictl.ticks = 0x0000ffff - (ticks & 0x0000ffff);
/*
* restart this timer.
*/
sc->timer.expires = jiffies + (HZ);
add_timer (&sc->timer);
spin_unlock_irqrestore(&sc->lmc_lock, flags);
lmc_trace(dev, "lmc_watchdog out");
}
static int lmc_attach(struct net_device *dev, unsigned short encoding,
unsigned short parity)
if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
return 0;
return -EINVAL;
static const struct net_device_ops lmc_ops = {
.ndo_open = lmc_open,
.ndo_stop = lmc_close,
.ndo_change_mtu = hdlc_change_mtu,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = lmc_ioctl,
.ndo_tx_timeout = lmc_driver_timeout,
.ndo_get_stats = lmc_get_stats,
};
static int __devinit lmc_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
lmc_softc_t *sc;
struct net_device *dev;
u16 subdevice;
u16 AdapModelNum;
int err;
static int cards_found;
/* lmc_trace(dev, "lmc_init_one in"); */
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR "lmc: pci enable failed: %d\n", err);
return err;
}
err = pci_request_regions(pdev, "lmc");
if (err) {
printk(KERN_ERR "lmc: pci_request_region failed\n");
goto err_req_io;
}
/*
* Allocate our own device structure
*/
sc = kzalloc(sizeof(lmc_softc_t), GFP_KERNEL);
if (!sc) {
err = -ENOMEM;
goto err_kzalloc;
}
dev = alloc_hdlcdev(sc);
if (!dev) {
printk(KERN_ERR "lmc:alloc_netdev for device failed\n");
goto err_hdlcdev;
}
dev->type = ARPHRD_HDLC;
dev_to_hdlc(dev)->xmit = lmc_start_xmit;
dev_to_hdlc(dev)->attach = lmc_attach;
dev->netdev_ops = &lmc_ops;
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
dev->watchdog_timeo = HZ; /* 1 second */
dev->tx_queue_len = 100;
sc->lmc_device = dev;
sc->name = dev->name;
sc->if_type = LMC_PPP;
sc->check = 0xBEAFCAFE;
dev->base_addr = pci_resource_start(pdev, 0);
dev->irq = pdev->irq;
pci_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
/*
* This will get the protocol layer ready and do any 1 time init's
* Must have a valid sc and dev structure
*/
lmc_proto_attach(sc);
/* Init the spin lock so can call it latter */
spin_lock_init(&sc->lmc_lock);
pci_set_master(pdev);
printk(KERN_INFO "%s: detected at %lx, irq %d\n", dev->name,
dev->base_addr, dev->irq);
err = register_hdlc_device(dev);
if (err) {
printk(KERN_ERR "%s: register_netdev failed.\n", dev->name);
free_netdev(dev);
goto err_hdlcdev;
}
sc->lmc_cardtype = LMC_CARDTYPE_UNKNOWN;
sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;
/*
*
* Check either the subvendor or the subdevice, some systems reverse
* the setting in the bois, seems to be version and arch dependent?
* Fix the error, exchange the two values
*/
if ((subdevice = pdev->subsystem_device) == PCI_VENDOR_ID_LMC)
subdevice = pdev->subsystem_vendor;
switch (subdevice) {
case PCI_DEVICE_ID_LMC_HSSI:
printk(KERN_INFO "%s: LMC HSSI\n", dev->name);
sc->lmc_cardtype = LMC_CARDTYPE_HSSI;
sc->lmc_media = &lmc_hssi_media;
break;
case PCI_DEVICE_ID_LMC_DS3:
printk(KERN_INFO "%s: LMC DS3\n", dev->name);
sc->lmc_cardtype = LMC_CARDTYPE_DS3;
sc->lmc_media = &lmc_ds3_media;
break;
case PCI_DEVICE_ID_LMC_SSI:
printk(KERN_INFO "%s: LMC SSI\n", dev->name);
sc->lmc_cardtype = LMC_CARDTYPE_SSI;
sc->lmc_media = &lmc_ssi_media;
break;
case PCI_DEVICE_ID_LMC_T1:
printk(KERN_INFO "%s: LMC T1\n", dev->name);
sc->lmc_cardtype = LMC_CARDTYPE_T1;
sc->lmc_media = &lmc_t1_media;
break;
default:
printk(KERN_WARNING "%s: LMC UNKOWN CARD!\n", dev->name);
break;
}
lmc_initcsrs (sc, dev->base_addr, 8);
lmc_gpio_mkinput (sc, 0xff);
sc->lmc_gpio = 0; /* drive no signals yet */
sc->lmc_media->defaults (sc);
sc->lmc_media->set_link_status (sc, LMC_LINK_UP);
/* verify that the PCI Sub System ID matches the Adapter Model number
* from the MII register
*/
AdapModelNum = (lmc_mii_readreg (sc, 0, 3) & 0x3f0) >> 4;
if ((AdapModelNum != LMC_ADAP_T1 || /* detect LMC1200 */
subdevice != PCI_DEVICE_ID_LMC_T1) &&
(AdapModelNum != LMC_ADAP_SSI || /* detect LMC1000 */
subdevice != PCI_DEVICE_ID_LMC_SSI) &&
(AdapModelNum != LMC_ADAP_DS3 || /* detect LMC5245 */
subdevice != PCI_DEVICE_ID_LMC_DS3) &&
(AdapModelNum != LMC_ADAP_HSSI || /* detect LMC5200 */
subdevice != PCI_DEVICE_ID_LMC_HSSI))
printk(KERN_WARNING "%s: Model number (%d) miscompare for PCI"
" Subsystem ID = 0x%04x\n",
dev->name, AdapModelNum, subdevice);
/*
* reset clock
*/
LMC_CSR_WRITE (sc, csr_gp_timer, 0xFFFFFFFFUL);
sc->board_idx = cards_found++;
sc->extra_stats.check = STATCHECK;
sc->extra_stats.version_size = (DRIVER_VERSION << 16) +
sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats);
sc->extra_stats.lmc_cardtype = sc->lmc_cardtype;
sc->lmc_ok = 0;
sc->last_link_status = 0;
lmc_trace(dev, "lmc_init_one out");
return 0;
err_hdlcdev:
pci_set_drvdata(pdev, NULL);
kfree(sc);
err_kzalloc:
pci_release_regions(pdev);
err_req_io:
pci_disable_device(pdev);
return err;
}
/*
* Called from pci when removing module.
*/
static void __devexit lmc_remove_one(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
if (dev) {
printk(KERN_DEBUG "%s: removing...\n", dev->name);
unregister_hdlc_device(dev);
free_netdev(dev);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
}