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

📄 hp100.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    if ( dev->irq == 2 )      dev->irq = 9;#ifdef LINUX_2_1  }#endif  if(lp->mode==1) /* busmaster */    dev->dma=4;   /* Ask the card for its MAC address and store it for later use. */  hp100_page( ID_MAC_ADDR );  for ( i = uc = 0; i < 6; i++ )    dev->dev_addr[ i ] = hp100_inb( LAN_ADDR + i );  /* Reset statistics (counters) */  hp100_clear_stats( ioaddr );  ether_setup( dev );  /* If busmaster mode is wanted, a dma-capable memory area is needed for   * the rx and tx PDLs    * PCI cards can access the whole PC memory. Therefore GFP_DMA is not   * needed for the allocation of the memory area.    */  /* TODO: We do not need this with old cards, where PDLs are stored   * in the cards shared memory area. But currently, busmaster has been   * implemented/tested only with the lassen chip anyway... */  if(lp->mode==1) /* busmaster */    {      /* Get physically continous memory for TX & RX PDLs    */      if ( (lp->page_vaddr=kmalloc(MAX_RINGSIZE+0x0f,GFP_KERNEL) ) == NULL)        return -ENOMEM;      lp->page_vaddr_algn=((u_int *) ( ((u_int)(lp->page_vaddr)+0x0f) &~0x0f));      memset(lp->page_vaddr, 0, MAX_RINGSIZE+0x0f);#ifdef HP100_DEBUG_BM      printk("hp100: %s: Reserved DMA memory from 0x%x to 0x%x\n",      	     dev->name,             (u_int)lp->page_vaddr_algn,             (u_int)lp->page_vaddr_algn+MAX_RINGSIZE);#endif      lp->rxrcommit  = lp->txrcommit = 0;      lp->rxrhead    = lp->rxrtail   = &(lp->rxring[0]);      lp->txrhead    = lp->txrtail   = &(lp->txring[0]);     }  /* Initialise the card. */  /* (I'm not really sure if it's a good idea to do this during probing, but    * like this it's assured that the lan connection type can be sensed   * correctly)   */  hp100_hwinit( dev );  /* Try to find out which kind of LAN the card is connected to. */  lp->lan_type = hp100_sense_lan( dev );       /* Print out a message what about what we think we have probed. */  printk( "hp100: %s: %s at 0x%x, IRQ %d, ",          dev->name, lp->id->name, ioaddr, dev->irq );  switch ( bus ) {  case HP100_BUS_EISA: printk( "EISA" ); break;  case HP100_BUS_PCI:  printk( "PCI" );  break;  default:     printk( "ISA" );  break;  }  printk( " bus, %dk SRAM (rx/tx %d%%).\n",          lp->memory_size >> 10, lp->rx_ratio );  if ( lp->mode==2 ) /* memory mapped */     {      printk( "hp100: %s: Memory area at 0x%lx-0x%lx",              dev->name,(u_long)mem_ptr_phys,              ((u_long)mem_ptr_phys+(mem_ptr_phys>(u_int *)0x100000?(u_long)lp->memory_size:16*1024))-1 );      if ( mem_ptr_virt )	printk( " (virtual base 0x%lx)", (u_long)mem_ptr_virt );      printk( ".\n" );      /* Set for info when doing ifconfig */      dev->mem_start = (u_long)mem_ptr_phys;      dev->mem_end = (u_long)mem_ptr_phys+(u_long)lp->memory_size;    }  printk( "hp100: %s: ", dev->name );  if ( lp->lan_type != HP100_LAN_ERR )    printk( "Adapter is attached to " );  switch ( lp->lan_type ) {  case HP100_LAN_100:    printk( "100Mb/s Voice Grade AnyLAN network.\n" );    break;  case HP100_LAN_10:    printk( "10Mb/s network.\n" );    break;  default:    printk( "Warning! Link down.\n" );  }  return 0;}/* This procedure puts the card into a stable init state */static void hp100_hwinit( struct device *dev ){  int ioaddr = dev->base_addr;  struct hp100_private *lp = (struct hp100_private *)dev->priv;#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 );

⌨️ 快捷键说明

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