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

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