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

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