⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hp100.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
/*** hp100.c ** HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters**** $Id: hp100.c,v 1.1 1999/04/26 05:52:18 tb Exp $**** Based on the HP100 driver written by Jaroslav Kysela <perex@jcu.cz>** Extended for new busmaster capable chipsets by ** Siegfried "Frieder" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>**** Maintained by: Jaroslav Kysela <perex@jcu.cz>** ** This driver has only been tested with** -- HP J2585B 10/100 Mbit/s PCI Busmaster** -- HP J2585A 10/100 Mbit/s PCI ** -- HP J2970  10 Mbit/s PCI Combo 10base-T/BNC** -- HP J2973  10 Mbit/s PCI 10base-T** -- HP J2573  10/100 ISA** -- Compex ReadyLink ENET100-VG4  10/100 Mbit/s PCI / EISA** -- Compex FreedomLine 100/VG  10/100 Mbit/s ISA / EISA / PCI** ** but it should also work with the other CASCADE based adapters.**** TODO:**       -  J2573 seems to hang sometimes when in shared memory mode.**       -  Mode for Priority TX**       -  Check PCI registers, performance might be improved?**       -  To reduce interrupt load in busmaster, one could switch off**          the interrupts that are used to refill the queues whenever the**          queues are filled up to more than a certain threshold.**       -  some updates for EISA version of card****** This source/code is public free; you can distribute it and/or modify ** it under terms of the GNU General Public License (published by the** Free Software Foundation) either version two of this License, or any ** later version.**** 1.55 -> 1.56**   - removed printk in misc. interrupt and update statistics to allow**     monitoring of card status**   - timing changes in xmit routines, relogin to 100VG hub added when**     driver does reset**   - included fix for Compex FreedomLine PCI adapter** ** 1.54 -> 1.55**   - fixed bad initialization in init_module**   - added Compex FreedomLine adapter**   - some fixes in card initialization**** 1.53 -> 1.54**   - added hardware multicast filter support (doesn't work)**   - little changes in hp100_sense_lan routine **     - added support for Coax and AUI (J2970)**   - fix for multiple cards and hp100_mode parameter (insmod)**   - fix for shared IRQ **** 1.52 -> 1.53**   - fixed bug in multicast support***/#define HP100_DEFAULT_PRIORITY_TX 0 #undef HP100_DEBUG#undef HP100_DEBUG_B           /* Trace  */#undef HP100_DEBUG_BM          /* Debug busmaster code (PDL stuff) */#undef HP100_DEBUG_TRAINING    /* Debug login-to-hub procedure */#undef HP100_DEBUG_TX   #undef HP100_DEBUG_IRQ #undef HP100_DEBUG_RX #undef HP100_MULTICAST_FILTER  /* Need to be debugged... */#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/ioport.h>#include <linux/malloc.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/bios32.h>#include <asm/bitops.h>#include <asm/io.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/types.h>#include <linux/config.h>  /* for CONFIG_PCI */#include <linux/delay.h>#if LINUX_VERSION_CODE < 0x020100#define ioremap vremap#define iounmap vfreetypedef struct enet_statistics hp100_stats_t;#else#define LINUX_2_1typedef struct net_device_stats hp100_stats_t;#endif#ifndef __initfunc#define __initfunc(__initarg) __initarg#else#include <linux/init.h>#endif#include "hp100.h"/* *  defines */#define HP100_BUS_ISA     0#define HP100_BUS_EISA    1#define HP100_BUS_PCI     2#ifndef PCI_DEVICE_ID_HP_J2585B#define PCI_DEVICE_ID_HP_J2585B 0x1031#endif#ifndef PCI_VENDOR_ID_COMPEX#define PCI_VENDOR_ID_COMPEX 0x11f6#endif#ifndef PCI_DEVICE_ID_COMPEX_ENET100VG4#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112#endif#ifndef PCI_VENDOR_ID_COMPEX2#define PCI_VENDOR_ID_COMPEX2 0x101a#endif#ifndef PCI_DEVICE_ID_COMPEX2_100VG#define PCI_DEVICE_ID_COMPEX2_100VG 0x0005#endif#define HP100_REGION_SIZE  0x20 /* for ioports */#define HP100_MAX_PACKET_SIZE  (1536+4)#define HP100_MIN_PACKET_SIZE  60#ifndef HP100_DEFAULT_RX_RATIO/* default - 75% onboard memory on the card are used for RX packets */#define HP100_DEFAULT_RX_RATIO  75#endif#ifndef HP100_DEFAULT_PRIORITY_TX/* default - don't enable transmit outgoing packets as priority */#define HP100_DEFAULT_PRIORITY_TX 0#endif/* *  structures */struct hp100_eisa_id {  u_int id;  const char *name;  u_char bus;};struct hp100_pci_id {  u_short vendor;  u_short device;};struct hp100_private {  struct hp100_eisa_id *id;  u_short chip;  u_short soft_model;  u_int memory_size;   u_int virt_memory_size;  u_short rx_ratio;       /* 1 - 99 */  u_short priority_tx;    /* != 0 - priority tx */  u_short mode;           /* PIO, Shared Mem or Busmaster */  u_char bus;  u_char pci_bus;  u_char pci_device_fn;  short mem_mapped;	  /* memory mapped access */  u_int *mem_ptr_virt;    /* virtual memory mapped area, maybe NULL */  u_int *mem_ptr_phys;	  /* physical memory mapped area */  short lan_type;	  /* 10Mb/s, 100Mb/s or -1 (error) */  int hub_status;	  /* was login to hub successful? */  u_char mac1_mode;  u_char mac2_mode;  u_char hash_bytes[ 8 ];  hp100_stats_t stats;  /* Rings for busmaster mode: */  hp100_ring_t *rxrhead;  /* Head (oldest) index into rxring */  hp100_ring_t *rxrtail;  /* Tail (newest) index into rxring */  hp100_ring_t *txrhead;  /* Head (oldest) index into txring */  hp100_ring_t *txrtail;  /* Tail (newest) index into txring */  hp100_ring_t rxring[ MAX_RX_PDL ];  hp100_ring_t txring[ MAX_TX_PDL ];  u_int *page_vaddr;      /* Virtual address of allocated page */  u_int *page_vaddr_algn; /* Aligned virtual address of allocated page */  int rxrcommit;          /* # Rx PDLs commited to adapter */  int txrcommit;          /* # Tx PDLs commited to adapter */};/* *  variables */static struct hp100_eisa_id hp100_eisa_ids[] = {  /* 10/100 EISA card with revision A Cascade chip */  { 0x80F1F022, "HP J2577 rev A", HP100_BUS_EISA },  /* 10/100 ISA card with revision A Cascade chip */  { 0x50F1F022, "HP J2573 rev A", HP100_BUS_ISA },  /* 10 only EISA card with Cascade chip */  { 0x2019F022, "HP 27248B",      HP100_BUS_EISA },  /* 10/100 EISA card with Cascade chip */  { 0x4019F022, "HP J2577",       HP100_BUS_EISA },  /* 10/100 ISA card with Cascade chip */  { 0x5019F022, "HP J2573",       HP100_BUS_ISA },  /* 10/100 PCI card - old J2585A */  { 0x1030103c, "HP J2585A", 	    HP100_BUS_PCI },  /* 10/100 PCI card - new J2585B - master capable */  { 0x1041103c, "HP J2585B",      HP100_BUS_PCI },  /* 10 Mbit Combo Adapter */  { 0x1042103c, "HP J2970",       HP100_BUS_PCI },  /* 10 Mbit 10baseT Adapter */  { 0x1040103c, "HP J2973",       HP100_BUS_PCI },  /* 10/100 EISA card from Compex */  { 0x0103180e, "ReadyLink ENET100-VG4", HP100_BUS_EISA },  /* 10/100 EISA card from Compex - FreedomLine (sq5bpf) */  /* Note: plhbrod@mbox.vol.cz reported that same ID have ISA */  /*       version of adapter, too... */  { 0x0104180e, "FreedomLine 100/VG", HP100_BUS_EISA },  /* 10/100 PCI card from Compex - FreedomLine   *   * I think this card doesn't like aic7178 scsi controller, but   * I haven't tested this much. It works fine on diskless machines.   *                            Jacek Lipkowski <sq5bpf@acid.ch.pw.edu.pl>   */  { 0x021211f6, "FreedomLine 100/VG", HP100_BUS_PCI },    /* 10/100 PCI card from Compex (J2585A compatible) */  { 0x011211f6, "ReadyLink ENET100-VG4", HP100_BUS_PCI }};#define HP100_EISA_IDS_SIZE	(sizeof(hp100_eisa_ids)/sizeof(struct hp100_eisa_id))static struct hp100_pci_id hp100_pci_ids[] = {  { PCI_VENDOR_ID_HP, 		PCI_DEVICE_ID_HP_J2585A },  { PCI_VENDOR_ID_HP,		PCI_DEVICE_ID_HP_J2585B },  { PCI_VENDOR_ID_COMPEX,	PCI_DEVICE_ID_COMPEX_ENET100VG4 },  { PCI_VENDOR_ID_COMPEX2,	PCI_DEVICE_ID_COMPEX2_100VG }};#define HP100_PCI_IDS_SIZE	(sizeof(hp100_pci_ids)/sizeof(struct hp100_pci_id))static int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO;static int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;static int hp100_mode = 1;#ifdef LINUX_2_1MODULE_PARM( hp100_rx_ratio, "1i" );MODULE_PARM( hp100_priority_tx, "1i" );MODULE_PARM( hp100_mode, "1i" );#endif/* *  prototypes */static int  hp100_probe1( struct device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn  );static int  hp100_open( struct device *dev );static int  hp100_close( struct device *dev );static int  hp100_start_xmit( struct sk_buff *skb, struct device *dev );static int  hp100_start_xmit_bm (struct sk_buff *skb, struct device *dev );static void hp100_rx( struct device *dev );static hp100_stats_t *hp100_get_stats( struct device *dev );static void hp100_misc_interrupt( struct device *dev );static void hp100_update_stats( struct device *dev );static void hp100_clear_stats( int ioaddr );static void hp100_set_multicast_list( struct device *dev);static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs );static void hp100_start_interface( struct device *dev );static void hp100_stop_interface( struct device *dev );static void hp100_load_eeprom( struct device *dev, u_short ioaddr );static int  hp100_sense_lan( struct device *dev );static int  hp100_login_to_vg_hub( struct device *dev, u_short force_relogin );static int  hp100_down_vg_link( struct device *dev );static void hp100_cascade_reset( struct device *dev, u_short enable );static void hp100_BM_shutdown( struct device *dev );static void hp100_mmuinit( struct device *dev );static void hp100_init_pdls( struct device *dev );static int  hp100_init_rxpdl( struct device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr);static int  hp100_init_txpdl( struct device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr);static void hp100_rxfill( struct device *dev );static void hp100_hwinit( struct device *dev );static void hp100_clean_txring( struct device *dev );#ifdef HP100_DEBUGstatic void hp100_RegisterDump( struct device *dev );#endif/* TODO: This function should not really be needed in a good design... */static void wait( void ){  udelay( 1000 );}/* *  probe functions *  These functions should - if possible - avoid doing write operations *  since this could cause problems when the card is not installed. */ __initfunc(int hp100_probe( struct device *dev )){  int base_addr = dev ? dev -> base_addr : 0;  int ioaddr = 0;#ifdef CONFIG_PCI  int pci_start_index = 0;#endif#ifdef HP100_DEBUG_B  hp100_outw( 0x4200, TRACE );  printk( "hp100: %s: probe\n", dev->name );#endif  if ( base_addr > 0xff )	/* Check a single specified location. */    {      if ( check_region( base_addr, HP100_REGION_SIZE ) ) return -EINVAL;      if ( base_addr < 0x400 )        return hp100_probe1( dev, base_addr, HP100_BUS_ISA, 0, 0 );      if ( EISA_bus && base_addr >= 0x1c38 && ( (base_addr - 0x1c38) & 0x3ff ) == 0 )        return hp100_probe1( dev, base_addr, HP100_BUS_EISA, 0, 0 );#ifdef CONFIG_PCI      printk( "hp100: %s: You may specify card # in i/o address parameter for PCI bus...", dev->name );      return hp100_probe1( dev, base_addr, HP100_BUS_PCI, 0, 0 );#else      return -ENODEV;#endif    }  else#ifdef CONFIG_PCI    if ( base_addr > 0 && base_addr < 8 + 1 )      pci_start_index = 0x100 | ( base_addr - 1 );    else#endif      if ( base_addr != 0 ) return -ENXIO;  /* at first - scan PCI bus(es) */#ifdef CONFIG_PCI  if ( pcibios_present() )    {      int pci_index;#ifdef HP100_DEBUG_PCI      printk( "hp100: %s: PCI BIOS is present, checking for devices..\n", dev->name );#endif      for ( pci_index = pci_start_index & 7; pci_index < 8; pci_index++ )        {          u_char pci_bus, pci_device_fn;          u_short pci_command;          int pci_id_index;	  for ( pci_id_index = 0; pci_id_index < HP100_PCI_IDS_SIZE; pci_id_index++ )            if ( pcibios_find_device( hp100_pci_ids[ pci_id_index ].vendor,            			      hp100_pci_ids[ pci_id_index ].device,                                      pci_index, &pci_bus,                                      &pci_device_fn ) == 0 ) goto __pci_found;          break;	  __pci_found:          pcibios_read_config_dword( pci_bus, pci_device_fn,                                     PCI_BASE_ADDRESS_0, &ioaddr );          ioaddr &= ~3;    /* remove I/O space marker in bit 0. */          if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;          pcibios_read_config_word( pci_bus, pci_device_fn,                                    PCI_COMMAND, &pci_command );          if ( !( pci_command & PCI_COMMAND_IO ) )            {#ifdef HP100_DEBUG              printk( "hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name );#endif              pci_command |= PCI_COMMAND_IO;              pcibios_write_config_word( pci_bus, pci_device_fn,                                         PCI_COMMAND, pci_command );            }          if ( !( pci_command & PCI_COMMAND_MASTER ) )            {#ifdef HP100_DEBUG              printk( "hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name );#endif              pci_command |= PCI_COMMAND_MASTER;              pcibios_write_config_word( pci_bus, pci_device_fn,                                         PCI_COMMAND, pci_command );            }#ifdef HP100_DEBUG          printk( "hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr );#endif	  if ( hp100_probe1( dev, ioaddr, HP100_BUS_PCI, pci_bus, pci_device_fn ) == 0 )	    return 0;        }    }  if ( pci_start_index > 0 ) return -ENODEV;#endif /* CONFIG_PCI */  /* Second: Probe all EISA possible port regions (if EISA bus present) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -