root/drivers/net/hp100.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hp100_probe
  2. hp100_probe1
  3. hp100_open
  4. hp100_close
  5. hp100_start_xmit
  6. hp100_rx
  7. hp100_get_stats
  8. hp100_update_stats
  9. hp100_clear_stats
  10. hp100_set_multicast_list
  11. hp100_interrupt
  12. hp100_start_interface
  13. hp100_stop_interface
  14. hp100_load_eeprom
  15. hp100_sense_lan
  16. hp100_down_vg_link
  17. hp100_login_to_vg_hub
  18. init_module
  19. cleanup_module

   1 /*
   2  * hp100.c: Hewlett Packard HP10/100VG ANY LAN ethernet driver for Linux.
   3  *
   4  * Author:  Jaroslav Kysela, <perex@pf.jcu.cz>
   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 <nelson@crynwr.com> 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 #ifdef MODULE
  86 #include <linux/module.h>
  87 #include <linux/version.h>
  88 #endif /* MODULE */
  89 
  90 #include <linux/kernel.h>
  91 #include <linux/sched.h>
  92 #include <linux/string.h>
  93 #include <linux/errno.h>
  94 #include <linux/ioport.h>
  95 #include <linux/malloc.h>
  96 #include <linux/interrupt.h>
  97 #include <linux/pci.h>
  98 #include <linux/bios32.h>
  99 #include <asm/bitops.h>
 100 #include <asm/io.h>
 101 
 102 #include <linux/netdevice.h>
 103 #include <linux/etherdevice.h>
 104 #include <linux/skbuff.h>
 105 
 106 #include <linux/types.h>
 107 
 108 #include "hp100.h"
 109 
 110 /*
 111  *  defines
 112  */
 113 
 114 #define HP100_BUS_ISA           0
 115 #define HP100_BUS_EISA          1
 116 #define HP100_BUS_PCI           2
 117 
 118 #define HP100_REGION_SIZE       0x20
 119 
 120 #define HP100_MAX_PACKET_SIZE   (1536+4)
 121 #define HP100_MIN_PACKET_SIZE   60
 122 
 123 #ifndef HP100_DEFAULT_RX_RATIO
 124 /* default - 65% onboard memory on the card are used for RX packets */
 125 #define HP100_DEFAULT_RX_RATIO  65
 126 #endif
 127 
 128 #ifndef HP100_DEFAULT_PRIORITY_TX
 129 /* default - don't enable transmit outgoing packets as priority */
 130 #define HP100_DEFAULT_PRIORITY_TX 0
 131 #endif
 132 
 133 /*
 134  *  structures
 135  */
 136 
 137 struct hp100_eisa_id {
 138   u_int id;
 139   const char *name;
 140   u_char bus;
 141 };
 142 
 143 struct hp100_private {
 144   struct hp100_eisa_id *id;
 145   u_short soft_model;
 146   u_int memory_size;
 147   u_short rx_ratio;                 /* 1 - 99 */
 148   u_short priority_tx;              /* != 0 - priority tx */
 149   short mem_mapped;                 /* memory mapped access */
 150   u_char *mem_ptr_virt;             /* virtual memory mapped area, maybe NULL */
 151   u_char *mem_ptr_phys;             /* physical memory mapped area */
 152   short lan_type;                   /* 10Mb/s, 100Mb/s or -1 (error) */
 153   int hub_status;                   /* login to hub was successfull? */
 154   u_char mac1_mode;
 155   u_char mac2_mode;
 156   struct enet_statistics stats;
 157 };
 158 
 159 /*
 160  *  variables
 161  */
 162  
 163 static struct hp100_eisa_id hp100_eisa_ids[] = {
 164 
 165   /* 10/100 EISA card with REVA Cascade chip */
 166   { 0x080F1F022, "HP J2577 rev A", HP100_BUS_EISA }, 
 167 
 168   /* 10/100 ISA card with REVA Cascade chip */
 169   { 0x050F1F022, "HP J2573 rev A", HP100_BUS_ISA },
 170 
 171   /* 10 only EISA card with Cascade chip */
 172   { 0x02019F022, "HP 27248B",      HP100_BUS_EISA }, 
 173 
 174   /* 10/100 EISA card with Cascade chip */
 175   { 0x04019F022, "HP J2577",       HP100_BUS_EISA },
 176 
 177   /* 10/100 ISA card with Cascade chip */
 178   { 0x05019F022, "HP J2573",       HP100_BUS_ISA },
 179 
 180   /* 10/100 PCI card */
 181   /* Note: ID for this card is same as PCI vendor/device numbers. */
 182   { 0x01030103c, "HP J2585",       HP100_BUS_PCI },
 183 };
 184 
 185 int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO;
 186 int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;
 187 
 188 /*
 189  *  prototypes
 190  */
 191 
 192 static int hp100_probe1( struct device *dev, int ioaddr, int bus );
 193 static int hp100_open( struct device *dev );
 194 static int hp100_close( struct device *dev );
 195 static int hp100_start_xmit( struct sk_buff *skb, struct device *dev );
 196 static void hp100_rx( struct device *dev );
 197 static struct enet_statistics *hp100_get_stats( struct device *dev );
 198 static void hp100_update_stats( struct device *dev );
 199 static void hp100_clear_stats( int ioaddr );
 200 #ifdef HAVE_MULTICAST
 201 static void hp100_set_multicast_list( struct device *dev, int num_addrs, void *addrs );
 202 #endif
 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 )
     /* [previous][next][first][last][top][bottom][index][help] */
 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 )
     /* [previous][next][first][last][top][bottom][index][help] */
 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 #ifdef HAVE_MULTICAST
 436   dev -> set_multicast_list = &hp100_set_multicast_list;
 437 #endif
 438 
 439   request_region( dev -> base_addr, HP100_REGION_SIZE, eid -> name );
 440 
 441   hp100_page( ID_MAC_ADDR );
 442   for ( i = uc = 0; i < 6; i++ )
 443     dev -> dev_addr[ i ] = hp100_inb( LAN_ADDR + i );
 444 
 445   hp100_clear_stats( ioaddr );
 446 
 447   ether_setup( dev );
 448 
 449   lp -> lan_type = hp100_sense_lan( dev );
 450      
 451   printk( "%s: %s at 0x%x, IRQ %d, ",
 452     dev -> name, lp -> id -> name, ioaddr, dev -> irq );
 453   switch ( bus ) {
 454     case HP100_BUS_EISA: printk( "EISA" ); break;
 455     case HP100_BUS_PCI:  printk( "PCI" );  break;
 456     default:             printk( "ISA" );  break;
 457   }
 458   printk( " bus, %dk SRAM (rx/tx %d%%).\n",
 459     lp -> memory_size >> ( 10 - 4 ), lp -> rx_ratio );
 460   if ( mem_mapped )
 461     {
 462       printk( "%s: Memory area at 0x%lx-0x%lx",
 463                 dev -> name, (u_long)mem_ptr_phys, (u_long)mem_ptr_phys + 0x1fff );
 464       if ( mem_ptr_virt )
 465         printk( " (virtual base 0x%lx)", (u_long)mem_ptr_virt );
 466       printk( ".\n" );
 467     }
 468   printk( "%s: ", dev -> name );
 469   if ( lp -> lan_type != HP100_LAN_ERR )
 470     printk( "Adapter is attached to " );
 471   switch ( lp -> lan_type ) {
 472     case HP100_LAN_100:
 473       printk( "100Mb/s Voice Grade AnyLAN network.\n" );
 474       break;
 475     case HP100_LAN_10:
 476       printk( "10Mb/s network.\n" );
 477       break;
 478     default:
 479       printk( "Warning! Link down.\n" );
 480   }
 481                 
 482   hp100_stop_interface( dev );
 483   
 484   return 0;
 485 }
 486 
 487 /*
 488  *  open/close functions
 489  */
 490 
 491 static int hp100_open( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
 492 {
 493   int i;
 494   int ioaddr = dev -> base_addr;
 495   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
 496 
 497   if ( request_irq( dev -> irq, hp100_interrupt, SA_INTERRUPT, lp -> id -> name ) )
 498     {
 499       printk( "%s: unable to get IRQ %d\n", dev -> name, dev -> irq );
 500       return -EAGAIN;
 501     }
 502   irq2dev_map[ dev -> irq ] = dev;
 503 
 504 #ifdef MODULE
 505   MOD_INC_USE_COUNT;
 506 #endif
 507   
 508   dev -> tbusy = 0;
 509   dev -> trans_start = jiffies;
 510   dev -> interrupt = 0;
 511   dev -> start = 1;
 512 
 513   lp -> lan_type = hp100_sense_lan( dev );
 514   lp -> mac1_mode = HP100_MAC1MODE3;
 515   lp -> mac2_mode = HP100_MAC2MODE3;
 516   
 517   hp100_page( MAC_CTRL );
 518   hp100_orw( HP100_LINK_BEAT_DIS | HP100_RESET_LB, LAN_CFG_10 );
 519 
 520   hp100_stop_interface( dev );
 521   hp100_load_eeprom( dev );
 522 
 523   hp100_outw( HP100_MMAP_DIS | HP100_SET_HB | 
 524               HP100_IO_EN | HP100_SET_LB, OPTION_LSW );
 525   hp100_outw( HP100_DEBUG_EN | HP100_RX_HDR | HP100_EE_EN | HP100_RESET_HB |
 526               HP100_FAKE_INT | HP100_RESET_LB, OPTION_LSW );
 527   hp100_outw( HP100_ADV_NXT_PKT | HP100_TX_CMD | HP100_RESET_LB |
 528                 HP100_PRIORITY_TX | ( hp100_priority_tx ? HP100_SET_HB : HP100_RESET_HB ),
 529               OPTION_MSW );
 530                                         
 531   hp100_page( MAC_ADDRESS );
 532   for ( i = 0; i < 6; i++ )
 533     hp100_outb( dev -> dev_addr[ i ], MAC_ADDR + i );
 534   for ( i = 0; i < 8; i++ )             /* setup multicast filter to receive all */
 535     hp100_outb( 0xff, HASH_BYTE0 + i );
 536   hp100_page( PERFORMANCE );
 537   hp100_outw( 0xfefe, IRQ_MASK );       /* mask off all ints */
 538   hp100_outw( 0xffff, IRQ_STATUS );     /* ack IRQ */
 539   hp100_outw( (HP100_RX_PACKET | HP100_RX_ERROR | HP100_SET_HB) |
 540               (HP100_TX_ERROR | HP100_SET_LB ), IRQ_MASK );
 541                                         /* and enable few */
 542   hp100_reset_card();
 543   hp100_page( MMU_CFG );
 544   hp100_outw( ( lp -> memory_size * lp -> rx_ratio ) / 100, RX_MEM_STOP );
 545   hp100_outw( lp -> memory_size - 1, TX_MEM_STOP );
 546   hp100_unreset_card();
 547 
 548   if ( lp -> lan_type == HP100_LAN_100 )
 549     lp -> hub_status = hp100_login_to_vg_hub( dev );
 550 
 551   hp100_start_interface( dev );
 552 
 553   return 0;
 554 }
 555 
 556 static int hp100_close( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
 557 {
 558   int ioaddr = dev -> base_addr;
 559   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
 560 
 561   hp100_page( PERFORMANCE );
 562   hp100_outw( 0xfefe, IRQ_MASK );               /* mask off all IRQs */
 563 
 564   hp100_stop_interface( dev );
 565 
 566   if ( lp -> lan_type == HP100_LAN_100 )        /* relogin */
 567     hp100_login_to_vg_hub( dev );
 568 
 569   dev -> tbusy = 1;
 570   dev -> start = 0;
 571 
 572   free_irq( dev -> irq );
 573   irq2dev_map[ dev -> irq ] = NULL;
 574 #ifdef MODULE
 575   MOD_DEC_USE_COUNT;
 576 #endif
 577   return 0;
 578 }
 579 
 580 /* 
 581  *  transmit
 582  */
 583 
 584 static int hp100_start_xmit( struct sk_buff *skb, struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
 585 {
 586   int i, ok_flag;
 587   int ioaddr = dev -> base_addr;
 588   u_short val;
 589   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
 590 
 591   if ( lp -> lan_type < 0 )
 592     {
 593       hp100_stop_interface( dev );
 594       if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) < 0 )
 595         {
 596           printk( "%s: no connection found - check wire\n", dev -> name );
 597           hp100_start_interface( dev ); /* 10Mb/s RX packets maybe handled */
 598           return -EIO;
 599         }
 600       if ( lp -> lan_type == HP100_LAN_100 )
 601         lp -> hub_status = hp100_login_to_vg_hub( dev );
 602       hp100_start_interface( dev );
 603     }
 604   
 605   if ( ( i = ( hp100_inl( TX_MEM_FREE ) & ~0x7fffffff ) ) < skb -> len + 16 )
 606     {
 607 #ifdef HP100_DEBUG
 608       printk( "hp100_start_xmit: rx free mem = 0x%x\n", i );
 609 #endif
 610       if ( jiffies - dev -> trans_start < 2 * HZ ) return -EAGAIN;
 611       if ( lp -> lan_type == HP100_LAN_100 && lp -> hub_status < 0 )
 612                                 /* 100Mb/s adapter isn't connected to hub */
 613         {
 614           printk( "%s: login to 100Mb/s hub retry\n", dev -> name );
 615           hp100_stop_interface( dev );
 616           lp -> hub_status = hp100_login_to_vg_hub( dev );
 617           hp100_start_interface( dev );
 618         }
 619        else
 620         {
 621           hp100_ints_off();
 622           i = hp100_sense_lan( dev );
 623           hp100_page( PERFORMANCE );
 624           hp100_ints_on();
 625           if ( i == HP100_LAN_ERR )
 626             printk( "%s: link down detected\n", dev -> name );
 627            else
 628           if ( lp -> lan_type != i )
 629             {
 630               /* it's very heavy - all network setting must be changed!!! */
 631               printk( "%s: cable change 10Mb/s <-> 100Mb/s detected\n", dev -> name );
 632               lp -> lan_type = i;
 633               hp100_stop_interface( dev );
 634               if ( lp -> lan_type == HP100_LAN_100 )
 635                 lp -> hub_status = hp100_login_to_vg_hub( dev );
 636               hp100_start_interface( dev );
 637             }
 638            else
 639             {
 640               printk( "%s: interface reset\n", dev -> name );
 641               hp100_stop_interface( dev );
 642               hp100_start_interface( dev );
 643             }
 644         }
 645       dev -> trans_start = jiffies;
 646       return -EAGAIN;
 647     }
 648     
 649   if ( skb == NULL )
 650     {
 651       dev_tint( dev );
 652       return 0;
 653     }
 654     
 655   if ( skb -> len <= 0 ) return 0;
 656 
 657   for ( i = 0; i < 6000 && ( hp100_inw( OPTION_MSW ) & HP100_TX_CMD ); i++ )
 658     {
 659 #ifdef HP100_DEBUG_TX
 660       printk( "hp100_start_xmit: busy\n" );
 661 #endif    
 662     }
 663 
 664   hp100_ints_off();
 665   val = hp100_inw( IRQ_STATUS );
 666   hp100_outw( val & HP100_TX_COMPLETE, IRQ_STATUS );
 667 #ifdef HP100_DEBUG_TX
 668   printk( "hp100_start_xmit: irq_status = 0x%x, len = %d\n", val, (int)skb -> len );
 669 #endif
 670   ok_flag = skb -> len >= HP100_MIN_PACKET_SIZE;
 671   i = ok_flag ? skb -> len : HP100_MIN_PACKET_SIZE;
 672   hp100_outw( i, DATA32 );              /* length to memory manager */
 673   hp100_outw( i, FRAGMENT_LEN );
 674   if ( lp -> mem_mapped )
 675     {
 676       if ( lp -> mem_ptr_virt )
 677         {
 678           memcpy( lp -> mem_ptr_virt, skb -> data, skb -> len );
 679           if ( !ok_flag )
 680             memset( lp -> mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb -> len );
 681         }
 682        else
 683         {
 684           memcpy_toio( lp -> mem_ptr_phys, skb -> data, skb -> len );
 685           if ( !ok_flag )
 686             memset_io( lp -> mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb -> len );
 687         }
 688     }
 689    else
 690     {
 691       outsl( ioaddr + HP100_REG_DATA32, skb -> data, ( skb -> len + 3 ) >> 2 );
 692       if ( !ok_flag )
 693         for ( i = ( skb -> len + 3 ) & ~3; i < HP100_MIN_PACKET_SIZE; i += 4 )
 694           hp100_outl( 0, DATA32 );
 695     }
 696   hp100_outw( HP100_TX_CMD | HP100_SET_LB, OPTION_MSW ); /* send packet */
 697   lp -> stats.tx_packets++;
 698   dev -> trans_start = jiffies;
 699   hp100_ints_on();
 700 
 701   dev_kfree_skb( skb, FREE_WRITE );
 702 
 703 #ifdef HP100_DEBUG_TX
 704   printk( "hp100_start_xmit: end\n" );
 705 #endif
 706 
 707   return 0;
 708 }
 709 
 710 /*
 711  *  receive - called from interrupt handler
 712  */
 713 
 714 static void hp100_rx( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
 715 {
 716   int packets, pkt_len;
 717   int ioaddr = dev -> base_addr;
 718   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
 719   u_int header;
 720   struct sk_buff *skb;
 721 
 722 #if 0
 723   if ( lp -> lan_type < 0 )
 724     {
 725       if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) == HP100_LAN_100 )
 726         lp -> hub_status = hp100_login_to_vg_hub( dev );
 727       hp100_page( PERFORMANCE );
 728     }
 729 #endif
 730   
 731   packets = hp100_inb( RX_PKT_CNT );
 732 #ifdef HP100_DEBUG
 733   if ( packets > 1 )
 734     printk( "hp100_rx: waiting packets = %d\n", packets );
 735 #endif
 736   while ( packets-- > 0 )
 737     {
 738       for ( pkt_len = 0; pkt_len < 6000 && ( hp100_inw( OPTION_MSW ) & HP100_ADV_NXT_PKT ); pkt_len++ )
 739         {
 740 #ifdef HP100_DEBUG_TX
 741           printk( "hp100_rx: busy, remaining packets = %d\n", packets );
 742 #endif    
 743         }
 744       if ( lp -> mem_mapped )
 745         {
 746           if ( lp -> mem_ptr_virt )
 747             header = *(__u32 *)lp -> mem_ptr_virt;
 748            else
 749             header = readl( lp -> mem_ptr_phys );
 750         }
 751        else
 752         header = hp100_inl( DATA32 );
 753       pkt_len = header & HP100_PKT_LEN_MASK;
 754 #ifdef HP100_DEBUG_RX
 755       printk( "hp100_rx: new packet - length = %d, errors = 0x%x, dest = 0x%x\n",
 756         header & HP100_PKT_LEN_MASK, ( header >> 16 ) & 0xfff8, ( header >> 16 ) & 7 );
 757 #endif
 758       /*
 759        * NOTE! This (and the skb_put() below) depends on the skb-functions
 760        * allocating more than asked (notably, aligning the request up to
 761        * the next 16-byte length).
 762        */
 763       skb = dev_alloc_skb( pkt_len );
 764       if ( skb == NULL )
 765         {
 766 #ifdef HP100_DEBUG
 767           printk( "hp100_rx: couldn't allocate a sk_buff of size %d\n", pkt_len );
 768 #endif
 769           lp -> stats.rx_dropped++;
 770         }
 771        else
 772         {
 773           u_char *ptr;
 774         
 775           skb -> dev = dev;
 776           ptr = (u_char *)skb_put( skb, pkt_len );
 777           if ( lp -> mem_mapped )
 778             {
 779               if ( lp -> mem_ptr_virt )
 780                 memcpy( ptr, lp -> mem_ptr_virt, ( pkt_len + 3 ) & ~3 );
 781                else
 782                 memcpy_fromio( ptr, lp -> mem_ptr_phys, ( pkt_len + 3 ) & ~3 );
 783             }
 784            else
 785             insl( ioaddr + HP100_REG_DATA32, ptr, ( pkt_len + 3 ) >> 2 );
 786           skb -> protocol = eth_type_trans( skb, dev );
 787           netif_rx( skb );
 788           lp -> stats.rx_packets++;
 789 #ifdef HP100_DEBUG_RX
 790           printk( "rx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
 791                 ptr[ 0 ], ptr[ 1 ], ptr[ 2 ], ptr[ 3 ], ptr[ 4 ], ptr[ 5 ],
 792                 ptr[ 6 ], ptr[ 7 ], ptr[ 8 ], ptr[ 9 ], ptr[ 10 ], ptr[ 11 ] );
 793 #endif
 794         }
 795       hp100_outw( HP100_ADV_NXT_PKT | HP100_SET_LB, OPTION_MSW );
 796       switch ( header & 0x00070000 ) {
 797         case (HP100_MULTI_ADDR_HASH<<16):
 798         case (HP100_MULTI_ADDR_NO_HASH<<16):
 799           lp -> stats.multicast++; break;
 800       }
 801     }
 802 #ifdef HP100_DEBUG_RX
 803    printk( "hp100_rx: end\n" );
 804 #endif
 805 }
 806 
 807 /*
 808  *  statistics
 809  */
 810  
 811 static struct enet_statistics *hp100_get_stats( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
 812 {
 813   int ioaddr = dev -> base_addr;
 814 
 815   hp100_ints_off();
 816   hp100_update_stats( dev );
 817   hp100_ints_on();
 818   return &((struct hp100_private *)dev -> priv) -> stats;
 819 }
 820 
 821 static void hp100_update_stats( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
 822 {
 823   int ioaddr = dev -> base_addr;
 824   u_short val;
 825   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
 826          
 827   hp100_page( MAC_CTRL );               /* get all statistics bytes */
 828   val = hp100_inw( DROPPED ) & 0x0fff;
 829   lp -> stats.rx_errors += val;
 830   lp -> stats.rx_over_errors += val;
 831   val = hp100_inb( CRC );
 832   lp -> stats.rx_errors += val;
 833   lp -> stats.rx_crc_errors += val;
 834   val = hp100_inb( ABORT );
 835   lp -> stats.tx_errors += val;
 836   lp -> stats.tx_aborted_errors += val;
 837   hp100_page( PERFORMANCE );
 838 }
 839 
 840 static void hp100_clear_stats( int ioaddr )
     /* [previous][next][first][last][top][bottom][index][help] */
 841 {
 842   cli();
 843   hp100_page( MAC_CTRL );               /* get all statistics bytes */
 844   hp100_inw( DROPPED );
 845   hp100_inb( CRC );
 846   hp100_inb( ABORT );
 847   hp100_page( PERFORMANCE );
 848   sti();
 849 }
 850 
 851 /*
 852  *  multicast setup
 853  */
 854 
 855 #ifdef HAVE_MULTICAST
 856 
 857 /*
 858  *  Set or clear the multicast filter for this adapter.
 859  *
 860  *  num_addrs == -1             Promiscuous mode, receive all packets
 861  *  num_addrs == 0              Normal mode, clear multicast list
 862  *  num_addrs > 0               Multicast mode, receive normal and MC packets,
 863  *                              best-effort filtering.
 864  */
 865                                                           
 866 static void hp100_set_multicast_list( struct device *dev, int num_addrs, void *addrs )
     /* [previous][next][first][last][top][bottom][index][help] */
 867 {
 868   int ioaddr = dev -> base_addr;
 869   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
 870 
 871 #ifdef HP100_DEBUG_MULTI
 872   printk( "hp100_set_multicast_list: num_addrs = %d\n", num_addrs );
 873 #endif
 874   cli();
 875   hp100_ints_off();
 876   hp100_page( MAC_CTRL );
 877   hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 );        /* stop rx/tx */
 878 
 879   if ( num_addrs < 0 )
 880     {
 881       lp -> mac2_mode = HP100_MAC2MODE6;  /* promiscuous mode, all good */
 882       lp -> mac1_mode = HP100_MAC1MODE6;  /* packets on the net */
 883     }
 884    else
 885   if ( num_addrs > 0 )
 886     {
 887       lp -> mac2_mode = HP100_MAC2MODE5;  /* multicast mode, packets for me */
 888       lp -> mac1_mode = HP100_MAC1MODE5;  /* broadcasts and all multicasts */
 889     }
 890    else
 891     {
 892       lp -> mac2_mode = HP100_MAC2MODE3;  /* normal mode, packets for me */
 893       lp -> mac1_mode = HP100_MAC1MODE3;  /* and broadcasts */
 894     }
 895 
 896   hp100_outb( lp -> mac2_mode, MAC_CFG_2 );
 897   hp100_andb( HP100_MAC1MODEMASK, MAC_CFG_1 );
 898   hp100_orb( lp -> mac1_mode |
 899              HP100_RX_EN | HP100_RX_IDLE |              /* enable rx */
 900              HP100_TX_EN | HP100_TX_IDLE, MAC_CFG_1 );  /* enable tx */
 901   hp100_page( PERFORMANCE );
 902   hp100_ints_on();
 903   sti();
 904 }
 905 
 906 #endif /* HAVE_MULTICAST */
 907 
 908 /*
 909  *  hardware interrupt handling
 910  */
 911 
 912 static void hp100_interrupt( int irq, struct pt_regs *regs )
     /* [previous][next][first][last][top][bottom][index][help] */
 913 {
 914   struct device *dev = (struct device *)irq2dev_map[ irq ];
 915   struct hp100_private *lp;
 916   int ioaddr;
 917   u_short val;
 918 
 919   if ( dev == NULL ) return;
 920   ioaddr = dev -> base_addr;
 921   if ( dev -> interrupt )
 922     printk( "%s: re-entering the interrupt handler\n", dev -> name );
 923   hp100_ints_off();
 924   dev -> interrupt = 1;
 925   hp100_page( PERFORMANCE );
 926   val = hp100_inw( IRQ_STATUS );
 927 #ifdef HP100_DEBUG_IRQ
 928   printk( "hp100_interrupt: irq_status = 0x%x\n", val );
 929 #endif
 930   if ( val & HP100_RX_PACKET )
 931     {
 932       hp100_rx( dev );
 933       hp100_outw( HP100_RX_PACKET, IRQ_STATUS );
 934     }
 935   if ( val & (HP100_TX_SPACE_AVAIL | HP100_TX_COMPLETE) )
 936     {
 937       hp100_outw( val & (HP100_TX_SPACE_AVAIL | HP100_TX_COMPLETE), IRQ_STATUS );
 938     }
 939   if ( val & ( HP100_TX_ERROR | HP100_RX_ERROR ) )
 940     {
 941       lp = (struct hp100_private *)dev -> priv;
 942       hp100_update_stats( dev );
 943       hp100_outw( val & (HP100_TX_ERROR | HP100_RX_ERROR), IRQ_STATUS );
 944     }
 945 #ifdef HP100_DEBUG_IRQ
 946   printk( "hp100_interrupt: end\n" );
 947 #endif
 948   dev -> interrupt = 0;
 949   hp100_ints_on();
 950 }
 951 
 952 /*
 953  *  some misc functions
 954  */
 955 
 956 static void hp100_start_interface( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
 957 {
 958   int ioaddr = dev -> base_addr;
 959   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
 960 
 961   cli();
 962   hp100_unreset_card();
 963   hp100_page( MAC_CTRL );
 964   hp100_outb( lp -> mac2_mode, MAC_CFG_2 );
 965   hp100_andb( HP100_MAC1MODEMASK, MAC_CFG_1 );
 966   hp100_orb( lp -> mac1_mode |
 967              HP100_RX_EN | HP100_RX_IDLE |
 968              HP100_TX_EN | HP100_TX_IDLE, MAC_CFG_1 );
 969   hp100_page( PERFORMANCE );
 970   hp100_outw( HP100_INT_EN | HP100_SET_LB, OPTION_LSW );
 971   hp100_outw( HP100_TRI_INT | HP100_RESET_HB, OPTION_LSW );
 972   if ( lp -> mem_mapped )
 973     {
 974       /* enable memory mapping */
 975       hp100_outw( HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW );
 976     }
 977   sti();
 978 } 
 979 
 980 static void hp100_stop_interface( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
 981 {
 982   int ioaddr = dev -> base_addr;
 983   u_short val;
 984 
 985   hp100_outw( HP100_INT_EN | HP100_RESET_LB | 
 986               HP100_TRI_INT | HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW );
 987   val = hp100_inw( OPTION_LSW );
 988   hp100_page( HW_MAP );
 989   hp100_andb( HP100_BM_SLAVE, BM );
 990   hp100_page( MAC_CTRL );
 991   hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 );
 992   if ( !(val & HP100_HW_RST) ) return;
 993   for ( val = 0; val < 6000; val++ )
 994     if ( ( hp100_inb( MAC_CFG_1 ) & (HP100_TX_IDLE | HP100_RX_IDLE) ) ==
 995                                     (HP100_TX_IDLE | HP100_RX_IDLE) )
 996       return;
 997   printk( "%s: hp100_stop_interface - timeout\n", dev -> name );
 998 }
 999 
1000 static void hp100_load_eeprom( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
1001 {
1002   int i;
1003   int ioaddr = dev -> base_addr;
1004 
1005   hp100_page( EEPROM_CTRL );
1006   hp100_andw( ~HP100_EEPROM_LOAD, EEPROM_CTRL );
1007   hp100_orw( HP100_EEPROM_LOAD, EEPROM_CTRL );
1008   for ( i = 0; i < 6000; i++ )
1009     if ( !( hp100_inw( OPTION_MSW ) & HP100_EE_LOAD ) ) return;
1010   printk( "%s: hp100_load_eeprom - timeout\n", dev -> name );
1011 }
1012 
1013 /* return values: LAN_10, LAN_100 or LAN_ERR (not connected or hub is down)... */
1014 
1015 static int hp100_sense_lan( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
1016 {
1017   int i;
1018   int ioaddr = dev -> base_addr;
1019   u_short val_VG, val_10;
1020   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
1021 
1022   hp100_page( MAC_CTRL );
1023   hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
1024   val_10 = hp100_inw( LAN_CFG_10 );
1025   val_VG = hp100_inw( LAN_CFG_VG );
1026 #ifdef HP100_DEBUG_SENSE
1027   printk( "hp100_sense_lan: val_VG = 0x%04x, val_10 = 0x%04x\n", val_VG, val_10 );
1028 #endif
1029   if ( val_10 & HP100_LINK_BEAT_ST ) return HP100_LAN_10;
1030   if ( lp -> id -> id == 0x02019F022 ) /* HP J27248B doesn't have 100Mb/s interface */
1031     return HP100_LAN_ERR;
1032   for ( i = 0; i < 2500; i++ )
1033     {
1034       val_VG = hp100_inw( LAN_CFG_VG );
1035       if ( val_VG & HP100_LINK_CABLE_ST ) return HP100_LAN_100;
1036     }
1037   return HP100_LAN_ERR;
1038 }
1039 
1040 static int hp100_down_vg_link( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
1041 {
1042   int ioaddr = dev -> base_addr;
1043   unsigned long time;
1044   int i;
1045 
1046   hp100_page( MAC_CTRL );
1047   for ( i = 2500; i > 0; i-- )
1048     if ( hp100_inw( LAN_CFG_VG ) & HP100_LINK_CABLE_ST ) break;
1049   if ( i <= 0 )                         /* not signal - not logout */
1050     return 0;
1051   hp100_andw( ~HP100_LINK_CMD, LAN_CFG_VG );
1052   time = jiffies + 10; 
1053   while ( time > jiffies )
1054     if ( !( hp100_inw( LAN_CFG_VG ) & ( HP100_LINK_UP_ST | 
1055                                         HP100_LINK_CABLE_ST | 
1056                                         HP100_LINK_GOOD_ST ) ) )
1057       return 0;
1058 #ifdef HP100_DEBUG
1059   printk( "hp100_down_vg_link: timeout\n" );
1060 #endif
1061   return -EIO;
1062 }
1063 
1064 static int hp100_login_to_vg_hub( struct device *dev )
     /* [previous][next][first][last][top][bottom][index][help] */
1065 {
1066   int i;
1067   int ioaddr = dev -> base_addr;
1068   u_short val;
1069   unsigned long time;  
1070 
1071   hp100_page( MAC_CTRL );
1072   hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
1073   time = jiffies + ( HZ / 2 );
1074   do {
1075     if ( hp100_inw( LAN_CFG_VG ) & HP100_LINK_CABLE_ST ) break;
1076   } while ( time > jiffies );
1077   if ( time <= jiffies )
1078     {
1079 #ifdef HP100_DEBUG
1080       printk( "hp100_login_to_vg_hub: timeout for link\n" );
1081 #endif
1082       return -EIO;
1083     }
1084     
1085   if ( hp100_down_vg_link( dev ) < 0 )  /* if fail, try reset VG link */
1086     {
1087       hp100_andw( ~HP100_VG_RESET, LAN_CFG_VG );
1088       hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
1089     }
1090   /* bring up link */
1091   hp100_orw( HP100_LOAD_ADDR | HP100_LINK_CMD, LAN_CFG_VG );
1092   for ( i = 2500; i > 0; i-- )
1093     if ( hp100_inw( LAN_CFG_VG ) & HP100_LINK_CABLE_ST ) break;
1094   if ( i <= 0 )
1095     {
1096 #ifdef HP100_DEBUG
1097       printk( "hp100_login_to_vg_hub: timeout for link (bring up)\n" );
1098 #endif
1099       goto down_link;
1100     }
1101 
1102   time = jiffies + ( HZ / 2 );
1103   do {   
1104     val = hp100_inw( LAN_CFG_VG );
1105     if ( ( val & ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) ) == 
1106                  ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) )
1107       return 0; /* success */
1108   } while ( time > jiffies );
1109   if ( val & HP100_LINK_GOOD_ST )
1110     printk( "%s: 100Mb cable training failed, check cable.\n", dev -> name );
1111    else
1112     printk( "%s: 100Mb node not accepted by hub, check frame type or security.\n", dev -> name );
1113 
1114 down_link:
1115   hp100_down_vg_link( dev );
1116   hp100_page( MAC_CTRL );
1117   hp100_andw( ~( HP100_LOAD_ADDR | HP100_PROM_MODE ), LAN_CFG_VG );
1118   hp100_orw( HP100_LINK_CMD, LAN_CFG_VG );
1119   return -EIO;
1120 }
1121 
1122 /*
1123  *  module section
1124  */
1125  
1126 #ifdef MODULE
1127 
1128 char kernel_version[] = UTS_RELEASE;
1129 
1130 static int hp100_port = -1;
1131 
1132 static char devicename[9] = { 0, };
1133 static struct device dev_hp100 = {
1134         devicename, /* device name is inserted by linux/drivers/net/net_init.c */
1135         0, 0, 0, 0,
1136         0, 0,
1137         0, 0, 0, NULL, hp100_probe
1138 };
1139 
1140 int init_module( void )
     /* [previous][next][first][last][top][bottom][index][help] */
1141 {
1142   if (hp100_port == 0 && !EISA_bus)
1143     printk("HP100: You should not use auto-probing with insmod!\n");
1144   if ( hp100_port > 0 )
1145     dev_hp100.base_addr = hp100_port;
1146   if ( register_netdev( &dev_hp100 ) != 0 )
1147     return -EIO;
1148   return 0;
1149 }         
1150 
1151 void cleanup_module( void )
     /* [previous][next][first][last][top][bottom][index][help] */
1152 {
1153   unregister_netdev( &dev_hp100 );
1154   release_region( dev_hp100.base_addr, HP100_REGION_SIZE );
1155   if ( ((struct hp100_private *)dev_hp100.priv) -> mem_ptr_virt )
1156     vfree( ((struct hp100_private *)dev_hp100.priv) -> mem_ptr_virt );
1157   kfree_s( dev_hp100.priv, sizeof( struct hp100_private ) );
1158   dev_hp100.priv = NULL;
1159 }
1160 
1161 #endif

/* [previous][next][first][last][top][bottom][index][help] */