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

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