Annotation of Gnu-Mach/i386/i386at/gpl/linux/net/hp100.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * hp100.c: Hewlett Packard HP10/100VG ANY LAN ethernet driver for Linux.
                      3:  *
                      4:  * Author:  Jaroslav Kysela, <[email protected]>
                      5:  *
                      6:  * Supports only the following Hewlett Packard cards:
                      7:  *
                      8:  *     HP J2577        10/100 EISA card with REVA Cascade chip
                      9:  *     HP J2573        10/100 ISA card with REVA Cascade chip
                     10:  *     HP 27248B       10 only EISA card with Cascade chip
                     11:  *     HP J2577        10/100 EISA card with Cascade chip
                     12:  *     HP J2573        10/100 ISA card with Cascade chip
                     13:  *     HP J2585        10/100 PCI card
                     14:  *
                     15:  * Other ATT2MD01 Chip based boards might be supported in the future
                     16:  * (there are some minor changes needed).
                     17:  *
                     18:  * This driver is based on the 'hpfepkt' crynwr packet driver.
                     19:  *
                     20:  * This source/code is public free; you can distribute it and/or modify 
                     21:  * it under terms of the GNU General Public License (published by the
                     22:  * Free Software Foundation) either version two of this License, or any 
                     23:  * later version.
                     24:  * ----------------------------------------------------------------------------
                     25:  *
                     26:  * Note: Some routines (interrupt handling, transmit) assumes that  
                     27:  *       there is the PERFORMANCE page selected...
                     28:  *
                     29:  * ----------------------------------------------------------------------------
                     30:  *
                     31:  * If you are going to use the module version of this driver, you may
                     32:  * change this values at the "insert time" :
                     33:  *
                     34:  *   Variable                   Description
                     35:  *
                     36:  *   hp100_rx_ratio            Range 1-99 - onboard memory used for RX
                     37:  *                              packets in %.
                     38:  *   hp100_priority_tx         If this variable is nonzero - all outgoing
                     39:  *                              packets will be transmitted as priority.
                     40:  *   hp100_port                        Adapter port (for example 0x380).
                     41:  *
                     42:  * ----------------------------------------------------------------------------
                     43:  * MY BEST REGARDS GOING TO:
                     44:  *
                     45:  * IPEX s.r.o which lend me two HP J2573 cards and
                     46:  * the HP AdvanceStack 100VG Hub-15 for debugging.
                     47:  *
                     48:  * Russel Nellson <[email protected]> for help with obtaining sources
                     49:  * of the 'hpfepkt' packet driver.
                     50:  *
                     51:  * Also thanks to Abacus Electric s.r.o which let me to use their 
                     52:  * motherboard for my second computer.
                     53:  *
                     54:  * ----------------------------------------------------------------------------
                     55:  *
                     56:  * TO DO:
                     57:  * ======
                     58:  *       - ioctl handling - some runtime setup things
                     59:  *       - 100Mb/s Voice Grade AnyLAN network adapter/hub services support
                     60:  *             - 802.5 frames
                     61:  *             - promiscuous mode
                     62:  *             - bridge mode
                     63:  *             - cascaded repeater mode
                     64:  *             - 100Mbit MAC
                     65:  *
                     66:  * Revision history:
                     67:  * =================
                     68:  * 
                     69:  *    Version   Date       Description
                     70:  *
                     71:  *     0.1     14-May-95   Initial writing. ALPHA code was released.
                     72:  *                          Only HP J2573 on 10Mb/s (two machines) tested.
                     73:  *      0.11    14-Jun-95   Reset interface bug fixed?
                     74:  *                         Little bug in hp100_close function fixed.
                     75:  *                          100Mb/s connection debugged.
                     76:  *      0.12    14-Jul-95   Link down is now handled better.
                     77:  *      0.20    01-Aug-95   Added PCI support for HP J2585A card.
                     78:  *                          Statistics bug fixed.
                     79:  *      0.21    04-Aug-95   Memory mapped access support for PCI card.
                     80:  *                          Added priority transmit support for 100Mb/s
                     81:  *                          Voice Grade AnyLAN network.
                     82:  *
                     83:  */
                     84: 
                     85: #include <linux/module.h>
                     86: 
                     87: #include <linux/kernel.h>
                     88: #include <linux/sched.h>
                     89: #include <linux/string.h>
                     90: #include <linux/errno.h>
                     91: #include <linux/ioport.h>
                     92: #include <linux/malloc.h>
                     93: #include <linux/interrupt.h>
                     94: #include <linux/pci.h>
                     95: #include <linux/bios32.h>
                     96: #include <asm/bitops.h>
                     97: #include <asm/io.h>
                     98: 
                     99: #include <linux/netdevice.h>
                    100: #include <linux/etherdevice.h>
                    101: #include <linux/skbuff.h>
                    102: 
                    103: #include <linux/types.h>
                    104: #include <linux/config.h>      /* for CONFIG_PCI */
                    105: 
                    106: #include "hp100.h"
                    107: 
                    108: /*
                    109:  *  defines
                    110:  */
                    111: 
                    112: #define HP100_BUS_ISA          0
                    113: #define HP100_BUS_EISA         1
                    114: #define HP100_BUS_PCI          2
                    115: 
                    116: #define HP100_REGION_SIZE      0x20
                    117: 
                    118: #define HP100_MAX_PACKET_SIZE  (1536+4)
                    119: #define HP100_MIN_PACKET_SIZE  60
                    120: 
                    121: #ifndef HP100_DEFAULT_RX_RATIO
                    122: /* default - 65% onboard memory on the card are used for RX packets */
                    123: #define HP100_DEFAULT_RX_RATIO 65
                    124: #endif
                    125: 
                    126: #ifndef HP100_DEFAULT_PRIORITY_TX
                    127: /* default - don't enable transmit outgoing packets as priority */
                    128: #define HP100_DEFAULT_PRIORITY_TX 0
                    129: #endif
                    130: 
                    131: #ifdef MACH
                    132: #define HP100_IO_MAPPED
                    133: #endif
                    134: 
                    135: /*
                    136:  *  structures
                    137:  */
                    138: 
                    139: struct hp100_eisa_id {
                    140:   u_int id;
                    141:   const char *name;
                    142:   u_char bus;
                    143: };
                    144: 
                    145: struct hp100_private {
                    146:   struct hp100_eisa_id *id;
                    147:   u_short soft_model;
                    148:   u_int memory_size;
                    149:   u_short rx_ratio;                /* 1 - 99 */
                    150:   u_short priority_tx;             /* != 0 - priority tx */
                    151:   short mem_mapped;                /* memory mapped access */
                    152:   u_char *mem_ptr_virt;                    /* virtual memory mapped area, maybe NULL */
                    153:   u_char *mem_ptr_phys;                    /* physical memory mapped area */
                    154:   short lan_type;                  /* 10Mb/s, 100Mb/s or -1 (error) */
                    155:   int hub_status;                  /* login to hub was successfull? */
                    156:   u_char mac1_mode;
                    157:   u_char mac2_mode;
                    158:   struct enet_statistics stats;
                    159: };
                    160: 
                    161: /*
                    162:  *  variables
                    163:  */
                    164:  
                    165: static struct hp100_eisa_id hp100_eisa_ids[] = {
                    166: 
                    167:   /* 10/100 EISA card with REVA Cascade chip */
                    168:   { 0x080F1F022, "HP J2577 rev A", HP100_BUS_EISA }, 
                    169: 
                    170:   /* 10/100 ISA card with REVA Cascade chip */
                    171:   { 0x050F1F022, "HP J2573 rev A", HP100_BUS_ISA },
                    172: 
                    173:   /* 10 only EISA card with Cascade chip */
                    174:   { 0x02019F022, "HP 27248B",      HP100_BUS_EISA }, 
                    175: 
                    176:   /* 10/100 EISA card with Cascade chip */
                    177:   { 0x04019F022, "HP J2577",       HP100_BUS_EISA },
                    178: 
                    179:   /* 10/100 ISA card with Cascade chip */
                    180:   { 0x05019F022, "HP J2573",       HP100_BUS_ISA },
                    181: 
                    182:   /* 10/100 PCI card */
                    183:   /* Note: ID for this card is same as PCI vendor/device numbers. */
                    184:   { 0x01030103c, "HP J2585",      HP100_BUS_PCI },
                    185: };
                    186: 
                    187: int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO;
                    188: int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;
                    189: 
                    190: /*
                    191:  *  prototypes
                    192:  */
                    193: 
                    194: static int hp100_probe1( struct device *dev, int ioaddr, int bus );
                    195: static int hp100_open( struct device *dev );
                    196: static int hp100_close( struct device *dev );
                    197: static int hp100_start_xmit( struct sk_buff *skb, struct device *dev );
                    198: static void hp100_rx( struct device *dev );
                    199: static struct enet_statistics *hp100_get_stats( struct device *dev );
                    200: static void hp100_update_stats( struct device *dev );
                    201: static void hp100_clear_stats( int ioaddr );
                    202: static void hp100_set_multicast_list( struct device *dev);
                    203: static void hp100_interrupt( int irq, struct pt_regs *regs );
                    204: 
                    205: static void hp100_start_interface( struct device *dev );
                    206: static void hp100_stop_interface( struct device *dev );
                    207: static void hp100_load_eeprom( struct device *dev );
                    208: static int hp100_sense_lan( struct device *dev );
                    209: static int hp100_login_to_vg_hub( struct device *dev );
                    210: static int hp100_down_vg_link( struct device *dev );
                    211: 
                    212: /*
                    213:  *  probe functions
                    214:  */
                    215:  
                    216: int hp100_probe( struct device *dev )
                    217: {
                    218:   int base_addr = dev ? dev -> base_addr : 0;
                    219:   int ioaddr;
                    220: #ifdef CONFIG_PCI
                    221:   int pci_start_index = 0;
                    222: #endif
                    223: 
                    224:   if ( base_addr > 0xff )      /* Check a single specified location. */
                    225:     {
                    226:       if ( check_region( base_addr, HP100_REGION_SIZE ) ) return -EINVAL;
                    227:       if ( base_addr < 0x400 )
                    228:         return hp100_probe1( dev, base_addr, HP100_BUS_ISA );
                    229:        else
                    230:         return hp100_probe1( dev, base_addr, HP100_BUS_EISA );
                    231:     }
                    232:    else 
                    233: #ifdef CONFIG_PCI
                    234:   if ( base_addr > 0 && base_addr < 8 + 1 )
                    235:     pci_start_index = 0x100 | ( base_addr - 1 );
                    236:    else
                    237: #endif
                    238:     if ( base_addr != 0 ) return -ENXIO;
                    239: 
                    240:   /* at first - scan PCI bus(es) */
                    241:   
                    242: #ifdef CONFIG_PCI
                    243:   if ( pcibios_present() )
                    244:     {
                    245:       int pci_index;
                    246:       
                    247: #ifdef HP100_DEBUG_PCI
                    248:       printk( "hp100: PCI BIOS is present, checking for devices..\n" );
                    249: #endif
                    250:       for ( pci_index = pci_start_index & 7; pci_index < 8; pci_index++ )
                    251:         {
                    252:           u_char pci_bus, pci_device_fn;
                    253:           u_short pci_command;
                    254:           
                    255:           if ( pcibios_find_device( PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A,
                    256:                                    pci_index, &pci_bus,
                    257:                                    &pci_device_fn ) != 0 ) break;
                    258:           pcibios_read_config_dword( pci_bus, pci_device_fn,
                    259:                                     PCI_BASE_ADDRESS_0, &ioaddr );
                    260:                                         
                    261:           ioaddr &= ~3;                /* remove I/O space marker in bit 0. */
                    262:               
                    263:           if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
                    264:               
                    265:           pcibios_read_config_word( pci_bus, pci_device_fn,
                    266:                                    PCI_COMMAND, &pci_command );
                    267:           if ( !( pci_command & PCI_COMMAND_MASTER ) )
                    268:             {
                    269: #ifdef HP100_DEBUG_PCI
                    270:               printk( "hp100: PCI Master Bit has not been set. Setting...\n" );
                    271: #endif
                    272:               pci_command |= PCI_COMMAND_MASTER;
                    273:               pcibios_write_config_word( pci_bus, pci_device_fn,
                    274:                                         PCI_COMMAND, pci_command );
                    275:             }
                    276: #ifdef HP100_DEBUG_PCI
                    277:           printk( "hp100: PCI adapter found at 0x%x\n", ioaddr );
                    278: #endif
                    279:                  if ( hp100_probe1( dev, ioaddr, HP100_BUS_PCI ) == 0 ) return 0;
                    280:         }
                    281:     }
                    282:   if ( pci_start_index > 0 ) return -ENODEV;
                    283: #endif /* CONFIG_PCI */
                    284:          
                    285:   /* at second - probe all EISA possible port regions (if EISA bus present) */
                    286:   
                    287:   for ( ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400 )
                    288:     {
                    289:       if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
                    290:       if ( hp100_probe1( dev, ioaddr, HP100_BUS_EISA ) == 0 ) return 0;
                    291:     }
                    292:          
                    293:   /* at third - probe all ISA possible port regions */
                    294:          
                    295:   for ( ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20 )
                    296:     {
                    297:       if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
                    298:       if ( hp100_probe1( dev, ioaddr, HP100_BUS_ISA ) == 0 ) return 0;
                    299:     }
                    300:                                                                             
                    301:   return -ENODEV;
                    302: }
                    303: 
                    304: static int hp100_probe1( struct device *dev, int ioaddr, int bus )
                    305: {
                    306:   int i;
                    307:   u_char uc, uc_1;
                    308:   u_int eisa_id;
                    309:   short mem_mapped;
                    310:   u_char *mem_ptr_phys, *mem_ptr_virt;
                    311:   struct hp100_private *lp;
                    312:   struct hp100_eisa_id *eid;
                    313: 
                    314:   if ( dev == NULL )
                    315:     {
                    316: #ifdef HP100_DEBUG
                    317:       printk( "hp100_probe1: dev == NULL ?\n" );
                    318: #endif
                    319:       return EIO;
                    320:     }
                    321: 
                    322:   if ( bus != HP100_BUS_PCI )          /* don't check PCI cards again */
                    323:     if ( inb( ioaddr + 0 ) != HP100_HW_ID_0 ||
                    324:          inb( ioaddr + 1 ) != HP100_HW_ID_1 ||
                    325:          ( inb( ioaddr + 2 ) & 0xf0 ) != HP100_HW_ID_2_REVA ||
                    326:          inb( ioaddr + 3 ) != HP100_HW_ID_3 ) 
                    327:        return -ENODEV;
                    328: 
                    329:   dev -> base_addr = ioaddr;
                    330: 
                    331: #ifdef HP100_DEBUG_PROBE1
                    332:   printk( "hp100_probe1: card found at port 0x%x\n", ioaddr );
                    333: #endif
                    334: 
                    335:   hp100_page( ID_MAC_ADDR );
                    336:   for ( i = uc = eisa_id = 0; i < 4; i++ )
                    337:     {
                    338:       eisa_id >>= 8;
                    339:       uc_1 = hp100_inb( BOARD_ID + i );
                    340:       eisa_id |= uc_1 << 24;
                    341:       uc += uc_1;
                    342:     }
                    343:   uc += hp100_inb( BOARD_ID + 4 );
                    344: 
                    345: #ifdef HP100_DEBUG_PROBE1
                    346:   printk( "hp100_probe1: EISA ID = 0x%08x  checksum = 0x%02x\n", eisa_id, uc );
                    347: #endif
                    348: 
                    349:   if ( uc != 0xff )            /* bad checksum? */
                    350:     {
                    351:       printk( "hp100_probe: bad EISA ID checksum at base port 0x%x\n", ioaddr );
                    352:       return -ENODEV;
                    353:     }  
                    354: 
                    355:   for ( i = 0; i < sizeof( hp100_eisa_ids ) / sizeof( struct hp100_eisa_id ); i++ )
                    356:     if ( ( hp100_eisa_ids[ i ].id & 0xf0ffffff ) == ( eisa_id & 0xf0ffffff ) )
                    357:       break;
                    358:   if ( i >= sizeof( hp100_eisa_ids ) / sizeof( struct hp100_eisa_id ) )
                    359:     {
                    360:       printk( "hp100_probe1: card at port 0x%x isn't known (id = 0x%x)\n", ioaddr, eisa_id );
                    361:       return -ENODEV;
                    362:     }
                    363:   eid = &hp100_eisa_ids[ i ];
                    364:   if ( ( eid -> id & 0x0f000000 ) < ( eisa_id & 0x0f000000 ) )
                    365:     {
                    366:       printk( "hp100_probe1: newer version of card %s at port 0x%x - unsupported\n", 
                    367:        eid -> name, ioaddr );
                    368:       return -ENODEV;
                    369:     }
                    370: 
                    371:   for ( i = uc = 0; i < 7; i++ )
                    372:     uc += hp100_inb( LAN_ADDR + i );
                    373:   if ( uc != 0xff )
                    374:     {
                    375:       printk( "hp100_probe1: bad lan address checksum (card %s at port 0x%x)\n", 
                    376:        eid -> name, ioaddr );
                    377:       return -EIO;
                    378:     }
                    379: 
                    380: #ifndef HP100_IO_MAPPED
                    381:   hp100_page( HW_MAP );
                    382:   mem_mapped = ( hp100_inw( OPTION_LSW ) & 
                    383:                  ( HP100_MEM_EN | HP100_BM_WRITE | HP100_BM_READ ) ) != 0;
                    384:   mem_ptr_phys = mem_ptr_virt = NULL;
                    385:   if ( mem_mapped )
                    386:     {
                    387:       mem_ptr_phys = (u_char *)( hp100_inw( MEM_MAP_LSW ) | 
                    388:                                ( hp100_inw( MEM_MAP_MSW ) << 16 ) );
                    389:       (u_int)mem_ptr_phys &= ~0x1fff;  /* 8k aligment */
                    390:       if ( bus == HP100_BUS_ISA && ( (u_long)mem_ptr_phys & ~0xfffff ) != 0 )
                    391:         {
                    392:           mem_ptr_phys = NULL;
                    393:           mem_mapped = 0;
                    394:         }
                    395:       if ( mem_mapped && bus == HP100_BUS_PCI )
                    396:         {
                    397:           if ( ( mem_ptr_virt = vremap( (u_long)mem_ptr_phys, 0x2000 ) ) == NULL )
                    398:             {
                    399:               printk( "hp100: vremap for high PCI memory at 0x%lx failed\n", (u_long)mem_ptr_phys );
                    400:               mem_ptr_phys = NULL;
                    401:               mem_mapped = 0;
                    402:             }
                    403:         }
                    404:     }
                    405: #else
                    406:   mem_mapped = 0;
                    407:   mem_ptr_phys = mem_ptr_virt = NULL;
                    408: #endif
                    409: 
                    410:   if ( ( dev -> priv = kmalloc( sizeof( struct hp100_private ), GFP_KERNEL ) ) == NULL )
                    411:     return -ENOMEM;
                    412:   memset( dev -> priv, 0, sizeof( struct hp100_private ) );
                    413: 
                    414:   lp = (struct hp100_private *)dev -> priv;
                    415:   lp -> id = eid;
                    416:   lp -> mem_mapped = mem_mapped;
                    417:   lp -> mem_ptr_phys = mem_ptr_phys;
                    418:   lp -> mem_ptr_virt = mem_ptr_virt;
                    419:   hp100_page( ID_MAC_ADDR );
                    420:   lp -> soft_model = hp100_inb( SOFT_MODEL );
                    421:   lp -> mac1_mode = HP100_MAC1MODE3;
                    422:   lp -> mac2_mode = HP100_MAC2MODE3;
                    423:   
                    424:   dev -> base_addr = ioaddr;
                    425:   hp100_page( HW_MAP );
                    426:   dev -> irq = hp100_inb( IRQ_CHANNEL ) & HP100_IRQ_MASK;
                    427:   if ( dev -> irq == 2 ) dev -> irq = 9;
                    428:   lp -> memory_size = 0x200 << ( ( hp100_inb( SRAM ) & 0xe0 ) >> 5 );
                    429:   lp -> rx_ratio = hp100_rx_ratio;
                    430: 
                    431:   dev -> open = hp100_open;
                    432:   dev -> stop = hp100_close;
                    433:   dev -> hard_start_xmit = hp100_start_xmit;
                    434:   dev -> get_stats = hp100_get_stats;
                    435:   dev -> set_multicast_list = &hp100_set_multicast_list;
                    436: 
                    437:   request_region( dev -> base_addr, HP100_REGION_SIZE, eid -> name );
                    438: 
                    439:   hp100_page( ID_MAC_ADDR );
                    440:   for ( i = uc = 0; i < 6; i++ )
                    441:     dev -> dev_addr[ i ] = hp100_inb( LAN_ADDR + i );
                    442: 
                    443:   hp100_clear_stats( ioaddr );
                    444: 
                    445:   ether_setup( dev );
                    446: 
                    447:   lp -> lan_type = hp100_sense_lan( dev );
                    448:      
                    449:   printk( "%s: %s at 0x%x, IRQ %d, ",
                    450:     dev -> name, lp -> id -> name, ioaddr, dev -> irq );
                    451:   switch ( bus ) {
                    452:     case HP100_BUS_EISA: printk( "EISA" ); break;
                    453:     case HP100_BUS_PCI:  printk( "PCI" );  break;
                    454:     default:            printk( "ISA" );  break;
                    455:   }
                    456:   printk( " bus, %dk SRAM (rx/tx %d%%).\n",
                    457:     lp -> memory_size >> ( 10 - 4 ), lp -> rx_ratio );
                    458:   if ( mem_mapped )
                    459:     {
                    460:       printk( "%s: Memory area at 0x%lx-0x%lx",
                    461:                dev -> name, (u_long)mem_ptr_phys, (u_long)mem_ptr_phys + 0x1fff );
                    462:       if ( mem_ptr_virt )
                    463:         printk( " (virtual base 0x%lx)", (u_long)mem_ptr_virt );
                    464:       printk( ".\n" );
                    465:     }
                    466:   printk( "%s: ", dev -> name );
                    467:   if ( lp -> lan_type != HP100_LAN_ERR )
                    468:     printk( "Adapter is attached to " );
                    469:   switch ( lp -> lan_type ) {
                    470:     case HP100_LAN_100:
                    471:       printk( "100Mb/s Voice Grade AnyLAN network.\n" );
                    472:       break;
                    473:     case HP100_LAN_10:
                    474:       printk( "10Mb/s network.\n" );
                    475:       break;
                    476:     default:
                    477:       printk( "Warning! Link down.\n" );
                    478:   }
                    479:                
                    480:   hp100_stop_interface( dev );
                    481:   
                    482:   return 0;
                    483: }
                    484: 
                    485: /*
                    486:  *  open/close functions
                    487:  */
                    488: 
                    489: static int hp100_open( struct device *dev )
                    490: {
                    491:   int i;
                    492:   int ioaddr = dev -> base_addr;
                    493:   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
                    494: 
                    495:   if ( request_irq( dev -> irq, hp100_interrupt, SA_INTERRUPT, lp -> id -> name ) )
                    496:     {
                    497:       printk( "%s: unable to get IRQ %d\n", dev -> name, dev -> irq );
                    498:       return -EAGAIN;
                    499:     }
                    500:   irq2dev_map[ dev -> irq ] = dev;
                    501: 
                    502:   MOD_INC_USE_COUNT;
                    503:   
                    504:   dev -> tbusy = 0;
                    505:   dev -> trans_start = jiffies;
                    506:   dev -> interrupt = 0;
                    507:   dev -> start = 1;
                    508: 
                    509:   lp -> lan_type = hp100_sense_lan( dev );
                    510:   lp -> mac1_mode = HP100_MAC1MODE3;
                    511:   lp -> mac2_mode = HP100_MAC2MODE3;
                    512:   
                    513:   hp100_page( MAC_CTRL );
                    514:   hp100_orw( HP100_LINK_BEAT_DIS | HP100_RESET_LB, LAN_CFG_10 );
                    515: 
                    516:   hp100_stop_interface( dev );
                    517:   hp100_load_eeprom( dev );
                    518: 
                    519:   hp100_outw( HP100_MMAP_DIS | HP100_SET_HB | 
                    520:               HP100_IO_EN | HP100_SET_LB, OPTION_LSW );
                    521:   hp100_outw( HP100_DEBUG_EN | HP100_RX_HDR | HP100_EE_EN | HP100_RESET_HB |
                    522:               HP100_FAKE_INT | HP100_RESET_LB, OPTION_LSW );
                    523:   hp100_outw( HP100_ADV_NXT_PKT | HP100_TX_CMD | HP100_RESET_LB |
                    524:                 HP100_PRIORITY_TX | ( hp100_priority_tx ? HP100_SET_HB : HP100_RESET_HB ),
                    525:               OPTION_MSW );
                    526:                                        
                    527:   hp100_page( MAC_ADDRESS );
                    528:   for ( i = 0; i < 6; i++ )
                    529:     hp100_outb( dev -> dev_addr[ i ], MAC_ADDR + i );
                    530:   for ( i = 0; i < 8; i++ )            /* setup multicast filter to receive all */
                    531:     hp100_outb( 0xff, HASH_BYTE0 + i );
                    532:   hp100_page( PERFORMANCE );
                    533:   hp100_outw( 0xfefe, IRQ_MASK );      /* mask off all ints */
                    534:   hp100_outw( 0xffff, IRQ_STATUS );    /* ack IRQ */
                    535:   hp100_outw( (HP100_RX_PACKET | HP100_RX_ERROR | HP100_SET_HB) |
                    536:               (HP100_TX_ERROR | HP100_SET_LB ), IRQ_MASK );
                    537:                                        /* and enable few */
                    538:   hp100_reset_card();
                    539:   hp100_page( MMU_CFG );
                    540:   hp100_outw( ( lp -> memory_size * lp -> rx_ratio ) / 100, RX_MEM_STOP );
                    541:   hp100_outw( lp -> memory_size - 1, TX_MEM_STOP );
                    542:   hp100_unreset_card();
                    543: 
                    544:   if ( lp -> lan_type == HP100_LAN_100 )
                    545:     lp -> hub_status = hp100_login_to_vg_hub( dev );
                    546: 
                    547:   hp100_start_interface( dev );
                    548: 
                    549:   return 0;
                    550: }
                    551: 
                    552: static int hp100_close( struct device *dev )
                    553: {
                    554:   int ioaddr = dev -> base_addr;
                    555:   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
                    556: 
                    557:   hp100_page( PERFORMANCE );
                    558:   hp100_outw( 0xfefe, IRQ_MASK );              /* mask off all IRQs */
                    559: 
                    560:   hp100_stop_interface( dev );
                    561: 
                    562:   if ( lp -> lan_type == HP100_LAN_100 )       /* relogin */
                    563:     hp100_login_to_vg_hub( dev );
                    564: 
                    565:   dev -> tbusy = 1;
                    566:   dev -> start = 0;
                    567: 
                    568:   free_irq( dev -> irq );
                    569:   irq2dev_map[ dev -> irq ] = NULL;
                    570:   MOD_DEC_USE_COUNT;
                    571:   return 0;
                    572: }
                    573: 
                    574: /* 
                    575:  *  transmit
                    576:  */
                    577: 
                    578: static int hp100_start_xmit( struct sk_buff *skb, struct device *dev )
                    579: {
                    580:   int i, ok_flag;
                    581:   int ioaddr = dev -> base_addr;
                    582:   u_short val;
                    583:   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
                    584: 
                    585:   if ( lp -> lan_type < 0 )
                    586:     {
                    587:       hp100_stop_interface( dev );
                    588:       if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) < 0 )
                    589:         {
                    590:           printk( "%s: no connection found - check wire\n", dev -> name );
                    591:           hp100_start_interface( dev );        /* 10Mb/s RX packets maybe handled */
                    592:           return -EIO;
                    593:         }
                    594:       if ( lp -> lan_type == HP100_LAN_100 )
                    595:         lp -> hub_status = hp100_login_to_vg_hub( dev );
                    596:       hp100_start_interface( dev );
                    597:     }
                    598:   
                    599:   if ( ( i = ( hp100_inl( TX_MEM_FREE ) & ~0x7fffffff ) ) < skb -> len + 16 )
                    600:     {
                    601: #ifdef HP100_DEBUG
                    602:       printk( "hp100_start_xmit: rx free mem = 0x%x\n", i );
                    603: #endif
                    604:       if ( jiffies - dev -> trans_start < 2 * HZ ) return -EAGAIN;
                    605:       if ( lp -> lan_type == HP100_LAN_100 && lp -> hub_status < 0 )
                    606:                                /* 100Mb/s adapter isn't connected to hub */
                    607:         {
                    608:           printk( "%s: login to 100Mb/s hub retry\n", dev -> name );
                    609:           hp100_stop_interface( dev );
                    610:           lp -> hub_status = hp100_login_to_vg_hub( dev );
                    611:           hp100_start_interface( dev );
                    612:         }
                    613:        else
                    614:         {
                    615:           hp100_ints_off();
                    616:           i = hp100_sense_lan( dev );
                    617:           hp100_page( PERFORMANCE );
                    618:           hp100_ints_on();
                    619:           if ( i == HP100_LAN_ERR )
                    620:             printk( "%s: link down detected\n", dev -> name );
                    621:            else
                    622:           if ( lp -> lan_type != i )
                    623:             {
                    624:               /* it's very heavy - all network setting must be changed!!! */
                    625:               printk( "%s: cable change 10Mb/s <-> 100Mb/s detected\n", dev -> name );
                    626:               lp -> lan_type = i;
                    627:               hp100_stop_interface( dev );
                    628:               if ( lp -> lan_type == HP100_LAN_100 )
                    629:                 lp -> hub_status = hp100_login_to_vg_hub( dev );
                    630:               hp100_start_interface( dev );
                    631:             }
                    632:            else
                    633:             {
                    634:               printk( "%s: interface reset\n", dev -> name );
                    635:               hp100_stop_interface( dev );
                    636:               hp100_start_interface( dev );
                    637:             }
                    638:         }
                    639:       dev -> trans_start = jiffies;
                    640:       return -EAGAIN;
                    641:     }
                    642:     
                    643:   if ( skb == NULL )
                    644:     {
                    645:       dev_tint( dev );
                    646:       return 0;
                    647:     }
                    648:     
                    649:   if ( skb -> len <= 0 ) return 0;
                    650: 
                    651:   for ( i = 0; i < 6000 && ( hp100_inw( OPTION_MSW ) & HP100_TX_CMD ); i++ )
                    652:     {
                    653: #ifdef HP100_DEBUG_TX
                    654:       printk( "hp100_start_xmit: busy\n" );
                    655: #endif    
                    656:     }
                    657: 
                    658:   hp100_ints_off();
                    659:   val = hp100_inw( IRQ_STATUS );
                    660:   hp100_outw( val & HP100_TX_COMPLETE, IRQ_STATUS );
                    661: #ifdef HP100_DEBUG_TX
                    662:   printk( "hp100_start_xmit: irq_status = 0x%x, len = %d\n", val, (int)skb -> len );
                    663: #endif
                    664:   ok_flag = skb -> len >= HP100_MIN_PACKET_SIZE;
                    665:   i = ok_flag ? skb -> len : HP100_MIN_PACKET_SIZE;
                    666:   hp100_outw( i, DATA32 );             /* length to memory manager */
                    667:   hp100_outw( i, FRAGMENT_LEN );
                    668:   if ( lp -> mem_mapped )
                    669:     {
                    670:       if ( lp -> mem_ptr_virt )
                    671:         {
                    672:           memcpy( lp -> mem_ptr_virt, skb -> data, skb -> len );
                    673:           if ( !ok_flag )
                    674:             memset( lp -> mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb -> len );
                    675:         }
                    676:        else
                    677:         {
                    678:           memcpy_toio( lp -> mem_ptr_phys, skb -> data, skb -> len );
                    679:           if ( !ok_flag )
                    680:             memset_io( lp -> mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb -> len );
                    681:         }
                    682:     }
                    683:    else
                    684:     {
                    685:       outsl( ioaddr + HP100_REG_DATA32, skb -> data, ( skb -> len + 3 ) >> 2 );
                    686:       if ( !ok_flag )
                    687:         for ( i = ( skb -> len + 3 ) & ~3; i < HP100_MIN_PACKET_SIZE; i += 4 )
                    688:           hp100_outl( 0, DATA32 );
                    689:     }
                    690:   hp100_outw( HP100_TX_CMD | HP100_SET_LB, OPTION_MSW ); /* send packet */
                    691:   lp -> stats.tx_packets++;
                    692:   dev -> trans_start = jiffies;
                    693:   hp100_ints_on();
                    694: 
                    695:   dev_kfree_skb( skb, FREE_WRITE );
                    696: 
                    697: #ifdef HP100_DEBUG_TX
                    698:   printk( "hp100_start_xmit: end\n" );
                    699: #endif
                    700: 
                    701:   return 0;
                    702: }
                    703: 
                    704: /*
                    705:  *  receive - called from interrupt handler
                    706:  */
                    707: 
                    708: static void hp100_rx( struct device *dev )
                    709: {
                    710:   int packets, pkt_len;
                    711:   int ioaddr = dev -> base_addr;
                    712:   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
                    713:   u_int header;
                    714:   struct sk_buff *skb;
                    715: 
                    716: #if 0
                    717:   if ( lp -> lan_type < 0 )
                    718:     {
                    719:       if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) == HP100_LAN_100 )
                    720:         lp -> hub_status = hp100_login_to_vg_hub( dev );
                    721:       hp100_page( PERFORMANCE );
                    722:     }
                    723: #endif
                    724:   
                    725:   packets = hp100_inb( RX_PKT_CNT );
                    726: #ifdef HP100_DEBUG
                    727:   if ( packets > 1 )
                    728:     printk( "hp100_rx: waiting packets = %d\n", packets );
                    729: #endif
                    730:   while ( packets-- > 0 )
                    731:     {
                    732:       for ( pkt_len = 0; pkt_len < 6000 && ( hp100_inw( OPTION_MSW ) & HP100_ADV_NXT_PKT ); pkt_len++ )
                    733:         {
                    734: #ifdef HP100_DEBUG_TX
                    735:           printk( "hp100_rx: busy, remaining packets = %d\n", packets );
                    736: #endif    
                    737:         }
                    738:       if ( lp -> mem_mapped )
                    739:         {
                    740:           if ( lp -> mem_ptr_virt )
                    741:             header = *(__u32 *)lp -> mem_ptr_virt;
                    742:            else
                    743:             header = readl( lp -> mem_ptr_phys );
                    744:         }
                    745:        else
                    746:         header = hp100_inl( DATA32 );
                    747:       pkt_len = header & HP100_PKT_LEN_MASK;
                    748: #ifdef HP100_DEBUG_RX
                    749:       printk( "hp100_rx: new packet - length = %d, errors = 0x%x, dest = 0x%x\n",
                    750:        header & HP100_PKT_LEN_MASK, ( header >> 16 ) & 0xfff8, ( header >> 16 ) & 7 );
                    751: #endif
                    752:       /*
                    753:        * NOTE! This (and the skb_put() below) depends on the skb-functions
                    754:        * allocating more than asked (notably, aligning the request up to
                    755:        * the next 16-byte length).
                    756:        */
                    757:       skb = dev_alloc_skb( pkt_len );
                    758:       if ( skb == NULL )
                    759:         {
                    760: #ifdef HP100_DEBUG
                    761:           printk( "hp100_rx: couldn't allocate a sk_buff of size %d\n", pkt_len );
                    762: #endif
                    763:           lp -> stats.rx_dropped++;
                    764:         }
                    765:        else
                    766:         {
                    767:           u_char *ptr;
                    768:         
                    769:           skb -> dev = dev;
                    770:           ptr = (u_char *)skb_put( skb, pkt_len );
                    771:           if ( lp -> mem_mapped )
                    772:             {
                    773:               if ( lp -> mem_ptr_virt )
                    774:                 memcpy( ptr, lp -> mem_ptr_virt, ( pkt_len + 3 ) & ~3 );
                    775:                else
                    776:                 memcpy_fromio( ptr, lp -> mem_ptr_phys, ( pkt_len + 3 ) & ~3 );
                    777:             }
                    778:            else
                    779:             insl( ioaddr + HP100_REG_DATA32, ptr, ( pkt_len + 3 ) >> 2 );
                    780:           skb -> protocol = eth_type_trans( skb, dev );
                    781:           netif_rx( skb );
                    782:           lp -> stats.rx_packets++;
                    783: #ifdef HP100_DEBUG_RX
                    784:           printk( "rx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
                    785:                ptr[ 0 ], ptr[ 1 ], ptr[ 2 ], ptr[ 3 ], ptr[ 4 ], ptr[ 5 ],
                    786:                ptr[ 6 ], ptr[ 7 ], ptr[ 8 ], ptr[ 9 ], ptr[ 10 ], ptr[ 11 ] );
                    787: #endif
                    788:         }
                    789:       hp100_outw( HP100_ADV_NXT_PKT | HP100_SET_LB, OPTION_MSW );
                    790:       switch ( header & 0x00070000 ) {
                    791:         case (HP100_MULTI_ADDR_HASH<<16):
                    792:         case (HP100_MULTI_ADDR_NO_HASH<<16):
                    793:           lp -> stats.multicast++; break;
                    794:       }
                    795:     }
                    796: #ifdef HP100_DEBUG_RX
                    797:    printk( "hp100_rx: end\n" );
                    798: #endif
                    799: }
                    800: 
                    801: /*
                    802:  *  statistics
                    803:  */
                    804:  
                    805: static struct enet_statistics *hp100_get_stats( struct device *dev )
                    806: {
                    807:   int ioaddr = dev -> base_addr;
                    808: 
                    809:   hp100_ints_off();
                    810:   hp100_update_stats( dev );
                    811:   hp100_ints_on();
                    812:   return &((struct hp100_private *)dev -> priv) -> stats;
                    813: }
                    814: 
                    815: static void hp100_update_stats( struct device *dev )
                    816: {
                    817:   int ioaddr = dev -> base_addr;
                    818:   u_short val;
                    819:   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
                    820:          
                    821:   hp100_page( MAC_CTRL );              /* get all statistics bytes */
                    822:   val = hp100_inw( DROPPED ) & 0x0fff;
                    823:   lp -> stats.rx_errors += val;
                    824:   lp -> stats.rx_over_errors += val;
                    825:   val = hp100_inb( CRC );
                    826:   lp -> stats.rx_errors += val;
                    827:   lp -> stats.rx_crc_errors += val;
                    828:   val = hp100_inb( ABORT );
                    829:   lp -> stats.tx_errors += val;
                    830:   lp -> stats.tx_aborted_errors += val;
                    831:   hp100_page( PERFORMANCE );
                    832: }
                    833: 
                    834: static void hp100_clear_stats( int ioaddr )
                    835: {
                    836:   cli();
                    837:   hp100_page( MAC_CTRL );              /* get all statistics bytes */
                    838:   hp100_inw( DROPPED );
                    839:   hp100_inb( CRC );
                    840:   hp100_inb( ABORT );
                    841:   hp100_page( PERFORMANCE );
                    842:   sti();
                    843: }
                    844: 
                    845: /*
                    846:  *  multicast setup
                    847:  */
                    848: 
                    849: /*
                    850:  *  Set or clear the multicast filter for this adapter.
                    851:  */
                    852:                                                           
                    853: static void hp100_set_multicast_list( struct device *dev)
                    854: {
                    855:   int ioaddr = dev -> base_addr;
                    856:   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
                    857: 
                    858: #ifdef HP100_DEBUG_MULTI
                    859:   printk( "hp100_set_multicast_list: num_addrs = %d\n", dev->mc_count);
                    860: #endif
                    861:   cli();
                    862:   hp100_ints_off();
                    863:   hp100_page( MAC_CTRL );
                    864:   hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 );       /* stop rx/tx */
                    865: 
                    866:   if ( dev->flags&IFF_PROMISC)
                    867:     {
                    868:       lp -> mac2_mode = HP100_MAC2MODE6;  /* promiscuous mode, all good */
                    869:       lp -> mac1_mode = HP100_MAC1MODE6;  /* packets on the net */
                    870:     }
                    871:    else
                    872:   if ( dev->mc_count || dev->flags&IFF_ALLMULTI )
                    873:     {
                    874:       lp -> mac2_mode = HP100_MAC2MODE5;  /* multicast mode, packets for me */
                    875:       lp -> mac1_mode = HP100_MAC1MODE5;  /* broadcasts and all multicasts */
                    876:     }
                    877:    else
                    878:     {
                    879:       lp -> mac2_mode = HP100_MAC2MODE3;  /* normal mode, packets for me */
                    880:       lp -> mac1_mode = HP100_MAC1MODE3;  /* and broadcasts */
                    881:     }
                    882: 
                    883:   hp100_outb( lp -> mac2_mode, MAC_CFG_2 );
                    884:   hp100_andb( HP100_MAC1MODEMASK, MAC_CFG_1 );
                    885:   hp100_orb( lp -> mac1_mode |
                    886:             HP100_RX_EN | HP100_RX_IDLE |              /* enable rx */
                    887:             HP100_TX_EN | HP100_TX_IDLE, MAC_CFG_1 );  /* enable tx */
                    888:   hp100_page( PERFORMANCE );
                    889:   hp100_ints_on();
                    890:   sti();
                    891: }
                    892: 
                    893: /*
                    894:  *  hardware interrupt handling
                    895:  */
                    896: 
                    897: static void hp100_interrupt( int irq, struct pt_regs *regs )
                    898: {
                    899:   struct device *dev = (struct device *)irq2dev_map[ irq ];
                    900:   struct hp100_private *lp;
                    901:   int ioaddr;
                    902:   u_short val;
                    903: 
                    904:   if ( dev == NULL ) return;
                    905:   ioaddr = dev -> base_addr;
                    906:   if ( dev -> interrupt )
                    907:     printk( "%s: re-entering the interrupt handler\n", dev -> name );
                    908:   hp100_ints_off();
                    909:   dev -> interrupt = 1;
                    910:   hp100_page( PERFORMANCE );
                    911:   val = hp100_inw( IRQ_STATUS );
                    912: #ifdef HP100_DEBUG_IRQ
                    913:   printk( "hp100_interrupt: irq_status = 0x%x\n", val );
                    914: #endif
                    915:   if ( val & HP100_RX_PACKET )
                    916:     {
                    917:       hp100_rx( dev );
                    918:       hp100_outw( HP100_RX_PACKET, IRQ_STATUS );
                    919:     }
                    920:   if ( val & (HP100_TX_SPACE_AVAIL | HP100_TX_COMPLETE) )
                    921:     {
                    922:       hp100_outw( val & (HP100_TX_SPACE_AVAIL | HP100_TX_COMPLETE), IRQ_STATUS );
                    923:     }
                    924:   if ( val & ( HP100_TX_ERROR | HP100_RX_ERROR ) )
                    925:     {
                    926:       lp = (struct hp100_private *)dev -> priv;
                    927:       hp100_update_stats( dev );
                    928:       hp100_outw( val & (HP100_TX_ERROR | HP100_RX_ERROR), IRQ_STATUS );
                    929:     }
                    930: #ifdef HP100_DEBUG_IRQ
                    931:   printk( "hp100_interrupt: end\n" );
                    932: #endif
                    933:   dev -> interrupt = 0;
                    934:   hp100_ints_on();
                    935: }
                    936: 
                    937: /*
                    938:  *  some misc functions
                    939:  */
                    940: 
                    941: static void hp100_start_interface( struct device *dev )
                    942: {
                    943:   int ioaddr = dev -> base_addr;
                    944:   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
                    945: 
                    946:   cli();
                    947:   hp100_unreset_card();
                    948:   hp100_page( MAC_CTRL );
                    949:   hp100_outb( lp -> mac2_mode, MAC_CFG_2 );
                    950:   hp100_andb( HP100_MAC1MODEMASK, MAC_CFG_1 );
                    951:   hp100_orb( lp -> mac1_mode |
                    952:              HP100_RX_EN | HP100_RX_IDLE |
                    953:              HP100_TX_EN | HP100_TX_IDLE, MAC_CFG_1 );
                    954:   hp100_page( PERFORMANCE );
                    955:   hp100_outw( HP100_INT_EN | HP100_SET_LB, OPTION_LSW );
                    956:   hp100_outw( HP100_TRI_INT | HP100_RESET_HB, OPTION_LSW );
                    957:   if ( lp -> mem_mapped )
                    958:     {
                    959:       /* enable memory mapping */
                    960:       hp100_outw( HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW );
                    961:     }
                    962:   sti();
                    963: } 
                    964: 
                    965: static void hp100_stop_interface( struct device *dev )
                    966: {
                    967:   int ioaddr = dev -> base_addr;
                    968:   u_short val;
                    969: 
                    970:   hp100_outw( HP100_INT_EN | HP100_RESET_LB | 
                    971:               HP100_TRI_INT | HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW );
                    972:   val = hp100_inw( OPTION_LSW );
                    973:   hp100_page( HW_MAP );
                    974:   hp100_andb( HP100_BM_SLAVE, BM );
                    975:   hp100_page( MAC_CTRL );
                    976:   hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 );
                    977:   if ( !(val & HP100_HW_RST) ) return;
                    978:   for ( val = 0; val < 6000; val++ )
                    979:     if ( ( hp100_inb( MAC_CFG_1 ) & (HP100_TX_IDLE | HP100_RX_IDLE) ) ==
                    980:                                     (HP100_TX_IDLE | HP100_RX_IDLE) )
                    981:       return;
                    982:   printk( "%s: hp100_stop_interface - timeout\n", dev -> name );
                    983: }
                    984: 
                    985: static void hp100_load_eeprom( struct device *dev )
                    986: {
                    987:   int i;
                    988:   int ioaddr = dev -> base_addr;
                    989: 
                    990:   hp100_page( EEPROM_CTRL );
                    991:   hp100_andw( ~HP100_EEPROM_LOAD, EEPROM_CTRL );
                    992:   hp100_orw( HP100_EEPROM_LOAD, EEPROM_CTRL );
                    993:   for ( i = 0; i < 6000; i++ )
                    994:     if ( !( hp100_inw( OPTION_MSW ) & HP100_EE_LOAD ) ) return;
                    995:   printk( "%s: hp100_load_eeprom - timeout\n", dev -> name );
                    996: }
                    997: 
                    998: /* return values: LAN_10, LAN_100 or LAN_ERR (not connected or hub is down)... */
                    999: 
                   1000: static int hp100_sense_lan( struct device *dev )
                   1001: {
                   1002:   int i;
                   1003:   int ioaddr = dev -> base_addr;
                   1004:   u_short val_VG, val_10;
                   1005:   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
                   1006: 
                   1007:   hp100_page( MAC_CTRL );
                   1008:   hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
                   1009:   val_10 = hp100_inw( LAN_CFG_10 );
                   1010:   val_VG = hp100_inw( LAN_CFG_VG );
                   1011: #ifdef HP100_DEBUG_SENSE
                   1012:   printk( "hp100_sense_lan: val_VG = 0x%04x, val_10 = 0x%04x\n", val_VG, val_10 );
                   1013: #endif
                   1014:   if ( val_10 & HP100_LINK_BEAT_ST ) return HP100_LAN_10;
                   1015:   if ( lp -> id -> id == 0x02019F022 ) /* HP J27248B doesn't have 100Mb/s interface */
                   1016:     return HP100_LAN_ERR;
                   1017:   for ( i = 0; i < 2500; i++ )
                   1018:     {
                   1019:       val_VG = hp100_inw( LAN_CFG_VG );
                   1020:       if ( val_VG & HP100_LINK_CABLE_ST ) return HP100_LAN_100;
                   1021:     }
                   1022:   return HP100_LAN_ERR;
                   1023: }
                   1024: 
                   1025: static int hp100_down_vg_link( struct device *dev )
                   1026: {
                   1027:   int ioaddr = dev -> base_addr;
                   1028:   unsigned long time;
                   1029:   int i;
                   1030: 
                   1031:   hp100_page( MAC_CTRL );
                   1032:   for ( i = 2500; i > 0; i-- )
                   1033:     if ( hp100_inw( LAN_CFG_VG ) & HP100_LINK_CABLE_ST ) break;
                   1034:   if ( i <= 0 )                                /* not signal - not logout */
                   1035:     return 0;
                   1036:   hp100_andw( ~HP100_LINK_CMD, LAN_CFG_VG );
                   1037:   time = jiffies + 10; 
                   1038:   while ( time > jiffies )
                   1039:     if ( !( hp100_inw( LAN_CFG_VG ) & ( HP100_LINK_UP_ST | 
                   1040:                                         HP100_LINK_CABLE_ST | 
                   1041:                                         HP100_LINK_GOOD_ST ) ) )
                   1042:       return 0;
                   1043: #ifdef HP100_DEBUG
                   1044:   printk( "hp100_down_vg_link: timeout\n" );
                   1045: #endif
                   1046:   return -EIO;
                   1047: }
                   1048: 
                   1049: static int hp100_login_to_vg_hub( struct device *dev )
                   1050: {
                   1051:   int i;
                   1052:   int ioaddr = dev -> base_addr;
                   1053:   u_short val;
                   1054:   unsigned long time;  
                   1055: 
                   1056:   hp100_page( MAC_CTRL );
                   1057:   hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
                   1058:   time = jiffies + ( HZ / 2 );
                   1059:   do {
                   1060:     if ( hp100_inw( LAN_CFG_VG ) & HP100_LINK_CABLE_ST ) break;
                   1061:   } while ( time > jiffies );
                   1062:   if ( time <= jiffies )
                   1063:     {
                   1064: #ifdef HP100_DEBUG
                   1065:       printk( "hp100_login_to_vg_hub: timeout for link\n" );
                   1066: #endif
                   1067:       return -EIO;
                   1068:     }
                   1069:     
                   1070:   if ( hp100_down_vg_link( dev ) < 0 ) /* if fail, try reset VG link */
                   1071:     {
                   1072:       hp100_andw( ~HP100_VG_RESET, LAN_CFG_VG );
                   1073:       hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
                   1074:     }
                   1075:   /* bring up link */
                   1076:   hp100_orw( HP100_LOAD_ADDR | HP100_LINK_CMD, LAN_CFG_VG );
                   1077:   for ( i = 2500; i > 0; i-- )
                   1078:     if ( hp100_inw( LAN_CFG_VG ) & HP100_LINK_CABLE_ST ) break;
                   1079:   if ( i <= 0 )
                   1080:     {
                   1081: #ifdef HP100_DEBUG
                   1082:       printk( "hp100_login_to_vg_hub: timeout for link (bring up)\n" );
                   1083: #endif
                   1084:       goto down_link;
                   1085:     }
                   1086: 
                   1087:   time = jiffies + ( HZ / 2 );
                   1088:   do {   
                   1089:     val = hp100_inw( LAN_CFG_VG );
                   1090:     if ( ( val & ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) ) == 
                   1091:                  ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) )
                   1092:       return 0;        /* success */
                   1093:   } while ( time > jiffies );
                   1094:   if ( val & HP100_LINK_GOOD_ST )
                   1095:     printk( "%s: 100Mb cable training failed, check cable.\n", dev -> name );
                   1096:    else
                   1097:     printk( "%s: 100Mb node not accepted by hub, check frame type or security.\n", dev -> name );
                   1098: 
                   1099: down_link:
                   1100:   hp100_down_vg_link( dev );
                   1101:   hp100_page( MAC_CTRL );
                   1102:   hp100_andw( ~( HP100_LOAD_ADDR | HP100_PROM_MODE ), LAN_CFG_VG );
                   1103:   hp100_orw( HP100_LINK_CMD, LAN_CFG_VG );
                   1104:   return -EIO;
                   1105: }
                   1106: 
                   1107: /*
                   1108:  *  module section
                   1109:  */
                   1110:  
                   1111: #ifdef MODULE
                   1112: 
                   1113: static int hp100_port = -1;
                   1114: 
                   1115: static char devicename[9] = { 0, };
                   1116: static struct device dev_hp100 = {
                   1117:        devicename, /* device name is inserted by linux/drivers/net/net_init.c */
                   1118:        0, 0, 0, 0,
                   1119:        0, 0,
                   1120:        0, 0, 0, NULL, hp100_probe
                   1121: };
                   1122: 
                   1123: int init_module( void )
                   1124: {
                   1125:   if (hp100_port == 0 && !EISA_bus)
                   1126:     printk("HP100: You should not use auto-probing with insmod!\n");
                   1127:   if ( hp100_port > 0 )
                   1128:     dev_hp100.base_addr = hp100_port;
                   1129:   if ( register_netdev( &dev_hp100 ) != 0 )
                   1130:     return -EIO;
                   1131:   return 0;
                   1132: }         
                   1133: 
                   1134: void cleanup_module( void )
                   1135: {
                   1136:   unregister_netdev( &dev_hp100 );
                   1137:   release_region( dev_hp100.base_addr, HP100_REGION_SIZE );
                   1138:   if ( ((struct hp100_private *)dev_hp100.priv) -> mem_ptr_virt )
                   1139:     vfree( ((struct hp100_private *)dev_hp100.priv) -> mem_ptr_virt );
                   1140:   kfree_s( dev_hp100.priv, sizeof( struct hp100_private ) );
                   1141:   dev_hp100.priv = NULL;
                   1142: }
                   1143: 
                   1144: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.