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

📄 hp100.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef HP100_DEBUG_B  hp100_outw( 0x4202, TRACE );  printk("hp100: %s: hwinit\n", dev->name);#endif  /* Initialise the card. -------------------------------------------- */  /* Clear all pending Ints and disable Ints */  hp100_page( PERFORMANCE );  hp100_outw( 0xfefe, IRQ_MASK );    /* mask off all ints */  hp100_outw( 0xffff, IRQ_STATUS );  /* clear all pending ints */  hp100_outw( HP100_INT_EN | HP100_RESET_LB, OPTION_LSW );  hp100_outw( HP100_TRI_INT | HP100_SET_HB, OPTION_LSW );  if(lp->mode==1)    {       hp100_BM_shutdown( dev ); /* disables BM, puts cascade in reset */      wait();    }  else    {      hp100_outw( HP100_INT_EN | HP100_RESET_LB, OPTION_LSW );      hp100_cascade_reset( dev, TRUE );      hp100_page( MAC_CTRL );      hp100_andb( ~(HP100_RX_EN|HP100_TX_EN), MAC_CFG_1);     }		  /* Initiate EEPROM reload */  hp100_load_eeprom( dev, 0 );		  wait();		  /* Go into reset again. */  hp100_cascade_reset( dev, TRUE );		  /* Set Option Registers to a safe state  */  hp100_outw( HP100_DEBUG_EN |              HP100_RX_HDR   |              HP100_EE_EN    |              HP100_BM_WRITE |              HP100_BM_READ  | HP100_RESET_HB |              HP100_FAKE_INT |              HP100_INT_EN   |	      HP100_MEM_EN   |              HP100_IO_EN    | HP100_RESET_LB, OPTION_LSW);		  hp100_outw( HP100_TRI_INT  |              HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW );  hp100_outb( HP100_PRIORITY_TX |              HP100_ADV_NXT_PKT |              HP100_TX_CMD      | HP100_RESET_LB, OPTION_MSW );  /* TODO: Configure MMU for Ram Test. */  /* TODO: Ram Test. */  /* Re-check if adapter is still at same i/o location      */  /* (If the base i/o in eeprom has been changed but the    */  /* registers had not been changed, a reload of the eeprom */  /* would move the adapter to the address stored in eeprom */    /* TODO: Code to implement. */		  /* Until here it was code from HWdiscover procedure. */  /* Next comes code from mmuinit procedure of SCO BM driver which is   * called from HWconfigure in the SCO driver.  */  /* Initialise MMU, eventually switch on Busmaster Mode, initialise    * multicast filter...   */  hp100_mmuinit( dev );  /* We don't turn the interrupts on here - this is done by start_interface. */  wait(); /* TODO: Do we really need this? */  /* Enable Hardware (e.g. unreset) */  hp100_cascade_reset( dev, FALSE );  /* ------- initialisation complete ----------- */  /* Finally try to log in the Hub if there may be a VG connection. */  if( lp->lan_type != HP100_LAN_10 )    hp100_login_to_vg_hub( dev, FALSE ); /* relogin */}/*  * mmuinit - Reinitialise Cascade MMU and MAC settings. * Note: Must already be in reset and leaves card in reset.  */static void hp100_mmuinit( struct device *dev ){  int ioaddr = dev->base_addr;  struct hp100_private *lp = (struct hp100_private *)dev->priv;  int i;#ifdef HP100_DEBUG_B  hp100_outw( 0x4203, TRACE );  printk("hp100: %s: mmuinit\n",dev->name);#endif#ifdef HP100_DEBUG  if( 0!=(hp100_inw(OPTION_LSW)&HP100_HW_RST) )    {      printk("hp100: %s: Not in reset when entering mmuinit. Fix me.\n",dev->name);      return;    }#endif  /* Make sure IRQs are masked off and ack'ed. */  hp100_page( PERFORMANCE );  hp100_outw( 0xfefe, IRQ_MASK );  /* mask off all ints */  hp100_outw( 0xffff, IRQ_STATUS );  /* ack IRQ */  /*   * Enable Hardware    * - Clear Debug En, Rx Hdr Pipe, EE En, I/O En, Fake Int and Intr En   * - Set Tri-State Int, Bus Master Rd/Wr, and Mem Map Disable   * - Clear Priority, Advance Pkt and Xmit Cmd   */  hp100_outw( HP100_DEBUG_EN |              HP100_RX_HDR   |              HP100_EE_EN    | HP100_RESET_HB |              HP100_IO_EN    |              HP100_FAKE_INT |              HP100_INT_EN   | HP100_RESET_LB, OPTION_LSW );  	  hp100_outw( HP100_TRI_INT | HP100_SET_HB, OPTION_LSW);		  if(lp->mode==1) /* busmaster */    {      hp100_outw( HP100_BM_WRITE | 		  HP100_BM_READ  |		  HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW );    }  else if(lp->mode==2) /* memory mapped */    {      hp100_outw( HP100_BM_WRITE |		  HP100_BM_READ  | HP100_RESET_HB, OPTION_LSW );      hp100_outw( HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW );      hp100_outw( HP100_MEM_EN | HP100_SET_LB, OPTION_LSW );      hp100_outw( HP100_IO_EN | HP100_SET_LB, OPTION_LSW );    }  else if( lp->mode==3 ) /* i/o mapped mode */    {      hp100_outw( HP100_MMAP_DIS | HP100_SET_HB |                   HP100_IO_EN    | HP100_SET_LB, OPTION_LSW );    }  hp100_page( HW_MAP );  hp100_outb( 0, EARLYRXCFG );  hp100_outw( 0, EARLYTXCFG );    /*   * Enable Bus Master mode   */  if(lp->mode==1) /* busmaster */    {      /* Experimental: Set some PCI configuration bits */      hp100_page( HW_MAP );      hp100_andb( ~HP100_PDL_USE3, MODECTRL1 ); /* BM engine read maximum */      hp100_andb( ~HP100_TX_DUALQ, MODECTRL1 ); /* No Queue for Priority TX */      /* PCI Bus failures should result in a Misc. Interrupt */      hp100_orb( HP100_EN_BUS_FAIL, MODECTRL2);					      hp100_outw( HP100_BM_READ | HP100_BM_WRITE | HP100_SET_HB, OPTION_LSW );      hp100_page( HW_MAP );					      /* Use Burst Mode and switch on PAGE_CK */      hp100_orb( HP100_BM_BURST_RD |                 HP100_BM_BURST_WR, BM);      if((lp->chip==HP100_CHIPID_RAINIER)||(lp->chip==HP100_CHIPID_SHASTA))	hp100_orb( HP100_BM_PAGE_CK, BM );      hp100_orb( HP100_BM_MASTER, BM );		    }  else /* not busmaster */    {      hp100_page(HW_MAP);      hp100_andb(~HP100_BM_MASTER, BM );    }  /*   * Divide card memory into regions for Rx, Tx and, if non-ETR chip, PDLs   */    hp100_page( MMU_CFG );  if(lp->mode==1) /* only needed for Busmaster */    {      int xmit_stop, recv_stop;      if((lp->chip==HP100_CHIPID_RAINIER)||(lp->chip==HP100_CHIPID_SHASTA))        {          int pdl_stop;                    /*           * Each pdl is 508 bytes long. (63 frags * 4 bytes for address and           * 4 bytes for header). We will leave NUM_RXPDLS * 508 (rounded           * to the next higher 1k boundary) bytes for the rx-pdl's	   * Note: For non-etr chips the transmit stop register must be	   * programmed on a 1k boundary, i.e. bits 9:0 must be zero. 	   */          pdl_stop  = lp->memory_size;          xmit_stop = ( pdl_stop-508*(MAX_RX_PDL)-16 )& ~(0x03ff);          recv_stop = ( xmit_stop * (lp->rx_ratio)/100 ) &~(0x03ff);          hp100_outw( (pdl_stop>>4)-1, PDL_MEM_STOP );#ifdef HP100_DEBUG_BM          printk("hp100: %s: PDL_STOP = 0x%x\n", dev->name, pdl_stop);#endif        }      else /* ETR chip (Lassen) in busmaster mode */        {          xmit_stop = ( lp->memory_size ) - 1;          recv_stop = ( ( lp->memory_size * lp->rx_ratio ) / 100 ) & ~(0x03ff);        }      hp100_outw( xmit_stop>>4 , TX_MEM_STOP );      hp100_outw( recv_stop>>4 , RX_MEM_STOP );#ifdef HP100_DEBUG_BM      printk("hp100: %s: TX_STOP  = 0x%x\n",dev->name,xmit_stop>>4);      printk("hp100: %s: RX_STOP  = 0x%x\n",dev->name,recv_stop>>4);#endif    }    else /* Slave modes (memory mapped and programmed io)  */    {      hp100_outw( (((lp->memory_size*lp->rx_ratio)/100)>>4), RX_MEM_STOP );      hp100_outw( ((lp->memory_size - 1 )>>4), TX_MEM_STOP );  #ifdef HP100_DEBUG      printk("hp100: %s: TX_MEM_STOP: 0x%x\n", dev->name,hp100_inw(TX_MEM_STOP));      printk("hp100: %s: RX_MEM_STOP: 0x%x\n", dev->name,hp100_inw(RX_MEM_STOP));#endif    }  /* Write MAC address into page 1 */  hp100_page( MAC_ADDRESS );  for ( i = 0; i < 6; i++ )    hp100_outb( dev->dev_addr[ i ], MAC_ADDR + i );    /* Zero the multicast hash registers */  for ( i = 0; i < 8; i++ )    hp100_outb( 0x0, HASH_BYTE0 + i );      /* Set up MAC defaults */  hp100_page( MAC_CTRL );   /* Go to LAN Page and zero all filter bits */  /* Zero accept error, accept multicast, accept broadcast and accept */  /* all directed packet bits */  hp100_andb( ~(HP100_RX_EN|		HP100_TX_EN|		HP100_ACC_ERRORED|		HP100_ACC_MC|		HP100_ACC_BC|		HP100_ACC_PHY),   MAC_CFG_1 );  hp100_outb( 0x00, MAC_CFG_2 );  /* Zero the frame format bit. This works around a training bug in the */  /* new hubs. */  hp100_outb( 0x00, VG_LAN_CFG_2); /* (use 802.3) */	  if(lp->priority_tx)    hp100_outb( HP100_PRIORITY_TX | HP100_SET_LB, OPTION_MSW );  else    hp100_outb( HP100_PRIORITY_TX | HP100_RESET_LB, OPTION_MSW );	  hp100_outb( HP100_ADV_NXT_PKT |	      HP100_TX_CMD      | HP100_RESET_LB, OPTION_MSW );	  /* If busmaster, initialize the PDLs */  if(lp->mode==1)    hp100_init_pdls( dev );  /* Go to performance page and initalize isr and imr registers */  hp100_page( PERFORMANCE );  hp100_outw( 0xfefe, IRQ_MASK );  /* mask off all ints */  hp100_outw( 0xffff, IRQ_STATUS );  /* ack IRQ */}/* *  open/close functions */static int hp100_open( struct device *dev ){  struct hp100_private *lp = (struct hp100_private *)dev->priv;#ifdef HP100_DEBUG_B  int ioaddr=dev->base_addr;#endif#ifdef HP100_DEBUG_B  hp100_outw( 0x4204, TRACE );  printk("hp100: %s: open\n",dev->name);#endif		  /* New: if bus is PCI or EISA, interrupts might be shared interrupts */  if ( request_irq(dev->irq, hp100_interrupt,  		   lp->bus==HP100_BUS_PCI||lp->bus==HP100_BUS_EISA?SA_SHIRQ:SA_INTERRUPT,  		   lp->id->name, dev))    {      printk( "hp100: %s: unable to get IRQ %d\n", dev->name, dev->irq );      return -EAGAIN;    }  MOD_INC_USE_COUNT;  dev->tbusy = 0;  dev->trans_start = jiffies;  dev->interrupt = 0;  dev->start = 1;  lp->lan_type = hp100_sense_lan( dev );  lp->mac1_mode = HP100_MAC1MODE3;  lp->mac2_mode = HP100_MAC2MODE3;  memset( &lp->hash_bytes, 0x00, 8 );  hp100_stop_interface( dev );   hp100_hwinit( dev );  hp100_start_interface( dev ); /* sets mac modes, enables interrupts */  return 0;}/* The close function is called when the interface is to be brought down */static int hp100_close( struct device *dev ){  int ioaddr = dev->base_addr;  struct hp100_private *lp = (struct hp100_private *)dev->priv;#ifdef HP100_DEBUG_B  hp100_outw( 0x4205, TRACE );  printk("hp100: %s: close\n", dev->name);#endif  hp100_page( PERFORMANCE );  hp100_outw( 0xfefe, IRQ_MASK );    /* mask off all IRQs */  hp100_stop_interface( dev );  if ( lp->lan_type == HP100_LAN_100 )     lp->hub_status=hp100_login_to_vg_hub( dev, FALSE );  dev->tbusy = 1;  dev->start = 0;  free_irq( dev->irq, dev );#ifdef HP100_DEBUG  printk( "hp100: %s: close LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW) );#endif  MOD_DEC_USE_COUNT;  return 0;}/* * Configure the PDL Rx rings and LAN  */static void hp100_init_pdls( struct device *dev ){  struct hp100_private *lp = (struct hp100_private *)dev->priv;  hp100_ring_t         *ringptr;  u_int                *pageptr;  int                  i;#ifdef HP100_DEBUG_B  int ioaddr = dev->base_addr;#endif#ifdef HP100_DEBUG_B  hp100_outw( 0x4206, TRACE );  printk("hp100: %s: init pdls\n", dev->name);#endif  if(0==lp->page_vaddr_algn)    printk("hp100: %s: Warning: lp->page_vaddr_algn not initialised!\n",dev->name);  else    {      /* pageptr shall point into the DMA accessible memory region  */      /* we use this pointer to status the upper limit of allocated */      /* memory in the allocated page. */      /* note: align the pointers to the pci cache line size */      memset(lp->page_vaddr_algn, 0, MAX_RINGSIZE); /* Zero  Rx/Tx ring page */      pageptr=lp->page_vaddr_algn;						      lp->rxrcommit =0;      ringptr = lp->rxrhead = lp-> rxrtail = &(lp->rxring[0]);            /* Initialise Rx Ring */      for (i=MAX_RX_PDL-1; i>=0; i--)        {          lp->rxring[i].next = ringptr;          ringptr=&(lp->rxring[i]);          pageptr+=hp100_init_rxpdl(dev, ringptr, pageptr);        }            /* Initialise Tx Ring */      lp->txrcommit = 0;      ringptr = lp->txrhead = lp->txrtail = &(lp->txring[0]);      for (i=MAX_TX_PDL-1; i>=0; i--)        {          lp->txring[i].next = ringptr;          ringptr=&(lp->txring[i]);          pageptr+=hp100_init_txpdl(dev, ringptr, pageptr);        }    }}/* These functions "format" the entries in the pdl structure   *//* They return how much memory the fragments need.            */static int hp100_init_rxpdl( struct device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ){  /* pdlptr is starting adress for this pdl */  if( 0!=( ((unsigned)pdlptr) & 0xf) )    printk("hp100: %s: Init rxpdl: Unaligned pdlptr 0x%x.\n",dev->name,(unsigned)pdlptr);

⌨️ 快捷键说明

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